source: WAeUP_SRP/trunk/Widgets.py @ 1897

Last change on this file since 1897 was 1891, checked in by joachim, 18 years ago

avoid modificaton of zodb by constant error messages

  • Property svn:keywords set to Id
File size: 43.3 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 1891 2007-06-13 12:42:38Z 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            if len(value.split()) > 1:
513                err = 'Invalid Id, Id contains space(s).'
514            elif self.portal_catalog(portal_type=portal_type_query,id=value):
515                brain = self.portal_catalog(portal_type=portal_type_query,id=value)[0]
516                err = 'An %s object with the Id %s already exists at %s.'\
517                      % (brain.portal_type,value,brain.getPath())
518            if err:
519                datastructure.setError(widget_id, err)
520            else:
521                datamodel = datastructure.getDataModel()
522                datamodel[self.fields[0]] = value
523
524            return not err
525
526InitializeClass(WAeUPIdWidget)
527
528widgetRegistry.register(WAeUPIdWidget)
529
530
531###)
532
533class StudyCourseWidget(CPSStringWidget): ###(
534    """ StudyCourse Widget"""
535    meta_type = "StudyCourse Widget"
536
537    def validate(self, datastructure, **kw):
538        """Validate datastructure and update datamodel."""
539        #from Products.zdb import set_trace
540        #set_trace()
541##        valid = CPSStringWidget.validate(self, datastructure, **kw)
542##        if not valid:
543##            return 0
544        widget_id = self.getWidgetId()
545        value = makeCertificateCode(datastructure[widget_id]).upper()
546        id_pat_str = r"\S"
547        inv_id_pat = compile(r"^%s$" % id_pat_str)
548        err = 0
549        if len(value.split()) > 1:
550            err = 'Invalid Id, Id contains space(s).'
551        elif not self.portal_catalog(portal_type='Certificate',id=value):
552            err = 'No such certificate'
553        if err:
554            datastructure.setError(widget_id, err)
555        else:
556            datamodel = datastructure.getDataModel()
557            datamodel[self.fields[0]] = value
558        return not err
559
560InitializeClass(StudyCourseWidget)
561
562widgetRegistry.register(StudyCourseWidget)
563###)
564
565class JambRegNoWidget(CPSStringWidget): ###(
566    """ JambRegNo Widget"""
567    meta_type = "JambRegNo Widget"
568    _properties = CPSStringWidget._properties + (
569        {'id': 'catalog', 'type': 'string', 'mode': 'w',
570         'label': 'Catalog to search'},
571         {'id': 'reference', 'type': 'string', 'mode': 'w',
572         'label': 'Reference Field'},
573         )
574    catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
575    reference = ""
576    digits = 8
577    digits_str = "N"*digits
578    letters = 2
579    letters_str = "L"*letters
580    def validate(self, datastructure, **kw):
581        """Validate datastructure and update datamodel."""
582        valid = CPSStringWidget.validate(self, datastructure, **kw)
583        jamb_nr_catalog = getattr(self,self.catalog)
584        widget_id = self.getWidgetId()
585        value = datastructure[widget_id].upper()
586        err = 0
587        if not valid: #or not (len(value) == self.digits + self.letters and value[:self.digits].isdigit() and value[self.digits:].isalpha()):
588            #err = 'Invalid number, the expected format is: %s%s with N = Number, L = Letter' % (self.digits_str,self.letters_str)
589            err = 'Invalid number'
590        elif self.reference == '':
591            #s = getStudentByRegNo(self,value)
592            pume = jamb_nr_catalog(jamb_reg_no = value)
593            if len(pume) < 1:
594                err = 'No student record with this registration number.'
595            else:
596                datastructure['pume'] = pume[0]
597        else:
598            #import pdb;pdb.set_trace()
599            record = datastructure[self.reference]
600            #jamb_reg_no = getattr(record,widget_id)
601            jamb_reg_no = record.Entryregno
602            if jamb_reg_no != value:
603                err = 'Registration number does not match.'
604        if err:
605            datastructure.setError(widget_id, err)
606        else:
607            datamodel = datastructure.getDataModel()
608            datamodel[self.fields[0]] = value
609        return not err
610
611InitializeClass(JambRegNoWidget)
612
613widgetRegistry.register(JambRegNoWidget)
614###)
615
616class SecretWidget(CPSStringWidget): ###(
617    """ Secret Widget"""
618    meta_type = "Secret Widget"
619    _properties = CPSStringWidget._properties + (
620        {'id': 'reference', 'type': 'string', 'mode': 'w',
621         'label': 'Reference Record'},
622         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
623         'label': 'Fields to check'},
624         )
625    reference = "student"
626    matric_no_catalog = 'returning_import'
627    check_fields = ("Firstname", "Middlename","Lastname")
628    def validate(self, datastructure, **kw):
629        """Validate datastructure and update datamodel."""
630        logger = logging.getLogger('Widgets.SecretWidget.validate')
631        valid = CPSStringWidget.validate(self, datastructure, **kw)
632        widget_id = self.getWidgetId()
633        value = datastructure[widget_id].upper()
634        err = 0
635        record = datastructure.get(self.reference,None)
636        #import pdb;pdb.set_trace()
637        if not valid or len(value) < 2:
638            err = 'Invalid string'
639        elif not record or datastructure.errors:
640            err = 0
641        else:
642            found = False
643            cvs = []
644            for field in self.check_fields:
645                cv = getattr(record,field).upper()
646                if len(cv.split()) > 1:
647                    for splited in cv.split():
648                        cvs.append(splited.strip())
649                else:
650                    cvs.append(cv)
651            for cv in cvs:
652                if cv  == value.upper():
653                    found = True
654                    break
655            matric_no = record.matric_no
656            name = " ".join(cvs)
657            if not found:
658                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
659                err = 'No name does match.'
660            else:
661                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
662        if err:
663            datastructure.setError(widget_id, err)
664        else:
665            datamodel = datastructure.getDataModel()
666            datamodel[self.fields[0]] = value
667        return not err
668
669InitializeClass(SecretWidget)
670
671widgetRegistry.register(SecretWidget)
672###)
673
674class WAeUPSexWidget(CPSBooleanWidget): ###(
675    """WAeUP sex widget."""
676    meta_type = 'WAeUP Sex Widget'
677
678    def validate(self, datastructure, **kw):
679        """Validate datastructure and update datamodel."""
680        value = datastructure[self.getWidgetId()]
681
682        if self.render_format not in self.render_formats:
683            self.render_format = 'select'
684
685        female = value in ('F','f','Female','female',"True",True)
686        male = value in ('M','m','Male','male','False',False)
687        if not female and not male:
688            datastructure.setError(self.getWidgetId(),
689                                   "invalid sex %s" % value)
690            return 0
691        elif female:
692            v = True
693        else:
694            v = False
695        datamodel = datastructure.getDataModel()
696        datamodel[self.fields[0]] = v
697        return 1
698
699InitializeClass(WAeUPSexWidget)
700
701widgetRegistry.register(WAeUPSexWidget)
702
703###)
704
705class MatricNoWidget(CPSStringWidget): ###(
706    """ MatricNo Widget"""
707    meta_type = "MatricNo Widget"
708
709    _properties = CPSStringWidget._properties + (
710        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
711         'label': 'Catalog to search for MatricNo'},
712        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
713         'label': 'Results Catalog'},
714         )
715    matric_no_catalog = "" #the catalog to search for matric_no
716    results_catalog = "results_import" #results catalog
717
718    def validate(self, datastructure, **kw):
719        """Validate datastructure and update datamodel."""
720        #import pdb;pdb.set_trace()
721        valid = CPSStringWidget.validate(self, datastructure, **kw)
722        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
723        returning = getattr(self,self.matric_no_catalog)
724        results = getattr(self,self.results_catalog,None)
725        err = 0
726        widget_id = self.getWidgetId()
727        value = datastructure[widget_id]
728        if not valid or not value:
729            err = 'Invalid string'
730            logger.info('Invalid matric_no string %s' % value)
731        else:
732            value = value.upper()
733            datastructure['student'] = None
734            while not err:
735                res = returning(matric_no = value)
736                if len(res) < 1:
737                    logger.info('matric_no %s not found' % value)
738                    err = 'No student with this matriculation number.'
739                    break
740                datastructure['student'] = res[0]
741                if results is not None:
742                    res = results(matric_no = value)
743                    if len(res) < 1:
744                        err = 'No results for this matriculation number'
745                        continue
746                    datastructure['results'] = res
747                break
748        if err:
749            datastructure.setError(widget_id, err)
750        else:
751            datamodel = datastructure.getDataModel()
752            datamodel[self.fields[0]] = value
753        return not err
754
755InitializeClass(MatricNoWidget)
756
757widgetRegistry.register(MatricNoWidget)
758###)
759
760class StudentIdWidget(CPSStringWidget): ###(
761    """ StudentId Widget"""
762    meta_type = "StudentId Widget"
763    def validate(self, datastructure, **kw):
764        """Validate datastructure and update datamodel."""
765        valid = CPSStringWidget.validate(self, datastructure, **kw)
766        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
767        #import pdb;pdb.set_trace()
768        s_cat = self.students_catalog
769        err = 0
770        widget_id = self.getWidgetId()
771        value = datastructure[widget_id]
772        if not valid or not value:
773            err = 'Invalid Id string'
774            logger.info('Invalid id string %s' % value)
775            datastructure['student'] = None
776        else:
777            value = value.upper()
778            res = s_cat(id = value)
779            if not res:
780                logger.info('Student id %s not found' % value)
781                err = 'No student with this Id'
782                datastructure['student'] = None
783            else:
784                datastructure['student'] = res[0]
785        if err:
786            datastructure.setError(widget_id, err)
787        else:
788            datamodel = datastructure.getDataModel()
789            datamodel[self.fields[0]] = value
790        return not err
791
792InitializeClass(StudentIdWidget)
793
794widgetRegistry.register(StudentIdWidget)
795###)
796
797class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
798    """ WAeUPMultilineResults Widget"""
799    meta_type = "WAeUp Multiline Results Widget"
800    _properties = CPSWidget._properties + (
801        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
802         'label': 'Nr of Lines'},
803         )
804    nr_of_lines = 5
805    def prepare(self, datastructure, **kw): ###(
806        """Prepare datastructure from datamodel."""
807        datamodel = datastructure.getDataModel()
808        #import pdb;pdb.set_trace()
809        widget_id = self.getWidgetId()
810        v = datamodel[self.fields[0]]
811        if type(v) is ListType and v:
812            nr_results = len(v)
813        else:
814            v = []
815            nr_results = 0
816        count = 1
817        for s,g in v:
818            wid = "%s%02d"% (widget_id,count)
819            datastructure[wid+'_s'] = s
820            datastructure[wid+'_g'] = g
821            count += 1
822        if nr_results < self.nr_of_lines:
823            for line in range(nr_results,self.nr_of_lines):
824                v.append(('',''))
825                wid = "%s%02d"% (widget_id,line)
826                datastructure[wid+'_s'] = ''
827                datastructure[wid+'_g'] = ''
828        datastructure[widget_id] = v
829        datastructure[widget_id+'_s'] = ''
830        datastructure[widget_id+'_g'] = ''
831    ###)
832
833    def validate(self, datastructure, **kw): ###(
834        """Validate datastructure and update datamodel."""
835        #import pdb;pdb.set_trace()
836        widget_id = self.getWidgetId()
837        err = 0
838        lines = []
839        for line in range(1,30):
840            wid = "%s%02d"% (widget_id,line)
841            if not datastructure.has_key(wid+'_s'):
842                break
843            lines.append((datastructure[wid+'_s'].strip(),
844                         datastructure[wid+'_g'].strip()))
845
846        s = datastructure[widget_id+'_s'].strip()
847        g = datastructure[widget_id+'_g'].strip()
848        if s and g:
849            lines.append((s,g))
850        active = []
851        for s,g in lines:
852            if g != "":
853                active.append((s,g))
854        if err:
855            datastructure.setError(widget_id, err)
856        else:
857            datamodel = datastructure.getDataModel()
858            datamodel[self.fields[0]] = active
859        return not err
860    ###)
861
862    def render(self, mode, datastructure, **kw): ###(
863        """Render in mode from datastructure."""
864        render_method = 'widget_waeup_multiline_result_render'
865        meth = getattr(self, render_method, None)
866        if meth is None:
867            raise RuntimeError("Unknown Render Method %s for widget type %s"
868                               % (render_method, self.getId()))
869        #import pdb;pdb.set_trace()
870        datamodel = datastructure.getDataModel()
871        widget_id = self.getWidgetId()
872        lines = datamodel[self.fields[0]]
873        if len(lines) < self.nr_of_lines:
874            for line in range(len(lines),self.nr_of_lines + 1):
875                lines.append(('',''))
876        datastructure[widget_id] = lines
877        datastructure[widget_id+'_s'] = ''
878        datastructure[widget_id+'_g'] = ''
879##        count = 1
880##        for s,g in v:
881##            wid = "%s%02d"% (widget_id,count)
882##            count += 1
883        return meth(mode=mode,
884                    datastructure=datastructure,
885                    )
886    ###)
887
888
889InitializeClass(WAeUPMultilineResultsWidget)
890widgetRegistry.register(WAeUPMultilineResultsWidget)
891###)
892
893class WAeUPResultsWidget(CPSStringWidget): ###(
894    """ WAeUPResults Widget"""
895    meta_type = "WAeUp Results Widget"
896
897    def prepare(self, datastructure, **kw): ###(
898        """Prepare datastructure from datamodel."""
899        datamodel = datastructure.getDataModel()
900        v = datamodel[self.fields[0]]
901        #import pdb;pdb.set_trace()
902        widget_id = self.getWidgetId()
903        datastructure[widget_id] = v
904        datastructure[widget_id+'_s'] = ''
905        datastructure[widget_id+'_g'] = ''
906    ###)
907
908    def validate(self, datastructure, **kw): ###(
909        """Validate datastructure and update datamodel."""
910        #import pdb;pdb.set_trace()
911        widget_id = self.getWidgetId()
912        v = datastructure[widget_id]
913        err = 0
914        s = datastructure[widget_id+'_s'].strip()
915        g = datastructure[widget_id+'_g'].strip()
916        while 1:
917            if not s and g:
918                err = "No subject grade for subject"
919                break
920            i = 0
921            done = False
922            for sv,gv in v:
923                if sv == s:
924                    done = True
925                    if not g:
926                        v.pop(i)
927                        break
928                    v[i] = (s,g)
929                    break
930                i += 1
931            if done:
932                break
933            if s and g:
934                v.append((s,g))
935            break
936        if err:
937            datastructure.setError(widget_id, err)
938        else:
939            datamodel = datastructure.getDataModel()
940            datamodel[self.fields[0]] = v
941            datastructure[widget_id+'_s'] = s
942            datastructure[widget_id+'_g'] = g
943        return not err
944    ###)
945
946    def render(self, mode, datastructure, **kw): ###(
947        """Render in mode from datastructure."""
948        render_method = 'widget_waeup_result_render'
949        meth = getattr(self, render_method, None)
950        if meth is None:
951            raise RuntimeError("Unknown Render Method %s for widget type %s"
952                               % (render_method, self.getId()))
953        #import pdb;pdb.set_trace()
954        datamodel = datastructure.getDataModel()
955        widget_id = self.getWidgetId()
956        datastructure[widget_id+'_s'] = ''
957        datastructure[widget_id+'_g'] = ''
958        return meth(mode=mode,
959                    datastructure=datastructure,
960                    )
961    ###)
962
963
964InitializeClass(WAeUPResultsWidget)
965widgetRegistry.register(WAeUPResultsWidget)
966###)
967
968class ScratchCardPin: ###(
969    """the ScratchCardPin"""
970    def __init__(self,prefix,batch_no,number):
971        if not batch_no and not number:
972            s = prefix
973            if len(s) > 3:
974                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
975            else:
976                prefix,batch_no,number = s,'',''
977        self.p = prefix
978        self.b = batch_no
979        self.n = number
980
981    def __str__(self):
982        return "%s-%s-%s" % (self.p,self.b,self.n)
983
984    def __repr__(self):
985        return "%s%s%s" % (self.p,self.b,self.n)
986###)
987
988class ScratchcardPinWidget(CPSStringWidget): ###(
989    """ ScratchcardPin Widget"""
990    meta_type = "Scratchcard Pin Widget"
991    _properties = CPSWidget._properties + (
992        {'id': 'prefix', 'type': 'string', 'mode': 'w',
993         'label': 'Prefix'},
994         {'id': 'reference', 'type': 'string', 'mode': 'w',
995         'label': 'Reference Field'},
996        )
997    prefix = ''
998    reference = ''
999    def prepare(self, datastructure, **kw): ###(
1000        """Prepare datastructure from datamodel."""
1001        datamodel = datastructure.getDataModel()
1002        v = datamodel[self.fields[0]]
1003        widget_id = self.getWidgetId()
1004        #import pdb;pdb.set_trace()
1005        if v and type(v) is StringType:
1006            try:
1007                p,b,n = v.split('-')
1008                v = ScratchCardPin(p,b,n)
1009            except ValueError:
1010                v = ScratchCardPin(v,'','')
1011        if v:
1012            p = '%s' % v.p
1013            b = '%s' % v.b
1014            n = '%s' % v.n
1015        else:
1016            p = self.prefix
1017            if p.startswith('@'):
1018                p = getattr(self,self.prefix[1:])()
1019            b = n = ''
1020            v = ScratchCardPin(p,b,n)
1021        datastructure[widget_id] = v
1022        datastructure[widget_id+'_p'] = p
1023        datastructure[widget_id+'_b'] = b
1024        datastructure[widget_id+'_n'] = n
1025    ###)
1026
1027    def validate(self, datastructure, **kw): ###(
1028        """Validate datastructure and update datamodel."""
1029        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1030        widget_id = self.getWidgetId()
1031        v = datastructure[widget_id]
1032        #import pdb;pdb.set_trace()
1033        err = 0
1034        prefix= self.prefix
1035        if prefix.startswith('@'):
1036            prefix= getattr(self,self.prefix[1:])()
1037        b = datastructure[widget_id+'_b'].strip()
1038        n = datastructure[widget_id+'_n'].strip()
1039        pins = self.portal_pins
1040        pin = "%(prefix)s%(b)s%(n)s" % vars()
1041        pin_str = "%(prefix)s-%(b)-s%(n)s" % vars()
1042        do = 1
1043        s_id = str(self.portal_membership.getAuthenticatedMember())
1044        #import pdb;pdb.set_trace()
1045        if self.isStaff():
1046            do = 0
1047            err ='You are not a Student. PIN neither checked nor used.'
1048            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1049        elif len(b) > 1 and b.find('-') > -1:
1050            do = 0
1051            err = 'PIN must not contain "-"'
1052            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1053        elif n.find('-') > -1:
1054            do = 0
1055            err = 'PIN must not contain "-"'
1056            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1057        elif len(n) != 10:
1058            do = 0
1059            err = 'Invalid PIN length'
1060            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1061        elif self.reference == "":
1062            ref = s_id
1063        else:
1064            ref = datastructure[self.reference]
1065            if datastructure.errors:
1066                do = 0
1067                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1068                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1069        while do:
1070            ok = pins.searchAndSetRecord(pin,ref,prefix)
1071            if ok < -2 or ok > 2:
1072                err = 'Unknown error, please report!'
1073                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1074                break
1075            elif ok == -2:
1076                err = 'Service already is activated but with a different PIN.'
1077                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1078                break
1079            elif ok == -1:
1080                err = 'Invalid PIN'
1081                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1082                break
1083            if ok == 0:
1084                err = 'PIN already used'
1085                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1086                break
1087            if ok >= 1:
1088                #import pdb;pdb.set_trace()
1089                if self.isStudent():
1090                    if self.reference == "jamb_reg_no":
1091                        err = "You are already logged in."
1092                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1093                        break
1094                    if ok == 1:
1095                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1096                    else:
1097                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1098                    break
1099                else:
1100                    student = getStudentByRegNo(self,ref)
1101                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1102                if student is None:
1103                    err = "Student not found"
1104                    s_logger.info('%s not found in admission list' % (ref))
1105                    break
1106                s_id = student.getId()
1107                if ok == 2:
1108                    if self.reference == "jamb_reg_no":
1109                        if hasattr(self.portal_directories.students,s_id):
1110                            err = "Please login with your Student Id %s and 10-digit PIN." % s_id
1111                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1112                            break
1113                        else:
1114                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1115                    else:
1116                        err = "Unknown error"
1117                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1118                        break
1119                try:
1120                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1121                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1122                except:
1123                    err = "Please login with your Student Id %s and 10-digit PIN." % s_id
1124                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1125                    break
1126            break
1127        if err:
1128            datastructure.setError(widget_id, err)
1129        else:
1130            datamodel = datastructure.getDataModel()
1131            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1132            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1133            datastructure[widget_id+'_p'] = prefix
1134            datastructure[widget_id+'_b'] = b
1135            datastructure[widget_id+'_n'] = n
1136            datastructure['s_id'] = s_id
1137        return not err
1138
1139###)
1140
1141    def render(self, mode, datastructure, **kw): ###(
1142        """Render in mode from datastructure."""
1143        render_method = 'widget_scratch_card_pin_render'
1144        meth = getattr(self, render_method, None)
1145        if meth is None:
1146            raise RuntimeError("Unknown Render Method %s for widget type %s"
1147                               % (render_method, self.getId()))
1148
1149        # XXX AT: datastructure has to be set again here, in case we're in edit
1150        # or create mode, because a default value has to be provided.
1151        #import pdb;pdb.set_trace()
1152        datamodel = datastructure.getDataModel()
1153        v = datamodel[self.fields[0]]
1154        if v and type(v) is StringType:
1155            try:
1156                p,b,n = v.split('-')
1157                v = ScratchCardPin(p,b,n)
1158            except ValueError:
1159                v = ScratchCardPin(self.prefix,'1',v)
1160                pass
1161        if v:
1162            prefix= '%s' % v.p
1163            b = '%s' % v.b
1164            n = '%s' % v.n
1165        else:
1166            prefix= self.prefix
1167            if prefix.startswith('@'):
1168                prefix= getattr(self,self.prefix[1:])()
1169            b = n = ''
1170            v = ScratchCardPin(prefix,b,n)
1171        widget_id = self.getWidgetId()
1172        datastructure[widget_id] = v
1173        datastructure[widget_id+'_p'] = prefix
1174        datastructure[widget_id+'_b'] = b
1175        datastructure[widget_id+'_n'] = n
1176        return meth(mode=mode,
1177                    datastructure=datastructure,
1178                    )
1179    ###)
1180
1181
1182InitializeClass(ScratchcardPinWidget)
1183widgetRegistry.register(ScratchcardPinWidget)
1184
1185
1186###)
1187
1188class WAeUPImageWidget(CPSImageWidget): ###(
1189    """Photo widget."""
1190    meta_type = 'WAeUP Image Widget'
1191
1192    def render(self, mode, datastructure, **kw):
1193        render_method = 'widget_waeup_image_render'
1194        meth = getattr(self, render_method, None)
1195        if meth is None:
1196            raise RuntimeError("Unknown Render Method %s for widget type %s"
1197                               % (render_method, self.getId()))
1198        img_info = self.getImageInfo(datastructure)
1199        return meth(mode=mode, datastructure=datastructure, **img_info)
1200
1201InitializeClass(WAeUPImageWidget)
1202
1203widgetRegistry.register(WAeUPImageWidget)
1204###)
1205
1206
1207###########
1208
Note: See TracBrowser for help on using the repository browser.