Skip to content

Commit

Permalink
Rename collection library associations. (PP-1875) (#2195)
Browse files Browse the repository at this point in the history
* Rename Circulation `libraries` to `associated_libraries`.

* Rename Library `collections` to `associated_collections`.

* Rename a couple more library/collection association properties.
  • Loading branch information
tdilauro authored Nov 26, 2024
1 parent 0c5328e commit c741d34
Show file tree
Hide file tree
Showing 54 changed files with 149 additions and 139 deletions.
2 changes: 1 addition & 1 deletion src/palace/manager/api/admin/controller/admin_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def search_field_values(self) -> dict:
- Subject
"""
library = get_request_library()
collection_ids = [coll.id for coll in library.collections if coll.id]
collection_ids = [coll.id for coll in library.associated_collections if coll.id]
return self._search_field_values_cached(collection_ids)

@classmethod
Expand Down
4 changes: 2 additions & 2 deletions src/palace/manager/api/admin/controller/custom_lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def _get_work_from_urn(self, library: Library, urn: str | None) -> Work | None:
.join(LicensePool, LicensePool.work_id == Work.id)
.join(Collection, LicensePool.collection_id == Collection.id)
.filter(LicensePool.identifier_id == identifier.id)
.filter(Collection.id.in_([c.id for c in library.collections]))
.filter(Collection.id.in_([c.id for c in library.associated_collections]))
)
work = query.one()
return work
Expand Down Expand Up @@ -286,7 +286,7 @@ def _create_or_update_list(
if not collection:
self._db.rollback()
return MISSING_COLLECTION
if list.library not in collection.libraries:
if list.library not in collection.associated_libraries:
self._db.rollback()
return COLLECTION_NOT_ASSOCIATED_WITH_LIBRARY
new_collections.append(collection)
Expand Down
4 changes: 3 additions & 1 deletion src/palace/manager/api/admin/dashboard_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ def _authorized_collections(
all_collections = self._all_collections()

for library in authorized_libraries:
library_collections = {all_collections[c.id] for c in library.collections}
library_collections = {
all_collections[c.id] for c in library.associated_collections
}
authorized_collections_by_library[library.short_name] = sorted(
library_collections, key=lambda c: c.id
)
Expand Down
2 changes: 1 addition & 1 deletion src/palace/manager/api/circulation_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def load_settings(self):
collections: set[Collection] = set()
libraries_collections: dict[int | None, list[Collection]] = {}
for library in libraries:
library_collections = library.collections
library_collections = library.associated_collections
collections.update(library_collections)
libraries_collections[library.id] = library_collections

Expand Down
2 changes: 1 addition & 1 deletion src/palace/manager/api/controller/marc.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def download_page_body(self, session: Session, library: Library) -> str:

if len(marc_files) == 0:
# Are there any collections configured to export MARC records?
if any(c.export_marc_records for c in library.collections):
if any(c.export_marc_records for c in library.associated_collections):
return "<p>" + "MARC files aren't ready to download yet." + "</p>"
else:
return (
Expand Down
2 changes: 1 addition & 1 deletion src/palace/manager/api/controller/playtime_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def track_playtimes(self, collection_id, identifier_type, identifier_idn):
f"The collection {collection_id} was not found."
)

if collection not in library.collections:
if collection not in library.associated_collections:
return INVALID_INPUT.detailed("Collection was not found in the Library.")

if not identifier.licensed_through_collection(collection):
Expand Down
4 changes: 2 additions & 2 deletions src/palace/manager/api/lanes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1396,7 +1396,7 @@ def initialize(self, library_or_collections):
if isinstance(library_or_collections, Library):
# We're looking at all the collections in a given library.
library = library_or_collections
collections = library.collections
collections = library.associated_collections
identifier = library.name
else:
# We're looking at collections directly, without respect
Expand Down Expand Up @@ -1532,7 +1532,7 @@ def __init__(self, library, facets):
# Add one or more WorkLists for every collection in the
# system, so that a client can test borrowing a book from
# every collection.
for collection in sorted(library.collections, key=lambda x: x.name):
for collection in sorted(library.associated_collections, key=lambda x: x.name):
for medium in Edition.FULFILLABLE_MEDIA:
# Give each Worklist a name that is distinctive
# and easy for a client to parse.
Expand Down
2 changes: 1 addition & 1 deletion src/palace/manager/api/metadata/novelist.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ def get_items_from_query(self, library: Library) -> list[dict[str, str]]:
:return: a list of Novelist objects to send
"""
collectionList = []
for c in library.collections:
for c in library.associated_collections:
collectionList.append(c.id)

LEFT_OUTER_JOIN = True
Expand Down
4 changes: 2 additions & 2 deletions src/palace/manager/api/selftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def default_patrons(
- a failure SelfTestResult when it cannot.
"""
_db = Session.object_session(collection)
if not collection.libraries:
if not collection.associated_libraries:
yield cls.test_failure(
"Acquiring test patron credentials.",
"Collection is not associated with any libraries.",
Expand All @@ -60,7 +60,7 @@ def default_patrons(
# Not strictly necessary, but makes it obvious that we won't do anything else.
return

for library in collection.libraries:
for library in collection.associated_libraries:
task = "Acquiring test patron credentials for library %s" % library.name
try:
patron, password = cls._determine_self_test_patron(library, _db=_db)
Expand Down
4 changes: 2 additions & 2 deletions src/palace/manager/core/query/customlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ def share_locally_with_library(
f"Attempting to share customlist '{customlist.name}' with library '{library.name}'."
)
for collection in customlist.collections:
if collection not in library.collections:
if collection not in library.associated_collections:
log.info(
f"Unable to share customlist: Collection '{collection.name}' is missing from the library."
)
return CUSTOMLIST_SOURCE_COLLECTION_MISSING

# All entries must be valid for the library
library_collection_ids = [c.id for c in library.collections]
library_collection_ids = [c.id for c in library.associated_collections]
entry: CustomListEntry
missing_work_id_count = 0
for entry in customlist.entries:
Expand Down
4 changes: 2 additions & 2 deletions src/palace/manager/scripts/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ def do_run(self, _db=None, cmd_args=None, output=sys.stdout):
if library_names:
message += " I only know about: %s" % library_names
raise ValueError(message)
if collection not in library.collections:
collection.libraries.append(library)
if collection not in library.associated_collections:
collection.associated_libraries.append(library)
site_configuration_has_changed(_db)
_db.commit()
output.write("Configuration settings stored.\n")
Expand Down
8 changes: 5 additions & 3 deletions src/palace/manager/scripts/informational.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,9 @@ def explain_license_pool(self, pool):
self.write("Licensepool info:")
if pool.collection:
self.write(" Collection: %r" % pool.collection)
libraries = [library.name for library in pool.collection.libraries]
libraries = [
library.name for library in pool.collection.associated_libraries
]
if libraries:
self.write(" Available to libraries: %s" % ", ".join(libraries))
else:
Expand Down Expand Up @@ -472,10 +474,10 @@ def check_library(self, library):
self.out("Checking library %s", library.name)

# Make sure it has collections.
if not library.collections:
if not library.associated_collections:
self.out(" This library has no collections -- that's a problem.")
else:
for collection in library.collections:
for collection in library.associated_collections:
self.out(" Associated with collection %s.", collection.name)

# Make sure it has lanes.
Expand Down
2 changes: 1 addition & 1 deletion src/palace/manager/scripts/self_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def do_run(self, *args, **kwargs):
for library in parsed.libraries:
api_map = self.services.integration_registry.license_providers()
self.out.write("Testing %s\n" % library.name)
for collection in library.collections:
for collection in library.associated_collections:
try:
self.test_collection(collection, api_map)
except Exception as e:
Expand Down
2 changes: 1 addition & 1 deletion src/palace/manager/search/external_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,7 @@ def __init__(

if isinstance(collections, Library):
# Find all works in this Library's collections.
collections = collections.collections
collections = collections.associated_collections
self.collection_ids = self._filter_ids(collections)

self.media = media
Expand Down
2 changes: 1 addition & 1 deletion src/palace/manager/service/redis/models/patron_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ def collections_ready_for_sync(
patron activity sync. This indicates that the collection is ready to be
synced.
"""
collections = patron.library.collections
collections = patron.library.associated_collections
keys = [
cls._get_key(redis_client, patron.id, collection.id)
for collection in collections
Expand Down
2 changes: 1 addition & 1 deletion src/palace/manager/sqlalchemy/model/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def lookup_hook():
def can_see_collection(self, collection):
if self.is_system_admin():
return True
for library in collection.libraries:
for library in collection.associated_libraries:
if self.is_librarian(library):
return True
return False
Expand Down
4 changes: 2 additions & 2 deletions src/palace/manager/sqlalchemy/model/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class Collection(Base, HasSessionCache, RedisKeyMixin):

# A Collection can provide books to many Libraries.
# https://docs.sqlalchemy.org/en/14/orm/extensions/associationproxy.html#composite-association-proxies
libraries: Mapped[list[Library]] = association_proxy(
associated_libraries: Mapped[list[Library]] = association_proxy(
"integration_configuration", "libraries"
)

Expand Down Expand Up @@ -563,7 +563,7 @@ def delete(
_db = Session.object_session(self)

# Disassociate all libraries from this collection.
self.libraries.clear()
self.associated_libraries.clear()

# Delete all the license pools. This should be the only part
# of the application where LicensePools are permanently
Expand Down
4 changes: 2 additions & 2 deletions src/palace/manager/sqlalchemy/model/lane.py
Original file line number Diff line number Diff line change
Expand Up @@ -1499,7 +1499,7 @@ def initialize(
self.library_id = library.id
if self.collection_ids is None:
self.collection_ids = [
collection.id for collection in library.collection_ids
collection.id for collection in library.associated_collections_ids
]
self.display_name = display_name
if genres:
Expand Down Expand Up @@ -2782,7 +2782,7 @@ def get_library(self, _db):

@property
def collection_ids(self):
return [x.id for x in self.library.collections]
return [x.id for x in self.library.associated_collections]

@property
def children(self):
Expand Down
18 changes: 9 additions & 9 deletions src/palace/manager/sqlalchemy/model/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ class Library(Base, HasSessionCache):
uselist=False,
)

def collections_query(self, base_query: Select | None = None) -> Select:
def _associated_collections_query(self, base_query: Select | None = None) -> Select:
from palace.manager.sqlalchemy.model.collection import Collection
from palace.manager.sqlalchemy.model.integration import (
IntegrationConfiguration,
Expand All @@ -182,7 +182,7 @@ def collections_query(self, base_query: Select | None = None) -> Select:
)

@property
def collection_ids(self) -> list[CollectionInfoTuple]:
def associated_collections_ids(self) -> list[CollectionInfoTuple]:
"""Get the collection ids for this library"""
from palace.manager.sqlalchemy.model.collection import Collection
from palace.manager.sqlalchemy.model.integration import IntegrationConfiguration
Expand All @@ -191,15 +191,15 @@ def collection_ids(self) -> list[CollectionInfoTuple]:
query = select(Collection.id, IntegrationConfiguration.protocol).select_from(
Collection
)
query = self.collections_query(query)
query = self._associated_collections_query(query)
results = _db.execute(query).all()
return [CollectionInfoTuple(*row) for row in results]

@property
def collections(self) -> Sequence[Collection]:
"""Get the collections for this library"""
def associated_collections(self) -> Sequence[Collection]:
"""Get all associated collections for this library."""
_db = Session.object_session(self)
return _db.scalars(self.collections_query()).all()
return _db.scalars(self._associated_collections_query()).all()

# Cache of the libraries loaded settings object
_settings: LibrarySettings | None
Expand Down Expand Up @@ -323,14 +323,14 @@ def enabled_facets(self, group_name: str) -> list[str]:
"""Look up the enabled facets for a given facet group."""
if group_name == FacetConstants.DISTRIBUTOR_FACETS_GROUP_NAME:
enabled = []
for collection in self.collections:
for collection in self.associated_collections:
if collection.data_source and collection.data_source.name:
enabled.append(collection.data_source.name)
return list(set(enabled))

if group_name == FacetConstants.COLLECTION_NAME_FACETS_GROUP_NAME:
enabled = []
for collection in self.collections:
for collection in self.associated_collections:
if collection.name is not None:
enabled.append(collection.name)
return enabled
Expand Down Expand Up @@ -388,7 +388,7 @@ def restrict_to_ready_deliverable_works(
from palace.manager.sqlalchemy.model.collection import Collection

collection_ids = collection_ids or [
x.id for x in self.collections if x.id is not None
x.id for x in self.associated_collections if x.id is not None
]
return Collection.restrict_to_ready_deliverable_works(
query,
Expand Down
2 changes: 1 addition & 1 deletion src/palace/manager/sqlalchemy/model/work.py
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,7 @@ def active_license_pool(self, library: Library | None = None) -> LicensePool | N
# associated with a loan, were a loan to be issued right
# now.
active_license_pool = None
collections = [] if not library else [c for c in library.collections]
collections = [] if not library else [c for c in library.associated_collections]
for p in self.license_pools:
if collections and p.collection not in collections:
continue
Expand Down
8 changes: 4 additions & 4 deletions tests/fixtures/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ def _make_default_library(self) -> Library:
protocol=OPDSAPI,
settings=self.opds_settings(data_source="OPDS"),
)
collection.libraries.append(library)
collection.associated_libraries.append(library)
return library

@classmethod
Expand Down Expand Up @@ -470,7 +470,7 @@ def default_collection(self) -> Collection:
saves time.
"""
if not self._default_collection:
self._default_collection = self.default_library().collections[0]
self._default_collection = self.default_library().associated_collections[0]

return self._default_collection

Expand Down Expand Up @@ -606,8 +606,8 @@ def collection(
collection.integration_configuration.settings_dict = settings
flag_modified(collection.integration_configuration, "settings_dict")

if library and library not in collection.libraries:
collection.libraries.append(library)
if library and library not in collection.associated_libraries:
collection.associated_libraries.append(library)
return collection

def work(
Expand Down
6 changes: 3 additions & 3 deletions tests/fixtures/marc.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ def __init__(
self.collection2 = db.collection()
self.collection3 = db.collection()

self.collection1.libraries = [self.library1, self.library2]
self.collection2.libraries = [self.library1]
self.collection3.libraries = [self.library2]
self.collection1.associated_libraries = [self.library1, self.library2]
self.collection2.associated_libraries = [self.library1]
self.collection3.associated_libraries = [self.library2]

def integration(self) -> IntegrationConfiguration:
return self._db.integration_configuration(
Expand Down
Loading

0 comments on commit c741d34

Please sign in to comment.