Beispiel #1
0
class InvitationFormBase(IndicoForm):
    _invitation_fields = ('skip_moderation', )
    _email_fields = ('email_from', 'email_subject', 'email_body')
    email_from = SelectField(_('From'), [DataRequired()])
    email_subject = StringField(_("Email subject"), [DataRequired()])
    email_body = TextAreaField(_("Email body"), [DataRequired()],
                               widget=CKEditorWidget(simple=True))
    skip_moderation = BooleanField(
        _("Skip moderation"),
        widget=SwitchWidget(),
        description=
        _("If enabled, the user's registration will be approved automatically."
          ))

    def __init__(self, *args, **kwargs):
        self.regform = kwargs.pop('regform')
        event = self.regform.event_new
        super(InvitationFormBase, self).__init__(*args, **kwargs)
        if not self.regform.moderation_enabled:
            del self.skip_moderation
        self.email_from.choices = event.get_allowed_sender_emails().items()
        self.email_body.description = render_placeholder_info(
            'registration-invitation-email', invitation=None)

    def validate_email_body(self, field):
        missing = get_missing_placeholders('registration-invitation-email',
                                           field.data,
                                           invitation=None)
        if missing:
            raise ValidationError(
                _('Missing placeholders: {}').format(', '.join(missing)))
Beispiel #2
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()],
                               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
Beispiel #3
0
class SessionTypeForm(IndicoForm):
    """Form to create or edit a SessionType"""

    name = StringField(_("Name"), [DataRequired()])
    is_poster = BooleanField(
        _("Poster"),
        widget=SwitchWidget(),
        description=
        _("Whether the session is a poster session or contains normal presentations"
          ))
    code = StringField(_('Programme code'))

    def __init__(self, *args, **kwargs):
        self.event = kwargs.pop('event')
        self.session_type = kwargs.get('obj')
        super(SessionTypeForm, self).__init__(*args, **kwargs)

    def validate_name(self, field):
        query = SessionType.query.with_parent(self.event).filter(
            db.func.lower(SessionType.name) == field.data.lower())
        if self.session_type:
            query = query.filter(SessionType.id != self.session_type.id)
        if query.count():
            raise ValidationError(
                _("A session type with this name already exists"))
Beispiel #4
0
class BOASettingsForm(IndicoForm):
    """Settings form for the 'Book of Abstracts'."""

    extra_text = IndicoMarkdownField(_('Additional text'),
                                     editor=True,
                                     mathjax=True)
    extra_text_end = IndicoMarkdownField(_('Additional text at end'),
                                         editor=True,
                                         mathjax=True)
    sort_by = IndicoEnumSelectField(_('Sort by'), [DataRequired()],
                                    enum=BOASortField,
                                    sorted=True)
    corresponding_author = IndicoEnumSelectField(
        _('Corresponding author'), [DataRequired()],
        enum=BOACorrespondingAuthorType,
        sorted=True)
    show_abstract_ids = BooleanField(
        _('Show abstract IDs'),
        widget=SwitchWidget(),
        description=_("Show abstract IDs in the table of contents."))
    min_lines_per_abstract = IntegerField(
        _("Minimum lines per abstract"),
        description=_("Minimum lines to reserve per abstract."))
    link_format = IndicoEnumSelectField(_('Link formatting'), [DataRequired()],
                                        enum=BOALinkFormat,
                                        sorted=True)
Beispiel #5
0
class VCRoomForm(VCRoomFormBase, VidyoAdvancedFormMixin):
    """Contains all information concerning a Vidyo booking"""

    advanced_fields = {'show_pin', 'show_autojoin', 'show_phone_numbers'} | VCRoomFormBase.advanced_fields
    skip_fields = advanced_fields | VCRoomFormBase.conditional_fields

    description = TextAreaField(_('Description'), [DataRequired()], description=_('The description of the room'))
    owner_user = PrincipalField(_('Owner'), [DataRequired()], description=_('The owner of the room'))
    moderation_pin = IndicoPasswordField(_('Moderation PIN'), PIN_VALIDATORS, toggle=True,
                                         description=_('Used to moderate the VC Room. Only digits allowed.'))
    room_pin = IndicoPasswordField(_('Room PIN'), PIN_VALIDATORS, toggle=True,
                                   description=_('Used to protect the access to the VC Room (leave blank for open '
                                                 'access). Only digits allowed.'))
    auto_mute = BooleanField(_('Auto mute'),
                             widget=SwitchWidget(_('On'), _('Off')),
                             description=_('The VidyoDesktop clients will join the VC room muted by default '
                                           '(audio and video)'))

    def __init__(self, *args, **kwargs):
        defaults = kwargs['obj']
        if defaults.owner_user is None and defaults.owner is not None:
            defaults.owner_user = retrieve_principal(defaults.owner)
        super(VCRoomForm, self).__init__(*args, **kwargs)

    @generated_data
    def owner(self):
        return self.owner_user.data.as_principal

    def validate_owner_user(self, field):
        if not field.data:
            raise ValidationError(_("Unable to find this user in Indico."))
        if not next(iter_user_identities(field.data), None):
            raise ValidationError(_("This user does not have a suitable account to use Vidyo."))
Beispiel #6
0
class SessionForm(IndicoForm):
    title = StringField(_('Title'), [DataRequired()])
    code = StringField(
        _('Session code'),
        description=_('The code that will identify the session in the Book of '
                      'Abstracts.'))
    description = TextAreaField(_('Description'))
    default_contribution_duration = TimeDeltaField(
        _('Default contribution duration'),
        units=('minutes', 'hours'),
        description=_('Duration that a contribution created within this '
                      'session will have by default.'),
        default=timedelta(minutes=20))
    location_data = IndicoLocationField(
        _("Default location"),
        description=_("Default location for blocks inside the session."))
    colors = IndicoPalettePickerField(_('Colours'), color_list=get_colors())
    is_poster = BooleanField(
        _('Poster session'),
        widget=SwitchWidget(),
        description=
        _('Whether the session is a poster session or contains normal presentations.'
          ))

    def __init__(self, *args, **kwargs):
        event = kwargs.pop('event')
        super(SessionForm, self).__init__(*args, **kwargs)
        if event.type != 'conference':
            del self.is_poster
            del self.code
Beispiel #7
0
 def _add_form_fields(self, form_cls, **kwargs):
     exts = ', '.join(self.settings.get('valid_extensions'))
     return 'convert_to_pdf', \
            BooleanField(_("Convert to PDF"), widget=SwitchWidget(),
                         description=_("If enabled, your files will be be converted to PDF if possible. "
                                       "The following file types can be converted: {exts}").format(exts=exts),
                         default=True)
Beispiel #8
0
class ContributionTypeForm(IndicoForm):
    """Form to create or edit a ContributionType."""

    name = StringField(_("Name"), [DataRequired()])
    is_private = BooleanField(
        _("Private"),
        widget=SwitchWidget(),
        description=_(
            "If selected, this contribution type cannot be chosen by users "
            "submitting an abstract."))
    description = TextAreaField(_("Description"))

    def __init__(self, *args, **kwargs):
        self.event = kwargs.pop('event')
        self.contrib_type = kwargs.get('obj')
        super().__init__(*args, **kwargs)

    def validate_name(self, field):
        query = self.event.contribution_types.filter(
            db.func.lower(ContributionType.name) == field.data.lower())
        if self.contrib_type:
            query = query.filter(ContributionType.id != self.contrib_type.id)
        if query.count():
            raise ValidationError(
                _("A contribution type with this name already exists"))
Beispiel #9
0
class OutlookUserPreferences(ExtraUserPreferences):
    fields = {
        'outlook_active':
        BooleanField(
            _('Sync with Outlook'),
            widget=SwitchWidget(),
            description=_(
                'Add Indico events in which I participate to my Outlook '
                'calendar')),
        'outlook_status':
        SelectField(_('Outlook entry status'),
                    [HiddenUnless('extra_outlook_active', preserve_data=True)],
                    choices=_status_choices,
                    description=_('The status for Outlook Calendar entries'))
    }

    def load(self):
        default_status = OutlookPlugin.settings.get('status')
        return {
            'outlook_active':
            OutlookPlugin.user_settings.get(self.user, 'enabled'),
            'outlook_status':
            OutlookPlugin.user_settings.get(self.user, 'status',
                                            default_status)
        }

    def save(self, data):
        OutlookPlugin.user_settings.set_multi(self.user, {
            'enabled': data['outlook_active'],
            'status': data['outlook_status']
        })
Beispiel #10
0
class SectionForm(IndicoForm):
    display_as_section = BooleanField(_("Display as section"), widget=SwitchWidget(), default=True,
                                      description=_("Whether this is going to be displayed as a section or standalone"))
    title = StringField(_('Title'), [HiddenUnless('display_as_section', preserve_data=True), DataRequired()],
                        description=_("The title of the section."))
    description = TextAreaField(_('Description'), [HiddenUnless('display_as_section', preserve_data=True)],
                                description=_("The description text of the section."))
Beispiel #11
0
class SettingsForm(IndicoForm):
    bucket_info_enabled = BooleanField(_("Bucket info API"),
                                       widget=SwitchWidget())
    username = StringField(
        _("Username"), [
            HiddenUnless('bucket_info_enabled', preserve_data=True),
            DataRequired()
        ],
        description=_("The username to access the S3 bucket info endpoint"))
    password = IndicoPasswordField(
        _('Password'), [
            HiddenUnless('bucket_info_enabled', preserve_data=True),
            DataRequired()
        ],
        toggle=True,
        description=_("The password to access the S3 bucket info endpoint"))

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        url = Markup('<strong><code>{}</code></strong>').format(
            url_for_plugin('storage_s3.buckets'))
        self.bucket_info_enabled.description = _(
            "Enables an API on {url} that returns information on all S3 buckets "
            "currently in use, including dynamically-named ones.").format(
                url=url)
Beispiel #12
0
class TicketsForm(IndicoForm):
    tickets_enabled = BooleanField(
        _('Enable Tickets'),
        widget=SwitchWidget(),
        description=_(
            'Create tickets for registrations using this registration form.'))
    ticket_on_email = BooleanField(
        _('Send with an e-mail'),
        [HiddenUnless('tickets_enabled', preserve_data=True)],
        widget=SwitchWidget(),
        description=_(
            'Attach PDF ticket to the email sent to a user after completing '
            'their registration.'))
    ticket_on_event_page = BooleanField(
        _('Download from event homepage'),
        [HiddenUnless('tickets_enabled', preserve_data=True)],
        widget=SwitchWidget(),
        description=_('Allow users to download their ticket from the '
                      'conference homepage.'))
    ticket_on_summary_page = BooleanField(
        _('Download from summary page'),
        [HiddenUnless('tickets_enabled', preserve_data=True)],
        widget=SwitchWidget(),
        description=_(
            'Allow users to download their ticket from the registration '
            'summary page.'))

    ticket_template_id = SelectField(
        _('Ticket template'),
        [HiddenUnless('tickets_enabled', preserve_data=True),
         Optional()],
        coerce=int)

    def __init__(self, *args, **kwargs):
        event = kwargs.pop('event')
        super().__init__(*args, **kwargs)
        default_tpl = get_default_ticket_on_category(event.category)
        all_templates = set(
            event.designer_templates) | get_inherited_templates(event)
        badge_templates = [
            (tpl.id, tpl.title) for tpl in all_templates
            if tpl.type == TemplateType.badge and tpl != default_tpl
        ]
        # Show the default template first
        badge_templates.insert(0, (default_tpl.id, '{} ({})'.format(
            default_tpl.title, _('Default category template'))))
        self.ticket_template_id.choices = badge_templates
Beispiel #13
0
class PluginSettingsForm(PaymentPluginSettingsFormBase):
    """Configuration form for the Plugin across all events."""

    url = URLField(
        label=gettext('SixPay Saferpay URL'),
        validators=[DataRequired()],
        description=gettext('URL to contact the Six Payment Service'),
    )
    credentials_in_db = BooleanField(
        label=gettext("API credentials in Database"),
        widget=SwitchWidget(),
        description=gettext(
            'Note that the API password will be saved as plain text in the database.'
            'If not set, the credentials must be put into the .netrc file of the user running the Indico server.'
        ))
    username = StringField(label=gettext('Username'),
                           validators=[
                               HiddenUnless('credentials_in_db',
                                            preserve_data=False),
                               DataRequired()
                           ],
                           description=gettext('SaferPay JSON API User name.'))
    password = IndicoPasswordField(
        label=gettext('Password'),
        validators=[
            HiddenUnless('credentials_in_db', preserve_data=False),
            DataRequired()
        ],
        description=gettext('SaferPay JSON API User password.'),
        toggle=True,
    )
    account_id = StringField(
        label='Account ID',
        # can be set EITHER or BOTH globally and per event
        validators=[
            Optional(),
            Regexp(r'[0-9-]{0,15}',
                   message='Field must contain up to 15 digits or "-".')
        ],
        description=gettext('Default ID of your Saferpay account,'
                            ' such as "401860-17795278".'))
    order_description = StringField(
        label=gettext('Order Description'),
        validators=[DataRequired(), FormatField(max_length=80)],
        description=gettext(
            'The description of each order in a human readable way. '
            'This description is presented to the registrant during the '
            'transaction with SixPay.'))
    order_identifier = StringField(
        label=gettext('Order Identifier'),
        validators=[DataRequired(), FormatField(max_length=80)],
        description=gettext(
            'The identifier of each order for further processing.'))
    notification_mail = StringField(
        label=gettext('Notification Email'),
        validators=[Optional(), Email(), Length(0, 50)],
        description=gettext(
            'Mail address to receive notifications of transactions.'
            'This is independent of Indico\'s own payment notifications.'))
Beispiel #14
0
class RejectRegistrantsForm(IndicoForm):
    rejection_reason = TextAreaField(_('Reason'), description=_('You can provide a reason for the rejection here.'))
    attach_rejection_reason = BooleanField(_('Attach reason'), widget=SwitchWidget())
    registration_id = HiddenFieldList()
    submitted = HiddenField()

    def is_submitted(self):
        return super().is_submitted() and 'submitted' in request.form
Beispiel #15
0
class AbstractSubmissionSettingsForm(IndicoForm):
    """Settings form for abstract submission."""

    announcement = IndicoMarkdownField(_('Announcement'), editor=True)
    allow_multiple_tracks = BooleanField(_('Multiple tracks'), widget=SwitchWidget(),
                                         description=_('Allow the selection of multiple tracks'))
    tracks_required = BooleanField(_('Require tracks'), widget=SwitchWidget(),
                                   description=_('Make the track selection mandatory'))
    contrib_type_required = BooleanField(_('Require contrib. type'), widget=SwitchWidget(),
                                         description=_('Make the selection of a contribution type mandatory'))
    allow_attachments = BooleanField(_('Allow attachments'), widget=SwitchWidget(),
                                     description=_('Allow files to be attached to the abstract'))
    copy_attachments = BooleanField(_('Copy attachments'), [HiddenUnless('allow_attachments')], widget=SwitchWidget(),
                                    description=_('Copy attachments to the contribution when accepting an abstract'))
    allow_speakers = BooleanField(_('Allow speakers'), widget=SwitchWidget(),
                                  description=_('Allow the selection of the abstract speakers'))
    speakers_required = BooleanField(_('Require a speaker'), [HiddenUnless('allow_speakers')], widget=SwitchWidget(),
                                     description=_('Make the selection of at least one author as speaker mandatory'))
    allow_editing = IndicoEnumSelectField(_('Allow editing'), enum=AllowEditingType, sorted=True,
                                          description=_('Specify who will be able to edit the abstract'))
    contribution_submitters = IndicoEnumSelectField(_('Contribution submitters'),
                                                    enum=SubmissionRightsType, sorted=True,
                                                    description=_('Specify who will get contribution submission rights '
                                                                  'once an abstract has been accepted'))
    authorized_submitters = PrincipalListField(_('Authorized submitters'), event=lambda form: form.event,
                                               allow_external_users=True, allow_groups=True,
                                               allow_event_roles=True, allow_category_roles=True,
                                               description=_('These users may always submit abstracts, '
                                                             'even outside the regular submission period.'))
    submission_instructions = IndicoMarkdownField(_('Instructions'), editor=True,
                                                  description=_('These instructions will be displayed right before the '
                                                                'submission form'))

    @generated_data
    def announcement_render_mode(self):
        return RenderMode.markdown

    def __init__(self, *args, **kwargs):
        self.event = kwargs.pop('event')
        super().__init__(*args, **kwargs)
        if self.event and self.event.is_unlisted:
            self.authorized_submitters.allow_category_roles = False

    def validate_contrib_type_required(self, field):
        if field.data and not self.event.contribution_types.count():
            raise ValidationError(_('The event has no contribution types defined.'))
Beispiel #16
0
    class RegistrationFormWTF(IndicoForm):
        if management:
            notify_user = BooleanField(_('Send email'), widget=SwitchWidget())

        def validate_email(self, field):
            status = check_registration_email(regform, field.data, registration, management=management)
            if status['status'] == 'error':
                raise ValidationError('Email validation failed: ' + status['conflict'])
Beispiel #17
0
class EditEmailTemplateTextForm(IndicoForm):
    """Form for editing the text of a new e-mail template."""

    reply_to_address = SelectField(_('"Reply to" address'), [DataRequired()])
    include_submitter = BooleanField(_('Send to submitter'), widget=SwitchWidget())
    include_authors = BooleanField(_('Send to primary authors'), widget=SwitchWidget())
    include_coauthors = BooleanField(_('Send to co-authors'), widget=SwitchWidget())
    extra_cc_emails = EmailListField(_("CC"), description=_("Additional CC e-mail addresses (one per line)"))
    subject = StringField(_("Subject"), [DataRequired()])
    body = TextAreaField(_("Body"), [DataRequired()])

    def __init__(self, *args, **kwargs):
        self.event = kwargs.pop('event')
        super().__init__(*args, **kwargs)
        self.reply_to_address.choices = (list(self.event
                                         .get_allowed_sender_emails(extra=self.reply_to_address.object_data).items()))
        self.body.description = render_placeholder_info('abstract-notification-email', event=self.event)
Beispiel #18
0
class UserPreferencesForm(IndicoForm):
    lang = SelectField(_('Language'))
    timezone = SelectField(_('Timezone'))
    force_timezone = BooleanField(
        _('Use my timezone'),
        widget=SwitchWidget(),
        description=
        'Always use my current timezone instead of an event\'s timezone.')
    show_past_events = BooleanField(_('Show past events'),
                                    widget=SwitchWidget(),
                                    description='Show past events by default.')

    def __init__(self, *args, **kwargs):
        super(UserPreferencesForm, self).__init__(*args, **kwargs)
        self.lang.choices = sorted(get_all_locales().items(),
                                   key=itemgetter(1))
        self.timezone.choices = zip(all_timezones, all_timezones)
Beispiel #19
0
class FieldConfigForm(IndicoForm):
    # data that is stored directly on the question and not in data
    _common_fields = {'title', 'description', 'is_required'}

    title = StringField(_('Title'), [DataRequired()], description=_("The title of the question"))
    description = TextAreaField(_('Description'), description=_("The description (shown below the question's field.)"))
    is_required = BooleanField(_('Required'), widget=SwitchWidget(),
                               description=_("If the user has to answer the question."))
Beispiel #20
0
class RegistrationFormPersonalDataForm(AccessIdentityDataForm):
    request_cern_access = BooleanField(_('Request access to the CERN site'), widget=SwitchWidget())

    @classmethod
    def _add_fields_hidden_unless(cls):
        for field_name in ('birth_date', 'nationality', 'birth_place'):
            inject_validators(RegistrationFormPersonalDataForm, field_name,
                              [UsedIf(lambda form, field: form.request_cern_access.data)], early=True)
Beispiel #21
0
class BootstrapForm(LocalRegistrationForm):
    first_name = StringField('First Name', [DataRequired()])
    last_name = StringField('Last Name', [DataRequired()])
    email = EmailField(_('Email address'), [DataRequired()])
    affiliation = StringField('Affiliation', [DataRequired()])
    enable_tracking = BooleanField('Join the community', widget=SwitchWidget())
    contact_name = StringField('Contact Name', [UsedIfChecked('enable_tracking'), DataRequired()])
    contact_email = EmailField('Contact Email Address',  [UsedIfChecked('enable_tracking'), DataRequired(), Email()])
Beispiel #22
0
class BadgeSettingsForm(IndicoForm):
    template = SelectField(_('Template'))
    save_values = BooleanField(
        _("Save values for next time"),
        widget=SwitchWidget(),
        description=_("Save these values in the event settings"))
    dashed_border = BooleanField(
        _("Dashed border around each badge"),
        widget=SwitchWidget(),
        description=_("Display a dashed border around each badge"))
    page_size = IndicoEnumSelectField(_('Page size'), enum=PageSize)
    page_orientation = IndicoEnumSelectField(_('Page orientation'),
                                             enum=PageOrientation)
    page_layout = IndicoEnumSelectField(
        _('Page layout'),
        enum=PageLayout,
        description=_(
            'The single sided (foldable) option is only available if the '
            'template orientation is the same as the page orientation and '
            'its width is exactly half of the page width'))

    top_margin = FloatField(_('Top margin'), [InputRequired()])
    left_margin = FloatField(_('Left margin'), [InputRequired()])
    right_margin = FloatField(_('Right margin'), [InputRequired()])
    bottom_margin = FloatField(_('Bottom margin'), [InputRequired()])
    margin_columns = FloatField(_('Margin between columns'), [InputRequired()])
    margin_rows = FloatField(_('Margin between rows'), [InputRequired()])

    submitted = HiddenField()

    def __init__(self, event, **kwargs):
        all_templates = set(
            event.designer_templates) | get_inherited_templates(event)
        badge_templates = [
            tpl for tpl in all_templates if tpl.type.name == 'badge'
        ]
        tickets = kwargs.pop('tickets')
        super(BadgeSettingsForm, self).__init__(**kwargs)
        self.template.choices = sorted(
            ((unicode(tpl.id), tpl.title)
             for tpl in badge_templates if tpl.is_ticket == tickets),
            key=itemgetter(1))

    def is_submitted(self):
        return super(BadgeSettingsForm,
                     self).is_submitted() and 'submitted' in request.form
Beispiel #23
0
class CategoryProtectionForm(IndicoForm):
    _event_creation_fields = ('event_creation_restricted',
                              'event_creation_notification_emails')
    permissions = PermissionsField(_('Permissions'), object_type='category')
    protection_mode = IndicoProtectionField(
        _('Protection mode'),
        protected_object=lambda form: form.protected_object)
    own_no_access_contact = StringField(
        _('No access contact'),
        description=_(
            'Contact information shown when someone lacks access to the '
            'category'))
    visibility = SelectField(
        _('Event visibility'), [Optional()],
        coerce=lambda x: None if x == '' else int(x),
        description=
        _('''From which point in the category tree contents will be visible from '''
          '''(number of categories upwards). Applies to "Today's events" and '''
          '''Calendar. If the category is moved, this number will be preserved.'''
          ))
    event_creation_restricted = BooleanField(
        _('Restricted event creation'),
        widget=SwitchWidget(),
        description=_('Whether the event creation should be restricted '
                      'to a list of specific persons'))

    def __init__(self, *args, **kwargs):
        self.protected_object = self.category = kwargs.pop('category')
        super().__init__(*args, **kwargs)
        self._init_visibility()

    def _init_visibility(self):
        self.visibility.choices = get_visibility_options(self.category,
                                                         allow_invisible=False)
        # Check if category visibility would be affected by any of the parents
        real_horizon = self.category.real_visibility_horizon
        own_horizon = self.category.own_visibility_horizon
        if real_horizon and real_horizon.is_descendant_of(own_horizon):
            self.visibility.warning = _(
                "This category's visibility is currently limited by that of '{}'."
            ).format(real_horizon.title)

    def validate_permissions(self, field):
        for principal_fossil, permissions in field.data:
            principal = principal_from_identifier(
                principal_fossil['identifier'],
                allow_groups=True,
                allow_networks=True,
                allow_category_roles=True,
                category_id=self.category.id)
            if isinstance(principal, IPNetworkGroup
                          ) and set(permissions) - {READ_ACCESS_PERMISSION}:
                msg = _('IP networks cannot have management permissions: {}'
                        ).format(principal.name)
                raise ValidationError(msg)
            if FULL_ACCESS_PERMISSION in permissions and len(permissions) != 1:
                # when full access permission is set, discard rest of permissions
                permissions[:] = [FULL_ACCESS_PERMISSION]
Beispiel #24
0
class EventProtectionForm(IndicoForm):
    permissions = PermissionsField(_("Permissions"), object_type='event')
    protection_mode = IndicoProtectionField(_('Protection mode'),
                                            protected_object=lambda form: form.protected_object,
                                            acl_message_url=lambda form: url_for('event_management.acl_message',
                                                                                 form.protected_object))
    access_key = IndicoPasswordField(_('Access key'), toggle=True,
                                     description=_('It is more secure to use only the ACL and not set an access key. '
                                                   '<strong>It will have no effect if the event is not '
                                                   'protected</strong>'))
    own_no_access_contact = StringField(_('No access contact'),
                                        description=_('Contact information shown when someone lacks access to the '
                                                      'event'))
    visibility = SelectField(_("Visibility"), [Optional()], coerce=lambda x: None if x == '' else int(x),
                             description=_("""From which point in the category tree this event will be visible from """
                                           """(number of categories upwards). Applies to "Today's events", """
                                           """Calendar. If the event is moved, this number will be preserved. """
                                           """The "Invisible" option will also hide the event from the category's """
                                           """event list except for managers."""))
    public_regform_access = BooleanField(_('Public registration'), widget=SwitchWidget(),
                                         description=_('Allow users who cannot access the event to register. This will '
                                                       'expose open registration forms to anyone with a link to the '
                                                       'event, so you can let users register without giving access '
                                                       'to anything else in your event.'))
    priv_fields = set()

    def __init__(self, *args, **kwargs):
        self.protected_object = self.event = kwargs.pop('event')
        super().__init__(*args, **kwargs)
        self._init_visibility(self.event)

    def _get_event_own_visibility_horizon(self, event):
        if self.visibility.data is None:  # unlimited
            return Category.get_root()
        elif self.visibility.data == 0:  # invisible
            return None
        else:
            return event.category.nth_parent(self.visibility.data - 1)

    def _init_visibility(self, event):
        self.visibility.choices = get_visibility_options(event, allow_invisible=True)
        # Check if event visibility would be affected by any of the categories
        real_horizon = event.category.real_visibility_horizon
        own_horizon = self._get_event_own_visibility_horizon(event)
        if own_horizon and real_horizon and real_horizon.is_descendant_of(own_horizon):
            self.visibility.warning = _("This event's visibility is currently limited by that of '{}'.").format(
                real_horizon.title)

    def validate_permissions(self, field):
        except_msg = check_permissions(self.event, field, allow_networks=True, allow_registration_forms=True)
        if except_msg:
            raise ValidationError(except_msg)

    @classmethod
    def _create_coordinator_priv_fields(cls):
        for name, title in sorted(COORDINATOR_PRIV_TITLES.items(), key=itemgetter(1)):
            setattr(cls, name, BooleanField(title, widget=SwitchWidget(), description=COORDINATOR_PRIV_DESCS[name]))
            cls.priv_fields.add(name)
Beispiel #25
0
class AbstractReviewingSettingsForm(IndicoForm):
    """Settings form for abstract reviewing."""

    scale_lower = IntegerField(_('Scale (from)'), [InputRequired()])
    scale_upper = IntegerField(_('Scale (to)'), [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_convener_track_change = BooleanField(_('Allow conveners to change tracks'),
                                               [HiddenUnless('allow_convener_judgment',
                                                             value=False, preserve_data=True)],
                                               widget=SwitchWidget(),
                                               description=_('Enabling this allows track conveners to update the track '
                                                             'an abstract is part of.'))
    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.'))
    reviewing_instructions = IndicoMarkdownField(_('Reviewing Instructions'), editor=True,
                                                 description=_('These instructions will be displayed right before the '
                                                               'reviewing form.'))
    judgment_instructions = IndicoMarkdownField(_('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().__init__(*args, **kwargs)
        if self.has_ratings:
            self.scale_upper.warning = _('Changing the ratings scale will proportionally affect existing ratings.')

    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."))
Beispiel #26
0
class AttachmentFolderForm(IndicoForm):
    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)],
                                 allow_groups=True, allow_external_users=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"),
                                     [HiddenUnless('is_hidden', value=False)],
                                     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."))
    is_hidden = BooleanField(_("Always hidden"),
                             [HiddenUnless('is_always_visible', value=False)],
                             widget=SwitchWidget(),
                             description=_("Always hide the folder and its contents from public display areas of "
                                           "the event. You can use this for folders to store non-image files used "
                                           "e.g. in download links. The access permissions still apply."))

    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)

    def validate_is_always_visible(self, field):
        if self.is_always_visible.data and self.is_hidden.data:
            raise ValidationError('These two options cannot be used at the same time')

    validate_is_hidden = validate_is_always_visible

    @generated_data
    def protection_mode(self):
        return ProtectionMode.protected if self.protected.data else ProtectionMode.inheriting
Beispiel #27
0
class FieldConfigForm(IndicoForm):
    title = StringField(_('Title'), [DataRequired()],
                        description=_("The title of the field"))
    description = TextAreaField(_('Description'),
                                description=_("The description of the field"))
    is_required = BooleanField(
        _('Required'),
        widget=SwitchWidget(),
        description=_("Whether the user has to fill out the field"))
Beispiel #28
0
 def _create_coordinator_priv_fields(cls):
     for name, title in sorted(COORDINATOR_PRIV_TITLES.iteritems(),
                               key=itemgetter(1)):
         setattr(
             cls, name,
             BooleanField(title,
                          widget=SwitchWidget(),
                          description=COORDINATOR_PRIV_DESCS[name]))
         cls.priv_fields.add(name)
Beispiel #29
0
class DeadlineForm(IndicoForm):
    deadline = IndicoDateTimeField(_("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)
Beispiel #30
0
class TicketsForm(IndicoForm):
    tickets_enabled = BooleanField(_('Enable Tickets'), widget=SwitchWidget(),
                                   description=_('Create tickets for registrations using this registration form.'))
    ticket_on_email = BooleanField(_('Attach to registration e-mail'), [HiddenUnless('tickets_enabled',
                                                                                     preserve_data=True)],
                                   widget=SwitchWidget(),
                                   description=_('Attach PDF ticket to the email sent to a user after completing '
                                                 'their registration.'))
    ticket_on_event_page = BooleanField(_('Download from event homepage'), [HiddenUnless('tickets_enabled',
                                                                                         preserve_data=True)],
                                        widget=SwitchWidget(),
                                        description=_('Allow users to download their ticket from the '
                                                      'conference homepage.'))
    ticket_on_summary_page = BooleanField(_('Download from summary page'), [HiddenUnless('tickets_enabled',
                                                                                         preserve_data=True)],
                                          widget=SwitchWidget(),
                                          description=_('Allow users to download their ticket from the registration '
                                                        'summary page.'))