X-Git-Url: https://git.llucax.com/software/sercom-old.git/blobdiff_plain/c97a8ba9005213c26fabccb8d3804020cb8e772a..a1359c9554ba2ed0ee030cdb2947e484a7b7b51a:/src/sercom/sqlo.py diff --git a/src/sercom/sqlo.py b/src/sercom/sqlo.py index 541b612..47069f5 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,19 +14,19 @@ 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(limit=1, **kw)[0] 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 - descripcion = Col() + descripcion = StringCol() # Joins docentes = RelatedJoin('Docente') entregas = MultipleJoin('Entrega') @@ -32,21 +35,21 @@ class Curso(BaseSQLObject): class Inscripto(BaseSQLObject): # Clave - padron = Col(alternateID = True) + padron = IntCol(alternateID=True) # Campos curso = ForeignKey('Curso') - mail = Col() - activo = Col(default = True) + mail = StringCol() + activo = BoolCol(default=True) # Joins intentos = MultipleJoin('Intento') correcciones = MultipleJoin('Correccion') class Docente(BaseSQLObject): # Clave - nombre = Col(alternateID = True) + nombre = StringCol(alternateID=True) # Campos - mail = Col() - corrige = Col() + mail = StringCol() + corrige = BoolCol() # Joins cursos = RelatedJoin('Curso') ejercicios = MultipleJoin('Ejercicio') @@ -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') @@ -69,71 +72,97 @@ class Ejercicio(BaseSQLObject): class Entrega(BaseSQLObject): # Clave curso = ForeignKey('Curso') - nroEjercicio = Col() - entrega = Col() + nroEjercicio = IntCol() + entrega = IntCol() # 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') + @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 = Col() + nombre = StringCol() # Campos - privado = Col() - activo = Col(default = True) - parametros = Col(default = None) - codigoRetorno = Col(default = False) - 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) + 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 inscripto = ForeignKey('Inscripto') entrega = ForeignKey('Entrega') - numero = Col() + numero = IntCol() # 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 = False) - 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: - 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 _get_path(self): curso = self.inscripto.curso entrega = self.entrega @@ -142,24 +171,53 @@ class Intento(BaseSQLObject): '%s.%s.%s' % (curso.curso, entrega.nroEjercicio, entrega.entrega), '%s.%s' % (self.inscripto.padron, self.numero)) + def _get_chrootPath(self): + return path.join(self.path, 'chroot') + + 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 - entrega = ForeignKey('Ejercicio') + entrega = ForeignKey('Entrega') 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 - 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) \ + if f in sal or f not in ent and f <> 'tp']) # vim: set et sw=4 sts=4 :