source: WAeUP_SRP/base/Widgets.py @ 2660

Last change on this file since 2660 was 2656, checked in by Henrik Bettermann, 17 years ago

Several modifications made to enable payment for all sessions, all payment modes and both portals I tested all combinations.

'N/A' replaced by in level, verdict and session widgets. A missing value is now always .

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