grooveondemand/groove/cli.py
2022-12-21 22:27:30 -08:00

176 lines
4.2 KiB
Python

import logging
import os
import sys
import typer
from pathlib import Path
from typing import Optional
from textwrap import dedent
from dotenv import load_dotenv
from rich import print
from rich.logging import RichHandler
import groove.path
from groove.shell import interactive_shell
from groove.db.manager import database_manager
from groove.webserver import webserver
from groove.exceptions import ConfigurationError
from groove.console import Console
SETUP_HELP = """
Please make sure you set MEDIA_ROOT and SECRET_KEY in your environment.
By default, Groove on Demand will attempt to load these variables from
~/.groove, which may contain the following variables as well. See also
the --env paramter.
# Set this one. The path containing your media files
MEDIA_ROOT=
# the kinds of files to import
# MEDIA_GLOB=*.mp3,*.flac,*.m4a
# where to store the groove_on_demand.db sqlite database.
# DATABASE_PATH=~
# Try 'groove themes' to see a list of available themes.
# DEFAULT_THEME=blue_train
# Web interface configuration
# HOST=127.0.0.1
# PORT=2323
# Set this to a suitably random string.
SECRET_KEY=much secret very private
# Console configuration
# EDITOR=
# CONSOLE_WIDTH=auto
"""
app = typer.Typer()
@app.callback()
def main(
context: typer.Context,
env: Optional[Path] = typer.Option(
Path('~/.groove'),
help="Path to the Groove on Demand environment",
)
):
load_dotenv(env.expanduser())
debug = os.getenv('DEBUG', None)
logging.basicConfig(
format='%(message)s',
level=logging.DEBUG if debug else logging.INFO,
handlers=[
RichHandler(rich_tracebacks=True, tracebacks_suppress=[typer])
]
)
logging.getLogger('asyncio').setLevel(logging.ERROR)
try:
groove.path.media_root()
groove.path.static_root()
groove.path.themes_root()
groove.path.database()
except ConfigurationError as e:
sys.stderr.write(f'{e}\n\n{SETUP_HELP}')
sys.exit(1)
@app.command()
def setup(context: typer.Context):
"""
(Re)Initialize Groove on Demand.
"""
print(dedent(
"""
Interactive setup is not yet available. Sorry!
{SETUP_HELP}
"""
))
@app.command()
def themes(context: typer.Context):
"""
List the available themes.
"""
print("Available themes:")
themes = [theme for theme in groove.path.themes_root().iterdir()]
tags = ('artist', 'title', 'bold', 'dim', 'link', 'prompt', 'bright', 'text', 'help')
for theme in themes:
text = ''
for tag in tags:
text += f'[{tag}]◼◼◼◼◼◼'
Console(theme=theme.name).print(f' ▪ [title]{theme.name}[/title] {text}')
@app.command()
def playlists(context: typer.Context):
"""
List all playlists
"""
with database_manager() as manager:
shell = interactive_shell.InteractiveShell(manager)
shell.list(None)
@app.command()
def scan(
context: typer.Context,
path: Optional[Path] = typer.Option(
'',
help="A path to scan, relative to your MEDIA_ROOT. "
"If not specified, the entire MEDIA_ROOT will be scanned."
),
):
"""
Scan the filesystem and create track entries in the database.
"""
with database_manager() as manager:
shell = interactive_shell.InteractiveShell(manager)
shell.console.print("Starting the Groove on Demand scanner...")
shell.scan([str(path)])
@app.command()
def shell(context: typer.Context):
"""
Start the Groove on Demand interactive shell.
"""
with database_manager() as manager:
interactive_shell.InteractiveShell(manager).start()
@app.command()
def server(
context: typer.Context,
host: str = typer.Argument(
'0.0.0.0',
help="bind address",
),
port: int = typer.Argument(
2323,
help="bind port",
),
debug: bool = typer.Option(
False,
help='Enable debugging output'
),
):
"""
Start the Groove on Demand playlsit server.
"""
with database_manager() as manager:
manager.import_from_filesystem()
webserver.start(host=host, port=port, debug=debug)
if __name__ == '__main__':
app()