source: WAeUP_SRP/base/Widgets.py @ 2437

Last change on this file since 2437 was 2433, checked in by joachim, 17 years ago

fixes for emailed problems

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