From 56bd024ddedd21095e1af1325c5d0da51705ba69 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 23 Apr 2022 11:20:43 +0200 Subject: [PATCH] CLI - refactoring --- fittrackee/__init__.py | 14 ---------- fittrackee/__main__.py | 7 ----- fittrackee/cli/__init__.py | 14 ++++++++++ fittrackee/cli/app.py | 3 +++ fittrackee/migrations/commands.py | 44 +++++++++++++++++++++++++++++++ fittrackee/users/commands.py | 23 ++++++++++++++++ fittrackee/users/users.py | 14 ---------- pyproject.toml | 3 +-- 8 files changed, 85 insertions(+), 37 deletions(-) create mode 100644 fittrackee/cli/__init__.py create mode 100644 fittrackee/cli/app.py create mode 100644 fittrackee/migrations/commands.py create mode 100644 fittrackee/users/commands.py diff --git a/fittrackee/__init__.py b/fittrackee/__init__.py index a39d8fff..064ba03f 100644 --- a/fittrackee/__init__.py +++ b/fittrackee/__init__.py @@ -1,7 +1,6 @@ import logging import os import re -import shutil from importlib import import_module, reload from typing import Any @@ -147,17 +146,4 @@ def create_app() -> Flask: else: return render_template('index.html') - @app.cli.command('drop-db') - def drop_db() -> None: - """Empty database and delete uploaded files for dev environments.""" - if app_settings == 'fittrackee.config.ProductionConfig': - print('This is a production server, aborting!') - return - db.engine.execute("DROP TABLE IF EXISTS alembic_version;") - db.drop_all() - db.session.commit() - print('Database dropped.') - shutil.rmtree(app.config['UPLOAD_FOLDER'], ignore_errors=True) - print('Uploaded files deleted.') - return app diff --git a/fittrackee/__main__.py b/fittrackee/__main__.py index cab00192..1890c648 100644 --- a/fittrackee/__main__.py +++ b/fittrackee/__main__.py @@ -5,14 +5,12 @@ from typing import Dict, Optional import gunicorn.app.base from flask import Flask -from flask_migrate import upgrade from fittrackee import create_app HOST = os.getenv('HOST', '0.0.0.0') PORT = os.getenv('PORT', '5000') WORKERS = os.getenv('APP_WORKERS', 1) -BASEDIR = os.path.abspath(os.path.dirname(__file__)) app = create_app() @@ -37,11 +35,6 @@ class StandaloneApplication(gunicorn.app.base.BaseApplication): return self.application -def upgrade_db() -> None: - with app.app_context(): - upgrade(directory=BASEDIR + '/migrations') - - def main() -> None: options = {'bind': f'{HOST}:{PORT}', 'workers': WORKERS} StandaloneApplication(app, options).run() diff --git a/fittrackee/cli/__init__.py b/fittrackee/cli/__init__.py new file mode 100644 index 00000000..c3c9a9bc --- /dev/null +++ b/fittrackee/cli/__init__.py @@ -0,0 +1,14 @@ +import click + +from fittrackee.migrations.commands import db_cli +from fittrackee.users.commands import users_cli + + +@click.group() +def cli() -> None: + """FitTrackee Command Line Interface""" + pass + + +cli.add_command(db_cli) +cli.add_command(users_cli) diff --git a/fittrackee/cli/app.py b/fittrackee/cli/app.py new file mode 100644 index 00000000..3b6ee7f6 --- /dev/null +++ b/fittrackee/cli/app.py @@ -0,0 +1,3 @@ +from fittrackee import create_app + +app = create_app() diff --git a/fittrackee/migrations/commands.py b/fittrackee/migrations/commands.py new file mode 100644 index 00000000..ea2cfb75 --- /dev/null +++ b/fittrackee/migrations/commands.py @@ -0,0 +1,44 @@ +import os +import shutil + +import click +from flask_migrate import upgrade + +from fittrackee import db +from fittrackee.cli.app import app + +BASEDIR = os.path.abspath(os.path.dirname(__file__)) +app_settings = os.getenv('APP_SETTINGS', 'fittrackee.config.ProductionConfig') + + +@click.group(name='db') +def db_cli() -> None: + """Manage database.""" + pass + + +@db_cli.command('upgrade') +def upgrade_db() -> None: + """Apply migrations.""" + with app.app_context(): + upgrade(directory=BASEDIR) + + +@db_cli.command('drop') +def drop_db() -> None: + """Empty database and delete uploaded files for dev environments.""" + with app.app_context(): + if app_settings == 'fittrackee.config.ProductionConfig': + click.echo( + click.style( + 'This is a production server, aborting!', bold=True + ), + err=True, + ) + return + db.engine.execute("DROP TABLE IF EXISTS alembic_version;") + db.drop_all() + db.session.commit() + click.echo('Database dropped.') + shutil.rmtree(app.config['UPLOAD_FOLDER'], ignore_errors=True) + click.echo('Uploaded files deleted.') diff --git a/fittrackee/users/commands.py b/fittrackee/users/commands.py new file mode 100644 index 00000000..97679e68 --- /dev/null +++ b/fittrackee/users/commands.py @@ -0,0 +1,23 @@ +import click + +from fittrackee.cli.app import app +from fittrackee.users.exceptions import UserNotFoundException +from fittrackee.users.utils.admin import set_admin_rights + + +@click.group(name='users') +def users_cli() -> None: + """Manage users.""" + pass + + +@users_cli.command('set-admin') +@click.argument('username') +def set_admin(username: str) -> None: + """Set admin rights for given user""" + with app.app_context(): + try: + set_admin_rights(username) + click.echo(f"User '{username}' updated.") + except UserNotFoundException: + click.echo(f"User '{username}' not found.", err=True) diff --git a/fittrackee/users/users.py b/fittrackee/users/users.py index c40f3e01..5efe3704 100644 --- a/fittrackee/users/users.py +++ b/fittrackee/users/users.py @@ -3,7 +3,6 @@ import secrets import shutil from typing import Any, Dict, Tuple, Union -import click from flask import Blueprint, current_app, request, send_file from sqlalchemy import exc @@ -27,26 +26,13 @@ from fittrackee.utils import get_readable_duration from fittrackee.workouts.models import Record, Workout, WorkoutSegment from .decorators import authenticate, authenticate_as_admin -from .exceptions import UserNotFoundException from .models import User, UserSportPreference -from .utils.admin import set_admin_rights users_blueprint = Blueprint('users', __name__) USER_PER_PAGE = 10 -@users_blueprint.cli.command('set-admin') -@click.argument('username') -def set_admin(username: str) -> None: - """Set admin rights for given user""" - try: - set_admin_rights(username) - print(f"User '{username}' updated.") - except UserNotFoundException: - print(f"User '{username}' not found.") - - @users_blueprint.route('/users', methods=['GET']) @authenticate_as_admin def get_users(auth_user: User) -> Dict: diff --git a/pyproject.toml b/pyproject.toml index cafe28bf..25d33b62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,9 +63,8 @@ Sphinx = "^4.5" [tool.poetry.scripts] fittrackee = 'fittrackee.__main__:main' -fittrackee_set_admin = 'fittrackee.users.users:set_admin' -fittrackee_upgrade_db = 'fittrackee.__main__:upgrade_db' fittrackee_worker = 'flask_dramatiq:worker' +ftcli = 'fittrackee.cli:cli' [tool.black] line-length = 79