feat: layed out promising collection syncing
This commit is contained in:
parent
0bf0754f6e
commit
59d73ed07e
@ -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
|
||||
|
@ -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)
|
||||
|
93
src/music_kraken/objects/new_collection.py
Normal file
93
src/music_kraken/objects/new_collection.py
Normal 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
|
Loading…
Reference in New Issue
Block a user