source: WAeUP_SRP/base/Widgets.py @ 3396

Last change on this file since 3396 was 3393, checked in by joachim, 17 years ago

remove expiration-property (not used)

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