source: WAeUP_SRP/trunk/Widgets.py @ 2186

Last change on this file since 2186 was 2185, checked in by joachim, 17 years ago

ignore empty lga, state fields, headings can now start with spaces

  • Property svn:keywords set to Id
File size: 63.2 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 2185 2007-09-07 12:15:45Z joachim $
3from cgi import escape
4from types import *
5import Globals
6from Globals import InitializeClass
7from ZPublisher.HTTPRequest import FileUpload
8##from Products.CPSSchemas.Widget import CPSWidgetType
9from Products.CMFCore.utils import getToolByName
10from Products.CPSSchemas.BasicWidgets import CPSBooleanWidget, CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget
11from Products.CPSSchemas.BasicWidgets import CPSFileWidget
12from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget
13from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget
14from Products.CPSSchemas.Widget import widgetRegistry
15from Products.CPSUtil.file import PersistableFileUpload
16from Products.CPSUtil.id import generateFileName
17##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry
18from DateTime.DateTime import DateTime
19from AccessControl import getSecurityManager
20from Products.WAeUP_SRP.Students import getStudentByRegNo
21from Products.WAeUP_SRP.Academics import makeCertificateCode
22#from Products.ExtFile.ExtFile import ExtFile
23import logging,os,re
24import operator
25p_home = Globals.package_home(globals())
26i_home = Globals.INSTANCE_HOME
27
28#from zLOG import LOG, DEBUG
29
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()
55            res = renderHtmlTag('select',
56                                name='%s.%s:records' % (self.record_id,html_widget_id),
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
84class CPSStringWidgetForRecord(CPSStringWidget): ###(
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,
106                  'name': '%s.%s:records' % (self.record_id,html_widget_id),
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
119###)
120
121class CertificateCourseIdWidget(CPSStringWidget): ###(
122    """ CertificateCourseId Widget"""
123    meta_type = "CertificateCourseId Widget"
124
125    def validate(self, datastructure, **kw):
126        """Validate datastructure and update datamodel."""
127
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"})]
136            if hasattr(self.aq_parent,value):
137                err = 'Course already exists'
138            elif value not in c_ids:
139                err = 'Course does not exist'
140            if err:
141                datastructure.setError(widget_id, err)
142            else:
143                datamodel = datastructure.getDataModel()
144                datamodel[self.fields[0]] = value
145
146            return not err
147
148InitializeClass(CertificateCourseIdWidget)
149
150widgetRegistry.register(CertificateCourseIdWidget)
151###)
152
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:
169                err = 'Course already exists'
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
183###)
184
185class WAeUPStudyModeWidget(CPSSelectWidget): ###(
186    """WAeUP StudyMode Widget."""
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:
208            v = value = 'ume_ft'
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
254class WAeUPSessionWidget(CPSSelectWidget): ###(
255    """WAeUP Session Widget."""
256    meta_type = 'WAeUP Session Widget'
257
258    def _getSessions(self):
259        current_year = DateTime().year()
260        d = {'-1': 'N/A'}
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
274
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:
304                vocabulary_items.sort(key=operator.itemgetter(0))
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):
330        d = {'000':'N/A'}
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
344
345        if not value:
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:
372                vocabulary_items.sort(key=operator.itemgetter(0))
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): ###(
394    """WAeUP Verdict Widget."""
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
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():
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()))
498            if state not in states:
499                states.append(state)
500            lgas.append(lga)
501            d[k] = v
502
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 len(v) == 0:
519            pass
520        elif not self.state_field and not self.lga_field:
521            one_field = True
522            if v not in combined.keys():
523                datastructure.setError(widget_id, "'%s' not a valid lga key" % v)
524                return 0
525        else:
526            if widget_id == self.state_field:
527                if v not in states:
528                    datastructure.setError(widget_id, "'%s' not a valid state" % v)
529                    return 0
530            elif widget_id == self.lga_field:
531                if "_".join(re.split('\W+',v)) not in lgas:
532                    datastructure.setError(widget_id, "'%s' not a valid lga" % v)
533                    return 0
534                if datastructure[self.state_field]:
535                    v = datastructure[self.state_field] + '_' + v
536
537        if self.is_required and not len(v):
538            datastructure.setError(widget_id, "lga required")
539            return 0
540
541        datamodel = datastructure.getDataModel()
542        if one_field:
543            datamodel[self.fields[0]] = v
544        else:
545            state = datastructure[self.state_field].lower()
546            lga = "_".join(datastructure[self.lga_field].lower().split())
547            datamodel[self.fields[0]] =   state + "_" + lga
548        return 1
549
550    def render(self, mode, datastructure, **kw):
551        """Render in mode from datastructure."""
552        w_id = self
553        value = datastructure[self.getWidgetId()]
554        lgas,x,y = self._getLGAs(datastructure)
555        if mode == 'view':
556            return escape(lgas.get(value, value))
557        elif mode == 'edit':
558            html_widget_id = self.getHtmlWidgetId()
559            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
560            in_selection = 0
561            vocabulary_items = lgas.items()
562            # if self.sorted:
563            #     vocabulary_items.sort(key=operator.itemgetter(1))
564            for k, v in vocabulary_items:
565                kw = {'value': k, 'contents': v}
566                if value == k:
567                    kw['selected'] = 'selected'
568                    in_selection = 1
569                res += renderHtmlTag('option', **kw)
570            if value and not in_selection:
571                kw = {'value': value, 'contents': 'invalid: '+ str(value),
572                      'selected': 'selected'}
573                res += renderHtmlTag('option', **kw)
574            res += '</select>'
575            return res
576        raise RuntimeError('unknown mode %s' % mode)
577
578InitializeClass(WAeUPLGAWidget)
579
580widgetRegistry.register(WAeUPLGAWidget)
581
582###)
583
584class WAeUPReservedRoomsWidget(CPSStringWidget): ###(
585    """ WAeUPReservedRooms Widget"""
586    meta_type = "WAeUPReservedRooms Widget"
587
588    def validate(self, datastructure, **kw):
589        """Validate datastructure and update datamodel."""
590        import re
591        valid = CPSStringWidget.validate(self, datastructure, **kw)
592        if not valid:
593            return 0
594        else:
595            widget_id = self.getWidgetId()
596            value = datastructure[widget_id]
597            err = 0
598            try:
599                reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',value)
600                                     if r]
601            except (ValueError,IndexError),msg:
602                err = str(msg)
603            if err:
604                datastructure.setError(widget_id, err)
605            else:
606                datamodel = datastructure.getDataModel()
607                datamodel[self.fields[0]] = value
608            return not err
609
610InitializeClass(WAeUPReservedRoomsWidget)
611
612widgetRegistry.register(WAeUPReservedRoomsWidget)
613###)
614
615class WAeUPIdWidget(CPSStringWidget): ###(
616    """ WAeUPId Widget"""
617    meta_type = "WAeUPId Widget"
618
619    def validate(self, datastructure, **kw):
620        """Validate datastructure and update datamodel."""
621
622        valid = CPSStringWidget.validate(self, datastructure, **kw)
623        id_pat_str = r"\S"
624        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
625        if not valid:
626            return 0
627        else:
628            portal_type_query = {'query':['Faculty',
629                                          'Department',
630                                          'Course',
631                                          'Certificate',
632                                          'CertificateCourse',]}
633            widget_id = self.getWidgetId()
634            value = datastructure[widget_id]  #.upper()  is not necessary here because it's also done in waeup_document_create_do
635            err = 0
636            mapping = {}
637            if len(value.split()) > 1:
638                err = 'Invalid Id, Id contains space(s).'
639            elif self.portal_catalog(portal_type=portal_type_query,id=value):
640                brain = self.portal_catalog(portal_type=portal_type_query,id=value)[0]
641                err = 'An ${portal_type} object with the Id ${id} already exists at ${path}.'
642                mapping = {'portal_type': brain.portal_type,
643                           'id': value,
644                           'path': brain.getPath(),
645                           }
646            if err:
647                datastructure.setError(widget_id, err, mapping)
648            else:
649                datamodel = datastructure.getDataModel()
650                datamodel[self.fields[0]] = value
651
652            return not err
653
654InitializeClass(WAeUPIdWidget)
655
656widgetRegistry.register(WAeUPIdWidget)
657
658
659###)
660
661class StudyCourseWidget(CPSStringWidget): ###(
662    """ StudyCourse Widget"""
663    meta_type = "StudyCourse Widget"
664
665    def validate(self, datastructure, **kw):
666        """Validate datastructure and update datamodel."""
667        #from Products.zdb import set_trace
668        #set_trace()
669##        valid = CPSStringWidget.validate(self, datastructure, **kw)
670##        if not valid:
671##            return 0
672        widget_id = self.getWidgetId()
673        value = makeCertificateCode(datastructure[widget_id]).upper()
674        id_pat_str = r"\S"
675        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
676        err = 0
677        if len(value.split()) > 1:
678            err = 'Invalid Id, Id contains space(s).'
679        elif not self.portal_catalog(portal_type='Certificate',id=value):
680            err = 'No such certificate'
681        if err:
682            datastructure.setError(widget_id, err)
683        else:
684            datamodel = datastructure.getDataModel()
685            datamodel[self.fields[0]] = value
686        return not err
687
688InitializeClass(StudyCourseWidget)
689
690widgetRegistry.register(StudyCourseWidget)
691###)
692
693class JambRegNoWidget(CPSStringWidget): ###(
694    """ JambRegNo Widget"""
695    meta_type = "JambRegNo Widget"
696    _properties = CPSStringWidget._properties + (
697        {'id': 'catalog', 'type': 'string', 'mode': 'w',
698         'label': 'Catalog to search'},
699         {'id': 'reference', 'type': 'string', 'mode': 'w',
700         'label': 'Reference Field'},
701         )
702    #catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
703    reference = ""
704    digits = 8
705    digits_str = "N"*digits
706    letters = 2
707    letters_str = "L"*letters
708    def validate(self, datastructure, **kw):
709        """Validate datastructure and update datamodel."""
710        valid = CPSStringWidget.validate(self, datastructure, **kw)
711        reg_no_catalog = getattr(self,self.catalog)
712        widget_id = self.getWidgetId()
713        value = datastructure[widget_id].upper()
714        err = 0
715        #import pdb;pdb.set_trace()
716        if kw.has_key('mode'):
717            mode = kw['mode']
718        else:
719            mode = "edit"
720        if not valid:
721            err = 'Invalid registration number'
722        elif self.reference == '':
723            #s = getStudentByRegNo(self,value)
724            pume = reg_no_catalog(jamb_reg_no = value)
725            if len(pume) < 1:
726                err = 'No student record with this registration number'
727            else:
728                datastructure['pume'] = pume[0]
729        elif mode == 'add':
730            pass
731        elif self.reference != '' and self.catalog == "applicants_catalog":
732            res = reg_no_catalog.searchResults({"%s" % self.reference: value})
733            if len(res) != 1:
734                err = 'No record with this registration number'
735            else:
736                datastructure['record'] = res[0]
737        else:
738            record = datastructure[self.reference]
739            #jamb_reg_no = getattr(record,widget_id)
740            jamb_reg_no = record.Entryregno
741            if jamb_reg_no != value:
742                err = 'Registration number does not match.'
743        if err:
744            datastructure.setError(widget_id, err)
745        else:
746            datamodel = datastructure.getDataModel()
747            datamodel[self.fields[0]] = value
748        return not err
749
750InitializeClass(JambRegNoWidget)
751
752widgetRegistry.register(JambRegNoWidget)
753###)
754
755class SecretWidget(CPSStringWidget): ###(
756    """ Secret Widget"""
757    meta_type = "Secret Widget"
758    _properties = CPSStringWidget._properties + (
759        {'id': 'reference', 'type': 'string', 'mode': 'w',
760         'label': 'Reference Record'},
761         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
762         'label': 'Fields to check'},
763         )
764    reference = "student"
765    matric_no_catalog = 'returning_import'
766    check_fields = ("Firstname", "Middlename","Lastname")
767    def validate(self, datastructure, **kw):
768        """Validate datastructure and update datamodel."""
769        logger = logging.getLogger('Widgets.SecretWidget.validate')
770        valid = CPSStringWidget.validate(self, datastructure, **kw)
771        widget_id = self.getWidgetId()
772        value = datastructure[widget_id].upper()
773        err = 0
774        record = datastructure.get(self.reference,None)
775        #import pdb;pdb.set_trace()
776        if not valid or len(value) < 2:
777            err = 'Invalid string'
778        elif not record or datastructure.errors:
779            err = 0
780        else:
781            found = False
782            cvs = []
783            for field in self.check_fields:
784                cv = getattr(record,field).upper()
785                if len(cv.split()) > 1:
786                    for splited in cv.split():
787                        cvs.append(splited.strip())
788                else:
789                    cvs.append(cv)
790            for cv in cvs:
791                if cv  == value.upper():
792                    found = True
793                    break
794            matric_no = record.matric_no
795            name = " ".join(cvs)
796            if not found:
797                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
798                err = 'No name does match.'
799            else:
800                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
801        if err:
802            datastructure.setError(widget_id, err)
803        else:
804            datamodel = datastructure.getDataModel()
805            datamodel[self.fields[0]] = value
806        return not err
807
808InitializeClass(SecretWidget)
809
810widgetRegistry.register(SecretWidget)
811###)
812
813class WAeUPSexWidget(CPSBooleanWidget): ###(
814    """WAeUP sex widget."""
815    meta_type = 'WAeUP Sex Widget'
816
817    def validate(self, datastructure, **kw):
818        """Validate datastructure and update datamodel."""
819        value = datastructure[self.getWidgetId()]
820
821        if self.render_format not in self.render_formats:
822            self.render_format = 'select'
823
824        female = value in ('F','f','Female','female',"True",True)
825        male = value in ('M','m','Male','male','False',False)
826        if not female and not male:
827            datastructure.setError(self.getWidgetId(),
828                                   "invalid sex %s" % value)
829            return 0
830        elif female:
831            v = True
832        else:
833            v = False
834        datamodel = datastructure.getDataModel()
835        datamodel[self.fields[0]] = v
836        return 1
837
838InitializeClass(WAeUPSexWidget)
839
840widgetRegistry.register(WAeUPSexWidget)
841
842###)
843
844class MatricNoWidget(CPSStringWidget): ###(
845    """ MatricNo Widget"""
846    meta_type = "MatricNo Widget"
847
848    _properties = CPSStringWidget._properties + (
849        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
850         'label': 'Catalog to search for MatricNo'},
851        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
852         'label': 'Results Catalog'},
853         )
854    matric_no_catalog = "" #the catalog to search for matric_no
855    results_catalog = "results_import" #results catalog
856
857    def validate(self, datastructure, **kw):
858        """Validate datastructure and update datamodel."""
859        #import pdb;pdb.set_trace()
860        valid = CPSStringWidget.validate(self, datastructure, **kw)
861        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
862        returning = getattr(self,self.matric_no_catalog)
863        results = getattr(self,self.results_catalog,None)
864        err = 0
865        widget_id = self.getWidgetId()
866        value = datastructure[widget_id]
867        if not valid or not value:
868            err = 'Invalid string'
869            logger.info('Invalid matric_no string %s' % value)
870        else:
871            value = value.upper()
872            datastructure['student'] = None
873            while not err:
874                res = returning(matric_no = value)
875                if len(res) < 1:
876                    logger.info('matric_no %s not found' % value)
877                    err = 'No student with this matriculation number.'
878                    break
879                datastructure['student'] = res[0]
880                if results is not None:
881                    res = results(matric_no = value)
882                    if len(res) < 1:
883                        err = 'No results for this matriculation number'
884                        continue
885                    datastructure['results'] = res
886                break
887        if err:
888            datastructure.setError(widget_id, err)
889        else:
890            datamodel = datastructure.getDataModel()
891            datamodel[self.fields[0]] = value
892        return not err
893
894InitializeClass(MatricNoWidget)
895
896widgetRegistry.register(MatricNoWidget)
897###)
898
899class StudentIdWidget(CPSStringWidget): ###(
900    """ StudentId Widget"""
901    meta_type = "StudentId Widget"
902    def validate(self, datastructure, **kw):
903        """Validate datastructure and update datamodel."""
904        valid = CPSStringWidget.validate(self, datastructure, **kw)
905        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
906        #import pdb;pdb.set_trace()
907        s_cat = self.students_catalog
908        err = 0
909        widget_id = self.getWidgetId()
910        value = datastructure[widget_id]
911        if not valid or not value:
912            err = 'Invalid Id string'
913            logger.info('Invalid id string %s' % value)
914            datastructure['student'] = None
915        else:
916            value = value.upper()
917            res = s_cat(id = value)
918            if not res:
919                logger.info('Student id %s not found' % value)
920                err = 'No student with this Id'
921                datastructure['student'] = None
922            else:
923                datastructure['student'] = res[0]
924        if err:
925            datastructure.setError(widget_id, err)
926        else:
927            datamodel = datastructure.getDataModel()
928            datamodel[self.fields[0]] = value
929        return not err
930
931InitializeClass(StudentIdWidget)
932
933widgetRegistry.register(StudentIdWidget)
934###)
935
936class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
937    """ WAeUPMultilineResults Widget"""
938    meta_type = "WAeUp Multiline Results Widget"
939    _properties = CPSWidget._properties + (
940        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
941         'label': 'Nr of Lines'},
942         )
943    nr_of_lines = 5
944    def prepare(self, datastructure, **kw): ###(
945        """Prepare datastructure from datamodel."""
946        datamodel = datastructure.getDataModel()
947        #import pdb;pdb.set_trace()
948        widget_id = self.getWidgetId()
949        v = datamodel[self.fields[0]]
950        if type(v) is ListType and v:
951            nr_results = len(v)
952        else:
953            v = []
954            nr_results = 0
955        count = 1
956        for s,g in v:
957            wid = "%s%02d"% (widget_id,count)
958            datastructure[wid+'_s'] = s
959            datastructure[wid+'_g'] = g
960            count += 1
961        if nr_results < self.nr_of_lines:
962            for line in range(nr_results,self.nr_of_lines):
963                v.append(('',''))
964                wid = "%s%02d"% (widget_id,line)
965                datastructure[wid+'_s'] = ''
966                datastructure[wid+'_g'] = ''
967        datastructure[widget_id] = v
968        datastructure[widget_id+'_s'] = ''
969        datastructure[widget_id+'_g'] = ''
970    ###)
971
972    def validate(self, datastructure, **kw): ###(
973        """Validate datastructure and update datamodel."""
974        #import pdb;pdb.set_trace()
975        widget_id = self.getWidgetId()
976        err = 0
977        lines = []
978        for line in range(1,30):
979            wid = "%s%02d"% (widget_id,line)
980            if not datastructure.has_key(wid+'_s'):
981                break
982            lines.append((datastructure[wid+'_s'].strip(),
983                         datastructure[wid+'_g'].strip()))
984
985        s = datastructure[widget_id+'_s'].strip()
986        g = datastructure[widget_id+'_g'].strip()
987        if s and g:
988            lines.append((s,g))
989        active = []
990        for s,g in lines:
991            if g != "":
992                active.append((s,g))
993        if err:
994            datastructure.setError(widget_id, err)
995        else:
996            datamodel = datastructure.getDataModel()
997            datamodel[self.fields[0]] = active
998        return not err
999    ###)
1000
1001    def render(self, mode, datastructure, **kw): ###(
1002        """Render in mode from datastructure."""
1003        render_method = 'widget_waeup_multiline_result_render'
1004        meth = getattr(self, render_method, None)
1005        if meth is None:
1006            raise RuntimeError("Unknown Render Method %s for widget type %s"
1007                               % (render_method, self.getId()))
1008        #import pdb;pdb.set_trace()
1009        datamodel = datastructure.getDataModel()
1010        widget_id = self.getWidgetId()
1011        lines = datamodel[self.fields[0]]
1012        if len(lines) < self.nr_of_lines:
1013            for line in range(len(lines),self.nr_of_lines + 1):
1014                lines.append(('',''))
1015        datastructure[widget_id] = lines
1016        datastructure[widget_id+'_s'] = ''
1017        datastructure[widget_id+'_g'] = ''
1018##        count = 1
1019##        for s,g in v:
1020##            wid = "%s%02d"% (widget_id,count)
1021##            count += 1
1022        return meth(mode=mode,
1023                    datastructure=datastructure,
1024                    )
1025    ###)
1026
1027
1028InitializeClass(WAeUPMultilineResultsWidget)
1029widgetRegistry.register(WAeUPMultilineResultsWidget)
1030###)
1031
1032class WAeUPResultsWidget(CPSStringWidget): ###(
1033    """ WAeUPResults Widget"""
1034    meta_type = "WAeUp Results Widget"
1035
1036    def prepare(self, datastructure, **kw): ###(
1037        """Prepare datastructure from datamodel."""
1038        datamodel = datastructure.getDataModel()
1039        v = datamodel[self.fields[0]]
1040        #import pdb;pdb.set_trace()
1041        widget_id = self.getWidgetId()
1042        datastructure[widget_id] = v
1043        datastructure[widget_id+'_s'] = ''
1044        datastructure[widget_id+'_g'] = ''
1045    ###)
1046
1047    def validate(self, datastructure, **kw): ###(
1048        """Validate datastructure and update datamodel."""
1049        #import pdb;pdb.set_trace()
1050        widget_id = self.getWidgetId()
1051        v = datastructure[widget_id]
1052        err = 0
1053        s = datastructure[widget_id+'_s'].strip()
1054        g = datastructure[widget_id+'_g'].strip()
1055        while 1:
1056            if not s and g:
1057                err = "No subject grade for subject"
1058                break
1059            i = 0
1060            done = False
1061            for sv,gv in v:
1062                if sv == s:
1063                    done = True
1064                    if not g:
1065                        v.pop(i)
1066                        break
1067                    v[i] = (s,g)
1068                    break
1069                i += 1
1070            if done:
1071                break
1072            if s and g:
1073                v.append((s,g))
1074            break
1075        if err:
1076            datastructure.setError(widget_id, err)
1077        else:
1078            datamodel = datastructure.getDataModel()
1079            datamodel[self.fields[0]] = v
1080            datastructure[widget_id+'_s'] = s
1081            datastructure[widget_id+'_g'] = g
1082        return not err
1083    ###)
1084
1085    def render(self, mode, datastructure, **kw): ###(
1086        """Render in mode from datastructure."""
1087        render_method = 'widget_waeup_result_render'
1088        meth = getattr(self, render_method, None)
1089        if meth is None:
1090            raise RuntimeError("Unknown Render Method %s for widget type %s"
1091                               % (render_method, self.getId()))
1092        #import pdb;pdb.set_trace()
1093        datamodel = datastructure.getDataModel()
1094        widget_id = self.getWidgetId()
1095        datastructure[widget_id+'_s'] = ''
1096        datastructure[widget_id+'_g'] = ''
1097        return meth(mode=mode,
1098                    datastructure=datastructure,
1099                    )
1100    ###)
1101
1102
1103InitializeClass(WAeUPResultsWidget)
1104widgetRegistry.register(WAeUPResultsWidget)
1105###)
1106
1107class ScratchCardPin: ###(
1108    """the ScratchCardPin"""
1109    def __init__(self,prefix,batch_no,number):
1110        if not batch_no and not number:
1111            s = prefix
1112            if len(s) > 3:
1113                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1114            else:
1115                prefix,batch_no,number = s,'',''
1116        self.p = prefix
1117        self.b = batch_no
1118        self.n = number
1119
1120    def __str__(self):
1121        return "%s-%s-%s" % (self.p,self.b,self.n)
1122
1123    def __repr__(self):
1124        return "%s%s%s" % (self.p,self.b,self.n)
1125###)
1126
1127class ScratchcardPinWidget(CPSStringWidget): ###(
1128    """ ScratchcardPin Widget"""
1129    meta_type = "Scratchcard Pin Widget"
1130    _properties = CPSWidget._properties + (
1131        {'id': 'prefix', 'type': 'string', 'mode': 'w',
1132         'label': 'Prefix'},
1133         {'id': 'reference', 'type': 'string', 'mode': 'w',
1134         'label': 'Reference Field'},
1135        )
1136    prefix = ''
1137    reference = ''
1138    def prepare(self, datastructure, **kw): ###(
1139        """Prepare datastructure from datamodel."""
1140        datamodel = datastructure.getDataModel()
1141        v = datamodel[self.fields[0]]
1142        widget_id = self.getWidgetId()
1143        if v and type(v) is StringType:
1144            try:
1145                p,b,n = v.split('-')
1146                v = ScratchCardPin(p,b,n)
1147            except ValueError:
1148                v = ScratchCardPin(v,'','')
1149        if v:
1150            p = '%s' % v.p
1151            b = '%s' % v.b
1152            n = '%s' % v.n
1153        else:
1154            p = self.prefix
1155            if p.startswith('@'):
1156                p = getattr(self,self.prefix[1:])()
1157            b = n = ''
1158            v = ScratchCardPin(p,b,n)
1159        datastructure[widget_id] = v
1160        datastructure[widget_id+'_p'] = p
1161        datastructure[widget_id+'_b'] = b
1162        datastructure[widget_id+'_n'] = n
1163    ###)
1164
1165    def validate(self, datastructure, **kw): ###(
1166        """Validate datastructure and update datamodel."""
1167        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1168        widget_id = self.getWidgetId()
1169        v = datastructure[widget_id]
1170        #import pdb;pdb.set_trace()
1171        err = 0
1172        mapping = {}
1173        prefix= self.prefix
1174        if prefix.startswith('@'):
1175            prefix= getattr(self,self.prefix[1:])()
1176        b = datastructure[widget_id+'_b'].strip()
1177        n = datastructure[widget_id+'_n'].strip()
1178        pins = self.portal_pins
1179        pin = "%(prefix)s%(b)s%(n)s" % vars()
1180        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1181        do = 1
1182        s_id = str(self.portal_membership.getAuthenticatedMember())
1183        if self.isStaff():
1184            do = 0
1185            err ='You are not a Student. PIN neither checked nor used.'
1186            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1187        elif len(b) > 1 and b.find('-') > -1:
1188            do = 0
1189            err = 'PIN must not contain "-"'
1190            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1191        elif n.find('-') > -1:
1192            do = 0
1193            err = 'PIN must not contain "-"'
1194            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1195        elif len(n) != 10:
1196            do = 0
1197            err = 'Invalid PIN length'
1198            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1199        elif self.reference == "":
1200            ref = s_id
1201        else:
1202            ref = datastructure[self.reference]
1203            if datastructure.errors:
1204                do = 0
1205                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1206                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1207        while do:
1208            ok = pins.searchAndSetRecord(pin,ref,prefix)
1209            if ok < -2 or ok > 2:
1210                err = 'Unknown error, please report!'
1211                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1212                break
1213            elif ok == -2:
1214                err = 'Service already is activated but with a different PIN.'
1215                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1216                break
1217            elif ok == -1:
1218                err = 'Invalid PIN'
1219                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1220                break
1221            if ok == 0:
1222                err = 'PIN already used'
1223                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1224                break
1225            if ok >= 1:
1226                #import pdb;pdb.set_trace()
1227                if self.isStudent():
1228                    if self.reference == "jamb_reg_no":
1229                        err = "You are already logged in."
1230                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1231                        break
1232                    if ok == 1:
1233                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1234                    else:
1235                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1236                    break
1237                else:
1238                    student = getStudentByRegNo(self,ref)
1239                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1240                if student is None:
1241                    err = "Student not found"
1242                    s_logger.info('%s not found in admission list' % (ref))
1243                    break
1244                s_id = student.getId()
1245                if ok == 2:
1246                    if self.reference == "jamb_reg_no":
1247                        if hasattr(self.portal_directories.students,s_id):
1248                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1249                            mapping = {'id': s_id}
1250                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1251                            break
1252                        else:
1253                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1254                    else:
1255                        err = "Unknown error"
1256                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1257                        break
1258                try:
1259                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1260                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1261                except:
1262                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1263                    mapping = {'id': s_id}
1264                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1265                    break
1266            break
1267        if err:
1268            datastructure.setError(widget_id, err,mapping)
1269        else:
1270            datamodel = datastructure.getDataModel()
1271            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1272            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1273            datastructure[widget_id+'_p'] = prefix
1274            datastructure[widget_id+'_b'] = b
1275            datastructure[widget_id+'_n'] = n
1276            datastructure['s_id'] = s_id
1277        return not err
1278
1279###)
1280
1281    def render(self, mode, datastructure, **kw): ###(
1282        """Render in mode from datastructure."""
1283        render_method = 'widget_scratch_card_pin_render'
1284        meth = getattr(self, render_method, None)
1285        if meth is None:
1286            raise RuntimeError("Unknown Render Method %s for widget type %s"
1287                               % (render_method, self.getId()))
1288
1289        # XXX AT: datastructure has to be set again here, in case we're in edit
1290        # or create mode, because a default value has to be provided.
1291        #import pdb;pdb.set_trace()
1292        datamodel = datastructure.getDataModel()
1293        v = datamodel[self.fields[0]]
1294        if v and type(v) is StringType:
1295            try:
1296                p,b,n = v.split('-')
1297                v = ScratchCardPin(p,b,n)
1298            except ValueError:
1299                v = ScratchCardPin(self.prefix,'XXX',v)
1300                pass
1301        if v:
1302            prefix= '%s' % v.p
1303            b = '%s' % v.b
1304            n = '%s' % v.n
1305        else:
1306            prefix= self.prefix
1307            if prefix.startswith('@'):
1308                prefix= getattr(self,self.prefix[1:])()
1309            b = n = ''
1310            v = ScratchCardPin(prefix,b,n)
1311        widget_id = self.getWidgetId()
1312        datastructure[widget_id] = v
1313        datastructure[widget_id+'_p'] = prefix
1314        datastructure[widget_id+'_b'] = b
1315        datastructure[widget_id+'_n'] = n
1316        return meth(mode=mode,
1317                    datastructure=datastructure,
1318                    )
1319    ###)
1320
1321InitializeClass(ScratchcardPinWidget)
1322widgetRegistry.register(ScratchcardPinWidget)
1323###)
1324
1325class PumePinWidget(ScratchcardPinWidget): ###(
1326    """ Pume Pin Widget"""
1327    meta_type = "Pume Pin Widget"
1328    catalog = "applicants_catalog"
1329
1330    def validate(self, datastructure, **kw): ###(
1331        """Validate datastructure and update datamodel."""
1332        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1333        widget_id = self.getWidgetId()
1334        v = datastructure[widget_id]
1335        err = 0
1336        mapping = {}
1337
1338        prefix= self.prefix
1339        if prefix.startswith('@'):
1340            prefix= getattr(self,self.prefix[1:])()
1341        b = datastructure[widget_id+'_b'].strip()
1342        n = datastructure[widget_id+'_n'].strip()
1343        pins = self.portal_pins
1344        pin = "%(prefix)s%(b)s%(n)s" % vars()
1345        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1346        do = 1
1347        s_id = str(self.portal_membership.getAuthenticatedMember())
1348        if self.isStaff():
1349            do = 0
1350            err ='You are not a Student. PIN neither checked nor used.'
1351            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1352        elif len(b) > 1 and b.find('-') > -1:
1353            do = 0
1354            err = 'PIN must not contain "-"'
1355            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1356        elif n.find('-') > -1:
1357            do = 0
1358            err = 'PIN must not contain "-"'
1359            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1360        elif len(n) != 10:
1361            do = 0
1362            err = 'Invalid PIN length'
1363            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1364        elif self.reference == "":
1365            ref = s_id
1366        else:
1367            ref = datastructure[self.reference]
1368            if datastructure.errors:
1369                do = 0
1370                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1371                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1372        while do:
1373            ok = pins.searchAndSetRecord(pin,ref,prefix)
1374            if ok < -2 or ok > 2:
1375                err = 'Unknown error, please report!'
1376                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1377                break
1378            elif ok == -2:
1379                err = 'Service already is activated but with a different PIN.'
1380                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1381                break
1382            elif ok == -1:
1383                err = 'Invalid PIN'
1384                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1385                break
1386            if ok == 0:
1387                err = 'PIN already used'
1388                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1389                break
1390            if ok >= 1:
1391                if self.isStudent():
1392                    err = "This is only for Pume application."
1393                    s_logger.info('%s/%s applied for screening test with PIN %s' % (s_id,ref,pin_str))
1394                    break
1395                else:
1396                    applicant = datastructure['record']
1397                    if not applicant.pin:
1398                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1399                        d = {}
1400                        d['reg_no'] = applicant.reg_no
1401                        d['pin'] = pin_str
1402                        d['status'] = 'entered'
1403                        getattr(self,self.catalog).modifyRecord(**d)
1404                    elif applicant.pin != pin_str:
1405                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (s_id,ref,pin_str))
1406                    elif applicant.pin == pin_str:
1407                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (s_id,ref,pin_str))
1408            break
1409        if err:
1410            datastructure.setError(widget_id, err,mapping)
1411        else:
1412            datamodel = datastructure.getDataModel()
1413            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1414            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1415            datastructure[widget_id+'_p'] = prefix
1416            datastructure[widget_id+'_b'] = b
1417            datastructure[widget_id+'_n'] = n
1418            datastructure['s_id'] = s_id
1419        return not err
1420    ###)
1421
1422    def render(self, mode, datastructure, **kw): ###(
1423        """Render in mode from datastructure."""
1424        render_method = 'widget_scratch_card_pin_render'
1425        meth = getattr(self, render_method, None)
1426        if meth is None:
1427            raise RuntimeError("Unknown Render Method %s for widget type %s"
1428                               % (render_method, self.getId()))
1429
1430        # XXX AT: datastructure has to be set again here, in case we're in edit
1431        # or create mode, because a default value has to be provided.
1432        #import pdb;pdb.set_trace()
1433        datamodel = datastructure.getDataModel()
1434        v = datamodel[self.fields[0]]
1435        #import pdb;pdb.set_trace()
1436        if v and type(v) is StringType:
1437            try:
1438                p,b,n = v.split('-')
1439                v = ScratchCardPin(p,b,n)
1440            except ValueError:
1441                v = ScratchCardPin(self.prefix,'XXX',v)
1442                pass
1443        if v:
1444            prefix= '%s' % v.p
1445            b = '%s' % v.b
1446            n = '%s' % v.n
1447        else:
1448            prefix= self.prefix
1449            if prefix.startswith('@'):
1450                prefix= getattr(self,self.prefix[1:])()
1451            b = n = ''
1452            v = ScratchCardPin(prefix,b,n)
1453        widget_id = self.getWidgetId()
1454        datastructure[widget_id] = v
1455        datastructure[widget_id+'_p'] = prefix
1456        datastructure[widget_id+'_b'] = b
1457        datastructure[widget_id+'_n'] = n
1458        return meth(mode=mode,
1459                    datastructure=datastructure,
1460                    )
1461    ###)
1462
1463InitializeClass(PumePinWidget)
1464widgetRegistry.register(PumePinWidget)
1465###)
1466
1467class WAeUPImageWidget(CPSImageWidget): ###(
1468    """Photo widget."""
1469    meta_type = 'WAeUP Image Widget'
1470
1471    def render(self, mode, datastructure, **kw):
1472        render_method = 'widget_waeup_image_render'
1473        meth = getattr(self, render_method, None)
1474        if meth is None:
1475            raise RuntimeError("Unknown Render Method %s for widget type %s"
1476                               % (render_method, self.getId()))
1477        img_info = self.getImageInfo(datastructure)
1478        return meth(mode=mode, datastructure=datastructure, **img_info)
1479
1480InitializeClass(WAeUPImageWidget)
1481
1482widgetRegistry.register(WAeUPImageWidget)
1483###)
1484
1485class NoZodbImageWidget(CPSImageWidget): ###(
1486    """Image widget with filesystem storage."""
1487    meta_type = 'No Zodb Image Widget'
1488    _properties = CPSImageWidget._properties +\
1489    (
1490     {'id': 'path', 'type': 'string', 'mode': 'w',
1491      'label': 'Relative Path'},
1492     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1493      'label': 'Field to build the id'},
1494    )
1495    path = "images"
1496    storage_path = "%s/import/%s" % (i_home,path)
1497    id_field = "reg_no"
1498
1499    def getImageInfo(self, datastructure): ###(
1500        """Get the file info from the datastructure."""
1501        #import pdb; pdb.set_trace()
1502        widget_id = self.getWidgetId()
1503        if  datastructure.has_key(widget_id):
1504            fileupload = datastructure[widget_id]
1505            dm = datastructure.getDataModel()
1506            field_id = self.fields[0]
1507            content_url = "/uniben/viewimage?path=%s/%s_%s.jpg" %\
1508                                    (self.path,
1509                                    datastructure[self.id_field],
1510                                    self.getWidgetId(),
1511                                    )
1512            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1513                                            field_id,)
1514            file_path = "/%s/%s" % (self.storage_path,
1515                                        current_filename)
1516        else:
1517            file_path = "XXX"
1518        # read the file from the filesystem
1519        if not os.path.exists(file_path):
1520            height = -1
1521            width = -1
1522            empty_file = True
1523            session_file = False
1524            current_filename = ''
1525            content_url = ''
1526            size = 0
1527            mimetype = ''
1528            last_modified = ''
1529            height = ''
1530            width = ''
1531
1532        else:
1533            image = open(file_path)
1534            from OFS.Image import getImageInfo as getImageInfoOFS
1535            image.seek(0)
1536            data = image.read(2000)
1537            size = len(data)
1538            empty_file = size == 0
1539            session_file = False
1540            last_modified = ''
1541            image.close()
1542            mimetype, width, height = getImageInfoOFS(data)
1543
1544            if width < 0:
1545                width = None
1546            if height < 0:
1547                height = None
1548
1549            if (self.allow_resize
1550                and height is not None
1551                and width  is not None):
1552                z_w = z_h = 1
1553                h = int(self.display_height)
1554                w = int(self.display_width)
1555                if w and h:
1556                    if w < width:
1557                        z_w = w / float(width)
1558                    if h < height:
1559                        z_h = h / float(height)
1560                    zoom = min(z_w, z_h)
1561                    width = int(zoom * width)
1562                    height = int(zoom * height)
1563                #import pdb;pdb.set_trace()
1564        image_info = {
1565            'empty_file': empty_file,
1566            'session_file': session_file,
1567            'current_filename': current_filename,
1568            'size': size,
1569            'last_modified': last_modified,
1570            'content_url': content_url,
1571            'mimetype': mimetype,
1572            }
1573        title = image_info['current_filename']
1574        alt = title or ''
1575        #height = int(self.display_height)
1576        #width = int(self.display_width)
1577        if height is None or width is None:
1578            tag = renderHtmlTag('img', src=image_info['content_url'],
1579                                alt=alt, title=title)
1580        else:
1581            tag = renderHtmlTag('img', src=image_info['content_url'],
1582                                width=str(width), height=str(height),
1583                                alt=alt, title=title)
1584
1585        image_info['height'] = height
1586        image_info['width'] = width
1587        image_info['image_tag'] = tag
1588        return image_info
1589    ###)
1590
1591
1592    def checkFileName(self, filename, mimetype):
1593        return '', {}
1594        if mimetype and mimetype.startswith('image'):
1595            return '', {}
1596        return 'cpsschemas_err_image', {}
1597
1598    def prepare(self, datastructure, **kw): ###(
1599        """Prepare datastructure from datamodel."""
1600        datamodel = datastructure.getDataModel()
1601        widget_id = self.getWidgetId()
1602        file_name = datamodel[self.fields[0]]
1603        #import pdb; pdb.set_trace()
1604        if self.allow_resize:
1605            datastructure[self.getWidgetId() + '_resize'] = ''
1606        datastructure[widget_id] = file_name
1607        datastructure[widget_id + '_choice'] = 'change'
1608        title = 'Passport Foto'
1609        datastructure[widget_id + '_filename'] = title
1610    ###)
1611
1612    def validate(self, datastructure, **kw): ###(
1613        """Update datamodel from user data in datastructure.
1614        """
1615        logger = logging.getLogger('Widgets.NoZodbImageWidget.validate')
1616        datamodel = datastructure.getDataModel()
1617        field_id = self.fields[0]
1618        widget_id = self.getWidgetId()
1619        store = False
1620        fileupload = None
1621        mimetype = None
1622        old_file = datamodel[field_id]
1623        # if old_file is not None:
1624        #     old_filename = old_file.title
1625        # else:
1626        #     old_filename = ''
1627        choice = datastructure[widget_id+'_choice']
1628        fileupload = datastructure[widget_id]
1629        is_upload = isinstance(fileupload, FileUpload)
1630        #import pdb; pdb.set_trace()
1631        if not is_upload and not datamodel[field_id]:
1632            if self.is_required:
1633                return self.validateError('Picture upload required', {},
1634                                          datastructure)
1635        if choice == 'delete':
1636            if self.is_required:
1637                return self.validateError('cpsschemas_err_required', {},
1638                                          datastructure)
1639            datamodel[field_id] = None
1640        elif choice == 'keep':
1641            fileupload = datastructure[widget_id]
1642            if isinstance(fileupload, PersistableFileUpload):
1643                # Keeping something from the session means we
1644                # actually want to store it.
1645                store = True
1646            # else:
1647            #     # Nothing to change, don't pollute datastructure
1648            #     # with something costly already stored, which therefore
1649            #     # doesn't need to be kept in the session.
1650            #     self.unprepare(datastructure)
1651        elif choice == 'change' and is_upload:
1652            if not fileupload:
1653                return self.validateError('cpsschemas_err_file_empty', {},
1654                                          datastructure)
1655            if not isinstance(fileupload, FileUpload):
1656                return self.validateError('cpsschemas_err_file', {},
1657                                          datastructure)
1658            fileupload.seek(0, 2) # end of file
1659            size = fileupload.tell()
1660            if not size:
1661                return self.validateError('cpsschemas_err_file_empty', {},
1662                                          datastructure)
1663            if self.size_max and size > self.size_max:
1664                max_size_str = self.getHumanReadableSize(self.size_max)
1665                err = 'This file is too big, the allowed max size is ${max_size}'
1666                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1667                err_mapping = {'max_size': max_size_str}
1668                return self.validateError(err, err_mapping, datastructure)
1669            store = True
1670
1671
1672        # Find filename
1673        if is_upload and store:
1674            ext ='jpg'
1675            filename = "%s_%s.%s" % (datastructure[self.id_field],
1676                                 self.getWidgetId(),
1677                                 ext)
1678            datamodel[field_id] = filename
1679            registry = getToolByName(self, 'mimetypes_registry')
1680            mimetype = registry.lookupExtension(filename.lower())
1681            if mimetype is not None:
1682                mimetype = str(mimetype) # normalize
1683            # Set/update data
1684            # file_path = "%s_%s.jpg" % (datamodel[self.id_field],
1685            #                            field_id,)
1686            full_path = "%s/%s" % (self.storage_path, filename)
1687            #import pdb; pdb.set_trace()
1688            file = self.makeFile(filename, fileupload, datastructure)
1689            # Fixup mimetype
1690            if mimetype and file.content_type != mimetype:
1691                file.content_type = mimetype
1692            # Store the file in the filesystem
1693            if not os.path.exists(self.storage_path):
1694                os.mkdir(self.storage_path)
1695            #import pdb;pdb.set_trace()
1696            pict = open(full_path,"w")
1697            fileupload.seek(0)
1698            pict.write(fileupload.read())
1699            pict.close()
1700
1701
1702        return True
1703
1704###)
1705
1706    def render(self, mode, datastructure, **kw): ###(
1707        render_method = 'widget_passport_render'
1708        meth = getattr(self, render_method, None)
1709        if meth is None:
1710            raise RuntimeError("Unknown Render Method %s for widget type %s"
1711                               % (render_method, self.getId()))
1712        img_info = self.getImageInfo(datastructure)
1713        return meth(mode=mode, datastructure=datastructure, **img_info)
1714    ###)
1715
1716InitializeClass(NoZodbImageWidget)
1717
1718widgetRegistry.register(NoZodbImageWidget)
1719###)
1720
1721
1722###########
1723
Note: See TracBrowser for help on using the repository browser.