Example #1
0
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
Example #2
0
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())
Example #3
0
    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()
Example #4
0
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
Example #5
0
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']))
Example #6
0
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'))
Example #7
0
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'))
Example #8
0
 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'))
Example #9
0
    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.'))
Example #10
0
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))
Example #12
0
 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."))
Example #13
0
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)
Example #14
0
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))
Example #17
0
 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."))
Example #18
0
 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)
Example #19
0
 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))
Example #20
0
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
Example #21
0
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'))
Example #22
0
 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')
Example #24
0
 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'
                   ))
Example #25
0
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())
Example #27
0
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'
Example #29
0
 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."
               ))
Example #30
0
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)