watching now works

This commit is contained in:
2025-01-25 15:39:24 +01:00
parent 2793ae830a
commit 1fe2a21d0d
4 changed files with 78 additions and 48 deletions

View File

@@ -51,27 +51,32 @@ pub async fn get_achievement_data(client: &Client, app_id: u32, context: &Contex
let ini_data = steam::get_achievement_data_all_ini(&context.dirs);
let ini_game = ini_data.iter().find(|m| m.id == app_id)?;
for json_achievement in &game_data.game.available_game_stats.achievements {
let mut achievement = Achievement {
achieved: false,
max_progress: 0,
current_progress: 0,
unlock_time: 0,
description: json_achievement.description.clone(),
name: json_achievement.display_name.clone(),
hidden: if json_achievement.hidden == 1 {
true
} else if json_achievement.hidden == 0 {
false
} else {
panic!("Unexpected hidden value")
},
icon: json_achievement.icon.clone(),
icongray: json_achievement.icongray.clone(),
};
for ini_achievement in &ini_game.achievements {
if json_achievement.name == ini_achievement.name {
game.achievements.push(Achievement {
achieved: ini_achievement.achieved,
max_progress: ini_achievement.max_progress,
current_progress: ini_achievement.current_progress,
unlock_time: ini_achievement.unlock_time,
description: json_achievement.description.clone(),
name: json_achievement.display_name.clone(),
hidden: if json_achievement.hidden == 1 {
true
} else if json_achievement.hidden == 0 {
false
} else {
panic!("Unexpected hidden value")
},
icon: json_achievement.icon.clone(),
icongray: json_achievement.icongray.clone(),
});
}
achievement.achieved = ini_achievement.achieved;
achievement.max_progress = ini_achievement.max_progress;
achievement.current_progress = ini_achievement.current_progress;
achievement.unlock_time = ini_achievement.unlock_time;
}
}
game.achievements.push(achievement);
}
Some(game)
}

View File

@@ -13,9 +13,9 @@ async fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
if args.is_empty() {
ui::ui(games).unwrap();
} else if args.len() == 3 {
} else if args.len() == 1 {
match args[0].as_str() {
"-w" => watch::watch_file(&args[1], args[2].parse().unwrap(), &context, &mut games)
"-w" => watch::watch_file(&context, &mut games)
.await
.unwrap(),
_ => panic!("wrong arg"),

View File

@@ -14,10 +14,23 @@ pub fn get_game_name_file_cache(path: &str) -> Vec<App> {
.collect()
}
pub fn send_notification(game_name: &str, achievement_name: &str, achievement_description: Option<&str>, icon_path: Option<&str>) {
pub fn send_notification(
game_name: &str,
achievement_name: &str,
achievement_description: Option<&str>,
icon_path: Option<&str>,
) {
std::process::Command::new("notify-send")
.args(["-a", game_name, "-i", icon_path.unwrap_or(""), achievement_name, achievement_description.unwrap_or("")])
.args([
"-a",
game_name,
"-i",
icon_path.unwrap_or(""),
achievement_name,
achievement_description.unwrap_or(""),
])
.spawn()
.unwrap()
.wait()
.unwrap();
}

View File

@@ -4,26 +4,39 @@ use reqwest::Client;
use std::path::Path;
use std::sync::mpsc;
pub async fn watch_file(
path: &str,
app_id: u32,
context: &Context,
games: &mut Vec<Game>,
) -> Result<()> {
pub async fn watch_file(context: &Context, games: &mut Vec<Game>) -> Result<()> {
let (tx, rx) = mpsc::channel::<Result<Event>>();
let mut watcher = notify::recommended_watcher(tx)?;
watcher.watch(Path::new(path), RecursiveMode::NonRecursive)?;
let client = Client::new();
for res in rx {
for dir in &context.dirs {
watcher.watch(Path::new(dir), RecursiveMode::Recursive)?;
}
for res in &rx {
match res {
Ok(event) => {
println!("event: {:#?}", event);
// println!("event: {:#?}", event);
if let EventKind::Access(AccessKind::Close(notify::event::AccessMode::Write)) =
event.kind
{
check_for_new_achievement(&client, games, app_id, context).await;
assert_eq!(event.paths.len(), 1);
let path = &event.paths[0];
if path.file_name().unwrap() == "achievements.ini" {
println!("WATCHER: found achievement file change");
let app_id: u32 = path
.parent()
.unwrap()
.file_name()
.unwrap()
.to_str()
.unwrap()
.parse()
.unwrap();
println!("WATCHER: app id for change: {app_id}");
check_for_new_achievement(&client, games, app_id, context).await;
} else {
println!("\n\n####\nSome other file changed\n####\n\n");
}
}
}
Err(e) => panic!("watch error: {:?}", e),
@@ -44,7 +57,11 @@ async fn check_for_new_achievement(
.unwrap();
let old = games.iter().find(|m| m.app_id == app_id);
if let Some(old) = old {
assert_eq!(new.achievements.len(), old.achievements.len());
let indexes = compare_achievements(&new.achievements, &old.achievements);
if indexes.is_empty() {
println!("WATCHER: found no new achievements");
}
for i in indexes {
let new_achievement = &new.achievements[i];
println!("new achievement: {:#?}", new_achievement);
@@ -68,23 +85,18 @@ async fn check_for_new_achievement(
);
}
} else {
println!("\n\nWATCHER: did not find the game");
println!("WATCHER: did not find the game");
}
let u_old = games.iter_mut().find(|m| m.app_id == app_id).unwrap();
*u_old = new;
}
fn compare_achievements(new: &Vec<Achievement>, old: &Vec<Achievement>) -> Vec<usize> {
let mut indexes = Vec::new();
for (i, new_a) in new.iter().enumerate() {
if old
.iter()
.find(|m| m.name == new_a.name && !m.achieved && new_a.achieved)
.is_some()
{
println!("\n\nWATCHER: found new achievement {}", new_a.name);
indexes.push(i);
}
}
indexes
new.iter()
.map(|n| {
old.iter()
.position(|o| !o.achieved && n.achieved && o.name == n.name)
})
.flatten()
.collect()
}