selftracker / main.py
Nakvi's picture
Upload 14 files
cd7bed1 verified
"""
FocusTrack - Main Entry Point
Starts the tracker service and optionally the dashboard.
"""
import sys
import os
import argparse
import threading
import subprocess
import logging
from pathlib import Path
# Add project root to path
ROOT = Path(__file__).parent
sys.path.insert(0, str(ROOT))
# ── Create required directories BEFORE logging setup ──────────────────────────
(ROOT / "logs").mkdir(exist_ok=True)
(ROOT / "data").mkdir(exist_ok=True)
from tracker import ActivityTracker
from database import Database
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
handlers=[
logging.FileHandler(ROOT / "logs" / "focustrack.log"),
logging.StreamHandler(),
],
)
logger = logging.getLogger("focustrack.main")
def start_dashboard():
"""Launch the Streamlit dashboard in a subprocess."""
ui_path = Path(__file__).parent / "app.py"
cmd = [sys.executable, "-m", "streamlit", "run", str(ui_path),
"--server.port", "8501",
"--server.headless", "true",
"--server.address", "localhost",
"--browser.gatherUsageStats", "false"]
logger.info("Starting FocusTrack Dashboard at http://localhost:8501")
proc = subprocess.Popen(cmd)
return proc
def start_tray(tracker: ActivityTracker):
"""Start system tray icon (optional, graceful fallback)."""
try:
from tray import TrayApp
tray = TrayApp(tracker)
tray.run()
except Exception as e:
logger.warning(f"System tray unavailable: {e}. Running headless.")
def main():
parser = argparse.ArgumentParser(description="FocusTrack - Local Activity Tracker")
parser.add_argument("--no-tray", action="store_true", help="Disable system tray")
parser.add_argument("--no-dashboard", action="store_true", help="Don't open browser dashboard")
parser.add_argument("--tracker-only", action="store_true", help="Run tracker without dashboard")
args = parser.parse_args()
# Initialize database
db = Database()
db.initialize()
logger.info("Database initialized")
# Start tracker
tracker = ActivityTracker(db)
tracker_thread = threading.Thread(target=tracker.run, daemon=True)
tracker_thread.start()
logger.info("Activity tracker started")
# Start dashboard
dashboard_proc = None
if not args.tracker_only and not args.no_dashboard:
dashboard_proc = start_dashboard()
# Start tray
if not args.no_tray:
tray_thread = threading.Thread(target=start_tray, args=(tracker,), daemon=True)
tray_thread.start()
logger.info("FocusTrack is running. Press Ctrl+C to stop.")
try:
tracker_thread.join()
except KeyboardInterrupt:
logger.info("Shutting down FocusTrack...")
tracker.stop()
if dashboard_proc:
dashboard_proc.terminate()
sys.exit(0)
if __name__ == "__main__":
main()