]> git.llucax.com Git - software/sercom.git/blob - sercom/subcontrollers/ejercicio/__init__.py
Especificar con más detalle TODO del backend.
[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 def validate_del(id):
76     return val.validate_del(cls, name, id)
77 #}}}
78
79 #{{{ Formulario
80 def get_options():
81     return [(0, _(u'--'))] + [(fk.id, fk.shortrepr()) for fk in fkcls.select()]
82
83 # Un poco de ajax para llenar los cursos
84 ajax = """
85     function showHint()
86     {
87         MochiKit.DOM.showElement('hint')
88     }
89
90     function hideHint()
91     {
92         MochiKit.DOM.hideElement('hint')
93     }
94
95     function clearEnunciados ()
96     {
97         l = MochiKit.DOM.getElement('form_enunciadoID');
98         l.options.length = 0;
99         l.disabled = true;
100     }
101
102     function mostrarEnunciados (res)
103     {
104         clearEnunciados();
105         for(i in res.enunciados) {
106             id = res.enunciados[i].id;
107             label = res.enunciados[i].nombre;
108             MochiKit.DOM.appendChildNodes("form_enunciadoID", OPTION({"value":id}, label))
109         }
110         l.disabled = false;
111         hideHint();
112     }
113
114     function err (err)
115     {
116         alert("The metadata for MochiKit.Async could not be fetched :(");
117         hideHint();
118     }
119
120     function actualizar_enunciados ()
121     {
122         l = MochiKit.DOM.getElement('form_cursoID');
123         id = l.options[l.selectedIndex].value;
124         if (id == 0) {
125             clearEnunciados();
126             return;
127         }
128
129         url = "/enunciado/de_curso?curso_id="+id;
130         var d = loadJSONDoc(url);
131         d.addCallbacks(mostrarEnunciados, err);
132         showHint();
133     }
134
135     function prepare()
136     {
137         connect('form_cursoID', 'onchange', actualizar_enunciados);
138         hideHint();
139         clearEnunciados();
140         actualizar_enunciados();
141         if (select_enunciado) {
142             wait(0.1).addCallback(function (res) { return select_enunciado() });
143         }
144     }
145
146     MochiKit.DOM.addLoadEvent(prepare)
147 """
148
149 class EjercicioForm(W.TableForm):
150     class Fields(W.WidgetsList):
151         fk = W.SingleSelectField(name=fkname+'ID', label=_(fkname.capitalize()),
152             options=get_options, validator=V.Int(not_empty=True))
153         numero = W.TextField(name="numero",label=_(u'Nro'),
154             help_text=_(u'Requerido.'),
155             validator=V.Int(not_empty=True))
156         fk1 = W.SingleSelectField(name=fk1name+'ID', label=_(fk1name.capitalize()),
157             validator=V.Int(not_empty=True))
158         grupal = W.CheckBox(name='grupal', label=_(u"Grupal?"))
159     fields = Fields()
160     javascript = [W.JSSource("MochiKit.DOM.focusOnLoad('form_nombre');"), W.JSSource(ajax)]
161
162 form = EjercicioForm()
163 #}}}
164
165 #{{{ Controlador
166 class EjercicioController(controllers.Controller, identity.SecureResource):
167     """Basic model admin interface"""
168     require = identity.has_permission('admin')
169
170     entrega = EntregaController()
171
172     @expose()
173     def default(self, tg_errors=None):
174         """handle non exist urls"""
175         raise redirect('list')
176
177     @expose()
178     def index(self):
179         raise redirect('list')
180
181     @expose(template='kid:%s.templates.list' % __name__)
182     @validate(validators=dict(autor=V.Int))
183     @paginate('records')
184     def list(self, autor=None):
185         """List records in model"""
186         r = cls.select()
187         return dict(records=r, name=name, namepl=namepl, parcial=autor)
188
189     @expose(template='kid:%s.templates.new' % __name__)
190     def new(self, **kw):
191         """Create new records in model"""
192         return dict(name=name, namepl=namepl, form=form, values=kw)
193
194     @validate(form=form)
195     @error_handler(new)
196     @expose()
197     def create(self, **kw):
198         """Save or create record to model"""
199         validate_new(kw)
200         flash(_(u'Se creó un nuevo %s.') % name)
201         raise redirect('list')
202
203     @expose(template='kid:%s.templates.edit' % __name__)
204     def edit(self, id, **kw):
205         """Edit record in model"""
206         r = validate_get(id)
207         return dict(name=name, namepl=namepl, record=r, form=form)
208
209     @validate(form=form)
210     @error_handler(edit)
211     @expose()
212     def update(self, id, **kw):
213         """Save or create record to model"""
214         r = validate_set(id, kw)
215         flash(_(u'El %s fue actualizado.') % name)
216         raise redirect('../list')
217
218     @expose(template='kid:%s.templates.show' % __name__)
219     def show(self,id, **kw):
220         """Show record in model"""
221         r = validate_get(id)
222         return dict(name=name, namepl=namepl, record=r)
223
224     @expose()
225     def delete(self, id):
226         """Destroy record in model"""
227         validate_del(id)
228         flash(_(u'El %s fue eliminado permanentemente.') % name)
229         raise redirect('../list')
230
231     @expose()
232     def files(self, id):
233         r = validate_get(id)
234         response.headers["Content-Type"] = r.archivo_type
235         response.headers["Content-disposition"] = "attachment;filename=%s" % (r.archivo_name)
236         flash(_(u'El %s fue eliminado permanentemente.') % name)
237         return r.archivo
238 #}}}
239