Files
AccountForger-neuerUpload/ROADMAP.md
Claude Project Manager 14eefa18f6 Abuse-Schutz fertig
2025-11-10 03:09:35 +01:00

1039 Zeilen
33 KiB
Markdown

# AccountForger - Roadmap
Dieses Dokument enthält geplante Features und Verbesserungen für AccountForger.
---
## 🎯 Feature 1: Bestätigungscodes-Reiter
**Priorität:** Hoch
**Status:** Geplant
**Geschätzter Aufwand:** 3-5 Tage
### Beschreibung
Neuer Reiter "Bestätigungscodes" neben "Plattformen" und "Accounts" für die Verwaltung eingehender Verifizierungscodes.
### Funktionale Anforderungen
#### UI/UX Design
- **Chat-ähnliche Oberfläche** mit Liste aller eingehenden Codes
- **Code-Anzeige Format:**
```
[Social Media Logo] username_123
Code: 456789
📧 example@domain.com ODER 📱 +49123456789
⏱ Löscht sich in 5h 32min
[Kopieren] [Ausblenden]
```
- **WICHTIG:** Keine Emojis für Logo-Platzhalter - echte Platform-Icons verwenden
- **Sortierung:** Neueste Codes oben
- **Leerer Zustand:** "Keine Bestätigungscodes vorhanden"
#### Code-Status & Lebensdauer
- **Automatische Löschung:** Codes werden nach **6 Stunden** automatisch entfernt
- **Countdown-Timer:** Zeigt verbleibende Zeit bis zur Löschung
- **Verwendete Codes:** Grau ausgegraut mit Hinweis "Verwendet"
- **Ausblenden-Funktion:** Nutzer kann Codes manuell ausblenden (kein permanentes Löschen)
#### Filter & Suche
- **Filter-Optionen:**
- Nach Plattform (Instagram, Facebook, TikTok, etc.)
- Nach Account-Name
- Nach Code-Typ (E-Mail vs SMS)
- **Suchfeld:** Schnellsuche nach Account-Namen
- **Filter kombinierbar:** Mehrere Filter gleichzeitig aktiv
#### Copy-Funktion
- **Copy-Button:** Kopiert Code mit einem Klick in Zwischenablage
- **Visuelles Feedback:** "Kopiert!" kurz anzeigen nach Klick
#### Code-Abfrage & Aktualisierung
- **Automatische Abfrage erfolgt bei:**
1. **Account-Erstellung gestartet** → Polling alle 10-15 Sekunden
2. **Login-Versuch fehlgeschlagen** (Code erwartet) → Sofort prüfen + alle 5 Sekunden
3. **Manueller Refresh-Button** → Auf Knopfdruck
4. **Öffnen des Bestätigungscodes-Reiters** → Einmalig beim Laden
- **Intelligentes Polling:**
- Polling stoppt wenn kein aktiver Prozess läuft (Server-Schonung)
- Status-Indikator zeigt Aktualisierungsstatus:
- "Prüfe auf neue Codes..." (während Abfrage)
- "Aktualisiert vor X Sekunden" (nach erfolgreicher Abfrage)
#### Datenquellen
- **E-Mail-Codes:** Abfrage über Server-API (perspektivisch, siehe Feature 3)
- **SMS-Codes:** Abfrage über Server-API (perspektivisch)
- Codes erscheinen automatisch wenn sie vom Server abgerufen werden
### Technische Umsetzung
#### Betroffene Module
- `views/components/` - Neuer Tab für Bestätigungscodes
- `views/tabs/` - Tab-Integration in Hauptfenster
- `controllers/` - Controller für Code-Verwaltung
- `database/` - Repository für Code-Speicherung
- `licensing/api_client.py` - API-Calls für Code-Abruf (perspektivisch)
#### Datenbank-Schema
```sql
CREATE TABLE verification_codes (
id INTEGER PRIMARY KEY,
account_name TEXT NOT NULL,
platform TEXT NOT NULL,
code TEXT NOT NULL,
source_type TEXT NOT NULL, -- 'email' oder 'sms'
source_value TEXT NOT NULL, -- E-Mail-Adresse oder Telefonnummer
received_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP NOT NULL,
used BOOLEAN DEFAULT 0,
hidden BOOLEAN DEFAULT 0,
auto_used BOOLEAN DEFAULT 0
);
```
#### API-Endpunkte (perspektivisch)
- `GET /api/codes/poll` - Neue Codes abrufen
- `POST /api/codes/mark-used` - Code als verwendet markieren
### Abhängigkeiten
- Feature 3 (Server-seitige E-Mail/SMS-Abfrage) muss implementiert sein für vollständige Funktionalität
- Bis dahin: Lokale E-Mail/SMS-Abfrage als Übergangslösung
---
## 📦 Feature 2: Profil-Export
**Priorität:** Mittel
**Status:** Geplant
**Geschätzter Aufwand:** 2-3 Tage
### Beschreibung
Export-Funktion für einzelne Account-Profile zur Weitergabe an andere Nutzer oder als Backup.
### Funktionale Anforderungen
#### Export-Umfang
**Exportierte Daten:**
- ✓ Benutzername
- ✓ Passwort
- ✓ E-Mail-Adresse
- ✓ Telefonnummer
- ✓ Plattform
- ✓ Vor-/Nachname
- ✓ Geburtsdatum
- ✓ Erstellungsdatum
**NICHT exportiert:**
- ✗ Browser-Cookies
- ✗ Session Storage
- ✗ Browser-Fingerprint
- ✗ Proxy-Einstellungen
#### Export-Formate
##### 1. CSV-Format
```csv
Username,Passwort,E-Mail,Telefon,Plattform,Vorname,Nachname,Geburtsdatum,Erstellt_am
waster_ha_948,P@ssw0rd123,waster@domain.com,+49123456789,Instagram,Max,Mustermann,15.03.1995,01.11.2025
```
- **Trennzeichen:** Komma (,)
- **Encoding:** UTF-8
- **Kopfzeile:** Ja (erste Zeile)
- **Auch bei Einzelexport:** Nur eine Datenzeile
##### 2. TXT-Format
```
Username: waster_ha_948
Passwort: P@ssw0rd123
E-Mail: waster@domain.com
Telefon: +49123456789
Plattform: Instagram
Name: Max Mustermann
Geburtsdatum: 15.03.1995
Erstellt am: 01.11.2025
```
- **Struktur:** Key-Value Paare
- **Encoding:** UTF-8
##### 3. PDF-Format
```
┌────────────────────────────────────────┐
│ [IntelSight Logo] │
│ │
│ Account-Profil: waster_ha_948 │
│ Plattform: [Instagram Logo] Instagram │
│ │
│ LOGIN-DATEN │
│ • Benutzername: waster_ha_948 │
│ • Passwort: P@ssw0rd123 │
│ • E-Mail: waster@domain.com │
│ • Telefon: +49123456789 │
│ │
│ PROFIL-INFORMATIONEN │
│ • Name: Max Mustermann │
│ • Geburtsdatum: 15.03.1995 │
│ • Erstellt am: 01.11.2025 │
│ │
│ Exportiert am: 09.11.2025 15:30 │
└────────────────────────────────────────┘
```
- **Layout:** Schöne Übersicht mit Logos
- **IntelSight-Logo:** Oben links
- **Platform-Logo:** Bei Plattform-Angabe
- **Fallback:** Text-Only PDF wenn Logos nicht verfügbar
#### Mehrfach-Auswahl
- **CSV + TXT + PDF** gleichzeitig auswählbar
- Alle ausgewählten Formate werden in einem Vorgang exportiert
#### Dateinamen-Konvention
```
{username}_{plattform}_{exportdatum}.{format}
Beispiele:
waster_ha_948_instagram_2025-11-09_15-30.csv
waster_ha_948_instagram_2025-11-09_15-30.txt
waster_ha_948_instagram_2025-11-09_15-30.pdf
```
- **Datumsformat:** `YYYY-MM-DD_HH-mm`
- **Kleinschreibung:** Plattform-Name in Kleinbuchstaben
#### Passwortschutz
##### Automatische Passwort-Generierung
- **Aktivierung:** Optional per Checkbox im Export-Dialog
- **Länge:** 10 Zeichen
- **Zeichen:** Alphanumerisch + Sonderzeichen
- **Beispiel:** `Xy7#mK9@pL`
##### Passwort-Anzeige
Nach erfolgreichem Export wird Passwort angezeigt:
```
┌─ Export erfolgreich ──────────────────┐
│ │
│ ✓ Profil exportiert! │
│ │
│ Datei: │
│ waster_ha_948_instagram_2025-...zip │
│ │
│ 🔒 Passwort: Xy7#mK9@pL │
│ [Kopieren] │
│ │
│ ⚠ Bitte Passwort speichern! │
│ │
│ [Ordner öffnen] [OK] │
└────────────────────────────────────────┘
```
- **Kopieren-Button:** Kopiert Passwort in Zwischenablage
- **Warnung:** Nutzer wird aufgefordert, Passwort zu speichern
##### Verschlüsselung
**Mit Passwortschutz:**
- Alle ausgewählten Formate werden in **eine ZIP-Datei** gepackt
- ZIP-Datei wird mit generiertem Passwort verschlüsselt
- Dateiname: `{username}_{plattform}_{exportdatum}.zip`
- Enthält: CSV, TXT, PDF (je nach Auswahl)
**Ohne Passwortschutz:**
- Separate Dateien für jedes Format
- Keine ZIP-Datei
#### Export-Dialog
```
┌─ Profil exportieren ──────────────┐
│ │
│ Format (mehrfach auswählbar): │
│ ☑ CSV │
│ ☑ TXT │
│ ☐ PDF │
│ │
│ ☑ Mit Passwort schützen │
│ (Wird automatisch generiert) │
│ │
│ [Abbrechen] [Exportieren] │
└────────────────────────────────────┘
```
- **Mindestens ein Format** muss ausgewählt sein
- Bei Passwortschutz: Keine manuelle Passworteingabe
- Nach Klick auf "Exportieren": Save-Dialog öffnet sich
#### Speicherort
- **Nutzer wählt** Speicherort per Standard-Datei-Dialog
- **Kein Standard-Ordner** vordefiniert
- Letzte Auswahl wird **nicht** gespeichert
#### UI-Integration
- **Bestehender Button:** "Exportieren" im Accounts-Tab wird erweitert
- **Einzelexport:** Nur der aktuell ausgewählte Account
- **Kein Batch-Export:** Mehrfach-Export vorerst nicht implementiert
#### Erfolgs-Feedback
```
┌─ Export erfolgreich ──────────────────┐
│ │
│ ✓ Profil exportiert! │
│ │
│ Dateien: │
│ • waster_ha_948_instagram_2025-...csv │
│ • waster_ha_948_instagram_2025-...txt │
│ │
│ [MIT PASSWORT: Passwort-Anzeige] │
│ │
│ Gespeichert in: C:\Users\...\ │
│ │
│ [Ordner öffnen] [OK] │
└────────────────────────────────────────┘
```
- **Dateiliste:** Alle exportierten Dateien anzeigen
- **Ordner öffnen:** Button öffnet Zielordner im Explorer/Finder
- **Passwort:** Nur wenn Passwortschutz aktiviert wurde
#### Fehlerbehandlung
- **Export fehlgeschlagen:** Fehlermeldung mit Grund
- "Festplatte voll"
- "Keine Schreibrechte"
- "Datei bereits vorhanden und schreibgeschützt"
- **Logo nicht gefunden:** PDF-Export mit Text-Only Fallback
### Technische Umsetzung
#### Betroffene Module
- `views/tabs/accounts_tab.py` - Erweiterung Export-Button
- `views/dialogs/` - Neue Export-Dialogs
- `controllers/` - Export-Controller
- `utils/` - Export-Service für Format-Generierung
- `resources/icons/` - Platform-Logos für PDF
#### Abhängigkeiten
- **Python-Libraries:**
- `csv` - CSV-Export (Standard-Library)
- `reportlab` oder `fpdf` - PDF-Generierung
- `zipfile` - ZIP mit Passwortschutz (Standard-Library)
- `secrets` - Sichere Passwort-Generierung (Standard-Library)
#### Export-Service Struktur
```python
class ProfileExportService:
def export_to_csv(account_data) -> bytes
def export_to_txt(account_data) -> bytes
def export_to_pdf(account_data) -> bytes
def generate_password() -> str
def create_protected_zip(files, password) -> bytes
```
### Ausschlüsse
- **Kein Re-Import:** Import-Funktion wird NICHT implementiert
- **Kein Batch-Export:** Nur Einzelexport
- **Keine Verschlüsselung ohne Passwort:** Ungeschützte Dateien sind Plain-Text
---
## 📋 Weitere Features
### Feature 3: Server-seitige E-Mail/SMS-Abfrage
**Status:** Geplant
*Details folgen nach Abstimmung*
---
## 🔒 Feature 4: Privater Account erstellen
**Priorität:** Mittel
**Status:** Geplant
**Geschätzter Aufwand:** 3-4 Tage
### Beschreibung
Checkbox in der Account-Erstellungsmaske zum automatischen Setzen des Account-Privatsphäre-Modus auf "privat" während der Registrierung.
### Funktionale Anforderungen
#### Unterstützte Plattformen
- **Facebook** - Privacy Settings auf "Friends"
- **Instagram** - Private Account aktivieren
- **TikTok** - Private Account aktivieren
- **X/Twitter** - Protect your posts aktivieren
**NICHT unterstützt:**
- Gmail (keine Privatsphäre-Einstellung in diesem Sinne)
- VK, OK.ru (vorerst)
#### UI-Integration
**Checkbox in Account-Erstellungsmaske:**
```
┌─ Account erstellen (Instagram) ────┐
│ │
│ Vorname: [_______________] │
│ Nachname: [_______________] │
│ Alter: [___] │
│ │
│ ☐ Privaten Account erstellen │
│ │
│ Registrierungsmethode: │
│ ○ E-Mail ○ Telefon │
│ │
│ [Abbrechen] [Erstellen] │
└─────────────────────────────────────┘
```
- **Position:** Unterhalb der Basis-Daten (Name, Alter), oberhalb Registrierungsmethode
- **Standard:** Deaktiviert (nicht angehakt)
- **Sichtbarkeit:** Nur bei unterstützten Plattformen anzeigen
- **Label:** "Privaten Account erstellen"
#### Ablauf
**Wenn Checkbox aktiviert:**
```
1. Normale Account-Erstellung (wie bisher)
- Registrierung
- Profil-Daten eingeben
- Verifizierung abschließen
2. Account erfolgreich erstellt
3. Navigiere zu Privacy-Settings
4. Setze Account auf "privat"
- Instagram: Settings → Privacy → Private Account (Toggle ON)
- Facebook: Settings → Privacy → Who can see posts → Friends
- TikTok: Settings → Privacy → Private Account (Toggle ON)
- X: Settings → Privacy and Safety → Protect your posts (Toggle ON)
5. Zurück zum Hauptbildschirm
```
**Timing:** Als **Teil des Registrierungs-Flows**, direkt nach erfolgreicher Verifizierung, bevor "Account erstellt"-Dialog erscheint.
#### Erfolgs-/Fehler-Feedback
**Bei Erfolg:**
```
┌─ Account erstellt ────────────────┐
│ │
│ ✓ Account erstellt: waster_ha_948 │
│ ✓ Account auf privat gesetzt │
│ │
│ [OK] │
└────────────────────────────────────┘
```
**Bei Fehler:**
```
┌─ Account erstellt ────────────────┐
│ │
│ ✓ Account erstellt: waster_ha_948 │
│ │
│ ⚠ Account konnte nicht auf privat │
│ gesetzt werden │
│ │
│ Fehler: Timeout beim Laden der │
│ Privacy-Settings │
│ │
│ Bitte setzen Sie den Account │
│ manuell auf privat. │
│ │
│ [OK] │
└────────────────────────────────────┘
```
- **Kein Retry:** Keine "Erneut versuchen" Option
- **Account behalten:** Account wird auch bei Fehler gespeichert
- **Nutzer-Aktion:** Hinweis dass manuelles Setzen erforderlich ist
#### Keine Verifizierung
- **Keine Prüfung** ob Account tatsächlich privat ist
- Software versucht nur, Privacy-Setting zu setzen
- Bei Erfolg (kein Fehler) → Annehmen dass es funktioniert hat
### Technische Umsetzung
#### Betroffene Module
- `views/tabs/generator_tab_factory.py` - Checkbox hinzufügen
- `views/tabs/facebook_generator_tab.py` - Facebook-spezifische UI
- `views/tabs/instagram_generator_tab.py` - Instagram-spezifische UI (falls existent)
- `social_networks/facebook/facebook_workflow.py` - Privacy-Setting Flow
- `social_networks/instagram/instagram_workflow.py` - Privacy-Setting Flow
- `social_networks/tiktok/tiktok_workflow.py` - Privacy-Setting Flow
- `social_networks/x/x_workflow.py` - Privacy-Setting Flow
#### Implementierung pro Plattform
**Neue Methoden in Workflow-Klassen:**
```python
class FacebookWorkflow:
def set_privacy_to_private(self) -> bool:
"""
Setzt Facebook-Account auf privat (Friends only).
Returns:
True bei Erfolg, False bei Fehler
"""
try:
# 1. Navigiere zu Settings
# 2. Öffne Privacy-Bereich
# 3. Setze "Who can see posts" auf "Friends"
# 4. Speichern
return True
except Exception as e:
logger.error(f"Privacy-Setting fehlgeschlagen: {e}")
return False
```
**Analoger Code für Instagram, TikTok, X**
#### Workflow-Integration
**In Account-Creation Workflow:**
```python
# Nach erfolgreicher Verifizierung
if registration_successful:
# Account in DB speichern
save_account_to_db(account_data)
# Wenn "Privat"-Checkbox aktiviert war
if create_private_account:
try:
privacy_success = workflow.set_privacy_to_private()
if privacy_success:
return {
"success": True,
"message": "Account erstellt und auf privat gesetzt",
"privacy_set": True
}
else:
return {
"success": True,
"message": "Account erstellt, aber Privacy-Setting fehlgeschlagen",
"privacy_set": False,
"privacy_error": "Konnte nicht auf privat gesetzt werden"
}
except Exception as e:
return {
"success": True,
"message": "Account erstellt",
"privacy_set": False,
"privacy_error": str(e)
}
else:
return {
"success": True,
"message": "Account erstellt",
"privacy_set": None # Nicht versucht
}
```
#### Selektoren (pro Plattform neu)
**Neue Selector-Definitionen benötigt:**
- `facebook_selectors.py` - Privacy Settings Selektoren
- `instagram_selectors.py` - Privacy Settings Selektoren
- `tiktok_selectors.py` - Privacy Settings Selektoren
- `x_selectors.py` - Privacy Settings Selektoren
### Abhängigkeiten
- **Playwright/Browser-Automatisierung** muss Privacy-Settings-Seiten navigieren können
- **Plattform-spezifische Selektoren** müssen recherchiert und getestet werden
- **Zeitverzögerung:** Rechne mit +10-20 Sekunden pro Account-Erstellung
### Risiken & Bekannte Probleme
- **UI-Änderungen:** Wenn Plattformen Privacy-Settings-UI ändern, bricht Feature
- **Rate-Limiting:** Zusätzliche Aktionen könnten Rate-Limits schneller erreichen
- **A/B-Testing:** Manche Nutzer sehen andere UI-Varianten
- **Keine Garantie:** Auch bei "Erfolg" könnte Setting nicht gesetzt sein (keine Verifizierung)
### Ausschlüsse
- **Keine Verifizierung:** Wird nicht geprüft ob Account wirklich privat ist
- **Kein Retry:** Bei Fehler keine automatische Wiederholung
- **Keine Datenbank-Speicherung:** `is_private` Flag wird NICHT in DB gespeichert
- **Keine nachträgliche Änderung:** Funktion nur während Erstellung, nicht nachträglich änderbar
---
## 🛡️ Feature 5: Software Missbrauch Schutz
**Priorität:** Hoch
**Status:** ✅ Abgeschlossen (2025-11-10)
**Tatsächlicher Aufwand:** 2 Tage
### Beschreibung
Schutzmaßnahmen gegen versehentlichen oder absichtlichen Missbrauch der Software durch parallele Prozesse, zu viele Browser-Instanzen oder wiederholte Fehlversuche.
### Funktionale Anforderungen
#### 1. Process Lock Manager
**Zentrale Steuerung für alle Prozesse:**
- Nur **ein Vorgang gleichzeitig** erlaubt
- Gilt für: Account-Erstellung, Login, Export (alle Prozess-Typen)
- Plattform-übergreifend: Keine Instagram-Erstellung während Facebook-Login
**Verhalten:**
```
Situation: Instagram-Account wird erstellt
Nutzer versucht Facebook-Account zu erstellen
⚠️ Warnung: "Prozess läuft bereits"
"Bitte warten Sie bis 'Account-Erstellung (Instagram)'
abgeschlossen ist."
Buttons ausgegraut + Tooltip
```
**UI-Feedback:**
- Alle Prozess-Buttons werden **deaktiviert** (ausgegraut)
- Tooltip zeigt: "Warten Sie bis aktueller Vorgang abgeschlossen ist"
- Warnmeldung bei Klick-Versuch auf deaktivierten Button
**Crash-Sicherheit:**
- Bei Programm-Neustart: Lock wird **automatisch zurückgesetzt**
- Keine persistente Speicherung des Lock-Status
- Lock nur im Memory während Laufzeit
#### 2. Browser-Instanz Schutz
**Nur eine Playwright-Instanz gleichzeitig:**
- Verhindert mehrere Browser-Fenster parallel
- Ressourcen-Schonung (RAM, CPU)
- Vermeidet Konflikte zwischen Browser-Instanzen
**Implementierung:**
```python
class PlaywrightManager:
_active_browser_count = 0
_max_browsers = 1
def launch_browser(self):
if self._active_browser_count >= self._max_browsers:
raise Exception(
"Browser bereits aktiv. "
"Beenden Sie den aktuellen Prozess."
)
self._active_browser_count += 1
# ... Browser starten
def close_browser(self):
self._active_browser_count -= 1
```
**Fehlerbehandlung:**
- Bei Absturz: Browser-Counter wird beim Neustart zurückgesetzt
- Bei forciertem Schließen: Counter wird dekrementiert
#### 3. Fehler-Tracking mit Zwangspause
**Automatische Pause nach wiederholten Fehlschlägen:**
- Nach **3 fehlgeschlagenen** Account-Erstellungen **hintereinander**
- **Zwangspause von 1 Stunde** (nicht überspringbar)
- Verhindert Rate-Limiting und IP-Sperren
**Fehler-Zählung:**
```
Versuch 1: Instagram Account → Fehler ❌ (Zähler: 1)
Versuch 2: Facebook Account → Fehler ❌ (Zähler: 2)
Versuch 3: TikTok Account → Fehler ❌ (Zähler: 3)
🚫 ZWANGSPAUSE AKTIVIERT (1 Stunde)
```
**Reset-Bedingungen:**
- Bei **Erfolg**: Fehler-Zähler wird auf 0 zurückgesetzt
- Nach **Pause-Ende**: Fehler-Zähler wird auf 0 zurückgesetzt
- Bei **Programm-Neustart**: Fehler-Zähler wird NICHT zurückgesetzt (persistiert)
**UI während Zwangspause:**
```
┌─ Automatische Pause aktiv ────────┐
│ │
│ ⏸️ Zwangspause wegen Fehlerrate │
│ │
│ Nach 3 fehlgeschlagenen Versuchen │
│ ist eine Pause erforderlich. │
│ │
│ ⏰ Verbleibende Zeit: 47 Min │
│ │
│ Empfehlung: │
│ • Proxy-Einstellungen prüfen │
│ • Internetverbindung prüfen │
│ • Plattform-Status überprüfen │
│ │
│ [Schließen] │
└────────────────────────────────────┘
```
- **Countdown-Timer** zeigt verbleibende Zeit
- Alle Prozess-Buttons **deaktiviert**
- **Nicht überspringbar** - kein "Pause beenden" Button
- Persistiert über Programm-Neustarts (in Datei gespeichert)
**Persistierung:**
```json
// config/.error_tracking
{
"consecutive_failures": 3,
"pause_until": "2025-11-09T16:30:00",
"last_failure_platform": "Instagram",
"last_failure_reason": "Timeout bei Verifizierung"
}
```
### Technische Umsetzung
#### Process Lock Manager Klasse
```python
# utils/process_lock_manager.py
import time
from typing import Optional
from datetime import datetime
class ProcessLockManager:
"""
Zentrale Verwaltung für Prozess-Locks und Fehler-Tracking.
Singleton-Pattern für globalen Zugriff.
"""
_instance = None
_lock_active = False
_current_process = None
_current_platform = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
@classmethod
def start_process(cls, process_type: str, platform: str) -> bool:
"""
Versucht einen Prozess zu starten.
Args:
process_type: Art des Prozesses ("Account-Erstellung", "Login", etc.)
platform: Plattform (Instagram, Facebook, etc.)
Returns:
True wenn gestartet, False wenn blockiert
"""
if cls._lock_active:
return False
cls._lock_active = True
cls._current_process = process_type
cls._current_platform = platform
return True
@classmethod
def end_process(cls, success: bool = True):
"""
Beendet den aktuellen Prozess.
Args:
success: Ob Prozess erfolgreich war
"""
cls._lock_active = False
cls._current_process = None
cls._current_platform = None
# Fehler-Tracking aktualisieren
if success:
ErrorTracker.reset_failures()
else:
ErrorTracker.report_failure(cls._current_platform)
@classmethod
def is_locked(cls) -> bool:
"""Gibt zurück ob aktuell ein Prozess läuft"""
return cls._lock_active
@classmethod
def get_current_process_info(cls) -> Optional[dict]:
"""Gibt Info über aktuellen Prozess zurück"""
if not cls._lock_active:
return None
return {
"type": cls._current_process,
"platform": cls._current_platform
}
@classmethod
def force_unlock(cls, reason: str = "Manuell"):
"""
Entsperrt zwangsweise (nur bei Absturz).
Args:
reason: Grund für Force-Unlock
"""
logger.warning(f"Process Lock wurde entsperrt: {reason}")
cls._lock_active = False
cls._current_process = None
cls._current_platform = None
@classmethod
def reset_on_startup(cls):
"""Wird beim Programmstart aufgerufen"""
cls.force_unlock("Programm-Neustart")
```
#### Error Tracker Klasse
```python
# utils/error_tracker.py
import json
import os
from datetime import datetime, timedelta
from typing import Optional
class ErrorTracker:
"""Tracking von fehlgeschlagenen Prozessen mit Zwangspause."""
CONFIG_FILE = os.path.join("config", ".error_tracking")
MAX_FAILURES = 3
PAUSE_DURATION_HOURS = 1
_consecutive_failures = 0
_pause_until = None
@classmethod
def load_state(cls):
"""Lädt gespeicherten State beim Start"""
if not os.path.exists(cls.CONFIG_FILE):
return
try:
with open(cls.CONFIG_FILE, 'r') as f:
data = json.load(f)
cls._consecutive_failures = data.get('consecutive_failures', 0)
pause_until_str = data.get('pause_until')
if pause_until_str:
cls._pause_until = datetime.fromisoformat(pause_until_str)
# Prüfe ob Pause abgelaufen
if datetime.now() > cls._pause_until:
cls._pause_until = None
cls._consecutive_failures = 0
cls._save_state()
except Exception as e:
logger.error(f"Fehler beim Laden von Error Tracking: {e}")
@classmethod
def _save_state(cls):
"""Speichert aktuellen State"""
try:
os.makedirs(os.path.dirname(cls.CONFIG_FILE), exist_ok=True)
data = {
'consecutive_failures': cls._consecutive_failures,
'pause_until': cls._pause_until.isoformat() if cls._pause_until else None,
'last_update': datetime.now().isoformat()
}
with open(cls.CONFIG_FILE, 'w') as f:
json.dump(data, f, indent=2)
except Exception as e:
logger.error(f"Fehler beim Speichern von Error Tracking: {e}")
@classmethod
def report_failure(cls, platform: str):
"""
Meldet einen Fehlschlag.
Args:
platform: Plattform auf der Fehler auftrat
"""
cls._consecutive_failures += 1
logger.warning(f"Fehlschlag #{cls._consecutive_failures} auf {platform}")
if cls._consecutive_failures >= cls.MAX_FAILURES:
# Aktiviere Zwangspause
cls._pause_until = datetime.now() + timedelta(hours=cls.PAUSE_DURATION_HOURS)
logger.error(
f"Zwangspause aktiviert bis {cls._pause_until.strftime('%H:%M')} "
f"nach {cls.MAX_FAILURES} Fehlschlägen"
)
cls._save_state()
@classmethod
def reset_failures(cls):
"""Setzt Fehler-Zähler bei Erfolg zurück"""
if cls._consecutive_failures > 0:
logger.info("Fehler-Zähler zurückgesetzt nach Erfolg")
cls._consecutive_failures = 0
cls._save_state()
@classmethod
def is_paused(cls) -> bool:
"""Gibt zurück ob aktuell Zwangspause aktiv ist"""
if cls._pause_until is None:
return False
if datetime.now() > cls._pause_until:
# Pause ist abgelaufen
cls._pause_until = None
cls._consecutive_failures = 0
cls._save_state()
return False
return True
@classmethod
def get_pause_remaining_seconds(cls) -> Optional[int]:
"""Gibt verbleibende Sekunden der Pause zurück"""
if not cls.is_paused():
return None
remaining = (cls._pause_until - datetime.now()).total_seconds()
return max(0, int(remaining))
@classmethod
def get_pause_info(cls) -> Optional[dict]:
"""Gibt Info über aktive Pause zurück"""
if not cls.is_paused():
return None
remaining_seconds = cls.get_pause_remaining_seconds()
remaining_minutes = remaining_seconds // 60
return {
'active': True,
'remaining_seconds': remaining_seconds,
'remaining_minutes': remaining_minutes,
'pause_until': cls._pause_until.strftime('%H:%M'),
'consecutive_failures': cls._consecutive_failures
}
```
#### Integration in bestehenden Code
**In main.py beim Start:**
```python
# Beim Programmstart
ProcessLockManager.reset_on_startup()
ErrorTracker.load_state()
# Prüfe ob Pause aktiv
if ErrorTracker.is_paused():
pause_info = ErrorTracker.get_pause_info()
show_pause_dialog(pause_info)
```
**In allen Controller-Klassen:**
```python
# facebook_controller.py, instagram_controller.py, etc.
def create_account(self, account_data):
# 1. Prüfe Zwangspause
if ErrorTracker.is_paused():
pause_info = ErrorTracker.get_pause_info()
show_pause_warning(pause_info)
return
# 2. Prüfe Process Lock
if not ProcessLockManager.start_process("Account-Erstellung", "Instagram"):
current = ProcessLockManager.get_current_process_info()
show_warning(
"Prozess läuft bereits",
f"Bitte warten Sie bis '{current['type']} ({current['platform']})' "
f"abgeschlossen ist."
)
return
try:
# 3. Normaler Prozess
self.show_modal()
result = self._perform_account_creation(account_data)
# 4. Lock freigeben mit Erfolgs-Status
ProcessLockManager.end_process(success=result['success'])
return result
except Exception as e:
# Bei Fehler: Lock freigeben mit Fehler-Status
ProcessLockManager.end_process(success=False)
raise
```
**In Generator Tabs (UI):**
```python
# views/tabs/generator_tab.py
def update_ui_state(self):
"""Aktualisiert Button-Status basierend auf Locks"""
# Prüfe Zwangspause
is_paused = ErrorTracker.is_paused()
is_locked = ProcessLockManager.is_locked()
# Deaktiviere Buttons wenn Pause oder Lock aktiv
self.create_button.setEnabled(not is_paused and not is_locked)
# Tooltip setzen
if is_paused:
pause_info = ErrorTracker.get_pause_info()
tooltip = f"Zwangspause aktiv (noch {pause_info['remaining_minutes']} Min)"
elif is_locked:
current = ProcessLockManager.get_current_process_info()
tooltip = f"Warten Sie bis '{current['type']}' abgeschlossen ist"
else:
tooltip = "Account erstellen"
self.create_button.setToolTip(tooltip)
```
#### Betroffene Module
- `utils/process_lock_manager.py` - **NEU** - Zentrale Lock-Verwaltung
- `utils/error_tracker.py` - **NEU** - Fehler-Tracking mit Zwangspause
- `browser/playwright_manager.py` - Erweitern um Browser-Instanz-Zähler
- `controllers/*_controller.py` - Alle Controller integrieren Lock-Prüfung
- `views/tabs/generator_tab*.py` - UI-Updates für deaktivierte Buttons
- `views/dialogs/` - **NEU** - Pause-Warning Dialog
- `main.py` - Startup-Initialisierung
### Abhängigkeiten
- Bestehendes Modal-System (ProgressModal, AccountCreationModal, LoginProcessModal)
- Logging-System für Error-Tracking
- File-System für Persistierung (.error_tracking)
### Risiken & Edge Cases
- **Browser-Absturz:** Counter könnte falsch sein → Reset bei Neustart
- **Zwangspause zu streng:** Nutzer könnte frustriert sein → Klare Kommunikation wichtig
- **Lock bleibt hängen:** Failsafe-Timer (5 Min) im Modal verhindert dies
### Ausschlüsse
- **KEIN** Manual Override / Force-Unlock Button
- **KEIN** Cooldown zwischen Account-Erstellungen
- **KEINE** Plattform-spezifischen Rate-Limits
- **KEINE** Pause-Überspringen-Funktion
---
## 📋 Weitere Features
### Feature 3: Server-seitige E-Mail/SMS-Abfrage
**Status:** Geplant
*Details folgen nach Abstimmung*
---
**Letzte Aktualisierung:** 2025-11-09