class UserInterfaceConfigurationSchema(Schema): picture = colander.SchemaNode( ObjectData(File), widget=get_file_widget(file_extensions=['png', 'jpg', 'svg']), title=_('Logo'), missing=None, description=_("Only PNG and SVG files are supported."), ) favicon = colander.SchemaNode( ObjectData(File), widget=get_file_widget(file_extensions=['ico']), title=_('Favicon'), missing=None, description=_("Only ICO files are supported."), ) theme = colander.SchemaNode( ObjectData(File), widget=get_file_widget(file_extensions=['css']), title=_('Theme'), missing=None, description=_("Only CSS files are supported."), ) social_share = colander.SchemaNode( colander.Boolean(), widget=deform.widget.CheckboxWidget(), label=_('Activate the sharing on social networks'), title='', missing=False )
class NewsletterWorkingParamConf(Schema): """Schema for newsletter conf""" automatic_registration = colander.SchemaNode( colander.Boolean(), widget=deform.widget.CheckboxWidget(), label=_('Automatic subscription'), description=_('Automatic subscription at user registration'), title='', missing=True) propose_to_registration = colander.SchemaNode( colander.Boolean(), widget=deform.widget.CheckboxWidget(), label=_('Propose for subscription'), description=_('Allow users to subscribe manually'), title='', missing=True) allow_unsubscribing = colander.SchemaNode( colander.Boolean(), widget=deform.widget.CheckboxWidget(), label=_('Allow unsubscription'), description=_('Allow users to unsubscribe'), title='', missing=True) content_template = colander.SchemaNode( ObjectDataOrigine(File), widget=get_file_widget(file_extensions=['html']), title=_('Content template'), missing=None, description=_("Only HTML files are supported."), )
class OrganizationSchema(VisualisableElementSchema): """Schema for Organization""" name = NameSchemaNode(editing=context_is_a_organization, ) logo = colander.SchemaNode( ObjectData(Image), widget=get_file_widget(), required=False, missing=None, title=_('Logo'), ) cover_picture = colander.SchemaNode( ObjectData(File), widget=get_file_widget(file_extensions=['png', 'jpg', 'svg']), title=_('Cover picture'), missing=None, description=_("Only PNG and SVG files are supported."), ) contacts = colander.SchemaNode( colander.Sequence(), omit( select( ContactSchema( name='contact', widget=SimpleMappingWidget( css_class='contact-well object-well default-well')), [ 'title', 'address', 'phone', 'surtax', 'email', 'website', 'fax' ]), ['_csrf_token_']), widget=SequenceWidget( min_len=1, add_subitem_text_template=_('Add a new contact')), title='Contacts', oid='contacts') members = colander.SchemaNode(colander.Set(), widget=members_choice, title=_('Members'), missing=[]) managers = colander.SchemaNode(colander.Set(), widget=managers_choice, title=_('The managers'), missing=[])
class IdeaSchema(VisualisableElementSchema, SearchableEntitySchema): """Schema for idea""" name = NameSchemaNode(editing=context_is_a_idea, ) challenge = colander.SchemaNode( ObjectType(), widget=challenge_choice, missing=None, title=_("Challenge (optional)"), description= _("You can select and/or modify the challenge associated to this idea. " "For an open idea, do not select anything in the « Challenge » field." )) text = colander.SchemaNode( colander.String(), widget=LimitedTextAreaWidget( rows=5, cols=30, limit=2000, alert_template='novaideo:views/templates/idea_text_alert.pt', alert_values={'limit': 2000}, item_css_class='content-preview-form', placeholder=_('I have an idea!')), title=_("Text")) note = colander.SchemaNode(colander.String(), widget=LimitedTextAreaWidget( rows=3, cols=30, limit=300, alert_values={'limit': 300}), title=_("Note"), missing="") attached_files = colander.SchemaNode( colander.Sequence(), colander.SchemaNode(ObjectData(File), name=_("File"), widget=get_file_widget()), widget=FilesWidget(add_subitem_text_template='', item_css_class='files-block'), missing=[], title=_('Attached files'), ) anonymous = colander.SchemaNode( colander.Boolean(), widget=anonymous_widget, label=_('Remain anonymous'), description=_('Check this box if you want to remain anonymous.'), title='', missing=False, default=False)
class WebAdvertisingSchema(AdvertisingSchema): """Schema for Web advertising""" name = NameSchemaNode( editing=context_is_a_webadvertising, ) picture = colander.SchemaNode( ObjectData(File), widget=get_file_widget( item_css_class="advertising-file-content", css_class="file-content", file_type=['image', 'flash']), title=_('Announcement file'), description=_("Only image and flash files are supported."), missing=None ) html_content = colander.SchemaNode( colander.String(), widget=RichTextWidget(item_css_class="advertising-html-content", css_class="html-content-text"), title=_("Or HTML content"), missing="" ) advertisting_url = colander.SchemaNode( colander.String(), title=_('URL'), missing="#" ) positions = colander.SchemaNode( colander.Set(), widget=advertisting_widget, title=_('Positions') ) @invariant def content_invariant(self, appstruct): if not(appstruct['html_content'] or appstruct['picture']): raise colander.Invalid(self, _ ('Content must be defined.')) @invariant def banner_invariant(self, appstruct): positions = appstruct['positions'] if positions: for position in positions: ADVERTISING_CONTAINERS[position]['validator']( self.get('picture'), appstruct)
class HomepageConfigurationSchema(Schema): homepage_picture = colander.SchemaNode( ObjectData(File), widget=get_file_widget(file_extensions=['png', 'jpg', 'svg']), title=_('Picture of the homepage'), missing=None, description=_("Only PNG and SVG files are supported."), ) homepage_text = colander.SchemaNode(colander.String(), widget=RichTextWidget(), title=_("Text"), missing='')
class WorkspaceSchema(VisualisableElementSchema): """Schema for working group""" name = NameSchemaNode(editing=context_is_a_workspace, ) files = colander.SchemaNode( colander.Sequence(), colander.SchemaNode(ObjectData(File), name=_("File"), widget=get_file_widget()), widget=FilesWidget(add_subitem_text_template=_('Attach file'), item_css_class='files-block'), missing=[], title=_('Attached files'), )
class CommentSchema(VisualisableElementSchema): """Schema for comment""" name = NameSchemaNode(editing=context_is_a_comment, ) intention = colander.SchemaNode(colander.String(), widget=intention_choice, title=_('Intention'), description=_('Choose your intention'), default=_('Remark')) associated_contents = colander.SchemaNode( colander.Set(), widget=relatedcontents_choice, title=_('Associated contents'), description=_('Choose contents to associate'), missing=[], default=[], ) files = colander.SchemaNode( colander.Sequence(), colander.SchemaNode(ObjectData(File), name=_("File"), widget=get_file_widget()), widget=FilesWidget( add_subitem_text_template='', item_css_class="files-block comment-form-group comment-files"), missing=[], description=_('Add files to your comment'), title=_('Attached files'), ) comment = colander.SchemaNode(colander.String(), validator=colander.Length(max=2000), widget=comment_textarea, title=_("Message")) anonymous = colander.SchemaNode( colander.Boolean(), widget=deform.widget.CheckboxWidget( item_css_class="comment-form-group comment-anonymous-form"), label=_('Remain anonymous'), description=_('Check this box if you want to remain anonymous.'), title='', missing=False, default=False)
class AddFilesSchemaSchema(Schema): """Schema for interview""" ws_files = colander.SchemaNode( colander.Set(), widget=files_choice, missing=[], title=_("Connect to the files of the workspace")) attached_files = colander.SchemaNode( colander.Sequence(), colander.SchemaNode(ObjectData(File), name=_("File"), widget=get_file_widget()), widget=FilesWidget(add_subitem_text_template=_('Upload a new file'), item_css_class='files-block'), missing=[], title=_('Upload new files'), )
class ChallengeSchema(VisualisableElementSchema, SearchableEntitySchema): """Schema for challenge""" name = NameSchemaNode(editing=context_is_a_challenge, ) description = colander.SchemaNode( colander.String(), validator=colander.Length(max=300), widget=LimitedTextAreaWidget(rows=5, cols=30, limit=300), title=_("Abstract"), description=_("Describe in a few words the challenge.")) text = colander.SchemaNode( colander.String(), widget=RichTextWidget(), title=_("Text"), description=_("You can describe in detail the challenge.")) image = colander.SchemaNode( ObjectData(Image), widget=image_widget, title=_('Image'), description= _('You see a square on the top left of the image if it exceeds the maximum' ' size allowed. Move and enlarge it if necessary, to determine an area of' ' interest. Several images will be generated from this area.'), ) attached_files = colander.SchemaNode( colander.Sequence(), colander.SchemaNode(ObjectData(File), name=_("File"), widget=get_file_widget()), widget=FilesWidget(add_subitem_text_template='', item_css_class='files-block'), missing=[], title=_('Attached files'), ) is_restricted = colander.SchemaNode( colander.Boolean(), widget=deform.widget.CheckboxWidget( item_css_class='is-restricted-input'), label=_('Is restricted'), title='', description= _('Check this box if the challenge is restricted to a set of members. ' 'Only concerned members can add and see the contents created in this challenge.' ), missing=False) invited_users = colander.SchemaNode( colander.Set(), widget=users_to_invite, title=_('Concerned users'), description=_( 'Find and select the concerned members or organizations. ' 'If you want to see the members or organizations... already ' 'registered on the platform, enter a *'), missing=[], ) deadline = colander.SchemaNode( colander.Date(), title=_('Deadline'), description= _("If your challenge is punctual, you can add a deadline for participation." ), missing=None) anonymous = colander.SchemaNode( colander.Boolean(), widget=anonymous_widget, label=_('Remain anonymous'), description=_('Check this box if you want to remain anonymous.'), title='', missing=False, default=False)
class PersonSchema(VisualisableElementSchema, UserSchema, SearchableEntitySchema): """Schema for Person""" name = NameSchemaNode(editing=context_is_a_person, ) function = colander.SchemaNode(colander.String(), widget=deform.widget.TextInputWidget(), title=_('Function'), missing='') description = colander.SchemaNode(colander.String(), widget=LimitedTextAreaWidget( rows=5, cols=30, limit=1200, alert_values={'limit': 1200}), title=_("Description"), missing="") tree = colander.SchemaNode( typ=DictSchemaType(), widget=keyword_widget, default=DEFAULT_TREE, missing=DEFAULT_TREE, title=_('Topics of interest'), description= _('Indicate keywords. You can specify a second keyword level for each keyword chosen.' )) email = colander.SchemaNode(colander.String(), validator=colander.All( colander.Email(), email_validator, colander.Length(max=100)), title=_('Login (email)')) picture = colander.SchemaNode( ObjectData(Image), widget=picture_widget, title=_('Picture'), description= _('You see a square on the top left of the image if it exceeds the maximum' ' size allowed. Move and enlarge it if necessary, to determine an area of' ' interest. Several images will be generated from this area.'), required=False, missing=None, ) cover_picture = colander.SchemaNode( ObjectData(File), widget=get_file_widget(file_extensions=['png', 'jpg', 'svg']), title=_('Cover picture'), missing=None, description=_("Only PNG and SVG files are supported."), ) first_name = colander.SchemaNode( colander.String(), title=_('Given name(s)'), description= _("Given name(s), as it(they) appear(s) on your official identity documents" )) last_name = colander.SchemaNode( colander.String(), title=_('Family name(s)'), description= _("Family name(s), as it(they) appear(s) on your official identity documents" )) birth_date = colander.SchemaNode(colander.Date(), title=_('Date of birth')) citizenship = colander.SchemaNode( colander.String(), widget=citizenship_choice, title=_('Citizenship'), description= _('What is the Member State of the European Union of which you are a citizen? Only citizens of the European Union can be members of the CosmoPolitical Cooperative.' ), ) birthplace = colander.SchemaNode( colander.String(), title=_('Place of birth'), description=_( "Place of birth (city or municipality + country if relevant), " "as it appears on your official identity documents")) user_title = colander.SchemaNode( colander.String(), widget=titles_choice, title=_('Title', context='user'), description= _('Please do not select anything if you do not want to communicate this information.' ), missing='') locale = colander.SchemaNode( colander.String(), title=_('Locale'), widget=locale_widget, missing=locale_missing, validator=colander.OneOf(AVAILABLE_LANGUAGES), ) password = colander.SchemaNode( colander.String(), widget=deform.widget.CheckedPasswordWidget(), validator=colander.Length(min=3, max=100), title=_("Password")) organization = colander.SchemaNode( ObjectType(), widget=organization_choice, missing=None, title=_('Organization'), ) pseudonym = colander.SchemaNode( colander.String(), widget=deform.widget.TextInputWidget(item_css_class='pseudonym-input'), validator=colander.All(pseudonym_validator, ), title=_('Pseudonym'), description= _("Please choose the pseudonym that will identify you for the whole duration of your " "activity on the platform. We STRONGLY recommend that you select a pseudonym that makes " "tracking back to your real identity impossible (or extremely difficult). Thereby, you " "protect the confidentiality of your political opinions (i.e. personal data that are the " "purpose of a specific protection under the General Data Protection Regulation - GDPR) " "against any form of external pressure in real life (e.g. by your employer or your customers). " "Be very careful! Once you have chosen it, you will NEVER be able to change this pseudonym afterwards. " "Choose it with care!"), ) accept_conditions = colander.SchemaNode( colander.Boolean(), widget=conditions_widget, label=_('I have read and accept the terms and conditions of use'), title='', missing=False) @invariant def user_invariant(self, appstruct): context = self.bindings['context'] first_name = appstruct.get('first_name', None) last_name = appstruct.get('last_name', None) birth_date = appstruct.get('birth_date', None) birthplace = appstruct.get('birthplace', None) if first_name and last_name and birth_date and birthplace: try: birth_date = colander.iso8601.parse_date(birth_date) birth_date = birth_date.date() except colander.iso8601.ParseError as e: return key = first_name + last_name + birthplace + birth_date.strftime( "%d/%m/%Y") key = normalize_title(key).replace(' ', '') novaideo_catalog = find_catalog('novaideo') identifier_index = novaideo_catalog['identifier'] query = identifier_index.any([key]) users = list(query.execute().all()) if context in users: users.remove(context) if users: raise colander.Invalid(self, _('User already exists'))
class WorkParamsConfigurationSchema(Schema): """Schema for site configuration.""" content_to_manage = colander.SchemaNode( colander.Set(), widget=content_manage_choices, title=_('Contents to be managed with the ideas'), description=_('Content that can be created by members. Ideas are included by default.'), default=DEFAULT_CONTENT_TO_MANAGE, missing=DEFAULT_CONTENT_TO_MANAGE ) content_to_moderate = colander.SchemaNode( colander.Set(), widget=content_types_choices, title=_('Contents to be moderated'), description=_('Contents can be moderated.'), missing=[] ) content_to_support = colander.SchemaNode( colander.Set(), widget=content_types_choices, title=_('Contents to be supported'), description=_('Contents can be supported by users.'), missing=[] ) content_to_examine = colander.SchemaNode( colander.Set(), widget=content_types_choices, title=_('Contents to be examined'), description=_('Contents must be examined by a review committee.'), missing=[] ) proposal_template = colander.SchemaNode( ObjectData(File), widget=get_file_widget(file_extensions=['html']), title=_('Proposal template'), missing=None, description=_("Only HTML files are supported."), ) work_modes = colander.SchemaNode( colander.Set(), title=_('Work modes'), description=_('Work modes of the working group (for proposals).'), widget=modes_choice, default=[], ) nonproductive_cycle_nb = colander.SchemaNode( colander.Integer(), validator=colander.Range(1, 10), title=_('Number of non-productive cycles'), description=_('The number of non-productive improvement cycles before the closure of the working group.'), default=3, ) can_submit_directly = colander.SchemaNode( colander.Boolean(), widget=deform.widget.CheckboxWidget(), label=_('Allow direct submission of proposal'), description=_('Members can submit directly the proposal.'), title='', missing=False )
class SmartFolderSchema(VisualisableElementSchema): """Schema for keyword""" name = NameSchemaNode(editing=context_is_a_smartfolder, ) title = colander.SchemaNode( colander.String(), widget=TextInputWidget(css_class="smartfolder-title-field"), title=_('Title'), ) description = colander.SchemaNode( colander.String(), widget=deform.widget.TextAreaWidget(rows=4, cols=60), title=_("Description"), ) locale = colander.SchemaNode( colander.String(), title=_('Locale'), description=_('The language for which the folder will be displayed'), widget=locale_widget, missing='') cover_picture = colander.SchemaNode( ObjectData(File), widget=get_file_widget(file_extensions=['png', 'jpg', 'svg']), title=_('Cover picture'), missing=None, description=_("Only PNG and SVG files are supported."), ) filters = colander.SchemaNode( colander.Sequence(), omit( select( FilterSchema(name='filter', title=_('Filter'), widget=SimpleMappingWidget( css_class='object-well default-well')), [ 'metadata_filter', 'temporal_filter', 'contribution_filter', 'text_filter', 'other_filter' ]), ["_csrf_token_"]), widget=SequenceWidget(add_subitem_text_template=_('Add a new filter')), title=_('Filters'), description=_('Applied filters'), missing=[]) contents = colander.SchemaNode( colander.Set(), widget=relatedcontents_choice, title=_('Associated contents'), description=_('Choose the contents to be associated'), missing=[], default=[], ) view_type = colander.SchemaNode(colander.String(), widget=view_type_widget, title=_("View type"), description=_('How to display contents'), default='default') icon_data = colander.SchemaNode(DictSchemaType(), widget=BootstrapIconInputWidget(), title=_('Icon'), default={ 'icon': 'glyphicon-folder-open', 'icon_class': 'glyphicon' }, description=_('Select an icon.')) style = omit(CssSchema(widget=SimpleMappingWidget()), ["_csrf_token_"]) @invariant def contact_invariant(self, appstruct): contents = appstruct.get('contents', []) filters = appstruct.get('filters', []) if not contents and not filters: raise colander.Invalid( self, _('Filters or associated contents must be specified.'))
class QuestionSchema(VisualisableElementSchema, SearchableEntitySchema): """Schema for question""" name = NameSchemaNode( editing=context_is_a_question, ) challenge = colander.SchemaNode( ObjectType(), widget=challenge_choice, missing=None, title=_("Challenge (optional)"), description=_("You can select and/or modify the challenge associated to this question. " "For an open question, do not select anything in the « Challenge » field.") ) title = colander.SchemaNode( colander.String(), title=_("Question") ) options = colander.SchemaNode( colander.Sequence(), colander.SchemaNode( colander.String(), name=_("Option") ), widget=SequenceWidget( add_subitem_text_template='', orderable=True), title=_('Options'), description=_("You can add options to your question. " "Users can only answer questions with options once. " "Statistics will be provided indicating the percentage " "of each option."), missing=[] ) text = colander.SchemaNode( colander.String(), widget=LimitedTextAreaWidget( rows=5, cols=30, limit=2000, alert_values={'limit': 2000}, item_css_class='content-preview-form', placeholder=_('I have a question!')), title=_("Details"), missing='' ) attached_files = colander.SchemaNode( colander.Sequence(), colander.SchemaNode( ObjectData(File), name=_("File"), widget=get_file_widget() ), widget=FilesWidget( add_subitem_text_template='', item_css_class='files-block'), missing=[], title=_('Attached files'), ) anonymous = colander.SchemaNode( colander.Boolean(), widget=anonymous_widget, label=_('Remain anonymous'), description=_('Check this box if you want to remain anonymous.'), title='', missing=False, default=False )