Skip to content

Commit 7b6b808

Browse files
committed
Added startup question
1 parent 00d8707 commit 7b6b808

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ dependencies = [
3737
"PyYAML>=6.0.0",
3838
]
3939

40+
[project.optional-dependencies]
41+
windows = ["pywin32>=300"]
42+
4043
[project.urls]
4144
"Homepage" = "https://github.com/NtWriteCode/ssh-tunnel-manager"
4245
"Bug Tracker" = "https://github.com/NtWriteCode/ssh-tunnel-manager/issues"

ssh_tunnel_manager/gui.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from . import config
1717
from . import utils
18+
from . import startup_shortcut
1819

1920
# Find the directory of the script to locate the icon
2021
# This might need adjustment based on how the app is packaged
@@ -82,6 +83,9 @@ def __init__(self):
8283
# --- Apply Initial State ---
8384
self._update_ui_state()
8485
QTimer.singleShot(0, self._adjust_window_height)
86+
87+
# Check if we should ask about creating a shortcut
88+
QTimer.singleShot(100, lambda: startup_shortcut.check_and_ask_shortcut(self))
8589

8690
def _create_profile_section(self):
8791
profile_group = QGroupBox("Profile Management")
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import os
2+
import sys
3+
import platform
4+
import subprocess
5+
from pathlib import Path
6+
from typing import Optional
7+
from PyQt6.QtWidgets import QMessageBox
8+
from PyQt6.QtCore import Qt
9+
from .config import get_config_path, load_config, save_config
10+
11+
12+
def get_shortcut_preference() -> Optional[bool]:
13+
"""Get the saved preference for creating shortcuts."""
14+
config = load_config()
15+
return config.get("shortcut_created")
16+
17+
18+
def save_shortcut_preference(created: bool) -> None:
19+
"""Save the preference for creating shortcuts."""
20+
config = load_config()
21+
config["shortcut_created"] = created
22+
save_config(config)
23+
24+
25+
def create_windows_shortcut() -> bool:
26+
"""Create a Windows Start Menu shortcut."""
27+
try:
28+
import win32com.client
29+
30+
# Get the Start Menu path
31+
start_menu = Path(os.environ['APPDATA']) / "Microsoft" / "Windows" / "Start Menu" / "Programs"
32+
shortcut_path = start_menu / "SSH Tunnel Manager.lnk"
33+
34+
# Get the executable path
35+
if getattr(sys, 'frozen', False):
36+
# Running as compiled executable
37+
target_path = sys.executable
38+
else:
39+
# Running as Python script
40+
target_path = sys.executable
41+
arguments = f'"{sys.argv[0]}"'
42+
43+
# Create shortcut
44+
shell = win32com.client.Dispatch("WScript.Shell")
45+
shortcut = shell.CreateShortCut(str(shortcut_path))
46+
shortcut.TargetPath = target_path
47+
if not getattr(sys, 'frozen', False):
48+
shortcut.Arguments = arguments
49+
shortcut.WorkingDirectory = str(Path(target_path).parent)
50+
shortcut.IconLocation = target_path
51+
shortcut.Description = "SSH Tunnel Manager - Manage your SSH tunnels with ease"
52+
shortcut.save()
53+
54+
return True
55+
except Exception as e:
56+
print(f"Error creating Windows shortcut: {e}")
57+
return False
58+
59+
60+
def create_linux_desktop_entry() -> bool:
61+
"""Create a Linux desktop entry for the application launcher."""
62+
try:
63+
# Get the desktop entry path
64+
desktop_dir = Path.home() / ".local" / "share" / "applications"
65+
desktop_dir.mkdir(parents=True, exist_ok=True)
66+
desktop_file = desktop_dir / "ssh-tunnel-manager.desktop"
67+
68+
# Get the executable command
69+
if getattr(sys, 'frozen', False):
70+
# Running as compiled executable
71+
exec_command = sys.executable
72+
else:
73+
# Running as Python script - use the console script entry point
74+
exec_command = "ssh-tunnel-manager"
75+
76+
# Get icon path
77+
icon_path = Path(__file__).parent / "icon.ico"
78+
if not icon_path.exists():
79+
icon_path = "ssh-tunnel-manager" # Fallback to icon name
80+
81+
# Create desktop entry content
82+
desktop_content = f"""[Desktop Entry]
83+
Version=1.0
84+
Type=Application
85+
Name=SSH Tunnel Manager
86+
Comment=Manage your SSH tunnels with ease
87+
Exec={exec_command}
88+
Icon={icon_path}
89+
Terminal=false
90+
Categories=Network;Utility;
91+
StartupNotify=true
92+
"""
93+
94+
# Write desktop file
95+
desktop_file.write_text(desktop_content)
96+
97+
# Make it executable
98+
desktop_file.chmod(0o755)
99+
100+
# Update desktop database
101+
try:
102+
subprocess.run(["update-desktop-database", str(desktop_dir)],
103+
capture_output=True, check=False)
104+
except:
105+
pass # Not critical if this fails
106+
107+
return True
108+
except Exception as e:
109+
print(f"Error creating Linux desktop entry: {e}")
110+
return False
111+
112+
113+
def create_shortcut() -> bool:
114+
"""Create a shortcut based on the current platform."""
115+
system = platform.system()
116+
117+
if system == "Windows":
118+
return create_windows_shortcut()
119+
elif system == "Linux":
120+
return create_linux_desktop_entry()
121+
else:
122+
print(f"Unsupported platform: {system}")
123+
return False
124+
125+
126+
def check_and_ask_shortcut(parent=None) -> None:
127+
"""Check if we should ask about creating a shortcut and handle the response."""
128+
# Check if we've already asked
129+
preference = get_shortcut_preference()
130+
if preference is not None:
131+
# Already asked, don't ask again
132+
return
133+
134+
# Prepare the message based on platform
135+
system = platform.system()
136+
if system == "Windows":
137+
location = "Windows Start Menu"
138+
elif system == "Linux":
139+
location = "application launcher"
140+
else:
141+
# Unsupported platform, don't ask
142+
save_shortcut_preference(False)
143+
return
144+
145+
# Create and show the message box
146+
msg_box = QMessageBox(parent)
147+
msg_box.setWindowTitle("Create Shortcut")
148+
msg_box.setText(f"Would you like to add SSH Tunnel Manager to your {location}?")
149+
msg_box.setInformativeText("This will make it easier to launch the application in the future.")
150+
msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
151+
msg_box.setDefaultButton(QMessageBox.StandardButton.Yes)
152+
msg_box.setIcon(QMessageBox.Icon.Question)
153+
154+
# Show the dialog and get the response
155+
response = msg_box.exec()
156+
157+
if response == QMessageBox.StandardButton.Yes:
158+
# Try to create the shortcut
159+
success = create_shortcut()
160+
save_shortcut_preference(success)
161+
162+
if success:
163+
QMessageBox.information(
164+
parent,
165+
"Success",
166+
f"SSH Tunnel Manager has been added to your {location}!",
167+
QMessageBox.StandardButton.Ok
168+
)
169+
else:
170+
QMessageBox.warning(
171+
parent,
172+
"Error",
173+
"Failed to create the shortcut. You can try again later by running the application with administrator privileges.",
174+
QMessageBox.StandardButton.Ok
175+
)
176+
else:
177+
# User said no, save the preference
178+
save_shortcut_preference(False)

0 commit comments

Comments
 (0)