65 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 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 ..utils.config import main_settings
 | |
| 
 | |
| 
 | |
| class ArtworkVariant(TypedDict):
 | |
|     url: str
 | |
|     width: int
 | |
|     height: int
 | |
|     deviation: float
 | |
| 
 | |
| 
 | |
| class Artwork:
 | |
|     def __init__(self, *variants: List[ArtworkVariant]) -> None:
 | |
|         self._variant_mapping: Dict[str, ArtworkVariant] = {}
 | |
| 
 | |
|         for variant in variants:
 | |
|             self.append(**variant)
 | |
| 
 | |
|     @staticmethod
 | |
|     def _calculate_deviation(*dimensions: List[int]) -> float:
 | |
|         return sum(abs(d - main_settings["preferred_artwork_resolution"]) for d in dimensions) / len(dimensions)
 | |
| 
 | |
|     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,
 | |
|             "height": height,
 | |
|             "deviation": self._calculate_deviation(width, height),
 | |
|         }
 | |
| 
 | |
|     @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"])
 | |
| 
 | |
|     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:
 | |
|         for key, value in other._variant_mapping.items():
 | |
|             if key not in self._variant_mapping:
 | |
|                 self._variant_mapping[key] = value
 | |
| 
 | |
|     def __eq__(self, other: Artwork) -> bool:
 | |
|         if not isinstance(other, Artwork):
 | |
|             return False
 | |
|         return any(a == b for a, b in zip(self._variant_mapping.keys(), other._variant_mapping.keys()))
 |