border: medium black solid;
border-collapse: collapse;
}
+ caption
+ {
+ margin: 5pt;
+ font-weight: bold;
+ }
th
{
border: thin black solid;
{
border: thin black solid;
padding: 3pt;
- text-align: center;
vertical-align: middle;
}
.warn
return input_entrega(req, entrega_id) \
+ '<input type="hidden" name="zip" value="1" />\n'
+def input_zip_rechazados(req, entrega_id):
+ return input_entrega(req, entrega_id) \
+ + '<input type="hidden" name="zip" value="1" />\n' \
+ + '<input type="hidden" name="rechazados" 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' \
r = '</table>\n<p>\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 += '<a href="/intentos/%s.%s/%s.%s.%s/%s.%s/">ver fuentes</a></p>' \
+ % (i.inscripto.curso.anio, i.inscripto.curso.cuatrimestre,
+ i.inscripto.curso.curso, i.entrega.nroEjercicio, i.entrega.entrega,
+ i.inscripto.padron, i.numero)
r += '</p>\n'
return r
def row(p):
r += footer()
return r
-def zip(req, entrega_id):
+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(p):
+ 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
- req.write(http_header_zip(req, 'entrega-%d.%d.%d-%d.%d.zip'
- % (c.anio, c.cuatrimestre, c.curso, e.nroEjercicio, e.entrega)))
+ 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)
- for c in e.correcciones:
- zip_path(os.path.join(conf.get('general', 'data_dir'), c.intento.path),
- str(c.intento.inscripto.padron), zipfd)
+ 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 header():
+ def correccion_header():
return '''<table>
- <tr>
- <th>Padrón</th>
- <th>Pruebas</th>
- <th>Intentos</th>
- <tr>
+ <caption>Entregas aceptadas</caption>
+ <thead>
+ <tr>
+ <th>Padrón</th>
+ <th>Pruebas</th>
+ <th>Intentos</th>
+ <tr>
+ </thead>
+ <tbody>
'''
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):
+ def correccion_footer():
+ return ' </tbody>\n</table>\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 '''
- <tr>
- <td>%d</td>
- <td>%s</td>
- <td>%s</td>
- </tr>
+ <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)))
+ def rechazado_header():
+ return '''<table>
+ <caption>Entregas rechazadas</caption>
+ <thead>
+ <tr>
+ <th>Padrón</th>
+ <th>Intentos</th>
+ <tr>
+ </thead>
+ <tbody>
+'''
+ pass
+ def rechazado_footer():
+ return ' </tbody>\n</table>\n'
+ def rechazado_row(inscripto, entrega):
+ intentos = int(Intento.selectBy(inscriptoID=inscripto.id,
+ entregaID=entrega.id, connection=conn).count())
+ return '''
+ <tr>
+ <td>%d</td>
+ <td>%s</td>
+ </tr>
+''' % (inscripto.padron,
+ form(req, intentos, input_intentos(req, entrega.id, inscripto.id)))
+ def footer():
+ r = '<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 += form(req, 'Bajar entrega rechazadas en .zip',
+ input_zip_rechazados(req, entrega_id))
+ r += '</p>\n'
+ return r
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)
+ 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
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')))
+ zip(req, int(f.getfirst('entrega')), f.getfirst('rechazados', False))
else:
print correcciones(req, int(f.getfirst('entrega')))