class VCRoomListFilterForm(fossirForm): direction = SelectField(_('Sort direction'), [DataRequired()], choices=[('asc', _('Ascending')), ('desc', _('Descending'))]) abs_start_date = fossirDateField( _('Start Date'), [Optional(), Exclusive('rel_start_date')]) abs_end_date = fossirDateField( _('End Date'), [Optional(), Exclusive('rel_end_date')]) rel_start_date = IntegerField( _('Days in the past'), [Optional(), Exclusive('abs_start_date'), NumberRange(min=0)], default=0) rel_end_date = IntegerField( _('Days in the future'), [Optional(), Exclusive('abs_end_date'), NumberRange(min=0)], default=7) @generated_data def start_date(self): if self.abs_start_date.data is None and self.rel_start_date.data is None: return None return self.abs_start_date.data or ( date.today() - timedelta(days=self.rel_start_date.data)) @generated_data def end_date(self): if self.abs_end_date.data is None and self.rel_end_date.data is None: return None return self.abs_end_date.data or ( date.today() + timedelta(days=self.rel_end_date.data))
class BookingSearchForm(fossirForm): room_ids = SelectMultipleField('Rooms', [DataRequired()], coerce=int) start_date = fossirDateField('Start Date', [InputRequired()]) start_time = TimeField('Start Time', [InputRequired()]) end_date = fossirDateField('End Date', [InputRequired()]) end_time = TimeField('End Time', [InputRequired()]) booked_for_name = StringField('Booked For Name') reason = StringField('Reason') is_only_mine = BooleanField('Only Mine') is_only_my_rooms = BooleanField('Only My Rooms') is_only_confirmed_bookings = BooleanField('Only Confirmed Bookings') is_only_pending_bookings = BooleanField('Only Prebookings') is_rejected = BooleanField('Is Rejected') is_cancelled = BooleanField('Is Cancelled') is_archived = BooleanField('Is Archived') uses_vc = BooleanField(_('Uses Videoconference')) needs_vc_assistance = BooleanField(_('Videoconference Setup Assistance')) needs_assistance = BooleanField('General Assistance') @generated_data def start_dt(self): return datetime.combine(self.start_date.data, self.start_time.data) @generated_data def end_dt(self): return datetime.combine(self.end_date.data, self.end_time.data)
class CreateBlockingForm(BlockingForm): start_date = fossirDateField(_(u'Start date'), [DataRequired()]) end_date = fossirDateField(_(u'End date'), [DataRequired()]) def validate_start_date(self, field): if self.start_date.data > self.end_date.data: raise ValidationError('Blocking may not end before it starts!') validate_end_date = validate_start_date
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 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 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