class _TimePair(Form): start = TimeField(_(u'from'), [UsedIf(lambda form, field: form.end.data)]) end = TimeField(_(u'to'), [UsedIf(lambda form, field: form.start.data)]) def validate_start(self, field): if self.start.data and self.end.data and self.start.data >= self.end.data: raise ValidationError( 'The start time must be earlier than the end time.') validate_end = validate_start
class BreakEntryForm(EntryFormMixin, fossirForm): _entry_type = TimetableEntryType.BREAK _default_duration = timedelta(minutes=20) _display_fields = ('title', 'description', 'time', 'duration', 'location_data', 'colors') title = StringField(_("Title"), [DataRequired()]) description = TextAreaField(_("Description")) location_data = fossirLocationField(_("Location")) colors = fossirPalettePickerField(_('Colours'), color_list=get_colors())
def __init__(self, event): super(ContributionListGenerator, self).__init__(event) self.default_list_config = {'filters': {'items': {}}} session_empty = {None: _('No session')} track_empty = {None: _('No track')} type_empty = {None: _('No type')} session_choices = OrderedDict((unicode(s.id), s.title) for s in sorted(self.event.sessions, key=attrgetter('title'))) track_choices = OrderedDict((unicode(t.id), t.title) for t in sorted(self.event.tracks, key=attrgetter('title'))) type_choices = OrderedDict((unicode(t.id), t.name) for t in sorted(self.event.contribution_types, key=attrgetter('name'))) self.static_items = OrderedDict([ ('session', {'title': _('Session'), 'filter_choices': OrderedDict(session_empty.items() + session_choices.items())}), ('track', {'title': _('Track'), 'filter_choices': OrderedDict(track_empty.items() + track_choices.items())}), ('type', {'title': _('Type'), 'filter_choices': OrderedDict(type_empty.items() + type_choices.items())}), ('status', {'title': _('Status'), 'filter_choices': {'scheduled': _('Scheduled'), 'unscheduled': _('Not scheduled')}}) ]) self.list_config = self._get_config()
def _get_merge_problems(source, target): errors = [] warnings = [] if source == target: errors.append(_("Users are the same!")) if (source.first_name.strip().lower() != target.first_name.strip().lower() or source.last_name.strip().lower() != target.last_name.strip().lower()): warnings.append(_("Users' names seem to be different!")) if source.is_pending: warnings.append(_("Source user has never logged in to fossir!")) if target.is_pending: warnings.append(_("Target user has never logged in to fossir!")) if source.is_deleted: errors.append(_("Source user has been deleted!")) if target.is_deleted: errors.append(_("Target user has been deleted!")) if source.is_admin: warnings.append(_("Source user is an administrator!")) if target.is_admin: warnings.append(_("Target user is an administrator!")) if source.is_admin and not target.is_admin: errors.append( _("Source user is an administrator but target user isn't!")) return errors, warnings
class UpcomingEventsForm(fossirForm): max_entries = IntegerField(_('Max. events'), [InputRequired(), NumberRange(min=0)], description=_("The maximum number of upcoming events to show. Events are sorted by " "weight so events with a lower weight are more likely to be omitted if " "there are too many events to show.")) entries = MultipleItemsField(_('Upcoming events'), fields=[{'id': 'type', 'caption': _("Type"), 'required': True, 'type': 'select'}, {'id': 'id', 'caption': _("ID"), 'required': True, 'type': 'number', 'step': 1, 'coerce': int}, {'id': 'days', 'caption': _("Days"), 'required': True, 'type': 'number', 'step': 1, 'coerce': int}, {'id': 'weight', 'caption': _("Weight"), 'required': True, 'type': 'number', 'coerce': float}], choices={'type': {'category': _('Category'), 'event': _('Event')}}, description=_("Specify categories/events shown in the 'upcoming events' list on the " "home page.")) def validate_entries(self, field): if field.errors: return for entry in field.data: if entry['days'] < 0: raise ValidationError(_("'Days' must be a positive integer")) if entry['type'] not in {'category', 'event'}: raise ValidationError(_('Invalid type')) if entry['type'] == 'category' and not Category.get(entry['id'], is_deleted=False): raise ValidationError(_('Invalid category: {}').format(entry['id'])) if entry['type'] == 'event' and not Event.get(entry['id'], is_deleted=False): raise ValidationError(_('Invalid event: {}').format(entry['id']))
class AttachmentPackageForm(fossirForm): added_since = fossirDateField( _('Added Since'), [Optional()], description=_('Include only attachments uploaded after this date')) filter_type = fossirRadioField(_('Include'), [DataRequired()]) sessions = fossirSelectMultipleCheckboxField( _('Sessions'), [HiddenUnless('filter_type', 'sessions'), DataRequired()], description=_('Include materials from selected sessions'), coerce=int) contributions = fossirSelectMultipleCheckboxField( _('Contributions'), [HiddenUnless('filter_type', 'contributions'), DataRequired()], description=_('Include materials from selected contributions'), coerce=int) dates = fossirSelectMultipleCheckboxField( _('Events scheduled on'), [HiddenUnless('filter_type', 'dates'), DataRequired()], description=_( 'Include materials from sessions/contributions scheduled ' 'on the selected dates'))
class RequestManagerForm(fossirForm): action_buttons = {'action_save', 'action_accept', 'action_reject'} comment = TextAreaField( _('Comment'), description= _('The comment will be shown only if the request is accepted or rejected.' )) action_save = SubmitField(_('Save')) action_accept = SubmitField(_('Accept')) action_reject = SubmitField(_('Reject'))
def validate_csrf_token(self, form, field): if field.current_token == field.data: return if not g.get('flashed_csrf_message'): # Only flash the message once per request. We may end up in here # multiple times if `validate()` is called more than once flash( _('It looks like there was a problem with your current session. Please submit the form again.' ), 'error') g.flashed_csrf_message = True raise ValidationError(_('Invalid CSRF token'))
def validate_end_dt(self, field): super(NewBookingSimpleForm, self).validate_end_dt(field) new_end_dt = field.data now = datetime.now() if self._old_end_dt < now and new_end_dt != self._old_end_dt and not session.user.is_admin: raise ValidationError( _("The end time is in the past and cannot be modified.")) if self._old_end_dt >= now and new_end_dt < now and not session.user.is_admin: raise ValidationError( _('The end time cannot be moved into the past.'))
class AddTemplateForm(fossirForm): title = StringField(_('Title'), [DataRequired()]) type = fossirEnumSelectField(_('Template'), enum=TemplateType, default=TemplateType.poster) is_clonable = BooleanField( _('Allow cloning'), widget=SwitchWidget(), default=True, description=_( "Allow cloning this template in subcategories and events"))
def _create_booking_response(self, form, room): """Creates the booking and returns a JSON response.""" try: booking = self._create_booking(form, room) except NoReportError as e: db.session.rollback() return jsonify(success=False, msg=unicode(e)) flash( _(u'Pre-Booking created') if booking.is_pending else _(u'Booking created'), 'success') return jsonify(success=True, url=self._get_success_url(booking))
def _process_args(self): RHMoveCategoryBase._process_args(self) if self.category.is_root: raise BadRequest(_("Cannot move the root category.")) if self.target_category is not None: if self.target_category == self.category: raise BadRequest(_("Cannot move the category inside itself.")) if self.target_category.parent_chain_query.filter( Category.id == self.category.id).count(): raise BadRequest( _("Cannot move the category in a descendant of itself."))
class LectureCreationForm(EventCreationFormBase): _field_order = ('title', 'occurrences', 'timezone', 'location_data', 'person_link_data', 'protection_mode') _advanced_field_order = ('description', 'theme') occurrences = OccurrencesField(_("Dates"), [DataRequired()], default_time=time(8), default_duration=timedelta(minutes=90)) person_link_data = EventPersonLinkListField(_('Speakers')) description = TextAreaField(_('Description'), widget=CKEditorWidget()) theme = fossirThemeSelectField(_('Theme'), event_type=EventType.lecture, allow_default=True)
def _sidemenu_sections(sender, **kwargs): yield SideMenuSection('security', _("Security"), 90, icon='shield') yield SideMenuSection('user_management', _("User Management"), 60, icon='users') yield SideMenuSection('customization', _("Customization"), 50, icon='wrench') yield SideMenuSection('integration', _("Integration"), 30, icon='earth') yield SideMenuSection('homepage', _("Homepage"), 40, icon='home')
def _getAnswer(self): if not self._start_dt or not self._end_dt: return None start_date = self._start_dt.date() end_date = self._end_dt.date() holidays = Holiday.find_all(Holiday.date.in_([start_date, end_date])) if holidays: return _(u'Holidays chosen: {0}'.format(', '.join( h.name or format_date(h.date) for h in holidays))) if is_weekend(start_date) or is_weekend(end_date): return _(u'Weekend chosen') return None
def _process(self): if self.reminder.is_sent: flash(_('Sent reminders cannot be deleted.'), 'error') else: db.session.delete(self.reminder) logger.info('Reminder deleted by %s: %s', session.user, self.reminder) flash( _("The reminder at {} has been deleted.").format( to_unicode(format_datetime(self.reminder.scheduled_dt))), 'success') return redirect(url_for('.list', self.event))
def _process_args(self): RHMoveCategoryBase._process_args(self) subcategory_ids = map(int, request.values.getlist('category_id')) self.subcategories = (Category.query.with_parent(self.category).filter( Category.id.in_(subcategory_ids)).order_by(Category.title).all()) if self.target_category is not None: if self.target_category.id in subcategory_ids: raise BadRequest(_("Cannot move a category inside itself.")) if self.target_category.parent_chain_query.filter( Category.id.in_(subcategory_ids)).count(): raise BadRequest( _("Cannot move a category in a descendant of itself."))
def _process(self): form = AbstractsScheduleForm(obj=FormDefaults(**abstracts_settings.get_all(self.event)), event=self.event) if form.validate_on_submit(): rescheduled = self.event.cfa.start_dt is not None schedule_cfa(self.event, **form.data) if rescheduled: flash(_("Call for abstracts has been rescheduled"), 'success') else: flash(_("Call for abstracts has been scheduled"), 'success') return jsonify_data(flash=False) return jsonify_form(form)
def type_name(self): if isinstance(self.object, db.m.Session): return _('Session') elif isinstance(self.object, db.m.Contribution): return _('Contribution') elif isinstance(self.object, db.m.AttachmentFolder): return _('Folder') elif isinstance(self.object, db.m.Attachment): return _('File') else: raise TypeError('Unexpected object of type {}: {}'.format( type(self.object).__name__, self.object))
class NumberConfigForm(object): min_value = IntegerField(_('Min value'), [Optional()]) max_value = IntegerField(_('Max value'), [Optional()]) def _validate_min_max_value(self, field): if (self.min_value.data is not None and self.max_value.data is not None and self.min_value.data >= self.max_value.data): raise ValidationError( _('The min value must be less than the max value.')) validate_min_value = _validate_min_max_value validate_max_value = _validate_min_max_value
class VCRoomAttachFormBase(VCRoomLinkFormBase): room = VCRoomField( _("Room to link"), [DataRequired()], description=_( "Please start writing the name of the room you would like to attach. " "fossir will suggest existing rooms.")) def __init__(self, *args, **kwargs): super(VCRoomAttachFormBase, self).__init__(*args, **kwargs) self.room.widget.search_url = url_for('.manage_vc_rooms_search', self.event, service=kwargs.pop('service'))
def validate_entries(self, field): if field.errors: return for entry in field.data: if entry['days'] < 0: raise ValidationError(_("'Days' must be a positive integer")) if entry['type'] not in {'category', 'event'}: raise ValidationError(_('Invalid type')) if entry['type'] == 'category' and not Category.get(entry['id'], is_deleted=False): raise ValidationError(_('Invalid category: {}').format(entry['id'])) if entry['type'] == 'event' and not Event.get(entry['id'], is_deleted=False): raise ValidationError(_('Invalid event: {}').format(entry['id']))
def _sidemenu_sections(sender, **kwargs): user_has_rooms = session.user is not None and Room.user_owns_rooms( session.user) yield SideMenuSection('search', _("Search"), 40, icon='search', active=True) if user_has_rooms: yield SideMenuSection('my_rooms', _("My Rooms"), 30, icon='user') yield SideMenuSection('blocking', _("Room Blocking"), 20, icon='lock')
def validate_duration(self, field): start_dt = self.start_dt.data if self.start_dt else None if start_dt: end_dt = start_dt + field.data if self.session_block and end_dt > self.session_block.end_dt: raise ValidationError( _("With the current duration the contribution exceeds the block end date" )) if end_dt > self.event.end_dt: raise ValidationError( _('With the current duration the contribution exceeds the event end date' ))
class ReportErrorForm(fossirForm): comment = TextAreaField( _('Details'), [DataRequired()], render_kw={'rows': 5}, description=_( 'Please let us know what you were doing when the error showed up.') ) email = EmailField( _('Email address'), description=_( 'If you enter your email address we can contact you to follow-up ' 'on your error report.'))
def _process(self): if not self.plugin.can_manage_vc_rooms(session.user, self.event): flash( _('You are not allowed to create {plugin_name} rooms for this event.' ).format(plugin_name=self.plugin.friendly_name), 'error') return redirect(url_for('.manage_vc_rooms', self.event)) form = self.plugin.create_form(event=self.event) if form.validate_on_submit(): vc_room = VCRoom(created_by_user=session.user) vc_room.type = self.plugin.service_name vc_room.status = VCRoomStatus.created event_vc_room = process_vc_room_association( self.plugin, self.event, vc_room, form) if not event_vc_room: return redirect(url_for('.manage_vc_rooms', self.event)) with db.session.no_autoflush: self.plugin.update_data_vc_room(vc_room, form.data) try: # avoid flushing the incomplete vc room to the database with db.session.no_autoflush: self.plugin.create_room(vc_room, self.event) notify_created(self.plugin, vc_room, event_vc_room, self.event, session.user) except VCRoomError as err: if err.field is None: raise field = getattr(form, err.field) field.errors.append(err.message) db.session.rollback( ) # otherwise the incomplete vc room would be added to the db! else: db.session.add(vc_room) # TODO: notify_created(vc_room, self.event, session.user) flash( _("{plugin_name} room '{room.name}' created").format( plugin_name=self.plugin.friendly_name, room=vc_room), 'success') return jsonify_data(flash=False) form_html = self.plugin.render_form(plugin=self.plugin, event=self.event, form=form, skip_fields=form.skip_fields | {'name'}) return jsonify(html=form_html, js=_pop_injected_js())
class CephalopodForm(fossirForm): joined = BooleanField('Join the community', widget=SwitchWidget()) contact_name = StringField( 'Contact Name', [UsedIfChecked('joined'), DataRequired()], description=_( 'Name of the person responsible for your fossir server.')) contact_email = EmailField( 'Contact Email', [UsedIfChecked('joined'), DataRequired(), Email()], description=_( 'Email address of the person responsible for your fossir server.'))
def test_lazy_translation(monkeypatch): monkeypatch.setattr('fossir.util.i18n.has_request_context', lambda: False) a = _(u'Fetch the cow') b = _(u'The wheels') monkeypatch.setattr('fossir.util.i18n.has_request_context', lambda: True) assert isinstance(a, _LazyString) assert isinstance(b, _LazyString) session.lang = 'fr_MP' assert unicode(a) == u'Fetchez la vache' assert unicode(b) == u'Les wheels'
def validate_scale_upper(self, field): lower = self.scale_lower.data upper = self.scale_upper.data if lower is None or upper is None: return if lower >= upper: raise ValidationError( _("The scale's 'to' value must be greater than the 'from' value." )) if upper - lower > 20: raise ValidationError( _("The difference between 'to' and' from' may not be greater than 20." ))
class EventCreationForm(EventCreationFormBase): _field_order = ('title', 'start_dt', 'end_dt', 'timezone', 'location_data', 'protection_mode') _advanced_field_order = () start_dt = fossirDateTimeField(_("Start"), [InputRequired()], default_time=time(8), allow_clear=False) end_dt = fossirDateTimeField( _("End"), [InputRequired(), LinkedDateTime('start_dt', not_equal=True)], default_time=time(18), allow_clear=False)