diff --git a/docs/conf.py b/docs/conf.py index 56f2584..3401925 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ project = "streamrip" copyright = "2021, nathom" author = "nathom" -pygments_style = 'sphinx' +pygments_style = "sphinx" # -- General configuration --------------------------------------------------- diff --git a/rip/cli.py b/rip/cli.py index 5e2a1e7..76537ed 100644 --- a/rip/cli.py +++ b/rip/cli.py @@ -1,6 +1,8 @@ """The streamrip command line interface.""" -import click import logging + +import click + from streamrip import __version__ logging.basicConfig(level="WARNING") @@ -303,12 +305,14 @@ def lastfm(ctx, source, url): @click.pass_context def config(ctx, **kwargs): """Manage the streamrip configuration file.""" - from streamrip.clients import TidalClient - from .constants import CONFIG_PATH - from hashlib import md5 - from getpass import getpass - import shutil import os + import shutil + from getpass import getpass + from hashlib import md5 + + from streamrip.clients import TidalClient + + from .constants import CONFIG_PATH global config if kwargs["reset"]: @@ -398,11 +402,13 @@ def convert(ctx, **kwargs): $ rip convert ALAC --sampling-rate 48000 /my/music """ - from streamrip import converter import concurrent.futures - from tqdm import tqdm import os + from tqdm import tqdm + + from streamrip import converter + codec_map = { "FLAC": converter.FLAC, "ALAC": converter.ALAC, diff --git a/rip/config.py b/rip/config.py index e3a431f..d510763 100644 --- a/rip/config.py +++ b/rip/config.py @@ -10,9 +10,10 @@ from typing import Any, Dict import click import tomlkit -from .constants import CONFIG_DIR, CONFIG_PATH, DOWNLOADS_DIR from streamrip.exceptions import InvalidSourceError +from .constants import CONFIG_DIR, CONFIG_PATH, DOWNLOADS_DIR + logger = logging.getLogger("streamrip") diff --git a/rip/constants.py b/rip/constants.py index 9a59a14..96a9bd6 100644 --- a/rip/constants.py +++ b/rip/constants.py @@ -1,8 +1,9 @@ -import click -import re import os +import re from pathlib import Path +import click + APPNAME = "streamrip" APP_DIR = click.get_app_dir(APPNAME) HOME = Path.home() diff --git a/rip/core.py b/rip/core.py index 57a1ade..7b1bc10 100644 --- a/rip/core.py +++ b/rip/core.py @@ -5,7 +5,6 @@ import html import logging import os import re - from getpass import getpass from hashlib import md5 from string import Formatter @@ -15,16 +14,6 @@ import click import requests from tqdm import tqdm -from streamrip.media import ( - Track, - Video, - YoutubeVideo, - Album, - Artist, - Label, - Playlist, - Tracklist, -) from streamrip.clients import ( Client, DeezerClient, @@ -33,36 +22,43 @@ from streamrip.clients import ( SoundCloudClient, TidalClient, ) -from .config import Config from streamrip.constants import MEDIA_TYPES -from streamrip.utils import set_progress_bar_theme, TQDM_DEFAULT_THEME -from .constants import ( - URL_REGEX, - SOUNDCLOUD_URL_REGEX, - LASTFM_URL_REGEX, - QOBUZ_INTERPRETER_URL_REGEX, - YOUTUBE_URL_REGEX, - DEEZER_DYNAMIC_LINK_REGEX, - CONFIG_PATH, - DB_PATH, - FAILED_DB_PATH, -) -from . import db from streamrip.exceptions import ( AuthenticationError, - PartialFailure, ItemExists, MissingCredentials, NonStreamable, NoResultsFound, ParsingError, + PartialFailure, ) -from .utils import ( - extract_deezer_dynamic_link, - extract_interpreter_url, +from streamrip.media import ( + Album, + Artist, + Label, + Playlist, + Track, + Tracklist, + Video, + YoutubeVideo, +) +from streamrip.utils import TQDM_DEFAULT_THEME, set_progress_bar_theme + +from . import db +from .config import Config +from .constants import ( + CONFIG_PATH, + DB_PATH, + DEEZER_DYNAMIC_LINK_REGEX, + FAILED_DB_PATH, + LASTFM_URL_REGEX, + QOBUZ_INTERPRETER_URL_REGEX, + SOUNDCLOUD_URL_REGEX, + URL_REGEX, + YOUTUBE_URL_REGEX, ) from .exceptions import DeezloaderFallback - +from .utils import extract_deezer_dynamic_link, extract_interpreter_url logger = logging.getLogger("streamrip") diff --git a/rip/utils.py b/rip/utils.py index ac91776..8bab1b6 100644 --- a/rip/utils.py +++ b/rip/utils.py @@ -1,7 +1,8 @@ -from streamrip.utils import gen_threadsafe_session -from streamrip.constants import AGENT -from typing import Tuple import re +from typing import Tuple + +from streamrip.constants import AGENT +from streamrip.utils import gen_threadsafe_session interpreter_artist_regex = re.compile(r"getSimilarArtist\(\s*'(\w+)'") diff --git a/streamrip/__init__.py b/streamrip/__init__.py index 5a871af..1e7fde2 100644 --- a/streamrip/__init__.py +++ b/streamrip/__init__.py @@ -2,4 +2,4 @@ __version__ = "0.7.1" -from . import clients, converter, media, constants +from . import clients, constants, converter, media diff --git a/streamrip/clients.py b/streamrip/clients.py index f39da39..a499ffb 100644 --- a/streamrip/clients.py +++ b/streamrip/clients.py @@ -4,31 +4,31 @@ import base64 import binascii import hashlib import json -from Cryptodome.Cipher import Blowfish, AES # type: ignore import logging import re import time -from pprint import pformat -import requests -import deezer # type: ignore from abc import ABC, abstractmethod -from typing import Generator, Sequence, Tuple, Union, Dict, Any, Optional +from pprint import pformat +from typing import Any, Dict, Generator, Optional, Sequence, Tuple, Union import click # type: ignore +import deezer # type: ignore +import requests +from Cryptodome.Cipher import AES, Blowfish # type: ignore from .constants import ( AGENT, AVAILABLE_QUALITY_IDS, DEEZER_BASE, - DEEZER_FORMATS, DEEZER_DL, + DEEZER_FORMATS, DEEZER_MAX_Q, QOBUZ_BASE, QOBUZ_FEATURED_KEYS, + SOUNDCLOUD_APP_VERSION, SOUNDCLOUD_BASE, SOUNDCLOUD_CLIENT_ID, SOUNDCLOUD_USER_ID, - SOUNDCLOUD_APP_VERSION, TIDAL_AUTH_URL, TIDAL_BASE, TIDAL_CLIENT_INFO, diff --git a/streamrip/exceptions.py b/streamrip/exceptions.py index feefbcc..04b9846 100644 --- a/streamrip/exceptions.py +++ b/streamrip/exceptions.py @@ -1,4 +1,5 @@ from typing import List + import click diff --git a/streamrip/media.py b/streamrip/media.py index 471f2c3..4a38f9b 100644 --- a/streamrip/media.py +++ b/streamrip/media.py @@ -5,48 +5,53 @@ and the other objects. They can also be downloaded individually, for example, as a single track. """ +import abc import concurrent.futures import logging import os -import abc import re import shutil import subprocess from tempfile import gettempdir -from tqdm import tqdm -from typing import Any, Optional, Union, Iterable, Generator, Dict, Tuple, List +from typing import Any, Dict, Generator, Iterable, List, Optional, Tuple, Union import click from mutagen.flac import FLAC, Picture from mutagen.id3 import APIC, ID3, ID3NoHeaderError from mutagen.mp4 import MP4, MP4Cover -from pathvalidate import sanitize_filepath, sanitize_filename +from pathvalidate import sanitize_filename, sanitize_filepath +from tqdm import tqdm from . import converter from .clients import Client, DeezloaderClient -from .constants import FLAC_MAX_BLOCKSIZE, FOLDER_FORMAT, TRACK_FORMAT, ALBUM_KEYS +from .constants import ( + ALBUM_KEYS, + FLAC_MAX_BLOCKSIZE, + FOLDER_FORMAT, + TRACK_FORMAT, +) from .exceptions import ( InvalidQuality, - PartialFailure, - ItemExists, InvalidSourceError, + ItemExists, NonStreamable, + PartialFailure, TooLargeCoverArt, ) from .metadata import TrackMetadata from .utils import ( - clean_format, - tqdm_stream, - downsize_image, - get_cover_urls, - decrypt_mqa_file, - tqdm_download, - get_container, DownloadStream, + clean_format, + decrypt_mqa_file, + downsize_image, ext, + get_container, + get_cover_urls, get_stats_from_quality, safe_get, tidal_cover_url, + tqdm_download, + tqdm_stream, ) logger = logging.getLogger("streamrip") diff --git a/streamrip/metadata.py b/streamrip/metadata.py index e748661..d278fe2 100644 --- a/streamrip/metadata.py +++ b/streamrip/metadata.py @@ -19,7 +19,7 @@ from .constants import ( TRACK_KEYS, ) from .exceptions import InvalidContainerError, InvalidSourceError -from .utils import get_quality_id, safe_get, tidal_cover_url, get_cover_urls +from .utils import get_cover_urls, get_quality_id, safe_get, tidal_cover_url logger = logging.getLogger("streamrip") diff --git a/streamrip/utils.py b/streamrip/utils.py index 90c41ab..15b401d 100644 --- a/streamrip/utils.py +++ b/streamrip/utils.py @@ -3,31 +3,24 @@ from __future__ import annotations import base64 +import functools +import hashlib import logging import os -from string import Formatter -from typing import ( - Dict, - Hashable, - Optional, - Tuple, - Union, - Generator, -) -from collections import OrderedDict -import functools -from Cryptodome.Cipher import Blowfish -import hashlib import re +from collections import OrderedDict from json import JSONDecodeError +from string import Formatter +from typing import Dict, Generator, Hashable, Optional, Tuple, Union import click import requests +from Cryptodome.Cipher import Blowfish from pathvalidate import sanitize_filename from requests.packages import urllib3 from tqdm import tqdm -from .constants import TIDAL_COVER_URL, COVER_SIZES +from .constants import COVER_SIZES, TIDAL_COVER_URL from .exceptions import InvalidQuality, InvalidSourceError, NonStreamable urllib3.disable_warnings() @@ -60,19 +53,6 @@ def safe_get(d: dict, *keys: Hashable, default=None): curr = res return res - """ - FLAC = 9 - MP3_320 = 3 - MP3_128 = 1 - MP4_RA3 = 15 - MP4_RA2 = 14 - MP4_RA1 = 13 - DEFAULT = 8 - LOCAL = 0 - - - """ - __QUALITY_MAP: Dict[str, Dict[int, Union[int, str, Tuple[int, str]]]] = { "qobuz": {