diff --git a/.github/workflows/.ruff.yaml b/.github/workflows/.ruff.yaml new file mode 100644 index 0000000..cd077fb --- /dev/null +++ b/.github/workflows/.ruff.yaml @@ -0,0 +1,31 @@ +name: Build and Push Docker Image + +on: + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup python + uses: actions/setup-python@v4 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run Ruff + run: | + pip install ruff + ruff format --check + ruff check diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 0000000..3c2f83c --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,2 @@ +[lint] +extend-select = ["I"] \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8604e94 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "charliermarsh.ruff" +} \ No newline at end of file diff --git a/src/api.py b/src/api.py index 79ddc59..0a0465a 100644 --- a/src/api.py +++ b/src/api.py @@ -1,33 +1,32 @@ -from fastapi import FastAPI -from fastapi import FastAPI, Request -from fastapi.responses import HTMLResponse -from fastapi.responses import FileResponse -from fastapi.templating import Jinja2Templates -from cachetools import cached, TTLCache -from bs4 import BeautifulSoup -import requests -import re import logging +import re + +import requests +from bs4 import BeautifulSoup +from cachetools import TTLCache, cached +from fastapi import FastAPI, Request +from fastapi.responses import FileResponse, HTMLResponse +from fastapi.templating import Jinja2Templates logger = logging.getLogger("uvicorn.error") - cache = TTLCache(maxsize=1, ttl=3600) app = FastAPI() templates = Jinja2Templates(directory="template") -regex = re.compile(r'spätzle ([^/]*)', re.IGNORECASE) +regex = re.compile(r"spätzle ([^/]*)", re.IGNORECASE) + @cached(cache) def checkMensa(): logger.info("Checking Mensa") - - try: - url = 'https://seezeit.com/essen/speiseplaene/mensa-giessberg/' - r = requests.get(url) - soup = BeautifulSoup(r.text, 'html.parser') - today = soup.find('a', class_='heute')['rel'][0] - today_menu = soup.find('div', id=f'tab{today}') - meals = today_menu.find_all('div', class_='title') + try: + url = "https://seezeit.com/essen/speiseplaene/mensa-giessberg/" + r = requests.get(url) + soup = BeautifulSoup(r.text, "html.parser") + + today = soup.find("a", class_="heute")["rel"][0] + today_menu = soup.find("div", id=f"tab{today}") + meals = today_menu.find_all("div", class_="title") spaetzle = None for m in meals: @@ -37,11 +36,11 @@ def checkMensa(): if spaetzle is not None: ingredients = re.search(regex, str(spaetzle)).group(1) - if '28' in ingredients: + if "28" in ingredients: answer = "Spätzle with egg today" color = "green" emoji = "✅" - + else: answer = "WARNING: Spätzle without egg today" color = "red" @@ -50,7 +49,7 @@ def checkMensa(): answer = "No Spätzle today " color = "grey" emoji = "🤷" - except Exception as e: + except Exception: answer = "No menu today" color = "grey" emoji = "⛱️" @@ -58,17 +57,22 @@ def checkMensa(): logger.info(f"Answer: {answer}, Color: {color}, Emoji: {emoji}") return answer, color, emoji + @app.get("/", response_class=HTMLResponse) async def root(request: Request): answer, color, emoji = checkMensa() return templates.TemplateResponse( - request=request, name="main.html", context={"text": answer, "color": color , "emoji": emoji} + request=request, + name="main.html", + context={"text": answer, "color": color, "emoji": emoji}, ) + @app.get("/manifest.json") async def manifest(request: Request): return FileResponse(path="assets/manifest.json") + @app.get("/icons/512.png") async def icon(request: Request): return FileResponse(path="assets/logo.png")