コード例 #1
0
 def __init__(self,
              _db,
              api,
              datasource,
              batch_size=10,
              metadata_replacement_policy=None,
              circulationdata_replacement_policy=None,
              cutoff_time=None):
     self._db = _db
     self.api = api
     output_source = DataSource.lookup(_db, datasource)
     input_identifier_types = [output_source.primary_identifier_type]
     service_name = "%s Bibliographic Coverage Provider" % datasource
     metadata_replacement_policy = (
         metadata_replacement_policy
         or ReplacementPolicy.from_metadata_source())
     circulationdata_replacement_policy = (
         circulationdata_replacement_policy
         or ReplacementPolicy.from_license_source())
     self.metadata_replacement_policy = metadata_replacement_policy
     self.circulationdata_replacement_policy = circulationdata_replacement_policy
     super(BibliographicCoverageProvider,
           self).__init__(service_name,
                          input_identifier_types,
                          output_source,
                          batch_size=batch_size,
                          cutoff_time=cutoff_time)
コード例 #2
0
    def populate_all_catalog(self):
        """ Call get_all_catalog to get all of library's book info from OneClick.
        Create Work, Edition, LicensePool objects in our database.
        """
        catalog_list = self.get_all_catalog()
        items_transmitted = len(catalog_list)
        items_created = 0
        coverage_provider = OneClickBibliographicCoverageProvider(_db=self._db)
        # the default policy doesn't update delivery mechanisms, which we do want to do
        metadata_replacement_policy = ReplacementPolicy.from_metadata_source()
        metadata_replacement_policy.formats = True

        for catalog_item in catalog_list:
            result = coverage_provider.update_metadata(
                catalog_item=catalog_item,
                metadata_replacement_policy=metadata_replacement_policy)
            if not isinstance(result, CoverageFailure):
                items_created += 1

                if isinstance(result, Identifier):
                    # calls work.set_presentation_ready() for us
                    coverage_provider.handle_success(result)

                    # We're populating the catalog, so we can assume the list OneClick
                    # sent us is of books we own licenses to.
                    # NOTE:  TODO later:  For the 4 out of 2000 libraries that chose to display
                    # books they don't own, we'd need to call the search endpoint to get
                    # the interest field, and then deal with licenses_owned.
                    if result.licensed_through:
                        result.licensed_through.licenses_owned = 1

        # stay data, stay!
        self._db.commit()

        return items_transmitted, items_created
コード例 #3
0
    def _set_metadata(self,
                      identifier,
                      metadata,
                      metadata_replacement_policy=None):
        """Finds or creates the Edition for an Identifier, updates it
        with the given metadata.

        :return: The Identifier (if successful) or an appropriate
        CoverageFailure (if not).
        """
        metadata_replacement_policy = metadata_replacement_policy or (
            ReplacementPolicy.from_metadata_source())

        edition = self.edition(identifier)
        if isinstance(edition, CoverageFailure):
            return edition

        if not metadata:
            e = "Did not receive metadata from input source"
            return CoverageFailure(identifier,
                                   e,
                                   data_source=self.output_source,
                                   transient=True)

        try:
            metadata.apply(
                edition,
                replace=metadata_replacement_policy,
            )
        except Exception as e:
            self.log.warn("Error applying metadata to edition %d: %s",
                          edition.id,
                          e,
                          exc_info=e)
            return CoverageFailure(identifier,
                                   repr(e),
                                   data_source=self.output_source,
                                   transient=True)

        return identifier
コード例 #4
0
class TitleFromExternalList(object):
    """This class helps you convert data from external lists into Simplified
    Edition and CustomListEntry objects.
    """
    def __init__(self, metadata, first_appearance, most_recent_appearance,
                 annotation):
        self.log = logging.getLogger("Title from external list")
        self.metadata = metadata
        self.first_appearance = first_appearance or most_recent_appearance
        self.most_recent_appearance = (most_recent_appearance
                                       or datetime.datetime.now())
        self.annotation = annotation

    def to_custom_list_entry(self,
                             custom_list,
                             metadata_client,
                             overwrite_old_data=False):
        """Turn this object into a CustomListEntry with associated Edition."""
        _db = Session.object_session(custom_list)
        edition = self.to_edition(_db, metadata_client, overwrite_old_data)

        list_entry, is_new = get_one_or_create(_db,
                                               CustomListEntry,
                                               edition=edition,
                                               customlist=custom_list)

        if (not list_entry.first_appearance
                or list_entry.first_appearance > self.first_appearance):
            if list_entry.first_appearance:
                self.log.info(
                    "I thought %s first showed up at %s, but then I saw it earlier, at %s!",
                    self.metadata.title, list_entry.first_appearance,
                    self.first_appearance)
            list_entry.first_appearance = self.first_appearance

        if (not list_entry.most_recent_appearance
                or list_entry.most_recent_appearance <
                self.most_recent_appearance):
            if list_entry.most_recent_appearance:
                self.log.info(
                    "I thought %s most recently showed up at %s, but then I saw it later, at %s!",
                    self.metadata.title, list_entry.most_recent_appearance,
                    self.most_recent_appearance)
            list_entry.most_recent_appearance = self.most_recent_appearance

        list_entry.annotation = self.annotation

        list_entry.set_work(self.metadata, metadata_client)
        return list_entry, is_new

    def to_edition(self, _db, metadata_client, overwrite_old_data=False):
        """Create or update an Edition object for this list item.

        We have two goals here:

        1. Make sure there is an Edition representing the list's view
        of the data.

        2. If at all possible, connect the Edition's primary
        identifier to other identifiers in the system, identifiers
        which may have associated LicensePools. This can happen in two
        ways:

        2a. The Edition's primary identifier, or other identifiers
        associated with the Edition, may be directly associated with
        LicensePools. This can happen if a book's list entry includes
        (e.g.) an Overdrive ID.

        2b. The Edition's permanent work ID may identify it as the
        same work as other Editions in the system. In that case this
        Edition's primary identifier may be associated with the other
        Editions' primary identifiers. (p=0.85)
        """
        self.log.info("Converting %s to an Edition object.",
                      self.metadata.title)

        # Make sure the Metadata object's view of the book is present
        # as an Edition. This will also associate all its identifiers
        # with its primary identifier, and calculate the permanent work
        # ID if possible.
        try:
            edition, is_new = self.metadata.edition(_db)
        except ValueError, e:
            self.log.info("Ignoring %s, no corresponding edition.",
                          self.metadata.title)
            return None
        if overwrite_old_data:
            policy = ReplacementPolicy.from_metadata_source(
                even_if_not_apparently_updated=True)
        else:
            policy = ReplacementPolicy.append_only(
                even_if_not_apparently_updated=True)
        self.metadata.apply(
            edition=edition,
            metadata_client=metadata_client,
            replace=policy,
        )
        self.metadata.associate_with_identifiers_based_on_permanent_work_id(
            _db)
        return edition
コード例 #5
0
 def _default_replacement_policy(self, _db):
     """Unless told otherwise, assume that we are getting
     this data from a reliable metadata source.
     """
     return ReplacementPolicy.from_metadata_source()
コード例 #6
0
 def __init__(self, **metadata_replacement_args):
     
     self.metadata_replacement_policy = ReplacementPolicy.from_metadata_source(
         **metadata_replacement_args
     )