source: WAeUP_SRP/base/Widgets.py @ 3336

Last change on this file since 3336 was 3284, checked in by joachim, 17 years ago

upload file only if upload-object does not exist.

  • Property svn:keywords set to Id
File size: 88.3 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 3284 2008-03-07 17:25:28Z joachim $
3from cgi import escape
4from types import *
5import Globals
6from Globals import InitializeClass
7from ZPublisher.HTTPRequest import FileUpload
8from OFS.Image import cookId, File, Image
9##from Products.CPSSchemas.Widget import CPSWidgetType
10from Products.CMFCore.utils import getToolByName
11from Products.CPSSchemas.BasicWidgets import CPSBooleanWidget, CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget
12from Products.CPSSchemas.BasicWidgets import CPSFileWidget, CPSPasswordWidget
13from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget
14from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget
15from Products.CPSSchemas.Widget import widgetRegistry
16from Products.CPSUtil.file import PersistableFileUpload
17from Products.CPSUtil.id import generateFileName
18##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry
19from DateTime.DateTime import DateTime
20from AccessControl import getSecurityManager
21from Products.WAeUP_SRP.Students import getStudentByRegNo
22from Products.WAeUP_SRP.Academics import makeCertificateCode
23from Products.WAeUP_SRP.WAeUPTool import getImagesDir
24#from Products.ExtFile.ExtFile import ExtFile
25import logging,os,re
26import random
27import operator
28p_home = Globals.package_home(globals())
29i_home = Globals.INSTANCE_HOME
30
31#from zLOG import LOG, DEBUG
32
33
34class WAeUPPasswordWidget(CPSPasswordWidget): ###(
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'},
51        )
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)
120###)
121
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()
147            res = renderHtmlTag('select',
148                                name='%s.%s:records' % (self.record_id,html_widget_id),
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
176class CPSStringWidgetForRecord(CPSStringWidget): ###(
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,
198                  'name': '%s.%s:records' % (self.record_id,html_widget_id),
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
211###)
212
213class CertificateCourseIdWidget(CPSStringWidget): ###(
214    """ CertificateCourseId Widget"""
215    meta_type = "CertificateCourseId Widget"
216
217    def validate(self, datastructure, **kw):
218        """Validate datastructure and update datamodel."""
219
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"})]
228            if hasattr(self.aq_parent,value):
229                err = 'Course already exists'
230            elif value not in c_ids:
231                err = 'Course does not exist'
232            if err:
233                datastructure.setError(widget_id, err)
234            else:
235                datamodel = datastructure.getDataModel()
236                datamodel[self.fields[0]] = value
237
238            return not err
239
240InitializeClass(CertificateCourseIdWidget)
241
242widgetRegistry.register(CertificateCourseIdWidget)
243###)
244
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
259            res = self.courses_catalog(code = value)
260            if len(res) > 0:
261                err = 'Course already exists'
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
275###)
276
277class WAeUPStudyModeWidget(CPSSelectWidget): ###(
278    """WAeUP StudyMode Widget."""
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:
300            v = value = 'ume_ft'
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
346class WAeUPSessionWidget(CPSSelectWidget): ###(
347    """WAeUP Session Widget for import only"""
348    meta_type = 'WAeUP Session Widget'
349
350    def _getSessions(self):
351        current_year = DateTime().year()
352        d = {'': ''}
353        for y in range(current_year - 10,current_year + 1):
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
366
367        if len(v) == 1:
368            v = value = '0%c' % v
369        elif len(v) == 9:
370            v = value[2:4]
371        elif not value:
372            v = ''
373        sessions = self._getSessions()
374        #import pdb;pdb.set_trace()
375        if not sessions.has_key(v):
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
386    # rendering is not used, instead we use a select widget with dynamic vocabulary
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:
399                vocabulary_items.sort(key=operator.itemgetter(0))
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):
425        d = {'':'','000':'Pre-Studies'}
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
439
440        # if not value:
441        #     v = value = '100'
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
447        # if self.is_required and len(v) == 0:
448        #     datastructure.setError(widget_id, "level key required")
449        #     return 0
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:
467                vocabulary_items.sort(key=operator.itemgetter(0))
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): ###(
489    """WAeUP Verdict Widget."""
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:
518            v = value = verdicts['']
519        if not verdicts.has_key(value):
520            datastructure.setError(widget_id, "'%s' not a valid verdict key" % v)
521            return 0
522        # if self.is_required and not len(v):
523        #     datastructure.setError(widget_id, "verdict required")
524        #     return 0
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
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',
570         'label': 'Name of the lga field (without state)'},
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):
583        if getattr(self,'_v_states',None) is not None and\
584           getattr(self,'_v_lgas',None) is not None and\
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)
594
595
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()
607        combined,states,lgas,word_dict = self._getLGAs()
608        datamodel = datastructure.getDataModel()
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:
615                datastructure.setError(widget_id, "'%s' not a valid lga key" % v)
616                #datastructure.setError(widget_id, "%s required" % widget_id)
617                return 0
618            else:
619                state_lga = v
620        datamodel[self.fields[0]] = state_lga
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
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:
672                reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',value)
673                                     if r]
674            except (ValueError,IndexError),msg:
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
688class WAeUPIdWidget(CPSStringWidget): ###(
689    """ WAeUPId Widget"""
690    meta_type = "WAeUPId Widget"
691
692    def validate(self, datastructure, **kw):
693        """Validate datastructure and update datamodel."""
694        mode = kw.get('mode','create')
695        valid = CPSStringWidget.validate(self, datastructure, **kw)
696        id_pat_str = r"\S"
697        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
698        if not valid:
699            return 0
700        else:
701            portal_type_query = {'query':['Faculty',
702                                          'Department',
703                                          'Course',
704                                          'Certificate',
705                                          'CertificateCourse',]}
706            widget_id = self.getWidgetId()
707            value = datastructure[widget_id]  #.upper()  is not necessary here because it's also done in waeup_document_create_do
708            err = 0
709            mapping = {}
710            if len(value.split()) > 1:
711                err = 'Invalid Id, Id contains space(s).'
712            elif mode == "create" and\
713                          self.portal_catalog(portal_type=portal_type_query,id=value):
714                brain = self.portal_catalog(portal_type=portal_type_query,id=value)[0]
715                err = 'An ${portal_type} object with the Id ${id} already exists at ${path}.'
716                mapping = {'portal_type': brain.portal_type,
717                           'id': value,
718                           'path': brain.getPath(),
719                           }
720            if err:
721                datastructure.setError(widget_id, err, mapping)
722            else:
723                datamodel = datastructure.getDataModel()
724                datamodel[self.fields[0]] = value
725
726            return not err
727
728InitializeClass(WAeUPIdWidget)
729
730widgetRegistry.register(WAeUPIdWidget)
731
732
733###)
734
735class StudyCourseWidget(CPSStringWidget): ###(
736    """ StudyCourse Widget"""
737    meta_type = "StudyCourse Widget"
738
739    def validate(self, datastructure, **kw):
740        """Validate datastructure and update datamodel."""
741        #from Products.zdb import set_trace
742        #set_trace()
743##        valid = CPSStringWidget.validate(self, datastructure, **kw)
744##        if not valid:
745##            return 0
746        widget_id = self.getWidgetId()
747        #value = makeCertificateCode(datastructure[widget_id]).upper()
748        value = datastructure[widget_id].upper()
749        id_pat_str = r"\S"
750        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
751        err = 0
752        if len(value.split()) > 1:
753            err = 'Invalid Id, Id contains space(s).'
754        elif not self.portal_catalog(portal_type='Certificate',id=value):
755            err = 'No such certificate'
756        if err:
757            datastructure.setError(widget_id, err)
758        else:
759            datamodel = datastructure.getDataModel()
760            datamodel[self.fields[0]] = value
761        return not err
762
763InitializeClass(StudyCourseWidget)
764
765widgetRegistry.register(StudyCourseWidget)
766###)
767
768class JambRegNoWidget(CPSStringWidget): ###(
769    """ JambRegNo Widget"""
770    meta_type = "JambRegNo Widget"
771    _properties = CPSStringWidget._properties + (
772        {'id': 'catalog', 'type': 'string', 'mode': 'w',
773         'label': 'Catalog to search'},
774         {'id': 'reference', 'type': 'string', 'mode': 'w',
775         'label': 'Reference Field'},
776         )
777    #catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
778    reference = ""
779    digits = 8
780    digits_str = "N"*digits
781    letters = 2
782    letters_str = "L"*letters
783    def validate(self, datastructure, **kw):
784        """Validate datastructure and update datamodel."""
785        valid = CPSStringWidget.validate(self, datastructure, **kw)
786        reg_no_catalog = getattr(self,self.catalog)
787        widget_id = self.getWidgetId()
788        value = datastructure[widget_id].upper()
789        err = 0
790        #import pdb;pdb.set_trace()
791        if kw.has_key('mode'):
792            mode = kw['mode']
793        else:
794            mode = "edit"
795        if not valid:
796            err = 'Invalid registration number'
797        elif self.reference == '':
798            #s = getStudentByRegNo(self,value)
799            pume = reg_no_catalog(jamb_reg_no = value)
800            if len(pume) < 1:
801                err = 'No student record with this registration number'
802            else:
803                datastructure['pume'] = pume[0]
804        elif mode == 'add':
805            pass
806        elif self.reference != '' and self.catalog == "applicants_catalog":
807            res = reg_no_catalog.searchResults({"%s" % self.reference: value})
808            if len(res) != 1:
809                err = 'No record with this registration number'
810            else:
811                datastructure['record'] = res[0]
812        else:
813            record = datastructure[self.reference]
814            #jamb_reg_no = getattr(record,widget_id)
815            jamb_reg_no = record.Entryregno
816            if jamb_reg_no != value:
817                err = 'Registration number does not match.'
818        if err:
819            datastructure.setError(widget_id, err)
820        else:
821            datamodel = datastructure.getDataModel()
822            datamodel[self.fields[0]] = value
823        return not err
824
825InitializeClass(JambRegNoWidget)
826
827widgetRegistry.register(JambRegNoWidget)
828###)
829
830class SecretWidget(CPSStringWidget): ###(
831    """ Secret Widget"""
832    meta_type = "Secret Widget"
833    _properties = CPSStringWidget._properties + (
834        {'id': 'reference', 'type': 'string', 'mode': 'w',
835         'label': 'Reference Record'},
836         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
837         'label': 'Fields to check'},
838         )
839    reference = "student"
840    matric_no_catalog = 'returning_import'
841    check_fields = ("Firstname", "Middlename","Lastname")
842    def validate(self, datastructure, **kw):
843        """Validate datastructure and update datamodel."""
844        logger = logging.getLogger('Widgets.SecretWidget.validate')
845        valid = CPSStringWidget.validate(self, datastructure, **kw)
846        widget_id = self.getWidgetId()
847        value = datastructure[widget_id].upper()
848        err = 0
849        record = datastructure.get(self.reference,None)
850        #import pdb;pdb.set_trace()
851        if not valid or len(value) < 2:
852            err = 'Invalid string'
853        elif not record or datastructure.errors:
854            err = 0
855        else:
856            found = False
857            cvs = []
858            for field in self.check_fields:
859                cv = getattr(record,field).upper()
860                if len(cv.split()) > 1:
861                    for splited in cv.split():
862                        cvs.append(splited.strip())
863                else:
864                    cvs.append(cv.strip(),)
865            for cv in cvs:
866                if cv  == value.strip().upper():
867                    found = True
868                    break
869            matric_no = record.matric_no
870            name = " ".join(cvs)
871            if not found:
872                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
873                err = 'No name does match.'
874            else:
875                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
876        if err:
877            datastructure.setError(widget_id, err)
878        else:
879            datamodel = datastructure.getDataModel()
880            datamodel[self.fields[0]] = value
881        return not err
882
883InitializeClass(SecretWidget)
884
885widgetRegistry.register(SecretWidget)
886###)
887
888class WAeUPSexWidget(CPSBooleanWidget): ###(
889    """WAeUP sex widget."""
890    meta_type = 'WAeUP Sex Widget'
891
892    def validate(self, datastructure, **kw):
893        """Validate datastructure and update datamodel."""
894        value = datastructure[self.getWidgetId()]
895
896        if self.render_format not in self.render_formats:
897            self.render_format = 'select'
898
899        female = value in ('F','f','Female','female',"True",True)
900        male = value in ('M','m','Male','male','False',False)
901        if not female and not male:
902            datastructure.setError(self.getWidgetId(),
903                                   "invalid sex %s" % value)
904            return 0
905        elif female:
906            v = True
907        else:
908            v = False
909        datamodel = datastructure.getDataModel()
910        datamodel[self.fields[0]] = v
911        return 1
912
913InitializeClass(WAeUPSexWidget)
914
915widgetRegistry.register(WAeUPSexWidget)
916
917###)
918
919class MatricNoWidget(CPSStringWidget): ###(
920    """ MatricNo Widget"""
921    meta_type = "MatricNo Widget"
922
923    _properties = CPSStringWidget._properties + (
924        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
925         'label': 'Catalog to search for MatricNo'},
926        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
927         'label': 'Results Catalog'},
928         )
929    matric_no_catalog = "" #the catalog to search for matric_no
930    results_catalog = "results_import" #results catalog
931
932    def validate(self, datastructure, **kw):
933        """Validate datastructure and update datamodel."""
934        #import pdb;pdb.set_trace()
935        valid = CPSStringWidget.validate(self, datastructure, **kw)
936        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
937        returning = getattr(self,self.matric_no_catalog)
938        results = getattr(self,self.results_catalog,None)
939        err = 0
940        widget_id = self.getWidgetId()
941        value = datastructure[widget_id]
942        if not valid or not value:
943            err = 'Invalid string'
944            logger.info('Invalid matric_no string %s' % value)
945        else:
946            value = value.upper()
947            datastructure['student'] = None
948            while not err:
949                res = returning(matric_no = value)
950                if len(res) < 1:
951                    logger.info('matric_no %s not found' % value)
952                    err = 'No student with this matriculation number.'
953                    break
954                datastructure['student'] = res[0]
955                if results is not None:
956                    res = results(matric_no = value)
957                    if len(res) < 1:
958                        err = 'No results for this matriculation number'
959                        continue
960                    datastructure['results'] = res
961                break
962        if err:
963            datastructure.setError(widget_id, err)
964        else:
965            datamodel = datastructure.getDataModel()
966            datamodel[self.fields[0]] = value
967        return not err
968
969InitializeClass(MatricNoWidget)
970
971widgetRegistry.register(MatricNoWidget)
972###)
973
974class StudentIdWidget(CPSStringWidget): ###(
975    """ StudentId Widget"""
976    meta_type = "StudentId Widget"
977    def validate(self, datastructure, **kw):
978        """Validate datastructure and update datamodel."""
979        valid = CPSStringWidget.validate(self, datastructure, **kw)
980        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
981        #import pdb;pdb.set_trace()
982        s_cat = self.students_catalog
983        err = 0
984        widget_id = self.getWidgetId()
985        value = datastructure[widget_id]
986        if not valid or not value:
987            err = 'Invalid Id string'
988            logger.info('Invalid id string %s' % value)
989            datastructure['student'] = None
990        else:
991            value = value.upper()
992            res = s_cat(id = value)
993            if not res:
994                logger.info('Student id %s not found' % value)
995                err = 'No student with this Id'
996                datastructure['student'] = None
997            else:
998                datastructure['student'] = res[0]
999        if err:
1000            datastructure.setError(widget_id, err)
1001        else:
1002            datamodel = datastructure.getDataModel()
1003            datamodel[self.fields[0]] = value
1004        return not err
1005
1006InitializeClass(StudentIdWidget)
1007
1008widgetRegistry.register(StudentIdWidget)
1009###)
1010
1011class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
1012    """ WAeUPMultilineResults Widget"""
1013    meta_type = "WAeUp Multiline Results Widget"
1014    _properties = CPSWidget._properties + (
1015        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
1016         'label': 'Nr of Lines'},
1017         )
1018    nr_of_lines = 5
1019    def prepare(self, datastructure, **kw): ###(
1020        """Prepare datastructure from datamodel."""
1021        datamodel = datastructure.getDataModel()
1022        #import pdb;pdb.set_trace()
1023        widget_id = self.getWidgetId()
1024        v = datamodel[self.fields[0]]
1025        if type(v) is ListType and v:
1026            nr_results = len(v)
1027        else:
1028            v = []
1029            nr_results = 0
1030        count = 1
1031        for s,g in v:
1032            wid = "%s%02d"% (widget_id,count)
1033            datastructure[wid+'_s'] = s
1034            datastructure[wid+'_g'] = g
1035            count += 1
1036        if nr_results < self.nr_of_lines:
1037            for line in range(nr_results,self.nr_of_lines):
1038                v.append(('',''))
1039                wid = "%s%02d"% (widget_id,line)
1040                datastructure[wid+'_s'] = ''
1041                datastructure[wid+'_g'] = ''
1042        datastructure[widget_id] = v
1043        datastructure[widget_id+'_s'] = ''
1044        datastructure[widget_id+'_g'] = ''
1045    ###)
1046
1047    def validate(self, datastructure, **kw): ###(
1048        """Validate datastructure and update datamodel."""
1049        #import pdb;pdb.set_trace()
1050        widget_id = self.getWidgetId()
1051        err = 0
1052        lines = []
1053        for line in range(1,30):
1054            wid = "%s%02d"% (widget_id,line)
1055            if not datastructure.has_key(wid+'_s'):
1056                break
1057            lines.append((datastructure[wid+'_s'].strip(),
1058                         datastructure[wid+'_g'].strip()))
1059
1060        s = datastructure[widget_id+'_s'].strip()
1061        g = datastructure[widget_id+'_g'].strip()
1062        if s and g:
1063            lines.append((s,g))
1064        active = []
1065        for s,g in lines:
1066            if g != "":
1067                active.append((s,g))
1068        if err:
1069            datastructure.setError(widget_id, err)
1070        else:
1071            datamodel = datastructure.getDataModel()
1072            datamodel[self.fields[0]] = active
1073        return not err
1074    ###)
1075
1076    def render(self, mode, datastructure, **kw): ###(
1077        """Render in mode from datastructure."""
1078        render_method = 'widget_waeup_multiline_result_render'
1079        meth = getattr(self, render_method, None)
1080        if meth is None:
1081            raise RuntimeError("Unknown Render Method %s for widget type %s"
1082                               % (render_method, self.getId()))
1083        #import pdb;pdb.set_trace()
1084        datamodel = datastructure.getDataModel()
1085        widget_id = self.getWidgetId()
1086        lines = datamodel[self.fields[0]]
1087        if len(lines) < self.nr_of_lines:
1088            for line in range(len(lines),self.nr_of_lines + 1):
1089                lines.append(('',''))
1090        datastructure[widget_id] = lines
1091        datastructure[widget_id+'_s'] = ''
1092        datastructure[widget_id+'_g'] = ''
1093##        count = 1
1094##        for s,g in v:
1095##            wid = "%s%02d"% (widget_id,count)
1096##            count += 1
1097        return meth(mode=mode,
1098                    datastructure=datastructure,
1099                    )
1100    ###)
1101
1102
1103InitializeClass(WAeUPMultilineResultsWidget)
1104widgetRegistry.register(WAeUPMultilineResultsWidget)
1105###)
1106
1107class WAeUPResultsWidget(CPSStringWidget): ###(
1108    """ WAeUPResults Widget"""
1109    meta_type = "WAeUp Results Widget"
1110
1111    def prepare(self, datastructure, **kw): ###(
1112        """Prepare datastructure from datamodel."""
1113        datamodel = datastructure.getDataModel()
1114        v = datamodel[self.fields[0]]
1115        #import pdb;pdb.set_trace()
1116        widget_id = self.getWidgetId()
1117        datastructure[widget_id] = v
1118        datastructure[widget_id+'_s'] = ''
1119        datastructure[widget_id+'_g'] = ''
1120    ###)
1121
1122    def validate(self, datastructure, **kw): ###(
1123        """Validate datastructure and update datamodel."""
1124        #import pdb;pdb.set_trace()
1125        widget_id = self.getWidgetId()
1126        v = datastructure[widget_id]
1127        if not v:
1128            v = []
1129        err = 0
1130        s = datastructure[widget_id+'_s'].strip()
1131        g = datastructure[widget_id+'_g'].strip()
1132        while 1:
1133            if not s and g:
1134                err = "No subject grade for subject"
1135                break
1136            i = 0
1137            done = False
1138            #import pdb;pdb.set_trace()
1139            for sv,gv in v:
1140                if sv == s:
1141                    done = True
1142                    if not g:
1143                        v.pop(i)
1144                        break
1145                    v[i] = (s,g)
1146                    break
1147                i += 1
1148            if done:
1149                break
1150            if s and g:
1151                if v:
1152                    v += (s,g),
1153                else:
1154                    v = [(s,g),]
1155            break
1156        if err:
1157            datastructure.setError(widget_id, err)
1158        else:
1159            datamodel = datastructure.getDataModel()
1160            datamodel[self.fields[0]] = v
1161            datastructure[widget_id] = v
1162            datastructure[widget_id+'_s'] = s
1163            datastructure[widget_id+'_g'] = g
1164        return not err
1165    ###)
1166
1167    def render(self, mode, datastructure, **kw): ###(
1168        """Render in mode from datastructure."""
1169        render_method = 'widget_waeup_result_render'
1170        meth = getattr(self, render_method, None)
1171        if meth is None:
1172            raise RuntimeError("Unknown Render Method %s for widget type %s"
1173                               % (render_method, self.getId()))
1174        datamodel = datastructure.getDataModel()
1175        widget_id = self.getWidgetId()
1176        datastructure[widget_id+'_s'] = ''
1177        datastructure[widget_id+'_g'] = ''
1178        return meth(mode=mode,
1179                    datastructure=datastructure,
1180                    )
1181    ###)
1182
1183
1184InitializeClass(WAeUPResultsWidget)
1185widgetRegistry.register(WAeUPResultsWidget)
1186###)
1187
1188class ScratchCardPin: ###(
1189    """the ScratchCardPin"""
1190    def __init__(self,prefix,batch_no,number):
1191        if not batch_no and not number:
1192            s = prefix
1193            if len(s) > 3:
1194                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1195            else:
1196                prefix,batch_no,number = s,'',''
1197        self.p = prefix
1198        self.b = batch_no
1199        self.n = number
1200
1201    def __str__(self):
1202        return "%s-%s-%s" % (self.p,self.b,self.n)
1203
1204    def __repr__(self):
1205        return "%s%s%s" % (self.p,self.b,self.n)
1206###)
1207
1208class ScratchcardPinWidget(CPSStringWidget): ###(
1209    """ ScratchcardPin Widget"""
1210    meta_type = "Scratchcard Pin Widget"
1211    _properties = CPSWidget._properties + (
1212        {'id': 'prefix', 'type': 'string', 'mode': 'w',
1213         'label': 'Prefix'},
1214         {'id': 'reference', 'type': 'string', 'mode': 'w',
1215         'label': 'Reference Field'},
1216         {'id': 'reuse_pin', 'type': 'boolean', 'mode': 'w',
1217         'label': 'Reuse Application Pin'},
1218        )
1219    prefix = ''
1220    reference = ''
1221    reuse_pin = False
1222
1223    def prepare(self, datastructure, **kw): ###(
1224        """Prepare datastructure from datamodel."""
1225        datamodel = datastructure.getDataModel()
1226        v = datamodel[self.fields[0]]
1227        widget_id = self.getWidgetId()
1228        if v and type(v) is StringType:
1229            try:
1230                p,b,n = v.split('-')
1231                v = ScratchCardPin(p,b,n)
1232            except ValueError:
1233                v = ScratchCardPin(v,'','')
1234        if v:
1235            p = '%s' % v.p
1236            b = '%s' % v.b
1237            n = '%s' % v.n
1238        else:
1239            p = self.prefix
1240            if p.startswith('@'):
1241                p = getattr(self,self.prefix[1:])()
1242            b = n = ''
1243            v = ScratchCardPin(p,b,n)
1244        datastructure[widget_id] = v
1245        datastructure[widget_id+'_p'] = p
1246        datastructure[widget_id+'_b'] = b
1247        datastructure[widget_id+'_n'] = n
1248    ###)
1249
1250    def validate(self, datastructure, **kw): ###(
1251        """Validate datastructure and update datamodel."""
1252        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1253        widget_id = self.getWidgetId()
1254        v = datastructure[widget_id]
1255        #import pdb;pdb.set_trace()
1256        err = 0
1257        mapping = {}
1258        prefix= self.prefix
1259        if prefix.startswith('@'):
1260            prefix= getattr(self,self.prefix[1:])()
1261        b = datastructure[widget_id+'_b'].strip()
1262        n = datastructure[widget_id+'_n'].strip()
1263        pins = self.portal_pins
1264        pin = "%(prefix)s%(b)s%(n)s" % vars()
1265        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1266        do = 1
1267        s_id = str(self.portal_membership.getAuthenticatedMember())
1268        if self.isStaff():
1269            do = 0
1270            err ='You are not a Student. PIN neither checked nor used.'
1271            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1272        elif len(b) > 1 and b.find('-') > -1:
1273            do = 0
1274            err = 'PIN must not contain "-".'
1275            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1276        elif n.find('-') > -1:
1277            do = 0
1278            err = 'PIN must not contain "-".'
1279            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1280        elif len(n) != 10:
1281            do = 0
1282            err = 'Invalid PIN length'
1283            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1284        elif self.reference == "":
1285            ref = s_id
1286        else:
1287            ref = datastructure[self.reference]
1288            if datastructure.errors:
1289                do = 0
1290                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1291                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1292            elif prefix == 'APP' and not self.reuse_pin:
1293                res =  self.applicants_catalog(reg_no = ref)
1294                if not res:
1295                    res =  self.applicants_catalog(reg_no = ref.upper())
1296                if res and res[0].pin == pin_str:
1297                    do = 0
1298                    err = 'Application PINs cannot be reused.'
1299                    s_logger.info('%s entered same PIN as for screening application %s' % (s_id,pin_str))
1300
1301        while do:
1302            ok,record = pins.searchAndSetRecord(pin,ref,prefix)
1303            if ok < -2 or ok > 2:
1304                err = 'Unknown error, please report!'
1305                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1306                break
1307            elif ok == -2:
1308                err = 'Service already is activated but with a different PIN.'
1309                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1310                break
1311            elif ok == -1:
1312                err = 'Invalid PIN'
1313                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1314                break
1315            if ok == 0:
1316                err = 'PIN already used'
1317                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1318                break
1319            if ok >= 1:
1320                #import pdb;pdb.set_trace()
1321                if self.isStudent():
1322                    if self.reference == "jamb_reg_no":
1323                        err = "You are already logged in."
1324                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1325                        break
1326                    if ok == 1:
1327                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1328                    else:
1329                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1330                    break
1331                else:
1332                    student = getStudentByRegNo(self,ref)
1333                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1334                if student is None:
1335                    err = "Student record not found."
1336                    s_logger.info('%s not found in admission list' % (ref))
1337                    break
1338                s_id = student.getId()
1339                if ok == 2:
1340                    if self.reference == "jamb_reg_no":
1341                        if hasattr(self.portal_directories.students,s_id):
1342                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1343                            mapping = {'id': s_id}
1344                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1345                            break
1346                        else:
1347                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1348                    else:
1349                        err = "Unknown error"
1350                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1351                        break
1352                try:
1353                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1354                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1355                except:
1356                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1357                    mapping = {'id': s_id}
1358                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1359                    break
1360            break
1361        if err:
1362            datastructure.setError(widget_id, err,mapping)
1363        else:
1364            datamodel = datastructure.getDataModel()
1365            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1366            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1367            datastructure[widget_id+'_p'] = prefix
1368            datastructure[widget_id+'_b'] = b
1369            datastructure[widget_id+'_n'] = n
1370            datastructure['s_id'] = s_id
1371        return not err
1372
1373###)
1374
1375    def render(self, mode, datastructure, **kw): ###(
1376        """Render in mode from datastructure."""
1377        render_method = 'widget_scratch_card_pin_render'
1378        meth = getattr(self, render_method, None)
1379        if meth is None:
1380            raise RuntimeError("Unknown Render Method %s for widget type %s"
1381                               % (render_method, self.getId()))
1382
1383        # XXX AT: datastructure has to be set again here, in case we're in edit
1384        # or create mode, because a default value has to be provided.
1385        #import pdb;pdb.set_trace()
1386        datamodel = datastructure.getDataModel()
1387        v = datamodel[self.fields[0]]
1388        if v and type(v) is StringType:
1389            try:
1390                p,b,n = v.split('-')
1391                v = ScratchCardPin(p,b,n)
1392            except ValueError:
1393                v = ScratchCardPin(self.prefix,'XXX',v)
1394                pass
1395        if v:
1396            prefix= '%s' % v.p
1397            b = '%s' % v.b
1398            n = '%s' % v.n
1399        else:
1400            prefix= self.prefix
1401            if prefix.startswith('@'):
1402                prefix= getattr(self,self.prefix[1:])()
1403            b = n = ''
1404            v = ScratchCardPin(prefix,b,n)
1405        widget_id = self.getWidgetId()
1406        datastructure[widget_id] = v
1407        datastructure[widget_id+'_p'] = prefix
1408        datastructure[widget_id+'_b'] = b
1409        datastructure[widget_id+'_n'] = n
1410        return meth(mode=mode,
1411                    datastructure=datastructure,
1412                    )
1413    ###)
1414
1415InitializeClass(ScratchcardPinWidget)
1416widgetRegistry.register(ScratchcardPinWidget)
1417###)
1418
1419class PumePinWidget(ScratchcardPinWidget): ###(
1420    """ Pume Pin Widget"""
1421    meta_type = "Pume Pin Widget"
1422    catalog = "applicants_catalog"
1423    reference = ''
1424
1425    def prepare(self, datastructure, **kw): ###(
1426        """Prepare datastructure from datamodel."""
1427        datamodel = datastructure.getDataModel()
1428        #import pdb;pdb.set_trace()
1429        v = datamodel[self.fields[0]]
1430        widget_id = self.getWidgetId()
1431        if v and type(v) is StringType:
1432            try:
1433                p,b,n = v.split('-')
1434                v = ScratchCardPin(p,b,n)
1435            except ValueError:
1436                v = ScratchCardPin(v,'','')
1437        if v:
1438            p = '%s' % v.p
1439            b = '%s' % v.b
1440            n = '%s' % v.n
1441        else:
1442            p = self.prefix
1443            if p.startswith('@'):
1444                p = getattr(self,self.prefix[1:])()
1445            b = n = ''
1446            v = ScratchCardPin(p,b,n)
1447        datastructure[widget_id] = v
1448        datastructure[widget_id+'_p'] = p
1449        datastructure[widget_id+'_b'] = b
1450        datastructure[widget_id+'_n'] = n
1451    ###)
1452
1453    def validate(self, datastructure, **kw): ###(
1454        """Validate datastructure and update datamodel."""
1455        s_logger = logging.getLogger('Widgets.PumePinWidget.validate')
1456        widget_id = self.getWidgetId()
1457        v = datastructure[widget_id]
1458        err = 0
1459        mapping = {}
1460        prefix= self.prefix
1461        if prefix.startswith('@'):
1462            prefix= getattr(self,self.prefix[1:])()
1463        b = datastructure[widget_id+'_b'].strip()
1464        n = datastructure[widget_id+'_n'].strip()
1465        pins = self.portal_pins
1466        pin = "%(prefix)s%(b)s%(n)s" % vars()
1467        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1468        member_id = str(self.portal_membership.getAuthenticatedMember())
1469        do = 1
1470        if self.isStaff():
1471            do = 0
1472            err ='You are logged in, please log out. PIN neither checked nor used.'
1473            s_logger.info('%s tried to use scratch card %s' % (member_id,pin_str))
1474        elif self.isStudent():
1475            do = 0
1476            #ref = datastructure[self.reference]
1477            err ='You are logged in, please log out. PIN neither checked nor used.'
1478            s_logger.info('%s applied for screening test while logged in with pin %s' % (member_id,pin_str))
1479        elif len(b) > 1 and b.find('-') > -1:
1480            do = 0
1481            err = 'PIN must not contain "-"'
1482            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1483        elif n.find('-') > -1:
1484            do = 0
1485            err = 'PIN must not contain "-"'
1486            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1487        elif len(n) != 10:
1488            do = 0
1489            err = 'Invalid PIN length'
1490            s_logger.info('%s entered invalid PIN with length %d' % (member_id,len(n)))
1491        elif self.reference == "":
1492            ref = n
1493        else:
1494            ref = datastructure[self.reference]
1495            if datastructure.errors:
1496                do = 0
1497                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1498                s_logger.info('%s/%s entered wrong data together with PIN %s' % (member_id,ref,pin_str))
1499        while do:
1500            ok,pin_record = pins.searchAndSetRecord(pin,ref,prefix)
1501            if ok < -2 or ok > 2:
1502                err = 'Unknown error, please report!'
1503                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
1504                break
1505            elif ok == -2:
1506                err = 'Service is already activated but with a different PIN.'
1507                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
1508                break
1509            elif ok == -1:
1510                err = 'Invalid PIN'
1511                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
1512                break
1513            if ok == 0:
1514                err = 'PIN already used'
1515                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
1516                break
1517            if ok >= 1:
1518                #screening_type = self.REQUEST.form.get('screening_type','unknown')
1519                #screening_type = datastructure['screening_type']
1520                if self.REQUEST.traverse_subpath:
1521                    screening_type_request = self.REQUEST.traverse_subpath[0]
1522                else:
1523                    screening_type_request = 'manage'
1524
1525                if datastructure.has_key('record'):
1526                    applicant = datastructure['record']
1527                    if applicant.screening_type != screening_type_request\
1528                          and screening_type_request != 'manage':
1529                        err = "You are using the wrong access form!"
1530                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1531                        break
1532                    if not applicant.pin:
1533                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1534                        d = {}
1535                        d['reg_no'] = applicant.reg_no
1536                        d['pin'] = pin_str
1537                        #d['screening_type'] = screening_type
1538                        #d['status'] = 'entered'
1539                        getattr(self,self.catalog).modifyRecord(**d)
1540                    elif applicant.pin != pin_str:
1541                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
1542                    elif applicant.pin == pin_str:
1543                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1544                else:
1545                    datastructure['reg_no'] = ref
1546                    res = self.applicants_catalog(reg_no = ref)
1547                    if res:
1548                        if getattr(res[0],'screening_type',None) != screening_type_request\
1549                              and screening_type_request != 'manage':
1550                            err = "You are using the wrong access form!"
1551                            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)))
1552                            break
1553                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1554                    else:
1555                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1556                        d = {}
1557                        d['reg_no'] = ref
1558                        d['pin'] = pin_str
1559                        d['status'] = 'entered'
1560                        d['screening_type'] = screening_type_request
1561                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
1562                                                  pin_record.serial)
1563                        self.applicants_catalog.addRecord(**d)
1564
1565            break
1566        if err:
1567            datastructure.setError(widget_id, err,mapping)
1568        else:
1569            datamodel = datastructure.getDataModel()
1570            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1571            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1572            datastructure[widget_id+'_p'] = prefix
1573            datastructure[widget_id+'_b'] = b
1574            datastructure[widget_id+'_n'] = n
1575        return not err
1576    ###)
1577
1578    def render(self, mode, datastructure, **kw): ###(
1579        """Render in mode from datastructure."""
1580        render_method = 'widget_scratch_card_pin_render'
1581        meth = getattr(self, render_method, None)
1582        if meth is None:
1583            raise RuntimeError("Unknown Render Method %s for widget type %s"
1584                               % (render_method, self.getId()))
1585
1586        # XXX AT: datastructure has to be set again here, in case we're in edit
1587        # or create mode, because a default value has to be provided.
1588        #import pdb;pdb.set_trace()
1589        datamodel = datastructure.getDataModel()
1590        v = datamodel[self.fields[0]]
1591        #import pdb;pdb.set_trace()
1592        if v and type(v) is StringType:
1593            try:
1594                p,b,n = v.split('-')
1595                v = ScratchCardPin(p,b,n)
1596            except ValueError:
1597                v = ScratchCardPin(self.prefix,'XXX',v)
1598                pass
1599        if v:
1600            prefix= '%s' % v.p
1601            b = '%s' % v.b
1602            n = '%s' % v.n
1603        else:
1604            prefix= self.prefix
1605            if prefix.startswith('@'):
1606                prefix= getattr(self,self.prefix[1:])()
1607            b = n = ''
1608            v = ScratchCardPin(prefix,b,n)
1609        widget_id = self.getWidgetId()
1610        datastructure[widget_id] = v
1611        datastructure[widget_id+'_p'] = prefix
1612        datastructure[widget_id+'_b'] = b
1613        datastructure[widget_id+'_n'] = n
1614        return meth(mode=mode,
1615                    datastructure=datastructure,
1616                    )
1617    ###)
1618
1619InitializeClass(PumePinWidget)
1620widgetRegistry.register(PumePinWidget)
1621###)
1622
1623class WAeUPImageWidget(CPSImageWidget): ###(
1624    """Photo widget."""
1625    meta_type = 'WAeUP Image Widget'
1626
1627    def render(self, mode, datastructure, **kw):
1628        render_method = 'widget_waeup_image_render'
1629        meth = getattr(self, render_method, None)
1630        if meth is None:
1631            raise RuntimeError("Unknown Render Method %s for widget type %s"
1632                               % (render_method, self.getId()))
1633        img_info = self.getImageInfo(datastructure)
1634        return meth(mode=mode, datastructure=datastructure, **img_info)
1635
1636InitializeClass(WAeUPImageWidget)
1637
1638widgetRegistry.register(WAeUPImageWidget)
1639###)
1640
1641class ApplicationImageWidget(CPSImageWidget): ###(
1642    """Image widget with filesystem storage."""
1643    meta_type = 'Application Image Widget'
1644    _properties = CPSImageWidget._properties +\
1645    (
1646     {'id': 'path', 'type': 'string', 'mode': 'w',
1647      'label': 'Relative Path'},
1648     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1649      'label': 'Field to build the id'},
1650    )
1651    path = "images"
1652    storage_path = "%s/import/%s" % (i_home,path)
1653    id_field = "reg_no"
1654
1655    def getImageInfo(self, datastructure): ###(
1656        """Get the file info from the datastructure."""
1657        widget_id = self.getWidgetId()
1658        if  datastructure.has_key(widget_id):
1659            fileupload = datastructure[widget_id]
1660            dm = datastructure.getDataModel()
1661            field_id = self.fields[0]
1662            screening_type = datastructure.get('screening_type')
1663            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1664                                            field_id,)
1665            base_path = os.path.join(screening_type,current_filename)
1666            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1667            file_path = os.path.join(self.storage_path,base_path)
1668            #import pdb; pdb.set_trace()
1669        else:
1670            file_path = "XXX"
1671        # read the file from the filesystem
1672        if not os.path.exists(file_path):
1673            height = -1
1674            width = -1
1675            empty_file = True
1676            session_file = False
1677            current_filename = ''
1678            content_url = ''
1679            size = 0
1680            mimetype = ''
1681            last_modified = ''
1682            height = ''
1683            width = ''
1684
1685        else:
1686            image = open(file_path)
1687            from OFS.Image import getImageInfo as getImageInfoOFS
1688            image.seek(0)
1689            data = image.read(2000)
1690            size = len(data)
1691            empty_file = size == 0
1692            session_file = False
1693            last_modified = ''
1694            image.close()
1695            mimetype, width, height = getImageInfoOFS(data)
1696
1697            if width < 0:
1698                width = None
1699            if height < 0:
1700                height = None
1701
1702            if (self.allow_resize
1703                and height is not None
1704                and width  is not None):
1705                z_w = z_h = 1
1706                h = int(self.display_height)
1707                w = int(self.display_width)
1708                if w and h:
1709                    if w < width:
1710                        z_w = w / float(width)
1711                    if h < height:
1712                        z_h = h / float(height)
1713                    zoom = min(z_w, z_h)
1714                    width = int(zoom * width)
1715                    height = int(zoom * height)
1716                #import pdb;pdb.set_trace()
1717        image_info = {
1718            'empty_file': empty_file,
1719            'session_file': session_file,
1720            'current_filename': current_filename,
1721            'size': size,
1722            'last_modified': last_modified,
1723            'content_url': content_url,
1724            'mimetype': mimetype,
1725            }
1726        title = image_info['current_filename']
1727        alt = title or ''
1728        #height = int(self.display_height)
1729        #width = int(self.display_width)
1730        if height is None or width is None:
1731            tag = renderHtmlTag('img', src=image_info['content_url'],
1732                                alt=alt, title=title)
1733        else:
1734            tag = renderHtmlTag('img', src=image_info['content_url'],
1735                                width=str(width), height=str(height),
1736                                alt=alt, title=title)
1737
1738        image_info['height'] = height
1739        image_info['width'] = width
1740        image_info['image_tag'] = tag
1741        return image_info
1742    ###)
1743
1744    def checkFileName(self, filename, mimetype):
1745        return '', {}
1746        if mimetype and mimetype.startswith('image'):
1747            return '', {}
1748        return 'cpsschemas_err_image', {}
1749
1750    def prepare(self, datastructure, **kw): ###(
1751        """Prepare datastructure from datamodel."""
1752        datamodel = datastructure.getDataModel()
1753        widget_id = self.getWidgetId()
1754        file_name = datamodel[self.fields[0]]
1755        #import pdb; pdb.set_trace()
1756        if self.allow_resize:
1757            datastructure[self.getWidgetId() + '_resize'] = ''
1758        screening_type = datamodel.get('screening_type',None)
1759        if not screening_type:
1760            screening_type = self.REQUEST.form.get('screening_type','pume')
1761        datastructure["screening_type"] = screening_type
1762        datastructure[widget_id] = file_name
1763        datastructure[widget_id + '_choice'] = 'change'
1764        title = 'Passport Foto'
1765        datastructure[widget_id + '_filename'] = title
1766    ###)
1767
1768    def validate(self, datastructure, **kw): ###(
1769        """Update datamodel from user data in datastructure.
1770        """
1771        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1772        datamodel = datastructure.getDataModel()
1773        field_id = self.fields[0]
1774        widget_id = self.getWidgetId()
1775        store = False
1776        fileupload = None
1777        mimetype = None
1778        old_file = datamodel[field_id]
1779        # if old_file is not None:
1780        #     old_filename = old_file.title
1781        # else:
1782        #     old_filename = ''
1783        choice = datastructure[widget_id+'_choice']
1784        fileupload = datastructure[widget_id]
1785        is_upload = isinstance(fileupload, FileUpload)
1786        #import pdb; pdb.set_trace()
1787        if not is_upload and not datamodel[field_id]:
1788            if self.is_required:
1789                return self.validateError('Picture upload required', {},
1790                                          datastructure)
1791        if choice == 'delete':
1792            if self.is_required:
1793                return self.validateError('cpsschemas_err_required', {},
1794                                          datastructure)
1795            datamodel[field_id] = None
1796        elif choice == 'keep':
1797            fileupload = datastructure[widget_id]
1798            if isinstance(fileupload, PersistableFileUpload):
1799                # Keeping something from the session means we
1800                # actually want to store it.
1801                store = True
1802            # else:
1803            #     # Nothing to change, don't pollute datastructure
1804            #     # with something costly already stored, which therefore
1805            #     # doesn't need to be kept in the session.
1806            #     self.unprepare(datastructure)
1807        elif choice == 'change' and is_upload:
1808            if not fileupload:
1809                return self.validateError('cpsschemas_err_file_empty', {},
1810                                          datastructure)
1811            if not isinstance(fileupload, FileUpload):
1812                return self.validateError('cpsschemas_err_file', {},
1813                                          datastructure)
1814            fileupload.seek(0, 2) # end of file
1815            size = fileupload.tell()
1816            if not size:
1817                return self.validateError('cpsschemas_err_file_empty', {},
1818                                          datastructure)
1819            if self.size_max and size > self.size_max:
1820                max_size_str = self.getHumanReadableSize(self.size_max)
1821                err = 'This file is too big, the allowed max size is ${max_size}'
1822                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1823                err_mapping = {'max_size': max_size_str}
1824                return self.validateError(err, err_mapping, datastructure)
1825            store = True
1826
1827
1828        # Find filename
1829        if is_upload and store:
1830            ext ='jpg'
1831            screening_type = datastructure.get('screening_type')
1832            filename = "%s_%s.%s" % (datastructure[self.id_field],
1833                                     self.getWidgetId(),
1834                                     ext)
1835            datamodel[field_id] = filename
1836            registry = getToolByName(self, 'mimetypes_registry')
1837            mimetype = registry.lookupExtension(filename.lower())
1838            if mimetype is not None:
1839                mimetype = str(mimetype) # normalize
1840            file = self.makeFile(filename, fileupload, datastructure)
1841            # Fixup mimetype
1842            if mimetype and file.content_type != mimetype:
1843                file.content_type = mimetype
1844            # Store the file in the filesystem
1845            #import pdb;pdb.set_trace()
1846            base_path = os.path.join(self.storage_path, screening_type)
1847            if not os.path.exists(base_path):
1848                os.mkdir(base_path)
1849            full_path = os.path.join(base_path, filename)
1850            pict = open(full_path,"w")
1851            fileupload.seek(0)
1852            pict.write(fileupload.read())
1853            pict.close()
1854
1855
1856        return True
1857
1858###)
1859
1860    def render(self, mode, datastructure, **kw): ###(
1861        render_method = 'widget_passport_render'
1862        meth = getattr(self, render_method, None)
1863        if meth is None:
1864            raise RuntimeError("Unknown Render Method %s for widget type %s"
1865                               % (render_method, self.getId()))
1866        img_info = self.getImageInfo(datastructure)
1867        return meth(mode=mode, datastructure=datastructure, **img_info)
1868    ###)
1869
1870InitializeClass(ApplicationImageWidget)
1871
1872widgetRegistry.register(ApplicationImageWidget)
1873###)
1874
1875class FileImageWidget(CPSImageWidget): ###(
1876    """Image widget with filesystem storage."""
1877    meta_type = 'File Image Widget'
1878    _properties = CPSImageWidget._properties +\
1879    (
1880     {'id': 'path', 'type': 'string', 'mode': 'w',
1881      'label': 'Relative Path'},
1882     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1883      'label': 'Field to build the id'},
1884     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
1885      'label': 'Show Image'},
1886    )
1887    path = "images"
1888    #storage_path = "%s/%s" % (i_home,path)
1889    id_field = ""
1890    show_image = False
1891
1892    def getStorageImageInfo(self,field_id):
1893        info = {}
1894        if self.id_field == "":
1895            student_id = self.getStudentId()
1896        else:
1897            student_id = datastructure[self.id_field]
1898        # student_path = os.path.join(self.storage_path,
1899        #                             student_id)
1900        student_path = getImagesDir(student_id)
1901        image_name = ''
1902        content_url = ''
1903        current_filename = ''
1904        if os.path.exists(student_path):
1905            for name in os.listdir(student_path):
1906                if name.startswith(field_id):
1907                    image_name = name
1908                    break
1909        if image_name:
1910            info['image_name'] = image_name
1911            info['content_url'] = os.path.join(self.portal_url(),
1912                                               "viewimage",
1913                                               student_id,
1914                                               image_name,
1915                                              )
1916            info['current_filename'] =  image_name
1917            info['file_path'] = os.path.join(student_path, image_name)
1918        return info
1919
1920    def getImageInfo(self, datastructure): ###(
1921        """Get the file info from the datastructure."""
1922        widget_id = self.getWidgetId()
1923        info = None
1924        if  datastructure.has_key(widget_id):
1925            fileupload = datastructure[widget_id]
1926            dm = datastructure.getDataModel()
1927            field_id = self.fields[0]
1928            info = self.getStorageImageInfo(field_id)
1929        else:
1930            file_path = "XXX"
1931            title = ""
1932        # read the file from the filesystem
1933        #import pdb; pdb.set_trace()
1934        #if not os.path.exists(file_path):
1935        if not info:
1936            title = ""
1937            height = -1
1938            width = -1
1939            empty_file = True
1940            session_file = False
1941            current_filename = ''
1942            content_url = ''
1943            size = 0
1944            mimetype = ''
1945            last_modified = ''
1946            height = ''
1947            width = ''
1948        else:
1949            title = info['image_name']
1950            current_filename = info['current_filename']
1951            content_url = info['content_url']
1952            image = open(info['file_path'])
1953            from OFS.Image import getImageInfo as getImageInfoOFS
1954            image.seek(0)
1955            data = image.read(2000)
1956            size = len(data)
1957            empty_file = size == 0
1958            session_file = False
1959            last_modified = ''
1960            image.close()
1961            mimetype, width, height = getImageInfoOFS(data)
1962            registry = getToolByName(self, 'mimetypes_registry')
1963            mimetype = (registry.lookupExtension(current_filename.lower()) or
1964                        registry.lookupExtension('file.bin'))
1965            if width < 0:
1966                width = None
1967            if height < 0:
1968                height = None
1969
1970            if (self.allow_resize
1971                and height is not None
1972                and width  is not None):
1973                z_w = z_h = 1
1974                h = int(self.display_height)
1975                w = int(self.display_width)
1976                if w and h:
1977                    if w < width:
1978                        z_w = w / float(width)
1979                    if h < height:
1980                        z_h = h / float(height)
1981                    zoom = min(z_w, z_h)
1982                    width = int(zoom * width)
1983                    height = int(zoom * height)
1984                #import pdb;pdb.set_trace()
1985        image_info = {
1986            'empty_file': empty_file,
1987            'session_file': session_file,
1988            'current_filename': title,
1989            'size': size,
1990            'last_modified': last_modified,
1991            'content_url': content_url,
1992            'mimetype': mimetype,
1993            }
1994        alt = title or ''
1995        #height = int(self.display_height)
1996        #width = int(self.display_width)
1997        if height is None or width is None:
1998            tag = renderHtmlTag('img', src=image_info['content_url'],
1999                                alt=alt, title=title)
2000        else:
2001            tag = renderHtmlTag('img', src=image_info['content_url'],
2002                                width=str(width), height=str(height),
2003                                alt=alt, title=title)
2004
2005        image_info['height'] = height
2006        image_info['width'] = width
2007        image_info['image_tag'] = tag
2008        image_info['show_image'] = self.show_image
2009        return image_info
2010    ###)
2011
2012    # def checkFileName(self, filename, mimetype):
2013    #     return '', {}
2014    #     if mimetype and mimetype.startswith('image'):
2015    #         return '', {}
2016    #     return 'cpsschemas_err_image', {}
2017
2018    def prepare(self, datastructure, **kw): ###(
2019        """Prepare datastructure from datamodel."""
2020        datamodel = datastructure.getDataModel()
2021        widget_id = self.getWidgetId()
2022        file_name = datamodel[self.fields[0]]
2023        if self.id_field == "":
2024            student_id = self.getStudentId()
2025        else:
2026            student_id = datastructure[self.id_field]
2027        if student_id is not None:
2028            # student_path = os.path.join(self.storage_path,
2029            #                             student_id)
2030            student_path = getImagesDir(student_id)
2031            if not os.path.exists(student_path):
2032                self.waeup_tool.moveImagesToFS(student_id)
2033        if self.allow_resize:
2034            datastructure[self.getWidgetId() + '_resize'] = ''
2035        datastructure[widget_id] = file_name
2036        datastructure[widget_id + '_choice'] = 'change'
2037        title = 'Passport Foto'
2038        datastructure[widget_id + '_filename'] = title
2039    ###)
2040
2041    def validate(self, datastructure, **kw): ###(
2042        """Update datamodel from user data in datastructure.
2043        """
2044        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2045        datamodel = datastructure.getDataModel()
2046        field_id = self.fields[0]
2047        widget_id = self.getWidgetId()
2048        store = False
2049        fileupload = None
2050        mimetype = None
2051        old_file = datamodel[field_id]
2052        choice = datastructure[widget_id+'_choice']
2053        fileupload = datastructure[widget_id]
2054        is_upload = isinstance(fileupload, FileUpload)
2055        #import pdb; pdb.set_trace()
2056        if not is_upload and not datamodel[field_id]:
2057            if self.is_required:
2058                return self.validateError('Picture upload required', {},
2059                                          datastructure)
2060        if self.id_field == "":
2061            student_id = self.getStudentId()
2062        else:
2063            student_id = datastructure[self.id_field]
2064        if choice == 'delete':
2065            if self.is_required:
2066                return self.validateError('cpsschemas_err_required', {},
2067                                          datastructure)
2068            info= self.getStorageImageInfo(field_id)
2069            # Remove the file in the filesystem
2070            if info:
2071                os.remove(info['file_path'])
2072            datamodel[field_id] = None
2073        elif choice == 'keep':
2074            fileupload = datastructure[widget_id]
2075            if isinstance(fileupload, PersistableFileUpload):
2076                # Keeping something from the session means we
2077                # actually want to store it.
2078                store = True
2079            # else:
2080            #     # Nothing to change, don't pollute datastructure
2081            #     # with something costly already stored, which therefore
2082            #     # doesn't need to be kept in the session.
2083            #     self.unprepare(datastructure)
2084        elif choice == 'change' and is_upload:
2085            if not fileupload:
2086                return self.validateError('cpsschemas_err_file_empty', {},
2087                                          datastructure)
2088            if not isinstance(fileupload, FileUpload):
2089                return self.validateError('cpsschemas_err_file', {},
2090                                          datastructure)
2091            fileupload.seek(0, 2) # end of file
2092            size = fileupload.tell()
2093            if not size:
2094                return self.validateError('cpsschemas_err_file_empty', {},
2095                                          datastructure)
2096            if self.size_max and size > self.size_max:
2097                max_size_str = self.getHumanReadableSize(self.size_max)
2098                err = 'This file is too big, the allowed max size is ${max_size}'
2099                member_id = str(self.portal_membership.getAuthenticatedMember())
2100                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2101                err_mapping = {'max_size': max_size_str}
2102                return self.validateError(err, err_mapping, datastructure)
2103            store = True
2104
2105
2106        # Find filename
2107        if is_upload and store:
2108            filename = cookId('', '', fileupload)[0].strip()
2109            base,ext = os.path.splitext(filename)
2110            filename = "%s_%s%s" % (field_id,
2111                                    student_id,
2112                                    ext)
2113            datamodel[field_id] = filename
2114            registry = getToolByName(self, 'mimetypes_registry')
2115            mimetype = registry.lookupExtension(filename.lower())
2116            if mimetype is not None:
2117                mimetype = str(mimetype) # normalize
2118            file = self.makeFile(filename, fileupload, datastructure)
2119            # Fixup mimetype
2120            if mimetype and file.content_type != mimetype:
2121                file.content_type = mimetype
2122            # Store the file in the filesystem
2123            #student_path = os.path.join(self.storage_path,student_id)
2124            student_path = getImagesDir(student_id)
2125            if not os.path.exists(student_path):
2126                os.mkdir(student_path)
2127            full_path = os.path.join(student_path, filename)
2128            pict = open(full_path,"w")
2129            #fileupload.seek(0)
2130            #import pdb; pdb.set_trace()
2131            pict.write(str(file.data))
2132            pict.close()
2133        return True
2134    ###)
2135
2136    def render(self, mode, datastructure, **kw): ###(
2137        render_method = 'widget_image_render'
2138        meth = getattr(self, render_method, None)
2139        #import pdb;pdb.set_trace()
2140        if meth is None:
2141            raise RuntimeError("Unknown Render Method %s for widget type %s"
2142                               % (render_method, self.getId()))
2143        img_info = self.getImageInfo(datastructure)
2144        return meth(mode=mode, datastructure=datastructure, **img_info)
2145    ###)
2146
2147InitializeClass(FileImageWidget)
2148
2149widgetRegistry.register(FileImageWidget)
2150###)
2151
2152class DiscFileWidget(CPSFileWidget): ###(
2153    """File widget with filesystem storage."""
2154    meta_type = 'Disc File Widget'
2155    _properties = CPSFileWidget._properties +\
2156    (
2157     {'id': 'path', 'type': 'string', 'mode': 'w',
2158      'label': 'Relative Path'},
2159    )
2160    path = "import"
2161    storage_path = "%s/%s" % (i_home,path)
2162
2163    def getStoredFileInfo(self,datastructure): ###(
2164        datamodel = datastructure.getDataModel()
2165        field_id = self.fields[0]
2166        widget_id = self.getWidgetId()
2167        file_name = datamodel[field_id]
2168        info = {}
2169        registry = getToolByName(self, 'mimetypes_registry')
2170        info['mimetype'] = registry.lookupExtension('file.csv')
2171        info['empty_file'] = True
2172        info['size'] = 0
2173        info['last_modified'] = ''
2174        file_path = os.path.join(self.storage_path, file_name)
2175        if os.path.exists(file_path):
2176            info['empty_file'] = False
2177            info['file_name'] = file_name
2178            info['content_url'] = os.path.join(self.portal_url(),
2179                                            "viewfile",
2180                                            file_name,
2181                                            )
2182            info['current_filename'] =  file_name
2183            # get the mimetype
2184            mimetype = (registry.lookupExtension(file_name.lower()) or
2185                        registry.lookupExtension('file.bin'))
2186            info['mimetype'] = mimetype
2187            info['file_path'] = file_path
2188        else:
2189            info['file_name'] = ''
2190            info['content_url'] = ''
2191            info['current_filename'] = ''
2192            info['file_path'] = ''
2193        return info
2194        ###)
2195   
2196    def prepare(self, datastructure, **kw): ###(
2197        """Prepare datastructure from datamodel."""
2198        datamodel = datastructure.getDataModel()
2199        #import pdb;pdb.set_trace()
2200        widget_id = self.getWidgetId()
2201        file_name = datamodel[self.fields[0]]
2202        datastructure[widget_id] = file_name
2203        datastructure[widget_id + '_filename'] = file_name
2204        datastructure[widget_id+'_choice'] = "keep"
2205    ###)
2206
2207    def validate(self, datastructure, **kw): ###(
2208        """Update datamodel from user data in datastructure.
2209        """
2210        logger = logging.getLogger('Widgets.DiscFileWidget.validate')
2211        datamodel = datastructure.getDataModel()
2212        field_id = self.fields[0]
2213        widget_id = self.getWidgetId()
2214        store = False
2215        fileupload = None
2216        mimetype = None
2217        old_file = datamodel[field_id]
2218        choice = datastructure[widget_id+'_choice']
2219        fileupload = datastructure[widget_id]
2220        is_upload = isinstance(fileupload, FileUpload)
2221        if not is_upload and not datamodel[field_id]:
2222            if self.is_required:
2223                return self.validateError('File upload required', {},
2224                                          datastructure)
2225        if choice == 'delete':
2226            if self.is_required:
2227                return self.validateError('cpsschemas_err_required', {},
2228                                          datastructure)
2229            info = self.getStoredFileInfo(datastructure)
2230            # Remove the file in the filesystem
2231            if info:
2232                os.remove(info['file_path'])
2233            datamodel[field_id] = None
2234        elif choice == 'keep':
2235            fileupload = datastructure[widget_id]
2236            if isinstance(fileupload, PersistableFileUpload):
2237                # Keeping something from the session means we
2238                # actually want to store it.
2239                store = True
2240            # else:
2241            #     # Nothing to change, don't pollute datastructure
2242            #     # with something costly already stored, which therefore
2243            #     # doesn't need to be kept in the session.
2244            #     self.unprepare(datastructure)
2245        elif choice == 'change' and is_upload:
2246            if not fileupload:
2247                return self.validateError('cpsschemas_err_file_empty', {},
2248                                          datastructure)
2249            if not isinstance(fileupload, FileUpload):
2250                return self.validateError('cpsschemas_err_file', {},
2251                                          datastructure)
2252            fileupload.seek(0, 2) # end of file
2253            size = fileupload.tell()
2254            if not size:
2255                return self.validateError('cpsschemas_err_file_empty', {},
2256                                          datastructure)
2257            if self.size_max and size > self.size_max:
2258                max_size_str = self.getHumanReadableSize(self.size_max)
2259                err = 'This file is too big, the allowed max size is ${max_size}'
2260                member_id = str(self.portal_membership.getAuthenticatedMember())
2261                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2262                err_mapping = {'max_size': max_size_str}
2263                return self.validateError(err, err_mapping, datastructure)
2264            store = True
2265
2266
2267        # Find filename
2268        if is_upload and store:
2269            filename = cookId('', '', fileupload)[0].strip()
2270            base,ext = os.path.splitext(filename)
2271            if ext not in ("csv",".csv"):
2272                return self.validateError('only csv files allowed', {},
2273                                          datastructure)
2274            uploads_folder = self.portal_url.getPortalObject().campus.uploads
2275            if hasattr(uploads_folder,filename):
2276                return self.validateError('upload object exists', {},
2277                                          datastructure)
2278            datamodel[field_id] = filename
2279            registry = getToolByName(self, 'mimetypes_registry')
2280            mimetype = registry.lookupExtension(filename.lower())
2281            if mimetype is not None:
2282                mimetype = str(mimetype) # normalize
2283            file = self.makeFile(filename, fileupload, datastructure)
2284            # Fixup mimetype
2285            if mimetype and file.content_type != mimetype:
2286                file.content_type = mimetype
2287            file_path = os.path.join(self.storage_path,filename)
2288            data = open(file_path,"w")
2289            data.write(str(file.data))
2290            data.close()
2291        return True
2292    ###)
2293
2294    def render(self, mode, datastructure, **kw): ###(
2295        render_method = 'widget_uploadfile_render'
2296        meth = getattr(self, render_method, None)
2297        #import pdb;pdb.set_trace()
2298        if meth is None:
2299            raise RuntimeError("Unknown Render Method %s for widget type %s"
2300                               % (render_method, self.getId()))
2301        file_info = self.getStoredFileInfo(datastructure)
2302
2303        return meth(mode=mode, datastructure=datastructure, **file_info)
2304    ###)
2305
2306InitializeClass(DiscFileWidget)
2307
2308widgetRegistry.register(DiscFileWidget)
2309###)
2310
2311###########
2312
Note: See TracBrowser for help on using the repository browser.