diff --git a/music_kraken/objects/artwork.py b/music_kraken/objects/artwork.py index 178edf6..4421f05 100644 --- a/music_kraken/objects/artwork.py +++ b/music_kraken/objects/artwork.py @@ -1,18 +1,14 @@ from __future__ import annotations -from typing import List, Optional, Dict, Tuple, Type, Union, TypedDict - -from .collection import Collection -from .metadata import ( - Mapping as id3Mapping, - ID3Timestamp, - Metadata -) -from ..utils.string_processing import unify, hash_url - -from .parents import OuterProxy as Base +from typing import Dict, List, Optional, Set, Tuple, Type, TypedDict, Union from ..utils.config import main_settings +from ..utils.string_processing import hash_url, unify +from .collection import Collection +from .metadata import ID3Timestamp +from .metadata import Mapping as id3Mapping +from .metadata import Metadata +from .parents import OuterProxy as Base class ArtworkVariant(TypedDict): @@ -23,7 +19,9 @@ class ArtworkVariant(TypedDict): class Artwork: - def __init__(self, *variants: List[ArtworkVariant]) -> None: + def __init__(self, *variants: List[ArtworkVariant], parent_artworks: Set[Artwork] = None) -> None: + self.parent_artworks: Set[Artwork] = parent_artworks or set() + self._variant_mapping: Dict[str, ArtworkVariant] = {} for variant in variants: @@ -36,7 +34,7 @@ class Artwork: def append(self, url: str, width: int = main_settings["preferred_artwork_resolution"], height: int = main_settings["preferred_artwork_resolution"], **kwargs) -> None: if url is None: return - + self._variant_mapping[hash_url(url=url)] = { "url": url, "width": width, @@ -44,21 +42,36 @@ class Artwork: "deviation": self._calculate_deviation(width, height), } + @property + def flat_empty(self) -> bool: + return len(self._variant_mapping.keys()) <= 0 + + def _get_best_from_list(self, artwork_variants: List[ArtworkVariant]) -> Optional[ArtworkVariant]: + return min(artwork_variants, key=lambda x: x["deviation"]) + @property def best_variant(self) -> ArtworkVariant: - if len(self._variant_mapping.keys()) <= 0: - return None - return min(self._variant_mapping.values(), key=lambda x: x["deviation"]) + if self.flat_empty: + return self._get_best_from_list([parent.best_variant for parent in self.parent_artworks]) + return self._get_best_from_list(self._variant_mapping.values()) def get_variant_name(self, variant: ArtworkVariant) -> str: return f"artwork_{variant['width']}x{variant['height']}_{hash_url(variant['url']).replace('/', '_')}" def __merge__(self, other: Artwork, **kwargs) -> None: + self.parent_artworks.update(other.parent_artworks) + for key, value in other._variant_mapping.items(): if key not in self._variant_mapping: self._variant_mapping[key] = value + def __hash__(self) -> int: + return id(self) + def __eq__(self, other: Artwork) -> bool: + if hash(self) == hash(other): + return True + if not isinstance(other, Artwork): return False return any(a == b for a, b in zip(self._variant_mapping.keys(), other._variant_mapping.keys()))