diff --git a/groove/cli.py b/groove/cli.py index 237e97f..6473e54 100644 --- a/groove/cli.py +++ b/groove/cli.py @@ -3,26 +3,19 @@ import os import typer from dotenv import load_dotenv -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker -from groove import ondemand -from groove.db import metadata +from groove import webserver +from groove.db.manager import database_manager app = typer.Typer() -@app.command() def initialize(): load_dotenv() - - # todo: abstract this and replace in_memory_db fixture - engine = create_engine(f"sqlite:///{os.environ.get('DATABASE_PATH')}", future=True) - Session = sessionmaker(bind=engine, future=True) - session = Session() - metadata.create_all(bind=engine) - session.close() + debug = os.getenv('DEBUG', None) + logging.basicConfig(format='%(asctime)s - %(message)s', + level=logging.DEBUG if debug else logging.INFO) @app.command() @@ -43,21 +36,11 @@ def server( """ Start the Groove on Demand playlsit server. """ - load_dotenv() - - ondemand.initialize() - print("Starting Groove On Demand...") - - debug = os.getenv('DEBUG', None) - logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.DEBUG if debug else logging.INFO) - ondemand.server.run( - host=os.getenv('HOST', host), - port=os.getenv('PORT', port), - debug=debug, - server='paste', - quiet=True - ) + initialize() + with database_manager as manager: + manager.import_from_filesystem() + webserver.start(host=host, port=port, debug=debug) if __name__ == '__main__': diff --git a/groove/db/__init__.py b/groove/db/__init__.py new file mode 100644 index 0000000..bccd04d --- /dev/null +++ b/groove/db/__init__.py @@ -0,0 +1 @@ +from groove.db.schema import metadata, track, playlist, entry diff --git a/groove/db/manager.py b/groove/db/manager.py new file mode 100644 index 0000000..92a14a1 --- /dev/null +++ b/groove/db/manager.py @@ -0,0 +1,43 @@ +import os + +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + +from . import metadata + + +class DatabaseManager: + """ + A context manager for working with sqllite database. + """ + + def __init__(self): + self._engine = None + self._session = None + + @property + def engine(self): + if not self._engine: + self._engine = create_engine(f"sqlite:///{os.environ.get('DATABASE_PATH')}", future=True) + return self._engine + + @property + def session(self): + if not self._session: + Session = sessionmaker(bind=self.engine, future=True) + self._session = Session() + return self._session + + def import_from_filesystem(self): + pass + + def __enter__(self): + metadata.create_all(bind=self.engine) + return self + + def __exit__(self, exc_type, exc_value, traceback): + if self.session: + self.session.close() + + +database_manager = DatabaseManager() diff --git a/groove/db.py b/groove/db/schema.py similarity index 100% rename from groove/db.py rename to groove/db/schema.py diff --git a/groove/ondemand.py b/groove/webserver.py similarity index 67% rename from groove/ondemand.py rename to groove/webserver.py index 2b8a909..d1dd6c9 100644 --- a/groove/ondemand.py +++ b/groove/webserver.py @@ -11,11 +11,20 @@ from groove.helper import PlaylistDatabaseHelper server = bottle.Bottle() -def initialize(): +def start(host: str, port: int, debug: bool) -> None: """ - Configure the sqlite database. + Start the Bottle app. """ + logging.debug(f"Configuring sqllite using {os.environ.get('DATABASE_PATH')}") server.install(sqlite.Plugin(dbfile=os.environ.get('DATABASE_PATH'))) + 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 + ) @server.route('/') diff --git a/test/test_ondemand.py b/test/test_webserver.py similarity index 75% rename from test/test_ondemand.py rename to test/test_webserver.py index 2a5c62a..e026cf5 100644 --- a/test/test_ondemand.py +++ b/test/test_webserver.py @@ -7,23 +7,18 @@ import atheris import bottle from boddle import boddle -from groove import ondemand - - -@pytest.fixture(autouse=True, scope='session') -def init_db(): - ondemand.initialize() +from groove import webserver def test_server(): with boddle(): - ondemand.index() + webserver.index() assert bottle.response.status_code == 200 def test_auth_with_valid_credentials(): with boddle(auth=(os.environ.get('USERNAME'), os.environ.get('PASSWORD'))): - ondemand.build() + webserver.build() assert bottle.response.status_code == 200 @@ -31,7 +26,7 @@ def test_auth_random_input(): def auth(fuzzed_input): with boddle(auth=(fuzzed_input, fuzzed_input)): - response = ondemand.build() + response = webserver.build() assert response.status_code == 401 atheris.Setup([sys.argv[0], "-atheris_runs=100000"], auth) @@ -49,11 +44,11 @@ def test_auth_random_input(): ]) def test_playlist(db, slug, expected): with boddle(): - response = ondemand.get_playlist(slug, db) + response = webserver.get_playlist(slug, db) assert response.status_code == expected def test_playlist_on_empty_db(in_memory_db): with boddle(): - response = ondemand.get_playlist('some-slug', in_memory_db) + response = webserver.get_playlist('some-slug', in_memory_db) assert response.status_code == 404