source: WAeUP_SRP/base/Widgets.py @ 3141

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

enable import of entry_session value 1998/1999

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