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)
class PapersScheduleForm(fossirForm): start_dt = fossirDateTimeField( _("Start"), [Optional()], default_time=time(0, 0), description=_("The moment users can start submitting papers")) end_dt = fossirDateTimeField( _("End"), [Optional(), LinkedDateTime('start_dt')], default_time=time(23, 59), description=_("The moment the submission process ends")) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(PapersScheduleForm, self).__init__(*args, **kwargs)
class ContributionStartDateForm(fossirForm): start_dt = fossirDateTimeField(_('Start date'), [ DataRequired(), DateTimeRange(earliest=lambda form, field: form.event.start_dt, latest=lambda form, field: form.event.end_dt) ], allow_clear=False) def __init__(self, *args, **kwargs): self.contrib = kwargs.pop('contrib') self.event = self.contrib.event self.timezone = self.event.timezone super(ContributionStartDateForm, self).__init__(*args, **kwargs) def validate_start_dt(self, field): event = self.contrib.event day = self.contrib.start_dt.astimezone(event.tzinfo).date() if day == event.end_dt_local.date(): latest_dt = event.end_dt error_msg = _( "With this time, the contribution would exceed the event end time." ) else: latest_dt = get_day_end(day, tzinfo=event.tzinfo) error_msg = _( "With this time, the contribution would exceed the current day." ) if field.data + self.contrib.duration > latest_dt: raise ValidationError(error_msg)
class DeadlineForm(fossirForm): deadline = fossirDateTimeField(_("Deadline"), [Optional()], default_time=time(23, 59)) enforce = BooleanField(_("Enforce deadline"), [HiddenUnless('deadline')], widget=SwitchWidget()) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(DeadlineForm, self).__init__(*args, **kwargs)
class AbstractsScheduleForm(fossirForm): start_dt = fossirDateTimeField( _("Start"), [Optional()], default_time=time(0, 0), description=_("The moment users can start submitting abstracts")) end_dt = fossirDateTimeField( _("End"), [Optional(), LinkedDateTime('start_dt')], default_time=time(23, 59), description=_("The moment the submission process will end")) modification_end_dt = fossirDateTimeField( _("Modification deadline"), [Optional(), LinkedDateTime('end_dt')], default_time=time(23, 59), description=_("Deadline until which the submitted abstracts can be " "modified")) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(AbstractsScheduleForm, self).__init__(*args, **kwargs)
class RegistrationFormScheduleForm(fossirForm): start_dt = fossirDateTimeField( _("Start"), [Optional()], default_time=time(0, 0), description=_("Moment when registrations will be open")) end_dt = fossirDateTimeField( _("End"), [Optional(), LinkedDateTime('start_dt')], default_time=time(23, 59), description=_("Moment when registrations will be closed")) modification_end_dt = fossirDateTimeField( _("Modification deadline"), [Optional(), LinkedDateTime('end_dt')], default_time=time(23, 59), description=_("Deadline until which registration information can be " "modified (defaults to the end date if empty)")) def __init__(self, *args, **kwargs): regform = kwargs.pop('regform') self.timezone = regform.event.timezone super(fossirForm, self).__init__(*args, **kwargs)
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 EventDatesForm(fossirForm): _main_fields = ('start_dt', 'end_dt', 'timezone', 'update_timetable') _override_date_fields = ('start_dt_override', 'end_dt_override') timezone = fossirTimezoneSelectField(_('Timezone'), [DataRequired()]) start_dt = fossirDateTimeField(_("Start"), [InputRequired()], allow_clear=False) end_dt = fossirDateTimeField( _("End"), [InputRequired(), LinkedDateTime('start_dt', not_equal=True)], allow_clear=False) update_timetable = BooleanField( _('Update timetable'), widget=SwitchWidget(), description=_( "Move sessions/contributions/breaks in the timetable according " "to the new event start time.")) start_dt_override = fossirDateTimeField( _("Start"), [Optional()], allow_clear=True, description=_( "Specifying this date overrides the start date displayed " "on the main conference page.")) end_dt_override = fossirDateTimeField( _("End"), [Optional(), LinkedDateTime('start_dt_override', not_equal=True)], allow_clear=True, description=_("Specifying this date overrides the end date displayed " "on the main conference page.")) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(EventDatesForm, self).__init__(*args, **kwargs) # timetable synchronization self.check_timetable_boundaries = (self.event.type_ != EventType.lecture) if self.check_timetable_boundaries: self.toplevel_timetable_entries = get_top_level_entries(self.event) if not self.toplevel_timetable_entries: self.check_timetable_boundaries = False if not self.check_timetable_boundaries: del self.update_timetable # displayed dates self.has_displayed_dates = (self.event.type_ == EventType.conference) if self.has_displayed_dates: start_dt = self.start_dt.data or self.start_dt.object_data end_dt = self.end_dt.data or self.end_dt.object_data self.start_dt_override.default_time = start_dt.astimezone( timezone(self.timezone.data)).time() self.end_dt_override.default_time = end_dt.astimezone( timezone(self.timezone.data)).time() else: del self.start_dt_override del self.end_dt_override def validate_start_dt(self, field): if not self.check_timetable_boundaries or self.update_timetable.data or field.object_data == field.data: return if field.data > min(self.toplevel_timetable_entries, key=attrgetter('start_dt')).start_dt: raise ValidationError( _("To use this start date the timetable must be updated.")) def validate_end_dt(self, field): if not self.check_timetable_boundaries: return if self.update_timetable.data: # if we move timetable entries according to the start date # change, check that there's enough time at the end. start_dt_offset = self.start_dt.data - self.start_dt.object_data end_buffer = field.data - max(self.toplevel_timetable_entries, key=attrgetter('end_dt')).end_dt delta = max(timedelta(), start_dt_offset - end_buffer) if delta: delta_str = format_human_timedelta(delta, 'minutes', True) raise ValidationError( _("The event is too short to fit all timetable entries. " "It must be at least {} longer.").format(delta_str)) else: # if we do not update timetable entries, only check that # the event does not end before its last timetable entry; # a similar check for the start time is done above in that # field's validation method. max_end_dt = max(self.toplevel_timetable_entries, key=attrgetter('end_dt')).end_dt if field.data < max_end_dt: raise ValidationError( _("The event cannot end before its last timetable entry, which is at {}." ).format( to_unicode( format_datetime(max_end_dt, timezone=self.event.tzinfo))))
class CloneRepeatOnceForm(CloneRepeatFormBase): start_dt = fossirDateTimeField(_('Starting'), allow_clear=False)
class ContributionForm(fossirForm): title = StringField(_("Title"), [DataRequired()]) description = TextAreaField(_("Description")) start_dt = fossirDateTimeField( _("Start date"), [ DataRequired(), DateTimeRange( earliest=lambda form, field: form._get_earliest_start_dt(), latest=lambda form, field: form._get_latest_start_dt()) ], allow_clear=False, description=_("Start date of the contribution")) duration = TimeDeltaField( _("Duration"), [DataRequired(), MaxDuration(timedelta(hours=24))], default=timedelta(minutes=20), units=('minutes', 'hours')) type = QuerySelectField(_("Type"), get_label='name', allow_blank=True, blank_text=_("No type selected")) person_link_data = ContributionPersonLinkListField(_("People")) location_data = fossirLocationField(_("Location")) keywords = fossirTagListField(_('Keywords')) references = ReferencesField( _("External IDs"), reference_class=ContributionReference, description=_("Manage external resources for this contribution")) board_number = StringField(_("Board Number")) @generated_data def render_mode(self): return RenderMode.markdown def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') self.contrib = kwargs.pop('contrib', None) self.session_block = kwargs.get('session_block') self.timezone = self.event.timezone to_schedule = kwargs.pop('to_schedule', False) super(ContributionForm, self).__init__(*args, **kwargs) self.type.query = self.event.contribution_types if self.event.type != 'conference': self.person_link_data.label.text = _("Speakers") if not self.type.query.count(): del self.type if not to_schedule and (self.contrib is None or not self.contrib.is_scheduled): del self.start_dt def _get_earliest_start_dt(self): return self.session_block.start_dt if self.session_block else self.event.start_dt def _get_latest_start_dt(self): return self.session_block.end_dt if self.session_block else self.event.end_dt 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' )) @property def custom_field_names(self): return tuple([ field_name for field_name in self._fields if field_name.startswith('custom_') ])