source: WAeUP_SRP/base/Widgets.py @ 2997

Last change on this file since 2997 was 2875, checked in by joachim, 17 years ago

fix for traceback in Widgets line 1501, please check error message

  • Property svn:keywords set to Id
File size: 82.0 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 2875 2007-12-07 12:41:01Z 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.strip().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            #import pdb;pdb.set_trace()
1164            for sv,gv in v:
1165                if sv == s:
1166                    done = True
1167                    if not g:
1168                        v.pop(i)
1169                        break
1170                    v[i] = (s,g)
1171                    break
1172                i += 1
1173            if done:
1174                break
1175            if s and g:
1176                if v:
1177                    v += (s,g),
1178                else:
1179                    v = [(s,g),]
1180            break
1181        if err:
1182            datastructure.setError(widget_id, err)
1183        else:
1184            datamodel = datastructure.getDataModel()
1185            datamodel[self.fields[0]] = v
1186            datastructure[widget_id] = v
1187            datastructure[widget_id+'_s'] = s
1188            datastructure[widget_id+'_g'] = g
1189        return not err
1190    ###)
1191
1192    def render(self, mode, datastructure, **kw): ###(
1193        """Render in mode from datastructure."""
1194        render_method = 'widget_waeup_result_render'
1195        meth = getattr(self, render_method, None)
1196        if meth is None:
1197            raise RuntimeError("Unknown Render Method %s for widget type %s"
1198                               % (render_method, self.getId()))
1199        datamodel = datastructure.getDataModel()
1200        widget_id = self.getWidgetId()
1201        datastructure[widget_id+'_s'] = ''
1202        datastructure[widget_id+'_g'] = ''
1203        return meth(mode=mode,
1204                    datastructure=datastructure,
1205                    )
1206    ###)
1207
1208
1209InitializeClass(WAeUPResultsWidget)
1210widgetRegistry.register(WAeUPResultsWidget)
1211###)
1212
1213class ScratchCardPin: ###(
1214    """the ScratchCardPin"""
1215    def __init__(self,prefix,batch_no,number):
1216        if not batch_no and not number:
1217            s = prefix
1218            if len(s) > 3:
1219                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1220            else:
1221                prefix,batch_no,number = s,'',''
1222        self.p = prefix
1223        self.b = batch_no
1224        self.n = number
1225
1226    def __str__(self):
1227        return "%s-%s-%s" % (self.p,self.b,self.n)
1228
1229    def __repr__(self):
1230        return "%s%s%s" % (self.p,self.b,self.n)
1231###)
1232
1233class ScratchcardPinWidget(CPSStringWidget): ###(
1234    """ ScratchcardPin Widget"""
1235    meta_type = "Scratchcard Pin Widget"
1236    _properties = CPSWidget._properties + (
1237        {'id': 'prefix', 'type': 'string', 'mode': 'w',
1238         'label': 'Prefix'},
1239         {'id': 'reference', 'type': 'string', 'mode': 'w',
1240         'label': 'Reference Field'},
1241         {'id': 'reuse_pin', 'type': 'boolean', 'mode': 'w',
1242         'label': 'Reuse Application Pin'},
1243        )
1244    prefix = ''
1245    reference = ''
1246    reuse_pin = False
1247
1248    def prepare(self, datastructure, **kw): ###(
1249        """Prepare datastructure from datamodel."""
1250        datamodel = datastructure.getDataModel()
1251        v = datamodel[self.fields[0]]
1252        widget_id = self.getWidgetId()
1253        if v and type(v) is StringType:
1254            try:
1255                p,b,n = v.split('-')
1256                v = ScratchCardPin(p,b,n)
1257            except ValueError:
1258                v = ScratchCardPin(v,'','')
1259        if v:
1260            p = '%s' % v.p
1261            b = '%s' % v.b
1262            n = '%s' % v.n
1263        else:
1264            p = self.prefix
1265            if p.startswith('@'):
1266                p = getattr(self,self.prefix[1:])()
1267            b = n = ''
1268            v = ScratchCardPin(p,b,n)
1269        datastructure[widget_id] = v
1270        datastructure[widget_id+'_p'] = p
1271        datastructure[widget_id+'_b'] = b
1272        datastructure[widget_id+'_n'] = n
1273    ###)
1274
1275    def validate(self, datastructure, **kw): ###(
1276        """Validate datastructure and update datamodel."""
1277        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1278        widget_id = self.getWidgetId()
1279        v = datastructure[widget_id]
1280        #import pdb;pdb.set_trace()
1281        err = 0
1282        mapping = {}
1283        prefix= self.prefix
1284        if prefix.startswith('@'):
1285            prefix= getattr(self,self.prefix[1:])()
1286        b = datastructure[widget_id+'_b'].strip()
1287        n = datastructure[widget_id+'_n'].strip()
1288        pins = self.portal_pins
1289        pin = "%(prefix)s%(b)s%(n)s" % vars()
1290        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1291        do = 1
1292        s_id = str(self.portal_membership.getAuthenticatedMember())
1293        if self.isStaff():
1294            do = 0
1295            err ='You are not a Student. PIN neither checked nor used.'
1296            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1297        elif len(b) > 1 and b.find('-') > -1:
1298            do = 0
1299            err = 'PIN must not contain "-".'
1300            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1301        elif n.find('-') > -1:
1302            do = 0
1303            err = 'PIN must not contain "-".'
1304            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1305        elif len(n) != 10:
1306            do = 0
1307            err = 'Invalid PIN length'
1308            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1309        elif self.reference == "":
1310            ref = s_id
1311        else:
1312            ref = datastructure[self.reference]
1313            if datastructure.errors:
1314                do = 0
1315                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1316                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1317            elif prefix == 'APP' and not self.reuse_pin:
1318                res =  self.applicants_catalog(reg_no = ref)
1319                if not res:
1320                    res =  self.applicants_catalog(reg_no = ref.upper())
1321                if res and res[0].pin == pin_str:
1322                    do = 0
1323                    err = 'Application PINs cannot be reused.'
1324                    s_logger.info('%s entered same PIN as for screening application %s' % (s_id,pin_str))
1325
1326        while do:
1327            ok,record = pins.searchAndSetRecord(pin,ref,prefix)
1328            if ok < -2 or ok > 2:
1329                err = 'Unknown error, please report!'
1330                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1331                break
1332            elif ok == -2:
1333                err = 'Service already is activated but with a different PIN.'
1334                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1335                break
1336            elif ok == -1:
1337                err = 'Invalid PIN'
1338                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1339                break
1340            if ok == 0:
1341                err = 'PIN already used'
1342                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1343                break
1344            if ok >= 1:
1345                #import pdb;pdb.set_trace()
1346                if self.isStudent():
1347                    if self.reference == "jamb_reg_no":
1348                        err = "You are already logged in."
1349                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1350                        break
1351                    if ok == 1:
1352                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1353                    else:
1354                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1355                    break
1356                else:
1357                    student = getStudentByRegNo(self,ref)
1358                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1359                if student is None:
1360                    err = "Student record not found."
1361                    s_logger.info('%s not found in admission list' % (ref))
1362                    break
1363                s_id = student.getId()
1364                if ok == 2:
1365                    if self.reference == "jamb_reg_no":
1366                        if hasattr(self.portal_directories.students,s_id):
1367                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1368                            mapping = {'id': s_id}
1369                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1370                            break
1371                        else:
1372                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1373                    else:
1374                        err = "Unknown error"
1375                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1376                        break
1377                try:
1378                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1379                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1380                except:
1381                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1382                    mapping = {'id': s_id}
1383                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1384                    break
1385            break
1386        if err:
1387            datastructure.setError(widget_id, err,mapping)
1388        else:
1389            datamodel = datastructure.getDataModel()
1390            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1391            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1392            datastructure[widget_id+'_p'] = prefix
1393            datastructure[widget_id+'_b'] = b
1394            datastructure[widget_id+'_n'] = n
1395            datastructure['s_id'] = s_id
1396        return not err
1397
1398###)
1399
1400    def render(self, mode, datastructure, **kw): ###(
1401        """Render in mode from datastructure."""
1402        render_method = 'widget_scratch_card_pin_render'
1403        meth = getattr(self, render_method, None)
1404        if meth is None:
1405            raise RuntimeError("Unknown Render Method %s for widget type %s"
1406                               % (render_method, self.getId()))
1407
1408        # XXX AT: datastructure has to be set again here, in case we're in edit
1409        # or create mode, because a default value has to be provided.
1410        #import pdb;pdb.set_trace()
1411        datamodel = datastructure.getDataModel()
1412        v = datamodel[self.fields[0]]
1413        if v and type(v) is StringType:
1414            try:
1415                p,b,n = v.split('-')
1416                v = ScratchCardPin(p,b,n)
1417            except ValueError:
1418                v = ScratchCardPin(self.prefix,'XXX',v)
1419                pass
1420        if v:
1421            prefix= '%s' % v.p
1422            b = '%s' % v.b
1423            n = '%s' % v.n
1424        else:
1425            prefix= self.prefix
1426            if prefix.startswith('@'):
1427                prefix= getattr(self,self.prefix[1:])()
1428            b = n = ''
1429            v = ScratchCardPin(prefix,b,n)
1430        widget_id = self.getWidgetId()
1431        datastructure[widget_id] = v
1432        datastructure[widget_id+'_p'] = prefix
1433        datastructure[widget_id+'_b'] = b
1434        datastructure[widget_id+'_n'] = n
1435        return meth(mode=mode,
1436                    datastructure=datastructure,
1437                    )
1438    ###)
1439
1440InitializeClass(ScratchcardPinWidget)
1441widgetRegistry.register(ScratchcardPinWidget)
1442###)
1443
1444class PumePinWidget(ScratchcardPinWidget): ###(
1445    """ Pume Pin Widget"""
1446    meta_type = "Pume Pin Widget"
1447    catalog = "applicants_catalog"
1448    reference = ''
1449
1450    def prepare(self, datastructure, **kw): ###(
1451        """Prepare datastructure from datamodel."""
1452        datamodel = datastructure.getDataModel()
1453        #import pdb;pdb.set_trace()
1454        v = datamodel[self.fields[0]]
1455        widget_id = self.getWidgetId()
1456        if v and type(v) is StringType:
1457            try:
1458                p,b,n = v.split('-')
1459                v = ScratchCardPin(p,b,n)
1460            except ValueError:
1461                v = ScratchCardPin(v,'','')
1462        if v:
1463            p = '%s' % v.p
1464            b = '%s' % v.b
1465            n = '%s' % v.n
1466        else:
1467            p = self.prefix
1468            if p.startswith('@'):
1469                p = getattr(self,self.prefix[1:])()
1470            b = n = ''
1471            v = ScratchCardPin(p,b,n)
1472        datastructure[widget_id] = v
1473        datastructure[widget_id+'_p'] = p
1474        datastructure[widget_id+'_b'] = b
1475        datastructure[widget_id+'_n'] = n
1476    ###)
1477
1478    def validate(self, datastructure, **kw): ###(
1479        """Validate datastructure and update datamodel."""
1480        s_logger = logging.getLogger('Widgets.PumePinWidget.validate')
1481        widget_id = self.getWidgetId()
1482        v = datastructure[widget_id]
1483        err = 0
1484        mapping = {}
1485        prefix= self.prefix
1486        if prefix.startswith('@'):
1487            prefix= getattr(self,self.prefix[1:])()
1488        b = datastructure[widget_id+'_b'].strip()
1489        n = datastructure[widget_id+'_n'].strip()
1490        pins = self.portal_pins
1491        pin = "%(prefix)s%(b)s%(n)s" % vars()
1492        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1493        member_id = str(self.portal_membership.getAuthenticatedMember())
1494        do = 1
1495        if self.isStaff():
1496            do = 0
1497            err ='You are logged in, please log out. PIN neither checked nor used.'
1498            s_logger.info('%s tried to use scratch card %s' % (member_id,pin_str))
1499        elif self.isStudent():
1500            do = 0
1501            #ref = datastructure[self.reference]
1502            err ='You are logged in, please log out. PIN neither checked nor used.'
1503            s_logger.info('%s applied for screening test while logged in with pin %s' % (member_id,pin_str))
1504        elif len(b) > 1 and b.find('-') > -1:
1505            do = 0
1506            err = 'PIN must not contain "-"'
1507            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1508        elif n.find('-') > -1:
1509            do = 0
1510            err = 'PIN must not contain "-"'
1511            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1512        elif len(n) != 10:
1513            do = 0
1514            err = 'Invalid PIN length'
1515            s_logger.info('%s entered invalid PIN with length %d' % (member_id,len(n)))
1516        elif self.reference == "":
1517            ref = n
1518        else:
1519            ref = datastructure[self.reference]
1520            if datastructure.errors:
1521                do = 0
1522                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1523                s_logger.info('%s/%s entered wrong data together with PIN %s' % (member_id,ref,pin_str))
1524        while do:
1525            ok,pin_record = pins.searchAndSetRecord(pin,ref,prefix)
1526            if ok < -2 or ok > 2:
1527                err = 'Unknown error, please report!'
1528                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
1529                break
1530            elif ok == -2:
1531                err = 'Service is already activated but with a different PIN.'
1532                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
1533                break
1534            elif ok == -1:
1535                err = 'Invalid PIN'
1536                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
1537                break
1538            if ok == 0:
1539                err = 'PIN already used'
1540                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
1541                break
1542            if ok >= 1:
1543                #screening_type = self.REQUEST.form.get('screening_type','unknown')
1544                #screening_type = datastructure['screening_type']
1545                if self.REQUEST.traverse_subpath:
1546                    screening_type_request = self.REQUEST.traverse_subpath[0]
1547                else:
1548                    screening_type_request = 'manage'
1549
1550                if datastructure.has_key('record'):
1551                    applicant = datastructure['record']
1552                    if applicant.screening_type != screening_type_request\
1553                          and screening_type_request != 'manage':
1554                        err = "You are using the wrong access form!"
1555                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1556                        break
1557                    if not applicant.pin:
1558                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1559                        d = {}
1560                        d['reg_no'] = applicant.reg_no
1561                        d['pin'] = pin_str
1562                        #d['screening_type'] = screening_type
1563                        #d['status'] = 'entered'
1564                        getattr(self,self.catalog).modifyRecord(**d)
1565                    elif applicant.pin != pin_str:
1566                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
1567                    elif applicant.pin == pin_str:
1568                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1569                else:
1570                    datastructure['reg_no'] = ref
1571                    res = self.applicants_catalog(reg_no = ref)
1572                    if not res:
1573                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1574                        d = {}
1575                        d['reg_no'] = ref
1576                        d['pin'] = pin_str
1577                        d['status'] = 'entered'
1578                        d['screening_type'] = screening_type_request
1579                        d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1],
1580                                                  pin_record.serial)                       
1581                        self.applicants_catalog.addRecord(**d)
1582                    else:
1583                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (ref,ref,pin_str))
1584            break
1585        if err:
1586            datastructure.setError(widget_id, err,mapping)
1587        else:
1588            datamodel = datastructure.getDataModel()
1589            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1590            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1591            datastructure[widget_id+'_p'] = prefix
1592            datastructure[widget_id+'_b'] = b
1593            datastructure[widget_id+'_n'] = n
1594        return not err
1595    ###)
1596
1597    def render(self, mode, datastructure, **kw): ###(
1598        """Render in mode from datastructure."""
1599        render_method = 'widget_scratch_card_pin_render'
1600        meth = getattr(self, render_method, None)
1601        if meth is None:
1602            raise RuntimeError("Unknown Render Method %s for widget type %s"
1603                               % (render_method, self.getId()))
1604
1605        # XXX AT: datastructure has to be set again here, in case we're in edit
1606        # or create mode, because a default value has to be provided.
1607        #import pdb;pdb.set_trace()
1608        datamodel = datastructure.getDataModel()
1609        v = datamodel[self.fields[0]]
1610        #import pdb;pdb.set_trace()
1611        if v and type(v) is StringType:
1612            try:
1613                p,b,n = v.split('-')
1614                v = ScratchCardPin(p,b,n)
1615            except ValueError:
1616                v = ScratchCardPin(self.prefix,'XXX',v)
1617                pass
1618        if v:
1619            prefix= '%s' % v.p
1620            b = '%s' % v.b
1621            n = '%s' % v.n
1622        else:
1623            prefix= self.prefix
1624            if prefix.startswith('@'):
1625                prefix= getattr(self,self.prefix[1:])()
1626            b = n = ''
1627            v = ScratchCardPin(prefix,b,n)
1628        widget_id = self.getWidgetId()
1629        datastructure[widget_id] = v
1630        datastructure[widget_id+'_p'] = prefix
1631        datastructure[widget_id+'_b'] = b
1632        datastructure[widget_id+'_n'] = n
1633        return meth(mode=mode,
1634                    datastructure=datastructure,
1635                    )
1636    ###)
1637
1638InitializeClass(PumePinWidget)
1639widgetRegistry.register(PumePinWidget)
1640###)
1641
1642class WAeUPImageWidget(CPSImageWidget): ###(
1643    """Photo widget."""
1644    meta_type = 'WAeUP Image Widget'
1645
1646    def render(self, mode, datastructure, **kw):
1647        render_method = 'widget_waeup_image_render'
1648        meth = getattr(self, render_method, None)
1649        if meth is None:
1650            raise RuntimeError("Unknown Render Method %s for widget type %s"
1651                               % (render_method, self.getId()))
1652        img_info = self.getImageInfo(datastructure)
1653        return meth(mode=mode, datastructure=datastructure, **img_info)
1654
1655InitializeClass(WAeUPImageWidget)
1656
1657widgetRegistry.register(WAeUPImageWidget)
1658###)
1659
1660class ApplicationImageWidget(CPSImageWidget): ###(
1661    """Image widget with filesystem storage."""
1662    meta_type = 'Application Image Widget'
1663    _properties = CPSImageWidget._properties +\
1664    (
1665     {'id': 'path', 'type': 'string', 'mode': 'w',
1666      'label': 'Relative Path'},
1667     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1668      'label': 'Field to build the id'},
1669    )
1670    path = "images"
1671    storage_path = "%s/import/%s" % (i_home,path)
1672    id_field = "reg_no"
1673
1674    def getImageInfo(self, datastructure): ###(
1675        """Get the file info from the datastructure."""
1676        widget_id = self.getWidgetId()
1677        if  datastructure.has_key(widget_id):
1678            fileupload = datastructure[widget_id]
1679            dm = datastructure.getDataModel()
1680            field_id = self.fields[0]
1681            screening_type = datastructure.get('screening_type')
1682            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1683                                            field_id,)
1684            base_path = os.path.join(screening_type,current_filename)
1685            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1686            file_path = os.path.join(self.storage_path,base_path)
1687            #import pdb; pdb.set_trace()
1688        else:
1689            file_path = "XXX"
1690        # read the file from the filesystem
1691        if not os.path.exists(file_path):
1692            height = -1
1693            width = -1
1694            empty_file = True
1695            session_file = False
1696            current_filename = ''
1697            content_url = ''
1698            size = 0
1699            mimetype = ''
1700            last_modified = ''
1701            height = ''
1702            width = ''
1703
1704        else:
1705            image = open(file_path)
1706            from OFS.Image import getImageInfo as getImageInfoOFS
1707            image.seek(0)
1708            data = image.read(2000)
1709            size = len(data)
1710            empty_file = size == 0
1711            session_file = False
1712            last_modified = ''
1713            image.close()
1714            mimetype, width, height = getImageInfoOFS(data)
1715
1716            if width < 0:
1717                width = None
1718            if height < 0:
1719                height = None
1720
1721            if (self.allow_resize
1722                and height is not None
1723                and width  is not None):
1724                z_w = z_h = 1
1725                h = int(self.display_height)
1726                w = int(self.display_width)
1727                if w and h:
1728                    if w < width:
1729                        z_w = w / float(width)
1730                    if h < height:
1731                        z_h = h / float(height)
1732                    zoom = min(z_w, z_h)
1733                    width = int(zoom * width)
1734                    height = int(zoom * height)
1735                #import pdb;pdb.set_trace()
1736        image_info = {
1737            'empty_file': empty_file,
1738            'session_file': session_file,
1739            'current_filename': current_filename,
1740            'size': size,
1741            'last_modified': last_modified,
1742            'content_url': content_url,
1743            'mimetype': mimetype,
1744            }
1745        title = image_info['current_filename']
1746        alt = title or ''
1747        #height = int(self.display_height)
1748        #width = int(self.display_width)
1749        if height is None or width is None:
1750            tag = renderHtmlTag('img', src=image_info['content_url'],
1751                                alt=alt, title=title)
1752        else:
1753            tag = renderHtmlTag('img', src=image_info['content_url'],
1754                                width=str(width), height=str(height),
1755                                alt=alt, title=title)
1756
1757        image_info['height'] = height
1758        image_info['width'] = width
1759        image_info['image_tag'] = tag
1760        return image_info
1761    ###)
1762
1763    def checkFileName(self, filename, mimetype):
1764        return '', {}
1765        if mimetype and mimetype.startswith('image'):
1766            return '', {}
1767        return 'cpsschemas_err_image', {}
1768
1769    def prepare(self, datastructure, **kw): ###(
1770        """Prepare datastructure from datamodel."""
1771        datamodel = datastructure.getDataModel()
1772        widget_id = self.getWidgetId()
1773        file_name = datamodel[self.fields[0]]
1774        #import pdb; pdb.set_trace()
1775        if self.allow_resize:
1776            datastructure[self.getWidgetId() + '_resize'] = ''
1777        screening_type = datamodel.get('screening_type',None)
1778        if not screening_type:
1779            screening_type = self.REQUEST.form.get('screening_type','pume')
1780        datastructure["screening_type"] = screening_type
1781        datastructure[widget_id] = file_name
1782        datastructure[widget_id + '_choice'] = 'change'
1783        title = 'Passport Foto'
1784        datastructure[widget_id + '_filename'] = title
1785    ###)
1786
1787    def validate(self, datastructure, **kw): ###(
1788        """Update datamodel from user data in datastructure.
1789        """
1790        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1791        datamodel = datastructure.getDataModel()
1792        field_id = self.fields[0]
1793        widget_id = self.getWidgetId()
1794        store = False
1795        fileupload = None
1796        mimetype = None
1797        old_file = datamodel[field_id]
1798        # if old_file is not None:
1799        #     old_filename = old_file.title
1800        # else:
1801        #     old_filename = ''
1802        choice = datastructure[widget_id+'_choice']
1803        fileupload = datastructure[widget_id]
1804        is_upload = isinstance(fileupload, FileUpload)
1805        #import pdb; pdb.set_trace()
1806        if not is_upload and not datamodel[field_id]:
1807            if self.is_required:
1808                return self.validateError('Picture upload required', {},
1809                                          datastructure)
1810        if choice == 'delete':
1811            if self.is_required:
1812                return self.validateError('cpsschemas_err_required', {},
1813                                          datastructure)
1814            datamodel[field_id] = None
1815        elif choice == 'keep':
1816            fileupload = datastructure[widget_id]
1817            if isinstance(fileupload, PersistableFileUpload):
1818                # Keeping something from the session means we
1819                # actually want to store it.
1820                store = True
1821            # else:
1822            #     # Nothing to change, don't pollute datastructure
1823            #     # with something costly already stored, which therefore
1824            #     # doesn't need to be kept in the session.
1825            #     self.unprepare(datastructure)
1826        elif choice == 'change' and is_upload:
1827            if not fileupload:
1828                return self.validateError('cpsschemas_err_file_empty', {},
1829                                          datastructure)
1830            if not isinstance(fileupload, FileUpload):
1831                return self.validateError('cpsschemas_err_file', {},
1832                                          datastructure)
1833            fileupload.seek(0, 2) # end of file
1834            size = fileupload.tell()
1835            if not size:
1836                return self.validateError('cpsschemas_err_file_empty', {},
1837                                          datastructure)
1838            if self.size_max and size > self.size_max:
1839                max_size_str = self.getHumanReadableSize(self.size_max)
1840                err = 'This file is too big, the allowed max size is ${max_size}'
1841                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1842                err_mapping = {'max_size': max_size_str}
1843                return self.validateError(err, err_mapping, datastructure)
1844            store = True
1845
1846
1847        # Find filename
1848        if is_upload and store:
1849            ext ='jpg'
1850            screening_type = datastructure.get('screening_type')
1851            filename = "%s_%s.%s" % (datastructure[self.id_field],
1852                                     self.getWidgetId(),
1853                                     ext)
1854            datamodel[field_id] = filename
1855            registry = getToolByName(self, 'mimetypes_registry')
1856            mimetype = registry.lookupExtension(filename.lower())
1857            if mimetype is not None:
1858                mimetype = str(mimetype) # normalize
1859            file = self.makeFile(filename, fileupload, datastructure)
1860            # Fixup mimetype
1861            if mimetype and file.content_type != mimetype:
1862                file.content_type = mimetype
1863            # Store the file in the filesystem
1864            #import pdb;pdb.set_trace()
1865            base_path = os.path.join(self.storage_path, screening_type)
1866            if not os.path.exists(base_path):
1867                os.mkdir(base_path)
1868            full_path = os.path.join(base_path, filename)
1869            pict = open(full_path,"w")
1870            fileupload.seek(0)
1871            pict.write(fileupload.read())
1872            pict.close()
1873
1874
1875        return True
1876
1877###)
1878
1879    def render(self, mode, datastructure, **kw): ###(
1880        render_method = 'widget_passport_render'
1881        meth = getattr(self, render_method, None)
1882        if meth is None:
1883            raise RuntimeError("Unknown Render Method %s for widget type %s"
1884                               % (render_method, self.getId()))
1885        img_info = self.getImageInfo(datastructure)
1886        return meth(mode=mode, datastructure=datastructure, **img_info)
1887    ###)
1888
1889InitializeClass(ApplicationImageWidget)
1890
1891widgetRegistry.register(ApplicationImageWidget)
1892###)
1893
1894class FileImageWidget(CPSImageWidget): ###(
1895    """Image widget with filesystem storage."""
1896    meta_type = 'File Image Widget'
1897    _properties = CPSImageWidget._properties +\
1898    (
1899     {'id': 'path', 'type': 'string', 'mode': 'w',
1900      'label': 'Relative Path'},
1901     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1902      'label': 'Field to build the id'},
1903     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
1904      'label': 'Show Image'},
1905    )
1906    path = "images"
1907    #storage_path = "%s/%s" % (i_home,path)
1908    id_field = ""
1909    show_image = False
1910
1911    def getStorageImageInfo(self,field_id):
1912        info = {}
1913        if self.id_field == "":
1914            student_id = self.getStudentId()
1915        else:
1916            student_id = datastructure[self.id_field]
1917        # student_path = os.path.join(self.storage_path,
1918        #                             student_id)
1919        student_path = getImagesDir(student_id)
1920        image_name = ''
1921        content_url = ''
1922        current_filename = ''
1923        if os.path.exists(student_path):
1924            for name in os.listdir(student_path):
1925                if name.startswith(field_id):
1926                    image_name = name
1927                    break
1928        if image_name:
1929            info['image_name'] = image_name
1930            info['content_url'] = os.path.join(self.portal_url(),
1931                                               "viewimage",
1932                                               student_id,
1933                                               image_name,
1934                                              )
1935            info['current_filename'] =  image_name
1936            info['file_path'] = os.path.join(student_path, image_name)
1937        return info
1938
1939    def getImageInfo(self, datastructure): ###(
1940        """Get the file info from the datastructure."""
1941        widget_id = self.getWidgetId()
1942        if  datastructure.has_key(widget_id):
1943            fileupload = datastructure[widget_id]
1944            dm = datastructure.getDataModel()
1945            field_id = self.fields[0]
1946            info = self.getStorageImageInfo(field_id)
1947        else:
1948            file_path = "XXX"
1949            title = ""
1950        # read the file from the filesystem
1951        #import pdb; pdb.set_trace()
1952        #if not os.path.exists(file_path):
1953        if not info:
1954            title = ""
1955            height = -1
1956            width = -1
1957            empty_file = True
1958            session_file = False
1959            current_filename = ''
1960            content_url = ''
1961            size = 0
1962            mimetype = ''
1963            last_modified = ''
1964            height = ''
1965            width = ''
1966        else:
1967            title = info['image_name']
1968            current_filename = info['current_filename']
1969            content_url = info['content_url']
1970            image = open(info['file_path'])
1971            from OFS.Image import getImageInfo as getImageInfoOFS
1972            image.seek(0)
1973            data = image.read(2000)
1974            size = len(data)
1975            empty_file = size == 0
1976            session_file = False
1977            last_modified = ''
1978            image.close()
1979            mimetype, width, height = getImageInfoOFS(data)
1980            registry = getToolByName(self, 'mimetypes_registry')
1981            mimetype = (registry.lookupExtension(current_filename.lower()) or
1982                        registry.lookupExtension('file.bin'))
1983            if width < 0:
1984                width = None
1985            if height < 0:
1986                height = None
1987
1988            if (self.allow_resize
1989                and height is not None
1990                and width  is not None):
1991                z_w = z_h = 1
1992                h = int(self.display_height)
1993                w = int(self.display_width)
1994                if w and h:
1995                    if w < width:
1996                        z_w = w / float(width)
1997                    if h < height:
1998                        z_h = h / float(height)
1999                    zoom = min(z_w, z_h)
2000                    width = int(zoom * width)
2001                    height = int(zoom * height)
2002                #import pdb;pdb.set_trace()
2003        image_info = {
2004            'empty_file': empty_file,
2005            'session_file': session_file,
2006            'current_filename': title,
2007            'size': size,
2008            'last_modified': last_modified,
2009            'content_url': content_url,
2010            'mimetype': mimetype,
2011            }
2012        alt = title or ''
2013        #height = int(self.display_height)
2014        #width = int(self.display_width)
2015        if height is None or width is None:
2016            tag = renderHtmlTag('img', src=image_info['content_url'],
2017                                alt=alt, title=title)
2018        else:
2019            tag = renderHtmlTag('img', src=image_info['content_url'],
2020                                width=str(width), height=str(height),
2021                                alt=alt, title=title)
2022
2023        image_info['height'] = height
2024        image_info['width'] = width
2025        image_info['image_tag'] = tag
2026        image_info['show_image'] = self.show_image
2027        return image_info
2028    ###)
2029
2030    # def checkFileName(self, filename, mimetype):
2031    #     return '', {}
2032    #     if mimetype and mimetype.startswith('image'):
2033    #         return '', {}
2034    #     return 'cpsschemas_err_image', {}
2035
2036    def prepare(self, datastructure, **kw): ###(
2037        """Prepare datastructure from datamodel."""
2038        datamodel = datastructure.getDataModel()
2039        widget_id = self.getWidgetId()
2040        file_name = datamodel[self.fields[0]]
2041        if self.id_field == "":
2042            student_id = self.getStudentId()
2043        else:
2044            student_id = datastructure[self.id_field]
2045        if student_id is not None:
2046            # student_path = os.path.join(self.storage_path,
2047            #                             student_id)
2048            student_path = getImagesDir(student_id)
2049            if not os.path.exists(student_path):
2050                self.waeup_tool.moveImagesToFS(student_id)
2051        if self.allow_resize:
2052            datastructure[self.getWidgetId() + '_resize'] = ''
2053        datastructure[widget_id] = file_name
2054        datastructure[widget_id + '_choice'] = 'change'
2055        title = 'Passport Foto'
2056        datastructure[widget_id + '_filename'] = title
2057    ###)
2058
2059    def validate(self, datastructure, **kw): ###(
2060        """Update datamodel from user data in datastructure.
2061        """
2062        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2063        datamodel = datastructure.getDataModel()
2064        field_id = self.fields[0]
2065        widget_id = self.getWidgetId()
2066        store = False
2067        fileupload = None
2068        mimetype = None
2069        old_file = datamodel[field_id]
2070        choice = datastructure[widget_id+'_choice']
2071        fileupload = datastructure[widget_id]
2072        is_upload = isinstance(fileupload, FileUpload)
2073        #import pdb; pdb.set_trace()
2074        if not is_upload and not datamodel[field_id]:
2075            if self.is_required:
2076                return self.validateError('Picture upload required', {},
2077                                          datastructure)
2078        if self.id_field == "":
2079            student_id = self.getStudentId()
2080        else:
2081            student_id = datastructure[self.id_field]
2082        if choice == 'delete':
2083            if self.is_required:
2084                return self.validateError('cpsschemas_err_required', {},
2085                                          datastructure)
2086            info= self.getStorageImageInfo(field_id)
2087            # Remove the file in the filesystem
2088            if info:
2089                os.remove(info['file_path'])
2090            datamodel[field_id] = None
2091        elif choice == 'keep':
2092            fileupload = datastructure[widget_id]
2093            if isinstance(fileupload, PersistableFileUpload):
2094                # Keeping something from the session means we
2095                # actually want to store it.
2096                store = True
2097            # else:
2098            #     # Nothing to change, don't pollute datastructure
2099            #     # with something costly already stored, which therefore
2100            #     # doesn't need to be kept in the session.
2101            #     self.unprepare(datastructure)
2102        elif choice == 'change' and is_upload:
2103            if not fileupload:
2104                return self.validateError('cpsschemas_err_file_empty', {},
2105                                          datastructure)
2106            if not isinstance(fileupload, FileUpload):
2107                return self.validateError('cpsschemas_err_file', {},
2108                                          datastructure)
2109            fileupload.seek(0, 2) # end of file
2110            size = fileupload.tell()
2111            if not size:
2112                return self.validateError('cpsschemas_err_file_empty', {},
2113                                          datastructure)
2114            if self.size_max and size > self.size_max:
2115                max_size_str = self.getHumanReadableSize(self.size_max)
2116                err = 'This file is too big, the allowed max size is ${max_size}'
2117                member_id = str(self.portal_membership.getAuthenticatedMember())
2118                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2119                err_mapping = {'max_size': max_size_str}
2120                return self.validateError(err, err_mapping, datastructure)
2121            store = True
2122
2123
2124        # Find filename
2125        if is_upload and store:
2126            filename = cookId('', '', fileupload)[0].strip()
2127            base,ext = os.path.splitext(filename)
2128            filename = "%s_%s%s" % (field_id,
2129                                    student_id,
2130                                    ext)
2131            datamodel[field_id] = filename
2132            registry = getToolByName(self, 'mimetypes_registry')
2133            mimetype = registry.lookupExtension(filename.lower())
2134            if mimetype is not None:
2135                mimetype = str(mimetype) # normalize
2136            file = self.makeFile(filename, fileupload, datastructure)
2137            # Fixup mimetype
2138            if mimetype and file.content_type != mimetype:
2139                file.content_type = mimetype
2140            # Store the file in the filesystem
2141            #student_path = os.path.join(self.storage_path,student_id)
2142            student_path = getImagesDir(student_id)
2143            if not os.path.exists(student_path):
2144                os.mkdir(student_path)
2145            full_path = os.path.join(student_path, filename)
2146            pict = open(full_path,"w")
2147            #fileupload.seek(0)
2148            #import pdb; pdb.set_trace()
2149            pict.write(str(file.data))
2150            pict.close()
2151        return True
2152    ###)
2153
2154    def render(self, mode, datastructure, **kw): ###(
2155        render_method = 'widget_image_render'
2156        meth = getattr(self, render_method, None)
2157        #import pdb;pdb.set_trace()
2158        if meth is None:
2159            raise RuntimeError("Unknown Render Method %s for widget type %s"
2160                               % (render_method, self.getId()))
2161        img_info = self.getImageInfo(datastructure)
2162        return meth(mode=mode, datastructure=datastructure, **img_info)
2163    ###)
2164
2165InitializeClass(FileImageWidget)
2166
2167widgetRegistry.register(FileImageWidget)
2168###)
2169
2170###########
2171
Note: See TracBrowser for help on using the repository browser.