#-*- mode: python; mode: fold -*- # $Id: Widgets.py 1151 2006-12-29 22:05:53Z joachim $ from cgi import escape from types import * from Globals import InitializeClass ##from Products.CPSSchemas.Widget import CPSWidgetType from Products.CMFCore.utils import getToolByName from Products.CPSSchemas.BasicWidgets import CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget from Products.CPSSchemas.Widget import widgetRegistry ##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry from DateTime.DateTime import DateTime from AccessControl import getSecurityManager from Products.WAeUP_SRP.Students import getStudentByRegNo from re import compile import logging #from zLOG import LOG, DEBUG class CPSSelectWidgetForRecord(CPSSelectWidget): ###( """Select widget. with record names""" meta_type = 'Select Widget for Records' field_types = ('CPS String Field',) field_inits = ({'is_searchabletext': 1,},) _properties = CPSSelectWidget._properties + ( {'id': 'record_id', 'type': 'string', 'mode': 'w', 'label': 'Record Id', 'is_required' : 1}, ) def render(self, mode, datastructure, **kw): """Render in mode from datastructure.""" value = datastructure[self.getWidgetId()] vocabulary = self._getVocabulary(datastructure) portal = getToolByName(self, 'portal_url').getPortalObject() cpsmcat = portal.translation_service if mode == 'view': if self.translated: return escape(cpsmcat(vocabulary.getMsgid(value, value)).encode('ISO-8859-15', 'ignore')) else: return escape(vocabulary.get(value, value)) elif mode == 'edit': html_widget_id = self.getHtmlWidgetId() res = renderHtmlTag('select', name='%s.%s:records' % (self.record_id,html_widget_id), id=html_widget_id) in_selection = 0 for k, v in vocabulary.items(): if self.translated: kw = {'value': k, 'contents': cpsmcat(vocabulary.getMsgid(k, k)).encode('ISO-8859-15', 'ignore') } else: kw = {'value': k, 'contents': v} if value == k: kw['selected'] = 'selected' in_selection = 1 res += renderHtmlTag('option', **kw) if value and not in_selection: kw = {'value': value, 'contents': 'invalid: '+ str(value), 'selected': 'selected'} res += renderHtmlTag('option', **kw) res += '' return res raise RuntimeError('unknown mode %s' % mode) InitializeClass(CPSSelectWidgetForRecord) widgetRegistry.register(CPSSelectWidgetForRecord) ###) class CPSStringWidgetForRecord(CPSStringWidget): ###( """String widget.""" meta_type = 'String Widget For Record' field_types = ('CPS String Field',) field_inits = ({'is_searchabletext': 1,},) _properties = CPSStringWidget._properties + ( {'id': 'record_id', 'type': 'string', 'mode': 'w', 'label': 'Record Id', 'is_required' : 1}, ) def render(self, mode, datastructure, **kw): """Render in mode from datastructure.""" value = datastructure[self.getWidgetId()] if mode == 'view': return escape(value) elif mode == 'edit': # XXX TODO should use an other name than kw ! # XXX change this everywhere html_widget_id = self.getHtmlWidgetId() kw = {'type': 'text', 'id' : html_widget_id, 'name': '%s.%s:records' % (self.record_id,html_widget_id), 'value': escape(value), 'size': self.display_width, } if self.size_max: kw['maxlength'] = self.size_max return renderHtmlTag('input', **kw) raise RuntimeError('unknown mode %s' % mode) InitializeClass(CPSStringWidgetForRecord) widgetRegistry.register(CPSStringWidgetForRecord) ###) class CertificateCourseIdWidget(CPSStringWidget): ###( """ CertificateCourseId Widget""" meta_type = "CertificateCourseId Widget" def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" valid = CPSStringWidget.validate(self, datastructure, **kw) if not valid: return 0 else: widget_id = self.getWidgetId() value = datastructure[widget_id].upper() err = 0 c_ids = [c.id for c in self.portal_catalog({'meta_type': "Course"})] if hasattr(self.aq_parent,value): err = 'Course %s already exists' % (value) elif value not in c_ids: err = 'Course %s does not exist' % (value) if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = value return not err InitializeClass(CertificateCourseIdWidget) widgetRegistry.register(CertificateCourseIdWidget) ###) class CourseIdWidget(CPSStringWidget): ###( """ CourseId Widget""" meta_type = "CourseId Widget" def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" valid = CPSStringWidget.validate(self, datastructure, **kw) if not valid: return 0 else: widget_id = self.getWidgetId() value = datastructure[widget_id].upper() err = 0 res = self.portal_catalog(meta_type= "Course",id = value) if len(res) > 0: err = 'Course %s already exists' % (value) if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = value return not err InitializeClass(CourseIdWidget) widgetRegistry.register(CourseIdWidget) ###) class WAeUPReservedRoomsWidget(CPSStringWidget): ###( """ WAeUPReservedRooms Widget""" meta_type = "WAeUPReservedRooms Widget" def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" import re valid = CPSStringWidget.validate(self, datastructure, **kw) if not valid: return 0 else: widget_id = self.getWidgetId() value = datastructure[widget_id] err = 0 try: reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',value) if r] except (ValueError,IndexError),msg: err = str(msg) if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = value return not err InitializeClass(WAeUPReservedRoomsWidget) widgetRegistry.register(WAeUPReservedRoomsWidget) ###) class WAeUPIdWidget(CPSStringWidget): ###( """ WAeUPId Widget""" meta_type = "WAeUPId Widget" def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" valid = CPSStringWidget.validate(self, datastructure, **kw) id_pat_str = r"\S" inv_id_pat = compile(r"^%s$" % id_pat_str) if not valid: return 0 else: portal_type_query = {'query':['Faculty', 'Department', 'Course', 'Certificate', 'CertificateCourse',]} widget_id = self.getWidgetId() value = datastructure[widget_id].upper() err = 0 if len(value.split()) > 1: err = 'Invalid Id, Id contains space(s).' elif self.portal_catalog(portal_type=portal_type_query,id=value): err = 'An object with the Id %s already exists in the Academic Section.' % (value) if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = value return not err InitializeClass(WAeUPIdWidget) widgetRegistry.register(WAeUPIdWidget) ###) class StudyCourseWidget(CPSStringWidget): ###( """ StudyCourse Widget""" meta_type = "StudyCourse Widget" def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" #from Products.zdb import set_trace #set_trace() valid = CPSStringWidget.validate(self, datastructure, **kw) id_pat_str = r"\S" inv_id_pat = compile(r"^%s$" % id_pat_str) if not valid: return 0 else: widget_id = self.getWidgetId() value = datastructure[widget_id].upper() err = 0 if len(value.split()) > 1: err = 'Invalid Id, Id contains space(s).' elif not self.portal_catalog(portal_type='Certificate',id=value): err = 'No such certificate' if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = value return not err InitializeClass(StudyCourseWidget) widgetRegistry.register(StudyCourseWidget) ###) ##class StudentIdWidget(CPSStringWidget): ###( ## """ StudentId Widget""" ## meta_type = "StudentId Widget" ## digits = 8 ## digits_str = "N"*digits ## letters = 2 ## letters_str = "L"*letters ## ## def validate(self, datastructure, **kw): ## """Validate datastructure and update datamodel.""" ## ## valid = CPSStringWidget.validate(self, datastructure, **kw) ## if not valid: ## return 0 ## else: ## widget_id = self.getWidgetId() ## value = datastructure[widget_id] ## err = 0 ## if not (len(value) == self.digits + self.letters and value[:self.digits].isdigit() and value[self.digits:].isalpha()): ## err = 'Invalid Registration Number in the format: %s%s with N = Number, L = Letter' % (self.digits_str,self.letters_str) ## if err: ## datastructure.setError(widget_id, err) ## else: ## datamodel = datastructure.getDataModel() ## datamodel[self.fields[0]] = value ## ## return not err ## ##InitializeClass(StudentIdWidget) ##widgetRegistry.register(StudentIdWidget) ## #####) class JambRegNoWidget(CPSStringWidget): ###( """ JambRegNo Widget""" meta_type = "JambRegNo Widget" digits = 8 digits_str = "N"*digits letters = 2 letters_str = "L"*letters def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" valid = CPSStringWidget.validate(self, datastructure, **kw) #import pdb;pdb.set_trace() pumeresults = self.pumeresults if not valid: return 0 else: widget_id = self.getWidgetId() value = datastructure[widget_id].upper() err = 0 if not (len(value) == self.digits + self.letters and value[:self.digits].isdigit() and value[self.digits:].isalpha()): err = 'Invalid number, the expected format is: %s%s with N = Number, L = Letter' % (self.digits_str,self.letters_str) else: #s = getStudentByRegNo(self,value) pume = pumeresults(jamb_reg_no = value) if len(pume) < 1: err = 'No Student with JAMB RegNo %s.' % (value) else: datastructure['pume'] = pume[0] if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = value return not err InitializeClass(JambRegNoWidget) widgetRegistry.register(JambRegNoWidget) ###) class MatricNoWidget(CPSStringWidget): ###( """ MatricNo Widget""" meta_type = "MatricNo Widget" def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" valid = CPSStringWidget.validate(self, datastructure, **kw) #import pdb;pdb.set_trace() returning = self.returning_import results = self.results_import err = 0 if not valid: err = 'Invalid MatricNo %s.' % (value) else: widget_id = self.getWidgetId() value = datastructure[widget_id].upper() #s = getStudentByRegNo(self,value) while not err: res = returning(matric_no = value) if len(res) < 1: err = 'No Student with MatricNo %s.' % (value) continue datastructure['student'] = res[0] res = results(matric_no = value) if len(res) < 1: err = 'No Results with MatricNo %s.' % (value) continue datastructure['results'] = res break if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = value return not err InitializeClass(MatricNoWidget) widgetRegistry.register(MatricNoWidget) ###) class WAeUPMultilineResultsWidget(CPSStringWidget): ###( """ WAeUPMultilineResults Widget""" meta_type = "WAeUp Multiline Results Widget" _properties = CPSWidget._properties + ( {'id': 'nr_of_lines', 'type': 'int', 'mode': 'w', 'label': 'Nr of Lines'}, ) nr_of_lines = 5 def prepare(self, datastructure, **kw): ###( """Prepare datastructure from datamodel.""" datamodel = datastructure.getDataModel() #import pdb;pdb.set_trace() widget_id = self.getWidgetId() v = datamodel[self.fields[0]] if type(v) is ListType and v: nr_results = len(v) else: v = [] nr_results = 0 count = 1 for s,g in v: wid = "%s%02d"% (widget_id,count) datastructure[wid+'_s'] = s datastructure[wid+'_g'] = g count += 1 if nr_results < self.nr_of_lines: for line in range(nr_results,self.nr_of_lines): v.append(('','')) wid = "%s%02d"% (widget_id,line) datastructure[wid+'_s'] = '' datastructure[wid+'_g'] = '' datastructure[widget_id] = v datastructure[widget_id+'_s'] = '' datastructure[widget_id+'_g'] = '' ###) def validate(self, datastructure, **kw): ###( """Validate datastructure and update datamodel.""" #import pdb;pdb.set_trace() widget_id = self.getWidgetId() err = 0 lines = [] for line in range(1,30): wid = "%s%02d"% (widget_id,line) if not datastructure.has_key(wid+'_s'): break lines.append((datastructure[wid+'_s'].strip(), datastructure[wid+'_g'].strip())) s = datastructure[widget_id+'_s'].strip() g = datastructure[widget_id+'_g'].strip() if s and g: lines.append((s,g)) active = [] for s,g in lines: if g != "": active.append((s,g)) if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = active return not err ###) def render(self, mode, datastructure, **kw): ###( """Render in mode from datastructure.""" render_method = 'widget_waeup_multiline_result_render' meth = getattr(self, render_method, None) if meth is None: raise RuntimeError("Unknown Render Method %s for widget type %s" % (render_method, self.getId())) #import pdb;pdb.set_trace() datamodel = datastructure.getDataModel() widget_id = self.getWidgetId() lines = datamodel[self.fields[0]] if len(lines) < self.nr_of_lines: for line in range(len(lines),self.nr_of_lines + 1): lines.append(('','')) datastructure[widget_id] = lines datastructure[widget_id+'_s'] = '' datastructure[widget_id+'_g'] = '' ## count = 1 ## for s,g in v: ## wid = "%s%02d"% (widget_id,count) ## count += 1 return meth(mode=mode, datastructure=datastructure, ) ###) InitializeClass(WAeUPMultilineResultsWidget) widgetRegistry.register(WAeUPMultilineResultsWidget) ###) class WAeUPResultsWidget(CPSStringWidget): ###( """ WAeUPResults Widget""" meta_type = "WAeUp Results Widget" def prepare(self, datastructure, **kw): ###( """Prepare datastructure from datamodel.""" datamodel = datastructure.getDataModel() v = datamodel[self.fields[0]] #import pdb;pdb.set_trace() widget_id = self.getWidgetId() datastructure[widget_id] = v datastructure[widget_id+'_s'] = '' datastructure[widget_id+'_g'] = '' ###) def validate(self, datastructure, **kw): ###( """Validate datastructure and update datamodel.""" #import pdb;pdb.set_trace() widget_id = self.getWidgetId() v = datastructure[widget_id] err = 0 s = datastructure[widget_id+'_s'].strip() g = datastructure[widget_id+'_g'].strip() while 1: if not s and g: err = "no subject grad for subject %s " % s break i = 0 done = False for sv,gv in v: if sv == s: done = True if not g: v.pop(i) break v[i] = (s,g) break i += 1 if done: break if s and g: v.append((s,g)) break if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = v datastructure[widget_id+'_s'] = s datastructure[widget_id+'_g'] = g return not err ###) def render(self, mode, datastructure, **kw): ###( """Render in mode from datastructure.""" render_method = 'widget_waeup_result_render' meth = getattr(self, render_method, None) if meth is None: raise RuntimeError("Unknown Render Method %s for widget type %s" % (render_method, self.getId())) #import pdb;pdb.set_trace() datamodel = datastructure.getDataModel() widget_id = self.getWidgetId() datastructure[widget_id+'_s'] = '' datastructure[widget_id+'_g'] = '' return meth(mode=mode, datastructure=datastructure, ) ###) InitializeClass(WAeUPResultsWidget) widgetRegistry.register(WAeUPResultsWidget) ###) class ScratchCardPin: ###( """the ScratchCardPin""" def __init__(self,prefix,batch_no,number): if not batch_no and not number: s = prefix if len(s) > 3: prefix,batch_no,number = s[:3],s[3:-10],s[-10:] else: prefix,batch_no,number = s,'','' self.p = prefix self.b = batch_no self.n = number def __str__(self): return "%s-%s-%s" % (self.p,self.b,self.n) def __repr__(self): return "%s%s%s" % (self.p,self.b,self.n) ###) class ScratchcardPinWidget(CPSStringWidget): ###( """ ScratchcardPin Widget""" meta_type = "Scratchcard Pin Widget" _properties = CPSWidget._properties + ( {'id': 'prefix', 'type': 'string', 'mode': 'w', 'label': 'Prefix'}, {'id': 'reference', 'type': 'string', 'mode': 'w', 'label': 'Reference Field'}, ) prefix = '' reference = '' def prepare(self, datastructure, **kw): ###( """Prepare datastructure from datamodel.""" datamodel = datastructure.getDataModel() v = datamodel[self.fields[0]] widget_id = self.getWidgetId() #import pdb;pdb.set_trace() if v and type(v) is StringType: try: p,b,n = v.split('-') v = ScratchCardPin(p,b,n) except ValueError: v = ScratchCardPin(v,'','') if v: p = '%s' % v.p b = '%s' % v.b n = '%s' % v.n else: p = self.prefix if p.startswith('@'): p = getattr(self,self.prefix[1:])() b = n = '' v = ScratchCardPin(p,b,n) datastructure[widget_id] = v datastructure[widget_id+'_p'] = p datastructure[widget_id+'_b'] = b datastructure[widget_id+'_n'] = n ###) def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" s_logger = logging.getLogger('Pin.Validate') widget_id = self.getWidgetId() v = datastructure[widget_id] #import pdb;pdb.set_trace() err = 0 prefix= self.prefix if prefix.startswith('@'): prefix= getattr(self,self.prefix[1:])() b = datastructure[widget_id+'_b'].strip() n = datastructure[widget_id+'_n'].strip() pins = self.portal_pins pin = "%(prefix)s%(b)s%(n)s" % vars() do = 1 s_id = str(self.portal_membership.getAuthenticatedMember()) if self.reference == "": ref = s_id else: ref = datastructure[self.reference] if datastructure.errors: do = 0 datastructure.setError(widget_id, 'Errors in other data, PIN neither checked nor used.') s_logger.info('"%s", "%s","entered wrong data together with pin", "%s"' % (s_id,ref,pin)) while do: ok = pins.searchAndSetRecord(pin,ref,prefix) if ok < -2 or ok > 2: err = 'Unknown error, please report!' s_logger.info('"%s","%s", "caused unknown error with pin", "%s"' % (s_id,ref,pin)) break elif ok == -2: err = 'Service already activated but with a different PIN.' s_logger.info('"%s","%s", "repeatedly activated service but with different pin", "%s"' % (s_id,ref,pin)) break elif ok == -1: err = 'Invalid PIN' s_logger.info('"%s","%s", "entered invalid pin", "%s"' % (s_id,ref,pin)) break if ok == 0: err = 'PIN already used.' s_logger.info('"%s","%s", "entered used pin", "%s"' % (s_id,ref,pin)) break if ok >= 1: #import pdb;pdb.set_trace() if self.isStudent(): if self.reference == "jamb_reg_no": err = "You are already logged in." s_logger.info('"%s","%s", "checked admission though logged in", "%s"' % (s_id,ref,pin)) break if ok == 1: s_logger.info('"%s","%s", "successfully used pin", "%s"' % (s_id,ref,pin)) else: s_logger.info('"%s","%s", "repeatedly used pin", "%s"' % (s_id,ref,pin)) break else: student = getStudentByRegNo(self,ref) s_logger.info('"%s","%s","successfully used pin","%s"' % (s_id,ref,pin)) if student is None: err = "Student not found." s_logger.info('"%s","not found in admission list"' % (ref)) break s_id = student.getId() if ok == 2: if self.reference == "jamb_reg_no": if hasattr(self.portal_directories.students,s_id): err = "Please login with your Student Id %s and 10-digit PIN." % s_id s_logger.info('"%s","%s", "repeatedly checked admission with pin", "%s"' % (s_id,ref,pin)) break else: s_logger.info('"%s","%s","(non-member) repeatedly checked admission with pin", "%s"' % (s_id,ref,pin)) else: err = "Unknown error" % s_id s_logger.info('"%s","%s", "repeatedly activated service with pin", "%s"' % (s_id,ref,pin)) break try: student.getContent().makeStudentMember(s_id,password=pin[4:]) s_logger.info('"%s","%s", "has been created using pin", "%s"' % (s_id,ref,pin)) except: err = "Please login with your Student Id %s and 10-digit PIN." % s_id s_logger.info('"%s","%s", "could not be made a member with pin", "%s"' % (s_id,ref,pin)) break break if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = ScratchCardPin(prefix,b,n) datastructure[widget_id] = ScratchCardPin(prefix,b,n) datastructure[widget_id+'_p'] = prefix datastructure[widget_id+'_b'] = b datastructure[widget_id+'_n'] = n datastructure['s_id'] = s_id return not err def render(self, mode, datastructure, **kw): ###( """Render in mode from datastructure.""" render_method = 'widget_scratch_card_pin_render' meth = getattr(self, render_method, None) if meth is None: raise RuntimeError("Unknown Render Method %s for widget type %s" % (render_method, self.getId())) # XXX AT: datastructure has to be set again here, in case we're in edit # or create mode, because a default value has to be provided. #import pdb;pdb.set_trace() datamodel = datastructure.getDataModel() v = datamodel[self.fields[0]] if v and type(v) is StringType: try: p,b,n = v.split('-') v = ScratchCardPin(p,b,n) except ValueError: v = ScratchCardPin(self.prefix,'1',v) pass if v: prefix= '%s' % v.p b = '%s' % v.b n = '%s' % v.n else: prefix= self.prefix if prefix.startswith('@'): prefix= getattr(self,self.prefix[1:])() b = n = '' v = ScratchCardPin(prefix,b,n) widget_id = self.getWidgetId() datastructure[widget_id] = v datastructure[widget_id+'_p'] = prefix datastructure[widget_id+'_b'] = b datastructure[widget_id+'_n'] = n return meth(mode=mode, datastructure=datastructure, ) ###) InitializeClass(ScratchcardPinWidget) widgetRegistry.register(ScratchcardPinWidget) ###) class WAeUPImageWidget(CPSImageWidget): """Photo widget.""" meta_type = 'WAeUP Image Widget' def render(self, mode, datastructure, **kw): render_method = 'widget_waeup_image_render' meth = getattr(self, render_method, None) if meth is None: raise RuntimeError("Unknown Render Method %s for widget type %s" % (render_method, self.getId())) img_info = self.getImageInfo(datastructure) return meth(mode=mode, datastructure=datastructure, **img_info) InitializeClass(WAeUPImageWidget) widgetRegistry.register(WAeUPImageWidget) ###########