Files
CameraSave/main.py

135 lines
4.7 KiB
Python

import imaplib
import email
import email.header
import email.utils
import os
import re
import shutil
from datetime import datetime, timedelta
# === KONFIGURATION ===
IMAP_SERVER = os.getenv("IMAP_SERVER", "secureimap.t-online.de")
IMAP_PORT = int(os.getenv("IMAP_PORT", "993"))
EMAIL_USER = os.getenv("EMAIL_USER", "dk2ge@t-online.de")
EMAIL_PASS = os.getenv("EMAIL_PASS", "ETBjw65tf2")
SAVE_DIR = os.getenv("SAVE_DIR", "./videospeicher")
HEARTBEAT_FILE = os.getenv("HEARTBEAT_FILE", "./heartbeat.txt")
# === HEARTBEAT ===
def update_heartbeat():
"""Schreibt einen Heartbeat für das Monitoring."""
try:
dir_name = os.path.dirname(HEARTBEAT_FILE)
if dir_name:
os.makedirs(dir_name, exist_ok=True)
with open(HEARTBEAT_FILE, "w") as f:
f.write(datetime.now().isoformat())
print(f"💓 Heartbeat aktualisiert: {HEARTBEAT_FILE}")
except Exception as e:
print(f"⚠️ Fehler beim Heartbeat-Update: {e}")
# === ALTE DATEIEN LÖSCHEN (älter als 1 Jahr) ===
def cleanup_old_files(base_dir, days=365):
cutoff = datetime.now() - timedelta(days=days)
for root, dirs, files in os.walk(base_dir):
for file in files:
filepath = os.path.join(root, file)
try:
mtime = datetime.fromtimestamp(os.path.getmtime(filepath))
if mtime < cutoff:
print(f"Lösche altes Video: {filepath}")
os.remove(filepath)
except Exception as e:
print(f"Fehler beim Löschen von {filepath}: {e}")
# leere Ordner aufräumen
for root, dirs, files in os.walk(base_dir, topdown=False):
for d in dirs:
dirpath = os.path.join(root, d)
if not os.listdir(dirpath):
shutil.rmtree(dirpath)
# === MAILS VERARBEITEN ===
def process_mails():
mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
mail.login(EMAIL_USER, EMAIL_PASS)
mail.select("INBOX")
status, messages = mail.search(None, "ALL")
if status != "OK":
print("Keine Mails gefunden.")
return
for num in messages[0].split():
status, msg_data = mail.fetch(num, "(RFC822)")
if status != "OK":
continue
msg = email.message_from_bytes(msg_data[0][1])
# Datum für Ordnerstruktur bestimmen
mail_date = msg["Date"]
try:
parsed_date = email.utils.parsedate_to_datetime(mail_date)
except Exception:
parsed_date = datetime.now()
year = parsed_date.strftime("%Y")
month = parsed_date.strftime("%m")
day = parsed_date.strftime("%d")
# Subject dekodieren
raw_subject = msg.get("Subject", "")
decoded_subject = email.header.decode_header(raw_subject)
subject_parts = []
for part_bytes, charset in decoded_subject:
if isinstance(part_bytes, bytes):
subject_parts.append(part_bytes.decode(charset or "utf-8", errors="replace"))
else:
subject_parts.append(part_bytes)
subject = "".join(subject_parts).strip()
# Kameranummer extrahieren: z. B. "Camera1" → "Camera1"
cam_match = re.search(r'Camera(\d+)', subject, re.IGNORECASE)
cam_name = f"C{cam_match.group(1)}" if cam_match else "C0"
# Datum und Uhrzeit aus Subject extrahieren: z. B. "2026/3/2 16:26:02"
dt_match = re.search(r'(\d{4})/(\d{1,2})/(\d{1,2})\s+(\d{2}):(\d{2}):(\d{2})', subject)
if dt_match:
y, mo, d_s, h, mi, s = dt_match.groups()
subject_dt = f"{y}-{mo.zfill(2)}-{d_s.zfill(2)}_{h}{mi}{s}"
else:
subject_dt = parsed_date.strftime("%Y-%m-%d_%H%M%S")
safe_subject = f"{cam_name}_{subject_dt}"
folder_path = os.path.join(SAVE_DIR, year, month, day)
os.makedirs(folder_path, exist_ok=True)
# Anhänge speichern
for part in msg.walk():
if part.get_content_disposition() == "attachment":
filename = part.get_filename()
if not filename:
filename = "anhang.mp4"
ext = os.path.splitext(filename)[1] or ".mp4"
filename = f"{safe_subject}{ext}"
filepath = os.path.join(folder_path, filename)
with open(filepath, "wb") as f:
f.write(part.get_payload(decode=True))
print(f"Gespeichert: {filepath}")
# Mail nach Verarbeitung löschen
mail.store(num, "+FLAGS", "\\Deleted")
mail.expunge()
mail.logout()
if __name__ == "__main__":
update_heartbeat() # Heartbeat zu Beginn
cleanup_old_files(SAVE_DIR, days=365)
process_mails()
update_heartbeat() # Heartbeat nach erfolgreicher Ausführung