source: WAeUP_SRP/base/Widgets.py @ 2832

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