source: WAeUP_SRP/trunk/Widgets.py @ 2111

Last change on this file since 2111 was 2110, checked in by joachim, 17 years ago

better lga checking

  • Property svn:keywords set to Id
File size: 62.7 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 2110 2007-08-16 21:38:55Z 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 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:
529                if "_".join(re.split('\W+',v)) not in lgas:
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
534
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())
545            datamodel[self.fields[0]] =   state + "_" + lga
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
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:
597                reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',value)
598                                     if r]
599            except (ValueError,IndexError),msg:
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
613class WAeUPIdWidget(CPSStringWidget): ###(
614    """ WAeUPId Widget"""
615    meta_type = "WAeUPId Widget"
616
617    def validate(self, datastructure, **kw):
618        """Validate datastructure and update datamodel."""
619
620        valid = CPSStringWidget.validate(self, datastructure, **kw)
621        id_pat_str = r"\S"
622        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
623        if not valid:
624            return 0
625        else:
626            portal_type_query = {'query':['Faculty',
627                                          'Department',
628                                          'Course',
629                                          'Certificate',
630                                          'CertificateCourse',]}
631            widget_id = self.getWidgetId()
632            value = datastructure[widget_id]  #.upper()  is not necessary here because it's also done in waeup_document_create_do
633            err = 0
634            mapping = {}
635            if len(value.split()) > 1:
636                err = 'Invalid Id, Id contains space(s).'
637            elif self.portal_catalog(portal_type=portal_type_query,id=value):
638                brain = self.portal_catalog(portal_type=portal_type_query,id=value)[0]
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                           }
644            if err:
645                datastructure.setError(widget_id, err, mapping)
646            else:
647                datamodel = datastructure.getDataModel()
648                datamodel[self.fields[0]] = value
649
650            return not err
651
652InitializeClass(WAeUPIdWidget)
653
654widgetRegistry.register(WAeUPIdWidget)
655
656
657###)
658
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()
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()
672        id_pat_str = r"\S"
673        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
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)
681        else:
682            datamodel = datastructure.getDataModel()
683            datamodel[self.fields[0]] = value
684        return not err
685
686InitializeClass(StudyCourseWidget)
687
688widgetRegistry.register(StudyCourseWidget)
689###)
690
691class JambRegNoWidget(CPSStringWidget): ###(
692    """ JambRegNo Widget"""
693    meta_type = "JambRegNo Widget"
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         )
700    #catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
701    reference = ""
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)
709        reg_no_catalog = getattr(self,self.catalog)
710        widget_id = self.getWidgetId()
711        value = datastructure[widget_id].upper()
712        err = 0
713        #import pdb;pdb.set_trace()
714        if kw.has_key('mode'):
715            mode = kw['mode']
716        else:
717            mode = "edit"
718        if not valid:
719            err = 'Invalid registration number'
720        elif self.reference == '':
721            #s = getStudentByRegNo(self,value)
722            pume = reg_no_catalog(jamb_reg_no = value)
723            if len(pume) < 1:
724                err = 'No student record with this registration number'
725            else:
726                datastructure['pume'] = pume[0]
727        elif mode == 'add':
728            pass
729        elif self.reference != '' and self.catalog == "applicants_catalog":
730            res = reg_no_catalog.searchResults({"%s" % self.reference: value})
731            if len(res) != 1:
732                err = 'No record with this registration number'
733            else:
734                datastructure['record'] = res[0]
735        else:
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:
740                err = 'Registration number does not match.'
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
747
748InitializeClass(JambRegNoWidget)
749
750widgetRegistry.register(JambRegNoWidget)
751###)
752
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"
763    matric_no_catalog = 'returning_import'
764    check_fields = ("Firstname", "Middlename","Lastname")
765    def validate(self, datastructure, **kw):
766        """Validate datastructure and update datamodel."""
767        logger = logging.getLogger('Widgets.SecretWidget.validate')
768        valid = CPSStringWidget.validate(self, datastructure, **kw)
769        widget_id = self.getWidgetId()
770        value = datastructure[widget_id].upper()
771        err = 0
772        record = datastructure.get(self.reference,None)
773        #import pdb;pdb.set_trace()
774        if not valid or len(value) < 2:
775            err = 'Invalid string'
776        elif not record or datastructure.errors:
777            err = 0
778        else:
779            found = False
780            cvs = []
781            for field in self.check_fields:
782                cv = getattr(record,field).upper()
783                if len(cv.split()) > 1:
784                    for splited in cv.split():
785                        cvs.append(splited.strip())
786                else:
787                    cvs.append(cv)
788            for cv in cvs:
789                if cv  == value.upper():
790                    found = True
791                    break
792            matric_no = record.matric_no
793            name = " ".join(cvs)
794            if not found:
795                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
796                err = 'No name does match.'
797            else:
798                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
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
811class WAeUPSexWidget(CPSBooleanWidget): ###(
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
840###)
841
842class MatricNoWidget(CPSStringWidget): ###(
843    """ MatricNo Widget"""
844    meta_type = "MatricNo Widget"
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
853    results_catalog = "results_import" #results catalog
854
855    def validate(self, datastructure, **kw):
856        """Validate datastructure and update datamodel."""
857        #import pdb;pdb.set_trace()
858        valid = CPSStringWidget.validate(self, datastructure, **kw)
859        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
860        returning = getattr(self,self.matric_no_catalog)
861        results = getattr(self,self.results_catalog,None)
862        err = 0
863        widget_id = self.getWidgetId()
864        value = datastructure[widget_id]
865        if not valid or not value:
866            err = 'Invalid string'
867            logger.info('Invalid matric_no string %s' % value)
868        else:
869            value = value.upper()
870            datastructure['student'] = None
871            while not err:
872                res = returning(matric_no = value)
873                if len(res) < 1:
874                    logger.info('matric_no %s not found' % value)
875                    err = 'No student with this matriculation number.'
876                    break
877                datastructure['student'] = res[0]
878                if results is not None:
879                    res = results(matric_no = value)
880                    if len(res) < 1:
881                        err = 'No results for this matriculation number'
882                        continue
883                    datastructure['results'] = res
884                break
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
891
892InitializeClass(MatricNoWidget)
893
894widgetRegistry.register(MatricNoWidget)
895###)
896
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)
903        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
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:
910            err = 'Invalid Id string'
911            logger.info('Invalid id string %s' % value)
912            datastructure['student'] = None
913        else:
914            value = value.upper()
915            res = s_cat(id = value)
916            if not res:
917                logger.info('Student id %s not found' % value)
918                err = 'No student with this Id'
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
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()))
982
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
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()
1040        datastructure[widget_id] = v
1041        datastructure[widget_id+'_s'] = ''
1042        datastructure[widget_id+'_g'] = ''
1043    ###)
1044
1045    def validate(self, datastructure, **kw): ###(
1046        """Validate datastructure and update datamodel."""
1047        #import pdb;pdb.set_trace()
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()
1053        while 1:
1054            if not s and g:
1055                err = "No subject grade for subject"
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
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
1105class ScratchCardPin: ###(
1106    """the ScratchCardPin"""
1107    def __init__(self,prefix,batch_no,number):
1108        if not batch_no and not number:
1109            s = prefix
1110            if len(s) > 3:
1111                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1112            else:
1113                prefix,batch_no,number = s,'',''
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)
1120
1121    def __repr__(self):
1122        return "%s%s%s" % (self.p,self.b,self.n)
1123###)
1124
1125class ScratchcardPinWidget(CPSStringWidget): ###(
1126    """ ScratchcardPin Widget"""
1127    meta_type = "Scratchcard Pin Widget"
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 = ''
1136    def prepare(self, datastructure, **kw): ###(
1137        """Prepare datastructure from datamodel."""
1138        datamodel = datastructure.getDataModel()
1139        v = datamodel[self.fields[0]]
1140        widget_id = self.getWidgetId()
1141        if v and type(v) is StringType:
1142            try:
1143                p,b,n = v.split('-')
1144                v = ScratchCardPin(p,b,n)
1145            except ValueError:
1146                v = ScratchCardPin(v,'','')
1147        if v:
1148            p = '%s' % v.p
1149            b = '%s' % v.b
1150            n = '%s' % v.n
1151        else:
1152            p = self.prefix
1153            if p.startswith('@'):
1154                p = getattr(self,self.prefix[1:])()
1155            b = n = ''
1156            v = ScratchCardPin(p,b,n)
1157        datastructure[widget_id] = v
1158        datastructure[widget_id+'_p'] = p
1159        datastructure[widget_id+'_b'] = b
1160        datastructure[widget_id+'_n'] = n
1161    ###)
1162
1163    def validate(self, datastructure, **kw): ###(
1164        """Validate datastructure and update datamodel."""
1165        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1166        widget_id = self.getWidgetId()
1167        v = datastructure[widget_id]
1168        #import pdb;pdb.set_trace()
1169        err = 0
1170        mapping = {}
1171        prefix= self.prefix
1172        if prefix.startswith('@'):
1173            prefix= getattr(self,self.prefix[1:])()
1174        b = datastructure[widget_id+'_b'].strip()
1175        n = datastructure[widget_id+'_n'].strip()
1176        pins = self.portal_pins
1177        pin = "%(prefix)s%(b)s%(n)s" % vars()
1178        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1179        do = 1
1180        s_id = str(self.portal_membership.getAuthenticatedMember())
1181        if self.isStaff():
1182            do = 0
1183            err ='You are not a Student. PIN neither checked nor used.'
1184            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1185        elif len(b) > 1 and b.find('-') > -1:
1186            do = 0
1187            err = 'PIN must not contain "-"'
1188            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1189        elif n.find('-') > -1:
1190            do = 0
1191            err = 'PIN must not contain "-"'
1192            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1193        elif len(n) != 10:
1194            do = 0
1195            err = 'Invalid PIN length'
1196            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1197        elif self.reference == "":
1198            ref = s_id
1199        else:
1200            ref = datastructure[self.reference]
1201            if datastructure.errors:
1202                do = 0
1203                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1204                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1205        while do:
1206            ok = pins.searchAndSetRecord(pin,ref,prefix)
1207            if ok < -2 or ok > 2:
1208                err = 'Unknown error, please report!'
1209                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1210                break
1211            elif ok == -2:
1212                err = 'Service already is activated but with a different PIN.'
1213                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1214                break
1215            elif ok == -1:
1216                err = 'Invalid PIN'
1217                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1218                break
1219            if ok == 0:
1220                err = 'PIN already used'
1221                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1222                break
1223            if ok >= 1:
1224                #import pdb;pdb.set_trace()
1225                if self.isStudent():
1226                    if self.reference == "jamb_reg_no":
1227                        err = "You are already logged in."
1228                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1229                        break
1230                    if ok == 1:
1231                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1232                    else:
1233                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1234                    break
1235                else:
1236                    student = getStudentByRegNo(self,ref)
1237                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1238                if student is None:
1239                    err = "Student not found"
1240                    s_logger.info('%s not found in admission list' % (ref))
1241                    break
1242                s_id = student.getId()
1243                if ok == 2:
1244                    if self.reference == "jamb_reg_no":
1245                        if hasattr(self.portal_directories.students,s_id):
1246                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1247                            mapping = {'id': s_id}
1248                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1249                            break
1250                        else:
1251                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1252                    else:
1253                        err = "Unknown error"
1254                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1255                        break
1256                try:
1257                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1258                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1259                except:
1260                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1261                    mapping = {'id': s_id}
1262                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1263                    break
1264            break
1265        if err:
1266            datastructure.setError(widget_id, err,mapping)
1267        else:
1268            datamodel = datastructure.getDataModel()
1269            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1270            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1271            datastructure[widget_id+'_p'] = prefix
1272            datastructure[widget_id+'_b'] = b
1273            datastructure[widget_id+'_n'] = n
1274            datastructure['s_id'] = s_id
1275        return not err
1276
1277###)
1278
1279    def render(self, mode, datastructure, **kw): ###(
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]]
1292        if v and type(v) is StringType:
1293            try:
1294                p,b,n = v.split('-')
1295                v = ScratchCardPin(p,b,n)
1296            except ValueError:
1297                v = ScratchCardPin(self.prefix,'XXX',v)
1298                pass
1299        if v:
1300            prefix= '%s' % v.p
1301            b = '%s' % v.b
1302            n = '%s' % v.n
1303        else:
1304            prefix= self.prefix
1305            if prefix.startswith('@'):
1306                prefix= getattr(self,self.prefix[1:])()
1307            b = n = ''
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
1314        return meth(mode=mode,
1315                    datastructure=datastructure,
1316                    )
1317    ###)
1318
1319InitializeClass(ScratchcardPinWidget)
1320widgetRegistry.register(ScratchcardPinWidget)
1321###)
1322
1323class PumePinWidget(ScratchcardPinWidget): ###(
1324    """ Pume Pin Widget"""
1325    meta_type = "Pume Pin Widget"
1326    catalog = "applicants_catalog"
1327
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 = {}
1335
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."
1391                    s_logger.info('%s/%s applied for PUME with PIN %s' % (s_id,ref,pin_str))
1392                    break
1393                else:
1394                    applicant = datastructure['record']
1395                    if not applicant.pin:
1396                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1397                        d = {}
1398                        d['reg_no'] = applicant.reg_no
1399                        d['pin'] = pin_str
1400                        getattr(self,self.catalog).modifyRecord(**d)
1401                    elif applicant.pin != pin_str:
1402                        s_logger.info('%s/%s repeatedly applied for PUME with different PIN %s' % (s_id,ref,pin_str))
1403                    elif applicant.pin == pin_str:
1404                        s_logger.info('%s/%s repeatedly applied for PUME with PIN %s' % (s_id,ref,pin_str))
1405            break
1406        if err:
1407            datastructure.setError(widget_id, err,mapping)
1408        else:
1409            datamodel = datastructure.getDataModel()
1410            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1411            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1412            datastructure[widget_id+'_p'] = prefix
1413            datastructure[widget_id+'_b'] = b
1414            datastructure[widget_id+'_n'] = n
1415            datastructure['s_id'] = s_id
1416        return not err
1417    ###)
1418
1419    def render(self, mode, datastructure, **kw): ###(
1420        """Render in mode from datastructure."""
1421        render_method = 'widget_scratch_card_pin_render'
1422        meth = getattr(self, render_method, None)
1423        if meth is None:
1424            raise RuntimeError("Unknown Render Method %s for widget type %s"
1425                               % (render_method, self.getId()))
1426
1427        # XXX AT: datastructure has to be set again here, in case we're in edit
1428        # or create mode, because a default value has to be provided.
1429        #import pdb;pdb.set_trace()
1430        datamodel = datastructure.getDataModel()
1431        v = datamodel[self.fields[0]]
1432        #import pdb;pdb.set_trace()
1433        if v and type(v) is StringType:
1434            try:
1435                p,b,n = v.split('-')
1436                v = ScratchCardPin(p,b,n)
1437            except ValueError:
1438                v = ScratchCardPin(self.prefix,'XXX',v)
1439                pass
1440        if v:
1441            prefix= '%s' % v.p
1442            b = '%s' % v.b
1443            n = '%s' % v.n
1444        else:
1445            prefix= self.prefix
1446            if prefix.startswith('@'):
1447                prefix= getattr(self,self.prefix[1:])()
1448            b = n = ''
1449            v = ScratchCardPin(prefix,b,n)
1450        widget_id = self.getWidgetId()
1451        datastructure[widget_id] = v
1452        datastructure[widget_id+'_p'] = prefix
1453        datastructure[widget_id+'_b'] = b
1454        datastructure[widget_id+'_n'] = n
1455        return meth(mode=mode,
1456                    datastructure=datastructure,
1457                    )
1458    ###)
1459
1460InitializeClass(PumePinWidget)
1461widgetRegistry.register(PumePinWidget)
1462###)
1463
1464class WAeUPImageWidget(CPSImageWidget): ###(
1465    """Photo widget."""
1466    meta_type = 'WAeUP Image Widget'
1467
1468    def render(self, mode, datastructure, **kw):
1469        render_method = 'widget_waeup_image_render'
1470        meth = getattr(self, render_method, None)
1471        if meth is None:
1472            raise RuntimeError("Unknown Render Method %s for widget type %s"
1473                               % (render_method, self.getId()))
1474        img_info = self.getImageInfo(datastructure)
1475        return meth(mode=mode, datastructure=datastructure, **img_info)
1476
1477InitializeClass(WAeUPImageWidget)
1478
1479widgetRegistry.register(WAeUPImageWidget)
1480###)
1481
1482class NoZodbImageWidget(CPSImageWidget): ###(
1483    """Image widget with filesystem storage."""
1484    meta_type = 'No Zodb Image Widget'
1485    _properties = CPSImageWidget._properties +\
1486    (
1487     {'id': 'path', 'type': 'string', 'mode': 'w',
1488      'label': 'Relative Path'},
1489     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1490      'label': 'Field to build the id'},
1491    )
1492    path = "images"
1493    storage_path = "%s/var/%s" % (i_home,path)
1494    id_field = "reg_no"
1495
1496    def getImageInfo(self, datastructure): ###(
1497        """Get the file info from the datastructure."""
1498        import pdb; pdb.set_trace()
1499        widget_id = self.getWidgetId()
1500        fileupload = datastructure[widget_id]
1501        dm = datastructure.getDataModel()
1502        field_id = self.fields[0]
1503        if fileupload:
1504            empty_file = False
1505            session_file = isinstance(fileupload, PersistableFileUpload)
1506            current_filename = generateFileName(fileupload.filename)
1507            fileupload.seek(0, 2) # end of file
1508            size = fileupload.tell()
1509            fileupload.seek(0)
1510            file = dm[field_id] # last stored file
1511            if file is not None:
1512                last_modified = str(file._p_mtime or '')
1513            else:
1514                last_modified = ''
1515        else:
1516            empty_file = True
1517            session_file = False
1518            current_filename = ''
1519            size = 0
1520            last_modified = ''
1521
1522        # get the adapter
1523        for adapter in dm._adapters:
1524            if adapter.getSchema().has_key(field_id):
1525                break # Note: 'adapter' is still the right one
1526        else:
1527            raise ValueError('No schema for field %r' % field_id)
1528
1529        content_url = None
1530        registry = getToolByName(self, 'mimetypes_registry')
1531        mimetype = (registry.lookupExtension(current_filename.lower()) or
1532                    registry.lookupExtension('file.bin'))
1533
1534        image_info = {
1535            'empty_file': empty_file,
1536            'session_file': session_file,
1537            'current_filename': current_filename,
1538            'size': size,
1539            'last_modified': last_modified,
1540            'content_url': content_url,
1541            'mimetype': mimetype,
1542            }
1543        if image_info['empty_file']:
1544            tag = ''
1545            height = 0
1546            width = 0
1547        else:
1548            file_path = "/%s/%s_%s.jpg" % (self.storage_path,
1549                                           datamodel[self.id_field],
1550                                           self.field_id,)
1551            # read the file from the filesystem
1552            if not os.path.exists(file_path):
1553                image = None
1554            else:
1555                image = open(file_path).read()
1556            from OFS.Image import getImageInfo
1557            image.seek(0)
1558            data = image.read(24)
1559            ct, width, height = getImageInfo(data)
1560            if width < 0:
1561                width = None
1562            if height < 0:
1563                height = None
1564
1565            if (self.allow_resize
1566                and height is not None
1567                and width  is not None):
1568                z_w = z_h = 1
1569                h = int(self.display_height)
1570                w = int(self.display_width)
1571                if w and h:
1572                    if w < width:
1573                        z_w = w / float(width)
1574                    if h < height:
1575                        z_h = h / float(height)
1576                    zoom = min(z_w, z_h)
1577                    width = int(zoom * width)
1578                    height = int(zoom * height)
1579
1580            title = image_info['current_filename']
1581            alt = title or ''
1582            if height is None or width is None:
1583                tag = renderHtmlTag('img', src=image_info['content_url'],
1584                                    alt=alt, title=title)
1585            else:
1586                tag = renderHtmlTag('img', src=image_info['content_url'],
1587                                    width=str(width), height=str(height),
1588                                    alt=alt, title=title)
1589
1590        image_info['height'] = height
1591        image_info['width'] = width
1592        image_info['image_tag'] = tag
1593        return image_info
1594    ###)
1595
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]]
1601        if not file_name:
1602            file = None
1603        else:
1604            import pdb; pdb.set_trace()
1605        datastructure[widget_id] = file_name
1606        datastructure[widget_id + '_choice'] = ''
1607        if file is not None:
1608            title = file.title
1609        else:
1610            title = ''
1611        datastructure[widget_id + '_filename'] = title
1612    ###)
1613
1614    def validate(self, datastructure, **kw):
1615        """Update datamodel from user data in datastructure.
1616        """
1617        datamodel = datastructure.getDataModel()
1618        field_id = self.fields[0]
1619        widget_id = self.getWidgetId()
1620        choice = datastructure[widget_id+'_choice']
1621        store = False
1622        fileupload = None
1623        mimetype = None
1624        old_file = datamodel[field_id]
1625        if old_file is not None:
1626            old_filename = old_file.title
1627        else:
1628            old_filename = ''
1629
1630        if choice == 'delete':
1631            if self.is_required:
1632                return self.validateError('cpsschemas_err_required', {},
1633                                          datastructure)
1634            datamodel[field_id] = None
1635        elif choice == 'keep':
1636            fileupload = datastructure[widget_id]
1637            if isinstance(fileupload, PersistableFileUpload):
1638                # Keeping something from the session means we
1639                # actually want to store it.
1640                store = True
1641            else:
1642                # Nothing to change, don't pollute datastructure
1643                # with something costly already stored, which therefore
1644                # doesn't need to be kept in the session.
1645                self.unprepare(datastructure)
1646        elif choice == 'change':
1647            fileupload = datastructure[widget_id]
1648            if not fileupload:
1649                return self.validateError('cpsschemas_err_file_empty', {},
1650                                          datastructure)
1651            if not isinstance(fileupload, FileUpload):
1652                return self.validateError('cpsschemas_err_file', {},
1653                                          datastructure)
1654            fileupload.seek(0, 2) # end of file
1655            size = fileupload.tell()
1656            if not size:
1657                return self.validateError('cpsschemas_err_file_empty', {},
1658                                          datastructure)
1659            if self.size_max and size > self.size_max:
1660                max_size_str = self.getHumanReadableSize(self.size_max)
1661                err = 'cpsschemas_err_file_too_big ${max_size}'
1662                err_mapping = {'max_size': max_size_str}
1663                return self.validateError(err, err_mapping, datastructure)
1664            store = True
1665
1666        self.otherProcessing(choice, datastructure)
1667
1668        # Find filename
1669        if fileupload is not None:
1670            filename = self.getFileName(fileupload, datastructure, choice,
1671                                        old_filename)
1672            if filename != old_filename:
1673                registry = getToolByName(self, 'mimetypes_registry')
1674                mimetype = registry.lookupExtension(filename.lower())
1675                if mimetype is not None:
1676                    mimetype = str(mimetype) # normalize
1677                err, err_mapping = self.checkFileName(filename, mimetype)
1678                if err:
1679                    return self.validateError(err, err_mapping, datastructure)
1680        elif datamodel[field_id] is not None:
1681            # FIXME: not correct in the case of change=='resize' (CPSPhotoWidget)
1682            filename = datamodel[field_id].title
1683
1684        import pdb;pdb.set_trace()
1685        # Set/update data
1686        file_path = "/%s/%s_%s.jpg" % (storage_path,
1687                                       datamodel[self.id_field],
1688                                       self.field_id,)
1689        if store:
1690            file = self.makeFile(filename, fileupload, datastructure)
1691            # Fixup mimetype
1692            if mimetype and file.content_type != mimetype:
1693                file.content_type = mimetype
1694            # Store the file in the filesystem
1695            if not os.path.exists(storage_path):
1696                os.mkdir(storage_path)
1697            open(file_path,"w").write(file)
1698            datamodel[field_id] = file_path
1699        # elif datamodel[field_id] is not None:
1700        #     # Change filename
1701        #     if datamodel[field_id].title != filename:
1702        #         datamodel[field_id].title = filename
1703
1704
1705        return True
1706
1707
1708InitializeClass(NoZodbImageWidget)
1709
1710widgetRegistry.register(NoZodbImageWidget)
1711###)
1712
1713
1714###########
1715
Note: See TracBrowser for help on using the repository browser.