mirror of
https://github.com/nathom/streamrip.git
synced 2025-05-09 14:11:55 -04:00
Misc fixes related to search
This commit is contained in:
parent
8c9673a067
commit
a515b9c1fd
6 changed files with 55 additions and 26 deletions
|
@ -181,6 +181,7 @@ class DeezerClient(Client):
|
|||
)
|
||||
|
||||
dl_info["url"] = url
|
||||
logger.debug("dz track info: %s", track_info)
|
||||
return DeezerDownloadable(self.session, dl_info)
|
||||
|
||||
def _get_encrypted_file_url(
|
||||
|
@ -212,5 +213,6 @@ class DeezerClient(Client):
|
|||
path = binascii.hexlify(
|
||||
AES.new(b"jo6aey6haid2Teih", AES.MODE_ECB).encrypt(info_bytes),
|
||||
).decode("utf-8")
|
||||
|
||||
return f"https://e-cdns-proxy-{track_hash[0]}.dzcdn.net/mobile/1/{path}"
|
||||
url = f"https://e-cdns-proxy-{track_hash[0]}.dzcdn.net/mobile/1/{path}"
|
||||
logger.debug("Encrypted file path %s", url)
|
||||
return url
|
||||
|
|
|
@ -36,7 +36,7 @@ class SoundcloudClient(Client):
|
|||
async def login(self):
|
||||
self.session = await self.get_session()
|
||||
client_id, app_version = self.config.client_id, self.config.app_version
|
||||
if not client_id or not app_version or not (await self._announce()):
|
||||
if not client_id or not app_version or not (await self._announce_success()):
|
||||
client_id, app_version = await self._refresh_tokens()
|
||||
# update file and session configs and save to disk
|
||||
cf = self.global_config.file.soundcloud
|
||||
|
@ -54,13 +54,14 @@ class SoundcloudClient(Client):
|
|||
"""Fetch metadata for an item in Soundcloud API.
|
||||
|
||||
Args:
|
||||
----
|
||||
|
||||
item_id (str): Plain soundcloud item ID (e.g 1633786176)
|
||||
media_type (str): track or playlist
|
||||
|
||||
Returns:
|
||||
-------
|
||||
API response.
|
||||
|
||||
API response. The item IDs for the tracks in the playlist are modified to
|
||||
include resolution status.
|
||||
"""
|
||||
if media_type == "track":
|
||||
# parse custom id that we injected
|
||||
|
@ -227,12 +228,15 @@ class SoundcloudClient(Client):
|
|||
async with self.session.get(url, params=_params, headers=headers) as resp:
|
||||
return await resp.content.read(), resp.status
|
||||
|
||||
async def _resolve_url(self, url: str) -> dict:
|
||||
async def resolve_url(self, url: str) -> dict:
|
||||
resp, status = await self._api_request("resolve", params={"url": url})
|
||||
assert status == 200
|
||||
if resp["kind"] == "track":
|
||||
resp["id"] = self._get_custom_id(resp)
|
||||
|
||||
return resp
|
||||
|
||||
async def _announce(self):
|
||||
async def _announce_success(self):
|
||||
url = f"{BASE}/announcements"
|
||||
_, status = await self._request_body(url)
|
||||
return status == 200
|
||||
|
|
|
@ -39,7 +39,7 @@ class ArtistSummary(Summary):
|
|||
return "artist"
|
||||
|
||||
def summarize(self) -> str:
|
||||
return self.name
|
||||
return clean(self.name)
|
||||
|
||||
def preview(self) -> str:
|
||||
return f"{self.num_albums} Albums\n\nID: {self.id}"
|
||||
|
@ -73,7 +73,8 @@ class TrackSummary(Summary):
|
|||
return "track"
|
||||
|
||||
def summarize(self) -> str:
|
||||
return f"{self.name} by {self.artist}"
|
||||
# This char breaks the menu for some reason
|
||||
return f"{clean(self.name)} by {clean(self.artist)}"
|
||||
|
||||
def preview(self) -> str:
|
||||
return f"Released on:\n{self.date_released}\n\nID: {self.id}"
|
||||
|
@ -119,7 +120,7 @@ class AlbumSummary(Summary):
|
|||
return "album"
|
||||
|
||||
def summarize(self) -> str:
|
||||
return f"{self.name} by {self.artist}"
|
||||
return f"{clean(self.name)} by {clean(self.artist)}"
|
||||
|
||||
def preview(self) -> str:
|
||||
return f"Date released:\n{self.date_released}\n\n{self.num_tracks} Tracks\n\nID: {self.id}"
|
||||
|
@ -188,11 +189,14 @@ class PlaylistSummary(Summary):
|
|||
description: str
|
||||
|
||||
def summarize(self) -> str:
|
||||
return f"{self.name} by {self.creator}"
|
||||
name = clean(self.name)
|
||||
creator = clean(self.creator)
|
||||
return f"{name} by {creator}"
|
||||
|
||||
def preview(self) -> str:
|
||||
desc = clean(self.description, trunc=False)
|
||||
wrapped = "\n".join(
|
||||
textwrap.wrap(self.description, os.get_terminal_size().columns - 4 or 70),
|
||||
textwrap.wrap(desc, os.get_terminal_size().columns - 4 or 70),
|
||||
)
|
||||
return f"{self.num_tracks} tracks\n\nDescription:\n{wrapped}\n\nID: {self.id}"
|
||||
|
||||
|
@ -214,6 +218,7 @@ class PlaylistSummary(Summary):
|
|||
item.get("tracks_count")
|
||||
or item.get("nb_tracks")
|
||||
or item.get("numberOfTracks")
|
||||
or len(item.get("tracks", []))
|
||||
or -1
|
||||
)
|
||||
description = item.get("description") or "No description"
|
||||
|
@ -273,3 +278,11 @@ class SearchResults:
|
|||
assert ind is not None
|
||||
i = int(ind.group(0))
|
||||
return self.results[i - 1].preview()
|
||||
|
||||
|
||||
def clean(s: str, trunc=True) -> str:
|
||||
s = s.replace("|", "").replace("\n", "")
|
||||
if trunc:
|
||||
max_chars = 50
|
||||
return s[:max_chars]
|
||||
return s
|
||||
|
|
|
@ -25,8 +25,6 @@ class ProgressManager:
|
|||
BarColumn(bar_width=None),
|
||||
"[progress.percentage]{task.percentage:>3.1f}%",
|
||||
"•",
|
||||
# DownloadColumn(),
|
||||
# "•",
|
||||
TransferSpeedColumn(),
|
||||
"•",
|
||||
TimeRemainingColumn(),
|
||||
|
|
|
@ -36,8 +36,14 @@ def coro(f):
|
|||
"--config-path",
|
||||
default=DEFAULT_CONFIG_PATH,
|
||||
help="Path to the configuration file",
|
||||
type=click.Path(readable=True, writable=True),
|
||||
)
|
||||
@click.option(
|
||||
"-f",
|
||||
"--folder",
|
||||
help="The folder to download items into.",
|
||||
type=click.Path(file_okay=False, dir_okay=True),
|
||||
)
|
||||
@click.option("-f", "--folder", help="The folder to download items into.")
|
||||
@click.option(
|
||||
"-ndb",
|
||||
"--no-db",
|
||||
|
@ -46,11 +52,14 @@ def coro(f):
|
|||
is_flag=True,
|
||||
)
|
||||
@click.option(
|
||||
"-q", "--quality", help="The maximum quality allowed to download", type=int
|
||||
"-q",
|
||||
"--quality",
|
||||
help="The maximum quality allowed to download",
|
||||
type=click.IntRange(min=0, max=4),
|
||||
)
|
||||
@click.option(
|
||||
"-c",
|
||||
"--convert",
|
||||
"--codec",
|
||||
help="Convert the downloaded files to an audio codec (ALAC, FLAC, MP3, AAC, or OGG)",
|
||||
)
|
||||
@click.option(
|
||||
|
@ -66,7 +75,7 @@ def coro(f):
|
|||
is_flag=True,
|
||||
)
|
||||
@click.pass_context
|
||||
def rip(ctx, config_path, folder, no_db, quality, convert, no_progress, verbose):
|
||||
def rip(ctx, config_path, folder, no_db, quality, codec, no_progress, verbose):
|
||||
"""Streamrip: the all in one music downloader."""
|
||||
global logger
|
||||
logging.basicConfig(
|
||||
|
@ -112,7 +121,8 @@ def rip(ctx, config_path, folder, no_db, quality, convert, no_progress, verbose)
|
|||
return
|
||||
|
||||
# set session config values to command line args
|
||||
c.session.database.downloads_enabled = not no_db
|
||||
if no_db:
|
||||
c.session.database.downloads_enabled = False
|
||||
if folder is not None:
|
||||
c.session.downloads.folder = folder
|
||||
|
||||
|
@ -122,10 +132,10 @@ def rip(ctx, config_path, folder, no_db, quality, convert, no_progress, verbose)
|
|||
c.session.deezer.quality = quality
|
||||
c.session.soundcloud.quality = quality
|
||||
|
||||
if convert is not None:
|
||||
if codec is not None:
|
||||
c.session.conversion.enabled = True
|
||||
assert convert.upper() in ("ALAC", "FLAC", "OGG", "MP3", "AAC")
|
||||
c.session.conversion.codec = convert.upper()
|
||||
assert codec.upper() in ("ALAC", "FLAC", "OGG", "MP3", "AAC")
|
||||
c.session.conversion.codec = codec.upper()
|
||||
|
||||
if no_progress:
|
||||
c.session.cli.progress_bars = False
|
||||
|
@ -147,7 +157,9 @@ async def url(ctx, urls):
|
|||
|
||||
|
||||
@rip.command()
|
||||
@click.argument("path", required=True)
|
||||
@click.argument(
|
||||
"path", required=True, type=click.Path(file_okay=True, dir_okay=False, exists=True)
|
||||
)
|
||||
@click.pass_context
|
||||
@coro
|
||||
async def file(ctx, path):
|
||||
|
@ -275,7 +287,7 @@ async def search(ctx, first, source, media_type, query):
|
|||
"""Search for content using a specific source.
|
||||
|
||||
Example:
|
||||
-------
|
||||
|
||||
rip search qobuz album 'rumours'
|
||||
"""
|
||||
with ctx.obj["config"] as cfg:
|
||||
|
|
|
@ -140,7 +140,7 @@ class SoundcloudURL(URL):
|
|||
config: Config,
|
||||
db: Database,
|
||||
) -> Pending:
|
||||
resolved = await client._resolve_url(self.url)
|
||||
resolved = await client.resolve_url(self.url)
|
||||
media_type = resolved["kind"]
|
||||
item_id = str(resolved["id"])
|
||||
if media_type == "track":
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue