diff --git a/rip/cli.py b/rip/cli.py
index 06e8b5d..4a881dc 100644
--- a/rip/cli.py
+++ b/rip/cli.py
@@ -169,11 +169,12 @@ class SearchCommand(Command):
class DiscoverCommand(Command):
"""
- Browse and download items in interactive mode (Qobuz only).
+ Browse and download items in interactive mode (Qobuz and Deezer only).
discover
- {--s|scrape : Download all of the items in the list}
+ {--scrape : Download all of the items in the list}
{--m|max-items=50 : The number of items to fetch}
+ {--s|source=qobuz : The source to download from (qobuz or deezer)}
{list=ideal-discography : The list to fetch}
"""
@@ -182,7 +183,7 @@ class DiscoverCommand(Command):
"$ rip discover\n\n"
"Browse the best-sellers list\n"
"$ rip discover best-sellers\n\n"
- "Available options for list:\n\n"
+ "Available options for Qobuz list:\n\n"
" • most-streamed\n"
" • recent-releases\n"
" • best-sellers\n"
@@ -197,21 +198,46 @@ class DiscoverCommand(Command):
" • universal-classic\n"
" • universal-jazz\n"
" • universal-jeunesse\n"
- " • universal-chanson\n"
+ " • universal-chanson\n\n"
+ "Browse the Deezer editorial releases list\n"
+ "$ rip discover --source deezer\n\n"
+ "Browse the Deezer charts\n"
+ "$ rip discover --source deezer charts\n\n"
+ "Available options for Deezer list:\n\n"
+ " • releases\n"
+ " • charts\n"
+ " • selection\n"
)
def handle(self):
- from streamrip.constants import QOBUZ_FEATURED_KEYS
-
- chosen_list = self.argument("list")
+ source = self.option("source")
scrape = self.option("scrape")
+ chosen_list = self.argument("list")
max_items = self.option("max-items")
- if chosen_list not in QOBUZ_FEATURED_KEYS:
+ if source == "qobuz":
+ from streamrip.constants import QOBUZ_FEATURED_KEYS
+
+ if chosen_list not in QOBUZ_FEATURED_KEYS:
+ self.line(
+ f'Error: list "{chosen_list}" not available'
+ )
+ self.line(self.help)
+ return 1
+ elif source == "deezer":
+ from streamrip.constants import DEEZER_FEATURED_KEYS
+
+ if chosen_list not in DEEZER_FEATURED_KEYS:
+ self.line(
+ f'Error: list "{chosen_list}" not available'
+ )
+ self.line(self.help)
+ return 1
+
+ else:
self.line(
- f'Error: list "{chosen_list}" not available'
+ "Invalid source. Choose either qobuz or deezer"
)
- self.line(self.help)
return 1
config = Config()
@@ -223,12 +249,14 @@ class DiscoverCommand(Command):
return 0
if core.interactive_search(
- chosen_list, "qobuz", "featured", limit=int(max_items)
+ chosen_list, source, "featured", limit=int(max_items)
):
core.download()
else:
self.line("No items chosen, exiting.")
+ return 0
+
class LastfmCommand(Command):
"""
diff --git a/rip/core.py b/rip/core.py
index 9bc59d9..c998412 100644
--- a/rip/core.py
+++ b/rip/core.py
@@ -654,6 +654,8 @@ class RipCore(list):
client = self.get_client(source)
results = client.search(query, media_type)
+ if media_type == "featured":
+ media_type = "album"
if isinstance(results, Generator): # QobuzClient
for page in results:
@@ -670,11 +672,11 @@ class RipCore(list):
if i >= limit - 1:
return
else:
- logger.debug("Not generator")
items = (
results.get("data")
or results.get("items")
or results.get("collection")
+ or results.get("albums", {}).get("data", False)
)
if items is None:
raise NoResultsFound(query)
diff --git a/streamrip/clients.py b/streamrip/clients.py
index ab9869e..1637fc3 100644
--- a/streamrip/clients.py
+++ b/streamrip/clients.py
@@ -499,7 +499,19 @@ class DeezerClient(Client):
"""
# TODO: use limit parameter
try:
- search_function = getattr(self.client.api, f"search_{media_type}")
+ if media_type == "featured":
+ if query:
+ print(query)
+ search_function = getattr(
+ self.client.api, f"get_editorial_{query}"
+ )
+ else:
+ search_function = self.client.api.get_editorial_releases
+
+ else:
+ search_function = getattr(
+ self.client.api, f"search_{media_type}"
+ )
except AttributeError:
raise Exception
diff --git a/streamrip/constants.py b/streamrip/constants.py
index fb10724..ee00ed8 100644
--- a/streamrip/constants.py
+++ b/streamrip/constants.py
@@ -152,6 +152,7 @@ TIDAL_Q_MAP = {
}
DEEZER_MAX_Q = 6
+DEEZER_FEATURED_KEYS = {"releases", "charts", "selection"}
AVAILABLE_QUALITY_IDS = (0, 1, 2, 3, 4)
DEEZER_FORMATS = {
"AAC_64",
diff --git a/streamrip/media.py b/streamrip/media.py
index fd09e03..b73b673 100644
--- a/streamrip/media.py
+++ b/streamrip/media.py
@@ -303,9 +303,11 @@ class Track(Media):
url_id = self.id
try:
+ print(url_id)
+ print(self.quality)
dl_info = self.client.get_file_url(url_id, self.quality)
except Exception as e:
- # raise NonStreamable(repr(e))
+ logger.debug(repr(e))
raise NonStreamable(e)
if self.client.source == "qobuz":
diff --git a/streamrip/utils.py b/streamrip/utils.py
index 0b71b23..050d71b 100644
--- a/streamrip/utils.py
+++ b/streamrip/utils.py
@@ -103,12 +103,17 @@ class DownloadStream:
assert isinstance(self.id, str), self.id
blowfish_key = self._generate_blowfish_key(self.id)
- decryptor = self._create_deezer_decryptor(blowfish_key)
+ # decryptor = self._create_deezer_decryptor(blowfish_key)
+ CHUNK_SIZE = 2048 * 3
return (
- (decryptor.decrypt(chunk[:2048]) + chunk[2048:])
- # (self._decrypt_chunk(blowfish_key, chunk[:2048]) + chunk[2048:])
- if len(chunk) >= 2048 else chunk
- for chunk in self.request.iter_content(2048 * 3)
+ # (decryptor.decrypt(chunk[:2048]) + chunk[2048:])
+ (
+ self._decrypt_chunk(blowfish_key, chunk[:2048])
+ + chunk[2048:]
+ )
+ if len(chunk) >= 2048
+ else chunk
+ for chunk in self.request.iter_content(CHUNK_SIZE)
)
return self.request.iter_content(chunk_size=1024)
@@ -155,6 +160,7 @@ class DownloadStream:
return Blowfish.new(
key,
Blowfish.MODE_CBC,
+ b"\x00\x01\x02\x03\x04\x05\x06\x07",
).decrypt(data)