fix/musify_artist_spam #27
@ -2,6 +2,8 @@ from __future__ import annotations
|
||||
|
||||
from collections import defaultdict
|
||||
from typing import TypeVar, Generic, Dict, Optional, Iterable, List, Iterator, Tuple, Generator, Union, Any, Set
|
||||
import copy
|
||||
|
||||
from .parents import OuterProxy
|
||||
from ..utils import object_trace
|
||||
from ..utils import output, BColors
|
||||
@ -47,8 +49,15 @@ class Collection(Generic[T]):
|
||||
|
||||
self.extend(data)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return id(self)
|
||||
|
||||
@property
|
||||
def collection_names(self) -> List[str]:
|
||||
return list(set(self._collection_for.values()))
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Collection({' | '.join(self._collection_for.values())} {id(self)})"
|
||||
return f"Collection({' | '.join(self.collection_names)} {id(self)})"
|
||||
|
||||
def _map_element(self, __object: T, no_unmap: bool = False, **kwargs):
|
||||
if not no_unmap:
|
||||
@ -104,8 +113,9 @@ class Collection(Generic[T]):
|
||||
"""
|
||||
|
||||
self._data.append(other)
|
||||
other._inner._is_in_collection.add(self)
|
||||
|
||||
# all of the existing hooks to get the defined datastructure
|
||||
# all of the existing hooks to get the defined datastructures
|
||||
for collection_attribute, generator in self.extend_object_to_attribute.items():
|
||||
other.__getattribute__(collection_attribute).extend(generator, **kwargs)
|
||||
|
||||
@ -148,32 +158,28 @@ class Collection(Generic[T]):
|
||||
|
||||
object_trace(f"Appending {other.option_string} to {self}")
|
||||
|
||||
|
||||
for c in self.pull_from:
|
||||
r = c._find_object(other)
|
||||
if r is not None:
|
||||
output("found pull from", r, other, self, color=BColors.RED, sep="\t")
|
||||
other.merge(r, **kwargs)
|
||||
c.remove(r, existing=r, **kwargs)
|
||||
break
|
||||
|
||||
existing_object = self._find_object(other)
|
||||
|
||||
# switching collection in the case of push to
|
||||
for c in self.push_to:
|
||||
r = c._find_object(other)
|
||||
if r is not None:
|
||||
output("found push to", r, other, self, color=BColors.RED, sep="\t")
|
||||
if existing_object is not None:
|
||||
self.remove(existing_object)
|
||||
# output("found push to", r, other, c, self, color=BColors.RED, sep="\t")
|
||||
return c.append(other, **kwargs)
|
||||
|
||||
for c in self.pull_from:
|
||||
r = c._find_object(other)
|
||||
if r is not None:
|
||||
# output("found pull from", r, other, c, self, color=BColors.RED, sep="\t")
|
||||
c.remove(r, existing=r, **kwargs)
|
||||
|
||||
if existing_object is None:
|
||||
existing = self._find_object(other)
|
||||
|
||||
if existing is None:
|
||||
self._append_new_object(other, **kwargs)
|
||||
else:
|
||||
existing_object.merge(other, **kwargs)
|
||||
existing.merge(other, **kwargs)
|
||||
|
||||
def remove(self, *other_list: List[T], silent: bool = False, existing: Optional[T] = None, **kwargs):
|
||||
def remove(self, *other_list: List[T], silent: bool = False, existing: Optional[T] = None, remove_from_other_collection=True, **kwargs):
|
||||
other: T
|
||||
for other in other_list:
|
||||
existing: Optional[T] = existing or self._indexed_values["id"].get(other.id, None)
|
||||
if existing is None:
|
||||
@ -181,14 +187,13 @@ class Collection(Generic[T]):
|
||||
raise ValueError(f"Object {other} not found in {self}")
|
||||
return other
|
||||
|
||||
for collection_attribute, generator in self.extend_object_to_attribute.items():
|
||||
other.__getattribute__(collection_attribute).remove(*generator, silent=True, **kwargs)
|
||||
|
||||
for attribute, new_object in self.append_object_to_attribute.items():
|
||||
other.__getattribute__(attribute).remove(new_object, silent=True, **kwargs)
|
||||
|
||||
self._data.remove(existing)
|
||||
self._unmap_element(existing)
|
||||
if remove_from_other_collection:
|
||||
for c in copy.copy(other._inner._is_in_collection):
|
||||
c.remove(other, silent=True, remove_from_other_collection=False, **kwargs)
|
||||
other._inner._is_in_collection = set()
|
||||
else:
|
||||
self._data.remove(existing)
|
||||
self._unmap_element(existing)
|
||||
|
||||
def contains(self, __object: T) -> bool:
|
||||
return self._find_object(__object) is not None
|
||||
|
@ -29,12 +29,15 @@ class InnerData:
|
||||
"""
|
||||
|
||||
_refers_to_instances: set = None
|
||||
_is_in_collection: set = None
|
||||
"""
|
||||
Attribute versions keep track, of if the attribute has been changed.
|
||||
"""
|
||||
|
||||
def __init__(self, object_type, **kwargs):
|
||||
self._refers_to_instances = set()
|
||||
self._is_in_collection = set()
|
||||
|
||||
self._fetched_from: dict = {}
|
||||
|
||||
# initialize the default values
|
||||
@ -58,6 +61,7 @@ class InnerData:
|
||||
"""
|
||||
|
||||
self._fetched_from.update(__other._fetched_from)
|
||||
self._is_in_collection.update(__other._is_in_collection)
|
||||
|
||||
for key, value in __other.__dict__.copy().items():
|
||||
if key.startswith("_"):
|
||||
|
@ -222,17 +222,9 @@ class Song(Base):
|
||||
r = OPTION_FOREGROUND.value + self.title_string + BColors.ENDC.value + OPTION_BACKGROUND.value
|
||||
r += get_collection_string(self.album_collection, " from {}", ignore_titles={self.title})
|
||||
r += get_collection_string(self.main_artist_collection, " by {}")
|
||||
r += get_collection_string(self.feature_artist_collection, " feat. {}" if not self.main_artist_collection.empty or True else " by {}")
|
||||
r += get_collection_string(self.feature_artist_collection, " feat. {}")
|
||||
return r
|
||||
|
||||
@property
|
||||
def options(self) -> List[P]:
|
||||
options = self.main_artist_collection.shallow_list
|
||||
options.extend(self.feature_artist_collection)
|
||||
options.extend(self.album_collection)
|
||||
options.append(self)
|
||||
return options
|
||||
|
||||
@property
|
||||
def tracksort_str(self) -> str:
|
||||
"""
|
||||
@ -260,7 +252,6 @@ class Album(Base):
|
||||
barcode: str
|
||||
albumsort: int
|
||||
notes: FormattedText
|
||||
artwork: Artwork
|
||||
|
||||
source_collection: SourceCollection
|
||||
|
||||
@ -279,7 +270,6 @@ class Album(Base):
|
||||
"language": lambda: Language.by_alpha_2("en"),
|
||||
"date": ID3Timestamp,
|
||||
"notes": FormattedText,
|
||||
"artwork": Artwork,
|
||||
|
||||
"source_collection": SourceCollection,
|
||||
"artist_collection": Collection,
|
||||
|
Loading…
Reference in New Issue
Block a user