Files
2025-11-10 03:43:02 +01:00

33 KiB

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

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: Abgeschlossen (2025-11-10) Tatsächlicher Aufwand: 1 Tag

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
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

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:

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:

# 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:

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:

// 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

# 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

# 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:

# 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:

# 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):

# 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