Soundcloud album search working

This commit is contained in:
nathom 2021-04-05 18:24:26 -07:00
parent 07b6e402b1
commit 47723c45cf
3 changed files with 39 additions and 11 deletions

View file

@ -58,7 +58,7 @@ def cli(ctx, **kwargs):
config.session["conversion"]["enabled"] = True config.session["conversion"]["enabled"] = True
config.session["conversion"]["codec"] = kwargs["convert"] config.session["conversion"]["codec"] = kwargs["convert"]
if kwargs["quality"] is not None: if kwargs["quality"] is not None:
quality = int(kwargs['quality']) quality = int(kwargs["quality"])
if quality not in range(5): if quality not in range(5):
click.secho("Invalid quality", fg="red") click.secho("Invalid quality", fg="red")
return return

View file

@ -1,10 +1,10 @@
import logging import logging
from pprint import pprint
import os import os
import re import re
import sys import sys
from getpass import getpass from getpass import getpass
from hashlib import md5 from hashlib import md5
from pprint import pprint
from string import Formatter from string import Formatter
from typing import Generator, Optional, Tuple, Union from typing import Generator, Optional, Tuple, Union
@ -12,7 +12,13 @@ import click
from .clients import DeezerClient, QobuzClient, SoundCloudClient, TidalClient from .clients import DeezerClient, QobuzClient, SoundCloudClient, TidalClient
from .config import Config from .config import Config
from .constants import (CONFIG_PATH, DB_PATH, SOUNDCLOUD_URL_REGEX, URL_REGEX, MEDIA_TYPES) from .constants import (
CONFIG_PATH,
DB_PATH,
MEDIA_TYPES,
SOUNDCLOUD_URL_REGEX,
URL_REGEX,
)
from .db import MusicDB from .db import MusicDB
from .downloader import Album, Artist, Label, Playlist, Track from .downloader import Album, Artist, Label, Playlist, Track
from .exceptions import AuthenticationError, ParsingError from .exceptions import AuthenticationError, ParsingError
@ -129,8 +135,8 @@ class MusicDL(list):
client = self.get_client(source) client = self.get_client(source)
if media_type not in MEDIA_TYPES: if media_type not in MEDIA_TYPES:
if 'playlist' in media_type: # for SoundCloud if "playlist" in media_type: # for SoundCloud
media_type = 'playlist' media_type = "playlist"
assert media_type in MEDIA_TYPES, media_type assert media_type in MEDIA_TYPES, media_type
item = MEDIA_CLASS[media_type](client=client, id=item_id) item = MEDIA_CLASS[media_type](client=client, id=item_id)
@ -265,7 +271,9 @@ class MusicDL(list):
if i > limit: if i > limit:
return return
else: else:
for item in results.get("data") or results.get("items"): for item in (
results.get("data") or results.get("items") or results.get("collection")
):
yield MEDIA_CLASS[media_type].from_api(item, client) yield MEDIA_CLASS[media_type].from_api(item, client)
i += 1 i += 1
if i > limit: if i > limit:
@ -283,6 +291,13 @@ class MusicDL(list):
fmt = "{name}" fmt = "{name}"
elif isinstance(media, Track): elif isinstance(media, Track):
fmt = "{artist} - {title}\nReleased on {year}" fmt = "{artist} - {title}\nReleased on {year}"
elif isinstance(media, Playlist):
fmt = (
"{title}\n"
"{tracktotal} tracks\n"
"{popularity}\n"
"Description: {description}"
)
else: else:
raise NotImplementedError raise NotImplementedError
@ -301,7 +316,7 @@ class MusicDL(list):
def from_title(s): def from_title(s):
num = [] num = []
for char in s: for char in s:
if char.isdigit(): if char != '.':
num.append(char) num.append(char)
else: else:
break break

View file

@ -1,5 +1,4 @@
import logging import logging
from pprint import pprint
import os import os
import re import re
import shutil import shutil
@ -133,7 +132,9 @@ class Track:
elif self.client.source == "deezer": elif self.client.source == "deezer":
self.cover_url = self.resp["album"]["cover_medium"] self.cover_url = self.resp["album"]["cover_medium"]
elif self.client.source == "soundcloud": elif self.client.source == "soundcloud":
self.cover_url = (self.resp["artwork_url"] or self.resp['user'].get("avatar_url")).replace("large", "t500x500") self.cover_url = (
self.resp["artwork_url"] or self.resp["user"].get("avatar_url")
).replace("large", "t500x500")
else: else:
raise InvalidSourceError(self.client.source) raise InvalidSourceError(self.client.source)
except KeyError: except KeyError:
@ -241,7 +242,7 @@ class Track:
[ [
"ffmpeg", "ffmpeg",
"-i", "-i",
dl_info['url'], dl_info["url"],
"-c", "-c",
"copy", "copy",
"-y", "-y",
@ -718,6 +719,9 @@ class Album(Tracklist):
@classmethod @classmethod
def from_api(cls, resp, client): def from_api(cls, resp, client):
if client.source == "soundcloud":
return Playlist.from_api(resp, client)
info = cls._parse_get_resp(resp, client) info = cls._parse_get_resp(resp, client)
return cls(client, **info) return cls(client, **info)
@ -731,7 +735,7 @@ class Album(Tracklist):
""" """
if client.source == "qobuz": if client.source == "qobuz":
if resp.get("maximum_sampling_rate", False): if resp.get("maximum_sampling_rate", False):
sampling_rate = resp['maximum_sampling_rate'] * 1000 sampling_rate = resp["maximum_sampling_rate"] * 1000
else: else:
sampling_rate = None sampling_rate = None
@ -1063,6 +1067,7 @@ class Playlist(Tracklist):
else: else:
raise NotImplementedError raise NotImplementedError
self.tracktotal = len(tracklist)
if self.client.source == "soundcloud": if self.client.source == "soundcloud":
# No meta is included in soundcloud playlist # No meta is included in soundcloud playlist
# response, so it is loaded at download time # response, so it is loaded at download time
@ -1147,6 +1152,14 @@ class Playlist(Tracklist):
"name": item["title"], "name": item["title"],
"id": item["id"], "id": item["id"],
} }
elif client.source == "soundcloud":
return {
"name": item["title"],
"id": item["permalink_url"],
"description": item["description"],
"popularity": f"{item['likes_count']} likes",
"tracktotal": len(item["tracks"]),
}
raise InvalidSourceError(client.source) raise InvalidSourceError(client.source)