source: WAeUP_SRP/trunk/Widgets.py @ 1913

Last change on this file since 1913 was 1907, checked in by joachim, 18 years ago

error messages with variables cause no modifications to zodb

  • Property svn:keywords set to Id
File size: 43.5 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 1907 2007-06-16 14:09:52Z joachim $
3from cgi import escape
4from types import *
5from Globals import InitializeClass
6##from Products.CPSSchemas.Widget import CPSWidgetType
7from Products.CMFCore.utils import getToolByName
8from Products.CPSSchemas.BasicWidgets import CPSBooleanWidget, CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget
9from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget
10from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget
11from Products.CPSSchemas.Widget import widgetRegistry
12##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry
13from DateTime.DateTime import DateTime
14from AccessControl import getSecurityManager
15from Products.WAeUP_SRP.Students import getStudentByRegNo
16from Products.WAeUP_SRP.Academics import makeCertificateCode
17from re import compile
18import logging
19
20#from zLOG import LOG, DEBUG
21
22class CPSSelectWidgetForRecord(CPSSelectWidget): ###(
23    """Select widget. with record names"""
24    meta_type = 'Select Widget for Records'
25
26    field_types = ('CPS String Field',)
27    field_inits = ({'is_searchabletext': 1,},)
28
29    _properties = CPSSelectWidget._properties + (
30        {'id': 'record_id', 'type': 'string', 'mode': 'w',
31         'label': 'Record Id', 'is_required' : 1},
32        )
33
34    def render(self, mode, datastructure, **kw):
35        """Render in mode from datastructure."""
36        value = datastructure[self.getWidgetId()]
37        vocabulary = self._getVocabulary(datastructure)
38        portal = getToolByName(self, 'portal_url').getPortalObject()
39        cpsmcat = portal.translation_service
40        if mode == 'view':
41            if self.translated:
42                return escape(cpsmcat(vocabulary.getMsgid(value, value)).encode('ISO-8859-15', 'ignore'))
43            else:
44                return escape(vocabulary.get(value, value))
45        elif mode == 'edit':
46            html_widget_id = self.getHtmlWidgetId()
47            res = renderHtmlTag('select',
48                                name='%s.%s:records' % (self.record_id,html_widget_id),
49                                id=html_widget_id)
50            in_selection = 0
51            for k, v in vocabulary.items():
52                if self.translated:
53                    kw = {'value': k,
54                          'contents': cpsmcat(vocabulary.getMsgid(k, k)).encode('ISO-8859-15', 'ignore')
55                          }
56                else:
57                    kw = {'value': k, 'contents': v}
58                if value == k:
59                    kw['selected'] = 'selected'
60                    in_selection = 1
61                res += renderHtmlTag('option', **kw)
62            if value and not in_selection:
63                kw = {'value': value, 'contents': 'invalid: '+ str(value),
64                      'selected': 'selected'}
65                res += renderHtmlTag('option', **kw)
66            res += '</select>'
67            return res
68        raise RuntimeError('unknown mode %s' % mode)
69
70InitializeClass(CPSSelectWidgetForRecord)
71
72widgetRegistry.register(CPSSelectWidgetForRecord)
73
74###)
75
76class CPSStringWidgetForRecord(CPSStringWidget): ###(
77    """String widget."""
78    meta_type = 'String Widget For Record'
79
80    field_types = ('CPS String Field',)
81    field_inits = ({'is_searchabletext': 1,},)
82    _properties = CPSStringWidget._properties + (
83        {'id': 'record_id', 'type': 'string', 'mode': 'w',
84         'label': 'Record Id', 'is_required' : 1},
85        )
86
87    def render(self, mode, datastructure, **kw):
88        """Render in mode from datastructure."""
89        value = datastructure[self.getWidgetId()]
90        if mode == 'view':
91            return escape(value)
92        elif mode == 'edit':
93            # XXX TODO should use an other name than kw !
94            # XXX change this everywhere
95            html_widget_id = self.getHtmlWidgetId()
96            kw = {'type': 'text',
97                  'id'  : html_widget_id,
98                  'name': '%s.%s:records' % (self.record_id,html_widget_id),
99                  'value': escape(value),
100                  'size': self.display_width,
101                  }
102            if self.size_max:
103                kw['maxlength'] = self.size_max
104            return renderHtmlTag('input', **kw)
105        raise RuntimeError('unknown mode %s' % mode)
106
107InitializeClass(CPSStringWidgetForRecord)
108
109widgetRegistry.register(CPSStringWidgetForRecord)
110
111###)
112
113class CertificateCourseIdWidget(CPSStringWidget): ###(
114    """ CertificateCourseId Widget"""
115    meta_type = "CertificateCourseId Widget"
116
117    def validate(self, datastructure, **kw):
118        """Validate datastructure and update datamodel."""
119
120        valid = CPSStringWidget.validate(self, datastructure, **kw)
121        if not valid:
122            return 0
123        else:
124            widget_id = self.getWidgetId()
125            value = datastructure[widget_id].upper()
126            err = 0
127            c_ids = [c.id for c in self.portal_catalog({'meta_type': "Course"})]
128            if hasattr(self.aq_parent,value):
129                err = 'Course already exists'
130            elif value not in c_ids:
131                err = 'Course does not exist'
132            if err:
133                datastructure.setError(widget_id, err)
134            else:
135                datamodel = datastructure.getDataModel()
136                datamodel[self.fields[0]] = value
137
138            return not err
139
140InitializeClass(CertificateCourseIdWidget)
141
142widgetRegistry.register(CertificateCourseIdWidget)
143###)
144
145class CourseIdWidget(CPSStringWidget): ###(
146    """ CourseId Widget"""
147    meta_type = "CourseId Widget"
148
149    def validate(self, datastructure, **kw):
150        """Validate datastructure and update datamodel."""
151
152        valid = CPSStringWidget.validate(self, datastructure, **kw)
153        if not valid:
154            return 0
155        else:
156            widget_id = self.getWidgetId()
157            value = datastructure[widget_id].upper()
158            err = 0
159            res = self.portal_catalog(meta_type= "Course",id = value)
160            if len(res) > 0:
161                err = 'Course already exists'
162            if err:
163                datastructure.setError(widget_id, err)
164            else:
165                datamodel = datastructure.getDataModel()
166                datamodel[self.fields[0]] = value
167
168            return not err
169
170InitializeClass(CourseIdWidget)
171
172widgetRegistry.register(CourseIdWidget)
173
174
175###)
176
177class WAeUPStudyModeWidget(CPSSelectWidget): ###(
178    """WAeUP StudyMode widget."""
179    meta_type = 'WAeUP StudyMode Widget'
180    vocabulary = 'entry_modes'
181
182    def _getStudyModes(self):
183        voc = getattr(self.portal_vocabularies,self.vocabulary)
184        d = {}
185        for k,v in voc.items():
186            d[k] = v
187        return d
188
189    def validate(self, datastructure, **kw):
190        """Validate datastructure and update datamodel."""
191        widget_id = self.getWidgetId()
192        value = datastructure[widget_id]
193        try:
194            v = str(value)
195        except ValueError:
196            datastructure.setError(widget_id, "'%s' not a valid session key" % value)
197            return 0
198        studymodes = self._getStudyModes()
199        if not value:
200            v = value = 'ume_ft'
201        #import pdb;pdb.set_trace()
202        if not studymodes.has_key(value):
203            datastructure.setError(widget_id, "'%s' not a valid session key" % v)
204            return 0
205        if self.is_required and not len(v):
206            datastructure.setError(widget_id, "session key required")
207            return 0
208
209        datamodel = datastructure.getDataModel()
210        datamodel[self.fields[0]] = v
211        return 1
212
213    def render(self, mode, datastructure, **kw):
214        """Render in mode from datastructure."""
215        value = datastructure[self.getWidgetId()]
216        studymodes = self._getStudyModes()
217        if mode == 'view':
218            return escape(studymodes.get(value, value))
219        elif mode == 'edit':
220            html_widget_id = self.getHtmlWidgetId()
221            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
222            in_selection = 0
223            vocabulary_items = studymodes.items()
224            if self.sorted:
225                vocabulary_items.sort(key=operator.itemgetter(1))
226            for k, v in vocabulary_items:
227                kw = {'value': k, 'contents': v}
228                if value == k:
229                    kw['selected'] = 'selected'
230                    in_selection = 1
231                res += renderHtmlTag('option', **kw)
232            if value and not in_selection:
233                kw = {'value': value, 'contents': 'invalid: '+ str(value),
234                      'selected': 'selected'}
235                res += renderHtmlTag('option', **kw)
236            res += '</select>'
237            return res
238        raise RuntimeError('unknown mode %s' % mode)
239
240InitializeClass(WAeUPStudyModeWidget)
241
242widgetRegistry.register(WAeUPStudyModeWidget)
243
244###)
245
246class WAeUPSessionWidget(CPSSelectWidget): ###(
247    """WAeUP Session widget."""
248    meta_type = 'WAeUP Session Widget'
249
250    def _getSessions(self):
251        current_year = DateTime().year()
252        d = {'xx': 'unknown'}
253        for y in range(current_year - 9,current_year + 1):
254            d['%s' % str(y)[-2:]] = '%4d/%4d' % (y,y+1)
255        return d
256
257    def validate(self, datastructure, **kw):
258        """Validate datastructure and update datamodel."""
259        widget_id = self.getWidgetId()
260        value = datastructure[widget_id]
261        try:
262            v = str(value)
263        except ValueError:
264            datastructure.setError(widget_id, "'%s' not a valid session key" % value)
265            return 0
266
267        if len(v) == 1:
268            v = value = '0%c' % v
269        elif not value:
270            v = value = self.getSessionId()[-2:]
271        #import pdb;pdb.set_trace()
272        sessions = self._getSessions()
273        if not sessions.has_key(value):
274            datastructure.setError(widget_id, "'%s' not a valid session key" % v)
275            return 0
276        if self.is_required and not len(v):
277            datastructure.setError(widget_id, "session key required")
278            return 0
279
280        datamodel = datastructure.getDataModel()
281        datamodel[self.fields[0]] = v
282        return 1
283
284    def render(self, mode, datastructure, **kw):
285        """Render in mode from datastructure."""
286        value = datastructure[self.getWidgetId()]
287        sessions = self._getSessions()
288        if mode == 'view':
289            return escape(sessions.get(value, value))
290        elif mode == 'edit':
291            html_widget_id = self.getHtmlWidgetId()
292            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
293            in_selection = 0
294            vocabulary_items = sessions.items()
295            if self.sorted:
296                vocabulary_items.sort(key=operator.itemgetter(1))
297            for k, v in vocabulary_items:
298                kw = {'value': k, 'contents': v}
299                if value == k:
300                    kw['selected'] = 'selected'
301                    in_selection = 1
302                res += renderHtmlTag('option', **kw)
303            if value and not in_selection:
304                kw = {'value': value, 'contents': 'invalid: '+ str(value),
305                      'selected': 'selected'}
306                res += renderHtmlTag('option', **kw)
307            res += '</select>'
308            return res
309        raise RuntimeError('unknown mode %s' % mode)
310
311InitializeClass(WAeUPSessionWidget)
312
313widgetRegistry.register(WAeUPSessionWidget)
314
315###)
316
317class WAeUPLevelWidget(CPSSelectWidget): ###(
318    """WAeUP Level Widget."""
319    meta_type = 'WAeUP Level Widget'
320
321    def _getLevels(self):
322        d = {'999':'unknown'}
323        for y in range(100,800,100):
324            d['%s' % str(y)] = 'Year %1d (%3d Level)' % (y/100,y)
325        return d
326
327    def validate(self, datastructure, **kw):
328        """Validate datastructure and update datamodel."""
329        widget_id = self.getWidgetId()
330        value = datastructure[widget_id]
331        try:
332            v = str(value)
333        except ValueError:
334            datastructure.setError(widget_id, "'%s' not a valid level key" % value)
335            return 0
336
337        if not value:
338            v = value = '100'
339        #import pdb;pdb.set_trace()
340        levels = self._getLevels()
341        if not levels.has_key(value):
342            datastructure.setError(widget_id, "'%s' not a valid level" % v)
343            return 0
344        if self.is_required and not len(v):
345            datastructure.setError(widget_id, "level key required")
346            return 0
347
348        datamodel = datastructure.getDataModel()
349        datamodel[self.fields[0]] = v
350        return 1
351
352    def render(self, mode, datastructure, **kw):
353        """Render in mode from datastructure."""
354        value = datastructure[self.getWidgetId()]
355        levels = self._getLevels()
356        if mode == 'view':
357            return escape(levels.get(value, value))
358        elif mode == 'edit':
359            html_widget_id = self.getHtmlWidgetId()
360            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
361            in_selection = 0
362            vocabulary_items = levels.items()
363            if self.sorted:
364                vocabulary_items.sort(key=operator.itemgetter(1))
365            for k, v in vocabulary_items:
366                kw = {'value': k, 'contents': v}
367                if value == k:
368                    kw['selected'] = 'selected'
369                    in_selection = 1
370                res += renderHtmlTag('option', **kw)
371            if value and not in_selection:
372                kw = {'value': value, 'contents': 'invalid: '+ str(value),
373                      'selected': 'selected'}
374                res += renderHtmlTag('option', **kw)
375            res += '</select>'
376            return res
377        raise RuntimeError('unknown mode %s' % mode)
378
379InitializeClass(WAeUPLevelWidget)
380
381widgetRegistry.register(WAeUPLevelWidget)
382
383###)
384
385class WAeUPVerdictWidget(CPSSelectWidget): ###(
386    """WAeUP Verdict widget."""
387    meta_type = 'WAeUP Verdict Widget'
388
389    # XXX make a menu for the vocabulary.
390    vocabulary = 'verdicts'
391
392    # Associating the widget label with an input area to improve the widget
393    # accessibility.
394    has_input_area = True
395
396    def _getVerdicts(self,datastructure):
397        voc = getattr(self.portal_vocabularies,self.vocabulary)
398        d = {}
399        for k,v in voc.items():
400            d[k] = v
401        return d
402
403    def validate(self, datastructure, **kw):
404        """Validate datastructure and update datamodel."""
405        widget_id = self.getWidgetId()
406        value = datastructure[widget_id]
407        try:
408            v = str(value)
409        except ValueError:
410            datastructure.setError(widget_id, "'%s' not a valid verdict key" % value)
411            return 0
412        #import pdb;pdb.set_trace()
413        verdicts = self._getVerdicts(datastructure)
414        if not value:
415            v = value = verdicts['N/A']
416        if not verdicts.has_key(value):
417            datastructure.setError(widget_id, "'%s' not a valid verdict key" % v)
418            return 0
419        if self.is_required and not len(v):
420            datastructure.setError(widget_id, "verdict required")
421            return 0
422
423        datamodel = datastructure.getDataModel()
424        datamodel[self.fields[0]] = v
425        return 1
426
427    def render(self, mode, datastructure, **kw):
428        """Render in mode from datastructure."""
429        value = datastructure[self.getWidgetId()]
430        verdicts = self._getVerdicts(datastructure)
431        if mode == 'view':
432            return escape(verdicts.get(value, value))
433        elif mode == 'edit':
434            html_widget_id = self.getHtmlWidgetId()
435            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
436            in_selection = 0
437            vocabulary_items = verdicts.items()
438            if self.sorted:
439                vocabulary_items.sort(key=operator.itemgetter(1))
440            for k, v in vocabulary_items:
441                kw = {'value': k, 'contents': v}
442                if value == k:
443                    kw['selected'] = 'selected'
444                    in_selection = 1
445                res += renderHtmlTag('option', **kw)
446            if value and not in_selection:
447                kw = {'value': value, 'contents': 'invalid: '+ str(value),
448                      'selected': 'selected'}
449                res += renderHtmlTag('option', **kw)
450            res += '</select>'
451            return res
452        raise RuntimeError('unknown mode %s' % mode)
453
454InitializeClass(WAeUPVerdictWidget)
455
456widgetRegistry.register(WAeUPVerdictWidget)
457
458###)
459
460class WAeUPReservedRoomsWidget(CPSStringWidget): ###(
461    """ WAeUPReservedRooms Widget"""
462    meta_type = "WAeUPReservedRooms Widget"
463
464    def validate(self, datastructure, **kw):
465        """Validate datastructure and update datamodel."""
466        import re
467        valid = CPSStringWidget.validate(self, datastructure, **kw)
468        if not valid:
469            return 0
470        else:
471            widget_id = self.getWidgetId()
472            value = datastructure[widget_id]
473            err = 0
474            try:
475                reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',value)
476                                     if r]
477            except (ValueError,IndexError),msg:
478                err = str(msg)
479            if err:
480                datastructure.setError(widget_id, err)
481            else:
482                datamodel = datastructure.getDataModel()
483                datamodel[self.fields[0]] = value
484            return not err
485
486InitializeClass(WAeUPReservedRoomsWidget)
487
488widgetRegistry.register(WAeUPReservedRoomsWidget)
489###)
490
491class WAeUPIdWidget(CPSStringWidget): ###(
492    """ WAeUPId Widget"""
493    meta_type = "WAeUPId Widget"
494
495    def validate(self, datastructure, **kw):
496        """Validate datastructure and update datamodel."""
497
498        valid = CPSStringWidget.validate(self, datastructure, **kw)
499        id_pat_str = r"\S"
500        inv_id_pat = compile(r"^%s$" % id_pat_str)
501        if not valid:
502            return 0
503        else:
504            portal_type_query = {'query':['Faculty',
505                                          'Department',
506                                          'Course',
507                                          'Certificate',
508                                          'CertificateCourse',]}
509            widget_id = self.getWidgetId()
510            value = datastructure[widget_id].upper()
511            err = 0
512            mapping = {}
513            if len(value.split()) > 1:
514                err = 'Invalid Id, Id contains space(s).'
515            elif self.portal_catalog(portal_type=portal_type_query,id=value):
516                brain = self.portal_catalog(portal_type=portal_type_query,id=value)[0]
517                err = 'An ${portal_type} object with the Id ${id} already exists at ${path}.'
518                mapping = {'portal_type': brain.portal_type,
519                           'id': value,
520                           'path': brain.getPath(),
521                           }
522            if err:
523                datastructure.setError(widget_id, err, mapping)
524            else:
525                datamodel = datastructure.getDataModel()
526                datamodel[self.fields[0]] = value
527
528            return not err
529
530InitializeClass(WAeUPIdWidget)
531
532widgetRegistry.register(WAeUPIdWidget)
533
534
535###)
536
537class StudyCourseWidget(CPSStringWidget): ###(
538    """ StudyCourse Widget"""
539    meta_type = "StudyCourse Widget"
540
541    def validate(self, datastructure, **kw):
542        """Validate datastructure and update datamodel."""
543        #from Products.zdb import set_trace
544        #set_trace()
545##        valid = CPSStringWidget.validate(self, datastructure, **kw)
546##        if not valid:
547##            return 0
548        widget_id = self.getWidgetId()
549        value = makeCertificateCode(datastructure[widget_id]).upper()
550        id_pat_str = r"\S"
551        inv_id_pat = compile(r"^%s$" % id_pat_str)
552        err = 0
553        if len(value.split()) > 1:
554            err = 'Invalid Id, Id contains space(s).'
555        elif not self.portal_catalog(portal_type='Certificate',id=value):
556            err = 'No such certificate'
557        if err:
558            datastructure.setError(widget_id, err)
559        else:
560            datamodel = datastructure.getDataModel()
561            datamodel[self.fields[0]] = value
562        return not err
563
564InitializeClass(StudyCourseWidget)
565
566widgetRegistry.register(StudyCourseWidget)
567###)
568
569class JambRegNoWidget(CPSStringWidget): ###(
570    """ JambRegNo Widget"""
571    meta_type = "JambRegNo Widget"
572    _properties = CPSStringWidget._properties + (
573        {'id': 'catalog', 'type': 'string', 'mode': 'w',
574         'label': 'Catalog to search'},
575         {'id': 'reference', 'type': 'string', 'mode': 'w',
576         'label': 'Reference Field'},
577         )
578    catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
579    reference = ""
580    digits = 8
581    digits_str = "N"*digits
582    letters = 2
583    letters_str = "L"*letters
584    def validate(self, datastructure, **kw):
585        """Validate datastructure and update datamodel."""
586        valid = CPSStringWidget.validate(self, datastructure, **kw)
587        jamb_nr_catalog = getattr(self,self.catalog)
588        widget_id = self.getWidgetId()
589        value = datastructure[widget_id].upper()
590        err = 0
591        if not valid: #or not (len(value) == self.digits + self.letters and value[:self.digits].isdigit() and value[self.digits:].isalpha()):
592            #err = 'Invalid number, the expected format is: %s%s with N = Number, L = Letter' % (self.digits_str,self.letters_str)
593            err = 'Invalid number'
594        elif self.reference == '':
595            #s = getStudentByRegNo(self,value)
596            pume = jamb_nr_catalog(jamb_reg_no = value)
597            if len(pume) < 1:
598                err = 'No student record with this registration number.'
599            else:
600                datastructure['pume'] = pume[0]
601        else:
602            #import pdb;pdb.set_trace()
603            record = datastructure[self.reference]
604            #jamb_reg_no = getattr(record,widget_id)
605            jamb_reg_no = record.Entryregno
606            if jamb_reg_no != value:
607                err = 'Registration number does not match.'
608        if err:
609            datastructure.setError(widget_id, err)
610        else:
611            datamodel = datastructure.getDataModel()
612            datamodel[self.fields[0]] = value
613        return not err
614
615InitializeClass(JambRegNoWidget)
616
617widgetRegistry.register(JambRegNoWidget)
618###)
619
620class SecretWidget(CPSStringWidget): ###(
621    """ Secret Widget"""
622    meta_type = "Secret Widget"
623    _properties = CPSStringWidget._properties + (
624        {'id': 'reference', 'type': 'string', 'mode': 'w',
625         'label': 'Reference Record'},
626         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
627         'label': 'Fields to check'},
628         )
629    reference = "student"
630    matric_no_catalog = 'returning_import'
631    check_fields = ("Firstname", "Middlename","Lastname")
632    def validate(self, datastructure, **kw):
633        """Validate datastructure and update datamodel."""
634        logger = logging.getLogger('Widgets.SecretWidget.validate')
635        valid = CPSStringWidget.validate(self, datastructure, **kw)
636        widget_id = self.getWidgetId()
637        value = datastructure[widget_id].upper()
638        err = 0
639        record = datastructure.get(self.reference,None)
640        #import pdb;pdb.set_trace()
641        if not valid or len(value) < 2:
642            err = 'Invalid string'
643        elif not record or datastructure.errors:
644            err = 0
645        else:
646            found = False
647            cvs = []
648            for field in self.check_fields:
649                cv = getattr(record,field).upper()
650                if len(cv.split()) > 1:
651                    for splited in cv.split():
652                        cvs.append(splited.strip())
653                else:
654                    cvs.append(cv)
655            for cv in cvs:
656                if cv  == value.upper():
657                    found = True
658                    break
659            matric_no = record.matric_no
660            name = " ".join(cvs)
661            if not found:
662                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
663                err = 'No name does match.'
664            else:
665                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
666        if err:
667            datastructure.setError(widget_id, err)
668        else:
669            datamodel = datastructure.getDataModel()
670            datamodel[self.fields[0]] = value
671        return not err
672
673InitializeClass(SecretWidget)
674
675widgetRegistry.register(SecretWidget)
676###)
677
678class WAeUPSexWidget(CPSBooleanWidget): ###(
679    """WAeUP sex widget."""
680    meta_type = 'WAeUP Sex Widget'
681
682    def validate(self, datastructure, **kw):
683        """Validate datastructure and update datamodel."""
684        value = datastructure[self.getWidgetId()]
685
686        if self.render_format not in self.render_formats:
687            self.render_format = 'select'
688
689        female = value in ('F','f','Female','female',"True",True)
690        male = value in ('M','m','Male','male','False',False)
691        if not female and not male:
692            datastructure.setError(self.getWidgetId(),
693                                   "invalid sex %s" % value)
694            return 0
695        elif female:
696            v = True
697        else:
698            v = False
699        datamodel = datastructure.getDataModel()
700        datamodel[self.fields[0]] = v
701        return 1
702
703InitializeClass(WAeUPSexWidget)
704
705widgetRegistry.register(WAeUPSexWidget)
706
707###)
708
709class MatricNoWidget(CPSStringWidget): ###(
710    """ MatricNo Widget"""
711    meta_type = "MatricNo Widget"
712
713    _properties = CPSStringWidget._properties + (
714        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
715         'label': 'Catalog to search for MatricNo'},
716        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
717         'label': 'Results Catalog'},
718         )
719    matric_no_catalog = "" #the catalog to search for matric_no
720    results_catalog = "results_import" #results catalog
721
722    def validate(self, datastructure, **kw):
723        """Validate datastructure and update datamodel."""
724        #import pdb;pdb.set_trace()
725        valid = CPSStringWidget.validate(self, datastructure, **kw)
726        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
727        returning = getattr(self,self.matric_no_catalog)
728        results = getattr(self,self.results_catalog,None)
729        err = 0
730        widget_id = self.getWidgetId()
731        value = datastructure[widget_id]
732        if not valid or not value:
733            err = 'Invalid string'
734            logger.info('Invalid matric_no string %s' % value)
735        else:
736            value = value.upper()
737            datastructure['student'] = None
738            while not err:
739                res = returning(matric_no = value)
740                if len(res) < 1:
741                    logger.info('matric_no %s not found' % value)
742                    err = 'No student with this matriculation number.'
743                    break
744                datastructure['student'] = res[0]
745                if results is not None:
746                    res = results(matric_no = value)
747                    if len(res) < 1:
748                        err = 'No results for this matriculation number'
749                        continue
750                    datastructure['results'] = res
751                break
752        if err:
753            datastructure.setError(widget_id, err)
754        else:
755            datamodel = datastructure.getDataModel()
756            datamodel[self.fields[0]] = value
757        return not err
758
759InitializeClass(MatricNoWidget)
760
761widgetRegistry.register(MatricNoWidget)
762###)
763
764class StudentIdWidget(CPSStringWidget): ###(
765    """ StudentId Widget"""
766    meta_type = "StudentId Widget"
767    def validate(self, datastructure, **kw):
768        """Validate datastructure and update datamodel."""
769        valid = CPSStringWidget.validate(self, datastructure, **kw)
770        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
771        #import pdb;pdb.set_trace()
772        s_cat = self.students_catalog
773        err = 0
774        widget_id = self.getWidgetId()
775        value = datastructure[widget_id]
776        if not valid or not value:
777            err = 'Invalid Id string'
778            logger.info('Invalid id string %s' % value)
779            datastructure['student'] = None
780        else:
781            value = value.upper()
782            res = s_cat(id = value)
783            if not res:
784                logger.info('Student id %s not found' % value)
785                err = 'No student with this Id'
786                datastructure['student'] = None
787            else:
788                datastructure['student'] = res[0]
789        if err:
790            datastructure.setError(widget_id, err)
791        else:
792            datamodel = datastructure.getDataModel()
793            datamodel[self.fields[0]] = value
794        return not err
795
796InitializeClass(StudentIdWidget)
797
798widgetRegistry.register(StudentIdWidget)
799###)
800
801class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
802    """ WAeUPMultilineResults Widget"""
803    meta_type = "WAeUp Multiline Results Widget"
804    _properties = CPSWidget._properties + (
805        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
806         'label': 'Nr of Lines'},
807         )
808    nr_of_lines = 5
809    def prepare(self, datastructure, **kw): ###(
810        """Prepare datastructure from datamodel."""
811        datamodel = datastructure.getDataModel()
812        #import pdb;pdb.set_trace()
813        widget_id = self.getWidgetId()
814        v = datamodel[self.fields[0]]
815        if type(v) is ListType and v:
816            nr_results = len(v)
817        else:
818            v = []
819            nr_results = 0
820        count = 1
821        for s,g in v:
822            wid = "%s%02d"% (widget_id,count)
823            datastructure[wid+'_s'] = s
824            datastructure[wid+'_g'] = g
825            count += 1
826        if nr_results < self.nr_of_lines:
827            for line in range(nr_results,self.nr_of_lines):
828                v.append(('',''))
829                wid = "%s%02d"% (widget_id,line)
830                datastructure[wid+'_s'] = ''
831                datastructure[wid+'_g'] = ''
832        datastructure[widget_id] = v
833        datastructure[widget_id+'_s'] = ''
834        datastructure[widget_id+'_g'] = ''
835    ###)
836
837    def validate(self, datastructure, **kw): ###(
838        """Validate datastructure and update datamodel."""
839        #import pdb;pdb.set_trace()
840        widget_id = self.getWidgetId()
841        err = 0
842        lines = []
843        for line in range(1,30):
844            wid = "%s%02d"% (widget_id,line)
845            if not datastructure.has_key(wid+'_s'):
846                break
847            lines.append((datastructure[wid+'_s'].strip(),
848                         datastructure[wid+'_g'].strip()))
849
850        s = datastructure[widget_id+'_s'].strip()
851        g = datastructure[widget_id+'_g'].strip()
852        if s and g:
853            lines.append((s,g))
854        active = []
855        for s,g in lines:
856            if g != "":
857                active.append((s,g))
858        if err:
859            datastructure.setError(widget_id, err)
860        else:
861            datamodel = datastructure.getDataModel()
862            datamodel[self.fields[0]] = active
863        return not err
864    ###)
865
866    def render(self, mode, datastructure, **kw): ###(
867        """Render in mode from datastructure."""
868        render_method = 'widget_waeup_multiline_result_render'
869        meth = getattr(self, render_method, None)
870        if meth is None:
871            raise RuntimeError("Unknown Render Method %s for widget type %s"
872                               % (render_method, self.getId()))
873        #import pdb;pdb.set_trace()
874        datamodel = datastructure.getDataModel()
875        widget_id = self.getWidgetId()
876        lines = datamodel[self.fields[0]]
877        if len(lines) < self.nr_of_lines:
878            for line in range(len(lines),self.nr_of_lines + 1):
879                lines.append(('',''))
880        datastructure[widget_id] = lines
881        datastructure[widget_id+'_s'] = ''
882        datastructure[widget_id+'_g'] = ''
883##        count = 1
884##        for s,g in v:
885##            wid = "%s%02d"% (widget_id,count)
886##            count += 1
887        return meth(mode=mode,
888                    datastructure=datastructure,
889                    )
890    ###)
891
892
893InitializeClass(WAeUPMultilineResultsWidget)
894widgetRegistry.register(WAeUPMultilineResultsWidget)
895###)
896
897class WAeUPResultsWidget(CPSStringWidget): ###(
898    """ WAeUPResults Widget"""
899    meta_type = "WAeUp Results Widget"
900
901    def prepare(self, datastructure, **kw): ###(
902        """Prepare datastructure from datamodel."""
903        datamodel = datastructure.getDataModel()
904        v = datamodel[self.fields[0]]
905        #import pdb;pdb.set_trace()
906        widget_id = self.getWidgetId()
907        datastructure[widget_id] = v
908        datastructure[widget_id+'_s'] = ''
909        datastructure[widget_id+'_g'] = ''
910    ###)
911
912    def validate(self, datastructure, **kw): ###(
913        """Validate datastructure and update datamodel."""
914        #import pdb;pdb.set_trace()
915        widget_id = self.getWidgetId()
916        v = datastructure[widget_id]
917        err = 0
918        s = datastructure[widget_id+'_s'].strip()
919        g = datastructure[widget_id+'_g'].strip()
920        while 1:
921            if not s and g:
922                err = "No subject grade for subject"
923                break
924            i = 0
925            done = False
926            for sv,gv in v:
927                if sv == s:
928                    done = True
929                    if not g:
930                        v.pop(i)
931                        break
932                    v[i] = (s,g)
933                    break
934                i += 1
935            if done:
936                break
937            if s and g:
938                v.append((s,g))
939            break
940        if err:
941            datastructure.setError(widget_id, err)
942        else:
943            datamodel = datastructure.getDataModel()
944            datamodel[self.fields[0]] = v
945            datastructure[widget_id+'_s'] = s
946            datastructure[widget_id+'_g'] = g
947        return not err
948    ###)
949
950    def render(self, mode, datastructure, **kw): ###(
951        """Render in mode from datastructure."""
952        render_method = 'widget_waeup_result_render'
953        meth = getattr(self, render_method, None)
954        if meth is None:
955            raise RuntimeError("Unknown Render Method %s for widget type %s"
956                               % (render_method, self.getId()))
957        #import pdb;pdb.set_trace()
958        datamodel = datastructure.getDataModel()
959        widget_id = self.getWidgetId()
960        datastructure[widget_id+'_s'] = ''
961        datastructure[widget_id+'_g'] = ''
962        return meth(mode=mode,
963                    datastructure=datastructure,
964                    )
965    ###)
966
967
968InitializeClass(WAeUPResultsWidget)
969widgetRegistry.register(WAeUPResultsWidget)
970###)
971
972class ScratchCardPin: ###(
973    """the ScratchCardPin"""
974    def __init__(self,prefix,batch_no,number):
975        if not batch_no and not number:
976            s = prefix
977            if len(s) > 3:
978                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
979            else:
980                prefix,batch_no,number = s,'',''
981        self.p = prefix
982        self.b = batch_no
983        self.n = number
984
985    def __str__(self):
986        return "%s-%s-%s" % (self.p,self.b,self.n)
987
988    def __repr__(self):
989        return "%s%s%s" % (self.p,self.b,self.n)
990###)
991
992class ScratchcardPinWidget(CPSStringWidget): ###(
993    """ ScratchcardPin Widget"""
994    meta_type = "Scratchcard Pin Widget"
995    _properties = CPSWidget._properties + (
996        {'id': 'prefix', 'type': 'string', 'mode': 'w',
997         'label': 'Prefix'},
998         {'id': 'reference', 'type': 'string', 'mode': 'w',
999         'label': 'Reference Field'},
1000        )
1001    prefix = ''
1002    reference = ''
1003    def prepare(self, datastructure, **kw): ###(
1004        """Prepare datastructure from datamodel."""
1005        datamodel = datastructure.getDataModel()
1006        v = datamodel[self.fields[0]]
1007        widget_id = self.getWidgetId()
1008        #import pdb;pdb.set_trace()
1009        if v and type(v) is StringType:
1010            try:
1011                p,b,n = v.split('-')
1012                v = ScratchCardPin(p,b,n)
1013            except ValueError:
1014                v = ScratchCardPin(v,'','')
1015        if v:
1016            p = '%s' % v.p
1017            b = '%s' % v.b
1018            n = '%s' % v.n
1019        else:
1020            p = self.prefix
1021            if p.startswith('@'):
1022                p = getattr(self,self.prefix[1:])()
1023            b = n = ''
1024            v = ScratchCardPin(p,b,n)
1025        datastructure[widget_id] = v
1026        datastructure[widget_id+'_p'] = p
1027        datastructure[widget_id+'_b'] = b
1028        datastructure[widget_id+'_n'] = n
1029    ###)
1030
1031    def validate(self, datastructure, **kw): ###(
1032        """Validate datastructure and update datamodel."""
1033        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1034        widget_id = self.getWidgetId()
1035        v = datastructure[widget_id]
1036        #import pdb;pdb.set_trace()
1037        err = 0
1038        mapping = {}
1039        prefix= self.prefix
1040        if prefix.startswith('@'):
1041            prefix= getattr(self,self.prefix[1:])()
1042        b = datastructure[widget_id+'_b'].strip()
1043        n = datastructure[widget_id+'_n'].strip()
1044        pins = self.portal_pins
1045        pin = "%(prefix)s%(b)s%(n)s" % vars()
1046        pin_str = "%(prefix)s-%(b)-s%(n)s" % vars()
1047        do = 1
1048        s_id = str(self.portal_membership.getAuthenticatedMember())
1049        #import pdb;pdb.set_trace()
1050        if self.isStaff():
1051            do = 0
1052            err ='You are not a Student. PIN neither checked nor used.'
1053            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1054        elif len(b) > 1 and b.find('-') > -1:
1055            do = 0
1056            err = 'PIN must not contain "-"'
1057            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1058        elif n.find('-') > -1:
1059            do = 0
1060            err = 'PIN must not contain "-"'
1061            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1062        elif len(n) != 10:
1063            do = 0
1064            err = 'Invalid PIN length'
1065            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1066        elif self.reference == "":
1067            ref = s_id
1068        else:
1069            ref = datastructure[self.reference]
1070            if datastructure.errors:
1071                do = 0
1072                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1073                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1074        while do:
1075            ok = pins.searchAndSetRecord(pin,ref,prefix)
1076            if ok < -2 or ok > 2:
1077                err = 'Unknown error, please report!'
1078                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1079                break
1080            elif ok == -2:
1081                err = 'Service already is activated but with a different PIN.'
1082                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1083                break
1084            elif ok == -1:
1085                err = 'Invalid PIN'
1086                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1087                break
1088            if ok == 0:
1089                err = 'PIN already used'
1090                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1091                break
1092            if ok >= 1:
1093                #import pdb;pdb.set_trace()
1094                if self.isStudent():
1095                    if self.reference == "jamb_reg_no":
1096                        err = "You are already logged in."
1097                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1098                        break
1099                    if ok == 1:
1100                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1101                    else:
1102                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1103                    break
1104                else:
1105                    student = getStudentByRegNo(self,ref)
1106                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1107                if student is None:
1108                    err = "Student not found"
1109                    s_logger.info('%s not found in admission list' % (ref))
1110                    break
1111                s_id = student.getId()
1112                if ok == 2:
1113                    if self.reference == "jamb_reg_no":
1114                        if hasattr(self.portal_directories.students,s_id):
1115                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1116                            mapping = {'id': s_id}
1117                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1118                            break
1119                        else:
1120                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1121                    else:
1122                        err = "Unknown error"
1123                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1124                        break
1125                try:
1126                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1127                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1128                except:
1129                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1130                    mapping = {'id': s_id}
1131                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1132                    break
1133            break
1134        if err:
1135            datastructure.setError(widget_id, err,mapping)
1136        else:
1137            datamodel = datastructure.getDataModel()
1138            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1139            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1140            datastructure[widget_id+'_p'] = prefix
1141            datastructure[widget_id+'_b'] = b
1142            datastructure[widget_id+'_n'] = n
1143            datastructure['s_id'] = s_id
1144        return not err
1145
1146###)
1147
1148    def render(self, mode, datastructure, **kw): ###(
1149        """Render in mode from datastructure."""
1150        render_method = 'widget_scratch_card_pin_render'
1151        meth = getattr(self, render_method, None)
1152        if meth is None:
1153            raise RuntimeError("Unknown Render Method %s for widget type %s"
1154                               % (render_method, self.getId()))
1155
1156        # XXX AT: datastructure has to be set again here, in case we're in edit
1157        # or create mode, because a default value has to be provided.
1158        #import pdb;pdb.set_trace()
1159        datamodel = datastructure.getDataModel()
1160        v = datamodel[self.fields[0]]
1161        if v and type(v) is StringType:
1162            try:
1163                p,b,n = v.split('-')
1164                v = ScratchCardPin(p,b,n)
1165            except ValueError:
1166                v = ScratchCardPin(self.prefix,'1',v)
1167                pass
1168        if v:
1169            prefix= '%s' % v.p
1170            b = '%s' % v.b
1171            n = '%s' % v.n
1172        else:
1173            prefix= self.prefix
1174            if prefix.startswith('@'):
1175                prefix= getattr(self,self.prefix[1:])()
1176            b = n = ''
1177            v = ScratchCardPin(prefix,b,n)
1178        widget_id = self.getWidgetId()
1179        datastructure[widget_id] = v
1180        datastructure[widget_id+'_p'] = prefix
1181        datastructure[widget_id+'_b'] = b
1182        datastructure[widget_id+'_n'] = n
1183        return meth(mode=mode,
1184                    datastructure=datastructure,
1185                    )
1186    ###)
1187
1188
1189InitializeClass(ScratchcardPinWidget)
1190widgetRegistry.register(ScratchcardPinWidget)
1191
1192
1193###)
1194
1195class WAeUPImageWidget(CPSImageWidget): ###(
1196    """Photo widget."""
1197    meta_type = 'WAeUP Image Widget'
1198
1199    def render(self, mode, datastructure, **kw):
1200        render_method = 'widget_waeup_image_render'
1201        meth = getattr(self, render_method, None)
1202        if meth is None:
1203            raise RuntimeError("Unknown Render Method %s for widget type %s"
1204                               % (render_method, self.getId()))
1205        img_info = self.getImageInfo(datastructure)
1206        return meth(mode=mode, datastructure=datastructure, **img_info)
1207
1208InitializeClass(WAeUPImageWidget)
1209
1210widgetRegistry.register(WAeUPImageWidget)
1211###)
1212
1213
1214###########
1215
Note: See TracBrowser for help on using the repository browser.