Compare commits
3 Commits
c85f51b205
...
bd2b87fd51
| Author | SHA1 | Date | |
|---|---|---|---|
| bd2b87fd51 | |||
| 4f27c895fd | |||
| e1f8ee95da |
131
gemini.md
131
gemini.md
@@ -78,9 +78,6 @@ Example notification:
|
||||
```
|
||||
Git Monitor
|
||||
modify: program.nc committed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Logging
|
||||
|
||||
@@ -346,112 +343,64 @@ Example:
|
||||
}
|
||||
```
|
||||
|
||||
# Project Status: Completed
|
||||
|
||||
The application is fully implemented and tested for Windows 11 background operation.
|
||||
|
||||
---
|
||||
|
||||
# Packaging
|
||||
# Current Architecture (Finalized)
|
||||
|
||||
The application must be packaged using **PyInstaller**.
|
||||
|
||||
Requirements:
|
||||
|
||||
* single executable
|
||||
* no console window
|
||||
|
||||
Example build command:
|
||||
The project is structured as a proper Python package to ensure compatibility with PyInstaller and robust path handling.
|
||||
|
||||
```
|
||||
pyinstaller --onefile --noconsole main.py
|
||||
auto-git/
|
||||
├── run.py # Main entry point for Python/PyInstaller
|
||||
├── git_monitor/ # Main package
|
||||
│ ├── __init__.py # Package marker
|
||||
│ ├── main.py # Application lifecycle
|
||||
│ ├── tray_app.py # System tray (pystray) + UI (tkinter)
|
||||
│ ├── git_manager.py # Git operations (GitPython)
|
||||
│ ├── file_watcher.py # Filesystem monitoring (watchdog)
|
||||
│ ├── notifier.py # Windows notifications (plyer + win10toast fallback)
|
||||
│ ├── config.py # Persistent configuration (config.json)
|
||||
│ ├── logger.py # Application logging (git_monitor.log)
|
||||
│ └── requirements.txt # Dependency list
|
||||
└── .gitignore # Project ignore rules
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Error Handling
|
||||
# Implemented Solutions & Fixes
|
||||
|
||||
The application must gracefully handle:
|
||||
### 1. UI Responsive Fix (Windows 11)
|
||||
To prevent the application from freezing during folder selection:
|
||||
* **Threading**: `pystray` runs in a separate background thread.
|
||||
* **Main Loop**: `tkinter.mainloop()` runs in the main thread to handle system dialogs properly.
|
||||
* **Non-blocking Dialogs**: Folder selection is scheduled via `root.after(0, ...)` to ensure it doesn't block the tray icon.
|
||||
|
||||
* invalid repository path
|
||||
* git errors
|
||||
* filesystem watcher errors
|
||||
* missing permissions
|
||||
|
||||
Errors must:
|
||||
|
||||
* be logged
|
||||
* generate a Windows notification
|
||||
### 2. PyInstaller Compatibility
|
||||
* **Package Imports**: All internal imports use absolute paths (e.g., `from git_monitor.logger import ...`).
|
||||
* **Path Management**: `logger.py` and `config.py` use `sys.frozen` detection to ensure data files are always located relative to the `.exe` file, not temporary directories.
|
||||
* **Notification Robustness**: Added a fallback mechanism in `notifier.py`. If `plyer` fails to find a platform implementation (common in isolated environments), it automatically switches to `win10toast`.
|
||||
|
||||
---
|
||||
|
||||
# Performance Considerations
|
||||
# Build Instructions
|
||||
|
||||
The application should:
|
||||
To generate the standalone executable, use the following command from the project root:
|
||||
|
||||
* avoid duplicate commits for rapid file changes
|
||||
* debounce filesystem events if necessary
|
||||
* run with minimal CPU usage
|
||||
|
||||
---
|
||||
|
||||
# Recommended Python Libraries
|
||||
|
||||
```
|
||||
watchdog
|
||||
GitPython
|
||||
pystray
|
||||
pillow
|
||||
win10toast
|
||||
```powershell
|
||||
pyinstaller.exe --onefile --noconsole --name git-monitor --hidden-import="plyer.platforms.win.notification" run.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Example Workflow
|
||||
|
||||
1. Application starts
|
||||
2. Tray icon appears
|
||||
3. User selects repository
|
||||
4. Monitoring begins
|
||||
5. User edits a file
|
||||
6. File watcher detects modification
|
||||
7. GitManager stages file
|
||||
8. Commit created automatically
|
||||
9. Notification appears
|
||||
10. Event logged
|
||||
### Build Parameters:
|
||||
* `--onefile`: Packages everything into a single `.exe`.
|
||||
* `--noconsole`: Hides the command prompt window during execution.
|
||||
* `--hidden-import`: Manually includes the dynamic notification module for Windows.
|
||||
|
||||
---
|
||||
|
||||
# Future Improvements
|
||||
|
||||
Possible future features:
|
||||
|
||||
* commit batching
|
||||
* ignore patterns (.gitignore support)
|
||||
* commit history viewer
|
||||
* push to remote repository
|
||||
* repository auto-detection
|
||||
* configuration GUI
|
||||
* multiple repository support
|
||||
|
||||
---
|
||||
|
||||
# Coding Style
|
||||
|
||||
Requirements:
|
||||
|
||||
* Python 3.11+
|
||||
* object-oriented design
|
||||
* clear class responsibilities
|
||||
* structured logging
|
||||
* minimal global state
|
||||
|
||||
---
|
||||
|
||||
# Summary
|
||||
|
||||
The goal is to create a **lightweight background Windows application** that automatically commits changes in a Git repository without requiring the user to interact with Git.
|
||||
|
||||
The system should be:
|
||||
|
||||
* stable
|
||||
* silent
|
||||
* automatic
|
||||
* easy to deploy (single EXE)
|
||||
* minimal UI (tray only)
|
||||
# Runtime Files
|
||||
* **Log File**: `git_monitor.log` (created in the same folder as the `.exe`).
|
||||
* **Config File**: `config.json` (created in the same folder as the `.exe`).
|
||||
|
||||
@@ -4,23 +4,42 @@ try:
|
||||
from plyer import notification
|
||||
PLYER_AVAILABLE = True
|
||||
except ImportError:
|
||||
logger.warning("plyer not found. Notifications will be printed to stdout.")
|
||||
logger.warning("plyer not found. Will try win10toast.")
|
||||
PLYER_AVAILABLE = False
|
||||
|
||||
try:
|
||||
from win10toast import ToastNotifier
|
||||
WIN10TOAST_AVAILABLE = True
|
||||
toaster = ToastNotifier()
|
||||
except ImportError:
|
||||
WIN10TOAST_AVAILABLE = False
|
||||
|
||||
class Notifier:
|
||||
def notify(self, title, message):
|
||||
logger.info(f"Notification: {title} - {message}")
|
||||
|
||||
# Try plyer first
|
||||
if PLYER_AVAILABLE:
|
||||
try:
|
||||
notification.notify(
|
||||
title=title,
|
||||
message=message,
|
||||
app_name="Git Monitor",
|
||||
# timeout=10
|
||||
app_name="Git Monitor"
|
||||
)
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error(f"Error showing notification: {e}")
|
||||
else:
|
||||
print(f"[{title}] {message}")
|
||||
logger.error(f"Plyer notification failed: {e}. Trying fallback...")
|
||||
|
||||
# Fallback to win10toast
|
||||
if WIN10TOAST_AVAILABLE:
|
||||
try:
|
||||
# threaded=True prevents blocking the app
|
||||
toaster.show_toast(title, message, duration=5, threaded=True)
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error(f"win10toast notification failed: {e}")
|
||||
|
||||
# Final fallback to stdout
|
||||
print(f"[{title}] {message}")
|
||||
|
||||
notifier = Notifier()
|
||||
|
||||
Reference in New Issue
Block a user