def set_work(self, metadata=None, metadata_client=None, policy=None): """If possible, identify a locally known Work that is the same title as the title identified by this CustomListEntry. :param policy: A PresentationCalculationPolicy, used to determine how far to go when looking for equivalent Identifiers. """ _db = Session.object_session(self) edition = self.edition if not self.edition: # This shouldn't happen, but no edition means no work self.work = None return self.work new_work = None if not metadata: from ..metadata_layer import Metadata metadata = Metadata.from_edition(edition) # Try to guess based on metadata, if we can get a high-quality # guess. potential_license_pools = metadata.guess_license_pools( _db, metadata_client) for lp, quality in sorted(potential_license_pools.items(), key=lambda x: -x[1]): if lp.deliverable and lp.work and quality >= 0.8: # This work has at least one deliverable LicensePool # associated with it, so it's likely to be real # data and not leftover junk. new_work = lp.work break if not new_work: # Try using the less reliable, more expensive method of # matching based on equivalent identifiers. equivalent_identifier_id_subquery = Identifier.recursively_equivalent_identifier_ids_query( self.edition.primary_identifier.id, policy=policy) pool_q = _db.query(LicensePool).filter( LicensePool.identifier_id.in_( equivalent_identifier_id_subquery)).order_by( LicensePool.licenses_available.desc(), LicensePool.patrons_in_hold_queue.asc()) pools = [x for x in pool_q if x.deliverable] for pool in pools: if pool.deliverable and pool.work: new_work = pool.work break old_work = self.work if old_work != new_work: if old_work: logging.info("Changing work for list entry %r to %r (was %r)", self.edition, new_work, old_work) else: logging.info("Setting work for list entry %r to %r", self.edition, new_work) self.work = new_work return self.work
def equivalent_editions(self, policy=None): """All Editions whose primary ID is equivalent to this Edition's primary ID, according to the given PresentationCalculationPolicy. """ _db = Session.object_session(self) identifier_id_subquery = Identifier.recursively_equivalent_identifier_ids_query( self.primary_identifier.id, policy=policy) return _db.query(Edition).filter( Edition.primary_identifier_id.in_(identifier_id_subquery))
def equivalent_identifiers(self, type=None, policy=None): """All Identifiers equivalent to this Edition's primary identifier, according to the given PresentationCalculationPolicy """ _db = Session.object_session(self) identifier_id_subquery = Identifier.recursively_equivalent_identifier_ids_query( self.primary_identifier.id, policy=policy) q = _db.query(Identifier).filter( Identifier.id.in_(identifier_id_subquery)) if type: if isinstance(type, list): q = q.filter(Identifier.type.in_(type)) else: q = q.filter(Identifier.type == type) return q.all()
def set_work(self, metadata=None, metadata_client=None, policy=None): """If possible, identify a locally known Work that is the same title as the title identified by this CustomListEntry. :param policy: A PresentationCalculationPolicy, used to determine how far to go when looking for equivalent Identifiers. """ _db = Session.object_session(self) edition = self.edition if not self.edition: # This shouldn't happen, but no edition means no work self.work = None return self.work new_work = None if not metadata: from ..metadata_layer import Metadata metadata = Metadata.from_edition(edition) # Try to guess based on metadata, if we can get a high-quality # guess. potential_license_pools = metadata.guess_license_pools( _db, metadata_client) for lp, quality in sorted( potential_license_pools.items(), key=lambda x: -x[1]): if lp.deliverable and lp.work and quality >= 0.8: # This work has at least one deliverable LicensePool # associated with it, so it's likely to be real # data and not leftover junk. new_work = lp.work break if not new_work: # Try using the less reliable, more expensive method of # matching based on equivalent identifiers. equivalent_identifier_id_subquery = Identifier.recursively_equivalent_identifier_ids_query( self.edition.primary_identifier.id, policy=policy ) pool_q = _db.query(LicensePool).filter( LicensePool.identifier_id.in_(equivalent_identifier_id_subquery)).order_by( LicensePool.licenses_available.desc(), LicensePool.patrons_in_hold_queue.asc()) pools = [x for x in pool_q if x.deliverable] for pool in pools: if pool.deliverable and pool.work: new_work = pool.work break old_work = self.work if old_work != new_work: if old_work: logging.info( "Changing work for list entry %r to %r (was %r)", self.edition, new_work, old_work ) else: logging.info( "Setting work for list entry %r to %r", self.edition, new_work ) self.work = new_work return self.work