source: WAeUP_SRP/base/Widgets.py @ 2726

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

dynamic vocs fixed

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