-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
171 lines (148 loc) · 6.39 KB
/
Copy pathmain.py
File metadata and controls
171 lines (148 loc) · 6.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
"""
ASTRA AI - Haupteinstieg
========================
Main entry point für die Anwendung
Mit Crash-Recovery und Error-Handling
"""
import sys
import os
import traceback
from pathlib import Path
# Stelle sicher, dass wir im richtigen Verzeichnis sind
os.chdir(Path(__file__).parent)
def safe_init_database():
"""Sicheres Initialisieren der Datenbank mit Recovery"""
try:
from modules.database import Database
db = Database()
# Test Database-Integrität über die bestehende Connection (kein zweiter SQLite-Handle!)
try:
with db._db_lock:
conn = db._get_connection()
cursor = conn.cursor()
cursor.execute("PRAGMA integrity_check;")
result = cursor.fetchone()
if result[0] != "ok":
print(f"⚠️ Database integrity issue detected: {result[0]}")
print(" Versuche zu reparieren...")
except Exception as integrity_err:
print(f"⚠️ Integrity-Check fehlgeschlagen: {integrity_err}")
return db
except Exception as e:
print(f"❌ Kritischer Database-Fehler: {e}")
print(" Bitte überprüfen Sie die astra.db Datei")
raise
try:
from PyQt6.QtWidgets import QApplication, QMessageBox
from modules.ui import ChatWindow
from modules.ollama_client import OllamaClient
from config import OLLAMA_HOST
from modules.logger import log_error, log_info
def main():
"""Startet die ASTRA-Anwendung mit Crash-Recovery"""
try:
# ⚡ Windows: Eigene AppUserModelID setzen
# Damit zeigt die Taskbar das ASTRA-Icon statt das Python-Icon
try:
import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("astra.ai.desktop.v2")
except Exception:
pass # Nicht-Windows oder fehlende Rechte — ignorieren
# PyQt6 App erstellen
app = QApplication(sys.argv)
# App-Icon global setzen (für Taskbar, Alt+Tab, etc.)
from PyQt6.QtGui import QIcon
icon_path = Path(__file__).parent / "assets" / "astra_icon.ico"
if icon_path.exists():
app.setWindowIcon(QIcon(str(icon_path)))
# Sichere Database-Initialisierung
try:
db = safe_init_database()
log_info("Database initialisiert", "STARTUP")
except Exception as e:
log_error(f"Database-Init fehlgeschlagen: {e}", "STARTUP", e)
QMessageBox.critical(
None,
"❌ Kritischer Fehler",
f"Datenbank konnte nicht initialisiert werden:\n\n{str(e)}\n\n"
"Bitte versuchen Sie die Anwendung später erneut zu starten."
)
return 1
# ⚡ GPU erkennen & Ollama konfigurieren
from modules.gpu_detect import configure_ollama_gpu
gpu_info = configure_ollama_gpu()
print(f"🎮 GPU: {gpu_info.summary()}")
log_info(f"GPU erkannt: {gpu_info.summary()}", "STARTUP")
# Prüfe Ollama-Verbindung
print("🔍 Prüfe Ollama-Verbindung...")
ollama = OllamaClient(OLLAMA_HOST)
if not ollama.is_alive():
print(f"❌ Ollama nicht erreichbar unter {OLLAMA_HOST}")
# Zeige Fehlerdialog
msg_box = QMessageBox()
msg_box.setWindowTitle("🔴 Ollama nicht erreichbar")
msg_box.setText(
f"Ollama läuft nicht auf {OLLAMA_HOST}\n\n"
"Bitte starten Sie Ollama mit:\n"
" ollama serve\n\n"
"Die Anwendung wird trotzdem gestartet, "
"aber Sie können keine KI-Anfragen senden."
)
msg_box.setIcon(QMessageBox.Icon.Warning)
msg_box.exec()
else:
print("✅ Ollama erreichbar")
models = ollama.get_available_models()
if models:
print(f"✅ Verfügbare Modelle: {', '.join(models)}")
else:
print("⚠️ Keine Modelle verfügbar. Bitte laden Sie ein Modell mit:")
print(" ollama pull qwen2.5:14b")
# Starte Hauptfenster
print("🚀 Starte ASTRA AI...")
log_info("Starte ChatWindow", "STARTUP")
window = ChatWindow(db=db)
window._gpu_info = gpu_info # GPU-Info für Statusanzeige
window.show()
log_info("Anwendung erfolgreich gestartet", "STARTUP")
return app.exec()
except Exception as e:
# Unerwarteter Fehler
error_msg = f"Unerwarteter Fehler:\n\n{str(e)}\n\n{traceback.format_exc()}"
log_error(error_msg, "STARTUP", e)
# Versuche Dialog zu zeigen
try:
msg_box = QMessageBox()
msg_box.setWindowTitle("❌ Kritischer Fehler")
msg_box.setText(
f"Anwendung ist abgestürzt:\n\n{str(e)}\n\n"
"Siehe Logdatei für Details."
)
msg_box.setIcon(QMessageBox.Icon.Critical)
msg_box.exec()
except Exception:
print(error_msg)
return 1
if __name__ == "__main__":
try:
exit_code = main()
sys.exit(exit_code)
except KeyboardInterrupt:
print("\n\n[SHUTDOWN] Benutzer hat Anwendung beendet")
log_info("Anwendung durch Benutzer beendet", "SHUTDOWN")
sys.exit(0)
except Exception as e:
print(f"\n[FATAL] Kritischer Fehler beim Starten: {e}")
traceback.print_exc()
log_error(f"Kritischer Fehler: {e}", "FATAL", e)
sys.exit(1)
except ImportError as e:
print(f"❌ Fehler beim Import: {e}")
print("\nBitte installieren Sie die Abhängigkeiten:")
print(" pip install -r requirements.txt")
sys.exit(1)
except Exception as e:
print(f"❌ Fehler beim Starten: {e}")
import traceback
traceback.print_exc()
sys.exit(1)