source: WAeUP_SRP/trunk/Widgets.py @ 996

Last change on this file since 996 was 996, checked in by joachim, 18 years ago

=fix pin-formatting

  • Property svn:keywords set to Id
File size: 21.6 KB
RevLine 
[47]1#-*- mode: python; mode: fold -*-
[990]2# $Id: Widgets.py 996 2006-12-05 19:28:18Z joachim $
[295]3from cgi import escape
[502]4from types import *
[22]5from Globals import InitializeClass
[199]6##from Products.CPSSchemas.Widget import CPSWidgetType
[295]7from Products.CMFCore.utils import getToolByName
[537]8from Products.CPSSchemas.BasicWidgets import CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget
[295]9from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget
[22]10from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget
[199]11from Products.CPSSchemas.Widget import widgetRegistry
12##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry
[22]13from DateTime.DateTime import DateTime
14from AccessControl import getSecurityManager
[502]15from Products.WAeUP_SRP.Students import getStudentByRegNo
[22]16from re import compile
[952]17import logging
[22]18
[952]19#from zLOG import LOG, DEBUG
[22]20
[295]21class CPSSelectWidgetForRecord(CPSSelectWidget): ###(
22    """Select widget. with record names"""
23    meta_type = 'Select Widget for Records'
24
25    field_types = ('CPS String Field',)
26    field_inits = ({'is_searchabletext': 1,},)
27
28    _properties = CPSSelectWidget._properties + (
29        {'id': 'record_id', 'type': 'string', 'mode': 'w',
30         'label': 'Record Id', 'is_required' : 1},
31        )
32
33    def render(self, mode, datastructure, **kw):
34        """Render in mode from datastructure."""
35        value = datastructure[self.getWidgetId()]
36        vocabulary = self._getVocabulary(datastructure)
37        portal = getToolByName(self, 'portal_url').getPortalObject()
38        cpsmcat = portal.translation_service
39        if mode == 'view':
40            if self.translated:
41                return escape(cpsmcat(vocabulary.getMsgid(value, value)).encode('ISO-8859-15', 'ignore'))
42            else:
43                return escape(vocabulary.get(value, value))
44        elif mode == 'edit':
45            html_widget_id = self.getHtmlWidgetId()
[444]46            res = renderHtmlTag('select',
47                                name='%s.%s:records' % (self.record_id,html_widget_id),
[295]48                                id=html_widget_id)
49            in_selection = 0
50            for k, v in vocabulary.items():
51                if self.translated:
52                    kw = {'value': k,
53                          'contents': cpsmcat(vocabulary.getMsgid(k, k)).encode('ISO-8859-15', 'ignore')
54                          }
55                else:
56                    kw = {'value': k, 'contents': v}
57                if value == k:
58                    kw['selected'] = 'selected'
59                    in_selection = 1
60                res += renderHtmlTag('option', **kw)
61            if value and not in_selection:
62                kw = {'value': value, 'contents': 'invalid: '+ str(value),
63                      'selected': 'selected'}
64                res += renderHtmlTag('option', **kw)
65            res += '</select>'
66            return res
67        raise RuntimeError('unknown mode %s' % mode)
68
69InitializeClass(CPSSelectWidgetForRecord)
70
71widgetRegistry.register(CPSSelectWidgetForRecord)
72
73###)
74
[373]75class CPSStringWidgetForRecord(CPSStringWidget): ###(
[295]76    """String widget."""
77    meta_type = 'String Widget For Record'
78
79    field_types = ('CPS String Field',)
80    field_inits = ({'is_searchabletext': 1,},)
81    _properties = CPSStringWidget._properties + (
82        {'id': 'record_id', 'type': 'string', 'mode': 'w',
83         'label': 'Record Id', 'is_required' : 1},
84        )
85
86    def render(self, mode, datastructure, **kw):
87        """Render in mode from datastructure."""
88        value = datastructure[self.getWidgetId()]
89        if mode == 'view':
90            return escape(value)
91        elif mode == 'edit':
92            # XXX TODO should use an other name than kw !
93            # XXX change this everywhere
94            html_widget_id = self.getHtmlWidgetId()
95            kw = {'type': 'text',
96                  'id'  : html_widget_id,
[444]97                  'name': '%s.%s:records' % (self.record_id,html_widget_id),
[295]98                  'value': escape(value),
99                  'size': self.display_width,
100                  }
101            if self.size_max:
102                kw['maxlength'] = self.size_max
103            return renderHtmlTag('input', **kw)
104        raise RuntimeError('unknown mode %s' % mode)
105
106InitializeClass(CPSStringWidgetForRecord)
107
108widgetRegistry.register(CPSStringWidgetForRecord)
109
[373]110###)
111
112class CertificateCourseIdWidget(CPSStringWidget): ###(
113    """ CertificateCourseId Widget"""
114    meta_type = "CertificateCourseId Widget"
[444]115
[373]116    def validate(self, datastructure, **kw):
117        """Validate datastructure and update datamodel."""
[444]118
[373]119        valid = CPSStringWidget.validate(self, datastructure, **kw)
120        if not valid:
121            return 0
122        else:
123            widget_id = self.getWidgetId()
124            value = datastructure[widget_id].upper()
125            err = 0
126            c_ids = [c.id for c in self.portal_catalog({'meta_type': "Course"})]
[381]127            if hasattr(self.aq_parent,value):
[444]128                err = 'Course %s already exists' % (value)
[381]129            elif value not in c_ids:
[444]130                err = 'Course %s does not exist' % (value)
[373]131            if err:
132                datastructure.setError(widget_id, err)
133            else:
134                datamodel = datastructure.getDataModel()
135                datamodel[self.fields[0]] = value
[444]136
[373]137            return not err
138
139InitializeClass(CertificateCourseIdWidget)
140
141widgetRegistry.register(CertificateCourseIdWidget)
[551]142###)
[373]143
144
[551]145class CourseIdWidget(CPSStringWidget): ###(
146    """ CourseId Widget"""
147    meta_type = "CourseId Widget"
148
149    def validate(self, datastructure, **kw):
150        """Validate datastructure and update datamodel."""
151
152        valid = CPSStringWidget.validate(self, datastructure, **kw)
153        if not valid:
154            return 0
155        else:
156            widget_id = self.getWidgetId()
157            value = datastructure[widget_id].upper()
158            err = 0
159            res = self.portal_catalog(meta_type= "Course",id = value)
160            if len(res) > 0:
161                err = 'Course %s already exists' % (value)
162            if err:
163                datastructure.setError(widget_id, err)
164            else:
165                datamodel = datastructure.getDataModel()
166                datamodel[self.fields[0]] = value
167
168            return not err
169
170InitializeClass(CourseIdWidget)
171
172widgetRegistry.register(CourseIdWidget)
173
174
[373]175###)
176
[714]177class WAeUPReservedRoomsWidget(CPSStringWidget): ###(
178    """ WAeUPReservedRooms Widget"""
179    meta_type = "WAeUPReservedRooms Widget"
180
181    def validate(self, datastructure, **kw):
182        """Validate datastructure and update datamodel."""
183        import re
184        valid = CPSStringWidget.validate(self, datastructure, **kw)
185        if not valid:
186            return 0
187        else:
188            widget_id = self.getWidgetId()
189            value = datastructure[widget_id]
190            err = 0
191            try:
[926]192                reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',value)
[714]193                                     if r]
194            except ValueError,msg:
195                err = str(msg)
196            if err:
197                datastructure.setError(widget_id, err)
198            else:
199                datamodel = datastructure.getDataModel()
200                datamodel[self.fields[0]] = value
201            return not err
202
203InitializeClass(WAeUPReservedRoomsWidget)
204
205widgetRegistry.register(WAeUPReservedRoomsWidget)
206
207
208###)
209
[388]210class WAeUPIdWidget(CPSStringWidget): ###(
211    """ WAeUPId Widget"""
212    meta_type = "WAeUPId Widget"
[444]213
[388]214    def validate(self, datastructure, **kw):
215        """Validate datastructure and update datamodel."""
[444]216
[388]217        valid = CPSStringWidget.validate(self, datastructure, **kw)
[422]218        id_pat_str = r"\S"
219        inv_id_pat = compile(r"^%s$" % id_pat_str)
[388]220        if not valid:
221            return 0
222        else:
[586]223            portal_type_query = {'query':['Faculty',
224                                          'Department',
225                                          'Course',
226                                          'Certificate',
227                                          'CertificateCourse',]}
[388]228            widget_id = self.getWidgetId()
229            value = datastructure[widget_id].upper()
230            err = 0
[440]231            if len(value.split()) > 1:
[783]232                err = 'Invalid Id, Id contains space(s).'
[586]233            elif self.portal_catalog(portal_type=portal_type_query,id=value):
[783]234                err = 'An object with the Id %s already exists in the Academic Section.' % (value)
[388]235            if err:
236                datastructure.setError(widget_id, err)
237            else:
238                datamodel = datastructure.getDataModel()
239                datamodel[self.fields[0]] = value
[444]240
[388]241            return not err
242
243InitializeClass(WAeUPIdWidget)
244
245widgetRegistry.register(WAeUPIdWidget)
246
247
248###)
249
[710]250##class StudentIdWidget(CPSStringWidget): ###(
251##    """ StudentId Widget"""
252##    meta_type = "StudentId Widget"
253##    digits = 8
254##    digits_str = "N"*digits
255##    letters = 2
256##    letters_str = "L"*letters
257##
258##    def validate(self, datastructure, **kw):
259##        """Validate datastructure and update datamodel."""
260##
261##        valid = CPSStringWidget.validate(self, datastructure, **kw)
262##        if not valid:
263##            return 0
264##        else:
265##            widget_id = self.getWidgetId()
266##            value = datastructure[widget_id]
267##            err = 0
268##            if not (len(value) == self.digits + self.letters and value[:self.digits].isdigit() and value[self.digits:].isalpha()):
269##                err = 'Invalid Registration Number in the format: %s%s with N = Number, L = Letter' % (self.digits_str,self.letters_str)
270##            if err:
271##                datastructure.setError(widget_id, err)
272##            else:
273##                datamodel = datastructure.getDataModel()
274##                datamodel[self.fields[0]] = value
275##
276##            return not err
277##
278##InitializeClass(StudentIdWidget)
279##widgetRegistry.register(StudentIdWidget)
280##
281#####)
[444]282
[463]283class JambRegNoWidget(CPSStringWidget): ###(
284    """ JambRegNo Widget"""
285    meta_type = "JambRegNo Widget"
286    digits = 8
287    digits_str = "N"*digits
288    letters = 2
289    letters_str = "L"*letters
290    def validate(self, datastructure, **kw):
291        """Validate datastructure and update datamodel."""
292
293        valid = CPSStringWidget.validate(self, datastructure, **kw)
[816]294        #import pdb;pdb.set_trace()
[966]295        pumeresults = self.portal_pumeresults
[463]296        if not valid:
297            return 0
298        else:
299            widget_id = self.getWidgetId()
[912]300            value = datastructure[widget_id].upper()
[463]301            err = 0
302            if not (len(value) == self.digits + self.letters and value[:self.digits].isdigit() and value[self.digits:].isalpha()):
[783]303                err = 'Invalid number, the expected format is: %s%s with N = Number, L = Letter' % (self.digits_str,self.letters_str)
[463]304            else:
[966]305                #s = getStudentByRegNo(self,value)
306                pume = pumeresults(jamb_reg_no = value)
[969]307                if len(pume) < 1:
[977]308                    err = 'No Student with JAMB RegNo %s.' % (value)
[780]309                else:
[966]310                    datastructure['pume'] = pume[0]
[463]311            if err:
312                datastructure.setError(widget_id, err)
313            else:
314                datamodel = datastructure.getDataModel()
315                datamodel[self.fields[0]] = value
316            return not err
317
318InitializeClass(JambRegNoWidget)
319
320widgetRegistry.register(JambRegNoWidget)
[47]321###)
322
[794]323class WAeUPResultsWidget(CPSStringWidget): ###(
324    """ WAeUPResults Widget"""
325    meta_type = "WAeUp Results Widget"
326
327    def prepare(self, datastructure, **kw): ###(
328        """Prepare datastructure from datamodel."""
329        datamodel = datastructure.getDataModel()
330        v = datamodel[self.fields[0]]
331        #import pdb;pdb.set_trace()
332        widget_id = self.getWidgetId()
[807]333        datastructure[widget_id] = v
[794]334        datastructure[widget_id+'_s'] = ''
335        datastructure[widget_id+'_g'] = ''
336    ###)
337
338    def validate(self, datastructure, **kw): ###(
339        """Validate datastructure and update datamodel."""
[807]340        #import pdb;pdb.set_trace()
[794]341        widget_id = self.getWidgetId()
342        v = datastructure[widget_id]
343        err = 0
344        s = datastructure[widget_id+'_s'].strip()
345        g = datastructure[widget_id+'_g'].strip()
[807]346        while 1:
347            if not s and g:
348                err = "no subject grad for subject %s " % s
349                break
350            i = 0
351            done = False
352            for sv,gv in v:
353                if sv == s:
354                    done = True
355                    if not g:
356                        v.pop(i)
357                        break
358                    v[i] = (s,g)
359                    break
360                i += 1
361            if done:
362                break
363            if s and g:
364                v.append((s,g))
365            break
[794]366        if err:
367            datastructure.setError(widget_id, err)
368        else:
369            datamodel = datastructure.getDataModel()
370            datamodel[self.fields[0]] = v
371            datastructure[widget_id+'_s'] = s
372            datastructure[widget_id+'_g'] = g
373        return not err
374    ###)
375
376    def render(self, mode, datastructure, **kw): ###(
377        """Render in mode from datastructure."""
378        render_method = 'widget_waeup_result_render'
379        meth = getattr(self, render_method, None)
380        if meth is None:
381            raise RuntimeError("Unknown Render Method %s for widget type %s"
382                               % (render_method, self.getId()))
383        #import pdb;pdb.set_trace()
384        datamodel = datastructure.getDataModel()
385        widget_id = self.getWidgetId()
386        v = datamodel[self.fields[0]]
[807]387        datastructure[widget_id] = v
[794]388        datastructure[widget_id+'_s'] = ''
389        datastructure[widget_id+'_g'] = ''
390        return meth(mode=mode,
391                    datastructure=datastructure,
392                    )
393    ###)
394
395
396InitializeClass(WAeUPResultsWidget)
397widgetRegistry.register(WAeUPResultsWidget)
398###)
399
[488]400class ScratchCardPin: ###(
401    """the ScratchCardPin"""
402    def __init__(self,prefix,batch_no,number):
[990]403        if not batch_no and not number:
404            s = prefix
[996]405            if len(s) > 3:
[990]406                prefix,batch_no,number = s[:3],s[3:-10],s[-10:]
407            else:
[996]408                prefix,batch_no,number = s,'',''
[488]409        self.p = prefix
410        self.b = batch_no
411        self.n = number
412
413    def __str__(self):
414        return "%s-%s-%s" % (self.p,self.b,self.n)
415###)
416
[47]417class ScratchcardPinWidget(CPSStringWidget): ###(
[22]418    """ ScratchcardPin Widget"""
[199]419    meta_type = "Scratchcard Pin Widget"
[488]420    _properties = CPSWidget._properties + (
421        {'id': 'prefix', 'type': 'string', 'mode': 'w',
422         'label': 'Prefix'},
423         {'id': 'reference', 'type': 'string', 'mode': 'w',
424         'label': 'Reference Field'},
425
426        )
427    prefix = ''
428    reference = ''
[502]429    def prepare(self, datastructure, **kw): ###(
[488]430        """Prepare datastructure from datamodel."""
431        datamodel = datastructure.getDataModel()
432        v = datamodel[self.fields[0]]
433        widget_id = self.getWidgetId()
[742]434        #import pdb;pdb.set_trace()
[747]435        if v and type(v) is StringType:
[990]436            try:
437                p,b,n = v.split('-')
438                v = ScratchCardPin(p,b,n)
439            except ValueError:
440                v = ScratchCardPin(v,'','')
[488]441        if v:
[742]442            p = '%s' % v.p
[488]443            b = '%s' % v.b
444            n = '%s' % v.n
445        else:
[742]446            p = self.prefix
447            if p.startswith('@'):
448                p = getattr(self,self.prefix[1:])()
[488]449            b = n = ''
[742]450            v = ScratchCardPin(p,b,n)
[488]451        datastructure[widget_id] = v
[742]452        datastructure[widget_id+'_p'] = p
[488]453        datastructure[widget_id+'_b'] = b
454        datastructure[widget_id+'_n'] = n
[758]455
[502]456###)
457
[22]458    def validate(self, datastructure, **kw):
459        """Validate datastructure and update datamodel."""
[952]460        s_logger = logging.getLogger('students_pin_usage')
[488]461        widget_id = self.getWidgetId()
462        v = datastructure[widget_id]
[996]463        #import pdb;pdb.set_trace()
[488]464        err = 0
[742]465        prefix= self.prefix
466        if prefix.startswith('@'):
467            prefix= getattr(self,self.prefix[1:])()
[488]468        b = datastructure[widget_id+'_b'].strip()
469        n = datastructure[widget_id+'_n'].strip()
[502]470        pins = self.portal_pins
[742]471        pin = "%(prefix)s%(b)s%(n)s" % vars()
[816]472        do = 1
[843]473        s_id = ''
[635]474        if self.reference == "":
475            ref = str(self.portal_membership.getAuthenticatedMember())
476        else:
477            ref = datastructure[self.reference]
[843]478            if datastructure.errors:
[816]479                do = 0
[977]480                datastructure.setError(widget_id, 'Errors in other data, PIN neither checked nor used.')
[816]481        while do:
482            ok = pins.searchAndSetRecord(pin,ref,prefix)
[710]483            if ok == -2:
[819]484                err = 'Service already activated but with a different PIN.'
[710]485                break
486            elif ok == -1:
[783]487                err = 'Invalid PIN'
[502]488                break
489            if ok == 0:
[796]490                err = 'PIN already used.'
[502]491                break
492            if ok >= 1:
[710]493                #import pdb;pdb.set_trace()
[635]494                if self.isStudent():
[992]495                    if self.reference == "jamb_reg_no":
[995]496                        err = "You are already logged in"
[994]497                        s_logger.info("Student %s logged in used Pin %s" % (ref,pin))
[992]498                        break
[952]499                    s_logger.info("Student %s used Pin %s" % (s_id,pin))
[637]500                    break
[635]501                else:
502                    student = getStudentByRegNo(self,ref)
[987]503                    s_logger.info("Student RegNo %s used Pin %s" % (ref,pin))
[502]504                if student is None:
[796]505                    err = "Student not found."
[502]506                    break
[648]507                s_id = student.getId()
[502]508                if ok == 2:
[990]509                    if self.reference == "jamb_reg_no":
510                        if hasattr(self.portal_directories.students,s_id):
511                            err = "Please login with your Student Id %s and 10-digit PIN." % s_id
512                            s_logger.info("Student %s double used Pin %s" % (s_id,pin))
513                            break
514                        else:
515                            s_logger.info("Student not Member %s double used Pin %s" % (s_id,pin))
516                    else:
[989]517                        err = "Please login with your Student Id %s and 10-digit PIN." % s_id
[990]518                        s_logger.info("Student %s double used Pin %s" % (s_id,pin))
[986]519                        break
[990]520##                if self.reference == "jamb_reg_no":
521##                    res = self.students_catalog(jamb_reg_no = ref)
522##                    if len(res) > 0:
523##                        err = "Please login with your Student Id %s and 10-digit PIN." % s_id
524##                        s_logger.info("Student %s double checked Admission Pin %s" % (s_id,pin))
525##                        break
[986]526                try:
527                    student.getContent().makeStudentMember(s_id,password=pin[4:])
528                    s_logger.info("Student %s created using Pin %s" % (s_id,pin))
529                except:
[989]530                    err = "Please login with your Student Id %s and 10-digit PIN." % s_id
[986]531                    s_logger.info("Student %s double creation with Pin %s" % (s_id,ref))
532                    break
[502]533            break
[488]534        if err:
535            datastructure.setError(widget_id, err)
536        else:
537            datamodel = datastructure.getDataModel()
[742]538            datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n)
539            datastructure[widget_id] = ScratchCardPin(prefix,b,n)
540            datastructure[widget_id+'_p'] = prefix
[488]541            datastructure[widget_id+'_b'] = b
542            datastructure[widget_id+'_n'] = n
[502]543            datastructure['s_id'] = s_id
[488]544        return not err
[444]545
[502]546    def render(self, mode, datastructure, **kw): ###(
[488]547        """Render in mode from datastructure."""
548        render_method = 'widget_scratch_card_pin_render'
549        meth = getattr(self, render_method, None)
550        if meth is None:
551            raise RuntimeError("Unknown Render Method %s for widget type %s"
552                               % (render_method, self.getId()))
553
554        # XXX AT: datastructure has to be set again here, in case we're in edit
555        # or create mode, because a default value has to be provided.
556        #import pdb;pdb.set_trace()
557        datamodel = datastructure.getDataModel()
558        v = datamodel[self.fields[0]]
[502]559        if v and type(v) is StringType:
[990]560            try:
561                p,b,n = v.split('-')
562                v = ScratchCardPin(p,b,n)
563            except ValueError:
[996]564                v = ScratchCardPin(self.prefix,'1',v)
565                pass
[488]566        if v:
[742]567            prefix= '%s' % v.p
[488]568            b = '%s' % v.b
569            n = '%s' % v.n
[22]570        else:
[742]571            prefix= self.prefix
572            if prefix.startswith('@'):
573                prefix= getattr(self,self.prefix[1:])()
[488]574            b = n = ''
[742]575            v = ScratchCardPin(prefix,b,n)
576        widget_id = self.getWidgetId()
577        datastructure[widget_id] = v
578        datastructure[widget_id+'_p'] = prefix
579        datastructure[widget_id+'_b'] = b
580        datastructure[widget_id+'_n'] = n
[758]581        return meth(mode=mode,
582                    datastructure=datastructure,
[488]583                    )
[523]584    ###)
[488]585
586
[22]587InitializeClass(ScratchcardPinWidget)
[199]588widgetRegistry.register(ScratchcardPinWidget)
[22]589
[47]590
591###)
592
[537]593class WAeUPImageWidget(CPSImageWidget):
594    """Photo widget."""
595    meta_type = 'WAeUP Image Widget'
596
597    def render(self, mode, datastructure, **kw):
598        render_method = 'widget_waeup_image_render'
599        meth = getattr(self, render_method, None)
600        if meth is None:
601            raise RuntimeError("Unknown Render Method %s for widget type %s"
602                               % (render_method, self.getId()))
603        img_info = self.getImageInfo(datastructure)
604        return meth(mode=mode, datastructure=datastructure, **img_info)
605
606
607
608InitializeClass(WAeUPImageWidget)
609
610widgetRegistry.register(WAeUPImageWidget)
611
612
[22]613###########
614
Note: See TracBrowser for help on using the repository browser.