105 lines
3.5 KiB
Python
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 git_monitor.logger import logger
|
|
from git_monitor.config import config
|
|
from git_monitor.git_manager import git_manager
|
|
from git_monitor.file_watcher import RepositoryWatcher
|
|
from git_monitor.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()
|