Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

major refactorings #178

Merged
merged 19 commits into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions .github/workflows/ci_testing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ jobs:
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip flit
flit install --symlink --deps develop
run: pip install -e '.[dev,test]'
- name: Analysing the code with pylint
run: make pylint

Expand All @@ -29,9 +27,7 @@ jobs:
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip flit
flit install --symlink --deps develop
run: pip install -e '.[dev,test]'
- name: Analysing the code with mypy
run: make mypy

Expand Down Expand Up @@ -69,9 +65,7 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip flit
flit install --symlink --deps develop
run: pip install -e '.[dev,test]'
- name: Run all tests
run: pytest tests --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html

Expand All @@ -84,9 +78,7 @@ jobs:
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip flit
flit install --symlink --deps develop
run: pip install -e '.[dev,test]'
- name: Check formatting
run: make check-format

Expand Down Expand Up @@ -142,7 +134,7 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Build web app
run: npx nx affected:test --all
run: npx nx run-many --target test

lint-frontend:
runs-on: ubuntu-latest
Expand All @@ -160,4 +152,4 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Build web app
run: npx nx affected:lint --all
run: npx nx run-many --target lint
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ test:

.PHONY: format
format:
isort .
black .
cd frontend && npx prettier --write . && cd ..

.PHONY: check-format
check-format:
isort --check-only .
black --check .

.PHONY: check-format-frontend
Expand All @@ -28,7 +30,7 @@ eslint:

.PHONY: mypy
mypy:
mypy --ignore-missing-imports .
mypy .

.PHONY: package
package:
Expand All @@ -37,3 +39,8 @@ package:
.PHONY: docs
docs:
$(MAKE) -C docs html

.PHONY: generate-openapi
generate-openapi:
mkdir -p api
python3 -m abrechnung -c config.yaml show-openapi > api/openapi.json
74 changes: 1 addition & 73 deletions abrechnung/__main__.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,4 @@
import argparse
import asyncio
from pathlib import Path

from abrechnung.config import read_config
from abrechnung.util import log_setup

from abrechnung.mailer import MailerCli
from abrechnung.http.cli import ApiCli
from abrechnung.database.cli import DatabaseCli
from abrechnung.admin import AdminCli
from abrechnung.demo import DemoCli


def main():
"""
main CLI entry point

parses commands and jumps into the subprogram's entry point
"""
cli = argparse.ArgumentParser()

cli.add_argument(
"-c",
"--config-path",
default="/etc/abrechnung/abrechnung.yaml",
help="config file, default: %(default)s",
)

cli.add_argument(
"-d", "--debug", action="store_true", help="enable asyncio debugging"
)
cli.add_argument(
"-v", "--verbose", action="count", default=0, help="increase program verbosity"
)
cli.add_argument(
"-q", "--quiet", action="count", default=0, help="decrease program verbosity"
)

subparsers = cli.add_subparsers()

def add_subcommand(name, subcommand_class):
subparser = subparsers.add_parser(name)
subparser.set_defaults(subcommand_class=subcommand_class)
subcommand_class.argparse_register(subparser)

# add all the subcommands here
add_subcommand("mailer", MailerCli)
add_subcommand("api", ApiCli)
add_subcommand("db", DatabaseCli)
add_subcommand("admin", AdminCli)
add_subcommand("demo", DemoCli)

args = vars(cli.parse_args())

# set up log level
log_setup(args["verbose"] - args["quiet"])

# enable asyncio debugging
# loop = asyncio.get_event_loop()
# loop.set_debug(args["debug"])

config_path = args.pop("config_path")
config = read_config(Path(config_path))

try:
subcommand_class = args.pop("subcommand_class")
except KeyError:
cli.error("no subcommand was given")
subcommand_class.argparse_validate(args, cli.error)
subcommand_object = subcommand_class(config=config, **args)
asyncio.run(subcommand_object.run())

from abrechnung.cli.main import main

if __name__ == "__main__":
main()
64 changes: 19 additions & 45 deletions abrechnung/admin.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,26 @@
import argparse
import logging
from getpass import getpass

from abrechnung import subcommand
from abrechnung.application.users import UserService
from abrechnung.config import Config
from abrechnung.framework.database import create_db_pool


class AdminCli(subcommand.SubCommand):
def __init__(self, config: Config, **args): # pylint: disable=super-init-not-called
self.config = config
self.logger = logging.getLogger(__name__)

self.command = args.pop("command")
self.args = args

@staticmethod
def argparse_register(subparser: argparse.ArgumentParser):
subparsers = subparser.add_subparsers(required=True)

create_user_parser = subparsers.add_parser("create-user")
create_user_parser.set_defaults(command="create_user")
create_user_parser.add_argument("-n", "--name", type=str, required=True)
create_user_parser.add_argument("-e", "--email", type=str, required=True)
create_user_parser.add_argument("--skip-email-check", action="store_true")

async def handle_create_user_command(self):
self.logger.info(
f"Creating user with email: {self.args['email']} and username: {self.args['name']}"
)
password = getpass(prompt="Input initial password for user:")
repeat_password = getpass(prompt="Repeat password:")
if password != repeat_password:
print("Passwords do not match!")
return

db_pool = await create_db_pool(self.config.database)
user_service = UserService(db_pool, self.config)
user_service.enable_registration = True
if self.args["skip_email_check"]:
user_service.valid_email_domains = None
await user_service.register_user( # pylint: disable=missing-kwoa
username=self.args["name"],
email=self.args["email"],
password=password,
)

async def run(self):
if self.command == "create_user":
return await self.handle_create_user_command()
logger = logging.getLogger(__name__)


async def create_user(config: Config, name: str, email: str, skip_email_check: bool, no_email_confirmation: bool):
logger.info(f"Creating user with email: {email} and username: {name}")
password = getpass(prompt="Input initial password for user:")
repeat_password = getpass(prompt="Repeat password:")
if password != repeat_password:
print("Passwords do not match!")
return

db_pool = await create_db_pool(config.database)
user_service = UserService(db_pool, config)
user_service.enable_registration = True
if skip_email_check:
user_service.valid_email_domains = None
await user_service.register_user( # pylint: disable=missing-kwoa
username=name, email=email, password=password, requires_email_confirmation=not no_email_confirmation
)
Loading
Loading