diff --git a/Cargo.toml b/Cargo.toml index 8197f5d..13c6772 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,11 @@ nom = "^7.0.*" nom_locate = "^3.0.*" flate2 = "^1.0.22" toml = { version = "^0.5.8", optional = true } -futures = {version="*", optional=true} +futures = { version = "*", optional = true } + [build-dependencies] fl2rust = { version = "0.4", optional = true } [features] # default = ["ui"] -ui = ["fltk", "fl2rust", "toml","futures"] +ui = ["fltk", "fl2rust", "toml", "futures"] \ No newline at end of file diff --git a/src/steamgriddb/cached_search.rs b/src/steamgriddb/cached_search.rs index e51e1ff..0e86dd4 100644 --- a/src/steamgriddb/cached_search.rs +++ b/src/steamgriddb/cached_search.rs @@ -19,24 +19,26 @@ impl<'a> CachedSearch<'a> { save_search_map(&self.search_map); } - pub async fn search( + pub async fn search( &mut self, app_id: u32, - query: &str, - ) -> Result, Box> { + query: S, + ) -> Result, Box> + where + S: AsRef + Into, + { let cached_result = self.search_map.get(&app_id); if let Some(result) = cached_result { return Ok(Some(result.1)); } - println!("Searching for {}", query); - let search = self.client.search(query).await?; + println!("Searching for {}", query.as_ref()); + let search = self.client.search(query.as_ref()).await?; if search.is_empty() { return Ok(None); } let first_item = &search[0]; let assumed_id = first_item.id; - self.search_map - .insert(app_id, (query.to_owned(), assumed_id)); + self.search_map.insert(app_id, (query.into(), assumed_id)); Ok(Some(assumed_id)) } diff --git a/src/steamgriddb/downloader.rs b/src/steamgriddb/downloader.rs index adb0e6c..bda3aa6 100644 --- a/src/steamgriddb/downloader.rs +++ b/src/steamgriddb/downloader.rs @@ -3,17 +3,17 @@ use std::io::Write; use std::{collections::HashMap, path::Path}; use std::error::Error; -use steam_shortcuts_util::Shortcut; +use steam_shortcuts_util::shortcut::ShortcutOwned; use steamgriddb_api::Client; use crate::steamgriddb::ImageType; use super::CachedSearch; -pub async fn download_images<'a, 'b>( +pub async fn download_images<'b>( known_images: Vec, user_data_folder: &str, - shortcuts: Vec>, + shortcuts: &Vec, search: &mut CachedSearch<'b>, client: &Client, ) -> Result<(), Box> { @@ -31,7 +31,7 @@ pub async fn download_images<'a, 'b>( } let mut search_results = HashMap::new(); for s in shortcuts_to_search_for { - let search = search.search(s.app_id, s.app_name).await?; + let search = search.search(s.app_id, &s.app_name).await?; if let Some(search) = search { search_results.insert(s.app_id, search); } diff --git a/src/sync/mod.rs b/src/sync/mod.rs index 611a31c..1b92daf 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -1,2 +1,5 @@ +#[cfg(target_os = "linux")] +mod symlinks; mod sync; -pub use sync::run_sync; \ No newline at end of file + +pub use sync::run_sync; diff --git a/src/sync/symlinks.rs b/src/sync/symlinks.rs new file mode 100644 index 0000000..f554796 --- /dev/null +++ b/src/sync/symlinks.rs @@ -0,0 +1,62 @@ +use std::path::Path; + +use steam_shortcuts_util::{ + shortcut::{ShortcutOwned}, + Shortcut, +}; + +fn get_boilr_links_path() -> std::path::PathBuf { + let home = std::env::var("HOME").expect("Expected a home variable to be defined"); + let boilr_links_path = Path::new(&home).join(".boilr").join("links"); + boilr_links_path +} + +pub fn create_sym_links(shortcut: &ShortcutOwned) -> ShortcutOwned { + let links_folder = get_boilr_links_path(); + + let target_link = links_folder.join(format!("t{}", shortcut.app_id)); + let workdir_link = links_folder.join(format!("w{}", shortcut.app_id)); + + let target_original = Path::new(&shortcut.exe); + let workdir_original = Path::new(&shortcut.start_dir); + + use std::os::unix::fs::symlink; + // If the links exsists, then they must point towards what is needed, otherwise they would have a different app id + let target_ok = target_link.exists() || symlink(&target_original, &target_link).is_ok(); + let workdir_ok = workdir_link.exists() || symlink(&workdir_original, &workdir_link).is_ok(); + match (target_ok, workdir_ok) { + (true, true) => { + let exe = target_link.to_string_lossy().to_string(); + let start_dir = workdir_link.to_string_lossy().to_string(); + let new_shortcut = Shortcut::new( + 0, + shortcut.app_name.as_str(), + exe.as_str(), + &start_dir.as_str(), + shortcut.icon.as_str(), + shortcut.shortcut_path.as_str(), + shortcut.launch_options.as_str(), + ); + let mut new_shortcut = new_shortcut.to_owned(); + new_shortcut.tags = shortcut.tags.clone(); + new_shortcut + } + _ => { + println!("Could not create symlinks for game: {}", shortcut.app_name); + shortcut.clone() + } + } +} + +pub fn ensure_links_folder_created(name: &str) { + let boilr_links_path = get_boilr_links_path(); + if !boilr_links_path.exists() { + if let Err(e) = std::fs::create_dir_all(&boilr_links_path) { + println!( + "Could not create links folder for symlinks at path: {:?} , error: {:?} , you can try to disable creating symlinks for platform {}", + boilr_links_path, e, name + ); + return; + } + } +} diff --git a/src/sync/sync.rs b/src/sync/sync.rs index 4336239..a47aa5e 100644 --- a/src/sync/sync.rs +++ b/src/sync/sync.rs @@ -23,47 +23,12 @@ pub async fn run_sync(settings: &Settings) -> Result<(), Box> { for user in userinfo_shortcuts.iter() { let start_time = std::time::Instant::now(); - let shortcut_info = get_shortcuts_for_user(user); - - let mut new_user_shortcuts: Vec = shortcut_info.shortcuts; - - update_platform_shortcuts( - &EpicPlatform::new(settings.epic_games.clone()), - &mut new_user_shortcuts, - ); - - update_platform_shortcuts( - &LegendaryPlatform::new(settings.legendary.clone()), - &mut new_user_shortcuts, - ); - - update_platform_shortcuts( - &ItchPlatform::new(settings.itch.clone()), - &mut new_user_shortcuts, - ); - - update_platform_shortcuts( - &OriginPlatform { - settings: settings.origin.clone(), - }, - &mut new_user_shortcuts, - ); - - update_platform_shortcuts( - &GogPlatform { - settings: settings.gog.clone(), - }, - &mut new_user_shortcuts, - ); - - let shortcuts = new_user_shortcuts.iter().map(|f| f.borrow()).collect(); - - save_shortcuts(&shortcuts, Path::new(&shortcut_info.path)); + let mut shortcut_info = get_shortcuts_for_user(user); + update_platforms(settings, &mut shortcut_info.shortcuts); + save_shortcuts(&shortcut_info.shortcuts, Path::new(&shortcut_info.path)); let duration = start_time.elapsed(); - println!("Finished synchronizing games in: {:?}", duration); - if settings.steamgrid_db.enabled { let auth_key = &settings.steamgrid_db.auth_key; if let Some(auth_key) = auth_key { @@ -75,7 +40,7 @@ pub async fn run_sync(settings: &Settings) -> Result<(), Box> { download_images( known_images, user.steam_user_data_folder.as_str(), - shortcuts, + &shortcut_info.shortcuts, &mut search, &client, ) @@ -91,10 +56,56 @@ pub async fn run_sync(settings: &Settings) -> Result<(), Box> { Ok(()) } -fn save_shortcuts(shortcuts: &Vec, path: &Path) { - let new_content = shortcuts_to_bytes(shortcuts); - let mut file = File::create(path).unwrap(); - file.write_all(new_content.as_slice()).unwrap(); +fn update_platforms(settings: &Settings, new_user_shortcuts: &mut Vec) { + update_platform_shortcuts( + &EpicPlatform::new(settings.epic_games.clone()), + new_user_shortcuts, + ); + update_platform_shortcuts( + &LegendaryPlatform::new(settings.legendary.clone()), + new_user_shortcuts, + ); + update_platform_shortcuts( + &ItchPlatform::new(settings.itch.clone()), + new_user_shortcuts, + ); + update_platform_shortcuts( + &OriginPlatform { + settings: settings.origin.clone(), + }, + new_user_shortcuts, + ); + update_platform_shortcuts( + &GogPlatform { + settings: settings.gog.clone(), + }, + new_user_shortcuts, + ); +} + +fn save_shortcuts(shortcuts: &Vec, path: &Path) { + let mut shortcuts_refs = vec![]; + for shortcut in shortcuts { + shortcuts_refs.push(shortcut.borrow()); + } + let new_content = shortcuts_to_bytes(&shortcuts_refs); + match File::create(path) { + Ok(mut file) => match file.write_all(new_content.as_slice()) { + Ok(_) => println!("Saved {} shortcuts", shortcuts.len()), + Err(e) => println!( + "Failed to save shortcuts to {} error: {}", + path.to_string_lossy(), + e + ), + }, + Err(e) => { + println!( + "Failed to save shortcuts to {} error: {}", + path.to_string_lossy(), + e + ); + } + } } fn update_platform_shortcuts(platform: &P, current_shortcuts: &mut Vec) @@ -104,22 +115,15 @@ where T: Into, { if platform.enabled() { - let shortcuts_to_add_result = platform.get_shortcuts(); + let name = platform.name(); #[cfg(target_os = "linux")] if platform.create_symlinks() { - let boilr_links_path = get_boilr_links_path(); - if !boilr_links_path.exists() { - if let Err(e) = std::fs::create_dir_all(&boilr_links_path) { - println!( - "Could not create links folder for symlinks at path: {:?} , error: {:?} , you can try to disable creating symlinks for platform {}", - boilr_links_path, e, platform.name() - ); - return; - } - } + super::symlinks::ensure_links_folder_created(name); } + let shortcuts_to_add_result = platform.get_shortcuts(); + match shortcuts_to_add_result { Ok(shortcuts_to_add) => { println!( @@ -133,7 +137,7 @@ where let shortcut_owned: ShortcutOwned = shortcut.into(); #[cfg(target_os = "linux")] let shortcut_owned = if platform.create_symlinks() { - create_sym_links(&shortcut_owned) + crate::sync::symlinks::create_sym_links(&shortcut_owned) } else { shortcut_owned }; @@ -147,46 +151,3 @@ where } } } -#[cfg(target_os = "linux")] -fn get_boilr_links_path() -> std::path::PathBuf { - let home = std::env::var("HOME").expect("Expected a home variable to be defined"); - let boilr_links_path = Path::new(&home).join(".boilr").join("links"); - boilr_links_path -} -#[cfg(target_os = "linux")] -fn create_sym_links(shortcut: &ShortcutOwned) -> ShortcutOwned { - let links_folder = get_boilr_links_path(); - - let target_link = links_folder.join(format!("t{}", shortcut.app_id)); - let workdir_link = links_folder.join(format!("w{}", shortcut.app_id)); - - let target_original = Path::new(&shortcut.exe); - let workdir_original = Path::new(&shortcut.start_dir); - - use std::os::unix::fs::symlink; - // If the links exsists, then they must point towards what is needed, otherwise they would have a different app id - let target_ok = target_link.exists() || symlink(&target_original, &target_link).is_ok(); - let workdir_ok = workdir_link.exists() || symlink(&workdir_original, &workdir_link).is_ok(); - match (target_ok, workdir_ok) { - (true, true) => { - let exe = target_link.to_string_lossy().to_string(); - let start_dir = workdir_link.to_string_lossy().to_string(); - let new_shortcut = Shortcut::new( - 0, - shortcut.app_name.as_str(), - exe.as_str(), - &start_dir.as_str(), - shortcut.icon.as_str(), - shortcut.shortcut_path.as_str(), - shortcut.launch_options.as_str(), - ); - let mut new_shortcut = new_shortcut.to_owned(); - new_shortcut.tags = shortcut.tags.clone(); - new_shortcut - } - _ => { - println!("Could not create symlinks for game: {}", shortcut.app_name); - shortcut.clone() - } - } -}