Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename collection library associations. (PP-1875) #2195

Merged
merged 3 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -1500,7 +1500,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 @@ -2776,7 +2776,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 @@ -1165,7 +1165,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