source: WAeUP_SRP/base/Widgets.py @ 3276

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

resolve ticket #496

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