]> git.llucax.com Git - software/sercom.git/blob - sercom/subcontrollers/ejercicio/__init__.py
Cursos y alumnos
[software/sercom.git] / sercom / subcontrollers / ejercicio / __init__.py
1 # vim: set et sw=4 sts=4 encoding=utf-8 foldmethod=marker :
2
3 #{{{ Imports
4 from turbogears import controllers, expose, redirect
5 from turbogears import validate, flash, error_handler
6 from turbogears import validators as V
7 from turbogears import widgets as W
8 from turbogears import identity
9 from turbogears import paginate
10 from docutils.core import publish_parts
11 from sercom.subcontrollers import validate as val
12 from sercom.model import Ejercicio, Curso, Enunciado
13 from cherrypy import request, response
14
15 from entrega import  *
16
17 #}}}
18
19 #{{{ Configuración
20 cls = Ejercicio
21 name = 'ejercicio'
22 namepl = name + 's'
23
24 fkcls = Curso
25 fkname = 'curso'
26 fknamepl = fkname + 's'
27
28 fk1cls = Enunciado
29 fk1name = 'enunciado'
30 fk1namepl = fk1name + 's'
31 #}}}
32
33 #{{{ Validación
34 def validate_fk(data):
35     fk = data.get(fkname + 'ID', None)
36     if fk == 0: fk = None
37     if fk is not None:
38         try:
39             fk = fkcls.get(fk)
40         except LookupError:
41             flash(_(u'No se pudo crear el nuevo %s porque el %s con '
42                 'identificador %d no existe.' % (name, fkname, fk)))
43             raise redirect('new', **data)
44     data.pop(fkname + 'ID', None)
45     data[fkname] = fk
46     return fk
47
48 def validate_fk1(data):
49     fk = data.get(fk1name + 'ID', None)
50     if fk == 0: fk = None
51     if fk is not None:
52         try:
53             fk = fk1cls.get(fk)
54         except LookupError:
55             flash(_(u'No se pudo crear el nuevo %s porque el %s con '
56                 'identificador %d no existe.' % (name, fk1name, fk)))
57             raise redirect('new', **data)
58     data.pop(fk1name + 'ID', None)
59     data[fk1name] = fk
60     return fk
61
62 def validate_get(id):
63     return val.validate_get(cls, name, id)
64
65 def validate_set(id, data):
66     validate_fk(data)
67     validate_fk1(data)
68     return val.validate_set(cls, name, id, data)
69
70 def validate_new(data):
71     validate_fk(data)
72     validate_fk1(data)
73     return val.validate_new(cls, name, data)
74 #}}}
75
76 #{{{ Formulario
77 def get_options():
78     return [(0, _(u'--'))] + [(fk.id, fk.shortrepr()) for fk in fkcls.select()]
79
80 # Un poco de ajax para llenar los cursos
81 ajax = """
82     function showHint()
83     {
84         MochiKit.DOM.showElement('hint')
85     }
86
87     function hideHint()
88     {
89         MochiKit.DOM.hideElement('hint')
90     }
91
92     function clearEnunciados ()
93     {
94         l = MochiKit.DOM.getElement('form_enunciadoID');
95         l.options.length = 0;
96         l.disabled = true;
97     }
98
99     function mostrarEnunciados (res)
100     {
101         clearEnunciados();
102         for(i in res.enunciados) {
103             id = res.enunciados[i].id;
104             label = res.enunciados[i].nombre;
105             MochiKit.DOM.appendChildNodes("form_enunciadoID", OPTION({"value":id}, label))
106         }
107         l.disabled = false;
108         hideHint();
109     }
110
111     function err (err)
112     {
113         alert("The metadata for MochiKit.Async could not be fetched :(");
114         hideHint();
115     }
116
117     function actualizar_enunciados ()
118     {
119         l = MochiKit.DOM.getElement('form_cursoID');
120         id = l.options[l.selectedIndex].value;
121         if (id == 0) {
122             clearEnunciados();
123             return;
124         }
125
126         url = "/enunciado/de_curso?curso_id="+id;
127         var d = loadJSONDoc(url);
128         d.addCallbacks(mostrarEnunciados, err);
129         showHint();
130     }
131
132     function prepare()
133     {
134         connect('form_cursoID', 'onchange', actualizar_enunciados);
135         hideHint();
136         clearEnunciados();
137         actualizar_enunciados();
138         if (select_enunciado) {
139             wait(0.1).addCallback(function (res) { return select_enunciado() });
140         }
141     }
142
143     MochiKit.DOM.addLoadEvent(prepare)
144 """
145
146 class EjercicioForm(W.TableForm):
147     class Fields(W.WidgetsList):
148         fk = W.SingleSelectField(name=fkname+'ID', label=_(fkname.capitalize()),
149             options=get_options, validator=V.Int(not_empty=True))
150         numero = W.TextField(name="numero",label=_(u'Nro'),
151             help_text=_(u'Requerido.'),
152             validator=V.Int(not_empty=True))
153         fk1 = W.SingleSelectField(name=fk1name+'ID', label=_(fk1name.capitalize()),
154             validator=V.Int(not_empty=True))
155         grupal = W.CheckBox(name='grupal', label=_(u"Grupal?"))
156     fields = Fields()
157     javascript = [W.JSSource("MochiKit.DOM.focusOnLoad('form_nombre');"), W.JSSource(ajax)]
158
159 form = EjercicioForm()
160 #}}}
161
162 #{{{ Controlador
163 class EjercicioController(controllers.Controller, identity.SecureResource):
164     """Basic model admin interface"""
165     require = identity.has_permission('admin')
166
167     entrega = EntregaController()
168
169     @expose()
170     def default(self, tg_errors=None):
171         """handle non exist urls"""
172         raise redirect('list')
173
174     @expose()
175     def index(self):
176         raise redirect('list')
177
178     @expose(template='kid:%s.templates.list' % __name__)
179     @validate(validators=dict(autor=V.Int))
180     @paginate('records')
181     def list(self, autor=None):
182         """List records in model"""
183         r = cls.select()
184         return dict(records=r, name=name, namepl=namepl, parcial=autor)
185
186     @expose(template='kid:%s.templates.new' % __name__)
187     def new(self, **kw):
188         """Create new records in model"""
189         return dict(name=name, namepl=namepl, form=form, values=kw)
190
191     @validate(form=form)
192     @error_handler(new)
193     @expose()
194     def create(self, **kw):
195         """Save or create record to model"""
196         validate_new(kw)
197         flash(_(u'Se creó un nuevo %s.') % name)
198         raise redirect('list')
199
200     @expose(template='kid:%s.templates.edit' % __name__)
201     def edit(self, id, **kw):
202         """Edit record in model"""
203         r = validate_get(id)
204         return dict(name=name, namepl=namepl, record=r, form=form)
205
206     @validate(form=form)
207     @error_handler(edit)
208     @expose()
209     def update(self, id, **kw):
210         """Save or create record to model"""
211         r = validate_set(id, kw)
212         flash(_(u'El %s fue actualizado.') % name)
213         raise redirect('../list')
214
215     @expose(template='kid:%s.templates.show' % __name__)
216     def show(self,id, **kw):
217         """Show record in model"""
218         r = validate_get(id)
219         return dict(name=name, namepl=namepl, record=r)
220
221     @expose()
222     def delete(self, id):
223         """Destroy record in model"""
224         r = validate_get(id)
225         r.destroySelf()
226         flash(_(u'El %s fue eliminado permanentemente.') % name)
227         raise redirect('../list')
228
229     @expose()
230     def files(self, id):
231         r = validate_get(id)
232         response.headers["Content-Type"] = r.archivo_type
233         response.headers["Content-disposition"] = "attachment;filename=%s" % (r.archivo_name)
234         flash(_(u'El %s fue eliminado permanentemente.') % name)
235         return r.archivo
236 #}}}
237