]> git.llucax.com Git - software/sercom-old.git/blobdiff - src/sercom/sqlo.py
Bugfix: faltaba copiar las entradas al chroot de las pruebas.
[software/sercom-old.git] / src / sercom / sqlo.py
index d01e0f78156ba56003aacbe738492aa683f4aa65..c81e066eed114cd7837716fdd0842c4974811707 100644 (file)
@@ -1,6 +1,9 @@
 from sqlobject import *
 from sqlobject.sqlbuilder import *
 from sqlobject import *
 from sqlobject.sqlbuilder import *
+import errno
+import os
 from os import path
 from os import path
+from datetime import datetime
 
 __all__ = ('Curso', 'Inscripto', 'Docente', 'Ejercicio', 'Entrega',
            'CasoDePrueba', 'Intento', 'Correccion', 'Prueba')
 
 __all__ = ('Curso', 'Inscripto', 'Docente', 'Ejercicio', 'Entrega',
            'CasoDePrueba', 'Intento', 'Correccion', 'Prueba')
@@ -11,19 +14,19 @@ dir_base = '.'
 class BaseSQLObject(SQLObject):
 
     @classmethod
 class BaseSQLObject(SQLObject):
 
     @classmethod
-    def by(cls, connection = None, **kw):
+    def by(cls, **kw):
         try:
         try:
-            return cls.selectBy(connection = connection, **kw)[0]
+            return cls.selectBy(**kw)[0]
         except IndexError:
             raise SQLObjectNotFound, "The object %s with columns %s does not exist" % (cls.__name__, kw)
 
 class Curso(BaseSQLObject):
     # Clave
         except IndexError:
             raise SQLObjectNotFound, "The object %s with columns %s does not exist" % (cls.__name__, kw)
 
 class Curso(BaseSQLObject):
     # Clave
-    anio            = Col()
-    cuatrimestre    = Col()
-    curso           = Col()
+    anio            = IntCol()
+    cuatrimestre    = IntCol()
+    curso           = IntCol()
     # Campos
     # Campos
-    descripcion     = Col()
+    descripcion     = StringCol()
     # Joins
     docentes        = RelatedJoin('Docente')
     entregas        = MultipleJoin('Entrega')
     # Joins
     docentes        = RelatedJoin('Docente')
     entregas        = MultipleJoin('Entrega')
@@ -32,21 +35,21 @@ class Curso(BaseSQLObject):
 
 class Inscripto(BaseSQLObject):
     # Clave
 
 class Inscripto(BaseSQLObject):
     # Clave
-    padron          = Col(alternateID = True)
+    padron          = IntCol(alternateID=True)
     # Campos
     curso           = ForeignKey('Curso')
     # Campos
     curso           = ForeignKey('Curso')
-    mail            = Col()
-    activo          = Col(default = 1)
+    mail            = StringCol()
+    activo          = BoolCol(default=True)
     # Joins
     intentos        = MultipleJoin('Intento')
     correcciones    = MultipleJoin('Correccion')
 
 class Docente(BaseSQLObject):
     # Clave
     # Joins
     intentos        = MultipleJoin('Intento')
     correcciones    = MultipleJoin('Correccion')
 
 class Docente(BaseSQLObject):
     # Clave
-    nombre          = Col(alternateID = True)
+    nombre          = StringCol(alternateID=True)
     # Campos
     # Campos
-    mail            = Col()
-    corrige         = Col()
+    mail            = StringCol()
+    corrige         = BoolCol()
     # Joins
     cursos          = RelatedJoin('Curso')
     ejercicios      = MultipleJoin('Ejercicio')
     # Joins
     cursos          = RelatedJoin('Curso')
     ejercicios      = MultipleJoin('Ejercicio')
@@ -59,7 +62,7 @@ class Ejercicio(BaseSQLObject):
     numero          = Col()
     docente         = ForeignKey('Docente')
     # Joins
     numero          = Col()
     docente         = ForeignKey('Docente')
     # Joins
-    casosDePrueba   = MultipleJoin('CasoDePrueba', joinMethodName='casosDePrueba') # XXX hack
+    casosDePrueba   = MultipleJoin('CasoDePrueba')
     entregas        = MultipleJoin('Entrega')
     cursos          = RelatedJoin('Curso', intermediateTable = 'entrega')
 
     entregas        = MultipleJoin('Entrega')
     cursos          = RelatedJoin('Curso', intermediateTable = 'entrega')
 
@@ -69,59 +72,100 @@ class Ejercicio(BaseSQLObject):
 class Entrega(BaseSQLObject):
     # Clave
     curso           = ForeignKey('Curso')
 class Entrega(BaseSQLObject):
     # Clave
     curso           = ForeignKey('Curso')
-    nroEjercicio    = Col()
-    entrega         = Col()
+    nroEjercicio    = IntCol()
+    entrega         = IntCol()
     # Campos
     ejercicio       = ForeignKey('Ejercicio')
     # Campos
     ejercicio       = ForeignKey('Ejercicio')
-    desde           = Col()
-    hasta           = Col()
+    desde           = DateTimeCol()
+    hasta           = DateTimeCol()
+    finalizada      = BoolCol(default=False)
     # Joins
     cursos          = MultipleJoin('Curso')
     correcciones    = MultipleJoin('Correccion')
     intentos        = MultipleJoin('Intento')
 
     # Joins
     cursos          = MultipleJoin('Curso')
     correcciones    = MultipleJoin('Correccion')
     intentos        = MultipleJoin('Intento')
 
+    @classmethod
+    def getPendientes(cls, connection=None):
+        return cls.select((cls.q.finalizada == False)
+            & (cls.q.hasta <= datetime.now()),
+            orderBy=cls.q.hasta, connection=connection)
+
 class CasoDePrueba(BaseSQLObject):
     # Clave
     ejercicio       = ForeignKey('Ejercicio')
 class CasoDePrueba(BaseSQLObject):
     # Clave
     ejercicio       = ForeignKey('Ejercicio')
-    nombre          = Col()
+    nombre          = StringCol()
     # Campos
     # Campos
-    privado         = Col()
-    activo          = Col(default = 1)
-    parametros      = Col(default = None)
-    codigoRetorno   = Col(default = 0)
-    tiempoCpu       = Col(default = None)
+    privado         = BoolCol()
+    activo          = BoolCol(default=True)
+    parametros      = StringCol(default=None)
+    codigoRetorno   = IntCol(default=False)
+    tiempoCpu       = FloatCol(default=None)
     # Joins
     pruebas         = MultipleJoin('Prueba')
 
     def _get_path(self):
         return path.join(self.ejercicio.path, 'casos_de_prueba', self.nombre)
 
     # Joins
     pruebas         = MultipleJoin('Prueba')
 
     def _get_path(self):
         return path.join(self.ejercicio.path, 'casos_de_prueba', self.nombre)
 
+    def _get_pathEntradas(self):
+        return path.join(self.path, 'entradas')
+
+    def _get_pathSalidas(self):
+        return path.join(self.path, 'salidas')
+
+    def _get_archivosEntrada(self):
+        try:
+            return frozenset(os.listdir(self.pathEntradas))
+        except OSError, (err, msg):
+            if err == errno.ENOENT:
+                return frozenset()
+            else:
+                raise
+
+    def _get_archivosSalida(self):
+        try:
+            return frozenset(os.listdir(self.pathSalidas))
+        except OSError, (err, msg):
+            if err == errno.ENOENT:
+                return frozenset()
+            else:
+                raise
+
 class Intento(BaseSQLObject):
     # Clave
     inscripto       = ForeignKey('Inscripto')
     entrega         = ForeignKey('Entrega')
 class Intento(BaseSQLObject):
     # Clave
     inscripto       = ForeignKey('Inscripto')
     entrega         = ForeignKey('Entrega')
-    numero          = Col()
+    numero          = IntCol()
     # Campos
     # Campos
-    llegada         = Col()
-    inicioCompila   = Col(default = None)
-    finCompila      = Col(default = None)
-    inicioPruebas   = Col(default = None)
-    finPruebas      = Col(default = None)
-    compila         = Col(default = None)
-    notificado      = Col(default = 0)
-    mailRespuesta   = Col()
-    observaciones   = Col(default = None)
+    llegada         = DateTimeCol()
+    inicioCompila   = DateTimeCol(default=None)
+    finCompila      = DateTimeCol(default=None)
+    inicioPruebas   = DateTimeCol(default=None)
+    finPruebas      = DateTimeCol(default=None)
+    compila         = BoolCol(default=None)
+    mailRespuesta   = StringCol()
+    observaciones   = StringCol(default=None)
     # Joins
     pruebas         = MultipleJoin('Prueba')
 
     @classmethod
     def getProximoAProbar(cls, connection=None):
         try:
     # Joins
     pruebas         = MultipleJoin('Prueba')
 
     @classmethod
     def getProximoAProbar(cls, connection=None):
         try:
-            return cls.select(None == cls.q.compila, limit=1,
+            return cls.select(cls.q.compila == None, limit=1,
                 orderBy=cls.q.llegada, connection=connection)[0]
         except IndexError:
             return None
 
                 orderBy=cls.q.llegada, connection=connection)[0]
         except IndexError:
             return None
 
+    @classmethod
+    def faltaCompilar(cls, entrega, connection=None):
+        no_compilados = cls.selectBy(entregaID=entrega.id, compila=None,
+            connection=connection).count()
+        no_probados = cls.selectBy(entregaID=entrega.id, compila=True,
+            finPruebas=None, connection=connection).count()
+        return no_compilados + no_probados
+
+    def chrootPath(self, caso_de_prueba):
+        return path.join(self.path, 'pruebas', caso_de_prueba.nombre)
+
     def _get_path(self):
         curso = self.inscripto.curso
         entrega = self.entrega
     def _get_path(self):
         curso = self.inscripto.curso
         entrega = self.entrega
@@ -130,24 +174,50 @@ class Intento(BaseSQLObject):
             '%s.%s.%s' % (curso.curso, entrega.nroEjercicio, entrega.entrega),
             '%s.%s' % (self.inscripto.padron, self.numero))
 
             '%s.%s.%s' % (curso.curso, entrega.nroEjercicio, entrega.entrega),
             '%s.%s' % (self.inscripto.padron, self.numero))
 
+    def _get_pruebasPasadas(self):
+        if not self.compila: return False
+        for p in self.pruebas:
+            if not p.pasada: return False
+        return True
+
+    def _get_pruebasPublicasPasadas(self):
+        if not self.compila: return False
+        for p in self.pruebas:
+            if not p.pasada and not p.casoDePrueba.privado:
+                return False
+        return True
+
+    def _get_pruebasPrivadasPasadas(self):
+        if not self.compila: return False
+        for p in self.pruebas:
+            if not p.pasada and p.casoDePrueba.privado:
+                return False
+        return True
+
 class Correccion(BaseSQLObject):
     # Clave
 class Correccion(BaseSQLObject):
     # Clave
-    entrega         = ForeignKey('Ejercicio')
+    entrega         = ForeignKey('Entrega')
     inscripto       = ForeignKey('Inscripto')
     # Campos
     intento         = ForeignKey('Intento')
     docente         = ForeignKey('Docente')
     inscripto       = ForeignKey('Inscripto')
     # Campos
     intento         = ForeignKey('Intento')
     docente         = ForeignKey('Docente')
-    nota            = Col(default = None)
-    observaciones   = Col(default = None)
+    nota            = IntCol(default=None)
+    observaciones   = StringCol(default=None)
 
 class Prueba(BaseSQLObject):
     # Clave
     intento         = ForeignKey('Intento')
     casoDePrueba    = ForeignKey('CasoDePrueba')
     # Campos
 
 class Prueba(BaseSQLObject):
     # Clave
     intento         = ForeignKey('Intento')
     casoDePrueba    = ForeignKey('CasoDePrueba')
     # Campos
-    inicio          = Col()
-    fin             = Col(default = None)
-    pasada          = Col(default = None)
-    observaciones   = Col(default = None)
+    inicio          = DateTimeCol()
+    fin             = DateTimeCol(default=None)
+    pasada          = BoolCol(default=None)
+    observaciones   = StringCol(default=None)
+
+    def _get_archivosSalida(self):
+        ent = self.casoDePrueba.archivosEntrada
+        sal = self.casoDePrueba.archivosSalida
+        return frozenset([f for f in os.listdir(self.intento.chrootPath(self.casoDePrueba)) \
+                    if f in sal or f not in ent and f <> 'tp'])
 
 # vim: set et sw=4 sts=4 :
 
 # vim: set et sw=4 sts=4 :