Files
auto-git/git_monitor/tray_app.py

105 lines
3.5 KiB
Python

import os
import threading
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageDraw
import pystray
from pystray import MenuItem as item
from logger import logger
from config import config
from git_manager import git_manager
from file_watcher import RepositoryWatcher
from notifier import notifier
class TrayApp:
def __init__(self):
self.icon = None
self.watcher = None
self.root = tk.Tk()
self.root.withdraw() # Hide main tkinter window
# Load last used repo if exists
last_repo = config.repository_path
if last_repo:
if git_manager.load_repository(last_repo):
self.start_monitoring(last_repo)
def create_icon(self):
# Create a simple icon
width = 64
height = 64
image = Image.new('RGB', (width, height), color=(73, 109, 137))
dc = ImageDraw.Draw(image)
dc.rectangle([width // 4, height // 4, width * 3 // 4, height * 3 // 4], fill=(255, 255, 255))
menu = (
item('Git Monitor', lambda: None, enabled=False),
pystray.Menu.SEPARATOR,
item('Select Repository', self.select_repository),
item('Exit', self.exit_app),
)
self.icon = pystray.Icon("GitMonitor", image, "Git Monitor", menu)
def select_repository(self, icon=None, item=None):
logger.info("Opening folder selection dialog...")
# Use a temporary function to run in a way that doesn't block
def ask_folder():
try:
# Ensure the root window is focused and on top
self.root.deiconify()
self.root.attributes("-topmost", True)
repo_path = filedialog.askdirectory(
parent=self.root,
title="Select Git Repository Folder"
)
self.root.withdraw()
if repo_path:
logger.info(f"User selected repository: {repo_path}")
if git_manager.load_repository(repo_path):
config.repository_path = repo_path
self.start_monitoring(repo_path)
else:
logger.info("Folder selection cancelled by user.")
except Exception as e:
logger.error(f"Error in folder selection: {e}")
# Schedule the dialog to run
self.root.after(0, ask_folder)
def start_monitoring(self, path):
if self.watcher:
self.stop_monitoring()
self.watcher = RepositoryWatcher(path)
self.watcher.start()
notifier.notify("Git Monitor", f"Started monitoring: {os.path.basename(path)}")
def stop_monitoring(self):
if self.watcher:
self.watcher.stop()
self.watcher = None
notifier.notify("Git Monitor", "Stopped monitoring")
def exit_app(self, icon=None, item=None):
logger.info("Exiting application...")
self.stop_monitoring()
if self.icon:
self.icon.stop()
self.root.quit()
os._exit(0) # Ensure all threads terminate
def run(self):
self.create_icon()
# Run pystray in a separate thread
threading.Thread(target=self.icon.run, daemon=True).start()
# Keep the main thread for tkinter mainloop to handle dialogs
self.root.mainloop()
if __name__ == "__main__":
app = TrayApp()
app.run()