Implement current changed files count in tray menu and abstract code into functions

This commit is contained in:
Robin Gottschalk 2025-02-03 08:20:22 +01:00
parent bf70e1b7f9
commit ef2cc1db23
3 changed files with 55 additions and 30 deletions

View File

@ -10,7 +10,9 @@ This script automates the process of backing up your Obsidian vault to a Git rep
- [x] Tray Menu
- [x] Exit
- [x] Backup now
- [ ] See current status (Time after last file change, backup in progress)
- [x] See current changed files
- [ ] See time after last file change
- [ ] Easy configuration of paths and delay
## Installation

View File

@ -31,7 +31,7 @@ pub fn backup_changes(repo_path: &Path) -> Result<(), Box<dyn std::error::Error>
}
// Print out all changes
println!("Detected changes:");
println!("Detected changes: {:?}", statuses.len());
for entry in statuses.iter() {
let path = entry.path().unwrap_or("<unknown>");
let status = entry.status();
@ -86,7 +86,7 @@ pub fn backup_changes(repo_path: &Path) -> Result<(), Box<dyn std::error::Error>
fn get_git_token() -> String {
// Get token from Windows Credential Manager
let service = "obsidian-git-backup";
let service = "obsidian-git-backup"; // git.obsidian-git-backup in Credetial Manager
let username = "git";
let entry = Entry::new(service, username).unwrap();
entry

View File

@ -2,7 +2,7 @@ use notify::{Event, RecursiveMode, Watcher};
use std::path::Path;
use std::time::{Duration, Instant};
use tray_icon::{
menu::{Menu, MenuId, MenuItem},
menu::{Menu, MenuItem},
Icon, TrayIconBuilder,
};
use winit::event::StartCause;
@ -15,8 +15,8 @@ use winit::{
mod filesync;
mod git;
const SOURCE_VAULT: &str = "X:\\test\\obsidian-vault-source"; // syncthing vault folder
const REPO_VAULT: &str = "X:\\test\\obsidian-vault-test"; // git repo folder
const SOURCE_VAULT: &str = "D:\\test\\obsidian-vault-source"; // syncthing vault folder
const REPO_VAULT: &str = "D:\\test\\obsidian-vault-test"; // git repo folder
#[derive(Debug)]
enum UserEvent {
@ -27,20 +27,23 @@ enum UserEvent {
#[derive(Default)]
struct App {
tray_icon: Option<tray_icon::TrayIcon>,
menu_backup_now_id: Option<MenuId>,
menu_exit_id: Option<MenuId>,
menu_changed_status: Option<MenuItem>,
menu_backup_now: Option<MenuItem>,
menu_exit: Option<MenuItem>,
last_change_time: Option<Instant>,
duration_threshold: Duration,
current_change_count: usize,
}
impl ApplicationHandler<UserEvent> for App {
fn resumed(&mut self, _event_loop: &ActiveEventLoop) {
impl App {
fn create_tray_icon_menu(&mut self) {
// Create and show the tray icon
let menu_item_changed_status = MenuItem::new("Changed: 0", true, None);
let menu_item_backup_now = MenuItem::new("Backup Now", true, None);
let menu_item_exit = MenuItem::new("Exit", true, None);
let tray_menu = Menu::new();
tray_menu.append(&menu_item_changed_status).unwrap();
tray_menu.append(&menu_item_backup_now).unwrap();
tray_menu.append(&menu_item_exit).unwrap();
@ -54,8 +57,41 @@ impl ApplicationHandler<UserEvent> for App {
.unwrap();
self.tray_icon = Some(tray_icon);
self.menu_backup_now_id = Some(menu_item_backup_now.id().clone());
self.menu_exit_id = Some(menu_item_exit.id().clone());
self.menu_changed_status = Some(menu_item_changed_status);
self.menu_backup_now = Some(menu_item_backup_now);
self.menu_exit = Some(menu_item_exit);
}
fn start_backup(&mut self) {
self.last_change_time = None;
let repo_dir = Path::new(REPO_VAULT);
git::backup_changes(repo_dir).expect("Changes could not be pushed");
self.current_change_count = 0;
self.menu_update_change_count();
}
fn process_file_event(&mut self) {
self.last_change_time = Some(Instant::now());
let source = Path::new(SOURCE_VAULT);
let target = Path::new(REPO_VAULT);
filesync::sync_directory(source, target, Some(".git"))
.expect("Directories could not be synced");
self.current_change_count =
git::current_change_count(target).expect("Changes could not get counted using git");
self.menu_update_change_count();
println!("Currently changed files: {:?}", self.current_change_count);
}
fn menu_update_change_count(&mut self) {
if let Some(menu_item) = &mut self.menu_changed_status {
menu_item.set_text(format!("Changed: {:?}", self.current_change_count));
}
}
}
impl ApplicationHandler<UserEvent> for App {
fn resumed(&mut self, _event_loop: &ActiveEventLoop) {
self.create_tray_icon_menu();
// Set the duration threshold (e.g., 5 minutes)
self.last_change_time = None;
@ -66,15 +102,12 @@ impl ApplicationHandler<UserEvent> for App {
match event {
UserEvent::MenuEvent(menu_event) => {
match menu_event.id() {
id if id == self.menu_backup_now_id.as_ref().unwrap() => {
id if id == self.menu_backup_now.as_ref().unwrap().id() => {
println!("---> Backup triggered by menu");
// Handle push now menu item
self.last_change_time = None;
let repo_dir = Path::new(REPO_VAULT);
git::backup_changes(repo_dir).expect("Changes could not be pushed");
self.current_change_count = 0;
self.start_backup();
}
id if id == self.menu_exit_id.as_ref().unwrap() => {
id if id == self.menu_exit.as_ref().unwrap().id() => {
println!("---> Exit triggert by menu");
// Handle exit menu item
event_loop.exit();
@ -84,14 +117,7 @@ impl ApplicationHandler<UserEvent> for App {
}
UserEvent::FileEvent(_event) => {
println!("---> File change detected");
self.last_change_time = Some(Instant::now());
let source = Path::new(SOURCE_VAULT);
let target = Path::new(REPO_VAULT);
filesync::sync_directory(source, target, Some(".git"))
.expect("Directories could not be synced");
self.current_change_count = git::current_change_count(target)
.expect("Changes could not get counted using git");
println!("Currently changed files: {:?}", self.current_change_count);
self.process_file_event();
}
}
}
@ -103,10 +129,7 @@ impl ApplicationHandler<UserEvent> for App {
if let Some(last_change_time) = self.last_change_time {
if now.duration_since(last_change_time) > self.duration_threshold {
println!("---> Backup triggered by file change");
self.last_change_time = None;
let repo_dir = Path::new(REPO_VAULT);
git::backup_changes(repo_dir).expect("Changes could not be pushed");
self.current_change_count = 0;
self.start_backup();
}
}