commit f140cd13bf66ee8998bba09803c8883f21887d0f Author: rxf Date: Mon Aug 4 15:58:42 2025 +0000 V 1.0.0 - erste Version diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..99eded6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.venv/ +__pycache__/ +*.pyc +logs +.env +.DS_Store \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dee9c9c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.venv +.env +logs + diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6b76b4f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal" + } + ] +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a1aea56 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +FROM python:3.10-slim + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + tesseract-ocr \ + tesseract-ocr-deu \ + cron \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /app + +# Copy project files +COPY . /app + +# Install Python packages +RUN pip install --no-cache-dir -r requirements.txt + +# Set environment variables +ENV PYTHONUNBUFFERED=1 + +# Set up cron job +RUN echo "10 7 * * * bash /app/run_citysensor.sh >> /app/logs/cron.log 2>&1" > citysensor-cron \ + && crontab citysensor-cron + +# Make shell script executable +RUN chmod +x /app/run_citysensor.sh + +# Start cron in foreground +CMD ["cron", "-f"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a08ae30 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +services: + wettercheck: + build: . + container_name: wetterserver + env_file: + - .env + volumes: + - ./logs:/app/logs + restart: unless-stopped \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..520599b --- /dev/null +++ b/main.py @@ -0,0 +1,102 @@ +''' +Webseiten auf citysensor prüfen + +Täglich morgens um 07:20 (mit Hilfe des cron) prüfen, ob die 3 citysensor-Seiten (Lärm, Multigeiger und Feinstaub) +erreichbar sind. Wenn nicht, eine Meldung per E-Mail absetzen + +*** Versiongeschichte + +V 1.0.0 2025-08-03 rxf + - erste laufende Version + +''' +VERSION = "1.0.0" +VDATE = "2025-08-04" + + +import requests +import os, smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +from dotenv import load_dotenv + +# ----------------------- +# Einstellungen +# ----------------------- + +# 1. Optional: Lade .env, falls vorhanden (nur wenn lokal vorhanden) +env_path = os.path.join(os.path.dirname(__file__), '.env') +if os.path.exists(env_path): + load_dotenv(dotenv_path=env_path) + print("⚙️ .env-Datei geladen") +else: + print("⚙️ Keine .env-Datei gefunden, verwende Docker-/Systemvariablen") + +# E-Mail-Konfiguration +EMAIL_ABSENDER = os.getenv("GMX_EMAIL") +EMAIL_EMPFÄNGER = "rexfue@gmail.com" +SMTP_SERVER = "smtp.gmx.com" +SMTP_PORT = 465 +SMTP_USER = os.getenv("GMX_EMAIL") +SMTP_PASS = os.getenv("GMX_PASSWORD") + +print(f"Citysensor-Check\r\nVersion {VERSION} vom {VDATE}") + +alleOK = True + +load_dotenv() + +# ----------------------- +# E-Mail senden +# ----------------------- +def sendmail(s,b): + msg = MIMEMultipart() + msg["From"] = EMAIL_ABSENDER + msg["To"] = EMAIL_EMPFÄNGER + msg["Subject"] = s + msg.attach(MIMEText(b, "plain")) + + try: + with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server: + server.login(SMTP_USER, SMTP_PASS) + server.send_message(msg) + print("📧 Benachrichtigungs-Mail gesendet.") + except Exception as e: + print(f"❌ Fehler beim Senden der Mail: {e}") + + +# ----------------------- +# Fehler melden +# ----------------------- +def meldError(u, e): + global alleOK + print(f"❌ Fehler beim Abrufen von {urls[i]} ({e})") + body = f"{u} ist nicht erreichbar" + subject = f"⚠️ {u} antwortet nicht! {e}" + sendmail(subject, body) + alleOK = False + + +# ----------------------- +# Webseiten checken +# ----------------------- + +urls = [ "https://laerm.citysensor.de", + "https://multigeiger.citysensor.de", + "https://feinstaub.citysensor.de" ] + +for i in range(len(urls)): + try: + res = requests.get(urls[i]) + if res.status_code != 200: + meldError(urls[i],"") + except: + meldError(urls[i],"Exception") + + + +if alleOK: + print("Alle 3 erreichbar") + body = "Gut so" + subject = "✅ citysensor.de ist OK" + sendmail(subject, body) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..3a2cb77 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +certifi==2025.8.3 +charset-normalizer==3.4.2 +dotenv==0.9.9 +idna==3.10 +packaging==25.0 +pillow==11.3.0 +pytesseract==0.3.13 +python-dotenv==1.1.1 +requests==2.32.4 +urllib3==2.5.0 diff --git a/run_citysensor.sh b/run_citysensor.sh new file mode 100755 index 0000000..3175ca3 --- /dev/null +++ b/run_citysensor.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Aktiviere virtuelle Umgebung +source /home/rxf/Projekte/citysensor/.venv/bin/activate + +cd /home/rxf/Projekte/citysensor + +# Protokollfunktion mit Zeitstempel +log() { + echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> logs/cron.log +} + +log ">>> Starte Citysensor-Prüfung" + +# Python-Skript ausführen und Ergebnis loggen +python main.py >> logs/cron.log 2>&1 + +log ">>> Citysensor-Püfung abgeschlossen" +log "------------------------------------" \ No newline at end of file