source: WAeUP_SRP/base/Widgets.py @ 3474

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

add postgraduate

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