# Entregas
archivo_zip = file('doc/entrega.zip').read()
ai1.add_entrega(ide, archivos=archivo_zip)
-entrega = ai2.add_entrega(ide, inicio_tareas=datetime.now(),
- fin_tareas=datetime.now() + timedelta(0, 0, 1), correcta=True,
+entrega = ai2.add_entrega(ide, inicio=datetime.now(),
+ fin=datetime.now() + timedelta(0, 0, 1), exito=True,
archivos=archivo_zip)
-entrega2 = g1.add_entrega(ide, inicio_tareas=datetime.now(),
- fin_tareas=datetime.now() + timedelta(0, 0, 3), correcta=False,
+entrega2 = g1.add_entrega(ide, inicio=datetime.now(),
+ fin=datetime.now() + timedelta(0, 0, 3), exito=False,
archivos=archivo_zip)
d.add_entrega(ide, observaciones='Prueba de docente', archivos=archivo_zip)
return '%s-%s' % (self.alumno.shortrepr(), self.grupo.shortrepr())
#}}}
-class Entrega(SQLObject): #{{{
+class Ejecucion(InheritableSQLObject): #{{{
+ # Campos
+ inicio = DateTimeCol(notNone=True, default=DateTimeCol.now)
+ fin = DateTimeCol(default=None)
+ exito = IntCol(default=None)
+ observaciones = UnicodeCol(notNone=True, default=u'')
+ archivos = BLOBCol(default=None) # ZIP con archivos
+
+ def __repr__(self, clave='', mas=''):
+ return ('%s(%s inicio=%s, fin=%s, exito=%s, observaciones=%s%s)'
+ % (self.__class__.__name__, clave, self.inicio, self.fin,
+ self.exito, self.observaciones, mas))
+#}}}
+
+class Entrega(Ejecucion): #{{{
+ _inheritable = False
# Clave
instancia = ForeignKey('InstanciaDeEntrega', notNone=True, cascade=False)
entregador = ForeignKey('Entregador', default=None, cascade=False) # Si es None era un Docente
fecha = DateTimeCol(notNone=True, default=DateTimeCol.now)
pk = DatabaseIndex(instancia, entregador, fecha, unique=True)
- # Campos
- archivos = BLOBCol(notNone=True) # ZIP con fuentes de la entrega
- correcta = BoolCol(default=None) # None es que no se sabe qué pasó
- inicio_tareas = DateTimeCol(default=None) # Si es None no se procesó
- fin_tareas = DateTimeCol(default=None) # Si es None pero inicio no, se está procesando
- observaciones = UnicodeCol(notNone=True, default=u'')
# Joins
comandos_ejecutados = MultipleJoin('ComandoFuenteEjecutado')
pruebas = MultipleJoin('Prueba')
Prueba.pk.get(self.id, caso_de_prueba).destroySelf()
def __repr__(self):
- return 'Entrega(id=%s, instancia=%s, entregador=%s, fecha=%s, ' \
- 'correcta=%s, inicio_tareas=%s, fin_tareas=%s, observaciones=%s)' \
- % (self.id, self.instancia.shortrepr(), srepr(self.entregador),
- self.fecha, self.inicio_tareas, self.fin_tareas,
- self.correcta, self.observaciones)
+ return super(Entrega, self).__repr__('instancia=%s, entregador=%s, '
+ 'fecha=%s' % (self.instancia.shortrepr(), srepr(self.entregador),
+ self.fecha))
def shortrepr(self):
return '%s-%s-%s' % (self.instancia.shortrepr(),
return '%s,%s' % (self.entrega.shortrepr(), self.corrector.shortrepr())
#}}}
-class ComandoEjecutado(InheritableSQLObject): #{{{
+class ComandoEjecutado(Ejecucion): #{{{
# Campos
- inicio = DateTimeCol(notNone=True, default=DateTimeCol.now)
- fin = DateTimeCol(default=None)
- exito = IntCol(default=None)
- archivos_comparados = BLOBCol(default=None) # ZIP con archivos diff
- archivos_guardados = BLOBCol(default=None) # ZIP con archivos guardados
- observaciones = UnicodeCol(notNone=True, default=u'')
+ diferencias = BLOBCol(default=None) # ZIP con archivos guardados
def __repr__(self, clave='', mas=''):
- return ('%s(%s inicio=%s, fin=%s, exito=%s, observaciones=%s%s)'
- % (self.__class__.__name__, clave, self.inicio, self.fin,
- self.exito, self.observaciones, mas))
+ return super(ComandoFuenteEjecutado, self).__repr__(clave, mas)
#}}}
class ComandoFuenteEjecutado(ComandoEjecutado): #{{{
<tr py:for="record in records">
<td><span py:replace="record.fecha">usuario</span></td>
<td align="center">
- <span py:if="record.correcta">Si</span>
- <span py:if="not record.correcta">No</span>
+ <span py:replace="tg.strbool(record.exito)">Si</span>
</td>
<td><span py:replace="record.observaciones">fecha corregido</span></td>
<td>
<td>${i.inicio}</td>
<td>${i.fin}</td>
<td align="center">
- <span py:if="i.exito">Si</span>
- <span py:if="not i.exito">No</span>
+ <span py:replace="tg.strbool(i.exito)">Si</span>
</td>
<td>${i.observaciones}</td>
</tr>
<td><span py:if="record.entregador" py:replace="record.entregador.shortrepr()">usuario</span></td>
<td><span py:replace="record.instancia.ejercicio.enunciado.nombre">usuario</span></td>
<td><span py:replace="record.instancia.shortrepr()">usuario</span></td>
- <td><span py:replace="record.correcta">fecha asignado</span></td>
- <td><span py:replace="record.inicio_tareas">fecha corregido</span></td>
- <td><span py:replace="record.fin_tareas">fecha corregido</span></td>
+ <td><span py:replace="record.exito">fecha asignado</span></td>
+ <td><span py:replace="record.inicio">fecha corregido</span></td>
+ <td><span py:replace="record.fin">fecha corregido</span></td>
<td><span py:replace="record.observaciones">nota</span></td>
<td>
<a href="${tg.url('/mis_entregas/corrida/%d' % record.id)}">Corrida</a>
def test(self, entrega): #{{{
log.debug(_(u'Tester.test(entrega=%s)'), entrega)
- entrega.inicio_tareas = datetime.now()
+ entrega.inicio = datetime.now()
try:
try:
self.setup_chroot(entrega)
self.ejecutar_tareas_prueba(entrega)
self.clean_chroot(entrega)
except ExecutionFailure, e:
- entrega.correcta = False
+ entrega.exito = False
log.info(_(u'Entrega incorrecta: %s'), entrega)
except Exception, e:
if isinstance(e, SystemExit): raise
entrega.observaciones += error_interno
log.exception(_('Hubo una excepcion inesperada desconocida')) # FIXME encoding
else:
- entrega.correcta = True
+ entrega.exito = True
log.debug(_(u'Entrega correcta: %s'), entrega)
finally:
- entrega.fin_tareas = datetime.now()
+ entrega.fin = datetime.now()
#}}}
def setup_chroot(self, entrega): #{{{ y clean_chroot()
if self.retorno == self.RET_FAIL:
if proc.returncode == 0:
if self.rechazar_si_falla:
- entrega.correcta = False
+ entrega.exito = False
comando_ejecutado.exito = False
comando_ejecutado.observaciones += _(u'Se esperaba que el '
u'programa termine con un error (código de retorno '
u'terminó bien (código de retorno 0).\n'))
elif self.retorno != proc.returncode:
if self.rechazar_si_falla:
- entrega.correcta = False
+ entrega.exito = False
comando_ejecutado.exito = False
if proc.returncode < 0:
comando_ejecutado.observaciones += _(u'Se esperaba terminar '
for f in a_guardar:
if not os.path.exists(join(path, f)):
if self.rechazar_si_falla:
- entrega.correcta = False
+ entrega.exito = False
comando_ejecutado.exito = False
comando_ejecutado.observaciones += _(u'Se esperaba un archivo '
u'"%s" para guardar pero no fue encontrado.\n') % f
else:
zip.write(join(path, f), f)
zip.close()
- comando_ejecutado.archivos_guardados = buffer.getvalue()
+ comando_ejecutado.archivos = buffer.getvalue()
def diff(new, zip_in, zip_out, name, longname=None, origname='correcto',
newname='entregado'):
if longname is None:
tofile=name+'.'+newname)))
if udiff:
if self.rechazar_si_falla:
- entrega.correcta = False
+ entrega.exito = False
comando_ejecutado.exito = False
comando_ejecutado.observaciones += _(u'%s no coincide con lo '
u'esperado (archivo "%s.diff").\n') % (longname, name)
for f in a_comparar:
if not os.path.exists(join(path, f)):
if self.rechazar_si_falla:
- entrega.correcta = False
+ entrega.exito = False
comando_ejecutado.exito = False
comando_ejecutado.observaciones += _(u'Se esperaba un archivo '
u'"%s" para comparar pero no fue encontrado') % f
else:
diff(join(path, f), zip_a_comparar, zip, f)
zip.close()
- comando_ejecutado.archivos_guardados = buffer.getvalue()
+ comando_ejecutado.diferencias = buffer.getvalue()
if comando_ejecutado.exito is None:
comando_ejecutado.exito = True
elif self.terminar_si_falla:
#model.hub.commit()
#model.hub.begin()
-#model.Entrega.get(5).correcta = True
+#model.Entrega.get(5).exito = True
#model.hub.rollback()