1 # vim: set et sw=4 sts=4 encoding=utf-8 foldmethod=marker :
5 from turbogears import controllers, expose, redirect
6 from turbogears import validate, flash, error_handler
7 from turbogears import validators as V
8 from turbogears import widgets as W
9 from turbogears import identity
10 from turbogears import paginate
11 from docutils.core import publish_parts
12 from sercom.subcontrollers import validate as val
13 from sercom.model import Curso, Correccion, Ejercicio, Alumno, Docente, Grupo, DocenteInscripto
14 from curso_alumno import *
15 from sqlobject import *
16 from sqlobject.dberrors import *
17 from sercom.widgets import *
18 from alumno import AlumnoInscriptoController
28 function alumnos_agregar_a_la_lista(texto, lista)
30 t = MochiKit.DOM.getElement(texto);
32 url = "/alumno/get_alumno?padron="+t.value;
39 alert("The metadata for MochiKit.Async could not be fetched :(");
42 function procesar(result)
44 l = MochiKit.DOM.getElement('form_responsable_info');
46 l.innerHTML = result.msg;
48 l.innerHTML = result.msg.value;
51 function buscar_alumno()
53 /* Obtengo el curso */
54 l = MochiKit.DOM.getElement('form_cursoID');
55 cursoid = l.options[l.selectedIndex].value;
57 alert('Debe seleccionar un curso');
60 /* Obtengo el padron ingresado */
61 p = MochiKit.DOM.getElement('form_responsable');
64 alert('Debe ingresar el padrón del alumno responsable');
67 url = "/grupo/get_inscripto?cursoid="+cursoid+'&padron='+padron;
68 var d = loadJSONDoc(url);
69 d.addCallbacks(procesar, err);
74 /* TODO : Validar datos y evitar el submit si no esta completo */
76 /* Selecciono todos los miembros si no, no llegan al controllere*/
77 l = MochiKit.DOM.getElement('form_alumnos');
78 for (i=0; i<l.options.length; i++) {
79 l.options[i].selected = true;
81 /* Selecciono todos los miembros si no, no llegan al controllere*/
82 l = MochiKit.DOM.getElement('form_docentes_to');
83 for (i=0; i<l.options.length; i++) {
84 l.options[i].selected = true;
86 return true; // Dejo hacer el submit
94 return val.validate_get(cls, name, id)
96 def validate_set(id, data):
97 return val.validate_set(cls, name, id, data)
99 def validate_new(data):
100 return val.validate_new(cls, name, data)
102 def validate_del(id):
103 return val.validate_del(cls, name, id)
106 def get_ejercicios():
107 return [(fk1.id, fk1.shortrepr()) for fk1 in Ejercicio.select()]
110 return [(fk1.id, fk1.shortrepr()) for fk1 in Docente.select()]
113 return [(fk1.id, fk1.shortrepr()) for fk1 in Alumno.select()]
116 return [(fk1.id, fk1.shortrepr()) for fk1 in Grupo.select()]
120 class CursoForm(W.TableForm):
121 class Fields(W.WidgetsList):
122 anio = W.TextField(label=_(u'Anio'),
123 help_text=_(u'Requerido y único.'),
124 validator=V.Number(min=4, max=4, strip=True))
125 cuatrimestre = W.TextField(label=_(u'Cuatrimestre'),
126 help_text=_(u'Requerido.'),
127 validator=V.Number(min=1, max=1, strip=True))
128 numero = W.TextField(label=_(u'Numero'),
129 help_text=_(u'Requerido'),
130 validator=V.Number(min=1, max=2, strip=True))
131 descripcion = W.TextArea(name='descripcion', label=_(u'Descripcion'),
132 help_text=_(u'Descripcion.'),
133 validator=V.UnicodeString(not_empty=False, strip=True))
135 #docentes = W.MultipleSelectField(name="docentes",
136 # label=_(u'Docentes'),
137 # attrs=dict(style='width:300px'),
138 # options=get_docentes,
139 # validator=V.Int(not_empty=True))
140 #addDocente = W.Button(default='Asignar', label='',
141 # attrs=dict( onclick='mover("form_docentes","form_docentes_curso")'))
142 #remDocente = W.Button(default='Remover', label='',
143 # attrs=dict( onclick='remover("form_docentes_curso","form_docentes")'))
144 #docentes_curso = W.MultipleSelectField(name="docentes_curso",
145 # label=_(u'Docentes del curso'),
146 # attrs=dict(style='width:300px'),
147 # # options=get_docentes_curso,
148 # validator=V.Int(not_empty=True))
149 docentes = AjaxDosListasSelect(label=_(u'Docentes'),
150 title_from="Docentes",
151 title_to="Docentes del Curso",
152 options=get_docentes,
153 validator=V.Int(not_empty=True))
155 alumnos = AjaxMultiSelect(label=_(u'Alumnos'),
157 attrs = dict(size='20'),
158 on_add="alumnos_agregar_a_la_lista")
161 javascript = [W.JSSource("MochiKit.DOM.focusOnLoad('anio');"),
163 form_attrs = dict(onsubmit='return doSubmit();')
168 class CursoController(controllers.Controller, identity.SecureResource):
169 """Basic model admin interface"""
170 require = identity.has_permission('admin')
171 curso_alumno = CursoAlumnoController()
172 alumno = AlumnoInscriptoController()
175 def default(self, tg_errors=None):
176 """handle non exist urls"""
177 raise redirect('list')
181 raise redirect('list')
183 @expose(template='kid:%s.templates.list' % __name__)
186 """List records in model"""
188 return dict(records=r, name=name, namepl=namepl)
191 def activate(self, id, activo):
192 """Save or create record to model"""
195 r.activo = bool(int(activo))
197 raise cherrypy.NotFound
198 raise redirect('../../list')
200 @expose(template='kid:%s.templates.new' % __name__)
202 """Create new records in model"""
203 params = dict([(k,v) for (k,v) in kw.iteritems() if k in Curso.sqlmeta.columns.keys()])
204 return dict(name=name, namepl=namepl, form=form, values=params)
209 def create(self, **kw):
210 """Save or create record to model"""
212 docentes = kw.get('docentes_to', [])
213 alumnos = kw.get('alumnos', [])
214 del(kw['docentes_to'])
217 """ Agrego la nueva seleccion de docentes """
220 """ El curso es nuevo, por ende no hay alumnos inscriptos """
223 flash(_(u'Se creó un nuevo %s.') % name)
224 raise redirect('list')
226 @expose(template='kid:%s.templates.edit' % __name__)
227 def edit(self, id, **kw):
228 """Edit record in model"""
232 values = EmptyClass()
235 values.numero = r.numero
236 values.cuatrimestre = r.cuatrimestre
237 values.cursoID = r.id
238 values.descripcion = r.descripcion
239 # cargo la lista con los docentes asignados al curso
240 values.docentes_to = [{"id":d.docente.id, "label":d.docente.shortrepr()} for d in DocenteInscripto.selectBy(curso=r.id)]
241 values.alumnos_inscriptos = [{"id":a.alumno.id, "label":a.alumno.shortrepr()} for a in AlumnoInscripto.selectBy(curso=r.id)]
243 return dict(name=name, namepl=namepl, record=values, form=form)
248 def update(self, id, **kw):
249 """Save or create record to model"""
250 params = dict([(k,v) for (k,v) in kw.iteritems() if k in Curso.sqlmeta.columns.keys()])
251 r = validate_set(id, params)
253 docentes = [a for a in kw.get('docentes_to', [])]
254 alumnos = [a for a in kw.get('alumnos', [])]
255 alumnos_inscriptos = AlumnoInscripto.selectBy(curso=id)
256 """ levanto los doncentes del curso para ver cuales tengo que agregar """
257 docentes_inscriptos = DocenteInscripto.selectBy(curso=id)
259 """ elimino a los docentes que no fueron seleccionados """
260 for di in docentes_inscriptos:
261 if di.id not in docentes:
262 r.remove_docente(di.docente)
264 """ Agrego la nueva seleccion """
271 """ Verifico que los alumnos no esten ya inscriptos """
272 for a in alumnos_inscriptos:
273 if (a.id not in alumnos):
275 r.remove_alumno(a.alumno)
283 flash(_(u'El %s fue actualizado.') % name)
284 raise redirect('../list')
286 @expose(template='kid:%s.templates.show' % __name__)
287 def show(self,id, **kw):
288 """Show record in model"""
290 return dict(name=name, namepl=namepl, record=r)
293 def delete(self, id):
294 """Destroy record in model"""
296 flash(_(u'El %s fue eliminado permanentemente.') % name)
297 raise redirect('../list')
299 @expose(template='kid:%s.templates.from_file' % __name__)
300 def from_file(self, id):
301 return dict(cursoID=int(id))
303 @expose(template='kid:%s.templates.import_results' % __name__)
304 def from_file_add(self, id, archivo):
306 padron,nombre,email,telefono
309 lines = archivo.file.read().split('\n')
312 curso = Curso.get(int(id))
314 for row in csv.reader([line]):
318 u = Alumno(row[0], nombre=row[1])
320 u = Alumno.byPadron(row[0])
324 u.contrasenia = row[0]
331 return dict(ok=ok, fail=fail)
333 @expose(template='kid:%s.templates.notas' % __name__)
334 def notas(self, cursoid):
335 r = validate_get(cursoid)
336 # Armo las columnas del listado
337 cols = ["Padron", "Nombre", "Grupo"]
339 for ej in r.ejercicios:
340 for ins in ej.instancias:
341 print "E"+str(ej.numero)+str(ins.numero)
342 cols.append("E"+str(ej.numero)+str(ins.numero))
351 col["Padron"] = i.alumno.padron
352 col["Nombre"] = i.alumno.nombre
353 miembro = Grupo.selectByAlumno(i.alumno)
354 if miembro.count() > 0:
355 col["Grupo"] = miembro[0].grupo.shortrepr()
357 for ej in r.ejercicios:
358 for ins in ej.instancias:
360 # Busco la correccion del grupo
361 g = Grupo.selectByAlumno(i.alumno).getOne()
362 c = Correccion.selectBy(instancia=ins, entregador=g.grupo)
366 # Busco la correccion del alumno
367 c = Correccion.selectBy(instancia=ins, entregador=i)
369 col["E"+str(ej.numero)+str(ins.numero)] = c[0].nota
373 col["E"+str(ej.numero)+str(ins.numero)] = ""
374 col["EA"] = correctas
375 col["NP"] = i.nota_practica
376 col["NF"] = i.nota_final
377 col["NL"] = i.nota_libreta
379 return dict(curso=r, rows=rows, cols=cols)
382 def notascsv(self, cursoid):
383 r = validate_get(cursoid)
384 # Armo las columnas del listado
385 cols = ["Padron", "Nombre", "Grupo"]
387 for ej in r.ejercicios:
388 for ins in ej.instancias:
389 print "E"+str(ej.numero)+str(ins.numero)
390 cols.append("E"+str(ej.numero)+str(ins.numero))
399 col.append(i.alumno.padron)
400 col.append(i.alumno.nombre)
401 miembro = Grupo.selectByAlumno(i.alumno)
402 if miembro.count() > 0:
403 col.append(miembro[0].grupo.shortrepr())
405 for ej in r.ejercicios:
406 for ins in ej.instancias:
408 # Busco la correccion del grupo
409 g = Grupo.selectByAlumno(i.alumno).getOne()
410 c = Correccion.selectBy(instancia=ins, entregador=g.grupo)
412 # Busco la correccion del alumno
413 c = Correccion.selectBy(instancia=ins, entregador=i)
415 col.append(str(c[0].nota))
420 col.append(str(correctas))
421 col.append(str(i.nota_practica))
422 col.append(str(i.nota_final))
423 col.append(str(i.nota_libreta))
425 s = ",".join(cols) + "\n"
427 s = s + ",".join(i) + "\n"