mirror of
https://github.com/nathom/streamrip.git
synced 2024-09-19 11:18:45 -04:00
Clean up exceptions
This commit is contained in:
parent
4228525dc3
commit
3e297d9643
11 changed files with 36 additions and 86 deletions
|
@ -7,7 +7,11 @@ import deezer
|
|||
from Cryptodome.Cipher import AES
|
||||
|
||||
from ..config import Config
|
||||
from ..exceptions import AuthenticationError, MissingCredentials, NonStreamable
|
||||
from ..exceptions import (
|
||||
AuthenticationError,
|
||||
MissingCredentialsError,
|
||||
NonStreamableError,
|
||||
)
|
||||
from .client import Client
|
||||
from .downloadable import DeezerDownloadable
|
||||
|
||||
|
@ -41,7 +45,7 @@ class DeezerClient(Client):
|
|||
self.session = await self.get_session()
|
||||
arl = self.config.arl
|
||||
if not arl:
|
||||
raise MissingCredentials
|
||||
raise MissingCredentialsError
|
||||
success = self.client.login_via_arl(arl)
|
||||
if not success:
|
||||
raise AuthenticationError
|
||||
|
@ -64,7 +68,7 @@ class DeezerClient(Client):
|
|||
try:
|
||||
item = await asyncio.to_thread(self.client.api.get_track, item_id)
|
||||
except Exception as e:
|
||||
raise NonStreamable(e)
|
||||
raise NonStreamableError(e)
|
||||
|
||||
album_id = item["album"]["id"]
|
||||
try:
|
||||
|
@ -157,7 +161,7 @@ class DeezerClient(Client):
|
|||
logger.debug("Fetching deezer url with token %s", token)
|
||||
url = self.client.get_track_url(token, format_str)
|
||||
except deezer.WrongLicense:
|
||||
raise NonStreamable(
|
||||
raise NonStreamableError(
|
||||
"The requested quality is not available with your subscription. "
|
||||
"Deezer HiFi is required for quality 2. Otherwise, the maximum "
|
||||
"quality allowed is 1.",
|
||||
|
@ -165,7 +169,7 @@ class DeezerClient(Client):
|
|||
except deezer.WrongGeolocation:
|
||||
if not is_retry:
|
||||
return await self.get_downloadable(fallback_id, quality, is_retry=True)
|
||||
raise NonStreamable(
|
||||
raise NonStreamableError(
|
||||
"The requested track is not available. This may be due to your country/location.",
|
||||
)
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ from Cryptodome.Cipher import AES, Blowfish
|
|||
from Cryptodome.Util import Counter
|
||||
|
||||
from .. import converter
|
||||
from ..exceptions import NonStreamable
|
||||
from ..exceptions import NonStreamableError
|
||||
|
||||
logger = logging.getLogger("streamrip")
|
||||
|
||||
|
@ -107,12 +107,12 @@ class DeezerDownloadable(Downloadable):
|
|||
info = await resp.json()
|
||||
try:
|
||||
# Usually happens with deezloader downloads
|
||||
raise NonStreamable(f"{info['error']} - {info['message']}")
|
||||
raise NonStreamableError(f"{info['error']} - {info['message']}")
|
||||
except KeyError:
|
||||
raise NonStreamable(info)
|
||||
raise NonStreamableError(info)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
raise NonStreamable("File not found.")
|
||||
raise NonStreamableError("File not found.")
|
||||
|
||||
if self.is_encrypted.search(self.url) is None:
|
||||
logger.debug(f"Deezer file at {self.url} not encrypted.")
|
||||
|
@ -206,10 +206,10 @@ class TidalDownloadable(Downloadable):
|
|||
# Turn CamelCase code into a readable sentence
|
||||
if restrictions:
|
||||
words = re.findall(r"([A-Z][a-z]+)", restrictions[0]["code"])
|
||||
raise NonStreamable(
|
||||
raise NonStreamableError(
|
||||
words[0] + " " + " ".join(map(str.lower, words[1:])),
|
||||
)
|
||||
raise NonStreamable(
|
||||
raise NonStreamableError(
|
||||
f"Tidal download: dl_info = {url, codec, encryption_key}"
|
||||
)
|
||||
self.url = url
|
||||
|
|
|
@ -15,8 +15,8 @@ from ..exceptions import (
|
|||
IneligibleError,
|
||||
InvalidAppIdError,
|
||||
InvalidAppSecretError,
|
||||
MissingCredentials,
|
||||
NonStreamable,
|
||||
MissingCredentialsError,
|
||||
NonStreamableError,
|
||||
)
|
||||
from .client import Client
|
||||
from .downloadable import BasicDownloadable, Downloadable
|
||||
|
@ -149,7 +149,7 @@ class QobuzClient(Client):
|
|||
self.session = await self.get_session()
|
||||
c = self.config.session.qobuz
|
||||
if not c.email_or_userid or not c.password_or_token:
|
||||
raise MissingCredentials
|
||||
raise MissingCredentialsError
|
||||
|
||||
assert not self.logged_in, "Already logged in"
|
||||
|
||||
|
@ -226,7 +226,7 @@ class QobuzClient(Client):
|
|||
status, resp = await self._api_request(epoint, params)
|
||||
|
||||
if status != 200:
|
||||
raise NonStreamable(
|
||||
raise NonStreamableError(
|
||||
f'Error fetching metadata. Message: "{resp["message"]}"',
|
||||
)
|
||||
|
||||
|
@ -313,10 +313,10 @@ class QobuzClient(Client):
|
|||
if restrictions:
|
||||
# Turn CamelCase code into a readable sentence
|
||||
words = re.findall(r"([A-Z][a-z]+)", restrictions[0]["code"])
|
||||
raise NonStreamable(
|
||||
raise NonStreamableError(
|
||||
words[0] + " " + " ".join(map(str.lower, words[1:])) + ".",
|
||||
)
|
||||
raise NonStreamable
|
||||
raise NonStreamableError
|
||||
|
||||
return BasicDownloadable(
|
||||
self.session,
|
||||
|
|
|
@ -4,7 +4,7 @@ import logging
|
|||
import re
|
||||
|
||||
from ..config import Config
|
||||
from ..exceptions import NonStreamable
|
||||
from ..exceptions import NonStreamableError
|
||||
from .client import Client
|
||||
from .downloadable import SoundcloudDownloadable
|
||||
|
||||
|
@ -155,7 +155,7 @@ class SoundcloudClient(Client):
|
|||
assert re.match(r"\d+", item_id) is not None
|
||||
|
||||
if download_info == self.NON_STREAMABLE:
|
||||
raise NonStreamable(item_info)
|
||||
raise NonStreamableError(item_info)
|
||||
|
||||
if download_info == self.ORIGINAL_DOWNLOAD:
|
||||
resp_json, status = await self._api_request(f"tracks/{item_id}/download")
|
||||
|
@ -183,7 +183,7 @@ class SoundcloudClient(Client):
|
|||
offset: int = 0,
|
||||
) -> list[dict]:
|
||||
# TODO: implement pagination
|
||||
assert media_type in ("track", "playlist")
|
||||
assert media_type in ("track", "playlist"), f"Cannot search for {media_type}"
|
||||
params = {
|
||||
"q": query,
|
||||
"facet": "genre",
|
||||
|
|
|
@ -115,7 +115,6 @@ class TidalClient(Client):
|
|||
:type limit: int
|
||||
:rtype: dict
|
||||
"""
|
||||
# TODD: paginate
|
||||
params = {
|
||||
"query": query,
|
||||
"limit": limit,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"""Streamrip specific exceptions."""
|
||||
from typing import List
|
||||
|
||||
from click import echo, style
|
||||
|
||||
|
@ -8,7 +7,7 @@ class AuthenticationError(Exception):
|
|||
"""AuthenticationError."""
|
||||
|
||||
|
||||
class MissingCredentials(Exception):
|
||||
class MissingCredentialsError(Exception):
|
||||
"""MissingCredentials."""
|
||||
|
||||
|
||||
|
@ -27,11 +26,7 @@ class InvalidAppSecretError(Exception):
|
|||
"""InvalidAppSecretError."""
|
||||
|
||||
|
||||
class InvalidQuality(Exception):
|
||||
"""InvalidQuality."""
|
||||
|
||||
|
||||
class NonStreamable(Exception):
|
||||
class NonStreamableError(Exception):
|
||||
"""Item is not streamable.
|
||||
|
||||
A versatile error that can have many causes.
|
||||
|
@ -71,50 +66,5 @@ class NonStreamable(Exception):
|
|||
return " ".join(base_msg)
|
||||
|
||||
|
||||
class InvalidContainerError(Exception):
|
||||
"""InvalidContainerError."""
|
||||
|
||||
|
||||
class InvalidSourceError(Exception):
|
||||
"""InvalidSourceError."""
|
||||
|
||||
|
||||
class ParsingError(Exception):
|
||||
"""ParsingError."""
|
||||
|
||||
|
||||
class TooLargeCoverArt(Exception):
|
||||
"""TooLargeCoverArt."""
|
||||
|
||||
|
||||
class BadEncoderOption(Exception):
|
||||
"""BadEncoderOption."""
|
||||
|
||||
|
||||
class ConversionError(Exception):
|
||||
"""ConversionError."""
|
||||
|
||||
|
||||
class NoResultsFound(Exception):
|
||||
"""NoResultsFound."""
|
||||
|
||||
|
||||
class ItemExists(Exception):
|
||||
"""ItemExists."""
|
||||
|
||||
|
||||
class PartialFailure(Exception):
|
||||
"""Raise if part of a tracklist fails to download."""
|
||||
|
||||
def __init__(self, failed_items: List):
|
||||
"""Create a PartialFailure exception.
|
||||
|
||||
:param failed_items:
|
||||
:type failed_items: List
|
||||
"""
|
||||
self.failed_items = failed_items
|
||||
super().__init__()
|
||||
|
||||
|
||||
class FfmpegError(Exception):
|
||||
"""Raise if ffmpeg returns nonzero exit code."""
|
||||
|
|
|
@ -7,7 +7,6 @@ from .. import progress
|
|||
from ..client import Client
|
||||
from ..config import Config
|
||||
from ..db import Database
|
||||
from ..exceptions import NonStreamable
|
||||
from ..metadata import AlbumMetadata
|
||||
from ..metadata.util import get_album_track_ids
|
||||
from .artwork import download_artwork
|
||||
|
@ -52,9 +51,8 @@ class PendingAlbum(Pending):
|
|||
async def resolve(self) -> Album | None:
|
||||
resp = await self.client.get_metadata(self.id, "album")
|
||||
|
||||
try:
|
||||
meta = AlbumMetadata.from_album_resp(resp, self.client.source)
|
||||
except NonStreamable:
|
||||
meta = AlbumMetadata.from_album_resp(resp, self.client.source)
|
||||
if meta is None:
|
||||
logger.error(
|
||||
f"Album {self.id} not available to stream on {self.client.source}",
|
||||
)
|
||||
|
|
|
@ -15,7 +15,7 @@ from ..client import Client
|
|||
from ..config import Config
|
||||
from ..console import console
|
||||
from ..db import Database
|
||||
from ..exceptions import NonStreamable
|
||||
from ..exceptions import NonStreamableError
|
||||
from ..filepath_utils import clean_filename
|
||||
from ..metadata import (
|
||||
AlbumMetadata,
|
||||
|
@ -47,7 +47,7 @@ class PendingPlaylistTrack(Pending):
|
|||
return None
|
||||
try:
|
||||
resp = await self.client.get_metadata(self.id, "track")
|
||||
except NonStreamable as e:
|
||||
except NonStreamableError as e:
|
||||
logger.error(f"Could not stream track {self.id}: {e}")
|
||||
return None
|
||||
|
||||
|
@ -78,7 +78,7 @@ class PendingPlaylistTrack(Pending):
|
|||
self._download_cover(album.covers, self.folder),
|
||||
self.client.get_downloadable(self.id, quality),
|
||||
)
|
||||
except NonStreamable as e:
|
||||
except NonStreamableError as e:
|
||||
logger.error("Error fetching download info for track: %s", e)
|
||||
self.db.set_failed(self.client.source, "track", self.id)
|
||||
return None
|
||||
|
|
|
@ -7,7 +7,7 @@ from .. import converter
|
|||
from ..client import Client, Downloadable
|
||||
from ..config import Config
|
||||
from ..db import Database
|
||||
from ..exceptions import NonStreamable
|
||||
from ..exceptions import NonStreamableError
|
||||
from ..filepath_utils import clean_filename
|
||||
from ..metadata import AlbumMetadata, Covers, TrackMetadata, tag_file
|
||||
from ..progress import add_title, get_progress_callback, remove_title
|
||||
|
@ -106,7 +106,7 @@ class PendingTrack(Pending):
|
|||
source = self.client.source
|
||||
try:
|
||||
resp = await self.client.get_metadata(self.id, "track")
|
||||
except NonStreamable as e:
|
||||
except NonStreamableError as e:
|
||||
logger.error(f"Track {self.id} not available for stream on {source}: {e}")
|
||||
return None
|
||||
|
||||
|
@ -150,7 +150,7 @@ class PendingSingle(Pending):
|
|||
|
||||
try:
|
||||
resp = await self.client.get_metadata(self.id, "track")
|
||||
except NonStreamable as e:
|
||||
except NonStreamableError as e:
|
||||
logger.error(f"Error fetching track {self.id}: {e}")
|
||||
return None
|
||||
# Patch for soundcloud
|
||||
|
|
|
@ -70,7 +70,6 @@ class Covers:
|
|||
@classmethod
|
||||
def from_deezer(cls, resp):
|
||||
c = cls()
|
||||
# c.set_cover_url("original", "org".join(resp["cover_xl"].rsplit("600", 1)))
|
||||
c.set_cover_url("original", resp["cover_xl"])
|
||||
c.set_cover_url("large", resp["cover_big"])
|
||||
c.set_cover_url("small", resp["cover_medium"])
|
||||
|
|
|
@ -10,7 +10,7 @@ from rich.prompt import Prompt
|
|||
from ..client import Client, DeezerClient, QobuzClient, SoundcloudClient, TidalClient
|
||||
from ..config import Config
|
||||
from ..console import console
|
||||
from ..exceptions import AuthenticationError, MissingCredentials
|
||||
from ..exceptions import AuthenticationError, MissingCredentialsError
|
||||
|
||||
logger = logging.getLogger("streamrip")
|
||||
|
||||
|
@ -61,7 +61,7 @@ class QobuzPrompter(CredentialPrompter):
|
|||
except AuthenticationError:
|
||||
console.print("[yellow]Invalid credentials, try again.")
|
||||
self._prompt_creds_and_set_session_config()
|
||||
except MissingCredentials:
|
||||
except MissingCredentialsError:
|
||||
self._prompt_creds_and_set_session_config()
|
||||
|
||||
def _prompt_creds_and_set_session_config(self):
|
||||
|
|
Loading…
Reference in a new issue