source: WAeUP_SRP/base/Widgets.py @ 2761

Last change on this file since 2761 was 2738, checked in by joachim, 17 years ago

parttime application

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