feat: huge conceptual improvements to merging

This commit is contained in:
Hellow 2023-10-24 14:53:29 +02:00
parent 11c2917dad
commit b34e9be52a
4 changed files with 64 additions and 18 deletions

View File

@ -9,7 +9,7 @@ from music_kraken.objects import (
from music_kraken.objects.collection import Collection from music_kraken.objects.collection import Collection
from music_kraken.utils.enums import SourcePages from music_kraken.utils.enums import SourcePages
"""
only_smile = Artist( only_smile = Artist(
name="Only Smile", name="Only Smile",
source_list=[Source(SourcePages.BANDCAMP, "https://onlysmile.bandcamp.com/")], source_list=[Source(SourcePages.BANDCAMP, "https://onlysmile.bandcamp.com/")],
@ -103,7 +103,7 @@ for _id, _object in objects_by_id.items():
print(_id, _object, sep=": ") print(_id, _object, sep=": ")
print(only_smile) print(only_smile)
"""
c = Collection([Song(title="hi"), Song(title="hi2"), Song(title="hi3")]) c = Collection([Song(title="hi"), Song(title="hi2"), Song(title="hi3")])
c1 = Collection([Song(title="he"), Song(title="hi5")]) c1 = Collection([Song(title="he"), Song(title="hi5")])
@ -139,7 +139,7 @@ print(other_song)
print() print()
print(c.data, len(c)) print(c.data, len(c))
print(c1.data) print(c1.data)
print([obj.genre for obj in c.data]) print([(obj.genre or "various") + ":" + obj.title for obj in c.data])
print() print()
print("c: ", c) print("c: ", c)

View File

@ -73,15 +73,51 @@ class Collection(Generic[T], metaclass=MetaClass):
return True return True
return False return False
def _contained_in(self, __object: T) -> Optional["Collection"]: def _get_root_collections(self) -> List["Collection"]:
if not len(self.upper_collections):
return [self]
root_collections = []
for upper_collection in self.upper_collections:
root_collections.extend(upper_collection._get_root_collections())
return root_collections
@property
def _is_root(self) -> bool:
return len(self.upper_collections) <= 0
def _contained_in_sub(self, __object: T, break_at_first: bool = True) -> List["Collection"]:
results = []
if self._contained_in_self(__object): if self._contained_in_self(__object):
return self return [self]
for collection in self.contained_collections: for collection in self.contained_collections:
if collection._contained_in_self(__object): results.extend(collection._contained_in_sub(__object, break_at_first=break_at_first))
return collection if break_at_first:
return results
return results
def _get_parents_of_multiple_contained_children(self, __object: T):
results = []
if len(self.contained_collections) < 2 or self._contained_in_self(__object):
return results
count = 0
for collection in self.contained_collections:
sub_results = collection._get_parents_of_multiple_contained_children(__object)
if len(sub_results) > 0:
count += 1
results.extend(sub_results)
if count >= 2:
results.append(self)
return results
return None
def _merge_in_self(self, __object: T): def _merge_in_self(self, __object: T):
""" """
@ -110,23 +146,31 @@ class Collection(Generic[T], metaclass=MetaClass):
self._map_element(existing_object) self._map_element(existing_object)
def contains(self, __object: T) -> bool: def contains(self, __object: T) -> bool:
return self._contained_in(__object) is not None return len(self._contained_in_sub(__object)) > 0
def _append(self, __object: T): def _append(self, __object: T):
self._map_element(__object) self._map_element(__object)
self._data.append(__object) self._data.append(__object)
def append(self, __object: Optional[T]): def append(self, __object: Optional[T], already_is_parent: bool = False):
if __object is None: if __object is None:
return return
exists_in_collection = self._contained_in(__object) exists_in_collection = self._contained_in_sub(__object)
if len(exists_in_collection) and self is exists_in_collection[0]:
# assuming that the object already is contained in the correct collections
if not already_is_parent:
self._merge_in_self(__object)
return
if exists_in_collection is None: if not len(exists_in_collection):
self._append(__object) self._append(__object)
else: else:
exists_in_collection._merge_in_self(__object) exists_in_collection[0]._merge_in_self(__object)
if not already_is_parent or not self._is_root:
for parent_collection in self._get_parents_of_multiple_contained_children(__object):
parent_collection.append(__object, already_is_parent=True)
def extend(self, __iterable: Optional[Iterable[T]]): def extend(self, __iterable: Optional[Iterable[T]]):
if __iterable is None: if __iterable is None:
@ -135,6 +179,7 @@ class Collection(Generic[T], metaclass=MetaClass):
for __object in __iterable: for __object in __iterable:
self.append(__object) self.append(__object)
def sync_with_other_collection(self, equal_collection: "Collection"): def sync_with_other_collection(self, equal_collection: "Collection"):
""" """
If two collections always need to have the same values, this can be used. If two collections always need to have the same values, this can be used.

View File

@ -1,3 +1,4 @@
from __future__ import annotations
import random import random
from collections import defaultdict from collections import defaultdict
from typing import Optional, Dict, Tuple, List, Type, Generic, TypeVar, Any from typing import Optional, Dict, Tuple, List, Type, Generic, TypeVar, Any
@ -94,17 +95,17 @@ class DatabaseObject(metaclass=MetaClass):
self.build_version = -1 self.build_version = -1
@property @property
def upwards_collection(self) -> "Collection": def upwards_collection(self) -> Collection:
for attribute in self._upwards_collection_attributes: for attribute in self._upwards_collection_attributes:
yield attribute.get() yield attribute.get()
@property @property
def downwards_collection(self) -> "Collection": def downwards_collection(self) -> Collection:
for attribute in self._downwards_collection_attributes: for attribute in self._downwards_collection_attributes:
yield attribute.get() yield attribute.get()
@property @property
def all_collections(self) -> "Collection": def all_collections(self) -> Collection:
for attribute in self._collection_attributes: for attribute in self._collection_attributes:
yield attribute.get() yield attribute.get()

View File

@ -594,7 +594,7 @@ class Artist(MainObject):
self.unformated_location: Optional[str] = unformated_location self.unformated_location: Optional[str] = unformated_location
self.source_collection: SourceCollection = SourceCollection(source_list) self.source_collection: SourceCollection = SourceCollection(source_list)
self.contact_collection: Collection[Label] = Collection(data=contact_list, element_type=Contact) self.contact_collection: Collection[Label] = Collection(data=contact_list)
self.feature_song_collection: Collection[Song] = Collection( self.feature_song_collection: Collection[Song] = Collection(
data=feature_song_list, data=feature_song_list,