Compare commits
	
		
			2 Commits
		
	
	
		
			4ee6fd2137
			...
			274f1bce90
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 274f1bce90 | |||
| b1a306f3f3 | 
| @@ -1,15 +1,13 @@ | |||||||
|  | import logging | ||||||
|  |  | ||||||
| import music_kraken | import music_kraken | ||||||
|  |  | ||||||
| import logging |  | ||||||
| print("Setting logging-level to DEBUG") | print("Setting logging-level to DEBUG") | ||||||
| logging.getLogger().setLevel(logging.DEBUG) | logging.getLogger().setLevel(logging.DEBUG) | ||||||
|  |  | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     commands = [ |     commands = [ | ||||||
|         "s: #a Crystal F", |         "s: #a Ghost Bath", | ||||||
|         "10", |  | ||||||
|         "1", |  | ||||||
|         "3", |  | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|      |      | ||||||
|   | |||||||
| @@ -107,7 +107,7 @@ def write_metadata_to_target(metadata: Metadata, target: Target, song: Song): | |||||||
|                 mime="image/jpeg", |                 mime="image/jpeg", | ||||||
|                 type=3, |                 type=3, | ||||||
|                 desc=u"Cover", |                 desc=u"Cover", | ||||||
|                 data=converted_target.read_bytes(), |                 data=converted_target.raw_content, | ||||||
|             ) |             ) | ||||||
|         ) |         ) | ||||||
|         id3_object.frames.delall("USLT") |         id3_object.frames.delall("USLT") | ||||||
|   | |||||||
| @@ -1,12 +1,12 @@ | |||||||
| from __future__ import annotations | from __future__ import annotations | ||||||
|  |  | ||||||
|  | import copy | ||||||
|  | import inspect | ||||||
| import logging | import logging | ||||||
| import threading | import threading | ||||||
| import time | import time | ||||||
| from typing import List, Dict, Optional, Set | from typing import TYPE_CHECKING, Dict, List, Optional, Set | ||||||
| from urllib.parse import urlparse, urlunsplit, ParseResult | from urllib.parse import ParseResult, urlparse, urlunsplit | ||||||
| import copy |  | ||||||
| import inspect |  | ||||||
|  |  | ||||||
| import requests | import requests | ||||||
| import responses | import responses | ||||||
| @@ -14,12 +14,15 @@ from tqdm import tqdm | |||||||
|  |  | ||||||
| from .cache import Cache | from .cache import Cache | ||||||
| from .rotating import RotatingProxy | from .rotating import RotatingProxy | ||||||
| from ..objects import Target |  | ||||||
|  | if TYPE_CHECKING: | ||||||
|  |     from ..objects import Target | ||||||
|  |  | ||||||
| from ..utils import request_trace | from ..utils import request_trace | ||||||
| from ..utils.string_processing import shorten_display_url |  | ||||||
| from ..utils.config import main_settings | from ..utils.config import main_settings | ||||||
| from ..utils.support_classes.download_result import DownloadResult |  | ||||||
| from ..utils.hacking import merge_args | from ..utils.hacking import merge_args | ||||||
|  | from ..utils.string_processing import shorten_display_url | ||||||
|  | from ..utils.support_classes.download_result import DownloadResult | ||||||
|  |  | ||||||
|  |  | ||||||
| class Connection: | class Connection: | ||||||
|   | |||||||
| @@ -2,8 +2,10 @@ from __future__ import annotations | |||||||
|  |  | ||||||
| from copy import copy | from copy import copy | ||||||
| from dataclasses import dataclass, field | from dataclasses import dataclass, field | ||||||
|  | from functools import cached_property | ||||||
| from typing import Dict, List, Optional, Set, Tuple, Type, TypedDict, Union | from typing import Dict, List, Optional, Set, Tuple, Type, TypedDict, Union | ||||||
|  |  | ||||||
|  | from ..connection import Connection | ||||||
| from ..utils import create_dataclass_instance, custom_hash | from ..utils import create_dataclass_instance, custom_hash | ||||||
| from ..utils.config import main_settings | from ..utils.config import main_settings | ||||||
| from ..utils.enums import PictureType | from ..utils.enums import PictureType | ||||||
| @@ -13,6 +15,9 @@ from .metadata import ID3Timestamp | |||||||
| from .metadata import Mapping as id3Mapping | from .metadata import Mapping as id3Mapping | ||||||
| from .metadata import Metadata | from .metadata import Metadata | ||||||
| from .parents import OuterProxy as Base | from .parents import OuterProxy as Base | ||||||
|  | from .target import Target | ||||||
|  |  | ||||||
|  | artwork_connection: Connection = Connection(module="artwork") | ||||||
|  |  | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| @@ -20,7 +25,7 @@ class ArtworkVariant: | |||||||
|     url: str |     url: str | ||||||
|     width: Optional[int] = None |     width: Optional[int] = None | ||||||
|     height: Optional[int] = None |     height: Optional[int] = None | ||||||
|     image_format: Optional[str] = "" |     image_format: Optional[str] = None | ||||||
|  |  | ||||||
|     def __hash__(self) -> int: |     def __hash__(self) -> int: | ||||||
|         return custom_hash(self.url) |         return custom_hash(self.url) | ||||||
| @@ -31,6 +36,26 @@ class ArtworkVariant: | |||||||
|     def __contains__(self, other: str) -> bool: |     def __contains__(self, other: str) -> bool: | ||||||
|         return custom_hash(other) == hash(self.url) |         return custom_hash(other) == hash(self.url) | ||||||
|  |  | ||||||
|  |     def __merge__(self, other: ArtworkVariant) -> None: | ||||||
|  |         for key, value in other.__dict__.items(): | ||||||
|  |             if value is None: | ||||||
|  |                 continue | ||||||
|  |  | ||||||
|  |             if getattr(self, key) is None: | ||||||
|  |                 setattr(self, key, value) | ||||||
|  |  | ||||||
|  |     @cached_property | ||||||
|  |     def target(self) -> Target: | ||||||
|  |         return Target.temp() | ||||||
|  |  | ||||||
|  |     def fetch(self) -> None: | ||||||
|  |         global artwork_connection | ||||||
|  |  | ||||||
|  |         r = artwork_connection.get(self.url, name=hash_url(url)) | ||||||
|  |         if r is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         self.target.raw_content = r.content | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| class Artwork: | class Artwork: | ||||||
| @@ -55,10 +80,9 @@ class Artwork: | |||||||
|         variant = self.search_variant(kwargs.get("url")) |         variant = self.search_variant(kwargs.get("url")) | ||||||
|  |  | ||||||
|         if variant is None: |         if variant is None: | ||||||
|             variant, kwargs = create_dataclass_instance(ArtworkVariant, **kwargs) |             variant, kwargs = create_dataclass_instance(ArtworkVariant, kwargs) | ||||||
|             self.variants.append(variant) |             self.variants.append(variant) | ||||||
|  |  | ||||||
|         variant.url = url |  | ||||||
|         variant.__dict__.update(kwargs) |         variant.__dict__.update(kwargs) | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
| @@ -67,6 +91,10 @@ class Artwork: | |||||||
|             return None |             return None | ||||||
|         return self.variants[0].url |         return self.variants[0].url | ||||||
|  |  | ||||||
|  |     def fetch(self) -> None: | ||||||
|  |         for variant in self.variants: | ||||||
|  |             variant.fetch() | ||||||
|  |  | ||||||
|  |  | ||||||
| class ArtworkCollection: | class ArtworkCollection: | ||||||
|     """ |     """ | ||||||
| @@ -91,8 +119,6 @@ class ArtworkCollection: | |||||||
|         self._data = [] |         self._data = [] | ||||||
|         self.extend(data) |         self.extend(data) | ||||||
|  |  | ||||||
|         |  | ||||||
|  |  | ||||||
|     def search_artwork(self, url: str) -> Optional[ArtworkVariant]: |     def search_artwork(self, url: str) -> Optional[ArtworkVariant]: | ||||||
|         for artwork in self._data: |         for artwork in self._data: | ||||||
|             if url in artwork: |             if url in artwork: | ||||||
| @@ -106,18 +132,19 @@ class ArtworkCollection: | |||||||
|     def _create_new_artwork(self, **kwargs) -> Tuple[Artwork, dict]: |     def _create_new_artwork(self, **kwargs) -> Tuple[Artwork, dict]: | ||||||
|         kwargs["artwork_type"] = kwargs.get("artwork_type", self.artwork_type) |         kwargs["artwork_type"] = kwargs.get("artwork_type", self.artwork_type) | ||||||
|  |  | ||||||
|         return create_dataclass_instance(ArtworkVariant, dict(**kwargs)) |         return create_dataclass_instance(Artwork, dict(**kwargs)) | ||||||
|  |  | ||||||
|     def add_data(self, url: str, **kwargs) -> None: |     def add_data(self, url: str, **kwargs) -> Artwork: | ||||||
|         kwargs["url"] = url |         kwargs["url"] = url | ||||||
|  |  | ||||||
|         artwork = self.search_artwork(url) |         artwork = self.search_artwork(url) | ||||||
|  |  | ||||||
|         if artwork is None: |         if artwork is None: | ||||||
|             artwork, kwargs = self._create_new_artwork(url=url) |             artwork, kwargs = self._create_new_artwork(**kwargs) | ||||||
|             self._data.append(artwork) |             self._data.append(artwork) | ||||||
|  |  | ||||||
|         artwork.add_data(url, **kwargs) |         artwork.add_data(**kwargs) | ||||||
|  |         return artwork | ||||||
|  |  | ||||||
|     def append(self, value: Union[Artwork, ArtworkVariant, dict], **kwargs): |     def append(self, value: Union[Artwork, ArtworkVariant, dict], **kwargs): | ||||||
|         """ |         """ | ||||||
| @@ -145,9 +172,7 @@ class ArtworkCollection: | |||||||
|         This will make the artworks ready for download |         This will make the artworks ready for download | ||||||
|         """ |         """ | ||||||
|         for artwork in self._data: |         for artwork in self._data: | ||||||
|             for variants in artwork.variants: |             artwork.fetch() | ||||||
|                 pass |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     def __merge__(self, other: ArtworkCollection, **kwargs) -> None: |     def __merge__(self, other: ArtworkCollection, **kwargs) -> None: | ||||||
|         self.parent_artworks.update(other.parent_artworks) |         self.parent_artworks.update(other.parent_artworks) | ||||||
|   | |||||||
| @@ -1,17 +1,17 @@ | |||||||
| from __future__ import annotations | from __future__ import annotations | ||||||
|  |  | ||||||
| from pathlib import Path |  | ||||||
| from typing import List, Tuple, TextIO, Union, Optional |  | ||||||
| import logging | import logging | ||||||
| import random | import random | ||||||
|  | from pathlib import Path | ||||||
|  | from typing import List, Optional, TextIO, Tuple, Union | ||||||
|  |  | ||||||
| import requests | import requests | ||||||
| from tqdm import tqdm | from tqdm import tqdm | ||||||
|  |  | ||||||
| from .parents import OuterProxy | from ..utils.config import logging_settings, main_settings | ||||||
| from ..utils.shared import HIGHEST_ID | from ..utils.shared import HIGHEST_ID | ||||||
| from ..utils.config import main_settings, logging_settings |  | ||||||
| from ..utils.string_processing import fit_to_file_system | from ..utils.string_processing import fit_to_file_system | ||||||
|  | from .parents import OuterProxy | ||||||
|  |  | ||||||
| LOGGER = logging.getLogger("target") | LOGGER = logging.getLogger("target") | ||||||
|  |  | ||||||
| @@ -117,3 +117,11 @@ class Target(OuterProxy): | |||||||
|  |  | ||||||
|     def read_bytes(self) -> bytes: |     def read_bytes(self) -> bytes: | ||||||
|         return self.file_path.read_bytes() |         return self.file_path.read_bytes() | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def raw_content(self) -> bytes: | ||||||
|  |         return self.file_path.read_bytes() | ||||||
|  |  | ||||||
|  |     @raw_content.setter | ||||||
|  |     def raw_content(self, content: bytes): | ||||||
|  |         self.file_path.write_bytes(content) | ||||||
|   | |||||||
| @@ -156,6 +156,7 @@ def create_dataclass_instance(t, data: dict): | |||||||
|         Tuple[Type, dict]: The created instance and a dict, containing the data, which was not used in the creation |         Tuple[Type, dict]: The created instance and a dict, containing the data, which was not used in the creation | ||||||
|     """ |     """ | ||||||
|      |      | ||||||
|     data = {k: v for k, v in data.items() if hasattr(t, k)} |     needed_data = {k: v for k, v in data.items() if k in t.__dataclass_fields__} | ||||||
|     removed_data = {k: v for k, v in data.items() if not hasattr(t, k)} |     removed_data = {k: v for k, v in data.items() if k not in t.__dataclass_fields__} | ||||||
|     return t(**data), removed_data |  | ||||||
|  |     return t(**needed_data), removed_data | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import re | ||||||
| import string | import string | ||||||
| from functools import lru_cache | from functools import lru_cache | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| @@ -238,4 +239,5 @@ def is_url(value: Any) -> bool: | |||||||
|     if not isinstance(value, str): |     if not isinstance(value, str): | ||||||
|         return True |         return True | ||||||
|          |          | ||||||
|     return re.match(URL_PATTERN, query) is not None |     # value has to be a string | ||||||
|  |     return re.match(URL_PATTERN, value) is not None | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user