Esempio n. 1
0
class MetadataSchemaBaseV1(StrictKeysMixin):
    """Schema for the record metadata."""

    id = PersistentIdentifier()
    identifiers = Nested(IdentifierSchemaV1, many=True, required=True)
    name = SanitizedUnicode(required=True, validate=validate.Length(min=3))
    status = SanitizedUnicode()
    aliases = fields.List(SanitizedUnicode(), many=True)
    acronyms = fields.List(SanitizedUnicode(), many=True)
    types = fields.List(SanitizedUnicode(), many=True)
    wikipedia_url = fields.Url()
    email_address = fields.Email()
    ip_addresses = fields.List(SanitizedUnicode(), many=True)
    established = fields.Integer()
    onei_registry = fields.Integer()
    exportable = fields.Bool()
    links = fields.List(fields.Url(), many=True)
    labels = Nested(LabelSchemaV1, many=True)
    relationships = Nested(RelationSchemaV1, many=True)
    addresses = Nested(AddressSchemaV1, many=True)
    redirect = IdentifierSchemaV1()

    _schema = GenFunction(
        attribute="$schema",
        data_key="$schema",
        deserialize=schema_from_context,  # to be added only when loading
    )
class _TestSchemaNested(Schema):
    """Test schema with custom Nested field."""

    nested_field = Nested(NestedSchema,
                          attribute='metadata.nested',
                          many=True,
                          required=True)
    non_list = Nested(_TestSchema)
Esempio n. 3
0
class MetadataFullSchemaV1(MetadataSchemaBaseV1):
    """Schema for the record metadata."""
    source_repo = Nested(SourceSchemaV1)
    contributors = Nested(ContributorSchemaV1, many=True)

    @post_dump(pass_many=False)
    def full_source(self, record, **kwargs):
        source_uuid = record['source_repo']['uuid']
        source = SourceRecord.get_record(source_uuid)
        record['source_repo'] = source
        return record
Esempio n. 4
0
class MetadataSchemaV1(StrictKeysMixin):
    """Schema for the record metadata."""

    id = PersistentIdentifier()
    title = SanitizedUnicode()
    resource_type = SanitizedUnicode()
    docset = fields.Nested(DocsetSchemaV1, many=False)
    publications = fields.Nested(PublicationchemaV1, many=True)
    datasets = fields.Nested(DatasetSchemaV1, many=True)
    tools = Nested(ToolSchemaV1, many=True)
    outputs = Nested(OutputSchemaV1, many=True)
    virtenvs = Nested(VirtenvSchemaV1, many=True)
    contributors = Nested(ContributorSchemaV1, many=True)
Esempio n. 5
0
class RelatedIdentifierSchemaV1(BaseSchema):
    """Related identifier schema."""

    RELATIONS = [
        "IsCitedBy", "Cites", "IsSupplementTo", "IsSupplementedBy",
        "IsContinuedBy", "Continues", "IsDescribedBy", "Describes",
        "HasMetadata", "IsMetadataFor", "HasVersion", "IsVersionOf",
        "IsNewVersionOf", "IsPreviousVersionOf", "IsPartOf", "HasPart",
        "IsReferencedBy", "References", "IsDocumentedBy", "Documents",
        "IsCompiledBy", "Compiles", "IsVariantFormOf", "IsOriginalFormOf",
        "IsIdenticalTo", "IsReviewedBy", "Reviews", "IsDerivedFrom",
        "IsSourceOf", "IsRequiredBy", "Requires", "IsObsoletedBy", "Obsoletes"
    ]

    SCHEMES = [
        "ARK", "arXiv", "bibcode", "DOI", "EAN13", "EISSN", "Handle", "IGSN",
        "ISBN", "ISSN", "ISTC", "LISSN", "LSID", "PMID", "PURL", "UPC", "URL",
        "URN", "w3id"
    ]

    identifier = SanitizedUnicode(required=True)
    scheme = SanitizedUnicode(
        required=True,
        validate=validate.OneOf(choices=SCHEMES,
                                error=_('Invalid related identifier scheme. ' +
                                        '{input} not one of {choices}.')))
    relation_type = SanitizedUnicode(
        required=True,
        validate=validate.OneOf(
            choices=RELATIONS,
            error=_('Invalid relation type. {input} not one of {choices}.')))
    resource_type = Nested(ResourceTypeSchemaV1)
class MetadataSchemaV1(StrictKeysMixin):
    """Schema for the record metadata."""

    {{ cookiecutter.datamodel_pid_name }} = PersistentIdentifier()
    title = SanitizedUnicode(required=True, validate=validate.Length(min=3))
    keywords = fields.List(SanitizedUnicode(), many=True)
    publication_date = DateString()
    contributors = Nested(ContributorSchemaV1, many=True, required=True)
Esempio n. 7
0
class MetadataSchemaV1(SchemaEnforcingMixin, StrictKeysMixin):
    """Schema for the record metadata."""

    control_number = PersistentIdentifier()
    title = SanitizedUnicode(required=True, validate=validate.Length(min=3))
    keywords = fields.List(SanitizedUnicode(), many=True)
    publication_date = DateString()
    contributors = Nested(ContributorSchemaV1, many=True, required=True)
Esempio n. 8
0
class AuthorMetadataSchemaV1(StrictKeysMixin):
    """Schema for the author metadata."""
    _oai = Nested(OaiSchemaV1)
    id = PersistentIdentifier()
    name = SanitizedUnicode(required=True)
    organization = SanitizedUnicode(required=False)

    class Meta:
        unknown = INCLUDE
Esempio n. 9
0
class BibliographicRecordSchemaV1(BaseSchema):
    """Record schema."""

    metadata = Nested(MetadataSchemaV1)
    bucket = fields.Str()
    created = fields.Str(dump_only=True)
    revision = fields.Integer(dump_only=True)
    updated = fields.Str(dump_only=True)
    links = fields.Dict(dump_only=True)
    id = PersistentIdentifier(attribute='pid.pid_value')
Esempio n. 10
0
class RecordSchemaV1(BaseSchema):
    """Record schema."""

    # TODO: Use `RecordMetadataSchemaJSONV1` to inject PID in PUT/PATCH/...
    metadata = Nested(MetadataSchemaV1)
    bucket = fields.Str()
    created = fields.Str(dump_only=True)
    revision = fields.Integer(dump_only=True)
    updated = fields.Str(dump_only=True)
    links = fields.Dict(dump_only=True)
    id = PersistentIdentifier(attribute='pid.pid_value')
Esempio n. 11
0
class MetadataSchemaV1(StrictKeysMixin):
    """Schema for the record metadata."""
    def get_id(self, obj):
        """Get record id."""
        pid = self.context.get('pid')
        return pid.pid_value if pid else missing

    id = PersistentIdentifier()
    title = SanitizedUnicode(required=True, validate=validate.Length(min=3))
    keywords = fields.Nested(fields.Str(), many=True)
    publication_date = DateString()
    contributors = Nested(ContributorSchemaV1, many=True, required=True)
    testOption = fields.Integer()
Esempio n. 12
0
class MetadataSchemaV1(StrictKeysMixin):
    """Schema for the record metadata."""

    id = PersistentIdentifier()
    title = SanitizedUnicode(required=True, validate=validate.Length(min=3))
    keywords = fields.List(SanitizedUnicode(), many=True)
    publication_date = DateString()
    contributors = Nested(ContributorSchemaV1, many=True, required=True)
    _schema = GenFunction(
        attribute="$schema",
        data_key="$schema",
        deserialize=schema_from_context,  # to be added only when loading
    )
Esempio n. 13
0
class MetadataSchemaV1(StrictKeysMixin):
    """Schema for the record metadata."""

    id = PersistentIdentifier()
    title = SanitizedUnicode(required=True, validate=validate.Length(min=3))
    keywords = fields.List(SanitizedUnicode(), many=True)
    publication_date = DateString()
    contributors = Nested(ContributorSchemaV1, many=True, required=True)
    educationLevel = SanitizedUnicode(required=True)
    subject = SanitizedUnicode(required=True)
    coverage = SanitizedUnicode(required=True)
    description = SanitizedUnicode(required=True)
    revisioned = fields.Boolean(required=True)
    license = SanitizedUnicode(required=True)
Esempio n. 14
0
class MetadataSchemaV1(StrictKeysMixin):
    """Schema for the record metadata."""

    id = PersistentIdentifier()
    title = SanitizedUnicode()
    creator = SanitizedUnicode()
    fileName = SanitizedUnicode()
    fileType = SanitizedUnicode()
    owner = fields.Integer()
    metadata = Nested(MetaDataSchemaX)
    keywords = fields.List(SanitizedUnicode(), many=True)
    publication_date = DateString()
    contributors = Nested(ContributorSchemaV1, many=True)
    doi = fields.Str()
    _schema = GenFunction(
        attribute="$schema",
        data_key="$schema",
        deserialize=schema_from_context,  # to be added only when loading
    )
    _oai = Nested(OaiSchemaV1)

    class Meta:
        unknown = INCLUDE
Esempio n. 15
0
class CreatorSchemaV1(BaseSchema):
    """Creator schema."""

    NAMES = ["Organizational", "Personal"]

    # TODO: Need to revisit `name` in Deposit form:
    #       current mock-up doesn't have `name` field, so there is assumed
    #       work on the front-end to fill this value.
    name = SanitizedUnicode(required=True)
    type = SanitizedUnicode(
        required=True,
        validate=validate.OneOf(
            choices=NAMES,
            error=_('Invalid name type. {input} not one of {choices}.')))
    given_name = SanitizedUnicode()
    family_name = SanitizedUnicode()
    identifiers = fields.Dict()
    affiliations = fields.List(Nested(AffiliationSchemaV1))

    @validates("identifiers")
    def validate_identifiers(self, value):
        """Validate well-formed identifiers are passed."""
        if any(key not in ['Orcid', 'ror'] for key in value.keys()):
            raise ValidationError(_("Invalid identifier."))

        if 'Orcid' in value:
            if not idutils.is_orcid(value.get('Orcid')):
                raise ValidationError(_("Invalid identifier."))

        if 'ror' in value:
            if not idutils.is_ror(value.get('ror')):
                raise ValidationError(_("Invalid identifier."))

    @validates_schema
    def validate_data(self, data, **kwargs):
        """Validate identifier based on type."""
        if data['type'] == "Personal":
            person_identifiers = ['Orcid']
            identifiers = data.get('identifiers', {}).keys()
            if any([ident not in person_identifiers for ident in identifiers]):
                raise ValidationError(_("Invalid identifier for a person."))
        elif data['type'] == "Organizational":
            org_identifiers = ['ror']
            identifiers = data.get('identifiers', {}).keys()
            if any([ident not in org_identifiers for ident in identifiers]):
                raise ValidationError(
                    _("Invalid identifier for an organization."))
Esempio n. 16
0
class RelationSchemaWithIDsV1(StrictKeysMixin):
    """Ids schema."""

    id = SanitizedUnicode()
    identifiers = Nested(IdentifierSchemaV1, many=True, required=True)
    type = SanitizedUnicode()
    label = SanitizedUnicode()

    @post_dump
    def dump_id(self, relationship, **kwargs):
        if 'id' not in relationship:
            pidvalue = relationship['identifiers'][0]['value']
            # TODO: ver si hay que optimizar esto.
            pid, org = OrganizationRecord.get_org_by_pid(pidvalue)
            if pid and org:
                relationship['id'] = str(pid.pid_value)
        return relationship
Esempio n. 17
0
class MetadataSchemaBaseV1(StrictKeysMixin):
    """Base Schema for the record metadata."""

    id = PersistentIdentifier()
    identifiers = Nested(IdentifierSchemaV1, many=True)
    source_repo = Nested(SourceSchemaV1)
    spec = Nested(SpecSchemaV1)
    title = SanitizedUnicode(required=True, validate=validate.Length(min=3))
    creators = Nested(ContributorSchemaV1, many=True)
    keywords = fields.List(SanitizedUnicode(), many=True)
    description = SanitizedUnicode(required=True,
                                   validate=validate.Length(min=3))
    publisher = SanitizedUnicode()
    sources = fields.List(SanitizedUnicode(), many=True)
    rights = fields.List(SanitizedUnicode(), many=True)
    types = fields.List(SanitizedUnicode(), many=True)
    formats = fields.List(SanitizedUnicode(), many=True)
    language = fields.Str()
    publication_date = DateString()
    references = Nested(ReferenceSchemaV1, many=True)
    terms = fields.List(SanitizedUnicode(), many=True)
    status = fields.Str()
    organizations = Nested(OrganizationDataSchema, many=True)
    classifications = Nested(ClasificationDataSchema, many=True)
Esempio n. 18
0
class DocumentMetadataSchemaV1(StrictKeysMixin):
    """Schema for the document metadata."""

    pid = PersistentIdentifier()
    ark = SanitizedUnicode()
    documentType = SanitizedUnicode()
    title = fields.List(fields.Dict())
    partOf = fields.List(fields.Dict())
    abstracts = fields.List(fields.Dict())
    contribution = fields.List(fields.Dict())
    organisation = fields.List(fields.Dict())
    language = fields.List(fields.Dict())
    copyrightDate = fields.List(fields.String())
    editionStatement = fields.Dict()
    provisionActivity = fields.List(fields.Dict())
    extent = SanitizedUnicode()
    otherMaterialCharacteristics = SanitizedUnicode()
    formats = fields.List(SanitizedUnicode())
    additionalMaterials = SanitizedUnicode()
    series = fields.List(fields.Dict())
    notes = fields.List(fields.String())
    identifiedBy = fields.List(fields.Dict())
    subjects = fields.List(fields.Dict())
    classification = fields.List(fields.Dict())
    collections = fields.List(fields.Dict())
    dissertation = fields.Dict()
    otherEdition = fields.List(fields.Dict())
    usageAndAccessPolicy = fields.Dict()
    projects = fields.List(fields.Dict())
    oa_status = SanitizedUnicode()
    subdivisions = fields.List(fields.Dict())
    harvested = fields.Boolean()
    contentNote = fields.List(SanitizedUnicode())
    customField1 = fields.List(fields.String(validate=validate.Length(min=1)))
    customField2 = fields.List(fields.String(validate=validate.Length(min=1)))
    customField3 = fields.List(fields.String(validate=validate.Length(min=1)))
    masked = SanitizedUnicode()
    _bucket = SanitizedUnicode()
    _files = Nested(FileSchemaV1, many=True)
    _oai = fields.Dict()
    # When loading, if $schema is not provided, it's retrieved by
    # Record.schema property.
    schema = GenFunction(load_only=True,
                         attribute="$schema",
                         data_key="$schema",
                         deserialize=schema_from_document)
    permissions = fields.Dict(dump_only=True)
    permalink = SanitizedUnicode(dump_only=True)

    @pre_dump
    def populate_files_properties(self, item, **kwargs):
        """Add some customs properties to file before dumping it.

        :param item: Item object to process
        :returns: Modified item
        """
        if not item.get('_files'):
            return item

        # Check if organisation record forces to point file to an external url
        item['external_url'] = has_external_urls_for_files(item)

        # Add restriction, link and thumbnail to files
        populate_files_properties(item)

        # Sort files to have the main file in first position
        item['_files'] = sorted(item['_files'],
                                key=lambda file: file.get('order', 100))

        return item

    @pre_dump
    def add_permissions(self, item, **kwargs):
        """Add permissions to record.

        :param item: Dict representing the record.
        :returns: Modified dict.
        """
        # For public views, no check for permissions
        if request.args.get('view'):
            return item

        item['permissions'] = {
            'read': DocumentPermission.read(current_user_record, item),
            'update': DocumentPermission.update(current_user_record, item),
            'delete': DocumentPermission.delete(current_user_record, item)
        }

        return item

    @pre_dump
    def add_permalink(self, item, **kwargs):
        """Add permanent link to document."""
        item['permalink'] = DocumentRecord.get_permanent_link(
            request.host_url, item['pid'])
        return item

    @pre_dump
    def add_formatted_texts(self, item, **kwargs):
        """Add formatted texts for objects which are processing in backend.

        :param item: Dict of record data.
        :returns: Modified data.
        """
        # Provision activity processing
        for index, provision_activity in enumerate(
                item.get('provisionActivity', [])):
            item['provisionActivity'][index][
                'text'] = create_publication_statement(provision_activity)

        # Part of proccessing
        for index, part_of in enumerate(item.get('partOf', [])):
            item['partOf'][index]['text'] = part_of_format(part_of)

        # Contribution
        for index, contribution in enumerate(item.get('contribution', [])):
            item['contribution'][index]['text'] = contribution_text(
                contribution)

        if item.get('dissertation'):
            item['dissertation']['text'] = dissertation(item)

        return item

    @pre_load
    def guess_organisation(self, data, **kwargs):
        """Guess organisation from current logged user.

        :param data: Dict of record data.
        :returns: Modified dict of record data.
        """
        # Organisation already attached to document, we do nothing.
        if data.get('organisation'):
            return data

        # Store current user organisation in new document.
        if current_user_record.get('organisation'):
            data['organisation'] = [current_user_record['organisation']]

        return data

    @pre_load
    def remove_fields(self, data, **kwargs):
        """Removes computed fields.

        :param data: Dict of record data.
        :returns: Modified data.
        """
        for provision_activity in data.get('provisionActivity', []):
            provision_activity.pop('text', None)

        for part_of in data.get('partOf', []):
            part_of.pop('text', None)

        for contribution in data.get('contribution', []):
            contribution.pop('text', None)

        data.get('dissertation', {}).pop('text', None)

        data.pop('permalink', None)
        data.pop('permissions', None)

        return data
Esempio n. 19
0
class MetadataSchemaRelIDsV1(MetadataSchemaBaseV1):
    """Schema for the record metadata."""
    relationships = Nested(RelationSchemaWithIDsV1, many=True)
Esempio n. 20
0
class MetadataSchemaV1(BaseSchema):
    """Schema for the record metadata."""

    # Administrative fields
    _access = Nested(AccessSchemaV1, required=True)
    _owners = fields.List(fields.Integer,
                          validate=validate.Length(min=1),
                          required=True)
    _created_by = fields.Integer(required=True)
    _default_preview = SanitizedUnicode()
    _files = fields.List(Nested(FilesSchemaV1, dump_only=True))
    _internal_notes = fields.List(Nested(InternalNoteSchemaV1))
    _embargo_date = DateString(data_key="embargo_date",
                               attribute="embargo_date")
    _communities = GenMethod('dump_communities')
    _contact = SanitizedUnicode(data_key="contact", attribute="contact")

    # Metadata fields
    access_right = SanitizedUnicode(required=True)
    identifiers = Identifiers()
    creators = fields.List(Nested(CreatorSchemaV1), required=True)
    titles = fields.List(Nested(TitleSchemaV1), required=True)
    resource_type = Nested(ResourceTypeSchemaV1, required=True)
    recid = PersistentIdentifier()
    publication_date = EDTFLevel0DateString(
        missing=lambda: date.today().isoformat())
    subjects = fields.List(Nested(SubjectSchemaV1))
    contributors = fields.List(Nested(ContributorSchemaV1))
    dates = fields.List(Nested(DateSchemaV1))
    language = SanitizedUnicode(validate=validate_iso639_3)
    related_identifiers = fields.List(Nested(RelatedIdentifierSchemaV1))
    version = SanitizedUnicode()
    licenses = fields.List(Nested(LicenseSchemaV1))
    descriptions = fields.List(Nested(DescriptionSchemaV1))
    locations = fields.List(Nested(LocationSchemaV1))
    references = fields.List(Nested(ReferenceSchemaV1))
    extensions = fields.Method('dump_extensions', 'load_extensions')

    def dump_extensions(self, obj):
        """Dumps the extensions value.

        :params obj: invenio_records_files.api.Record instance
        """
        current_app_metadata_extensions = (
            current_app.extensions['invenio-rdm-records'].metadata_extensions)
        ExtensionSchema = current_app_metadata_extensions.to_schema()
        return ExtensionSchema().dump(obj.get('extensions', {}))

    def load_extensions(self, value):
        """Loads the 'extensions' field.

        :params value: content of the input's 'extensions' field
        """
        current_app_metadata_extensions = (
            current_app.extensions['invenio-rdm-records'].metadata_extensions)
        ExtensionSchema = current_app_metadata_extensions.to_schema()

        return ExtensionSchema().load(value)

    def dump_communities(self, obj):
        """Dumps communities related to the record."""
        # NOTE: If the field is already there, it's coming from ES
        if '_communities' in obj:
            return CommunityStatusV1().dump(obj['_communities'])

        record = self.context.get('record')
        if record:
            _record = Record(record, model=record.model)
            return CommunityStatusV1().dump(
                RecordCommunitiesCollection(_record).as_dict())

    @validates('_embargo_date')
    def validate_embargo_date(self, value):
        """Validate that embargo date is in the future."""
        if arrow.get(value).date() <= arrow.utcnow().date():
            raise ValidationError(_('Embargo date must be in the future.'),
                                  field_names=['embargo_date'])

    @validates('access_right')
    def validate_access_right(self, value):
        """Validate that access right is one of the allowed ones."""
        access_right_key = {'access_right': value}
        validate_entry('access_right', access_right_key)

    @post_load
    def post_load_publication_date(self, obj, **kwargs):
        """Add '_publication_date_search' field."""
        prepare_publication_date(obj)
        return obj
Esempio n. 21
0
class CommunityStatusV1(BaseSchema):
    """Status of a community request."""

    pending = fields.List(Nested(CommunitiesRequestV1))
    accepted = fields.List(Nested(CommunitiesRequestV1))
    rejected = fields.List(Nested(CommunitiesRequestV1))
Esempio n. 22
0
class LocationSchemaV1(BaseSchema):
    """Location schema."""

    point = Nested(PointSchemaV1)
    place = SanitizedUnicode(required=True)
    description = SanitizedUnicode()
Esempio n. 23
0
class RelationSchemaV1(StrictKeysMixin):
    """Ids schema."""

    identifiers = Nested(IdentifierSchemaV1, many=True, required=True)
    type = SanitizedUnicode()
    label = SanitizedUnicode()
Esempio n. 24
0
    name = fields.Str(required=True)
    role = fields.Str()
    affiliations = fields.List(fields.Str())
    email = fields.Str()


class MetadataSchemaV1(StrictKeysMixin):
    """Schema for the record metadata."""

    def get_{{ cookiecutter.pid_name }}(self, obj):
        """Get record id."""
        pid = self.context.get('pid')
        return pid.pid_value if pid else missing

    {{ cookiecutter.pid_name }} = PersistentIdentifier()
    title = SanitizedUnicode(required=True, validate=validate.Length(min=3))
    keywords = fields.Nested(fields.Str(), many=True)
    publication_date = DateString()
    contributors = Nested(ContributorSchemaV1, many=True, required=True)


class RecordSchemaV1(StrictKeysMixin):
    """Record schema."""

    metadata = fields.Nested(MetadataSchemaV1)
    created = fields.Str(dump_only=True)
    revision = fields.Integer(dump_only=True)
    updated = fields.Str(dump_only=True)
    links = fields.Dict(dump_only=True)
    id = PersistentIdentifier()
Esempio n. 25
0
class MetadataSchemaV1(MetadataSchemaBaseV1):
    """Schema for the record metadata."""
    source_repo = Nested(SourceSchemaV1)