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 ExplanationGroupsSchema(Schema): groups = colander.SchemaNode( colander.Sequence(), omit( ExplanationGroupSchema(name='Amendment', widget=DragDropMappingWidget()), ['_csrf_token_']), widget=groups_widget, title=_('Group your improvements into amendments')) single_amendment = colander.SchemaNode( colander.Boolean(), widget=deform.widget.CheckboxWidget( css_class="single-amendment-control"), label=_('Group the improvements into a single amendment'), title='', missing=False) justification = colander.SchemaNode( colander.String(), widget=LimitedTextAreaWidget( limit=350, item_css_class="justification-amendment hide-bloc", placeholder=_("Justification")), missing="", title=_("Justification"))
class ExplanationGroupSchema(Schema): title = colander.SchemaNode(colander.String(), missing="", widget=TextInputWidget( css_class="title-select-item", item_css_class="col-md-4", readonly=True)) explanations = colander.SchemaNode( colander.Set(), widget=explanations_choice, missing=[], default=[], title=_('Improvements'), ) justification = colander.SchemaNode( colander.String(), widget=LimitedTextAreaWidget(limit=350, css_class="justification-select-item", item_css_class="col-md-4", placeholder=_("Justification")), missing="", title=_("Justification"))
class SubmitSchema(Schema): justification = colander.SchemaNode(colander.String(), validator=colander.Length(max=600), widget=LimitedTextAreaWidget( rows=5, cols=30, limit=600), title=_("Justification"))
class ArchiveProposalSchema(Schema): explanation = colander.SchemaNode(colander.String(), validator=colander.Length(max=300), widget=LimitedTextAreaWidget(rows=5, cols=30, limit=300), title=_("Explanation"))
class ProposalSchema(VisualisableElementSchema, SearchableEntitySchema): """Schema for Proposal""" name = NameSchemaNode( editing=context_is_a_proposal, ) challenge = colander.SchemaNode( ObjectType(), widget=challenge_choice, missing=None, title=_("Challenge (optional)"), description=_("You can select and/or modify the challenge associated to this proposal. " "For an open proposal, do not select anything in the « Challenge » field.") ) description = colander.SchemaNode( colander.String(), validator=colander.Length(max=600), widget=LimitedTextAreaWidget(rows=5, cols=30, limit=600), title=_("Abstract") ) text = colander.SchemaNode( colander.String(), widget=RichTextWidget(), title=_("Text") ) related_ideas = colander.SchemaNode( colander.Set(), widget=ideas_choice, title=_('Related ideas'), validator=Length(_, min=1), default=[], ) add_files = omit(AddFilesSchemaSchema( widget=SimpleMappingtWidget( mapping_css_class='controled-form' ' object-well default-well hide-bloc', ajax=True, activator_icon="glyphicon glyphicon-file", activator_title=_('Add files'))), ["_csrf_token_"]) 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 OpinionSchema(Schema): opinion = colander.SchemaNode(colander.String(), widget=opinion_choice, title=_('Opinion'), default='to_study') explanation = colander.SchemaNode(colander.String(), validator=colander.Length(max=600), widget=LimitedTextAreaWidget(rows=5, cols=30, limit=600), title=_("Explanation"))
class IntentionItemSchema(Schema): """Schema for Intention item""" comment = colander.SchemaNode( colander.String(), title=_('Give a specific explanation'), validator=colander.Length(max=300), widget=LimitedTextAreaWidget(rows=5, cols=30, limit=300), ) related_ideas = colander.SchemaNode( colander.Set(), widget=relatedideas_choice, title=_('Related ideas'), description=_('Choose related ideas.'), missing=[], default=[], )
class CorrectionSchema(VisualisableElementSchema): """Schema for correction of a proposal""" name = NameSchemaNode( editing=context_is_a_correction, ) description = colander.SchemaNode( colander.String(), validator=colander.Length(max=600), widget=LimitedTextAreaWidget(rows=5, cols=30, limit=600), title=_("Abstract") ) text = colander.SchemaNode( colander.String(), widget=RichTextWidget(), title=_("Text") )
class ReportSchema(VisualisableElementSchema): """Schema for working group""" name = NameSchemaNode( editing=context_is_a_report, ) reporting_reasons = colander.SchemaNode( colander.Set(), widget=reporting_reasons_choice, title=_("Reporting reasons") ) details = colander.SchemaNode( colander.String(), validator=colander.Length(max=1200), widget=LimitedTextAreaWidget(rows=5, cols=30, limit=1200), title=_("Details"), missing='' )
class AmendmentSchema(VisualisableElementSchema, SearchableEntitySchema): """Schema for Amendment""" name = NameSchemaNode(editing=context_is_a_amendment, ) description = colander.SchemaNode(colander.String(), validator=colander.Length(max=300), widget=LimitedTextAreaWidget(rows=5, cols=30, limit=300), title=_("Abstract")) text = colander.SchemaNode(colander.String(), widget=RichTextWidget(), title=_("Text")) add_files = omit( AddFilesSchemaSchema(widget=SimpleMappingtWidget( mapping_css_class='controled-form' ' object-well default-well hide-bloc', ajax=True, activator_icon="glyphicon glyphicon-file", activator_title=_('Add files'))), ["_csrf_token_"])
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 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 )