#-*- mode: python; mode: fold -*- # $Id: Widgets.py 2099 2007-08-15 19:39:58Z henrik $ from cgi import escape from types import * from Globals import InitializeClass from ZPublisher.HTTPRequest import FileUpload ##from Products.CPSSchemas.Widget import CPSWidgetType from Products.CMFCore.utils import getToolByName from Products.CPSSchemas.BasicWidgets import CPSBooleanWidget, CPSWidget, CPSStringWidget, CPSEmailWidget,CPSImageWidget from Products.CPSSchemas.BasicWidgets import CPSFileWidget from Products.CPSSchemas.BasicWidgets import renderHtmlTag,CPSSelectWidget, CPSStringWidget from Products.CPSSchemas.ExtendedWidgets import CPSDateTimeWidget from Products.CPSSchemas.Widget import widgetRegistry from Products.CPSUtil.file import PersistableFileUpload from Products.CPSUtil.id import generateFileName ##from Products.CPSSchemas.WidgetTypesTool import WidgetTypeRegistry from DateTime.DateTime import DateTime from AccessControl import getSecurityManager from Products.WAeUP_SRP.Students import getStudentByRegNo from Products.WAeUP_SRP.Academics import makeCertificateCode #from Products.ExtFile.ExtFile import ExtFile from re import compile import logging import operator #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 already exists' elif value not in c_ids: err = 'Course does not exist' 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 already exists' 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 WAeUPStudyModeWidget(CPSSelectWidget): ###( """WAeUP StudyMode Widget.""" meta_type = 'WAeUP StudyMode Widget' vocabulary = 'entry_modes' def _getStudyModes(self): voc = getattr(self.portal_vocabularies,self.vocabulary) d = {} for k,v in voc.items(): d[k] = v return d def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" widget_id = self.getWidgetId() value = datastructure[widget_id] try: v = str(value) except ValueError: datastructure.setError(widget_id, "'%s' not a valid session key" % value) return 0 studymodes = self._getStudyModes() if not value: v = value = 'ume_ft' #import pdb;pdb.set_trace() if not studymodes.has_key(value): datastructure.setError(widget_id, "'%s' not a valid session key" % v) return 0 if self.is_required and not len(v): datastructure.setError(widget_id, "session key required") return 0 datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = v return 1 def render(self, mode, datastructure, **kw): """Render in mode from datastructure.""" value = datastructure[self.getWidgetId()] studymodes = self._getStudyModes() if mode == 'view': return escape(studymodes.get(value, value)) elif mode == 'edit': html_widget_id = self.getHtmlWidgetId() res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id) in_selection = 0 vocabulary_items = studymodes.items() if self.sorted: vocabulary_items.sort(key=operator.itemgetter(1)) for k, v in vocabulary_items: 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(WAeUPStudyModeWidget) widgetRegistry.register(WAeUPStudyModeWidget) ###) class WAeUPSessionWidget(CPSSelectWidget): ###( """WAeUP Session Widget.""" meta_type = 'WAeUP Session Widget' def _getSessions(self): current_year = DateTime().year() d = {'-1': 'N/A'} for y in range(current_year - 9,current_year + 1): d['%s' % str(y)[-2:]] = '%4d/%4d' % (y,y+1) return d def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" widget_id = self.getWidgetId() value = datastructure[widget_id] try: v = str(value) except ValueError: datastructure.setError(widget_id, "'%s' not a valid session key" % value) return 0 if len(v) == 1: v = value = '0%c' % v elif not value: v = value = self.getSessionId()[-2:] #import pdb;pdb.set_trace() sessions = self._getSessions() if not sessions.has_key(value): datastructure.setError(widget_id, "'%s' not a valid session key" % v) return 0 if self.is_required and not len(v): datastructure.setError(widget_id, "session key required") return 0 datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = v return 1 def render(self, mode, datastructure, **kw): """Render in mode from datastructure.""" value = datastructure[self.getWidgetId()] sessions = self._getSessions() if mode == 'view': return escape(sessions.get(value, value)) elif mode == 'edit': html_widget_id = self.getHtmlWidgetId() res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id) in_selection = 0 vocabulary_items = sessions.items() if self.sorted: vocabulary_items.sort(key=operator.itemgetter(0)) for k, v in vocabulary_items: 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(WAeUPSessionWidget) widgetRegistry.register(WAeUPSessionWidget) ###) class WAeUPLevelWidget(CPSSelectWidget): ###( """WAeUP Level Widget.""" meta_type = 'WAeUP Level Widget' def _getLevels(self): d = {'000':'N/A'} for y in range(100,800,100): d['%s' % str(y)] = 'Year %1d (%3d Level)' % (y/100,y) return d def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" widget_id = self.getWidgetId() value = datastructure[widget_id] try: v = str(value) except ValueError: datastructure.setError(widget_id, "'%s' not a valid level key" % value) return 0 if not value: v = value = '100' #import pdb;pdb.set_trace() levels = self._getLevels() if not levels.has_key(value): datastructure.setError(widget_id, "'%s' not a valid level" % v) return 0 if self.is_required and not len(v): datastructure.setError(widget_id, "level key required") return 0 datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = v return 1 def render(self, mode, datastructure, **kw): """Render in mode from datastructure.""" value = datastructure[self.getWidgetId()] levels = self._getLevels() if mode == 'view': return escape(levels.get(value, value)) elif mode == 'edit': html_widget_id = self.getHtmlWidgetId() res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id) in_selection = 0 vocabulary_items = levels.items() if self.sorted: vocabulary_items.sort(key=operator.itemgetter(0)) for k, v in vocabulary_items: 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(WAeUPLevelWidget) widgetRegistry.register(WAeUPLevelWidget) ###) class WAeUPVerdictWidget(CPSSelectWidget): ###( """WAeUP Verdict Widget.""" meta_type = 'WAeUP Verdict Widget' # XXX make a menu for the vocabulary. vocabulary = 'verdicts' # Associating the widget label with an input area to improve the widget # accessibility. has_input_area = True def _getVerdicts(self,datastructure): voc = getattr(self.portal_vocabularies,self.vocabulary) d = {} for k,v in voc.items(): d[k] = v return d def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" widget_id = self.getWidgetId() value = datastructure[widget_id] try: v = str(value) except ValueError: datastructure.setError(widget_id, "'%s' not a valid verdict key" % value) return 0 #import pdb;pdb.set_trace() verdicts = self._getVerdicts(datastructure) if not value: v = value = verdicts['N/A'] if not verdicts.has_key(value): datastructure.setError(widget_id, "'%s' not a valid verdict key" % v) return 0 if self.is_required and not len(v): datastructure.setError(widget_id, "verdict required") return 0 datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = v return 1 def render(self, mode, datastructure, **kw): """Render in mode from datastructure.""" value = datastructure[self.getWidgetId()] verdicts = self._getVerdicts(datastructure) if mode == 'view': return escape(verdicts.get(value, value)) elif mode == 'edit': html_widget_id = self.getHtmlWidgetId() res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id) in_selection = 0 vocabulary_items = verdicts.items() if self.sorted: vocabulary_items.sort(key=operator.itemgetter(1)) for k, v in vocabulary_items: 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(WAeUPVerdictWidget) widgetRegistry.register(WAeUPVerdictWidget) ###) class WAeUPLGAWidget(CPSSelectWidget): ###( """WAeUP LGA Widget.""" meta_type = 'WAeUP LGA Widget' _properties = CPSSelectWidget._properties + ( {'id': 'state_field', 'type': 'string', 'mode': 'w', 'label': 'Name of the state field'}, {'id': 'lga_field', 'type': 'string', 'mode': 'w', 'label': 'Name of the LGA Field (without state)'}, ) state_field = "state" lga_field = "lga" # XXX make a menu for the vocabulary. vocabulary = 'local_gov_areas' # Associating the widget label with an input area to improve the widget # accessibility. has_input_area = True def _getLGAs(self): voc = getattr(self.portal_vocabularies,self.vocabulary) states = [] lgas = [] d = {} for k,v in voc.items(): parts = k.split('_') state = parts[0] lga = ' '.join(parts[1:]) if state not in states: states.append(state) lgas.append(lga) d[k] = v return (d,states,lgas) def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" widget_id = self.getWidgetId() value = datastructure[widget_id] #import pdb;pdb.set_trace() try: v = str(value) except ValueError: datastructure.setError(widget_id, "'%s' not a valid lga key" % value) return 0 v = v.lower() combined,states,lgas = self._getLGAs() one_field = False if not self.state_field and not self.lga_field: one_field = True if v not in combined.keys(): datastructure.setError(widget_id, "'%s' not a valid lga key" % v) return 0 else: if widget_id == self.state_field: if v not in states: datastructure.setError(widget_id, "'%s' not a valid state" % v) return 0 elif widget_id == self.lga_field: if v not in lgas: datastructure.setError(widget_id, "'%s' not a valid lga" % v) return 0 if datastructure[self.state_field]: v = datastructure[self.state_field] + '_' + v if self.is_required and not len(v): datastructure.setError(widget_id, "lga required") return 0 datamodel = datastructure.getDataModel() if one_field: datamodel[self.fields[0]] = v else: state = datastructure[self.state_field].lower() lga = "_".join(datastructure[self.lga_field].lower().split()) datamodel[self.fields[0]] = state + "_" + lga return 1 def render(self, mode, datastructure, **kw): """Render in mode from datastructure.""" w_id = self value = datastructure[self.getWidgetId()] lgas,x,y = self._getLGAs(datastructure) if mode == 'view': return escape(lgas.get(value, value)) elif mode == 'edit': html_widget_id = self.getHtmlWidgetId() res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id) in_selection = 0 vocabulary_items = lgas.items() # if self.sorted: # vocabulary_items.sort(key=operator.itemgetter(1)) for k, v in vocabulary_items: 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(WAeUPLGAWidget) widgetRegistry.register(WAeUPLGAWidget) ###) 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() is not necessary here because it's also done in waeup_document_create_do err = 0 mapping = {} if len(value.split()) > 1: err = 'Invalid Id, Id contains space(s).' elif self.portal_catalog(portal_type=portal_type_query,id=value): brain = self.portal_catalog(portal_type=portal_type_query,id=value)[0] err = 'An ${portal_type} object with the Id ${id} already exists at ${path}.' mapping = {'portal_type': brain.portal_type, 'id': value, 'path': brain.getPath(), } if err: datastructure.setError(widget_id, err, mapping) 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) ## if not valid: ## return 0 widget_id = self.getWidgetId() value = makeCertificateCode(datastructure[widget_id]).upper() id_pat_str = r"\S" inv_id_pat = compile(r"^%s$" % id_pat_str) 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 JambRegNoWidget(CPSStringWidget): ###( """ JambRegNo Widget""" meta_type = "JambRegNo Widget" _properties = CPSStringWidget._properties + ( {'id': 'catalog', 'type': 'string', 'mode': 'w', 'label': 'Catalog to search'}, {'id': 'reference', 'type': 'string', 'mode': 'w', 'label': 'Reference Field'}, ) catalog = "portal_pumeresults" #the catalog to search for jamb_reg_no reference = "" 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) jamb_nr_catalog = getattr(self,self.catalog) widget_id = self.getWidgetId() value = datastructure[widget_id].upper() err = 0 #import pdb;pdb.set_trace() if kw.has_key('mode'): mode = kw['mode'] else: mode = "edit" if not valid: err = 'Invalid number' elif self.reference == '': #s = getStudentByRegNo(self,value) pume = jamb_nr_catalog(jamb_reg_no = value) if len(pume) < 1: err = 'No student record with this registration number.' else: datastructure['pume'] = pume[0] elif mode == 'add': pass elif self.reference != '' and self.catalog == "applicants_catalog": res = jamb_nr_catalog.searchResults({"%s" % self.reference: value}) if len(res) != 1: err = 'No record with this registration number.' else: datastructure['record'] = res[0] else: record = datastructure[self.reference] #jamb_reg_no = getattr(record,widget_id) jamb_reg_no = record.Entryregno if jamb_reg_no != value: err = 'Registration number does not match.' 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 SecretWidget(CPSStringWidget): ###( """ Secret Widget""" meta_type = "Secret Widget" _properties = CPSStringWidget._properties + ( {'id': 'reference', 'type': 'string', 'mode': 'w', 'label': 'Reference Record'}, {'id': 'check_fields', 'type': 'tokens', 'mode': 'w', 'label': 'Fields to check'}, ) reference = "student" matric_no_catalog = 'returning_import' check_fields = ("Firstname", "Middlename","Lastname") def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" logger = logging.getLogger('Widgets.SecretWidget.validate') valid = CPSStringWidget.validate(self, datastructure, **kw) widget_id = self.getWidgetId() value = datastructure[widget_id].upper() err = 0 record = datastructure.get(self.reference,None) #import pdb;pdb.set_trace() if not valid or len(value) < 2: err = 'Invalid string' elif not record or datastructure.errors: err = 0 else: found = False cvs = [] for field in self.check_fields: cv = getattr(record,field).upper() if len(cv.split()) > 1: for splited in cv.split(): cvs.append(splited.strip()) else: cvs.append(cv) for cv in cvs: if cv == value.upper(): found = True break matric_no = record.matric_no name = " ".join(cvs) if not found: logger.info('%(matric_no)s did not find %(value)s in %(name)s' % vars()) err = 'No name does match.' else: logger.info('%(matric_no)s found %(value)s in %(name)s' % vars()) if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = value return not err InitializeClass(SecretWidget) widgetRegistry.register(SecretWidget) ###) class WAeUPSexWidget(CPSBooleanWidget): ###( """WAeUP sex widget.""" meta_type = 'WAeUP Sex Widget' def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" value = datastructure[self.getWidgetId()] if self.render_format not in self.render_formats: self.render_format = 'select' female = value in ('F','f','Female','female',"True",True) male = value in ('M','m','Male','male','False',False) if not female and not male: datastructure.setError(self.getWidgetId(), "invalid sex %s" % value) return 0 elif female: v = True else: v = False datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = v return 1 InitializeClass(WAeUPSexWidget) widgetRegistry.register(WAeUPSexWidget) ###) class MatricNoWidget(CPSStringWidget): ###( """ MatricNo Widget""" meta_type = "MatricNo Widget" _properties = CPSStringWidget._properties + ( {'id': 'matric_no_catalog', 'type': 'string', 'mode': 'w', 'label': 'Catalog to search for MatricNo'}, { 'id': 'results_catalog', 'type': 'string', 'mode': 'w', 'label': 'Results Catalog'}, ) matric_no_catalog = "" #the catalog to search for matric_no results_catalog = "results_import" #results catalog def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" #import pdb;pdb.set_trace() valid = CPSStringWidget.validate(self, datastructure, **kw) logger = logging.getLogger('Widgets.MatricNoWidget.validate') returning = getattr(self,self.matric_no_catalog) results = getattr(self,self.results_catalog,None) err = 0 widget_id = self.getWidgetId() value = datastructure[widget_id] if not valid or not value: err = 'Invalid string' logger.info('Invalid matric_no string %s' % value) else: value = value.upper() datastructure['student'] = None while not err: res = returning(matric_no = value) if len(res) < 1: logger.info('matric_no %s not found' % value) err = 'No student with this matriculation number.' break datastructure['student'] = res[0] if results is not None: res = results(matric_no = value) if len(res) < 1: err = 'No results for this matriculation number' 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 StudentIdWidget(CPSStringWidget): ###( """ StudentId Widget""" meta_type = "StudentId Widget" def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" valid = CPSStringWidget.validate(self, datastructure, **kw) logger = logging.getLogger('Widgets.StudentIdWidget.validate') #import pdb;pdb.set_trace() s_cat = self.students_catalog err = 0 widget_id = self.getWidgetId() value = datastructure[widget_id] if not valid or not value: err = 'Invalid Id string' logger.info('Invalid id string %s' % value) datastructure['student'] = None else: value = value.upper() res = s_cat(id = value) if not res: logger.info('Student id %s not found' % value) err = 'No student with this Id' datastructure['student'] = None else: datastructure['student'] = res[0] 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 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 grade for subject" 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('Widgets.ScratchcardPinWidget.validate') widget_id = self.getWidgetId() v = datastructure[widget_id] #import pdb;pdb.set_trace() err = 0 mapping = {} 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() pin_str = "%(prefix)s-%(b)s-%(n)s" % vars() do = 1 s_id = str(self.portal_membership.getAuthenticatedMember()) if self.isStaff(): do = 0 err ='You are not a Student. PIN neither checked nor used.' s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str)) elif len(b) > 1 and b.find('-') > -1: do = 0 err = 'PIN must not contain "-"' s_logger.info('%s entered invalid PIN containing "-"' % (s_id)) elif n.find('-') > -1: do = 0 err = 'PIN must not contain "-"' s_logger.info('%s entered invalid PIN containing "-"' % (s_id)) elif len(n) != 10: do = 0 err = 'Invalid PIN length' s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n))) elif self.reference == "": ref = s_id else: ref = datastructure[self.reference] if datastructure.errors: do = 0 datastructure.setError(widget_id, 'PIN neither checked nor used.') s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str)) 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_str)) break elif ok == -2: err = 'Service already is activated but with a different PIN.' s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str)) break elif ok == -1: err = 'Invalid PIN' s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str)) break if ok == 0: err = 'PIN already used' s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str)) 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 with PIN %s though logged in' % (s_id,ref,pin_str)) break if ok == 1: s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str)) else: s_logger.info('%s/%s repeatedly used PIN %s' % (s_id,ref,pin_str)) break else: student = getStudentByRegNo(self,ref) s_logger.info('%s/%s successfully used PIN %s' % (s_id,ref,pin_str)) 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 ${id} and 10-digit PIN." mapping = {'id': s_id} s_logger.info('%s/%s repeatedly checked admission with PIN %s' % (s_id,ref,pin_str)) break else: s_logger.info('%s/%s (non-member) repeatedly checked admission with PIN %s' % (s_id,ref,pin_str)) else: err = "Unknown error" s_logger.info('%s/%s repeatedly activated service with PIN %s' % (s_id,ref,pin_str)) 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_str)) except: err = "Please login with your Student Id ${id} and 10-digit PIN." mapping = {'id': s_id} s_logger.info('%s/%s could not be made a member with PIN %s' % (s_id,ref,pin_str)) break break if err: datastructure.setError(widget_id, err,mapping) 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,'XXX',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 PumePinWidget(ScratchcardPinWidget): ###( """ Pume Pin Widget""" meta_type = "Pume Pin Widget" catalog = "applicants_catalog" def validate(self, datastructure, **kw): ###( """Validate datastructure and update datamodel.""" s_logger = logging.getLogger('Widgets.ScratchcardPinWidget.validate') widget_id = self.getWidgetId() v = datastructure[widget_id] err = 0 mapping = {} 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() pin_str = "%(prefix)s-%(b)s-%(n)s" % vars() do = 1 s_id = str(self.portal_membership.getAuthenticatedMember()) if self.isStaff(): do = 0 err ='You are not a Student. PIN neither checked nor used.' s_logger.info('%s tried to use scratch card %s' % (s_id,pin_str)) elif len(b) > 1 and b.find('-') > -1: do = 0 err = 'PIN must not contain "-"' s_logger.info('%s entered invalid PIN containing "-"' % (s_id)) elif n.find('-') > -1: do = 0 err = 'PIN must not contain "-"' s_logger.info('%s entered invalid PIN containing "-"' % (s_id)) elif len(n) != 10: do = 0 err = 'Invalid PIN length' s_logger.info('%s entered invalid PIN with length %d' % (s_id,len(n))) elif self.reference == "": ref = s_id else: ref = datastructure[self.reference] if datastructure.errors: do = 0 datastructure.setError(widget_id, 'PIN neither checked nor used.') s_logger.info('%s/%s entered wrong data together with PIN %s' % (s_id,ref,pin_str)) 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_str)) break elif ok == -2: err = 'Service already is activated but with a different PIN.' s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (s_id,ref,pin_str)) break elif ok == -1: err = 'Invalid PIN' s_logger.info('%s/%s entered invalid PIN %s' % (s_id,ref,pin_str)) break if ok == 0: err = 'PIN already used' s_logger.info('%s/%s entered used PIN %s' % (s_id,ref,pin_str)) break if ok >= 1: if self.isStudent(): err = "This is only for Pume application." s_logger.info('%s/%s applied for PUME with PIN %s' % (s_id,ref,pin_str)) break else: applicant = datastructure['record'] if not applicant.pin: s_logger.info('%s successfully used PIN %s' % (ref,pin_str)) d = {} d['reg_no'] = applicant.reg_no d['pin'] = pin_str getattr(self,self.catalog).modifyRecord(**d) elif applicant.pin != pin_str: s_logger.info('%s/%s repeatedly applied for PUME with different PIN %s' % (s_id,ref,pin_str)) elif applicant.pin == pin_str: s_logger.info('%s/%s repeatedly applied for PUME with PIN %s' % (s_id,ref,pin_str)) break if err: datastructure.setError(widget_id, err,mapping) 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]] #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(self.prefix,'XXX',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(PumePinWidget) widgetRegistry.register(PumePinWidget) ###) 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) ###) class ExtFileWidget(CPSFileWidget): ###( """Photo widget.""" meta_type = 'Ext File Widget' def getFileInfo(self, datastructure): ###( """Get the file info from the datastructure.""" widget_id = self.getWidgetId() fileupload = datastructure[widget_id] dm = datastructure.getDataModel() field_id = self.fields[0] if fileupload: import pdb; pdb.set_trace() empty_file = False session_file = isinstance(fileupload, PersistableFileUpload) current_filename = generateFileName(fileupload.filename) fileupload.seek(0, 2) # end of file size = fileupload.tell() fileupload.seek(0) file = dm[field_id] # last stored file if file is not None: last_modified = str(file._p_mtime or '') else: last_modified = '' else: empty_file = True session_file = False current_filename = '' size = 0 last_modified = '' # Find the URL for the file XXX Refactor this! # get the adapter for adapter in dm._adapters: if adapter.getSchema().has_key(field_id): break # Note: 'adapter' is still the right one else: raise ValueError('No schema for field %r' % field_id) # get the content_url from the adapter content_url = None ob = dm.getProxy() if ob is None: # non proxy case ob = dm.getObject() if ob is None: # Not stored in the ZODB. # StorageAdapters that do not store the object in # ZODB takes the entry_id instead of object. # Get the entry_id from the datamodel context(typically # a directory). id_field = getattr(dm.getContext(), 'id_field', None) if id_field: try: entry_id = datastructure[id_field] except KeyError: entry_id = None else: # No object passed, and no id_field entry_id = None if entry_id: # some adapters does not have _getContentUrl if getattr(adapter, '_getContentUrl', None) is not None: content_url = adapter._getContentUrl(entry_id, field_id) else: if hasattr(adapter,"_getContentUrl"): content_url = adapter._getContentUrl(ob, field_id, current_filename) else: content_url = None # get the mimetype registry = getToolByName(self, 'mimetypes_registry') mimetype = (registry.lookupExtension(current_filename.lower()) or registry.lookupExtension('file.bin')) file_info = { 'empty_file': empty_file, 'session_file': session_file, 'current_filename': current_filename, 'size': size, 'last_modified': last_modified, 'content_url': content_url, 'mimetype': mimetype, } return file_info ###) def prepare(self, datastructure, **kw): ###( """Prepare datastructure from datamodel.""" datamodel = datastructure.getDataModel() widget_id = self.getWidgetId() file_name = datamodel[self.fields[0]] if not file_name: file = None else: io = ExtFile(file) if filename is None: filename = ofsfile.title headers = {'content-type': ofsfile.content_type} fs = SimpleFieldStorage(io, filename, headers) FileUpload(fs) datastructure[widget_id] = file datastructure[widget_id + '_choice'] = '' if file is not None: title = file.title else: title = '' datastructure[widget_id + '_filename'] = title ###) def validate(self, datastructure, **kw): """Update datamodel from user data in datastructure. """ datamodel = datastructure.getDataModel() field_id = self.fields[0] widget_id = self.getWidgetId() choice = datastructure[widget_id+'_choice'] store = False fileupload = None mimetype = None old_file = datamodel[field_id] if old_file is not None: old_filename = old_file.title else: old_filename = '' if choice == 'delete': if self.is_required: return self.validateError('cpsschemas_err_required', {}, datastructure) datamodel[field_id] = None elif choice == 'keep': fileupload = datastructure[widget_id] if isinstance(fileupload, PersistableFileUpload): # Keeping something from the session means we # actually want to store it. store = True else: # Nothing to change, don't pollute datastructure # with something costly already stored, which therefore # doesn't need to be kept in the session. self.unprepare(datastructure) elif choice == 'change': fileupload = datastructure[widget_id] if not fileupload: return self.validateError('cpsschemas_err_file_empty', {}, datastructure) if not isinstance(fileupload, FileUpload): return self.validateError('cpsschemas_err_file', {}, datastructure) fileupload.seek(0, 2) # end of file size = fileupload.tell() if not size: return self.validateError('cpsschemas_err_file_empty', {}, datastructure) if self.size_max and size > self.size_max: max_size_str = self.getHumanReadableSize(self.size_max) err = 'cpsschemas_err_file_too_big ${max_size}' err_mapping = {'max_size': max_size_str} return self.validateError(err, err_mapping, datastructure) store = True self.otherProcessing(choice, datastructure) # Find filename if fileupload is not None: filename = self.getFileName(fileupload, datastructure, choice, old_filename) if filename != old_filename: registry = getToolByName(self, 'mimetypes_registry') mimetype = registry.lookupExtension(filename.lower()) if mimetype is not None: mimetype = str(mimetype) # normalize err, err_mapping = self.checkFileName(filename, mimetype) if err: return self.validateError(err, err_mapping, datastructure) elif datamodel[field_id] is not None: # FIXME: not correct in the case of change=='resize' (CPSPhotoWidget) filename = datamodel[field_id].title # Set/update data import pdb;pdb.set_trace() if store: # Create file #file = ExtFile(filename, fileupload, datastructure) table_store = False if not hasattr(datamodel._adapters[0],'_getContentUrl'): table_store = True ref_id = datamodel.get('reg_no') id = "%s_%s" % (ref_id,field_id) self.tempExtFile = ExtFile(id, field_id) if table_store: datastructure[widget_id] = self.tempExtFile self.tempExtFile.manage_file_upload(fileupload,content_type=mimetype) else: self._setObject(id, self.tempExtFile) self._getOb(id).manage_file_upload(fileupload, content_type) # Fixup mimetype if mimetype and self.tempExtFile.content_type != mimetype: self.tempExtFile.content_type = mimetype # Store if not table_store: datamodel[field_id] = file elif datamodel[field_id] is not None: # Change filename if datamodel[field_id].title != filename: datamodel[field_id].title = filename return True InitializeClass(ExtFileWidget) widgetRegistry.register(ExtFileWidget) ###) ###########