source: WAeUP_SRP/base/Widgets.py @ 3486

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

fix for #366

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