source: WAeUP_SRP/base/Widgets.py @ 3394

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

remove expiration-property (not used)

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