mirror of
https://github.com/nathom/streamrip.git
synced 2025-05-13 06:34:45 -04:00
182 lines
4.3 KiB
Python
182 lines
4.3 KiB
Python
import asyncio
|
|
import logging
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
from functools import wraps
|
|
|
|
import click
|
|
from click import secho
|
|
from click_help_colors import HelpColorsGroup
|
|
from rich.logging import RichHandler
|
|
from rich.traceback import install
|
|
|
|
from .config import Config, set_user_defaults
|
|
from .main import Main
|
|
from .user_paths import BLANK_CONFIG_PATH, CONFIG_PATH
|
|
|
|
logging.basicConfig(
|
|
level="DEBUG", format="%(message)s", datefmt="[%X]", handlers=[RichHandler()]
|
|
)
|
|
|
|
logger = logging.getLogger("streamrip")
|
|
|
|
|
|
def echo_i(msg, **kwargs):
|
|
secho(msg, fg="green", **kwargs)
|
|
|
|
|
|
def echo_w(msg, **kwargs):
|
|
secho(msg, fg="yellow", **kwargs)
|
|
|
|
|
|
def echo_e(msg, **kwargs):
|
|
secho(msg, fg="yellow", **kwargs)
|
|
|
|
|
|
def coro(f):
|
|
@wraps(f)
|
|
def wrapper(*args, **kwargs):
|
|
return asyncio.run(f(*args, **kwargs))
|
|
|
|
return wrapper
|
|
|
|
|
|
@click.group(
|
|
cls=HelpColorsGroup,
|
|
help_headers_color="yellow",
|
|
help_options_color="green",
|
|
)
|
|
@click.version_option(version="2.0")
|
|
@click.option(
|
|
"-c", "--config-path", default=CONFIG_PATH, help="Path to the configuration file"
|
|
)
|
|
@click.option(
|
|
"-v", "--verbose", help="Enable verbose output (debug mode)", is_flag=True
|
|
)
|
|
@click.pass_context
|
|
def rip(ctx, config_path, verbose):
|
|
"""
|
|
Streamrip: the all in one music downloader.
|
|
"""
|
|
if verbose:
|
|
install(suppress=[click], show_locals=True, locals_hide_sunder=False)
|
|
logger.setLevel(logging.DEBUG)
|
|
logger.debug("Showing all debug logs")
|
|
else:
|
|
install(suppress=[click, asyncio], max_frames=1)
|
|
logger.setLevel(logging.WARNING)
|
|
|
|
ctx.ensure_object(dict)
|
|
if not os.path.isfile(config_path):
|
|
echo_i(f"No file found at {config_path}, creating default config.")
|
|
shutil.copy(BLANK_CONFIG_PATH, config_path)
|
|
set_user_defaults(config_path)
|
|
|
|
ctx.obj["config_path"] = config_path
|
|
ctx.obj["verbose"] = verbose
|
|
|
|
|
|
@rip.command()
|
|
@click.argument("urls", nargs=-1, required=True)
|
|
@click.pass_context
|
|
@coro
|
|
async def url(ctx, urls):
|
|
"""Download content from URLs.
|
|
|
|
Example usage:
|
|
|
|
rip url TODO: find url
|
|
"""
|
|
config_path = ctx.obj["config_path"]
|
|
with Config(config_path) as cfg:
|
|
main = Main(cfg)
|
|
for u in urls:
|
|
await main.add(u)
|
|
await main.resolve()
|
|
await main.rip()
|
|
|
|
|
|
@rip.command()
|
|
@click.argument("path", required=True)
|
|
@click.pass_context
|
|
@coro
|
|
async def file(ctx, path):
|
|
"""Download content from URLs in a file seperated by newlines.
|
|
|
|
Example usage:
|
|
|
|
rip file urls.txt
|
|
"""
|
|
config_path = ctx.obj["config_path"]
|
|
with Config(config_path) as cfg:
|
|
main = Main(cfg)
|
|
with open(path) as f:
|
|
for u in f:
|
|
await main.add(u)
|
|
await main.resolve()
|
|
await main.rip()
|
|
|
|
|
|
@rip.group()
|
|
def config():
|
|
"""Manage configuration files."""
|
|
pass
|
|
|
|
|
|
@config.command("open")
|
|
@click.option("-v", "--vim", help="Open in (Neo)Vim", is_flag=True)
|
|
@click.pass_context
|
|
def config_open(ctx, vim):
|
|
"""Open the config file in a text editor."""
|
|
config_path = ctx.obj["config_path"]
|
|
echo_i(f"Opening file at {config_path}")
|
|
if vim:
|
|
if shutil.which("nvim") is not None:
|
|
subprocess.run(["nvim", config_path])
|
|
else:
|
|
subprocess.run(["vim", config_path])
|
|
else:
|
|
click.launch(config_path)
|
|
|
|
|
|
@config.command("reset")
|
|
@click.option("-y", "--yes", help="Don't ask for confirmation.", is_flag=True)
|
|
@click.pass_context
|
|
def config_reset(ctx, yes):
|
|
"""Reset the config file."""
|
|
config_path = ctx.obj["config_path"]
|
|
if not yes:
|
|
echo_w(
|
|
f"Are you sure you want to reset the config file at {config_path}? [y/n] ",
|
|
nl=False,
|
|
)
|
|
result = input()
|
|
if result.strip() != "y":
|
|
echo_i("Reset aborted.")
|
|
return
|
|
|
|
shutil.copy(BLANK_CONFIG_PATH, config_path)
|
|
set_user_defaults(config_path)
|
|
echo_i(f"Reset the config file at {config_path}!")
|
|
|
|
|
|
@rip.command()
|
|
@click.argument("query", required=True)
|
|
@click.argument("source", required=True)
|
|
@coro
|
|
async def search(query, source):
|
|
"""
|
|
Search for content using a specific source.
|
|
"""
|
|
echo_i(f'Searching for "{query}" in source: {source}')
|
|
|
|
|
|
@rip.command()
|
|
@click.argument("url", required=True)
|
|
def lastfm(url):
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
rip()
|