source: WAeUP_SRP/trunk/Widgets.py @ 4020

Last change on this file since 4020 was 3998, checked in by Henrik Bettermann, 16 years ago

fix 2

  • Property svn:keywords set to Id
File size: 97.1 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 3998 2009-03-05 11:39:58Z 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            ref = n
1649        else:
1650            ref = datastructure[self.reference]
1651            if datastructure.errors:
1652                do = 0
1653                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1654                s_logger.info('%s/%s entered wrong data together with PIN %s' % (member_id,ref,pin_str))
1655        while do:
1656            if self.REQUEST.traverse_subpath:
1657                screening_type_request = self.REQUEST.traverse_subpath[0]
1658            else:
1659                screening_type_request = 'manage'
1660            if datastructure.has_key('record'):
1661                applicant = datastructure['record']
1662                if applicant.screening_type != screening_type_request and screening_type_request != 'manage':
1663                    err = "You are using the wrong access form!"
1664                    s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1665                    break
1666            elif expiration_date and DateTime(expiration_date).lessThan(DateTime()):
1667                if not pins(student=ref):
1668                    if not self.applicants_catalog(reg_no=ref):
1669                        err = 'no application record found'
1670                        s_logger.info('%s/%s tried new application though expired with PIN %s' % (member_id,ref,pin_str))
1671                        break
1672                    else:
1673                        s_logger.info('%s/%s entered application record which has been created by import (with PIN %s)' % (member_id,ref,pin_str))
1674            ok,pin_record = pins.searchAndSetRecord(pin,ref,prefix)
1675            if ok < -2 or ok > 2:
1676                err = 'Unknown error, please report!'
1677                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
1678                break
1679            elif ok == -2:
1680                err = 'Service is already activated but with a different PIN.'
1681                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
1682                break
1683            elif ok == -1:
1684                err = 'Invalid PIN'
1685                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
1686                break
1687            if ok == 0:
1688                err = 'PIN already used'
1689                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
1690                break
1691            if ok >= 1:
1692                #screening_type = self.REQUEST.form.get('screening_type','unknown')
1693                #screening_type = datastructure['screening_type']
1694                if datastructure.has_key('record'):
1695                    applicant = datastructure['record']
1696                    if applicant.screening_type != screening_type_request\
1697                          and screening_type_request != 'manage':
1698                        err = "You are using the wrong access form!"
1699                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1700                        break
1701                    if not applicant.pin:
1702                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1703                        d = {}
1704                        d['reg_no'] = applicant.reg_no
1705                        d['pin'] = pin_str
1706                        #d['screening_type'] = screening_type
1707                        #d['status'] = 'entered'
1708                        getattr(self,self.catalog).modifyRecord(**d)
1709                    elif applicant.pin != pin_str:
1710                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
1711                    elif applicant.pin == pin_str:
1712                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1713                else:
1714                    datastructure['reg_no'] = ref
1715                    res = self.applicants_catalog(reg_no = ref)
1716                    if res:
1717                        if getattr(res[0],'screening_type',None) != screening_type_request\
1718                              and screening_type_request != 'manage':
1719                            err = "You are using the wrong access form!"
1720                            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)))
1721                            break
1722                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1723                    else:
1724                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1725                        d = {}
1726                        d['reg_no'] = ref
1727                        d['pin'] = pin_str
1728                        d['status'] = 'entered'
1729                        d['screening_type'] = screening_type_request
1730                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
1731                                                  pin_record.serial)
1732                        self.applicants_catalog.addRecord(**d)
1733
1734            break
1735        if err:
1736            datastructure.setError(widget_id, err,mapping)
1737        else:
1738            datamodel = datastructure.getDataModel()
1739            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1740            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1741            datastructure[widget_id+'_p'] = prefix
1742            datastructure[widget_id+'_b'] = b
1743            datastructure[widget_id+'_n'] = n
1744        return not err
1745    ###)
1746
1747    def render(self, mode, datastructure, **kw): ###(
1748        """Render in mode from datastructure."""
1749        render_method = 'widget_scratch_card_pin_render'
1750        meth = getattr(self, render_method, None)
1751        if meth is None:
1752            raise RuntimeError("Unknown Render Method %s for widget type %s"
1753                               % (render_method, self.getId()))
1754
1755        # XXX AT: datastructure has to be set again here, in case we're in edit
1756        # or create mode, because a default value has to be provided.
1757        #import pdb;pdb.set_trace()
1758        datamodel = datastructure.getDataModel()
1759        v = datamodel[self.fields[0]]
1760        #import pdb;pdb.set_trace()
1761        if v and type(v) is StringType:
1762            try:
1763                p,b,n = v.split('-')
1764                v = ScratchCardPin(p,b,n)
1765            except ValueError:
1766                v = ScratchCardPin(self.prefix,'XXX',v)
1767                pass
1768        if v:
1769            prefix= '%s' % v.p
1770            b = '%s' % v.b
1771            n = '%s' % v.n
1772        else:
1773            prefix= self.prefix
1774            if prefix.startswith('@'):
1775                prefix= getattr(self,self.prefix[1:])()
1776            b = n = ''
1777            v = ScratchCardPin(prefix,b,n)
1778        widget_id = self.getWidgetId()
1779        datastructure[widget_id] = v
1780        datastructure[widget_id+'_p'] = prefix
1781        datastructure[widget_id+'_b'] = b
1782        datastructure[widget_id+'_n'] = n
1783        return meth(mode=mode,
1784                    datastructure=datastructure,
1785                    )
1786    ###)
1787
1788InitializeClass(PumePinWidget)
1789widgetRegistry.register(PumePinWidget)
1790###)
1791
1792class WAeUPImageWidget(CPSImageWidget): ###(
1793    """Photo widget."""
1794    meta_type = 'WAeUP Image Widget'
1795
1796    def render(self, mode, datastructure, **kw):
1797        render_method = 'widget_waeup_image_render'
1798        meth = getattr(self, render_method, None)
1799        if meth is None:
1800            raise RuntimeError("Unknown Render Method %s for widget type %s"
1801                               % (render_method, self.getId()))
1802        img_info = self.getImageInfo(datastructure)
1803        return meth(mode=mode, datastructure=datastructure, **img_info)
1804
1805InitializeClass(WAeUPImageWidget)
1806
1807widgetRegistry.register(WAeUPImageWidget)
1808###)
1809
1810class ApplicationImageWidget(CPSImageWidget): ###(
1811    """Image widget with filesystem storage."""
1812    meta_type = 'Application Image Widget'
1813    _properties = CPSImageWidget._properties +\
1814    (
1815     {'id': 'path', 'type': 'string', 'mode': 'w',
1816      'label': 'Relative Path'},
1817     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1818      'label': 'Field to build the id'},
1819    )
1820    path = "images"
1821    storage_path = "%s/import/%s" % (i_home,path)
1822    id_field = "reg_no"
1823
1824    def getImageInfo(self, datastructure): ###(
1825        """Get the file info from the datastructure."""
1826        widget_id = self.getWidgetId()
1827        if  datastructure.has_key(widget_id):
1828            fileupload = datastructure[widget_id]
1829            dm = datastructure.getDataModel()
1830            field_id = self.fields[0]
1831            screening_type = datastructure.get('screening_type')
1832            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1833                                            field_id,)
1834            base_path = os.path.join(screening_type,current_filename)
1835            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1836            file_path = os.path.join(self.storage_path,base_path)
1837            #import pdb; pdb.set_trace()
1838        else:
1839            file_path = "XXX"
1840        # read the file from the filesystem
1841        if not os.path.exists(file_path):
1842            height = -1
1843            width = -1
1844            empty_file = True
1845            session_file = False
1846            current_filename = ''
1847            content_url = ''
1848            size = 0
1849            mimetype = ''
1850            last_modified = ''
1851            height = ''
1852            width = ''
1853
1854        else:
1855            image = open(file_path)
1856            from OFS.Image import getImageInfo as getImageInfoOFS
1857            image.seek(0)
1858            data = image.read(2000)
1859            size = len(data)
1860            empty_file = size == 0
1861            session_file = False
1862            last_modified = ''
1863            image.close()
1864            mimetype, width, height = getImageInfoOFS(data)
1865
1866            if width < 0:
1867                width = None
1868            if height < 0:
1869                height = None
1870
1871            if (self.allow_resize
1872                and height is not None
1873                and width  is not None):
1874                z_w = z_h = 1
1875                h = int(self.display_height)
1876                w = int(self.display_width)
1877                if w and h:
1878                    if w < width:
1879                        z_w = w / float(width)
1880                    if h < height:
1881                        z_h = h / float(height)
1882                    zoom = min(z_w, z_h)
1883                    width = int(zoom * width)
1884                    height = int(zoom * height)
1885                #import pdb;pdb.set_trace()
1886        image_info = {
1887            'empty_file': empty_file,
1888            'session_file': session_file,
1889            'current_filename': current_filename,
1890            'size': size,
1891            'last_modified': last_modified,
1892            'content_url': content_url,
1893            'mimetype': mimetype,
1894            }
1895        title = image_info['current_filename']
1896        alt = title or ''
1897        #height = int(self.display_height)
1898        #width = int(self.display_width)
1899        if height is None or width is None:
1900            tag = renderHtmlTag('img', src=image_info['content_url'],
1901                                alt=alt, title=title)
1902        else:
1903            tag = renderHtmlTag('img', src=image_info['content_url'],
1904                                width=str(width), height=str(height),
1905                                alt=alt, title=title)
1906
1907        image_info['height'] = height
1908        image_info['width'] = width
1909        image_info['image_tag'] = tag
1910        return image_info
1911    ###)
1912
1913    def checkFileName(self, filename, mimetype):
1914        return '', {}
1915        if mimetype and mimetype.startswith('image'):
1916            return '', {}
1917        return 'cpsschemas_err_image', {}
1918
1919    def prepare(self, datastructure, **kw): ###(
1920        """Prepare datastructure from datamodel."""
1921        datamodel = datastructure.getDataModel()
1922        widget_id = self.getWidgetId()
1923        file_name = datamodel[self.fields[0]]
1924        #import pdb; pdb.set_trace()
1925        if self.allow_resize:
1926            datastructure[self.getWidgetId() + '_resize'] = ''
1927        screening_type = datamodel.get('screening_type',None)
1928        if not screening_type:
1929            screening_type = self.REQUEST.form.get('screening_type','pume')
1930        datastructure["screening_type"] = screening_type
1931        datastructure[widget_id] = file_name
1932        datastructure[widget_id + '_choice'] = 'change'
1933        title = 'Passport Foto'
1934        datastructure[widget_id + '_filename'] = title
1935    ###)
1936
1937    def validate(self, datastructure, **kw): ###(
1938        """Update datamodel from user data in datastructure.
1939        """
1940        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1941        datamodel = datastructure.getDataModel()
1942        field_id = self.fields[0]
1943        widget_id = self.getWidgetId()
1944        store = False
1945        fileupload = None
1946        mimetype = None
1947        old_file = datamodel[field_id]
1948        # if old_file is not None:
1949        #     old_filename = old_file.title
1950        # else:
1951        #     old_filename = ''
1952        choice = datastructure[widget_id+'_choice']
1953        fileupload = datastructure[widget_id]
1954        is_upload = isinstance(fileupload, FileUpload)
1955        #import pdb; pdb.set_trace()
1956        if not is_upload and not datamodel[field_id]:
1957            if self.is_required:
1958                return self.validateError('Picture upload required', {},
1959                                          datastructure)
1960        if choice == 'delete':
1961            if self.is_required:
1962                return self.validateError('cpsschemas_err_required', {},
1963                                          datastructure)
1964            datamodel[field_id] = None
1965        elif choice == 'keep':
1966            fileupload = datastructure[widget_id]
1967            if isinstance(fileupload, PersistableFileUpload):
1968                # Keeping something from the session means we
1969                # actually want to store it.
1970                store = True
1971            # else:
1972            #     # Nothing to change, don't pollute datastructure
1973            #     # with something costly already stored, which therefore
1974            #     # doesn't need to be kept in the session.
1975            #     self.unprepare(datastructure)
1976        elif choice == 'change' and is_upload:
1977            if not fileupload:
1978                return self.validateError('cpsschemas_err_file_empty', {},
1979                                          datastructure)
1980            if not isinstance(fileupload, FileUpload):
1981                return self.validateError('cpsschemas_err_file', {},
1982                                          datastructure)
1983            fileupload.seek(0, 2) # end of file
1984            size = fileupload.tell()
1985            if not size:
1986                return self.validateError('cpsschemas_err_file_empty', {},
1987                                          datastructure)
1988            if self.size_max and size > self.size_max:
1989                max_size_str = self.getHumanReadableSize(self.size_max)
1990                err = 'This file is too big, the allowed max size is ${max_size}'
1991                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1992                err_mapping = {'max_size': max_size_str}
1993                return self.validateError(err, err_mapping, datastructure)
1994            store = True
1995
1996
1997        # Find filename
1998        if is_upload and store:
1999            ext ='jpg'
2000            screening_type = datastructure.get('screening_type')
2001            filename = "%s_%s.%s" % (datastructure[self.id_field],
2002                                     self.getWidgetId(),
2003                                     ext)
2004            datamodel[field_id] = filename
2005            registry = getToolByName(self, 'mimetypes_registry')
2006            mimetype = registry.lookupExtension(filename.lower())
2007            if mimetype is not None:
2008                mimetype = str(mimetype) # normalize
2009            file = self.makeFile(filename, fileupload, datastructure)
2010            # Fixup mimetype
2011            if mimetype and file.content_type != mimetype:
2012                file.content_type = mimetype
2013            # Store the file in the filesystem
2014            #import pdb;pdb.set_trace()
2015            base_path = os.path.join(self.storage_path, screening_type)
2016            if not os.path.exists(base_path):
2017                os.mkdir(base_path)
2018            full_path = os.path.join(base_path, filename)
2019            pict = open(full_path,"w")
2020            fileupload.seek(0)
2021            pict.write(fileupload.read())
2022            pict.close()
2023
2024
2025        return True
2026
2027###)
2028
2029    def render(self, mode, datastructure, **kw): ###(
2030        render_method = 'widget_passport_render'
2031        meth = getattr(self, render_method, None)
2032        if meth is None:
2033            raise RuntimeError("Unknown Render Method %s for widget type %s"
2034                               % (render_method, self.getId()))
2035        img_info = self.getImageInfo(datastructure)
2036        return meth(mode=mode, datastructure=datastructure, **img_info)
2037    ###)
2038
2039InitializeClass(ApplicationImageWidget)
2040
2041widgetRegistry.register(ApplicationImageWidget)
2042###)
2043
2044class FileImageWidget(CPSImageWidget): ###(
2045    """Image widget with filesystem storage."""
2046    meta_type = 'File Image Widget'
2047    _properties = CPSImageWidget._properties +\
2048    (
2049     {'id': 'path', 'type': 'string', 'mode': 'w',
2050      'label': 'Relative Path'},
2051     {'id': 'id_field', 'type': 'string', 'mode': 'w',
2052      'label': 'Field to build the id'},
2053     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
2054      'label': 'Show Image'},
2055    )
2056    path = "images"
2057    #storage_path = "%s/%s" % (i_home,path)
2058    id_field = ""
2059    show_image = False
2060
2061    def getStorageImageInfo(self,field_id):
2062        info = {}
2063        if self.id_field == "":
2064            student_id = self.getStudentId()
2065        else:
2066            student_id = datastructure[self.id_field]
2067        # student_path = os.path.join(self.storage_path,
2068        #                             student_id)
2069        student_path = getImagesDir(student_id)
2070        image_name = ''
2071        content_url = ''
2072        current_filename = ''
2073        if os.path.exists(student_path):
2074            for name in os.listdir(student_path):
2075                if name.startswith(field_id):
2076                    image_name = name
2077                    break
2078        if image_name:
2079            info['image_name'] = image_name
2080            info['content_url'] = os.path.join(self.portal_url(),
2081                                               "viewimage",
2082                                               student_id,
2083                                               image_name,
2084                                              )
2085            info['current_filename'] =  image_name
2086            info['file_path'] = os.path.join(student_path, image_name)
2087        return info
2088
2089    def getImageInfo(self, datastructure): ###(
2090        """Get the file info from the datastructure."""
2091        widget_id = self.getWidgetId()
2092        info = None
2093        if  datastructure.has_key(widget_id):
2094            fileupload = datastructure[widget_id]
2095            dm = datastructure.getDataModel()
2096            field_id = self.fields[0]
2097            info = self.getStorageImageInfo(field_id)
2098        else:
2099            file_path = "XXX"
2100            title = ""
2101        # read the file from the filesystem
2102        #import pdb; pdb.set_trace()
2103        #if not os.path.exists(file_path):
2104        if not info:
2105            title = ""
2106            height = -1
2107            width = -1
2108            empty_file = True
2109            session_file = False
2110            current_filename = ''
2111            content_url = ''
2112            size = 0
2113            mimetype = ''
2114            last_modified = ''
2115            height = ''
2116            width = ''
2117        else:
2118            title = info['image_name']
2119            current_filename = info['current_filename']
2120            content_url = info['content_url']
2121            image = open(info['file_path'])
2122            from OFS.Image import getImageInfo as getImageInfoOFS
2123            image.seek(0)
2124            data = image.read(2000)
2125            size = len(data)
2126            empty_file = size == 0
2127            session_file = False
2128            last_modified = ''
2129            image.close()
2130            mimetype, width, height = getImageInfoOFS(data)
2131            registry = getToolByName(self, 'mimetypes_registry')
2132            mimetype = (registry.lookupExtension(current_filename.lower()) or
2133                        registry.lookupExtension('file.bin'))
2134            if width < 0:
2135                width = None
2136            if height < 0:
2137                height = None
2138
2139            if (self.allow_resize
2140                and height is not None
2141                and width  is not None):
2142                z_w = z_h = 1
2143                h = int(self.display_height)
2144                w = int(self.display_width)
2145                if w and h:
2146                    if w < width:
2147                        z_w = w / float(width)
2148                    if h < height:
2149                        z_h = h / float(height)
2150                    zoom = min(z_w, z_h)
2151                    width = int(zoom * width)
2152                    height = int(zoom * height)
2153                #import pdb;pdb.set_trace()
2154        image_info = {
2155            'empty_file': empty_file,
2156            'session_file': session_file,
2157            'current_filename': title,
2158            'size': size,
2159            'last_modified': last_modified,
2160            'content_url': content_url,
2161            'mimetype': mimetype,
2162            }
2163        alt = title or ''
2164        #height = int(self.display_height)
2165        #width = int(self.display_width)
2166        if height is None or width is None:
2167            tag = renderHtmlTag('img', src=image_info['content_url'],
2168                                alt=alt, title=title)
2169        else:
2170            tag = renderHtmlTag('img', src=image_info['content_url'],
2171                                width=str(width), height=str(height),
2172                                alt=alt, title=title)
2173
2174        image_info['height'] = height
2175        image_info['width'] = width
2176        image_info['image_tag'] = tag
2177        image_info['show_image'] = self.show_image
2178        return image_info
2179    ###)
2180
2181    # def checkFileName(self, filename, mimetype):
2182    #     return '', {}
2183    #     if mimetype and mimetype.startswith('image'):
2184    #         return '', {}
2185    #     return 'cpsschemas_err_image', {}
2186
2187    def prepare(self, datastructure, **kw): ###(
2188        """Prepare datastructure from datamodel."""
2189        datamodel = datastructure.getDataModel()
2190        widget_id = self.getWidgetId()
2191        file_name = datamodel[self.fields[0]]
2192        if self.id_field == "":
2193            student_id = self.getStudentId()
2194        else:
2195            student_id = datastructure[self.id_field]
2196        if student_id is not None:
2197            # student_path = os.path.join(self.storage_path,
2198            #                             student_id)
2199            student_path = getImagesDir(student_id)
2200            if not os.path.exists(student_path):
2201                self.waeup_tool.moveImagesToFS(student_id)
2202        if self.allow_resize:
2203            datastructure[self.getWidgetId() + '_resize'] = ''
2204        datastructure[widget_id] = file_name
2205        datastructure[widget_id + '_choice'] = 'change'
2206        title = 'Passport Foto'
2207        datastructure[widget_id + '_filename'] = title
2208    ###)
2209
2210    def validate(self, datastructure, **kw): ###(
2211        """Update datamodel from user data in datastructure.
2212        """
2213        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2214        datamodel = datastructure.getDataModel()
2215        field_id = self.fields[0]
2216        widget_id = self.getWidgetId()
2217        store = False
2218        fileupload = None
2219        mimetype = None
2220        old_file = datamodel[field_id]
2221        choice = datastructure[widget_id+'_choice']
2222        fileupload = datastructure[widget_id]
2223        is_upload = isinstance(fileupload, FileUpload)
2224        #import pdb; pdb.set_trace()
2225        if not is_upload and not datamodel[field_id]:
2226            if self.is_required:
2227                return self.validateError('Picture upload required', {},
2228                                          datastructure)
2229        if self.id_field == "":
2230            student_id = self.getStudentId()
2231        else:
2232            student_id = datastructure[self.id_field]
2233        if choice == 'delete':
2234            if self.is_required:
2235                return self.validateError('cpsschemas_err_required', {},
2236                                          datastructure)
2237            info= self.getStorageImageInfo(field_id)
2238            # Remove the file in the filesystem
2239            if info:
2240                os.remove(info['file_path'])
2241            datamodel[field_id] = None
2242        elif choice == 'keep':
2243            fileupload = datastructure[widget_id]
2244            if isinstance(fileupload, PersistableFileUpload):
2245                # Keeping something from the session means we
2246                # actually want to store it.
2247                store = True
2248            # else:
2249            #     # Nothing to change, don't pollute datastructure
2250            #     # with something costly already stored, which therefore
2251            #     # doesn't need to be kept in the session.
2252            #     self.unprepare(datastructure)
2253        elif choice == 'change' and is_upload:
2254            if not fileupload:
2255                return self.validateError('cpsschemas_err_file_empty', {},
2256                                          datastructure)
2257            if not isinstance(fileupload, FileUpload):
2258                return self.validateError('cpsschemas_err_file', {},
2259                                          datastructure)
2260            fileupload.seek(0, 2) # end of file
2261            size = fileupload.tell()
2262            if not size:
2263                return self.validateError('cpsschemas_err_file_empty', {},
2264                                          datastructure)
2265            if self.size_max and size > self.size_max:
2266                max_size_str = self.getHumanReadableSize(self.size_max)
2267                err = 'This file is too big, the allowed max size is ${max_size}'
2268                member_id = str(self.portal_membership.getAuthenticatedMember())
2269                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2270                err_mapping = {'max_size': max_size_str}
2271                return self.validateError(err, err_mapping, datastructure)
2272            store = True
2273
2274
2275        # Find filename
2276        if is_upload and store:
2277            filename = cookId('', '', fileupload)[0].strip()
2278            base,ext = os.path.splitext(filename)
2279            filename = "%s_%s%s" % (field_id,
2280                                    student_id,
2281                                    ext)
2282            datamodel[field_id] = filename
2283            registry = getToolByName(self, 'mimetypes_registry')
2284            mimetype = registry.lookupExtension(filename.lower())
2285            if mimetype is not None:
2286                mimetype = str(mimetype) # normalize
2287            file = self.makeFile(filename, fileupload, datastructure)
2288            # Fixup mimetype
2289            if mimetype and file.content_type != mimetype:
2290                file.content_type = mimetype
2291            # Store the file in the filesystem
2292            #student_path = os.path.join(self.storage_path,student_id)
2293            student_path = getImagesDir(student_id)
2294            if not os.path.exists(student_path):
2295                os.mkdir(student_path)
2296            full_path = os.path.join(student_path, filename)
2297            pict = open(full_path,"w")
2298            #fileupload.seek(0)
2299            #import pdb; pdb.set_trace()
2300            pict.write(str(file.data))
2301            pict.close()
2302        return True
2303    ###)
2304
2305    def render(self, mode, datastructure, **kw): ###(
2306        render_method = 'widget_image_render'
2307        meth = getattr(self, render_method, None)
2308        #import pdb;pdb.set_trace()
2309        if meth is None:
2310            raise RuntimeError("Unknown Render Method %s for widget type %s"
2311                               % (render_method, self.getId()))
2312        img_info = self.getImageInfo(datastructure)
2313        return meth(mode=mode, datastructure=datastructure, **img_info)
2314    ###)
2315
2316InitializeClass(FileImageWidget)
2317
2318widgetRegistry.register(FileImageWidget)
2319###)
2320
2321class DiscFileWidget(CPSFileWidget): ###(
2322    """File widget with filesystem storage."""
2323    meta_type = 'Disc File Widget'
2324    _properties = CPSFileWidget._properties +\
2325    (
2326     {'id': 'path', 'type': 'string', 'mode': 'w',
2327      'label': 'Relative Path'},
2328    )
2329    path = "import"
2330    storage_path = "%s/%s" % (i_home,path)
2331
2332    def getStoredFileInfo(self,datastructure): ###(
2333        datamodel = datastructure.getDataModel()
2334        field_id = self.fields[0]
2335        widget_id = self.getWidgetId()
2336        file_name = datamodel[field_id]
2337        info = {}
2338        registry = getToolByName(self, 'mimetypes_registry')
2339        info['mimetype'] = registry.lookupExtension('file.csv')
2340        info['empty_file'] = True
2341        info['size'] = 0
2342        info['last_modified'] = ''
2343        file_path = os.path.join(self.storage_path, file_name)
2344        if os.path.exists(file_path):
2345            info['empty_file'] = False
2346            info['file_name'] = file_name
2347            info['content_url'] = os.path.join(self.portal_url(),
2348                                            "viewfile",
2349                                            file_name,
2350                                            )
2351            info['current_filename'] =  file_name
2352            # get the mimetype
2353            mimetype = (registry.lookupExtension(file_name.lower()) or
2354                        registry.lookupExtension('file.bin'))
2355            info['mimetype'] = mimetype
2356            info['file_path'] = file_path
2357        else:
2358            info['file_name'] = ''
2359            info['content_url'] = ''
2360            info['current_filename'] = ''
2361            info['file_path'] = ''
2362        return info
2363        ###)
2364
2365    def prepare(self, datastructure, **kw): ###(
2366        """Prepare datastructure from datamodel."""
2367        datamodel = datastructure.getDataModel()
2368        #import pdb;pdb.set_trace()
2369        widget_id = self.getWidgetId()
2370        file_name = datamodel[self.fields[0]]
2371        datastructure[widget_id] = file_name
2372        datastructure[widget_id + '_filename'] = file_name
2373        datastructure[widget_id+'_choice'] = "keep"
2374    ###)
2375
2376    def validate(self, datastructure, **kw): ###(
2377        """Update datamodel from user data in datastructure.
2378        """
2379        logger = logging.getLogger('Widgets.DiscFileWidget.validate')
2380        datamodel = datastructure.getDataModel()
2381        field_id = self.fields[0]
2382        widget_id = self.getWidgetId()
2383        store = False
2384        fileupload = None
2385        mimetype = None
2386        old_file = datamodel[field_id]
2387        choice = datastructure[widget_id+'_choice']
2388        fileupload = datastructure[widget_id]
2389        is_upload = isinstance(fileupload, FileUpload)
2390        if not is_upload and not datamodel[field_id]:
2391            if self.is_required:
2392                return self.validateError('File upload required', {},
2393                                          datastructure)
2394        if choice == 'delete':
2395            if self.is_required:
2396                return self.validateError('cpsschemas_err_required', {},
2397                                          datastructure)
2398            info = self.getStoredFileInfo(datastructure)
2399            # Remove the file in the filesystem
2400            if info:
2401                os.remove(info['file_path'])
2402            datamodel[field_id] = None
2403        elif choice == 'keep':
2404            fileupload = datastructure[widget_id]
2405            if isinstance(fileupload, PersistableFileUpload):
2406                # Keeping something from the session means we
2407                # actually want to store it.
2408                store = True
2409            # else:
2410            #     # Nothing to change, don't pollute datastructure
2411            #     # with something costly already stored, which therefore
2412            #     # doesn't need to be kept in the session.
2413            #     self.unprepare(datastructure)
2414        elif choice == 'change' and is_upload:
2415            if not fileupload:
2416                return self.validateError('cpsschemas_err_file_empty', {},
2417                                          datastructure)
2418            if not isinstance(fileupload, FileUpload):
2419                return self.validateError('cpsschemas_err_file', {},
2420                                          datastructure)
2421            fileupload.seek(0, 2) # end of file
2422            size = fileupload.tell()
2423            if not size:
2424                return self.validateError('cpsschemas_err_file_empty', {},
2425                                          datastructure)
2426            if self.size_max and size > self.size_max:
2427                max_size_str = self.getHumanReadableSize(self.size_max)
2428                err = 'This file is too big, the allowed max size is ${max_size}'
2429                member_id = str(self.portal_membership.getAuthenticatedMember())
2430                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2431                err_mapping = {'max_size': max_size_str}
2432                return self.validateError(err, err_mapping, datastructure)
2433            store = True
2434
2435
2436        # Find filename
2437        if is_upload and store:
2438            filename = cookId('', '', fileupload)[0].strip()
2439            base,ext = os.path.splitext(filename)
2440            if ext not in ("csv",".csv"):
2441                return self.validateError('only csv files allowed', {},
2442                                          datastructure)
2443            uploads_folder = self.portal_url.getPortalObject().campus.uploads
2444            if hasattr(uploads_folder,filename):
2445                return self.validateError('upload object exists', {},
2446                                          datastructure)
2447            datamodel[field_id] = filename
2448            registry = getToolByName(self, 'mimetypes_registry')
2449            mimetype = registry.lookupExtension(filename.lower())
2450            if mimetype is not None:
2451                mimetype = str(mimetype) # normalize
2452            file = self.makeFile(filename, fileupload, datastructure)
2453            # Fixup mimetype
2454            if mimetype and file.content_type != mimetype:
2455                file.content_type = mimetype
2456            file_path = os.path.join(self.storage_path,filename)
2457            data = open(file_path,"w")
2458            data.write(str(file.data))
2459            data.close()
2460        return True
2461    ###)
2462
2463    def render(self, mode, datastructure, **kw): ###(
2464        render_method = 'widget_uploadfile_render'
2465        meth = getattr(self, render_method, None)
2466        #import pdb;pdb.set_trace()
2467        if meth is None:
2468            raise RuntimeError("Unknown Render Method %s for widget type %s"
2469                               % (render_method, self.getId()))
2470        file_info = self.getStoredFileInfo(datastructure)
2471
2472        return meth(mode=mode, datastructure=datastructure, **file_info)
2473    ###)
2474
2475InitializeClass(DiscFileWidget)
2476
2477widgetRegistry.register(DiscFileWidget)
2478
2479
2480class RegMatricNoWidget(CPSStringWidget): ###(
2481    """ RegMatricNo Widget"""
2482    meta_type = "RegMatricNo Widget"
2483    def validate(self, datastructure, **kw):
2484        """Validate datastructure and update datamodel."""
2485        valid = CPSStringWidget.validate(self, datastructure, **kw)
2486        widget_id = self.getWidgetId()
2487        value = datastructure[widget_id].upper()
2488        err = 0
2489        #import pdb;pdb.set_trace()
2490        if not valid:
2491            err = 'Invalid number'
2492        else:
2493            student_record = self.students_catalog(jamb_reg_no = value)
2494            if len(student_record) < 1:
2495                student_record = self.students_catalog(matric_no = value)
2496                if len(student_record) < 1:
2497                    err = 'No student record with this registration or matric number'
2498                else:
2499                    datastructure['record'] = student_record[0]
2500                    #import pdb;pdb.set_trace()
2501            else:
2502                datastructure['record'] = student_record[0]
2503                #import pdb;pdb.set_trace()
2504        if err:
2505            datastructure.setError(widget_id, err)
2506        else:
2507            datamodel = datastructure.getDataModel()
2508            datamodel[self.fields[0]] = value
2509       
2510        return not err
2511
2512InitializeClass(RegMatricNoWidget)
2513
2514widgetRegistry.register(RegMatricNoWidget)
2515
2516class CheckEmailWidget(CPSStringWidget): ###(
2517    """ CheckEmail Widget"""
2518    meta_type = "CheckEmail Widget"
2519    def validate(self, datastructure, **kw):
2520        """Validate datastructure and update datamodel."""
2521        if datastructure.errors:
2522            return
2523        valid = CPSStringWidget.validate(self, datastructure, **kw)
2524        widget_id = self.getWidgetId()
2525        value = datastructure[widget_id].upper()
2526        err = 0
2527        #import pdb;pdb.set_trace()
2528        if not valid:
2529            err = 'Invalid string'
2530        else:
2531            email_cat = datastructure['record'].email.upper()
2532            if email_cat != value:
2533                err = 'Email address does not match'
2534            else:
2535                pass
2536        if err:
2537            datastructure.setError(widget_id, err)
2538        else:
2539            datamodel = datastructure.getDataModel()
2540            datamodel[self.fields[0]] = value           
2541       
2542        return not err
2543
2544InitializeClass(CheckEmailWidget)
2545
2546widgetRegistry.register(CheckEmailWidget)
2547
2548###)
2549
2550###########
2551
Note: See TracBrowser for help on using the repository browser.