diff --git a/src/palace/manager/api/admin/controller/admin_search.py b/src/palace/manager/api/admin/controller/admin_search.py index 9ab0a2f96..5fcdd24ff 100644 --- a/src/palace/manager/api/admin/controller/admin_search.py +++ b/src/palace/manager/api/admin/controller/admin_search.py @@ -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 diff --git a/src/palace/manager/api/admin/controller/custom_lists.py b/src/palace/manager/api/admin/controller/custom_lists.py index cb6680200..0b9a0a9b3 100644 --- a/src/palace/manager/api/admin/controller/custom_lists.py +++ b/src/palace/manager/api/admin/controller/custom_lists.py @@ -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 diff --git a/src/palace/manager/api/admin/dashboard_stats.py b/src/palace/manager/api/admin/dashboard_stats.py index 18fad5520..575b767fa 100644 --- a/src/palace/manager/api/admin/dashboard_stats.py +++ b/src/palace/manager/api/admin/dashboard_stats.py @@ -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 ) diff --git a/src/palace/manager/api/circulation_manager.py b/src/palace/manager/api/circulation_manager.py index 1a2c781ee..94130e20d 100644 --- a/src/palace/manager/api/circulation_manager.py +++ b/src/palace/manager/api/circulation_manager.py @@ -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 diff --git a/src/palace/manager/api/controller/marc.py b/src/palace/manager/api/controller/marc.py index cc6142689..019650411 100644 --- a/src/palace/manager/api/controller/marc.py +++ b/src/palace/manager/api/controller/marc.py @@ -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 "

" + "MARC files aren't ready to download yet." + "

" else: return ( diff --git a/src/palace/manager/api/controller/playtime_entries.py b/src/palace/manager/api/controller/playtime_entries.py index 58ff753c4..f05e4b0f7 100644 --- a/src/palace/manager/api/controller/playtime_entries.py +++ b/src/palace/manager/api/controller/playtime_entries.py @@ -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): diff --git a/src/palace/manager/api/lanes.py b/src/palace/manager/api/lanes.py index f532d4dbe..c071bc189 100644 --- a/src/palace/manager/api/lanes.py +++ b/src/palace/manager/api/lanes.py @@ -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 @@ -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. diff --git a/src/palace/manager/api/metadata/novelist.py b/src/palace/manager/api/metadata/novelist.py index 5fe38d0ef..84fcd4c43 100644 --- a/src/palace/manager/api/metadata/novelist.py +++ b/src/palace/manager/api/metadata/novelist.py @@ -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 diff --git a/src/palace/manager/core/query/customlist.py b/src/palace/manager/core/query/customlist.py index 398cc013a..a2b6a24b3 100644 --- a/src/palace/manager/core/query/customlist.py +++ b/src/palace/manager/core/query/customlist.py @@ -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: diff --git a/src/palace/manager/scripts/configuration.py b/src/palace/manager/scripts/configuration.py index 3cc0ff35a..f9dd92500 100644 --- a/src/palace/manager/scripts/configuration.py +++ b/src/palace/manager/scripts/configuration.py @@ -215,7 +215,7 @@ 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: + if collection not in library.associated_collections: collection.associated_libraries.append(library) site_configuration_has_changed(_db) _db.commit() diff --git a/src/palace/manager/scripts/informational.py b/src/palace/manager/scripts/informational.py index c9ab8bb4d..5a5ed34c0 100644 --- a/src/palace/manager/scripts/informational.py +++ b/src/palace/manager/scripts/informational.py @@ -474,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. diff --git a/src/palace/manager/scripts/self_test.py b/src/palace/manager/scripts/self_test.py index 1e20301da..7a2483deb 100644 --- a/src/palace/manager/scripts/self_test.py +++ b/src/palace/manager/scripts/self_test.py @@ -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: diff --git a/src/palace/manager/search/external_search.py b/src/palace/manager/search/external_search.py index 44191b8ae..7c326350f 100644 --- a/src/palace/manager/search/external_search.py +++ b/src/palace/manager/search/external_search.py @@ -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 diff --git a/src/palace/manager/service/redis/models/patron_activity.py b/src/palace/manager/service/redis/models/patron_activity.py index ca5992d62..2feaed471 100644 --- a/src/palace/manager/service/redis/models/patron_activity.py +++ b/src/palace/manager/service/redis/models/patron_activity.py @@ -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 diff --git a/src/palace/manager/sqlalchemy/model/lane.py b/src/palace/manager/sqlalchemy/model/lane.py index 0b3046048..7a6716a4a 100644 --- a/src/palace/manager/sqlalchemy/model/lane.py +++ b/src/palace/manager/sqlalchemy/model/lane.py @@ -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): diff --git a/src/palace/manager/sqlalchemy/model/library.py b/src/palace/manager/sqlalchemy/model/library.py index e8136a9c1..7389be9bc 100644 --- a/src/palace/manager/sqlalchemy/model/library.py +++ b/src/palace/manager/sqlalchemy/model/library.py @@ -196,8 +196,8 @@ def collection_ids(self) -> list[CollectionInfoTuple]: 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() @@ -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 @@ -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, diff --git a/src/palace/manager/sqlalchemy/model/work.py b/src/palace/manager/sqlalchemy/model/work.py index 80d6af970..90d85680e 100644 --- a/src/palace/manager/sqlalchemy/model/work.py +++ b/src/palace/manager/sqlalchemy/model/work.py @@ -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 diff --git a/tests/fixtures/database.py b/tests/fixtures/database.py index e6bff60f3..13933062d 100644 --- a/tests/fixtures/database.py +++ b/tests/fixtures/database.py @@ -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 diff --git a/tests/manager/api/admin/controller/test_collections.py b/tests/manager/api/admin/controller/test_collections.py index a91a1f8b3..620a74212 100644 --- a/tests/manager/api/admin/controller/test_collections.py +++ b/tests/manager/api/admin/controller/test_collections.py @@ -114,7 +114,7 @@ def test_collections_get_collections_with_multiple_collections( flask_app_fixture: FlaskAppFixture, db: DatabaseTransactionFixture, ) -> None: - [c1] = db.default_library().collections + [c1] = db.default_library().associated_collections c2 = db.collection( name="Collection 2", @@ -426,9 +426,9 @@ def test_collections_post_create( ) # Two libraries now have access to the collection. - assert [collection] == l1.collections - assert [collection] == l2.collections - assert [] == l3.collections + assert [collection] == l1.associated_collections + assert [collection] == l2.associated_collections + assert [] == l3.associated_collections # Additional settings were set on the collection. assert ( @@ -480,7 +480,7 @@ def test_collections_post_create( assert "website_id" not in child.integration_configuration.settings_dict # One library has access to the collection. - assert [child] == l3.collections + assert [child] == l3.associated_collections assert isinstance(l3.id, int) l3_settings = child.integration_configuration.for_library(l3.id) assert l3_settings is not None diff --git a/tests/manager/api/controller/test_base.py b/tests/manager/api/controller/test_base.py index 5bf9116c8..32840f5a2 100644 --- a/tests/manager/api/controller/test_base.py +++ b/tests/manager/api/controller/test_base.py @@ -196,7 +196,7 @@ def test_authentication_sends_proper_headers( def test_load_licensepools(self, circulation_fixture: CirculationControllerFixture): # Here's a Library that has two Collections. library = circulation_fixture.library - [c1] = library.collections + [c1] = library.associated_collections c2 = circulation_fixture.db.collection() c2.associated_libraries.append(library) diff --git a/tests/manager/api/controller/test_crawlfeed.py b/tests/manager/api/controller/test_crawlfeed.py index f0109abda..80385c9f4 100644 --- a/tests/manager/api/controller/test_crawlfeed.py +++ b/tests/manager/api/controller/test_crawlfeed.py @@ -79,7 +79,7 @@ def test_crawlable_library_feed( lane = kwargs.pop("worklist") assert isinstance(lane, CrawlableCollectionBasedLane) assert library.id == lane.library_id - assert [x.id for x in library.collections] == lane.collection_ids + assert [x.id for x in library.associated_collections] == lane.collection_ids assert {} == kwargs def test_crawlable_collection_feed( diff --git a/tests/manager/api/controller/test_loan.py b/tests/manager/api/controller/test_loan.py index 3837b7a8b..bc087ec3c 100644 --- a/tests/manager/api/controller/test_loan.py +++ b/tests/manager/api/controller/test_loan.py @@ -1419,8 +1419,10 @@ def test_active_loans( # We queued up a sync_patron_activity task to go sync the patrons information assert isinstance(patron, Patron) - assert sync_task.apply_async.call_count == len(patron.library.collections) - for library in patron.library.collections: + assert sync_task.apply_async.call_count == len( + patron.library.associated_collections + ) + for library in patron.library.associated_collections: sync_task.apply_async.assert_any_call( (library.id, patron.id, loan_fixture.valid_credentials["password"]), ) diff --git a/tests/manager/api/controller/test_multilib.py b/tests/manager/api/controller/test_multilib.py index 3c61bf418..5b6212b01 100644 --- a/tests/manager/api/controller/test_multilib.py +++ b/tests/manager/api/controller/test_multilib.py @@ -26,7 +26,7 @@ def make_default_collection(_db, library): external_account_id="http://url.com", data_source="OPDS" ) OPDSAPI.settings_update(collection.integration_configuration, settings) - library.collections.append(collection) + library.associated_collections.append(collection) return collection controller_fixture.circulation_manager_setup( diff --git a/tests/manager/api/test_lanes.py b/tests/manager/api/test_lanes.py index 05381ee89..5dbfd4014 100644 --- a/tests/manager/api/test_lanes.py +++ b/tests/manager/api/test_lanes.py @@ -933,7 +933,7 @@ def test_default(self, db: DatabaseTransactionFixture): # Except for distributor and collectionName, which have the default # and data for each collection in the library. for facet in [distributor, collectionName]: - assert len(facet) == 1 + len(db.default_library().collections) + assert len(facet) == 1 + len(db.default_library().associated_collections) @pytest.mark.parametrize( "group_name, expected", @@ -994,7 +994,9 @@ def test_init(self, db: DatabaseTransactionFixture): lane = CrawlableCollectionBasedLane() lane.initialize(library) assert "Crawlable feed: %s" % library.name == lane.display_name - assert {x.id for x in library.collections} == set(lane.collection_ids) + assert {x.id for x in library.associated_collections} == set( + lane.collection_ids + ) # A lane for specific collection, regardless of their library # affiliation. diff --git a/tests/manager/api/test_overdrive.py b/tests/manager/api/test_overdrive.py index 30c058e4d..2545b0488 100644 --- a/tests/manager/api/test_overdrive.py +++ b/tests/manager/api/test_overdrive.py @@ -2352,7 +2352,7 @@ def token_post( pin = "patron_pin" # clear out any collections added before we add ours - for collection in library.collections: + for collection in library.associated_collections: collection.associated_libraries = [] # Distinct credentials for the two OverDrive collections in which our diff --git a/tests/manager/scripts/test_configuration.py b/tests/manager/scripts/test_configuration.py index 68200c797..fea973f63 100644 --- a/tests/manager/scripts/test_configuration.py +++ b/tests/manager/scripts/test_configuration.py @@ -180,9 +180,9 @@ def test_success(self, db: DatabaseTransactionFixture): ) # Two libraries now have access to the collection. - assert [collection] == l1.collections - assert [collection] == l2.collections - assert [] == l3.collections + assert [collection] == l1.associated_collections + assert [collection] == l2.associated_collections + assert [] == l3.associated_collections # One CollectionSetting was set on the collection, in addition # to url, username, and password. diff --git a/tests/manager/scripts/test_self_test.py b/tests/manager/scripts/test_self_test.py index cdc0f0ce0..4721e329e 100644 --- a/tests/manager/scripts/test_self_test.py +++ b/tests/manager/scripts/test_self_test.py @@ -42,7 +42,7 @@ def test_collection(self, collection, api_map): # The default library is the only one with a collection; # test_collection() was called on that collection. [(collection, api_map)] = script.tested - assert [collection] == library1.collections + assert [collection] == library1.associated_collections # The API lookup map passed into test_collection() is a LicenseProvidersRegistry. assert isinstance(api_map, LicenseProvidersRegistry) diff --git a/tests/manager/search/test_external_search.py b/tests/manager/search/test_external_search.py index deefa677c..38398828d 100644 --- a/tests/manager/search/test_external_search.py +++ b/tests/manager/search/test_external_search.py @@ -3414,7 +3414,7 @@ def test_constructor(self, filter_fixture: FilterFixture): # If the library has no collections, the collection filter # will filter everything out. transaction.default_collection().associated_libraries = [] - assert transaction.default_library().collections == [] + assert transaction.default_library().associated_collections == [] library_filter = Filter(collections=transaction.default_library()) assert [] == library_filter.collection_ids diff --git a/tests/manager/sqlalchemy/model/test_collection.py b/tests/manager/sqlalchemy/model/test_collection.py index d8ce38e1a..3789af604 100644 --- a/tests/manager/sqlalchemy/model/test_collection.py +++ b/tests/manager/sqlalchemy/model/test_collection.py @@ -384,7 +384,7 @@ def test_disassociate_libraries( # It's gone. assert db.default_library() not in collection.associated_libraries - assert collection not in db.default_library().collections + assert collection not in db.default_library().associated_collections # The library-specific settings for that library have been deleted. library_config_ids = [ @@ -528,7 +528,7 @@ def test_delete( assert collection not in db.session.query(Collection).all() # The default library now has no collections. - assert [] == db.default_library().collections + assert [] == db.default_library().associated_collections # The collection based coverage record got deleted assert db.session.query(CoverageRecord).get(record.id) == None diff --git a/tests/manager/sqlalchemy/model/test_lane.py b/tests/manager/sqlalchemy/model/test_lane.py index 78183c53a..eba50eddd 100644 --- a/tests/manager/sqlalchemy/model/test_lane.py +++ b/tests/manager/sqlalchemy/model/test_lane.py @@ -1831,7 +1831,7 @@ def test_initialize(self, db: DatabaseTransactionFixture): # The Collections associated with the WorkList are those associated # with the Library. assert set(wl.collection_ids) == { - x.id for x in db.default_library().collections + x.id for x in db.default_library().associated_collections } # The Genres associated with the WorkList are the ones passed @@ -2955,14 +2955,14 @@ def test_works_from_database_end_to_end(self, db: DatabaseTransactionFixture): db.default_collection().associated_libraries = [] collection = db.collection() collection.associated_libraries.append(db.default_library()) - assert db.default_library().collections == [collection] + assert db.default_library().associated_collections == [collection] wl.initialize(db.default_library()) assert 0 == wl.works_from_database(db.session).count() # If a DatabaseBackedWorkList has no collections, it has no # books. collection.associated_libraries = [] - assert db.default_library().collections == [] + assert db.default_library().associated_collections == [] wl.initialize(db.default_library()) assert 0 == wl.works_from_database(db.session).count() diff --git a/tests/manager/sqlalchemy/model/test_library.py b/tests/manager/sqlalchemy/model/test_library.py index dede7840c..2f557b838 100644 --- a/tests/manager/sqlalchemy/model/test_library.py +++ b/tests/manager/sqlalchemy/model/test_library.py @@ -104,7 +104,7 @@ def test_collections(self, db: DatabaseTransactionFixture): parent = db.collection() db.default_collection().parent_id = parent.id - assert [db.default_collection()] == library.collections + assert [db.default_collection()] == library.associated_collections def test_estimated_holdings_by_language(self, db: DatabaseTransactionFixture): library = db.default_library()