示例#1
0
class SingleChoiceConfigForm(object):
    display_type = IndicoRadioField(_('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 = IndicoRadioField(_('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'))
示例#2
0
class AgreementForm(IndicoForm):
    agreed = IndicoRadioField(_("Do you agree with the stated above?"),
                              [InputRequired()],
                              coerce=lambda x: bool(int(x)),
                              choices=[(1, _("I agree")),
                                       (0, _("I disagree"))])
    reason = TextAreaField(_("Reason"))
示例#3
0
class AttachmentPackageForm(IndicoForm):
    added_since = IndicoDateField(
        _('Added Since'), [Optional()],
        description=_('Include only attachments uploaded after this date'))

    filter_type = IndicoRadioField(_('Include'), [DataRequired()])

    sessions = IndicoSelectMultipleCheckboxField(
        _('Sessions'), [
            UsedIf(lambda form, _: form.filter_type.data == 'sessions'),
            DataRequired()
        ],
        description=_('Include materials from selected sessions'),
        coerce=int)
    contributions = IndicoSelectMultipleCheckboxField(
        _('Contributions'), [
            UsedIf(lambda form, _: form.filter_type.data == 'contributions'),
            DataRequired()
        ],
        description=_('Include materials from selected contributions'),
        coerce=int)
    dates = IndicoSelectMultipleCheckboxField(
        _('Events scheduled on'), [
            UsedIf(lambda form, _: form.filter_type.data == 'dates'),
            DataRequired()
        ],
        description=_(
            'Include materials from sessions/contributions scheduled '
            'on the selected dates'))
示例#4
0
class InvitedAbstractMixin(object):
    users_with_no_account = IndicoRadioField(_('Type of user'), [DataRequired()], default='existing',
                                             choices=(('existing', _('Existing user')),
                                                      ('new', _('New user'))))
    submitter = PrincipalField(_('Submitter'),
                               [HiddenUnless('users_with_no_account', 'existing'), DataRequired()], allow_external=True,
                               description=_('The person invited to submit the abstract'))
    first_name = StringField(_('First name'), [HiddenUnless('users_with_no_account', 'new'), DataRequired()])
    last_name = StringField(_('Family name'), [HiddenUnless('users_with_no_account', 'new'), DataRequired()])
    email = EmailField(_('Email address'), [HiddenUnless('users_with_no_account', 'new'), DataRequired()],
                       filters=[lambda x: x.lower() if x else x])

    def __init__(self, *args, **kwargs):
        self.event = kwargs['event']
        super(InvitedAbstractMixin, self).__init__(*args, **kwargs)

    def validate_email(self, field):
        if get_user_by_email(field.data):
            raise ValidationError(_('There is already a user with this email address'))

    def validate(self):
        from indico.modules.events.abstracts.util import can_create_invited_abstracts
        if not can_create_invited_abstracts(self.event):
            raise ValidationError(_('You have to create an "Invited" abstract notification template in order to '
                                    'be able to create invited abstracts.'))
        else:
            return super(InvitedAbstractMixin, self).validate()
示例#5
0
文件: forms.py 项目: mkopcic/indico
class VCRoomLinkFormBase(IndicoForm):
    conditional_fields = {'contribution', 'block'}

    linking = IndicoRadioField(_("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().__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
示例#6
0
文件: forms.py 项目: wtakase/indico
class AttachmentPackageForm(IndicoForm):
    added_since = DateField(
        _('Added Since'), [Optional()],
        parse_kwargs={'dayfirst': True},
        description=_('Include only attachments uploaded after this date'))

    filter_type = IndicoRadioField(_('Include'), [DataRequired()])

    sessions = IndicoSelectMultipleCheckboxField(
        _('Sessions'),
        [HiddenUnless('filter_type', 'sessions'),
         DataRequired()],
        description=_('Include materials from selected sessions'),
        coerce=int)
    contributions = IndicoSelectMultipleCheckboxField(
        _('Contributions'),
        [HiddenUnless('filter_type', 'contributions'),
         DataRequired()],
        description=_('Include materials from selected contributions'),
        coerce=int)
    dates = IndicoSelectMultipleCheckboxField(
        _('Events scheduled on'),
        [HiddenUnless('filter_type', 'dates'),
         DataRequired()],
        description=_(
            'Include materials from sessions/contributions scheduled '
            'on the selected dates'))
示例#7
0
class VCRoomLinkFormBase(IndicoForm):
    conditional_fields = {'contribution', 'block'}

    linking = IndicoRadioField(_("Link to"), [DataRequired()],
                               choices=[('event', _("Event")),
                                        ('contribution', _("Contribution")),
                                        ('block', _("Session"))],
                               widget=LinkingWidget())
    contribution = SelectField(_("Contribution"), [
        UsedIf(lambda form, field: form.linking.data == 'contribution'),
        DataRequired()
    ])
    block = SelectField(_("Session block"), [
        UsedIf(lambda form, field: form.linking.data == 'block'),
        DataRequired()
    ])

    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.getContributionList(), key=attrgetter('title'))]
        block_choices = [(full_block_id(block), block.getFullTitle())
                         for block in sorted(self.event.getSessionSlotList(),
                                             key=methodcaller('getFullTitle'))]
        self.contribution.choices = [('', _("Please select a contribution"))
                                     ] + contrib_choices
        self.block.choices = [('', _("Please select a session block"))
                              ] + block_choices
示例#8
0
文件: forms.py 项目: mkopcic/indico
class AgreementAnswerSubmissionForm(IndicoForm):
    answer = IndicoRadioField(_("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."))
示例#9
0
class VCRoomAttachForm(VCRoomAttachFormBase):
    password_visibility = IndicoRadioField(
        _('Passcode visibility'),
        description=_("Who should be able to know this meeting's passcode"),
        orientation='horizontal',
        choices=[('everyone', _('Everyone')),
                 ('logged_in', _('Logged-in users')),
                 ('registered', _('Registered participants')),
                 ('no_one', _('No one'))])
示例#10
0
class CloneRepeatUntilFormBase(CloneRepeatOnceForm):
    stop_criterion = IndicoRadioField(_('Clone'), [DataRequired()], default='num_times',
                                      choices=(('day', _('Until a given day (inclusive)')),
                                               ('num_times', _('A number of times'))))
    until_dt = IndicoDateField(_('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.setdefault('until_dt', (self._calc_start_dt(event) + timedelta(days=14)).date())
        super().__init__(event, **kwargs)
示例#11
0
文件: forms.py 项目: imfht/flaskapps
class VCRoomLinkFormBase(IndicoForm):
    conditional_fields = {'contribution', 'block'}

    linking = IndicoRadioField(_("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().__init__(*args, **kwargs)
        contrib_choices = [
            (contrib.id, '{} (#{}, {})'.format(
                contrib.title, contrib.friendly_id,
                format_datetime(contrib.start_dt, timezone=self.event.tzinfo)))
            for contrib in sorted(self.event.contributions,
                                  key=lambda c: (c.title, c.start_dt or as_utc(
                                      datetime(1970, 1, 1))))
            if contrib.start_dt is not None
        ]
        blocks = (SessionBlock.query.filter(
            SessionBlock.session.has((Session.event == self.event)
                                     & ~Session.is_deleted)).all())
        block_choices = [(block.id, '{} ({})'.format(
            block.full_title,
            format_datetime(block.start_dt, timezone=self.event.tzinfo)))
                         for block in sorted(
                             blocks, key=attrgetter('full_title', 'start_dt'))]
        self.contribution.choices = [('', _("Please select a contribution"))
                                     ] + contrib_choices
        self.block.choices = [('', _("Please select a session block"))
                              ] + block_choices
示例#12
0
文件: forms.py 项目: hkilter/indico
class CloneRepeatabilityForm(IndicoForm):
    repeatability = IndicoRadioField(_('How to repeat'),
                                     choices=CLONE_REPEAT_CHOICES,
                                     coerce=lambda x: x or None)
示例#13
0
class ReminderForm(IndicoForm):
    recipient_fields = {'recipients', 'send_to_participants'}
    schedule_fields = {'schedule_type', 'absolute_dt', 'relative_delta'}
    schedule_recipient_fields = recipient_fields | schedule_fields

    # Schedule
    schedule_type = IndicoRadioField(
        _('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_dt = IndicoDateTimeField(_('Date'), [
        HiddenUnless('schedule_type', 'absolute'),
        DataRequired(),
        DateTimeRange()
    ])
    # 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."
        ))
    include_description = BooleanField(
        _('Include description'),
        description=_("Includes the event's description in the email."))

    def __init__(self, *args, **kwargs):
        self.event = kwargs.pop('event')
        self.timezone = self.event.timezone
        super().__init__(*args, **kwargs)
        self.reply_to_address.choices = (list(
            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'))

    @generated_data
    def scheduled_dt(self):
        if self.schedule_type.data == 'absolute':
            if self.absolute_dt.data is None:
                return None
            return self.absolute_dt.data
        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
示例#14
0
class VCRoomForm(VCRoomFormBase):
    """Contains all information concerning a Zoom booking."""

    advanced_fields = {
        'mute_audio', 'mute_host_video', 'mute_participant_video'
    } | VCRoomFormBase.advanced_fields

    skip_fields = advanced_fields | VCRoomFormBase.conditional_fields

    meeting_type = IndicoRadioField(
        _('Meeting Type'),
        description=_('The type of Zoom meeting to be created'),
        orientation='horizontal',
        choices=[('regular', _('Regular Meeting')), ('webinar', _('Webinar'))])

    host_choice = IndicoRadioField(_('Meeting Host'), [DataRequired()],
                                   choices=[('myself', _('Myself')),
                                            ('someone_else', _('Someone else'))
                                            ])

    host_user = PrincipalField(
        _('User'),
        [HiddenUnless('host_choice', 'someone_else'),
         DataRequired()])

    password = StringField(
        _('Passcode'),
        [DataRequired(), IndicoRegexp(r'^\d{8,10}$')],
        description=_('Meeting passcode (8-10 digits)'))

    password_visibility = IndicoRadioField(
        _('Passcode visibility'),
        description=_("Who should be able to know this meeting's passcode"),
        orientation='horizontal',
        choices=[('everyone', _('Everyone')),
                 ('logged_in', _('Logged-in users')),
                 ('registered', _('Registered participants')),
                 ('no_one', _('No one'))])

    mute_audio = BooleanField(
        _('Mute audio'),
        widget=SwitchWidget(),
        description=_('Participants will join the VC room muted by default '))

    mute_host_video = BooleanField(
        _('Mute video (host)'),
        widget=SwitchWidget(),
        description=_('The host will join the VC room with video disabled'))

    mute_participant_video = BooleanField(
        _('Mute video (participants)'),
        widget=SwitchWidget(),
        description=_(
            'Participants will join the VC room with video disabled'))

    waiting_room = BooleanField(
        _('Waiting room'),
        widget=SwitchWidget(),
        description=_(
            'Participants may be kept in a waiting room by the host'))

    description = TextAreaField(
        _('Description'), description=_('Optional description for this room'))

    def __init__(self, *args, **kwargs):
        defaults = kwargs['obj']
        if defaults.host_user is None and defaults.host is not None:
            host = principal_from_identifier(defaults.host)
            defaults.host_choice = 'myself' if host == session.user else 'someone_else'
            defaults.host_user = None if host == session.user else host

        allow_webinars = current_plugin.settings.get('allow_webinars')

        if allow_webinars:
            for field_name in {
                    'mute_audio', 'mute_participant_video', 'waiting_room'
            }:
                inject_validators(self, field_name,
                                  [HiddenUnless('meeting_type', 'regular')])

        super().__init__(*args, **kwargs)

        if not allow_webinars:
            del self.meeting_type

    def validate_host_choice(self, field):
        if field.data == 'myself':
            self._check_zoom_user(session.user)

    def validate_host_user(self, field):
        if self.host_choice.data == 'someone_else':
            self._check_zoom_user(field.data)

    def _check_zoom_user(self, user):
        if find_enterprise_email(user) is None:
            raise ValidationError(_('This user has no Zoom account'))

    def validate_name(self, field):
        # Duplicate names are fine on Zoom
        pass

    @generated_data
    def host(self):
        if self.host_choice is None:
            return None
        elif self.host_choice.data == 'myself':
            return session.user.identifier
        else:
            return self.host_user.data.identifier if self.host_user.data else None
示例#15
0
class ReminderForm(IndicoForm):
    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 = IndicoRadioField(
        _('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 = DateField(
        _('Date'), [HiddenUnless('schedule_type', 'absolute'),
                    DataRequired()],
        parse_kwargs={'dayfirst': True})
    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 = _(
            'Your active timezone is {tz}.').format(tz=self.timezone)
        self._set_email_choices()
        if self.event.getType() == 'simple_event':
            del self.include_summary

    def _set_email_choices(self):
        # User
        emails = {session.user.email: session.user.full_name}
        # Creator
        emails[self.event.as_event.creator.
               email] = self.event.as_event.creator.full_name
        # Support
        support = self.event.getSupportInfo()
        emails[support.getEmail()] = support.getCaption() or support.getEmail()
        # Chairs
        emails.update((pl.email, pl.full_name)
                      for pl in self.event.as_event.person_links if pl.email)
        # Current email to avoid destructive modifications
        emails.setdefault(self.reply_to_address.object_data,
                          self.reply_to_address.object_data)
        # Sanitize and format emails
        emails = {
            to_unicode(email.strip().lower()):
            '{} <{}>'.format(to_unicode(name), to_unicode(email))
            for email, name in emails.iteritems() if email and email.strip()
        }
        self.reply_to_address.choices = sorted(
            emails.items(),
            key=lambda x: (x[0] != session.user.email, x[1].lower()))

    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'))

    @property
    def timezone(self):
        return DisplayTZ(conf=self.event).getDisplayTZ()

    @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 get_timezone(self.timezone).localize(dt).astimezone(
                pytz.utc)
        elif self.schedule_type.data == 'relative':
            if self.relative_delta.data is None:
                return None
            return self.event.getStartDate() - 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