source: WAeUP_SRP/trunk/Widgets.py @ 8145

Last change on this file since 8145 was 7961, checked in by Henrik Bettermann, 13 years ago

Two new screening types: pg_ft and pg_pt

  • Property svn:keywords set to Id
File size: 99.1 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 7961 2012-03-22 20:58:25Z henrik $
3from cgi import escape
4from types import *
5import Globals
6from Globals import InitializeClass
7from ZPublisher.HTTPRequest import FileUpload
8from OFS.Image import cookId, File, Image
9##from Products.CPSSchemas.Widget import CPSWidgetType
10from Products.CMFCore.utils import getToolByName
11from Products.CPSSchemas.BasicWidgets import CPSBooleanWidget, CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget,CPSIntWidget
12from Products.CPSSchemas.BasicWidgets import CPSFileWidget, CPSPasswordWidget
13from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget
14from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget
15from Products.CPSSchemas.Vocabulary import Vocabulary
16from Products.CPSSchemas.Widget import widgetRegistry
17from Products.CPSUtil.file import PersistableFileUpload
18from Products.CPSUtil.id import generateFileName
19##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry
20from DateTime.DateTime import DateTime
21from AccessControl import getSecurityManager
22from Products.WAeUP_SRP.Students import getStudentByRegNo
23from Products.WAeUP_SRP.Academics import makeCertificateCode
24from Products.WAeUP_SRP.WAeUPTool import getImagesDir
25#from Products.ExtFile.ExtFile import ExtFile
26import logging,os,re
27import random
28import operator
29p_home = Globals.package_home(globals())
30i_home = Globals.INSTANCE_HOME
31
32#from zLOG import LOG, DEBUG
33
34
35class WAeUPPasswordWidget(CPSPasswordWidget): ###(
36    """WAeUP Password Widget"""
37    meta_type = 'WAeUP Password Widget'
38
39    _properties = CPSStringWidget._properties + (
40        {'id': 'password_widget', 'type': 'string', 'mode': 'w',
41         'label': 'Password widget to compare with'},
42        {'id': 'check_lower', 'type': 'boolean', 'mode': 'w',
43         'label': 'Checking at least one lower case [a-z]'},
44        {'id': 'check_upper', 'type': 'boolean', 'mode': 'w',
45         'label': 'Checking at least one upper case [A-Z]'},
46        {'id': 'check_digit', 'type': 'boolean', 'mode': 'w',
47         'label': 'Checking at least one digit [0-9]'},
48        {'id': 'check_extra', 'type': 'boolean', 'mode': 'w',
49         'label': 'Checking at least one extra char other than [a-zA-Z0-9]'},
50        {'id': 'check_words', 'type': 'string', 'mode': 'w',
51         'label': 'Checking for words'},
52        )
53
54    field_types = ('CPS Password Field',)
55    password_widget = ''
56    check_lower = 0
57    check_upper = 0
58    check_digit = 0
59    check_extra = 0
60    check_words = ''
61    display_width = 8
62    size_min = 5
63    size_max = 8
64
65    def validate(self, datastructure, **kw):
66        """Validate datastructure and update datamodel."""
67        widget_id = self.getWidgetId()
68        value = datastructure[widget_id]
69        err = 0
70        try:
71            v = str(value).strip()
72        except ValueError:
73            err = 'cpsschemas_err_string'
74        else:
75            if self.password_widget:
76                # here we only check that that our confirm match the pwd
77                pwidget_id = self.password_widget
78                pvalue = datastructure[pwidget_id]
79                datastructure[widget_id] = ''
80                datastructure[pwidget_id] = ''
81                pv = str(pvalue).strip()
82                if pv and v != pv:
83                    err = 'cpsschemas_err_password_mismatch'
84            else:
85                if not v:
86                    if self.is_required:
87                        datamodel = datastructure.getDataModel()
88                        if not datamodel[self.fields[0]]:
89                            err = 'cpsschemas_err_required'
90                else:
91                    # checking pw consistancy
92                    len_v = len(v)
93                    if not err and self.size_max and len_v > self.size_max:
94                        err = 'cpsschemas_err_string_too_long'
95                    if not err and self.size_min and len_v < self.size_min:
96                        err = 'cpsschemas_err_password_size_min'
97                    if not err and self.check_lower and not search(r'[a-z]', v):
98                        err = 'cpsschemas_err_password_lower'
99                    if not err and self.check_upper and not search(r'[A-Z]', v):
100                        err = 'cpsschemas_err_password_upper'
101                    if not err and self.check_digit and not search(r'[0-9]', v):
102                        err = 'cpsschemas_err_password_digit'
103                    if not err and self.check_extra and not search(r'[^a-zA-Z0-9]',
104                                                                   v):
105                        err = 'cpsschemas_err_password_extra'
106                    if not err and v in self.check_words:
107                        err = 'Your password is unsecure, please choose another password!'
108
109        if err:
110            datastructure[widget_id] = ''
111            datastructure.setError(widget_id, err)
112        elif v:
113            datamodel = datastructure.getDataModel()
114            datamodel[self.fields[0]] = v
115
116        return not err
117
118InitializeClass(WAeUPPasswordWidget)
119
120widgetRegistry.register(WAeUPPasswordWidget)
121###)
122
123class CPSSelectWidgetForRecord(CPSSelectWidget): ###(
124    """Select widget. with record names"""
125    meta_type = 'Select Widget for Records'
126
127    field_types = ('CPS String Field',)
128    field_inits = ({'is_searchabletext': 1,},)
129
130    _properties = CPSSelectWidget._properties + (
131        {'id': 'record_id', 'type': 'string', 'mode': 'w',
132         'label': 'Record Id', 'is_required' : 1},
133        )
134
135    def render(self, mode, datastructure, **kw):
136        """Render in mode from datastructure."""
137        value = datastructure[self.getWidgetId()]
138        vocabulary = self._getVocabulary(datastructure)
139        portal = getToolByName(self, 'portal_url').getPortalObject()
140        cpsmcat = portal.translation_service
141        if mode == 'view':
142            if self.translated:
143                return escape(cpsmcat(vocabulary.getMsgid(value, value)).encode('ISO-8859-15', 'ignore'))
144            else:
145                return escape(vocabulary.get(value, value))
146        elif mode == 'edit':
147            html_widget_id = self.getHtmlWidgetId()
148            res = renderHtmlTag('select',
149                                name='%s.%s:records' % (self.record_id,html_widget_id),
150                                id=html_widget_id)
151            in_selection = 0
152            for k, v in vocabulary.items():
153                if self.translated:
154                    kw = {'value': k,
155                          'contents': cpsmcat(vocabulary.getMsgid(k, k)).encode('ISO-8859-15', 'ignore')
156                          }
157                else:
158                    kw = {'value': k, 'contents': v}
159                if value == k:
160                    kw['selected'] = 'selected'
161                    in_selection = 1
162                res += renderHtmlTag('option', **kw)
163            if value and not in_selection:
164                kw = {'value': value, 'contents': 'invalid: '+ str(value),
165                      'selected': 'selected'}
166                res += renderHtmlTag('option', **kw)
167            res += '</select>'
168            return res
169        raise RuntimeError('unknown mode %s' % mode)
170
171InitializeClass(CPSSelectWidgetForRecord)
172
173widgetRegistry.register(CPSSelectWidgetForRecord)
174
175###)
176
177class CPSStringWidgetForRecord(CPSStringWidget): ###(
178    """String widget."""
179    meta_type = 'String Widget For Record'
180
181    field_types = ('CPS String Field',)
182    field_inits = ({'is_searchabletext': 1,},)
183    _properties = CPSStringWidget._properties + (
184        {'id': 'record_id', 'type': 'string', 'mode': 'w',
185         'label': 'Record Id', 'is_required' : 1},
186        )
187
188    def render(self, mode, datastructure, **kw):
189        """Render in mode from datastructure."""
190        value = datastructure[self.getWidgetId()]
191        if mode == 'view':
192            return escape(value)
193        elif mode == 'edit':
194            # XXX TODO should use an other name than kw !
195            # XXX change this everywhere
196            html_widget_id = self.getHtmlWidgetId()
197            kw = {'type': 'text',
198                  'id'  : html_widget_id,
199                  'name': '%s.%s:records' % (self.record_id,html_widget_id),
200                  'value': escape(value),
201                  'size': self.display_width,
202                  }
203            if self.size_max:
204                kw['maxlength'] = self.size_max
205            return renderHtmlTag('input', **kw)
206        raise RuntimeError('unknown mode %s' % mode)
207
208InitializeClass(CPSStringWidgetForRecord)
209
210widgetRegistry.register(CPSStringWidgetForRecord)
211
212###)
213
214class CertificateCourseIdWidget(CPSStringWidget): ###(
215    """ CertificateCourseId Widget"""
216    meta_type = "CertificateCourseId Widget"
217
218    def validate(self, datastructure, **kw):
219        """Validate datastructure and update datamodel."""
220
221        valid = CPSStringWidget.validate(self, datastructure, **kw)
222        if not valid:
223            return 0
224        else:
225            widget_id = self.getWidgetId()
226            value = datastructure[widget_id].upper()
227            err = 0
228            c_ids = [c.id for c in self.portal_catalog({'meta_type': "Course"})]
229            if hasattr(self.aq_parent,value):
230                err = 'Course already exists'
231            elif value not in c_ids:
232                err = 'Course does not exist'
233            if err:
234                datastructure.setError(widget_id, err)
235            else:
236                datamodel = datastructure.getDataModel()
237                datamodel[self.fields[0]] = value
238
239            return not err
240
241InitializeClass(CertificateCourseIdWidget)
242
243widgetRegistry.register(CertificateCourseIdWidget)
244###)
245
246class CourseIdWidget(CPSStringWidget): ###(
247    """ CourseId Widget"""
248    meta_type = "CourseId Widget"
249
250    def validate(self, datastructure, **kw):
251        """Validate datastructure and update datamodel."""
252
253        valid = CPSStringWidget.validate(self, datastructure, **kw)
254        if not valid:
255            return 0
256        else:
257            widget_id = self.getWidgetId()
258            value = datastructure[widget_id].upper()
259            err = 0
260            res = self.courses_catalog(code = value)
261            if len(res) > 0:
262                err = 'Course already exists'
263            if err:
264                datastructure.setError(widget_id, err)
265            else:
266                datamodel = datastructure.getDataModel()
267                datamodel[self.fields[0]] = value
268
269            return not err
270
271InitializeClass(CourseIdWidget)
272
273widgetRegistry.register(CourseIdWidget)
274
275
276###)
277
278class WAeUPStudyModeWidget(CPSSelectWidget): ###(
279    """WAeUP StudyMode Widget."""
280    meta_type = 'WAeUP StudyMode Widget'
281    vocabulary = 'entry_modes'
282
283    def _getStudyModes(self):
284        voc = getattr(self.portal_vocabularies,self.vocabulary)
285        d = {}
286        for k,v in voc.items():
287            d[k] = v
288        return d
289
290    def validate(self, datastructure, **kw):
291        """Validate datastructure and update datamodel."""
292        widget_id = self.getWidgetId()
293        value = datastructure[widget_id]
294        try:
295            v = str(value)
296        except ValueError:
297            datastructure.setError(widget_id, "'%s' not a valid mode key" % value)
298            return 0
299        studymodes = self._getStudyModes()
300        if not value:
301            v = value = 'ume_ft'
302        #import pdb;pdb.set_trace()
303        if not studymodes.has_key(value):
304            datastructure.setError(widget_id, "'%s' not a valid mode key" % v)
305            return 0
306        if self.is_required and not len(v):
307            datastructure.setError(widget_id, "mode key required")
308            return 0
309
310        datamodel = datastructure.getDataModel()
311        datamodel[self.fields[0]] = v
312        return 1
313
314    def render(self, mode, datastructure, **kw):
315        """Render in mode from datastructure."""
316        value = datastructure[self.getWidgetId()]
317        studymodes = self._getStudyModes()
318        if mode == 'view':
319            return escape(studymodes.get(value, value))
320        elif mode == 'edit':
321            html_widget_id = self.getHtmlWidgetId()
322            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
323            in_selection = 0
324            vocabulary_items = studymodes.items()
325            if self.sorted:
326                vocabulary_items.sort(key=operator.itemgetter(1))
327            for k, v in vocabulary_items:
328                kw = {'value': k, 'contents': v}
329                if value == k:
330                    kw['selected'] = 'selected'
331                    in_selection = 1
332                res += renderHtmlTag('option', **kw)
333            if value and not in_selection:
334                kw = {'value': value, 'contents': 'invalid: '+ str(value),
335                      'selected': 'selected'}
336                res += renderHtmlTag('option', **kw)
337            res += '</select>'
338            return res
339        raise RuntimeError('unknown mode %s' % mode)
340
341InitializeClass(WAeUPStudyModeWidget)
342
343widgetRegistry.register(WAeUPStudyModeWidget)
344
345###)
346
347class WAeUPSessionWidget(CPSSelectWidget): ###(
348    """WAeUP Session Widget for import only"""
349    meta_type = 'WAeUP Session Widget'
350
351    def _getSessions(self):
352        current_year = DateTime().year()
353        #d = {'': ''}
354        d = {}
355        for y in range(current_year - 25,current_year + 1):
356            d['%s' % str(y)[-2:]] = '%4d/%4d' % (y,y+1)
357        return d
358
359    def validate(self, datastructure, **kw):
360        """Validate datastructure and update datamodel."""
361        widget_id = self.getWidgetId()
362        value = datastructure[widget_id]
363        #import pdb;pdb.set_trace()       
364        try:
365            v = str(value)
366        except ValueError:
367            datastructure.setError(widget_id, "'%s' not a valid session key" % value)
368            return 0
369        if len(v) == 1:
370            v = value = '0%c' % v
371        elif len(v) == 9:
372            v = value[2:4]
373        elif not value:
374            v = ''
375        sessions = self._getSessions()
376
377        if not sessions.has_key(v):
378            datastructure.setError(widget_id, "'%s' not a valid session key" % v)
379            return 0
380        if self.is_required and not len(v):
381            datastructure.setError(widget_id, "session key required")
382            return 0
383
384        datamodel = datastructure.getDataModel()
385        datamodel[self.fields[0]] = v
386        return 1
387
388    # rendering is not used, instead we use a select widget with dynamic vocabulary
389    def render(self, mode, datastructure, **kw):
390        """Render in mode from datastructure."""
391        value = datastructure[self.getWidgetId()]
392        sessions = self._getSessions()
393        if mode == 'view':
394            return escape(sessions.get(value, value))
395        elif mode == 'edit':
396            html_widget_id = self.getHtmlWidgetId()
397            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
398            in_selection = 0
399            vocabulary_items = sessions.items()
400            if self.sorted:
401                vocabulary_items.sort(key=operator.itemgetter(0))
402            for k, v in vocabulary_items:
403                kw = {'value': k, 'contents': v}
404                if value == k:
405                    kw['selected'] = 'selected'
406                    in_selection = 1
407                res += renderHtmlTag('option', **kw)
408            if value and not in_selection:
409                kw = {'value': value, 'contents': 'invalid: '+ str(value),
410                      'selected': 'selected'}
411                res += renderHtmlTag('option', **kw)
412            res += '</select>'
413            return res
414        raise RuntimeError('unknown mode %s' % mode)
415
416InitializeClass(WAeUPSessionWidget)
417
418widgetRegistry.register(WAeUPSessionWidget)
419
420###)
421
422class WAeUPLevelWidget(CPSSelectWidget): ###(
423    """WAeUP Level Widget."""
424    meta_type = 'WAeUP Level Widget'
425
426    def _getLevels(self):
427        #d = {'':'','000':'Pre-Studies'}
428        d = {'000':'Pre-Studies'}
429        for y in range(100,800,100):
430            d['%s' % str(y)] = 'Year %1d (%3d Level)' % (y/100,y)
431        return d
432
433    def validate(self, datastructure, **kw):
434        """Validate datastructure and update datamodel."""
435        widget_id = self.getWidgetId()
436        value = datastructure[widget_id]
437        try:
438            v = str(value)
439        except ValueError:
440            datastructure.setError(widget_id, "'%s' not a valid level key" % value)
441            return 0
442
443        # if not value:
444        #     v = value = '100'
445        #import pdb;pdb.set_trace()
446        levels = self._getLevels()
447        if v == '0':
448            v = '000'
449        if not levels.has_key(v):
450            datastructure.setError(widget_id, "'%s' not a valid level" % v)
451            return 0
452        # if self.is_required and len(v) == 0:
453        #     datastructure.setError(widget_id, "level key required")
454        #     return 0
455
456        datamodel = datastructure.getDataModel()
457        datamodel[self.fields[0]] = v
458        return 1
459
460    def render(self, mode, datastructure, **kw):
461        """Render in mode from datastructure."""
462        value = datastructure[self.getWidgetId()]
463        levels = self._getLevels()
464        if mode == 'view':
465            return escape(levels.get(value, value))
466        elif mode == 'edit':
467            html_widget_id = self.getHtmlWidgetId()
468            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
469            in_selection = 0
470            vocabulary_items = levels.items()
471            if self.sorted:
472                vocabulary_items.sort(key=operator.itemgetter(0))
473            for k, v in vocabulary_items:
474                kw = {'value': k, 'contents': v}
475                if value == k:
476                    kw['selected'] = 'selected'
477                    in_selection = 1
478                res += renderHtmlTag('option', **kw)
479            if value and not in_selection:
480                kw = {'value': value, 'contents': 'invalid: '+ str(value),
481                      'selected': 'selected'}
482                res += renderHtmlTag('option', **kw)
483            res += '</select>'
484            return res
485        raise RuntimeError('unknown mode %s' % mode)
486
487InitializeClass(WAeUPLevelWidget)
488
489widgetRegistry.register(WAeUPLevelWidget)
490
491###)
492
493class WAeUPVerdictWidget(CPSSelectWidget): ###(
494    """WAeUP Verdict Widget."""
495    meta_type = 'WAeUP Verdict Widget'
496
497    # XXX make a menu for the vocabulary.
498    vocabulary = 'verdicts'
499
500    # Associating the widget label with an input area to improve the widget
501    # accessibility.
502    has_input_area = True
503
504    def _getVerdicts(self,datastructure):
505        voc = getattr(self.portal_vocabularies,self.vocabulary)
506        d = {}
507        for k,v in voc.items():
508            d[k] = v
509        return d
510
511    def validate(self, datastructure, **kw):
512        """Validate datastructure and update datamodel."""
513        widget_id = self.getWidgetId()
514        value = datastructure[widget_id]
515        try:
516            v = str(value)
517        except ValueError:
518            datastructure.setError(widget_id, "'%s' not a valid verdict key" % value)
519            return 0
520        #import pdb;pdb.set_trace()
521        verdicts = self._getVerdicts(datastructure)
522        if not value:
523            v = value = verdicts['']
524        if not verdicts.has_key(value):
525            datastructure.setError(widget_id, "'%s' not a valid verdict key" % v)
526            return 0
527        # if self.is_required and not len(v):
528        #     datastructure.setError(widget_id, "verdict required")
529        #     return 0
530
531        datamodel = datastructure.getDataModel()
532        datamodel[self.fields[0]] = v
533        return 1
534
535    def render(self, mode, datastructure, **kw):
536        """Render in mode from datastructure."""
537        value = datastructure[self.getWidgetId()]
538        verdicts = self._getVerdicts(datastructure)
539        if mode == 'view':
540            return escape(verdicts.get(value, value))
541        elif mode == 'edit':
542            html_widget_id = self.getHtmlWidgetId()
543            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
544            in_selection = 0
545            vocabulary_items = verdicts.items()
546            if self.sorted:
547                vocabulary_items.sort(key=operator.itemgetter(1))
548            for k, v in vocabulary_items:
549                kw = {'value': k, 'contents': v}
550                if value == k:
551                    kw['selected'] = 'selected'
552                    in_selection = 1
553                res += renderHtmlTag('option', **kw)
554            if value and not in_selection:
555                kw = {'value': value, 'contents': 'invalid: '+ str(value),
556                      'selected': 'selected'}
557                res += renderHtmlTag('option', **kw)
558            res += '</select>'
559            return res
560        raise RuntimeError('unknown mode %s' % mode)
561
562InitializeClass(WAeUPVerdictWidget)
563
564widgetRegistry.register(WAeUPVerdictWidget)
565
566###)
567
568class WAeUPLGAWidget(CPSSelectWidget): ###(
569    """WAeUP LGA Widget."""
570    meta_type = 'WAeUP LGA Widget'
571    _properties = CPSSelectWidget._properties + (
572        {'id': 'state_field', 'type': 'string', 'mode': 'w',
573         'label': 'Name of the state field'},
574         {'id': 'lga_field', 'type': 'string', 'mode': 'w',
575         'label': 'Name of the lga field (without state)'},
576         )
577    state_field = "state"
578    lga_field = "lga"
579
580    # XXX make a menu for the vocabulary.
581    vocabulary = 'local_gov_areas'
582
583    # Associating the widget label with an input area to improve the widget
584    # accessibility.
585    has_input_area = True
586
587    def _getLGAs(self):
588        if getattr(self,'_v_states',None) is not None and\
589           getattr(self,'_v_lgas',None) is not None and\
590           getattr(self,'_v_d',None) is not None and\
591           getattr(self,'_v_word_dict',None) is not None:
592            return (self._v_d,self._v_states,self._v_lgas,self._v_word_dict)
593        mapping = self.waeup_tool.getStatesLgas()
594        self._v_d = mapping['lga_dict']
595        self._v_states = mapping['states']
596        self._v_lgas = mapping['lgas']
597        self._v_word_dict = mapping['word_dict']
598        return (self._v_d,self._v_states,self._v_lgas,self._v_word_dict)
599
600
601    def validate(self, datastructure, **kw):
602        """Validate datastructure and update datamodel."""
603        widget_id = self.getWidgetId()
604        value = datastructure[widget_id]
605        #import pdb;pdb.set_trace()
606        try:
607            v = str(value)
608        except ValueError:
609            datastructure.setError(widget_id, "'%s' not a valid lga key" % value)
610            return 0
611        v = v.lower()
612        combined,states,lgas,word_dict = self._getLGAs()
613        datamodel = datastructure.getDataModel()
614        if self.state_field and self.lga_field:
615            v = ' '.join((datastructure.get(self.state_field,""),
616                              datastructure.get(self.lga_field,"")))
617        state_lga = self.waeup_tool.findLga(v,word_dict)
618        if not state_lga:
619            if self.is_required:
620                datastructure.setError(widget_id, "'%s' not a valid lga key" % v)
621                #datastructure.setError(widget_id, "%s required" % widget_id)
622                return 0
623            else:
624                state_lga = v
625        datamodel[self.fields[0]] = state_lga
626        return 1
627
628    def render(self, mode, datastructure, **kw):
629        """Render in mode from datastructure."""
630        w_id = self
631        value = datastructure[self.getWidgetId()]
632        lgas,x,y = self._getLGAs(datastructure)
633        if mode == 'view':
634            return escape(lgas.get(value, value))
635        elif mode == 'edit':
636            html_widget_id = self.getHtmlWidgetId()
637            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
638            in_selection = 0
639            vocabulary_items = lgas.items()
640            # if self.sorted:
641            #     vocabulary_items.sort(key=operator.itemgetter(1))
642            for k, v in vocabulary_items:
643                kw = {'value': k, 'contents': v}
644                if value == k:
645                    kw['selected'] = 'selected'
646                    in_selection = 1
647                res += renderHtmlTag('option', **kw)
648            if value and not in_selection:
649                kw = {'value': value, 'contents': 'invalid: '+ str(value),
650                      'selected': 'selected'}
651                res += renderHtmlTag('option', **kw)
652            res += '</select>'
653            return res
654        raise RuntimeError('unknown mode %s' % mode)
655
656InitializeClass(WAeUPLGAWidget)
657
658widgetRegistry.register(WAeUPLGAWidget)
659
660###)
661
662class WAeUPReservedRoomsWidget(CPSStringWidget): ###(
663    """ WAeUPReservedRooms Widget"""
664    meta_type = "WAeUPReservedRooms Widget"
665
666    def validate(self, datastructure, **kw):
667        """Validate datastructure and update datamodel."""
668        import re
669        valid = CPSStringWidget.validate(self, datastructure, **kw)
670        if not valid:
671            return 0
672        else:
673            widget_id = self.getWidgetId()
674            value = datastructure[widget_id]
675            err = 0
676            try:
677                reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',value)
678                                     if r]
679            except (ValueError,IndexError),msg:
680                err = str(msg)
681            if err:
682                datastructure.setError(widget_id, err)
683            else:
684                datamodel = datastructure.getDataModel()
685                datamodel[self.fields[0]] = value
686            return not err
687
688InitializeClass(WAeUPReservedRoomsWidget)
689
690widgetRegistry.register(WAeUPReservedRoomsWidget)
691###)
692
693class WAeUPIdWidget(CPSStringWidget): ###(
694    """ WAeUPId Widget"""
695    meta_type = "WAeUPId Widget"
696
697    def validate(self, datastructure, **kw):
698        """Validate datastructure and update datamodel."""
699        mode = kw.get('mode','create')
700        valid = CPSStringWidget.validate(self, datastructure, **kw)
701        id_pat_str = r"\S"
702        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
703        if not valid:
704            return 0
705        else:
706            portal_type_query = {'query':[#'Faculty',
707                                          'Department',
708                                          'Course',
709                                          'Certificate',
710                                          #'CertificateCourse',
711                                         ]}
712            widget_id = self.getWidgetId()
713            value = datastructure[widget_id]  #.upper()  is not necessary here because it's also done in waeup_document_create_do
714            err = 0
715            mapping = {}
716            if len(value.split()) > 1 and mode != 'remove':
717                err = 'Invalid Id, Id contains space(s).'
718            elif mode == "create" and\
719                          self.portal_catalog(portal_type=portal_type_query,id=value):
720                brain = self.portal_catalog(portal_type=portal_type_query,id=value)[0]
721                err = 'An ${portal_type} object with the Id ${id} already exists at ${path}.'
722                mapping = {'portal_type': brain.portal_type,
723                           'id': value,
724                           'path': brain.getPath(),
725                           }
726            if err:
727                datastructure.setError(widget_id, err, mapping)
728            else:
729                datamodel = datastructure.getDataModel()
730                datamodel[self.fields[0]] = value
731
732            return not err
733
734InitializeClass(WAeUPIdWidget)
735
736widgetRegistry.register(WAeUPIdWidget)
737
738
739###)
740
741class StudyCourseWidget(CPSStringWidget): ###(
742    """ StudyCourse Widget"""
743    meta_type = "StudyCourse Widget"
744
745    def validate(self, datastructure, **kw):
746        """Validate datastructure and update datamodel."""
747        #from Products.zdb import set_trace
748        #set_trace()
749        valid = CPSStringWidget.validate(self, datastructure, **kw)
750        if not valid:
751            return 0
752        widget_id = self.getWidgetId()
753        #value = makeCertificateCode(datastructure[widget_id]).upper()
754        value = datastructure[widget_id].upper()
755        #id_pat_str = r"\S"
756        #inv_id_pat = re.compile(r"^%s$" % id_pat_str)
757        err = 0
758        if len(value.split()) > 1:
759            err = 'Invalid Id, Id contains space(s).'
760        elif not self.portal_catalog(portal_type='Certificate',id=value):
761            err = 'No such certificate'
762        if err:
763            datastructure.setError(widget_id, err)
764        else:
765            datamodel = datastructure.getDataModel()
766            datamodel[self.fields[0]] = value
767        return not err
768
769InitializeClass(StudyCourseWidget)
770
771widgetRegistry.register(StudyCourseWidget)
772###)
773
774class VocabularyOnTheFly: ###(
775    def __init__(self, tuples):
776        """a nonpersistent vocabulary (copy from CPSSchemas.Vocabulary.Vocabulary).
777        Allowed parameter syntaxes is:
778          - Vocabulary((('foo', "Foo", 'label_foo'), ('bar', "Bar", 'label_bar')))
779            Same as first with message ids (msgids) that can be used for i18n
780        """
781        l = []
782        d = {}
783        m = {}
784        # We suppose that initial vocabulary is sorted
785        # Vocabulary((('foo', "Foo", 'label_foo'), ('bar', "Bar", 'label_bar')))
786        for k, v, msgid in tuples:
787            l.append(k)
788            d[k] = v
789            m[k] = msgid
790        self._list = l
791        self._dict = d
792        self._msgids = m
793
794    def __getitem__(self, key):
795        """Get a label for a key."""
796        return self._dict[key]
797
798    def get(self, key, default=None):
799        """Get a label for a key, default to None."""
800        try:
801            v = self._dict.get(key, default)
802        except TypeError:
803            # XXX temporary fix, don't know why sometime rendering try to do
804            # get([]) that returning a typeError
805            return ''
806        return v
807
808    def getMsgid(self, key, default=None):
809        """Get a msgid for a key, default to None."""
810        return self._msgids.get(key, default)
811
812    def has_key(self, key):
813        """Test if a key is present."""
814        return self._dict.has_key(key)
815
816    def keys(self):
817        """Get the ordered list of keys."""
818        return self._list[:]
819
820    def items(self):
821        """Get the ordered list of (key, value)."""
822        return [(key, self._dict.get(key)) for key in self._list]
823
824    def values(self):
825        """Get the ordered list of values."""
826        return [self._dict.get(key) for key in self._list]
827
828    def keysSortedBy(self, crit='id'):
829        """Return a keys list sorted on a criterium
830
831        Crit is one of 'id', 'label' or 'i18n'.
832        """
833
834        if crit == 'label':
835            l = [(x[1], x[0]) for x in self.items()]
836            l.sort()
837            return [x[1] for x in l]
838        elif crit == 'i18n':
839            portal = getToolByName(self, 'portal_url').getPortalObject()
840            cpsmcat = portal.translation_service
841            l = [(cpsmcat(self.getMsgid(key)).encode('ISO-8859-15', 'ignore'),
842                  key) for key in self.keys()]
843            l.sort()
844            return [x[1] for x in l]
845        else:
846            return self.keys()
847###)
848
849class ApplicationCourseWidget(CPSSelectWidget): ###(
850    """ ApplicationCourse Widget"""
851    meta_type = "Application Course Widget"
852
853    def _getVocabulary(self,datastructure=None):
854        if self.REQUEST.traverse_subpath:
855            screening_type = self.REQUEST.traverse_subpath[0].lower()
856        else:
857            screening_type = 'all'
858        if screening_type in ("all","sandwich","sandwich2008","pg_ft","pg_pt"):
859            application_category = screening_type
860        elif screening_type in ("cest","dp","ct","pt"):
861            application_category = "cest"
862        else:
863            application_category = "basic"
864        if not hasattr(self,'_v_certificates_docs'):
865            # res = self.portal_catalog_real.search({'meta_type': "Certificate"})
866            # d = {}
867            # for cert in res:
868            #     c = cert.getObject().getContent()
869            #     if getattr(c,'application_category',''):
870            #         d[cert.getId] = c
871            res = self.certificates_catalog()
872            d = {}
873            for cert in res:
874                if getattr(cert,'application_category',''):
875                    d[cert.code] = cert
876            self._v_certificates_docs = d
877        l  = [('','','')]
878        #l = []
879        for k,d in self._v_certificates_docs.items():
880            if application_category == "all":
881                l  += (k,self._v_certificates_docs[k].title,k),
882            else:
883                if getattr(d,'application_category','') == application_category:
884                    l  += (k,self._v_certificates_docs[k].title,k),
885        #import ipdb;ipdb.set_trace()
886        return VocabularyOnTheFly(l)
887
888InitializeClass(ApplicationCourseWidget)
889
890widgetRegistry.register(ApplicationCourseWidget)
891###)
892
893class JambRegNoWidget(CPSStringWidget): ###(
894    """ JambRegNo Widget"""
895    meta_type = "JambRegNo Widget"
896    _properties = CPSStringWidget._properties + (
897        {'id': 'catalog', 'type': 'string', 'mode': 'w',
898         'label': 'Catalog to search'},
899         {'id': 'reference', 'type': 'string', 'mode': 'w',
900         'label': 'Reference Field'},
901         )
902    #catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
903    reference = ""
904    digits = 8
905    digits_str = "N"*digits
906    letters = 2
907    letters_str = "L"*letters
908    def validate(self, datastructure, **kw):
909        """Validate datastructure and update datamodel."""
910        valid = CPSStringWidget.validate(self, datastructure, **kw)
911        reg_no_catalog = getattr(self,self.catalog)
912        widget_id = self.getWidgetId()
913        value = datastructure[widget_id].upper()
914        err = 0
915        #import pdb;pdb.set_trace()
916        if kw.has_key('mode'):
917            mode = kw['mode']
918        else:
919            mode = "edit"
920        if not valid:
921            err = 'Invalid registration number'
922        elif self.reference == '':
923            #s = getStudentByRegNo(self,value)
924            student_record = reg_no_catalog(jamb_reg_no = value)
925            if len(student_record) < 1:
926                err = 'No student record with this registration number'
927            #elif self.catalog == "students_catalog" and student_record[0].review_state not in ('student_created','admitted'):
928            #    err = 'Admission checking not allowed (wrong registration state)'
929            else:
930                datastructure['pume'] = student_record[0]
931        elif mode == 'add':
932            pass
933        elif self.reference != '' and self.catalog == "applicants_catalog":
934            res = reg_no_catalog.searchResults({"%s" % self.reference: value})
935            if len(res) != 1:
936                err = 'No record with this registration number'
937            else:
938                datastructure['record'] = res[0]
939        else:
940            record = datastructure[self.reference]
941            #jamb_reg_no = getattr(record,widget_id)
942            jamb_reg_no = record.Entryregno
943            if jamb_reg_no != value:
944                err = 'Registration number does not match.'
945        if err:
946            datastructure.setError(widget_id, err)
947        else:
948            datamodel = datastructure.getDataModel()
949            datamodel[self.fields[0]] = value
950        return not err
951
952InitializeClass(JambRegNoWidget)
953
954widgetRegistry.register(JambRegNoWidget)
955###)
956
957class SecretWidget(CPSStringWidget): ###(
958    """ Secret Widget"""
959    meta_type = "Secret Widget"
960    _properties = CPSStringWidget._properties + (
961        {'id': 'reference', 'type': 'string', 'mode': 'w',
962         'label': 'Reference Record'},
963         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
964         'label': 'Fields to check'},
965         )
966    reference = "student"
967    matric_no_catalog = 'returning_import'
968    check_fields = ("Firstname", "Middlename","Lastname")
969    def validate(self, datastructure, **kw):
970        """Validate datastructure and update datamodel."""
971        logger = logging.getLogger('Widgets.SecretWidget.validate')
972        valid = CPSStringWidget.validate(self, datastructure, **kw)
973        widget_id = self.getWidgetId()
974        value = datastructure[widget_id].upper()
975        err = 0
976        record = datastructure.get(self.reference,None)
977        #import pdb;pdb.set_trace()
978        if not valid or len(value) < 2:
979            err = 'Invalid string'
980        elif not record or datastructure.errors:
981            err = 0
982        else:
983            found = False
984            cvs = []
985            for field in self.check_fields:
986                cv = getattr(record,field).upper()
987                if len(cv.split()) > 1:
988                    for splited in cv.split():
989                        cvs.append(splited.strip())
990                else:
991                    cvs.append(cv.strip(),)
992            for cv in cvs:
993                if cv  == value.strip().upper():
994                    found = True
995                    break
996            matric_no = record.matric_no
997            name = " ".join(cvs)
998            if not found:
999                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
1000                err = 'No name does match.'
1001            else:
1002                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
1003        if err:
1004            datastructure.setError(widget_id, err)
1005        else:
1006            datamodel = datastructure.getDataModel()
1007            datamodel[self.fields[0]] = value
1008        return not err
1009
1010InitializeClass(SecretWidget)
1011
1012widgetRegistry.register(SecretWidget)
1013###)
1014
1015class WAeUPSexWidget(CPSBooleanWidget): ###(
1016    """WAeUP sex widget."""
1017    meta_type = 'WAeUP Sex Widget'
1018
1019    def validate(self, datastructure, **kw):
1020        """Validate datastructure and update datamodel."""
1021        value = datastructure[self.getWidgetId()]
1022
1023        if self.render_format not in self.render_formats:
1024            self.render_format = 'select'
1025
1026        female = value in ('F','f','Female','female','True','true','TRUE',True)
1027        male = value in ('M','m','Male','male','False','false','FALSE',False)
1028        if not female and not male:
1029            datastructure.setError(self.getWidgetId(),
1030                                   "invalid sex %s" % value)
1031            return 0
1032        elif female:
1033            v = True
1034        else:
1035            v = False
1036        datamodel = datastructure.getDataModel()
1037        datamodel[self.fields[0]] = v
1038        return 1
1039
1040InitializeClass(WAeUPSexWidget)
1041
1042widgetRegistry.register(WAeUPSexWidget)
1043
1044###)
1045
1046class WAeUPBooleanWidget(CPSBooleanWidget): ###(
1047    """WAeUP boolean widget."""
1048    meta_type = 'WAeUP Boolean Widget'
1049
1050    def validate(self, datastructure, **kw):
1051        """Validate datastructure and update datamodel."""
1052        value = datastructure[self.getWidgetId()]
1053
1054        if self.render_format not in self.render_formats:
1055            self.render_format = 'select'
1056        true = value.upper() in ('T','1','TRUE','True','true','WAHR',True)
1057        false = value.upper() in ('F','0','FALSE','False','false','FALSCH',False)
1058        if not true and not false:
1059            datastructure.setError(self.getWidgetId(),
1060                                   "invalid boolean %s" % value)
1061            return 0
1062        elif true:
1063            v = True
1064        else:
1065            v = False
1066        datamodel = datastructure.getDataModel()
1067        datamodel[self.fields[0]] = v
1068        return 1
1069
1070InitializeClass(WAeUPBooleanWidget)
1071
1072widgetRegistry.register(WAeUPBooleanWidget)
1073
1074###)
1075
1076class MatricNoWidget(CPSStringWidget): ###(
1077    """ MatricNo Widget"""
1078    meta_type = "MatricNo Widget"
1079
1080    _properties = CPSStringWidget._properties + (
1081        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
1082         'label': 'Catalog to search for MatricNo'},
1083        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
1084         'label': 'Results Catalog'},
1085         )
1086    matric_no_catalog = "" #the catalog to search for matric_no
1087    results_catalog = "results_import" #results catalog
1088
1089    def validate(self, datastructure, **kw):
1090        """Validate datastructure and update datamodel."""
1091        #import pdb;pdb.set_trace()
1092        valid = CPSStringWidget.validate(self, datastructure, **kw)
1093        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
1094        returning = getattr(self,self.matric_no_catalog)
1095        results = getattr(self,self.results_catalog,None)
1096        err = 0
1097        widget_id = self.getWidgetId()
1098        value = datastructure[widget_id]
1099        if not valid or not value:
1100            err = 'Invalid string'
1101            logger.info('Invalid matric_no string %s' % value)
1102        else:
1103            value = value.upper()
1104            datastructure['student'] = None
1105            while not err:
1106                res = returning(matric_no = value)
1107                if len(res) < 1:
1108                    logger.info('matric_no %s not found' % value)
1109                    err = 'No student with this matriculation number.'
1110                    break
1111                datastructure['student'] = res[0]
1112                if results is not None:
1113                    res = results(matric_no = value)
1114                    if len(res) < 1:
1115                        err = 'No results for this matriculation number'
1116                        continue
1117                    datastructure['results'] = res
1118                break
1119        if err:
1120            datastructure.setError(widget_id, err)
1121        else:
1122            datamodel = datastructure.getDataModel()
1123            datamodel[self.fields[0]] = value
1124        return not err
1125
1126InitializeClass(MatricNoWidget)
1127
1128widgetRegistry.register(MatricNoWidget)
1129###)
1130
1131class StudentIdWidget(CPSStringWidget): ###(
1132    """ StudentId Widget"""
1133    meta_type = "StudentId Widget"
1134    def validate(self, datastructure, **kw):
1135        """Validate datastructure and update datamodel."""
1136        valid = CPSStringWidget.validate(self, datastructure, **kw)
1137        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
1138        #import pdb;pdb.set_trace()
1139        s_cat = self.students_catalog
1140        err = 0
1141        widget_id = self.getWidgetId()
1142        value = datastructure[widget_id]
1143        if not valid or not value:
1144            err = 'Invalid Id string'
1145            logger.info('Invalid id string %s' % value)
1146            datastructure['student'] = None
1147        else:
1148            value = value.upper()
1149            res = s_cat(id = value)
1150            if not res:
1151                logger.info('Student id %s not found' % value)
1152                err = 'No student with this Id'
1153                datastructure['student'] = None
1154            else:
1155                datastructure['student'] = res[0]
1156        if err:
1157            datastructure.setError(widget_id, err)
1158        else:
1159            datamodel = datastructure.getDataModel()
1160            datamodel[self.fields[0]] = value
1161        return not err
1162
1163InitializeClass(StudentIdWidget)
1164
1165widgetRegistry.register(StudentIdWidget)
1166###)
1167
1168class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
1169    """ WAeUPMultilineResults Widget"""
1170    meta_type = "WAeUp Multiline Results Widget"
1171    _properties = CPSWidget._properties + (
1172        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
1173         'label': 'Nr of Lines'},
1174         )
1175    nr_of_lines = 5
1176    def prepare(self, datastructure, **kw): ###(
1177        """Prepare datastructure from datamodel."""
1178        datamodel = datastructure.getDataModel()
1179        #import pdb;pdb.set_trace()
1180        widget_id = self.getWidgetId()
1181        v = datamodel[self.fields[0]]
1182        if type(v) is ListType and v:
1183            nr_results = len(v)
1184        else:
1185            v = []
1186            nr_results = 0
1187        count = 1
1188        for s,g in v:
1189            wid = "%s%02d"% (widget_id,count)
1190            datastructure[wid+'_s'] = s
1191            datastructure[wid+'_g'] = g
1192            count += 1
1193        if nr_results < self.nr_of_lines:
1194            for line in range(nr_results,self.nr_of_lines):
1195                v.append(('',''))
1196                wid = "%s%02d"% (widget_id,line)
1197                datastructure[wid+'_s'] = ''
1198                datastructure[wid+'_g'] = ''
1199        datastructure[widget_id] = v
1200        datastructure[widget_id+'_s'] = ''
1201        datastructure[widget_id+'_g'] = ''
1202    ###)
1203
1204    def validate(self, datastructure, **kw): ###(
1205        """Validate datastructure and update datamodel."""
1206        #import pdb;pdb.set_trace()
1207        widget_id = self.getWidgetId()
1208        err = 0
1209        lines = []
1210        for line in range(1,30):
1211            wid = "%s%02d"% (widget_id,line)
1212            if not datastructure.has_key(wid+'_s'):
1213                break
1214            lines.append((datastructure[wid+'_s'].strip(),
1215                         datastructure[wid+'_g'].strip()))
1216
1217        s = datastructure[widget_id+'_s'].strip()
1218        g = datastructure[widget_id+'_g'].strip()
1219        if s and g:
1220            lines.append((s,g))
1221        active = []
1222        for s,g in lines:
1223            if g != "":
1224                active.append((s,g))
1225        if err:
1226            datastructure.setError(widget_id, err)
1227        else:
1228            datamodel = datastructure.getDataModel()
1229            datamodel[self.fields[0]] = active
1230        return not err
1231    ###)
1232
1233    def render(self, mode, datastructure, **kw): ###(
1234        """Render in mode from datastructure."""
1235        render_method = 'widget_waeup_multiline_result_render'
1236        meth = getattr(self, render_method, None)
1237        if meth is None:
1238            raise RuntimeError("Unknown Render Method %s for widget type %s"
1239                               % (render_method, self.getId()))
1240        #import pdb;pdb.set_trace()
1241        datamodel = datastructure.getDataModel()
1242        widget_id = self.getWidgetId()
1243        lines = datamodel[self.fields[0]]
1244        if len(lines) < self.nr_of_lines:
1245            for line in range(len(lines),self.nr_of_lines + 1):
1246                lines.append(('',''))
1247        datastructure[widget_id] = lines
1248        datastructure[widget_id+'_s'] = ''
1249        datastructure[widget_id+'_g'] = ''
1250##        count = 1
1251##        for s,g in v:
1252##            wid = "%s%02d"% (widget_id,count)
1253##            count += 1
1254        return meth(mode=mode,
1255                    datastructure=datastructure,
1256                    )
1257    ###)
1258
1259
1260InitializeClass(WAeUPMultilineResultsWidget)
1261widgetRegistry.register(WAeUPMultilineResultsWidget)
1262###)
1263
1264class WAeUPResultsWidget(CPSStringWidget): ###(
1265    """ WAeUPResults Widget"""
1266    meta_type = "WAeUp Results Widget"
1267
1268    def prepare(self, datastructure, **kw): ###(
1269        """Prepare datastructure from datamodel."""
1270        datamodel = datastructure.getDataModel()
1271        v = datamodel[self.fields[0]]
1272        #import pdb;pdb.set_trace()
1273        widget_id = self.getWidgetId()
1274        datastructure[widget_id] = v
1275        datastructure[widget_id+'_s'] = ''
1276        datastructure[widget_id+'_g'] = ''
1277    ###)
1278
1279    def validate(self, datastructure, **kw): ###(
1280        """Validate datastructure and update datamodel."""
1281        #import pdb;pdb.set_trace()
1282        widget_id = self.getWidgetId()
1283        v = datastructure[widget_id]
1284        if not v:
1285            v = []
1286        err = 0
1287        s = datastructure[widget_id+'_s'].strip()
1288        g = datastructure[widget_id+'_g'].strip()
1289        while 1:
1290            if not s and g:
1291                err = "No subject grade for subject"
1292                break
1293            i = 0
1294            done = False
1295            #import pdb;pdb.set_trace()
1296            for sv,gv in v:
1297                if sv == s:
1298                    done = True
1299                    if not g:
1300                        v.pop(i)
1301                        break
1302                    v[i] = (s,g)
1303                    break
1304                i += 1
1305            if done:
1306                break
1307            if s and g:
1308                if v:
1309                    v += (s,g),
1310                else:
1311                    v = [(s,g),]
1312            break
1313        if err:
1314            datastructure.setError(widget_id, err)
1315        else:
1316            datamodel = datastructure.getDataModel()
1317            datamodel[self.fields[0]] = v
1318            datastructure[widget_id] = v
1319            datastructure[widget_id+'_s'] = s
1320            datastructure[widget_id+'_g'] = g
1321        return not err
1322    ###)
1323
1324    def render(self, mode, datastructure, **kw): ###(
1325        """Render in mode from datastructure."""
1326        render_method = 'widget_waeup_result_render'
1327        meth = getattr(self, render_method, None)
1328        if meth is None:
1329            raise RuntimeError("Unknown Render Method %s for widget type %s"
1330                               % (render_method, self.getId()))
1331        datamodel = datastructure.getDataModel()
1332        widget_id = self.getWidgetId()
1333        datastructure[widget_id+'_s'] = ''
1334        datastructure[widget_id+'_g'] = ''
1335        return meth(mode=mode,
1336                    datastructure=datastructure,
1337                    )
1338    ###)
1339
1340
1341InitializeClass(WAeUPResultsWidget)
1342widgetRegistry.register(WAeUPResultsWidget)
1343###)
1344
1345class ScratchCardPin: ###(
1346    """the ScratchCardPin"""
1347    def __init__(self,prefix,batch_no,number):
1348        if not batch_no and not number:
1349            s = prefix
1350            if len(s) > 3:
1351                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1352            else:
1353                prefix,batch_no,number = s,'',''
1354        self.p = prefix
1355        self.b = batch_no
1356        self.n = number
1357
1358    def __str__(self):
1359        return "%s-%s-%s" % (self.p,self.b,self.n)
1360
1361    def __repr__(self):
1362        return "%s%s%s" % (self.p,self.b,self.n)
1363###)
1364
1365class ScratchcardPinWidget(CPSStringWidget): ###(
1366    """ ScratchcardPin Widget"""
1367    meta_type = "Scratchcard Pin Widget"
1368    _properties = CPSWidget._properties + (
1369        {'id': 'prefix', 'type': 'string', 'mode': 'w',
1370         'label': 'Prefix'},
1371         {'id': 'reference', 'type': 'string', 'mode': 'w',
1372         'label': 'Reference Field'},
1373         {'id': 'reuse_pin', 'type': 'boolean', 'mode': 'w',
1374         'label': 'Reuse Application Pin'},
1375        )
1376    prefix = ''
1377    reference = ''
1378    reuse_pin = False
1379
1380    def prepare(self, datastructure, **kw): ###(
1381        """Prepare datastructure from datamodel."""
1382        datamodel = datastructure.getDataModel()
1383        v = datamodel[self.fields[0]]
1384        widget_id = self.getWidgetId()
1385        if v and type(v) is StringType:
1386            try:
1387                p,b,n = v.split('-')
1388                v = ScratchCardPin(p,b,n)
1389            except ValueError:
1390                v = ScratchCardPin(v,'','')
1391        if v:
1392            p = '%s' % v.p
1393            b = '%s' % v.b
1394            n = '%s' % v.n
1395        else:
1396            p = self.prefix
1397            if p.startswith('@'):
1398                p = getattr(self,self.prefix[1:])()
1399            b = n = ''
1400            v = ScratchCardPin(p,b,n)
1401        datastructure[widget_id] = v
1402        datastructure[widget_id+'_p'] = p
1403        datastructure[widget_id+'_b'] = b
1404        datastructure[widget_id+'_n'] = n
1405    ###)
1406
1407    def validate(self, datastructure, **kw): ###(
1408        """Validate datastructure and update datamodel."""
1409        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1410        widget_id = self.getWidgetId()
1411        v = datastructure[widget_id]
1412        #import pdb;pdb.set_trace()
1413        err = 0
1414        mapping = {}
1415        prefix= self.prefix
1416        if prefix.startswith('@'):
1417            prefix= getattr(self,self.prefix[1:])()
1418        b = datastructure[widget_id+'_b'].strip()
1419        n = datastructure[widget_id+'_n'].strip()
1420        pins = self.portal_pins
1421        pin = "%(prefix)s%(b)s%(n)s" % vars()
1422        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1423        do = 1
1424        s_id = str(self.portal_membership.getAuthenticatedMember())
1425        if self.isStaff():
1426            do = 0
1427            err ='You are not a Student. PIN neither checked nor used.'
1428            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1429        elif len(b) > 1 and b.find('-') > -1:
1430            do = 0
1431            err = 'PIN must not contain "-".'
1432            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1433        elif n.find('-') > -1:
1434            do = 0
1435            err = 'PIN must not contain "-".'
1436            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1437        elif len(n) != 10:
1438            do = 0
1439            err = 'Invalid PIN length'
1440            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1441        elif self.reference == "":
1442            ref = s_id
1443        else:
1444            ref = datastructure[self.reference]
1445            if datastructure.errors:
1446                do = 0
1447                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1448                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1449            elif prefix == 'APP' and not self.reuse_pin:
1450                res =  self.applicants_catalog(reg_no = ref)
1451                if not res:
1452                    res =  self.applicants_catalog(reg_no = ref.upper())
1453                if res and res[0].pin == pin_str:
1454                    do = 0
1455                    err = 'Application PINs cannot be reused.'
1456                    s_logger.info('%s entered same PIN as for screening application %s' % (s_id,pin_str))
1457
1458        while do:
1459            ok,record = pins.searchAndSetRecord(pin,ref,prefix)
1460            if ok < -2 or ok > 2:
1461                err = 'Unknown error, please report!'
1462                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1463                break
1464            elif ok == -2:
1465                err = 'Service already is activated but with a different PIN.'
1466                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1467                break
1468            elif ok == -1:
1469                err = 'Invalid PIN'
1470                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1471                break
1472            if ok == 0:
1473                err = 'PIN already used'
1474                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1475                break
1476            if ok >= 1:
1477                #import pdb;pdb.set_trace()
1478                if self.isStudent():
1479                    if self.reference == "jamb_reg_no":
1480                        err = "You are already logged in."
1481                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1482                        break
1483                    if ok == 1:
1484                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1485                    else:
1486                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1487                    break
1488                else:
1489                    student = getStudentByRegNo(self,ref)
1490                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1491                if student is None:
1492                    err = "Student record not found."
1493                    s_logger.info('%s not found in admission list' % (ref))
1494                    break
1495                s_id = student.getId()
1496                if ok == 2:
1497                    if self.reference == "jamb_reg_no":
1498                        if hasattr(self.portal_directories.students,s_id):
1499                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1500                            mapping = {'id': s_id}
1501                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1502                            break
1503                        else:
1504                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1505                    else:
1506                        err = "Unknown error"
1507                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1508                        break
1509                try:
1510                    student.getContent().makeStudentMember(s_id,password=n)
1511                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1512                except:
1513                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1514                    mapping = {'id': s_id}
1515                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1516                    break
1517            break
1518        if err:
1519            datastructure.setError(widget_id, err,mapping)
1520        else:
1521            datamodel = datastructure.getDataModel()
1522            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1523            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1524            datastructure[widget_id+'_p'] = prefix
1525            datastructure[widget_id+'_b'] = b
1526            datastructure[widget_id+'_n'] = n
1527            datastructure['s_id'] = s_id
1528        return not err
1529
1530###)
1531
1532    def render(self, mode, datastructure, **kw): ###(
1533        """Render in mode from datastructure."""
1534        render_method = 'widget_scratch_card_pin_render'
1535        meth = getattr(self, render_method, None)
1536        if meth is None:
1537            raise RuntimeError("Unknown Render Method %s for widget type %s"
1538                               % (render_method, self.getId()))
1539
1540        # XXX AT: datastructure has to be set again here, in case we're in edit
1541        # or create mode, because a default value has to be provided.
1542        #import pdb;pdb.set_trace()
1543        datamodel = datastructure.getDataModel()
1544        v = datamodel[self.fields[0]]
1545        if v and type(v) is StringType:
1546            try:
1547                p,b,n = v.split('-')
1548                v = ScratchCardPin(p,b,n)
1549            except ValueError:
1550                v = ScratchCardPin(self.prefix,'XXX',v)
1551                pass
1552        if v:
1553            prefix= '%s' % v.p
1554            b = '%s' % v.b
1555            n = '%s' % v.n
1556        else:
1557            prefix= self.prefix
1558            if prefix.startswith('@'):
1559                prefix= getattr(self,self.prefix[1:])()
1560            b = n = ''
1561            v = ScratchCardPin(prefix,b,n)
1562        widget_id = self.getWidgetId()
1563        datastructure[widget_id] = v
1564        datastructure[widget_id+'_p'] = prefix
1565        datastructure[widget_id+'_b'] = b
1566        datastructure[widget_id+'_n'] = n
1567        return meth(mode=mode,
1568                    datastructure=datastructure,
1569                    )
1570    ###)
1571
1572InitializeClass(ScratchcardPinWidget)
1573widgetRegistry.register(ScratchcardPinWidget)
1574###)
1575
1576class PumePinWidget(ScratchcardPinWidget): ###(
1577    """ Pume Pin Widget"""
1578    meta_type = "Pume Pin Widget"
1579    catalog = "applicants_catalog"
1580    reference = ''
1581
1582    def prepare(self, datastructure, **kw): ###(
1583        """Prepare datastructure from datamodel."""
1584        datamodel = datastructure.getDataModel()
1585        #import pdb;pdb.set_trace()
1586        v = datamodel[self.fields[0]]
1587        widget_id = self.getWidgetId()
1588        if v and type(v) is StringType:
1589            try:
1590                p,b,n = v.split('-')
1591                v = ScratchCardPin(p,b,n)
1592            except ValueError:
1593                v = ScratchCardPin(v,'','')
1594        if v:
1595            p = '%s' % v.p
1596            b = '%s' % v.b
1597            n = '%s' % v.n
1598        else:
1599            p = self.prefix
1600            if p.startswith('@'):
1601                p = getattr(self,self.prefix[1:])()
1602            b = n = ''
1603            v = ScratchCardPin(p,b,n)
1604        datastructure[widget_id] = v
1605        datastructure[widget_id+'_p'] = p
1606        datastructure[widget_id+'_b'] = b
1607        datastructure[widget_id+'_n'] = n
1608    ###)
1609
1610    def validate(self, datastructure, **kw): ###(
1611        """Validate datastructure and update datamodel."""
1612        s_logger = logging.getLogger('Widgets.PumePinWidget.validate')
1613        widget_id = self.getWidgetId()
1614        v = datastructure[widget_id]
1615        err = 0
1616        mapping = {}
1617        prefix= self.prefix
1618        if prefix.startswith('@'):
1619            prefix= getattr(self,self.prefix[1:])()
1620        b = datastructure[widget_id+'_b'].strip()
1621        n = datastructure[widget_id+'_n'].strip()
1622        pins = self.portal_pins
1623        pin = "%(prefix)s%(b)s%(n)s" % vars()
1624        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1625        member_id = str(self.portal_membership.getAuthenticatedMember())
1626        do = 1
1627        expiration_date = self.REQUEST.get('expiration_date')
1628        if self.isStaff():
1629            do = 0
1630            err ='You are logged in, please log out. PIN neither checked nor used.'
1631            s_logger.info('%s tried to use scratch card %s' % (member_id,pin_str))
1632        elif self.isStudent():
1633            do = 0
1634            #ref = datastructure[self.reference]
1635            err ='You are logged in, please log out. PIN neither checked nor used.'
1636            s_logger.info('%s applied for screening test while logged in with pin %s' % (member_id,pin_str))
1637        elif len(b) > 1 and b.find('-') > -1:
1638            do = 0
1639            err = 'PIN must not contain "-"'
1640            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1641        elif n.find('-') > -1:
1642            do = 0
1643            err = 'PIN must not contain "-"'
1644            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1645        elif len(n) != 10:
1646            do = 0
1647            err = 'Invalid PIN length'
1648            s_logger.info('%s entered invalid PIN with length %d' % (member_id,len(n)))
1649        elif self.reference == "":
1650            # see fceokene #147. must be also changed for uniben after clearing the catalog
1651            #import pdb;pdb.set_trace()
1652            if 'sandwich2008' in self.REQUEST.get('screening_type'):
1653                ref = n
1654            else:
1655                ref = pin
1656        else:
1657            ref = datastructure[self.reference]
1658            if datastructure.errors:
1659                do = 0
1660                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1661                s_logger.info('%s/%s entered wrong data together with PIN %s' % (member_id,ref,pin_str))
1662        while do:
1663            if self.REQUEST.traverse_subpath:
1664                screening_type_request = self.REQUEST.traverse_subpath[0]
1665            else:
1666                screening_type_request = 'manage'
1667            if datastructure.has_key('record'):
1668                applicant = datastructure['record']
1669                if applicant.screening_type != screening_type_request and screening_type_request != 'manage':
1670                    err = "You are using the wrong access form!"
1671                    s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1672                    break
1673            elif expiration_date and DateTime(expiration_date).lessThan(DateTime()):
1674                if not pins(student=ref):
1675                    if not self.applicants_catalog(reg_no=ref):
1676                        err = 'no application record found'
1677                        s_logger.info('%s/%s tried new application though expired with PIN %s' % (member_id,ref,pin_str))
1678                        break
1679                    else:
1680                        s_logger.info('%s/%s entered application record which has been created by import (with PIN %s)' % (member_id,ref,pin_str))
1681            ok,pin_record = pins.searchAndSetRecord(pin,ref,prefix)
1682            if ok < -2 or ok > 2:
1683                err = 'Unknown error, please report!'
1684                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
1685                break
1686            elif ok == -2:
1687                err = 'Service is already activated but with a different PIN.'
1688                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
1689                break
1690            elif ok == -1:
1691                err = 'Invalid PIN'
1692                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
1693                break
1694            if ok == 0:
1695                err = 'PIN already used'
1696                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
1697                break
1698            if ok >= 1:
1699                #screening_type = self.REQUEST.form.get('screening_type','unknown')
1700                #screening_type = datastructure['screening_type']
1701                if datastructure.has_key('record'):
1702                    applicant = datastructure['record']
1703                    if applicant.screening_type != screening_type_request\
1704                          and screening_type_request != 'manage':
1705                        err = "You are using the wrong access form!"
1706                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1707                        break
1708                    if not applicant.pin:
1709                        s_logger.info('%s successfully used PIN %s, imported applicant record modified' % (ref,pin_str))
1710                        d = {}
1711                        d['reg_no'] = applicant.reg_no
1712                        d['pin'] = pin_str
1713                        #d['screening_type'] = screening_type
1714                        #d['status'] = 'entered'
1715                        getattr(self,self.catalog).modifyRecord(**d)
1716                    elif applicant.pin != pin_str:
1717                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
1718                    #elif applicant.pin == pin_str:
1719                        #s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1720                else:
1721                    datastructure['reg_no'] = ref
1722                    res = self.applicants_catalog(reg_no = ref)
1723                    if res:
1724                        if getattr(res[0],'screening_type',None) != screening_type_request\
1725                              and screening_type_request != 'manage':
1726                            err = "You are using the wrong access form!"
1727                            s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,getattr(res[0],'screening_type',None)))
1728                            break
1729                        #s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1730                    else:
1731                        s_logger.info('%s successfully used PIN %s, applicant record added' % (ref,pin_str))
1732                        d = {}
1733                        d['reg_no'] = ref
1734                        d['pin'] = pin_str
1735                        d['status'] = 'entered'
1736                        d['screening_type'] = screening_type_request
1737                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
1738                                                  pin_record.serial)
1739                        self.applicants_catalog.addRecord(**d)
1740
1741            break
1742        if err:
1743            datastructure.setError(widget_id, err,mapping)
1744        else:
1745            datamodel = datastructure.getDataModel()
1746            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1747            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1748            datastructure[widget_id+'_p'] = prefix
1749            datastructure[widget_id+'_b'] = b
1750            datastructure[widget_id+'_n'] = n
1751        return not err
1752    ###)
1753
1754    def render(self, mode, datastructure, **kw): ###(
1755        """Render in mode from datastructure."""
1756        render_method = 'widget_scratch_card_pin_render'
1757        meth = getattr(self, render_method, None)
1758        if meth is None:
1759            raise RuntimeError("Unknown Render Method %s for widget type %s"
1760                               % (render_method, self.getId()))
1761
1762        # XXX AT: datastructure has to be set again here, in case we're in edit
1763        # or create mode, because a default value has to be provided.
1764        #import pdb;pdb.set_trace()
1765        datamodel = datastructure.getDataModel()
1766        v = datamodel[self.fields[0]]
1767        #import pdb;pdb.set_trace()
1768        if v and type(v) is StringType:
1769            try:
1770                p,b,n = v.split('-')
1771                v = ScratchCardPin(p,b,n)
1772            except ValueError:
1773                v = ScratchCardPin(self.prefix,'XXX',v)
1774                pass
1775        if v:
1776            prefix= '%s' % v.p
1777            b = '%s' % v.b
1778            n = '%s' % v.n
1779        else:
1780            prefix= self.prefix
1781            if prefix.startswith('@'):
1782                prefix= getattr(self,self.prefix[1:])()
1783            b = n = ''
1784            v = ScratchCardPin(prefix,b,n)
1785        widget_id = self.getWidgetId()
1786        datastructure[widget_id] = v
1787        datastructure[widget_id+'_p'] = prefix
1788        datastructure[widget_id+'_b'] = b
1789        datastructure[widget_id+'_n'] = n
1790        return meth(mode=mode,
1791                    datastructure=datastructure,
1792                    )
1793    ###)
1794
1795InitializeClass(PumePinWidget)
1796widgetRegistry.register(PumePinWidget)
1797###)
1798
1799class WAeUPImageWidget(CPSImageWidget): ###(
1800    """Photo widget."""
1801    meta_type = 'WAeUP Image Widget'
1802
1803    def render(self, mode, datastructure, **kw):
1804        render_method = 'widget_waeup_image_render'
1805        meth = getattr(self, render_method, None)
1806        if meth is None:
1807            raise RuntimeError("Unknown Render Method %s for widget type %s"
1808                               % (render_method, self.getId()))
1809        img_info = self.getImageInfo(datastructure)
1810        return meth(mode=mode, datastructure=datastructure, **img_info)
1811
1812InitializeClass(WAeUPImageWidget)
1813
1814widgetRegistry.register(WAeUPImageWidget)
1815###)
1816
1817class ApplicationImageWidget(CPSImageWidget): ###(
1818    """Image widget with filesystem storage."""
1819    meta_type = 'Application Image Widget'
1820    _properties = CPSImageWidget._properties +\
1821    (
1822     {'id': 'path', 'type': 'string', 'mode': 'w',
1823      'label': 'Relative Path'},
1824     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1825      'label': 'Field to build the id'},
1826    )
1827    path = "images"
1828    storage_path = "%s/import/%s" % (i_home,path)
1829    id_field = "reg_no"
1830
1831    def getImageInfo(self, datastructure): ###(
1832        """Get the file info from the datastructure."""
1833        widget_id = self.getWidgetId()
1834        if  datastructure.has_key(widget_id):
1835            fileupload = datastructure[widget_id]
1836            dm = datastructure.getDataModel()
1837            field_id = self.fields[0]
1838            screening_type = datastructure.get('screening_type')
1839            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1840                                            field_id,)
1841            base_path = os.path.join(screening_type,current_filename)
1842            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1843            file_path = os.path.join(self.storage_path,base_path)
1844            #import pdb; pdb.set_trace()
1845        else:
1846            file_path = "XXX"
1847        # read the file from the filesystem
1848        if not os.path.exists(file_path):
1849            height = -1
1850            width = -1
1851            empty_file = True
1852            session_file = False
1853            current_filename = ''
1854            content_url = ''
1855            size = 0
1856            mimetype = ''
1857            last_modified = ''
1858            height = ''
1859            width = ''
1860
1861        else:
1862            image = open(file_path)
1863            from OFS.Image import getImageInfo as getImageInfoOFS
1864            image.seek(0)
1865            data = image.read(2000)
1866            size = len(data)
1867            empty_file = size == 0
1868            session_file = False
1869            last_modified = ''
1870            image.close()
1871            mimetype, width, height = getImageInfoOFS(data)
1872
1873            if width < 0:
1874                width = None
1875            if height < 0:
1876                height = None
1877
1878            if (self.allow_resize
1879                and height is not None
1880                and width  is not None):
1881                z_w = z_h = 1
1882                h = int(self.display_height)
1883                w = int(self.display_width)
1884                if w and h:
1885                    if w < width:
1886                        z_w = w / float(width)
1887                    if h < height:
1888                        z_h = h / float(height)
1889                    zoom = min(z_w, z_h)
1890                    width = int(zoom * width)
1891                    height = int(zoom * height)
1892                #import pdb;pdb.set_trace()
1893        image_info = {
1894            'empty_file': empty_file,
1895            'session_file': session_file,
1896            'current_filename': current_filename,
1897            'size': size,
1898            'last_modified': last_modified,
1899            'content_url': content_url,
1900            'mimetype': mimetype,
1901            }
1902        title = image_info['current_filename']
1903        alt = title or ''
1904        #height = int(self.display_height)
1905        #width = int(self.display_width)
1906        if height is None or width is None:
1907            tag = renderHtmlTag('img', src=image_info['content_url'],
1908                                alt=alt, title=title)
1909        else:
1910            tag = renderHtmlTag('img', src=image_info['content_url'],
1911                                width=str(width), height=str(height),
1912                                alt=alt, title=title)
1913
1914        image_info['height'] = height
1915        image_info['width'] = width
1916        image_info['image_tag'] = tag
1917        return image_info
1918    ###)
1919
1920    def checkFileName(self, filename, mimetype):
1921        return '', {}
1922        if mimetype and mimetype.startswith('image'):
1923            return '', {}
1924        return 'cpsschemas_err_image', {}
1925
1926    def prepare(self, datastructure, **kw): ###(
1927        """Prepare datastructure from datamodel."""
1928        datamodel = datastructure.getDataModel()
1929        widget_id = self.getWidgetId()
1930        file_name = datamodel[self.fields[0]]
1931        #import pdb; pdb.set_trace()
1932        if self.allow_resize:
1933            datastructure[self.getWidgetId() + '_resize'] = ''
1934        screening_type = datamodel.get('screening_type',None)
1935        if not screening_type:
1936            screening_type = self.REQUEST.form.get('screening_type','pume')
1937        datastructure["screening_type"] = screening_type
1938        datastructure[widget_id] = file_name
1939        datastructure[widget_id + '_choice'] = 'change'
1940        title = 'Passport Foto'
1941        datastructure[widget_id + '_filename'] = title
1942    ###)
1943
1944    def validate(self, datastructure, **kw): ###(
1945        """Update datamodel from user data in datastructure.
1946        """
1947        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1948        datamodel = datastructure.getDataModel()
1949        field_id = self.fields[0]
1950        widget_id = self.getWidgetId()
1951        store = False
1952        fileupload = None
1953        mimetype = None
1954        old_file = datamodel[field_id]
1955        # if old_file is not None:
1956        #     old_filename = old_file.title
1957        # else:
1958        #     old_filename = ''
1959        choice = datastructure[widget_id+'_choice']
1960        fileupload = datastructure[widget_id]
1961        is_upload = isinstance(fileupload, FileUpload)
1962        #import pdb; pdb.set_trace()
1963        if not is_upload and not datamodel[field_id]:
1964            if self.is_required:
1965                return self.validateError('Picture upload required', {},
1966                                          datastructure)
1967        if choice == 'delete':
1968            if self.is_required:
1969                return self.validateError('cpsschemas_err_required', {},
1970                                          datastructure)
1971            datamodel[field_id] = None
1972        elif choice == 'keep':
1973            fileupload = datastructure[widget_id]
1974            if isinstance(fileupload, PersistableFileUpload):
1975                # Keeping something from the session means we
1976                # actually want to store it.
1977                store = True
1978            # else:
1979            #     # Nothing to change, don't pollute datastructure
1980            #     # with something costly already stored, which therefore
1981            #     # doesn't need to be kept in the session.
1982            #     self.unprepare(datastructure)
1983        elif choice == 'change' and is_upload:
1984            if not fileupload:
1985                return self.validateError('cpsschemas_err_file_empty', {},
1986                                          datastructure)
1987            if not isinstance(fileupload, FileUpload):
1988                return self.validateError('cpsschemas_err_file', {},
1989                                          datastructure)
1990            fileupload.seek(0, 2) # end of file
1991            size = fileupload.tell()
1992            if not size:
1993                return self.validateError('cpsschemas_err_file_empty', {},
1994                                          datastructure)
1995            if self.size_max and size > self.size_max:
1996                max_size_str = self.getHumanReadableSize(self.size_max)
1997                err = 'This file is too big, the allowed max size is ${max_size}'
1998                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1999                err_mapping = {'max_size': max_size_str}
2000                return self.validateError(err, err_mapping, datastructure)
2001            store = True
2002
2003
2004        # Find filename
2005        if is_upload and store:
2006            ext ='jpg'
2007            screening_type = datastructure.get('screening_type')
2008            filename = "%s_%s.%s" % (datastructure[self.id_field],
2009                                     self.getWidgetId(),
2010                                     ext)
2011            datamodel[field_id] = filename
2012            registry = getToolByName(self, 'mimetypes_registry')
2013            mimetype = registry.lookupExtension(filename.lower())
2014            if mimetype is not None:
2015                mimetype = str(mimetype) # normalize
2016            file = self.makeFile(filename, fileupload, datastructure)
2017            # Fixup mimetype
2018            if mimetype and file.content_type != mimetype:
2019                file.content_type = mimetype
2020            # Store the file in the filesystem
2021            #import pdb;pdb.set_trace()
2022            base_path = os.path.join(self.storage_path, screening_type)
2023            if not os.path.exists(base_path):
2024                os.mkdir(base_path)
2025            full_path = os.path.join(base_path, filename)
2026            pict = open(full_path,"w")
2027            fileupload.seek(0)
2028            pict.write(fileupload.read())
2029            pict.close()
2030        return True
2031
2032###)
2033
2034    def render(self, mode, datastructure, **kw): ###(
2035        render_method = 'widget_passport_render'
2036        meth = getattr(self, render_method, None)
2037        if meth is None:
2038            raise RuntimeError("Unknown Render Method %s for widget type %s"
2039                               % (render_method, self.getId()))
2040        img_info = self.getImageInfo(datastructure)
2041        return meth(mode=mode, datastructure=datastructure, **img_info)
2042    ###)
2043
2044InitializeClass(ApplicationImageWidget)
2045
2046widgetRegistry.register(ApplicationImageWidget)
2047###)
2048
2049class FileImageWidget(CPSImageWidget): ###(
2050    """Image widget with filesystem storage."""
2051    meta_type = 'File Image Widget'
2052    _properties = CPSImageWidget._properties +\
2053    (
2054     {'id': 'path', 'type': 'string', 'mode': 'w',
2055      'label': 'Relative Path'},
2056     {'id': 'id_field', 'type': 'string', 'mode': 'w',
2057      'label': 'Field to build the id'},
2058     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
2059      'label': 'Show Image'},
2060    )
2061    path = "images"
2062    #storage_path = "%s/%s" % (i_home,path)
2063    id_field = ""
2064    show_image = False
2065
2066    def getStorageImageInfo(self,field_id):
2067        info = {}
2068        if self.id_field == "":
2069            student_id = self.getStudentId()
2070        else:
2071            student_id = datastructure[self.id_field]
2072        # student_path = os.path.join(self.storage_path,
2073        #                             student_id)
2074        student_path = getImagesDir(student_id)
2075        image_name = ''
2076        content_url = ''
2077        current_filename = ''
2078        if os.path.exists(student_path):
2079            for name in os.listdir(student_path):
2080                if name.startswith(field_id):
2081                    image_name = name
2082                    break
2083        if image_name:
2084            info['image_name'] = image_name
2085            info['content_url'] = os.path.join(self.portal_url(),
2086                                               "viewimage",
2087                                               student_id,
2088                                               image_name,
2089                                              )
2090            info['current_filename'] =  image_name
2091            info['file_path'] = os.path.join(student_path, image_name)
2092        return info
2093
2094    def getImageInfo(self, datastructure): ###(
2095        """Get the file info from the datastructure."""
2096        widget_id = self.getWidgetId()
2097        info = None
2098        if  datastructure.has_key(widget_id):
2099            fileupload = datastructure[widget_id]
2100            dm = datastructure.getDataModel()
2101            field_id = self.fields[0]
2102            info = self.getStorageImageInfo(field_id)
2103        else:
2104            file_path = "XXX"
2105            title = ""
2106        # read the file from the filesystem
2107        #import pdb; pdb.set_trace()
2108        #if not os.path.exists(file_path):
2109        if not info:
2110            title = ""
2111            height = -1
2112            width = -1
2113            empty_file = True
2114            session_file = False
2115            current_filename = ''
2116            content_url = ''
2117            size = 0
2118            mimetype = ''
2119            last_modified = ''
2120            height = ''
2121            width = ''
2122        else:
2123            title = info['image_name']
2124            current_filename = info['current_filename']
2125            content_url = info['content_url']
2126            image = open(info['file_path'])
2127            from OFS.Image import getImageInfo as getImageInfoOFS
2128            image.seek(0)
2129            data = image.read(2000)
2130            size = len(data)
2131            empty_file = size == 0
2132            session_file = False
2133            last_modified = ''
2134            image.close()
2135            mimetype, width, height = getImageInfoOFS(data)
2136            registry = getToolByName(self, 'mimetypes_registry')
2137            mimetype = (registry.lookupExtension(current_filename.lower()) or
2138                        registry.lookupExtension('file.bin'))
2139            if width < 0:
2140                width = None
2141            if height < 0:
2142                height = None
2143
2144            if (self.allow_resize
2145                and height is not None
2146                and width  is not None):
2147                z_w = z_h = 1
2148                h = int(self.display_height)
2149                w = int(self.display_width)
2150                if w and h:
2151                    if w < width:
2152                        z_w = w / float(width)
2153                    if h < height:
2154                        z_h = h / float(height)
2155                    zoom = min(z_w, z_h)
2156                    width = int(zoom * width)
2157                    height = int(zoom * height)
2158                #import pdb;pdb.set_trace()
2159        image_info = {
2160            'empty_file': empty_file,
2161            'session_file': session_file,
2162            'current_filename': title,
2163            'size': size,
2164            'last_modified': last_modified,
2165            'content_url': content_url,
2166            'mimetype': mimetype,
2167            }
2168        alt = title or ''
2169        #height = int(self.display_height)
2170        #width = int(self.display_width)
2171        if height is None or width is None:
2172            tag = renderHtmlTag('img', src=image_info['content_url'],
2173                                alt=alt, title=title)
2174        else:
2175            tag = renderHtmlTag('img', src=image_info['content_url'],
2176                                width=str(width), height=str(height),
2177                                alt=alt, title=title)
2178
2179        image_info['height'] = height
2180        image_info['width'] = width
2181        image_info['image_tag'] = tag
2182        image_info['show_image'] = self.show_image
2183        return image_info
2184    ###)
2185
2186    # def checkFileName(self, filename, mimetype):
2187    #     return '', {}
2188    #     if mimetype and mimetype.startswith('image'):
2189    #         return '', {}
2190    #     return 'cpsschemas_err_image', {}
2191
2192    def prepare(self, datastructure, **kw): ###(
2193        """Prepare datastructure from datamodel."""
2194        datamodel = datastructure.getDataModel()
2195        widget_id = self.getWidgetId()
2196        file_name = datamodel[self.fields[0]]
2197        if self.id_field == "":
2198            student_id = self.getStudentId()
2199        else:
2200            student_id = datastructure[self.id_field]
2201        if student_id is not None:
2202            # student_path = os.path.join(self.storage_path,
2203            #                             student_id)
2204            student_path = getImagesDir(student_id)
2205            if not os.path.exists(student_path):
2206                self.waeup_tool.moveImagesToFS(student_id)
2207        if self.allow_resize:
2208            datastructure[self.getWidgetId() + '_resize'] = ''
2209        datastructure[widget_id] = file_name
2210        datastructure[widget_id + '_choice'] = 'change'
2211        title = 'Passport Foto'
2212        datastructure[widget_id + '_filename'] = title
2213    ###)
2214
2215    def validate(self, datastructure, **kw): ###(
2216        """Update datamodel from user data in datastructure.
2217        """
2218        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2219        datamodel = datastructure.getDataModel()
2220        field_id = self.fields[0]
2221        widget_id = self.getWidgetId()
2222        store = False
2223        fileupload = None
2224        mimetype = None
2225        old_file = datamodel[field_id]
2226        choice = datastructure[widget_id+'_choice']
2227        fileupload = datastructure[widget_id]
2228        is_upload = isinstance(fileupload, FileUpload)
2229        #import pdb; pdb.set_trace()
2230        if not is_upload and not datamodel[field_id]:
2231            if self.is_required:
2232                return self.validateError('Picture upload required', {},
2233                                          datastructure)
2234        if self.id_field == "":
2235            student_id = self.getStudentId()
2236        else:
2237            student_id = datastructure[self.id_field]
2238        if choice == 'delete':
2239            if self.is_required:
2240                return self.validateError('cpsschemas_err_required', {},
2241                                          datastructure)
2242            info= self.getStorageImageInfo(field_id)
2243            # Remove the file in the filesystem
2244            if info:
2245                os.remove(info['file_path'])
2246            datamodel[field_id] = None
2247        elif choice == 'keep':
2248            fileupload = datastructure[widget_id]
2249            if isinstance(fileupload, PersistableFileUpload):
2250                # Keeping something from the session means we
2251                # actually want to store it.
2252                store = True
2253            # else:
2254            #     # Nothing to change, don't pollute datastructure
2255            #     # with something costly already stored, which therefore
2256            #     # doesn't need to be kept in the session.
2257            #     self.unprepare(datastructure)
2258        elif choice == 'change' and is_upload:
2259            if not fileupload:
2260                return self.validateError('cpsschemas_err_file_empty', {},
2261                                          datastructure)
2262            if not isinstance(fileupload, FileUpload):
2263                return self.validateError('cpsschemas_err_file', {},
2264                                          datastructure)
2265            fileupload.seek(0, 2) # end of file
2266            size = fileupload.tell()
2267            if not size:
2268                return self.validateError('cpsschemas_err_file_empty', {},
2269                                          datastructure)
2270            if self.size_max and size > self.size_max:
2271                max_size_str = self.getHumanReadableSize(self.size_max)
2272                err = 'This file is too big, the allowed max size is ${max_size}'
2273                member_id = str(self.portal_membership.getAuthenticatedMember())
2274                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2275                err_mapping = {'max_size': max_size_str}
2276                return self.validateError(err, err_mapping, datastructure)
2277            store = True
2278
2279
2280        # Find filename
2281        if is_upload and store:
2282            filename = cookId('', '', fileupload)[0].strip()
2283            base,ext = os.path.splitext(filename)
2284            filename = "%s_%s%s" % (field_id,
2285                                    student_id,
2286                                    ext)
2287            datamodel[field_id] = filename
2288            registry = getToolByName(self, 'mimetypes_registry')
2289            mimetype = registry.lookupExtension(filename.lower())
2290            if mimetype is not None:
2291                mimetype = str(mimetype) # normalize
2292            file = self.makeFile(filename, fileupload, datastructure)
2293            # Fixup mimetype
2294            if mimetype and file.content_type != mimetype:
2295                file.content_type = mimetype
2296            # Store the file in the filesystem
2297            #student_path = os.path.join(self.storage_path,student_id)
2298            student_path = getImagesDir(student_id)
2299            if not os.path.exists(student_path):
2300                os.mkdir(student_path)
2301            full_path = os.path.join(student_path, filename)
2302            pict = open(full_path,"w")
2303            #fileupload.seek(0)
2304            #import pdb; pdb.set_trace()
2305            pict.write(str(file.data))
2306            pict.close()
2307        return True
2308    ###)
2309
2310    def render(self, mode, datastructure, **kw): ###(
2311        render_method = 'widget_image_render'
2312        meth = getattr(self, render_method, None)
2313        #import pdb;pdb.set_trace()
2314        if meth is None:
2315            raise RuntimeError("Unknown Render Method %s for widget type %s"
2316                               % (render_method, self.getId()))
2317        img_info = self.getImageInfo(datastructure)
2318        return meth(mode=mode, datastructure=datastructure, **img_info)
2319    ###)
2320
2321InitializeClass(FileImageWidget)
2322
2323widgetRegistry.register(FileImageWidget)
2324###)
2325
2326class DiscFileWidget(CPSFileWidget): ###(
2327    """File widget with filesystem storage."""
2328    meta_type = 'Disc File Widget'
2329    _properties = CPSFileWidget._properties +\
2330    (
2331     {'id': 'path', 'type': 'string', 'mode': 'w',
2332      'label': 'Relative Path'},
2333    )
2334    path = "import"
2335    storage_path = "%s/%s" % (i_home,path)
2336
2337    def getStoredFileInfo(self,datastructure): ###(
2338        datamodel = datastructure.getDataModel()
2339        field_id = self.fields[0]
2340        widget_id = self.getWidgetId()
2341        file_name = datamodel[field_id]
2342        info = {}
2343        registry = getToolByName(self, 'mimetypes_registry')
2344        info['mimetype'] = registry.lookupExtension('file.csv')
2345        info['empty_file'] = True
2346        info['size'] = 0
2347        info['last_modified'] = ''
2348        file_path = os.path.join(self.storage_path, file_name)
2349        if os.path.exists(file_path):
2350            info['empty_file'] = False
2351            info['file_name'] = file_name
2352            info['content_url'] = os.path.join(self.portal_url(),
2353                                            "viewfile",
2354                                            file_name,
2355                                            )
2356            info['current_filename'] =  file_name
2357            # get the mimetype
2358            mimetype = (registry.lookupExtension(file_name.lower()) or
2359                        registry.lookupExtension('file.bin'))
2360            info['mimetype'] = mimetype
2361            info['file_path'] = file_path
2362        else:
2363            info['file_name'] = ''
2364            info['content_url'] = ''
2365            info['current_filename'] = ''
2366            info['file_path'] = ''
2367        return info
2368        ###)
2369
2370    def prepare(self, datastructure, **kw): ###(
2371        """Prepare datastructure from datamodel."""
2372        datamodel = datastructure.getDataModel()
2373        #import pdb;pdb.set_trace()
2374        widget_id = self.getWidgetId()
2375        file_name = datamodel[self.fields[0]]
2376        datastructure[widget_id] = file_name
2377        datastructure[widget_id + '_filename'] = file_name
2378        datastructure[widget_id+'_choice'] = "keep"
2379    ###)
2380
2381    def validate(self, datastructure, **kw): ###(
2382        """Update datamodel from user data in datastructure.
2383        """
2384        logger = logging.getLogger('Widgets.DiscFileWidget.validate')
2385        datamodel = datastructure.getDataModel()
2386        field_id = self.fields[0]
2387        widget_id = self.getWidgetId()
2388        store = False
2389        fileupload = None
2390        mimetype = None
2391        old_file = datamodel[field_id]
2392        choice = datastructure[widget_id+'_choice']
2393        fileupload = datastructure[widget_id]
2394        is_upload = isinstance(fileupload, FileUpload)
2395        if not is_upload and not datamodel[field_id]:
2396            if self.is_required:
2397                return self.validateError('File upload required', {},
2398                                          datastructure)
2399        if choice == 'delete':
2400            if self.is_required:
2401                return self.validateError('cpsschemas_err_required', {},
2402                                          datastructure)
2403            info = self.getStoredFileInfo(datastructure)
2404            # Remove the file in the filesystem
2405            if info:
2406                os.remove(info['file_path'])
2407            datamodel[field_id] = None
2408        elif choice == 'keep':
2409            fileupload = datastructure[widget_id]
2410            if isinstance(fileupload, PersistableFileUpload):
2411                # Keeping something from the session means we
2412                # actually want to store it.
2413                store = True
2414            # else:
2415            #     # Nothing to change, don't pollute datastructure
2416            #     # with something costly already stored, which therefore
2417            #     # doesn't need to be kept in the session.
2418            #     self.unprepare(datastructure)
2419        elif choice == 'change' and is_upload:
2420            if not fileupload:
2421                return self.validateError('cpsschemas_err_file_empty', {},
2422                                          datastructure)
2423            if not isinstance(fileupload, FileUpload):
2424                return self.validateError('cpsschemas_err_file', {},
2425                                          datastructure)
2426            fileupload.seek(0, 2) # end of file
2427            size = fileupload.tell()
2428            if not size:
2429                return self.validateError('cpsschemas_err_file_empty', {},
2430                                          datastructure)
2431            if self.size_max and size > self.size_max:
2432                max_size_str = self.getHumanReadableSize(self.size_max)
2433                err = 'This file is too big, the allowed max size is ${max_size}'
2434                member_id = str(self.portal_membership.getAuthenticatedMember())
2435                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2436                err_mapping = {'max_size': max_size_str}
2437                return self.validateError(err, err_mapping, datastructure)
2438            store = True
2439
2440
2441        # Find filename
2442        if is_upload and store:
2443            filename = cookId('', '', fileupload)[0].strip()
2444            base,ext = os.path.splitext(filename)
2445            if ext not in ("csv",".csv"):
2446                return self.validateError('only csv files allowed', {},
2447                                          datastructure)
2448            uploads_folder = self.portal_url.getPortalObject().campus.uploads
2449            if hasattr(uploads_folder,filename):
2450                return self.validateError('upload object exists', {},
2451                                          datastructure)
2452            datamodel[field_id] = filename
2453            registry = getToolByName(self, 'mimetypes_registry')
2454            mimetype = registry.lookupExtension(filename.lower())
2455            if mimetype is not None:
2456                mimetype = str(mimetype) # normalize
2457            file = self.makeFile(filename, fileupload, datastructure)
2458            # Fixup mimetype
2459            if mimetype and file.content_type != mimetype:
2460                file.content_type = mimetype
2461            file_path = os.path.join(self.storage_path,filename)
2462            data = open(file_path,"w")
2463            data.write(str(file.data))
2464            data.close()
2465        return True
2466    ###)
2467
2468    def render(self, mode, datastructure, **kw): ###(
2469        render_method = 'widget_uploadfile_render'
2470        meth = getattr(self, render_method, None)
2471        #import pdb;pdb.set_trace()
2472        if meth is None:
2473            raise RuntimeError("Unknown Render Method %s for widget type %s"
2474                               % (render_method, self.getId()))
2475        file_info = self.getStoredFileInfo(datastructure)
2476
2477        return meth(mode=mode, datastructure=datastructure, **file_info)
2478    ###)
2479
2480InitializeClass(DiscFileWidget)
2481
2482widgetRegistry.register(DiscFileWidget)
2483
2484
2485class RegMatricNoWidget(CPSStringWidget): ###(
2486    """ RegMatricNo Widget"""
2487    meta_type = "RegMatricNo Widget"
2488    def validate(self, datastructure, **kw):
2489        """Validate datastructure and update datamodel."""
2490        valid = CPSStringWidget.validate(self, datastructure, **kw)
2491        widget_id = self.getWidgetId()
2492        value = datastructure[widget_id].upper()
2493        err = 0
2494        #import pdb;pdb.set_trace()
2495        if not valid:
2496            err = 'Invalid number'
2497        else:
2498            student_record = self.students_catalog(jamb_reg_no = value)
2499            if len(student_record) < 1:
2500                student_record = self.students_catalog(matric_no = value)
2501                if len(student_record) < 1:
2502                    err = 'No student record with this registration or matric number'
2503                else:
2504                    datastructure['record'] = student_record[0]
2505                    #import pdb;pdb.set_trace()
2506            else:
2507                datastructure['record'] = student_record[0]
2508                #import pdb;pdb.set_trace()
2509        if err:
2510            datastructure.setError(widget_id, err)
2511        else:
2512            datamodel = datastructure.getDataModel()
2513            datamodel[self.fields[0]] = value
2514       
2515        return not err
2516
2517InitializeClass(RegMatricNoWidget)
2518
2519widgetRegistry.register(RegMatricNoWidget)
2520
2521class CheckEmailWidget(CPSStringWidget): ###(
2522    """ CheckEmail Widget"""
2523    meta_type = "CheckEmail Widget"
2524    def validate(self, datastructure, **kw):
2525        """Validate datastructure and update datamodel."""
2526        if datastructure.errors:
2527            return
2528        valid = CPSStringWidget.validate(self, datastructure, **kw)
2529        widget_id = self.getWidgetId()
2530        value = datastructure[widget_id].upper()
2531        err = 0
2532        #import pdb;pdb.set_trace()
2533        if not valid:
2534            err = 'Invalid string'
2535        else:
2536            email_cat = datastructure['record'].email.upper()
2537            if email_cat != value:
2538                err = 'Email address does not match'
2539            else:
2540                pass
2541        if err:
2542            datastructure.setError(widget_id, err)
2543        else:
2544            datamodel = datastructure.getDataModel()
2545            datamodel[self.fields[0]] = value           
2546       
2547        return not err
2548
2549InitializeClass(CheckEmailWidget)
2550
2551widgetRegistry.register(CheckEmailWidget)
2552
2553###)
2554
2555class PhoneWidget(CPSIntWidget): ###(
2556    """ Phone Widget"""
2557    meta_type = "Phone Widget"
2558   
2559    def validate(self, datastructure, **kw):
2560        """Validate datastructure and update datamodel."""
2561
2562        valid = CPSIntWidget.validate(self, datastructure, **kw)
2563        if not valid:
2564            return 0
2565        else:
2566            widget_id = self.getWidgetId()
2567            value = datastructure[widget_id]
2568            #import pdb;pdb.set_trace()
2569            if value == '234':
2570                value = ''
2571                datamodel = datastructure.getDataModel()
2572                datamodel[self.fields[0]] = value
2573            elif value.startswith('2340'):
2574                err = 'Wrong Nigerian phone format'
2575                datastructure.setError(widget_id, err)
2576                return 0
2577            return 1
2578
2579    def render(self, mode, datastructure, **kw):
2580        """Render in mode from datastructure."""
2581        value = datastructure[self.getWidgetId()]
2582        #import pdb;pdb.set_trace()
2583        if mode == 'view':
2584            if value == '':
2585                return ''
2586            else:
2587                return '+' + escape(value)
2588        elif mode == 'edit':
2589            if value == '':
2590                value = 234
2591            tag = renderHtmlTag('input',
2592                                 type='text',
2593                                 name=self.getHtmlWidgetId(),
2594                                 value=value)
2595            return '<strong>+</strong>' + tag
2596        raise RuntimeError('unknown mode %s' % mode)
2597
2598
2599InitializeClass(PhoneWidget)
2600
2601widgetRegistry.register(PhoneWidget)
2602
2603
2604
2605
2606###########
2607
Note: See TracBrowser for help on using the repository browser.