feature/artwork_gallery #41
@ -1,27 +1,16 @@
|
||||
from typing_extensions import TypeVar
|
||||
|
||||
from .artwork import ArtworkCollection
|
||||
from .collection import Collection
|
||||
from .contact import Contact
|
||||
from .country import Country
|
||||
from .formatted_text import FormattedText
|
||||
from .metadata import ID3Timestamp
|
||||
from .metadata import Mapping as ID3Mapping
|
||||
from .metadata import Metadata
|
||||
from .option import Options
|
||||
|
||||
from .metadata import Metadata, Mapping as ID3Mapping, ID3Timestamp
|
||||
|
||||
from .parents import OuterProxy
|
||||
from .song import Album, Artist, Label, Lyrics, Song, Target
|
||||
from .source import Source, SourceType
|
||||
|
||||
from .song import (
|
||||
Song,
|
||||
Album,
|
||||
Artist,
|
||||
Target,
|
||||
Lyrics,
|
||||
Label
|
||||
)
|
||||
|
||||
from .formatted_text import FormattedText
|
||||
from .collection import Collection
|
||||
|
||||
from .country import Country
|
||||
from .contact import Contact
|
||||
|
||||
from .parents import OuterProxy
|
||||
|
||||
from .artwork import Artwork
|
||||
|
||||
DatabaseObject = OuterProxy
|
||||
|
@ -10,6 +10,7 @@ from .metadata import Mapping as id3Mapping
|
||||
from .metadata import Metadata
|
||||
from .parents import OuterProxy as Base
|
||||
|
||||
|
||||
class ArtworkVariant(TypedDict):
|
||||
url: str
|
||||
width: int
|
||||
@ -17,10 +18,10 @@ class ArtworkVariant(TypedDict):
|
||||
deviation: float
|
||||
|
||||
|
||||
class Artwork:
|
||||
def __init__(self, *variants: List[ArtworkVariant], parent_artworks: Set[Artwork] = None, crop_images: bool = True) -> None:
|
||||
class ArtworkCollection:
|
||||
def __init__(self, *variants: List[ArtworkVariant], parent_artworks: Set[ArtworkCollection] = None, crop_images: bool = True) -> None:
|
||||
self.crop_images: bool = crop_images
|
||||
self.parent_artworks: Set[Artwork] = parent_artworks or set()
|
||||
self.parent_artworks: Set[ArtworkCollection] = parent_artworks or set()
|
||||
|
||||
self._variant_mapping: Dict[str, ArtworkVariant] = {}
|
||||
|
||||
@ -58,7 +59,7 @@ class Artwork:
|
||||
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:
|
||||
def __merge__(self, other: ArtworkCollection, **kwargs) -> None:
|
||||
self.parent_artworks.update(other.parent_artworks)
|
||||
|
||||
for key, value in other._variant_mapping.items():
|
||||
@ -68,11 +69,11 @@ class Artwork:
|
||||
def __hash__(self) -> int:
|
||||
return id(self)
|
||||
|
||||
def __eq__(self, other: Artwork) -> bool:
|
||||
def __eq__(self, other: ArtworkCollection) -> bool:
|
||||
if hash(self) == hash(other):
|
||||
return True
|
||||
|
||||
if not isinstance(other, Artwork):
|
||||
if not isinstance(other, ArtworkCollection):
|
||||
return False
|
||||
return any(a == b for a, b in zip(self._variant_mapping.keys(), other._variant_mapping.keys()))
|
||||
|
||||
|
@ -1,35 +1,32 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import random
|
||||
from collections import defaultdict
|
||||
from typing import List, Optional, Dict, Tuple, Type, Union
|
||||
import copy
|
||||
from typing import Dict, List, Optional, Tuple, Type, Union
|
||||
|
||||
import pycountry
|
||||
|
||||
from ..utils.enums.album import AlbumType, AlbumStatus
|
||||
from .collection import Collection, AppendHookArguments
|
||||
from .formatted_text import FormattedText
|
||||
from .lyrics import Lyrics
|
||||
from .contact import Contact
|
||||
from .artwork import Artwork
|
||||
from .metadata import (
|
||||
Mapping as id3Mapping,
|
||||
ID3Timestamp,
|
||||
Metadata
|
||||
)
|
||||
from .option import Options
|
||||
from .parents import OuterProxy, P
|
||||
from .source import Source, SourceCollection
|
||||
from .target import Target
|
||||
from .country import Language, Country
|
||||
from ..utils.config import main_settings
|
||||
from ..utils.enums.album import AlbumStatus, AlbumType
|
||||
from ..utils.enums.colors import BColors
|
||||
from ..utils.shared import DEBUG_PRINT_ID
|
||||
from ..utils.string_processing import unify
|
||||
|
||||
from .artwork import ArtworkCollection
|
||||
from .collection import AppendHookArguments, Collection
|
||||
from .contact import Contact
|
||||
from .country import Country, Language
|
||||
from .formatted_text import FormattedText
|
||||
from .lyrics import Lyrics
|
||||
from .metadata import ID3Timestamp
|
||||
from .metadata import Mapping as id3Mapping
|
||||
from .metadata import Metadata
|
||||
from .option import Options
|
||||
from .parents import OuterProxy
|
||||
from .parents import OuterProxy as Base
|
||||
|
||||
from ..utils.config import main_settings
|
||||
from ..utils.enums.colors import BColors
|
||||
from .parents import P
|
||||
from .source import Source, SourceCollection
|
||||
from .target import Target
|
||||
|
||||
"""
|
||||
All Objects dependent
|
||||
@ -89,7 +86,7 @@ class Song(Base):
|
||||
genre: str
|
||||
note: FormattedText
|
||||
tracksort: int
|
||||
artwork: Artwork
|
||||
artwork: ArtworkCollection
|
||||
|
||||
source_collection: SourceCollection
|
||||
target_collection: Collection[Target]
|
||||
@ -105,7 +102,7 @@ class Song(Base):
|
||||
"source_collection": SourceCollection,
|
||||
"target_collection": Collection,
|
||||
"lyrics_collection": Collection,
|
||||
"artwork": Artwork,
|
||||
"artwork": ArtworkCollection,
|
||||
|
||||
"album_collection": Collection,
|
||||
"artist_collection": Collection,
|
||||
@ -133,7 +130,7 @@ class Song(Base):
|
||||
feature_artist_list: List[Artist] = None,
|
||||
album_list: List[Album] = None,
|
||||
tracksort: int = 0,
|
||||
artwork: Optional[Artwork] = None,
|
||||
artwork: Optional[ArtworkCollection] = None,
|
||||
**kwargs
|
||||
) -> None:
|
||||
real_kwargs = copy.copy(locals())
|
||||
@ -258,7 +255,7 @@ class Album(Base):
|
||||
albumsort: int
|
||||
notes: FormattedText
|
||||
|
||||
artwork: Artwork
|
||||
artwork: ArtworkCollection
|
||||
source_collection: SourceCollection
|
||||
|
||||
song_collection: Collection[Song]
|
||||
@ -278,7 +275,7 @@ class Album(Base):
|
||||
"date": ID3Timestamp,
|
||||
"notes": FormattedText,
|
||||
|
||||
"artwork": lambda: Artwork(crop_images=False),
|
||||
"artwork": lambda: ArtworkCollection(crop_images=False),
|
||||
"source_collection": SourceCollection,
|
||||
|
||||
"song_collection": Collection,
|
||||
@ -301,7 +298,7 @@ class Album(Base):
|
||||
barcode: str = None,
|
||||
albumsort: int = None,
|
||||
notes: FormattedText = None,
|
||||
artwork: Artwork = None,
|
||||
artwork: ArtworkCollection = None,
|
||||
source_list: List[Source] = None,
|
||||
artist_list: List[Artist] = None,
|
||||
song_list: List[Song] = None,
|
||||
@ -498,7 +495,7 @@ class Artist(Base):
|
||||
general_genre: str
|
||||
unformatted_location: str
|
||||
|
||||
artwork: Artwork
|
||||
artwork: ArtworkCollection
|
||||
|
||||
source_collection: SourceCollection
|
||||
contact_collection: Collection[Contact]
|
||||
@ -516,7 +513,7 @@ class Artist(Base):
|
||||
"lyrical_themes": list,
|
||||
"general_genre": lambda: "",
|
||||
|
||||
"artwork": Artwork,
|
||||
"artwork": ArtworkCollection,
|
||||
|
||||
"source_collection": SourceCollection,
|
||||
"album_collection": Collection,
|
||||
@ -536,7 +533,7 @@ class Artist(Base):
|
||||
notes: FormattedText = None,
|
||||
lyrical_themes: List[str] = None,
|
||||
general_genre: str = None,
|
||||
artwork: Artwork = None,
|
||||
artwork: ArtworkCollection = None,
|
||||
unformatted_location: str = None,
|
||||
source_list: List[Source] = None,
|
||||
contact_list: List[Contact] = None,
|
||||
|
@ -1,33 +1,22 @@
|
||||
from typing import List, Optional, Type
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
import json
|
||||
from enum import Enum
|
||||
from bs4 import BeautifulSoup
|
||||
import pycountry
|
||||
from typing import List, Optional, Type
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
|
||||
import pycountry
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from ..objects import Source, DatabaseObject
|
||||
from .abstract import Page
|
||||
from ..objects import (
|
||||
Artist,
|
||||
Source,
|
||||
SourceType,
|
||||
Song,
|
||||
Album,
|
||||
Label,
|
||||
Target,
|
||||
Contact,
|
||||
ID3Timestamp,
|
||||
Lyrics,
|
||||
FormattedText,
|
||||
Artwork,
|
||||
)
|
||||
from ..connection import Connection
|
||||
from ..objects import (Album, Artist, ArtworkCollection, Contact,
|
||||
DatabaseObject, FormattedText, ID3Timestamp, Label,
|
||||
Lyrics, Song, Source, SourceType, Target)
|
||||
from ..utils import dump_to_file
|
||||
from ..utils.enums import SourceType, ALL_SOURCE_TYPES
|
||||
from ..utils.support_classes.download_result import DownloadResult
|
||||
from ..utils.string_processing import clean_song_title
|
||||
from ..utils.config import main_settings, logging_settings
|
||||
from ..utils.config import logging_settings, main_settings
|
||||
from ..utils.enums import ALL_SOURCE_TYPES, SourceType
|
||||
from ..utils.shared import DEBUG
|
||||
from ..utils.string_processing import clean_song_title
|
||||
from ..utils.support_classes.download_result import DownloadResult
|
||||
from .abstract import Page
|
||||
|
||||
if DEBUG:
|
||||
from ..utils import dump_to_file
|
||||
@ -258,7 +247,7 @@ class Bandcamp(Page):
|
||||
artist.source_collection.append(source)
|
||||
return artist
|
||||
|
||||
def _parse_track_element(self, track: dict, artwork: Artwork) -> Optional[Song]:
|
||||
def _parse_track_element(self, track: dict, artwork: ArtworkCollection) -> Optional[Song]:
|
||||
lyrics_list: List[Lyrics] = []
|
||||
|
||||
_lyrics: Optional[str] = track.get("item", {}).get("recordingOf", {}).get("lyrics", {}).get("text")
|
||||
@ -308,7 +297,7 @@ class Bandcamp(Page):
|
||||
)]
|
||||
)
|
||||
|
||||
artwork: Artwork = Artwork()
|
||||
artwork: ArtworkCollection = ArtworkCollection()
|
||||
|
||||
def _get_artwork_url(_data: dict) -> Optional[str]:
|
||||
if "image" in _data:
|
||||
|
@ -1,33 +1,22 @@
|
||||
from typing import List, Optional, Type
|
||||
from urllib.parse import urlparse, urlunparse, urlencode
|
||||
import json
|
||||
from enum import Enum
|
||||
from bs4 import BeautifulSoup
|
||||
import pycountry
|
||||
from typing import List, Optional, Type
|
||||
from urllib.parse import urlencode, urlparse, urlunparse
|
||||
|
||||
import pycountry
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from ..objects import Source, DatabaseObject
|
||||
from .abstract import Page
|
||||
from ..objects import (
|
||||
Artist,
|
||||
Source,
|
||||
SourceType,
|
||||
Song,
|
||||
Album,
|
||||
Label,
|
||||
Target,
|
||||
Contact,
|
||||
ID3Timestamp,
|
||||
Lyrics,
|
||||
FormattedText,
|
||||
Artwork,
|
||||
)
|
||||
from ..connection import Connection
|
||||
from ..objects import (Album, Artist, ArtworkCollection, Contact,
|
||||
DatabaseObject, FormattedText, ID3Timestamp, Label,
|
||||
Lyrics, Song, Source, SourceType, Target)
|
||||
from ..utils import dump_to_file, traverse_json_path
|
||||
from ..utils.enums import SourceType, ALL_SOURCE_TYPES
|
||||
from ..utils.support_classes.download_result import DownloadResult
|
||||
from ..utils.string_processing import clean_song_title
|
||||
from ..utils.config import main_settings, logging_settings
|
||||
from ..utils.config import logging_settings, main_settings
|
||||
from ..utils.enums import ALL_SOURCE_TYPES, SourceType
|
||||
from ..utils.shared import DEBUG
|
||||
from ..utils.string_processing import clean_song_title
|
||||
from ..utils.support_classes.download_result import DownloadResult
|
||||
from .abstract import Page
|
||||
|
||||
if DEBUG:
|
||||
from ..utils import dump_to_file
|
||||
@ -56,7 +45,7 @@ class Genius(Page):
|
||||
|
||||
return Song
|
||||
|
||||
def add_to_artwork(self, artwork: Artwork, url: str):
|
||||
def add_to_artwork(self, artwork: ArtworkCollection, url: str):
|
||||
if url is None:
|
||||
return
|
||||
|
||||
@ -83,7 +72,7 @@ class Genius(Page):
|
||||
return None
|
||||
object_type = data.get("_type")
|
||||
|
||||
artwork = Artwork()
|
||||
artwork = ArtworkCollection()
|
||||
self.add_to_artwork(artwork, data.get("header_image_url"))
|
||||
self.add_to_artwork(artwork, data.get("image_url"))
|
||||
|
||||
|
@ -1,34 +1,24 @@
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import List, Optional, Type, Union, Generator, Dict, Any
|
||||
from typing import Any, Dict, Generator, List, Optional, Type, Union
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import pycountry
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from ..connection import Connection
|
||||
from .abstract import Page
|
||||
from ..utils.enums import SourceType, ALL_SOURCE_TYPES
|
||||
from ..utils.enums.album import AlbumType, AlbumStatus
|
||||
from ..objects import (
|
||||
Artist,
|
||||
Source,
|
||||
Song,
|
||||
Album,
|
||||
ID3Timestamp,
|
||||
FormattedText,
|
||||
Label,
|
||||
Target,
|
||||
DatabaseObject,
|
||||
Lyrics,
|
||||
Artwork
|
||||
)
|
||||
from ..objects import (Album, Artist, ArtworkCollection, DatabaseObject,
|
||||
FormattedText, ID3Timestamp, Label, Lyrics, Song,
|
||||
Source, Target)
|
||||
from ..utils import shared, string_processing
|
||||
from ..utils.config import logging_settings, main_settings
|
||||
from ..utils import string_processing, shared
|
||||
from ..utils.enums import ALL_SOURCE_TYPES, SourceType
|
||||
from ..utils.enums.album import AlbumStatus, AlbumType
|
||||
from ..utils.string_processing import clean_song_title
|
||||
from ..utils.support_classes.query import Query
|
||||
from ..utils.support_classes.download_result import DownloadResult
|
||||
from ..utils.support_classes.query import Query
|
||||
from .abstract import Page
|
||||
|
||||
"""
|
||||
https://musify.club/artist/ghost-bath-280348?_pjax=#bodyContent
|
||||
@ -486,7 +476,7 @@ class Musify(Page):
|
||||
track_name = list_points[4].text.strip()
|
||||
|
||||
# album artwork
|
||||
artwork: Artwork = Artwork()
|
||||
artwork: ArtworkCollection = ArtworkCollection()
|
||||
album_image_element_list: List[BeautifulSoup] = soup.find_all("img", {"class": "album-img"})
|
||||
for album_image_element in album_image_element_list:
|
||||
artwork.append(url=album_image_element.get("data-src", album_image_element.get("src")))
|
||||
@ -755,7 +745,7 @@ class Musify(Page):
|
||||
self.LOGGER.debug(f"Raw datetime doesn't match time format %Y-%m-%d: {raw_datetime}")
|
||||
|
||||
# album artwork
|
||||
album_artwork: Artwork = Artwork()
|
||||
album_artwork: ArtworkCollection = ArtworkCollection()
|
||||
album_artwork_list: List[BeautifulSoup] = soup.find_all("img", {"class":"artist-img"})
|
||||
for album_artwork in album_artwork_list:
|
||||
album_artwork.append(url=album_artwork.get("data-src", album_artwork.get("src")))
|
||||
@ -924,7 +914,7 @@ class Musify(Page):
|
||||
notes.html = note_soup.decode_contents()
|
||||
|
||||
# get artist profile artwork
|
||||
main_artist_artwork: Artwork = Artwork()
|
||||
main_artist_artwork: ArtworkCollection = ArtworkCollection()
|
||||
artist_image_element_list: List[BeautifulSoup] = soup.find_all("img", {"class":"artist-img"})
|
||||
for artist_image_element in artist_image_element_list:
|
||||
main_artist_artwork.append(url=artist_image_element.get("data-src", artist_image_element.get("src")))
|
||||
|
@ -1,46 +1,33 @@
|
||||
from __future__ import unicode_literals, annotations
|
||||
from __future__ import annotations, unicode_literals
|
||||
|
||||
from typing import Dict, List, Optional, Set, Type
|
||||
from urllib.parse import urlparse, urlunparse, quote, parse_qs, urlencode
|
||||
import json
|
||||
import logging
|
||||
import random
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
import re
|
||||
from functools import lru_cache
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
from functools import lru_cache
|
||||
from typing import Dict, List, Optional, Set, Type
|
||||
from urllib.parse import parse_qs, quote, urlencode, urlparse, urlunparse
|
||||
|
||||
import youtube_dl
|
||||
from youtube_dl.extractor.youtube import YoutubeIE
|
||||
from youtube_dl.utils import DownloadError
|
||||
|
||||
from ...connection import Connection
|
||||
from ...objects import Album, Artist, ArtworkCollection
|
||||
from ...objects import DatabaseObject as DataObject
|
||||
from ...objects import (FormattedText, ID3Timestamp, Label, Lyrics, Song,
|
||||
Source, Target)
|
||||
from ...utils import dump_to_file, get_current_millis, traverse_json_path
|
||||
from ...utils.config import logging_settings, main_settings, youtube_settings
|
||||
from ...utils.enums import ALL_SOURCE_TYPES, SourceType
|
||||
from ...utils.enums.album import AlbumType
|
||||
from ...utils.exception.config import SettingValueError
|
||||
from ...utils.config import main_settings, youtube_settings, logging_settings
|
||||
from ...utils.shared import DEBUG, DEBUG_YOUTUBE_INITIALIZING
|
||||
from ...utils.string_processing import clean_song_title
|
||||
from ...utils import get_current_millis, traverse_json_path
|
||||
|
||||
from ...utils import dump_to_file
|
||||
|
||||
from ..abstract import Page
|
||||
from ...objects import (
|
||||
DatabaseObject as DataObject,
|
||||
Source,
|
||||
FormattedText,
|
||||
ID3Timestamp,
|
||||
Artwork,
|
||||
Artist,
|
||||
Song,
|
||||
Album,
|
||||
Label,
|
||||
Target,
|
||||
Lyrics,
|
||||
)
|
||||
from ...connection import Connection
|
||||
from ...utils.enums import SourceType, ALL_SOURCE_TYPES
|
||||
from ...utils.enums.album import AlbumType
|
||||
from ...utils.support_classes.download_result import DownloadResult
|
||||
|
||||
from ..abstract import Page
|
||||
from ._list_render import parse_renderer
|
||||
from ._music_object_render import parse_run_element
|
||||
from .super_youtube import SuperYouTube
|
||||
@ -657,7 +644,7 @@ class YoutubeMusic(SuperYouTube):
|
||||
note=ydl_res.get("descriptions"),
|
||||
album_list=album_list,
|
||||
length=int(ydl_res.get("duration", 0)) * 1000,
|
||||
artwork=Artwork(*ydl_res.get("thumbnails", [])),
|
||||
artwork=ArtworkCollection(*ydl_res.get("thumbnails", [])),
|
||||
artist_list=artist_list,
|
||||
source_list=[Source(
|
||||
self.SOURCE_TYPE,
|
||||
|
Loading…
Reference in New Issue
Block a user