fix: correct collections
This commit is contained in:
		@@ -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,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user