feat: layed out promising collection syncing

This commit is contained in:
Hellow 2023-10-12 22:00:58 +02:00
parent 0bf0754f6e
commit 59d73ed07e
3 changed files with 140 additions and 1 deletions

View File

@ -17,3 +17,4 @@ regex~=2022.9.13
pyffmpeg~=2.4.2.18
ffmpeg-progress-yield~=0.7.8
pathvalidate~=2.5.2
guppy3~=3.1.3

View File

@ -6,9 +6,10 @@ from music_kraken.objects import (
Source,
DatabaseObject
)
from music_kraken.objects.new_collection import Collection
from music_kraken.utils.enums import SourcePages
"""
only_smile = Artist(
name="Only Smile",
source_list=[Source(SourcePages.BANDCAMP, "https://onlysmile.bandcamp.com/")],
@ -102,3 +103,47 @@ for _id, _object in objects_by_id.items():
print(_id, _object, sep=": ")
print(only_smile)
"""
c = Collection([Song(title="hi"), Song(title="hi2"), Song(title="hi3")])
c1 = Collection([Song(title="he"), Song(title="hi5")])
c11 = Collection([Song(title="wow how ultra subby")])
c2 = Collection([Song(title="heeee")])
b = Collection([Song(title="some b"), Song(title="other b")])
b1 = Collection([Song(title="sub b")])
b11 = Collection([Song(title="This shouldn't work")])
b1.contain_collection_inside(b11)
b.contain_collection_inside(b1)
b.contain_collection_inside(c1)
c.contain_collection_inside(c1)
c.contain_collection_inside(c2)
c1.contain_collection_inside(c11)
c1.contain_collection_inside(c11)
print(c.data)
print(c1.data)
c11.append(Song(title="after creation"))
print()
print(c.data, len(c))
print(c1.data)
print()
print("c: ", c)
print("b: ", b)
c.sync_with_other_collection(b)
print("synced: ")
print("c: ", c)
print("b: ", b)
print(c.data)
print(c._data)

View File

@ -0,0 +1,93 @@
from typing import List, Iterable, Iterator, Optional, TypeVar, Generic
import guppy
from guppy.heapy import Path
from .parents import DatabaseObject
T = TypeVar('T', bound=DatabaseObject)
hp = guppy.hpy()
def _replace_all_refs(replace_with, replace):
"""
NO
I have a very good reason to use this here
DONT use this anywhere else...
This replaces **ALL** references to replace with a reference to replace_with.
https://benkurtovic.com/2015/01/28/python-object-replacement.html
"""
for path in hp.iso(replace).pathsin:
relation = path.path[1]
if isinstance(relation, Path.R_INDEXVAL):
path.src.theone[relation.r] = replace_with
class Collection(Generic[T]):
_data: List[T]
shallow_list = property(fget=lambda self: self.data)
def __init__(self, data: Optional[Iterable[T]]) -> None:
self._data = []
self.contained_collections: List[Collection[T]] = []
self.extend(data)
def append(self, __object: T):
self._data.append(__object)
def extend(self, __iterable: Optional[Iterable[T]]):
if __iterable is None:
return
for __object in __iterable:
self.append(__object)
def sync_with_other_collection(self, equal_collection: "Collection"):
"""
If two collections always need to have the same values, this can be used.
Internally:
1. import the data from other to self
- _data
- contained_collections
2. replace all refs from the other object, with refs from this object
"""
if equal_collection is self:
return
# don't add the elements from the subelements from the other collection.
# this will be done in the next step.
self.extend(equal_collection._data)
# add all submodules
for equal_sub_collection in equal_collection.contained_collections:
self.contain_collection_inside(equal_sub_collection)
# now the ugly part
# replace all refs of the other element with this one
_replace_all_refs(self, equal_collection)
def contain_collection_inside(self, sub_collection: "Collection"):
"""
This collection will ALWAYS contain everything from the passed in collection
"""
if sub_collection in self.contained_collections:
return
self.contained_collections.append(sub_collection)
@property
def data(self) -> List[T]:
return [*self._data, *(__object for collection in self.contained_collections for __object in collection.shallow_list)]
def __len__(self) -> int:
return len(self._data) + sum(len(collection) for collection in self.contained_collections)
def __iter__(self) -> Iterator[T]:
for element in self._data:
yield element