class AgreementAnswerSubmissionForm(fossirForm): answer = fossirRadioField(_("Answer"), [InputRequired()], coerce=lambda x: bool(int(x)), choices=[(1, _("Agreement")), (0, _("Disagreement"))]) document = FileField(_("Document"), [UsedIf(lambda form, field: form.answer.data), DataRequired()]) upload_confirm = BooleanField(_("I confirm that I'm uploading a document that clearly shows this person's answer"), [UsedIf(lambda form, field: form.answer.data), DataRequired()]) understand = BooleanField(_("I understand that I'm answering the agreement on behalf of this person"), [DataRequired()], description=_("This answer is legally binding and can't be changed " "afterwards."))
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 AttachmentFormBase(fossirForm): protected = BooleanField(_("Protected"), widget=SwitchWidget()) folder = QuerySelectField( _("Folder"), allow_blank=True, blank_text=_("No folder selected"), get_label='title', description=_( "Adding materials to folders allow grouping and easier permission " "management.")) acl = AccessControlListField( _("Access control list"), [UsedIf(lambda form, field: form.protected.data)], groups=True, allow_external=True, default_text=_('Restrict access to this material'), description=_( "The list of users and groups allowed to access the material")) def __init__(self, *args, **kwargs): linked_object = kwargs.pop('linked_object') super(AttachmentFormBase, self).__init__(*args, **kwargs) self.folder.query = (AttachmentFolder.find( object=linked_object, is_default=False, is_deleted=False).order_by(db.func.lower(AttachmentFolder.title))) @generated_data def protection_mode(self): return ProtectionMode.protected if self.protected.data else ProtectionMode.inheriting
class SessionProtectionForm(fossirForm): protection_mode = fossirProtectionField( _('Protection mode'), protected_object=lambda form: form.protected_object, acl_message_url=lambda form: url_for('sessions.acl_message', form. protected_object)) acl = AccessControlListField( _('Access control list'), [UsedIf(lambda form, field: form.protected_object.is_protected)], groups=True, allow_emails=True, default_text=_('Restrict access to this session'), description=_('List of users allowed to access the session.')) managers = PrincipalListField( _('Managers'), groups=True, allow_emails=True, description=_('List of users allowed to modify the session')) coordinators = PrincipalListField(_('Coordinators'), groups=True, allow_emails=True) def __init__(self, *args, **kwargs): self.protected_object = kwargs.pop('session') super(SessionProtectionForm, self).__init__(*args, **kwargs)
class _DateTimePair(Form): start = DateTimeField(_(u'from'), [UsedIf(lambda form, field: form.end.data)], display_format='%d/%m/%Y %H:%M', parse_kwargs={'dayfirst': True}) end = DateTimeField(_(u'to'), [UsedIf(lambda form, field: form.start.data)], display_format='%d/%m/%Y %H:%M', parse_kwargs={'dayfirst': True}) def validate_start(self, field): if self.start.data and self.end.data and self.start.data >= self.end.data: raise ValidationError( 'The start date must be earlier than the end date.') validate_end = validate_start
class NewBookingSimpleForm(NewBookingConfirmForm): submit_check = SubmitField(_('Check conflicts')) booking_reason = TextAreaField(_('Reason'), [ UsedIf(lambda form, field: not form.submit_check.data), DataRequired() ]) room_usage = RadioField( validators=[ UsedIf(lambda form, field: not form.submit_check.data), DataRequired() ], choices=[('current_user', _("I'll be using the room myself")), ('other_user', _("I'm booking the room for someone else"))]) booked_for_user = PrincipalField(_('User'), [ UsedIf(lambda form, field: not form.submit_check.data), HiddenUnless('room_usage', 'other_user'), DataRequired() ], allow_external=True)
class VCRoomLinkFormBase(fossirForm): conditional_fields = {'contribution', 'block'} linking = fossirRadioField(_("Link to"), [DataRequired()], choices=[('event', _("Event")), ('contribution', _("Contribution")), ('block', _("Session"))], widget=LinkingWidget()) contribution = SelectField(_("Contribution"), [ UsedIf(lambda form, field: form.linking.data == 'contribution'), DataRequired() ], coerce=lambda x: int(x) if x else None) block = SelectField(_("Session block"), [ UsedIf(lambda form, field: form.linking.data == 'block'), DataRequired() ], coerce=lambda x: int(x) if x else None) show = BooleanField(_('Show room'), widget=SwitchWidget(), description=_('Display this room on the event page')) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(VCRoomLinkFormBase, self).__init__(*args, **kwargs) contrib_choices = [(contrib.id, contrib.title) for contrib in sorted(self.event.contributions, key=attrgetter('title'))] blocks = SessionBlock.find( SessionBlock.session.has((Session.event == self.event) & ~Session.is_deleted)) block_choices = [ (block.id, block.full_title) for block in sorted(blocks, key=attrgetter('full_title')) ] self.contribution.choices = [('', _("Please select a contribution")) ] + contrib_choices self.block.choices = [('', _("Please select a session block")) ] + block_choices
class AttachmentFolderForm(fossirForm): title = HiddenField(_("Name"), [DataRequired()], widget=TypeaheadWidget(), description=_("The name of the folder.")) description = TextAreaField( _("Description"), description=_("Description of the folder and its content")) protected = BooleanField(_("Protected"), widget=SwitchWidget()) acl = AccessControlListField( _("Access control list"), [UsedIf(lambda form, field: form.protected.data)], groups=True, allow_external=True, default_text=_('Restrict access to this folder'), description=_( "The list of users and groups allowed to access the folder")) is_always_visible = BooleanField( _("Always Visible"), widget=SwitchWidget(), description=_( "By default, folders are always visible, even if a user cannot " "access them. You can disable this behavior here, hiding the folder " "for anyone who does not have permission to access it.")) def __init__(self, *args, **kwargs): self.linked_object = kwargs.pop('linked_object') super(AttachmentFolderForm, self).__init__(*args, **kwargs) self.title.choices = self._get_title_suggestions() def _get_title_suggestions(self): query = db.session.query(AttachmentFolder.title).filter_by( is_deleted=False, is_default=False, object=self.linked_object) existing = set(x[0] for x in query) suggestions = set(get_default_folder_names()) - existing if self.title.data: suggestions.add(self.title.data) return sorted(suggestions) @generated_data def protection_mode(self): return ProtectionMode.protected if self.protected.data else ProtectionMode.inheriting
class ScheduleSurveyForm(fossirForm): start_dt = fossirDateTimeField( _("Start"), [UsedIf(lambda form, field: form.allow_reschedule_start), Optional()], default_time=time(0, 0), description=_("Moment when the survey will open for submissions")) end_dt = fossirDateTimeField( _("End"), [Optional(), LinkedDateTime('start_dt')], default_time=time(23, 59), description=_("Moment when the survey will close")) resend_start_notification = BooleanField( _('Resend start notification'), widget=SwitchWidget(), description=_("Resend the survey start notification.")) def __init__(self, *args, **kwargs): survey = kwargs.pop('survey') self.allow_reschedule_start = kwargs.pop('allow_reschedule_start') self.timezone = survey.event.timezone super(fossirForm, self).__init__(*args, **kwargs) if not survey.start_notification_sent or not self.allow_reschedule_start: del self.resend_start_notification
class AbstractReviewingSettingsForm(fossirForm): """Settings form for abstract reviewing""" RATING_FIELDS = ('scale_lower', 'scale_upper') scale_lower = IntegerField( _("Scale (from)"), [UsedIf(lambda form, field: not form.has_ratings), InputRequired()]) scale_upper = IntegerField( _("Scale (to)"), [UsedIf(lambda form, field: not form.has_ratings), InputRequired()]) allow_convener_judgment = BooleanField( _("Allow track conveners to judge"), widget=SwitchWidget(), description=_( "Enabling this allows track conveners to make a judgment " "such as accepting or rejecting an abstract.")) allow_comments = BooleanField( _("Allow comments"), widget=SwitchWidget(), description=_( "Enabling this allows judges, conveners and reviewers to leave " "comments on abstracts.")) allow_contributors_in_comments = BooleanField( _("Allow contributors in comments"), [HiddenUnless('allow_comments', preserve_data=True)], widget=SwitchWidget(), description=_("Enabling this allows submitters, authors, and " "speakers to also participate in the comments.")) abstract_review_questions = ReviewQuestionsField( _("Review questions"), question_model=AbstractReviewQuestion, extra_fields=[{ 'id': 'no_score', 'caption': _("Exclude from score"), 'type': 'checkbox' }]) reviewing_instructions = fossirMarkdownField( _('Reviewing Instructions'), editor=True, description=_("These instructions will be displayed right before the " "reviewing form.")) judgment_instructions = fossirMarkdownField( _('Judgment Instructions'), editor=True, description=_("These instructions will be displayed right before the " "decision box.")) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') self.has_ratings = kwargs.pop('has_ratings', False) super(AbstractReviewingSettingsForm, self).__init__(*args, **kwargs) if self.has_ratings: self.scale_upper.warning = _( "Some reviewers have already submitted ratings so the scale cannot be changed " "anymore.") 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." )) @property def data(self): data = super(AbstractReviewingSettingsForm, self).data if self.has_ratings: for key in self.RATING_FIELDS: del data[key] return data
class ConferenceLayoutForm(fossirForm): is_searchable = BooleanField( _("Enable search"), widget=SwitchWidget(), description=_("Enable search within the event")) show_nav_bar = BooleanField( _("Show navigation bar"), widget=SwitchWidget(), description=_("Show the navigation bar at the top")) show_banner = BooleanField( _("\"Now happening\""), widget=SwitchWidget(on_label=_("ON"), off_label=_("OFF")), description=_( "Show a banner with the current entries from the timetable")) show_social_badges = BooleanField(_("Show social badges"), widget=SwitchWidget()) # Style header_text_color = StringField(_("Text colour"), widget=ColorPickerWidget()) header_background_color = StringField(_("Background colour"), widget=ColorPickerWidget()) # Announcement announcement = StringField( _("Announcement"), [UsedIf(lambda form, field: form.show_announcement.data)], description=_("Short message shown below the title")) show_announcement = BooleanField( _("Show announcement"), widget=SwitchWidget(), description=_("Show the announcement message")) # Timetable timetable_by_room = BooleanField( _("Group by room"), widget=SwitchWidget(), description=_("Group the entries of the timetable by room by default")) timetable_detailed = BooleanField( _("Show detailed view"), widget=SwitchWidget(), description=_("Show the detailed view of the timetable by default.")) timetable_theme = SelectField(_('Theme'), [Optional()], coerce=lambda x: x or None) # Themes use_custom_css = BooleanField( _("Use custom CSS"), widget=SwitchWidget(), description=_( "Use a custom CSS file as a theme for the conference page. Deactivate " "this option to reveal the available fossir themes.")) theme = SelectField( _("Theme"), [Optional(), HiddenUnless('use_custom_css', False)], coerce=lambda x: (x or None), description=_( "Currently selected theme of the conference page. Click on the Preview button to " "preview and select a different one.")) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(ConferenceLayoutForm, self).__init__(*args, **kwargs) self.timetable_theme.choices = [ ('', _('Default')) ] + _get_timetable_theme_choices(self.event) self.theme.choices = _get_conference_theme_choices() def validate_use_custom_css(self, field): if field.data and not self.event.has_stylesheet: raise ValidationError( _('Cannot enable custom stylesheet unless there is one.'))
class AnnouncementForm(fossirForm): enabled = BooleanField(_('Enabled'), widget=SwitchWidget()) message = TextAreaField(_('Message'), [UsedIf(lambda form, _: form.enabled.data), DataRequired()])