X-Git-Url: https://git.llucax.com/software/sercom-old.git/blobdiff_plain/9c348742728b33f40e9fe55936741c544dbd7050..7f32a60f31bd104bc04c102bf6c66dd2af7220e7:/src/sercom/sqlo.py diff --git a/src/sercom/sqlo.py b/src/sercom/sqlo.py index f4824df..c81e066 100644 --- a/src/sercom/sqlo.py +++ b/src/sercom/sqlo.py @@ -1,6 +1,9 @@ from sqlobject import * from sqlobject.sqlbuilder import * +import errno +import os from os import path +from datetime import datetime __all__ = ('Curso', 'Inscripto', 'Docente', 'Ejercicio', 'Entrega', 'CasoDePrueba', 'Intento', 'Correccion', 'Prueba') @@ -11,9 +14,9 @@ dir_base = '.' class BaseSQLObject(SQLObject): @classmethod - def by(cls, connection = None, **kw): + def by(cls, **kw): 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) @@ -32,18 +35,18 @@ class Curso(BaseSQLObject): class Inscripto(BaseSQLObject): # Clave - padron = IntCol(alternateID = True) + padron = IntCol(alternateID=True) # Campos curso = ForeignKey('Curso') mail = StringCol() - activo = BoolCol(default = True) + activo = BoolCol(default=True) # Joins intentos = MultipleJoin('Intento') correcciones = MultipleJoin('Correccion') class Docente(BaseSQLObject): # Clave - nombre = StringCol(alternateID = True) + nombre = StringCol(alternateID=True) # Campos mail = StringCol() corrige = BoolCol() @@ -59,7 +62,7 @@ class Ejercicio(BaseSQLObject): numero = Col() docente = ForeignKey('Docente') # Joins - casosDePrueba = MultipleJoin('CasoDePrueba', joinMethodName='casosDePrueba') # XXX hack + casosDePrueba = MultipleJoin('CasoDePrueba') entregas = MultipleJoin('Entrega') cursos = RelatedJoin('Curso', intermediateTable = 'entrega') @@ -75,38 +78,57 @@ class Entrega(BaseSQLObject): ejercicio = ForeignKey('Ejercicio') desde = DateTimeCol() hasta = DateTimeCol() + finalizada = BoolCol(default=False) # 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') nombre = StringCol() # Campos privado = BoolCol() - activo = BoolCol(default = True) - parametros = StringCol(default = None) - codigoRetorno = IntCol(default = False) - tiempoCpu = FloatCol(default = None) + 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) + 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 os.listdir(path.join(self.path, 'entradas')) - except: - return [] + return frozenset(os.listdir(self.pathEntradas)) + except OSError, (err, msg): + if err == errno.ENOENT: + return frozenset() + else: + raise def _get_archivosSalida(self): try: - return os.listdir(path.join(self.path, 'salidas')) - except: - return [] + return frozenset(os.listdir(self.pathSalidas)) + except OSError, (err, msg): + if err == errno.ENOENT: + return frozenset() + else: + raise class Intento(BaseSQLObject): # Clave @@ -115,24 +137,35 @@ class Intento(BaseSQLObject): numero = IntCol() # Campos llegada = DateTimeCol() - inicioCompila = DateTimeCol(default = None) - finCompila = DateTimeCol(default = None) - inicioPruebas = DateTimeCol(default = None) - finPruebas = DateTimeCol(default = None) - compila = BoolCol(default = None) + 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) + observaciones = StringCol(default=None) # 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 + @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 @@ -142,18 +175,20 @@ class Intento(BaseSQLObject): '%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 + 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 @@ -161,13 +196,13 @@ class Intento(BaseSQLObject): class Correccion(BaseSQLObject): # Clave - entrega = ForeignKey('Ejercicio') + entrega = ForeignKey('Entrega') inscripto = ForeignKey('Inscripto') # Campos intento = ForeignKey('Intento') docente = ForeignKey('Docente') - nota = IntCol(default = None) - observaciones = StringCol(default = None) + nota = IntCol(default=None) + observaciones = StringCol(default=None) class Prueba(BaseSQLObject): # Clave @@ -175,8 +210,14 @@ class Prueba(BaseSQLObject): casoDePrueba = ForeignKey('CasoDePrueba') # Campos inicio = DateTimeCol() - fin = DateTimeCol(default = None) - pasada = BoolCol(default = None) - observaciones = StringCol(default = None) + 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 :