def handle_save(self, action): if not self.allow_edit: self.message(_(u'Imported events may not be edited, ' u'no changes where applied')) return data, errors = self.extractData() validate_event_submission(data) if errors: self.status = self.formErrorsMessage return self.prepare_coordinates(data) self.apply_coordinates(self.getContent()) self.prepare_submission(data) self.apply_submission(self.getContent()) changes = self.applyChanges(data) if changes: self.message(_(u'Event Saved')) else: self.message(_(u'No changes were applied')) url = self.context.absolute_url() self.redirect(append_token(self.context, url))
def steps(self): if self._steps: return self._steps steps = [ NavigationStep('submit', _(u'Enter'), None), NavigationStep('preview', _(u'Verify'), None), NavigationStep('finish', _(u'Finish'), None) ] if self.__name__ == 'submit': steps[0].url = self.context.absolute_url() + '/@@submit' steps[1].url = None steps[2].url = None elif self.__name__ == 'preview': steps[0].url = self.directory.absolute_url() + '/@@submit' steps[1].url = self.context.absolute_url() + '/@@preview' steps[2].url = None elif self.__name__ == 'finish': steps[0].url = self.directory.absolute_url() + '/@@submit' steps[1].url = self.context.absolute_url() + '/@@preview' steps[2].url = self.context.absolute_url() + '/@@finish' for i in range(0, len(steps)): if steps[i].url: steps[i].url = append_token(self.context, steps[i].url) self._steps = steps return self._steps
def handle_save(self, action): if not self.allow_edit: self.message( _(u'Imported events may not be edited, ' u'no changes where applied')) return data, errors = self.extractData() validate_event_submission(data) if errors: self.status = self.formErrorsMessage return self.prepare_coordinates(data) self.apply_coordinates(self.getContent()) self.prepare_submission(data) self.apply_submission(self.getContent()) changes = self.applyChanges(data) if changes: self.message(_(u'Event Saved')) else: self.message(_(u'No changes were applied')) url = self.context.absolute_url() self.redirect(append_token(self.context, url))
def update_widgets(self): occurrences = self.widgets['title'].occurrences_count if occurrences > 1: self.label = _(u'List Preview (${number} Occurrences)', mapping={'number': occurrences}) else: self.label = _(u'List Preview (No Occurrences)')
class DoActionView(grok.View): """ Pretty much like modify_content_status, but with better messages and redirection to the directory. """ grok.name('do-action') grok.context(IEventsDirectoryItem) grok.require('cmf.ReviewPortalContent') messages = { 'publish': _(u'Event was published'), 'archive': _(u'Event was archived'), 'deny': _(u'Publication of event was denied'), 'hide': _(u'Event was hidden') } def render(self): action = self.request.get('action') assert action in self.messages IStatusMessage(self.request).add(self.messages[action], "info") self.context.do_action(action) self.request.response.redirect( self.context.get_parent().absolute_url()) return ""
def setup_form(self): self.buttons = button.Buttons() self.handlers = button.Handlers() if self.form_type() == 'addform': preview = button.Button(title=_(u'Continue'), name='save') self.buttons += button.Buttons(preview) preview_handler = button.Handler(preview, self.__class__.handle_preview) self.handlers.addHandler(preview, preview_handler) self.ignoreContext = True self.ignoreReadonly = True else: update = button.Button(title=_(u'Continue'), name='save') self.buttons += button.Buttons(update) update_handler = button.Handler(update, self.__class__.handle_update) self.handlers.addHandler(update, update_handler) self.context = self.event cancel = button.Button(title=_(u'Cancel'), name='cancel') self.buttons += button.Buttons(cancel) cancel_handler = button.Handler(cancel, self.__class__.handle_cancel) self.handlers.addHandler(cancel, cancel_handler)
def setup_form(self): self.buttons = button.Buttons() self.handlers = button.Handlers() if self.form_type() == 'addform': preview = button.Button(title=_(u'Continue'), name='save') self.buttons += button.Buttons(preview) preview_handler = button.Handler( preview, self.__class__.handle_preview ) self.handlers.addHandler(preview, preview_handler) self.ignoreContext = True self.ignoreReadonly = True else: update = button.Button(title=_(u'Continue'), name='save') self.buttons += button.Buttons(update) update_handler = button.Handler( update, self.__class__.handle_update ) self.handlers.addHandler(update, update_handler) self.context = self.event cancel = button.Button(title=_(u'Cancel'), name='cancel') self.buttons += button.Buttons(cancel) cancel_handler = button.Handler(cancel, self.__class__.handle_cancel) self.handlers.addHandler(cancel, cancel_handler)
def update_widgets(self): occurrences = self.widgets['title'].occurrences_count if occurrences > 1: self.label = _(u'List Preview (${number} Occurrences)', mapping={ 'number': occurrences }) else: self.label = _(u'List Preview (No Occurrences)')
def validate_image(value): if not value: return if not imghdr.what(value.filename, value.data): raise Invalid(_(u'Unknown image format')) check_filesize(value, 1, _(u'Images'))
class SourceConditionEditForm(EditForm): """An edit form for portal type conditions """ form_fields = form.FormFields(ISourceCondition) label = _(u"Edit import source condition") description = _( u"An import source condition makes the rule apply only to content " u"with the given import source.") form_name = _(u"Configure source condition")
def state_filter_list(self): submitted = utils.translate(self.request, _(u'Submitted')) submitted += u' (%i)' % self.catalog.submitted_count return [ ('submitted', submitted), ('published', _(u'Published')) ]
def state_filter_list(self): submitted = utils.translate(self.request, _(u'Submitted')) submitted += u' (%i)' % self.catalog.submitted_count return [ ('submitted', submitted), ('published', _(u'Published')), ('hidden', _(u'Hidden')) ]
class ISourceCondition(Interface): """Interface for the configurable aspects of a source condition of a content rule. This is also used to create add and edit forms, below. """ source = TextLine(title=_(u'Source'), description=_(u"The source id to check for. " u"Leave empty for any source."), required=False)
def validate_attachment(value): if not value: return filetype = magic.from_buffer(value.data[:1024], mime=True) if filetype not in mime_whitelist: raise Invalid( _(u'Unsupported fileformat. Supported is ${formats}', mapping={'formats': u','.join(sorted(mime_whitelist.values()))})) check_filesize(value, 10, _(u'Attachments'))
def human_date_short(date, request): now = default_now() if now.date() == date.date(): return _(u'Today') if now.date() + timedelta(days=1) == date.date(): return _(u'Tomorrow') if now.year == date.year: return date.strftime('%d.%m') else: return date.strftime('%d.%m.%Y')
class FinishForm(EventSubmissionForm, form.AddForm, NavigationMixin): implements(IDirectoryPage) grok.context(IEventsDirectoryItem) grok.name('finish') groups = (SubmitterGroup, ) template = ViewPageTemplateFile('templates/finishform.pt') enable_form_tabbing = False label = _(u'Event Submission Finish') description = u'' @property def directory(self): return self.context.get_parent() def current_token(self): return current_token(self.request) def update(self, *args, **kwargs): verify_token(self.context, self.request) super(FinishForm, self).update(*args, **kwargs) @button.buttonAndHandler(_('Submit'), name='save') def handleSubmit(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return self.context.submitter = data['submitter'] self.context.submitter_email = data['submitter_email'] clear_token(self.context) self.context.submit() IStatusMessage(self.request).add(_(u"Event submitted"), "info") self.request.response.redirect(self.directory.absolute_url()) @button.buttonAndHandler(_(u'Back'), name='back') def handleBack(self, action): self.request.response.redirect( append_token(self.context, self.context.absolute_url() + '/@@preview')) @button.buttonAndHandler(_(u'Cancel'), name='cancel') def handleCancel(self, action): self.handle_cancel()
class SourceConditionAddForm(AddForm): """An add form for portal type conditions. """ form_fields = form.FormFields(ISourceCondition) label = _(u"Add import source condition") description = _( u"An import source condition makes the rule apply only to content " u"with the given import source.") form_name = _(u"Configure source condition") def create(self, data): c = SourceCondition() form.applyChanges(c, self.form_fields, data) return c
def validate_attachment(value): if not value: return filetype = magic.from_buffer(value.data[:1024], mime=True) if filetype not in mime_whitelist: raise Invalid( _( u'Unsupported fileformat. Supported is ${formats}', mapping={'formats': u','.join(sorted(mime_whitelist.values()))} ) ) check_filesize(value, 10, _(u'Attachments'))
class LocationGroup(EventBaseGroup): label = _(u'Location') group_fields = OrderedDict() group_fields[IEventsDirectoryItem] = ('locality', 'street', 'housenumber', 'zipcode', 'town', 'location_url')
def human_date(date, request): now = default_now() if now.date() == date.date(): return _(u'Today') if now.date() + timedelta(days=1) == date.date(): return _(u'Tomorrow') calendar = request.locale.dates.calendars['gregorian'] weekday = calendar.getDayNames()[date.weekday()] if now.year == date.year: return weekday + ' ' + date.strftime('%d.%m.') else: return weekday + ' ' + date.strftime('%d.%m.%Y.')
class SubmitterGroup(EventBaseGroup): label = _(u'Submitter') dynamic_fields = ('submitter', 'submitter_email') group_fields = OrderedDict() group_fields[IEventsDirectoryItem] = ('submitter', 'submitter_email') group_fields[ITerms] = ('agreed', ) def update_dynamic_fields(self): self.fields['submitter'].field.required = True self.fields['submitter_email'].field.required = True # remove the terms and conditions agreement if there is none if not self.context.get_parent().terms: del self.fields['agreed'] else: # otherwise be sure to link to it url = self.context.get_parent().absolute_url() + '/@@terms' self.fields['agreed'].field.description = utils.translate( self.request, _( u"I agree to the <a target='_blank' href='${url}'>" u"Terms and Conditions</a>", mapping={'url': url}))
def human_date(date, request): now = default_now() if now.date() == date.date(): return _(u'Today') if now.date() + timedelta(days=1) == date.date(): return _(u'Tomorrow') calendar = request.locale.dates.calendars['gregorian'] weekday = calendar.getDayNames()[date.weekday()] if now.year == date.year: return weekday + ' ' + date.strftime('%d.%m.') else: return weekday + ' ' + date.strftime('%d.%m.%Y')
def handle_cancel(self): try: clear_token(self.context) except ComponentLookupError: pass IStatusMessage(self.request).add(_(u"Event submission cancelled"), "info") self.request.response.redirect(self.directory.absolute_url())
def handle_cancel(self, action): try: clear_token(self.context) except ComponentLookupError: pass self.message(_(u"Event submission cancelled")) self.redirect(self.directory.absolute_url())
def validate_terms_and_conditions(agreed): if not agreed: raise Invalid( _( u'You have to agree to the terms ' u'and conditions to submit this event' ) )
class TermsView(grok.View): grok.name('terms') grok.context(IEventsDirectory) grok.require('zope2.View') label = _(u'Terms and Conditions') template = grok.PageTemplateFile('templates/terms.pt')
def check_filesize(value, size_in_mb, type): if value.getSize() > size_in_mb * 1024 ** 2: raise Invalid( _( u'${type} bigger than ${max} Megabyte are not allowed', mapping={'max': size_in_mb, 'type': type} ) )
def handle_cancel(self): try: clear_token(self.context) except ComponentLookupError: pass IStatusMessage(self.request).add( _(u"Event submission cancelled"), "info" ) self.request.response.redirect(self.directory.absolute_url())
def setup_form(self): self.buttons = button.Buttons() self.handlers = button.Handlers() save = button.Button(title=_(u'Save Event'), name='save') self.buttons += button.Buttons(save) save_handler = button.Handler(save, self.__class__.handle_save) self.handlers.addHandler(save, save_handler) self.event = self.context cancel = button.Button(title=_(u'Cancel Event Submission'), name='cancel') self.buttons += button.Buttons(cancel) cancel_handler = button.Handler(cancel, self.__class__.handle_cancel) self.handlers.addHandler(cancel, cancel_handler)
def check_filesize(value, size_in_mb, type): if value.getSize() > size_in_mb * 1024**2: raise Invalid( _(u'${type} bigger than ${max} Megabyte are not allowed', mapping={ 'max': size_in_mb, 'type': type }))
def update_widgets(self): # update labels of categories labels = self.context.labels() widgets = [w for w in self.widgets if w in labels] for widget in widgets: self.widgets[widget].label = labels[widget] self.widgets['title'].label = _(u'Title of event')
def setup_form(self): self.buttons = button.Buttons() self.handlers = button.Handlers() save = button.Button(title=_(u'Save Event'), name='save') self.buttons += button.Buttons(save) save_handler = button.Handler(save, self.__class__.handle_save) self.handlers.addHandler(save, save_handler) self.event = self.context cancel = button.Button( title=_(u'Cancel Event Submission'), name='cancel' ) self.buttons += button.Buttons(cancel) cancel_handler = button.Handler(cancel, self.__class__.handle_cancel) self.handlers.addHandler(cancel, cancel_handler)
def attachment_filename(self, attachment): filename = getattr(self, attachment).filename if not filename: number = attachment[-1] return _(u'Attachment ${number}', mapping=dict(number=number)) if len(filename) > 100: return filename[:100] + '...' else: return filename
class PreviewGroup(EventBaseGroup): label = _(u'Detail Preview') dynamic_fields = ('title', ) group_fields = OrderedDict() group_fields[IPreview] = ('title', ) def update_dynamic_fields(self): self.fields['title'].widgetFactory = DetailPreviewFieldWidget
class PreviewForm(EventSubmissionForm, form.AddForm, NavigationMixin): implements(IDirectoryPage) grok.context(IEventsDirectoryItem) grok.name('preview') groups = (PreviewGroup, ListPreviewGroup) template = ViewPageTemplateFile('templates/previewform.pt') enable_form_tabbing = True label = _(u'Event Submission Preview') description = u'' @property def directory(self): return self.context.get_parent() def current_token(self): return current_token(self.request) def update(self, *args, **kwargs): verify_token(self.context, self.request) super(PreviewForm, self).update(*args, **kwargs) @button.buttonAndHandler(_('Continue'), name='save') def handleSubmit(self, action): self.request.response.redirect( append_token(self.context, self.context.absolute_url() + '/@@finish')) @button.buttonAndHandler(_(u'Adjust'), name='adjust') def handleAdjust(self, action): self.request.response.redirect( append_token(self.context, self.directory.absolute_url() + '/@@submit')) @button.buttonAndHandler(_(u'Cancel'), name='cancel') def handleCancel(self, action): self.handle_cancel()
def handleSubmit(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return self.context.submitter = data['submitter'] self.context.submitter_email = data['submitter_email'] clear_token(self.context) self.context.submit() IStatusMessage(self.request).add(_(u"Event submitted"), "info") self.request.response.redirect(self.directory.absolute_url())
def handle_update(self, action): data, errors = self.extractData() validate_event_submission(data) if errors: self.status = self.formErrorsMessage return self.prepare_coordinates(data) self.apply_coordinates(self.getContent()) self.prepare_submission(data) self.apply_submission(self.getContent()) changes = self.applyChanges(data) if changes: self.message(_(u'Event Preview Updated')) else: self.message(_(u'No changes were applied')) url = self.context.absolute_url() + '/preview' self.redirect(append_token(self.context, url))
class ListPreviewGroup(PreviewGroup): label = _(u'List Preview') def update_dynamic_fields(self): self.fields['title'].widgetFactory = ListPreviewFieldWidget def update_widgets(self): occurrences = self.widgets['title'].occurrences_count if occurrences > 1: self.label = _(u'List Preview (${number} Occurrences)', mapping={'number': occurrences}) else: self.label = _(u'List Preview (No Occurrences)')
def check_coordinates_present(self): try: geo = IGeoreferenced(self.context) if geo.type: return except TypeError: pass self.context.plone_utils.addPortalMessage( _( u'No location set. The event will not be displayed in the' u' map.' ), 'warning' )
def human_daterange(start, end, request): if is_whole_day(start, end): if split_days_count(start, end) < 1: return utils.translate(request, _(u'Whole Day')) else: if default_now().year == start.year: return start.strftime('%d.%m. - ') \ + end.strftime('%d.%m. ') \ + utils.translate(request, _(u'Whole Day')) else: return start.strftime('%d.%m.%Y. - ') \ + end.strftime('%d.%m.%Y. ') \ + utils.translate(request, _(u'Whole Day')) if split_days_count(start, end) < 1: return start.strftime('%H:%M - ') + end.strftime('%H:%M') else: if default_now().year == start.year: return start.strftime('%d.%m. %H:%M - ') \ + end.strftime('%d.%m. %H:%M') else: return start.strftime('%d.%m.%Y. %H:%M - ') \ + end.strftime('%d.%m.%Y. %H:%M')
class MapGroup(EventBaseGroup): label = _(u'Map') dynamic_fields = ('wkt', ) group_fields = OrderedDict() group_fields[IGeoManager] = ('wkt', ) def update_widgets(self): self.widgets['wkt'].label = _(u'Coordinates') def update_dynamic_fields(self): coordinates = self.fields['wkt'] coordinates.widgetFactory = MapFieldWidget
class IEventsDirectory(IDirectory): """Extends the seantis.dir.base.directory.IDirectory""" image = NamedImage(title=_(u'Image'), required=False, default=None) searchable('terms') terms = Text(title=_(u'Terms and Conditions'), description=_( u'If entered, the terms and conditions have ' u'to be agreed to by anyone submitting an event.'), required=False, default=None) form.widget(terms=WysiwygFieldWidget) submit_event_link = Website( title=_(u'Event Report Link'), description=_( u'If a link is given, the "submit event" link on the directory ' u'will point to that link, instead of the internal submit form. ' u'If left empty, the internal submit form remains. ' u'Use this, if events should be submitted on an external website. ' ), required=False, default=None)
def update_dynamic_fields(self): self.fields['submitter'].field.required = True self.fields['submitter_email'].field.required = True # remove the terms and conditions agreement if there is none if not self.context.get_parent().terms: del self.fields['agreed'] else: # otherwise be sure to link to it url = self.context.get_parent().absolute_url() + '/@@terms' self.fields['agreed'].field.description = utils.translate( self.request, _( u"I agree to the <a target='_blank' href='${url}'>" u"Terms and Conditions</a>", mapping={'url': url} ) )
def labels(self): return dict(cat1=_(u'What'), cat2=_(u'Where'))
def validate_suggestion(value): if not value: raise Invalid(_(u'Please enter at least one suggestion'))
def no_events_helptext(self): if 'published' == self.catalog.state: return _(u'No events for the current daterange') else: return _(u'No events for the current state')
def validate_category(value): if not value: raise Invalid(_(u'Please choose at least one category'))
from zope.interface import Invalid, Interface, Attribute, alsoProvides from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm from seantis.dir.base.schemafields import Email, AutoProtocolURI from seantis.dir.base.interfaces import ( IDirectory, IDirectoryItem, IDirectoryItemCategories ) from seantis.dir.events import _ days = SimpleVocabulary( [ SimpleTerm(value='MO', title=_(u'Mo')), SimpleTerm(value='TU', title=_(u'Tu')), SimpleTerm(value='WE', title=_(u'We')), SimpleTerm(value='TH', title=_(u'Th')), SimpleTerm(value='FR', title=_(u'Fr')), SimpleTerm(value='SA', title=_(u'Sa')), SimpleTerm(value='SU', title=_(u'Su')), ] ) # cannot use the comprehension in the zope interface definition # because zope takes some weird magic to work days.keys = [str(d.value) for d in days._terms] class ITokenAccess(Interface):
def update_widgets(self): self.widgets['wkt'].label = _(u'Coordinates')
def summary(self): return _(u"Source contains: ${source}", mapping={'source': self.source})
def validate_event_submission(data): def fail(msg): raise ActionExecutionError(Invalid(msg)) if data['submission_date_type'] == ['date']: if data.get('submission_date') is None: fail(_(u'Missing start date')) if not data.get('submission_whole_day', False): if data.get('submission_start_time') is None: fail(_(u'Missing start time')) if data.get('submission_end_time') is None: fail(_(u'Missing end time')) if data['submission_date_type'] == ['range']: if data.get('submission_range_start_date') is None: fail(_(u'Missing start date')) if data.get('submission_range_end_date') is None: fail(_(u'Missing end date')) if not data.get('submission_whole_day', False): if data.get('submission_range_start_time') is None: fail(_(u'Missing start time')) if data.get('submission_range_end_time') is None: fail(_(u'Missing end time')) start, end, whole_day, recurrence = get_event_dates_from_submission(data) if not start: fail(_(u'Missing start date')) if not end: fail(_(u'Missing end date')) if end < start: fail(_(u'Start date after end date')) # ensure that the recurrences are not over limit if recurrence: limit = 365 # one event each day for a whole year if occurrences_over_limit(recurrence, start, limit): fail( _( u'You may not add more than ${max} occurences', mapping={'max': limit} ) )