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
RevLine 
[47]1#-*- mode: python; mode: fold -*-
[990]2# $Id: Widgets.py 3459 2008-04-21 19:39:06Z henrik $
[295]3from cgi import escape
[502]4from types import *
[2110]5import Globals
[22]6from Globals import InitializeClass
[2098]7from ZPublisher.HTTPRequest import FileUpload
[2354]8from OFS.Image import cookId, File, Image
[199]9##from Products.CPSSchemas.Widget import CPSWidgetType
[295]10from Products.CMFCore.utils import getToolByName
[1772]11from Products.CPSSchemas.BasicWidgets import CPSBooleanWidget, CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget
[2710]12from Products.CPSSchemas.BasicWidgets import CPSFileWidget, CPSPasswordWidget
[295]13from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget
[22]14from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget
[3436]15from Products.CPSSchemas.Vocabulary import Vocabulary
[199]16from Products.CPSSchemas.Widget import widgetRegistry
[2098]17from Products.CPSUtil.file import PersistableFileUpload
18from Products.CPSUtil.id import generateFileName
[199]19##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry
[22]20from DateTime.DateTime import DateTime
21from AccessControl import getSecurityManager
[502]22from Products.WAeUP_SRP.Students import getStudentByRegNo
[1747]23from Products.WAeUP_SRP.Academics import makeCertificateCode
[2675]24from Products.WAeUP_SRP.WAeUPTool import getImagesDir
[2099]25#from Products.ExtFile.ExtFile import ExtFile
[2110]26import logging,os,re
[2766]27import random
[1915]28import operator
[2110]29p_home = Globals.package_home(globals())
30i_home = Globals.INSTANCE_HOME
[22]31
[952]32#from zLOG import LOG, DEBUG
[22]33
[2710]34
[2766]35class WAeUPPasswordWidget(CPSPasswordWidget): ###(
[2710]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'},
[2723]52        )
[2710]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)
[2766]121###)
[2710]122
[295]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()
[444]148            res = renderHtmlTag('select',
149                                name='%s.%s:records' % (self.record_id,html_widget_id),
[295]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
[373]177class CPSStringWidgetForRecord(CPSStringWidget): ###(
[295]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,
[444]199                  'name': '%s.%s:records' % (self.record_id,html_widget_id),
[295]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
[373]212###)
213
214class CertificateCourseIdWidget(CPSStringWidget): ###(
215    """ CertificateCourseId Widget"""
216    meta_type = "CertificateCourseId Widget"
[444]217
[373]218    def validate(self, datastructure, **kw):
219        """Validate datastructure and update datamodel."""
[444]220
[373]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"})]
[381]229            if hasattr(self.aq_parent,value):
[1891]230                err = 'Course already exists'
[381]231            elif value not in c_ids:
[1891]232                err = 'Course does not exist'
[373]233            if err:
234                datastructure.setError(widget_id, err)
235            else:
236                datamodel = datastructure.getDataModel()
237                datamodel[self.fields[0]] = value
[444]238
[373]239            return not err
240
241InitializeClass(CertificateCourseIdWidget)
242
243widgetRegistry.register(CertificateCourseIdWidget)
[551]244###)
[373]245
[551]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
[2282]260            res = self.courses_catalog(code = value)
[551]261            if len(res) > 0:
[1891]262                err = 'Course already exists'
[551]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
[373]276###)
277
[1820]278class WAeUPStudyModeWidget(CPSSelectWidget): ###(
[1986]279    """WAeUP StudyMode Widget."""
[1820]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:
[1836]301            v = value = 'ume_ft'
[1820]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
[1804]347class WAeUPSessionWidget(CPSSelectWidget): ###(
[2656]348    """WAeUP Session Widget for import only"""
[1804]349    meta_type = 'WAeUP Session Widget'
[2099]350
[1804]351    def _getSessions(self):
352        current_year = DateTime().year()
[2656]353        d = {'': ''}
[3086]354        for y in range(current_year - 10,current_year + 1):
[1804]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
[1805]367
[1804]368        if len(v) == 1:
369            v = value = '0%c' % v
[2632]370        elif len(v) == 9:
371            v = value[2:4]
[1804]372        elif not value:
[2663]373            v = ''
[1804]374        sessions = self._getSessions()
[3277]375        #import pdb;pdb.set_trace()
[2632]376        if not sessions.has_key(v):
[1804]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
[2656]387    # rendering is not used, instead we use a select widget with dynamic vocabulary
[1804]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:
[1986]400                vocabulary_items.sort(key=operator.itemgetter(0))
[1804]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):
[2723]426        d = {'':'','000':'Pre-Studies'}
[1804]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
[1805]440
[3277]441        # if not value:
442        #     v = value = '100'
[1804]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
[3219]448        # if self.is_required and len(v) == 0:
449        #     datastructure.setError(widget_id, "level key required")
450        #     return 0
[1804]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:
[1986]468                vocabulary_items.sort(key=operator.itemgetter(0))
[1804]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): ###(
[1986]490    """WAeUP Verdict Widget."""
[1804]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:
[2723]519            v = value = verdicts['']
[1804]520        if not verdicts.has_key(value):
521            datastructure.setError(widget_id, "'%s' not a valid verdict key" % v)
522            return 0
[3219]523        # if self.is_required and not len(v):
524        #     datastructure.setError(widget_id, "verdict required")
525        #     return 0
[1804]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
[2094]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',
[2428]571         'label': 'Name of the lga field (without state)'},
[2094]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):
[2433]584        if getattr(self,'_v_states',None) is not None and\
585           getattr(self,'_v_lgas',None) is not None and\
[3014]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)
[2094]595
[3014]596
[2094]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()
[3014]608        combined,states,lgas,word_dict = self._getLGAs()
[2433]609        datamodel = datastructure.getDataModel()
[3014]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:
[2094]616                datastructure.setError(widget_id, "'%s' not a valid lga key" % v)
[3014]617                #datastructure.setError(widget_id, "%s required" % widget_id)
[2094]618                return 0
[3014]619            else:
620                state_lga = v
621        datamodel[self.fields[0]] = state_lga
[2094]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
[714]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:
[926]673                reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',value)
[714]674                                     if r]
[1038]675            except (ValueError,IndexError),msg:
[714]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
[388]689class WAeUPIdWidget(CPSStringWidget): ###(
690    """ WAeUPId Widget"""
691    meta_type = "WAeUPId Widget"
[444]692
[388]693    def validate(self, datastructure, **kw):
694        """Validate datastructure and update datamodel."""
[2289]695        mode = kw.get('mode','create')
[388]696        valid = CPSStringWidget.validate(self, datastructure, **kw)
[422]697        id_pat_str = r"\S"
[2110]698        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
[388]699        if not valid:
700            return 0
701        else:
[586]702            portal_type_query = {'query':['Faculty',
703                                          'Department',
704                                          'Course',
705                                          'Certificate',
[3355]706                                          #'CertificateCourse',
707                                         ]}
[388]708            widget_id = self.getWidgetId()
[2013]709            value = datastructure[widget_id]  #.upper()  is not necessary here because it's also done in waeup_document_create_do
[388]710            err = 0
[1907]711            mapping = {}
[440]712            if len(value.split()) > 1:
[783]713                err = 'Invalid Id, Id contains space(s).'
[2289]714            elif mode == "create" and\
715                          self.portal_catalog(portal_type=portal_type_query,id=value):
[1718]716                brain = self.portal_catalog(portal_type=portal_type_query,id=value)[0]
[1907]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                           }
[388]722            if err:
[1907]723                datastructure.setError(widget_id, err, mapping)
[388]724            else:
725                datamodel = datastructure.getDataModel()
726                datamodel[self.fields[0]] = value
[444]727
[388]728            return not err
729
730InitializeClass(WAeUPIdWidget)
731
732widgetRegistry.register(WAeUPIdWidget)
733
734
735###)
736
[1025]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()
[1747]745##        valid = CPSStringWidget.validate(self, datastructure, **kw)
746##        if not valid:
747##            return 0
748        widget_id = self.getWidgetId()
[2738]749        #value = makeCertificateCode(datastructure[widget_id]).upper()
750        value = datastructure[widget_id].upper()
[1025]751        id_pat_str = r"\S"
[2110]752        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
[1747]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)
[1025]760        else:
[1747]761            datamodel = datastructure.getDataModel()
762            datamodel[self.fields[0]] = value
763        return not err
[1025]764
765InitializeClass(StudyCourseWidget)
766
767widgetRegistry.register(StudyCourseWidget)
768###)
769
[3436]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
[3438]789
[3436]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:
[3438]851            screening_type = self.REQUEST.traverse_subpath[0].lower()
[3436]852        else:
[3438]853            screening_type = 'all'
[3459]854        if screening_type in ("all","cest","sandwich","pg"):
[3436]855            application_category = screening_type
856        else:
[3441]857            application_category = "basic"
[3436]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():
[3438]868            if application_category == "all":
[3436]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)
[3438]875
[3436]876InitializeClass(ApplicationCourseWidget)
877
878widgetRegistry.register(ApplicationCourseWidget)
879###)
880
[463]881class JambRegNoWidget(CPSStringWidget): ###(
882    """ JambRegNo Widget"""
883    meta_type = "JambRegNo Widget"
[1169]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         )
[2100]890    #catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
[1169]891    reference = ""
[463]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)
[2100]899        reg_no_catalog = getattr(self,self.catalog)
[1169]900        widget_id = self.getWidgetId()
901        value = datastructure[widget_id].upper()
902        err = 0
[2094]903        #import pdb;pdb.set_trace()
904        if kw.has_key('mode'):
905            mode = kw['mode']
906        else:
[2098]907            mode = "edit"
[2099]908        if not valid:
[2100]909            err = 'Invalid registration number'
[1169]910        elif self.reference == '':
911            #s = getStudentByRegNo(self,value)
[3367]912            student_record = reg_no_catalog(jamb_reg_no = value)
913            if len(student_record) < 1:
[2100]914                err = 'No student record with this registration number'
[3367]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)'
[1169]917            else:
[3369]918                datastructure['pume'] = student_record[0]
[2094]919        elif mode == 'add':
920            pass
[2095]921        elif self.reference != '' and self.catalog == "applicants_catalog":
[2100]922            res = reg_no_catalog.searchResults({"%s" % self.reference: value})
[2094]923            if len(res) != 1:
[2100]924                err = 'No record with this registration number'
[2094]925            else:
926                datastructure['record'] = res[0]
[463]927        else:
[1169]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:
[1783]932                err = 'Registration number does not match.'
[1169]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
[463]939
940InitializeClass(JambRegNoWidget)
941
942widgetRegistry.register(JambRegNoWidget)
[47]943###)
944
[1175]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"
[1747]955    matric_no_catalog = 'returning_import'
[1175]956    check_fields = ("Firstname", "Middlename","Lastname")
957    def validate(self, datastructure, **kw):
958        """Validate datastructure and update datamodel."""
[1571]959        logger = logging.getLogger('Widgets.SecretWidget.validate')
[1175]960        valid = CPSStringWidget.validate(self, datastructure, **kw)
961        widget_id = self.getWidgetId()
962        value = datastructure[widget_id].upper()
963        err = 0
[1189]964        record = datastructure.get(self.reference,None)
[1747]965        #import pdb;pdb.set_trace()
[1379]966        if not valid or len(value) < 2:
[1793]967            err = 'Invalid string'
[1189]968        elif not record or datastructure.errors:
[1177]969            err = 0
[1175]970        else:
971            found = False
972            cvs = []
973            for field in self.check_fields:
974                cv = getattr(record,field).upper()
[1243]975                if len(cv.split()) > 1:
976                    for splited in cv.split():
[1747]977                        cvs.append(splited.strip())
[1243]978                else:
[3265]979                    cvs.append(cv.strip(),)
[1747]980            for cv in cvs:
[2795]981                if cv  == value.strip().upper():
[1175]982                    found = True
983                    break
984            matric_no = record.matric_no
985            name = " ".join(cvs)
986            if not found:
[1573]987                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
988                err = 'No name does match.'
[1175]989            else:
[1571]990                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
[1175]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
[1804]1003class WAeUPSexWidget(CPSBooleanWidget): ###(
[1772]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
[1804]1032###)
1033
[1146]1034class MatricNoWidget(CPSStringWidget): ###(
1035    """ MatricNo Widget"""
1036    meta_type = "MatricNo Widget"
[1747]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
[1748]1045    results_catalog = "results_import" #results catalog
[1747]1046
[1146]1047    def validate(self, datastructure, **kw):
1048        """Validate datastructure and update datamodel."""
[1747]1049        #import pdb;pdb.set_trace()
[1146]1050        valid = CPSStringWidget.validate(self, datastructure, **kw)
[1571]1051        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
[1747]1052        returning = getattr(self,self.matric_no_catalog)
1053        results = getattr(self,self.results_catalog,None)
[1146]1054        err = 0
[1189]1055        widget_id = self.getWidgetId()
1056        value = datastructure[widget_id]
1057        if not valid or not value:
[1891]1058            err = 'Invalid string'
[1573]1059            logger.info('Invalid matric_no string %s' % value)
[1146]1060        else:
[1189]1061            value = value.upper()
[1177]1062            datastructure['student'] = None
[1146]1063            while not err:
[1151]1064                res = returning(matric_no = value)
[1146]1065                if len(res) < 1:
[1573]1066                    logger.info('matric_no %s not found' % value)
[1915]1067                    err = 'No student with this matriculation number.'
[1747]1068                    break
[1146]1069                datastructure['student'] = res[0]
[1747]1070                if results is not None:
1071                    res = results(matric_no = value)
1072                    if len(res) < 1:
[1891]1073                        err = 'No results for this matriculation number'
[1747]1074                        continue
1075                    datastructure['results'] = res
[1146]1076                break
[1189]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
[1146]1083
1084InitializeClass(MatricNoWidget)
1085
1086widgetRegistry.register(MatricNoWidget)
1087###)
1088
[1393]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)
[1571]1095        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
[1393]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:
[1891]1102            err = 'Invalid Id string'
[1573]1103            logger.info('Invalid id string %s' % value)
[1449]1104            datastructure['student'] = None
[1393]1105        else:
1106            value = value.upper()
1107            res = s_cat(id = value)
1108            if not res:
[1573]1109                logger.info('Student id %s not found' % value)
[1891]1110                err = 'No student with this Id'
[1393]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
[1146]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()))
[1155]1174
[1146]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
[794]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()
[807]1232        datastructure[widget_id] = v
[794]1233        datastructure[widget_id+'_s'] = ''
1234        datastructure[widget_id+'_g'] = ''
1235    ###)
1236
1237    def validate(self, datastructure, **kw): ###(
1238        """Validate datastructure and update datamodel."""
[807]1239        #import pdb;pdb.set_trace()
[794]1240        widget_id = self.getWidgetId()
1241        v = datastructure[widget_id]
[2738]1242        if not v:
1243            v = []
[794]1244        err = 0
1245        s = datastructure[widget_id+'_s'].strip()
1246        g = datastructure[widget_id+'_g'].strip()
[807]1247        while 1:
1248            if not s and g:
[1891]1249                err = "No subject grade for subject"
[807]1250                break
1251            i = 0
1252            done = False
[2785]1253            #import pdb;pdb.set_trace()
[807]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:
[2785]1266                if v:
1267                    v += (s,g),
1268                else:
1269                    v = [(s,g),]
[807]1270            break
[794]1271        if err:
1272            datastructure.setError(widget_id, err)
1273        else:
1274            datamodel = datastructure.getDataModel()
1275            datamodel[self.fields[0]] = v
[2785]1276            datastructure[widget_id] = v
[794]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
[488]1303class ScratchCardPin: ###(
1304    """the ScratchCardPin"""
1305    def __init__(self,prefix,batch_no,number):
[990]1306        if not batch_no and not number:
1307            s = prefix
[996]1308            if len(s) > 3:
[990]1309                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1310            else:
[996]1311                prefix,batch_no,number = s,'',''
[488]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)
[1146]1318
1319    def __repr__(self):
1320        return "%s%s%s" % (self.p,self.b,self.n)
[488]1321###)
1322
[47]1323class ScratchcardPinWidget(CPSStringWidget): ###(
[22]1324    """ ScratchcardPin Widget"""
[199]1325    meta_type = "Scratchcard Pin Widget"
[488]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'},
[2597]1331         {'id': 'reuse_pin', 'type': 'boolean', 'mode': 'w',
[2593]1332         'label': 'Reuse Application Pin'},
[488]1333        )
1334    prefix = ''
1335    reference = ''
[2597]1336    reuse_pin = False
[3413]1337
[502]1338    def prepare(self, datastructure, **kw): ###(
[488]1339        """Prepare datastructure from datamodel."""
1340        datamodel = datastructure.getDataModel()
1341        v = datamodel[self.fields[0]]
1342        widget_id = self.getWidgetId()
[747]1343        if v and type(v) is StringType:
[990]1344            try:
1345                p,b,n = v.split('-')
1346                v = ScratchCardPin(p,b,n)
1347            except ValueError:
1348                v = ScratchCardPin(v,'','')
[488]1349        if v:
[742]1350            p = '%s' % v.p
[488]1351            b = '%s' % v.b
1352            n = '%s' % v.n
1353        else:
[742]1354            p = self.prefix
1355            if p.startswith('@'):
1356                p = getattr(self,self.prefix[1:])()
[488]1357            b = n = ''
[742]1358            v = ScratchCardPin(p,b,n)
[488]1359        datastructure[widget_id] = v
[742]1360        datastructure[widget_id+'_p'] = p
[488]1361        datastructure[widget_id+'_b'] = b
1362        datastructure[widget_id+'_n'] = n
[1376]1363    ###)
[758]1364
[1169]1365    def validate(self, datastructure, **kw): ###(
[22]1366        """Validate datastructure and update datamodel."""
[1571]1367        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
[488]1368        widget_id = self.getWidgetId()
1369        v = datastructure[widget_id]
[996]1370        #import pdb;pdb.set_trace()
[488]1371        err = 0
[1907]1372        mapping = {}
[742]1373        prefix= self.prefix
1374        if prefix.startswith('@'):
1375            prefix= getattr(self,self.prefix[1:])()
[488]1376        b = datastructure[widget_id+'_b'].strip()
1377        n = datastructure[widget_id+'_n'].strip()
[502]1378        pins = self.portal_pins
[742]1379        pin = "%(prefix)s%(b)s%(n)s" % vars()
[2001]1380        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
[816]1381        do = 1
[1025]1382        s_id = str(self.portal_membership.getAuthenticatedMember())
[1343]1383        if self.isStaff():
[1326]1384            do = 0
1385            err ='You are not a Student. PIN neither checked nor used.'
[1571]1386            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
[1557]1387        elif len(b) > 1 and b.find('-') > -1:
1388            do = 0
[2604]1389            err = 'PIN must not contain "-".'
[1573]1390            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
[1557]1391        elif n.find('-') > -1:
1392            do = 0
[2604]1393            err = 'PIN must not contain "-".'
[1573]1394            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
[1376]1395        elif len(n) != 10:
1396            do = 0
[1891]1397            err = 'Invalid PIN length'
[1573]1398            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
[1326]1399        elif self.reference == "":
[1030]1400            ref = s_id
[635]1401        else:
1402            ref = datastructure[self.reference]
[843]1403            if datastructure.errors:
[816]1404                do = 0
[1805]1405                datastructure.setError(widget_id, 'PIN neither checked nor used.')
[1571]1406                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
[2603]1407            elif prefix == 'APP' and not self.reuse_pin:
1408                res =  self.applicants_catalog(reg_no = ref)
[2709]1409                if not res:
1410                    res =  self.applicants_catalog(reg_no = ref.upper())
[2603]1411                if res and res[0].pin == pin_str:
1412                    do = 0
[2604]1413                    err = 'Application PINs cannot be reused.'
[2603]1414                    s_logger.info('%s entered same PIN as for screening application %s' % (s_id,pin_str))
[2597]1415
[816]1416        while do:
[2766]1417            ok,record = pins.searchAndSetRecord(pin,ref,prefix)
[1030]1418            if ok < -2 or ok > 2:
1419                err = 'Unknown error, please report!'
[1571]1420                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
[1030]1421                break
1422            elif ok == -2:
[1783]1423                err = 'Service already is activated but with a different PIN.'
[1571]1424                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
[710]1425                break
1426            elif ok == -1:
[1793]1427                err = 'Invalid PIN'
[1571]1428                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
[502]1429                break
1430            if ok == 0:
[1571]1431                err = 'PIN already used'
1432                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
[502]1433                break
1434            if ok >= 1:
[710]1435                #import pdb;pdb.set_trace()
[635]1436                if self.isStudent():
[992]1437                    if self.reference == "jamb_reg_no":
[997]1438                        err = "You are already logged in."
[1573]1439                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
[992]1440                        break
[1082]1441                    if ok == 1:
[1571]1442                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
[1032]1443                    else:
[1571]1444                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
[637]1445                    break
[635]1446                else:
1447                    student = getStudentByRegNo(self,ref)
[1571]1448                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
[502]1449                if student is None:
[2604]1450                    err = "Student record not found."
[1571]1451                    s_logger.info('%s not found in admission list' % (ref))
[502]1452                    break
[648]1453                s_id = student.getId()
[502]1454                if ok == 2:
[990]1455                    if self.reference == "jamb_reg_no":
1456                        if hasattr(self.portal_directories.students,s_id):
[1907]1457                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1458                            mapping = {'id': s_id}
[1571]1459                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
[990]1460                            break
1461                        else:
[1571]1462                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
[990]1463                    else:
[1891]1464                        err = "Unknown error"
[1571]1465                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
[986]1466                        break
1467                try:
1468                    student.getContent().makeStudentMember(s_id,password=pin[4:])
[1571]1469                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
[986]1470                except:
[1907]1471                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1472                    mapping = {'id': s_id}
[1571]1473                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
[986]1474                    break
[502]1475            break
[488]1476        if err:
[1907]1477            datastructure.setError(widget_id, err,mapping)
[488]1478        else:
1479            datamodel = datastructure.getDataModel()
[742]1480            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1481            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1482            datastructure[widget_id+'_p'] = prefix
[488]1483            datastructure[widget_id+'_b'] = b
1484            datastructure[widget_id+'_n'] = n
[502]1485            datastructure['s_id'] = s_id
[488]1486        return not err
[444]1487
[1169]1488###)
1489
[502]1490    def render(self, mode, datastructure, **kw): ###(
[488]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]]
[502]1503        if v and type(v) is StringType:
[990]1504            try:
1505                p,b,n = v.split('-')
1506                v = ScratchCardPin(p,b,n)
1507            except ValueError:
[2002]1508                v = ScratchCardPin(self.prefix,'XXX',v)
[996]1509                pass
[488]1510        if v:
[742]1511            prefix= '%s' % v.p
[488]1512            b = '%s' % v.b
1513            n = '%s' % v.n
[22]1514        else:
[742]1515            prefix= self.prefix
1516            if prefix.startswith('@'):
1517                prefix= getattr(self,self.prefix[1:])()
[488]1518            b = n = ''
[742]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
[758]1525        return meth(mode=mode,
1526                    datastructure=datastructure,
[488]1527                    )
[523]1528    ###)
[488]1529
[22]1530InitializeClass(ScratchcardPinWidget)
[199]1531widgetRegistry.register(ScratchcardPinWidget)
[2094]1532###)
[22]1533
[2094]1534class PumePinWidget(ScratchcardPinWidget): ###(
1535    """ Pume Pin Widget"""
1536    meta_type = "Pume Pin Widget"
[2098]1537    catalog = "applicants_catalog"
[2307]1538    reference = ''
[2099]1539
[2342]1540    def prepare(self, datastructure, **kw): ###(
1541        """Prepare datastructure from datamodel."""
1542        datamodel = datastructure.getDataModel()
[2350]1543        #import pdb;pdb.set_trace()
[2342]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
[2094]1568    def validate(self, datastructure, **kw): ###(
1569        """Validate datastructure and update datamodel."""
[2789]1570        s_logger = logging.getLogger('Widgets.PumePinWidget.validate')
[2094]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()
[2307]1583        member_id = str(self.portal_membership.getAuthenticatedMember())
[2094]1584        do = 1
[3392]1585        expiration_date = self.REQUEST.get('expiration_date')
[2094]1586        if self.isStaff():
1587            do = 0
[2541]1588            err ='You are logged in, please log out. PIN neither checked nor used.'
[2344]1589            s_logger.info('%s tried to use scratch card %s' % (member_id,pin_str))
[2541]1590        elif self.isStudent():
1591            do = 0
[2875]1592            #ref = datastructure[self.reference]
[2541]1593            err ='You are logged in, please log out. PIN neither checked nor used.'
[2875]1594            s_logger.info('%s applied for screening test while logged in with pin %s' % (member_id,pin_str))
[2094]1595        elif len(b) > 1 and b.find('-') > -1:
1596            do = 0
1597            err = 'PIN must not contain "-"'
[2307]1598            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
[2094]1599        elif n.find('-') > -1:
1600            do = 0
1601            err = 'PIN must not contain "-"'
[2307]1602            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
[2094]1603        elif len(n) != 10:
1604            do = 0
1605            err = 'Invalid PIN length'
[2307]1606            s_logger.info('%s entered invalid PIN with length %d' % (member_id,len(n)))
[2094]1607        elif self.reference == "":
[2307]1608            ref = n
[2094]1609        else:
1610            ref = datastructure[self.reference]
1611            if datastructure.errors:
1612                do = 0
1613                datastructure.setError(widget_id, 'PIN neither checked nor used.')
[2307]1614                s_logger.info('%s/%s entered wrong data together with PIN %s' % (member_id,ref,pin_str))
[2094]1615        while do:
[3407]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()):
[3392]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
[2766]1632            ok,pin_record = pins.searchAndSetRecord(pin,ref,prefix)
[2094]1633            if ok < -2 or ok > 2:
1634                err = 'Unknown error, please report!'
[2307]1635                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
[2094]1636                break
1637            elif ok == -2:
[2352]1638                err = 'Service is already activated but with a different PIN.'
[2307]1639                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
[2094]1640                break
1641            elif ok == -1:
1642                err = 'Invalid PIN'
[2307]1643                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
[2094]1644                break
1645            if ok == 0:
1646                err = 'PIN already used'
[2307]1647                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
[2094]1648                break
1649            if ok >= 1:
[2342]1650                #screening_type = self.REQUEST.form.get('screening_type','unknown')
[2356]1651                #screening_type = datastructure['screening_type']
[2541]1652                if datastructure.has_key('record'):
[2094]1653                    applicant = datastructure['record']
[2355]1654                    if applicant.screening_type != screening_type_request\
1655                          and screening_type_request != 'manage':
[2357]1656                        err = "You are using the wrong access form!"
[2356]1657                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
[2350]1658                        break
[2099]1659                    if not applicant.pin:
[2094]1660                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1661                        d = {}
1662                        d['reg_no'] = applicant.reg_no
[2098]1663                        d['pin'] = pin_str
[2353]1664                        #d['screening_type'] = screening_type
[2536]1665                        #d['status'] = 'entered'
[2098]1666                        getattr(self,self.catalog).modifyRecord(**d)
[2094]1667                    elif applicant.pin != pin_str:
[2307]1668                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
[2094]1669                    elif applicant.pin == pin_str:
[2307]1670                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1671                else:
[2324]1672                    datastructure['reg_no'] = ref
[2307]1673                    res = self.applicants_catalog(reg_no = ref)
[3247]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:
[2307]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'
[2353]1687                        d['screening_type'] = screening_type_request
[2789]1688                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
[3032]1689                                                  pin_record.serial)
[2307]1690                        self.applicants_catalog.addRecord(**d)
[3265]1691
[2094]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
[2098]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
[2094]1746InitializeClass(PumePinWidget)
1747widgetRegistry.register(PumePinWidget)
[47]1748###)
1749
[1169]1750class WAeUPImageWidget(CPSImageWidget): ###(
[537]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)
[1804]1766###)
[537]1767
[2342]1768class ApplicationImageWidget(CPSImageWidget): ###(
[2110]1769    """Image widget with filesystem storage."""
[2342]1770    meta_type = 'Application Image Widget'
[2110]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"
[2119]1779    storage_path = "%s/import/%s" % (i_home,path)
[2110]1780    id_field = "reg_no"
[537]1781
[2110]1782    def getImageInfo(self, datastructure): ###(
[2098]1783        """Get the file info from the datastructure."""
1784        widget_id = self.getWidgetId()
[2120]1785        if  datastructure.has_key(widget_id):
1786            fileupload = datastructure[widget_id]
1787            dm = datastructure.getDataModel()
1788            field_id = self.fields[0]
[2342]1789            screening_type = datastructure.get('screening_type')
[2120]1790            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1791                                            field_id,)
[2342]1792            base_path = os.path.join(screening_type,current_filename)
[2684]1793            content_url = os.path.join('viewimage_applicant',self.path,base_path)
[2342]1794            file_path = os.path.join(self.storage_path,base_path)
1795            #import pdb; pdb.set_trace()
[2120]1796        else:
1797            file_path = "XXX"
[2114]1798        # read the file from the filesystem
1799        if not os.path.exists(file_path):
[2120]1800            height = -1
1801            width = -1
[2098]1802            empty_file = True
1803            session_file = False
1804            current_filename = ''
[2120]1805            content_url = ''
[2098]1806            size = 0
[2116]1807            mimetype = ''
[2098]1808            last_modified = ''
[2119]1809            height = ''
1810            width = ''
[2122]1811
[2098]1812        else:
[2114]1813            image = open(file_path)
[2142]1814            from OFS.Image import getImageInfo as getImageInfoOFS
[2110]1815            image.seek(0)
[2142]1816            data = image.read(2000)
[2114]1817            size = len(data)
1818            empty_file = size == 0
1819            session_file = False
1820            last_modified = ''
1821            image.close()
[2142]1822            mimetype, width, height = getImageInfoOFS(data)
[2119]1823
[2110]1824            if width < 0:
1825                width = None
1826            if height < 0:
1827                height = None
[2117]1828
[2110]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)
[2117]1843                #import pdb;pdb.set_trace()
[2114]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 ''
[2117]1855        #height = int(self.display_height)
1856        #width = int(self.display_width)
[2114]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)
[2110]1864
1865        image_info['height'] = height
1866        image_info['width'] = width
1867        image_info['image_tag'] = tag
1868        return image_info
[2098]1869    ###)
1870
[2114]1871    def checkFileName(self, filename, mimetype):
1872        return '', {}
1873        if mimetype and mimetype.startswith('image'):
1874            return '', {}
1875        return 'cpsschemas_err_image', {}
1876
[2098]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]]
[2136]1882        #import pdb; pdb.set_trace()
1883        if self.allow_resize:
1884            datastructure[self.getWidgetId() + '_resize'] = ''
[2342]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
[2110]1889        datastructure[widget_id] = file_name
[2114]1890        datastructure[widget_id + '_choice'] = 'change'
1891        title = 'Passport Foto'
[2098]1892        datastructure[widget_id + '_filename'] = title
1893    ###)
1894
[2114]1895    def validate(self, datastructure, **kw): ###(
[2098]1896        """Update datamodel from user data in datastructure.
1897        """
[2342]1898        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
[2098]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]
[2114]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)
[2136]1913        #import pdb; pdb.set_trace()
1914        if not is_upload and not datamodel[field_id]:
1915            if self.is_required:
[2137]1916                return self.validateError('Picture upload required', {},
[2136]1917                                          datastructure)
[2098]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
[2114]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:
[2098]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)
[2120]1948                err = 'This file is too big, the allowed max size is ${max_size}'
[2122]1949                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
[2098]1950                err_mapping = {'max_size': max_size_str}
1951                return self.validateError(err, err_mapping, datastructure)
1952            store = True
1953
1954
1955        # Find filename
[2136]1956        if is_upload and store:
[2114]1957            ext ='jpg'
[2342]1958            screening_type = datastructure.get('screening_type')
[2114]1959            filename = "%s_%s.%s" % (datastructure[self.id_field],
[2342]1960                                     self.getWidgetId(),
1961                                     ext)
[2136]1962            datamodel[field_id] = filename
[2114]1963            registry = getToolByName(self, 'mimetypes_registry')
1964            mimetype = registry.lookupExtension(filename.lower())
1965            if mimetype is not None:
1966                mimetype = str(mimetype) # normalize
[2110]1967            file = self.makeFile(filename, fileupload, datastructure)
[2098]1968            # Fixup mimetype
[2110]1969            if mimetype and file.content_type != mimetype:
1970                file.content_type = mimetype
1971            # Store the file in the filesystem
[2114]1972            #import pdb;pdb.set_trace()
[2342]1973            base_path = os.path.join(self.storage_path, screening_type)
1974            if not os.path.exists(base_path):
1975                os.mkdir(base_path)
[2344]1976            full_path = os.path.join(base_path, filename)
[2114]1977            pict = open(full_path,"w")
1978            fileupload.seek(0)
1979            pict.write(fileupload.read())
1980            pict.close()
[2098]1981
[2110]1982
[2098]1983        return True
1984
[2114]1985###)
[2098]1986
[2114]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
[2342]1997InitializeClass(ApplicationImageWidget)
[2098]1998
[2342]1999widgetRegistry.register(ApplicationImageWidget)
[2098]2000###)
2001
[2335]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'},
[2342]2011     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
2012      'label': 'Show Image'},
[2335]2013    )
2014    path = "images"
[2675]2015    #storage_path = "%s/%s" % (i_home,path)
[2335]2016    id_field = ""
[2342]2017    show_image = False
[2344]2018
[2354]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]
[2675]2025        # student_path = os.path.join(self.storage_path,
2026        #                             student_id)
2027        student_path = getImagesDir(student_id)
[2354]2028        image_name = ''
2029        content_url = ''
2030        current_filename = ''
[2358]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
[2354]2036        if image_name:
2037            info['image_name'] = image_name
2038            info['content_url'] = os.path.join(self.portal_url(),
[2675]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)
[2354]2045        return info
[2356]2046
[2335]2047    def getImageInfo(self, datastructure): ###(
2048        """Get the file info from the datastructure."""
2049        widget_id = self.getWidgetId()
[3277]2050        info = None
[2335]2051        if  datastructure.has_key(widget_id):
2052            fileupload = datastructure[widget_id]
2053            dm = datastructure.getDataModel()
2054            field_id = self.fields[0]
[2354]2055            info = self.getStorageImageInfo(field_id)
[2335]2056        else:
2057            file_path = "XXX"
[2354]2058            title = ""
[2335]2059        # read the file from the filesystem
[2354]2060        #import pdb; pdb.set_trace()
2061        #if not os.path.exists(file_path):
2062        if not info:
2063            title = ""
[2335]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:
[2354]2076            title = info['image_name']
2077            current_filename = info['current_filename']
2078            content_url = info['content_url']
2079            image = open(info['file_path'])
[2335]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
[2342]2135        image_info['show_image'] = self.show_image
[2335]2136        return image_info
2137    ###)
2138
[2354]2139    # def checkFileName(self, filename, mimetype):
2140    #     return '', {}
2141    #     if mimetype and mimetype.startswith('image'):
2142    #         return '', {}
2143    #     return 'cpsschemas_err_image', {}
[2335]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]]
[2336]2150        if self.id_field == "":
2151            student_id = self.getStudentId()
2152        else:
2153            student_id = datastructure[self.id_field]
[2346]2154        if student_id is not None:
[2675]2155            # student_path = os.path.join(self.storage_path,
2156            #                             student_id)
2157            student_path = getImagesDir(student_id)
[2346]2158            if not os.path.exists(student_path):
2159                self.waeup_tool.moveImagesToFS(student_id)
[2335]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)
[2354]2195            info= self.getStorageImageInfo(field_id)
[2335]2196            # Remove the file in the filesystem
[2354]2197            if info:
2198                os.remove(info['file_path'])
[2335]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}'
[2356]2226                member_id = str(self.portal_membership.getAuthenticatedMember())
2227                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
[2335]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:
[2354]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)
[2335]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
[2675]2250            #student_path = os.path.join(self.storage_path,student_id)
2251            student_path = getImagesDir(student_id)
[2335]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")
[2355]2256            #fileupload.seek(0)
2257            #import pdb; pdb.set_trace()
2258            pict.write(str(file.data))
[2335]2259            pict.close()
2260        return True
[2354]2261    ###)
[2335]2262
2263    def render(self, mode, datastructure, **kw): ###(
2264        render_method = 'widget_image_render'
2265        meth = getattr(self, render_method, None)
[2342]2266        #import pdb;pdb.set_trace()
[2335]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
[3277]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        ###)
[3367]2322
[3277]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)
[3284]2401            uploads_folder = self.portal_url.getPortalObject().campus.uploads
2402            if hasattr(uploads_folder,filename):
2403                return self.validateError('upload object exists', {},
2404                                          datastructure)
[3277]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
[22]2438###########
2439
Note: See TracBrowser for help on using the repository browser.