add tests

This commit is contained in:
evilchili
2022-12-05 01:06:57 -08:00
parent d5934a99fb
commit 72dc85ac74
22 changed files with 236 additions and 80 deletions
+29 -14
View File
@@ -1,7 +1,8 @@
import logging
import os
from pathlib import Path
from groove.exceptions import ConfigurationError, ThemeMissingException
from groove.exceptions import ConfigurationError, ThemeMissingException, ThemeConfigurationError
_setup_hint = "You may be able to solve this error by running 'groove setup'."
_reinstall_hint = "You might need to reinstall Groove On Demand to fix this error."
@@ -12,11 +13,12 @@ def root():
if not path:
raise ConfigurationError(f"GROOVE_ON_DEMAND_ROOT is not defined in your environment.\n\n{_setup_hint}")
path = Path(path).expanduser()
if not path.exists or not path.is_dir:
if not path.exists() or not path.is_dir():
raise ConfigurationError(
"The Groove on Demand root directory (GROOVE_ON_DEMAND_ROOT) "
f"does not exist or isn't a directory.\n\n{_reinstall_hint}"
)
logging.debug(f"Root is {path}")
return Path(path)
@@ -24,47 +26,64 @@ def media_root():
path = os.environ.get('MEDIA_ROOT', None)
if not path:
raise ConfigurationError(f"MEDIA_ROOT is not defined in your environment.\n\n{_setup_hint}")
path =Path(path).expanduser()
if not path.exists and path.is_dir:
path = Path(path).expanduser()
if not path.exists() or not path.is_dir():
raise ConfigurationError(
"The media_root directory (MEDIA_ROOT) doesn't exist, or isn't a directory.\n\n{_setup_hint}"
)
logging.debug(f"Media root is {path}")
return path
def media(relpath):
return themes_root() / Path(relpath)
path = media_root() / Path(relpath)
return path
def static_root():
dirname = os.environ.get('STATIC_PATH', 'static')
path = root() / Path(dirname)
if not path.exists or not path.is_dir:
if not path.exists() or not path.is_dir():
raise ConfigurationError(
f"The static assets directory {dirname} (STATIC_PATH) "
f"doesn't exist, or isn't a directory.\n\n{_reinstall_hint}"
)
logging.debug(f"Static root is {path}")
return path
def static(relpath):
return static_root() / Path(relpath)
def static(relpath, theme=None):
if theme:
root = theme.path / Path('static')
if not root.is_dir():
raise ThemeConfigurationError(
f"The themes directory {relpath} (THEMES_PATH) "
f"doesn't contain a 'static' directory."
)
path = root / Path(relpath)
logging.debug(f"Checking for {path}")
if path.exists():
return path
path = static_root() / Path(relpath)
logging.debug(f"Defaulting to {path}")
return path
def themes_root():
dirname = os.environ.get('THEMES_PATH', 'themes')
path = root() / Path(dirname)
if not path.exists or not path.is_dir:
if not path.exists() or not path.is_dir():
raise ConfigurationError(
f"The themes directory {dirname} (THEMES_PATH) "
f"doesn't exist, or isn't a directory.\n\n{_reinstall_hint}"
)
logging.debug(f"Themes root is {path}")
return path
def theme(name):
path = themes_root() / Path(name)
if not path.exists or not path.is_dir:
if not path.exists() or not path.is_dir():
available = ','.join(available_themes)
raise ThemeMissingException(
f"A theme directory named {name} does not exist or isn't a directory. "
@@ -74,10 +93,6 @@ def theme(name):
return path
def theme_static(relpath):
return Path('static') / Path(relpath)
def theme_template(template_name):
return Path('templates') / Path(f"{template_name}.tpl")
+16 -10
View File
@@ -8,32 +8,38 @@ from groove.exceptions import ThemeConfigurationError, ConfigurationError
import groove.path
Theme = namedtuple('Theme', 'path,author,author_link,version,about')
Theme = namedtuple('Theme', 'name,path,author,author_link,version,about')
def load_theme(name=None):
name = os.environ.get('DEFAULT_THEME', name)
if not name:
name = name or os.environ.get('DEFAULT_THEME', None)
if not name: # pragma: no cover
raise ConfigurationError(
"It seems like DEFAULT_THEME is not set in your current environment.\n"
"Running 'groove setup' may help you fix this problem."
)
theme_path = groove.path.theme(name)
theme_info = _get_theme_info(theme_path)
return Theme(
path=theme_path,
**theme_info
)
try:
return Theme(
name=name,
path=theme_path,
**theme_info
)
except TypeError:
raise ThemeConfigurationError(f"The {name} them is misconfigured. Does the README.md contain a credits secton?")
def _get_theme_info(theme_path):
readme = theme_path / Path('README.md')
if not readme.exists:
if not readme.exists: # pragma: no cover
raise ThemeConfigurationError(
"The theme is missing a required file: README.md.\n"
"Refer to the Groove On Demand documentation for help creating themes."
)
config = {'about': ''}
config = {
'about': '',
}
with readme.open() as fh:
in_credits = False
in_block = False
@@ -55,7 +61,7 @@ def _get_theme_info(theme_path):
key = key.strip()
value = value.strip()
except ValueError:
logging.warn(f"Could not parse credits line: {line}")
logging.warning(f"Could not parse credits line: {line}")
continue
logging.debug(f"Setting theme '{key}' to '{value}'.")
config[key] = value
+33 -36
View File
@@ -5,6 +5,7 @@ import os
import bottle
from bottle import HTTPResponse, template, static_file
from bottle.ext import sqlalchemy
from sqlalchemy.exc import NoResultFound, MultipleResultsFound
import groove.db
from groove.auth import is_authenticated
@@ -54,54 +55,32 @@ def index():
return "Groovy."
@server.route('/build')
@bottle.auth_basic(is_authenticated)
def build():
return "Authenticated. Groovy."
@server.route('/static/<filepath:path>')
def server_static(filepath):
def serve_static(filepath):
theme = themes.load_theme()
asset = theme.path / groove.path.theme_static(filepath)
if asset.exists():
root = asset.parent
else:
root = groove.path.static_root()
asset = groove.path.static(filepath)
if asset.is_dir():
logging.warning("Asset {asset} is a directory; returning 404.")
return HTTPResponse(status=404, body="Not found.")
logging.debug(f"Serving asset {asset.name} from {root}")
return static_file(asset.name, root=root)
@bottle.auth_basic(is_authenticated)
@server.route('/build/search/playlist')
def search_playlist(slug, db):
playlist = Playlist(slug=slug, session=db, create_ok=False)
response = json.dumps(playlist.as_dict)
logging.debug(response)
return HTTPResponse(status=200, content_type='application/json', body=response)
path = groove.path.static(filepath, theme=theme)
logging.debug(f"Serving asset {path.name} from {path.parent}")
return static_file(path.name, root=path.parent)
@server.route('/track/<request>/<track_id>')
def serve_track(request, track_id, db):
expected = requests.encode([track_id], '/track')
if not requests.verify(request, expected):
if not requests.verify(request, expected): # pragma: no cover
return HTTPResponse(status=404, body="Not found")
track_id = int(track_id)
track = db.query(groove.db.track).filter(
groove.db.track.c.id == track_id
).one()
try:
track_id = int(track_id)
track = db.query(groove.db.track).filter(
groove.db.track.c.id == track_id
).one()
except (NoResultFound, MultipleResultsFound):
return HTTPResponse(status=404, body="Not found")
path = groove.path.media(track['relpath'])
if path.exists:
return static_file(path.name, root=path.parent)
else:
return HTTPResponse(status=404, body="Not found")
logging.debug(f"Service track {path.name} from {path.parent}")
return static_file(path.name, root=path.parent)
@server.route('/playlist/<slug>')
@@ -123,3 +102,21 @@ def serve_playlist(slug, db):
entry['url'] = f"/track/{sig}/{entry['track_id']}"
return serve('playlist', playlist=pl)
@server.route('/build')
@bottle.auth_basic(is_authenticated)
def build():
return "Authenticated. Groovy."
@bottle.auth_basic(is_authenticated)
@server.route('/build/search/playlist/<slug>')
def search_playlist(slug, db):
playlist = Playlist(slug=slug, session=db, create_ok=False).load()
if not playlist.record:
logging.debug(f"Playist {slug} doesn't exist.")
body = {}
else:
body = json.dumps(playlist.as_dict)
return HTTPResponse(status=200, content_type='application/json', body=body)