732 Zeilen
23 KiB
Python
732 Zeilen
23 KiB
Python
|
|
Alle Projekte
|
|
Chimaira
|
|
Privat
|
|
Projektziel Das Hauptziel des Projekts ist die Entwicklung einer benutzerfreundlichen Software zur automatisierten Erstellung von Social-Media-Accounts. Die Anwendung ermöglicht es Benutzern, Konten für verschiedene Plattformen (Instagram, Facebook, Twitter, TikTok) mit minimaler manueller Intervention zu erstellen, zu verwalten und zu exportieren. Kernfunktionalitäten Automatisierte Account-Erstellung: Erstellen von Benutzerkonten für verschiedene Social-Media-Plattformen Proxy-Unterstützung: Verwendung von Proxies für anonyme Verbindungen und zur Umgehung von Einschränkungen E-Mail-Integration: Automatische Verarbeitung von Bestätigungscodes Datenbankintegration: Speichern und Verwalten erstellter Konten Benutzerfreundliche GUI: Intuitive Benutzeroberfläche mit Dark Mode Robuste Automatisierung: OCR-Fallback-Mechanismen für UI-Änderungen Code-Playwright/ # Social-Media-Account-Generator/ ├── config/ # Konfigurationsverzeichnis │ ├── browser_config.json │ ├── email_config.json │ ├── facebook_config.json │ ├── instagram_config.json │ ├── license_config.json │ ├── proxy_config.json │ ├── stealth_config.json │ ├── tiktok_config.json │ ├── twitter_config.json │ ├── update_config.json │ └── user_agents.json ├── controllers/ # Controller-Logik │ ├── account_controller.py │ ├── main_controller.py │ ├── settings_controller.py │ └── platform_controllers/ │ ├── base_controller.py │ ├── instagram_controller.py │ ├── facebook_controller.py (nicht implementiert) │ ├── twitter_controller.py (nicht implementiert) │ └── tiktok_controller.py (nicht implementiert) ├── database/ # Datenbankfunktionalität │ └── db_manager.py ├── licensing/ # Lizenzverwaltung │ ├── license_manager.py │ └── license_validator.py ├── logs/ # Log-Verzeichnis │ └── screenshots/ # Screenshots für OCR-Fallbacks ├── ocr/ # OCR-Funktionalität │ ├── fallback_actions.py │ ├── screenshot.py │ └── text_detector.py ├── resources/ # Ressourcen │ ├── icons/ # Icons für die UI │ │ ├── instagram.svg │ │ ├── facebook.svg │ │ ├── twitter.svg │ │ ├── tiktok.svg │ │ └── [andere Icons] │ └── themes/ # Theme-Ressourcen │ ├── dark.qss │ └── light.qss ├── social_networks/ # Social-Media-Automatisierung │ ├── base_automation.py │ ├── instagram/ │ │ ├── instagram_automation.py │ │ ├── instagram_selectors.py │ │ └── instagram_workflow.py │ ├── facebook/ # Noch nicht implementiert │ ├── twitter/ # Noch nicht implementiert │ └── tiktok/ # Noch nicht implementiert ├── updates/ # Update-Funktionalität │ └── update_checker.py ├── utils/ # Hilfsfunktionen │ ├── birthday_generator.py │ ├── email_handler.py │ ├── human_behavior.py │ ├── logger.py │ ├── password_generator.py │ ├── proxy_rotator.py │ ├── theme_manager.py │ └── username_generator.py ├── views/ # UI-Komponenten │ ├── main_window.py │ ├── platform_selector.py │ └── tabs/ │ ├── about_tab.py │ ├── accounts_tab.py │ ├── generator_tab.py │ └── settings_tab.py ├── browser/ # Browser-Automatisierung │ ├── playwright_manager.py │ └── stealth_config.py └── main.py # Haupteinstiegspunkt Kernstruktur und MVC-Framework: Grundlegendes MVC-Muster mit klarer Trennung von Daten, Ansicht und Logik Signale und Slots für die Kommunikation zwischen Komponenten Zentrale Logging-Funktionalität Benutzeroberfläche: Hauptfenster mit Plattformauswahl Plattformspezifische Tabs (Generator, Konten, Einstellungen, Über) Dark Mode für alle UI-Komponenten Utility-Klassen: Logger mit GUI-Integration Proxy-Rotator mit Testoption E-Mail-Handler für Verifizierungscodes Passwort-, Benutzernamen- und Geburtsdatumsgeneratoren Human-Behavior-Simulation für natürliche Verzögerungen Lizenzmanager Update-Checker Datenbankintegration: SQLite-Datenbankmanager für Account-Speicherung Import- und Exportfunktionen Suchfunktionen Instagram-Integration: Basis-Automation und Instagram-spezifische Logik Account-Generator-Workflow Stealth-Funktionalität zur Umgehung von Bot-Erkennung Noch ausstehende Aufgaben Plattform-Integration: Implementierung der Facebook-Automatisierung Implementierung der Twitter-Automatisierung Implementierung der TikTok-Automatisierung Model-Klassen: Entwicklung der Datenmodelle für Accounts und Plattformen Integration in die Controller-Logik OCR-Integration: Anpassung der OCR-Komponenten an die neue MVC-Struktur Verbesserung der Fallback-Mechanismen für UI-Änderungen Plattformspezifische Controller: Implementierung der Facebook-, Twitter- und TikTok-Controller Anpassung an spezifische Anforderungen jeder Plattform Erweiterte Funktionen: CAPTCHA-Behandlung mit externen Diensten oder manueller Eingabe SMS-Verifizierung mit SMS-Empfangsdiensten Verbesserte Fehlerbehandlung und Wiederherstellung Tests: Entwicklung von Unit-Tests für die Kernkomponenten End-to-End-Tests für den gesamten Workflow Performance-Optimierungen: Multi-Threading für parallele Account-Erstellung Optimierte Ressourcennutzung bei längeren Automatisierungen Zusammenfassung der Refaktorierung Das ursprüngliche, monolithische Design wurde zu einer modularen MVC-Architektur umgestaltet, die folgende Vorteile bietet: Verbesserte Wartbarkeit: Kleinere, spezialisierte Dateien statt einer großen main.py Einfachere Erweiterbarkeit: Neue Plattformen können durch Ableitung von Basisklassen hinzugefügt werden Bessere Testbarkeit: Komponenten können isoliert getestet werden Wiederverwendbarkeit: Gemeinsame Funktionalität in Basisklassen extrahiert Klare Verantwortlichkeiten: Jede Komponente hat eine spezifische Aufgabe Die größte Verbesserung ist die klare Trennung von Benutzeroberfläche, Geschäftslogik und Datenmanagement, was die Wartung und Erweiterung erheblich erleichtert und einen strukturierten Rahmen für die Implementierung weiterer Plattformen schafft. Nächste Schritte Die nächsten unmittelbaren Schritte sind: Implementierung der Datenmodelle zur Vervollständigung der MVC-Struktur Entwicklung der weiteren plattformspezifischen Controller Anpassung der bestehenden Automatisierungslogik an die neue Struktur Erstellung von Grundtests für die Kernfunktionalität. Nimm für die Pfade NIEMALS absolute Pfade, sondern IMMER relative Pfade
|
|
|
|
|
|
|
|
|
|
Unbenannt
|
|
Letzte Nachricht vor 21 Sekunden
|
|
Deprecation of generate_birthday() function
|
|
Letzte Nachricht vor 10 Minuten
|
|
Playwright Cookie Banner and Date Parsing Issues
|
|
Letzte Nachricht vor 30 Minuten
|
|
Troubleshooting Python script error with HumanBehavior class
|
|
Letzte Nachricht vor 2 Stunden
|
|
Troubleshooting Python code error with Instagram automation
|
|
Letzte Nachricht vor 2 Stunden
|
|
Troubleshooting Instagram Automation Error
|
|
Letzte Nachricht vor 3 Stunden
|
|
Modular Localization System for Multilingual App
|
|
Letzte Nachricht vor 4 Stunden
|
|
Instagram Account Creation Error
|
|
Letzte Nachricht vor 1 Tag
|
|
Code and Icon Structure Review for Social Media Account Generator
|
|
Letzte Nachricht vor 1 Tag
|
|
Projektwissen
|
|
57 % der Kapazität der Wissensdatenbank genutzt
|
|
|
|
instagram_automation.py
|
|
1.080 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
instagram_automation.py
|
|
1.075 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
human_behavior.py
|
|
488 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
main_window.py
|
|
168 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
platform_selector.py
|
|
96 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
platform_button.py
|
|
77 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
theme_manager.py
|
|
133 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
main.py
|
|
49 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
main_controller.py
|
|
226 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
light.qss
|
|
255 Zeilen
|
|
|
|
text
|
|
|
|
|
|
|
|
dark.qss
|
|
190 Zeilen
|
|
|
|
text
|
|
|
|
|
|
|
|
theme.json
|
|
47 Zeilen
|
|
|
|
json
|
|
|
|
|
|
|
|
birthday_generator.py
|
|
299 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
username_generator.py
|
|
426 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
stealth_config.py
|
|
216 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
playwright_manager.py
|
|
517 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
user_agents.json
|
|
31 Zeilen
|
|
|
|
json
|
|
|
|
|
|
|
|
update_config.json
|
|
9 Zeilen
|
|
|
|
json
|
|
|
|
|
|
|
|
stealth_config.json
|
|
14 Zeilen
|
|
|
|
json
|
|
|
|
|
|
|
|
proxy_config.json
|
|
15 Zeilen
|
|
|
|
json
|
|
|
|
|
|
|
|
license_config.json
|
|
9 Zeilen
|
|
|
|
json
|
|
|
|
|
|
|
|
email_config.json
|
|
6 Zeilen
|
|
|
|
json
|
|
|
|
|
|
|
|
instagram_controller.py
|
|
186 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
base_controller.py
|
|
130 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
settings_controller.py
|
|
295 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
account_controller.py
|
|
150 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
license_validator.py
|
|
304 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
license_manager.py
|
|
450 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
instagram_workflow.py
|
|
315 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
instagram_selectors.py
|
|
113 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
base_automation.py
|
|
329 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
version.py
|
|
193 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
update_checker.py
|
|
411 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
proxy_rotator.py
|
|
347 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
password_generator.py
|
|
338 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
logger.py
|
|
70 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
email_handler.py
|
|
410 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
about_tab.py
|
|
64 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
settings_tab.py
|
|
302 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
generator_tab.py
|
|
278 Zeilen
|
|
|
|
py
|
|
|
|
|
|
|
|
accounts_tab.py
|
|
138 Zeilen
|
|
|
|
py
|
|
|
|
|
|
update_checker.py
|
|
|
|
Die Formatierung kann von der Quelle abweichen
|
|
|
|
"""
|
|
Update-Checking-Funktionalität für den Social Media Account Generator.
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
import logging
|
|
import requests
|
|
import shutil
|
|
from datetime import datetime
|
|
from typing import Dict, List, Any, Optional, Tuple, Union
|
|
|
|
logger = logging.getLogger("update_checker")
|
|
|
|
class UpdateChecker:
|
|
"""Klasse zum Überprüfen und Herunterladen von Updates."""
|
|
|
|
CONFIG_FILE = os.path.join("config", "app_version.json")
|
|
UPDATE_SERVER_URL = "https://api.example.com/updates" # Platzhalter - in der Produktion anpassen
|
|
|
|
def __init__(self):
|
|
"""Initialisiert den UpdateChecker und lädt die Konfiguration."""
|
|
self.version_info = self.load_version_info()
|
|
|
|
# Stelle sicher, dass das Konfigurationsverzeichnis existiert
|
|
os.makedirs(os.path.dirname(self.CONFIG_FILE), exist_ok=True)
|
|
|
|
# Updates-Verzeichnis für Downloads
|
|
os.makedirs("updates", exist_ok=True)
|
|
|
|
def load_version_info(self) -> Dict[str, Any]:
|
|
"""Lädt die Versionsinformationen aus der Konfigurationsdatei."""
|
|
if not os.path.exists(self.CONFIG_FILE):
|
|
default_info = {
|
|
"current_version": "1.0.0",
|
|
"last_check": "",
|
|
"channel": "stable",
|
|
"auto_check": True,
|
|
"auto_download": False
|
|
}
|
|
|
|
# Standardwerte speichern
|
|
try:
|
|
with open(self.CONFIG_FILE, "w", encoding="utf-8") as f:
|
|
json.dump(default_info, f, indent=2)
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Speichern der Standardversionsinformationen: {e}")
|
|
|
|
return default_info
|
|
|
|
try:
|
|
with open(self.CONFIG_FILE, "r", encoding="utf-8") as f:
|
|
version_info = json.load(f)
|
|
|
|
logger.info(f"Versionsinformationen geladen: {version_info.get('current_version', 'unbekannt')}")
|
|
|
|
return version_info
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Laden der Versionsinformationen: {e}")
|
|
return {
|
|
"current_version": "1.0.0",
|
|
"last_check": "",
|
|
"channel": "stable",
|
|
"auto_check": True,
|
|
"auto_download": False
|
|
}
|
|
|
|
def save_version_info(self) -> bool:
|
|
"""Speichert die Versionsinformationen in die Konfigurationsdatei."""
|
|
try:
|
|
with open(self.CONFIG_FILE, "w", encoding="utf-8") as f:
|
|
json.dump(self.version_info, f, indent=2)
|
|
|
|
logger.info("Versionsinformationen gespeichert")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Speichern der Versionsinformationen: {e}")
|
|
return False
|
|
|
|
def compare_versions(self, version1: str, version2: str) -> int:
|
|
"""
|
|
Vergleicht zwei Versionsstrings (semver).
|
|
|
|
Args:
|
|
version1: Erste Version
|
|
version2: Zweite Version
|
|
|
|
Returns:
|
|
-1, wenn version1 < version2
|
|
0, wenn version1 == version2
|
|
1, wenn version1 > version2
|
|
"""
|
|
v1_parts = [int(part) for part in version1.split(".")]
|
|
v2_parts = [int(part) for part in version2.split(".")]
|
|
|
|
# Fülle fehlende Teile mit Nullen auf
|
|
while len(v1_parts) < 3:
|
|
v1_parts.append(0)
|
|
while len(v2_parts) < 3:
|
|
v2_parts.append(0)
|
|
|
|
# Vergleiche die Teile
|
|
for i in range(3):
|
|
if v1_parts[i] < v2_parts[i]:
|
|
return -1
|
|
elif v1_parts[i] > v2_parts[i]:
|
|
return 1
|
|
|
|
return 0
|
|
|
|
def check_for_updates(self, force: bool = False) -> Dict[str, Any]:
|
|
"""
|
|
Überprüft, ob Updates verfügbar sind.
|
|
|
|
Args:
|
|
force: Erzwingt eine Überprüfung, auch wenn erst kürzlich geprüft wurde
|
|
|
|
Returns:
|
|
Dictionary mit Update-Informationen
|
|
"""
|
|
result = {
|
|
"has_update": False,
|
|
"current_version": self.version_info["current_version"],
|
|
"latest_version": self.version_info["current_version"],
|
|
"release_date": "",
|
|
"release_notes": "",
|
|
"download_url": "",
|
|
"error": ""
|
|
}
|
|
|
|
# Prüfe, ob seit der letzten Überprüfung genügend Zeit vergangen ist (24 Stunden)
|
|
if not force and self.version_info.get("last_check"):
|
|
try:
|
|
last_check = datetime.fromisoformat(self.version_info["last_check"])
|
|
now = datetime.now()
|
|
|
|
# Wenn weniger als 24 Stunden seit der letzten Überprüfung vergangen sind
|
|
if (now - last_check).total_seconds() < 86400:
|
|
logger.info("Update-Überprüfung übersprungen (letzte Überprüfung vor weniger als 24 Stunden)")
|
|
return result
|
|
except Exception as e:
|
|
logger.warning(f"Fehler beim Parsen des letzten Überprüfungsdatums: {e}")
|
|
|
|
try:
|
|
# Simuliere eine Online-Überprüfung für Entwicklungszwecke
|
|
# In der Produktion sollte eine echte API-Anfrage implementiert werden
|
|
# response = requests.get(
|
|
# f"{self.UPDATE_SERVER_URL}/check",
|
|
# params={
|
|
# "version": self.version_info["current_version"],
|
|
# "channel": self.version_info["channel"]
|
|
# },
|
|
# timeout=10
|
|
# )
|
|
|
|
# For demonstration purposes only
|
|
latest_version = "1.1.0"
|
|
has_update = self.compare_versions(self.version_info["current_version"], latest_version) < 0
|
|
|
|
if has_update:
|
|
result["has_update"] = True
|
|
result["latest_version"] = latest_version
|
|
result["release_date"] = "2025-05-01"
|
|
result["release_notes"] = (
|
|
"Version 1.1.0:\n"
|
|
"- Unterstützung für Facebook-Accounts hinzugefügt\n"
|
|
"- Verbesserte Proxy-Rotation\n"
|
|
"- Bessere Fehlerbehandlung bei der Account-Erstellung\n"
|
|
"- Verschiedene Bugfixes und Leistungsverbesserungen"
|
|
)
|
|
result["download_url"] = f"{self.UPDATE_SERVER_URL}/download/v1.1.0"
|
|
|
|
# Update der letzten Überprüfung
|
|
self.version_info["last_check"] = datetime.now().isoformat()
|
|
self.save_version_info()
|
|
|
|
logger.info(f"Update-Überprüfung abgeschlossen: {result['latest_version']} verfügbar")
|
|
|
|
return result
|
|
|
|
except requests.RequestException as e:
|
|
error_msg = f"Netzwerkfehler bei der Update-Überprüfung: {e}"
|
|
logger.error(error_msg)
|
|
result["error"] = error_msg
|
|
return result
|
|
except Exception as e:
|
|
error_msg = f"Unerwarteter Fehler bei der Update-Überprüfung: {e}"
|
|
logger.error(error_msg)
|
|
result["error"] = error_msg
|
|
return result
|
|
|
|
def download_update(self, download_url: str, version: str) -> Dict[str, Any]:
|
|
"""
|
|
Lädt ein Update herunter.
|
|
|
|
Args:
|
|
download_url: URL zum Herunterladen des Updates
|
|
version: Version des Updates
|
|
|
|
Returns:
|
|
Dictionary mit Download-Informationen
|
|
"""
|
|
result = {
|
|
"success": False,
|
|
"file_path": "",
|
|
"version": version,
|
|
"error": ""
|
|
}
|
|
|
|
try:
|
|
# Zieldateiname erstellen
|
|
file_name = f"update_v{version}.zip"
|
|
file_path = os.path.join("updates", file_name)
|
|
|
|
# Simuliere einen Download für Entwicklungszwecke
|
|
# In der Produktion sollte ein echter Download implementiert werden
|
|
|
|
# response = requests.get(download_url, stream=True, timeout=60)
|
|
# if response.status_code == 200:
|
|
# with open(file_path, "wb") as f:
|
|
# shutil.copyfileobj(response.raw, f)
|
|
|
|
# Simulierter Download (erstelle eine leere Datei)
|
|
with open(file_path, "w") as f:
|
|
f.write(f"Placeholder for version {version} update")
|
|
|
|
result["success"] = True
|
|
result["file_path"] = file_path
|
|
|
|
logger.info(f"Update v{version} heruntergeladen: {file_path}")
|
|
|
|
return result
|
|
|
|
except requests.RequestException as e:
|
|
error_msg = f"Netzwerkfehler beim Herunterladen des Updates: {e}"
|
|
logger.error(error_msg)
|
|
result["error"] = error_msg
|
|
return result
|
|
except Exception as e:
|
|
error_msg = f"Unerwarteter Fehler beim Herunterladen des Updates: {e}"
|
|
logger.error(error_msg)
|
|
result["error"] = error_msg
|
|
return result
|
|
|
|
def is_update_available(self) -> bool:
|
|
"""
|
|
Überprüft, ob ein Update verfügbar ist.
|
|
|
|
Returns:
|
|
True, wenn ein Update verfügbar ist, sonst False
|
|
"""
|
|
update_info = self.check_for_updates()
|
|
return update_info["has_update"]
|
|
|
|
def get_current_version(self) -> str:
|
|
"""
|
|
Gibt die aktuelle Version zurück.
|
|
|
|
Returns:
|
|
Aktuelle Version
|
|
"""
|
|
return self.version_info["current_version"]
|
|
|
|
def set_current_version(self, version: str) -> bool:
|
|
"""
|
|
Setzt die aktuelle Version.
|
|
|
|
Args:
|
|
version: Neue Version
|
|
|
|
Returns:
|
|
True bei Erfolg, False im Fehlerfall
|
|
"""
|
|
try:
|
|
self.version_info["current_version"] = version
|
|
return self.save_version_info()
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Setzen der aktuellen Version: {e}")
|
|
return False
|
|
|
|
def set_update_channel(self, channel: str) -> bool:
|
|
"""
|
|
Setzt den Update-Kanal (stable, beta, dev).
|
|
|
|
Args:
|
|
channel: Update-Kanal
|
|
|
|
Returns:
|
|
True bei Erfolg, False im Fehlerfall
|
|
"""
|
|
if channel not in ["stable", "beta", "dev"]:
|
|
logger.warning(f"Ungültiger Update-Kanal: {channel}")
|
|
return False
|
|
|
|
try:
|
|
self.version_info["channel"] = channel
|
|
return self.save_version_info()
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Setzen des Update-Kanals: {e}")
|
|
return False
|
|
|
|
def get_update_channel(self) -> str:
|
|
"""
|
|
Gibt den aktuellen Update-Kanal zurück.
|
|
|
|
Returns:
|
|
Update-Kanal (stable, beta, dev)
|
|
"""
|
|
return self.version_info.get("channel", "stable")
|
|
|
|
def set_auto_check(self, auto_check: bool) -> bool:
|
|
"""
|
|
Aktiviert oder deaktiviert die automatische Update-Überprüfung.
|
|
|
|
Args:
|
|
auto_check: True, um automatische Updates zu aktivieren, False zum Deaktivieren
|
|
|
|
Returns:
|
|
True bei Erfolg, False im Fehlerfall
|
|
"""
|
|
try:
|
|
self.version_info["auto_check"] = bool(auto_check)
|
|
return self.save_version_info()
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Setzen der automatischen Update-Überprüfung: {e}")
|
|
return False
|
|
|
|
def is_auto_check_enabled(self) -> bool:
|
|
"""
|
|
Überprüft, ob die automatische Update-Überprüfung aktiviert ist.
|
|
|
|
Returns:
|
|
True, wenn die automatische Update-Überprüfung aktiviert ist, sonst False
|
|
"""
|
|
return self.version_info.get("auto_check", True)
|
|
|
|
def set_auto_download(self, auto_download: bool) -> bool:
|
|
"""
|
|
Aktiviert oder deaktiviert den automatischen Download von Updates.
|
|
|
|
Args:
|
|
auto_download: True, um automatische Downloads zu aktivieren, False zum Deaktivieren
|
|
|
|
Returns:
|
|
True bei Erfolg, False im Fehlerfall
|
|
"""
|
|
try:
|
|
self.version_info["auto_download"] = bool(auto_download)
|
|
return self.save_version_info()
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Setzen des automatischen Downloads: {e}")
|
|
return False
|
|
|
|
def is_auto_download_enabled(self) -> bool:
|
|
"""
|
|
Überprüft, ob der automatische Download von Updates aktiviert ist.
|
|
|
|
Returns:
|
|
True, wenn der automatische Download aktiviert ist, sonst False
|
|
"""
|
|
return self.version_info.get("auto_download", False)
|
|
|
|
def apply_update(self, update_file: str) -> Dict[str, Any]:
|
|
"""
|
|
Wendet ein heruntergeladenes Update an.
|
|
|
|
Args:
|
|
update_file: Pfad zur Update-Datei
|
|
|
|
Returns:
|
|
Dictionary mit Informationen über die Anwendung des Updates
|
|
"""
|
|
result = {
|
|
"success": False,
|
|
"version": "",
|
|
"error": ""
|
|
}
|
|
|
|
if not os.path.exists(update_file):
|
|
result["error"] = f"Update-Datei nicht gefunden: {update_file}"
|
|
logger.error(result["error"])
|
|
return result
|
|
|
|
try:
|
|
# In der Produktion sollte hier die tatsächliche Update-Logik implementiert werden
|
|
# 1. Extrahieren des Updates
|
|
# 2. Sichern der aktuellen Version
|
|
# 3. Anwenden der Änderungen
|
|
# 4. Aktualisieren der Versionsinformationen
|
|
|
|
# Simuliere ein erfolgreiches Update
|
|
logger.info(f"Update aus {update_file} erfolgreich angewendet (simuliert)")
|
|
|
|
# Extrahiere Version aus dem Dateinamen
|
|
file_name = os.path.basename(update_file)
|
|
version_match = re.search(r"v([0-9.]+)", file_name)
|
|
|
|
if version_match:
|
|
new_version = version_match.group(1)
|
|
self.set_current_version(new_version)
|
|
result["version"] = new_version
|
|
|
|
result["success"] = True
|
|
|
|
return result
|
|
|
|
except Exception as e:
|
|
error_msg = f"Fehler beim Anwenden des Updates: {e}"
|
|
logger.error(error_msg)
|
|
result["error"] = error_msg
|
|
return result
|