diff --git a/Dockerfile b/Dockerfile index e568243..ea1fe28 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,13 @@ FROM python:3.10-alpine3.18 -RUN pip install requests WORKDIR /app +COPY requirements.txt /app/requirements.txt +RUN pip install --no-cache-dir --upgrade --requirement requirements.txt COPY notifier.py template.html /app/ # TODO Dev purporse COPY conf.ini /app/conf.ini +EXPOSE 80 ENTRYPOINT ["python3", "/app/notifier.py"] +CMD ["uvicorn", "notifier:app", "--host", "0.0.0.0", "--port", "80"] diff --git a/Justfile b/Justfile index b367a24..633cc68 100644 --- a/Justfile +++ b/Justfile @@ -12,6 +12,10 @@ remote_build_image := remote_image_name + ":" + last_commit_sha1 run: _ensure_venv_is_ok {{ python }} notifier.py +# Launch the API +api: _ensure_venv_is_ok + {{ venv }}/bin/uvicorn notifier:app --reload + # Init python virtual env init: python3 -m venv venv diff --git a/docker-compose.yml b/docker-compose.yml index 4eb8239..ac4399c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,13 +6,15 @@ services: image: github-release-notifier container_name: github-release-notifier volumes: - - ./conf.ini:/app/conf.ini + - ./conf.ini:/app/conf.ini + ports: + - 8000:80 mailpit: image: axllent/mailpit ports: - - "8025:8025" - - "1025:1025" + - 8025:8025 + - 1025:1025 ofelia: image: mcuadros/ofelia:latest diff --git a/notifier.py b/notifier.py index 2acc741..f4154dc 100644 --- a/notifier.py +++ b/notifier.py @@ -8,6 +8,11 @@ from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import requests +from fastapi import FastAPI + +SCRIPT_DIR = os.path.dirname(__file__) +CONF_FILE = os.path.join(SCRIPT_DIR, "conf.ini") +TEMPLATE_FILE = os.path.join(SCRIPT_DIR, "template.html") class EnvInjection(configparser.Interpolation): @@ -26,15 +31,51 @@ class EnvInjection(configparser.Interpolation): return env_value if env_value else file_value -def main(): - script_dir = os.path.dirname(__file__) - conf_file = os.path.join(script_dir, "conf.ini") - template_file = os.path.join(script_dir, "template.html") +# +# API PARTS +# +app = FastAPI() + +@app.get("/subscriptions") +def get_projects(): + parser = load_conf() + projects = json.loads(parser["projects"].get("projects")) + return projects + + +@app.put("/subscriptions") +def put_projects(project: str, author: str | None = None): + # TODO Check if project really exist? + parser = load_conf() + projects = json.loads(parser.get("projects", "projects")) + + if author: + project = f"{author}/{project}" + projects.append(project) + + # TODO Watch a converter for list: https://stackoverflow.com/a/53274707/1346391 + parser.set("projects", "projects", json.dumps(projects, indent=0)) + + with open("conf.ini", "w", encoding="utf-8") as configfile: + parser.write(configfile) + + return project + + +def load_conf(conf_file=CONF_FILE) -> configparser.ConfigParser: parser = configparser.ConfigParser( default_section="config", interpolation=EnvInjection() ) parser.read(conf_file) + return parser + + +# +# SCRIPT PART +# +def main(): + parser = load_conf() default_config = parser["config"] try: @@ -67,8 +108,10 @@ def main(): return content = "" + news = [] for new_r in new_releases: + news.append(new_r["project_name"]) content += f"""