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 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 SingleChoiceConfigForm(object): display_type = fossirRadioField( _('Display type'), [DataRequired()], description=_( 'Widget that will be used to render the available options'), choices=[('radio', _('Radio buttons')), ('select', _('Drop-down list'))], default='radio') radio_display_type = fossirRadioField( _('Alignment'), [DataRequired(), HiddenUnless('display_type', 'radio')], description=_('The arrangement of the options'), choices=[('vertical', _('Vertical')), ('horizontal', _('Horizontal'))]) options = MultiStringField( _('Options'), [DataRequired()], field=('option', _('option')), unique=True, uuid_field='id', sortable=True, description=_('Specify the options the user can choose from'))
class CloneRepeatUntilFormBase(CloneRepeatOnceForm): stop_criterion = fossirRadioField( _('Clone'), [DataRequired()], default='num_times', choices=(('day', _('Until a given day (inclusive)')), ('num_times', _('A number of times')))) until_dt = fossirDateField( _('Day'), [HiddenUnless('stop_criterion', 'day'), DataRequired()]) num_times = IntegerField(_('Number of times'), [ HiddenUnless('stop_criterion', 'num_times'), DataRequired(), NumberRange(1, 100, message=_("You can clone a maximum of 100 times")) ], default=2) def __init__(self, event, **kwargs): kwargs['until_dt'] = (self._calc_start_dt(event) + timedelta(days=14)).date() super(CloneRepeatUntilFormBase, self).__init__(event, **kwargs)
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 AgreementForm(fossirForm): agreed = fossirRadioField(_("Do you agree with the stated above?"), [InputRequired()], coerce=lambda x: bool(int(x)), choices=[(1, _("I agree")), (0, _("I disagree"))]) reason = TextAreaField(_("Reason"))
class ReminderForm(fossirForm): default_widget_attrs = {'absolute_time': {'placeholder': 'HH:MM'}} recipient_fields = {'recipients', 'send_to_participants'} schedule_fields = {'schedule_type', 'absolute_date', 'absolute_time', 'relative_delta'} schedule_recipient_fields = recipient_fields | schedule_fields # Schedule schedule_type = fossirRadioField(_('Type'), [DataRequired()], choices=[('relative', _("Relative to the event start time")), ('absolute', _("Fixed date/time")), ('now', _('Send immediately'))]) relative_delta = TimeDeltaField(_('Offset'), [HiddenUnless('schedule_type', 'relative'), DataRequired()]) absolute_date = fossirDateField(_('Date'), [HiddenUnless('schedule_type', 'absolute'), DataRequired()]) absolute_time = TimeField(_('Time'), [HiddenUnless('schedule_type', 'absolute'), InputRequired()]) # Recipients recipients = EmailListField(_('Email addresses'), description=_('One email address per line.')) send_to_participants = BooleanField(_('Participants'), description=_('Send the reminder to all participants/registrants ' 'of the event.')) # Misc reply_to_address = SelectField(_('Sender'), [DataRequired()], description=_('The email address that will show up as the sender.')) message = TextAreaField(_('Note'), description=_('A custom message to include in the email.')) include_summary = BooleanField(_('Include agenda'), description=_("Includes a simple text version of the event's agenda in the email.")) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(ReminderForm, self).__init__(*args, **kwargs) self.absolute_time.description = _("The event's timezone is {tz}.").format(tz=self.event.tzinfo) self.reply_to_address.choices = (self.event .get_allowed_sender_emails(extra=self.reply_to_address.object_data) .items()) if self.event.type_ == EventType.lecture: del self.include_summary def validate_recipients(self, field): if not field.data and not self.send_to_participants.data: raise ValidationError(_('If participants are not included you need to specify recipients.')) def validate_send_to_participants(self, field): if not field.data and not self.recipients.data: raise ValidationError(_('If no recipients are specified you need to include participants.')) def validate_schedule_type(self, field): # Be graceful and allow a reminder that's in the past but on the same day. # It will be sent immediately but that way we are a little bit more user-friendly if field.data == 'now': return scheduled_dt = self.scheduled_dt.data if scheduled_dt is not None and scheduled_dt.date() < now_utc().date(): raise ValidationError(_('The specified date is in the past')) def validate_absolute_date(self, field): if self.schedule_type.data == 'absolute' and field.data < date.today(): raise ValidationError(_('The specified date is in the past')) @generated_data def scheduled_dt(self): if self.schedule_type.data == 'absolute': if self.absolute_date.data is None or self.absolute_time.data is None: return None dt = datetime.combine(self.absolute_date.data, self.absolute_time.data) return self.event.tzinfo.localize(dt).astimezone(pytz.utc) elif self.schedule_type.data == 'relative': if self.relative_delta.data is None: return None return self.event.start_dt - self.relative_delta.data elif self.schedule_type.data == 'now': return now_utc() @generated_data def event_start_delta(self): return self.relative_delta.data if self.schedule_type.data == 'relative' else None
class CloneRepeatabilityForm(fossirForm): repeatability = fossirRadioField(_('How to repeat'), choices=CLONE_REPEAT_CHOICES, coerce=lambda x: x or None)