draft implemented add_data

This commit is contained in:
2024-06-06 17:53:17 +02:00
parent df98a70717
commit 4e50bb1fba
11 changed files with 255 additions and 61 deletions

View File

@@ -1,8 +1,12 @@
from __future__ import annotations
from copy import copy
from dataclasses import dataclass, field
from typing import Dict, List, Optional, Set, Tuple, Type, TypedDict, Union
from ..utils import create_dataclass_instance, custom_hash
from ..utils.config import main_settings
from ..utils.enums import PictureType
from ..utils.string_processing import hash_url, unify
from .collection import Collection
from .metadata import ID3Timestamp
@@ -11,37 +15,113 @@ from .metadata import Metadata
from .parents import OuterProxy as Base
class ArtworkVariant(TypedDict):
@dataclass
class ArtworkVariant:
url: str
width: int
height: int
deviation: float
width: Optional[int] = None
height: Optional[int] = None
image_format: Optional[str] = ""
def __hash__(self) -> int:
return custom_hash(self.url)
def __eq__(self, other: ArtworkVariant) -> bool:
return hash(self) == hash(other)
def __contains__(self, other: str) -> bool:
return custom_hash(other) == hash(self.url)
@dataclass
class Artwork:
variants: List[ArtworkVariant] = field(default_factory=list)
artwork_type: PictureType = PictureType.OTHER
def search_variant(self, url: str) -> Optional[ArtworkVariant]:
if url is None:
return None
for variant in self.variants:
if url in variant:
return variant
return None
def __contains__(self, other: str) -> bool:
return self.search_variant(other) is not None
def add_data(self, **kwargs) -> None:
variant = self.search_variant(kwargs.get("url"))
if variant is None:
variant, kwargs = create_dataclass_instance(ArtworkVariant, **kwargs)
self.variants.append(variant)
variant.url = url
variant.__dict__.update(kwargs)
class ArtworkCollection:
def __init__(self, *variants: List[ArtworkVariant], parent_artworks: Set[ArtworkCollection] = None, crop_images: bool = True) -> None:
self.crop_images: bool = crop_images
"""
Stores all the images/artworks for one data object.
There could be duplicates before calling ArtworkCollection.compile()
_this is called before one object is downloaded automatically._
"""
artwork_type: PictureType = PictureType.OTHER
def __init__(
self,
*data: List[Union[Artwork, ArtworkVariant, dict]],
parent_artworks: Set[ArtworkCollection] = None,
crop_images: bool = True
) -> None:
# this is used for the song artwork, to fall back to the song artwork
self.parent_artworks: Set[ArtworkCollection] = parent_artworks or set()
self.crop_images: bool = crop_images
self._variant_mapping: Dict[str, ArtworkVariant] = {}
self._data = []
for variant in variants:
self.append(**variant)
def search_artwork(self, url: str) -> Optional[ArtworkVariant]:
for artwork in self._data:
if url in artwork:
return artwork
@staticmethod
def _calculate_deviation(*dimensions: List[int]) -> float:
return sum(abs(d - main_settings["preferred_artwork_resolution"]) for d in dimensions) / len(dimensions)
return None
def __contains__(self, other: str) -> bool:
return self.search_artwork(other) is not None
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:
def _create_new_artwork(self, **kwargs) -> Tuple[Artwork, dict]:
kwargs["artwork_type"] = kwargs.get("artwork_type", self.artwork_type)
return create_dataclass_instance(Artwork, **kwargs)
def add_data(self, url: str, **kwargs) -> None:
kwargs["url"] = url
artwork = self.search_artwork(url)
if artwork is None:
artwork, kwargs = self._create_new_artwork(url=url, **kwargs)
self._data.append(artwork)
artwork.add_data(url, **kwargs)
def append(self, value: Union[Artwork, ArtworkVariant, dict], **kwargs):
if isinstance(value, dict):
kwargs.update(value)
value, kwargs = create_dataclass_instance(ArtworkVariant, kwargs)
if isinstance(value, ArtworkVariant):
kwargs["variants"] = [value]
value, kwargs = create_dataclass_instance(Artwork, kwargs)
if isinstance(value, Artwork):
self._data.append(value)
return
self._variant_mapping[hash_url(url=url)] = {
"url": url,
"width": width,
"height": height,
"deviation": self._calculate_deviation(width, height),
}
@property
def flat_empty(self) -> bool:
@@ -69,14 +149,6 @@ class ArtworkCollection:
def __hash__(self) -> int:
return id(self)
def __eq__(self, other: ArtworkCollection) -> bool:
if hash(self) == hash(other):
return True
if not isinstance(other, ArtworkCollection):
return False
return any(a == b for a, b in zip(self._variant_mapping.keys(), other._variant_mapping.keys()))
def __iter__(self) -> Generator[ArtworkVariant, None, None]:
yield from self._variant_mapping.values()

View File

@@ -184,6 +184,10 @@ class Song(Base):
self.album_collection.extend(object_list)
return
def _compile(self):
self.artwork.compile()
INDEX_DEPENDS_ON = ("title", "isrc", "source_collection")
@property