--- /dev/null
+#!/usr/bin/env python2.4
+# -*- encoding: iso-8859-1 -*-
+# vim: set et sw=4 sts=4 :
+
+# Módulos estándar
+import os
+import sys
+import cgi
+# Módulos externos
+import sqlobject
+# Módulos locales
+import sercom
+from sercom.sqlo import *
+
+# Inicializo
+conf, conn, log = sercom.init('cgi')
+
+# Para debug web
+import cgitb; cgitb.enable()
+
+#XXX HORRIBLE
+PASSWD = conf.get('general', 'claves')
+
+def http_header_html(req):
+ return 'Content-type: text/html\r\n\r\n'
+
+def http_header_zip(req, filename):
+ return 'Content-type: application/zip\r\n' \
+ 'Content-Disposition: attachment;filename=%s\r\n' \
+ '\r\n' % filename
+
+def header(req):
+ return '''<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
+<html>
+ <head>
+ <title>SUWI - Sercom Ugly Web Interface</title>
+ <style type="text/css">
+ <!--
+ body
+ {
+ font-family: sans-serif;
+ background-color: rgb(255, 255, 255);
+ }
+ table
+ {
+ border: medium black solid;
+ border-collapse: collapse;
+ }
+ th
+ {
+ border: thin black solid;
+ color: white;
+ background-color: navy;
+ padding: 3pt;
+ text-align: center;
+ vertical-align: middle;
+ }
+ td
+ {
+ border: thin black solid;
+ padding: 3pt;
+ text-align: center;
+ vertical-align: middle;
+ }
+ .warn
+ {
+ color: red;
+ }
+ // -->
+ </style>
+ </head>
+ <body>
+'''
+ pass
+
+def footer(req):
+ return '''
+ </body>
+</html>
+'''
+ pass
+
+def form(req, submit, str=None):
+ r = submit
+ if submit is not None:
+ r = '<form method="post">\n'
+ if str: r += str
+ r += '<input type="submit" value="%s">\n' % submit
+ r += '</form>\n'
+ return r
+
+def pre(s):
+ return '<pre>%s</pre>' % cgi.escape(str(s))
+
+def input_login(req):
+ return '<input type="hidden" name="pw" value="%s" />\n' % PASSWD
+
+def input_curso(req, curso_id):
+ return input_login(req) \
+ + '<input type="hidden" name="curso" value="%d" />\n' % curso_id
+
+def input_entrega(req, entrega_id):
+ e = Entrega.get(entrega_id, connection=conn)
+ return input_curso(req, e.curso.id) \
+ + '<input type="hidden" name="entrega" value="%d" />\n' % entrega_id
+
+def input_zip(req, entrega_id):
+ return input_entrega(req, entrega_id) \
+ + '<input type="hidden" name="zip" value="1" />\n'
+
+def input_inscripto(req, inscripto_id=None):
+ if inscripto_id is not None:
+ return '<input type="hidden" name="inscripto" value="%d" />\n' \
+ % inscripto_id
+ return ''
+
+def input_pruebas(req, intento_id, inscripto_id=None):
+ i = Intento.get(intento_id, connection=conn)
+ r = input_entrega(req, i.entrega.id)
+ r += '<input type="hidden" name="intento" value="%d" />\n' % intento_id
+ r += input_inscripto(req, inscripto_id)
+ return r
+
+def input_intentos(req, entrega_id, inscripto_id):
+ return input_entrega(req, entrega_id) + input_inscripto(req, inscripto_id)
+
+def login(req):
+ r = '<h1>Bienvenido a ' \
+ '<acronym title="Sercom Ugly Web Interface">SUWI</acronym></h1>\n'
+ r += '<p>Debe ingresar la contraseña para seguir...</p>\n'
+ return r + form(req, 'Entrar',
+ '<p>Contraseña: <input type="password" name="pw" /></p>')
+
+def curso(req):
+ cursos = [c for c in Curso.select(connection=conn) if len(c.entregas)]
+ r = '<h1>Elegir curso</h1>\n'
+ if cursos:
+ r += '<p>Curso: <select name="curso">\n'
+ for c in cursos:
+ r += '\t<option value="%d">%d-%d-%d</option>\n' \
+ % (c.id, c.anio, c.cuatrimestre, c.curso)
+ r += '</select></p>\n'
+ else:
+ r += '<p>No hay cursos con entregas</p>\n'
+ return form(req, 'Ver', r + input_login(req))
+
+def entrega(req, curso_id):
+ c = Curso.get(curso_id, connection=conn)
+ r = '<h1>Elegir entrega del curso %d-%d-%d</h1>\n' \
+ % (c.anio, c.cuatrimestre, c.curso)
+ r += '<p>Entrega: <select name="entrega">\n'
+ for e in c.entregas:
+ r += '\t<option value="%d">%d-%d</option>\n' \
+ % (e.id, e.nroEjercicio, e.entrega)
+ r += '</select></p>\n'
+ return form(req, 'Ver', r + input_curso(req, curso_id))
+
+def pruebas(req, intento_id, inscripto_id=None):
+ def header():
+ return '''<table>
+ <tr>
+ <th>Nombre</th>
+ <th>Pasada</th>
+ <th>Privada</th>
+ <th>Activa</th>
+ <th>Inicio</th>
+ <th>Fin</th>
+ <th>Observaciones</th>
+ <tr>
+'''
+ pass
+ def footer():
+ r = '</table>\n<p>\n'
+ r += form(req, 'Volver', input_entrega(req, i.entrega.id)
+ + input_inscripto(req, inscripto_id))
+ r += '</p>\n'
+ return r
+ def row(p):
+ return '''
+ <tr>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ </tr>
+''' % (p.casoDePrueba.nombre, p.pasada, p.casoDePrueba.privado,
+ p.casoDePrueba.activo, p.inicio, p.fin,
+ pre(p.observaciones))
+
+ i = Intento.get(intento_id, connection=conn)
+ r = '<h1>Pruebas del intento %d del alumno %d</h1>\n' \
+ % (i.numero, i.inscripto.padron)
+ r += header()
+ for p in i.pruebas:
+ r += row(p)
+ r += footer()
+ return r
+
+def intentos(req, entrega_id, inscripto_id):
+ def header():
+ return '''<table>
+ <tr>
+ <th>Nro</th>
+ <th>Llegada</th>
+ <th>Compila</th>
+ <th>Pruebas</th>
+ <th>Observaciones</th>
+ <tr>
+'''
+ pass
+ def footer():
+ r = '</table>\n<p>\n'
+ r += form(req, 'Volver', input_entrega(req, entrega_id))
+ r += '</p>\n'
+ return r
+ def row(i):
+ if i.pruebasPasadas: pruebas = 'BIEN'
+ elif not i.compila: pruebas = None
+ else: pruebas = 'MAL'
+ return '''
+ <tr>
+ <td>%d</td>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ </tr>
+''' % (i.numero, i.llegada, i.compila,
+ form(req, pruebas, input_pruebas(req, i.id, inscripto_id)),
+ pre(i.observaciones))
+
+ r = '<h1>Intentos del alumno %d</h1>\n' \
+ % Inscripto.get(inscripto_id, connection=conn).padron
+ r += header()
+ for i in Intento.selectBy(entregaID=entrega_id, inscriptoID=inscripto_id,
+ connection=conn):
+ r += row(i)
+ r += footer()
+ return r
+
+def zip(req, entrega_id):
+ def zip_path(path, base, zipfd):
+ paths = os.listdir(path)
+ for p in paths:
+ if os.path.isdir(p):
+ zip_path(os.path.join(path, p), os.path.join(base, p), zipfd)
+ else:
+ zipfd.write(os.path.join(path, p), os.path.join(base, p))
+
+ from zipfile import ZipFile, ZIP_DEFLATED
+ e = Entrega.get(entrega_id, connection=conn)
+ c = e.curso
+ req.write(http_header_zip(req, 'entrega-%d.%d.%d-%d.%d.zip'
+ % (c.anio, c.cuatrimestre, c.curso, e.nroEjercicio, e.entrega)))
+ tmpfname = os.tmpnam()
+ zipfd = ZipFile(tmpfname, 'w', ZIP_DEFLATED)
+ for c in e.correcciones:
+ zip_path(os.path.join(conf.get('general', 'data_dir'), c.intento.path),
+ str(c.intento.inscripto.padron), zipfd)
+ zipfd.close()
+ req.write(file(tmpfname, 'r').read())
+ os.unlink(tmpfname)
+
+def correcciones(req, entrega_id):
+ def header():
+ return '''<table>
+ <tr>
+ <th>Padrón</th>
+ <th>Pruebas</th>
+ <th>Intentos</th>
+ <tr>
+'''
+ pass
+ def footer():
+ r = '</table>\n<p>\n'
+ r += form(req, 'Elegir curso', input_login(req))
+ r += form(req, 'Elegir entrega', input_curso(req, e.curso.id))
+ r += form(req, 'Bajar entrega en .zip', input_zip(req, entrega_id))
+ r += '</p>\n'
+ return r
+ def row(c):
+ if c.intento.pruebasPasadas: pruebas = 'BIEN'
+ elif not c.intento.compila: prubas = None
+ else: pruebas = 'MAL'
+ intentos = int(Intento.selectBy(inscriptoID=c.inscriptoID,
+ entregaID=c.entregaID, connection=conn).count())
+ return '''
+ <tr>
+ <td>%d</td>
+ <td>%s</td>
+ <td>%s</td>
+ </tr>
+''' % (c.inscripto.padron,
+ form(req, pruebas, input_pruebas(req, c.intento.id)),
+ form(req, intentos, input_intentos(req, c.entrega.id, c.inscripto.id)))
+
+ e = Entrega.get(entrega_id, connection=conn)
+ c = e.curso
+ r = '<h1>Entrega %d.%d del curso %d-%d-%d</h1>\n' \
+ % (e.nroEjercicio, e.entrega, c.anio, c.cuatrimestre, c.curso)
+ r += header()
+ for c in e.correcciones:
+ r += row(c)
+ r += footer()
+ return r
+
+#
+# MAIN
+#
+
+req = sys.stdout
+f = cgi.FieldStorage()
+raw = f.has_key('zip')
+
+
+if not raw:
+ print http_header_html(req)
+ print header(req)
+
+path = os.getenv('PATH_INFO')
+
+if not f.has_key('pw'):
+ print login(req)
+elif f.has_key('pw') and f.getfirst('pw') <> PASSWD:
+ print login(req)
+ print '<p class="warn">Password Incorrecto!</p>\n'
+elif not f.has_key('curso'):
+ print curso(req)
+elif not f.has_key('entrega'):
+ print entrega(req, int(f.getfirst('curso')))
+elif f.has_key('intento'):
+ inscripto_id = None
+ if f.has_key('inscripto'):
+ inscripto_id = int(f.getfirst('inscripto'))
+ print pruebas(req, int(f.getfirst('intento')), inscripto_id)
+elif f.has_key('inscripto'):
+ print intentos(req, int(f.getfirst('entrega')), int(f.getfirst('inscripto')))
+elif f.has_key('zip'):
+ zip(req, int(f.getfirst('entrega')))
+else:
+ print correcciones(req, int(f.getfirst('entrega')))
+
+if not raw:
+ print footer(req)
+