source: WAeUP_SRP/base/Widgets.py @ 2754

Last change on this file since 2754 was 2738, checked in by joachim, 17 years ago

parttime application

  • Property svn:keywords set to Id
File size: 81.7 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Widgets.py 2738 2007-11-22 10:28:41Z 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 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        value = datastructure[widget_id].upper()
773        id_pat_str = r"\S"
774        inv_id_pat = re.compile(r"^%s$" % id_pat_str)
775        err = 0
776        if len(value.split()) > 1:
777            err = 'Invalid Id, Id contains space(s).'
778        elif not self.portal_catalog(portal_type='Certificate',id=value):
779            err = 'No such certificate'
780        if err:
781            datastructure.setError(widget_id, err)
782        else:
783            datamodel = datastructure.getDataModel()
784            datamodel[self.fields[0]] = value
785        return not err
786
787InitializeClass(StudyCourseWidget)
788
789widgetRegistry.register(StudyCourseWidget)
790###)
791
792class JambRegNoWidget(CPSStringWidget): ###(
793    """ JambRegNo Widget"""
794    meta_type = "JambRegNo Widget"
795    _properties = CPSStringWidget._properties + (
796        {'id': 'catalog', 'type': 'string', 'mode': 'w',
797         'label': 'Catalog to search'},
798         {'id': 'reference', 'type': 'string', 'mode': 'w',
799         'label': 'Reference Field'},
800         )
801    #catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no
802    reference = ""
803    digits = 8
804    digits_str = "N"*digits
805    letters = 2
806    letters_str = "L"*letters
807    def validate(self, datastructure, **kw):
808        """Validate datastructure and update datamodel."""
809        valid = CPSStringWidget.validate(self, datastructure, **kw)
810        reg_no_catalog = getattr(self,self.catalog)
811        widget_id = self.getWidgetId()
812        value = datastructure[widget_id].upper()
813        err = 0
814        #import pdb;pdb.set_trace()
815        if kw.has_key('mode'):
816            mode = kw['mode']
817        else:
818            mode = "edit"
819        if not valid:
820            err = 'Invalid registration number'
821        elif self.reference == '':
822            #s = getStudentByRegNo(self,value)
823            pume = reg_no_catalog(jamb_reg_no = value)
824            if len(pume) < 1:
825                err = 'No student record with this registration number'
826            else:
827                datastructure['pume'] = pume[0]
828        elif mode == 'add':
829            pass
830        elif self.reference != '' and self.catalog == "applicants_catalog":
831            res = reg_no_catalog.searchResults({"%s" % self.reference: value})
832            if len(res) != 1:
833                err = 'No record with this registration number'
834            else:
835                datastructure['record'] = res[0]
836        else:
837            record = datastructure[self.reference]
838            #jamb_reg_no = getattr(record,widget_id)
839            jamb_reg_no = record.Entryregno
840            if jamb_reg_no != value:
841                err = 'Registration number does not match.'
842        if err:
843            datastructure.setError(widget_id, err)
844        else:
845            datamodel = datastructure.getDataModel()
846            datamodel[self.fields[0]] = value
847        return not err
848
849InitializeClass(JambRegNoWidget)
850
851widgetRegistry.register(JambRegNoWidget)
852###)
853
854class SecretWidget(CPSStringWidget): ###(
855    """ Secret Widget"""
856    meta_type = "Secret Widget"
857    _properties = CPSStringWidget._properties + (
858        {'id': 'reference', 'type': 'string', 'mode': 'w',
859         'label': 'Reference Record'},
860         {'id': 'check_fields', 'type': 'tokens', 'mode': 'w',
861         'label': 'Fields to check'},
862         )
863    reference = "student"
864    matric_no_catalog = 'returning_import'
865    check_fields = ("Firstname", "Middlename","Lastname")
866    def validate(self, datastructure, **kw):
867        """Validate datastructure and update datamodel."""
868        logger = logging.getLogger('Widgets.SecretWidget.validate')
869        valid = CPSStringWidget.validate(self, datastructure, **kw)
870        widget_id = self.getWidgetId()
871        value = datastructure[widget_id].upper()
872        err = 0
873        record = datastructure.get(self.reference,None)
874        #import pdb;pdb.set_trace()
875        if not valid or len(value) < 2:
876            err = 'Invalid string'
877        elif not record or datastructure.errors:
878            err = 0
879        else:
880            found = False
881            cvs = []
882            for field in self.check_fields:
883                cv = getattr(record,field).upper()
884                if len(cv.split()) > 1:
885                    for splited in cv.split():
886                        cvs.append(splited.strip())
887                else:
888                    cvs.append(cv)
889            for cv in cvs:
890                if cv  == value.upper():
891                    found = True
892                    break
893            matric_no = record.matric_no
894            name = " ".join(cvs)
895            if not found:
896                logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars())
897                err = 'No name does match.'
898            else:
899                logger.info('%(matric_no)s found %(value)s in %(name)s' % vars())
900        if err:
901            datastructure.setError(widget_id, err)
902        else:
903            datamodel = datastructure.getDataModel()
904            datamodel[self.fields[0]] = value
905        return not err
906
907InitializeClass(SecretWidget)
908
909widgetRegistry.register(SecretWidget)
910###)
911
912class WAeUPSexWidget(CPSBooleanWidget): ###(
913    """WAeUP sex widget."""
914    meta_type = 'WAeUP Sex Widget'
915
916    def validate(self, datastructure, **kw):
917        """Validate datastructure and update datamodel."""
918        value = datastructure[self.getWidgetId()]
919
920        if self.render_format not in self.render_formats:
921            self.render_format = 'select'
922
923        female = value in ('F','f','Female','female',"True",True)
924        male = value in ('M','m','Male','male','False',False)
925        if not female and not male:
926            datastructure.setError(self.getWidgetId(),
927                                   "invalid sex %s" % value)
928            return 0
929        elif female:
930            v = True
931        else:
932            v = False
933        datamodel = datastructure.getDataModel()
934        datamodel[self.fields[0]] = v
935        return 1
936
937InitializeClass(WAeUPSexWidget)
938
939widgetRegistry.register(WAeUPSexWidget)
940
941###)
942
943class MatricNoWidget(CPSStringWidget): ###(
944    """ MatricNo Widget"""
945    meta_type = "MatricNo Widget"
946
947    _properties = CPSStringWidget._properties + (
948        {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w',
949         'label': 'Catalog to search for MatricNo'},
950        { 'id': 'results_catalog', 'type': 'string', 'mode': 'w',
951         'label': 'Results Catalog'},
952         )
953    matric_no_catalog = "" #the catalog to search for matric_no
954    results_catalog = "results_import" #results catalog
955
956    def validate(self, datastructure, **kw):
957        """Validate datastructure and update datamodel."""
958        #import pdb;pdb.set_trace()
959        valid = CPSStringWidget.validate(self, datastructure, **kw)
960        logger = logging.getLogger('Widgets.MatricNoWidget.validate')
961        returning = getattr(self,self.matric_no_catalog)
962        results = getattr(self,self.results_catalog,None)
963        err = 0
964        widget_id = self.getWidgetId()
965        value = datastructure[widget_id]
966        if not valid or not value:
967            err = 'Invalid string'
968            logger.info('Invalid matric_no string %s' % value)
969        else:
970            value = value.upper()
971            datastructure['student'] = None
972            while not err:
973                res = returning(matric_no = value)
974                if len(res) < 1:
975                    logger.info('matric_no %s not found' % value)
976                    err = 'No student with this matriculation number.'
977                    break
978                datastructure['student'] = res[0]
979                if results is not None:
980                    res = results(matric_no = value)
981                    if len(res) < 1:
982                        err = 'No results for this matriculation number'
983                        continue
984                    datastructure['results'] = res
985                break
986        if err:
987            datastructure.setError(widget_id, err)
988        else:
989            datamodel = datastructure.getDataModel()
990            datamodel[self.fields[0]] = value
991        return not err
992
993InitializeClass(MatricNoWidget)
994
995widgetRegistry.register(MatricNoWidget)
996###)
997
998class StudentIdWidget(CPSStringWidget): ###(
999    """ StudentId Widget"""
1000    meta_type = "StudentId Widget"
1001    def validate(self, datastructure, **kw):
1002        """Validate datastructure and update datamodel."""
1003        valid = CPSStringWidget.validate(self, datastructure, **kw)
1004        logger = logging.getLogger('Widgets.StudentIdWidget.validate')
1005        #import pdb;pdb.set_trace()
1006        s_cat = self.students_catalog
1007        err = 0
1008        widget_id = self.getWidgetId()
1009        value = datastructure[widget_id]
1010        if not valid or not value:
1011            err = 'Invalid Id string'
1012            logger.info('Invalid id string %s' % value)
1013            datastructure['student'] = None
1014        else:
1015            value = value.upper()
1016            res = s_cat(id = value)
1017            if not res:
1018                logger.info('Student id %s not found' % value)
1019                err = 'No student with this Id'
1020                datastructure['student'] = None
1021            else:
1022                datastructure['student'] = res[0]
1023        if err:
1024            datastructure.setError(widget_id, err)
1025        else:
1026            datamodel = datastructure.getDataModel()
1027            datamodel[self.fields[0]] = value
1028        return not err
1029
1030InitializeClass(StudentIdWidget)
1031
1032widgetRegistry.register(StudentIdWidget)
1033###)
1034
1035class WAeUPMultilineResultsWidget(CPSStringWidget): ###(
1036    """ WAeUPMultilineResults Widget"""
1037    meta_type = "WAeUp Multiline Results Widget"
1038    _properties = CPSWidget._properties + (
1039        {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w',
1040         'label': 'Nr of Lines'},
1041         )
1042    nr_of_lines = 5
1043    def prepare(self, datastructure, **kw): ###(
1044        """Prepare datastructure from datamodel."""
1045        datamodel = datastructure.getDataModel()
1046        #import pdb;pdb.set_trace()
1047        widget_id = self.getWidgetId()
1048        v = datamodel[self.fields[0]]
1049        if type(v) is ListType and v:
1050            nr_results = len(v)
1051        else:
1052            v = []
1053            nr_results = 0
1054        count = 1
1055        for s,g in v:
1056            wid = "%s%02d"% (widget_id,count)
1057            datastructure[wid+'_s'] = s
1058            datastructure[wid+'_g'] = g
1059            count += 1
1060        if nr_results < self.nr_of_lines:
1061            for line in range(nr_results,self.nr_of_lines):
1062                v.append(('',''))
1063                wid = "%s%02d"% (widget_id,line)
1064                datastructure[wid+'_s'] = ''
1065                datastructure[wid+'_g'] = ''
1066        datastructure[widget_id] = v
1067        datastructure[widget_id+'_s'] = ''
1068        datastructure[widget_id+'_g'] = ''
1069    ###)
1070
1071    def validate(self, datastructure, **kw): ###(
1072        """Validate datastructure and update datamodel."""
1073        #import pdb;pdb.set_trace()
1074        widget_id = self.getWidgetId()
1075        err = 0
1076        lines = []
1077        for line in range(1,30):
1078            wid = "%s%02d"% (widget_id,line)
1079            if not datastructure.has_key(wid+'_s'):
1080                break
1081            lines.append((datastructure[wid+'_s'].strip(),
1082                         datastructure[wid+'_g'].strip()))
1083
1084        s = datastructure[widget_id+'_s'].strip()
1085        g = datastructure[widget_id+'_g'].strip()
1086        if s and g:
1087            lines.append((s,g))
1088        active = []
1089        for s,g in lines:
1090            if g != "":
1091                active.append((s,g))
1092        if err:
1093            datastructure.setError(widget_id, err)
1094        else:
1095            datamodel = datastructure.getDataModel()
1096            datamodel[self.fields[0]] = active
1097        return not err
1098    ###)
1099
1100    def render(self, mode, datastructure, **kw): ###(
1101        """Render in mode from datastructure."""
1102        render_method = 'widget_waeup_multiline_result_render'
1103        meth = getattr(self, render_method, None)
1104        if meth is None:
1105            raise RuntimeError("Unknown Render Method %s for widget type %s"
1106                               % (render_method, self.getId()))
1107        #import pdb;pdb.set_trace()
1108        datamodel = datastructure.getDataModel()
1109        widget_id = self.getWidgetId()
1110        lines = datamodel[self.fields[0]]
1111        if len(lines) < self.nr_of_lines:
1112            for line in range(len(lines),self.nr_of_lines + 1):
1113                lines.append(('',''))
1114        datastructure[widget_id] = lines
1115        datastructure[widget_id+'_s'] = ''
1116        datastructure[widget_id+'_g'] = ''
1117##        count = 1
1118##        for s,g in v:
1119##            wid = "%s%02d"% (widget_id,count)
1120##            count += 1
1121        return meth(mode=mode,
1122                    datastructure=datastructure,
1123                    )
1124    ###)
1125
1126
1127InitializeClass(WAeUPMultilineResultsWidget)
1128widgetRegistry.register(WAeUPMultilineResultsWidget)
1129###)
1130
1131class WAeUPResultsWidget(CPSStringWidget): ###(
1132    """ WAeUPResults Widget"""
1133    meta_type = "WAeUp Results Widget"
1134
1135    def prepare(self, datastructure, **kw): ###(
1136        """Prepare datastructure from datamodel."""
1137        datamodel = datastructure.getDataModel()
1138        v = datamodel[self.fields[0]]
1139        #import pdb;pdb.set_trace()
1140        widget_id = self.getWidgetId()
1141        datastructure[widget_id] = v
1142        datastructure[widget_id+'_s'] = ''
1143        datastructure[widget_id+'_g'] = ''
1144    ###)
1145
1146    def validate(self, datastructure, **kw): ###(
1147        """Validate datastructure and update datamodel."""
1148        #import pdb;pdb.set_trace()
1149        widget_id = self.getWidgetId()
1150        v = datastructure[widget_id]
1151        if not v:
1152            v = []
1153        err = 0
1154        s = datastructure[widget_id+'_s'].strip()
1155        g = datastructure[widget_id+'_g'].strip()
1156        while 1:
1157            if not s and g:
1158                err = "No subject grade for subject"
1159                break
1160            i = 0
1161            done = False
1162            for sv,gv in v:
1163                if sv == s:
1164                    done = True
1165                    if not g:
1166                        v.pop(i)
1167                        break
1168                    v[i] = (s,g)
1169                    break
1170                i += 1
1171            if done:
1172                break
1173            if s and g:
1174                v.append((s,g))
1175            break
1176        if err:
1177            datastructure.setError(widget_id, err)
1178        else:
1179            datamodel = datastructure.getDataModel()
1180            datamodel[self.fields[0]] = v
1181            datastructure[widget_id+'_s'] = s
1182            datastructure[widget_id+'_g'] = g
1183        return not err
1184    ###)
1185
1186    def render(self, mode, datastructure, **kw): ###(
1187        """Render in mode from datastructure."""
1188        render_method = 'widget_waeup_result_render'
1189        meth = getattr(self, render_method, None)
1190        if meth is None:
1191            raise RuntimeError("Unknown Render Method %s for widget type %s"
1192                               % (render_method, self.getId()))
1193        #import pdb;pdb.set_trace()
1194        datamodel = datastructure.getDataModel()
1195        widget_id = self.getWidgetId()
1196        datastructure[widget_id+'_s'] = ''
1197        datastructure[widget_id+'_g'] = ''
1198        return meth(mode=mode,
1199                    datastructure=datastructure,
1200                    )
1201    ###)
1202
1203
1204InitializeClass(WAeUPResultsWidget)
1205widgetRegistry.register(WAeUPResultsWidget)
1206###)
1207
1208class ScratchCardPin: ###(
1209    """the ScratchCardPin"""
1210    def __init__(self,prefix,batch_no,number):
1211        if not batch_no and not number:
1212            s = prefix
1213            if len(s) > 3:
1214                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
1215            else:
1216                prefix,batch_no,number = s,'',''
1217        self.p = prefix
1218        self.b = batch_no
1219        self.n = number
1220
1221    def __str__(self):
1222        return "%s-%s-%s" % (self.p,self.b,self.n)
1223
1224    def __repr__(self):
1225        return "%s%s%s" % (self.p,self.b,self.n)
1226###)
1227
1228class ScratchcardPinWidget(CPSStringWidget): ###(
1229    """ ScratchcardPin Widget"""
1230    meta_type = "Scratchcard Pin Widget"
1231    _properties = CPSWidget._properties + (
1232        {'id': 'prefix', 'type': 'string', 'mode': 'w',
1233         'label': 'Prefix'},
1234         {'id': 'reference', 'type': 'string', 'mode': 'w',
1235         'label': 'Reference Field'},
1236         {'id': 'reuse_pin', 'type': 'boolean', 'mode': 'w',
1237         'label': 'Reuse Application Pin'},
1238        )
1239    prefix = ''
1240    reference = ''
1241    reuse_pin = False
1242
1243    def prepare(self, datastructure, **kw): ###(
1244        """Prepare datastructure from datamodel."""
1245        datamodel = datastructure.getDataModel()
1246        v = datamodel[self.fields[0]]
1247        widget_id = self.getWidgetId()
1248        if v and type(v) is StringType:
1249            try:
1250                p,b,n = v.split('-')
1251                v = ScratchCardPin(p,b,n)
1252            except ValueError:
1253                v = ScratchCardPin(v,'','')
1254        if v:
1255            p = '%s' % v.p
1256            b = '%s' % v.b
1257            n = '%s' % v.n
1258        else:
1259            p = self.prefix
1260            if p.startswith('@'):
1261                p = getattr(self,self.prefix[1:])()
1262            b = n = ''
1263            v = ScratchCardPin(p,b,n)
1264        datastructure[widget_id] = v
1265        datastructure[widget_id+'_p'] = p
1266        datastructure[widget_id+'_b'] = b
1267        datastructure[widget_id+'_n'] = n
1268    ###)
1269
1270    def validate(self, datastructure, **kw): ###(
1271        """Validate datastructure and update datamodel."""
1272        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1273        widget_id = self.getWidgetId()
1274        v = datastructure[widget_id]
1275        #import pdb;pdb.set_trace()
1276        err = 0
1277        mapping = {}
1278        prefix= self.prefix
1279        if prefix.startswith('@'):
1280            prefix= getattr(self,self.prefix[1:])()
1281        b = datastructure[widget_id+'_b'].strip()
1282        n = datastructure[widget_id+'_n'].strip()
1283        pins = self.portal_pins
1284        pin = "%(prefix)s%(b)s%(n)s" % vars()
1285        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1286        do = 1
1287        s_id = str(self.portal_membership.getAuthenticatedMember())
1288        if self.isStaff():
1289            do = 0
1290            err ='You are not a Student. PIN neither checked nor used.'
1291            s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str))
1292        elif len(b) > 1 and b.find('-') > -1:
1293            do = 0
1294            err = 'PIN must not contain "-".'
1295            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1296        elif n.find('-') > -1:
1297            do = 0
1298            err = 'PIN must not contain "-".'
1299            s_logger.info('%s entered invalid PIN  containing "-"' % (s_id))
1300        elif len(n) != 10:
1301            do = 0
1302            err = 'Invalid PIN length'
1303            s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n)))
1304        elif self.reference == "":
1305            ref = s_id
1306        else:
1307            ref = datastructure[self.reference]
1308            if datastructure.errors:
1309                do = 0
1310                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1311                s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str))
1312            elif prefix == 'APP' and not self.reuse_pin:
1313                res =  self.applicants_catalog(reg_no = ref)
1314                if not res:
1315                    res =  self.applicants_catalog(reg_no = ref.upper())
1316                if res and res[0].pin == pin_str:
1317                    do = 0
1318                    err = 'Application PINs cannot be reused.'
1319                    s_logger.info('%s entered same PIN as for screening application %s' % (s_id,pin_str))
1320
1321        while do:
1322            ok = pins.searchAndSetRecord(pin,ref,prefix)
1323            if ok < -2 or ok > 2:
1324                err = 'Unknown error, please report!'
1325                s_logger.info('%s/%s caused unknown error with PIN %s' % (s_id,ref,pin_str))
1326                break
1327            elif ok == -2:
1328                err = 'Service already is activated but with a different PIN.'
1329                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str))
1330                break
1331            elif ok == -1:
1332                err = 'Invalid PIN'
1333                s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str))
1334                break
1335            if ok == 0:
1336                err = 'PIN already used'
1337                s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str))
1338                break
1339            if ok >= 1:
1340                #import pdb;pdb.set_trace()
1341                if self.isStudent():
1342                    if self.reference == "jamb_reg_no":
1343                        err = "You are already logged in."
1344                        s_logger.info('%s/%s checked admission with PIN %s though logged in' % (s_id,ref,pin_str))
1345                        break
1346                    if ok == 1:
1347                        s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1348                    else:
1349                        s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str))
1350                    break
1351                else:
1352                    student = getStudentByRegNo(self,ref)
1353                    s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str))
1354                if student is None:
1355                    err = "Student record not found."
1356                    s_logger.info('%s not found in admission list' % (ref))
1357                    break
1358                s_id = student.getId()
1359                if ok == 2:
1360                    if self.reference == "jamb_reg_no":
1361                        if hasattr(self.portal_directories.students,s_id):
1362                            err = "Please login with your Student Id ${id} and 10-digit PIN."
1363                            mapping = {'id': s_id}
1364                            s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1365                            break
1366                        else:
1367                            s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str))
1368                    else:
1369                        err = "Unknown error"
1370                        s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str))
1371                        break
1372                try:
1373                    student.getContent().makeStudentMember(s_id,password=pin[4:])
1374                    s_logger.info('%s/%s has been created using PIN %s' % (s_id,ref,pin_str))
1375                except:
1376                    err = "Please login with your Student Id ${id} and 10-digit PIN."
1377                    mapping = {'id': s_id}
1378                    s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str))
1379                    break
1380            break
1381        if err:
1382            datastructure.setError(widget_id, err,mapping)
1383        else:
1384            datamodel = datastructure.getDataModel()
1385            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1386            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1387            datastructure[widget_id+'_p'] = prefix
1388            datastructure[widget_id+'_b'] = b
1389            datastructure[widget_id+'_n'] = n
1390            datastructure['s_id'] = s_id
1391        return not err
1392
1393###)
1394
1395    def render(self, mode, datastructure, **kw): ###(
1396        """Render in mode from datastructure."""
1397        render_method = 'widget_scratch_card_pin_render'
1398        meth = getattr(self, render_method, None)
1399        if meth is None:
1400            raise RuntimeError("Unknown Render Method %s for widget type %s"
1401                               % (render_method, self.getId()))
1402
1403        # XXX AT: datastructure has to be set again here, in case we're in edit
1404        # or create mode, because a default value has to be provided.
1405        #import pdb;pdb.set_trace()
1406        datamodel = datastructure.getDataModel()
1407        v = datamodel[self.fields[0]]
1408        if v and type(v) is StringType:
1409            try:
1410                p,b,n = v.split('-')
1411                v = ScratchCardPin(p,b,n)
1412            except ValueError:
1413                v = ScratchCardPin(self.prefix,'XXX',v)
1414                pass
1415        if v:
1416            prefix= '%s' % v.p
1417            b = '%s' % v.b
1418            n = '%s' % v.n
1419        else:
1420            prefix= self.prefix
1421            if prefix.startswith('@'):
1422                prefix= getattr(self,self.prefix[1:])()
1423            b = n = ''
1424            v = ScratchCardPin(prefix,b,n)
1425        widget_id = self.getWidgetId()
1426        datastructure[widget_id] = v
1427        datastructure[widget_id+'_p'] = prefix
1428        datastructure[widget_id+'_b'] = b
1429        datastructure[widget_id+'_n'] = n
1430        return meth(mode=mode,
1431                    datastructure=datastructure,
1432                    )
1433    ###)
1434
1435InitializeClass(ScratchcardPinWidget)
1436widgetRegistry.register(ScratchcardPinWidget)
1437###)
1438
1439class PumePinWidget(ScratchcardPinWidget): ###(
1440    """ Pume Pin Widget"""
1441    meta_type = "Pume Pin Widget"
1442    catalog = "applicants_catalog"
1443    reference = ''
1444
1445    def prepare(self, datastructure, **kw): ###(
1446        """Prepare datastructure from datamodel."""
1447        datamodel = datastructure.getDataModel()
1448        #import pdb;pdb.set_trace()
1449        v = datamodel[self.fields[0]]
1450        widget_id = self.getWidgetId()
1451        if v and type(v) is StringType:
1452            try:
1453                p,b,n = v.split('-')
1454                v = ScratchCardPin(p,b,n)
1455            except ValueError:
1456                v = ScratchCardPin(v,'','')
1457        if v:
1458            p = '%s' % v.p
1459            b = '%s' % v.b
1460            n = '%s' % v.n
1461        else:
1462            p = self.prefix
1463            if p.startswith('@'):
1464                p = getattr(self,self.prefix[1:])()
1465            b = n = ''
1466            v = ScratchCardPin(p,b,n)
1467        datastructure[widget_id] = v
1468        datastructure[widget_id+'_p'] = p
1469        datastructure[widget_id+'_b'] = b
1470        datastructure[widget_id+'_n'] = n
1471    ###)
1472
1473    def validate(self, datastructure, **kw): ###(
1474        """Validate datastructure and update datamodel."""
1475        #import pdb;pdb.set_trace()
1476        s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate')
1477        widget_id = self.getWidgetId()
1478        v = datastructure[widget_id]
1479        err = 0
1480        mapping = {}
1481        prefix= self.prefix
1482        if prefix.startswith('@'):
1483            prefix= getattr(self,self.prefix[1:])()
1484        b = datastructure[widget_id+'_b'].strip()
1485        n = datastructure[widget_id+'_n'].strip()
1486        pins = self.portal_pins
1487        pin = "%(prefix)s%(b)s%(n)s" % vars()
1488        pin_str = "%(prefix)s-%(b)s-%(n)s" % vars()
1489        member_id = str(self.portal_membership.getAuthenticatedMember())
1490        do = 1
1491        if self.isStaff():
1492            do = 0
1493            err ='You are logged in, please log out. PIN neither checked nor used.'
1494            s_logger.info('%s tried to use scratch card %s' % (member_id,pin_str))
1495        elif self.isStudent():
1496            do = 0
1497            ref = datastructure[self.reference]
1498            err ='You are logged in, please log out. PIN neither checked nor used.'
1499            s_logger.info('%s/%s applied for screening test with PIN %s' % (member_id,ref,pin_str))
1500        elif len(b) > 1 and b.find('-') > -1:
1501            do = 0
1502            err = 'PIN must not contain "-"'
1503            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1504        elif n.find('-') > -1:
1505            do = 0
1506            err = 'PIN must not contain "-"'
1507            s_logger.info('%s entered invalid PIN  containing "-"' % (member_id))
1508        elif len(n) != 10:
1509            do = 0
1510            err = 'Invalid PIN length'
1511            s_logger.info('%s entered invalid PIN with length %d' % (member_id,len(n)))
1512        elif self.reference == "":
1513            ref = n
1514        else:
1515            ref = datastructure[self.reference]
1516            if datastructure.errors:
1517                do = 0
1518                datastructure.setError(widget_id, 'PIN neither checked nor used.')
1519                s_logger.info('%s/%s entered wrong data together with PIN %s' % (member_id,ref,pin_str))
1520        while do:
1521            ok = pins.searchAndSetRecord(pin,ref,prefix)
1522            if ok < -2 or ok > 2:
1523                err = 'Unknown error, please report!'
1524                s_logger.info('%s/%s caused unknown error with PIN %s' % (member_id,ref,pin_str))
1525                break
1526            elif ok == -2:
1527                err = 'Service is already activated but with a different PIN.'
1528                s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str))
1529                break
1530            elif ok == -1:
1531                err = 'Invalid PIN'
1532                s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str))
1533                break
1534            if ok == 0:
1535                err = 'PIN already used'
1536                s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str))
1537                break
1538            if ok >= 1:
1539                #screening_type = self.REQUEST.form.get('screening_type','unknown')
1540                #screening_type = datastructure['screening_type']
1541                if self.REQUEST.traverse_subpath:
1542                    screening_type_request = self.REQUEST.traverse_subpath[0]
1543                else:
1544                    screening_type_request = 'manage'
1545
1546                if datastructure.has_key('record'):
1547                    applicant = datastructure['record']
1548                    if applicant.screening_type != screening_type_request\
1549                          and screening_type_request != 'manage':
1550                        err = "You are using the wrong access form!"
1551                        s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type))
1552                        break
1553                    if not applicant.pin:
1554                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1555                        d = {}
1556                        d['reg_no'] = applicant.reg_no
1557                        d['pin'] = pin_str
1558                        #d['screening_type'] = screening_type
1559                        #d['status'] = 'entered'
1560                        getattr(self,self.catalog).modifyRecord(**d)
1561                    elif applicant.pin != pin_str:
1562                        s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str))
1563                    elif applicant.pin == pin_str:
1564                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str))
1565                else:
1566                    datastructure['reg_no'] = ref
1567                    res = self.applicants_catalog(reg_no = ref)
1568                    if not res:
1569                        s_logger.info('%s successfully used PIN %s' % (ref,pin_str))
1570                        d = {}
1571                        d['reg_no'] = ref
1572                        d['pin'] = pin_str
1573                        d['status'] = 'entered'
1574                        d['screening_type'] = screening_type_request
1575                        self.applicants_catalog.addRecord(**d)
1576                    else:
1577                        s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (ref,ref,pin_str))
1578            break
1579        if err:
1580            datastructure.setError(widget_id, err,mapping)
1581        else:
1582            datamodel = datastructure.getDataModel()
1583            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
1584            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
1585            datastructure[widget_id+'_p'] = prefix
1586            datastructure[widget_id+'_b'] = b
1587            datastructure[widget_id+'_n'] = n
1588        return not err
1589    ###)
1590
1591    def render(self, mode, datastructure, **kw): ###(
1592        """Render in mode from datastructure."""
1593        render_method = 'widget_scratch_card_pin_render'
1594        meth = getattr(self, render_method, None)
1595        if meth is None:
1596            raise RuntimeError("Unknown Render Method %s for widget type %s"
1597                               % (render_method, self.getId()))
1598
1599        # XXX AT: datastructure has to be set again here, in case we're in edit
1600        # or create mode, because a default value has to be provided.
1601        #import pdb;pdb.set_trace()
1602        datamodel = datastructure.getDataModel()
1603        v = datamodel[self.fields[0]]
1604        #import pdb;pdb.set_trace()
1605        if v and type(v) is StringType:
1606            try:
1607                p,b,n = v.split('-')
1608                v = ScratchCardPin(p,b,n)
1609            except ValueError:
1610                v = ScratchCardPin(self.prefix,'XXX',v)
1611                pass
1612        if v:
1613            prefix= '%s' % v.p
1614            b = '%s' % v.b
1615            n = '%s' % v.n
1616        else:
1617            prefix= self.prefix
1618            if prefix.startswith('@'):
1619                prefix= getattr(self,self.prefix[1:])()
1620            b = n = ''
1621            v = ScratchCardPin(prefix,b,n)
1622        widget_id = self.getWidgetId()
1623        datastructure[widget_id] = v
1624        datastructure[widget_id+'_p'] = prefix
1625        datastructure[widget_id+'_b'] = b
1626        datastructure[widget_id+'_n'] = n
1627        return meth(mode=mode,
1628                    datastructure=datastructure,
1629                    )
1630    ###)
1631
1632InitializeClass(PumePinWidget)
1633widgetRegistry.register(PumePinWidget)
1634###)
1635
1636class WAeUPImageWidget(CPSImageWidget): ###(
1637    """Photo widget."""
1638    meta_type = 'WAeUP Image Widget'
1639
1640    def render(self, mode, datastructure, **kw):
1641        render_method = 'widget_waeup_image_render'
1642        meth = getattr(self, render_method, None)
1643        if meth is None:
1644            raise RuntimeError("Unknown Render Method %s for widget type %s"
1645                               % (render_method, self.getId()))
1646        img_info = self.getImageInfo(datastructure)
1647        return meth(mode=mode, datastructure=datastructure, **img_info)
1648
1649InitializeClass(WAeUPImageWidget)
1650
1651widgetRegistry.register(WAeUPImageWidget)
1652###)
1653
1654class ApplicationImageWidget(CPSImageWidget): ###(
1655    """Image widget with filesystem storage."""
1656    meta_type = 'Application Image Widget'
1657    _properties = CPSImageWidget._properties +\
1658    (
1659     {'id': 'path', 'type': 'string', 'mode': 'w',
1660      'label': 'Relative Path'},
1661     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1662      'label': 'Field to build the id'},
1663    )
1664    path = "images"
1665    storage_path = "%s/import/%s" % (i_home,path)
1666    id_field = "reg_no"
1667
1668    def getImageInfo(self, datastructure): ###(
1669        """Get the file info from the datastructure."""
1670        widget_id = self.getWidgetId()
1671        if  datastructure.has_key(widget_id):
1672            fileupload = datastructure[widget_id]
1673            dm = datastructure.getDataModel()
1674            field_id = self.fields[0]
1675            screening_type = datastructure.get('screening_type')
1676            current_filename = "%s_%s.jpg" % (datastructure[self.id_field],
1677                                            field_id,)
1678            base_path = os.path.join(screening_type,current_filename)
1679            content_url = os.path.join('viewimage_applicant',self.path,base_path)
1680            file_path = os.path.join(self.storage_path,base_path)
1681            #import pdb; pdb.set_trace()
1682        else:
1683            file_path = "XXX"
1684        # read the file from the filesystem
1685        if not os.path.exists(file_path):
1686            height = -1
1687            width = -1
1688            empty_file = True
1689            session_file = False
1690            current_filename = ''
1691            content_url = ''
1692            size = 0
1693            mimetype = ''
1694            last_modified = ''
1695            height = ''
1696            width = ''
1697
1698        else:
1699            image = open(file_path)
1700            from OFS.Image import getImageInfo as getImageInfoOFS
1701            image.seek(0)
1702            data = image.read(2000)
1703            size = len(data)
1704            empty_file = size == 0
1705            session_file = False
1706            last_modified = ''
1707            image.close()
1708            mimetype, width, height = getImageInfoOFS(data)
1709
1710            if width < 0:
1711                width = None
1712            if height < 0:
1713                height = None
1714
1715            if (self.allow_resize
1716                and height is not None
1717                and width  is not None):
1718                z_w = z_h = 1
1719                h = int(self.display_height)
1720                w = int(self.display_width)
1721                if w and h:
1722                    if w < width:
1723                        z_w = w / float(width)
1724                    if h < height:
1725                        z_h = h / float(height)
1726                    zoom = min(z_w, z_h)
1727                    width = int(zoom * width)
1728                    height = int(zoom * height)
1729                #import pdb;pdb.set_trace()
1730        image_info = {
1731            'empty_file': empty_file,
1732            'session_file': session_file,
1733            'current_filename': current_filename,
1734            'size': size,
1735            'last_modified': last_modified,
1736            'content_url': content_url,
1737            'mimetype': mimetype,
1738            }
1739        title = image_info['current_filename']
1740        alt = title or ''
1741        #height = int(self.display_height)
1742        #width = int(self.display_width)
1743        if height is None or width is None:
1744            tag = renderHtmlTag('img', src=image_info['content_url'],
1745                                alt=alt, title=title)
1746        else:
1747            tag = renderHtmlTag('img', src=image_info['content_url'],
1748                                width=str(width), height=str(height),
1749                                alt=alt, title=title)
1750
1751        image_info['height'] = height
1752        image_info['width'] = width
1753        image_info['image_tag'] = tag
1754        return image_info
1755    ###)
1756
1757    def checkFileName(self, filename, mimetype):
1758        return '', {}
1759        if mimetype and mimetype.startswith('image'):
1760            return '', {}
1761        return 'cpsschemas_err_image', {}
1762
1763    def prepare(self, datastructure, **kw): ###(
1764        """Prepare datastructure from datamodel."""
1765        datamodel = datastructure.getDataModel()
1766        widget_id = self.getWidgetId()
1767        file_name = datamodel[self.fields[0]]
1768        #import pdb; pdb.set_trace()
1769        if self.allow_resize:
1770            datastructure[self.getWidgetId() + '_resize'] = ''
1771        screening_type = datamodel.get('screening_type',None)
1772        if not screening_type:
1773            screening_type = self.REQUEST.form.get('screening_type','pume')
1774        datastructure["screening_type"] = screening_type
1775        datastructure[widget_id] = file_name
1776        datastructure[widget_id + '_choice'] = 'change'
1777        title = 'Passport Foto'
1778        datastructure[widget_id + '_filename'] = title
1779    ###)
1780
1781    def validate(self, datastructure, **kw): ###(
1782        """Update datamodel from user data in datastructure.
1783        """
1784        logger = logging.getLogger('Widgets.ApplicationImageWidget.validate')
1785        datamodel = datastructure.getDataModel()
1786        field_id = self.fields[0]
1787        widget_id = self.getWidgetId()
1788        store = False
1789        fileupload = None
1790        mimetype = None
1791        old_file = datamodel[field_id]
1792        # if old_file is not None:
1793        #     old_filename = old_file.title
1794        # else:
1795        #     old_filename = ''
1796        choice = datastructure[widget_id+'_choice']
1797        fileupload = datastructure[widget_id]
1798        is_upload = isinstance(fileupload, FileUpload)
1799        #import pdb; pdb.set_trace()
1800        if not is_upload and not datamodel[field_id]:
1801            if self.is_required:
1802                return self.validateError('Picture upload required', {},
1803                                          datastructure)
1804        if choice == 'delete':
1805            if self.is_required:
1806                return self.validateError('cpsschemas_err_required', {},
1807                                          datastructure)
1808            datamodel[field_id] = None
1809        elif choice == 'keep':
1810            fileupload = datastructure[widget_id]
1811            if isinstance(fileupload, PersistableFileUpload):
1812                # Keeping something from the session means we
1813                # actually want to store it.
1814                store = True
1815            # else:
1816            #     # Nothing to change, don't pollute datastructure
1817            #     # with something costly already stored, which therefore
1818            #     # doesn't need to be kept in the session.
1819            #     self.unprepare(datastructure)
1820        elif choice == 'change' and is_upload:
1821            if not fileupload:
1822                return self.validateError('cpsschemas_err_file_empty', {},
1823                                          datastructure)
1824            if not isinstance(fileupload, FileUpload):
1825                return self.validateError('cpsschemas_err_file', {},
1826                                          datastructure)
1827            fileupload.seek(0, 2) # end of file
1828            size = fileupload.tell()
1829            if not size:
1830                return self.validateError('cpsschemas_err_file_empty', {},
1831                                          datastructure)
1832            if self.size_max and size > self.size_max:
1833                max_size_str = self.getHumanReadableSize(self.size_max)
1834                err = 'This file is too big, the allowed max size is ${max_size}'
1835                logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) )
1836                err_mapping = {'max_size': max_size_str}
1837                return self.validateError(err, err_mapping, datastructure)
1838            store = True
1839
1840
1841        # Find filename
1842        if is_upload and store:
1843            ext ='jpg'
1844            screening_type = datastructure.get('screening_type')
1845            filename = "%s_%s.%s" % (datastructure[self.id_field],
1846                                     self.getWidgetId(),
1847                                     ext)
1848            datamodel[field_id] = filename
1849            registry = getToolByName(self, 'mimetypes_registry')
1850            mimetype = registry.lookupExtension(filename.lower())
1851            if mimetype is not None:
1852                mimetype = str(mimetype) # normalize
1853            file = self.makeFile(filename, fileupload, datastructure)
1854            # Fixup mimetype
1855            if mimetype and file.content_type != mimetype:
1856                file.content_type = mimetype
1857            # Store the file in the filesystem
1858            #import pdb;pdb.set_trace()
1859            base_path = os.path.join(self.storage_path, screening_type)
1860            if not os.path.exists(base_path):
1861                os.mkdir(base_path)
1862            full_path = os.path.join(base_path, filename)
1863            pict = open(full_path,"w")
1864            fileupload.seek(0)
1865            pict.write(fileupload.read())
1866            pict.close()
1867
1868
1869        return True
1870
1871###)
1872
1873    def render(self, mode, datastructure, **kw): ###(
1874        render_method = 'widget_passport_render'
1875        meth = getattr(self, render_method, None)
1876        if meth is None:
1877            raise RuntimeError("Unknown Render Method %s for widget type %s"
1878                               % (render_method, self.getId()))
1879        img_info = self.getImageInfo(datastructure)
1880        return meth(mode=mode, datastructure=datastructure, **img_info)
1881    ###)
1882
1883InitializeClass(ApplicationImageWidget)
1884
1885widgetRegistry.register(ApplicationImageWidget)
1886###)
1887
1888class FileImageWidget(CPSImageWidget): ###(
1889    """Image widget with filesystem storage."""
1890    meta_type = 'File Image Widget'
1891    _properties = CPSImageWidget._properties +\
1892    (
1893     {'id': 'path', 'type': 'string', 'mode': 'w',
1894      'label': 'Relative Path'},
1895     {'id': 'id_field', 'type': 'string', 'mode': 'w',
1896      'label': 'Field to build the id'},
1897     {'id': 'show_image', 'type': 'boolean', 'mode': 'w',
1898      'label': 'Show Image'},
1899    )
1900    path = "images"
1901    #storage_path = "%s/%s" % (i_home,path)
1902    id_field = ""
1903    show_image = False
1904
1905    def getStorageImageInfo(self,field_id):
1906        info = {}
1907        if self.id_field == "":
1908            student_id = self.getStudentId()
1909        else:
1910            student_id = datastructure[self.id_field]
1911        # student_path = os.path.join(self.storage_path,
1912        #                             student_id)
1913        student_path = getImagesDir(student_id)
1914        image_name = ''
1915        content_url = ''
1916        current_filename = ''
1917        if os.path.exists(student_path):
1918            for name in os.listdir(student_path):
1919                if name.startswith(field_id):
1920                    image_name = name
1921                    break
1922        if image_name:
1923            info['image_name'] = image_name
1924            info['content_url'] = os.path.join(self.portal_url(),
1925                                               "viewimage",
1926                                               student_id,
1927                                               image_name,
1928                                              )
1929            info['current_filename'] =  image_name
1930            info['file_path'] = os.path.join(student_path, image_name)
1931        return info
1932
1933    def getImageInfo(self, datastructure): ###(
1934        """Get the file info from the datastructure."""
1935        widget_id = self.getWidgetId()
1936        if  datastructure.has_key(widget_id):
1937            fileupload = datastructure[widget_id]
1938            dm = datastructure.getDataModel()
1939            field_id = self.fields[0]
1940            info = self.getStorageImageInfo(field_id)
1941        else:
1942            file_path = "XXX"
1943            title = ""
1944        # read the file from the filesystem
1945        #import pdb; pdb.set_trace()
1946        #if not os.path.exists(file_path):
1947        if not info:
1948            title = ""
1949            height = -1
1950            width = -1
1951            empty_file = True
1952            session_file = False
1953            current_filename = ''
1954            content_url = ''
1955            size = 0
1956            mimetype = ''
1957            last_modified = ''
1958            height = ''
1959            width = ''
1960        else:
1961            title = info['image_name']
1962            current_filename = info['current_filename']
1963            content_url = info['content_url']
1964            image = open(info['file_path'])
1965            from OFS.Image import getImageInfo as getImageInfoOFS
1966            image.seek(0)
1967            data = image.read(2000)
1968            size = len(data)
1969            empty_file = size == 0
1970            session_file = False
1971            last_modified = ''
1972            image.close()
1973            mimetype, width, height = getImageInfoOFS(data)
1974            registry = getToolByName(self, 'mimetypes_registry')
1975            mimetype = (registry.lookupExtension(current_filename.lower()) or
1976                        registry.lookupExtension('file.bin'))
1977            if width < 0:
1978                width = None
1979            if height < 0:
1980                height = None
1981
1982            if (self.allow_resize
1983                and height is not None
1984                and width  is not None):
1985                z_w = z_h = 1
1986                h = int(self.display_height)
1987                w = int(self.display_width)
1988                if w and h:
1989                    if w < width:
1990                        z_w = w / float(width)
1991                    if h < height:
1992                        z_h = h / float(height)
1993                    zoom = min(z_w, z_h)
1994                    width = int(zoom * width)
1995                    height = int(zoom * height)
1996                #import pdb;pdb.set_trace()
1997        image_info = {
1998            'empty_file': empty_file,
1999            'session_file': session_file,
2000            'current_filename': title,
2001            'size': size,
2002            'last_modified': last_modified,
2003            'content_url': content_url,
2004            'mimetype': mimetype,
2005            }
2006        alt = title or ''
2007        #height = int(self.display_height)
2008        #width = int(self.display_width)
2009        if height is None or width is None:
2010            tag = renderHtmlTag('img', src=image_info['content_url'],
2011                                alt=alt, title=title)
2012        else:
2013            tag = renderHtmlTag('img', src=image_info['content_url'],
2014                                width=str(width), height=str(height),
2015                                alt=alt, title=title)
2016
2017        image_info['height'] = height
2018        image_info['width'] = width
2019        image_info['image_tag'] = tag
2020        image_info['show_image'] = self.show_image
2021        return image_info
2022    ###)
2023
2024    # def checkFileName(self, filename, mimetype):
2025    #     return '', {}
2026    #     if mimetype and mimetype.startswith('image'):
2027    #         return '', {}
2028    #     return 'cpsschemas_err_image', {}
2029
2030    def prepare(self, datastructure, **kw): ###(
2031        """Prepare datastructure from datamodel."""
2032        datamodel = datastructure.getDataModel()
2033        widget_id = self.getWidgetId()
2034        file_name = datamodel[self.fields[0]]
2035        if self.id_field == "":
2036            student_id = self.getStudentId()
2037        else:
2038            student_id = datastructure[self.id_field]
2039        if student_id is not None:
2040            # student_path = os.path.join(self.storage_path,
2041            #                             student_id)
2042            student_path = getImagesDir(student_id)
2043            if not os.path.exists(student_path):
2044                self.waeup_tool.moveImagesToFS(student_id)
2045        if self.allow_resize:
2046            datastructure[self.getWidgetId() + '_resize'] = ''
2047        datastructure[widget_id] = file_name
2048        datastructure[widget_id + '_choice'] = 'change'
2049        title = 'Passport Foto'
2050        datastructure[widget_id + '_filename'] = title
2051    ###)
2052
2053    def validate(self, datastructure, **kw): ###(
2054        """Update datamodel from user data in datastructure.
2055        """
2056        logger = logging.getLogger('Widgets.FileImageWidget.validate')
2057        datamodel = datastructure.getDataModel()
2058        field_id = self.fields[0]
2059        widget_id = self.getWidgetId()
2060        store = False
2061        fileupload = None
2062        mimetype = None
2063        old_file = datamodel[field_id]
2064        choice = datastructure[widget_id+'_choice']
2065        fileupload = datastructure[widget_id]
2066        is_upload = isinstance(fileupload, FileUpload)
2067        #import pdb; pdb.set_trace()
2068        if not is_upload and not datamodel[field_id]:
2069            if self.is_required:
2070                return self.validateError('Picture upload required', {},
2071                                          datastructure)
2072        if self.id_field == "":
2073            student_id = self.getStudentId()
2074        else:
2075            student_id = datastructure[self.id_field]
2076        if choice == 'delete':
2077            if self.is_required:
2078                return self.validateError('cpsschemas_err_required', {},
2079                                          datastructure)
2080            info= self.getStorageImageInfo(field_id)
2081            # Remove the file in the filesystem
2082            if info:
2083                os.remove(info['file_path'])
2084            datamodel[field_id] = None
2085        elif choice == 'keep':
2086            fileupload = datastructure[widget_id]
2087            if isinstance(fileupload, PersistableFileUpload):
2088                # Keeping something from the session means we
2089                # actually want to store it.
2090                store = True
2091            # else:
2092            #     # Nothing to change, don't pollute datastructure
2093            #     # with something costly already stored, which therefore
2094            #     # doesn't need to be kept in the session.
2095            #     self.unprepare(datastructure)
2096        elif choice == 'change' and is_upload:
2097            if not fileupload:
2098                return self.validateError('cpsschemas_err_file_empty', {},
2099                                          datastructure)
2100            if not isinstance(fileupload, FileUpload):
2101                return self.validateError('cpsschemas_err_file', {},
2102                                          datastructure)
2103            fileupload.seek(0, 2) # end of file
2104            size = fileupload.tell()
2105            if not size:
2106                return self.validateError('cpsschemas_err_file_empty', {},
2107                                          datastructure)
2108            if self.size_max and size > self.size_max:
2109                max_size_str = self.getHumanReadableSize(self.size_max)
2110                err = 'This file is too big, the allowed max size is ${max_size}'
2111                member_id = str(self.portal_membership.getAuthenticatedMember())
2112                logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) )
2113                err_mapping = {'max_size': max_size_str}
2114                return self.validateError(err, err_mapping, datastructure)
2115            store = True
2116
2117
2118        # Find filename
2119        if is_upload and store:
2120            filename = cookId('', '', fileupload)[0].strip()
2121            base,ext = os.path.splitext(filename)
2122            filename = "%s_%s%s" % (field_id,
2123                                    student_id,
2124                                    ext)
2125            datamodel[field_id] = filename
2126            registry = getToolByName(self, 'mimetypes_registry')
2127            mimetype = registry.lookupExtension(filename.lower())
2128            if mimetype is not None:
2129                mimetype = str(mimetype) # normalize
2130            file = self.makeFile(filename, fileupload, datastructure)
2131            # Fixup mimetype
2132            if mimetype and file.content_type != mimetype:
2133                file.content_type = mimetype
2134            # Store the file in the filesystem
2135            #student_path = os.path.join(self.storage_path,student_id)
2136            student_path = getImagesDir(student_id)
2137            if not os.path.exists(student_path):
2138                os.mkdir(student_path)
2139            full_path = os.path.join(student_path, filename)
2140            pict = open(full_path,"w")
2141            #fileupload.seek(0)
2142            #import pdb; pdb.set_trace()
2143            pict.write(str(file.data))
2144            pict.close()
2145        return True
2146    ###)
2147
2148    def render(self, mode, datastructure, **kw): ###(
2149        render_method = 'widget_image_render'
2150        meth = getattr(self, render_method, None)
2151        #import pdb;pdb.set_trace()
2152        if meth is None:
2153            raise RuntimeError("Unknown Render Method %s for widget type %s"
2154                               % (render_method, self.getId()))
2155        img_info = self.getImageInfo(datastructure)
2156        return meth(mode=mode, datastructure=datastructure, **img_info)
2157    ###)
2158
2159InitializeClass(FileImageWidget)
2160
2161widgetRegistry.register(FileImageWidget)
2162###)
2163
2164###########
2165
Note: See TracBrowser for help on using the repository browser.