source: WAeUP_SRP/trunk/Widgets.py @ 2099

Last change on this file since 2099 was 2099, checked in by Henrik Bettermann, 17 years ago

some corrections (see email 'Befund')

  • Property svn:keywords set to Id
File size: 62.2 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 2099 2007-08-15 19:39:58Z henrik $
3from cgi import escape
4from types import *
5from Globals import InitializeClass
6from ZPublisher.HTTPRequest import FileUpload
7##from Products.CPSSchemas.Widget import CPSWidgetType
8from Products.CMFCore.utils import getToolByName
9from Products.CPSSchemas.BasicWidgets import CPSBooleanWidget, CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget
10from Products.CPSSchemas.BasicWidgets import CPSFileWidget
11from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget
12from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget
13from Products.CPSSchemas.Widget import widgetRegistry
14from Products.CPSUtil.file import PersistableFileUpload
15from Products.CPSUtil.id import generateFileName
16##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry
17from DateTime.DateTime import DateTime
18from AccessControl import getSecurityManager
19from Products.WAeUP_SRP.Students import getStudentByRegNo
20from Products.WAeUP_SRP.Academics import makeCertificateCode
21#from Products.ExtFile.ExtFile import ExtFile
22from re import compile
23import logging
24import operator
25
26#from zLOG import LOG, DEBUG
27
28class CPSSelectWidgetForRecord(CPSSelectWidget): ###(
29    """Select widget. with record names"""
30    meta_type = 'Select Widget for Records'
31
32    field_types = ('CPS String Field',)
33    field_inits = ({'is_searchabletext': 1,},)
34
35    _properties = CPSSelectWidget._properties + (
36        {'id': 'record_id', 'type': 'string', 'mode': 'w',
37         'label': 'Record Id', 'is_required' : 1},
38        )
39
40    def render(self, mode, datastructure, **kw):
41        """Render in mode from datastructure."""
42        value = datastructure[self.getWidgetId()]
43        vocabulary = self._getVocabulary(datastructure)
44        portal = getToolByName(self, 'portal_url').getPortalObject()
45        cpsmcat = portal.translation_service
46        if mode == 'view':
47            if self.translated:
48                return escape(cpsmcat(vocabulary.getMsgid(value, value)).encode('ISO-8859-15', 'ignore'))
49            else:
50                return escape(vocabulary.get(value, value))
51        elif mode == 'edit':
52            html_widget_id = self.getHtmlWidgetId()
53            res = renderHtmlTag('select',
54                                name='%s.%s:records' % (self.record_id,html_widget_id),
55                                id=html_widget_id)
56            in_selection = 0
57            for k, v in vocabulary.items():
58                if self.translated:
59                    kw = {'value': k,
60                          'contents': cpsmcat(vocabulary.getMsgid(k, k)).encode('ISO-8859-15', 'ignore')
61                          }
62                else:
63                    kw = {'value': k, 'contents': v}
64                if value == k:
65                    kw['selected'] = 'selected'
66                    in_selection = 1
67                res += renderHtmlTag('option', **kw)
68            if value and not in_selection:
69                kw = {'value': value, 'contents': 'invalid: '+ str(value),
70                      'selected': 'selected'}
71                res += renderHtmlTag('option', **kw)
72            res += '</select>'
73            return res
74        raise RuntimeError('unknown mode %s' % mode)
75
76InitializeClass(CPSSelectWidgetForRecord)
77
78widgetRegistry.register(CPSSelectWidgetForRecord)
79
80###)
81
82class CPSStringWidgetForRecord(CPSStringWidget): ###(
83    """String widget."""
84    meta_type = 'String Widget For Record'
85
86    field_types = ('CPS String Field',)
87    field_inits = ({'is_searchabletext': 1,},)
88    _properties = CPSStringWidget._properties + (
89        {'id': 'record_id', 'type': 'string', 'mode': 'w',
90         'label': 'Record Id', 'is_required' : 1},
91        )
92
93    def render(self, mode, datastructure, **kw):
94        """Render in mode from datastructure."""
95        value = datastructure[self.getWidgetId()]
96        if mode == 'view':
97            return escape(value)
98        elif mode == 'edit':
99            # XXX TODO should use an other name than kw !
100            # XXX change this everywhere
101            html_widget_id = self.getHtmlWidgetId()
102            kw = {'type': 'text',
103                  'id'  : html_widget_id,
104                  'name': '%s.%s:records' % (self.record_id,html_widget_id),
105                  'value': escape(value),
106                  'size': self.display_width,
107                  }
108            if self.size_max:
109                kw['maxlength'] = self.size_max
110            return renderHtmlTag('input', **kw)
111        raise RuntimeError('unknown mode %s' % mode)
112
113InitializeClass(CPSStringWidgetForRecord)
114
115widgetRegistry.register(CPSStringWidgetForRecord)
116
117###)
118
119class CertificateCourseIdWidget(CPSStringWidget): ###(
120    """ CertificateCourseId Widget"""
121    meta_type = "CertificateCourseId Widget"
122
123    def validate(self, datastructure, **kw):
124        """Validate datastructure and update datamodel."""
125
126        valid = CPSStringWidget.validate(self, datastructure, **kw)
127        if not valid:
128            return 0
129        else:
130            widget_id = self.getWidgetId()
131            value = datastructure[widget_id].upper()
132            err = 0
133            c_ids = [c.id for c in self.portal_catalog({'meta_type': "Course"})]
134            if hasattr(self.aq_parent,value):
135                err = 'Course already exists'
136            elif value not in c_ids:
137                err = 'Course does not exist'
138            if err:
139                datastructure.setError(widget_id, err)
140            else:
141                datamodel = datastructure.getDataModel()
142                datamodel[self.fields[0]] = value
143
144            return not err
145
146InitializeClass(CertificateCourseIdWidget)
147
148widgetRegistry.register(CertificateCourseIdWidget)
149###)
150
151class CourseIdWidget(CPSStringWidget): ###(
152    """ CourseId Widget"""
153    meta_type = "CourseId Widget"
154
155    def validate(self, datastructure, **kw):
156        """Validate datastructure and update datamodel."""
157
158        valid = CPSStringWidget.validate(self, datastructure, **kw)
159        if not valid:
160            return 0
161        else:
162            widget_id = self.getWidgetId()
163            value = datastructure[widget_id].upper()
164            err = 0
165            res = self.portal_catalog(meta_type= "Course",id = value)
166            if len(res) > 0:
167                err = 'Course already exists'
168            if err:
169                datastructure.setError(widget_id, err)
170            else:
171                datamodel = datastructure.getDataModel()
172                datamodel[self.fields[0]] = value
173
174            return not err
175
176InitializeClass(CourseIdWidget)
177
178widgetRegistry.register(CourseIdWidget)
179
180
181###)
182
183class WAeUPStudyModeWidget(CPSSelectWidget): ###(
184    """WAeUP StudyMode Widget."""
185    meta_type = 'WAeUP StudyMode Widget'
186    vocabulary = 'entry_modes'
187
188    def _getStudyModes(self):
189        voc = getattr(self.portal_vocabularies,self.vocabulary)
190        d = {}
191        for k,v in voc.items():
192            d[k] = v
193        return d
194
195    def validate(self, datastructure, **kw):
196        """Validate datastructure and update datamodel."""
197        widget_id = self.getWidgetId()
198        value = datastructure[widget_id]
199        try:
200            v = str(value)
201        except ValueError:
202            datastructure.setError(widget_id, "'%s' not a valid session key" % value)
203            return 0
204        studymodes = self._getStudyModes()
205        if not value:
206            v = value = 'ume_ft'
207        #import pdb;pdb.set_trace()
208        if not studymodes.has_key(value):
209            datastructure.setError(widget_id, "'%s' not a valid session key" % v)
210            return 0
211        if self.is_required and not len(v):
212            datastructure.setError(widget_id, "session key required")
213            return 0
214
215        datamodel = datastructure.getDataModel()
216        datamodel[self.fields[0]] = v
217        return 1
218
219    def render(self, mode, datastructure, **kw):
220        """Render in mode from datastructure."""
221        value = datastructure[self.getWidgetId()]
222        studymodes = self._getStudyModes()
223        if mode == 'view':
224            return escape(studymodes.get(value, value))
225        elif mode == 'edit':
226            html_widget_id = self.getHtmlWidgetId()
227            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
228            in_selection = 0
229            vocabulary_items = studymodes.items()
230            if self.sorted:
231                vocabulary_items.sort(key=operator.itemgetter(1))
232            for k, v in vocabulary_items:
233                kw = {'value': k, 'contents': v}
234                if value == k:
235                    kw['selected'] = 'selected'
236                    in_selection = 1
237                res += renderHtmlTag('option', **kw)
238            if value and not in_selection:
239                kw = {'value': value, 'contents': 'invalid: '+ str(value),
240                      'selected': 'selected'}
241                res += renderHtmlTag('option', **kw)
242            res += '</select>'
243            return res
244        raise RuntimeError('unknown mode %s' % mode)
245
246InitializeClass(WAeUPStudyModeWidget)
247
248widgetRegistry.register(WAeUPStudyModeWidget)
249
250###)
251
252class WAeUPSessionWidget(CPSSelectWidget): ###(
253    """WAeUP Session Widget."""
254    meta_type = 'WAeUP Session Widget'
255
256    def _getSessions(self):
257        current_year = DateTime().year()
258        d = {'-1': 'N/A'}
259        for y in range(current_year - 9,current_year + 1):
260            d['%s' % str(y)[-2:]] = '%4d/%4d' % (y,y+1)
261        return d
262
263    def validate(self, datastructure, **kw):
264        """Validate datastructure and update datamodel."""
265        widget_id = self.getWidgetId()
266        value = datastructure[widget_id]
267        try:
268            v = str(value)
269        except ValueError:
270            datastructure.setError(widget_id, "'%s' not a valid session key" % value)
271            return 0
272
273        if len(v) == 1:
274            v = value = '0%c' % v
275        elif not value:
276            v = value = self.getSessionId()[-2:]
277        #import pdb;pdb.set_trace()
278        sessions = self._getSessions()
279        if not sessions.has_key(value):
280            datastructure.setError(widget_id, "'%s' not a valid session key" % v)
281            return 0
282        if self.is_required and not len(v):
283            datastructure.setError(widget_id, "session key required")
284            return 0
285
286        datamodel = datastructure.getDataModel()
287        datamodel[self.fields[0]] = v
288        return 1
289
290    def render(self, mode, datastructure, **kw):
291        """Render in mode from datastructure."""
292        value = datastructure[self.getWidgetId()]
293        sessions = self._getSessions()
294        if mode == 'view':
295            return escape(sessions.get(value, value))
296        elif mode == 'edit':
297            html_widget_id = self.getHtmlWidgetId()
298            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
299            in_selection = 0
300            vocabulary_items = sessions.items()
301            if self.sorted:
302                vocabulary_items.sort(key=operator.itemgetter(0))
303            for k, v in vocabulary_items:
304                kw = {'value': k, 'contents': v}
305                if value == k:
306                    kw['selected'] = 'selected'
307                    in_selection = 1
308                res += renderHtmlTag('option', **kw)
309            if value and not in_selection:
310                kw = {'value': value, 'contents': 'invalid: '+ str(value),
311                      'selected': 'selected'}
312                res += renderHtmlTag('option', **kw)
313            res += '</select>'
314            return res
315        raise RuntimeError('unknown mode %s' % mode)
316
317InitializeClass(WAeUPSessionWidget)
318
319widgetRegistry.register(WAeUPSessionWidget)
320
321###)
322
323class WAeUPLevelWidget(CPSSelectWidget): ###(
324    """WAeUP Level Widget."""
325    meta_type = 'WAeUP Level Widget'
326
327    def _getLevels(self):
328        d = {'000':'N/A'}
329        for y in range(100,800,100):
330            d['%s' % str(y)] = 'Year %1d (%3d Level)' % (y/100,y)
331        return d
332
333    def validate(self, datastructure, **kw):
334        """Validate datastructure and update datamodel."""
335        widget_id = self.getWidgetId()
336        value = datastructure[widget_id]
337        try:
338            v = str(value)
339        except ValueError:
340            datastructure.setError(widget_id, "'%s' not a valid level key" % value)
341            return 0
342
343        if not value:
344            v = value = '100'
345        #import pdb;pdb.set_trace()
346        levels = self._getLevels()
347        if not levels.has_key(value):
348            datastructure.setError(widget_id, "'%s' not a valid level" % v)
349            return 0
350        if self.is_required and not len(v):
351            datastructure.setError(widget_id, "level key required")
352            return 0
353
354        datamodel = datastructure.getDataModel()
355        datamodel[self.fields[0]] = v
356        return 1
357
358    def render(self, mode, datastructure, **kw):
359        """Render in mode from datastructure."""
360        value = datastructure[self.getWidgetId()]
361        levels = self._getLevels()
362        if mode == 'view':
363            return escape(levels.get(value, value))
364        elif mode == 'edit':
365            html_widget_id = self.getHtmlWidgetId()
366            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
367            in_selection = 0
368            vocabulary_items = levels.items()
369            if self.sorted:
370                vocabulary_items.sort(key=operator.itemgetter(0))
371            for k, v in vocabulary_items:
372                kw = {'value': k, 'contents': v}
373                if value == k:
374                    kw['selected'] = 'selected'
375                    in_selection = 1
376                res += renderHtmlTag('option', **kw)
377            if value and not in_selection:
378                kw = {'value': value, 'contents': 'invalid: '+ str(value),
379                      'selected': 'selected'}
380                res += renderHtmlTag('option', **kw)
381            res += '</select>'
382            return res
383        raise RuntimeError('unknown mode %s' % mode)
384
385InitializeClass(WAeUPLevelWidget)
386
387widgetRegistry.register(WAeUPLevelWidget)
388
389###)
390
391class WAeUPVerdictWidget(CPSSelectWidget): ###(
392    """WAeUP Verdict Widget."""
393    meta_type = 'WAeUP Verdict Widget'
394
395    # XXX make a menu for the vocabulary.
396    vocabulary = 'verdicts'
397
398    # Associating the widget label with an input area to improve the widget
399    # accessibility.
400    has_input_area = True
401
402    def _getVerdicts(self,datastructure):
403        voc = getattr(self.portal_vocabularies,self.vocabulary)
404        d = {}
405        for k,v in voc.items():
406            d[k] = v
407        return d
408
409    def validate(self, datastructure, **kw):
410        """Validate datastructure and update datamodel."""
411        widget_id = self.getWidgetId()
412        value = datastructure[widget_id]
413        try:
414            v = str(value)
415        except ValueError:
416            datastructure.setError(widget_id, "'%s' not a valid verdict key" % value)
417            return 0
418        #import pdb;pdb.set_trace()
419        verdicts = self._getVerdicts(datastructure)
420        if not value:
421            v = value = verdicts['N/A']
422        if not verdicts.has_key(value):
423            datastructure.setError(widget_id, "'%s' not a valid verdict key" % v)
424            return 0
425        if self.is_required and not len(v):
426            datastructure.setError(widget_id, "verdict required")
427            return 0
428
429        datamodel = datastructure.getDataModel()
430        datamodel[self.fields[0]] = v
431        return 1
432
433    def render(self, mode, datastructure, **kw):
434        """Render in mode from datastructure."""
435        value = datastructure[self.getWidgetId()]
436        verdicts = self._getVerdicts(datastructure)
437        if mode == 'view':
438            return escape(verdicts.get(value, value))
439        elif mode == 'edit':
440            html_widget_id = self.getHtmlWidgetId()
441            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
442            in_selection = 0
443            vocabulary_items = verdicts.items()
444            if self.sorted:
445                vocabulary_items.sort(key=operator.itemgetter(1))
446            for k, v in vocabulary_items:
447                kw = {'value': k, 'contents': v}
448                if value == k:
449                    kw['selected'] = 'selected'
450                    in_selection = 1
451                res += renderHtmlTag('option', **kw)
452            if value and not in_selection:
453                kw = {'value': value, 'contents': 'invalid: '+ str(value),
454                      'selected': 'selected'}
455                res += renderHtmlTag('option', **kw)
456            res += '</select>'
457            return res
458        raise RuntimeError('unknown mode %s' % mode)
459
460InitializeClass(WAeUPVerdictWidget)
461
462widgetRegistry.register(WAeUPVerdictWidget)
463
464###)
465
466class WAeUPLGAWidget(CPSSelectWidget): ###(
467    """WAeUP LGA Widget."""
468    meta_type = 'WAeUP LGA Widget'
469    _properties = CPSSelectWidget._properties + (
470        {'id': 'state_field', 'type': 'string', 'mode': 'w',
471         'label': 'Name of the state field'},
472         {'id': 'lga_field', 'type': 'string', 'mode': 'w',
473         'label': 'Name of the LGA Field (without state)'},
474         )
475    state_field = "state"
476    lga_field = "lga"
477
478    # XXX make a menu for the vocabulary.
479    vocabulary = 'local_gov_areas'
480
481    # Associating the widget label with an input area to improve the widget
482    # accessibility.
483    has_input_area = True
484
485    def _getLGAs(self):
486        voc = getattr(self.portal_vocabularies,self.vocabulary)
487        states = []
488        lgas  = []
489        d = {}
490        for k,v in voc.items():
491            parts = k.split('_')
492            state = parts[0]
493            lga = ' '.join(parts[1:])
494            if state not in states:
495                states.append(state)
496            lgas.append(lga)
497            d[k] = v
498        return (d,states,lgas)
499
500    def validate(self, datastructure, **kw):
501        """Validate datastructure and update datamodel."""
502        widget_id = self.getWidgetId()
503        value = datastructure[widget_id]
504        #import pdb;pdb.set_trace()
505        try:
506            v = str(value)
507        except ValueError:
508            datastructure.setError(widget_id, "'%s' not a valid lga key" % value)
509            return 0
510        v = v.lower()
511        combined,states,lgas = self._getLGAs()
512        one_field = False
513        if not self.state_field and not self.lga_field:
514            one_field = True
515            if v not in combined.keys():
516                datastructure.setError(widget_id, "'%s' not a valid lga key" % v)
517                return 0
518        else:
519            if widget_id == self.state_field:
520                if v not in states:
521                    datastructure.setError(widget_id, "'%s' not a valid state" % v)
522                    return 0
523            elif widget_id == self.lga_field:
524                if v not in lgas:
525                    datastructure.setError(widget_id, "'%s' not a valid lga" % v)
526                    return 0
527                if datastructure[self.state_field]:
528                    v = datastructure[self.state_field] + '_' + v
529
530        if self.is_required and not len(v):
531            datastructure.setError(widget_id, "lga required")
532            return 0
533
534        datamodel = datastructure.getDataModel()
535        if one_field:
536            datamodel[self.fields[0]] = v
537        else:
538            state = datastructure[self.state_field].lower()
539            lga = "_".join(datastructure[self.lga_field].lower().split())
540            datamodel[self.fields[0]] =   state + "_" + lga
541        return 1
542
543    def render(self, mode, datastructure, **kw):
544        """Render in mode from datastructure."""
545        w_id = self
546        value = datastructure[self.getWidgetId()]
547        lgas,x,y = self._getLGAs(datastructure)
548        if mode == 'view':
549            return escape(lgas.get(value, value))
550        elif mode == 'edit':
551            html_widget_id = self.getHtmlWidgetId()
552            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
553            in_selection = 0
554            vocabulary_items = lgas.items()
555            # if self.sorted:
556            #     vocabulary_items.sort(key=operator.itemgetter(1))
557            for k, v in vocabulary_items:
558                kw = {'value': k, 'contents': v}
559                if value == k:
560                    kw['selected'] = 'selected'
561                    in_selection = 1
562                res += renderHtmlTag('option', **kw)
563            if value and not in_selection:
564                kw = {'value': value, 'contents': 'invalid: '+ str(value),
565                      'selected': 'selected'}
566                res += renderHtmlTag('option', **kw)
567            res += '</select>'
568            return res
569        raise RuntimeError('unknown mode %s' % mode)
570
571InitializeClass(WAeUPLGAWidget)
572
573widgetRegistry.register(WAeUPLGAWidget)
574
575###)
576
577class WAeUPReservedRoomsWidget(CPSStringWidget): ###(
578    """ WAeUPReservedRooms Widget"""
579    meta_type = "WAeUPReservedRooms Widget"
580
581    def validate(self, datastructure, **kw):
582        """Validate datastructure and update datamodel."""
583        import re
584        valid = CPSStringWidget.validate(self, datastructure, **kw)
585        if not valid:
586            return 0
587        else:
588            widget_id = self.getWidgetId()
589            value = datastructure[widget_id]
590            err = 0
591            try:
592                reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',value)
593                                     if r]
594            except (ValueError,IndexError),msg:
595                err = str(msg)
596            if err:
597                datastructure.setError(widget_id, err)
598            else:
599                datamodel = datastructure.getDataModel()
600                datamodel[self.fields[0]] = value
601            return not err
602
603InitializeClass(WAeUPReservedRoomsWidget)
604
605widgetRegistry.register(WAeUPReservedRoomsWidget)
606###)
607
608class WAeUPIdWidget(CPSStringWidget): ###(
609    """ WAeUPId Widget"""
610    meta_type = "WAeUPId Widget"
611
612    def validate(self, datastructure, **kw):
613        """Validate datastructure and update datamodel."""
614
615        valid = CPSStringWidget.validate(self, datastructure, **kw)
616        id_pat_str = r"\S"
617        inv_id_pat = compile(r"^%s$" % id_pat_str)
618        if not valid:
619            return 0
620        else:
621            portal_type_query = {'query':['Faculty',
622                                          'Department',
623                                          'Course',
624                                          'Certificate',
625                                          'CertificateCourse',]}
626            widget_id = self.getWidgetId()
627            value = datastructure[widget_id]  #.upper()  is not necessary here because it's also done in waeup_document_create_do
628            err = 0
629            mapping = {}
630            if len(value.split()) > 1:
631                err = 'Invalid Id, Id contains space(s).'
632            elif self.portal_catalog(portal_type=portal_type_query,id=value):
633                brain = self.portal_catalog(portal_type=portal_type_query,id=value)[0]
634                err = 'An ${portal_type} object with the Id ${id} already exists at ${path}.'
635                mapping = {'portal_type': brain.portal_type,
636                           'id': value,
637                           'path': brain.getPath(),
638                           }
639            if err:
640                datastructure.setError(widget_id, err, mapping)
641            else:
642                datamodel = datastructure.getDataModel()
643                datamodel[self.fields[0]] = value
644
645            return not err
646
647InitializeClass(WAeUPIdWidget)
648
649widgetRegistry.register(WAeUPIdWidget)
650
651
652###)
653
654class StudyCourseWidget(CPSStringWidget): ###(
655    """ StudyCourse Widget"""
656    meta_type = "StudyCourse Widget"
657
658    def validate(self, datastructure, **kw):
659        """Validate datastructure and update datamodel."""
660        #from Products.zdb import set_trace
661        #set_trace()
662##        valid = CPSStringWidget.validate(self, datastructure, **kw)
663##        if not valid:
664##            return 0
665        widget_id = self.getWidgetId()
666        value = makeCertificateCode(datastructure[widget_id]).upper()
667        id_pat_str = r"\S"
668        inv_id_pat = compile(r"^%s$" % id_pat_str)
669        err = 0
670        if len(value.split()) > 1:
671            err = 'Invalid Id, Id contains space(s).'
672        elif not self.portal_catalog(portal_type='Certificate',id=value):
673            err = 'No such certificate'
674        if err:
675            datastructure.setError(widget_id, err)
676        else:
677            datamodel = datastructure.getDataModel()
678            datamodel[self.fields[0]] = value
679        return not err
680
681InitializeClass(StudyCourseWidget)
682
683widgetRegistry.register(StudyCourseWidget)
684###)
685
686class JambRegNoWidget(CPSStringWidget): ###(
687    """ JambRegNo Widget"""
688    meta_type = "JambRegNo Widget"
689    _properties = CPSStringWidget._properties + (
690        {'id': 'catalog', 'type': 'string', 'mode': 'w',
691         'label': 'Catalog to search'},
692         {'id': 'reference', 'type': 'string', 'mode': 'w',
693         'label': 'Reference Field'},
694         )
695    catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
696    reference = ""
697    digits = 8
698    digits_str = "N"*digits
699    letters = 2
700    letters_str = "L"*letters
701    def validate(self, datastructure, **kw):
702        """Validate datastructure and update datamodel."""
703        valid = CPSStringWidget.validate(self, datastructure, **kw)
704        jamb_nr_catalog = getattr(self,self.catalog)
705        widget_id = self.getWidgetId()
706        value = datastructure[widget_id].upper()
707        err = 0
708        #import pdb;pdb.set_trace()
709        if kw.has_key('mode'):
710            mode = kw['mode']
711        else:
712            mode = "edit"
713        if not valid:
714            err = 'Invalid number'
715        elif self.reference == '':
716            #s = getStudentByRegNo(self,value)
717            pume = jamb_nr_catalog(jamb_reg_no = value)
718            if len(pume) < 1:
719                err = 'No student record with this registration number.'
720            else:
721                datastructure['pume'] = pume[0]
722        elif mode == 'add':
723            pass
724        elif self.reference != '' and self.catalog == "applicants_catalog":
725            res = jamb_nr_catalog.searchResults({"%s" % self.reference: value})
726            if len(res) != 1:
727                err = 'No record with this registration number.'
728            else:
729                datastructure['record'] = res[0]
730        else:
731            record = datastructure[self.reference]
732            #jamb_reg_no = getattr(record,widget_id)
733            jamb_reg_no = record.Entryregno
734            if jamb_reg_no != value:
735                err = 'Registration number does not match.'
736        if err:
737            datastructure.setError(widget_id, err)
738        else:
739            datamodel = datastructure.getDataModel()
740            datamodel[self.fields[0]] = value
741        return not err
742
743InitializeClass(JambRegNoWidget)
744
745widgetRegistry.register(JambRegNoWidget)
746###)
747
748class SecretWidget(CPSStringWidget): ###(
749    """ Secret Widget"""
750    meta_type = "Secret Widget"
751    _properties = CPSStringWidget._properties + (
752        {'id': 'reference', 'type': 'string', 'mode': 'w',
753         'label': 'Reference Record'},
754         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
755         'label': 'Fields to check'},
756         )
757    reference = "student"
758    matric_no_catalog = 'returning_import'
759    check_fields = ("Firstname", "Middlename","Lastname")
760    def validate(self, datastructure, **kw):
761        """Validate datastructure and update datamodel."""
762        logger = logging.getLogger('Widgets.SecretWidget.validate')
763        valid = CPSStringWidget.validate(self, datastructure, **kw)
764        widget_id = self.getWidgetId()
765        value = datastructure[widget_id].upper()
766        err = 0
767        record = datastructure.get(self.reference,None)
768        #import pdb;pdb.set_trace()
769        if not valid or len(value) < 2:
770            err = 'Invalid string'
771        elif not record or datastructure.errors:
772            err = 0
773        else:
774            found = False
775            cvs = []
776            for field in self.check_fields:
777                cv = getattr(record,field).upper()
778                if len(cv.split()) > 1:
779                    for splited in cv.split():
780                        cvs.append(splited.strip())
781                else:
782                    cvs.append(cv)
783            for cv in cvs:
784                if cv  == value.upper():
785                    found = True
786                    break
787            matric_no = record.matric_no
788            name = " ".join(cvs)
789            if not found:
790                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
791                err = 'No name does match.'
792            else:
793                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
794        if err:
795            datastructure.setError(widget_id, err)
796        else:
797            datamodel = datastructure.getDataModel()
798            datamodel[self.fields[0]] = value
799        return not err
800
801InitializeClass(SecretWidget)
802
803widgetRegistry.register(SecretWidget)
804###)
805
806class WAeUPSexWidget(CPSBooleanWidget): ###(
807    """WAeUP sex widget."""
808    meta_type = 'WAeUP Sex Widget'
809
810    def validate(self, datastructure, **kw):
811        """Validate datastructure and update datamodel."""
812        value = datastructure[self.getWidgetId()]
813
814        if self.render_format not in self.render_formats:
815            self.render_format = 'select'
816
817        female = value in ('F','f','Female','female',"True",True)
818        male = value in ('M','m','Male','male','False',False)
819        if not female and not male:
820            datastructure.setError(self.getWidgetId(),
821                                   "invalid sex %s" % value)
822            return 0
823        elif female:
824            v = True
825        else:
826            v = False
827        datamodel = datastructure.getDataModel()
828        datamodel[self.fields[0]] = v
829        return 1
830
831InitializeClass(WAeUPSexWidget)
832
833widgetRegistry.register(WAeUPSexWidget)
834
835###)
836
837class MatricNoWidget(CPSStringWidget): ###(
838    """ MatricNo Widget"""
839    meta_type = "MatricNo Widget"
840
841    _properties = CPSStringWidget._properties + (
842        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
843         'label': 'Catalog to search for MatricNo'},
844        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
845         'label': 'Results Catalog'},
846         )
847    matric_no_catalog = "" #the catalog to search for matric_no
848    results_catalog = "results_import" #results catalog
849
850    def validate(self, datastructure, **kw):
851        """Validate datastructure and update datamodel."""
852        #import pdb;pdb.set_trace()
853        valid = CPSStringWidget.validate(self, datastructure, **kw)
854        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
855        returning = getattr(self,self.matric_no_catalog)
856        results = getattr(self,self.results_catalog,None)
857        err = 0
858        widget_id = self.getWidgetId()
859        value = datastructure[widget_id]
860        if not valid or not value:
861            err = 'Invalid string'
862            logger.info('Invalid matric_no string %s' % value)
863        else:
864            value = value.upper()
865            datastructure['student'] = None
866            while not err:
867                res = returning(matric_no = value)
868                if len(res) < 1:
869                    logger.info('matric_no %s not found' % value)
870                    err = 'No student with this matriculation number.'
871                    break
872                datastructure['student'] = res[0]
873                if results is not None:
874                    res = results(matric_no = value)
875                    if len(res) < 1:
876                        err = 'No results for this matriculation number'
877                        continue
878                    datastructure['results'] = res
879                break
880        if err:
881            datastructure.setError(widget_id, err)
882        else:
883            datamodel = datastructure.getDataModel()
884            datamodel[self.fields[0]] = value
885        return not err
886
887InitializeClass(MatricNoWidget)
888
889widgetRegistry.register(MatricNoWidget)
890###)
891
892class StudentIdWidget(CPSStringWidget): ###(
893    """ StudentId Widget"""
894    meta_type = "StudentId Widget"
895    def validate(self, datastructure, **kw):
896        """Validate datastructure and update datamodel."""
897        valid = CPSStringWidget.validate(self, datastructure, **kw)
898        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
899        #import pdb;pdb.set_trace()
900        s_cat = self.students_catalog
901        err = 0
902        widget_id = self.getWidgetId()
903        value = datastructure[widget_id]
904        if not valid or not value:
905            err = 'Invalid Id string'
906            logger.info('Invalid id string %s' % value)
907            datastructure['student'] = None
908        else:
909            value = value.upper()
910            res = s_cat(id = value)
911            if not res:
912                logger.info('Student id %s not found' % value)
913                err = 'No student with this Id'
914                datastructure['student'] = None
915            else:
916                datastructure['student'] = res[0]
917        if err:
918            datastructure.setError(widget_id, err)
919        else:
920            datamodel = datastructure.getDataModel()
921            datamodel[self.fields[0]] = value
922        return not err
923
924InitializeClass(StudentIdWidget)
925
926widgetRegistry.register(StudentIdWidget)
927###)
928
929class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
930    """ WAeUPMultilineResults Widget"""
931    meta_type = "WAeUp Multiline Results Widget"
932    _properties = CPSWidget._properties + (
933        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
934         'label': 'Nr of Lines'},
935         )
936    nr_of_lines = 5
937    def prepare(self, datastructure, **kw): ###(
938        """Prepare datastructure from datamodel."""
939        datamodel = datastructure.getDataModel()
940        #import pdb;pdb.set_trace()
941        widget_id = self.getWidgetId()
942        v = datamodel[self.fields[0]]
943        if type(v) is ListType and v:
944            nr_results = len(v)
945        else:
946            v = []
947            nr_results = 0
948        count = 1
949        for s,g in v:
950            wid = "%s%02d"% (widget_id,count)
951            datastructure[wid+'_s'] = s
952            datastructure[wid+'_g'] = g
953            count += 1
954        if nr_results < self.nr_of_lines:
955            for line in range(nr_results,self.nr_of_lines):
956                v.append(('',''))
957                wid = "%s%02d"% (widget_id,line)
958                datastructure[wid+'_s'] = ''
959                datastructure[wid+'_g'] = ''
960        datastructure[widget_id] = v
961        datastructure[widget_id+'_s'] = ''
962        datastructure[widget_id+'_g'] = ''
963    ###)
964
965    def validate(self, datastructure, **kw): ###(
966        """Validate datastructure and update datamodel."""
967        #import pdb;pdb.set_trace()
968        widget_id = self.getWidgetId()
969        err = 0
970        lines = []
971        for line in range(1,30):
972            wid = "%s%02d"% (widget_id,line)
973            if not datastructure.has_key(wid+'_s'):
974                break
975            lines.append((datastructure[wid+'_s'].strip(),
976                         datastructure[wid+'_g'].strip()))
977
978        s = datastructure[widget_id+'_s'].strip()
979        g = datastructure[widget_id+'_g'].strip()
980        if s and g:
981            lines.append((s,g))
982        active = []
983        for s,g in lines:
984            if g != "":
985                active.append((s,g))
986        if err:
987            datastructure.setError(widget_id, err)
988        else:
989            datamodel = datastructure.getDataModel()
990            datamodel[self.fields[0]] = active
991        return not err
992    ###)
993
994    def render(self, mode, datastructure, **kw): ###(
995        """Render in mode from datastructure."""
996        render_method = 'widget_waeup_multiline_result_render'
997        meth = getattr(self, render_method, None)
998        if meth is None:
999            raise RuntimeError("Unknown Render Method %s for widget type %s"
1000                               % (render_method, self.getId()))
1001        #import pdb;pdb.set_trace()
1002        datamodel = datastructure.getDataModel()
1003        widget_id = self.getWidgetId()
1004        lines = datamodel[self.fields[0]]
1005        if len(lines) < self.nr_of_lines:
1006            for line in range(len(lines),self.nr_of_lines + 1):
1007                lines.append(('',''))
1008        datastructure[widget_id] = lines
1009        datastructure[widget_id+'_s'] = ''
1010        datastructure[widget_id+'_g'] = ''
1011##        count = 1
1012##        for s,g in v:
1013##            wid = "%s%02d"% (widget_id,count)
1014##            count += 1
1015        return meth(mode=mode,
1016                    datastructure=datastructure,
1017                    )
1018    ###)
1019
1020
1021InitializeClass(WAeUPMultilineResultsWidget)
1022widgetRegistry.register(WAeUPMultilineResultsWidget)
1023###)
1024
1025class WAeUPResultsWidget(CPSStringWidget): ###(
1026    """ WAeUPResults Widget"""
1027    meta_type = "WAeUp Results Widget"
1028
1029    def prepare(self, datastructure, **kw): ###(
1030        """Prepare datastructure from datamodel."""
1031        datamodel = datastructure.getDataModel()
1032        v = datamodel[self.fields[0]]
1033        #import pdb;pdb.set_trace()
1034        widget_id = self.getWidgetId()
1035        datastructure[widget_id] = v
1036        datastructure[widget_id+'_s'] = ''
1037        datastructure[widget_id+'_g'] = ''
1038    ###)
1039
1040    def validate(self, datastructure, **kw): ###(
1041        """Validate datastructure and update datamodel."""
1042        #import pdb;pdb.set_trace()
1043        widget_id = self.getWidgetId()
1044        v = datastructure[widget_id]
1045        err = 0
1046        s = datastructure[widget_id+'_s'].strip()
1047        g = datastructure[widget_id+'_g'].strip()
1048        while 1:
1049            if not s and g:
1050                err = "No subject grade for subject"
1051                break
1052            i = 0
1053            done = False
1054            for sv,gv in v:
1055                if sv == s:
1056                    done = True
1057                    if not g:
1058                        v.pop(i)
1059                        break
1060                    v[i] = (s,g)
1061                    break
1062                i += 1
1063            if done:
1064                break
1065            if s and g:
1066                v.append((s,g))
1067            break
1068        if err:
1069            datastructure.setError(widget_id, err)
1070        else:
1071            datamodel = datastructure.getDataModel()
1072            datamodel[self.fields[0]] = v
1073            datastructure[widget_id+'_s'] = s
1074            datastructure[widget_id+'_g'] = g
1075        return not err
1076    ###)
1077
1078    def render(self, mode, datastructure, **kw): ###(
1079        """Render in mode from datastructure."""
1080        render_method = 'widget_waeup_result_render'
1081        meth = getattr(self, render_method, None)
1082        if meth is None:
1083            raise RuntimeError("Unknown Render Method %s for widget type %s"
1084                               % (render_method, self.getId()))
1085        #import pdb;pdb.set_trace()
1086        datamodel = datastructure.getDataModel()
1087        widget_id = self.getWidgetId()
1088        datastructure[widget_id+'_s'] = ''
1089        datastructure[widget_id+'_g'] = ''
1090        return meth(mode=mode,
1091                    datastructure=datastructure,
1092                    )
1093    ###)
1094
1095
1096InitializeClass(WAeUPResultsWidget)
1097widgetRegistry.register(WAeUPResultsWidget)
1098###)
1099
1100class ScratchCardPin: ###(
1101    """the ScratchCardPin"""
1102    def __init__(self,prefix,batch_no,number):
1103        if not batch_no and not number:
1104            s = prefix
1105            if len(s) > 3:
1106                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1107            else:
1108                prefix,batch_no,number = s,'',''
1109        self.p = prefix
1110        self.b = batch_no
1111        self.n = number
1112
1113    def __str__(self):
1114        return "%s-%s-%s" % (self.p,self.b,self.n)
1115
1116    def __repr__(self):
1117        return "%s%s%s" % (self.p,self.b,self.n)
1118###)
1119
1120class ScratchcardPinWidget(CPSStringWidget): ###(
1121    """ ScratchcardPin Widget"""
1122    meta_type = "Scratchcard Pin Widget"
1123    _properties = CPSWidget._properties + (
1124        {'id': 'prefix', 'type': 'string', 'mode': 'w',
1125         'label': 'Prefix'},
1126         {'id': 'reference', 'type': 'string', 'mode': 'w',
1127         'label': 'Reference Field'},
1128        )
1129    prefix = ''
1130    reference = ''
1131    def prepare(self, datastructure, **kw): ###(
1132        """Prepare datastructure from datamodel."""
1133        datamodel = datastructure.getDataModel()
1134        v = datamodel[self.fields[0]]
1135        widget_id = self.getWidgetId()
1136        #import pdb;pdb.set_trace()
1137        if v and type(v) is StringType:
1138            try:
1139                p,b,n = v.split('-')
1140                v = ScratchCardPin(p,b,n)
1141            except ValueError:
1142                v = ScratchCardPin(v,'','')
1143        if v:
1144            p = '%s' % v.p
1145            b = '%s' % v.b
1146            n = '%s' % v.n
1147        else:
1148            p = self.prefix
1149            if p.startswith('@'):
1150                p = getattr(self,self.prefix[1:])()
1151            b = n = ''
1152            v = ScratchCardPin(p,b,n)
1153        datastructure[widget_id] = v
1154        datastructure[widget_id+'_p'] = p
1155        datastructure[widget_id+'_b'] = b
1156        datastructure[widget_id+'_n'] = n
1157    ###)
1158
1159    def validate(self, datastructure, **kw): ###(
1160        """Validate datastructure and update datamodel."""
1161        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1162        widget_id = self.getWidgetId()
1163        v = datastructure[widget_id]
1164        #import pdb;pdb.set_trace()
1165        err = 0
1166        mapping = {}
1167        prefix= self.prefix
1168        if prefix.startswith('@'):
1169            prefix= getattr(self,self.prefix[1:])()
1170        b = datastructure[widget_id+'_b'].strip()
1171        n = datastructure[widget_id+'_n'].strip()
1172        pins = self.portal_pins
1173        pin = "%(prefix)s%(b)s%(n)s" % vars()
1174        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1175        do = 1
1176        s_id = str(self.portal_membership.getAuthenticatedMember())
1177        if self.isStaff():
1178            do = 0
1179            err ='You are not a Student. PIN neither checked nor used.'
1180            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1181        elif len(b) > 1 and b.find('-') > -1:
1182            do = 0
1183            err = 'PIN must not contain "-"'
1184            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1185        elif n.find('-') > -1:
1186            do = 0
1187            err = 'PIN must not contain "-"'
1188            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1189        elif len(n) != 10:
1190            do = 0
1191            err = 'Invalid PIN length'
1192            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1193        elif self.reference == "":
1194            ref = s_id
1195        else:
1196            ref = datastructure[self.reference]
1197            if datastructure.errors:
1198                do = 0
1199                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1200                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1201        while do:
1202            ok = pins.searchAndSetRecord(pin,ref,prefix)
1203            if ok < -2 or ok > 2:
1204                err = 'Unknown error, please report!'
1205                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1206                break
1207            elif ok == -2:
1208                err = 'Service already is activated but with a different PIN.'
1209                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1210                break
1211            elif ok == -1:
1212                err = 'Invalid PIN'
1213                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1214                break
1215            if ok == 0:
1216                err = 'PIN already used'
1217                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1218                break
1219            if ok >= 1:
1220                #import pdb;pdb.set_trace()
1221                if self.isStudent():
1222                    if self.reference == "jamb_reg_no":
1223                        err = "You are already logged in."
1224                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1225                        break
1226                    if ok == 1:
1227                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1228                    else:
1229                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1230                    break
1231                else:
1232                    student = getStudentByRegNo(self,ref)
1233                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1234                if student is None:
1235                    err = "Student not found"
1236                    s_logger.info('%s not found in admission list' % (ref))
1237                    break
1238                s_id = student.getId()
1239                if ok == 2:
1240                    if self.reference == "jamb_reg_no":
1241                        if hasattr(self.portal_directories.students,s_id):
1242                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1243                            mapping = {'id': s_id}
1244                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1245                            break
1246                        else:
1247                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1248                    else:
1249                        err = "Unknown error"
1250                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1251                        break
1252                try:
1253                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1254                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1255                except:
1256                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1257                    mapping = {'id': s_id}
1258                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1259                    break
1260            break
1261        if err:
1262            datastructure.setError(widget_id, err,mapping)
1263        else:
1264            datamodel = datastructure.getDataModel()
1265            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1266            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1267            datastructure[widget_id+'_p'] = prefix
1268            datastructure[widget_id+'_b'] = b
1269            datastructure[widget_id+'_n'] = n
1270            datastructure['s_id'] = s_id
1271        return not err
1272
1273###)
1274
1275    def render(self, mode, datastructure, **kw): ###(
1276        """Render in mode from datastructure."""
1277        render_method = 'widget_scratch_card_pin_render'
1278        meth = getattr(self, render_method, None)
1279        if meth is None:
1280            raise RuntimeError("Unknown Render Method %s for widget type %s"
1281                               % (render_method, self.getId()))
1282
1283        # XXX AT: datastructure has to be set again here, in case we're in edit
1284        # or create mode, because a default value has to be provided.
1285        #import pdb;pdb.set_trace()
1286        datamodel = datastructure.getDataModel()
1287        v = datamodel[self.fields[0]]
1288        if v and type(v) is StringType:
1289            try:
1290                p,b,n = v.split('-')
1291                v = ScratchCardPin(p,b,n)
1292            except ValueError:
1293                v = ScratchCardPin(self.prefix,'XXX',v)
1294                pass
1295        if v:
1296            prefix= '%s' % v.p
1297            b = '%s' % v.b
1298            n = '%s' % v.n
1299        else:
1300            prefix= self.prefix
1301            if prefix.startswith('@'):
1302                prefix= getattr(self,self.prefix[1:])()
1303            b = n = ''
1304            v = ScratchCardPin(prefix,b,n)
1305        widget_id = self.getWidgetId()
1306        datastructure[widget_id] = v
1307        datastructure[widget_id+'_p'] = prefix
1308        datastructure[widget_id+'_b'] = b
1309        datastructure[widget_id+'_n'] = n
1310        return meth(mode=mode,
1311                    datastructure=datastructure,
1312                    )
1313    ###)
1314
1315InitializeClass(ScratchcardPinWidget)
1316widgetRegistry.register(ScratchcardPinWidget)
1317###)
1318
1319class PumePinWidget(ScratchcardPinWidget): ###(
1320    """ Pume Pin Widget"""
1321    meta_type = "Pume Pin Widget"
1322    catalog = "applicants_catalog"
1323
1324    def validate(self, datastructure, **kw): ###(
1325        """Validate datastructure and update datamodel."""
1326        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1327        widget_id = self.getWidgetId()
1328        v = datastructure[widget_id]
1329        err = 0
1330        mapping = {}
1331
1332        prefix= self.prefix
1333        if prefix.startswith('@'):
1334            prefix= getattr(self,self.prefix[1:])()
1335        b = datastructure[widget_id+'_b'].strip()
1336        n = datastructure[widget_id+'_n'].strip()
1337        pins = self.portal_pins
1338        pin = "%(prefix)s%(b)s%(n)s" % vars()
1339        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1340        do = 1
1341        s_id = str(self.portal_membership.getAuthenticatedMember())
1342        if self.isStaff():
1343            do = 0
1344            err ='You are not a Student. PIN neither checked nor used.'
1345            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1346        elif len(b) > 1 and b.find('-') > -1:
1347            do = 0
1348            err = 'PIN must not contain "-"'
1349            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1350        elif n.find('-') > -1:
1351            do = 0
1352            err = 'PIN must not contain "-"'
1353            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1354        elif len(n) != 10:
1355            do = 0
1356            err = 'Invalid PIN length'
1357            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1358        elif self.reference == "":
1359            ref = s_id
1360        else:
1361            ref = datastructure[self.reference]
1362            if datastructure.errors:
1363                do = 0
1364                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1365                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1366        while do:
1367            ok = pins.searchAndSetRecord(pin,ref,prefix)
1368            if ok < -2 or ok > 2:
1369                err = 'Unknown error, please report!'
1370                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1371                break
1372            elif ok == -2:
1373                err = 'Service already is activated but with a different PIN.'
1374                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1375                break
1376            elif ok == -1:
1377                err = 'Invalid PIN'
1378                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1379                break
1380            if ok == 0:
1381                err = 'PIN already used'
1382                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1383                break
1384            if ok >= 1:
1385                if self.isStudent():
1386                    err = "This is only for Pume application."
1387                    s_logger.info('%s/%s applied for PUME with PIN %s' % (s_id,ref,pin_str))
1388                    break
1389                else:
1390                    applicant = datastructure['record']
1391                    if not applicant.pin:
1392                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1393                        d = {}
1394                        d['reg_no'] = applicant.reg_no
1395                        d['pin'] = pin_str
1396                        getattr(self,self.catalog).modifyRecord(**d)
1397                    elif applicant.pin != pin_str:
1398                        s_logger.info('%s/%s repeatedly applied for PUME with different PIN %s' % (s_id,ref,pin_str))
1399                    elif applicant.pin == pin_str:
1400                        s_logger.info('%s/%s repeatedly applied for PUME with PIN %s' % (s_id,ref,pin_str))
1401            break
1402        if err:
1403            datastructure.setError(widget_id, err,mapping)
1404        else:
1405            datamodel = datastructure.getDataModel()
1406            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1407            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1408            datastructure[widget_id+'_p'] = prefix
1409            datastructure[widget_id+'_b'] = b
1410            datastructure[widget_id+'_n'] = n
1411            datastructure['s_id'] = s_id
1412        return not err
1413    ###)
1414
1415    def render(self, mode, datastructure, **kw): ###(
1416        """Render in mode from datastructure."""
1417        render_method = 'widget_scratch_card_pin_render'
1418        meth = getattr(self, render_method, None)
1419        if meth is None:
1420            raise RuntimeError("Unknown Render Method %s for widget type %s"
1421                               % (render_method, self.getId()))
1422
1423        # XXX AT: datastructure has to be set again here, in case we're in edit
1424        # or create mode, because a default value has to be provided.
1425        #import pdb;pdb.set_trace()
1426        datamodel = datastructure.getDataModel()
1427        v = datamodel[self.fields[0]]
1428        #import pdb;pdb.set_trace()
1429        if v and type(v) is StringType:
1430            try:
1431                p,b,n = v.split('-')
1432                v = ScratchCardPin(p,b,n)
1433            except ValueError:
1434                v = ScratchCardPin(self.prefix,'XXX',v)
1435                pass
1436        if v:
1437            prefix= '%s' % v.p
1438            b = '%s' % v.b
1439            n = '%s' % v.n
1440        else:
1441            prefix= self.prefix
1442            if prefix.startswith('@'):
1443                prefix= getattr(self,self.prefix[1:])()
1444            b = n = ''
1445            v = ScratchCardPin(prefix,b,n)
1446        widget_id = self.getWidgetId()
1447        datastructure[widget_id] = v
1448        datastructure[widget_id+'_p'] = prefix
1449        datastructure[widget_id+'_b'] = b
1450        datastructure[widget_id+'_n'] = n
1451        return meth(mode=mode,
1452                    datastructure=datastructure,
1453                    )
1454    ###)
1455
1456InitializeClass(PumePinWidget)
1457widgetRegistry.register(PumePinWidget)
1458###)
1459
1460class WAeUPImageWidget(CPSImageWidget): ###(
1461    """Photo widget."""
1462    meta_type = 'WAeUP Image Widget'
1463
1464    def render(self, mode, datastructure, **kw):
1465        render_method = 'widget_waeup_image_render'
1466        meth = getattr(self, render_method, None)
1467        if meth is None:
1468            raise RuntimeError("Unknown Render Method %s for widget type %s"
1469                               % (render_method, self.getId()))
1470        img_info = self.getImageInfo(datastructure)
1471        return meth(mode=mode, datastructure=datastructure, **img_info)
1472
1473InitializeClass(WAeUPImageWidget)
1474
1475widgetRegistry.register(WAeUPImageWidget)
1476###)
1477
1478class ExtFileWidget(CPSFileWidget): ###(
1479    """Photo widget."""
1480    meta_type = 'Ext File Widget'
1481
1482    def getFileInfo(self, datastructure): ###(
1483        """Get the file info from the datastructure."""
1484        widget_id = self.getWidgetId()
1485        fileupload = datastructure[widget_id]
1486        dm = datastructure.getDataModel()
1487        field_id = self.fields[0]
1488        if fileupload:
1489            import pdb; pdb.set_trace()
1490            empty_file = False
1491            session_file = isinstance(fileupload, PersistableFileUpload)
1492            current_filename = generateFileName(fileupload.filename)
1493            fileupload.seek(0, 2) # end of file
1494            size = fileupload.tell()
1495            fileupload.seek(0)
1496            file = dm[field_id] # last stored file
1497            if file is not None:
1498                last_modified = str(file._p_mtime or '')
1499            else:
1500                last_modified = ''
1501        else:
1502            empty_file = True
1503            session_file = False
1504            current_filename = ''
1505            size = 0
1506            last_modified = ''
1507
1508        # Find the URL for the file  XXX Refactor this!
1509
1510        # get the adapter
1511        for adapter in dm._adapters:
1512            if adapter.getSchema().has_key(field_id):
1513                break # Note: 'adapter' is still the right one
1514        else:
1515            raise ValueError('No schema for field %r' % field_id)
1516
1517        # get the content_url from the adapter
1518        content_url = None
1519        ob = dm.getProxy()
1520        if ob is None:
1521            # non proxy case
1522            ob = dm.getObject()
1523        if ob is None:
1524            # Not stored in the ZODB.
1525            # StorageAdapters that do not store the object in
1526            # ZODB takes the entry_id instead of object.
1527            # Get the entry_id from the datamodel context(typically
1528            # a directory).
1529            id_field = getattr(dm.getContext(), 'id_field', None)
1530            if id_field:
1531                try:
1532                    entry_id = datastructure[id_field]
1533                except KeyError:
1534                    entry_id = None
1535            else:
1536                # No object passed, and no id_field
1537                entry_id = None
1538            if entry_id:
1539                # some adapters does not have _getContentUrl
1540                if getattr(adapter, '_getContentUrl', None) is not None:
1541                    content_url = adapter._getContentUrl(entry_id, field_id)
1542        else:
1543            if hasattr(adapter,"_getContentUrl"):
1544                content_url = adapter._getContentUrl(ob, field_id,
1545                                                 current_filename)
1546            else:
1547                content_url = None
1548        # get the mimetype
1549        registry = getToolByName(self, 'mimetypes_registry')
1550        mimetype = (registry.lookupExtension(current_filename.lower()) or
1551                    registry.lookupExtension('file.bin'))
1552
1553        file_info = {
1554            'empty_file': empty_file,
1555            'session_file': session_file,
1556            'current_filename': current_filename,
1557            'size': size,
1558            'last_modified': last_modified,
1559            'content_url': content_url,
1560            'mimetype': mimetype,
1561            }
1562
1563        return file_info
1564    ###)
1565
1566    def prepare(self, datastructure, **kw): ###(
1567        """Prepare datastructure from datamodel."""
1568        datamodel = datastructure.getDataModel()
1569        widget_id = self.getWidgetId()
1570        file_name = datamodel[self.fields[0]]
1571        if not file_name:
1572            file = None
1573        else:
1574            io = ExtFile(file)
1575            if filename is None:
1576                filename = ofsfile.title
1577            headers = {'content-type': ofsfile.content_type}
1578            fs = SimpleFieldStorage(io, filename, headers)
1579            FileUpload(fs)
1580        datastructure[widget_id] = file
1581        datastructure[widget_id + '_choice'] = ''
1582        if file is not None:
1583            title = file.title
1584        else:
1585            title = ''
1586        datastructure[widget_id + '_filename'] = title
1587    ###)
1588
1589    def validate(self, datastructure, **kw):
1590        """Update datamodel from user data in datastructure.
1591        """
1592        datamodel = datastructure.getDataModel()
1593        field_id = self.fields[0]
1594        widget_id = self.getWidgetId()
1595        choice = datastructure[widget_id+'_choice']
1596        store = False
1597        fileupload = None
1598        mimetype = None
1599        old_file = datamodel[field_id]
1600        if old_file is not None:
1601            old_filename = old_file.title
1602        else:
1603            old_filename = ''
1604
1605        if choice == 'delete':
1606            if self.is_required:
1607                return self.validateError('cpsschemas_err_required', {},
1608                                          datastructure)
1609            datamodel[field_id] = None
1610        elif choice == 'keep':
1611            fileupload = datastructure[widget_id]
1612            if isinstance(fileupload, PersistableFileUpload):
1613                # Keeping something from the session means we
1614                # actually want to store it.
1615                store = True
1616            else:
1617                # Nothing to change, don't pollute datastructure
1618                # with something costly already stored, which therefore
1619                # doesn't need to be kept in the session.
1620                self.unprepare(datastructure)
1621        elif choice == 'change':
1622            fileupload = datastructure[widget_id]
1623            if not fileupload:
1624                return self.validateError('cpsschemas_err_file_empty', {},
1625                                          datastructure)
1626            if not isinstance(fileupload, FileUpload):
1627                return self.validateError('cpsschemas_err_file', {},
1628                                          datastructure)
1629            fileupload.seek(0, 2) # end of file
1630            size = fileupload.tell()
1631            if not size:
1632                return self.validateError('cpsschemas_err_file_empty', {},
1633                                          datastructure)
1634            if self.size_max and size > self.size_max:
1635                max_size_str = self.getHumanReadableSize(self.size_max)
1636                err = 'cpsschemas_err_file_too_big ${max_size}'
1637                err_mapping = {'max_size': max_size_str}
1638                return self.validateError(err, err_mapping, datastructure)
1639            store = True
1640
1641        self.otherProcessing(choice, datastructure)
1642
1643        # Find filename
1644        if fileupload is not None:
1645            filename = self.getFileName(fileupload, datastructure, choice,
1646                                        old_filename)
1647            if filename != old_filename:
1648                registry = getToolByName(self, 'mimetypes_registry')
1649                mimetype = registry.lookupExtension(filename.lower())
1650                if mimetype is not None:
1651                    mimetype = str(mimetype) # normalize
1652                err, err_mapping = self.checkFileName(filename, mimetype)
1653                if err:
1654                    return self.validateError(err, err_mapping, datastructure)
1655        elif datamodel[field_id] is not None:
1656            # FIXME: not correct in the case of change=='resize' (CPSPhotoWidget)
1657            filename = datamodel[field_id].title
1658
1659        # Set/update data
1660        import pdb;pdb.set_trace()
1661        if store:
1662            # Create file
1663            #file = ExtFile(filename, fileupload, datastructure)
1664            table_store = False
1665            if not hasattr(datamodel._adapters[0],'_getContentUrl'):
1666                table_store = True
1667                ref_id = datamodel.get('reg_no')
1668                id = "%s_%s" % (ref_id,field_id)
1669            self.tempExtFile = ExtFile(id, field_id)
1670            if table_store:
1671                datastructure[widget_id] = self.tempExtFile
1672                self.tempExtFile.manage_file_upload(fileupload,content_type=mimetype)
1673            else:
1674                self._setObject(id, self.tempExtFile)
1675                self._getOb(id).manage_file_upload(fileupload, content_type)
1676            # Fixup mimetype
1677            if mimetype and self.tempExtFile.content_type != mimetype:
1678                self.tempExtFile.content_type = mimetype
1679            # Store
1680            if not table_store:
1681                datamodel[field_id] = file
1682        elif datamodel[field_id] is not None:
1683            # Change filename
1684            if datamodel[field_id].title != filename:
1685                datamodel[field_id].title = filename
1686
1687        return True
1688
1689
1690InitializeClass(ExtFileWidget)
1691
1692widgetRegistry.register(ExtFileWidget)
1693###)
1694
1695
1696###########
1697
Note: See TracBrowser for help on using the repository browser.