-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.py
More file actions
148 lines (121 loc) · 4.67 KB
/
Copy pathmain.py
File metadata and controls
148 lines (121 loc) · 4.67 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
"""
Main entry point for the Blink application.
Initializes the application components and starts the hotkey listener.
"""
import sys
from PyQt6.QtWidgets import QApplication
from src.text_capturer import TextCapturer
from src.llm_interface import LLMInterface
from src.overlay_ui import OverlayUI
from src.hotkey_manager import HotkeyManager
from src.config_manager import ConfigManager
from src.system_tray import SystemTrayManager
from src.settings_dialog import SettingsDialog
from src.history_manager import get_conversation_history
from src.first_run_wizard import run_first_run_wizard
# Import modules that PyInstaller might miss
try:
import psutil
except ImportError:
psutil = None
# Ensure pywin32 modules are bundled and available at runtime
try:
import pywintypes
import pythoncom
import win32clipboard
import win32gui
import win32api
import win32con
except ImportError:
pass # Will fail later if truly missing
def main() -> None:
"""
Main function to start the Blink application.
"""
# Check for existing instance
import os
lock_file = os.path.join(os.path.dirname(sys.executable) if getattr(sys, 'frozen', False) else os.getcwd(), 'blink.lock')
if os.path.exists(lock_file):
try:
with open(lock_file, 'r') as f:
pid = int(f.read().strip())
# Check if process is still running
import psutil
if psutil.pid_exists(pid):
print("Another instance of Blink is already running.")
return
except (ValueError, psutil.NoSuchProcess, psutil.AccessDenied):
pass # Lock file is stale, continue
# Create lock file with current PID
try:
with open(lock_file, 'w') as f:
f.write(str(os.getpid()))
except Exception:
pass # Ignore if we can't create lock file
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False) # Keep app running even when windows close
# Initialize config manager
config_manager = ConfigManager()
# Run first-run wizard if needed
if not run_first_run_wizard(config_manager):
print("First-run setup cancelled. Exiting.")
return
# Initialize components
text_capturer = TextCapturer()
llm_interface = LLMInterface(config_manager=config_manager)
overlay_ui = OverlayUI()
# Load saved model selection
selected_model = config_manager.get("selected_model", "ollama:llama3.2:latest")
llm_interface.set_selected_model(selected_model)
# Initialize system tray
system_tray = SystemTrayManager(app, config_manager)
# Connect system tray signals
def show_settings():
settings_dialog = SettingsDialog(config_manager, llm_interface, overlay_ui)
settings_dialog.exec()
def quit_app():
print("Quit requested")
app.quit()
def restart_application():
"""Restarts the application by saving history and relaunching."""
try:
# Save history before restart
history_manager = get_conversation_history(config_manager)
history_manager.save_history()
# Relaunch the executable and quit current instance
import sys, os
os.startfile(sys.executable) # Re-launches the .exe
import subprocess
if getattr(sys, "frozen", False):
os.startfile(sys.executable) # Re-Launch the .exe
else:
# Re-launch script if running from the source code
subprocess.Popen([sys.executable , sys.argv[0]])
app.quit() # Closes the current instance
except Exception as e:
print(f"Error during restart: {e}")
system_tray.settings_requested.connect(show_settings)
system_tray.quit_requested.connect(quit_app)
system_tray.restart_requested.connect(restart_application)
# Initialize hotkey manager with system tray reference
hotkey_manager = HotkeyManager(text_capturer, llm_interface, overlay_ui, config_manager, system_tray)
# Start the hotkey listener
hotkey_manager.start()
# Connect application shutdown to save history and cleanup
def save_history_on_quit():
try:
history_manager = get_conversation_history(config_manager)
history_manager.save_history()
except Exception as e:
print(f"Warning: Could not save history on shutdown: {e}")
# Clean up lock file
try:
if os.path.exists(lock_file):
os.remove(lock_file)
except Exception:
pass
app.aboutToQuit.connect(save_history_on_quit)
# Run the Qt event loop
sys.exit(app.exec())
if __name__ == "__main__":
main()