source: WAeUP_SRP/base/Widgets.py @ 3371

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

JambRegNo? Widget: pume in datastructure needed

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