class LegalMessagesForm(IndicoForm): network_protected_disclaimer = TextAreaField(_("Network-protected information disclaimer"), widget=CKEditorWidget()) restricted_disclaimer = TextAreaField(_("Restricted information disclaimer"), widget=CKEditorWidget()) tos_url = URLField(_('URL'), [URL()], description=_("The URL to an external page with terms and conditions")) tos = TextAreaField(_("Text"), widget=CKEditorWidget(), description=_('Only used if no URL is provided')) privacy_policy_url = URLField(_('URL'), [URL()], description=_("The URL to an external page with the privacy policy")) privacy_policy = TextAreaField(_("Text"), widget=CKEditorWidget(), description=_('Only used if no URL is provided'))
class EmailEventPersonsForm(IndicoForm): from_address = SelectField(_('From'), [DataRequired()]) subject = StringField(_('Subject'), [DataRequired()]) body = TextAreaField(_('Email body'), [DataRequired()], widget=CKEditorWidget(simple=True, images=True)) recipients = IndicoEmailRecipientsField(_('Recipients')) copy_for_sender = BooleanField( _('Send copy to me'), widget=SwitchWidget(), description=_('Send copy of each email to my mailbox')) person_id = HiddenFieldList() user_id = HiddenFieldList() submitted = HiddenField() def __init__(self, *args, **kwargs): register_link = kwargs.pop('register_link') event = kwargs.pop('event') super(EmailEventPersonsForm, self).__init__(*args, **kwargs) self.from_address.choices = event.get_allowed_sender_emails().items() self.body.description = render_placeholder_info( 'event-persons-email', event=None, person=None, register_link=register_link) def is_submitted(self): return super(EmailEventPersonsForm, self).is_submitted() and 'submitted' in request.form
class InvitationForm(IndicoForm): from_address = SelectField(_('From'), [DataRequired()]) subject = StringField(_('Subject'), [DataRequired()]) body = TextAreaField(_('Email body'), [DataRequired()], widget=CKEditorWidget(simple=True)) recipients = EmailListField(_('Recipients'), [DataRequired()], description=_('One email address per line.')) copy_for_sender = BooleanField(_('Send copy to me'), widget=SwitchWidget()) submitted = HiddenField() def __init__(self, *args, **kwargs): event = kwargs.pop('event') super(InvitationForm, self).__init__(*args, **kwargs) self.from_address.choices = event.get_allowed_sender_emails().items() self.body.description = render_placeholder_info('survey-link-email', event=None, survey=None) def is_submitted(self): return super(InvitationForm, self).is_submitted() and 'submitted' in request.form def validate_body(self, field): missing = get_missing_placeholders('survey-link-email', field.data, event=None, survey=None) if missing: raise ValidationError( _('Missing placeholders: {}').format(', '.join(missing)))
class EventContactInfoForm(IndicoForm): _contact_fields = ('contact_title', 'contact_emails', 'contact_phones') contact_title = StringField(_('Title'), [DataRequired()]) contact_emails = MultiStringField(_('Emails'), field=('email', _('email')), unique=True, flat=True, sortable=True) contact_phones = MultiStringField(_('Phone numbers'), field=('phone', _('number')), unique=True, flat=True, sortable=True) organizer_info = TextAreaField(_('Organizers')) additional_info = TextAreaField( _('Additional information'), widget=CKEditorWidget(simple=True, images=True, height=250), description=_("This text is displayed on the main conference page.")) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(EventContactInfoForm, self).__init__(*args, **kwargs) if self.event.type_ != EventType.lecture: del self.organizer_info if self.event.type_ != EventType.conference: del self.additional_info def validate_contact_emails(self, field): for email in field.data: if not is_valid_mail(email, False): raise ValidationError( _('Invalid email address: {}').format(escape(email)))
class AgreementEmailForm(IndicoForm): from_address = SelectField(_("From"), [DataRequired()]) cc_addresses = EmailField( _("CC"), [Optional(), Email()], description=_( "Warning: this email address will be able to sign the agreement!")) body = TextAreaField(_("Email body"), widget=CKEditorWidget(simple=True)) def __init__(self, *args, **kwargs): self._definition = kwargs.pop('definition') event = kwargs.pop('event') super().__init__(*args, **kwargs) self.from_address.choices = list( event.get_allowed_sender_emails().items()) self.body.description = render_placeholder_info( 'agreement-email', definition=self._definition, agreement=None) def validate_body(self, field): missing = get_missing_placeholders('agreement-email', field.data, definition=self._definition, agreement=None) if missing: raise ValidationError( _('Missing placeholders: {}').format(', '.join(missing)))
class EmailEventPersonsForm(IndicoForm): from_address = SelectField(_('From'), [DataRequired()]) subject = StringField(_('Subject'), [DataRequired()]) body = TextAreaField(_('Email body'), [DataRequired()], widget=CKEditorWidget(simple=True)) recipients = IndicoEmailRecipientsField(_('Recipients')) copy_for_sender = BooleanField( _('Send copy to me'), widget=SwitchWidget(), description=_('Send copy of each email to my mailbox')) person_id = HiddenFieldList() user_id = HiddenFieldList() submitted = HiddenField() def __init__(self, *args, **kwargs): register_link = kwargs.pop('register_link') super(EmailEventPersonsForm, self).__init__(*args, **kwargs) from_addresses = [ '{} <{}>'.format(session.user.full_name, email) for email in sorted(session.user.all_emails, key=lambda x: x != session.user.email) ] self.from_address.choices = zip(from_addresses, from_addresses) self.body.description = render_placeholder_info( 'event-persons-email', event=None, person=None, register_link=register_link) def is_submitted(self): return super(EmailEventPersonsForm, self).is_submitted() and 'submitted' in request.form
class InvitationFormBase(IndicoForm): _invitation_fields = ('skip_moderation', ) _email_fields = ('email_from', 'email_body') email_from = SelectField(_('From'), [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') super(InvitationFormBase, self).__init__(*args, **kwargs) if not self.regform.moderation_enabled: del self.skip_moderation from_addresses = [ '{} <{}>'.format(session.user.full_name, email) for email in sorted(session.user.all_emails, key=lambda x: x != session.user.email) ] self.email_from.choices = zip(from_addresses, from_addresses) 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)))
class EmailRegistrantsForm(IndicoForm): from_address = SelectField(_("From"), [DataRequired()]) cc_addresses = EmailListField( _("CC"), description=_( "Beware, addresses in this field will receive one mail per " "registrant.")) subject = StringField(_("Subject"), [DataRequired()]) body = TextAreaField(_("Email body"), [DataRequired()], widget=CKEditorWidget(simple=True)) def __init__(self, *args, **kwargs): self.regform = kwargs.pop('regform') super(EmailRegistrantsForm, self).__init__(*args, **kwargs) from_addresses = [ '{} <{}>'.format(session.user.full_name, email) for email in sorted(session.user.all_emails, key=lambda x: x != session.user.email) ] self.from_address.choices = zip(from_addresses, from_addresses) self.body.description = render_placeholder_info('registration-email', regform=self.regform, registration=None) def validate_body(self, field): missing = get_missing_placeholders('registration-email', field.data, regform=self.regform, registration=None) if missing: raise ValidationError( _('Missing placeholders: {}').format(', '.join(missing)))
class AgreementEmailForm(IndicoForm): from_address = SelectField(_("From"), [DataRequired()]) cc_addresses = EmailField( _("CC"), description=_( "Warning: this email address will be able to sign the agreement!")) body = TextAreaField(_("Email body"), widget=CKEditorWidget(simple=True)) def __init__(self, *args, **kwargs): self._definition = kwargs.pop('definition') super(AgreementEmailForm, self).__init__(*args, **kwargs) from_addresses = [ '{} <{}>'.format(session.user.full_name, email) for email in sorted(session.user.all_emails, key=lambda x: x != session.user.email) ] self.from_address.choices = zip(from_addresses, from_addresses) self.body.description = render_placeholder_info( 'agreement-email', definition=self._definition, agreement=None) def validate_body(self, field): missing = get_missing_placeholders('agreement-email', field.data, definition=self._definition, agreement=None) if missing: raise ValidationError( _('Missing placeholders: {}').format(', '.join(missing)))
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 super().__init__(*args, **kwargs) if not self.regform.moderation_enabled: del self.skip_moderation self.email_from.choices = list( 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)))
class EmailRegistrantsForm(IndicoForm): from_address = SelectField(_("From"), [DataRequired()]) cc_addresses = EmailListField(_("CC"), description=_("Beware, addresses in this field will receive one mail per " "registrant.")) subject = StringField(_("Subject"), [DataRequired()]) body = TextAreaField(_("Email body"), [DataRequired()], widget=CKEditorWidget(simple=True)) recipients = IndicoEmailRecipientsField(_('Recipients')) copy_for_sender = BooleanField(_('Send copy to me'), widget=SwitchWidget(), description=_('Send copy of each email to my mailbox')) attach_ticket = BooleanField(_('Attach ticket'), widget=SwitchWidget(), description=_('Attach tickets to emails')) registration_id = HiddenFieldList() submitted = HiddenField() def __init__(self, *args, **kwargs): self.regform = kwargs.pop('regform') event = self.regform.event super(EmailRegistrantsForm, self).__init__(*args, **kwargs) self.from_address.choices = event.get_allowed_sender_emails().items() self.body.description = render_placeholder_info('registration-email', regform=self.regform, registration=None) def validate_body(self, field): missing = get_missing_placeholders('registration-email', field.data, regform=self.regform, registration=None) if missing: raise ValidationError(_('Missing placeholders: {}').format(', '.join(missing))) def is_submitted(self): return super(EmailRegistrantsForm, self).is_submitted() and 'submitted' in request.form
class LectureCreationForm(EventCreationFormBase): _field_order = ('title', 'occurrences', 'timezone', 'location_data', 'person_link_data', 'protection_mode') _advanced_field_order = ('description', 'theme') occurrences = OccurrencesField(_("Dates"), [DataRequired()], default_time=time(8), default_duration=timedelta(minutes=90)) person_link_data = EventPersonLinkListField(_('Speakers')) description = TextAreaField(_('Description'), widget=CKEditorWidget()) theme = IndicoThemeSelectField(_('Theme'), event_type=EventType.lecture, allow_default=True)
class EventSponsorsForm(IndicoForm): sponsors_info = TextAreaField( _('Sponsors information'), widget=CKEditorWidget(simple=True, images=True, height=250), description= _("This text is displayed on the lower section of left menu. <br />Keep the images width under 200 pixels in order to properly fit in." )) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(EventSponsorsForm, self).__init__(*args, **kwargs)
class PluginSettingsForm(VCPluginSettingsFormBase): support_email = EmailField(_('Zoom email support')) api_key = StringField(_('API KEY'), [DataRequired()]) api_secret = StringField(_('API SECRET'), [DataRequired()]) auto_mute = BooleanField( _('Auto mute'), widget=SwitchWidget(_('On'), _('Off')), description=_( 'The Zoom clients will join the VC room muted by default ')) host_video = BooleanField( _('Host Video'), widget=SwitchWidget(_('On'), _('Off')), description=_('Start video when the host joins the meeting.')) participant_video = BooleanField( _('Participant Video'), widget=SwitchWidget(_('On'), _('Off')), description=_('Start video when participants join the meeting. ')) join_before_host = BooleanField( _('Join Before Host'), widget=SwitchWidget(_('On'), _('Off')), description= _('Allow participants to join the meeting before the host starts the meeting. Only used for scheduled or recurring meetings.' )) #indico_room_prefix = IntegerField(_('Indico tenant prefix'), [NumberRange(min=0)], # description=_('The tenant prefix for Indico rooms created on this server')) #room_group_name = StringField(_("Public rooms' group name"), [DataRequired()], # description=_('Group name for public videoconference rooms created by Indico')) num_days_old = IntegerField( _('VC room age threshold'), [NumberRange(min=1), DataRequired()], description=_( 'Number of days after an Indico event when a videoconference room is ' 'considered old')) max_rooms_warning = IntegerField( _('Max. num. VC rooms before warning'), [NumberRange(min=1), DataRequired()], description=_( 'Maximum number of rooms until a warning is sent to the managers')) zoom_phone_link = URLField( _('ZoomVoice phone number'), description=_('Link to the list of ZoomVoice phone numbers')) creation_email_footer = TextAreaField( _('Creation email footer'), widget=CKEditorWidget(), description=_( 'Footer to append to emails sent upon creation of a VC room'))
class SettingsForm(IndicoForm): admins = PrincipalListField( _('Administrators'), groups=True, description=_( 'List of users/groups who can manage chatrooms for all events')) server = StringField(_('XMPP server'), [DataRequired()], description=_('The hostname of the XMPP server')) muc_server = StringField( _('XMPP MUC server'), [DataRequired()], description=_("The hostname of the XMPP MUC server")) bot_jid = StringField( _('Bot JID'), [DataRequired()], description=_( "Jabber ID of the XMPP bot. Can be just a username (in that case the default " "server is assumed) or a username@server.")) bot_password = IndicoPasswordField(_('Bot Password'), [DataRequired()], toggle=True, description=_("Password for the bot")) notify_emails = EmailListField( _('Notification emails'), description=_( "Email addresses to sent notifications to (one per line)")) log_url = URLField( _('Log URL'), description=_( 'You can set this to the URL of the ' '<a href="https://github.com/indico/jabber-logs/">jabber-logs ' 'app</a>, running on the jabber server to let event managers can ' 'retrieve chat logs for rooms on that server.')) chat_links = MultipleItemsField( _('Chatroom links'), fields=[{ 'id': 'title', 'caption': _("Title"), 'required': True }, { 'id': 'link', 'caption': _("Link"), 'required': True }], description=_( "Links to join the chatroom. You can use the placeholders {room} for " "the room name and {server} for the MUC server.")) how_to_connect = TextAreaField( _('How to connect'), widget=CKEditorWidget(), description=_("Text shown below the chatrooms on an event page")) def validate_chat_links(self, field): for item in field.data: if not all(item.values()): raise ValidationError(_('All fields must contain a value.'))
class EmailEventPersonsForm(IndicoForm): from_address = SelectField(_('From'), [DataRequired()]) subject = StringField(_('Subject'), [DataRequired()]) body = TextAreaField(_('Email body'), [DataRequired()], widget=CKEditorWidget(simple=True)) recipients = IndicoStaticTextField(_('Recipients')) person_id = HiddenFieldList(validators=[DataRequired()]) submitted = HiddenField() def __init__(self, *args, **kwargs): super(EmailEventPersonsForm, self).__init__(*args, **kwargs) from_addresses = ['{} <{}>'.format(session.user.full_name, email) for email in sorted(session.user.all_emails, key=lambda x: x != session.user.email)] self.from_address.choices = zip(from_addresses, from_addresses) def is_submitted(self): return super(EmailEventPersonsForm, self).is_submitted() and 'submitted' in request.form
class EventDataForm(IndicoForm): title = StringField(_('Event title'), [DataRequired()]) description = TextAreaField(_('Description'), widget=CKEditorWidget(simple=True, images=True, height=250)) url_shortcut = StringField(_('URL shortcut'), filters=[lambda x: (x or None)]) def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super(EventDataForm, self).__init__(*args, **kwargs) # TODO: Add a custom widget showing the prefix right before the field prefix = '{}/e/'.format(config.BASE_URL) self.url_shortcut.description = _( '<strong>{}SHORTCUT</strong> - the URL shortcut must be unique within ' 'this Indico instance and is not case sensitive.').format(prefix) def validate_url_shortcut(self, field): shortcut = field.data if not shortcut: return if shortcut.isdigit(): raise ValidationError( _("The URL shortcut must contain at least one character that is not a digit." )) if not re.match(r'^[a-zA-Z0-9/._-]+$', shortcut): raise ValidationError( _("The URL shortcut contains an invalid character.")) if '//' in shortcut: raise ValidationError( _("The URL shortcut may not contain two consecutive slashes.")) if shortcut[0] == '/' or shortcut[-1] == '/': raise ValidationError( _("The URL shortcut may not begin/end with a slash.")) conflict = (Event.query.filter( db.func.lower(Event.url_shortcut) == shortcut.lower(), ~Event.is_deleted, Event.id != self.event.id).has_rows()) if conflict: raise ValidationError( _("The URL shortcut is already used in another event.")) if LegacyEventMapping.query.filter_by( legacy_event_id=shortcut).has_rows(): # Reject existing event ids. It'd be EXTREMELY confusing and broken to allow such a shorturl # Non-legacy event IDs are already covered by the `isdigit` check above. raise ValidationError( _("This URL shortcut is not available.") % shortcut)
class PluginSettingsForm(VCPluginSettingsFormBase): support_email = EmailField(_('Bluejeans email support')) username = StringField(_('Username'), [DataRequired()], description=_('Indico username for Bluejeans')) password = IndicoPasswordField( _('Password'), [DataRequired()], toggle=True, description=_('Indico password for Bluejeans')) admin_api_wsdl = URLField(_('Admin API WSDL URL'), [DataRequired()]) user_api_wsdl = URLField(_('User API WSDL URL'), [DataRequired()]) indico_room_prefix = IntegerField( _('Indico tenant prefix'), [NumberRange(min=0)], description=_( 'The tenant prefix for Indico rooms created on this server')) room_group_name = StringField( _("Public rooms' group name"), [DataRequired()], description=_( 'Group name for public videoconference rooms created by Indico')) authenticators = StringField( _('Authenticators'), [DataRequired()], description=_( 'Identity providers to convert Indico users to Bluejeans accounts') ) num_days_old = IntegerField( _('VC room age threshold'), [NumberRange(min=1), DataRequired()], description=_( 'Number of days after an Indico event when a videoconference room is ' 'considered old')) max_rooms_warning = IntegerField( _('Max. num. VC rooms before warning'), [NumberRange(min=1), DataRequired()], description=_( 'Maximum number of rooms until a warning is sent to the managers')) bluejeans_phone_link = URLField( _('BluejeansVoice phone number'), description=_('Link to the list of BluejeansVoice phone numbers')) client_chooser_url = URLField( _('Client Chooser URL'), description=_( "URL for client chooser interface. The room key will be passed as a " "'url' GET query argument")) creation_email_footer = TextAreaField( _('Creation email footer'), widget=CKEditorWidget(), description=_( 'Footer to append to emails sent upon creation of a VC room'))
class EventPrivacyForm(IndicoForm): _data_controller_fields = ('data_controller_name', 'data_controller_email') _privacy_policy_fields = ('privacy_policy_urls', 'privacy_policy') data_controller_name = StringField(_('Person/Institution')) data_controller_email = EmailField(_('Contact email'), [Optional(), Email()]) privacy_policy_urls = IndicoLinkListField( _('External page'), description=_('List of URLs to external pages containing privacy ' 'notices.')) privacy_policy = TextAreaField( _('Text'), widget=CKEditorWidget(), description=_('Only used if no URL is provided')) def validate_privacy_policy(self, field): if self.privacy_policy_urls.data and self.privacy_policy.data: raise ValidationError( _('Define either a privacy notice text or URLs'))
class AgreementEmailForm(IndicoForm): from_address = SelectField(_("From"), [DataRequired()]) cc_addresses = EmailField(_("CC"), description=_("Warning: this email address will be able to sign the agreement!")) body = TextAreaField(_("Email body"), widget=CKEditorWidget(simple=True)) def __init__(self, *args, **kwargs): self._definition = kwargs.pop('definition') super(AgreementEmailForm, self).__init__(*args, **kwargs) name = session.avatar.getStraightFullName() from_addresses = ['{} <{}>'.format(name, email) for email in session.avatar.getEmails()] self.from_address.choices = zip(from_addresses, from_addresses) placeholders = self._definition.get_email_placeholders() self.body.description = render_template('events/agreements/dialogs/placeholder_info.html', placeholders=placeholders) def validate_body(self, field): placeholders = {'{{{}}}'.format(name) for name, placeholder in self._definition.get_email_placeholders().iteritems() if placeholder.required} missing = {p for p in placeholders if p not in field.data} if missing: raise ValidationError(_('Missing placeholders: {}').format(', '.join(missing)))
class LegalMessagesForm(IndicoForm): network_protected_disclaimer = TextAreaField( _("Network-protected information disclaimer"), widget=CKEditorWidget()) restricted_disclaimer = TextAreaField( _("Restricted information disclaimer"), widget=CKEditorWidget()) tos = TextAreaField(_("Terms and conditions"), widget=CKEditorWidget())
class NoteForm(IndicoForm): # TODO: use something switchable source = TextAreaField(_("Minutes"), widget=CKEditorWidget())
class MenuPageForm(MenuUserEntryFormBase): html = TextAreaField(_('Content'), [DataRequired()], widget=CKEditorWidget())
class PluginSettingsForm(VCPluginSettingsFormBase): _fieldsets = [ (_('API Credentials'), ['api_key', 'api_secret', 'webhook_token']), (_('Zoom Account'), [ 'user_lookup_mode', 'email_domains', 'authenticators', 'enterprise_domain', 'allow_webinars' ]), (_('Room Settings'), [ 'mute_audio', 'mute_host_video', 'mute_participant_video', 'join_before_host', 'waiting_room' ]), (_('Notifications'), ['creation_email_footer', 'send_host_url', 'notification_emails']), (_('Access'), ['managers', 'acl']) ] api_key = StringField(_('API Key'), [DataRequired()]) api_secret = IndicoPasswordField(_('API Secret'), [DataRequired()], toggle=True) webhook_token = IndicoPasswordField( _('Webhook Token'), toggle=True, description=_("Specify Zoom's webhook token if you want live updates")) user_lookup_mode = IndicoEnumSelectField( _('User lookup mode'), [DataRequired()], enum=UserLookupMode, description=_('Specify how Indico should look up the zoom user that ' 'corresponds to an Indico user.')) email_domains = TextListField( _('E-mail domains'), [ HiddenUnless('user_lookup_mode', UserLookupMode.email_domains), DataRequired() ], description= _('List of e-mail domains which can use the Zoom API. Indico attempts ' 'to find Zoom accounts using all email addresses of a user which use ' 'those domains.')) authenticators = TextListField( _('Indico identity providers'), [ HiddenUnless('user_lookup_mode', UserLookupMode.authenticators), DataRequired() ], description= _('Identity providers from which to get usernames. ' 'Indico queries those providers using the email addresses of the user ' 'and attempts to find Zoom accounts having an email address with the ' 'format username@enterprise-domain.')) enterprise_domain = StringField( _('Enterprise domain'), [ HiddenUnless('user_lookup_mode', UserLookupMode.authenticators), DataRequired() ], description=_( 'The domain name used together with the usernames from the Indico ' 'identity provider')) allow_webinars = BooleanField( _('Allow Webinars (Experimental)'), widget=SwitchWidget(), description=_( 'Allow webinars to be created through Indico. Use at your own risk.' )) 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')) join_before_host = BooleanField( _('Join Before Host'), widget=SwitchWidget(), description=_( 'Allow participants to join the meeting before the host starts the ' 'meeting. Only used for scheduled or recurring meetings.')) waiting_room = BooleanField( _('Waiting room'), widget=SwitchWidget(), description=_( 'Participants may be kept in a waiting room by the host')) creation_email_footer = TextAreaField( _('Creation email footer'), widget=CKEditorWidget(), description=_( 'Footer to append to emails sent upon creation of a VC room')) send_host_url = BooleanField( _('Send host URL'), widget=SwitchWidget(), description=_( 'Whether to send an e-mail with the Host URL to the meeting host upon ' 'creation of a meeting')) def validate_authenticators(self, field): invalid = set(field.data) - set(multipass.identity_providers) if invalid: raise ValidationError( _('Invalid identity providers: {}').format( escape(', '.join(invalid))))
class NewsForm(IndicoForm): title = StringField(_('Title'), [DataRequired()]) content = TextAreaField(_('Content'), [DataRequired()], widget=CKEditorWidget())