source: WAeUP_SRP/base/Widgets.py @ 2770

Last change on this file since 2770 was 2766, checked in by joachim, 17 years ago

M skins/waeup_student/create_level.py
use course_results for carry_overs

M skins/waeup_pins/pins_view.pt
M skins/waeup_pins/search_pins.py
sort batches in select-box

M Widgets.py
M WAeUPTables.py
M WAeUPTool.py
mass_(create,edit)_courseresults edits verdict in level.

M profiles/default/layouts/application_cest.xml
M profiles/default/applicants_catalog.xml
new meta_data field "serial", index must be added manually

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