def ask_registry(self, service_area_object, db, do_get=HTTP.debuggable_get): # If the circulation manager doesn't know about this location, check whether the Library Registry does. result = None for registry in RemoteRegistry.for_protocol_and_goal( db, ExternalIntegration.OPDS_REGISTRATION, ExternalIntegration.DISCOVERY_GOAL, ): base_url = registry.integration.url + "/coverage?coverage=" response = do_get(base_url + service_area_object) if not response.status_code == 200: result = REMOTE_INTEGRATION_FAILED.detailed( _( "Unable to contact the registry at %(url)s.", url=registry.integration.url, ) ) if hasattr(response, "content"): content = json.loads(response.content) found_place = not (content.get("unknown") or content.get("ambiguous")) if found_place: return True return result
def setup_method(self): super(TestRegistration, self).setup_method() # Create a RemoteRegistry. self.integration = self._external_integration(protocol="some protocol", goal="some goal") self.registry = RemoteRegistry(self.integration) self.registration = Registration(self.registry, self._default_library)
def _registry(self, url): integration, is_new = create( self._db, ExternalIntegration, protocol=ExternalIntegration.OPDS_REGISTRATION, goal=ExternalIntegration.DISCOVERY_GOAL, ) integration.url = url return RemoteRegistry(integration)
def look_up_registry(self, integration_id): """Find the RemoteRegistry that the user is trying to register the library with, and check that it actually exists.""" registry = RemoteRegistry.for_integration_id(self._db, integration_id, self.goal) if not registry: return MISSING_SERVICE return registry
def look_up_service_from_registry(self, protocol, id): """Find an existing service, and make sure that the user is not trying to edit its protocol.""" registry = RemoteRegistry.for_integration_id(self._db, id, self.goal) if not registry: return MISSING_SERVICE service = registry.integration if protocol != service.protocol: return CANNOT_CHANGE_PROTOCOL return service
def test_registrations(self): registry = RemoteRegistry(self.integration) # Associate the default library with the registry. Registration(registry, self._default_library) # Create another library not associated with the registry. library2 = self._library() # registrations() finds a single Registration. [registration] = list(registry.registrations) assert isinstance(registration, Registration) assert registry == registration.registry assert self._default_library == registration.library
def test_process_library(self): """Test the things that might happen when process_library is called.""" script = LibraryRegistrationScript(self._db) library = self._default_library integration = self._external_integration( protocol="some protocol", goal=ExternalIntegration.DISCOVERY_GOAL) registry = RemoteRegistry(integration) # First, simulate success. class Success(Registration): def push(self, stage, url_for): self.pushed = (stage, url_for) return True registration = Success(registry, library) stage = object() url_for = object() assert True == script.process_library(registration, stage, url_for) # The stage and url_for values were passed into # Registration.push() assert (stage, url_for) == registration.pushed # Next, simulate an exception raised during push() # This can happen in real situations, though the next case # we'll test is more common. class FailsWithException(Registration): def push(self, stage, url_for): raise Exception("boo") registration = FailsWithException(registry, library) # We get False rather than the exception being propagated. # Useful information about the exception is added to the logs, # where someone actually running the script will see it. assert False == script.process_library(registration, stage, url_for) # Next, simulate push() returning a problem detail document. class FailsWithProblemDetail(Registration): def push(self, stage, url_for): return INVALID_INPUT.detailed("oops") registration = FailsWithProblemDetail(registry, library) result = script.process_library(registration, stage, url_for) # The problem document is returned. Useful information about # the exception is also added to the logs, where someone # actually running the script will see it. assert INVALID_INPUT.uri == result.uri assert "oops" == result.detail
def process_get(self): registries = list( RemoteRegistry.for_protocol_and_goal(self._db, self.opds_registration, self.goal)) if not registries: # There are no registries at all. Set up the default # library registry. self.set_up_default_registry() services = self._get_integration_info(self.goal, self.protocols) return dict( discovery_services=services, protocols=self.protocols, )
def test_for_protocol_and_goal(self): # Create two ExternalIntegrations that have different protocols # or goals from our original. same_goal_different_protocol = self._external_integration( protocol="some other protocol", goal=self.integration.goal) same_protocol_different_goal = self._external_integration( protocol=self.integration.protocol, goal="some other goal") # Only the original ExternalIntegration has both the requested # protocol and goal, so only it becomes a RemoteRegistry. [registry] = list( RemoteRegistry.for_protocol_and_goal(self._db, self.integration.protocol, self.integration.goal)) assert isinstance(registry, RemoteRegistry) assert self.integration == registry.integration
def process_get(self, do_get=HTTP.debuggable_get): """Make a list of all discovery services, each with the list of libraries registered with that service and the status of the registration.""" services = [] for registry in RemoteRegistry.for_protocol_and_goal( self._db, ExternalIntegration.OPDS_REGISTRATION, self.goal): result = registry.fetch_registration_document(do_get=do_get) if isinstance(result, ProblemDetail): # Unlike most cases like this, a ProblemDetail doesn't # mean the whole request is ruined -- just that one of # the discovery services isn't working. Turn the # ProblemDetail into a JSON object and return it for # handling on the client side. access_problem = json.loads(result.response[0]) terms_of_service_link = terms_of_service_html = None else: access_problem = None terms_of_service_link, terms_of_service_html = result libraries = [] for registration in registry.registrations: library_info = self.get_library_info(registration) if library_info: libraries.append(library_info) services.append( dict( id=registry.integration.id, access_problem=access_problem, terms_of_service_link=terms_of_service_link, terms_of_service_html=terms_of_service_html, libraries=libraries, )) return dict(library_registrations=services)
def mock_for_protocol_and_goal(_db, protocol, goal): for integration in integrations: yield RemoteRegistry(integration)
def test_constructor(self): registry = RemoteRegistry(self.integration) assert self.integration == registry.integration
def _decode_data_url(cls, url): cls.decoded = url return "Decoded: " + RemoteRegistry._decode_data_url(url)
def extract(document, type=RemoteRegistry.OPDS_2_TYPE): response = MockRequestsResponse(200, {"Content-Type": type}, document) return RemoteRegistry._extract_catalog_information(response)