From a998e52cd94b7f13569fdb7260cfb8a065a3206a Mon Sep 17 00:00:00 2001 From: Lars Noack Date: Fri, 19 Apr 2024 17:45:49 +0200 Subject: [PATCH] fix: syncing --- development/objects_collection.py | 97 ++++++------------------------ music_kraken/objects/collection.py | 25 ++++++-- music_kraken/objects/parents.py | 6 ++ music_kraken/objects/song.py | 1 + music_kraken/utils/__init__.py | 1 + music_kraken/utils/shared.py | 2 +- tests/test_collection.py | 46 +++++++++++++- 7 files changed, 91 insertions(+), 87 deletions(-) diff --git a/development/objects_collection.py b/development/objects_collection.py index 9e147f5..c7526dc 100644 --- a/development/objects_collection.py +++ b/development/objects_collection.py @@ -2,91 +2,30 @@ import music_kraken from music_kraken.objects import Song, Album, Artist, Collection if __name__ == "__main__": - artist: Artist = Artist( - name="artist", - main_album_list=[ - Album( - title="album", - song_list=[ - Song( - title="song", - album_list=[ - Album( - title="album", - albumsort=123, - main_artist=Artist(name="artist"), - ), - ], - ), - Song( - title="other_song", - album_list=[ - Album(title="album", albumsort=423), - ], - ), - ] - ), - Album(title="album", barcode="1234567890123"), + album_1 = Album( + title="album", + song_list=[ + Song(title="song", main_artist_list=[Artist(name="artist")]), + ], + artist_list=[ + Artist(name="artist 3"), ] ) - - other_artist: Artist = Artist( - name="artist", - main_album_list=[ - Album( - title="album", - song_list=[ - Song( - title="song", - album_list=[ - Album( - title="album", - albumsort=123, - main_artist=Artist(name="other_artist"), - ), - ], - ), - Song( - title="other_song", - album_list=[ - Album(title="album", albumsort=423), - ], - ), - ] - ), - Album(title="album", barcode="1234567890123"), + album_2 = Album( + title="album", + song_list=[ + Song(title="song", main_artist_list=[Artist(name="artist 2")]), + ], + artist_list=[ + Artist(name="artist"), ] ) - artist.merge(other_artist) + album_1.merge(album_2) - a = artist.main_album_collection[0] - b = a.song_collection[0].album_collection[0] - c = a.song_collection[1].album_collection[0] - d = b.song_collection[0].album_collection[0] - e = d.song_collection[0].album_collection[0] - f = e.song_collection[0].album_collection[0] - g = f.song_collection[0].album_collection[0] - - print(a.id, a.title, a.barcode, a.albumsort) - print(b.id, b.title, b.barcode, b.albumsort) - print(c.id, c.title, c.barcode, c.albumsort) - print(d.id, d.title, d.barcode, d.albumsort) - print(e.id, e.title, e.barcode, e.albumsort) - print(f.id, f.title, f.barcode, f.albumsort) - print(g.id, g.title, g.barcode, g.albumsort) print() + print(album_1.artist_collection.data) - d.title = "new_title" - - print(a.id, a.title, a.barcode, a.albumsort) - print(b.id, b.title, b.barcode, b.albumsort) - print(c.id, c.title, c.barcode, c.albumsort) - print(d.id, d.title, d.barcode, d.albumsort) - print(e.id, e.title, e.barcode, e.albumsort) - print(f.id, f.title, f.barcode, f.albumsort) - print(g.id, g.title, g.barcode, g.albumsort) - print() - - print(artist.main_album_collection._indexed_values) \ No newline at end of file + print(id(album_1.artist_collection), id(album_2.artist_collection)) + print(id(album_1.song_collection[0].main_artist_collection), id(album_2.song_collection[0].main_artist_collection)) \ No newline at end of file diff --git a/music_kraken/objects/collection.py b/music_kraken/objects/collection.py index 1d62116..c13a294 100644 --- a/music_kraken/objects/collection.py +++ b/music_kraken/objects/collection.py @@ -3,6 +3,7 @@ from __future__ import annotations from collections import defaultdict from typing import TypeVar, Generic, Dict, Optional, Iterable, List, Iterator, Tuple, Generator, Union from .parents import OuterProxy +from ..utils import object_trace T = TypeVar('T', bound=OuterProxy) @@ -25,6 +26,8 @@ class Collection(Generic[T]): contain_attribute_in_given: Dict[str, Collection] = None, append_object_to_attribute: Dict[str, T] = None ) -> None: + self._collection_for: dict = dict() + self._contains_ids = set() self._data = [] @@ -44,6 +47,9 @@ class Collection(Generic[T]): self.extend(data) + def __repr__(self) -> str: + return f"Collection({id(self)})" + def _map_element(self, __object: T, from_map: bool = False): self._contains_ids.add(__object.id) @@ -224,16 +230,25 @@ class Collection(Generic[T]): append_to._data.append(__object) append_to._map_element(__object) - # only modify collections if the object actually has been appended for collection_attribute, child_collection in self.contain_given_in_attribute.items(): __object.__getattribute__(collection_attribute).contain_collection_inside(child_collection, __object) for attribute, new_object in self.append_object_to_attribute.items(): __object.__getattribute__(attribute).append(new_object) - - for attribute, collection in self.sync_on_append.items(): - collection.extend(__object.__getattribute__(attribute)) - __object.__setattr__(attribute, collection) + + # only modify collections if the object actually has been appended + for attribute, a in self.sync_on_append.items(): + b = __object.__getattribute__(attribute) + object_trace(f"Syncing [{a}{id(a)}] = [{b}{id(b)}]") + + data_to_extend = b.data + + a._collection_for.update(b._collection_for) + for synced_with, key in b._collection_for.items(): + synced_with.__setattr__(key, a) + + a.extend(data_to_extend) + else: # merge only if the two objects are not the same diff --git a/music_kraken/objects/parents.py b/music_kraken/objects/parents.py index 4e87cfb..a0bad1e 100644 --- a/music_kraken/objects/parents.py +++ b/music_kraken/objects/parents.py @@ -44,8 +44,13 @@ class InnerData: self._default_values[name] = factory() for key, value in kwargs.items(): + if hasattr(value, "__is_collection__"): + value._collection_for[self] = key self.__setattr__(key, value) + def __hash__(self): + return self.id + def __merge__(self, __other: InnerData, override: bool = False): """ :param __other: @@ -116,6 +121,7 @@ class OuterProxy: self._inner._refers_to_instances.add(self) object_trace(f"creating {type(self).__name__} [{self.title_string}]") + self.__init_collections__() for name, data_list in collection_data.items(): diff --git a/music_kraken/objects/song.py b/music_kraken/objects/song.py index 9a068bf..93b39ba 100644 --- a/music_kraken/objects/song.py +++ b/music_kraken/objects/song.py @@ -204,6 +204,7 @@ class Album(Base): notes: FormattedText source_collection: SourceCollection + artist_collection: Collection[Artist] song_collection: Collection[Song] label_collection: Collection[Label] diff --git a/music_kraken/utils/__init__.py b/music_kraken/utils/__init__.py index b9715e3..2b63305 100644 --- a/music_kraken/utils/__init__.py +++ b/music_kraken/utils/__init__.py @@ -2,6 +2,7 @@ from datetime import datetime from pathlib import Path import json import logging +import inspect from .shared import DEBUG, DEBUG_LOGGING, DEBUG_DUMP, DEBUG_TRACE, DEBUG_OBJECT_TRACE, DEBUG_OBJECT_TRACE_CALLSTACK from .config import config, read_config, write_config diff --git a/music_kraken/utils/shared.py b/music_kraken/utils/shared.py index 638e6a4..6397fd3 100644 --- a/music_kraken/utils/shared.py +++ b/music_kraken/utils/shared.py @@ -16,7 +16,7 @@ DEBUG = (__stage__ == "dev") and True DEBUG_LOGGING = DEBUG and False DEBUG_TRACE = DEBUG and True DEBUG_OBJECT_TRACE = DEBUG and True -DEBUG_OBJECT_TRACE_CALLSTACK = DEBUG and False +DEBUG_OBJECT_TRACE_CALLSTACK = DEBUG and True DEBUG_YOUTUBE_INITIALIZING = DEBUG and False DEBUG_PAGES = DEBUG and False DEBUG_DUMP = DEBUG and False diff --git a/tests/test_collection.py b/tests/test_collection.py index 85b1941..7a9e3ca 100644 --- a/tests/test_collection.py +++ b/tests/test_collection.py @@ -70,7 +70,50 @@ class TestCollection(unittest.TestCase): self.assertTrue(a.name == b.name == c.name == d.name == "artist") self.assertTrue(a.country == b.country == c.country == d.country) - """ + def test_artist_artist_relation(self): + artist = Artist( + name="artist", + main_album_list=[ + Album( + title="album", + song_list=[ + Song(title="song"), + ], + artist_list=[ + Artist(name="artist"), + ] + ) + ] + ) + + self.assertTrue(artist.id == artist.main_album_collection[0].song_collection[0].artist_collection[0].id) + + def test_artist_collection_sync(self): + album_1 = Album( + title="album", + song_list=[ + Song(title="song", main_artist_list=[Artist(name="artist")]), + ], + artist_list=[ + Artist(name="artist"), + ] + ) + + album_2 = Album( + title="album", + song_list=[ + Song(title="song", main_artist_list=[Artist(name="artist")]), + ], + artist_list=[ + Artist(name="artist"), + ] + ) + + album_1.merge(album_2) + + self.assertTrue(id(album_1.artist_collection) == id(album_1.artist_collection)) + self.assertTrue(id(album_1.song_collection[0].main_artist_collection) == id(album_1.song_collection[0].main_artist_collection)) + def test_song_artist_relations(self): a = self.complicated_object() b = a.main_album_collection[0].song_collection[0].main_artist_collection[0] @@ -80,7 +123,6 @@ class TestCollection(unittest.TestCase): self.assertTrue(a.id == b.id == c.id == d.id) self.assertTrue(a.name == b.name == c.name == d.name == "artist") self.assertTrue(a.country == b.country == c.country == d.country) - """ if __name__ == "__main__": unittest.main()