Add settings page, PIN manager, and auto-config
- New settings page at /settings (localhost-only) accessible via tray icon - PIN manager with 6-digit codes, 5-min TTL, single-use - API token uses secrets.token_urlsafe(32) for 256-bit entropy - Config auto-creates config.yaml on first run with detected local IP - Default PIN and token generated randomly on first startup - Added pin_ttl setting (default 300s) - Updated build_exe.py for onefile exe with settings assets bundled - Added start.bat and start.sh for easy development startup
This commit is contained in:
+35
-3
@@ -8,7 +8,10 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import multiprocessing
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
import pystray
|
||||
@@ -42,9 +45,9 @@ def _run_server() -> None:
|
||||
|
||||
uvicorn.run(
|
||||
"main:app",
|
||||
host="0.0.0.0",
|
||||
port=8921,
|
||||
log_level="info",
|
||||
host=CONFIG_HOST,
|
||||
port=CONFIG_PORT,
|
||||
log_level=CONFIG_LOG_LEVEL,
|
||||
reload=False,
|
||||
)
|
||||
|
||||
@@ -55,6 +58,21 @@ def _on_quit(icon: pystray.Icon, item: pystray.MenuItem) -> None:
|
||||
icon.stop()
|
||||
|
||||
|
||||
def _on_settings(icon: pystray.Icon, item: pystray.MenuItem) -> None:
|
||||
"""Open the settings page in the default browser."""
|
||||
logger.info("Opening settings page...")
|
||||
url = "http://127.0.0.1:8921/settings"
|
||||
try:
|
||||
if sys.platform == "win32":
|
||||
os.startfile(url)
|
||||
elif sys.platform == "darwin":
|
||||
subprocess.run(["open", url])
|
||||
else:
|
||||
subprocess.run(["xdg-open", url])
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to open settings page: {e}")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Entry point for the compiled .exe."""
|
||||
logger.info("PaperDash starting...")
|
||||
@@ -72,6 +90,8 @@ def main() -> None:
|
||||
menu = pystray.Menu(
|
||||
pystray.MenuItem("PaperDash", pystray.MenuItem.default, enabled=False),
|
||||
pystray.Menu.Separator(),
|
||||
pystray.MenuItem("Settings", _on_settings),
|
||||
pystray.Menu.Separator(),
|
||||
pystray.MenuItem("Quit", _on_quit),
|
||||
)
|
||||
|
||||
@@ -100,5 +120,17 @@ def main() -> None:
|
||||
server_process.join(timeout=5)
|
||||
|
||||
|
||||
def _load_config_values() -> tuple[str, int, str]:
|
||||
"""Load config and return (host, port, log_level) for the server."""
|
||||
from .config import config
|
||||
|
||||
config.load()
|
||||
return config.host or "127.0.0.1", config.port, config.log_level.lower()
|
||||
|
||||
|
||||
# Load config at module level so _run_server uses detected values
|
||||
CONFIG_HOST, CONFIG_PORT, CONFIG_LOG_LEVEL = _load_config_values()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user