Skip to content

Commit

Permalink
Add -q <search_query> command line argument (#511)
Browse files Browse the repository at this point in the history
* Add -s <search_term> command line argument

* add final newline

* Format and lint

* Update README

* Update no results test to use random query

---------

Co-authored-by: 7x11x13 <[email protected]>
  • Loading branch information
mark-henry and 7x11x13 authored Aug 14, 2024
1 parent 091596c commit e06cc9c
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ scdl me -f
-h --help Show this screen
--version Show version
-l [url] URL can be track/playlist/user
-s [search_query] Search for a track/playlist/user and use the first result
-n [maxtracks] Download the n last tracks of a playlist according to the creation date
-a Download all tracks of user (including reposts)
-t Download all uploads of a user (no reposts)
Expand Down
33 changes: 30 additions & 3 deletions scdl/scdl.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""scdl allows you to download music from Soundcloud
Usage:
scdl (-l <track_url> | me) [-a | -f | -C | -t | -p | -r][-c | --force-metadata]
[-n <maxtracks>][-o <offset>][--hidewarnings][--debug | --error][--path <path>]
[--addtofile][--addtimestamp][--onlymp3][--hide-progress][--min-size <size>]
scdl (-l <track_url> | -s <search_query> | me) [-a | -f | -C | -t | -p | -r]
[-c | --force-metadata][-n <maxtracks>][-o <offset>][--hidewarnings][--debug | --error]
[--path <path>][--addtofile][--addtimestamp][--onlymp3][--hide-progress][--min-size <size>]
[--max-size <size>][--remove][--no-album-tag][--no-playlist-folder]
[--download-archive <file>][--sync <file>][--extract-artist][--flac][--original-art]
[--original-name][--original-metadata][--no-original][--only-original]
Expand All @@ -19,6 +19,7 @@
-h --help Show this screen
--version Show version
-l [url] URL can be track/playlist/user
-s [search_query] Search for a track/playlist/user and use the first result
-n [maxtracks] Download the n last tracks of a playlist according to the
creation date
-a Download all tracks of user (including reposts)
Expand Down Expand Up @@ -191,6 +192,7 @@ class SCDLArgs(TypedDict):
remove: bool
strict_playlist: bool
sync: Optional[str]
s: Optional[str]
t: bool


Expand Down Expand Up @@ -366,6 +368,14 @@ def main() -> None:
assert me is not None
arguments["-l"] = me.permalink_url

if arguments["-s"]:
url = search_soundcloud(client, arguments["-s"])
if url:
arguments["-l"] = url
else:
logger.error("Search failed. Exiting...")
sys.exit(1)

arguments["-l"] = validate_url(client, arguments["-l"])

if arguments["--download-archive"]:
Expand Down Expand Up @@ -439,6 +449,23 @@ def validate_url(client: SoundCloud, url: str) -> str:
sys.exit(1)


def search_soundcloud(client: SoundCloud, query: str) -> Optional[str]:
"""Search SoundCloud and return the URL of the first result."""
try:
results = list(client.search(query, limit=1))
if results:
item = results[0]
logger.info(f"Search resolved to url {item.permalink_url}")
if isinstance(item, (Track, AlbumPlaylist, User)):
return item.permalink_url
logger.warning(f"Unexpected search result type: {type(item)}")
logger.error(f"No results found for query: {query}")
return None
except Exception as e:
logger.error(f"Error searching SoundCloud: {e}")
return None


def get_config(config_file: pathlib.Path) -> configparser.ConfigParser:
"""Gets config from scdl.cfg"""
config = configparser.ConfigParser()
Expand Down
49 changes: 49 additions & 0 deletions tests/test_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import os
import secrets
from pathlib import Path

from tests.utils import assert_track, call_scdl_with_auth


def test_search(tmp_path: Path) -> None:
os.chdir(tmp_path)
r = call_scdl_with_auth(
"-s",
"7x11x13-testing test track",
"--name-format",
"track",
"--onlymp3",
)
assert r.returncode == 0
assert_track(tmp_path, "track.mp3")


def test_search_no_results(tmp_path: Path) -> None:
os.chdir(tmp_path)
r = call_scdl_with_auth(
"-s",
f"this query should not return any results {secrets.token_hex(16)}",
"--name-format",
"track",
"--onlymp3",
)
assert r.returncode == 1
assert "No results found for query" in r.stderr


def test_search_playlist(tmp_path: Path) -> None:
os.chdir(tmp_path)
r = call_scdl_with_auth(
"-s",
"playlist1 7x11x13-testing",
"--playlist-name-format",
"{playlist[tracknumber]}_{title}",
"--onlymp3",
)
assert r.returncode == 0
assert_track(tmp_path / "playlist1", "1_OK Bye.mp3", check_metadata=False)
assert_track(
tmp_path / "playlist1",
"2_Wan Bushi - Eurodance Vibes (part 1+2+3).mp3",
check_metadata=False,
)

0 comments on commit e06cc9c

Please sign in to comment.