Example #1
0
class IWidgetEvent(zope.interface.Interface):
    """A simple widget event."""

    widget = zope.schema.Object(
        title=_('Widget'),
        description=_('The widget for which the event was created.'),
        schema=IWidget)
Example #2
0
class EditSubForm(form.BaseForm):

    formErrorsMessage = _('There were some errors.')
    successMessage = _('Data successfully updated.')
    noChangesMessage = _('No changes were applied.')

    def __init__(self, context, request, parentForm):
        self.context = context
        self.request = request
        self.parentForm = self.__parent__ = parentForm

    @button.handler(form.EditForm.buttons['apply'])
    def handleApply(self, action):
        data, errors = self.widgets.extract()
        if errors:
            self.status = self.formErrorsMessage
            return
        content = self.getContent()
        changed = form.applyChanges(self, content, data)
        if changed:
            zope.event.notify(zope.lifecycleevent.ObjectModifiedEvent(content))
            self.status = self.successMessage
        else:
            self.status = self.noChangesMessage

    def update(self):
        super(EditSubForm, self).update()
        for action in self.parentForm.actions.executedActions:
            adapter = zope.component.queryMultiAdapter(
                (self, self.request, self.getContent(), action),
                interface=interfaces.IActionHandler)
            if adapter:
                adapter()
Example #3
0
class EditForm(Form):
    """A simple edit form with an apply button."""
    zope.interface.implements(interfaces.IEditForm)

    formErrorsMessage = _('There were some errors.')
    successMessage = _('Data successfully updated.')
    noChangesMessage = _('No changes were applied.')

    def applyChanges(self, data):
        content = self.getContent()
        changes = applyChanges(self, content, data)
        # ``changes`` is a dictionary; if empty, there were no changes
        if changes:
            # Construct change-descriptions for the object-modified event
            descriptions = []
            for interface, names in changes.items():
                descriptions.append(
                    zope.lifecycleevent.Attributes(interface, *names))
            # Send out a detailed object-modified event
            zope.event.notify(
                zope.lifecycleevent.ObjectModifiedEvent(
                    content, *descriptions))
        return changes

    @button.buttonAndHandler(_('Apply'), name='apply')
    def handleApply(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return
        changes = self.applyChanges(data)
        if changes:
            self.status = self.successMessage
        else:
            self.status = self.noChangesMessage
Example #4
0
class BoolTerms(Terms):
    """Default yes and no terms are used by default for IBool fields."""

    zope.component.adapts(
        zope.interface.Interface,
        interfaces.IFormLayer,
        zope.interface.Interface,
        zope.schema.interfaces.IBool,
        interfaces.IWidget)

    zope.interface.implementsOnly(interfaces.IBoolTerms)

    trueLabel = _('yes')
    falseLabel = _('no')

    def __init__(self, context, request, form, field, widget):
        self.context = context
        self.request = request
        self.form = form
        self.field = field
        self.widget = widget
        terms = [vocabulary.SimpleTerm(*args)
                 for args in [(True, 'true', self.trueLabel),
                              (False, 'false', self.falseLabel)]]
        self.terms = vocabulary.SimpleVocabulary(terms)
Example #5
0
class AddForm(Form):
    """A field and button based add form."""
    zope.interface.implements(interfaces.IAddForm)

    ignoreContext = True
    ignoreReadonly = True

    _finishedAdd = False
    formErrorsMessage = _('There were some errors.')

    @button.buttonAndHandler(_('Add'), name='add')
    def handleAdd(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return
        obj = self.create(data)
        zope.event.notify(zope.lifecycleevent.ObjectCreatedEvent(obj))
        self.add(obj)
        self._finishedAdd = True

    def create(self, data):
        raise NotImplementedError

    def add(self, object):
        raise NotImplementedError

    def nextURL(self):
        raise NotImplementedError

    def render(self):
        if self._finishedAdd:
            self.request.response.redirect(self.nextURL())
            return ""
        return super(AddForm, self).render()
Example #6
0
    def get_learner(self, classlist, code, name, gender_code, language_code):
        """ Look if the learner exists in the system.
            If we can't find them there, we create a new one and set its
            properties to those specified in the import data.

            Note: At this stage the code will not overwrite existing learners.
                  It just skips them.
            IMPORTANT - This assumes that a learner can only be in one classlist
                        at a time.
        """

        learner = None
        # Now try to find the learner in the system
        # better make sure we search with 'None' or we get false positives
        if code == '': code = None
        query = {'portal_type': 'upfront.classlist.content.learner',
                 'id': code}
        pc = getToolByName(self, 'portal_catalog')
        brains = pc(**query)

        # For the moment we assume there can be only one... 
        learner = len(brains) > 0 and brains[0].getObject() or None
        # We found her, no need to recreate.
        if learner is not None:
            message = _("Skipping existing learner") + ': %s' % name
            return message, learner
        
        # We could not find the learner, so we will create one, but first
        # get our data ducks in a row.

        if gender_code not in self.genders():
            msgid = _(u"learners_gender_not_recognized",
                default=u"Learner: ${name} gender: ${gender} not recognized",
                mapping={ u"name" : name, u"gender" : gender_code})
            msg = self.context.translate(msgid)
            return msg, None
    
        if language_code not in self.languages()[0]:
            msgid = _(u"learners_language_not_recognized",
                default=u"Learner: ${name} language: ${language} not recognized",
                mapping={ u"name" : name, u"language" : language_code})
            msg = self.context.translate(msgid)
            return msg, None

        # create learner
        classlist.invokeFactory('upfront.classlist.content.learner',
                                code,
                                title=name)
        new_learner = classlist._getOb(code)
        new_learner.code = code
        new_learner.name = name
        new_learner.gender = gender_code       
        # get position of language in language vocab, using index get its 
        # corresponding intid from initid list
        index = self.languages()[0].index(language_code)
        lang_intid = self.languages()[1][index]        
        new_learner.home_language = RelationValue(lang_intid)
        notify(ObjectModifiedEvent(new_learner))

        return None, new_learner
Example #7
0
    def get_validated_learner_data(self, request):
        """ Opens supplied xls spreadsheet file and does integrity checks
            to make sure that it contains valid data.
        """

        # Get the spreadsheet from the form.
        xl_file = request.get('csv_file', None)
        contents = xl_file.read()
        xl_file.close()
        if contents is None or len(contents) < 1:
            return _("Please supply a valid file"), None 
        
        # Get the spreadsheet
        book = xlrd.open_workbook(file_contents=contents)

        # If we don't have a worksheet, we cannot continue.
        if book.sheets() < 1:
            return _("Please supply at least one work sheet"), None

        sheet = book.sheet_by_index(0)
        # We must have at least one learner.
        if sheet.nrows < 1:
            return _("Please supply at least one learner"), None
        # We must have at least number and name for the new learner.
        if sheet.ncols < 4:
            return _("Please supply a number, name, gender and language"), None
        return None, sheet
Example #8
0
class IImageButton(IButton):
    """An image button in a form."""

    image = zope.schema.TextLine(
        title=_('Image Path'),
        description=_('A relative image path to the root of the resources.'),
        required=True)
Example #9
0
class IActionErrorEvent(IActionEvent):
    """An action event that is created when an error occurred."""

    error = zope.schema.Field(
        title=_('Error'),
        description=_('The error that occurred during the action.'),
        required=True)
Example #10
0
class Form(form.Form):

    fields = field.Fields(IPlaceMatch)

    ignoreContext = True  # don't use context to get widget data
    ignoreRequest = False

    label = u'Search across modern and ancient names for possible matches'
    _results = None
    _data = None

    @button.buttonAndHandler(_('Search'), name='search')
    def handleSearch(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return
        self._data = data
        catalog = getToolByName(self.context, 'portal_catalog')
        ms = MatchSet('0', data.get('mn'), data.get('co'), data.get('an'),
                      catalog, self.request)
        self._results = dict(modern=ms.modern_places(),
                             ancient=ms.ancient_places())

    @button.buttonAndHandler(_('Clear'), name='clear')
    def handleClear(self, action):
        self.request.response.redirect(self.request.getURL())
Example #11
0
class IButtonForm(IForm):
    """A form that is based upon defined buttons."""

    buttons = zope.schema.Object(
        title=_('Buttons'),
        description=_('A button manager describing the buttons to be used for '
                      'the form.'),
        schema=IButtons)
Example #12
0
class IActionEvent(zope.interface.Interface):
    """An event specific for an action."""

    action = zope.schema.Object(
        title=_('Action'),
        description=_('The action for which the event is created.'),
        schema=IAction,
        required=True)
Example #13
0
class IObjectWidgetTemplateDirective(IWidgetTemplateDirective):
    schema = zope.configuration.fields.GlobalObject(
        title=_('Schema'),
        description=_(
            'The schema of the field for which the template should be available'
        ),
        default=zope.interface.Interface,
        required=False)
Example #14
0
class IFieldsForm(IForm):
    """A form that is based upon defined fields."""

    fields = zope.schema.Object(
        title=_('Fields'),
        description=_('A field manager describing the fields to be used for '
                      'the form.'),
        schema=IFields)
Example #15
0
class IHandlerForm(zope.interface.Interface):
    """A form that stores the handlers locally."""

    handlers = zope.schema.Object(
        title=_('Handlers'),
        description=_('A list of action handlers defined on the form.'),
        schema=IButtonHandlers,
        required=True)
Example #16
0
class IFieldWidget(zope.interface.Interface):
    """Offers a field attribute.

    For advanced uses the widget will make decisions based on the field
    it is rendered for.
    """

    field = zope.schema.Field(
        title=_('Field'),
        description=_('The schema field which the widget is representing.'),
        required=True)
Example #17
0
class IBoolTerms(ITerms):
    """A specialization that handles boolean choices."""

    trueLabel = zope.schema.TextLine(
        title=_('True-value Label'),
        description=_('The label for a true value of the Bool field.'),
        required=True)

    falseLabel = zope.schema.TextLine(
        title=_('False-value Label'),
        description=_('The label for a false value of the Bool field.'),
        required=False)
class IMasterSelectField(IObject):
    """
    Additional Fields for MasterSelect
    """
    slave_fields = Tuple(
        title=_(u"title_slave_fields",
                default=u"Fields controlled by this field,"),
        description=_(
            u"description_slave_fields",
            default=u"Fields controlled by this field, if control_type "
            "# is vocabulary only the first entry is used"),
        default=(),
        required=False)
Example #19
0
class ISequenceWidget(IWidget):
    """Sequence widget."""

    noValueToken = zope.schema.ASCIILine(
        title=_('NOVALUE Token'),
        description=_('The token to be used, if no value has been selected.'))

    terms = zope.schema.Object(
        title=_('Terms'),
        description=_('A component that provides the options for selection.'),
        schema=ITerms)

    def updateTerms():
        """Update the widget's ``terms`` attribute and return the terms.
Example #20
0
class IErrorstatusTemplateDirective(zope.interface.Interface):
    """Parameters for the Formframe template directive."""

    template = zope.configuration.fields.Path(
        title=_('Errorstatus template.'),
        description=_('Refers to a file containing a page template (should '
                      'end in extension ``.pt`` or ``.html``).'),
        required=True)

    for_ = zope.configuration.fields.GlobalObject(
        title=_('View'),
        description=_('The view for which the template should be available'),
        default=zope.interface.Interface,
        required = False)

    layer = zope.configuration.fields.GlobalObject(
        title=_('Layer'),
        description=_('The layer for which the template should be available'),
        default=IDefaultBrowserLayer,
        required=False)

    contentType = zope.schema.BytesLine(
        title=_('Content Type'),
        description=_('The content type identifies the type of data.'),
        default='text/html',
        required=False)
Example #21
0
class IAction(zope.interface.Interface):
    """Action"""

    __name__ = zope.schema.TextLine(title=_('Name'),
                                    description=_('The object name.'),
                                    required=False,
                                    default=None)

    title = zope.schema.TextLine(title=_('Title'),
                                 description=_('The action title.'),
                                 required=True)

    def isExecuted():
        """Determine whether the action has been executed."""
Example #22
0
class EditSubForm(form.BaseForm):
    zope.interface.implements(
        interfaces.ISubForm, interfaces.IHandlerForm)

    formErrorsMessage = _('There were some errors.')
    successMessage = _('Data successfully updated.')
    noChangesMessage = _('No changes were applied.')

    def __init__(self, context, request, parentForm):
        self.context = context
        self.request = request
        self.parentForm = self.__parent__ = parentForm

    @button.handler(form.EditForm.buttons['apply'])
    def handleApply(self, action):
        data, errors = self.widgets.extract()
        if errors:
            self.status = self.formErrorsMessage
            return
        content = self.getContent()
        changed = form.applyChanges(self, content, data)
        if changed:
            zope.event.notify(
                zope.lifecycleevent.ObjectModifiedEvent(content))
            self.status = self.successMessage
        else:
            self.status = self.noChangesMessage


    def update(self):
        super(EditSubForm, self).update()
        #FIXME: the code below may not be executed at all!
        # The problem is that we update the subform while updating
        # the parentForm. That means at this moment the actions manager
        # has not been looked up and the parentForm.actions does not exist.
        # The right order may be !
        # -update form widgets
        # -update subform widgets
        # -update form actions
        # -update subform actions?
        
    def updateActions(self):
        if hasattr(self.parentForm, 'actions'):
            for action in self.parentForm.actions.executedActions:
                adapter = zope.component.queryMultiAdapter(
                    (self, self.request, self.getContent(), action),
                    interface=interfaces.IActionHandler)
                if adapter:
                    adapter()
Example #23
0
class IButton(zope.schema.interfaces.IField):
    """A button in a form."""

    accessKey = zope.schema.TextLine(
        title=_('Access Key'),
        description=_('The key when pressed causes the button to be pressed.'),
        min_length=1,
        max_length=1,
        required=False)

    actionFactory = zope.schema.Field(title=_('Action Factory'),
                                      description=_('The action factory.'),
                                      required=False,
                                      default=None,
                                      missing_value=None)
Example #24
0
class IErrorViewSnippet(zope.interface.Interface):
    """A view providing a view for an error"""

    widget = zope.schema.Field(title=_("Widget"),
                               description=_("The widget that the view is on"),
                               required=True)

    error = zope.schema.Field(title=_('Error'),
                              description=_('Error the view is for.'),
                              required=True)

    def update():
        """Update view."""

    def render():
        """Render view."""
Example #25
0
    def get_classlist(self, classlist_id):
        """ returns an existing classlist, if a classlist does not exist
            it is created in the correct context (the classlists folder)
        """

        pc = getToolByName(self, 'portal_catalog')
        query = {'portal_type': 'upfront.classlist.content.classlist',
                 'Title': classlist_id
                }
        brains = pc(**query)
        if brains is not None and len(brains) > 0:
            return None, brains[0].getObject()
        else:
            # get the context of classlists folder.
            context = self.context
            while context.portal_type != 'Folder':
                context = context.aq_parent

            # this should hopefully never be called
            if context.id != 'classlists':
                return _("import-learners called from incorrect context"), None

            # create new classlist in classlists folder.
            context.invokeFactory('upfront.classlist.content.classlist',
                                  classlist_id,
                                  title=classlist_id)
            classlist = context._getOb(classlist_id)

            return None, classlist
Example #26
0
    def toFieldValue(self, value):
        """See interfaces.IDataConverter"""
        if value is None or value == '':
            # When no new file is uploaded, send a signal that we do not want
            # to do anything special.
            return interfaces.NOT_CHANGED

        if isinstance(value, zope.publisher.browser.FileUpload):
            # By default a IBytes field is used for get a file upload widget.
            # But interfaces extending IBytes do not use file upload widgets.
            # Any way if we get a FileUpload object, we'll convert it.
            # We also store the additional FileUpload values on the widget
            # before we loose them.
            self.widget.headers = value.headers
            self.widget.filename = value.filename
            try:
                seek = value.seek
                read = value.read
            except AttributeError as e:
                raise ValueError(_('Bytes data are not a file object'), e)
            else:
                seek(0)
                data = read()
                if data or getattr(value, 'filename', ''):
                    return data
                else:
                    return self.field.missing_value
        else:
            return util.toBytes(value)
Example #27
0
    def toFieldValue(self, value):
        """See interfaces.IDataConverter"""
        if value is None or value == '':
            # When no new file is uploaded, send a signal that we do not want
            # to do anything special.
            return interfaces.NOT_CHANGED

        if isinstance(value, zope.publisher.browser.FileUpload):
            # By default a IBytes field is used for get a file upload widget.
            # But interfaces extending IBytes do not use file upload widgets.
            # Any way if we get a FileUpload object, we'll convert it.
            # We also store the additional FileUpload values on the widget
            # before we loose them.
            self.widget.headers = value.headers
            self.widget.filename = value.filename
            try:
                seek = value.seek
                read = value.read
            except AttributeError as e:
                raise ValueError(_('Bytes data are not a file object'), e)
            else:
                seek(0)
                data = read()
                if data or getattr(value, 'filename', ''):
                    return data
                else:
                    return self.field.missing_value
        else:
            return util.toBytes(value)
Example #28
0
 def _makeMissingTerm(self, value):
     """Return a term that should be displayed for the missing token"""
     uvalue = util.toUnicode(value)
     return vocabulary.SimpleTerm(value,
                                  self._makeToken(value),
                                  title=_(u'Missing: ${value}',
                                          mapping=dict(value=uvalue)))
Example #29
0
class SelectWidget(widget.HTMLSelectWidget, SequenceWidget):
    """Select widget implementation."""
    zope.interface.implementsOnly(interfaces.ISelectWidget)

    klass = u'select-widget'
    items = ()
    prompt = False

    noValueMessage = _('no value')
    promptMessage = _('select a value ...')

    # Internal attributes
    _adapterValueAttributes = SequenceWidget._adapterValueAttributes + \
        ('noValueMessage', 'promptMessage')

    def isSelected(self, term):
        return term.token in self.value

    def update(self):
        """See z3c.form.interfaces.IWidget."""
        super(SelectWidget, self).update()
        widget.addFieldClass(self)
        self.items = []
        if (not self.required or self.prompt) and self.multiple is None:
            message = self.noValueMessage
            if self.prompt:
                message = self.promptMessage
            self.items.append({
                'id': self.id + '-novalue',
                'value': self.noValueToken,
                'content': message,
                'selected': self.value == []
            })
        for count, term in enumerate(self.terms):
            selected = self.isSelected(term)
            id = '%s-%i' % (self.id, count)
            content = term.token
            if zope.schema.interfaces.ITitledTokenizedTerm.providedBy(term):
                content = translate(term.title,
                                    context=self.request,
                                    default=term.title)
            self.items.append({
                'id': id,
                'value': term.token,
                'content': content,
                'selected': selected
            })
Example #30
0
class IData(zope.interface.Interface):
    """A proxy object for form data.

    The object will make all keys within its data attribute available as
    attributes. The schema that is represented by the data will be directly
    provided by instances.
    """
    def __init__(schema, data, context):
        """The data proxy is instantiated using the schema it represents, the
        data fulfilling the schema and the context in which the data is
        validated.
        """

    __context__ = zope.schema.Field(
        title=_('Context'),
        description=_('The context in which the data is validated.'),
        required=True)
Example #31
0
class ValueErrorViewSnippet(ErrorViewSnippet):
    """An error view for ValueError."""
    zope.component.adapts(ValueError, None, None, None, None, None)

    defaultMessage = _('The system could not process the given value.')

    def createMessage(self):
        return self.defaultMessage
    def __call__(self, context):
        catalog = api.portal.get_tool('portal_catalog')
        style_template_brains = catalog(portal_type='StyleTemplate')
        voc_terms = [SimpleTerm('--NOVALUE--', '--NOVALUE--', _('No value'))]

        for brain in style_template_brains:
            voc_terms.append(SimpleTerm(brain.UID, brain.UID, brain.Title))

        vocabulary = SimpleVocabulary(voc_terms)

        return vocabulary
    def __call__(self, context):
        catalog = api.portal.get_tool('portal_catalog')
        pod_templates = catalog(
            portal_type=['PODTemplate', 'SubTemplate'],
            sort_on='sortable_title',
            sort_order='ascending',
        )
        voc_terms = [SimpleTerm('--NOVALUE--', '--NOVALUE--', _('No value'))]

        for brain in pod_templates:
            voc_terms.append(SimpleTerm(brain.UID, brain.UID, brain.Title))

        vocabulary = SimpleVocabulary(voc_terms)

        return vocabulary
    def get_validated_classlist_id(self, request):
        """ Checks the request for a classlist name specified via
            new_classlist_id - from a field in the importlearners template
            classlist_id - if upload-classlist-spreadsheet view called directly
            if none of these exist on the request - throw error
        """

        new_classlist_id = request.get('new_classlist_id', None)
        if new_classlist_id is not None and len(new_classlist_id) > 0:
            return None, new_classlist_id
        else:        
            classlist_uid = request.get('classlist_uid' , None)
            if classlist_uid is None:
                return _("Please indicate which class to use"), None
            else:
                return None, classlist_uid
    def add_learners(self, classlist, sheet):
        """ Extracts learners from specified xls spreadsheet and adds
            them to a classlist. Performs several checks to insure data
            integrity.
        """

        errors = []
        row_count = sheet.nrows
        for row_num in range(0, row_count):
            error = None
            learner = None
            code = sheet.cell(row_num, 0).value

            # if code is a number when imported from excel documents it will be 
            # imported as a float, but we want a string.
            # if code is a contains characters, it should be a string when
            # imported so these checks are not needed.

            if isinstance(code, float):
                # get rid of decimals (the .0 part) and convert to string)
                code = str(int(code))
            if isinstance(code, int): 
                # this may never execute but just in case
                code = str(code)

            name = sheet.cell(row_num, 1).value
            gender = sheet.cell(row_num, 2).value
            language = sheet.cell(row_num, 3).value

            error, learner = self.get_learner(classlist, code, name, gender,
                                              language)
            if learner is None:      
                message = _("Could not add learner:") + ' %s' % name
                errors.append(message)
                errors.append(error)
            else:
                if error is not None:
                    errors.append(error)
        
        notify(ObjectModifiedEvent(classlist))

        return errors
Example #36
0
def extractFileName(form, id, cleanup=True, allowEmptyPostfix=False):
    """Extract the filename of the widget with the given id.

    Uploads from win/IE need some cleanup because the filename includes also
    the path. The option ``cleanup=True`` will do this for you. The option
    ``allowEmptyPostfix`` allows to have a filename without extensions. By
    default this option is set to ``False`` and will raise a ``ValueError`` if
    a filename doesn't contain a extension.
    """
    widget = getWidgetById(form, id)
    if not allowEmptyPostfix or cleanup:
        # We need to strip out the path section even if we do not reomve them
        # later, because we just need to check the filename extension.
        cleanFileName = widget.filename.split('\\')[-1]
        cleanFileName = cleanFileName.split('/')[-1]
        dottedParts = cleanFileName.split('.')
    if not allowEmptyPostfix:
        if len(dottedParts) <= 1:
            raise ValueError(_('Missing filename extension.'))
    if cleanup:
        return cleanFileName
    return widget.filename
Example #37
0
 def _makeMissingTerm(self, value):
     """Return a term that should be displayed for the missing token"""
     uvalue = util.toUnicode(value)
     return vocabulary.SimpleTerm(
         value, self._makeToken(value),
         title=_(u'Missing: ${value}', mapping=dict(value=uvalue)))
 def add_portal_errors(self, errors):
     for error in errors:
         msg = _(error)
         IStatusMessage(self.request).addStatusMessage(msg,"error")