source: WAeUP_SRP/base/Widgets.py @ 3272

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

resolve ticket #496

  • Property svn:keywords set to Id
File size: 81.5 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 3265 2008-03-03 12:57:38Z 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 len(v) == 0:
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.strip(),)
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 res:
1547                        if getattr(res[0],'screening_type',None) != screening_type_request\
1548                              and screening_type_request != 'manage':
1549                            err = "You are using the wrong access form!"
1550                            s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,getattr(res[0],'screening_type',None)))
1551                            break
1552                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1553                    else:
1554                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1555                        d = {}
1556                        d['reg_no'] = ref
1557                        d['pin'] = pin_str
1558                        d['status'] = 'entered'
1559                        d['screening_type'] = screening_type_request
1560                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
1561                                                  pin_record.serial)
1562                        self.applicants_catalog.addRecord(**d)
1563
1564            break
1565        if err:
1566            datastructure.setError(widget_id, err,mapping)
1567        else:
1568            datamodel = datastructure.getDataModel()
1569            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1570            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1571            datastructure[widget_id+'_p'] = prefix
1572            datastructure[widget_id+'_b'] = b
1573            datastructure[widget_id+'_n'] = n
1574        return not err
1575    ###)
1576
1577    def render(self, mode, datastructure, **kw): ###(
1578        """Render in mode from datastructure."""
1579        render_method = 'widget_scratch_card_pin_render'
1580        meth = getattr(self, render_method, None)
1581        if meth is None:
1582            raise RuntimeError("Unknown Render Method %s for widget type %s"
1583                               % (render_method, self.getId()))
1584
1585        # XXX AT: datastructure has to be set again here, in case we're in edit
1586        # or create mode, because a default value has to be provided.
1587        #import pdb;pdb.set_trace()
1588        datamodel = datastructure.getDataModel()
1589        v = datamodel[self.fields[0]]
1590        #import pdb;pdb.set_trace()
1591        if v and type(v) is StringType:
1592            try:
1593                p,b,n = v.split('-')
1594                v = ScratchCardPin(p,b,n)
1595            except ValueError:
1596                v = ScratchCardPin(self.prefix,'XXX',v)
1597                pass
1598        if v:
1599            prefix= '%s' % v.p
1600            b = '%s' % v.b
1601            n = '%s' % v.n
1602        else:
1603            prefix= self.prefix
1604            if prefix.startswith('@'):
1605                prefix= getattr(self,self.prefix[1:])()
1606            b = n = ''
1607            v = ScratchCardPin(prefix,b,n)
1608        widget_id = self.getWidgetId()
1609        datastructure[widget_id] = v
1610        datastructure[widget_id+'_p'] = prefix
1611        datastructure[widget_id+'_b'] = b
1612        datastructure[widget_id+'_n'] = n
1613        return meth(mode=mode,
1614                    datastructure=datastructure,
1615                    )
1616    ###)
1617
1618InitializeClass(PumePinWidget)
1619widgetRegistry.register(PumePinWidget)
1620###)
1621
1622class WAeUPImageWidget(CPSImageWidget): ###(
1623    """Photo widget."""
1624    meta_type = 'WAeUP Image Widget'
1625
1626    def render(self, mode, datastructure, **kw):
1627        render_method = 'widget_waeup_image_render'
1628        meth = getattr(self, render_method, None)
1629        if meth is None:
1630            raise RuntimeError("Unknown Render Method %s for widget type %s"
1631                               % (render_method, self.getId()))
1632        img_info = self.getImageInfo(datastructure)
1633        return meth(mode=mode, datastructure=datastructure, **img_info)
1634
1635InitializeClass(WAeUPImageWidget)
1636
1637widgetRegistry.register(WAeUPImageWidget)
1638###)
1639
1640class ApplicationImageWidget(CPSImageWidget): ###(
1641    """Image widget with filesystem storage."""
1642    meta_type = 'Application Image Widget'
1643    _properties = CPSImageWidget._properties +\
1644    (
1645     {'id': 'path', 'type': 'string', 'mode': 'w',
1646      'label': 'Relative Path'},
1647     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1648      'label': 'Field to build the id'},
1649    )
1650    path = "images"
1651    storage_path = "%s/import/%s" % (i_home,path)
1652    id_field = "reg_no"
1653
1654    def getImageInfo(self, datastructure): ###(
1655        """Get the file info from the datastructure."""
1656        widget_id = self.getWidgetId()
1657        if  datastructure.has_key(widget_id):
1658            fileupload = datastructure[widget_id]
1659            dm = datastructure.getDataModel()
1660            field_id = self.fields[0]
1661            screening_type = datastructure.get('screening_type')
1662            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1663                                            field_id,)
1664            base_path = os.path.join(screening_type,current_filename)
1665            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1666            file_path = os.path.join(self.storage_path,base_path)
1667            #import pdb; pdb.set_trace()
1668        else:
1669            file_path = "XXX"
1670        # read the file from the filesystem
1671        if not os.path.exists(file_path):
1672            height = -1
1673            width = -1
1674            empty_file = True
1675            session_file = False
1676            current_filename = ''
1677            content_url = ''
1678            size = 0
1679            mimetype = ''
1680            last_modified = ''
1681            height = ''
1682            width = ''
1683
1684        else:
1685            image = open(file_path)
1686            from OFS.Image import getImageInfo as getImageInfoOFS
1687            image.seek(0)
1688            data = image.read(2000)
1689            size = len(data)
1690            empty_file = size == 0
1691            session_file = False
1692            last_modified = ''
1693            image.close()
1694            mimetype, width, height = getImageInfoOFS(data)
1695
1696            if width < 0:
1697                width = None
1698            if height < 0:
1699                height = None
1700
1701            if (self.allow_resize
1702                and height is not None
1703                and width  is not None):
1704                z_w = z_h = 1
1705                h = int(self.display_height)
1706                w = int(self.display_width)
1707                if w and h:
1708                    if w < width:
1709                        z_w = w / float(width)
1710                    if h < height:
1711                        z_h = h / float(height)
1712                    zoom = min(z_w, z_h)
1713                    width = int(zoom * width)
1714                    height = int(zoom * height)
1715                #import pdb;pdb.set_trace()
1716        image_info = {
1717            'empty_file': empty_file,
1718            'session_file': session_file,
1719            'current_filename': current_filename,
1720            'size': size,
1721            'last_modified': last_modified,
1722            'content_url': content_url,
1723            'mimetype': mimetype,
1724            }
1725        title = image_info['current_filename']
1726        alt = title or ''
1727        #height = int(self.display_height)
1728        #width = int(self.display_width)
1729        if height is None or width is None:
1730            tag = renderHtmlTag('img', src=image_info['content_url'],
1731                                alt=alt, title=title)
1732        else:
1733            tag = renderHtmlTag('img', src=image_info['content_url'],
1734                                width=str(width), height=str(height),
1735                                alt=alt, title=title)
1736
1737        image_info['height'] = height
1738        image_info['width'] = width
1739        image_info['image_tag'] = tag
1740        return image_info
1741    ###)
1742
1743    def checkFileName(self, filename, mimetype):
1744        return '', {}
1745        if mimetype and mimetype.startswith('image'):
1746            return '', {}
1747        return 'cpsschemas_err_image', {}
1748
1749    def prepare(self, datastructure, **kw): ###(
1750        """Prepare datastructure from datamodel."""
1751        datamodel = datastructure.getDataModel()
1752        widget_id = self.getWidgetId()
1753        file_name = datamodel[self.fields[0]]
1754        #import pdb; pdb.set_trace()
1755        if self.allow_resize:
1756            datastructure[self.getWidgetId() + '_resize'] = ''
1757        screening_type = datamodel.get('screening_type',None)
1758        if not screening_type:
1759            screening_type = self.REQUEST.form.get('screening_type','pume')
1760        datastructure["screening_type"] = screening_type
1761        datastructure[widget_id] = file_name
1762        datastructure[widget_id + '_choice'] = 'change'
1763        title = 'Passport Foto'
1764        datastructure[widget_id + '_filename'] = title
1765    ###)
1766
1767    def validate(self, datastructure, **kw): ###(
1768        """Update datamodel from user data in datastructure.
1769        """
1770        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1771        datamodel = datastructure.getDataModel()
1772        field_id = self.fields[0]
1773        widget_id = self.getWidgetId()
1774        store = False
1775        fileupload = None
1776        mimetype = None
1777        old_file = datamodel[field_id]
1778        # if old_file is not None:
1779        #     old_filename = old_file.title
1780        # else:
1781        #     old_filename = ''
1782        choice = datastructure[widget_id+'_choice']
1783        fileupload = datastructure[widget_id]
1784        is_upload = isinstance(fileupload, FileUpload)
1785        #import pdb; pdb.set_trace()
1786        if not is_upload and not datamodel[field_id]:
1787            if self.is_required:
1788                return self.validateError('Picture upload required', {},
1789                                          datastructure)
1790        if choice == 'delete':
1791            if self.is_required:
1792                return self.validateError('cpsschemas_err_required', {},
1793                                          datastructure)
1794            datamodel[field_id] = None
1795        elif choice == 'keep':
1796            fileupload = datastructure[widget_id]
1797            if isinstance(fileupload, PersistableFileUpload):
1798                # Keeping something from the session means we
1799                # actually want to store it.
1800                store = True
1801            # else:
1802            #     # Nothing to change, don't pollute datastructure
1803            #     # with something costly already stored, which therefore
1804            #     # doesn't need to be kept in the session.
1805            #     self.unprepare(datastructure)
1806        elif choice == 'change' and is_upload:
1807            if not fileupload:
1808                return self.validateError('cpsschemas_err_file_empty', {},
1809                                          datastructure)
1810            if not isinstance(fileupload, FileUpload):
1811                return self.validateError('cpsschemas_err_file', {},
1812                                          datastructure)
1813            fileupload.seek(0, 2) # end of file
1814            size = fileupload.tell()
1815            if not size:
1816                return self.validateError('cpsschemas_err_file_empty', {},
1817                                          datastructure)
1818            if self.size_max and size > self.size_max:
1819                max_size_str = self.getHumanReadableSize(self.size_max)
1820                err = 'This file is too big, the allowed max size is ${max_size}'
1821                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1822                err_mapping = {'max_size': max_size_str}
1823                return self.validateError(err, err_mapping, datastructure)
1824            store = True
1825
1826
1827        # Find filename
1828        if is_upload and store:
1829            ext ='jpg'
1830            screening_type = datastructure.get('screening_type')
1831            filename = "%s_%s.%s" % (datastructure[self.id_field],
1832                                     self.getWidgetId(),
1833                                     ext)
1834            datamodel[field_id] = filename
1835            registry = getToolByName(self, 'mimetypes_registry')
1836            mimetype = registry.lookupExtension(filename.lower())
1837            if mimetype is not None:
1838                mimetype = str(mimetype) # normalize
1839            file = self.makeFile(filename, fileupload, datastructure)
1840            # Fixup mimetype
1841            if mimetype and file.content_type != mimetype:
1842                file.content_type = mimetype
1843            # Store the file in the filesystem
1844            #import pdb;pdb.set_trace()
1845            base_path = os.path.join(self.storage_path, screening_type)
1846            if not os.path.exists(base_path):
1847                os.mkdir(base_path)
1848            full_path = os.path.join(base_path, filename)
1849            pict = open(full_path,"w")
1850            fileupload.seek(0)
1851            pict.write(fileupload.read())
1852            pict.close()
1853
1854
1855        return True
1856
1857###)
1858
1859    def render(self, mode, datastructure, **kw): ###(
1860        render_method = 'widget_passport_render'
1861        meth = getattr(self, render_method, None)
1862        if meth is None:
1863            raise RuntimeError("Unknown Render Method %s for widget type %s"
1864                               % (render_method, self.getId()))
1865        img_info = self.getImageInfo(datastructure)
1866        return meth(mode=mode, datastructure=datastructure, **img_info)
1867    ###)
1868
1869InitializeClass(ApplicationImageWidget)
1870
1871widgetRegistry.register(ApplicationImageWidget)
1872###)
1873
1874class FileImageWidget(CPSImageWidget): ###(
1875    """Image widget with filesystem storage."""
1876    meta_type = 'File Image Widget'
1877    _properties = CPSImageWidget._properties +\
1878    (
1879     {'id': 'path', 'type': 'string', 'mode': 'w',
1880      'label': 'Relative Path'},
1881     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1882      'label': 'Field to build the id'},
1883     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
1884      'label': 'Show Image'},
1885    )
1886    path = "images"
1887    #storage_path = "%s/%s" % (i_home,path)
1888    id_field = ""
1889    show_image = False
1890
1891    def getStorageImageInfo(self,field_id):
1892        info = {}
1893        if self.id_field == "":
1894            student_id = self.getStudentId()
1895        else:
1896            student_id = datastructure[self.id_field]
1897        # student_path = os.path.join(self.storage_path,
1898        #                             student_id)
1899        student_path = getImagesDir(student_id)
1900        image_name = ''
1901        content_url = ''
1902        current_filename = ''
1903        if os.path.exists(student_path):
1904            for name in os.listdir(student_path):
1905                if name.startswith(field_id):
1906                    image_name = name
1907                    break
1908        if image_name:
1909            info['image_name'] = image_name
1910            info['content_url'] = os.path.join(self.portal_url(),
1911                                               "viewimage",
1912                                               student_id,
1913                                               image_name,
1914                                              )
1915            info['current_filename'] =  image_name
1916            info['file_path'] = os.path.join(student_path, image_name)
1917        return info
1918
1919    def getImageInfo(self, datastructure): ###(
1920        """Get the file info from the datastructure."""
1921        widget_id = self.getWidgetId()
1922        if  datastructure.has_key(widget_id):
1923            fileupload = datastructure[widget_id]
1924            dm = datastructure.getDataModel()
1925            field_id = self.fields[0]
1926            info = self.getStorageImageInfo(field_id)
1927        else:
1928            file_path = "XXX"
1929            title = ""
1930        # read the file from the filesystem
1931        #import pdb; pdb.set_trace()
1932        #if not os.path.exists(file_path):
1933        if not info:
1934            title = ""
1935            height = -1
1936            width = -1
1937            empty_file = True
1938            session_file = False
1939            current_filename = ''
1940            content_url = ''
1941            size = 0
1942            mimetype = ''
1943            last_modified = ''
1944            height = ''
1945            width = ''
1946        else:
1947            title = info['image_name']
1948            current_filename = info['current_filename']
1949            content_url = info['content_url']
1950            image = open(info['file_path'])
1951            from OFS.Image import getImageInfo as getImageInfoOFS
1952            image.seek(0)
1953            data = image.read(2000)
1954            size = len(data)
1955            empty_file = size == 0
1956            session_file = False
1957            last_modified = ''
1958            image.close()
1959            mimetype, width, height = getImageInfoOFS(data)
1960            registry = getToolByName(self, 'mimetypes_registry')
1961            mimetype = (registry.lookupExtension(current_filename.lower()) or
1962                        registry.lookupExtension('file.bin'))
1963            if width < 0:
1964                width = None
1965            if height < 0:
1966                height = None
1967
1968            if (self.allow_resize
1969                and height is not None
1970                and width  is not None):
1971                z_w = z_h = 1
1972                h = int(self.display_height)
1973                w = int(self.display_width)
1974                if w and h:
1975                    if w < width:
1976                        z_w = w / float(width)
1977                    if h < height:
1978                        z_h = h / float(height)
1979                    zoom = min(z_w, z_h)
1980                    width = int(zoom * width)
1981                    height = int(zoom * height)
1982                #import pdb;pdb.set_trace()
1983        image_info = {
1984            'empty_file': empty_file,
1985            'session_file': session_file,
1986            'current_filename': title,
1987            'size': size,
1988            'last_modified': last_modified,
1989            'content_url': content_url,
1990            'mimetype': mimetype,
1991            }
1992        alt = title or ''
1993        #height = int(self.display_height)
1994        #width = int(self.display_width)
1995        if height is None or width is None:
1996            tag = renderHtmlTag('img', src=image_info['content_url'],
1997                                alt=alt, title=title)
1998        else:
1999            tag = renderHtmlTag('img', src=image_info['content_url'],
2000                                width=str(width), height=str(height),
2001                                alt=alt, title=title)
2002
2003        image_info['height'] = height
2004        image_info['width'] = width
2005        image_info['image_tag'] = tag
2006        image_info['show_image'] = self.show_image
2007        return image_info
2008    ###)
2009
2010    # def checkFileName(self, filename, mimetype):
2011    #     return '', {}
2012    #     if mimetype and mimetype.startswith('image'):
2013    #         return '', {}
2014    #     return 'cpsschemas_err_image', {}
2015
2016    def prepare(self, datastructure, **kw): ###(
2017        """Prepare datastructure from datamodel."""
2018        datamodel = datastructure.getDataModel()
2019        widget_id = self.getWidgetId()
2020        file_name = datamodel[self.fields[0]]
2021        if self.id_field == "":
2022            student_id = self.getStudentId()
2023        else:
2024            student_id = datastructure[self.id_field]
2025        if student_id is not None:
2026            # student_path = os.path.join(self.storage_path,
2027            #                             student_id)
2028            student_path = getImagesDir(student_id)
2029            if not os.path.exists(student_path):
2030                self.waeup_tool.moveImagesToFS(student_id)
2031        if self.allow_resize:
2032            datastructure[self.getWidgetId() + '_resize'] = ''
2033        datastructure[widget_id] = file_name
2034        datastructure[widget_id + '_choice'] = 'change'
2035        title = 'Passport Foto'
2036        datastructure[widget_id + '_filename'] = title
2037    ###)
2038
2039    def validate(self, datastructure, **kw): ###(
2040        """Update datamodel from user data in datastructure.
2041        """
2042        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2043        datamodel = datastructure.getDataModel()
2044        field_id = self.fields[0]
2045        widget_id = self.getWidgetId()
2046        store = False
2047        fileupload = None
2048        mimetype = None
2049        old_file = datamodel[field_id]
2050        choice = datastructure[widget_id+'_choice']
2051        fileupload = datastructure[widget_id]
2052        is_upload = isinstance(fileupload, FileUpload)
2053        #import pdb; pdb.set_trace()
2054        if not is_upload and not datamodel[field_id]:
2055            if self.is_required:
2056                return self.validateError('Picture upload required', {},
2057                                          datastructure)
2058        if self.id_field == "":
2059            student_id = self.getStudentId()
2060        else:
2061            student_id = datastructure[self.id_field]
2062        if choice == 'delete':
2063            if self.is_required:
2064                return self.validateError('cpsschemas_err_required', {},
2065                                          datastructure)
2066            info= self.getStorageImageInfo(field_id)
2067            # Remove the file in the filesystem
2068            if info:
2069                os.remove(info['file_path'])
2070            datamodel[field_id] = None
2071        elif choice == 'keep':
2072            fileupload = datastructure[widget_id]
2073            if isinstance(fileupload, PersistableFileUpload):
2074                # Keeping something from the session means we
2075                # actually want to store it.
2076                store = True
2077            # else:
2078            #     # Nothing to change, don't pollute datastructure
2079            #     # with something costly already stored, which therefore
2080            #     # doesn't need to be kept in the session.
2081            #     self.unprepare(datastructure)
2082        elif choice == 'change' and is_upload:
2083            if not fileupload:
2084                return self.validateError('cpsschemas_err_file_empty', {},
2085                                          datastructure)
2086            if not isinstance(fileupload, FileUpload):
2087                return self.validateError('cpsschemas_err_file', {},
2088                                          datastructure)
2089            fileupload.seek(0, 2) # end of file
2090            size = fileupload.tell()
2091            if not size:
2092                return self.validateError('cpsschemas_err_file_empty', {},
2093                                          datastructure)
2094            if self.size_max and size > self.size_max:
2095                max_size_str = self.getHumanReadableSize(self.size_max)
2096                err = 'This file is too big, the allowed max size is ${max_size}'
2097                member_id = str(self.portal_membership.getAuthenticatedMember())
2098                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2099                err_mapping = {'max_size': max_size_str}
2100                return self.validateError(err, err_mapping, datastructure)
2101            store = True
2102
2103
2104        # Find filename
2105        if is_upload and store:
2106            filename = cookId('', '', fileupload)[0].strip()
2107            base,ext = os.path.splitext(filename)
2108            filename = "%s_%s%s" % (field_id,
2109                                    student_id,
2110                                    ext)
2111            datamodel[field_id] = filename
2112            registry = getToolByName(self, 'mimetypes_registry')
2113            mimetype = registry.lookupExtension(filename.lower())
2114            if mimetype is not None:
2115                mimetype = str(mimetype) # normalize
2116            file = self.makeFile(filename, fileupload, datastructure)
2117            # Fixup mimetype
2118            if mimetype and file.content_type != mimetype:
2119                file.content_type = mimetype
2120            # Store the file in the filesystem
2121            #student_path = os.path.join(self.storage_path,student_id)
2122            student_path = getImagesDir(student_id)
2123            if not os.path.exists(student_path):
2124                os.mkdir(student_path)
2125            full_path = os.path.join(student_path, filename)
2126            pict = open(full_path,"w")
2127            #fileupload.seek(0)
2128            #import pdb; pdb.set_trace()
2129            pict.write(str(file.data))
2130            pict.close()
2131        return True
2132    ###)
2133
2134    def render(self, mode, datastructure, **kw): ###(
2135        render_method = 'widget_image_render'
2136        meth = getattr(self, render_method, None)
2137        #import pdb;pdb.set_trace()
2138        if meth is None:
2139            raise RuntimeError("Unknown Render Method %s for widget type %s"
2140                               % (render_method, self.getId()))
2141        img_info = self.getImageInfo(datastructure)
2142        return meth(mode=mode, datastructure=datastructure, **img_info)
2143    ###)
2144
2145InitializeClass(FileImageWidget)
2146
2147widgetRegistry.register(FileImageWidget)
2148###)
2149
2150###########
2151
Note: See TracBrowser for help on using the repository browser.