#!/usr/bin/env python3 """ Update-Checker für PDF zu ICS Konverter Prüft auf Updates über Gitea API """ import urllib.request import json from pathlib import Path try: from packaging import version as pkg_version except Exception: # pragma: no cover - packaging may be missing in user envs pkg_version = None # Gitea-Konfiguration GITEA_URL = "https://git.file-archive.de" REPO_OWNER = "webfarben" REPO_NAME = "pdf_to_ics" def get_current_version(): """Lese aktuelle lokal gespeicherte Version""" try: version_file = Path(__file__).parent / 'version.txt' if version_file.exists(): with open(version_file, 'r') as f: return f.read().strip() except Exception as e: print(f"Warnung: Version konnte nicht gelesen werden: {e}") return "0.0.0" def get_latest_version(): """ Prüfe Latest Release auf Gitea Returns: Tupel (version_string, download_url) oder (None, None) bei Fehler """ try: # Gitea API Endpoint für neueste Release url = f"{GITEA_URL}/api/v1/repos/{REPO_OWNER}/{REPO_NAME}/releases/latest" with urllib.request.urlopen(url, timeout=5) as response: data = json.loads(response.read().decode()) # Extrahiere Version aus Tag (z.B. "v1.0.0" -> "1.0.0") tag = data.get('tag_name', '').lstrip('v') if not tag: return None, None # HTML-URL für Download (Download-Seite auf Gitea) download_url = f"{GITEA_URL}/{REPO_OWNER}/{REPO_NAME}/releases/tag/{data.get('tag_name', '')}" return tag, download_url except urllib.error.URLError as e: print(f"Warnung: Konnte Gitea nicht erreichen ({GITEA_URL}): {e}") return None, None except json.JSONDecodeError: print("Warnung: Gitea Response konnte nicht geparst werden") return None, None except Exception as e: print(f"Warnung: Update-Check fehlgeschlagen: {e}") return None, None def check_for_updates(): """ Prüfe ob ein Update verfügbar ist Returns: Tupel (update_available, new_version, download_url) - update_available: Bool - new_version: Version String oder None - download_url: URL zur Download-Seite oder None """ current = get_current_version() latest, url = get_latest_version() if latest is None: # Bei Fehler kein Update-Dialog return False, None, None try: # Vergleiche Versionen if pkg_version is not None: if pkg_version.parse(latest) > pkg_version.parse(current): return True, latest, url else: if _simple_version_compare(latest, current) > 0: return True, latest, url except Exception as e: print(f"Warnung: Versionenvergleich fehlgeschlagen: {e}") return False, None, None def _simple_version_compare(left, right): """ Fallback-Versionsvergleich ohne externe Abhaengigkeiten. Gibt 1 zurueck wenn left > right, -1 wenn left < right, sonst 0. """ def to_parts(value): parts = [] for item in value.replace("v", "").split("."): try: parts.append(int(item)) except ValueError: parts.append(item) return parts left_parts = to_parts(left) right_parts = to_parts(right) max_len = max(len(left_parts), len(right_parts)) for i in range(max_len): l_val = left_parts[i] if i < len(left_parts) else 0 r_val = right_parts[i] if i < len(right_parts) else 0 if l_val == r_val: continue try: return 1 if l_val > r_val else -1 except TypeError: l_str = str(l_val) r_str = str(r_val) if l_str == r_str: continue return 1 if l_str > r_str else -1 return 0 if __name__ == "__main__": # Test current = get_current_version() print(f"Aktuelle Version: {current}") print(f"Gitea-Server: {GITEA_URL}/{REPO_OWNER}/{REPO_NAME}\n") latest, url = get_latest_version() if latest: print(f"Neueste Version auf Gitea: {latest}") print(f"Download-URL: {url}") update_available, new_version, download_url = check_for_updates() if update_available: print(f"✓ Update verfügbar: v{new_version}") else: print("✓ Sie verwenden bereits die neueste Version") else: print(f"⚠ Konnte Gitea nicht erreichen ({GITEA_URL})")