class MetadataSchema(colander.MappingSchema): """Metadata sheet data structure. `creation_date`: Creation date of this resource. defaults to now. `item_creation_date`: Equals creation date for ISimple/IPool, equals the item creation date for :class:`adhocracy_core.interfaces.IItemVersion`. This exists to ease the frontend end development. This may go away if we have a high level API to make :class:`adhocracy_core.interfaces.Item` / `IItemVersion` one `thing`. Defaults to now. `creator`: creator (user resource) of this resource. `modified_by`: the last person (user resources) who modified a resource, initially the creator `modification_date`: Modification date of this resource. defaults to now. `deleted`: whether the resource is marked as deleted (only shown to those that specifically ask for it) `hidden`: whether the resource is marked as hidden (only shown to those that have special permissions and ask for it) """ creator = Reference(reftype=MetadataCreatorsReference, readonly=True) creation_date = DateTime(missing=colander.drop, readonly=True) item_creation_date = DateTime(missing=colander.drop, readonly=True) modified_by = Reference(reftype=MetadataModifiedByReference, readonly=True) modification_date = DateTime(missing=colander.drop, readonly=True) deleted = Boolean() hidden = Boolean(validator=deferred_validate_hidden)
class HeardFromSchema(colander.MappingSchema): heard_from_colleague = Boolean() heard_from_website = Boolean() heard_from_newsletter = Boolean() heard_from_facebook = Boolean() # There is no heard_from_elsewhere Boolean, since that automatically # follows iff heard_elsewhere is not empty heard_elsewhere = Text()
class LocationSchema(colander.MappingSchema): """Data structure for for proposal location.""" location_is_specific = Boolean() location_specific_1 = SingleLine() location_specific_2 = SingleLine() location_specific_3 = SingleLine() location_is_online = Boolean() location_is_linked_to_ruhr = Boolean()
class WorkflowMeta(MappingSchema): """Data structure to define a workflow (finite state machine).""" initial_state = SingleLine(missing=drop) defaults = SingleLine(missing=drop) add_local_role_participant_to_default_group = Boolean(missing=drop, default=False) auto_transition = Boolean(missing=drop) states = SchemaNode(MappingType(unknown='preserve'), missing=drop) transitions = SchemaNode(MappingType(unknown='preserve'), missing=drop)
class AnonymizeDefaultSchema(MappingSchema): """Data structure for user default anonymize setting. `anonymize`: Boolean setting for anonymization default . """ anonymize = Boolean()
class LocationSchema(MappingSchema): location = SingleLine() is_online = Boolean() has_link_to_ruhr = Boolean(missing=required, default=False) link_to_ruhr = Text() def validator(self, node, value): """Extra validation depending on the status of the location. Make `link_to_ruhr` required if `has_link_to_ruhr` == `True`. """ has_link_to_ruhr = value.get('has_link_to_ruhr', None) if has_link_to_ruhr: if not value.get('link_to_ruhr', None): link_to_ruhr = node['link_to_ruhr'] raise Invalid(link_to_ruhr, msg='Required iff has_link_to_ruhr == True')
class FinanceSchema(MappingSchema): """Data structure for financial aspects.""" budget = CurrencyAmount(missing=required) requested_funding = CurrencyAmount(missing=required, validator=Range(min=0, max=50000)) other_sources = SingleLine() granted = Boolean()
class NotificationSchema(MappingSchema): """Notification sheet data structure. `follow_resources`: Follow activities these resources are involved in. """ follow_resources = UniqueReferences(reftype=NotificationFollowReference, choices_getter=get_follow_choices) email_notification_enabled = Boolean(default=True, missing=drop)
class ProposalSchema(MappingSchema): """Data structure for organizational information.""" # TODO: check exact length restrictions budget = CurrencyAmount(missing=required, validator=Range(min=0, max=50000)) creator_participate = Boolean() location_text = SingleLine(validator=Length(max=100))
class PartnersSchema(MappingSchema): has_partners = Boolean() partner1_name = SingleLine() partner1_website = URL() partner1_country = ISOCountryCode() partner2_name = SingleLine() partner2_website = URL() partner2_country = ISOCountryCode() partner3_name = SingleLine() partner3_website = URL() partner3_country = ISOCountryCode() other_partners = Text()
class FieldComparableBoolean(FieldComparableBase): """Tuple with values FieldComparable and Boolean.""" value = Boolean()
def inst(self): from adhocracy_core.schema import Boolean return Boolean()
def create_arbitrary_filter_node(index, example_value, query): return Boolean()
class GETPoolRequestSchema(MappingSchema): """GET parameters accepted for pool queries.""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Raise if unknown to tell client the query parameters are wrong. self.typ.unknown = 'raise' # TODO For now we don't have a way to specify GET parameters that can # be repeated, e.g. 'sheet=Blah&sheet=Blub'. The querystring is converted # by Cornice into a MultiDict (http://docs.pylonsproject.org/projects # /pyramid/en/master/api/interfaces.html#pyramid.interfaces.IMultiDict), # which by default will only return the LAST value if a key is specified # several times. One possible workaround is to allow specifying multiple # values as a comma-separated list instead of repeated key=value pairs, # e.g. 'sheet=Blah,Blub'. This would require a custom Multiple SchemaNode # that wraps a SchemaType, e.g. # sheet = Multiple(Interface(), missing=None, sep=',') # Elements in this schema were multiple values should be allowed: # sheet, aggregateby, tag. depth = PoolQueryDepth() elements = PoolElementsForm(missing=drop) count = Boolean(missing=drop) sort = SingleLine(missing=drop, validator=deferred_validate_sort) reverse = Boolean(missing=drop) # TODO: validate limit, offset to be multiple of 10, 20, 50, 100, 200, 500 limit = Integer(missing=drop) offset = Integer(missing=drop) aggregateby = SingleLine(missing=drop, validator=deferred_validate_aggregateby) def deserialize(self, cstruct=null): # noqa """Deserialize the :term:`cstruct` into an :term:`appstruct`. Adapt key/values to :class:`adhocracy_core.interfaces.SearchQuery`. for BBB. TODO: Change API according to internal SearchQuery api. refactor to follow coding guideline better. """ depth_cstruct = cstruct.get('depth', None) if depth_cstruct == 'all': cstruct['depth'] = 100 appstruct = super().deserialize(cstruct) search_query = {} if appstruct: # pragma: no branch search_query['root'] = self.bindings['context'] if 'depth' in appstruct: # pragma: no branch depth = appstruct['depth'] if depth == 100: depth = None search_query['depth'] = depth if 'elements' in appstruct: elements = appstruct.get('elements') search_query['serialization_form'] = elements if elements == 'omit': search_query['resolve'] = False interfaces = () if 'sheet' in appstruct: interfaces = appstruct['sheet'] if interfaces: search_query['interfaces'] = interfaces if 'aggregateby' in appstruct: search_query['frequency_of'] = appstruct['aggregateby'] search_query['show_frequency'] = True if 'sort' in appstruct: search_query['sort_by'] = appstruct['sort'] if 'limit' in appstruct: search_query['limit'] = appstruct['limit'] if 'offset' in appstruct: search_query['offset'] = appstruct['offset'] if 'reverse' in appstruct: search_query['reverse'] = appstruct['reverse'] if 'count' in appstruct: search_query['show_count'] = appstruct['count'] fields = tuple([x.name for x in GETPoolRequestSchema().children]) fields += ('sheet', ) for filter, query in appstruct.items(): if filter in fields + SearchQuery._fields: continue if ':' in filter: if 'references' not in search_query: # pragma: no branch search_query['references'] = [] isheet_name, isheet_field = filter.split(':') isheet = resolver.resolve(isheet_name) target = appstruct[filter] reference = ReferenceTuple(None, isheet, isheet_field, target) search_query['references'].append(reference) else: if 'indexes' not in search_query: search_query['indexes'] = {} if filter == 'content_type': search_query['indexes']['interfaces'] = appstruct[ 'content_type'] continue search_query['indexes'][filter] = query return search_query
class ServiceKontoSettingsSchema(MappingSchema): """Data structure for public ServiceKonto user information.""" enabled = Boolean()
class KeywordComparableBoolean(KeywordComparableBase): """Tuple with values KeywordComparable and Boolean.""" value = Boolean()
class ExtraFundingSchema(MappingSchema): other_sources = Text(missing='') secured = Boolean(default=False)