#-*- mode: python; mode: fold -*- # $Id: Widgets.py 3086 2008-02-02 07:11:49Z henrik $ from cgi import escape from types import * import Globals from Globals import InitializeClass from ZPublisher.HTTPRequest import FileUpload from OFS.Image import cookId, File, Image ##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, CPSPasswordWidget 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.WAeUP_SRP.WAeUPTool import getImagesDir #from Products.ExtFile.ExtFile import ExtFile import logging,os,re import random import operator p_home = Globals.package_home(globals()) i_home = Globals.INSTANCE_HOME #from zLOG import LOG, DEBUG class WAeUPPasswordWidget(CPSPasswordWidget): ###( """WAeUP Password Widget""" meta_type = 'WAeUP Password Widget' _properties = CPSStringWidget._properties + ( {'id': 'password_widget', 'type': 'string', 'mode': 'w', 'label': 'Password widget to compare with'}, {'id': 'check_lower', 'type': 'boolean', 'mode': 'w', 'label': 'Checking at least one lower case [a-z]'}, {'id': 'check_upper', 'type': 'boolean', 'mode': 'w', 'label': 'Checking at least one upper case [A-Z]'}, {'id': 'check_digit', 'type': 'boolean', 'mode': 'w', 'label': 'Checking at least one digit [0-9]'}, {'id': 'check_extra', 'type': 'boolean', 'mode': 'w', 'label': 'Checking at least one extra char other than [a-zA-Z0-9]'}, {'id': 'check_words', 'type': 'string', 'mode': 'w', 'label': 'Checking for words'}, ) field_types = ('CPS Password Field',) password_widget = '' check_lower = 0 check_upper = 0 check_digit = 0 check_extra = 0 check_words = '' display_width = 8 size_min = 5 size_max = 8 def validate(self, datastructure, **kw): """Validate datastructure and update datamodel.""" widget_id = self.getWidgetId() value = datastructure[widget_id] err = 0 try: v = str(value).strip() except ValueError: err = 'cpsschemas_err_string' else: if self.password_widget: # here we only check that that our confirm match the pwd pwidget_id = self.password_widget pvalue = datastructure[pwidget_id] datastructure[widget_id] = '' datastructure[pwidget_id] = '' pv = str(pvalue).strip() if pv and v != pv: err = 'cpsschemas_err_password_mismatch' else: if not v: if self.is_required: datamodel = datastructure.getDataModel() if not datamodel[self.fields[0]]: err = 'cpsschemas_err_required' else: # checking pw consistancy len_v = len(v) if not err and self.size_max and len_v > self.size_max: err = 'cpsschemas_err_string_too_long' if not err and self.size_min and len_v < self.size_min: err = 'cpsschemas_err_password_size_min' if not err and self.check_lower and not search(r'[a-z]', v): err = 'cpsschemas_err_password_lower' if not err and self.check_upper and not search(r'[A-Z]', v): err = 'cpsschemas_err_password_upper' if not err and self.check_digit and not search(r'[0-9]', v): err = 'cpsschemas_err_password_digit' if not err and self.check_extra and not search(r'[^a-zA-Z0-9]', v): err = 'cpsschemas_err_password_extra' if not err and v in self.check_words: err = 'Your password is unsecure, please choose another password!' if err: datastructure[widget_id] = '' datastructure.setError(widget_id, err) elif v: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = v return not err InitializeClass(WAeUPPasswordWidget) widgetRegistry.register(WAeUPPasswordWidget) ###) 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.courses_catalog(code = 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 for import only""" meta_type = 'WAeUP Session Widget' def _getSessions(self): current_year = DateTime().year() d = {'': ''} for y in range(current_year - 10,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 len(v) == 9: v = value[2:4] elif not value: v = '' sessions = self._getSessions() if not sessions.has_key(v): 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 # rendering is not used, instead we use a select widget with dynamic vocabulary 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':'Pre-Studies'} 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[''] 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): if getattr(self,'_v_states',None) is not None and\ getattr(self,'_v_lgas',None) is not None and\ getattr(self,'_v_d',None) is not None and\ getattr(self,'_v_word_dict',None) is not None: return (self._v_d,self._v_states,self._v_lgas,self._v_word_dict) mapping = self.waeup_tool.getStatesLgas() self._v_d = mapping['lga_dict'] self._v_states = mapping['states'] self._v_lgas = mapping['lgas'] self._v_word_dict = mapping['word_dict'] return (self._v_d,self._v_states,self._v_lgas,self._v_word_dict) 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,word_dict = self._getLGAs() datamodel = datastructure.getDataModel() if self.state_field and self.lga_field: v = ' '.join((datastructure.get(self.state_field,""), datastructure.get(self.lga_field,""))) state_lga = self.waeup_tool.findLga(v,word_dict) if not state_lga: if self.is_required: datastructure.setError(widget_id, "'%s' not a valid lga key" % v) #datastructure.setError(widget_id, "%s required" % widget_id) return 0 else: state_lga = v 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.""" mode = kw.get('mode','create') valid = CPSStringWidget.validate(self, datastructure, **kw) id_pat_str = r"\S" inv_id_pat = re.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 mode == "create" and\ 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() value = datastructure[widget_id].upper() id_pat_str = r"\S" inv_id_pat = re.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) reg_no_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 registration number' elif self.reference == '': #s = getStudentByRegNo(self,value) pume = reg_no_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 = reg_no_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.strip().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] if not v: v = [] 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 #import pdb;pdb.set_trace() 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: if v: v += (s,g), else: v = [(s,g),] break if err: datastructure.setError(widget_id, err) else: datamodel = datastructure.getDataModel() datamodel[self.fields[0]] = v datastructure[widget_id] = 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())) 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'}, {'id': 'reuse_pin', 'type': 'boolean', 'mode': 'w', 'label': 'Reuse Application Pin'}, ) prefix = '' reference = '' reuse_pin = False def prepare(self, datastructure, **kw): ###( """Prepare datastructure from datamodel.""" datamodel = datastructure.getDataModel() v = datamodel[self.fields[0]] widget_id = self.getWidgetId() 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)) elif prefix == 'APP' and not self.reuse_pin: res = self.applicants_catalog(reg_no = ref) if not res: res = self.applicants_catalog(reg_no = ref.upper()) if res and res[0].pin == pin_str: do = 0 err = 'Application PINs cannot be reused.' s_logger.info('%s entered same PIN as for screening application %s' % (s_id,pin_str)) while do: ok,record = 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 record 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" reference = '' def prepare(self, datastructure, **kw): ###( """Prepare datastructure from datamodel.""" datamodel = datastructure.getDataModel() #import pdb;pdb.set_trace() v = datamodel[self.fields[0]] widget_id = self.getWidgetId() 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.PumePinWidget.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() member_id = str(self.portal_membership.getAuthenticatedMember()) do = 1 if self.isStaff(): do = 0 err ='You are logged in, please log out. PIN neither checked nor used.' s_logger.info('%s tried to use scratch card %s' % (member_id,pin_str)) elif self.isStudent(): do = 0 #ref = datastructure[self.reference] err ='You are logged in, please log out. PIN neither checked nor used.' s_logger.info('%s applied for screening test while logged in with pin %s' % (member_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 "-"' % (member_id)) elif n.find('-') > -1: do = 0 err = 'PIN must not contain "-"' s_logger.info('%s entered invalid PIN containing "-"' % (member_id)) elif len(n) != 10: do = 0 err = 'Invalid PIN length' s_logger.info('%s entered invalid PIN with length %d' % (member_id,len(n))) elif self.reference == "": ref = n 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' % (member_id,ref,pin_str)) while do: ok,pin_record = 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' % (member_id,ref,pin_str)) break elif ok == -2: err = 'Service is already activated but with a different PIN.' s_logger.info('%s/%s repeatedly activated service but with different PIN %s' % (member_id,ref,pin_str)) break elif ok == -1: err = 'Invalid PIN' s_logger.info('%s/%s entered invalid PIN %s' % (member_id,ref,pin_str)) break if ok == 0: err = 'PIN already used' s_logger.info('%s/%s entered used PIN %s' % (member_id,ref,pin_str)) break if ok >= 1: #screening_type = self.REQUEST.form.get('screening_type','unknown') #screening_type = datastructure['screening_type'] if self.REQUEST.traverse_subpath: screening_type_request = self.REQUEST.traverse_subpath[0] else: screening_type_request = 'manage' if datastructure.has_key('record'): applicant = datastructure['record'] if applicant.screening_type != screening_type_request\ and screening_type_request != 'manage': err = "You are using the wrong access form!" s_logger.info('%s tried to use %s application form but has applied for %s' % (ref,screening_type_request,applicant.screening_type)) break 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 #d['screening_type'] = screening_type #d['status'] = 'entered' getattr(self,self.catalog).modifyRecord(**d) elif applicant.pin != pin_str: s_logger.info('%s/%s tried to enter application record with different PIN %s' % (member_id,ref,pin_str)) elif applicant.pin == pin_str: s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_id,ref,pin_str)) else: datastructure['reg_no'] = ref res = self.applicants_catalog(reg_no = ref) if not res: s_logger.info('%s successfully used PIN %s' % (ref,pin_str)) d = {} d['reg_no'] = ref d['pin'] = pin_str d['status'] = 'entered' d['screening_type'] = screening_type_request d['serial'] = "%c%05d" % (pin_record.prefix_batch[-1], pin_record.serial) self.applicants_catalog.addRecord(**d) else: s_logger.info('%s/%s repeatedly entered application record with PIN %s' % (member_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 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 ApplicationImageWidget(CPSImageWidget): ###( """Image widget with filesystem storage.""" meta_type = 'Application Image Widget' _properties = CPSImageWidget._properties +\ ( {'id': 'path', 'type': 'string', 'mode': 'w', 'label': 'Relative Path'}, {'id': 'id_field', 'type': 'string', 'mode': 'w', 'label': 'Field to build the id'}, ) path = "images" storage_path = "%s/import/%s" % (i_home,path) id_field = "reg_no" def getImageInfo(self, datastructure): ###( """Get the file info from the datastructure.""" widget_id = self.getWidgetId() if datastructure.has_key(widget_id): fileupload = datastructure[widget_id] dm = datastructure.getDataModel() field_id = self.fields[0] screening_type = datastructure.get('screening_type') current_filename = "%s_%s.jpg" % (datastructure[self.id_field], field_id,) base_path = os.path.join(screening_type,current_filename) content_url = os.path.join('viewimage_applicant',self.path,base_path) file_path = os.path.join(self.storage_path,base_path) #import pdb; pdb.set_trace() else: file_path = "XXX" # read the file from the filesystem if not os.path.exists(file_path): height = -1 width = -1 empty_file = True session_file = False current_filename = '' content_url = '' size = 0 mimetype = '' last_modified = '' height = '' width = '' else: image = open(file_path) from OFS.Image import getImageInfo as getImageInfoOFS image.seek(0) data = image.read(2000) size = len(data) empty_file = size == 0 session_file = False last_modified = '' image.close() mimetype, width, height = getImageInfoOFS(data) if width < 0: width = None if height < 0: height = None if (self.allow_resize and height is not None and width is not None): z_w = z_h = 1 h = int(self.display_height) w = int(self.display_width) if w and h: if w < width: z_w = w / float(width) if h < height: z_h = h / float(height) zoom = min(z_w, z_h) width = int(zoom * width) height = int(zoom * height) #import pdb;pdb.set_trace() image_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, } title = image_info['current_filename'] alt = title or '' #height = int(self.display_height) #width = int(self.display_width) if height is None or width is None: tag = renderHtmlTag('img', src=image_info['content_url'], alt=alt, title=title) else: tag = renderHtmlTag('img', src=image_info['content_url'], width=str(width), height=str(height), alt=alt, title=title) image_info['height'] = height image_info['width'] = width image_info['image_tag'] = tag return image_info ###) def checkFileName(self, filename, mimetype): return '', {} if mimetype and mimetype.startswith('image'): return '', {} return 'cpsschemas_err_image', {} def prepare(self, datastructure, **kw): ###( """Prepare datastructure from datamodel.""" datamodel = datastructure.getDataModel() widget_id = self.getWidgetId() file_name = datamodel[self.fields[0]] #import pdb; pdb.set_trace() if self.allow_resize: datastructure[self.getWidgetId() + '_resize'] = '' screening_type = datamodel.get('screening_type',None) if not screening_type: screening_type = self.REQUEST.form.get('screening_type','pume') datastructure["screening_type"] = screening_type datastructure[widget_id] = file_name datastructure[widget_id + '_choice'] = 'change' title = 'Passport Foto' datastructure[widget_id + '_filename'] = title ###) def validate(self, datastructure, **kw): ###( """Update datamodel from user data in datastructure. """ logger = logging.getLogger('Widgets.ApplicationImageWidget.validate') datamodel = datastructure.getDataModel() field_id = self.fields[0] widget_id = self.getWidgetId() 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 = '' choice = datastructure[widget_id+'_choice'] fileupload = datastructure[widget_id] is_upload = isinstance(fileupload, FileUpload) #import pdb; pdb.set_trace() if not is_upload and not datamodel[field_id]: if self.is_required: return self.validateError('Picture upload required', {}, datastructure) 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' and is_upload: 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 = 'This file is too big, the allowed max size is ${max_size}' logger.info('%s tried to upload picture with size %dk' %(datastructure['reg_no'],int(size)/1000) ) err_mapping = {'max_size': max_size_str} return self.validateError(err, err_mapping, datastructure) store = True # Find filename if is_upload and store: ext ='jpg' screening_type = datastructure.get('screening_type') filename = "%s_%s.%s" % (datastructure[self.id_field], self.getWidgetId(), ext) datamodel[field_id] = filename registry = getToolByName(self, 'mimetypes_registry') mimetype = registry.lookupExtension(filename.lower()) if mimetype is not None: mimetype = str(mimetype) # normalize file = self.makeFile(filename, fileupload, datastructure) # Fixup mimetype if mimetype and file.content_type != mimetype: file.content_type = mimetype # Store the file in the filesystem #import pdb;pdb.set_trace() base_path = os.path.join(self.storage_path, screening_type) if not os.path.exists(base_path): os.mkdir(base_path) full_path = os.path.join(base_path, filename) pict = open(full_path,"w") fileupload.seek(0) pict.write(fileupload.read()) pict.close() return True ###) def render(self, mode, datastructure, **kw): ###( render_method = 'widget_passport_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(ApplicationImageWidget) widgetRegistry.register(ApplicationImageWidget) ###) class FileImageWidget(CPSImageWidget): ###( """Image widget with filesystem storage.""" meta_type = 'File Image Widget' _properties = CPSImageWidget._properties +\ ( {'id': 'path', 'type': 'string', 'mode': 'w', 'label': 'Relative Path'}, {'id': 'id_field', 'type': 'string', 'mode': 'w', 'label': 'Field to build the id'}, {'id': 'show_image', 'type': 'boolean', 'mode': 'w', 'label': 'Show Image'}, ) path = "images" #storage_path = "%s/%s" % (i_home,path) id_field = "" show_image = False def getStorageImageInfo(self,field_id): info = {} if self.id_field == "": student_id = self.getStudentId() else: student_id = datastructure[self.id_field] # student_path = os.path.join(self.storage_path, # student_id) student_path = getImagesDir(student_id) image_name = '' content_url = '' current_filename = '' if os.path.exists(student_path): for name in os.listdir(student_path): if name.startswith(field_id): image_name = name break if image_name: info['image_name'] = image_name info['content_url'] = os.path.join(self.portal_url(), "viewimage", student_id, image_name, ) info['current_filename'] = image_name info['file_path'] = os.path.join(student_path, image_name) return info def getImageInfo(self, datastructure): ###( """Get the file info from the datastructure.""" widget_id = self.getWidgetId() if datastructure.has_key(widget_id): fileupload = datastructure[widget_id] dm = datastructure.getDataModel() field_id = self.fields[0] info = self.getStorageImageInfo(field_id) else: file_path = "XXX" title = "" # read the file from the filesystem #import pdb; pdb.set_trace() #if not os.path.exists(file_path): if not info: title = "" height = -1 width = -1 empty_file = True session_file = False current_filename = '' content_url = '' size = 0 mimetype = '' last_modified = '' height = '' width = '' else: title = info['image_name'] current_filename = info['current_filename'] content_url = info['content_url'] image = open(info['file_path']) from OFS.Image import getImageInfo as getImageInfoOFS image.seek(0) data = image.read(2000) size = len(data) empty_file = size == 0 session_file = False last_modified = '' image.close() mimetype, width, height = getImageInfoOFS(data) registry = getToolByName(self, 'mimetypes_registry') mimetype = (registry.lookupExtension(current_filename.lower()) or registry.lookupExtension('file.bin')) if width < 0: width = None if height < 0: height = None if (self.allow_resize and height is not None and width is not None): z_w = z_h = 1 h = int(self.display_height) w = int(self.display_width) if w and h: if w < width: z_w = w / float(width) if h < height: z_h = h / float(height) zoom = min(z_w, z_h) width = int(zoom * width) height = int(zoom * height) #import pdb;pdb.set_trace() image_info = { 'empty_file': empty_file, 'session_file': session_file, 'current_filename': title, 'size': size, 'last_modified': last_modified, 'content_url': content_url, 'mimetype': mimetype, } alt = title or '' #height = int(self.display_height) #width = int(self.display_width) if height is None or width is None: tag = renderHtmlTag('img', src=image_info['content_url'], alt=alt, title=title) else: tag = renderHtmlTag('img', src=image_info['content_url'], width=str(width), height=str(height), alt=alt, title=title) image_info['height'] = height image_info['width'] = width image_info['image_tag'] = tag image_info['show_image'] = self.show_image return image_info ###) # def checkFileName(self, filename, mimetype): # return '', {} # if mimetype and mimetype.startswith('image'): # return '', {} # return 'cpsschemas_err_image', {} def prepare(self, datastructure, **kw): ###( """Prepare datastructure from datamodel.""" datamodel = datastructure.getDataModel() widget_id = self.getWidgetId() file_name = datamodel[self.fields[0]] if self.id_field == "": student_id = self.getStudentId() else: student_id = datastructure[self.id_field] if student_id is not None: # student_path = os.path.join(self.storage_path, # student_id) student_path = getImagesDir(student_id) if not os.path.exists(student_path): self.waeup_tool.moveImagesToFS(student_id) if self.allow_resize: datastructure[self.getWidgetId() + '_resize'] = '' datastructure[widget_id] = file_name datastructure[widget_id + '_choice'] = 'change' title = 'Passport Foto' datastructure[widget_id + '_filename'] = title ###) def validate(self, datastructure, **kw): ###( """Update datamodel from user data in datastructure. """ logger = logging.getLogger('Widgets.FileImageWidget.validate') datamodel = datastructure.getDataModel() field_id = self.fields[0] widget_id = self.getWidgetId() store = False fileupload = None mimetype = None old_file = datamodel[field_id] choice = datastructure[widget_id+'_choice'] fileupload = datastructure[widget_id] is_upload = isinstance(fileupload, FileUpload) #import pdb; pdb.set_trace() if not is_upload and not datamodel[field_id]: if self.is_required: return self.validateError('Picture upload required', {}, datastructure) if self.id_field == "": student_id = self.getStudentId() else: student_id = datastructure[self.id_field] if choice == 'delete': if self.is_required: return self.validateError('cpsschemas_err_required', {}, datastructure) info= self.getStorageImageInfo(field_id) # Remove the file in the filesystem if info: os.remove(info['file_path']) 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' and is_upload: 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 = 'This file is too big, the allowed max size is ${max_size}' member_id = str(self.portal_membership.getAuthenticatedMember()) logger.info('%s tried to upload picture with size %dk' %(member_id,int(size)/1000) ) err_mapping = {'max_size': max_size_str} return self.validateError(err, err_mapping, datastructure) store = True # Find filename if is_upload and store: filename = cookId('', '', fileupload)[0].strip() base,ext = os.path.splitext(filename) filename = "%s_%s%s" % (field_id, student_id, ext) datamodel[field_id] = filename registry = getToolByName(self, 'mimetypes_registry') mimetype = registry.lookupExtension(filename.lower()) if mimetype is not None: mimetype = str(mimetype) # normalize file = self.makeFile(filename, fileupload, datastructure) # Fixup mimetype if mimetype and file.content_type != mimetype: file.content_type = mimetype # Store the file in the filesystem #student_path = os.path.join(self.storage_path,student_id) student_path = getImagesDir(student_id) if not os.path.exists(student_path): os.mkdir(student_path) full_path = os.path.join(student_path, filename) pict = open(full_path,"w") #fileupload.seek(0) #import pdb; pdb.set_trace() pict.write(str(file.data)) pict.close() return True ###) def render(self, mode, datastructure, **kw): ###( render_method = 'widget_image_render' meth = getattr(self, render_method, None) #import pdb;pdb.set_trace() 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(FileImageWidget) widgetRegistry.register(FileImageWidget) ###) ###########