1 from sqlobject import *
2 from sqlobject.sqlbuilder import *
7 __all__ = ('Curso', 'Inscripto', 'Docente', 'Ejercicio', 'Entrega',
8 'CasoDePrueba', 'Intento', 'Correccion', 'Prueba')
10 # Directorio con los datos por default
13 class BaseSQLObject(SQLObject):
16 def by(cls, connection = None, **kw):
18 return cls.selectBy(connection = connection, **kw)[0]
20 raise SQLObjectNotFound, "The object %s with columns %s does not exist" % (cls.__name__, kw)
22 class Curso(BaseSQLObject):
25 cuatrimestre = IntCol()
28 descripcion = StringCol()
30 docentes = RelatedJoin('Docente')
31 entregas = MultipleJoin('Entrega')
32 inscriptos = MultipleJoin('Inscripto')
33 ejercicios = RelatedJoin('Curso', intermediateTable = 'entrega')
35 class Inscripto(BaseSQLObject):
37 padron = IntCol(alternateID = True)
39 curso = ForeignKey('Curso')
41 activo = BoolCol(default = True)
43 intentos = MultipleJoin('Intento')
44 correcciones = MultipleJoin('Correccion')
46 class Docente(BaseSQLObject):
48 nombre = StringCol(alternateID = True)
53 cursos = RelatedJoin('Curso')
54 ejercicios = MultipleJoin('Ejercicio')
55 correcciones = MultipleJoin('Correccion')
57 class Ejercicio(BaseSQLObject):
62 docente = ForeignKey('Docente')
64 casosDePrueba = MultipleJoin('CasoDePrueba', joinMethodName='casosDePrueba') # XXX hack
65 entregas = MultipleJoin('Entrega')
66 cursos = RelatedJoin('Curso', intermediateTable = 'entrega')
69 return path.join(dir_base, 'ejercicios', str(self.id))
71 class Entrega(BaseSQLObject):
73 curso = ForeignKey('Curso')
74 nroEjercicio = IntCol()
77 ejercicio = ForeignKey('Ejercicio')
81 cursos = MultipleJoin('Curso')
82 correcciones = MultipleJoin('Correccion')
83 intentos = MultipleJoin('Intento')
85 class CasoDePrueba(BaseSQLObject):
87 ejercicio = ForeignKey('Ejercicio')
91 activo = BoolCol(default = True)
92 parametros = StringCol(default = None)
93 codigoRetorno = IntCol(default = False)
94 tiempoCpu = FloatCol(default = None)
96 pruebas = MultipleJoin('Prueba')
99 return path.join(self.ejercicio.path, 'casos_de_prueba', self.nombre)
101 def _get_pathEntradas(self):
102 return path.join(self.path, 'entradas')
104 def _get_pathSalidas(self):
105 return path.join(self.path, 'salidas')
107 def _get_archivosEntrada(self):
109 return frozenset(os.listdir(self.pathEntradas))
110 except OSError, (err, msg):
111 if err == errno.ENOENT:
116 def _get_archivosSalida(self):
118 return frozenset(os.listdir(self.pathSalidas))
119 except OSError, (err, msg):
120 if err == errno.ENOENT:
125 class Intento(BaseSQLObject):
127 inscripto = ForeignKey('Inscripto')
128 entrega = ForeignKey('Entrega')
131 llegada = DateTimeCol()
132 inicioCompila = DateTimeCol(default = None)
133 finCompila = DateTimeCol(default = None)
134 inicioPruebas = DateTimeCol(default = None)
135 finPruebas = DateTimeCol(default = None)
136 compila = BoolCol(default = None)
137 mailRespuesta = StringCol()
138 observaciones = StringCol(default = None)
140 pruebas = MultipleJoin('Prueba')
143 def getProximoAProbar(cls, connection=None):
145 return cls.select(None == cls.q.compila, limit=1,
146 orderBy=cls.q.llegada, connection=connection)[0]
151 curso = self.inscripto.curso
152 entrega = self.entrega
153 return path.join(dir_base, 'intentos',
154 '%s.%s' % (curso.anio, curso.cuatrimestre),
155 '%s.%s.%s' % (curso.curso, entrega.nroEjercicio, entrega.entrega),
156 '%s.%s' % (self.inscripto.padron, self.numero))
158 def _get_chrootPath(self):
159 return path.join(self.path, 'chroot')
161 def _get_pruebasPasadas(self):
162 for p in self.pruebas:
167 def _get_pruebasPublicasPasadas(self):
168 for p in self.pruebas:
169 if not p.pasada and not p.casoDePrueba.privado:
173 def _get_pruebasPrivadasPasadas(self):
174 for p in self.pruebas:
175 if not p.pasada and p.casoDePrueba.privado:
179 class Correccion(BaseSQLObject):
181 entrega = ForeignKey('Ejercicio')
182 inscripto = ForeignKey('Inscripto')
184 intento = ForeignKey('Intento')
185 docente = ForeignKey('Docente')
186 nota = IntCol(default = None)
187 observaciones = StringCol(default = None)
189 class Prueba(BaseSQLObject):
191 intento = ForeignKey('Intento')
192 casoDePrueba = ForeignKey('CasoDePrueba')
194 inicio = DateTimeCol()
195 fin = DateTimeCol(default = None)
196 pasada = BoolCol(default = None)
197 observaciones = StringCol(default = None)
199 def _get_archivosSalida(self):
200 ent = self.casoDePrueba.archivosEntrada
201 sal = self.casoDePrueba.archivosSalida
202 return frozenset([f for f in os.listdir(self.intento.chrootPath) \
203 if f in sal or f not in ent and f <> 'tp'])
205 # vim: set et sw=4 sts=4 :