Exemplo n.º 1
0
class TodoResourceConfig(ResourceConfig):
    blueprint_name = "todo"
    url_prefix = "/todos"

    response_handlers = {
        "application/json": ResponseHandler(JSONSerializer()),
    }
Exemplo n.º 2
0
class RecordResourceConfig(ResourceConfig):
    """Record resource config."""

    # Blueprint configuration
    blueprint_name = None
    url_prefix = "/records"
    routes = {
        "list": "",
        "item": "/<pid_value>",
    }

    # Request parsing
    request_read_args = {}
    request_view_args = {"pid_value": ma.fields.Str()}
    request_search_args = SearchRequestArgsSchema
    request_headers = {"if_match": ma.fields.Int()}
    request_body_parsers = {
        "application/json": RequestBodyParser(JSONDeserializer())
    }
    default_content_type = "application/json"

    # Response handling
    response_handlers = {
        "application/json": ResponseHandler(JSONSerializer(),
                                            headers=etag_headers)
    }
    default_accept_mimetype = "application/json"
Exemplo n.º 3
0
class VocabulariesResourceConfig(RecordResourceConfig):
    """Vocabulary resource configuration."""

    blueprint_name = "vocabularies"
    url_prefix = "/vocabularies"
    routes = {
        "list": "/<type>",
        "item": "/<type>/<pid_value>",
    }

    request_view_args = {
        "pid_value": ma.fields.Str(),
        "type": ma.fields.Str(required=True),
    }

    request_args = VocabularySearchRequestArgsSchema

    response_handlers = {
        "application/json":
        ResponseHandler(JSONSerializer(), headers=etag_headers),
        "application/vnd.inveniordm.v1+json":
        ResponseHandler(
            MarshmallowJSONSerializer(
                schema_cls=VocabularyL10NItemSchema,
                many_schema_cls=VocabularyL10NListSchema,
            ),
            headers=etag_headers,
        ),
    }
Exemplo n.º 4
0
class RDMPIDProviderResourceConfig(RecordResourceConfig):
    """PID provider resource configuration."""

    blueprint_name = "reserve"

    url_prefix = "/records/<pid_value>/draft/pids"

    routes = {"item": "/<providers>"}

    request_view_args = {
        "provider": ma.fields.Str(),
        "pid_value": ma.fields.Str(),
    }

    response_handlers = {"application/json": ResponseHandler(JSONSerializer())}

    error_handlers = record_links_error_handlers
class Marc21ParentRecordLinksResourceConfig(RecordResourceConfig):
    """User records resource configuration."""

    blueprint_name = "marc21_access"

    url_prefix = f"{url_prefix}/<pid_value>/access"

    routes = {
        "search": "",
        "list": "/links",
        "item": "/links/<link_id>",
    }

    links_config = {}

    request_view_args = {
        "pid_value": ma.fields.Str(),
        "link_id": ma.fields.Str()
    }

    response_handlers = {"application/json": ResponseHandler(JSONSerializer())}
Exemplo n.º 6
0
class IIIFResourceConfig(ResourceConfig):
    """IIIF resource configuration."""

    blueprint_name = "iiif"

    url_prefix = "/iiif"

    routes = {
        "manifest": "/<uuid>/manifest",
        "sequence": "/<uuid>/sequence/default",
        "canvas": "/<uuid>/canvas/<file_name>",
        "image_base": "/<uuid>",
        "image_info": "/<uuid>/info.json",
        "image_api":
        "/<uuid>/<region>/<size>/<rotation>/<quality>.<image_format>",
    }

    request_view_args = {
        "uuid": ma.fields.Str(),
        "file_name": ma.fields.Str(),
        "region": ma.fields.Str(),
        "size": ma.fields.Str(),
        "rotation": ma.fields.Str(),
        "quality": ma.fields.Str(),
        "image_format": ma.fields.Str(),
    }

    response_handler = {"application/json": ResponseHandler(JSONSerializer())}

    supported_formats = {
        "gif": "image/gif",
        "jp2": "image/jp2",
        "jpeg": "image/jpeg",
        "jpg": "image/jpeg",
        "pdf": "application/pdf",
        "png": "image/png",
        "tif": "image/tiff",
        "tiff": "image/tiff",
    }
Exemplo n.º 7
0
    DataCite43XMLSerializer, StringCitationSerializer, UIJSONSerializer


def csl_url_args_retriever():
    """Returns the style and locale passed as URL args for CSL export."""
    style = resource_requestctx.args.get("style")
    locale = resource_requestctx.args.get("locale")
    return style, locale


#
# Response handlers
#
record_serializers = {
    "application/json":
    ResponseHandler(JSONSerializer()),
    "application/vnd.inveniordm.v1+json":
    ResponseHandler(UIJSONSerializer()),
    "application/vnd.citationstyles.csl+json":
    ResponseHandler(CSLJSONSerializer()),
    "application/vnd.datacite.datacite+json":
    ResponseHandler(DataCite43JSONSerializer()),
    "application/vnd.datacite.datacite+xml":
    ResponseHandler(DataCite43XMLSerializer()),
    "text/x-bibliography":
    ResponseHandler(
        StringCitationSerializer(url_args_retriever=csl_url_args_retriever),
        headers={"content-type": "text/plain"}),
}

Exemplo n.º 8
0
"""Resources configuration."""

import marshmallow as ma
from flask_resources import HTTPJSONException, JSONSerializer, \
    ResponseHandler, create_error_handler
from invenio_drafts_resources.resources import RecordResourceConfig
from invenio_records_resources.resources.files import FileResourceConfig

from .serializers import UIJSONSerializer

#
# Response handlers
#
record_serializers = {
    "application/json": ResponseHandler(JSONSerializer()),
    "application/vnd.inveniordm.v1+json": ResponseHandler(UIJSONSerializer())
}


#
# Records and record versions
#
class RDMRecordResourceConfig(RecordResourceConfig):
    """Record resource configuration."""

    blueprint_name = "records"
    url_prefix = "/records"

    routes = RecordResourceConfig.routes
    routes["item-files-import"] = "/<pid_value>/draft/actions/files-import"
Exemplo n.º 9
0
class RecordResource(RecordResourceBase):
    """Draft-aware RecordResource."""

    def create_blueprint(self, **options):
        """Create the blueprint."""
        # We avoid passing url_prefix to the blueprint because we need to
        # install URLs under both /records and /user/records. Instead we
        # add the prefix manually to each route (which is anyway what Flask
        # does in the end)
        options["url_prefix"] = ""
        return super().create_blueprint(**options)

    def create_url_rules(self):
        """Create the URL rules for the record resource."""
        routes = self.config.routes

        def p(route):
            """Prefix a route with the URL prefix."""
            return f"{self.config.url_prefix}{route}"

        def s(route):
            """Suffix a route with the URL prefix."""
            return f"{route}{self.config.url_prefix}"

        rules = [
            route("GET", p(routes["list"]), self.search),
            route("POST", p(routes["list"]), self.create),
            route("GET", p(routes["item"]), self.read),
            route("PUT", p(routes["item"]), self.update),
            route("DELETE", p(routes["item"]), self.delete),
            route("GET", p(routes["item-versions"]), self.search_versions),
            route("POST", p(routes["item-versions"]), self.new_version),
            route("GET", p(routes["item-latest"]), self.read_latest),
            route("GET", p(routes["item-draft"]), self.read_draft),
            route("POST", p(routes["item-draft"]), self.edit),
            route("PUT", p(routes["item-draft"]), self.update_draft),
            route("DELETE", p(routes["item-draft"]), self.delete_draft),
            route("POST", p(routes["item-publish"]), self.publish),
            route("GET", s(routes["user-prefix"]), self.search_user_records),
        ]

        if self.service.draft_files:
            rules.append(route(
                "POST",
                p(routes["item-files-import"]),
                self.import_files,
                apply_decorators=False
            ))

        return rules

    @request_search_args
    @request_view_args
    @response_handler(many=True)
    def search_user_records(self):
        """Perform a search over the record's versions.

        GET /user/records
        """
        hits = self.service.search_drafts(
            identity=g.identity,
            params=resource_requestctx.args,
            es_preference=es_preference(),
        )
        return hits.to_dict(), 200

    @request_search_args
    @request_view_args
    @response_handler(many=True)
    def search_versions(self):
        """Perform a search over the record's versions.

        GET /records/:pid_value/versions
        """
        hits = self.service.search_versions(
            g.identity,
            resource_requestctx.view_args["pid_value"],
            params=resource_requestctx.args,
            es_preference=es_preference()
        )
        return hits.to_dict(), 200

    @request_view_args
    @response_handler()
    def new_version(self):
        """Create a new version.

        POST /records/:pid_value/versions
        """
        item = self.service.new_version(
            g.identity,
            resource_requestctx.view_args["pid_value"],
        )
        return item.to_dict(), 201

    @request_view_args
    @response_handler()
    def edit(self):
        """Edit a record.

        POST /records/:pid_value/draft
        """
        item = self.service.edit(
            g.identity,
            resource_requestctx.view_args["pid_value"],
        )
        return item.to_dict(), 201

    @request_view_args
    @response_handler()
    def publish(self):
        """Publish the draft."""
        item = self.service.publish(
            g.identity,
            resource_requestctx.view_args["pid_value"],
        )
        return item.to_dict(), 202

    @request_view_args
    @with_content_negotiation(
        response_handlers={
            'application/json': ResponseHandler(JSONSerializer())
        },
        default_accept_mimetype='application/json',
    )
    @response_handler(many=True)
    def import_files(self):
        """Import files from previous record version."""
        files = self.service.import_files(
            g.identity,
            resource_requestctx.view_args["pid_value"],
        )
        return files.to_dict(), 201

    @request_view_args
    def read_latest(self):
        """Redirect to latest record.

        GET /records/:pid_value/versions/latest
        """
        item = self.service.read_latest(
            g.identity,
            resource_requestctx.view_args["pid_value"],
        )
        raise RedirectException(item["links"]["self"])

    @request_read_args
    @request_view_args
    @response_handler()
    def read_draft(self):
        """Edit a draft.

        GET /records/:pid_value/draft
        """
        item = self.service.read_draft(
            g.identity,
            resource_requestctx.view_args["pid_value"],
        )
        return item.to_dict(), 200

    @request_headers
    @request_view_args
    @request_data
    @response_handler()
    def update_draft(self):
        """Update a draft.

        PUT /records/:pid_value/draft
        """
        item = self.service.update_draft(
            g.identity,
            resource_requestctx.view_args["pid_value"],
            resource_requestctx.data or {},
            revision_id=resource_requestctx.headers.get("if_match"),
        )
        return item.to_dict(), 200

    @request_headers
    @request_view_args
    def delete_draft(self):
        """Delete a draft.

        DELETE /records/:pid_value/draft
        """
        self.service.delete_draft(
            g.identity,
            resource_requestctx.view_args["pid_value"],
            revision_id=resource_requestctx.headers.get("if_match"),
        )
        return "", 204