source: WAeUP_SRP/base/Widgets.py @ 3359

Last change on this file since 3359 was 3355, checked in by joachim, 17 years ago

fix for #111 fceokene

  • Property svn:keywords set to Id
File size: 88.3 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 3355 2008-03-19 15:20:40Z joachim $
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            pume = reg_no_catalog(jamb_reg_no = value)
801            if len(pume) < 1:
802                err = 'No student record with this registration number'
803            else:
804                datastructure['pume'] = pume[0]
805        elif mode == 'add':
806            pass
807        elif self.reference != '' and self.catalog == "applicants_catalog":
808            res = reg_no_catalog.searchResults({"%s" % self.reference: value})
809            if len(res) != 1:
810                err = 'No record with this registration number'
811            else:
812                datastructure['record'] = res[0]
813        else:
814            record = datastructure[self.reference]
815            #jamb_reg_no = getattr(record,widget_id)
816            jamb_reg_no = record.Entryregno
817            if jamb_reg_no != value:
818                err = 'Registration number does not match.'
819        if err:
820            datastructure.setError(widget_id, err)
821        else:
822            datamodel = datastructure.getDataModel()
823            datamodel[self.fields[0]] = value
824        return not err
825
826InitializeClass(JambRegNoWidget)
827
828widgetRegistry.register(JambRegNoWidget)
829###)
830
831class SecretWidget(CPSStringWidget): ###(
832    """ Secret Widget"""
833    meta_type = "Secret Widget"
834    _properties = CPSStringWidget._properties + (
835        {'id': 'reference', 'type': 'string', 'mode': 'w',
836         'label': 'Reference Record'},
837         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
838         'label': 'Fields to check'},
839         )
840    reference = "student"
841    matric_no_catalog = 'returning_import'
842    check_fields = ("Firstname", "Middlename","Lastname")
843    def validate(self, datastructure, **kw):
844        """Validate datastructure and update datamodel."""
845        logger = logging.getLogger('Widgets.SecretWidget.validate')
846        valid = CPSStringWidget.validate(self, datastructure, **kw)
847        widget_id = self.getWidgetId()
848        value = datastructure[widget_id].upper()
849        err = 0
850        record = datastructure.get(self.reference,None)
851        #import pdb;pdb.set_trace()
852        if not valid or len(value) < 2:
853            err = 'Invalid string'
854        elif not record or datastructure.errors:
855            err = 0
856        else:
857            found = False
858            cvs = []
859            for field in self.check_fields:
860                cv = getattr(record,field).upper()
861                if len(cv.split()) > 1:
862                    for splited in cv.split():
863                        cvs.append(splited.strip())
864                else:
865                    cvs.append(cv.strip(),)
866            for cv in cvs:
867                if cv  == value.strip().upper():
868                    found = True
869                    break
870            matric_no = record.matric_no
871            name = " ".join(cvs)
872            if not found:
873                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
874                err = 'No name does match.'
875            else:
876                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
877        if err:
878            datastructure.setError(widget_id, err)
879        else:
880            datamodel = datastructure.getDataModel()
881            datamodel[self.fields[0]] = value
882        return not err
883
884InitializeClass(SecretWidget)
885
886widgetRegistry.register(SecretWidget)
887###)
888
889class WAeUPSexWidget(CPSBooleanWidget): ###(
890    """WAeUP sex widget."""
891    meta_type = 'WAeUP Sex Widget'
892
893    def validate(self, datastructure, **kw):
894        """Validate datastructure and update datamodel."""
895        value = datastructure[self.getWidgetId()]
896
897        if self.render_format not in self.render_formats:
898            self.render_format = 'select'
899
900        female = value in ('F','f','Female','female',"True",True)
901        male = value in ('M','m','Male','male','False',False)
902        if not female and not male:
903            datastructure.setError(self.getWidgetId(),
904                                   "invalid sex %s" % value)
905            return 0
906        elif female:
907            v = True
908        else:
909            v = False
910        datamodel = datastructure.getDataModel()
911        datamodel[self.fields[0]] = v
912        return 1
913
914InitializeClass(WAeUPSexWidget)
915
916widgetRegistry.register(WAeUPSexWidget)
917
918###)
919
920class MatricNoWidget(CPSStringWidget): ###(
921    """ MatricNo Widget"""
922    meta_type = "MatricNo Widget"
923
924    _properties = CPSStringWidget._properties + (
925        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
926         'label': 'Catalog to search for MatricNo'},
927        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
928         'label': 'Results Catalog'},
929         )
930    matric_no_catalog = "" #the catalog to search for matric_no
931    results_catalog = "results_import" #results catalog
932
933    def validate(self, datastructure, **kw):
934        """Validate datastructure and update datamodel."""
935        #import pdb;pdb.set_trace()
936        valid = CPSStringWidget.validate(self, datastructure, **kw)
937        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
938        returning = getattr(self,self.matric_no_catalog)
939        results = getattr(self,self.results_catalog,None)
940        err = 0
941        widget_id = self.getWidgetId()
942        value = datastructure[widget_id]
943        if not valid or not value:
944            err = 'Invalid string'
945            logger.info('Invalid matric_no string %s' % value)
946        else:
947            value = value.upper()
948            datastructure['student'] = None
949            while not err:
950                res = returning(matric_no = value)
951                if len(res) < 1:
952                    logger.info('matric_no %s not found' % value)
953                    err = 'No student with this matriculation number.'
954                    break
955                datastructure['student'] = res[0]
956                if results is not None:
957                    res = results(matric_no = value)
958                    if len(res) < 1:
959                        err = 'No results for this matriculation number'
960                        continue
961                    datastructure['results'] = res
962                break
963        if err:
964            datastructure.setError(widget_id, err)
965        else:
966            datamodel = datastructure.getDataModel()
967            datamodel[self.fields[0]] = value
968        return not err
969
970InitializeClass(MatricNoWidget)
971
972widgetRegistry.register(MatricNoWidget)
973###)
974
975class StudentIdWidget(CPSStringWidget): ###(
976    """ StudentId Widget"""
977    meta_type = "StudentId Widget"
978    def validate(self, datastructure, **kw):
979        """Validate datastructure and update datamodel."""
980        valid = CPSStringWidget.validate(self, datastructure, **kw)
981        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
982        #import pdb;pdb.set_trace()
983        s_cat = self.students_catalog
984        err = 0
985        widget_id = self.getWidgetId()
986        value = datastructure[widget_id]
987        if not valid or not value:
988            err = 'Invalid Id string'
989            logger.info('Invalid id string %s' % value)
990            datastructure['student'] = None
991        else:
992            value = value.upper()
993            res = s_cat(id = value)
994            if not res:
995                logger.info('Student id %s not found' % value)
996                err = 'No student with this Id'
997                datastructure['student'] = None
998            else:
999                datastructure['student'] = res[0]
1000        if err:
1001            datastructure.setError(widget_id, err)
1002        else:
1003            datamodel = datastructure.getDataModel()
1004            datamodel[self.fields[0]] = value
1005        return not err
1006
1007InitializeClass(StudentIdWidget)
1008
1009widgetRegistry.register(StudentIdWidget)
1010###)
1011
1012class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
1013    """ WAeUPMultilineResults Widget"""
1014    meta_type = "WAeUp Multiline Results Widget"
1015    _properties = CPSWidget._properties + (
1016        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
1017         'label': 'Nr of Lines'},
1018         )
1019    nr_of_lines = 5
1020    def prepare(self, datastructure, **kw): ###(
1021        """Prepare datastructure from datamodel."""
1022        datamodel = datastructure.getDataModel()
1023        #import pdb;pdb.set_trace()
1024        widget_id = self.getWidgetId()
1025        v = datamodel[self.fields[0]]
1026        if type(v) is ListType and v:
1027            nr_results = len(v)
1028        else:
1029            v = []
1030            nr_results = 0
1031        count = 1
1032        for s,g in v:
1033            wid = "%s%02d"% (widget_id,count)
1034            datastructure[wid+'_s'] = s
1035            datastructure[wid+'_g'] = g
1036            count += 1
1037        if nr_results < self.nr_of_lines:
1038            for line in range(nr_results,self.nr_of_lines):
1039                v.append(('',''))
1040                wid = "%s%02d"% (widget_id,line)
1041                datastructure[wid+'_s'] = ''
1042                datastructure[wid+'_g'] = ''
1043        datastructure[widget_id] = v
1044        datastructure[widget_id+'_s'] = ''
1045        datastructure[widget_id+'_g'] = ''
1046    ###)
1047
1048    def validate(self, datastructure, **kw): ###(
1049        """Validate datastructure and update datamodel."""
1050        #import pdb;pdb.set_trace()
1051        widget_id = self.getWidgetId()
1052        err = 0
1053        lines = []
1054        for line in range(1,30):
1055            wid = "%s%02d"% (widget_id,line)
1056            if not datastructure.has_key(wid+'_s'):
1057                break
1058            lines.append((datastructure[wid+'_s'].strip(),
1059                         datastructure[wid+'_g'].strip()))
1060
1061        s = datastructure[widget_id+'_s'].strip()
1062        g = datastructure[widget_id+'_g'].strip()
1063        if s and g:
1064            lines.append((s,g))
1065        active = []
1066        for s,g in lines:
1067            if g != "":
1068                active.append((s,g))
1069        if err:
1070            datastructure.setError(widget_id, err)
1071        else:
1072            datamodel = datastructure.getDataModel()
1073            datamodel[self.fields[0]] = active
1074        return not err
1075    ###)
1076
1077    def render(self, mode, datastructure, **kw): ###(
1078        """Render in mode from datastructure."""
1079        render_method = 'widget_waeup_multiline_result_render'
1080        meth = getattr(self, render_method, None)
1081        if meth is None:
1082            raise RuntimeError("Unknown Render Method %s for widget type %s"
1083                               % (render_method, self.getId()))
1084        #import pdb;pdb.set_trace()
1085        datamodel = datastructure.getDataModel()
1086        widget_id = self.getWidgetId()
1087        lines = datamodel[self.fields[0]]
1088        if len(lines) < self.nr_of_lines:
1089            for line in range(len(lines),self.nr_of_lines + 1):
1090                lines.append(('',''))
1091        datastructure[widget_id] = lines
1092        datastructure[widget_id+'_s'] = ''
1093        datastructure[widget_id+'_g'] = ''
1094##        count = 1
1095##        for s,g in v:
1096##            wid = "%s%02d"% (widget_id,count)
1097##            count += 1
1098        return meth(mode=mode,
1099                    datastructure=datastructure,
1100                    )
1101    ###)
1102
1103
1104InitializeClass(WAeUPMultilineResultsWidget)
1105widgetRegistry.register(WAeUPMultilineResultsWidget)
1106###)
1107
1108class WAeUPResultsWidget(CPSStringWidget): ###(
1109    """ WAeUPResults Widget"""
1110    meta_type = "WAeUp Results Widget"
1111
1112    def prepare(self, datastructure, **kw): ###(
1113        """Prepare datastructure from datamodel."""
1114        datamodel = datastructure.getDataModel()
1115        v = datamodel[self.fields[0]]
1116        #import pdb;pdb.set_trace()
1117        widget_id = self.getWidgetId()
1118        datastructure[widget_id] = v
1119        datastructure[widget_id+'_s'] = ''
1120        datastructure[widget_id+'_g'] = ''
1121    ###)
1122
1123    def validate(self, datastructure, **kw): ###(
1124        """Validate datastructure and update datamodel."""
1125        #import pdb;pdb.set_trace()
1126        widget_id = self.getWidgetId()
1127        v = datastructure[widget_id]
1128        if not v:
1129            v = []
1130        err = 0
1131        s = datastructure[widget_id+'_s'].strip()
1132        g = datastructure[widget_id+'_g'].strip()
1133        while 1:
1134            if not s and g:
1135                err = "No subject grade for subject"
1136                break
1137            i = 0
1138            done = False
1139            #import pdb;pdb.set_trace()
1140            for sv,gv in v:
1141                if sv == s:
1142                    done = True
1143                    if not g:
1144                        v.pop(i)
1145                        break
1146                    v[i] = (s,g)
1147                    break
1148                i += 1
1149            if done:
1150                break
1151            if s and g:
1152                if v:
1153                    v += (s,g),
1154                else:
1155                    v = [(s,g),]
1156            break
1157        if err:
1158            datastructure.setError(widget_id, err)
1159        else:
1160            datamodel = datastructure.getDataModel()
1161            datamodel[self.fields[0]] = v
1162            datastructure[widget_id] = v
1163            datastructure[widget_id+'_s'] = s
1164            datastructure[widget_id+'_g'] = g
1165        return not err
1166    ###)
1167
1168    def render(self, mode, datastructure, **kw): ###(
1169        """Render in mode from datastructure."""
1170        render_method = 'widget_waeup_result_render'
1171        meth = getattr(self, render_method, None)
1172        if meth is None:
1173            raise RuntimeError("Unknown Render Method %s for widget type %s"
1174                               % (render_method, self.getId()))
1175        datamodel = datastructure.getDataModel()
1176        widget_id = self.getWidgetId()
1177        datastructure[widget_id+'_s'] = ''
1178        datastructure[widget_id+'_g'] = ''
1179        return meth(mode=mode,
1180                    datastructure=datastructure,
1181                    )
1182    ###)
1183
1184
1185InitializeClass(WAeUPResultsWidget)
1186widgetRegistry.register(WAeUPResultsWidget)
1187###)
1188
1189class ScratchCardPin: ###(
1190    """the ScratchCardPin"""
1191    def __init__(self,prefix,batch_no,number):
1192        if not batch_no and not number:
1193            s = prefix
1194            if len(s) > 3:
1195                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1196            else:
1197                prefix,batch_no,number = s,'',''
1198        self.p = prefix
1199        self.b = batch_no
1200        self.n = number
1201
1202    def __str__(self):
1203        return "%s-%s-%s" % (self.p,self.b,self.n)
1204
1205    def __repr__(self):
1206        return "%s%s%s" % (self.p,self.b,self.n)
1207###)
1208
1209class ScratchcardPinWidget(CPSStringWidget): ###(
1210    """ ScratchcardPin Widget"""
1211    meta_type = "Scratchcard Pin Widget"
1212    _properties = CPSWidget._properties + (
1213        {'id': 'prefix', 'type': 'string', 'mode': 'w',
1214         'label': 'Prefix'},
1215         {'id': 'reference', 'type': 'string', 'mode': 'w',
1216         'label': 'Reference Field'},
1217         {'id': 'reuse_pin', 'type': 'boolean', 'mode': 'w',
1218         'label': 'Reuse Application Pin'},
1219        )
1220    prefix = ''
1221    reference = ''
1222    reuse_pin = False
1223
1224    def prepare(self, datastructure, **kw): ###(
1225        """Prepare datastructure from datamodel."""
1226        datamodel = datastructure.getDataModel()
1227        v = datamodel[self.fields[0]]
1228        widget_id = self.getWidgetId()
1229        if v and type(v) is StringType:
1230            try:
1231                p,b,n = v.split('-')
1232                v = ScratchCardPin(p,b,n)
1233            except ValueError:
1234                v = ScratchCardPin(v,'','')
1235        if v:
1236            p = '%s' % v.p
1237            b = '%s' % v.b
1238            n = '%s' % v.n
1239        else:
1240            p = self.prefix
1241            if p.startswith('@'):
1242                p = getattr(self,self.prefix[1:])()
1243            b = n = ''
1244            v = ScratchCardPin(p,b,n)
1245        datastructure[widget_id] = v
1246        datastructure[widget_id+'_p'] = p
1247        datastructure[widget_id+'_b'] = b
1248        datastructure[widget_id+'_n'] = n
1249    ###)
1250
1251    def validate(self, datastructure, **kw): ###(
1252        """Validate datastructure and update datamodel."""
1253        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1254        widget_id = self.getWidgetId()
1255        v = datastructure[widget_id]
1256        #import pdb;pdb.set_trace()
1257        err = 0
1258        mapping = {}
1259        prefix= self.prefix
1260        if prefix.startswith('@'):
1261            prefix= getattr(self,self.prefix[1:])()
1262        b = datastructure[widget_id+'_b'].strip()
1263        n = datastructure[widget_id+'_n'].strip()
1264        pins = self.portal_pins
1265        pin = "%(prefix)s%(b)s%(n)s" % vars()
1266        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1267        do = 1
1268        s_id = str(self.portal_membership.getAuthenticatedMember())
1269        if self.isStaff():
1270            do = 0
1271            err ='You are not a Student. PIN neither checked nor used.'
1272            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1273        elif len(b) > 1 and b.find('-') > -1:
1274            do = 0
1275            err = 'PIN must not contain "-".'
1276            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1277        elif n.find('-') > -1:
1278            do = 0
1279            err = 'PIN must not contain "-".'
1280            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1281        elif len(n) != 10:
1282            do = 0
1283            err = 'Invalid PIN length'
1284            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1285        elif self.reference == "":
1286            ref = s_id
1287        else:
1288            ref = datastructure[self.reference]
1289            if datastructure.errors:
1290                do = 0
1291                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1292                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1293            elif prefix == 'APP' and not self.reuse_pin:
1294                res =  self.applicants_catalog(reg_no = ref)
1295                if not res:
1296                    res =  self.applicants_catalog(reg_no = ref.upper())
1297                if res and res[0].pin == pin_str:
1298                    do = 0
1299                    err = 'Application PINs cannot be reused.'
1300                    s_logger.info('%s entered same PIN as for screening application %s' % (s_id,pin_str))
1301
1302        while do:
1303            ok,record = pins.searchAndSetRecord(pin,ref,prefix)
1304            if ok < -2 or ok > 2:
1305                err = 'Unknown error, please report!'
1306                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1307                break
1308            elif ok == -2:
1309                err = 'Service already is activated but with a different PIN.'
1310                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1311                break
1312            elif ok == -1:
1313                err = 'Invalid PIN'
1314                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1315                break
1316            if ok == 0:
1317                err = 'PIN already used'
1318                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1319                break
1320            if ok >= 1:
1321                #import pdb;pdb.set_trace()
1322                if self.isStudent():
1323                    if self.reference == "jamb_reg_no":
1324                        err = "You are already logged in."
1325                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1326                        break
1327                    if ok == 1:
1328                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1329                    else:
1330                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1331                    break
1332                else:
1333                    student = getStudentByRegNo(self,ref)
1334                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1335                if student is None:
1336                    err = "Student record not found."
1337                    s_logger.info('%s not found in admission list' % (ref))
1338                    break
1339                s_id = student.getId()
1340                if ok == 2:
1341                    if self.reference == "jamb_reg_no":
1342                        if hasattr(self.portal_directories.students,s_id):
1343                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1344                            mapping = {'id': s_id}
1345                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1346                            break
1347                        else:
1348                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1349                    else:
1350                        err = "Unknown error"
1351                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1352                        break
1353                try:
1354                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1355                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1356                except:
1357                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1358                    mapping = {'id': s_id}
1359                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1360                    break
1361            break
1362        if err:
1363            datastructure.setError(widget_id, err,mapping)
1364        else:
1365            datamodel = datastructure.getDataModel()
1366            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1367            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1368            datastructure[widget_id+'_p'] = prefix
1369            datastructure[widget_id+'_b'] = b
1370            datastructure[widget_id+'_n'] = n
1371            datastructure['s_id'] = s_id
1372        return not err
1373
1374###)
1375
1376    def render(self, mode, datastructure, **kw): ###(
1377        """Render in mode from datastructure."""
1378        render_method = 'widget_scratch_card_pin_render'
1379        meth = getattr(self, render_method, None)
1380        if meth is None:
1381            raise RuntimeError("Unknown Render Method %s for widget type %s"
1382                               % (render_method, self.getId()))
1383
1384        # XXX AT: datastructure has to be set again here, in case we're in edit
1385        # or create mode, because a default value has to be provided.
1386        #import pdb;pdb.set_trace()
1387        datamodel = datastructure.getDataModel()
1388        v = datamodel[self.fields[0]]
1389        if v and type(v) is StringType:
1390            try:
1391                p,b,n = v.split('-')
1392                v = ScratchCardPin(p,b,n)
1393            except ValueError:
1394                v = ScratchCardPin(self.prefix,'XXX',v)
1395                pass
1396        if v:
1397            prefix= '%s' % v.p
1398            b = '%s' % v.b
1399            n = '%s' % v.n
1400        else:
1401            prefix= self.prefix
1402            if prefix.startswith('@'):
1403                prefix= getattr(self,self.prefix[1:])()
1404            b = n = ''
1405            v = ScratchCardPin(prefix,b,n)
1406        widget_id = self.getWidgetId()
1407        datastructure[widget_id] = v
1408        datastructure[widget_id+'_p'] = prefix
1409        datastructure[widget_id+'_b'] = b
1410        datastructure[widget_id+'_n'] = n
1411        return meth(mode=mode,
1412                    datastructure=datastructure,
1413                    )
1414    ###)
1415
1416InitializeClass(ScratchcardPinWidget)
1417widgetRegistry.register(ScratchcardPinWidget)
1418###)
1419
1420class PumePinWidget(ScratchcardPinWidget): ###(
1421    """ Pume Pin Widget"""
1422    meta_type = "Pume Pin Widget"
1423    catalog = "applicants_catalog"
1424    reference = ''
1425
1426    def prepare(self, datastructure, **kw): ###(
1427        """Prepare datastructure from datamodel."""
1428        datamodel = datastructure.getDataModel()
1429        #import pdb;pdb.set_trace()
1430        v = datamodel[self.fields[0]]
1431        widget_id = self.getWidgetId()
1432        if v and type(v) is StringType:
1433            try:
1434                p,b,n = v.split('-')
1435                v = ScratchCardPin(p,b,n)
1436            except ValueError:
1437                v = ScratchCardPin(v,'','')
1438        if v:
1439            p = '%s' % v.p
1440            b = '%s' % v.b
1441            n = '%s' % v.n
1442        else:
1443            p = self.prefix
1444            if p.startswith('@'):
1445                p = getattr(self,self.prefix[1:])()
1446            b = n = ''
1447            v = ScratchCardPin(p,b,n)
1448        datastructure[widget_id] = v
1449        datastructure[widget_id+'_p'] = p
1450        datastructure[widget_id+'_b'] = b
1451        datastructure[widget_id+'_n'] = n
1452    ###)
1453
1454    def validate(self, datastructure, **kw): ###(
1455        """Validate datastructure and update datamodel."""
1456        s_logger = logging.getLogger('Widgets.PumePinWidget.validate')
1457        widget_id = self.getWidgetId()
1458        v = datastructure[widget_id]
1459        err = 0
1460        mapping = {}
1461        prefix= self.prefix
1462        if prefix.startswith('@'):
1463            prefix= getattr(self,self.prefix[1:])()
1464        b = datastructure[widget_id+'_b'].strip()
1465        n = datastructure[widget_id+'_n'].strip()
1466        pins = self.portal_pins
1467        pin = "%(prefix)s%(b)s%(n)s" % vars()
1468        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1469        member_id = str(self.portal_membership.getAuthenticatedMember())
1470        do = 1
1471        if self.isStaff():
1472            do = 0
1473            err ='You are logged in, please log out. PIN neither checked nor used.'
1474            s_logger.info('%s tried to use scratch card %s' % (member_id,pin_str))
1475        elif self.isStudent():
1476            do = 0
1477            #ref = datastructure[self.reference]
1478            err ='You are logged in, please log out. PIN neither checked nor used.'
1479            s_logger.info('%s applied for screening test while logged in with pin %s' % (member_id,pin_str))
1480        elif len(b) > 1 and b.find('-') > -1:
1481            do = 0
1482            err = 'PIN must not contain "-"'
1483            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1484        elif n.find('-') > -1:
1485            do = 0
1486            err = 'PIN must not contain "-"'
1487            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1488        elif len(n) != 10:
1489            do = 0
1490            err = 'Invalid PIN length'
1491            s_logger.info('%s entered invalid PIN with length %d' % (member_id,len(n)))
1492        elif self.reference == "":
1493            ref = n
1494        else:
1495            ref = datastructure[self.reference]
1496            if datastructure.errors:
1497                do = 0
1498                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1499                s_logger.info('%s/%s entered wrong data together with PIN %s' % (member_id,ref,pin_str))
1500        while do:
1501            ok,pin_record = pins.searchAndSetRecord(pin,ref,prefix)
1502            if ok < -2 or ok > 2:
1503                err = 'Unknown error, please report!'
1504                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
1505                break
1506            elif ok == -2:
1507                err = 'Service is already activated but with a different PIN.'
1508                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
1509                break
1510            elif ok == -1:
1511                err = 'Invalid PIN'
1512                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
1513                break
1514            if ok == 0:
1515                err = 'PIN already used'
1516                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
1517                break
1518            if ok >= 1:
1519                #screening_type = self.REQUEST.form.get('screening_type','unknown')
1520                #screening_type = datastructure['screening_type']
1521                if self.REQUEST.traverse_subpath:
1522                    screening_type_request = self.REQUEST.traverse_subpath[0]
1523                else:
1524                    screening_type_request = 'manage'
1525
1526                if datastructure.has_key('record'):
1527                    applicant = datastructure['record']
1528                    if applicant.screening_type != screening_type_request\
1529                          and screening_type_request != 'manage':
1530                        err = "You are using the wrong access form!"
1531                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1532                        break
1533                    if not applicant.pin:
1534                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1535                        d = {}
1536                        d['reg_no'] = applicant.reg_no
1537                        d['pin'] = pin_str
1538                        #d['screening_type'] = screening_type
1539                        #d['status'] = 'entered'
1540                        getattr(self,self.catalog).modifyRecord(**d)
1541                    elif applicant.pin != pin_str:
1542                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
1543                    elif applicant.pin == pin_str:
1544                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1545                else:
1546                    datastructure['reg_no'] = ref
1547                    res = self.applicants_catalog(reg_no = ref)
1548                    if res:
1549                        if getattr(res[0],'screening_type',None) != screening_type_request\
1550                              and screening_type_request != 'manage':
1551                            err = "You are using the wrong access form!"
1552                            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)))
1553                            break
1554                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1555                    else:
1556                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1557                        d = {}
1558                        d['reg_no'] = ref
1559                        d['pin'] = pin_str
1560                        d['status'] = 'entered'
1561                        d['screening_type'] = screening_type_request
1562                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
1563                                                  pin_record.serial)
1564                        self.applicants_catalog.addRecord(**d)
1565
1566            break
1567        if err:
1568            datastructure.setError(widget_id, err,mapping)
1569        else:
1570            datamodel = datastructure.getDataModel()
1571            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1572            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1573            datastructure[widget_id+'_p'] = prefix
1574            datastructure[widget_id+'_b'] = b
1575            datastructure[widget_id+'_n'] = n
1576        return not err
1577    ###)
1578
1579    def render(self, mode, datastructure, **kw): ###(
1580        """Render in mode from datastructure."""
1581        render_method = 'widget_scratch_card_pin_render'
1582        meth = getattr(self, render_method, None)
1583        if meth is None:
1584            raise RuntimeError("Unknown Render Method %s for widget type %s"
1585                               % (render_method, self.getId()))
1586
1587        # XXX AT: datastructure has to be set again here, in case we're in edit
1588        # or create mode, because a default value has to be provided.
1589        #import pdb;pdb.set_trace()
1590        datamodel = datastructure.getDataModel()
1591        v = datamodel[self.fields[0]]
1592        #import pdb;pdb.set_trace()
1593        if v and type(v) is StringType:
1594            try:
1595                p,b,n = v.split('-')
1596                v = ScratchCardPin(p,b,n)
1597            except ValueError:
1598                v = ScratchCardPin(self.prefix,'XXX',v)
1599                pass
1600        if v:
1601            prefix= '%s' % v.p
1602            b = '%s' % v.b
1603            n = '%s' % v.n
1604        else:
1605            prefix= self.prefix
1606            if prefix.startswith('@'):
1607                prefix= getattr(self,self.prefix[1:])()
1608            b = n = ''
1609            v = ScratchCardPin(prefix,b,n)
1610        widget_id = self.getWidgetId()
1611        datastructure[widget_id] = v
1612        datastructure[widget_id+'_p'] = prefix
1613        datastructure[widget_id+'_b'] = b
1614        datastructure[widget_id+'_n'] = n
1615        return meth(mode=mode,
1616                    datastructure=datastructure,
1617                    )
1618    ###)
1619
1620InitializeClass(PumePinWidget)
1621widgetRegistry.register(PumePinWidget)
1622###)
1623
1624class WAeUPImageWidget(CPSImageWidget): ###(
1625    """Photo widget."""
1626    meta_type = 'WAeUP Image Widget'
1627
1628    def render(self, mode, datastructure, **kw):
1629        render_method = 'widget_waeup_image_render'
1630        meth = getattr(self, render_method, None)
1631        if meth is None:
1632            raise RuntimeError("Unknown Render Method %s for widget type %s"
1633                               % (render_method, self.getId()))
1634        img_info = self.getImageInfo(datastructure)
1635        return meth(mode=mode, datastructure=datastructure, **img_info)
1636
1637InitializeClass(WAeUPImageWidget)
1638
1639widgetRegistry.register(WAeUPImageWidget)
1640###)
1641
1642class ApplicationImageWidget(CPSImageWidget): ###(
1643    """Image widget with filesystem storage."""
1644    meta_type = 'Application Image Widget'
1645    _properties = CPSImageWidget._properties +\
1646    (
1647     {'id': 'path', 'type': 'string', 'mode': 'w',
1648      'label': 'Relative Path'},
1649     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1650      'label': 'Field to build the id'},
1651    )
1652    path = "images"
1653    storage_path = "%s/import/%s" % (i_home,path)
1654    id_field = "reg_no"
1655
1656    def getImageInfo(self, datastructure): ###(
1657        """Get the file info from the datastructure."""
1658        widget_id = self.getWidgetId()
1659        if  datastructure.has_key(widget_id):
1660            fileupload = datastructure[widget_id]
1661            dm = datastructure.getDataModel()
1662            field_id = self.fields[0]
1663            screening_type = datastructure.get('screening_type')
1664            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1665                                            field_id,)
1666            base_path = os.path.join(screening_type,current_filename)
1667            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1668            file_path = os.path.join(self.storage_path,base_path)
1669            #import pdb; pdb.set_trace()
1670        else:
1671            file_path = "XXX"
1672        # read the file from the filesystem
1673        if not os.path.exists(file_path):
1674            height = -1
1675            width = -1
1676            empty_file = True
1677            session_file = False
1678            current_filename = ''
1679            content_url = ''
1680            size = 0
1681            mimetype = ''
1682            last_modified = ''
1683            height = ''
1684            width = ''
1685
1686        else:
1687            image = open(file_path)
1688            from OFS.Image import getImageInfo as getImageInfoOFS
1689            image.seek(0)
1690            data = image.read(2000)
1691            size = len(data)
1692            empty_file = size == 0
1693            session_file = False
1694            last_modified = ''
1695            image.close()
1696            mimetype, width, height = getImageInfoOFS(data)
1697
1698            if width < 0:
1699                width = None
1700            if height < 0:
1701                height = None
1702
1703            if (self.allow_resize
1704                and height is not None
1705                and width  is not None):
1706                z_w = z_h = 1
1707                h = int(self.display_height)
1708                w = int(self.display_width)
1709                if w and h:
1710                    if w < width:
1711                        z_w = w / float(width)
1712                    if h < height:
1713                        z_h = h / float(height)
1714                    zoom = min(z_w, z_h)
1715                    width = int(zoom * width)
1716                    height = int(zoom * height)
1717                #import pdb;pdb.set_trace()
1718        image_info = {
1719            'empty_file': empty_file,
1720            'session_file': session_file,
1721            'current_filename': current_filename,
1722            'size': size,
1723            'last_modified': last_modified,
1724            'content_url': content_url,
1725            'mimetype': mimetype,
1726            }
1727        title = image_info['current_filename']
1728        alt = title or ''
1729        #height = int(self.display_height)
1730        #width = int(self.display_width)
1731        if height is None or width is None:
1732            tag = renderHtmlTag('img', src=image_info['content_url'],
1733                                alt=alt, title=title)
1734        else:
1735            tag = renderHtmlTag('img', src=image_info['content_url'],
1736                                width=str(width), height=str(height),
1737                                alt=alt, title=title)
1738
1739        image_info['height'] = height
1740        image_info['width'] = width
1741        image_info['image_tag'] = tag
1742        return image_info
1743    ###)
1744
1745    def checkFileName(self, filename, mimetype):
1746        return '', {}
1747        if mimetype and mimetype.startswith('image'):
1748            return '', {}
1749        return 'cpsschemas_err_image', {}
1750
1751    def prepare(self, datastructure, **kw): ###(
1752        """Prepare datastructure from datamodel."""
1753        datamodel = datastructure.getDataModel()
1754        widget_id = self.getWidgetId()
1755        file_name = datamodel[self.fields[0]]
1756        #import pdb; pdb.set_trace()
1757        if self.allow_resize:
1758            datastructure[self.getWidgetId() + '_resize'] = ''
1759        screening_type = datamodel.get('screening_type',None)
1760        if not screening_type:
1761            screening_type = self.REQUEST.form.get('screening_type','pume')
1762        datastructure["screening_type"] = screening_type
1763        datastructure[widget_id] = file_name
1764        datastructure[widget_id + '_choice'] = 'change'
1765        title = 'Passport Foto'
1766        datastructure[widget_id + '_filename'] = title
1767    ###)
1768
1769    def validate(self, datastructure, **kw): ###(
1770        """Update datamodel from user data in datastructure.
1771        """
1772        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1773        datamodel = datastructure.getDataModel()
1774        field_id = self.fields[0]
1775        widget_id = self.getWidgetId()
1776        store = False
1777        fileupload = None
1778        mimetype = None
1779        old_file = datamodel[field_id]
1780        # if old_file is not None:
1781        #     old_filename = old_file.title
1782        # else:
1783        #     old_filename = ''
1784        choice = datastructure[widget_id+'_choice']
1785        fileupload = datastructure[widget_id]
1786        is_upload = isinstance(fileupload, FileUpload)
1787        #import pdb; pdb.set_trace()
1788        if not is_upload and not datamodel[field_id]:
1789            if self.is_required:
1790                return self.validateError('Picture upload required', {},
1791                                          datastructure)
1792        if choice == 'delete':
1793            if self.is_required:
1794                return self.validateError('cpsschemas_err_required', {},
1795                                          datastructure)
1796            datamodel[field_id] = None
1797        elif choice == 'keep':
1798            fileupload = datastructure[widget_id]
1799            if isinstance(fileupload, PersistableFileUpload):
1800                # Keeping something from the session means we
1801                # actually want to store it.
1802                store = True
1803            # else:
1804            #     # Nothing to change, don't pollute datastructure
1805            #     # with something costly already stored, which therefore
1806            #     # doesn't need to be kept in the session.
1807            #     self.unprepare(datastructure)
1808        elif choice == 'change' and is_upload:
1809            if not fileupload:
1810                return self.validateError('cpsschemas_err_file_empty', {},
1811                                          datastructure)
1812            if not isinstance(fileupload, FileUpload):
1813                return self.validateError('cpsschemas_err_file', {},
1814                                          datastructure)
1815            fileupload.seek(0, 2) # end of file
1816            size = fileupload.tell()
1817            if not size:
1818                return self.validateError('cpsschemas_err_file_empty', {},
1819                                          datastructure)
1820            if self.size_max and size > self.size_max:
1821                max_size_str = self.getHumanReadableSize(self.size_max)
1822                err = 'This file is too big, the allowed max size is ${max_size}'
1823                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1824                err_mapping = {'max_size': max_size_str}
1825                return self.validateError(err, err_mapping, datastructure)
1826            store = True
1827
1828
1829        # Find filename
1830        if is_upload and store:
1831            ext ='jpg'
1832            screening_type = datastructure.get('screening_type')
1833            filename = "%s_%s.%s" % (datastructure[self.id_field],
1834                                     self.getWidgetId(),
1835                                     ext)
1836            datamodel[field_id] = filename
1837            registry = getToolByName(self, 'mimetypes_registry')
1838            mimetype = registry.lookupExtension(filename.lower())
1839            if mimetype is not None:
1840                mimetype = str(mimetype) # normalize
1841            file = self.makeFile(filename, fileupload, datastructure)
1842            # Fixup mimetype
1843            if mimetype and file.content_type != mimetype:
1844                file.content_type = mimetype
1845            # Store the file in the filesystem
1846            #import pdb;pdb.set_trace()
1847            base_path = os.path.join(self.storage_path, screening_type)
1848            if not os.path.exists(base_path):
1849                os.mkdir(base_path)
1850            full_path = os.path.join(base_path, filename)
1851            pict = open(full_path,"w")
1852            fileupload.seek(0)
1853            pict.write(fileupload.read())
1854            pict.close()
1855
1856
1857        return True
1858
1859###)
1860
1861    def render(self, mode, datastructure, **kw): ###(
1862        render_method = 'widget_passport_render'
1863        meth = getattr(self, render_method, None)
1864        if meth is None:
1865            raise RuntimeError("Unknown Render Method %s for widget type %s"
1866                               % (render_method, self.getId()))
1867        img_info = self.getImageInfo(datastructure)
1868        return meth(mode=mode, datastructure=datastructure, **img_info)
1869    ###)
1870
1871InitializeClass(ApplicationImageWidget)
1872
1873widgetRegistry.register(ApplicationImageWidget)
1874###)
1875
1876class FileImageWidget(CPSImageWidget): ###(
1877    """Image widget with filesystem storage."""
1878    meta_type = 'File Image Widget'
1879    _properties = CPSImageWidget._properties +\
1880    (
1881     {'id': 'path', 'type': 'string', 'mode': 'w',
1882      'label': 'Relative Path'},
1883     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1884      'label': 'Field to build the id'},
1885     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
1886      'label': 'Show Image'},
1887    )
1888    path = "images"
1889    #storage_path = "%s/%s" % (i_home,path)
1890    id_field = ""
1891    show_image = False
1892
1893    def getStorageImageInfo(self,field_id):
1894        info = {}
1895        if self.id_field == "":
1896            student_id = self.getStudentId()
1897        else:
1898            student_id = datastructure[self.id_field]
1899        # student_path = os.path.join(self.storage_path,
1900        #                             student_id)
1901        student_path = getImagesDir(student_id)
1902        image_name = ''
1903        content_url = ''
1904        current_filename = ''
1905        if os.path.exists(student_path):
1906            for name in os.listdir(student_path):
1907                if name.startswith(field_id):
1908                    image_name = name
1909                    break
1910        if image_name:
1911            info['image_name'] = image_name
1912            info['content_url'] = os.path.join(self.portal_url(),
1913                                               "viewimage",
1914                                               student_id,
1915                                               image_name,
1916                                              )
1917            info['current_filename'] =  image_name
1918            info['file_path'] = os.path.join(student_path, image_name)
1919        return info
1920
1921    def getImageInfo(self, datastructure): ###(
1922        """Get the file info from the datastructure."""
1923        widget_id = self.getWidgetId()
1924        info = None
1925        if  datastructure.has_key(widget_id):
1926            fileupload = datastructure[widget_id]
1927            dm = datastructure.getDataModel()
1928            field_id = self.fields[0]
1929            info = self.getStorageImageInfo(field_id)
1930        else:
1931            file_path = "XXX"
1932            title = ""
1933        # read the file from the filesystem
1934        #import pdb; pdb.set_trace()
1935        #if not os.path.exists(file_path):
1936        if not info:
1937            title = ""
1938            height = -1
1939            width = -1
1940            empty_file = True
1941            session_file = False
1942            current_filename = ''
1943            content_url = ''
1944            size = 0
1945            mimetype = ''
1946            last_modified = ''
1947            height = ''
1948            width = ''
1949        else:
1950            title = info['image_name']
1951            current_filename = info['current_filename']
1952            content_url = info['content_url']
1953            image = open(info['file_path'])
1954            from OFS.Image import getImageInfo as getImageInfoOFS
1955            image.seek(0)
1956            data = image.read(2000)
1957            size = len(data)
1958            empty_file = size == 0
1959            session_file = False
1960            last_modified = ''
1961            image.close()
1962            mimetype, width, height = getImageInfoOFS(data)
1963            registry = getToolByName(self, 'mimetypes_registry')
1964            mimetype = (registry.lookupExtension(current_filename.lower()) or
1965                        registry.lookupExtension('file.bin'))
1966            if width < 0:
1967                width = None
1968            if height < 0:
1969                height = None
1970
1971            if (self.allow_resize
1972                and height is not None
1973                and width  is not None):
1974                z_w = z_h = 1
1975                h = int(self.display_height)
1976                w = int(self.display_width)
1977                if w and h:
1978                    if w < width:
1979                        z_w = w / float(width)
1980                    if h < height:
1981                        z_h = h / float(height)
1982                    zoom = min(z_w, z_h)
1983                    width = int(zoom * width)
1984                    height = int(zoom * height)
1985                #import pdb;pdb.set_trace()
1986        image_info = {
1987            'empty_file': empty_file,
1988            'session_file': session_file,
1989            'current_filename': title,
1990            'size': size,
1991            'last_modified': last_modified,
1992            'content_url': content_url,
1993            'mimetype': mimetype,
1994            }
1995        alt = title or ''
1996        #height = int(self.display_height)
1997        #width = int(self.display_width)
1998        if height is None or width is None:
1999            tag = renderHtmlTag('img', src=image_info['content_url'],
2000                                alt=alt, title=title)
2001        else:
2002            tag = renderHtmlTag('img', src=image_info['content_url'],
2003                                width=str(width), height=str(height),
2004                                alt=alt, title=title)
2005
2006        image_info['height'] = height
2007        image_info['width'] = width
2008        image_info['image_tag'] = tag
2009        image_info['show_image'] = self.show_image
2010        return image_info
2011    ###)
2012
2013    # def checkFileName(self, filename, mimetype):
2014    #     return '', {}
2015    #     if mimetype and mimetype.startswith('image'):
2016    #         return '', {}
2017    #     return 'cpsschemas_err_image', {}
2018
2019    def prepare(self, datastructure, **kw): ###(
2020        """Prepare datastructure from datamodel."""
2021        datamodel = datastructure.getDataModel()
2022        widget_id = self.getWidgetId()
2023        file_name = datamodel[self.fields[0]]
2024        if self.id_field == "":
2025            student_id = self.getStudentId()
2026        else:
2027            student_id = datastructure[self.id_field]
2028        if student_id is not None:
2029            # student_path = os.path.join(self.storage_path,
2030            #                             student_id)
2031            student_path = getImagesDir(student_id)
2032            if not os.path.exists(student_path):
2033                self.waeup_tool.moveImagesToFS(student_id)
2034        if self.allow_resize:
2035            datastructure[self.getWidgetId() + '_resize'] = ''
2036        datastructure[widget_id] = file_name
2037        datastructure[widget_id + '_choice'] = 'change'
2038        title = 'Passport Foto'
2039        datastructure[widget_id + '_filename'] = title
2040    ###)
2041
2042    def validate(self, datastructure, **kw): ###(
2043        """Update datamodel from user data in datastructure.
2044        """
2045        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2046        datamodel = datastructure.getDataModel()
2047        field_id = self.fields[0]
2048        widget_id = self.getWidgetId()
2049        store = False
2050        fileupload = None
2051        mimetype = None
2052        old_file = datamodel[field_id]
2053        choice = datastructure[widget_id+'_choice']
2054        fileupload = datastructure[widget_id]
2055        is_upload = isinstance(fileupload, FileUpload)
2056        #import pdb; pdb.set_trace()
2057        if not is_upload and not datamodel[field_id]:
2058            if self.is_required:
2059                return self.validateError('Picture upload required', {},
2060                                          datastructure)
2061        if self.id_field == "":
2062            student_id = self.getStudentId()
2063        else:
2064            student_id = datastructure[self.id_field]
2065        if choice == 'delete':
2066            if self.is_required:
2067                return self.validateError('cpsschemas_err_required', {},
2068                                          datastructure)
2069            info= self.getStorageImageInfo(field_id)
2070            # Remove the file in the filesystem
2071            if info:
2072                os.remove(info['file_path'])
2073            datamodel[field_id] = None
2074        elif choice == 'keep':
2075            fileupload = datastructure[widget_id]
2076            if isinstance(fileupload, PersistableFileUpload):
2077                # Keeping something from the session means we
2078                # actually want to store it.
2079                store = True
2080            # else:
2081            #     # Nothing to change, don't pollute datastructure
2082            #     # with something costly already stored, which therefore
2083            #     # doesn't need to be kept in the session.
2084            #     self.unprepare(datastructure)
2085        elif choice == 'change' and is_upload:
2086            if not fileupload:
2087                return self.validateError('cpsschemas_err_file_empty', {},
2088                                          datastructure)
2089            if not isinstance(fileupload, FileUpload):
2090                return self.validateError('cpsschemas_err_file', {},
2091                                          datastructure)
2092            fileupload.seek(0, 2) # end of file
2093            size = fileupload.tell()
2094            if not size:
2095                return self.validateError('cpsschemas_err_file_empty', {},
2096                                          datastructure)
2097            if self.size_max and size > self.size_max:
2098                max_size_str = self.getHumanReadableSize(self.size_max)
2099                err = 'This file is too big, the allowed max size is ${max_size}'
2100                member_id = str(self.portal_membership.getAuthenticatedMember())
2101                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2102                err_mapping = {'max_size': max_size_str}
2103                return self.validateError(err, err_mapping, datastructure)
2104            store = True
2105
2106
2107        # Find filename
2108        if is_upload and store:
2109            filename = cookId('', '', fileupload)[0].strip()
2110            base,ext = os.path.splitext(filename)
2111            filename = "%s_%s%s" % (field_id,
2112                                    student_id,
2113                                    ext)
2114            datamodel[field_id] = filename
2115            registry = getToolByName(self, 'mimetypes_registry')
2116            mimetype = registry.lookupExtension(filename.lower())
2117            if mimetype is not None:
2118                mimetype = str(mimetype) # normalize
2119            file = self.makeFile(filename, fileupload, datastructure)
2120            # Fixup mimetype
2121            if mimetype and file.content_type != mimetype:
2122                file.content_type = mimetype
2123            # Store the file in the filesystem
2124            #student_path = os.path.join(self.storage_path,student_id)
2125            student_path = getImagesDir(student_id)
2126            if not os.path.exists(student_path):
2127                os.mkdir(student_path)
2128            full_path = os.path.join(student_path, filename)
2129            pict = open(full_path,"w")
2130            #fileupload.seek(0)
2131            #import pdb; pdb.set_trace()
2132            pict.write(str(file.data))
2133            pict.close()
2134        return True
2135    ###)
2136
2137    def render(self, mode, datastructure, **kw): ###(
2138        render_method = 'widget_image_render'
2139        meth = getattr(self, render_method, None)
2140        #import pdb;pdb.set_trace()
2141        if meth is None:
2142            raise RuntimeError("Unknown Render Method %s for widget type %s"
2143                               % (render_method, self.getId()))
2144        img_info = self.getImageInfo(datastructure)
2145        return meth(mode=mode, datastructure=datastructure, **img_info)
2146    ###)
2147
2148InitializeClass(FileImageWidget)
2149
2150widgetRegistry.register(FileImageWidget)
2151###)
2152
2153class DiscFileWidget(CPSFileWidget): ###(
2154    """File widget with filesystem storage."""
2155    meta_type = 'Disc File Widget'
2156    _properties = CPSFileWidget._properties +\
2157    (
2158     {'id': 'path', 'type': 'string', 'mode': 'w',
2159      'label': 'Relative Path'},
2160    )
2161    path = "import"
2162    storage_path = "%s/%s" % (i_home,path)
2163
2164    def getStoredFileInfo(self,datastructure): ###(
2165        datamodel = datastructure.getDataModel()
2166        field_id = self.fields[0]
2167        widget_id = self.getWidgetId()
2168        file_name = datamodel[field_id]
2169        info = {}
2170        registry = getToolByName(self, 'mimetypes_registry')
2171        info['mimetype'] = registry.lookupExtension('file.csv')
2172        info['empty_file'] = True
2173        info['size'] = 0
2174        info['last_modified'] = ''
2175        file_path = os.path.join(self.storage_path, file_name)
2176        if os.path.exists(file_path):
2177            info['empty_file'] = False
2178            info['file_name'] = file_name
2179            info['content_url'] = os.path.join(self.portal_url(),
2180                                            "viewfile",
2181                                            file_name,
2182                                            )
2183            info['current_filename'] =  file_name
2184            # get the mimetype
2185            mimetype = (registry.lookupExtension(file_name.lower()) or
2186                        registry.lookupExtension('file.bin'))
2187            info['mimetype'] = mimetype
2188            info['file_path'] = file_path
2189        else:
2190            info['file_name'] = ''
2191            info['content_url'] = ''
2192            info['current_filename'] = ''
2193            info['file_path'] = ''
2194        return info
2195        ###)
2196   
2197    def prepare(self, datastructure, **kw): ###(
2198        """Prepare datastructure from datamodel."""
2199        datamodel = datastructure.getDataModel()
2200        #import pdb;pdb.set_trace()
2201        widget_id = self.getWidgetId()
2202        file_name = datamodel[self.fields[0]]
2203        datastructure[widget_id] = file_name
2204        datastructure[widget_id + '_filename'] = file_name
2205        datastructure[widget_id+'_choice'] = "keep"
2206    ###)
2207
2208    def validate(self, datastructure, **kw): ###(
2209        """Update datamodel from user data in datastructure.
2210        """
2211        logger = logging.getLogger('Widgets.DiscFileWidget.validate')
2212        datamodel = datastructure.getDataModel()
2213        field_id = self.fields[0]
2214        widget_id = self.getWidgetId()
2215        store = False
2216        fileupload = None
2217        mimetype = None
2218        old_file = datamodel[field_id]
2219        choice = datastructure[widget_id+'_choice']
2220        fileupload = datastructure[widget_id]
2221        is_upload = isinstance(fileupload, FileUpload)
2222        if not is_upload and not datamodel[field_id]:
2223            if self.is_required:
2224                return self.validateError('File upload required', {},
2225                                          datastructure)
2226        if choice == 'delete':
2227            if self.is_required:
2228                return self.validateError('cpsschemas_err_required', {},
2229                                          datastructure)
2230            info = self.getStoredFileInfo(datastructure)
2231            # Remove the file in the filesystem
2232            if info:
2233                os.remove(info['file_path'])
2234            datamodel[field_id] = None
2235        elif choice == 'keep':
2236            fileupload = datastructure[widget_id]
2237            if isinstance(fileupload, PersistableFileUpload):
2238                # Keeping something from the session means we
2239                # actually want to store it.
2240                store = True
2241            # else:
2242            #     # Nothing to change, don't pollute datastructure
2243            #     # with something costly already stored, which therefore
2244            #     # doesn't need to be kept in the session.
2245            #     self.unprepare(datastructure)
2246        elif choice == 'change' and is_upload:
2247            if not fileupload:
2248                return self.validateError('cpsschemas_err_file_empty', {},
2249                                          datastructure)
2250            if not isinstance(fileupload, FileUpload):
2251                return self.validateError('cpsschemas_err_file', {},
2252                                          datastructure)
2253            fileupload.seek(0, 2) # end of file
2254            size = fileupload.tell()
2255            if not size:
2256                return self.validateError('cpsschemas_err_file_empty', {},
2257                                          datastructure)
2258            if self.size_max and size > self.size_max:
2259                max_size_str = self.getHumanReadableSize(self.size_max)
2260                err = 'This file is too big, the allowed max size is ${max_size}'
2261                member_id = str(self.portal_membership.getAuthenticatedMember())
2262                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2263                err_mapping = {'max_size': max_size_str}
2264                return self.validateError(err, err_mapping, datastructure)
2265            store = True
2266
2267
2268        # Find filename
2269        if is_upload and store:
2270            filename = cookId('', '', fileupload)[0].strip()
2271            base,ext = os.path.splitext(filename)
2272            if ext not in ("csv",".csv"):
2273                return self.validateError('only csv files allowed', {},
2274                                          datastructure)
2275            uploads_folder = self.portal_url.getPortalObject().campus.uploads
2276            if hasattr(uploads_folder,filename):
2277                return self.validateError('upload object exists', {},
2278                                          datastructure)
2279            datamodel[field_id] = filename
2280            registry = getToolByName(self, 'mimetypes_registry')
2281            mimetype = registry.lookupExtension(filename.lower())
2282            if mimetype is not None:
2283                mimetype = str(mimetype) # normalize
2284            file = self.makeFile(filename, fileupload, datastructure)
2285            # Fixup mimetype
2286            if mimetype and file.content_type != mimetype:
2287                file.content_type = mimetype
2288            file_path = os.path.join(self.storage_path,filename)
2289            data = open(file_path,"w")
2290            data.write(str(file.data))
2291            data.close()
2292        return True
2293    ###)
2294
2295    def render(self, mode, datastructure, **kw): ###(
2296        render_method = 'widget_uploadfile_render'
2297        meth = getattr(self, render_method, None)
2298        #import pdb;pdb.set_trace()
2299        if meth is None:
2300            raise RuntimeError("Unknown Render Method %s for widget type %s"
2301                               % (render_method, self.getId()))
2302        file_info = self.getStoredFileInfo(datastructure)
2303
2304        return meth(mode=mode, datastructure=datastructure, **file_info)
2305    ###)
2306
2307InitializeClass(DiscFileWidget)
2308
2309widgetRegistry.register(DiscFileWidget)
2310###)
2311
2312###########
2313
Note: See TracBrowser for help on using the repository browser.