mirror of
https://github.com/nathom/streamrip.git
synced 2024-09-19 19:28:46 -04:00
Soundcloud downloads working
This commit is contained in:
parent
fa72e82769
commit
f3274693bb
6 changed files with 34 additions and 39 deletions
|
@ -656,14 +656,7 @@ class TidalClient(ClientInterface):
|
|||
class SoundCloudClient(ClientInterface):
|
||||
source = "soundcloud"
|
||||
max_quality = 0
|
||||
|
||||
def __init__(self):
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update(
|
||||
{
|
||||
"User-Agent": AGENT,
|
||||
}
|
||||
)
|
||||
logged_in = True
|
||||
|
||||
def login(self):
|
||||
raise NotImplementedError
|
||||
|
@ -671,10 +664,10 @@ class SoundCloudClient(ClientInterface):
|
|||
def get(self, id, media_type="track"):
|
||||
assert media_type in ("track", "playlist"), f"{media_type} not supported"
|
||||
|
||||
if media_type == "track":
|
||||
resp, _ = self._get(f"{media_type}s/{id}")
|
||||
elif "http" in id:
|
||||
if "http" in str(id):
|
||||
resp, _ = self._get(f"resolve?url={id}")
|
||||
elif media_type == "track":
|
||||
resp, _ = self._get(f"{media_type}s/{id}")
|
||||
else:
|
||||
raise Exception(id)
|
||||
|
||||
|
@ -716,7 +709,7 @@ class SoundCloudClient(ClientInterface):
|
|||
url = f"{SOUNDCLOUD_BASE}/{path}"
|
||||
|
||||
logger.debug(f"Fetching url {url}")
|
||||
r = self.session.get(url, params=params)
|
||||
r = requests.get(url, params=params)
|
||||
if resp_obj:
|
||||
return r
|
||||
|
||||
|
|
|
@ -54,6 +54,9 @@ class Config:
|
|||
"deezer": {
|
||||
"quality": 2,
|
||||
},
|
||||
"soundcloud": {
|
||||
"quality": 0,
|
||||
},
|
||||
"database": {"enabled": True, "path": None},
|
||||
"conversion": {
|
||||
"enabled": False,
|
||||
|
|
|
@ -135,13 +135,14 @@ FOLDER_FORMAT = (
|
|||
TRACK_FORMAT = "{tracknumber}. {artist} - {title}"
|
||||
|
||||
URL_REGEX = (
|
||||
r"https:\/\/(?:www|open|play|listen)?\.?(\w+)\.com(?:(?:\/(track|playlist|album|"
|
||||
r"https:\/\/(?:www|open|play|listen)?\.?(qobuz|tidal|deezer)\.com(?:(?:\/(track|playlist|album|"
|
||||
r"artist|label))|(?:\/[-\w]+?))+\/([-\w]+)"
|
||||
)
|
||||
SOUNDCLOUD_URL_REGEX = r"https://soundcloud.com/[-\w:]+"
|
||||
SOUNDCLOUD_URL_REGEX = r"https://soundcloud.com/[-\w:/]+"
|
||||
SOUNDCLOUD_CLIENT_ID = "a3e059563d7fd3372b49b37f00a00bcf"
|
||||
|
||||
|
||||
TIDAL_MAX_Q = 7
|
||||
DEEZER_MAX_Q = 6
|
||||
AVAILABLE_QUALITY_IDS = (0, 1, 2, 3, 4)
|
||||
MEDIA_TYPES = ("track", "album", "artist", "label", "playlist")
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
from pprint import pprint
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
@ -11,7 +12,7 @@ import click
|
|||
|
||||
from .clients import DeezerClient, QobuzClient, SoundCloudClient, TidalClient
|
||||
from .config import Config
|
||||
from .constants import CONFIG_PATH, DB_PATH, SOUNDCLOUD_URL_REGEX, URL_REGEX
|
||||
from .constants import (CONFIG_PATH, DB_PATH, SOUNDCLOUD_URL_REGEX, URL_REGEX, MEDIA_TYPES)
|
||||
from .db import MusicDB
|
||||
from .downloader import Album, Artist, Label, Playlist, Track
|
||||
from .exceptions import AuthenticationError, ParsingError
|
||||
|
@ -127,6 +128,11 @@ class MusicDL(list):
|
|||
|
||||
client = self.get_client(source)
|
||||
|
||||
if media_type not in MEDIA_TYPES:
|
||||
if 'playlist' in media_type: # for SoundCloud
|
||||
media_type = 'playlist'
|
||||
|
||||
assert media_type in MEDIA_TYPES, media_type
|
||||
item = MEDIA_CLASS[media_type](client=client, id=item_id)
|
||||
self.append(item)
|
||||
|
||||
|
@ -209,11 +215,13 @@ class MusicDL(list):
|
|||
|
||||
:raises exceptions.ParsingError
|
||||
"""
|
||||
parsed = self.url_parse.findall(url)
|
||||
parsed = self.url_parse.findall(url) # Qobuz, Tidal, Dezer
|
||||
soundcloud_urls = self.soundcloud_url_parse.findall(url)
|
||||
if len(soundcloud_urls) > 0:
|
||||
soundcloud_items = [self.clients["soundcloud"].get(u) for u in soundcloud_urls]
|
||||
|
||||
parsed.extend(
|
||||
self.clients["soundcloud"].resolve(u) for u in soundcloud_urls
|
||||
("soundcloud", item["kind"], url)
|
||||
for item, url in zip(soundcloud_items, soundcloud_urls)
|
||||
)
|
||||
|
||||
logger.debug(f"Parsed urls: {parsed}")
|
||||
|
|
|
@ -121,7 +121,6 @@ class Track:
|
|||
assert hasattr(self, "id"), "id must be set before loading metadata"
|
||||
|
||||
self.resp = self.client.get(self.id, media_type="track")
|
||||
pprint(self.resp)
|
||||
self.meta = TrackMetadata(
|
||||
track=self.resp, source=self.client.source
|
||||
) # meta dict -> TrackMetadata object
|
||||
|
@ -133,7 +132,7 @@ class Track:
|
|||
elif self.client.source == "deezer":
|
||||
self.cover_url = self.resp["album"]["cover_medium"]
|
||||
elif self.client.source == "soundcloud":
|
||||
self.cover_url = self.resp["artwork_url"].replace("large", "t500x500")
|
||||
self.cover_url = (self.resp["artwork_url"] or self.resp['user'].get("avatar_url")).replace("large", "t500x500")
|
||||
else:
|
||||
raise InvalidSourceError(self.client.source)
|
||||
except KeyError:
|
||||
|
@ -169,7 +168,7 @@ class Track:
|
|||
:type progress_bar: bool
|
||||
"""
|
||||
# args override attributes
|
||||
self.quality = min((quality or self.quality), self.client.max_quality)
|
||||
self.quality = min(quality, self.client.max_quality)
|
||||
self.folder = parent_folder or self.folder
|
||||
|
||||
self.file_format = kwargs.get("track_format", TRACK_FORMAT)
|
||||
|
@ -194,6 +193,7 @@ class Track:
|
|||
return False
|
||||
|
||||
if hasattr(self, "cover_url"): # only for playlists and singles
|
||||
logger.debug("Downloading cover")
|
||||
self.download_cover()
|
||||
|
||||
if self.client.source == "soundcloud":
|
||||
|
@ -203,7 +203,7 @@ class Track:
|
|||
|
||||
dl_info = self.client.get_file_url(url_id, self.quality)
|
||||
|
||||
temp_file = os.path.join(gettempdir(), f"~{self.id}_{quality}.tmp")
|
||||
temp_file = os.path.join(gettempdir(), f"~{hash(self.id)}_{quality}.tmp")
|
||||
logger.debug("Temporary file path: %s", temp_file)
|
||||
|
||||
if self.client.source == "qobuz":
|
||||
|
@ -240,7 +240,7 @@ class Track:
|
|||
[
|
||||
"ffmpeg",
|
||||
"-i",
|
||||
dl_info,
|
||||
dl_info['url'],
|
||||
"-c",
|
||||
"copy",
|
||||
"-y",
|
||||
|
@ -288,7 +288,7 @@ class Track:
|
|||
|
||||
assert hasattr(self, "cover_url"), "must set cover_url attribute"
|
||||
|
||||
self.cover_path = os.path.join(self.folder, f"cover{hash(self.meta.album)}.jpg")
|
||||
self.cover_path = os.path.join(self.folder, f"cover{hash(self.cover_url)}.jpg")
|
||||
logger.debug(f"Downloading cover from {self.cover_url}")
|
||||
click.secho(f"\nDownloading cover art for {self!s}", fg="blue")
|
||||
|
||||
|
@ -1019,7 +1019,7 @@ class Playlist(Tracklist):
|
|||
self.name = self.meta["name"]
|
||||
tracklist = self.meta["tracks"]["items"]
|
||||
|
||||
def gen_cover(track): # ?
|
||||
def gen_cover(track):
|
||||
return track["album"]["image"]["small"]
|
||||
|
||||
def meta_args(track):
|
||||
|
@ -1047,7 +1047,6 @@ class Playlist(Tracklist):
|
|||
return track["album"]["cover_medium"]
|
||||
|
||||
elif self.client.source == "soundcloud":
|
||||
pprint(self.meta)
|
||||
self.name = self.meta["title"]
|
||||
tracklist = self.meta["tracks"]
|
||||
|
||||
|
@ -1126,7 +1125,6 @@ class Playlist(Tracklist):
|
|||
:param client:
|
||||
:type client: ClientInterface
|
||||
"""
|
||||
print(item.keys())
|
||||
if client.source == "qobuz":
|
||||
return {
|
||||
"name": item["name"],
|
||||
|
@ -1223,7 +1221,7 @@ class Artist(Tracklist):
|
|||
|
||||
def download(
|
||||
self,
|
||||
parent_folder: str = "Downloads",
|
||||
parent_folder: str = "StreamripDownloads",
|
||||
filters: Optional[Tuple] = None,
|
||||
no_repeats: bool = False,
|
||||
quality: int = 6,
|
||||
|
|
|
@ -154,22 +154,14 @@ class TrackMetadata:
|
|||
|
||||
elif self.__source == "soundcloud":
|
||||
self.title = track["title"].strip()
|
||||
print(f"{self.title=}")
|
||||
self.genre = track["genre"]
|
||||
print(f"{self.genre=}")
|
||||
self.artist = track["user"]["username"]
|
||||
self.albumartist = self.artist
|
||||
print(f"{self.artist=}")
|
||||
self.year = track["created_at"][:4]
|
||||
print(f"{self.year=}")
|
||||
self.label = track["label_name"]
|
||||
print(f"{self.label=}")
|
||||
self.comment = track["description"]
|
||||
print(f"{self.comment=}")
|
||||
self.description = track["description"]
|
||||
self.tracknumber = 0
|
||||
print(f"{self.tracknumber=}")
|
||||
self.tracktotal = 0
|
||||
print(f"{self.tracktotal=}")
|
||||
|
||||
else:
|
||||
raise ValueError(self.__source)
|
||||
|
|
Loading…
Reference in a new issue