def make_opds_entry_from_metadata_lookups(self, identifier): """This identifier cannot be turned into a presentation-ready Work, but maybe we can make an OPDS entry based on metadata lookups. """ # We can only create an OPDS entry if all the lookups have # in fact been done. metadata_sources = DataSource.metadata_sources_for( self._db, identifier ) q = self._db.query(CoverageRecord).filter( CoverageRecord.identifier==identifier ).filter( CoverageRecord.data_source_id.in_( [x.id for x in metadata_sources] ) ) coverage_records = q.all() unaccounted_for = set(metadata_sources) for r in coverage_records: if r.data_source in unaccounted_for: unaccounted_for.remove(r.data_source) if unaccounted_for: # At least one metadata lookup has not successfully # completed. names = [x.name for x in unaccounted_for] self.log.info( "Cannot build metadata-based OPDS feed for %r: missing coverage records for %s", identifier, ", ".join(names) ) return self.register_identifier_as_unresolved( identifier.urn, identifier ) else: # All metadata lookups have completed. Create that OPDS # entry! entry = identifier.opds_entry() if entry is None: # We can't do lookups on an identifier of this type, so # the best thing to do is to treat this identifier as a # 404 error. return self.add_message( identifier.urn, HTTP_NOT_FOUND, self.UNRECOGNIZED_IDENTIFIER ) # We made it! return self.add_entry(entry)
def test_process_urn_isbn(self): # Create a new ISBN identifier. # Ask online providers for metadata to turn into an opds feed about this identifier. # Make sure a coverage record was created, and a 201 status obtained from provider. # Ask online provider again, and make sure we're now getting a 202 "working on it" status. # Ask again, this time getting a result. Make sure know that got a result. isbn, ignore = Identifier.for_foreign_id( self._db, Identifier.ISBN, self._isbn ) # The first time we look up an ISBN a CoverageRecord is created # representing the work to be done. self.controller.process_urn(isbn.urn) self.assert_one_message( isbn.urn, HTTP_CREATED, self.controller.IDENTIFIER_REGISTERED ) [record] = isbn.coverage_records eq_(record.exception, self.controller.NO_WORK_DONE_EXCEPTION) eq_(record.status, CoverageRecord.TRANSIENT_FAILURE) # So long as the necessary coverage is not provided, # future lookups will not provide useful information self.controller.precomposed_entries = [] self.controller.process_urn(isbn.urn) self.assert_one_message( isbn.urn, HTTP_ACCEPTED, self.controller.WORKING_TO_RESOLVE_IDENTIFIER ) # Let's provide the coverage. metadata_sources = DataSource.metadata_sources_for( self._db, isbn ) for source in metadata_sources: CoverageRecord.add_for(isbn, source) # Process the ISBN again, and we get an <entry> tag with the # information. self.controller.precomposed_entries = [] self.controller.process_urn(isbn.urn) expect = isbn.opds_entry() [actual] = self.controller.precomposed_entries eq_(etree.tostring(expect), etree.tostring(actual))
def make_opds_entry_from_metadata_lookups(self, identifier): """This identifier cannot be turned into a presentation-ready Work, but maybe we can make an OPDS entry based on metadata lookups. """ # We can only create an OPDS entry if all the lookups have # in fact been done. metadata_sources = DataSource.metadata_sources_for( self._db, identifier) q = self._db.query(CoverageRecord).filter( CoverageRecord.identifier == identifier).filter( CoverageRecord.data_source_id.in_( [x.id for x in metadata_sources])) coverage_records = q.all() unaccounted_for = set(metadata_sources) for r in coverage_records: if r.data_source in unaccounted_for: unaccounted_for.remove(r.data_source) if unaccounted_for: # At least one metadata lookup has not successfully # completed. names = [x.name for x in unaccounted_for] self.log.info( "Cannot build metadata-based OPDS feed for %r: missing coverage records for %s", identifier, ", ".join(names)) return self.register_identifier_as_unresolved( identifier.urn, identifier) else: # All metadata lookups have completed. Create that OPDS # entry! entry = identifier.opds_entry() if entry is None: # We can't do lookups on an identifier of this type, so # the best thing to do is to treat this identifier as a # 404 error. return self.add_message(identifier.urn, HTTP_NOT_FOUND, self.UNRECOGNIZED_IDENTIFIER) # We made it! return self.add_entry(entry)
def test_process_urn_isbn(self): # Create a new ISBN identifier. # Ask online providers for metadata to turn into an opds feed about this identifier. # Make sure a coverage record was created, and a 201 status obtained from provider. # Ask online provider again, and make sure we're now getting a 202 "working on it" status. # Ask again, this time getting a result. Make sure know that got a result. isbn, ignore = Identifier.for_foreign_id(self._db, Identifier.ISBN, self._isbn) # The first time we look up an ISBN a CoverageRecord is created # representing the work to be done. self.controller.process_urn(isbn.urn) self.assert_one_message(isbn.urn, HTTP_CREATED, self.controller.IDENTIFIER_REGISTERED) [record] = isbn.coverage_records eq_(record.exception, self.controller.NO_WORK_DONE_EXCEPTION) eq_(record.status, CoverageRecord.TRANSIENT_FAILURE) # So long as the necessary coverage is not provided, # future lookups will not provide useful information self.controller.precomposed_entries = [] self.controller.process_urn(isbn.urn) self.assert_one_message(isbn.urn, HTTP_ACCEPTED, self.controller.WORKING_TO_RESOLVE_IDENTIFIER) # Let's provide the coverage. metadata_sources = DataSource.metadata_sources_for(self._db, isbn) for source in metadata_sources: CoverageRecord.add_for(isbn, source) # Process the ISBN again, and we get an <entry> tag with the # information. self.controller.precomposed_entries = [] self.controller.process_urn(isbn.urn) expect = isbn.opds_entry() [actual] = self.controller.precomposed_entries eq_(etree.tostring(expect), etree.tostring(actual))