source: WAeUP_SRP/base/Widgets.py @ 3429

Last change on this file since 3429 was 3413, checked in by Henrik Bettermann, 17 years ago
  • Property svn:keywords set to Id
File size: 89.4 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 3413 2008-04-03 12:59:15Z henrik $
3from cgi import escape
4from types import *
5import Globals
6from Globals import InitializeClass
7from ZPublisher.HTTPRequest import FileUpload
8from OFS.Image import cookId, File, Image
9##from Products.CPSSchemas.Widget import CPSWidgetType
10from Products.CMFCore.utils import getToolByName
11from Products.CPSSchemas.BasicWidgets import CPSBooleanWidget, CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget
12from Products.CPSSchemas.BasicWidgets import CPSFileWidget, CPSPasswordWidget
13from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget
14from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget
15from Products.CPSSchemas.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 self.REQUEST.traverse_subpath:
1505                screening_type_request = self.REQUEST.traverse_subpath[0]
1506            else:
1507                screening_type_request = 'manage'
1508            if datastructure.has_key('record'):
1509                applicant = datastructure['record']
1510                if applicant.screening_type != screening_type_request and screening_type_request != 'manage':
1511                    err = "You are using the wrong access form!"
1512                    s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1513                    break
1514            elif expiration_date and DateTime(expiration_date).lessThan(DateTime()):
1515                if not pins(student=ref):
1516                    #import pdb;pdb.set_trace()
1517                    err = 'no application record found'
1518                    s_logger.info('%s/%s tried new application though expired with PIN %s' % (member_id,ref,pin_str))
1519                    break
1520            ok,pin_record = pins.searchAndSetRecord(pin,ref,prefix)
1521            if ok < -2 or ok > 2:
1522                err = 'Unknown error, please report!'
1523                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
1524                break
1525            elif ok == -2:
1526                err = 'Service is already activated but with a different PIN.'
1527                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
1528                break
1529            elif ok == -1:
1530                err = 'Invalid PIN'
1531                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
1532                break
1533            if ok == 0:
1534                err = 'PIN already used'
1535                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
1536                break
1537            if ok >= 1:
1538                #screening_type = self.REQUEST.form.get('screening_type','unknown')
1539                #screening_type = datastructure['screening_type']
1540                if datastructure.has_key('record'):
1541                    applicant = datastructure['record']
1542                    if applicant.screening_type != screening_type_request\
1543                          and screening_type_request != 'manage':
1544                        err = "You are using the wrong access form!"
1545                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1546                        break
1547                    if not applicant.pin:
1548                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1549                        d = {}
1550                        d['reg_no'] = applicant.reg_no
1551                        d['pin'] = pin_str
1552                        #d['screening_type'] = screening_type
1553                        #d['status'] = 'entered'
1554                        getattr(self,self.catalog).modifyRecord(**d)
1555                    elif applicant.pin != pin_str:
1556                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
1557                    elif applicant.pin == pin_str:
1558                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1559                else:
1560                    datastructure['reg_no'] = ref
1561                    res = self.applicants_catalog(reg_no = ref)
1562                    if res:
1563                        if getattr(res[0],'screening_type',None) != screening_type_request\
1564                              and screening_type_request != 'manage':
1565                            err = "You are using the wrong access form!"
1566                            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)))
1567                            break
1568                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1569                    else:
1570                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1571                        d = {}
1572                        d['reg_no'] = ref
1573                        d['pin'] = pin_str
1574                        d['status'] = 'entered'
1575                        d['screening_type'] = screening_type_request
1576                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
1577                                                  pin_record.serial)
1578                        self.applicants_catalog.addRecord(**d)
1579
1580            break
1581        if err:
1582            datastructure.setError(widget_id, err,mapping)
1583        else:
1584            datamodel = datastructure.getDataModel()
1585            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1586            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1587            datastructure[widget_id+'_p'] = prefix
1588            datastructure[widget_id+'_b'] = b
1589            datastructure[widget_id+'_n'] = n
1590        return not err
1591    ###)
1592
1593    def render(self, mode, datastructure, **kw): ###(
1594        """Render in mode from datastructure."""
1595        render_method = 'widget_scratch_card_pin_render'
1596        meth = getattr(self, render_method, None)
1597        if meth is None:
1598            raise RuntimeError("Unknown Render Method %s for widget type %s"
1599                               % (render_method, self.getId()))
1600
1601        # XXX AT: datastructure has to be set again here, in case we're in edit
1602        # or create mode, because a default value has to be provided.
1603        #import pdb;pdb.set_trace()
1604        datamodel = datastructure.getDataModel()
1605        v = datamodel[self.fields[0]]
1606        #import pdb;pdb.set_trace()
1607        if v and type(v) is StringType:
1608            try:
1609                p,b,n = v.split('-')
1610                v = ScratchCardPin(p,b,n)
1611            except ValueError:
1612                v = ScratchCardPin(self.prefix,'XXX',v)
1613                pass
1614        if v:
1615            prefix= '%s' % v.p
1616            b = '%s' % v.b
1617            n = '%s' % v.n
1618        else:
1619            prefix= self.prefix
1620            if prefix.startswith('@'):
1621                prefix= getattr(self,self.prefix[1:])()
1622            b = n = ''
1623            v = ScratchCardPin(prefix,b,n)
1624        widget_id = self.getWidgetId()
1625        datastructure[widget_id] = v
1626        datastructure[widget_id+'_p'] = prefix
1627        datastructure[widget_id+'_b'] = b
1628        datastructure[widget_id+'_n'] = n
1629        return meth(mode=mode,
1630                    datastructure=datastructure,
1631                    )
1632    ###)
1633
1634InitializeClass(PumePinWidget)
1635widgetRegistry.register(PumePinWidget)
1636###)
1637
1638class WAeUPImageWidget(CPSImageWidget): ###(
1639    """Photo widget."""
1640    meta_type = 'WAeUP Image Widget'
1641
1642    def render(self, mode, datastructure, **kw):
1643        render_method = 'widget_waeup_image_render'
1644        meth = getattr(self, render_method, None)
1645        if meth is None:
1646            raise RuntimeError("Unknown Render Method %s for widget type %s"
1647                               % (render_method, self.getId()))
1648        img_info = self.getImageInfo(datastructure)
1649        return meth(mode=mode, datastructure=datastructure, **img_info)
1650
1651InitializeClass(WAeUPImageWidget)
1652
1653widgetRegistry.register(WAeUPImageWidget)
1654###)
1655
1656class ApplicationImageWidget(CPSImageWidget): ###(
1657    """Image widget with filesystem storage."""
1658    meta_type = 'Application Image Widget'
1659    _properties = CPSImageWidget._properties +\
1660    (
1661     {'id': 'path', 'type': 'string', 'mode': 'w',
1662      'label': 'Relative Path'},
1663     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1664      'label': 'Field to build the id'},
1665    )
1666    path = "images"
1667    storage_path = "%s/import/%s" % (i_home,path)
1668    id_field = "reg_no"
1669
1670    def getImageInfo(self, datastructure): ###(
1671        """Get the file info from the datastructure."""
1672        widget_id = self.getWidgetId()
1673        if  datastructure.has_key(widget_id):
1674            fileupload = datastructure[widget_id]
1675            dm = datastructure.getDataModel()
1676            field_id = self.fields[0]
1677            screening_type = datastructure.get('screening_type')
1678            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1679                                            field_id,)
1680            base_path = os.path.join(screening_type,current_filename)
1681            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1682            file_path = os.path.join(self.storage_path,base_path)
1683            #import pdb; pdb.set_trace()
1684        else:
1685            file_path = "XXX"
1686        # read the file from the filesystem
1687        if not os.path.exists(file_path):
1688            height = -1
1689            width = -1
1690            empty_file = True
1691            session_file = False
1692            current_filename = ''
1693            content_url = ''
1694            size = 0
1695            mimetype = ''
1696            last_modified = ''
1697            height = ''
1698            width = ''
1699
1700        else:
1701            image = open(file_path)
1702            from OFS.Image import getImageInfo as getImageInfoOFS
1703            image.seek(0)
1704            data = image.read(2000)
1705            size = len(data)
1706            empty_file = size == 0
1707            session_file = False
1708            last_modified = ''
1709            image.close()
1710            mimetype, width, height = getImageInfoOFS(data)
1711
1712            if width < 0:
1713                width = None
1714            if height < 0:
1715                height = None
1716
1717            if (self.allow_resize
1718                and height is not None
1719                and width  is not None):
1720                z_w = z_h = 1
1721                h = int(self.display_height)
1722                w = int(self.display_width)
1723                if w and h:
1724                    if w < width:
1725                        z_w = w / float(width)
1726                    if h < height:
1727                        z_h = h / float(height)
1728                    zoom = min(z_w, z_h)
1729                    width = int(zoom * width)
1730                    height = int(zoom * height)
1731                #import pdb;pdb.set_trace()
1732        image_info = {
1733            'empty_file': empty_file,
1734            'session_file': session_file,
1735            'current_filename': current_filename,
1736            'size': size,
1737            'last_modified': last_modified,
1738            'content_url': content_url,
1739            'mimetype': mimetype,
1740            }
1741        title = image_info['current_filename']
1742        alt = title or ''
1743        #height = int(self.display_height)
1744        #width = int(self.display_width)
1745        if height is None or width is None:
1746            tag = renderHtmlTag('img', src=image_info['content_url'],
1747                                alt=alt, title=title)
1748        else:
1749            tag = renderHtmlTag('img', src=image_info['content_url'],
1750                                width=str(width), height=str(height),
1751                                alt=alt, title=title)
1752
1753        image_info['height'] = height
1754        image_info['width'] = width
1755        image_info['image_tag'] = tag
1756        return image_info
1757    ###)
1758
1759    def checkFileName(self, filename, mimetype):
1760        return '', {}
1761        if mimetype and mimetype.startswith('image'):
1762            return '', {}
1763        return 'cpsschemas_err_image', {}
1764
1765    def prepare(self, datastructure, **kw): ###(
1766        """Prepare datastructure from datamodel."""
1767        datamodel = datastructure.getDataModel()
1768        widget_id = self.getWidgetId()
1769        file_name = datamodel[self.fields[0]]
1770        #import pdb; pdb.set_trace()
1771        if self.allow_resize:
1772            datastructure[self.getWidgetId() + '_resize'] = ''
1773        screening_type = datamodel.get('screening_type',None)
1774        if not screening_type:
1775            screening_type = self.REQUEST.form.get('screening_type','pume')
1776        datastructure["screening_type"] = screening_type
1777        datastructure[widget_id] = file_name
1778        datastructure[widget_id + '_choice'] = 'change'
1779        title = 'Passport Foto'
1780        datastructure[widget_id + '_filename'] = title
1781    ###)
1782
1783    def validate(self, datastructure, **kw): ###(
1784        """Update datamodel from user data in datastructure.
1785        """
1786        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1787        datamodel = datastructure.getDataModel()
1788        field_id = self.fields[0]
1789        widget_id = self.getWidgetId()
1790        store = False
1791        fileupload = None
1792        mimetype = None
1793        old_file = datamodel[field_id]
1794        # if old_file is not None:
1795        #     old_filename = old_file.title
1796        # else:
1797        #     old_filename = ''
1798        choice = datastructure[widget_id+'_choice']
1799        fileupload = datastructure[widget_id]
1800        is_upload = isinstance(fileupload, FileUpload)
1801        #import pdb; pdb.set_trace()
1802        if not is_upload and not datamodel[field_id]:
1803            if self.is_required:
1804                return self.validateError('Picture upload required', {},
1805                                          datastructure)
1806        if choice == 'delete':
1807            if self.is_required:
1808                return self.validateError('cpsschemas_err_required', {},
1809                                          datastructure)
1810            datamodel[field_id] = None
1811        elif choice == 'keep':
1812            fileupload = datastructure[widget_id]
1813            if isinstance(fileupload, PersistableFileUpload):
1814                # Keeping something from the session means we
1815                # actually want to store it.
1816                store = True
1817            # else:
1818            #     # Nothing to change, don't pollute datastructure
1819            #     # with something costly already stored, which therefore
1820            #     # doesn't need to be kept in the session.
1821            #     self.unprepare(datastructure)
1822        elif choice == 'change' and is_upload:
1823            if not fileupload:
1824                return self.validateError('cpsschemas_err_file_empty', {},
1825                                          datastructure)
1826            if not isinstance(fileupload, FileUpload):
1827                return self.validateError('cpsschemas_err_file', {},
1828                                          datastructure)
1829            fileupload.seek(0, 2) # end of file
1830            size = fileupload.tell()
1831            if not size:
1832                return self.validateError('cpsschemas_err_file_empty', {},
1833                                          datastructure)
1834            if self.size_max and size > self.size_max:
1835                max_size_str = self.getHumanReadableSize(self.size_max)
1836                err = 'This file is too big, the allowed max size is ${max_size}'
1837                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1838                err_mapping = {'max_size': max_size_str}
1839                return self.validateError(err, err_mapping, datastructure)
1840            store = True
1841
1842
1843        # Find filename
1844        if is_upload and store:
1845            ext ='jpg'
1846            screening_type = datastructure.get('screening_type')
1847            filename = "%s_%s.%s" % (datastructure[self.id_field],
1848                                     self.getWidgetId(),
1849                                     ext)
1850            datamodel[field_id] = filename
1851            registry = getToolByName(self, 'mimetypes_registry')
1852            mimetype = registry.lookupExtension(filename.lower())
1853            if mimetype is not None:
1854                mimetype = str(mimetype) # normalize
1855            file = self.makeFile(filename, fileupload, datastructure)
1856            # Fixup mimetype
1857            if mimetype and file.content_type != mimetype:
1858                file.content_type = mimetype
1859            # Store the file in the filesystem
1860            #import pdb;pdb.set_trace()
1861            base_path = os.path.join(self.storage_path, screening_type)
1862            if not os.path.exists(base_path):
1863                os.mkdir(base_path)
1864            full_path = os.path.join(base_path, filename)
1865            pict = open(full_path,"w")
1866            fileupload.seek(0)
1867            pict.write(fileupload.read())
1868            pict.close()
1869
1870
1871        return True
1872
1873###)
1874
1875    def render(self, mode, datastructure, **kw): ###(
1876        render_method = 'widget_passport_render'
1877        meth = getattr(self, render_method, None)
1878        if meth is None:
1879            raise RuntimeError("Unknown Render Method %s for widget type %s"
1880                               % (render_method, self.getId()))
1881        img_info = self.getImageInfo(datastructure)
1882        return meth(mode=mode, datastructure=datastructure, **img_info)
1883    ###)
1884
1885InitializeClass(ApplicationImageWidget)
1886
1887widgetRegistry.register(ApplicationImageWidget)
1888###)
1889
1890class FileImageWidget(CPSImageWidget): ###(
1891    """Image widget with filesystem storage."""
1892    meta_type = 'File Image Widget'
1893    _properties = CPSImageWidget._properties +\
1894    (
1895     {'id': 'path', 'type': 'string', 'mode': 'w',
1896      'label': 'Relative Path'},
1897     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1898      'label': 'Field to build the id'},
1899     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
1900      'label': 'Show Image'},
1901    )
1902    path = "images"
1903    #storage_path = "%s/%s" % (i_home,path)
1904    id_field = ""
1905    show_image = False
1906
1907    def getStorageImageInfo(self,field_id):
1908        info = {}
1909        if self.id_field == "":
1910            student_id = self.getStudentId()
1911        else:
1912            student_id = datastructure[self.id_field]
1913        # student_path = os.path.join(self.storage_path,
1914        #                             student_id)
1915        student_path = getImagesDir(student_id)
1916        image_name = ''
1917        content_url = ''
1918        current_filename = ''
1919        if os.path.exists(student_path):
1920            for name in os.listdir(student_path):
1921                if name.startswith(field_id):
1922                    image_name = name
1923                    break
1924        if image_name:
1925            info['image_name'] = image_name
1926            info['content_url'] = os.path.join(self.portal_url(),
1927                                               "viewimage",
1928                                               student_id,
1929                                               image_name,
1930                                              )
1931            info['current_filename'] =  image_name
1932            info['file_path'] = os.path.join(student_path, image_name)
1933        return info
1934
1935    def getImageInfo(self, datastructure): ###(
1936        """Get the file info from the datastructure."""
1937        widget_id = self.getWidgetId()
1938        info = None
1939        if  datastructure.has_key(widget_id):
1940            fileupload = datastructure[widget_id]
1941            dm = datastructure.getDataModel()
1942            field_id = self.fields[0]
1943            info = self.getStorageImageInfo(field_id)
1944        else:
1945            file_path = "XXX"
1946            title = ""
1947        # read the file from the filesystem
1948        #import pdb; pdb.set_trace()
1949        #if not os.path.exists(file_path):
1950        if not info:
1951            title = ""
1952            height = -1
1953            width = -1
1954            empty_file = True
1955            session_file = False
1956            current_filename = ''
1957            content_url = ''
1958            size = 0
1959            mimetype = ''
1960            last_modified = ''
1961            height = ''
1962            width = ''
1963        else:
1964            title = info['image_name']
1965            current_filename = info['current_filename']
1966            content_url = info['content_url']
1967            image = open(info['file_path'])
1968            from OFS.Image import getImageInfo as getImageInfoOFS
1969            image.seek(0)
1970            data = image.read(2000)
1971            size = len(data)
1972            empty_file = size == 0
1973            session_file = False
1974            last_modified = ''
1975            image.close()
1976            mimetype, width, height = getImageInfoOFS(data)
1977            registry = getToolByName(self, 'mimetypes_registry')
1978            mimetype = (registry.lookupExtension(current_filename.lower()) or
1979                        registry.lookupExtension('file.bin'))
1980            if width < 0:
1981                width = None
1982            if height < 0:
1983                height = None
1984
1985            if (self.allow_resize
1986                and height is not None
1987                and width  is not None):
1988                z_w = z_h = 1
1989                h = int(self.display_height)
1990                w = int(self.display_width)
1991                if w and h:
1992                    if w < width:
1993                        z_w = w / float(width)
1994                    if h < height:
1995                        z_h = h / float(height)
1996                    zoom = min(z_w, z_h)
1997                    width = int(zoom * width)
1998                    height = int(zoom * height)
1999                #import pdb;pdb.set_trace()
2000        image_info = {
2001            'empty_file': empty_file,
2002            'session_file': session_file,
2003            'current_filename': title,
2004            'size': size,
2005            'last_modified': last_modified,
2006            'content_url': content_url,
2007            'mimetype': mimetype,
2008            }
2009        alt = title or ''
2010        #height = int(self.display_height)
2011        #width = int(self.display_width)
2012        if height is None or width is None:
2013            tag = renderHtmlTag('img', src=image_info['content_url'],
2014                                alt=alt, title=title)
2015        else:
2016            tag = renderHtmlTag('img', src=image_info['content_url'],
2017                                width=str(width), height=str(height),
2018                                alt=alt, title=title)
2019
2020        image_info['height'] = height
2021        image_info['width'] = width
2022        image_info['image_tag'] = tag
2023        image_info['show_image'] = self.show_image
2024        return image_info
2025    ###)
2026
2027    # def checkFileName(self, filename, mimetype):
2028    #     return '', {}
2029    #     if mimetype and mimetype.startswith('image'):
2030    #         return '', {}
2031    #     return 'cpsschemas_err_image', {}
2032
2033    def prepare(self, datastructure, **kw): ###(
2034        """Prepare datastructure from datamodel."""
2035        datamodel = datastructure.getDataModel()
2036        widget_id = self.getWidgetId()
2037        file_name = datamodel[self.fields[0]]
2038        if self.id_field == "":
2039            student_id = self.getStudentId()
2040        else:
2041            student_id = datastructure[self.id_field]
2042        if student_id is not None:
2043            # student_path = os.path.join(self.storage_path,
2044            #                             student_id)
2045            student_path = getImagesDir(student_id)
2046            if not os.path.exists(student_path):
2047                self.waeup_tool.moveImagesToFS(student_id)
2048        if self.allow_resize:
2049            datastructure[self.getWidgetId() + '_resize'] = ''
2050        datastructure[widget_id] = file_name
2051        datastructure[widget_id + '_choice'] = 'change'
2052        title = 'Passport Foto'
2053        datastructure[widget_id + '_filename'] = title
2054    ###)
2055
2056    def validate(self, datastructure, **kw): ###(
2057        """Update datamodel from user data in datastructure.
2058        """
2059        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2060        datamodel = datastructure.getDataModel()
2061        field_id = self.fields[0]
2062        widget_id = self.getWidgetId()
2063        store = False
2064        fileupload = None
2065        mimetype = None
2066        old_file = datamodel[field_id]
2067        choice = datastructure[widget_id+'_choice']
2068        fileupload = datastructure[widget_id]
2069        is_upload = isinstance(fileupload, FileUpload)
2070        #import pdb; pdb.set_trace()
2071        if not is_upload and not datamodel[field_id]:
2072            if self.is_required:
2073                return self.validateError('Picture upload required', {},
2074                                          datastructure)
2075        if self.id_field == "":
2076            student_id = self.getStudentId()
2077        else:
2078            student_id = datastructure[self.id_field]
2079        if choice == 'delete':
2080            if self.is_required:
2081                return self.validateError('cpsschemas_err_required', {},
2082                                          datastructure)
2083            info= self.getStorageImageInfo(field_id)
2084            # Remove the file in the filesystem
2085            if info:
2086                os.remove(info['file_path'])
2087            datamodel[field_id] = None
2088        elif choice == 'keep':
2089            fileupload = datastructure[widget_id]
2090            if isinstance(fileupload, PersistableFileUpload):
2091                # Keeping something from the session means we
2092                # actually want to store it.
2093                store = True
2094            # else:
2095            #     # Nothing to change, don't pollute datastructure
2096            #     # with something costly already stored, which therefore
2097            #     # doesn't need to be kept in the session.
2098            #     self.unprepare(datastructure)
2099        elif choice == 'change' and is_upload:
2100            if not fileupload:
2101                return self.validateError('cpsschemas_err_file_empty', {},
2102                                          datastructure)
2103            if not isinstance(fileupload, FileUpload):
2104                return self.validateError('cpsschemas_err_file', {},
2105                                          datastructure)
2106            fileupload.seek(0, 2) # end of file
2107            size = fileupload.tell()
2108            if not size:
2109                return self.validateError('cpsschemas_err_file_empty', {},
2110                                          datastructure)
2111            if self.size_max and size > self.size_max:
2112                max_size_str = self.getHumanReadableSize(self.size_max)
2113                err = 'This file is too big, the allowed max size is ${max_size}'
2114                member_id = str(self.portal_membership.getAuthenticatedMember())
2115                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2116                err_mapping = {'max_size': max_size_str}
2117                return self.validateError(err, err_mapping, datastructure)
2118            store = True
2119
2120
2121        # Find filename
2122        if is_upload and store:
2123            filename = cookId('', '', fileupload)[0].strip()
2124            base,ext = os.path.splitext(filename)
2125            filename = "%s_%s%s" % (field_id,
2126                                    student_id,
2127                                    ext)
2128            datamodel[field_id] = filename
2129            registry = getToolByName(self, 'mimetypes_registry')
2130            mimetype = registry.lookupExtension(filename.lower())
2131            if mimetype is not None:
2132                mimetype = str(mimetype) # normalize
2133            file = self.makeFile(filename, fileupload, datastructure)
2134            # Fixup mimetype
2135            if mimetype and file.content_type != mimetype:
2136                file.content_type = mimetype
2137            # Store the file in the filesystem
2138            #student_path = os.path.join(self.storage_path,student_id)
2139            student_path = getImagesDir(student_id)
2140            if not os.path.exists(student_path):
2141                os.mkdir(student_path)
2142            full_path = os.path.join(student_path, filename)
2143            pict = open(full_path,"w")
2144            #fileupload.seek(0)
2145            #import pdb; pdb.set_trace()
2146            pict.write(str(file.data))
2147            pict.close()
2148        return True
2149    ###)
2150
2151    def render(self, mode, datastructure, **kw): ###(
2152        render_method = 'widget_image_render'
2153        meth = getattr(self, render_method, None)
2154        #import pdb;pdb.set_trace()
2155        if meth is None:
2156            raise RuntimeError("Unknown Render Method %s for widget type %s"
2157                               % (render_method, self.getId()))
2158        img_info = self.getImageInfo(datastructure)
2159        return meth(mode=mode, datastructure=datastructure, **img_info)
2160    ###)
2161
2162InitializeClass(FileImageWidget)
2163
2164widgetRegistry.register(FileImageWidget)
2165###)
2166
2167class DiscFileWidget(CPSFileWidget): ###(
2168    """File widget with filesystem storage."""
2169    meta_type = 'Disc File Widget'
2170    _properties = CPSFileWidget._properties +\
2171    (
2172     {'id': 'path', 'type': 'string', 'mode': 'w',
2173      'label': 'Relative Path'},
2174    )
2175    path = "import"
2176    storage_path = "%s/%s" % (i_home,path)
2177
2178    def getStoredFileInfo(self,datastructure): ###(
2179        datamodel = datastructure.getDataModel()
2180        field_id = self.fields[0]
2181        widget_id = self.getWidgetId()
2182        file_name = datamodel[field_id]
2183        info = {}
2184        registry = getToolByName(self, 'mimetypes_registry')
2185        info['mimetype'] = registry.lookupExtension('file.csv')
2186        info['empty_file'] = True
2187        info['size'] = 0
2188        info['last_modified'] = ''
2189        file_path = os.path.join(self.storage_path, file_name)
2190        if os.path.exists(file_path):
2191            info['empty_file'] = False
2192            info['file_name'] = file_name
2193            info['content_url'] = os.path.join(self.portal_url(),
2194                                            "viewfile",
2195                                            file_name,
2196                                            )
2197            info['current_filename'] =  file_name
2198            # get the mimetype
2199            mimetype = (registry.lookupExtension(file_name.lower()) or
2200                        registry.lookupExtension('file.bin'))
2201            info['mimetype'] = mimetype
2202            info['file_path'] = file_path
2203        else:
2204            info['file_name'] = ''
2205            info['content_url'] = ''
2206            info['current_filename'] = ''
2207            info['file_path'] = ''
2208        return info
2209        ###)
2210
2211    def prepare(self, datastructure, **kw): ###(
2212        """Prepare datastructure from datamodel."""
2213        datamodel = datastructure.getDataModel()
2214        #import pdb;pdb.set_trace()
2215        widget_id = self.getWidgetId()
2216        file_name = datamodel[self.fields[0]]
2217        datastructure[widget_id] = file_name
2218        datastructure[widget_id + '_filename'] = file_name
2219        datastructure[widget_id+'_choice'] = "keep"
2220    ###)
2221
2222    def validate(self, datastructure, **kw): ###(
2223        """Update datamodel from user data in datastructure.
2224        """
2225        logger = logging.getLogger('Widgets.DiscFileWidget.validate')
2226        datamodel = datastructure.getDataModel()
2227        field_id = self.fields[0]
2228        widget_id = self.getWidgetId()
2229        store = False
2230        fileupload = None
2231        mimetype = None
2232        old_file = datamodel[field_id]
2233        choice = datastructure[widget_id+'_choice']
2234        fileupload = datastructure[widget_id]
2235        is_upload = isinstance(fileupload, FileUpload)
2236        if not is_upload and not datamodel[field_id]:
2237            if self.is_required:
2238                return self.validateError('File upload required', {},
2239                                          datastructure)
2240        if choice == 'delete':
2241            if self.is_required:
2242                return self.validateError('cpsschemas_err_required', {},
2243                                          datastructure)
2244            info = self.getStoredFileInfo(datastructure)
2245            # Remove the file in the filesystem
2246            if info:
2247                os.remove(info['file_path'])
2248            datamodel[field_id] = None
2249        elif choice == 'keep':
2250            fileupload = datastructure[widget_id]
2251            if isinstance(fileupload, PersistableFileUpload):
2252                # Keeping something from the session means we
2253                # actually want to store it.
2254                store = True
2255            # else:
2256            #     # Nothing to change, don't pollute datastructure
2257            #     # with something costly already stored, which therefore
2258            #     # doesn't need to be kept in the session.
2259            #     self.unprepare(datastructure)
2260        elif choice == 'change' and is_upload:
2261            if not fileupload:
2262                return self.validateError('cpsschemas_err_file_empty', {},
2263                                          datastructure)
2264            if not isinstance(fileupload, FileUpload):
2265                return self.validateError('cpsschemas_err_file', {},
2266                                          datastructure)
2267            fileupload.seek(0, 2) # end of file
2268            size = fileupload.tell()
2269            if not size:
2270                return self.validateError('cpsschemas_err_file_empty', {},
2271                                          datastructure)
2272            if self.size_max and size > self.size_max:
2273                max_size_str = self.getHumanReadableSize(self.size_max)
2274                err = 'This file is too big, the allowed max size is ${max_size}'
2275                member_id = str(self.portal_membership.getAuthenticatedMember())
2276                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2277                err_mapping = {'max_size': max_size_str}
2278                return self.validateError(err, err_mapping, datastructure)
2279            store = True
2280
2281
2282        # Find filename
2283        if is_upload and store:
2284            filename = cookId('', '', fileupload)[0].strip()
2285            base,ext = os.path.splitext(filename)
2286            if ext not in ("csv",".csv"):
2287                return self.validateError('only csv files allowed', {},
2288                                          datastructure)
2289            uploads_folder = self.portal_url.getPortalObject().campus.uploads
2290            if hasattr(uploads_folder,filename):
2291                return self.validateError('upload object exists', {},
2292                                          datastructure)
2293            datamodel[field_id] = filename
2294            registry = getToolByName(self, 'mimetypes_registry')
2295            mimetype = registry.lookupExtension(filename.lower())
2296            if mimetype is not None:
2297                mimetype = str(mimetype) # normalize
2298            file = self.makeFile(filename, fileupload, datastructure)
2299            # Fixup mimetype
2300            if mimetype and file.content_type != mimetype:
2301                file.content_type = mimetype
2302            file_path = os.path.join(self.storage_path,filename)
2303            data = open(file_path,"w")
2304            data.write(str(file.data))
2305            data.close()
2306        return True
2307    ###)
2308
2309    def render(self, mode, datastructure, **kw): ###(
2310        render_method = 'widget_uploadfile_render'
2311        meth = getattr(self, render_method, None)
2312        #import pdb;pdb.set_trace()
2313        if meth is None:
2314            raise RuntimeError("Unknown Render Method %s for widget type %s"
2315                               % (render_method, self.getId()))
2316        file_info = self.getStoredFileInfo(datastructure)
2317
2318        return meth(mode=mode, datastructure=datastructure, **file_info)
2319    ###)
2320
2321InitializeClass(DiscFileWidget)
2322
2323widgetRegistry.register(DiscFileWidget)
2324###)
2325
2326###########
2327
Note: See TracBrowser for help on using the repository browser.