Implement file change watching and tray menu to trigger backup
This commit is contained in:
commit
dc557ec780
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
2940
Cargo.lock
generated
Normal file
2940
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "obsidian-git-backup"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
winit = "0.30.8"
|
||||||
|
notify = "8.0.0"
|
||||||
|
tray-icon = "0.19.2"
|
||||||
|
git2 = "0.20.0"
|
||||||
134
src/main.rs
Normal file
134
src/main.rs
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
use notify::{Event, RecursiveMode, Watcher};
|
||||||
|
use std::path::Path;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
use tray_icon::{
|
||||||
|
menu::{Menu, MenuId, MenuItem},
|
||||||
|
Icon, TrayIconBuilder,
|
||||||
|
};
|
||||||
|
use winit::event::StartCause;
|
||||||
|
use winit::{
|
||||||
|
application::ApplicationHandler,
|
||||||
|
event::WindowEvent,
|
||||||
|
event_loop::{ActiveEventLoop, ControlFlow, EventLoop},
|
||||||
|
};
|
||||||
|
|
||||||
|
enum UserEvent {
|
||||||
|
MenuEvent(tray_icon::menu::MenuEvent),
|
||||||
|
FileEvent(Event),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct App {
|
||||||
|
tray_icon: Option<tray_icon::TrayIcon>,
|
||||||
|
menu_push_now_id: Option<MenuId>,
|
||||||
|
menu_exit_id: Option<MenuId>,
|
||||||
|
last_change_time: Option<Instant>,
|
||||||
|
duration_threshold: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApplicationHandler<UserEvent> for App {
|
||||||
|
fn resumed(&mut self, _event_loop: &ActiveEventLoop) {
|
||||||
|
// Create and show the tray icon
|
||||||
|
let menu_item_push_now = MenuItem::new("Push Now", true, None);
|
||||||
|
let menu_item_exit = MenuItem::new("Exit", true, None);
|
||||||
|
|
||||||
|
let tray_menu = Menu::new();
|
||||||
|
tray_menu.append(&menu_item_push_now).unwrap();
|
||||||
|
tray_menu.append(&menu_item_exit).unwrap();
|
||||||
|
|
||||||
|
let icon_path = Path::new("D:/Dev/obsidian-git-backup/sync.ico");
|
||||||
|
let icon = Icon::from_path(icon_path, None).unwrap();
|
||||||
|
let tray_icon = TrayIconBuilder::new()
|
||||||
|
.with_menu(Box::new(tray_menu))
|
||||||
|
.with_tooltip("Obsidian Git Backup")
|
||||||
|
.with_icon(icon)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
self.tray_icon = Some(tray_icon);
|
||||||
|
self.menu_push_now_id = Some(menu_item_push_now.id().clone());
|
||||||
|
self.menu_exit_id = Some(menu_item_exit.id().clone());
|
||||||
|
|
||||||
|
// Set the duration threshold (e.g., 5 minutes)
|
||||||
|
self.last_change_time = None;
|
||||||
|
self.duration_threshold = Duration::from_secs(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn user_event(&mut self, event_loop: &ActiveEventLoop, event: UserEvent) {
|
||||||
|
match event {
|
||||||
|
UserEvent::MenuEvent(menu_event) => {
|
||||||
|
match menu_event.id() {
|
||||||
|
id if id == self.menu_push_now_id.as_ref().unwrap() => {
|
||||||
|
// Handle push now menu item
|
||||||
|
self.last_change_time = None;
|
||||||
|
backup_changes();
|
||||||
|
}
|
||||||
|
id if id == self.menu_exit_id.as_ref().unwrap() => {
|
||||||
|
// Handle exit menu item
|
||||||
|
event_loop.exit();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UserEvent::FileEvent(_event) => {
|
||||||
|
println!("File change detected");
|
||||||
|
self.last_change_time = Some(Instant::now());
|
||||||
|
println!("At: {:?}", self.last_change_time.unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_events(&mut self, event_loop: &ActiveEventLoop, _cause: StartCause) {
|
||||||
|
let now = Instant::now();
|
||||||
|
|
||||||
|
// Backup changes if last file change time exceeded threshold
|
||||||
|
if let Some(last_change_time) = self.last_change_time {
|
||||||
|
if now.duration_since(last_change_time) > self.duration_threshold {
|
||||||
|
self.last_change_time = None;
|
||||||
|
backup_changes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset timer
|
||||||
|
event_loop.set_control_flow(ControlFlow::WaitUntil(now + Duration::from_secs(5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn window_event(
|
||||||
|
&mut self,
|
||||||
|
_event_loop: &ActiveEventLoop,
|
||||||
|
_window_id: winit::window::WindowId,
|
||||||
|
_event: WindowEvent,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn backup_changes() {
|
||||||
|
println!("Backup changes started");
|
||||||
|
println!("Checking for changes...");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let event_loop = EventLoop::<UserEvent>::with_user_event().build().unwrap();
|
||||||
|
event_loop.set_control_flow(ControlFlow::Wait);
|
||||||
|
|
||||||
|
// Set up menu event handler
|
||||||
|
let proxy = event_loop.create_proxy();
|
||||||
|
tray_icon::menu::MenuEvent::set_event_handler(Some(move |event| {
|
||||||
|
let _ = proxy.send_event(UserEvent::MenuEvent(event));
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Set up file change event handler
|
||||||
|
let proxy = event_loop.create_proxy();
|
||||||
|
let repo_path = Path::new("D:/test/obsidian-vault-test");
|
||||||
|
let mut watcher = notify::recommended_watcher(move |event| {
|
||||||
|
if let Ok(event) = event {
|
||||||
|
let _ = proxy.send_event(UserEvent::FileEvent(event));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
watcher.watch(repo_path, RecursiveMode::Recursive).unwrap();
|
||||||
|
|
||||||
|
// Start event loop
|
||||||
|
let mut app = App::default();
|
||||||
|
let _ = event_loop.run_app(&mut app);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user