source: WAeUP_SRP/trunk/Widgets.py @ 2166

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

generates applicants statistics

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