#!/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', 'cgipw') 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 ''' SUWI - Sercom Ugly Web Interface ''' pass def footer(req): return ''' ''' pass def form(req, submit, str=None): r = submit if submit is not None: r = '
\n' if str: r += str r += '\n' % submit r += '
\n' return r def pre(s): return '
%s
' % cgi.escape(str(s)) def input_login(req): return '\n' % PASSWD def input_curso(req, curso_id): return input_login(req) \ + '\n' % curso_id def input_entrega(req, entrega_id): e = Entrega.get(entrega_id, connection=conn) return input_curso(req, e.curso.id) \ + '\n' % entrega_id def input_zip(req, entrega_id): return input_entrega(req, entrega_id) \ + '\n' def input_zip_rechazados(req, entrega_id): return input_entrega(req, entrega_id) \ + '\n' \ + '\n' def input_inscripto(req, inscripto_id=None): if inscripto_id is not None: return '\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 += '\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 = '

Bienvenido a ' \ 'SUWI

\n' r += '

Debe ingresar la contraseña para seguir...

\n' return r + form(req, 'Entrar', '

Contraseña:

') def curso(req): cursos = [c for c in Curso.select(connection=conn) if len(c.entregas)] r = '

Elegir curso

\n' if cursos: r += '

Curso:

\n' else: r += '

No hay cursos con entregas

\n' return form(req, 'Ver', r + input_login(req)) def entrega(req, curso_id): c = Curso.get(curso_id, connection=conn) r = '

Elegir entrega del curso %d-%d-%d

\n' \ % (c.anio, c.cuatrimestre, c.curso) r += '

Entrega:

\n' return form(req, 'Ver', r + input_curso(req, curso_id)) def pruebas(req, intento_id, inscripto_id=None): def header(): return ''' ''' pass def footer(): r = '
Nombre Pasada Privada Activa Inicio Fin Observaciones
\n

\n' r += form(req, 'Volver', input_entrega(req, i.entrega.id) + input_inscripto(req, inscripto_id)) #XXX Hack feo y muy hardcodeado para ver los fuentes (morirá con suwi) r += 'ver fuentes

' \ % (i.inscripto.curso.anio, i.inscripto.curso.cuatrimestre, i.inscripto.curso.curso, i.entrega.nroEjercicio, i.entrega.entrega, i.inscripto.padron, i.numero) r += '

\n' return r def row(p): return ''' %s %s %s %s %s %s %s ''' % (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 = '

Pruebas del intento %d del alumno %d

\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 ''' ''' pass def footer(): r = '
Nro Llegada Compila Pruebas Observaciones
\n

\n' r += form(req, 'Volver', input_entrega(req, entrega_id)) r += '

\n' return r def row(i): if i.pruebasPasadas: pruebas = 'BIEN' elif not i.compila: pruebas = None else: pruebas = 'MAL' return ''' %d %s %s %s %s ''' % (i.numero, i.llegada, i.compila, form(req, pruebas, input_pruebas(req, i.id, inscripto_id)), pre(i.observaciones)) r = '

Intentos del alumno %d

\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, rechazados=False): def zip_path(path, base, zipfd): paths = os.listdir(path) for p in paths: if os.path.isdir(os.path.join(path, 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 filename = 'entrega-%d.%d.%d-%d.%d' \ % (c.anio, c.cuatrimestre, c.curso, e.nroEjercicio, e.entrega) if rechazados: filename += '-rechazados' filename += '.zip' req.write(http_header_zip(req, filename)) tmpfname = os.tmpnam() zipfd = ZipFile(tmpfname, 'w', ZIP_DEFLATED) if rechazados: inscriptos_ok = set([c.inscripto for c in e.correcciones]) inscriptos = set([i.inscripto for i in e.intentos]) for i in inscriptos - inscriptos_ok: intento = list(Intento.selectBy(entregaID=e.id, inscriptoID=i.id, connection=conn))[-1] zip_path(os.path.join(conf.get('general', 'data_dir'), intento.path), str(i.padron), zipfd) else: 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 correccion_header(): return ''' ''' pass def correccion_footer(): return ' \n
Entregas aceptadas
Padrón Pruebas Intentos
\n' def correccion_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 ''' %d %s %s ''' % (c.inscripto.padron, form(req, pruebas, input_pruebas(req, c.intento.id)), form(req, intentos, input_intentos(req, c.entrega.id, c.inscripto.id))) def rechazado_header(): return ''' ''' pass def rechazado_footer(): return ' \n
Entregas rechazadas
Padrón Intentos
\n' def rechazado_row(inscripto, entrega): intentos = int(Intento.selectBy(inscriptoID=inscripto.id, entregaID=entrega.id, connection=conn).count()) return ''' %d %s ''' % (inscripto.padron, form(req, intentos, input_intentos(req, entrega.id, inscripto.id))) def footer(): r = '

\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 += form(req, 'Bajar entrega rechazadas en .zip', input_zip_rechazados(req, entrega_id)) r += '

\n' return r e = Entrega.get(entrega_id, connection=conn) c = e.curso r = '

Entrega %d.%d del curso %d-%d-%d

\n' \ % (e.nroEjercicio, e.entrega, c.anio, c.cuatrimestre, c.curso) correcciones = list(e.correcciones) # Ordena comparando padron correcciones.sort(lambda x, y: cmp(x.inscripto.padron, y.inscripto.padron)) r += correccion_header() for c in correcciones: r += correccion_row(c) r += correccion_footer() inscriptos_ok = set([c.inscripto for c in correcciones]) inscriptos = set([i.inscripto for i in e.intentos]) rechazados = list(inscriptos - inscriptos_ok) rechazados.sort(lambda x, y: cmp(x.padron, y.padron)) r += rechazado_header() for i in rechazados: r += rechazado_row(i, e) r += rechazado_footer() 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 '

Password Incorrecto!

\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')), f.getfirst('rechazados', False)) else: print correcciones(req, int(f.getfirst('entrega'))) if not raw: print footer(req)