source: WAeUP_SRP/trunk/Widgets.py @ 3718

Last change on this file since 3718 was 3710, checked in by Henrik Bettermann, 16 years ago

add mising entry_session field in import_application.xml layout

  • Property svn:keywords set to Id
File size: 94.6 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 3710 2008-10-05 08:12:41Z henrik $
3from cgi import escape
4from types import *
5import Globals
6from Globals import InitializeClass
7from ZPublisher.HTTPRequest import FileUpload
8from OFS.Image import cookId, File, Image
9##from Products.CPSSchemas.Widget import CPSWidgetType
10from Products.CMFCore.utils import getToolByName
11from Products.CPSSchemas.BasicWidgets import CPSBooleanWidget, CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget
12from Products.CPSSchemas.BasicWidgets import CPSFileWidget, CPSPasswordWidget
13from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget
14from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget
15from Products.CPSSchemas.Vocabulary import Vocabulary
16from Products.CPSSchemas.Widget import widgetRegistry
17from Products.CPSUtil.file import PersistableFileUpload
18from Products.CPSUtil.id import generateFileName
19##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry
20from DateTime.DateTime import DateTime
21from AccessControl import getSecurityManager
22from Products.WAeUP_SRP.Students import getStudentByRegNo
23from Products.WAeUP_SRP.Academics import makeCertificateCode
24from Products.WAeUP_SRP.WAeUPTool import getImagesDir
25#from Products.ExtFile.ExtFile import ExtFile
26import logging,os,re
27import random
28import operator
29p_home = Globals.package_home(globals())
30i_home = Globals.INSTANCE_HOME
31
32#from zLOG import LOG, DEBUG
33
34
35class WAeUPPasswordWidget(CPSPasswordWidget): ###(
36    """WAeUP Password Widget"""
37    meta_type = 'WAeUP Password Widget'
38
39    _properties = CPSStringWidget._properties + (
40        {'id': 'password_widget', 'type': 'string', 'mode': 'w',
41         'label': 'Password widget to compare with'},
42        {'id': 'check_lower', 'type': 'boolean', 'mode': 'w',
43         'label': 'Checking at least one lower case [a-z]'},
44        {'id': 'check_upper', 'type': 'boolean', 'mode': 'w',
45         'label': 'Checking at least one upper case [A-Z]'},
46        {'id': 'check_digit', 'type': 'boolean', 'mode': 'w',
47         'label': 'Checking at least one digit [0-9]'},
48        {'id': 'check_extra', 'type': 'boolean', 'mode': 'w',
49         'label': 'Checking at least one extra char other than [a-zA-Z0-9]'},
50        {'id': 'check_words', 'type': 'string', 'mode': 'w',
51         'label': 'Checking for words'},
52        )
53
54    field_types = ('CPS Password Field',)
55    password_widget = ''
56    check_lower = 0
57    check_upper = 0
58    check_digit = 0
59    check_extra = 0
60    check_words = ''
61    display_width = 8
62    size_min = 5
63    size_max = 8
64
65    def validate(self, datastructure, **kw):
66        """Validate datastructure and update datamodel."""
67        widget_id = self.getWidgetId()
68        value = datastructure[widget_id]
69        err = 0
70        try:
71            v = str(value).strip()
72        except ValueError:
73            err = 'cpsschemas_err_string'
74        else:
75            if self.password_widget:
76                # here we only check that that our confirm match the pwd
77                pwidget_id = self.password_widget
78                pvalue = datastructure[pwidget_id]
79                datastructure[widget_id] = ''
80                datastructure[pwidget_id] = ''
81                pv = str(pvalue).strip()
82                if pv and v != pv:
83                    err = 'cpsschemas_err_password_mismatch'
84            else:
85                if not v:
86                    if self.is_required:
87                        datamodel = datastructure.getDataModel()
88                        if not datamodel[self.fields[0]]:
89                            err = 'cpsschemas_err_required'
90                else:
91                    # checking pw consistancy
92                    len_v = len(v)
93                    if not err and self.size_max and len_v > self.size_max:
94                        err = 'cpsschemas_err_string_too_long'
95                    if not err and self.size_min and len_v < self.size_min:
96                        err = 'cpsschemas_err_password_size_min'
97                    if not err and self.check_lower and not search(r'[a-z]', v):
98                        err = 'cpsschemas_err_password_lower'
99                    if not err and self.check_upper and not search(r'[A-Z]', v):
100                        err = 'cpsschemas_err_password_upper'
101                    if not err and self.check_digit and not search(r'[0-9]', v):
102                        err = 'cpsschemas_err_password_digit'
103                    if not err and self.check_extra and not search(r'[^a-zA-Z0-9]',
104                                                                   v):
105                        err = 'cpsschemas_err_password_extra'
106                    if not err and v in self.check_words:
107                        err = 'Your password is unsecure, please choose another password!'
108
109        if err:
110            datastructure[widget_id] = ''
111            datastructure.setError(widget_id, err)
112        elif v:
113            datamodel = datastructure.getDataModel()
114            datamodel[self.fields[0]] = v
115
116        return not err
117
118InitializeClass(WAeUPPasswordWidget)
119
120widgetRegistry.register(WAeUPPasswordWidget)
121###)
122
123class CPSSelectWidgetForRecord(CPSSelectWidget): ###(
124    """Select widget. with record names"""
125    meta_type = 'Select Widget for Records'
126
127    field_types = ('CPS String Field',)
128    field_inits = ({'is_searchabletext': 1,},)
129
130    _properties = CPSSelectWidget._properties + (
131        {'id': 'record_id', 'type': 'string', 'mode': 'w',
132         'label': 'Record Id', 'is_required' : 1},
133        )
134
135    def render(self, mode, datastructure, **kw):
136        """Render in mode from datastructure."""
137        value = datastructure[self.getWidgetId()]
138        vocabulary = self._getVocabulary(datastructure)
139        portal = getToolByName(self, 'portal_url').getPortalObject()
140        cpsmcat = portal.translation_service
141        if mode == 'view':
142            if self.translated:
143                return escape(cpsmcat(vocabulary.getMsgid(value, value)).encode('ISO-8859-15', 'ignore'))
144            else:
145                return escape(vocabulary.get(value, value))
146        elif mode == 'edit':
147            html_widget_id = self.getHtmlWidgetId()
148            res = renderHtmlTag('select',
149                                name='%s.%s:records' % (self.record_id,html_widget_id),
150                                id=html_widget_id)
151            in_selection = 0
152            for k, v in vocabulary.items():
153                if self.translated:
154                    kw = {'value': k,
155                          'contents': cpsmcat(vocabulary.getMsgid(k, k)).encode('ISO-8859-15', 'ignore')
156                          }
157                else:
158                    kw = {'value': k, 'contents': v}
159                if value == k:
160                    kw['selected'] = 'selected'
161                    in_selection = 1
162                res += renderHtmlTag('option', **kw)
163            if value and not in_selection:
164                kw = {'value': value, 'contents': 'invalid: '+ str(value),
165                      'selected': 'selected'}
166                res += renderHtmlTag('option', **kw)
167            res += '</select>'
168            return res
169        raise RuntimeError('unknown mode %s' % mode)
170
171InitializeClass(CPSSelectWidgetForRecord)
172
173widgetRegistry.register(CPSSelectWidgetForRecord)
174
175###)
176
177class CPSStringWidgetForRecord(CPSStringWidget): ###(
178    """String widget."""
179    meta_type = 'String Widget For Record'
180
181    field_types = ('CPS String Field',)
182    field_inits = ({'is_searchabletext': 1,},)
183    _properties = CPSStringWidget._properties + (
184        {'id': 'record_id', 'type': 'string', 'mode': 'w',
185         'label': 'Record Id', 'is_required' : 1},
186        )
187
188    def render(self, mode, datastructure, **kw):
189        """Render in mode from datastructure."""
190        value = datastructure[self.getWidgetId()]
191        if mode == 'view':
192            return escape(value)
193        elif mode == 'edit':
194            # XXX TODO should use an other name than kw !
195            # XXX change this everywhere
196            html_widget_id = self.getHtmlWidgetId()
197            kw = {'type': 'text',
198                  'id'  : html_widget_id,
199                  'name': '%s.%s:records' % (self.record_id,html_widget_id),
200                  'value': escape(value),
201                  'size': self.display_width,
202                  }
203            if self.size_max:
204                kw['maxlength'] = self.size_max
205            return renderHtmlTag('input', **kw)
206        raise RuntimeError('unknown mode %s' % mode)
207
208InitializeClass(CPSStringWidgetForRecord)
209
210widgetRegistry.register(CPSStringWidgetForRecord)
211
212###)
213
214class CertificateCourseIdWidget(CPSStringWidget): ###(
215    """ CertificateCourseId Widget"""
216    meta_type = "CertificateCourseId Widget"
217
218    def validate(self, datastructure, **kw):
219        """Validate datastructure and update datamodel."""
220
221        valid = CPSStringWidget.validate(self, datastructure, **kw)
222        if not valid:
223            return 0
224        else:
225            widget_id = self.getWidgetId()
226            value = datastructure[widget_id].upper()
227            err = 0
228            c_ids = [c.id for c in self.portal_catalog({'meta_type': "Course"})]
229            if hasattr(self.aq_parent,value):
230                err = 'Course already exists'
231            elif value not in c_ids:
232                err = 'Course does not exist'
233            if err:
234                datastructure.setError(widget_id, err)
235            else:
236                datamodel = datastructure.getDataModel()
237                datamodel[self.fields[0]] = value
238
239            return not err
240
241InitializeClass(CertificateCourseIdWidget)
242
243widgetRegistry.register(CertificateCourseIdWidget)
244###)
245
246class CourseIdWidget(CPSStringWidget): ###(
247    """ CourseId Widget"""
248    meta_type = "CourseId Widget"
249
250    def validate(self, datastructure, **kw):
251        """Validate datastructure and update datamodel."""
252
253        valid = CPSStringWidget.validate(self, datastructure, **kw)
254        if not valid:
255            return 0
256        else:
257            widget_id = self.getWidgetId()
258            value = datastructure[widget_id].upper()
259            err = 0
260            res = self.courses_catalog(code = value)
261            if len(res) > 0:
262                err = 'Course already exists'
263            if err:
264                datastructure.setError(widget_id, err)
265            else:
266                datamodel = datastructure.getDataModel()
267                datamodel[self.fields[0]] = value
268
269            return not err
270
271InitializeClass(CourseIdWidget)
272
273widgetRegistry.register(CourseIdWidget)
274
275
276###)
277
278class WAeUPStudyModeWidget(CPSSelectWidget): ###(
279    """WAeUP StudyMode Widget."""
280    meta_type = 'WAeUP StudyMode Widget'
281    vocabulary = 'entry_modes'
282
283    def _getStudyModes(self):
284        voc = getattr(self.portal_vocabularies,self.vocabulary)
285        d = {}
286        for k,v in voc.items():
287            d[k] = v
288        return d
289
290    def validate(self, datastructure, **kw):
291        """Validate datastructure and update datamodel."""
292        widget_id = self.getWidgetId()
293        value = datastructure[widget_id]
294        try:
295            v = str(value)
296        except ValueError:
297            datastructure.setError(widget_id, "'%s' not a valid session key" % value)
298            return 0
299        studymodes = self._getStudyModes()
300        if not value:
301            v = value = 'ume_ft'
302        #import pdb;pdb.set_trace()
303        if not studymodes.has_key(value):
304            datastructure.setError(widget_id, "'%s' not a valid session key" % v)
305            return 0
306        if self.is_required and not len(v):
307            datastructure.setError(widget_id, "session key required")
308            return 0
309
310        datamodel = datastructure.getDataModel()
311        datamodel[self.fields[0]] = v
312        return 1
313
314    def render(self, mode, datastructure, **kw):
315        """Render in mode from datastructure."""
316        value = datastructure[self.getWidgetId()]
317        studymodes = self._getStudyModes()
318        if mode == 'view':
319            return escape(studymodes.get(value, value))
320        elif mode == 'edit':
321            html_widget_id = self.getHtmlWidgetId()
322            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
323            in_selection = 0
324            vocabulary_items = studymodes.items()
325            if self.sorted:
326                vocabulary_items.sort(key=operator.itemgetter(1))
327            for k, v in vocabulary_items:
328                kw = {'value': k, 'contents': v}
329                if value == k:
330                    kw['selected'] = 'selected'
331                    in_selection = 1
332                res += renderHtmlTag('option', **kw)
333            if value and not in_selection:
334                kw = {'value': value, 'contents': 'invalid: '+ str(value),
335                      'selected': 'selected'}
336                res += renderHtmlTag('option', **kw)
337            res += '</select>'
338            return res
339        raise RuntimeError('unknown mode %s' % mode)
340
341InitializeClass(WAeUPStudyModeWidget)
342
343widgetRegistry.register(WAeUPStudyModeWidget)
344
345###)
346
347class WAeUPSessionWidget(CPSSelectWidget): ###(
348    """WAeUP Session Widget for import only"""
349    meta_type = 'WAeUP Session Widget'
350
351    def _getSessions(self):
352        current_year = DateTime().year()
353        d = {'': ''}
354        for y in range(current_year - 10,current_year + 1):
355            d['%s' % str(y)[-2:]] = '%4d/%4d' % (y,y+1)
356        return d
357
358    def validate(self, datastructure, **kw):
359        """Validate datastructure and update datamodel."""
360        widget_id = self.getWidgetId()
361        value = datastructure[widget_id]
362        try:
363            v = str(value)
364        except ValueError:
365            datastructure.setError(widget_id, "'%s' not a valid session key" % value)
366            return 0
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 VocabularyOnTheFly: ###(
770    def __init__(self, tuples):
771        """a nonpersistent vocabulary (copy from CPSSchemas.Vocabulary.Vocabulary).
772        Allowed parameter syntaxes is:
773          - Vocabulary((('foo', "Foo", 'label_foo'), ('bar', "Bar", 'label_bar')))
774            Same as first with message ids (msgids) that can be used for i18n
775        """
776        l = []
777        d = {}
778        m = {}
779        # We suppose that initial vocabulary is sorted
780        # Vocabulary((('foo', "Foo", 'label_foo'), ('bar', "Bar", 'label_bar')))
781        for k, v, msgid in tuples:
782            l.append(k)
783            d[k] = v
784            m[k] = msgid
785        self._list = l
786        self._dict = d
787        self._msgids = m
788
789    def __getitem__(self, key):
790        """Get a label for a key."""
791        return self._dict[key]
792
793    def get(self, key, default=None):
794        """Get a label for a key, default to None."""
795        try:
796            v = self._dict.get(key, default)
797        except TypeError:
798            # XXX temporary fix, don't know why sometime rendering try to do
799            # get([]) that returning a typeError
800            return ''
801        return v
802
803    def getMsgid(self, key, default=None):
804        """Get a msgid for a key, default to None."""
805        return self._msgids.get(key, default)
806
807    def has_key(self, key):
808        """Test if a key is present."""
809        return self._dict.has_key(key)
810
811    def keys(self):
812        """Get the ordered list of keys."""
813        return self._list[:]
814
815    def items(self):
816        """Get the ordered list of (key, value)."""
817        return [(key, self._dict.get(key)) for key in self._list]
818
819    def values(self):
820        """Get the ordered list of values."""
821        return [self._dict.get(key) for key in self._list]
822
823    def keysSortedBy(self, crit='id'):
824        """Return a keys list sorted on a criterium
825
826        Crit is one of 'id', 'label' or 'i18n'.
827        """
828
829        if crit == 'label':
830            l = [(x[1], x[0]) for x in self.items()]
831            l.sort()
832            return [x[1] for x in l]
833        elif crit == 'i18n':
834            portal = getToolByName(self, 'portal_url').getPortalObject()
835            cpsmcat = portal.translation_service
836            l = [(cpsmcat(self.getMsgid(key)).encode('ISO-8859-15', 'ignore'),
837                  key) for key in self.keys()]
838            l.sort()
839            return [x[1] for x in l]
840        else:
841            return self.keys()
842###)
843
844class ApplicationCourseWidget(CPSSelectWidget): ###(
845    """ ApplicationCourse Widget"""
846    meta_type = "Application Course Widget"
847
848    def _getVocabulary(self,datastructure=None):
849        if self.REQUEST.traverse_subpath:
850            screening_type = self.REQUEST.traverse_subpath[0].lower()
851        else:
852            screening_type = 'all'
853        if screening_type in ("all","cest","sandwich","pg"):
854            application_category = screening_type
855        else:
856            application_category = "basic"
857        if not hasattr(self,'_v_certificates_docs'):
858            # res = self.portal_catalog_real.search({'meta_type': "Certificate"})
859            # d = {}
860            # for cert in res:
861            #     c = cert.getObject().getContent()
862            #     if getattr(c,'application_category',''):
863            #         d[cert.getId] = c
864            res = self.certificates_catalog()
865            d = {}
866            for cert in res:
867                if getattr(cert,'application_category',''):
868                    d[cert.code] = cert
869            self._v_certificates_docs = d
870        l  = [('','','')]
871        #l = []
872        for k,d in self._v_certificates_docs.items():
873            if application_category == "all":
874                l  += (k,self._v_certificates_docs[k].title,k),
875            else:
876                if getattr(d,'application_category','') == application_category:
877                    l  += (k,self._v_certificates_docs[k].title,k),
878        #import ipdb;ipdb.set_trace()
879        return VocabularyOnTheFly(l)
880
881InitializeClass(ApplicationCourseWidget)
882
883widgetRegistry.register(ApplicationCourseWidget)
884###)
885
886class JambRegNoWidget(CPSStringWidget): ###(
887    """ JambRegNo Widget"""
888    meta_type = "JambRegNo Widget"
889    _properties = CPSStringWidget._properties + (
890        {'id': 'catalog', 'type': 'string', 'mode': 'w',
891         'label': 'Catalog to search'},
892         {'id': 'reference', 'type': 'string', 'mode': 'w',
893         'label': 'Reference Field'},
894         )
895    #catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
896    reference = ""
897    digits = 8
898    digits_str = "N"*digits
899    letters = 2
900    letters_str = "L"*letters
901    def validate(self, datastructure, **kw):
902        """Validate datastructure and update datamodel."""
903        valid = CPSStringWidget.validate(self, datastructure, **kw)
904        reg_no_catalog = getattr(self,self.catalog)
905        widget_id = self.getWidgetId()
906        value = datastructure[widget_id].upper()
907        err = 0
908        #import pdb;pdb.set_trace()
909        if kw.has_key('mode'):
910            mode = kw['mode']
911        else:
912            mode = "edit"
913        if not valid:
914            err = 'Invalid registration number'
915        elif self.reference == '':
916            #s = getStudentByRegNo(self,value)
917            student_record = reg_no_catalog(jamb_reg_no = value)
918            if len(student_record) < 1:
919                err = 'No student record with this registration number'
920            elif self.catalog == "students_catalog" and student_record[0].review_state not in ('student_created','admitted'):
921                err = 'Admission checking not allowed (wrong registration state)'
922            else:
923                datastructure['pume'] = student_record[0]
924        elif mode == 'add':
925            pass
926        elif self.reference != '' and self.catalog == "applicants_catalog":
927            res = reg_no_catalog.searchResults({"%s" % self.reference: value})
928            if len(res) != 1:
929                err = 'No record with this registration number'
930            else:
931                datastructure['record'] = res[0]
932        else:
933            record = datastructure[self.reference]
934            #jamb_reg_no = getattr(record,widget_id)
935            jamb_reg_no = record.Entryregno
936            if jamb_reg_no != value:
937                err = 'Registration number does not match.'
938        if err:
939            datastructure.setError(widget_id, err)
940        else:
941            datamodel = datastructure.getDataModel()
942            datamodel[self.fields[0]] = value
943        return not err
944
945InitializeClass(JambRegNoWidget)
946
947widgetRegistry.register(JambRegNoWidget)
948###)
949
950class SecretWidget(CPSStringWidget): ###(
951    """ Secret Widget"""
952    meta_type = "Secret Widget"
953    _properties = CPSStringWidget._properties + (
954        {'id': 'reference', 'type': 'string', 'mode': 'w',
955         'label': 'Reference Record'},
956         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
957         'label': 'Fields to check'},
958         )
959    reference = "student"
960    matric_no_catalog = 'returning_import'
961    check_fields = ("Firstname", "Middlename","Lastname")
962    def validate(self, datastructure, **kw):
963        """Validate datastructure and update datamodel."""
964        logger = logging.getLogger('Widgets.SecretWidget.validate')
965        valid = CPSStringWidget.validate(self, datastructure, **kw)
966        widget_id = self.getWidgetId()
967        value = datastructure[widget_id].upper()
968        err = 0
969        record = datastructure.get(self.reference,None)
970        #import pdb;pdb.set_trace()
971        if not valid or len(value) < 2:
972            err = 'Invalid string'
973        elif not record or datastructure.errors:
974            err = 0
975        else:
976            found = False
977            cvs = []
978            for field in self.check_fields:
979                cv = getattr(record,field).upper()
980                if len(cv.split()) > 1:
981                    for splited in cv.split():
982                        cvs.append(splited.strip())
983                else:
984                    cvs.append(cv.strip(),)
985            for cv in cvs:
986                if cv  == value.strip().upper():
987                    found = True
988                    break
989            matric_no = record.matric_no
990            name = " ".join(cvs)
991            if not found:
992                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
993                err = 'No name does match.'
994            else:
995                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
996        if err:
997            datastructure.setError(widget_id, err)
998        else:
999            datamodel = datastructure.getDataModel()
1000            datamodel[self.fields[0]] = value
1001        return not err
1002
1003InitializeClass(SecretWidget)
1004
1005widgetRegistry.register(SecretWidget)
1006###)
1007
1008class WAeUPSexWidget(CPSBooleanWidget): ###(
1009    """WAeUP sex widget."""
1010    meta_type = 'WAeUP Sex Widget'
1011
1012    def validate(self, datastructure, **kw):
1013        """Validate datastructure and update datamodel."""
1014        value = datastructure[self.getWidgetId()]
1015
1016        if self.render_format not in self.render_formats:
1017            self.render_format = 'select'
1018
1019        female = value in ('F','f','Female','female',"True",True)
1020        male = value in ('M','m','Male','male','False',False)
1021        if not female and not male:
1022            datastructure.setError(self.getWidgetId(),
1023                                   "invalid sex %s" % value)
1024            return 0
1025        elif female:
1026            v = True
1027        else:
1028            v = False
1029        datamodel = datastructure.getDataModel()
1030        datamodel[self.fields[0]] = v
1031        return 1
1032
1033InitializeClass(WAeUPSexWidget)
1034
1035widgetRegistry.register(WAeUPSexWidget)
1036
1037###)
1038
1039class WAeUPBooleanWidget(CPSBooleanWidget): ###(
1040    """WAeUP boolean widget."""
1041    meta_type = 'WAeUP Boolean Widget'
1042
1043    def validate(self, datastructure, **kw):
1044        """Validate datastructure and update datamodel."""
1045        value = datastructure[self.getWidgetId()]
1046
1047        if self.render_format not in self.render_formats:
1048            self.render_format = 'select'
1049        true = value.upper() in ('T','1','TRUE','WAHR',True)
1050        false = value.upper() in ('F','0','FALSE','FALSCH',False)
1051        if not true and not false:
1052            datastructure.setError(self.getWidgetId(),
1053                                   "invalid boolean %s" % value)
1054            return 0
1055        elif true:
1056            v = True
1057        else:
1058            v = False
1059        datamodel = datastructure.getDataModel()
1060        datamodel[self.fields[0]] = v
1061        return 1
1062
1063InitializeClass(WAeUPBooleanWidget)
1064
1065widgetRegistry.register(WAeUPBooleanWidget)
1066
1067###)
1068
1069class MatricNoWidget(CPSStringWidget): ###(
1070    """ MatricNo Widget"""
1071    meta_type = "MatricNo Widget"
1072
1073    _properties = CPSStringWidget._properties + (
1074        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
1075         'label': 'Catalog to search for MatricNo'},
1076        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
1077         'label': 'Results Catalog'},
1078         )
1079    matric_no_catalog = "" #the catalog to search for matric_no
1080    results_catalog = "results_import" #results catalog
1081
1082    def validate(self, datastructure, **kw):
1083        """Validate datastructure and update datamodel."""
1084        #import pdb;pdb.set_trace()
1085        valid = CPSStringWidget.validate(self, datastructure, **kw)
1086        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
1087        returning = getattr(self,self.matric_no_catalog)
1088        results = getattr(self,self.results_catalog,None)
1089        err = 0
1090        widget_id = self.getWidgetId()
1091        value = datastructure[widget_id]
1092        if not valid or not value:
1093            err = 'Invalid string'
1094            logger.info('Invalid matric_no string %s' % value)
1095        else:
1096            value = value.upper()
1097            datastructure['student'] = None
1098            while not err:
1099                res = returning(matric_no = value)
1100                if len(res) < 1:
1101                    logger.info('matric_no %s not found' % value)
1102                    err = 'No student with this matriculation number.'
1103                    break
1104                datastructure['student'] = res[0]
1105                if results is not None:
1106                    res = results(matric_no = value)
1107                    if len(res) < 1:
1108                        err = 'No results for this matriculation number'
1109                        continue
1110                    datastructure['results'] = res
1111                break
1112        if err:
1113            datastructure.setError(widget_id, err)
1114        else:
1115            datamodel = datastructure.getDataModel()
1116            datamodel[self.fields[0]] = value
1117        return not err
1118
1119InitializeClass(MatricNoWidget)
1120
1121widgetRegistry.register(MatricNoWidget)
1122###)
1123
1124class StudentIdWidget(CPSStringWidget): ###(
1125    """ StudentId Widget"""
1126    meta_type = "StudentId Widget"
1127    def validate(self, datastructure, **kw):
1128        """Validate datastructure and update datamodel."""
1129        valid = CPSStringWidget.validate(self, datastructure, **kw)
1130        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
1131        #import pdb;pdb.set_trace()
1132        s_cat = self.students_catalog
1133        err = 0
1134        widget_id = self.getWidgetId()
1135        value = datastructure[widget_id]
1136        if not valid or not value:
1137            err = 'Invalid Id string'
1138            logger.info('Invalid id string %s' % value)
1139            datastructure['student'] = None
1140        else:
1141            value = value.upper()
1142            res = s_cat(id = value)
1143            if not res:
1144                logger.info('Student id %s not found' % value)
1145                err = 'No student with this Id'
1146                datastructure['student'] = None
1147            else:
1148                datastructure['student'] = res[0]
1149        if err:
1150            datastructure.setError(widget_id, err)
1151        else:
1152            datamodel = datastructure.getDataModel()
1153            datamodel[self.fields[0]] = value
1154        return not err
1155
1156InitializeClass(StudentIdWidget)
1157
1158widgetRegistry.register(StudentIdWidget)
1159###)
1160
1161class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
1162    """ WAeUPMultilineResults Widget"""
1163    meta_type = "WAeUp Multiline Results Widget"
1164    _properties = CPSWidget._properties + (
1165        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
1166         'label': 'Nr of Lines'},
1167         )
1168    nr_of_lines = 5
1169    def prepare(self, datastructure, **kw): ###(
1170        """Prepare datastructure from datamodel."""
1171        datamodel = datastructure.getDataModel()
1172        #import pdb;pdb.set_trace()
1173        widget_id = self.getWidgetId()
1174        v = datamodel[self.fields[0]]
1175        if type(v) is ListType and v:
1176            nr_results = len(v)
1177        else:
1178            v = []
1179            nr_results = 0
1180        count = 1
1181        for s,g in v:
1182            wid = "%s%02d"% (widget_id,count)
1183            datastructure[wid+'_s'] = s
1184            datastructure[wid+'_g'] = g
1185            count += 1
1186        if nr_results < self.nr_of_lines:
1187            for line in range(nr_results,self.nr_of_lines):
1188                v.append(('',''))
1189                wid = "%s%02d"% (widget_id,line)
1190                datastructure[wid+'_s'] = ''
1191                datastructure[wid+'_g'] = ''
1192        datastructure[widget_id] = v
1193        datastructure[widget_id+'_s'] = ''
1194        datastructure[widget_id+'_g'] = ''
1195    ###)
1196
1197    def validate(self, datastructure, **kw): ###(
1198        """Validate datastructure and update datamodel."""
1199        #import pdb;pdb.set_trace()
1200        widget_id = self.getWidgetId()
1201        err = 0
1202        lines = []
1203        for line in range(1,30):
1204            wid = "%s%02d"% (widget_id,line)
1205            if not datastructure.has_key(wid+'_s'):
1206                break
1207            lines.append((datastructure[wid+'_s'].strip(),
1208                         datastructure[wid+'_g'].strip()))
1209
1210        s = datastructure[widget_id+'_s'].strip()
1211        g = datastructure[widget_id+'_g'].strip()
1212        if s and g:
1213            lines.append((s,g))
1214        active = []
1215        for s,g in lines:
1216            if g != "":
1217                active.append((s,g))
1218        if err:
1219            datastructure.setError(widget_id, err)
1220        else:
1221            datamodel = datastructure.getDataModel()
1222            datamodel[self.fields[0]] = active
1223        return not err
1224    ###)
1225
1226    def render(self, mode, datastructure, **kw): ###(
1227        """Render in mode from datastructure."""
1228        render_method = 'widget_waeup_multiline_result_render'
1229        meth = getattr(self, render_method, None)
1230        if meth is None:
1231            raise RuntimeError("Unknown Render Method %s for widget type %s"
1232                               % (render_method, self.getId()))
1233        #import pdb;pdb.set_trace()
1234        datamodel = datastructure.getDataModel()
1235        widget_id = self.getWidgetId()
1236        lines = datamodel[self.fields[0]]
1237        if len(lines) < self.nr_of_lines:
1238            for line in range(len(lines),self.nr_of_lines + 1):
1239                lines.append(('',''))
1240        datastructure[widget_id] = lines
1241        datastructure[widget_id+'_s'] = ''
1242        datastructure[widget_id+'_g'] = ''
1243##        count = 1
1244##        for s,g in v:
1245##            wid = "%s%02d"% (widget_id,count)
1246##            count += 1
1247        return meth(mode=mode,
1248                    datastructure=datastructure,
1249                    )
1250    ###)
1251
1252
1253InitializeClass(WAeUPMultilineResultsWidget)
1254widgetRegistry.register(WAeUPMultilineResultsWidget)
1255###)
1256
1257class WAeUPResultsWidget(CPSStringWidget): ###(
1258    """ WAeUPResults Widget"""
1259    meta_type = "WAeUp Results Widget"
1260
1261    def prepare(self, datastructure, **kw): ###(
1262        """Prepare datastructure from datamodel."""
1263        datamodel = datastructure.getDataModel()
1264        v = datamodel[self.fields[0]]
1265        #import pdb;pdb.set_trace()
1266        widget_id = self.getWidgetId()
1267        datastructure[widget_id] = v
1268        datastructure[widget_id+'_s'] = ''
1269        datastructure[widget_id+'_g'] = ''
1270    ###)
1271
1272    def validate(self, datastructure, **kw): ###(
1273        """Validate datastructure and update datamodel."""
1274        #import pdb;pdb.set_trace()
1275        widget_id = self.getWidgetId()
1276        v = datastructure[widget_id]
1277        if not v:
1278            v = []
1279        err = 0
1280        s = datastructure[widget_id+'_s'].strip()
1281        g = datastructure[widget_id+'_g'].strip()
1282        while 1:
1283            if not s and g:
1284                err = "No subject grade for subject"
1285                break
1286            i = 0
1287            done = False
1288            #import pdb;pdb.set_trace()
1289            for sv,gv in v:
1290                if sv == s:
1291                    done = True
1292                    if not g:
1293                        v.pop(i)
1294                        break
1295                    v[i] = (s,g)
1296                    break
1297                i += 1
1298            if done:
1299                break
1300            if s and g:
1301                if v:
1302                    v += (s,g),
1303                else:
1304                    v = [(s,g),]
1305            break
1306        if err:
1307            datastructure.setError(widget_id, err)
1308        else:
1309            datamodel = datastructure.getDataModel()
1310            datamodel[self.fields[0]] = v
1311            datastructure[widget_id] = v
1312            datastructure[widget_id+'_s'] = s
1313            datastructure[widget_id+'_g'] = g
1314        return not err
1315    ###)
1316
1317    def render(self, mode, datastructure, **kw): ###(
1318        """Render in mode from datastructure."""
1319        render_method = 'widget_waeup_result_render'
1320        meth = getattr(self, render_method, None)
1321        if meth is None:
1322            raise RuntimeError("Unknown Render Method %s for widget type %s"
1323                               % (render_method, self.getId()))
1324        datamodel = datastructure.getDataModel()
1325        widget_id = self.getWidgetId()
1326        datastructure[widget_id+'_s'] = ''
1327        datastructure[widget_id+'_g'] = ''
1328        return meth(mode=mode,
1329                    datastructure=datastructure,
1330                    )
1331    ###)
1332
1333
1334InitializeClass(WAeUPResultsWidget)
1335widgetRegistry.register(WAeUPResultsWidget)
1336###)
1337
1338class ScratchCardPin: ###(
1339    """the ScratchCardPin"""
1340    def __init__(self,prefix,batch_no,number):
1341        if not batch_no and not number:
1342            s = prefix
1343            if len(s) > 3:
1344                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1345            else:
1346                prefix,batch_no,number = s,'',''
1347        self.p = prefix
1348        self.b = batch_no
1349        self.n = number
1350
1351    def __str__(self):
1352        return "%s-%s-%s" % (self.p,self.b,self.n)
1353
1354    def __repr__(self):
1355        return "%s%s%s" % (self.p,self.b,self.n)
1356###)
1357
1358class ScratchcardPinWidget(CPSStringWidget): ###(
1359    """ ScratchcardPin Widget"""
1360    meta_type = "Scratchcard Pin Widget"
1361    _properties = CPSWidget._properties + (
1362        {'id': 'prefix', 'type': 'string', 'mode': 'w',
1363         'label': 'Prefix'},
1364         {'id': 'reference', 'type': 'string', 'mode': 'w',
1365         'label': 'Reference Field'},
1366         {'id': 'reuse_pin', 'type': 'boolean', 'mode': 'w',
1367         'label': 'Reuse Application Pin'},
1368        )
1369    prefix = ''
1370    reference = ''
1371    reuse_pin = False
1372
1373    def prepare(self, datastructure, **kw): ###(
1374        """Prepare datastructure from datamodel."""
1375        datamodel = datastructure.getDataModel()
1376        v = datamodel[self.fields[0]]
1377        widget_id = self.getWidgetId()
1378        if v and type(v) is StringType:
1379            try:
1380                p,b,n = v.split('-')
1381                v = ScratchCardPin(p,b,n)
1382            except ValueError:
1383                v = ScratchCardPin(v,'','')
1384        if v:
1385            p = '%s' % v.p
1386            b = '%s' % v.b
1387            n = '%s' % v.n
1388        else:
1389            p = self.prefix
1390            if p.startswith('@'):
1391                p = getattr(self,self.prefix[1:])()
1392            b = n = ''
1393            v = ScratchCardPin(p,b,n)
1394        datastructure[widget_id] = v
1395        datastructure[widget_id+'_p'] = p
1396        datastructure[widget_id+'_b'] = b
1397        datastructure[widget_id+'_n'] = n
1398    ###)
1399
1400    def validate(self, datastructure, **kw): ###(
1401        """Validate datastructure and update datamodel."""
1402        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1403        widget_id = self.getWidgetId()
1404        v = datastructure[widget_id]
1405        #import pdb;pdb.set_trace()
1406        err = 0
1407        mapping = {}
1408        prefix= self.prefix
1409        if prefix.startswith('@'):
1410            prefix= getattr(self,self.prefix[1:])()
1411        b = datastructure[widget_id+'_b'].strip()
1412        n = datastructure[widget_id+'_n'].strip()
1413        pins = self.portal_pins
1414        pin = "%(prefix)s%(b)s%(n)s" % vars()
1415        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1416        do = 1
1417        s_id = str(self.portal_membership.getAuthenticatedMember())
1418        if self.isStaff():
1419            do = 0
1420            err ='You are not a Student. PIN neither checked nor used.'
1421            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1422        elif len(b) > 1 and b.find('-') > -1:
1423            do = 0
1424            err = 'PIN must not contain "-".'
1425            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1426        elif n.find('-') > -1:
1427            do = 0
1428            err = 'PIN must not contain "-".'
1429            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1430        elif len(n) != 10:
1431            do = 0
1432            err = 'Invalid PIN length'
1433            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1434        elif self.reference == "":
1435            ref = s_id
1436        else:
1437            ref = datastructure[self.reference]
1438            if datastructure.errors:
1439                do = 0
1440                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1441                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1442            elif prefix == 'APP' and not self.reuse_pin:
1443                res =  self.applicants_catalog(reg_no = ref)
1444                if not res:
1445                    res =  self.applicants_catalog(reg_no = ref.upper())
1446                if res and res[0].pin == pin_str:
1447                    do = 0
1448                    err = 'Application PINs cannot be reused.'
1449                    s_logger.info('%s entered same PIN as for screening application %s' % (s_id,pin_str))
1450
1451        while do:
1452            ok,record = pins.searchAndSetRecord(pin,ref,prefix)
1453            if ok < -2 or ok > 2:
1454                err = 'Unknown error, please report!'
1455                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1456                break
1457            elif ok == -2:
1458                err = 'Service already is activated but with a different PIN.'
1459                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1460                break
1461            elif ok == -1:
1462                err = 'Invalid PIN'
1463                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1464                break
1465            if ok == 0:
1466                err = 'PIN already used'
1467                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1468                break
1469            if ok >= 1:
1470                #import pdb;pdb.set_trace()
1471                if self.isStudent():
1472                    if self.reference == "jamb_reg_no":
1473                        err = "You are already logged in."
1474                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1475                        break
1476                    if ok == 1:
1477                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1478                    else:
1479                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1480                    break
1481                else:
1482                    student = getStudentByRegNo(self,ref)
1483                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1484                if student is None:
1485                    err = "Student record not found."
1486                    s_logger.info('%s not found in admission list' % (ref))
1487                    break
1488                s_id = student.getId()
1489                if ok == 2:
1490                    if self.reference == "jamb_reg_no":
1491                        if hasattr(self.portal_directories.students,s_id):
1492                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1493                            mapping = {'id': s_id}
1494                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1495                            break
1496                        else:
1497                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1498                    else:
1499                        err = "Unknown error"
1500                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1501                        break
1502                try:
1503                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1504                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1505                except:
1506                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1507                    mapping = {'id': s_id}
1508                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1509                    break
1510            break
1511        if err:
1512            datastructure.setError(widget_id, err,mapping)
1513        else:
1514            datamodel = datastructure.getDataModel()
1515            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1516            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1517            datastructure[widget_id+'_p'] = prefix
1518            datastructure[widget_id+'_b'] = b
1519            datastructure[widget_id+'_n'] = n
1520            datastructure['s_id'] = s_id
1521        return not err
1522
1523###)
1524
1525    def render(self, mode, datastructure, **kw): ###(
1526        """Render in mode from datastructure."""
1527        render_method = 'widget_scratch_card_pin_render'
1528        meth = getattr(self, render_method, None)
1529        if meth is None:
1530            raise RuntimeError("Unknown Render Method %s for widget type %s"
1531                               % (render_method, self.getId()))
1532
1533        # XXX AT: datastructure has to be set again here, in case we're in edit
1534        # or create mode, because a default value has to be provided.
1535        #import pdb;pdb.set_trace()
1536        datamodel = datastructure.getDataModel()
1537        v = datamodel[self.fields[0]]
1538        if v and type(v) is StringType:
1539            try:
1540                p,b,n = v.split('-')
1541                v = ScratchCardPin(p,b,n)
1542            except ValueError:
1543                v = ScratchCardPin(self.prefix,'XXX',v)
1544                pass
1545        if v:
1546            prefix= '%s' % v.p
1547            b = '%s' % v.b
1548            n = '%s' % v.n
1549        else:
1550            prefix= self.prefix
1551            if prefix.startswith('@'):
1552                prefix= getattr(self,self.prefix[1:])()
1553            b = n = ''
1554            v = ScratchCardPin(prefix,b,n)
1555        widget_id = self.getWidgetId()
1556        datastructure[widget_id] = v
1557        datastructure[widget_id+'_p'] = prefix
1558        datastructure[widget_id+'_b'] = b
1559        datastructure[widget_id+'_n'] = n
1560        return meth(mode=mode,
1561                    datastructure=datastructure,
1562                    )
1563    ###)
1564
1565InitializeClass(ScratchcardPinWidget)
1566widgetRegistry.register(ScratchcardPinWidget)
1567###)
1568
1569class PumePinWidget(ScratchcardPinWidget): ###(
1570    """ Pume Pin Widget"""
1571    meta_type = "Pume Pin Widget"
1572    catalog = "applicants_catalog"
1573    reference = ''
1574
1575    def prepare(self, datastructure, **kw): ###(
1576        """Prepare datastructure from datamodel."""
1577        datamodel = datastructure.getDataModel()
1578        #import pdb;pdb.set_trace()
1579        v = datamodel[self.fields[0]]
1580        widget_id = self.getWidgetId()
1581        if v and type(v) is StringType:
1582            try:
1583                p,b,n = v.split('-')
1584                v = ScratchCardPin(p,b,n)
1585            except ValueError:
1586                v = ScratchCardPin(v,'','')
1587        if v:
1588            p = '%s' % v.p
1589            b = '%s' % v.b
1590            n = '%s' % v.n
1591        else:
1592            p = self.prefix
1593            if p.startswith('@'):
1594                p = getattr(self,self.prefix[1:])()
1595            b = n = ''
1596            v = ScratchCardPin(p,b,n)
1597        datastructure[widget_id] = v
1598        datastructure[widget_id+'_p'] = p
1599        datastructure[widget_id+'_b'] = b
1600        datastructure[widget_id+'_n'] = n
1601    ###)
1602
1603    def validate(self, datastructure, **kw): ###(
1604        """Validate datastructure and update datamodel."""
1605        s_logger = logging.getLogger('Widgets.PumePinWidget.validate')
1606        widget_id = self.getWidgetId()
1607        v = datastructure[widget_id]
1608        err = 0
1609        mapping = {}
1610        prefix= self.prefix
1611        if prefix.startswith('@'):
1612            prefix= getattr(self,self.prefix[1:])()
1613        b = datastructure[widget_id+'_b'].strip()
1614        n = datastructure[widget_id+'_n'].strip()
1615        pins = self.portal_pins
1616        pin = "%(prefix)s%(b)s%(n)s" % vars()
1617        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1618        member_id = str(self.portal_membership.getAuthenticatedMember())
1619        do = 1
1620        expiration_date = self.REQUEST.get('expiration_date')
1621        if self.isStaff():
1622            do = 0
1623            err ='You are logged in, please log out. PIN neither checked nor used.'
1624            s_logger.info('%s tried to use scratch card %s' % (member_id,pin_str))
1625        elif self.isStudent():
1626            do = 0
1627            #ref = datastructure[self.reference]
1628            err ='You are logged in, please log out. PIN neither checked nor used.'
1629            s_logger.info('%s applied for screening test while logged in with pin %s' % (member_id,pin_str))
1630        elif len(b) > 1 and b.find('-') > -1:
1631            do = 0
1632            err = 'PIN must not contain "-"'
1633            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1634        elif n.find('-') > -1:
1635            do = 0
1636            err = 'PIN must not contain "-"'
1637            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1638        elif len(n) != 10:
1639            do = 0
1640            err = 'Invalid PIN length'
1641            s_logger.info('%s entered invalid PIN with length %d' % (member_id,len(n)))
1642        elif self.reference == "":
1643            ref = n
1644        else:
1645            ref = datastructure[self.reference]
1646            if datastructure.errors:
1647                do = 0
1648                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1649                s_logger.info('%s/%s entered wrong data together with PIN %s' % (member_id,ref,pin_str))
1650        while do:
1651            if self.REQUEST.traverse_subpath:
1652                screening_type_request = self.REQUEST.traverse_subpath[0]
1653            else:
1654                screening_type_request = 'manage'
1655            if datastructure.has_key('record'):
1656                applicant = datastructure['record']
1657                if applicant.screening_type != screening_type_request and screening_type_request != 'manage':
1658                    err = "You are using the wrong access form!"
1659                    s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1660                    break
1661            elif expiration_date and DateTime(expiration_date).lessThan(DateTime()):
1662                if not pins(student=ref):
1663                    if not self.applicants_catalog(reg_no=ref):
1664                        err = 'no application record found'
1665                        s_logger.info('%s/%s tried new application though expired with PIN %s' % (member_id,ref,pin_str))
1666                        break
1667                    else:
1668                        s_logger.info('%s/%s entered application record which has been created by import (with PIN %s)' % (member_id,ref,pin_str))
1669            ok,pin_record = pins.searchAndSetRecord(pin,ref,prefix)
1670            if ok < -2 or ok > 2:
1671                err = 'Unknown error, please report!'
1672                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
1673                break
1674            elif ok == -2:
1675                err = 'Service is already activated but with a different PIN.'
1676                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
1677                break
1678            elif ok == -1:
1679                err = 'Invalid PIN'
1680                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
1681                break
1682            if ok == 0:
1683                err = 'PIN already used'
1684                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
1685                break
1686            if ok >= 1:
1687                #screening_type = self.REQUEST.form.get('screening_type','unknown')
1688                #screening_type = datastructure['screening_type']
1689                if datastructure.has_key('record'):
1690                    applicant = datastructure['record']
1691                    if applicant.screening_type != screening_type_request\
1692                          and screening_type_request != 'manage':
1693                        err = "You are using the wrong access form!"
1694                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1695                        break
1696                    if not applicant.pin:
1697                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1698                        d = {}
1699                        d['reg_no'] = applicant.reg_no
1700                        d['pin'] = pin_str
1701                        #d['screening_type'] = screening_type
1702                        #d['status'] = 'entered'
1703                        getattr(self,self.catalog).modifyRecord(**d)
1704                    elif applicant.pin != pin_str:
1705                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
1706                    elif applicant.pin == pin_str:
1707                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1708                else:
1709                    datastructure['reg_no'] = ref
1710                    res = self.applicants_catalog(reg_no = ref)
1711                    if res:
1712                        if getattr(res[0],'screening_type',None) != screening_type_request\
1713                              and screening_type_request != 'manage':
1714                            err = "You are using the wrong access form!"
1715                            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)))
1716                            break
1717                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1718                    else:
1719                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1720                        d = {}
1721                        d['reg_no'] = ref
1722                        d['pin'] = pin_str
1723                        d['status'] = 'entered'
1724                        d['screening_type'] = screening_type_request
1725                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
1726                                                  pin_record.serial)
1727                        self.applicants_catalog.addRecord(**d)
1728
1729            break
1730        if err:
1731            datastructure.setError(widget_id, err,mapping)
1732        else:
1733            datamodel = datastructure.getDataModel()
1734            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1735            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1736            datastructure[widget_id+'_p'] = prefix
1737            datastructure[widget_id+'_b'] = b
1738            datastructure[widget_id+'_n'] = n
1739        return not err
1740    ###)
1741
1742    def render(self, mode, datastructure, **kw): ###(
1743        """Render in mode from datastructure."""
1744        render_method = 'widget_scratch_card_pin_render'
1745        meth = getattr(self, render_method, None)
1746        if meth is None:
1747            raise RuntimeError("Unknown Render Method %s for widget type %s"
1748                               % (render_method, self.getId()))
1749
1750        # XXX AT: datastructure has to be set again here, in case we're in edit
1751        # or create mode, because a default value has to be provided.
1752        #import pdb;pdb.set_trace()
1753        datamodel = datastructure.getDataModel()
1754        v = datamodel[self.fields[0]]
1755        #import pdb;pdb.set_trace()
1756        if v and type(v) is StringType:
1757            try:
1758                p,b,n = v.split('-')
1759                v = ScratchCardPin(p,b,n)
1760            except ValueError:
1761                v = ScratchCardPin(self.prefix,'XXX',v)
1762                pass
1763        if v:
1764            prefix= '%s' % v.p
1765            b = '%s' % v.b
1766            n = '%s' % v.n
1767        else:
1768            prefix= self.prefix
1769            if prefix.startswith('@'):
1770                prefix= getattr(self,self.prefix[1:])()
1771            b = n = ''
1772            v = ScratchCardPin(prefix,b,n)
1773        widget_id = self.getWidgetId()
1774        datastructure[widget_id] = v
1775        datastructure[widget_id+'_p'] = prefix
1776        datastructure[widget_id+'_b'] = b
1777        datastructure[widget_id+'_n'] = n
1778        return meth(mode=mode,
1779                    datastructure=datastructure,
1780                    )
1781    ###)
1782
1783InitializeClass(PumePinWidget)
1784widgetRegistry.register(PumePinWidget)
1785###)
1786
1787class WAeUPImageWidget(CPSImageWidget): ###(
1788    """Photo widget."""
1789    meta_type = 'WAeUP Image Widget'
1790
1791    def render(self, mode, datastructure, **kw):
1792        render_method = 'widget_waeup_image_render'
1793        meth = getattr(self, render_method, None)
1794        if meth is None:
1795            raise RuntimeError("Unknown Render Method %s for widget type %s"
1796                               % (render_method, self.getId()))
1797        img_info = self.getImageInfo(datastructure)
1798        return meth(mode=mode, datastructure=datastructure, **img_info)
1799
1800InitializeClass(WAeUPImageWidget)
1801
1802widgetRegistry.register(WAeUPImageWidget)
1803###)
1804
1805class ApplicationImageWidget(CPSImageWidget): ###(
1806    """Image widget with filesystem storage."""
1807    meta_type = 'Application Image Widget'
1808    _properties = CPSImageWidget._properties +\
1809    (
1810     {'id': 'path', 'type': 'string', 'mode': 'w',
1811      'label': 'Relative Path'},
1812     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1813      'label': 'Field to build the id'},
1814    )
1815    path = "images"
1816    storage_path = "%s/import/%s" % (i_home,path)
1817    id_field = "reg_no"
1818
1819    def getImageInfo(self, datastructure): ###(
1820        """Get the file info from the datastructure."""
1821        widget_id = self.getWidgetId()
1822        if  datastructure.has_key(widget_id):
1823            fileupload = datastructure[widget_id]
1824            dm = datastructure.getDataModel()
1825            field_id = self.fields[0]
1826            screening_type = datastructure.get('screening_type')
1827            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1828                                            field_id,)
1829            base_path = os.path.join(screening_type,current_filename)
1830            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1831            file_path = os.path.join(self.storage_path,base_path)
1832            #import pdb; pdb.set_trace()
1833        else:
1834            file_path = "XXX"
1835        # read the file from the filesystem
1836        if not os.path.exists(file_path):
1837            height = -1
1838            width = -1
1839            empty_file = True
1840            session_file = False
1841            current_filename = ''
1842            content_url = ''
1843            size = 0
1844            mimetype = ''
1845            last_modified = ''
1846            height = ''
1847            width = ''
1848
1849        else:
1850            image = open(file_path)
1851            from OFS.Image import getImageInfo as getImageInfoOFS
1852            image.seek(0)
1853            data = image.read(2000)
1854            size = len(data)
1855            empty_file = size == 0
1856            session_file = False
1857            last_modified = ''
1858            image.close()
1859            mimetype, width, height = getImageInfoOFS(data)
1860
1861            if width < 0:
1862                width = None
1863            if height < 0:
1864                height = None
1865
1866            if (self.allow_resize
1867                and height is not None
1868                and width  is not None):
1869                z_w = z_h = 1
1870                h = int(self.display_height)
1871                w = int(self.display_width)
1872                if w and h:
1873                    if w < width:
1874                        z_w = w / float(width)
1875                    if h < height:
1876                        z_h = h / float(height)
1877                    zoom = min(z_w, z_h)
1878                    width = int(zoom * width)
1879                    height = int(zoom * height)
1880                #import pdb;pdb.set_trace()
1881        image_info = {
1882            'empty_file': empty_file,
1883            'session_file': session_file,
1884            'current_filename': current_filename,
1885            'size': size,
1886            'last_modified': last_modified,
1887            'content_url': content_url,
1888            'mimetype': mimetype,
1889            }
1890        title = image_info['current_filename']
1891        alt = title or ''
1892        #height = int(self.display_height)
1893        #width = int(self.display_width)
1894        if height is None or width is None:
1895            tag = renderHtmlTag('img', src=image_info['content_url'],
1896                                alt=alt, title=title)
1897        else:
1898            tag = renderHtmlTag('img', src=image_info['content_url'],
1899                                width=str(width), height=str(height),
1900                                alt=alt, title=title)
1901
1902        image_info['height'] = height
1903        image_info['width'] = width
1904        image_info['image_tag'] = tag
1905        return image_info
1906    ###)
1907
1908    def checkFileName(self, filename, mimetype):
1909        return '', {}
1910        if mimetype and mimetype.startswith('image'):
1911            return '', {}
1912        return 'cpsschemas_err_image', {}
1913
1914    def prepare(self, datastructure, **kw): ###(
1915        """Prepare datastructure from datamodel."""
1916        datamodel = datastructure.getDataModel()
1917        widget_id = self.getWidgetId()
1918        file_name = datamodel[self.fields[0]]
1919        #import pdb; pdb.set_trace()
1920        if self.allow_resize:
1921            datastructure[self.getWidgetId() + '_resize'] = ''
1922        screening_type = datamodel.get('screening_type',None)
1923        if not screening_type:
1924            screening_type = self.REQUEST.form.get('screening_type','pume')
1925        datastructure["screening_type"] = screening_type
1926        datastructure[widget_id] = file_name
1927        datastructure[widget_id + '_choice'] = 'change'
1928        title = 'Passport Foto'
1929        datastructure[widget_id + '_filename'] = title
1930    ###)
1931
1932    def validate(self, datastructure, **kw): ###(
1933        """Update datamodel from user data in datastructure.
1934        """
1935        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1936        datamodel = datastructure.getDataModel()
1937        field_id = self.fields[0]
1938        widget_id = self.getWidgetId()
1939        store = False
1940        fileupload = None
1941        mimetype = None
1942        old_file = datamodel[field_id]
1943        # if old_file is not None:
1944        #     old_filename = old_file.title
1945        # else:
1946        #     old_filename = ''
1947        choice = datastructure[widget_id+'_choice']
1948        fileupload = datastructure[widget_id]
1949        is_upload = isinstance(fileupload, FileUpload)
1950        #import pdb; pdb.set_trace()
1951        if not is_upload and not datamodel[field_id]:
1952            if self.is_required:
1953                return self.validateError('Picture upload required', {},
1954                                          datastructure)
1955        if choice == 'delete':
1956            if self.is_required:
1957                return self.validateError('cpsschemas_err_required', {},
1958                                          datastructure)
1959            datamodel[field_id] = None
1960        elif choice == 'keep':
1961            fileupload = datastructure[widget_id]
1962            if isinstance(fileupload, PersistableFileUpload):
1963                # Keeping something from the session means we
1964                # actually want to store it.
1965                store = True
1966            # else:
1967            #     # Nothing to change, don't pollute datastructure
1968            #     # with something costly already stored, which therefore
1969            #     # doesn't need to be kept in the session.
1970            #     self.unprepare(datastructure)
1971        elif choice == 'change' and is_upload:
1972            if not fileupload:
1973                return self.validateError('cpsschemas_err_file_empty', {},
1974                                          datastructure)
1975            if not isinstance(fileupload, FileUpload):
1976                return self.validateError('cpsschemas_err_file', {},
1977                                          datastructure)
1978            fileupload.seek(0, 2) # end of file
1979            size = fileupload.tell()
1980            if not size:
1981                return self.validateError('cpsschemas_err_file_empty', {},
1982                                          datastructure)
1983            if self.size_max and size > self.size_max:
1984                max_size_str = self.getHumanReadableSize(self.size_max)
1985                err = 'This file is too big, the allowed max size is ${max_size}'
1986                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1987                err_mapping = {'max_size': max_size_str}
1988                return self.validateError(err, err_mapping, datastructure)
1989            store = True
1990
1991
1992        # Find filename
1993        if is_upload and store:
1994            ext ='jpg'
1995            screening_type = datastructure.get('screening_type')
1996            filename = "%s_%s.%s" % (datastructure[self.id_field],
1997                                     self.getWidgetId(),
1998                                     ext)
1999            datamodel[field_id] = filename
2000            registry = getToolByName(self, 'mimetypes_registry')
2001            mimetype = registry.lookupExtension(filename.lower())
2002            if mimetype is not None:
2003                mimetype = str(mimetype) # normalize
2004            file = self.makeFile(filename, fileupload, datastructure)
2005            # Fixup mimetype
2006            if mimetype and file.content_type != mimetype:
2007                file.content_type = mimetype
2008            # Store the file in the filesystem
2009            #import pdb;pdb.set_trace()
2010            base_path = os.path.join(self.storage_path, screening_type)
2011            if not os.path.exists(base_path):
2012                os.mkdir(base_path)
2013            full_path = os.path.join(base_path, filename)
2014            pict = open(full_path,"w")
2015            fileupload.seek(0)
2016            pict.write(fileupload.read())
2017            pict.close()
2018
2019
2020        return True
2021
2022###)
2023
2024    def render(self, mode, datastructure, **kw): ###(
2025        render_method = 'widget_passport_render'
2026        meth = getattr(self, render_method, None)
2027        if meth is None:
2028            raise RuntimeError("Unknown Render Method %s for widget type %s"
2029                               % (render_method, self.getId()))
2030        img_info = self.getImageInfo(datastructure)
2031        return meth(mode=mode, datastructure=datastructure, **img_info)
2032    ###)
2033
2034InitializeClass(ApplicationImageWidget)
2035
2036widgetRegistry.register(ApplicationImageWidget)
2037###)
2038
2039class FileImageWidget(CPSImageWidget): ###(
2040    """Image widget with filesystem storage."""
2041    meta_type = 'File Image Widget'
2042    _properties = CPSImageWidget._properties +\
2043    (
2044     {'id': 'path', 'type': 'string', 'mode': 'w',
2045      'label': 'Relative Path'},
2046     {'id': 'id_field', 'type': 'string', 'mode': 'w',
2047      'label': 'Field to build the id'},
2048     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
2049      'label': 'Show Image'},
2050    )
2051    path = "images"
2052    #storage_path = "%s/%s" % (i_home,path)
2053    id_field = ""
2054    show_image = False
2055
2056    def getStorageImageInfo(self,field_id):
2057        info = {}
2058        if self.id_field == "":
2059            student_id = self.getStudentId()
2060        else:
2061            student_id = datastructure[self.id_field]
2062        # student_path = os.path.join(self.storage_path,
2063        #                             student_id)
2064        student_path = getImagesDir(student_id)
2065        image_name = ''
2066        content_url = ''
2067        current_filename = ''
2068        if os.path.exists(student_path):
2069            for name in os.listdir(student_path):
2070                if name.startswith(field_id):
2071                    image_name = name
2072                    break
2073        if image_name:
2074            info['image_name'] = image_name
2075            info['content_url'] = os.path.join(self.portal_url(),
2076                                               "viewimage",
2077                                               student_id,
2078                                               image_name,
2079                                              )
2080            info['current_filename'] =  image_name
2081            info['file_path'] = os.path.join(student_path, image_name)
2082        return info
2083
2084    def getImageInfo(self, datastructure): ###(
2085        """Get the file info from the datastructure."""
2086        widget_id = self.getWidgetId()
2087        info = None
2088        if  datastructure.has_key(widget_id):
2089            fileupload = datastructure[widget_id]
2090            dm = datastructure.getDataModel()
2091            field_id = self.fields[0]
2092            info = self.getStorageImageInfo(field_id)
2093        else:
2094            file_path = "XXX"
2095            title = ""
2096        # read the file from the filesystem
2097        #import pdb; pdb.set_trace()
2098        #if not os.path.exists(file_path):
2099        if not info:
2100            title = ""
2101            height = -1
2102            width = -1
2103            empty_file = True
2104            session_file = False
2105            current_filename = ''
2106            content_url = ''
2107            size = 0
2108            mimetype = ''
2109            last_modified = ''
2110            height = ''
2111            width = ''
2112        else:
2113            title = info['image_name']
2114            current_filename = info['current_filename']
2115            content_url = info['content_url']
2116            image = open(info['file_path'])
2117            from OFS.Image import getImageInfo as getImageInfoOFS
2118            image.seek(0)
2119            data = image.read(2000)
2120            size = len(data)
2121            empty_file = size == 0
2122            session_file = False
2123            last_modified = ''
2124            image.close()
2125            mimetype, width, height = getImageInfoOFS(data)
2126            registry = getToolByName(self, 'mimetypes_registry')
2127            mimetype = (registry.lookupExtension(current_filename.lower()) or
2128                        registry.lookupExtension('file.bin'))
2129            if width < 0:
2130                width = None
2131            if height < 0:
2132                height = None
2133
2134            if (self.allow_resize
2135                and height is not None
2136                and width  is not None):
2137                z_w = z_h = 1
2138                h = int(self.display_height)
2139                w = int(self.display_width)
2140                if w and h:
2141                    if w < width:
2142                        z_w = w / float(width)
2143                    if h < height:
2144                        z_h = h / float(height)
2145                    zoom = min(z_w, z_h)
2146                    width = int(zoom * width)
2147                    height = int(zoom * height)
2148                #import pdb;pdb.set_trace()
2149        image_info = {
2150            'empty_file': empty_file,
2151            'session_file': session_file,
2152            'current_filename': title,
2153            'size': size,
2154            'last_modified': last_modified,
2155            'content_url': content_url,
2156            'mimetype': mimetype,
2157            }
2158        alt = title or ''
2159        #height = int(self.display_height)
2160        #width = int(self.display_width)
2161        if height is None or width is None:
2162            tag = renderHtmlTag('img', src=image_info['content_url'],
2163                                alt=alt, title=title)
2164        else:
2165            tag = renderHtmlTag('img', src=image_info['content_url'],
2166                                width=str(width), height=str(height),
2167                                alt=alt, title=title)
2168
2169        image_info['height'] = height
2170        image_info['width'] = width
2171        image_info['image_tag'] = tag
2172        image_info['show_image'] = self.show_image
2173        return image_info
2174    ###)
2175
2176    # def checkFileName(self, filename, mimetype):
2177    #     return '', {}
2178    #     if mimetype and mimetype.startswith('image'):
2179    #         return '', {}
2180    #     return 'cpsschemas_err_image', {}
2181
2182    def prepare(self, datastructure, **kw): ###(
2183        """Prepare datastructure from datamodel."""
2184        datamodel = datastructure.getDataModel()
2185        widget_id = self.getWidgetId()
2186        file_name = datamodel[self.fields[0]]
2187        if self.id_field == "":
2188            student_id = self.getStudentId()
2189        else:
2190            student_id = datastructure[self.id_field]
2191        if student_id is not None:
2192            # student_path = os.path.join(self.storage_path,
2193            #                             student_id)
2194            student_path = getImagesDir(student_id)
2195            if not os.path.exists(student_path):
2196                self.waeup_tool.moveImagesToFS(student_id)
2197        if self.allow_resize:
2198            datastructure[self.getWidgetId() + '_resize'] = ''
2199        datastructure[widget_id] = file_name
2200        datastructure[widget_id + '_choice'] = 'change'
2201        title = 'Passport Foto'
2202        datastructure[widget_id + '_filename'] = title
2203    ###)
2204
2205    def validate(self, datastructure, **kw): ###(
2206        """Update datamodel from user data in datastructure.
2207        """
2208        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2209        datamodel = datastructure.getDataModel()
2210        field_id = self.fields[0]
2211        widget_id = self.getWidgetId()
2212        store = False
2213        fileupload = None
2214        mimetype = None
2215        old_file = datamodel[field_id]
2216        choice = datastructure[widget_id+'_choice']
2217        fileupload = datastructure[widget_id]
2218        is_upload = isinstance(fileupload, FileUpload)
2219        #import pdb; pdb.set_trace()
2220        if not is_upload and not datamodel[field_id]:
2221            if self.is_required:
2222                return self.validateError('Picture upload required', {},
2223                                          datastructure)
2224        if self.id_field == "":
2225            student_id = self.getStudentId()
2226        else:
2227            student_id = datastructure[self.id_field]
2228        if choice == 'delete':
2229            if self.is_required:
2230                return self.validateError('cpsschemas_err_required', {},
2231                                          datastructure)
2232            info= self.getStorageImageInfo(field_id)
2233            # Remove the file in the filesystem
2234            if info:
2235                os.remove(info['file_path'])
2236            datamodel[field_id] = None
2237        elif choice == 'keep':
2238            fileupload = datastructure[widget_id]
2239            if isinstance(fileupload, PersistableFileUpload):
2240                # Keeping something from the session means we
2241                # actually want to store it.
2242                store = True
2243            # else:
2244            #     # Nothing to change, don't pollute datastructure
2245            #     # with something costly already stored, which therefore
2246            #     # doesn't need to be kept in the session.
2247            #     self.unprepare(datastructure)
2248        elif choice == 'change' and is_upload:
2249            if not fileupload:
2250                return self.validateError('cpsschemas_err_file_empty', {},
2251                                          datastructure)
2252            if not isinstance(fileupload, FileUpload):
2253                return self.validateError('cpsschemas_err_file', {},
2254                                          datastructure)
2255            fileupload.seek(0, 2) # end of file
2256            size = fileupload.tell()
2257            if not size:
2258                return self.validateError('cpsschemas_err_file_empty', {},
2259                                          datastructure)
2260            if self.size_max and size > self.size_max:
2261                max_size_str = self.getHumanReadableSize(self.size_max)
2262                err = 'This file is too big, the allowed max size is ${max_size}'
2263                member_id = str(self.portal_membership.getAuthenticatedMember())
2264                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2265                err_mapping = {'max_size': max_size_str}
2266                return self.validateError(err, err_mapping, datastructure)
2267            store = True
2268
2269
2270        # Find filename
2271        if is_upload and store:
2272            filename = cookId('', '', fileupload)[0].strip()
2273            base,ext = os.path.splitext(filename)
2274            filename = "%s_%s%s" % (field_id,
2275                                    student_id,
2276                                    ext)
2277            datamodel[field_id] = filename
2278            registry = getToolByName(self, 'mimetypes_registry')
2279            mimetype = registry.lookupExtension(filename.lower())
2280            if mimetype is not None:
2281                mimetype = str(mimetype) # normalize
2282            file = self.makeFile(filename, fileupload, datastructure)
2283            # Fixup mimetype
2284            if mimetype and file.content_type != mimetype:
2285                file.content_type = mimetype
2286            # Store the file in the filesystem
2287            #student_path = os.path.join(self.storage_path,student_id)
2288            student_path = getImagesDir(student_id)
2289            if not os.path.exists(student_path):
2290                os.mkdir(student_path)
2291            full_path = os.path.join(student_path, filename)
2292            pict = open(full_path,"w")
2293            #fileupload.seek(0)
2294            #import pdb; pdb.set_trace()
2295            pict.write(str(file.data))
2296            pict.close()
2297        return True
2298    ###)
2299
2300    def render(self, mode, datastructure, **kw): ###(
2301        render_method = 'widget_image_render'
2302        meth = getattr(self, render_method, None)
2303        #import pdb;pdb.set_trace()
2304        if meth is None:
2305            raise RuntimeError("Unknown Render Method %s for widget type %s"
2306                               % (render_method, self.getId()))
2307        img_info = self.getImageInfo(datastructure)
2308        return meth(mode=mode, datastructure=datastructure, **img_info)
2309    ###)
2310
2311InitializeClass(FileImageWidget)
2312
2313widgetRegistry.register(FileImageWidget)
2314###)
2315
2316class DiscFileWidget(CPSFileWidget): ###(
2317    """File widget with filesystem storage."""
2318    meta_type = 'Disc File Widget'
2319    _properties = CPSFileWidget._properties +\
2320    (
2321     {'id': 'path', 'type': 'string', 'mode': 'w',
2322      'label': 'Relative Path'},
2323    )
2324    path = "import"
2325    storage_path = "%s/%s" % (i_home,path)
2326
2327    def getStoredFileInfo(self,datastructure): ###(
2328        datamodel = datastructure.getDataModel()
2329        field_id = self.fields[0]
2330        widget_id = self.getWidgetId()
2331        file_name = datamodel[field_id]
2332        info = {}
2333        registry = getToolByName(self, 'mimetypes_registry')
2334        info['mimetype'] = registry.lookupExtension('file.csv')
2335        info['empty_file'] = True
2336        info['size'] = 0
2337        info['last_modified'] = ''
2338        file_path = os.path.join(self.storage_path, file_name)
2339        if os.path.exists(file_path):
2340            info['empty_file'] = False
2341            info['file_name'] = file_name
2342            info['content_url'] = os.path.join(self.portal_url(),
2343                                            "viewfile",
2344                                            file_name,
2345                                            )
2346            info['current_filename'] =  file_name
2347            # get the mimetype
2348            mimetype = (registry.lookupExtension(file_name.lower()) or
2349                        registry.lookupExtension('file.bin'))
2350            info['mimetype'] = mimetype
2351            info['file_path'] = file_path
2352        else:
2353            info['file_name'] = ''
2354            info['content_url'] = ''
2355            info['current_filename'] = ''
2356            info['file_path'] = ''
2357        return info
2358        ###)
2359
2360    def prepare(self, datastructure, **kw): ###(
2361        """Prepare datastructure from datamodel."""
2362        datamodel = datastructure.getDataModel()
2363        #import pdb;pdb.set_trace()
2364        widget_id = self.getWidgetId()
2365        file_name = datamodel[self.fields[0]]
2366        datastructure[widget_id] = file_name
2367        datastructure[widget_id + '_filename'] = file_name
2368        datastructure[widget_id+'_choice'] = "keep"
2369    ###)
2370
2371    def validate(self, datastructure, **kw): ###(
2372        """Update datamodel from user data in datastructure.
2373        """
2374        logger = logging.getLogger('Widgets.DiscFileWidget.validate')
2375        datamodel = datastructure.getDataModel()
2376        field_id = self.fields[0]
2377        widget_id = self.getWidgetId()
2378        store = False
2379        fileupload = None
2380        mimetype = None
2381        old_file = datamodel[field_id]
2382        choice = datastructure[widget_id+'_choice']
2383        fileupload = datastructure[widget_id]
2384        is_upload = isinstance(fileupload, FileUpload)
2385        if not is_upload and not datamodel[field_id]:
2386            if self.is_required:
2387                return self.validateError('File upload required', {},
2388                                          datastructure)
2389        if choice == 'delete':
2390            if self.is_required:
2391                return self.validateError('cpsschemas_err_required', {},
2392                                          datastructure)
2393            info = self.getStoredFileInfo(datastructure)
2394            # Remove the file in the filesystem
2395            if info:
2396                os.remove(info['file_path'])
2397            datamodel[field_id] = None
2398        elif choice == 'keep':
2399            fileupload = datastructure[widget_id]
2400            if isinstance(fileupload, PersistableFileUpload):
2401                # Keeping something from the session means we
2402                # actually want to store it.
2403                store = True
2404            # else:
2405            #     # Nothing to change, don't pollute datastructure
2406            #     # with something costly already stored, which therefore
2407            #     # doesn't need to be kept in the session.
2408            #     self.unprepare(datastructure)
2409        elif choice == 'change' and is_upload:
2410            if not fileupload:
2411                return self.validateError('cpsschemas_err_file_empty', {},
2412                                          datastructure)
2413            if not isinstance(fileupload, FileUpload):
2414                return self.validateError('cpsschemas_err_file', {},
2415                                          datastructure)
2416            fileupload.seek(0, 2) # end of file
2417            size = fileupload.tell()
2418            if not size:
2419                return self.validateError('cpsschemas_err_file_empty', {},
2420                                          datastructure)
2421            if self.size_max and size > self.size_max:
2422                max_size_str = self.getHumanReadableSize(self.size_max)
2423                err = 'This file is too big, the allowed max size is ${max_size}'
2424                member_id = str(self.portal_membership.getAuthenticatedMember())
2425                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2426                err_mapping = {'max_size': max_size_str}
2427                return self.validateError(err, err_mapping, datastructure)
2428            store = True
2429
2430
2431        # Find filename
2432        if is_upload and store:
2433            filename = cookId('', '', fileupload)[0].strip()
2434            base,ext = os.path.splitext(filename)
2435            if ext not in ("csv",".csv"):
2436                return self.validateError('only csv files allowed', {},
2437                                          datastructure)
2438            uploads_folder = self.portal_url.getPortalObject().campus.uploads
2439            if hasattr(uploads_folder,filename):
2440                return self.validateError('upload object exists', {},
2441                                          datastructure)
2442            datamodel[field_id] = filename
2443            registry = getToolByName(self, 'mimetypes_registry')
2444            mimetype = registry.lookupExtension(filename.lower())
2445            if mimetype is not None:
2446                mimetype = str(mimetype) # normalize
2447            file = self.makeFile(filename, fileupload, datastructure)
2448            # Fixup mimetype
2449            if mimetype and file.content_type != mimetype:
2450                file.content_type = mimetype
2451            file_path = os.path.join(self.storage_path,filename)
2452            data = open(file_path,"w")
2453            data.write(str(file.data))
2454            data.close()
2455        return True
2456    ###)
2457
2458    def render(self, mode, datastructure, **kw): ###(
2459        render_method = 'widget_uploadfile_render'
2460        meth = getattr(self, render_method, None)
2461        #import pdb;pdb.set_trace()
2462        if meth is None:
2463            raise RuntimeError("Unknown Render Method %s for widget type %s"
2464                               % (render_method, self.getId()))
2465        file_info = self.getStoredFileInfo(datastructure)
2466
2467        return meth(mode=mode, datastructure=datastructure, **file_info)
2468    ###)
2469
2470InitializeClass(DiscFileWidget)
2471
2472widgetRegistry.register(DiscFileWidget)
2473###)
2474
2475###########
2476
Note: See TracBrowser for help on using the repository browser.