source: WAeUP_SRP/base/Widgets.py @ 2712

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

see ticket #398

Joachim, please check!

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