diff --git a/.forgejo/workflows/actions.yml b/.forgejo/workflows/actions.yml index b0da196..cdb4f36 100644 --- a/.forgejo/workflows/actions.yml +++ b/.forgejo/workflows/actions.yml @@ -47,6 +47,6 @@ jobs: - name: Install dependencies run: uv sync - name: Lint with Ruff - run: uv run ruff check + run: uv run ruff check $(git ls-files '*.py') - name: Lint with Pylint - run: uv run pylint src/ + run: uv run pylint --rcfile=.forgejo/workflows/config/.pylintrc $(git ls-files '*.py') diff --git a/.forgejo/workflows/config/.pylintrc b/.forgejo/workflows/config/.pylintrc new file mode 100644 index 0000000..c9dd75b --- /dev/null +++ b/.forgejo/workflows/config/.pylintrc @@ -0,0 +1,10 @@ + [MESSAGES CONTROL] + disable= + too-many-lines, + missing-module-docstring, + missing-function-docstring, + missing-class-docstring, + line-too-long, + too-many-arguments, + too-many-instance-attributes, + import-outside-toplevel, diff --git a/src/main.py b/src/main.py index 2118b8c..b94b053 100644 --- a/src/main.py +++ b/src/main.py @@ -10,7 +10,7 @@ from flask import Flask, Response, render_template @dataclass -class Config(): +class Config: base_url: str token: t.Optional[str] user: str @@ -20,15 +20,16 @@ class Config(): artifact_names: t.List[str] debug: bool + config = { - "base_url": os.environ.get('FORGEJO_BASE_URL'), - "token": os.environ.get('FORGEJO_TOKEN') or None, - "user": os.environ.get('FORGEJO_USER'), - "repo": os.environ.get('FORGEJO_REPO'), - "task_name": os.environ.get('FORGEJO_TASK_NAME'), - "page_size": os.environ.get('FORGEJO_PAGE_SIZE') or 10, - "artifact_names": os.environ.get('FORGEJO_ARTIFACT_NAMES', '').split(','), - "debug": os.environ.get('DEBUG', '') or False, + "base_url": os.environ.get("FORGEJO_BASE_URL"), + "token": os.environ.get("FORGEJO_TOKEN") or None, + "user": os.environ.get("FORGEJO_USER"), + "repo": os.environ.get("FORGEJO_REPO"), + "task_name": os.environ.get("FORGEJO_TASK_NAME"), + "page_size": os.environ.get("FORGEJO_PAGE_SIZE") or 10, + "artifact_names": os.environ.get("FORGEJO_ARTIFACT_NAMES", "").split(","), + "debug": os.environ.get("DEBUG", "") or False, } config = Config(**config) @@ -43,10 +44,11 @@ if not config.task_name: if not config.artifact_names: raise ValueError("FORGEJO_ARTIFACT_NAMES is required") -app = Flask(__name__, template_folder='templates') +app = Flask(__name__, template_folder="templates") + async def fetch_tasks(): - url = f'{config.base_url}/api/v1/repos/{config.user}/{config.repo}/actions/tasks' + url = f"{config.base_url}/api/v1/repos/{config.user}/{config.repo}/actions/tasks" headers = { "accept": "application/json", } @@ -59,9 +61,10 @@ async def fetch_tasks(): async with session.get(url, headers=headers, params=params) as response: response.raise_for_status() data = await response.json() - for task in data['workflow_runs']: - if task['name'] == config.task_name: - return task['url'] + for task in data["workflow_runs"]: + if task["name"] == config.task_name: + return task["url"] + async def fetch_artifact(artifact_url): async with aiohttp.ClientSession() as session: @@ -69,37 +72,55 @@ async def fetch_artifact(artifact_url): data = await response.read() return data + async def handle_artifact(artifact_name: str): task = await fetch_tasks() artifact_url = f"{task}/artifacts/{artifact_name}" artifact_data = await fetch_artifact(artifact_url) response = Response(artifact_data) - response.headers['Content-Disposition'] = 'attachment; filename="GalacticFactory.zip"' + response.headers["Content-Disposition"] = ( + 'attachment; filename="GalacticFactory.zip"' + ) return response + def create_handle_artifact(artifact_name: str): async def handle_artifact_async(): return await handle_artifact(artifact_name) + return handle_artifact_async -for artifact_name in config.artifact_names: - route = f'/{artifact_name}/GalacticFactory' - endpoint = f'handle_{artifact_name}' - app.add_url_rule(route, view_func=create_handle_artifact(artifact_name), endpoint=endpoint) -@app.route('/') +for artifact in config.artifact_names: + route = f"/{artifact}/GalacticFactory" # pylint: disable=invalid-name + endpoint = f"handle_{artifact}" # pylint: disable=invalid-name + app.add_url_rule( + route, view_func=create_handle_artifact(artifact), endpoint=endpoint + ) + + +@app.route("/") def index(): - return render_template('index.html', artifact_urls=[f'/{artifact_name}/GalacticFactory' for artifact_name in config.artifact_names]) + return render_template( + "index.html", + artifact_urls=[ + f"/{artifact_name}/GalacticFactory" + for artifact_name in config.artifact_names + ], + ) -def handle_sigterm(*args): + +def handle_sigterm(*args): # pylint: disable=unused-argument print("Received SIGTERM, exiting gracefully...") sys.exit(0) + signal.signal(signal.SIGTERM, handle_sigterm) -if __name__ == '__main__': +if __name__ == "__main__": from hypercorn.asyncio import serve from hypercorn.config import Config as HypercornConfig + h_config = HypercornConfig() h_config.bind = ["0.0.0.0:80"] asyncio.run(serve(app=app, config=h_config))