source: WAeUP_SRP/base/Widgets.py @ 3492

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

add WAHR and FALSCH to Boolean Widget

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