grooveondemand/groove/webserver/webserver.py

127 lines
3.7 KiB
Python
Raw Permalink Normal View History

2022-11-20 01:00:54 -08:00
import logging
2022-12-02 21:43:51 -08:00
import json
2022-11-20 01:00:54 -08:00
import os
import bottle
2022-12-02 21:43:51 -08:00
from bottle import HTTPResponse, template, static_file
from bottle.ext import sqlalchemy
2022-12-05 01:06:57 -08:00
from sqlalchemy.exc import NoResultFound, MultipleResultsFound
2022-11-20 01:00:54 -08:00
2022-12-02 21:43:51 -08:00
import groove.db
from groove.auth import is_authenticated
from groove.db.manager import database_manager
from groove.playlist import Playlist
from groove.webserver import requests, themes
2022-11-20 01:00:54 -08:00
server = bottle.Bottle()
2022-11-20 01:00:54 -08:00
2022-12-21 21:16:06 -08:00
def start(host: str = '127.0.0.1', port: int = 2323, debug: bool = False) -> None: # pragma: no cover
2022-11-20 01:00:54 -08:00
"""
2022-11-20 09:28:00 -08:00
Start the Bottle app.
2022-11-20 01:00:54 -08:00
"""
2022-11-20 09:28:00 -08:00
logging.debug(f"Configuring sqllite using {os.environ.get('DATABASE_PATH')}")
with database_manager() as manager:
server.install(sqlalchemy.Plugin(
manager.engine,
2022-12-02 21:43:51 -08:00
groove.db.metadata,
keyword='db',
create=True,
commit=True,
))
logging.debug(f"Configuring webserver with host={host}, port={port}, debug={debug}")
server.run(
host=os.getenv('HOST', host),
port=os.getenv('PORT', port),
debug=debug,
server='paste',
quiet=True
)
def serve(template_name, theme=None, **template_args):
theme = themes.load_theme(theme)
return HTTPResponse(status=200, body=template(
str(theme.path / groove.path.theme_template(template_name)),
url=requests.url(),
theme=theme,
**template_args
))
@server.route('/')
def index():
return "Groovy."
2022-12-03 23:23:25 -08:00
@server.route('/static/<filepath:path>')
2022-12-05 01:06:57 -08:00
def serve_static(filepath):
theme = themes.load_theme()
2022-12-05 01:06:57 -08:00
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)
2022-12-02 21:43:51 -08:00
@server.route('/track/<request>/<track_id>')
def serve_track(request, track_id, db):
expected = requests.encode([track_id], '/track')
2022-12-05 01:06:57 -08:00
if not requests.verify(request, expected): # pragma: no cover
2022-12-02 21:43:51 -08:00
return HTTPResponse(status=404, body="Not found")
2022-12-05 01:06:57 -08:00
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")
2022-12-02 21:43:51 -08:00
2022-12-31 12:42:31 -08:00
path = groove.path.transcoded_media(track['relpath'])
if not path.exists():
path = groove.path.media(track['relpath'])
logging.debug(f"Serving track {path.name}")
2022-12-05 01:06:57 -08:00
return static_file(path.name, root=path.parent)
2022-12-02 21:43:51 -08:00
2022-11-20 01:00:54 -08:00
@server.route('/playlist/<slug>')
2022-12-02 21:43:51 -08:00
def serve_playlist(slug, db):
2022-11-20 01:00:54 -08:00
"""
Retrieve a playlist and its entries by a slug.
"""
logging.debug(f"Looking up playlist: {slug}...")
2022-12-07 18:19:38 -08:00
try:
playlist = Playlist.by_slug(slug, session=db)
except NoResultFound:
2022-12-02 21:43:51 -08:00
logging.debug(f"Playist {slug} doesn't exist.")
2022-11-20 01:00:54 -08:00
return HTTPResponse(status=404, body="Not found")
2022-12-02 21:43:51 -08:00
logging.debug(f"Loaded {playlist.record}")
logging.debug(playlist.as_dict['entries'])
2022-12-03 23:23:25 -08:00
pl = playlist.as_dict
for entry in pl['entries']:
sig = requests.encode([str(entry['track_id'])], uri='/track')
entry['url'] = f"/track/{sig}/{entry['track_id']}"
2022-12-02 21:43:51 -08:00
return serve('playlist', playlist=pl)
2022-12-05 01:06:57 -08:00
@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):
2022-12-07 18:19:38 -08:00
try:
playlist = Playlist.by_slug(slug, session=db)
except NoResultFound:
logging.debug(f"Playlist {slug} doesn't exist.")
2022-12-05 01:06:57 -08:00
body = {}
else:
body = json.dumps(playlist.as_dict)
return HTTPResponse(status=200, content_type='application/json', body=body)