source: WAeUP_SRP/trunk/Widgets.py @ 4232

Last change on this file since 4232 was 4202, checked in by Henrik Bettermann, 15 years ago

remove tracer

  • Property svn:keywords set to Id
File size: 97.3 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 4202 2009-06-04 11:53:00Z 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
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 - 10,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:
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","cest","sandwich","pg","dp"):
859            application_category = screening_type
860        else:
861            application_category = "basic"
862        if not hasattr(self,'_v_certificates_docs'):
863            # res = self.portal_catalog_real.search({'meta_type': "Certificate"})
864            # d = {}
865            # for cert in res:
866            #     c = cert.getObject().getContent()
867            #     if getattr(c,'application_category',''):
868            #         d[cert.getId] = c
869            res = self.certificates_catalog()
870            d = {}
871            for cert in res:
872                if getattr(cert,'application_category',''):
873                    d[cert.code] = cert
874            self._v_certificates_docs = d
875        l  = [('','','')]
876        #l = []
877        for k,d in self._v_certificates_docs.items():
878            if application_category == "all":
879                l  += (k,self._v_certificates_docs[k].title,k),
880            else:
881                if getattr(d,'application_category','') == application_category:
882                    l  += (k,self._v_certificates_docs[k].title,k),
883        #import ipdb;ipdb.set_trace()
884        return VocabularyOnTheFly(l)
885
886InitializeClass(ApplicationCourseWidget)
887
888widgetRegistry.register(ApplicationCourseWidget)
889###)
890
891class JambRegNoWidget(CPSStringWidget): ###(
892    """ JambRegNo Widget"""
893    meta_type = "JambRegNo Widget"
894    _properties = CPSStringWidget._properties + (
895        {'id': 'catalog', 'type': 'string', 'mode': 'w',
896         'label': 'Catalog to search'},
897         {'id': 'reference', 'type': 'string', 'mode': 'w',
898         'label': 'Reference Field'},
899         )
900    #catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
901    reference = ""
902    digits = 8
903    digits_str = "N"*digits
904    letters = 2
905    letters_str = "L"*letters
906    def validate(self, datastructure, **kw):
907        """Validate datastructure and update datamodel."""
908        valid = CPSStringWidget.validate(self, datastructure, **kw)
909        reg_no_catalog = getattr(self,self.catalog)
910        widget_id = self.getWidgetId()
911        value = datastructure[widget_id].upper()
912        err = 0
913        #import pdb;pdb.set_trace()
914        if kw.has_key('mode'):
915            mode = kw['mode']
916        else:
917            mode = "edit"
918        if not valid:
919            err = 'Invalid registration number'
920        elif self.reference == '':
921            #s = getStudentByRegNo(self,value)
922            student_record = reg_no_catalog(jamb_reg_no = value)
923            if len(student_record) < 1:
924                err = 'No student record with this registration number'
925            #elif self.catalog == "students_catalog" and student_record[0].review_state not in ('student_created','admitted'):
926            #    err = 'Admission checking not allowed (wrong registration state)'
927            else:
928                datastructure['pume'] = student_record[0]
929        elif mode == 'add':
930            pass
931        elif self.reference != '' and self.catalog == "applicants_catalog":
932            res = reg_no_catalog.searchResults({"%s" % self.reference: value})
933            if len(res) != 1:
934                err = 'No record with this registration number'
935            else:
936                datastructure['record'] = res[0]
937        else:
938            record = datastructure[self.reference]
939            #jamb_reg_no = getattr(record,widget_id)
940            jamb_reg_no = record.Entryregno
941            if jamb_reg_no != value:
942                err = 'Registration number does not match.'
943        if err:
944            datastructure.setError(widget_id, err)
945        else:
946            datamodel = datastructure.getDataModel()
947            datamodel[self.fields[0]] = value
948        return not err
949
950InitializeClass(JambRegNoWidget)
951
952widgetRegistry.register(JambRegNoWidget)
953###)
954
955class SecretWidget(CPSStringWidget): ###(
956    """ Secret Widget"""
957    meta_type = "Secret Widget"
958    _properties = CPSStringWidget._properties + (
959        {'id': 'reference', 'type': 'string', 'mode': 'w',
960         'label': 'Reference Record'},
961         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
962         'label': 'Fields to check'},
963         )
964    reference = "student"
965    matric_no_catalog = 'returning_import'
966    check_fields = ("Firstname", "Middlename","Lastname")
967    def validate(self, datastructure, **kw):
968        """Validate datastructure and update datamodel."""
969        logger = logging.getLogger('Widgets.SecretWidget.validate')
970        valid = CPSStringWidget.validate(self, datastructure, **kw)
971        widget_id = self.getWidgetId()
972        value = datastructure[widget_id].upper()
973        err = 0
974        record = datastructure.get(self.reference,None)
975        #import pdb;pdb.set_trace()
976        if not valid or len(value) < 2:
977            err = 'Invalid string'
978        elif not record or datastructure.errors:
979            err = 0
980        else:
981            found = False
982            cvs = []
983            for field in self.check_fields:
984                cv = getattr(record,field).upper()
985                if len(cv.split()) > 1:
986                    for splited in cv.split():
987                        cvs.append(splited.strip())
988                else:
989                    cvs.append(cv.strip(),)
990            for cv in cvs:
991                if cv  == value.strip().upper():
992                    found = True
993                    break
994            matric_no = record.matric_no
995            name = " ".join(cvs)
996            if not found:
997                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
998                err = 'No name does match.'
999            else:
1000                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
1001        if err:
1002            datastructure.setError(widget_id, err)
1003        else:
1004            datamodel = datastructure.getDataModel()
1005            datamodel[self.fields[0]] = value
1006        return not err
1007
1008InitializeClass(SecretWidget)
1009
1010widgetRegistry.register(SecretWidget)
1011###)
1012
1013class WAeUPSexWidget(CPSBooleanWidget): ###(
1014    """WAeUP sex widget."""
1015    meta_type = 'WAeUP Sex Widget'
1016
1017    def validate(self, datastructure, **kw):
1018        """Validate datastructure and update datamodel."""
1019        value = datastructure[self.getWidgetId()]
1020
1021        if self.render_format not in self.render_formats:
1022            self.render_format = 'select'
1023
1024        female = value in ('F','f','Female','female','True','true',True)
1025        male = value in ('M','m','Male','male','False','false',False)
1026        if not female and not male:
1027            datastructure.setError(self.getWidgetId(),
1028                                   "invalid sex %s" % value)
1029            return 0
1030        elif female:
1031            v = True
1032        else:
1033            v = False
1034        datamodel = datastructure.getDataModel()
1035        datamodel[self.fields[0]] = v
1036        return 1
1037
1038InitializeClass(WAeUPSexWidget)
1039
1040widgetRegistry.register(WAeUPSexWidget)
1041
1042###)
1043
1044class WAeUPBooleanWidget(CPSBooleanWidget): ###(
1045    """WAeUP boolean widget."""
1046    meta_type = 'WAeUP Boolean Widget'
1047
1048    def validate(self, datastructure, **kw):
1049        """Validate datastructure and update datamodel."""
1050        value = datastructure[self.getWidgetId()]
1051
1052        if self.render_format not in self.render_formats:
1053            self.render_format = 'select'
1054        true = value.upper() in ('T','1','TRUE','True','true','WAHR',True)
1055        false = value.upper() in ('F','0','FALSE','False','false','FALSCH',False)
1056        if not true and not false:
1057            datastructure.setError(self.getWidgetId(),
1058                                   "invalid boolean %s" % value)
1059            return 0
1060        elif true:
1061            v = True
1062        else:
1063            v = False
1064        datamodel = datastructure.getDataModel()
1065        datamodel[self.fields[0]] = v
1066        return 1
1067
1068InitializeClass(WAeUPBooleanWidget)
1069
1070widgetRegistry.register(WAeUPBooleanWidget)
1071
1072###)
1073
1074class MatricNoWidget(CPSStringWidget): ###(
1075    """ MatricNo Widget"""
1076    meta_type = "MatricNo Widget"
1077
1078    _properties = CPSStringWidget._properties + (
1079        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
1080         'label': 'Catalog to search for MatricNo'},
1081        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
1082         'label': 'Results Catalog'},
1083         )
1084    matric_no_catalog = "" #the catalog to search for matric_no
1085    results_catalog = "results_import" #results catalog
1086
1087    def validate(self, datastructure, **kw):
1088        """Validate datastructure and update datamodel."""
1089        #import pdb;pdb.set_trace()
1090        valid = CPSStringWidget.validate(self, datastructure, **kw)
1091        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
1092        returning = getattr(self,self.matric_no_catalog)
1093        results = getattr(self,self.results_catalog,None)
1094        err = 0
1095        widget_id = self.getWidgetId()
1096        value = datastructure[widget_id]
1097        if not valid or not value:
1098            err = 'Invalid string'
1099            logger.info('Invalid matric_no string %s' % value)
1100        else:
1101            value = value.upper()
1102            datastructure['student'] = None
1103            while not err:
1104                res = returning(matric_no = value)
1105                if len(res) < 1:
1106                    logger.info('matric_no %s not found' % value)
1107                    err = 'No student with this matriculation number.'
1108                    break
1109                datastructure['student'] = res[0]
1110                if results is not None:
1111                    res = results(matric_no = value)
1112                    if len(res) < 1:
1113                        err = 'No results for this matriculation number'
1114                        continue
1115                    datastructure['results'] = res
1116                break
1117        if err:
1118            datastructure.setError(widget_id, err)
1119        else:
1120            datamodel = datastructure.getDataModel()
1121            datamodel[self.fields[0]] = value
1122        return not err
1123
1124InitializeClass(MatricNoWidget)
1125
1126widgetRegistry.register(MatricNoWidget)
1127###)
1128
1129class StudentIdWidget(CPSStringWidget): ###(
1130    """ StudentId Widget"""
1131    meta_type = "StudentId Widget"
1132    def validate(self, datastructure, **kw):
1133        """Validate datastructure and update datamodel."""
1134        valid = CPSStringWidget.validate(self, datastructure, **kw)
1135        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
1136        #import pdb;pdb.set_trace()
1137        s_cat = self.students_catalog
1138        err = 0
1139        widget_id = self.getWidgetId()
1140        value = datastructure[widget_id]
1141        if not valid or not value:
1142            err = 'Invalid Id string'
1143            logger.info('Invalid id string %s' % value)
1144            datastructure['student'] = None
1145        else:
1146            value = value.upper()
1147            res = s_cat(id = value)
1148            if not res:
1149                logger.info('Student id %s not found' % value)
1150                err = 'No student with this Id'
1151                datastructure['student'] = None
1152            else:
1153                datastructure['student'] = res[0]
1154        if err:
1155            datastructure.setError(widget_id, err)
1156        else:
1157            datamodel = datastructure.getDataModel()
1158            datamodel[self.fields[0]] = value
1159        return not err
1160
1161InitializeClass(StudentIdWidget)
1162
1163widgetRegistry.register(StudentIdWidget)
1164###)
1165
1166class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
1167    """ WAeUPMultilineResults Widget"""
1168    meta_type = "WAeUp Multiline Results Widget"
1169    _properties = CPSWidget._properties + (
1170        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
1171         'label': 'Nr of Lines'},
1172         )
1173    nr_of_lines = 5
1174    def prepare(self, datastructure, **kw): ###(
1175        """Prepare datastructure from datamodel."""
1176        datamodel = datastructure.getDataModel()
1177        #import pdb;pdb.set_trace()
1178        widget_id = self.getWidgetId()
1179        v = datamodel[self.fields[0]]
1180        if type(v) is ListType and v:
1181            nr_results = len(v)
1182        else:
1183            v = []
1184            nr_results = 0
1185        count = 1
1186        for s,g in v:
1187            wid = "%s%02d"% (widget_id,count)
1188            datastructure[wid+'_s'] = s
1189            datastructure[wid+'_g'] = g
1190            count += 1
1191        if nr_results < self.nr_of_lines:
1192            for line in range(nr_results,self.nr_of_lines):
1193                v.append(('',''))
1194                wid = "%s%02d"% (widget_id,line)
1195                datastructure[wid+'_s'] = ''
1196                datastructure[wid+'_g'] = ''
1197        datastructure[widget_id] = v
1198        datastructure[widget_id+'_s'] = ''
1199        datastructure[widget_id+'_g'] = ''
1200    ###)
1201
1202    def validate(self, datastructure, **kw): ###(
1203        """Validate datastructure and update datamodel."""
1204        #import pdb;pdb.set_trace()
1205        widget_id = self.getWidgetId()
1206        err = 0
1207        lines = []
1208        for line in range(1,30):
1209            wid = "%s%02d"% (widget_id,line)
1210            if not datastructure.has_key(wid+'_s'):
1211                break
1212            lines.append((datastructure[wid+'_s'].strip(),
1213                         datastructure[wid+'_g'].strip()))
1214
1215        s = datastructure[widget_id+'_s'].strip()
1216        g = datastructure[widget_id+'_g'].strip()
1217        if s and g:
1218            lines.append((s,g))
1219        active = []
1220        for s,g in lines:
1221            if g != "":
1222                active.append((s,g))
1223        if err:
1224            datastructure.setError(widget_id, err)
1225        else:
1226            datamodel = datastructure.getDataModel()
1227            datamodel[self.fields[0]] = active
1228        return not err
1229    ###)
1230
1231    def render(self, mode, datastructure, **kw): ###(
1232        """Render in mode from datastructure."""
1233        render_method = 'widget_waeup_multiline_result_render'
1234        meth = getattr(self, render_method, None)
1235        if meth is None:
1236            raise RuntimeError("Unknown Render Method %s for widget type %s"
1237                               % (render_method, self.getId()))
1238        #import pdb;pdb.set_trace()
1239        datamodel = datastructure.getDataModel()
1240        widget_id = self.getWidgetId()
1241        lines = datamodel[self.fields[0]]
1242        if len(lines) < self.nr_of_lines:
1243            for line in range(len(lines),self.nr_of_lines + 1):
1244                lines.append(('',''))
1245        datastructure[widget_id] = lines
1246        datastructure[widget_id+'_s'] = ''
1247        datastructure[widget_id+'_g'] = ''
1248##        count = 1
1249##        for s,g in v:
1250##            wid = "%s%02d"% (widget_id,count)
1251##            count += 1
1252        return meth(mode=mode,
1253                    datastructure=datastructure,
1254                    )
1255    ###)
1256
1257
1258InitializeClass(WAeUPMultilineResultsWidget)
1259widgetRegistry.register(WAeUPMultilineResultsWidget)
1260###)
1261
1262class WAeUPResultsWidget(CPSStringWidget): ###(
1263    """ WAeUPResults Widget"""
1264    meta_type = "WAeUp Results Widget"
1265
1266    def prepare(self, datastructure, **kw): ###(
1267        """Prepare datastructure from datamodel."""
1268        datamodel = datastructure.getDataModel()
1269        v = datamodel[self.fields[0]]
1270        #import pdb;pdb.set_trace()
1271        widget_id = self.getWidgetId()
1272        datastructure[widget_id] = v
1273        datastructure[widget_id+'_s'] = ''
1274        datastructure[widget_id+'_g'] = ''
1275    ###)
1276
1277    def validate(self, datastructure, **kw): ###(
1278        """Validate datastructure and update datamodel."""
1279        #import pdb;pdb.set_trace()
1280        widget_id = self.getWidgetId()
1281        v = datastructure[widget_id]
1282        if not v:
1283            v = []
1284        err = 0
1285        s = datastructure[widget_id+'_s'].strip()
1286        g = datastructure[widget_id+'_g'].strip()
1287        while 1:
1288            if not s and g:
1289                err = "No subject grade for subject"
1290                break
1291            i = 0
1292            done = False
1293            #import pdb;pdb.set_trace()
1294            for sv,gv in v:
1295                if sv == s:
1296                    done = True
1297                    if not g:
1298                        v.pop(i)
1299                        break
1300                    v[i] = (s,g)
1301                    break
1302                i += 1
1303            if done:
1304                break
1305            if s and g:
1306                if v:
1307                    v += (s,g),
1308                else:
1309                    v = [(s,g),]
1310            break
1311        if err:
1312            datastructure.setError(widget_id, err)
1313        else:
1314            datamodel = datastructure.getDataModel()
1315            datamodel[self.fields[0]] = v
1316            datastructure[widget_id] = v
1317            datastructure[widget_id+'_s'] = s
1318            datastructure[widget_id+'_g'] = g
1319        return not err
1320    ###)
1321
1322    def render(self, mode, datastructure, **kw): ###(
1323        """Render in mode from datastructure."""
1324        render_method = 'widget_waeup_result_render'
1325        meth = getattr(self, render_method, None)
1326        if meth is None:
1327            raise RuntimeError("Unknown Render Method %s for widget type %s"
1328                               % (render_method, self.getId()))
1329        datamodel = datastructure.getDataModel()
1330        widget_id = self.getWidgetId()
1331        datastructure[widget_id+'_s'] = ''
1332        datastructure[widget_id+'_g'] = ''
1333        return meth(mode=mode,
1334                    datastructure=datastructure,
1335                    )
1336    ###)
1337
1338
1339InitializeClass(WAeUPResultsWidget)
1340widgetRegistry.register(WAeUPResultsWidget)
1341###)
1342
1343class ScratchCardPin: ###(
1344    """the ScratchCardPin"""
1345    def __init__(self,prefix,batch_no,number):
1346        if not batch_no and not number:
1347            s = prefix
1348            if len(s) > 3:
1349                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1350            else:
1351                prefix,batch_no,number = s,'',''
1352        self.p = prefix
1353        self.b = batch_no
1354        self.n = number
1355
1356    def __str__(self):
1357        return "%s-%s-%s" % (self.p,self.b,self.n)
1358
1359    def __repr__(self):
1360        return "%s%s%s" % (self.p,self.b,self.n)
1361###)
1362
1363class ScratchcardPinWidget(CPSStringWidget): ###(
1364    """ ScratchcardPin Widget"""
1365    meta_type = "Scratchcard Pin Widget"
1366    _properties = CPSWidget._properties + (
1367        {'id': 'prefix', 'type': 'string', 'mode': 'w',
1368         'label': 'Prefix'},
1369         {'id': 'reference', 'type': 'string', 'mode': 'w',
1370         'label': 'Reference Field'},
1371         {'id': 'reuse_pin', 'type': 'boolean', 'mode': 'w',
1372         'label': 'Reuse Application Pin'},
1373        )
1374    prefix = ''
1375    reference = ''
1376    reuse_pin = False
1377
1378    def prepare(self, datastructure, **kw): ###(
1379        """Prepare datastructure from datamodel."""
1380        datamodel = datastructure.getDataModel()
1381        v = datamodel[self.fields[0]]
1382        widget_id = self.getWidgetId()
1383        if v and type(v) is StringType:
1384            try:
1385                p,b,n = v.split('-')
1386                v = ScratchCardPin(p,b,n)
1387            except ValueError:
1388                v = ScratchCardPin(v,'','')
1389        if v:
1390            p = '%s' % v.p
1391            b = '%s' % v.b
1392            n = '%s' % v.n
1393        else:
1394            p = self.prefix
1395            if p.startswith('@'):
1396                p = getattr(self,self.prefix[1:])()
1397            b = n = ''
1398            v = ScratchCardPin(p,b,n)
1399        datastructure[widget_id] = v
1400        datastructure[widget_id+'_p'] = p
1401        datastructure[widget_id+'_b'] = b
1402        datastructure[widget_id+'_n'] = n
1403    ###)
1404
1405    def validate(self, datastructure, **kw): ###(
1406        """Validate datastructure and update datamodel."""
1407        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1408        widget_id = self.getWidgetId()
1409        v = datastructure[widget_id]
1410        #import pdb;pdb.set_trace()
1411        err = 0
1412        mapping = {}
1413        prefix= self.prefix
1414        if prefix.startswith('@'):
1415            prefix= getattr(self,self.prefix[1:])()
1416        b = datastructure[widget_id+'_b'].strip()
1417        n = datastructure[widget_id+'_n'].strip()
1418        pins = self.portal_pins
1419        pin = "%(prefix)s%(b)s%(n)s" % vars()
1420        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1421        do = 1
1422        s_id = str(self.portal_membership.getAuthenticatedMember())
1423        if self.isStaff():
1424            do = 0
1425            err ='You are not a Student. PIN neither checked nor used.'
1426            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1427        elif len(b) > 1 and b.find('-') > -1:
1428            do = 0
1429            err = 'PIN must not contain "-".'
1430            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1431        elif n.find('-') > -1:
1432            do = 0
1433            err = 'PIN must not contain "-".'
1434            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1435        elif len(n) != 10:
1436            do = 0
1437            err = 'Invalid PIN length'
1438            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1439        elif self.reference == "":
1440            ref = s_id
1441        else:
1442            ref = datastructure[self.reference]
1443            if datastructure.errors:
1444                do = 0
1445                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1446                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1447            elif prefix == 'APP' and not self.reuse_pin:
1448                res =  self.applicants_catalog(reg_no = ref)
1449                if not res:
1450                    res =  self.applicants_catalog(reg_no = ref.upper())
1451                if res and res[0].pin == pin_str:
1452                    do = 0
1453                    err = 'Application PINs cannot be reused.'
1454                    s_logger.info('%s entered same PIN as for screening application %s' % (s_id,pin_str))
1455
1456        while do:
1457            ok,record = pins.searchAndSetRecord(pin,ref,prefix)
1458            if ok < -2 or ok > 2:
1459                err = 'Unknown error, please report!'
1460                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1461                break
1462            elif ok == -2:
1463                err = 'Service already is activated but with a different PIN.'
1464                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1465                break
1466            elif ok == -1:
1467                err = 'Invalid PIN'
1468                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1469                break
1470            if ok == 0:
1471                err = 'PIN already used'
1472                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1473                break
1474            if ok >= 1:
1475                #import pdb;pdb.set_trace()
1476                if self.isStudent():
1477                    if self.reference == "jamb_reg_no":
1478                        err = "You are already logged in."
1479                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1480                        break
1481                    if ok == 1:
1482                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1483                    else:
1484                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1485                    break
1486                else:
1487                    student = getStudentByRegNo(self,ref)
1488                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1489                if student is None:
1490                    err = "Student record not found."
1491                    s_logger.info('%s not found in admission list' % (ref))
1492                    break
1493                s_id = student.getId()
1494                if ok == 2:
1495                    if self.reference == "jamb_reg_no":
1496                        if hasattr(self.portal_directories.students,s_id):
1497                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1498                            mapping = {'id': s_id}
1499                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1500                            break
1501                        else:
1502                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1503                    else:
1504                        err = "Unknown error"
1505                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1506                        break
1507                try:
1508                    student.getContent().makeStudentMember(s_id,password=n)
1509                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1510                except:
1511                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1512                    mapping = {'id': s_id}
1513                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1514                    break
1515            break
1516        if err:
1517            datastructure.setError(widget_id, err,mapping)
1518        else:
1519            datamodel = datastructure.getDataModel()
1520            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1521            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1522            datastructure[widget_id+'_p'] = prefix
1523            datastructure[widget_id+'_b'] = b
1524            datastructure[widget_id+'_n'] = n
1525            datastructure['s_id'] = s_id
1526        return not err
1527
1528###)
1529
1530    def render(self, mode, datastructure, **kw): ###(
1531        """Render in mode from datastructure."""
1532        render_method = 'widget_scratch_card_pin_render'
1533        meth = getattr(self, render_method, None)
1534        if meth is None:
1535            raise RuntimeError("Unknown Render Method %s for widget type %s"
1536                               % (render_method, self.getId()))
1537
1538        # XXX AT: datastructure has to be set again here, in case we're in edit
1539        # or create mode, because a default value has to be provided.
1540        #import pdb;pdb.set_trace()
1541        datamodel = datastructure.getDataModel()
1542        v = datamodel[self.fields[0]]
1543        if v and type(v) is StringType:
1544            try:
1545                p,b,n = v.split('-')
1546                v = ScratchCardPin(p,b,n)
1547            except ValueError:
1548                v = ScratchCardPin(self.prefix,'XXX',v)
1549                pass
1550        if v:
1551            prefix= '%s' % v.p
1552            b = '%s' % v.b
1553            n = '%s' % v.n
1554        else:
1555            prefix= self.prefix
1556            if prefix.startswith('@'):
1557                prefix= getattr(self,self.prefix[1:])()
1558            b = n = ''
1559            v = ScratchCardPin(prefix,b,n)
1560        widget_id = self.getWidgetId()
1561        datastructure[widget_id] = v
1562        datastructure[widget_id+'_p'] = prefix
1563        datastructure[widget_id+'_b'] = b
1564        datastructure[widget_id+'_n'] = n
1565        return meth(mode=mode,
1566                    datastructure=datastructure,
1567                    )
1568    ###)
1569
1570InitializeClass(ScratchcardPinWidget)
1571widgetRegistry.register(ScratchcardPinWidget)
1572###)
1573
1574class PumePinWidget(ScratchcardPinWidget): ###(
1575    """ Pume Pin Widget"""
1576    meta_type = "Pume Pin Widget"
1577    catalog = "applicants_catalog"
1578    reference = ''
1579
1580    def prepare(self, datastructure, **kw): ###(
1581        """Prepare datastructure from datamodel."""
1582        datamodel = datastructure.getDataModel()
1583        #import pdb;pdb.set_trace()
1584        v = datamodel[self.fields[0]]
1585        widget_id = self.getWidgetId()
1586        if v and type(v) is StringType:
1587            try:
1588                p,b,n = v.split('-')
1589                v = ScratchCardPin(p,b,n)
1590            except ValueError:
1591                v = ScratchCardPin(v,'','')
1592        if v:
1593            p = '%s' % v.p
1594            b = '%s' % v.b
1595            n = '%s' % v.n
1596        else:
1597            p = self.prefix
1598            if p.startswith('@'):
1599                p = getattr(self,self.prefix[1:])()
1600            b = n = ''
1601            v = ScratchCardPin(p,b,n)
1602        datastructure[widget_id] = v
1603        datastructure[widget_id+'_p'] = p
1604        datastructure[widget_id+'_b'] = b
1605        datastructure[widget_id+'_n'] = n
1606    ###)
1607
1608    def validate(self, datastructure, **kw): ###(
1609        """Validate datastructure and update datamodel."""
1610        s_logger = logging.getLogger('Widgets.PumePinWidget.validate')
1611        widget_id = self.getWidgetId()
1612        v = datastructure[widget_id]
1613        err = 0
1614        mapping = {}
1615        prefix= self.prefix
1616        if prefix.startswith('@'):
1617            prefix= getattr(self,self.prefix[1:])()
1618        b = datastructure[widget_id+'_b'].strip()
1619        n = datastructure[widget_id+'_n'].strip()
1620        pins = self.portal_pins
1621        pin = "%(prefix)s%(b)s%(n)s" % vars()
1622        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1623        member_id = str(self.portal_membership.getAuthenticatedMember())
1624        do = 1
1625        expiration_date = self.REQUEST.get('expiration_date')
1626        if self.isStaff():
1627            do = 0
1628            err ='You are logged in, please log out. PIN neither checked nor used.'
1629            s_logger.info('%s tried to use scratch card %s' % (member_id,pin_str))
1630        elif self.isStudent():
1631            do = 0
1632            #ref = datastructure[self.reference]
1633            err ='You are logged in, please log out. PIN neither checked nor used.'
1634            s_logger.info('%s applied for screening test while logged in with pin %s' % (member_id,pin_str))
1635        elif len(b) > 1 and b.find('-') > -1:
1636            do = 0
1637            err = 'PIN must not contain "-"'
1638            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1639        elif n.find('-') > -1:
1640            do = 0
1641            err = 'PIN must not contain "-"'
1642            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1643        elif len(n) != 10:
1644            do = 0
1645            err = 'Invalid PIN length'
1646            s_logger.info('%s entered invalid PIN with length %d' % (member_id,len(n)))
1647        elif self.reference == "":
1648            # see fceokene #147. must be also changed for uniben after clearing the catalog
1649            #import pdb;pdb.set_trace()
1650            if 'uniben' in self.portal_url():
1651                ref = n
1652            else:
1653                ref = pin
1654        else:
1655            ref = datastructure[self.reference]
1656            if datastructure.errors:
1657                do = 0
1658                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1659                s_logger.info('%s/%s entered wrong data together with PIN %s' % (member_id,ref,pin_str))
1660        while do:
1661            if self.REQUEST.traverse_subpath:
1662                screening_type_request = self.REQUEST.traverse_subpath[0]
1663            else:
1664                screening_type_request = 'manage'
1665            if datastructure.has_key('record'):
1666                applicant = datastructure['record']
1667                if applicant.screening_type != screening_type_request and screening_type_request != 'manage':
1668                    err = "You are using the wrong access form!"
1669                    s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1670                    break
1671            elif expiration_date and DateTime(expiration_date).lessThan(DateTime()):
1672                if not pins(student=ref):
1673                    if not self.applicants_catalog(reg_no=ref):
1674                        err = 'no application record found'
1675                        s_logger.info('%s/%s tried new application though expired with PIN %s' % (member_id,ref,pin_str))
1676                        break
1677                    else:
1678                        s_logger.info('%s/%s entered application record which has been created by import (with PIN %s)' % (member_id,ref,pin_str))
1679            ok,pin_record = pins.searchAndSetRecord(pin,ref,prefix)
1680            if ok < -2 or ok > 2:
1681                err = 'Unknown error, please report!'
1682                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
1683                break
1684            elif ok == -2:
1685                err = 'Service is already activated but with a different PIN.'
1686                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
1687                break
1688            elif ok == -1:
1689                err = 'Invalid PIN'
1690                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
1691                break
1692            if ok == 0:
1693                err = 'PIN already used'
1694                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
1695                break
1696            if ok >= 1:
1697                #screening_type = self.REQUEST.form.get('screening_type','unknown')
1698                #screening_type = datastructure['screening_type']
1699                if datastructure.has_key('record'):
1700                    applicant = datastructure['record']
1701                    if applicant.screening_type != screening_type_request\
1702                          and screening_type_request != 'manage':
1703                        err = "You are using the wrong access form!"
1704                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1705                        break
1706                    if not applicant.pin:
1707                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1708                        d = {}
1709                        d['reg_no'] = applicant.reg_no
1710                        d['pin'] = pin_str
1711                        #d['screening_type'] = screening_type
1712                        #d['status'] = 'entered'
1713                        getattr(self,self.catalog).modifyRecord(**d)
1714                    elif applicant.pin != pin_str:
1715                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
1716                    elif applicant.pin == pin_str:
1717                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1718                else:
1719                    datastructure['reg_no'] = ref
1720                    res = self.applicants_catalog(reg_no = ref)
1721                    if res:
1722                        if getattr(res[0],'screening_type',None) != screening_type_request\
1723                              and screening_type_request != 'manage':
1724                            err = "You are using the wrong access form!"
1725                            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)))
1726                            break
1727                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1728                    else:
1729                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1730                        d = {}
1731                        d['reg_no'] = ref
1732                        d['pin'] = pin_str
1733                        d['status'] = 'entered'
1734                        d['screening_type'] = screening_type_request
1735                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
1736                                                  pin_record.serial)
1737                        self.applicants_catalog.addRecord(**d)
1738
1739            break
1740        if err:
1741            datastructure.setError(widget_id, err,mapping)
1742        else:
1743            datamodel = datastructure.getDataModel()
1744            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1745            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1746            datastructure[widget_id+'_p'] = prefix
1747            datastructure[widget_id+'_b'] = b
1748            datastructure[widget_id+'_n'] = n
1749        return not err
1750    ###)
1751
1752    def render(self, mode, datastructure, **kw): ###(
1753        """Render in mode from datastructure."""
1754        render_method = 'widget_scratch_card_pin_render'
1755        meth = getattr(self, render_method, None)
1756        if meth is None:
1757            raise RuntimeError("Unknown Render Method %s for widget type %s"
1758                               % (render_method, self.getId()))
1759
1760        # XXX AT: datastructure has to be set again here, in case we're in edit
1761        # or create mode, because a default value has to be provided.
1762        #import pdb;pdb.set_trace()
1763        datamodel = datastructure.getDataModel()
1764        v = datamodel[self.fields[0]]
1765        #import pdb;pdb.set_trace()
1766        if v and type(v) is StringType:
1767            try:
1768                p,b,n = v.split('-')
1769                v = ScratchCardPin(p,b,n)
1770            except ValueError:
1771                v = ScratchCardPin(self.prefix,'XXX',v)
1772                pass
1773        if v:
1774            prefix= '%s' % v.p
1775            b = '%s' % v.b
1776            n = '%s' % v.n
1777        else:
1778            prefix= self.prefix
1779            if prefix.startswith('@'):
1780                prefix= getattr(self,self.prefix[1:])()
1781            b = n = ''
1782            v = ScratchCardPin(prefix,b,n)
1783        widget_id = self.getWidgetId()
1784        datastructure[widget_id] = v
1785        datastructure[widget_id+'_p'] = prefix
1786        datastructure[widget_id+'_b'] = b
1787        datastructure[widget_id+'_n'] = n
1788        return meth(mode=mode,
1789                    datastructure=datastructure,
1790                    )
1791    ###)
1792
1793InitializeClass(PumePinWidget)
1794widgetRegistry.register(PumePinWidget)
1795###)
1796
1797class WAeUPImageWidget(CPSImageWidget): ###(
1798    """Photo widget."""
1799    meta_type = 'WAeUP Image Widget'
1800
1801    def render(self, mode, datastructure, **kw):
1802        render_method = 'widget_waeup_image_render'
1803        meth = getattr(self, render_method, None)
1804        if meth is None:
1805            raise RuntimeError("Unknown Render Method %s for widget type %s"
1806                               % (render_method, self.getId()))
1807        img_info = self.getImageInfo(datastructure)
1808        return meth(mode=mode, datastructure=datastructure, **img_info)
1809
1810InitializeClass(WAeUPImageWidget)
1811
1812widgetRegistry.register(WAeUPImageWidget)
1813###)
1814
1815class ApplicationImageWidget(CPSImageWidget): ###(
1816    """Image widget with filesystem storage."""
1817    meta_type = 'Application Image Widget'
1818    _properties = CPSImageWidget._properties +\
1819    (
1820     {'id': 'path', 'type': 'string', 'mode': 'w',
1821      'label': 'Relative Path'},
1822     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1823      'label': 'Field to build the id'},
1824    )
1825    path = "images"
1826    storage_path = "%s/import/%s" % (i_home,path)
1827    id_field = "reg_no"
1828
1829    def getImageInfo(self, datastructure): ###(
1830        """Get the file info from the datastructure."""
1831        widget_id = self.getWidgetId()
1832        if  datastructure.has_key(widget_id):
1833            fileupload = datastructure[widget_id]
1834            dm = datastructure.getDataModel()
1835            field_id = self.fields[0]
1836            screening_type = datastructure.get('screening_type')
1837            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1838                                            field_id,)
1839            base_path = os.path.join(screening_type,current_filename)
1840            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1841            file_path = os.path.join(self.storage_path,base_path)
1842            #import pdb; pdb.set_trace()
1843        else:
1844            file_path = "XXX"
1845        # read the file from the filesystem
1846        if not os.path.exists(file_path):
1847            height = -1
1848            width = -1
1849            empty_file = True
1850            session_file = False
1851            current_filename = ''
1852            content_url = ''
1853            size = 0
1854            mimetype = ''
1855            last_modified = ''
1856            height = ''
1857            width = ''
1858
1859        else:
1860            image = open(file_path)
1861            from OFS.Image import getImageInfo as getImageInfoOFS
1862            image.seek(0)
1863            data = image.read(2000)
1864            size = len(data)
1865            empty_file = size == 0
1866            session_file = False
1867            last_modified = ''
1868            image.close()
1869            mimetype, width, height = getImageInfoOFS(data)
1870
1871            if width < 0:
1872                width = None
1873            if height < 0:
1874                height = None
1875
1876            if (self.allow_resize
1877                and height is not None
1878                and width  is not None):
1879                z_w = z_h = 1
1880                h = int(self.display_height)
1881                w = int(self.display_width)
1882                if w and h:
1883                    if w < width:
1884                        z_w = w / float(width)
1885                    if h < height:
1886                        z_h = h / float(height)
1887                    zoom = min(z_w, z_h)
1888                    width = int(zoom * width)
1889                    height = int(zoom * height)
1890                #import pdb;pdb.set_trace()
1891        image_info = {
1892            'empty_file': empty_file,
1893            'session_file': session_file,
1894            'current_filename': current_filename,
1895            'size': size,
1896            'last_modified': last_modified,
1897            'content_url': content_url,
1898            'mimetype': mimetype,
1899            }
1900        title = image_info['current_filename']
1901        alt = title or ''
1902        #height = int(self.display_height)
1903        #width = int(self.display_width)
1904        if height is None or width is None:
1905            tag = renderHtmlTag('img', src=image_info['content_url'],
1906                                alt=alt, title=title)
1907        else:
1908            tag = renderHtmlTag('img', src=image_info['content_url'],
1909                                width=str(width), height=str(height),
1910                                alt=alt, title=title)
1911
1912        image_info['height'] = height
1913        image_info['width'] = width
1914        image_info['image_tag'] = tag
1915        return image_info
1916    ###)
1917
1918    def checkFileName(self, filename, mimetype):
1919        return '', {}
1920        if mimetype and mimetype.startswith('image'):
1921            return '', {}
1922        return 'cpsschemas_err_image', {}
1923
1924    def prepare(self, datastructure, **kw): ###(
1925        """Prepare datastructure from datamodel."""
1926        datamodel = datastructure.getDataModel()
1927        widget_id = self.getWidgetId()
1928        file_name = datamodel[self.fields[0]]
1929        #import pdb; pdb.set_trace()
1930        if self.allow_resize:
1931            datastructure[self.getWidgetId() + '_resize'] = ''
1932        screening_type = datamodel.get('screening_type',None)
1933        if not screening_type:
1934            screening_type = self.REQUEST.form.get('screening_type','pume')
1935        datastructure["screening_type"] = screening_type
1936        datastructure[widget_id] = file_name
1937        datastructure[widget_id + '_choice'] = 'change'
1938        title = 'Passport Foto'
1939        datastructure[widget_id + '_filename'] = title
1940    ###)
1941
1942    def validate(self, datastructure, **kw): ###(
1943        """Update datamodel from user data in datastructure.
1944        """
1945        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1946        datamodel = datastructure.getDataModel()
1947        field_id = self.fields[0]
1948        widget_id = self.getWidgetId()
1949        store = False
1950        fileupload = None
1951        mimetype = None
1952        old_file = datamodel[field_id]
1953        # if old_file is not None:
1954        #     old_filename = old_file.title
1955        # else:
1956        #     old_filename = ''
1957        choice = datastructure[widget_id+'_choice']
1958        fileupload = datastructure[widget_id]
1959        is_upload = isinstance(fileupload, FileUpload)
1960        #import pdb; pdb.set_trace()
1961        if not is_upload and not datamodel[field_id]:
1962            if self.is_required:
1963                return self.validateError('Picture upload required', {},
1964                                          datastructure)
1965        if choice == 'delete':
1966            if self.is_required:
1967                return self.validateError('cpsschemas_err_required', {},
1968                                          datastructure)
1969            datamodel[field_id] = None
1970        elif choice == 'keep':
1971            fileupload = datastructure[widget_id]
1972            if isinstance(fileupload, PersistableFileUpload):
1973                # Keeping something from the session means we
1974                # actually want to store it.
1975                store = True
1976            # else:
1977            #     # Nothing to change, don't pollute datastructure
1978            #     # with something costly already stored, which therefore
1979            #     # doesn't need to be kept in the session.
1980            #     self.unprepare(datastructure)
1981        elif choice == 'change' and is_upload:
1982            if not fileupload:
1983                return self.validateError('cpsschemas_err_file_empty', {},
1984                                          datastructure)
1985            if not isinstance(fileupload, FileUpload):
1986                return self.validateError('cpsschemas_err_file', {},
1987                                          datastructure)
1988            fileupload.seek(0, 2) # end of file
1989            size = fileupload.tell()
1990            if not size:
1991                return self.validateError('cpsschemas_err_file_empty', {},
1992                                          datastructure)
1993            if self.size_max and size > self.size_max:
1994                max_size_str = self.getHumanReadableSize(self.size_max)
1995                err = 'This file is too big, the allowed max size is ${max_size}'
1996                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1997                err_mapping = {'max_size': max_size_str}
1998                return self.validateError(err, err_mapping, datastructure)
1999            store = True
2000
2001
2002        # Find filename
2003        if is_upload and store:
2004            ext ='jpg'
2005            screening_type = datastructure.get('screening_type')
2006            filename = "%s_%s.%s" % (datastructure[self.id_field],
2007                                     self.getWidgetId(),
2008                                     ext)
2009            datamodel[field_id] = filename
2010            registry = getToolByName(self, 'mimetypes_registry')
2011            mimetype = registry.lookupExtension(filename.lower())
2012            if mimetype is not None:
2013                mimetype = str(mimetype) # normalize
2014            file = self.makeFile(filename, fileupload, datastructure)
2015            # Fixup mimetype
2016            if mimetype and file.content_type != mimetype:
2017                file.content_type = mimetype
2018            # Store the file in the filesystem
2019            #import pdb;pdb.set_trace()
2020            base_path = os.path.join(self.storage_path, screening_type)
2021            if not os.path.exists(base_path):
2022                os.mkdir(base_path)
2023            full_path = os.path.join(base_path, filename)
2024            pict = open(full_path,"w")
2025            fileupload.seek(0)
2026            pict.write(fileupload.read())
2027            pict.close()
2028        return True
2029
2030###)
2031
2032    def render(self, mode, datastructure, **kw): ###(
2033        render_method = 'widget_passport_render'
2034        meth = getattr(self, render_method, None)
2035        if meth is None:
2036            raise RuntimeError("Unknown Render Method %s for widget type %s"
2037                               % (render_method, self.getId()))
2038        img_info = self.getImageInfo(datastructure)
2039        return meth(mode=mode, datastructure=datastructure, **img_info)
2040    ###)
2041
2042InitializeClass(ApplicationImageWidget)
2043
2044widgetRegistry.register(ApplicationImageWidget)
2045###)
2046
2047class FileImageWidget(CPSImageWidget): ###(
2048    """Image widget with filesystem storage."""
2049    meta_type = 'File Image Widget'
2050    _properties = CPSImageWidget._properties +\
2051    (
2052     {'id': 'path', 'type': 'string', 'mode': 'w',
2053      'label': 'Relative Path'},
2054     {'id': 'id_field', 'type': 'string', 'mode': 'w',
2055      'label': 'Field to build the id'},
2056     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
2057      'label': 'Show Image'},
2058    )
2059    path = "images"
2060    #storage_path = "%s/%s" % (i_home,path)
2061    id_field = ""
2062    show_image = False
2063
2064    def getStorageImageInfo(self,field_id):
2065        info = {}
2066        if self.id_field == "":
2067            student_id = self.getStudentId()
2068        else:
2069            student_id = datastructure[self.id_field]
2070        # student_path = os.path.join(self.storage_path,
2071        #                             student_id)
2072        student_path = getImagesDir(student_id)
2073        image_name = ''
2074        content_url = ''
2075        current_filename = ''
2076        if os.path.exists(student_path):
2077            for name in os.listdir(student_path):
2078                if name.startswith(field_id):
2079                    image_name = name
2080                    break
2081        if image_name:
2082            info['image_name'] = image_name
2083            info['content_url'] = os.path.join(self.portal_url(),
2084                                               "viewimage",
2085                                               student_id,
2086                                               image_name,
2087                                              )
2088            info['current_filename'] =  image_name
2089            info['file_path'] = os.path.join(student_path, image_name)
2090        return info
2091
2092    def getImageInfo(self, datastructure): ###(
2093        """Get the file info from the datastructure."""
2094        widget_id = self.getWidgetId()
2095        info = None
2096        if  datastructure.has_key(widget_id):
2097            fileupload = datastructure[widget_id]
2098            dm = datastructure.getDataModel()
2099            field_id = self.fields[0]
2100            info = self.getStorageImageInfo(field_id)
2101        else:
2102            file_path = "XXX"
2103            title = ""
2104        # read the file from the filesystem
2105        #import pdb; pdb.set_trace()
2106        #if not os.path.exists(file_path):
2107        if not info:
2108            title = ""
2109            height = -1
2110            width = -1
2111            empty_file = True
2112            session_file = False
2113            current_filename = ''
2114            content_url = ''
2115            size = 0
2116            mimetype = ''
2117            last_modified = ''
2118            height = ''
2119            width = ''
2120        else:
2121            title = info['image_name']
2122            current_filename = info['current_filename']
2123            content_url = info['content_url']
2124            image = open(info['file_path'])
2125            from OFS.Image import getImageInfo as getImageInfoOFS
2126            image.seek(0)
2127            data = image.read(2000)
2128            size = len(data)
2129            empty_file = size == 0
2130            session_file = False
2131            last_modified = ''
2132            image.close()
2133            mimetype, width, height = getImageInfoOFS(data)
2134            registry = getToolByName(self, 'mimetypes_registry')
2135            mimetype = (registry.lookupExtension(current_filename.lower()) or
2136                        registry.lookupExtension('file.bin'))
2137            if width < 0:
2138                width = None
2139            if height < 0:
2140                height = None
2141
2142            if (self.allow_resize
2143                and height is not None
2144                and width  is not None):
2145                z_w = z_h = 1
2146                h = int(self.display_height)
2147                w = int(self.display_width)
2148                if w and h:
2149                    if w < width:
2150                        z_w = w / float(width)
2151                    if h < height:
2152                        z_h = h / float(height)
2153                    zoom = min(z_w, z_h)
2154                    width = int(zoom * width)
2155                    height = int(zoom * height)
2156                #import pdb;pdb.set_trace()
2157        image_info = {
2158            'empty_file': empty_file,
2159            'session_file': session_file,
2160            'current_filename': title,
2161            'size': size,
2162            'last_modified': last_modified,
2163            'content_url': content_url,
2164            'mimetype': mimetype,
2165            }
2166        alt = title or ''
2167        #height = int(self.display_height)
2168        #width = int(self.display_width)
2169        if height is None or width is None:
2170            tag = renderHtmlTag('img', src=image_info['content_url'],
2171                                alt=alt, title=title)
2172        else:
2173            tag = renderHtmlTag('img', src=image_info['content_url'],
2174                                width=str(width), height=str(height),
2175                                alt=alt, title=title)
2176
2177        image_info['height'] = height
2178        image_info['width'] = width
2179        image_info['image_tag'] = tag
2180        image_info['show_image'] = self.show_image
2181        return image_info
2182    ###)
2183
2184    # def checkFileName(self, filename, mimetype):
2185    #     return '', {}
2186    #     if mimetype and mimetype.startswith('image'):
2187    #         return '', {}
2188    #     return 'cpsschemas_err_image', {}
2189
2190    def prepare(self, datastructure, **kw): ###(
2191        """Prepare datastructure from datamodel."""
2192        datamodel = datastructure.getDataModel()
2193        widget_id = self.getWidgetId()
2194        file_name = datamodel[self.fields[0]]
2195        if self.id_field == "":
2196            student_id = self.getStudentId()
2197        else:
2198            student_id = datastructure[self.id_field]
2199        if student_id is not None:
2200            # student_path = os.path.join(self.storage_path,
2201            #                             student_id)
2202            student_path = getImagesDir(student_id)
2203            if not os.path.exists(student_path):
2204                self.waeup_tool.moveImagesToFS(student_id)
2205        if self.allow_resize:
2206            datastructure[self.getWidgetId() + '_resize'] = ''
2207        datastructure[widget_id] = file_name
2208        datastructure[widget_id + '_choice'] = 'change'
2209        title = 'Passport Foto'
2210        datastructure[widget_id + '_filename'] = title
2211    ###)
2212
2213    def validate(self, datastructure, **kw): ###(
2214        """Update datamodel from user data in datastructure.
2215        """
2216        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2217        datamodel = datastructure.getDataModel()
2218        field_id = self.fields[0]
2219        widget_id = self.getWidgetId()
2220        store = False
2221        fileupload = None
2222        mimetype = None
2223        old_file = datamodel[field_id]
2224        choice = datastructure[widget_id+'_choice']
2225        fileupload = datastructure[widget_id]
2226        is_upload = isinstance(fileupload, FileUpload)
2227        #import pdb; pdb.set_trace()
2228        if not is_upload and not datamodel[field_id]:
2229            if self.is_required:
2230                return self.validateError('Picture upload required', {},
2231                                          datastructure)
2232        if self.id_field == "":
2233            student_id = self.getStudentId()
2234        else:
2235            student_id = datastructure[self.id_field]
2236        if choice == 'delete':
2237            if self.is_required:
2238                return self.validateError('cpsschemas_err_required', {},
2239                                          datastructure)
2240            info= self.getStorageImageInfo(field_id)
2241            # Remove the file in the filesystem
2242            if info:
2243                os.remove(info['file_path'])
2244            datamodel[field_id] = None
2245        elif choice == 'keep':
2246            fileupload = datastructure[widget_id]
2247            if isinstance(fileupload, PersistableFileUpload):
2248                # Keeping something from the session means we
2249                # actually want to store it.
2250                store = True
2251            # else:
2252            #     # Nothing to change, don't pollute datastructure
2253            #     # with something costly already stored, which therefore
2254            #     # doesn't need to be kept in the session.
2255            #     self.unprepare(datastructure)
2256        elif choice == 'change' and is_upload:
2257            if not fileupload:
2258                return self.validateError('cpsschemas_err_file_empty', {},
2259                                          datastructure)
2260            if not isinstance(fileupload, FileUpload):
2261                return self.validateError('cpsschemas_err_file', {},
2262                                          datastructure)
2263            fileupload.seek(0, 2) # end of file
2264            size = fileupload.tell()
2265            if not size:
2266                return self.validateError('cpsschemas_err_file_empty', {},
2267                                          datastructure)
2268            if self.size_max and size > self.size_max:
2269                max_size_str = self.getHumanReadableSize(self.size_max)
2270                err = 'This file is too big, the allowed max size is ${max_size}'
2271                member_id = str(self.portal_membership.getAuthenticatedMember())
2272                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2273                err_mapping = {'max_size': max_size_str}
2274                return self.validateError(err, err_mapping, datastructure)
2275            store = True
2276
2277
2278        # Find filename
2279        if is_upload and store:
2280            filename = cookId('', '', fileupload)[0].strip()
2281            base,ext = os.path.splitext(filename)
2282            filename = "%s_%s%s" % (field_id,
2283                                    student_id,
2284                                    ext)
2285            datamodel[field_id] = filename
2286            registry = getToolByName(self, 'mimetypes_registry')
2287            mimetype = registry.lookupExtension(filename.lower())
2288            if mimetype is not None:
2289                mimetype = str(mimetype) # normalize
2290            file = self.makeFile(filename, fileupload, datastructure)
2291            # Fixup mimetype
2292            if mimetype and file.content_type != mimetype:
2293                file.content_type = mimetype
2294            # Store the file in the filesystem
2295            #student_path = os.path.join(self.storage_path,student_id)
2296            student_path = getImagesDir(student_id)
2297            if not os.path.exists(student_path):
2298                os.mkdir(student_path)
2299            full_path = os.path.join(student_path, filename)
2300            pict = open(full_path,"w")
2301            #fileupload.seek(0)
2302            #import pdb; pdb.set_trace()
2303            pict.write(str(file.data))
2304            pict.close()
2305        return True
2306    ###)
2307
2308    def render(self, mode, datastructure, **kw): ###(
2309        render_method = 'widget_image_render'
2310        meth = getattr(self, render_method, None)
2311        #import pdb;pdb.set_trace()
2312        if meth is None:
2313            raise RuntimeError("Unknown Render Method %s for widget type %s"
2314                               % (render_method, self.getId()))
2315        img_info = self.getImageInfo(datastructure)
2316        return meth(mode=mode, datastructure=datastructure, **img_info)
2317    ###)
2318
2319InitializeClass(FileImageWidget)
2320
2321widgetRegistry.register(FileImageWidget)
2322###)
2323
2324class DiscFileWidget(CPSFileWidget): ###(
2325    """File widget with filesystem storage."""
2326    meta_type = 'Disc File Widget'
2327    _properties = CPSFileWidget._properties +\
2328    (
2329     {'id': 'path', 'type': 'string', 'mode': 'w',
2330      'label': 'Relative Path'},
2331    )
2332    path = "import"
2333    storage_path = "%s/%s" % (i_home,path)
2334
2335    def getStoredFileInfo(self,datastructure): ###(
2336        datamodel = datastructure.getDataModel()
2337        field_id = self.fields[0]
2338        widget_id = self.getWidgetId()
2339        file_name = datamodel[field_id]
2340        info = {}
2341        registry = getToolByName(self, 'mimetypes_registry')
2342        info['mimetype'] = registry.lookupExtension('file.csv')
2343        info['empty_file'] = True
2344        info['size'] = 0
2345        info['last_modified'] = ''
2346        file_path = os.path.join(self.storage_path, file_name)
2347        if os.path.exists(file_path):
2348            info['empty_file'] = False
2349            info['file_name'] = file_name
2350            info['content_url'] = os.path.join(self.portal_url(),
2351                                            "viewfile",
2352                                            file_name,
2353                                            )
2354            info['current_filename'] =  file_name
2355            # get the mimetype
2356            mimetype = (registry.lookupExtension(file_name.lower()) or
2357                        registry.lookupExtension('file.bin'))
2358            info['mimetype'] = mimetype
2359            info['file_path'] = file_path
2360        else:
2361            info['file_name'] = ''
2362            info['content_url'] = ''
2363            info['current_filename'] = ''
2364            info['file_path'] = ''
2365        return info
2366        ###)
2367
2368    def prepare(self, datastructure, **kw): ###(
2369        """Prepare datastructure from datamodel."""
2370        datamodel = datastructure.getDataModel()
2371        #import pdb;pdb.set_trace()
2372        widget_id = self.getWidgetId()
2373        file_name = datamodel[self.fields[0]]
2374        datastructure[widget_id] = file_name
2375        datastructure[widget_id + '_filename'] = file_name
2376        datastructure[widget_id+'_choice'] = "keep"
2377    ###)
2378
2379    def validate(self, datastructure, **kw): ###(
2380        """Update datamodel from user data in datastructure.
2381        """
2382        logger = logging.getLogger('Widgets.DiscFileWidget.validate')
2383        datamodel = datastructure.getDataModel()
2384        field_id = self.fields[0]
2385        widget_id = self.getWidgetId()
2386        store = False
2387        fileupload = None
2388        mimetype = None
2389        old_file = datamodel[field_id]
2390        choice = datastructure[widget_id+'_choice']
2391        fileupload = datastructure[widget_id]
2392        is_upload = isinstance(fileupload, FileUpload)
2393        if not is_upload and not datamodel[field_id]:
2394            if self.is_required:
2395                return self.validateError('File upload required', {},
2396                                          datastructure)
2397        if choice == 'delete':
2398            if self.is_required:
2399                return self.validateError('cpsschemas_err_required', {},
2400                                          datastructure)
2401            info = self.getStoredFileInfo(datastructure)
2402            # Remove the file in the filesystem
2403            if info:
2404                os.remove(info['file_path'])
2405            datamodel[field_id] = None
2406        elif choice == 'keep':
2407            fileupload = datastructure[widget_id]
2408            if isinstance(fileupload, PersistableFileUpload):
2409                # Keeping something from the session means we
2410                # actually want to store it.
2411                store = True
2412            # else:
2413            #     # Nothing to change, don't pollute datastructure
2414            #     # with something costly already stored, which therefore
2415            #     # doesn't need to be kept in the session.
2416            #     self.unprepare(datastructure)
2417        elif choice == 'change' and is_upload:
2418            if not fileupload:
2419                return self.validateError('cpsschemas_err_file_empty', {},
2420                                          datastructure)
2421            if not isinstance(fileupload, FileUpload):
2422                return self.validateError('cpsschemas_err_file', {},
2423                                          datastructure)
2424            fileupload.seek(0, 2) # end of file
2425            size = fileupload.tell()
2426            if not size:
2427                return self.validateError('cpsschemas_err_file_empty', {},
2428                                          datastructure)
2429            if self.size_max and size > self.size_max:
2430                max_size_str = self.getHumanReadableSize(self.size_max)
2431                err = 'This file is too big, the allowed max size is ${max_size}'
2432                member_id = str(self.portal_membership.getAuthenticatedMember())
2433                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2434                err_mapping = {'max_size': max_size_str}
2435                return self.validateError(err, err_mapping, datastructure)
2436            store = True
2437
2438
2439        # Find filename
2440        if is_upload and store:
2441            filename = cookId('', '', fileupload)[0].strip()
2442            base,ext = os.path.splitext(filename)
2443            if ext not in ("csv",".csv"):
2444                return self.validateError('only csv files allowed', {},
2445                                          datastructure)
2446            uploads_folder = self.portal_url.getPortalObject().campus.uploads
2447            if hasattr(uploads_folder,filename):
2448                return self.validateError('upload object exists', {},
2449                                          datastructure)
2450            datamodel[field_id] = filename
2451            registry = getToolByName(self, 'mimetypes_registry')
2452            mimetype = registry.lookupExtension(filename.lower())
2453            if mimetype is not None:
2454                mimetype = str(mimetype) # normalize
2455            file = self.makeFile(filename, fileupload, datastructure)
2456            # Fixup mimetype
2457            if mimetype and file.content_type != mimetype:
2458                file.content_type = mimetype
2459            file_path = os.path.join(self.storage_path,filename)
2460            data = open(file_path,"w")
2461            data.write(str(file.data))
2462            data.close()
2463        return True
2464    ###)
2465
2466    def render(self, mode, datastructure, **kw): ###(
2467        render_method = 'widget_uploadfile_render'
2468        meth = getattr(self, render_method, None)
2469        #import pdb;pdb.set_trace()
2470        if meth is None:
2471            raise RuntimeError("Unknown Render Method %s for widget type %s"
2472                               % (render_method, self.getId()))
2473        file_info = self.getStoredFileInfo(datastructure)
2474
2475        return meth(mode=mode, datastructure=datastructure, **file_info)
2476    ###)
2477
2478InitializeClass(DiscFileWidget)
2479
2480widgetRegistry.register(DiscFileWidget)
2481
2482
2483class RegMatricNoWidget(CPSStringWidget): ###(
2484    """ RegMatricNo Widget"""
2485    meta_type = "RegMatricNo Widget"
2486    def validate(self, datastructure, **kw):
2487        """Validate datastructure and update datamodel."""
2488        valid = CPSStringWidget.validate(self, datastructure, **kw)
2489        widget_id = self.getWidgetId()
2490        value = datastructure[widget_id].upper()
2491        err = 0
2492        #import pdb;pdb.set_trace()
2493        if not valid:
2494            err = 'Invalid number'
2495        else:
2496            student_record = self.students_catalog(jamb_reg_no = value)
2497            if len(student_record) < 1:
2498                student_record = self.students_catalog(matric_no = value)
2499                if len(student_record) < 1:
2500                    err = 'No student record with this registration or matric number'
2501                else:
2502                    datastructure['record'] = student_record[0]
2503                    #import pdb;pdb.set_trace()
2504            else:
2505                datastructure['record'] = student_record[0]
2506                #import pdb;pdb.set_trace()
2507        if err:
2508            datastructure.setError(widget_id, err)
2509        else:
2510            datamodel = datastructure.getDataModel()
2511            datamodel[self.fields[0]] = value
2512       
2513        return not err
2514
2515InitializeClass(RegMatricNoWidget)
2516
2517widgetRegistry.register(RegMatricNoWidget)
2518
2519class CheckEmailWidget(CPSStringWidget): ###(
2520    """ CheckEmail Widget"""
2521    meta_type = "CheckEmail Widget"
2522    def validate(self, datastructure, **kw):
2523        """Validate datastructure and update datamodel."""
2524        if datastructure.errors:
2525            return
2526        valid = CPSStringWidget.validate(self, datastructure, **kw)
2527        widget_id = self.getWidgetId()
2528        value = datastructure[widget_id].upper()
2529        err = 0
2530        #import pdb;pdb.set_trace()
2531        if not valid:
2532            err = 'Invalid string'
2533        else:
2534            email_cat = datastructure['record'].email.upper()
2535            if email_cat != value:
2536                err = 'Email address does not match'
2537            else:
2538                pass
2539        if err:
2540            datastructure.setError(widget_id, err)
2541        else:
2542            datamodel = datastructure.getDataModel()
2543            datamodel[self.fields[0]] = value           
2544       
2545        return not err
2546
2547InitializeClass(CheckEmailWidget)
2548
2549widgetRegistry.register(CheckEmailWidget)
2550
2551###)
2552
2553###########
2554
Note: See TracBrowser for help on using the repository browser.