improved env loading

This commit is contained in:
evilchili 2022-12-21 21:16:06 -08:00
parent 7c82226ff9
commit 41a21671ca
6 changed files with 105 additions and 28 deletions

View File

@ -1,21 +1,36 @@
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
app = typer.Typer()
def initialize():
load_dotenv()
@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',
@ -26,13 +41,76 @@ def initialize():
)
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')
sys.exit(1)
@app.command()
def list():
def setup(context: typer.Context):
"""
List all Playlists
(Re)Initialize Groove on Demand.
"""
print(dedent(
"""
Interactive setup is not yet available. Sorry!
In the mean time, 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.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
"""
initialize()
with database_manager() as manager:
shell = interactive_shell.InteractiveShell(manager)
shell.list(None)
@ -40,6 +118,7 @@ def list():
@app.command()
def scan(
context: typer.Context,
path: Optional[Path] = typer.Option(
'',
help="A path to scan, relative to your MEDIA_ROOT. "
@ -49,7 +128,6 @@ def scan(
"""
Scan the filesystem and create track entries in the database.
"""
initialize()
with database_manager() as manager:
shell = interactive_shell.InteractiveShell(manager)
shell.console.print("Starting the Groove on Demand scanner...")
@ -57,13 +135,17 @@ def scan(
@app.command()
def shell():
initialize()
interactive_shell.start()
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",
@ -80,7 +162,6 @@ def server(
"""
Start the Groove on Demand playlsit server.
"""
initialize()
with database_manager() as manager:
manager.import_from_filesystem()
webserver.start(host=host, port=port, debug=debug)

View File

@ -26,7 +26,7 @@ BASE_STYLE = {
}
def console_theme(theme_name: Union[str, None] = None) -> dict:
def console_theme(theme_name: Union[str, None] = 'blue_train') -> dict:
"""
Return a console theme as a dictionary.
@ -36,8 +36,8 @@ def console_theme(theme_name: Union[str, None] = None) -> dict:
cfg = ConfigParser()
cfg.read_dict({'styles': BASE_STYLE})
cfg.read(theme(
theme_name or os.environ['DEFAULT_THEME']) / Path('console.cfg')
)
Path(theme_name or os.environ['DEFAULT_THEME']) / Path('console.cfg')
))
return cfg['styles']

View File

@ -69,7 +69,7 @@ class MediaScanner:
console: Union[Console, None] = None,
) -> None:
self._db = db
self._glob = tuple((glob or os.environ.get('MEDIA_GLOB')).split(','))
self._glob = tuple((glob or os.environ.get('MEDIA_GLOB', '*.mp3,*.flac,*.m4a')).split(','))
self._root = groove.path.media_root()
self._console = console or Console()
self._scanned = 0

View File

@ -4,14 +4,14 @@ import os
from pathlib import Path
from groove.exceptions import ConfigurationError, ThemeMissingException, ThemeConfigurationError
_setup_hint = "You may be able to solve this error by running 'groove setup'."
_setup_hint = "You may be able to solve this error by running 'groove setup' or specifying the --env parameter."
_reinstall_hint = "You might need to reinstall Groove On Demand to fix this error."
def root():
path = os.environ.get('GROOVE_ON_DEMAND_ROOT', None)
if not path:
raise ConfigurationError(f"GROOVE_ON_DEMAND_ROOT is not defined in your environment.\n\n{_setup_hint}")
raise ConfigurationError(f"GROOVE_ON_DEMAND_ROOT is not defined in your environment.\n{_setup_hint}")
path = Path(path).expanduser()
if not path.exists() or not path.is_dir():
raise ConfigurationError(
@ -83,7 +83,7 @@ def themes_root():
def theme(name):
path = themes_root() / Path(name)
if not path.exists() or not path.is_dir():
if not path.exists():
available = ','.join(available_themes())
raise ThemeMissingException(
f"A theme directory named {name} does not exist or isn't a directory. "
@ -102,13 +102,9 @@ def available_themes():
def database():
path = os.environ.get('DATABASE_PATH', None)
if not path:
path = root()
else: # pragma: no cover
path = Path(path).expanduser()
if not path.exists() or not path.is_dir():
raise ConfigurationError(
"DATABASE_PATH doesn't exist or isn't a directory.\n\n{_setup_hint}"
)
path = Path(os.environ.get('DATABASE_PATH', '~')).expanduser()
if not path.exists() or not path.is_dir():
raise ConfigurationError(
"DATABASE_PATH doesn't exist or isn't a directory.\n\n{_setup_hint}"
)
return path / Path('groove_on_demand.db')

View File

@ -16,7 +16,7 @@ from groove.webserver import requests, themes
server = bottle.Bottle()
def start(host: str, port: int, debug: bool) -> None: # pragma: no cover
def start(host: str = '127.0.0.1', port: int = 2323, debug: bool = False) -> None: # pragma: no cover
"""
Start the Bottle app.
"""

View File

@ -35,7 +35,7 @@ def test_theme_no_path():
def test_database_default(env):
assert path.database().relative_to(path.root())
assert path.database()
def test_database(env):