Source code for api.admin.controller.metadata_services

import flask
from flask import Response
from flask_babel import lazy_gettext as _
from api.admin.problem_details import *
from api.nyt import NYTBestSellerAPI
from api.novelist import NoveListAPI
from core.opds_import import MetadataWranglerOPDSLookup
from core.model import (
    ExternalIntegration,
    get_one,
)
from core.util.http import HTTP
from core.util.problem_detail import ProblemDetail

from . import SitewideRegistrationController

[docs]class MetadataServicesController(SitewideRegistrationController): def __init__(self, manager): super(MetadataServicesController, self).__init__(manager) self.provider_apis = [ NYTBestSellerAPI, NoveListAPI, MetadataWranglerOPDSLookup, ] self.protocols = self._get_integration_protocols(self.provider_apis, protocol_name_attr="PROTOCOL") self.goal = ExternalIntegration.METADATA_GOAL self.type = _("metadata service")
[docs] def process_metadata_services(self): self.require_system_admin() if flask.request.method == 'GET': return self.process_get() else: return self.process_post()
[docs] def process_get(self): metadata_services = self._get_integration_info(self.goal, self.protocols) for service in metadata_services: service_object = get_one(self._db, ExternalIntegration, id=service.get("id"), goal=ExternalIntegration.METADATA_GOAL) protocol_class, tuple = self.find_protocol_class(service_object) service["self_test_results"] = self._get_prior_test_results(service_object, protocol_class, *tuple) return dict( metadata_services=metadata_services, protocols=self.protocols, )
[docs] def find_protocol_class(self, integration): if integration.protocol == ExternalIntegration.METADATA_WRANGLER: return ( MetadataWranglerOPDSLookup, (MetadataWranglerOPDSLookup.from_config, self._db) ) elif integration.protocol == ExternalIntegration.NYT: return ( NYTBestSellerAPI, (NYTBestSellerAPI.from_config, self._db) ) elif integration.protocol == ExternalIntegration.NOVELIST: return ( NoveListAPI, (NoveListAPI.from_config, self._db) ) raise NotImplementedError( "No metadata self-test class for protocol %s" % integration.protocol )
[docs] def process_post(self, do_get=HTTP.debuggable_get, do_post=HTTP.debuggable_post): name = flask.request.form.get("name") protocol = flask.request.form.get("protocol") url = flask.request.form.get("url") fields = {"name": name, "protocol": protocol, "url": url} form_field_error = self.validate_form_fields(**fields) if form_field_error: return form_field_error id = flask.request.form.get("id") is_new = False if id: # Find an existing service in order to edit it service = self.look_up_service_by_id(id, protocol) else: service, is_new = self._create_integration( self.protocols, protocol, self.goal ) if isinstance(service, ProblemDetail): self._db.rollback() return service name_error = self.check_name_unique(service, name) if name_error: self._db.rollback() return name_error protocol_error = self.set_protocols(service, protocol) if protocol_error: self._db.rollback() return protocol_error wrangler_error = self.register_with_metadata_wrangler( do_get, do_post, is_new, service ) if isinstance(wrangler_error, ProblemDetail): self._db.rollback() return wrangler_error service.name = name if is_new: return Response(str(service.id), 201) else: return Response(str(service.id), 200)
[docs] def validate_form_fields(self, **fields): """The 'name' and 'protocol' fields cannot be blank, and the protocol must be selected from the list of recognized protocols. The URL must be valid.""" name = fields.get("name") protocol = fields.get("protocol") url = fields.get("url") if not name: return INCOMPLETE_CONFIGURATION if not protocol: return NO_PROTOCOL_FOR_NEW_SERVICE error = self.validate_protocol() if error: return error wrong_format = self.validate_formats() if wrong_format: return wrong_format
[docs] def register_with_metadata_wrangler(self, do_get, do_post, is_new, service): """Register this site with the Metadata Wrangler.""" if ((is_new or not service.password) and service.protocol == ExternalIntegration.METADATA_WRANGLER): return self.process_sitewide_registration( integration=service, do_get=do_get, do_post=do_post )
[docs] def process_delete(self, service_id): return self._delete_integration( service_id, self.goal )