From 81b9107bf57a47da14e0d1041167909be4d22c9c Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sat, 13 Apr 2024 10:14:02 -0400 Subject: [PATCH] Add some double-criteria symlinks (by app id and tag, by user id and tag) --- .../src/api/save_setting.rs | 48 +++++++++++++++++++ .../community_settings_srv/src/file_util.rs | 30 ++++++++++-- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/backend/community_settings_srv/src/api/save_setting.rs b/backend/community_settings_srv/src/api/save_setting.rs index 6b3d96e..bd4960e 100644 --- a/backend/community_settings_srv/src/api/save_setting.rs +++ b/backend/community_settings_srv/src/api/save_setting.rs @@ -109,6 +109,10 @@ pub async fn save_setting_handler( // create symlinks for each tag for tag in parsed_data.tags.iter() { + if !str_is_alphanumeric_or_space(&tag){ + continue; + } + // create symlinks for general tag folder let tag_folder = file_util::setting_folder_by_tag(&cli.folder, tag); if !tag_folder.exists() { std::fs::create_dir(&tag_folder)?; @@ -125,7 +129,51 @@ pub async fn save_setting_handler( std::os::unix::fs::symlink(&path_ron.canonicalize()?, tag_folder.join(&filename_ron))?; std::os::unix::fs::symlink(&path_json.canonicalize()?, tag_folder.join(&filename_json))?; } + + // create symlinks for app id tag folder + let app_tag_folder = file_util::setting_folder_by_app_id_tag(&cli.folder, parsed_data.steam_app_id, tag); + if !app_tag_folder.exists() { + std::fs::create_dir_all(&app_tag_folder)?; + } + #[cfg(target_family = "windows")] // NOTE: windows support is untested and unmaintained + { + log::debug!("Symlinking {} -> {}", app_tag_folder.join(&filename_ron).display(), path_ron.canonicalize()?.display()); + std::os::windows::fs::symlink_file(&path_ron.canonicalize()?, app_tag_folder.join(&filename_ron))?; + std::os::windows::fs::symlink_file(&path_json.canonicalize()?, app_tag_folder.join(&filename_json))?; + } + #[cfg(target_family = "unix")] + { + log::debug!("Symlinking {} -> {}", app_tag_folder.join(&filename_ron).display(), path_ron.canonicalize()?.display()); + std::os::unix::fs::symlink(&path_ron.canonicalize()?, app_tag_folder.join(&filename_ron))?; + std::os::unix::fs::symlink(&path_json.canonicalize()?, app_tag_folder.join(&filename_json))?; + } + + // create symlinks for user id tag folder + let user_tag_folder = file_util::setting_folder_by_user_id_tag(&cli.folder, parsed_data.steam_user_id, tag); + if !user_tag_folder.exists() { + std::fs::create_dir_all(&user_tag_folder)?; + } + #[cfg(target_family = "windows")] // NOTE: windows support is untested and unmaintained + { + log::debug!("Symlinking {} -> {}", user_tag_folder.join(&filename_ron).display(), path_ron.canonicalize()?.display()); + std::os::windows::fs::symlink_file(&path_ron.canonicalize()?, user_tag_folder.join(&filename_ron))?; + std::os::windows::fs::symlink_file(&path_json.canonicalize()?, user_tag_folder.join(&filename_json))?; + } + #[cfg(target_family = "unix")] + { + log::debug!("Symlinking {} -> {}", user_tag_folder.join(&filename_ron).display(), path_ron.canonicalize()?.display()); + std::os::unix::fs::symlink(&path_ron.canonicalize()?, user_tag_folder.join(&filename_ron))?; + std::os::unix::fs::symlink(&path_json.canonicalize()?, user_tag_folder.join(&filename_json))?; + } } Ok(actix_web::HttpResponse::NoContent()) } + +fn str_is_alphanumeric_or_space(s: &str) -> bool { + let mut result = true; + for ch in s.chars() { + result &= ch.is_ascii_alphanumeric() || ch == ' '; + } + result +} diff --git a/backend/community_settings_srv/src/file_util.rs b/backend/community_settings_srv/src/file_util.rs index 627a9fc..76f511b 100644 --- a/backend/community_settings_srv/src/file_util.rs +++ b/backend/community_settings_srv/src/file_util.rs @@ -120,8 +120,10 @@ pub fn sync_ids(root: impl AsRef) -> std::io::Result<()> { return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e_msg)); } }; - setting.id = id; - ron::ser::to_writer(std::fs::File::create(&f_path)?, &setting).unwrap(); + if setting.id != id { + setting.id = id; + ron::ser::to_writer(std::fs::File::create(&f_path)?, &setting).unwrap(); + } } else if ext == JSON_EXTENSION { let reader = std::io::BufReader::new(std::fs::File::open(&f_path)?); let mut setting: community_settings_core::v1::Metadata = match serde_json::from_reader(reader) { @@ -132,8 +134,10 @@ pub fn sync_ids(root: impl AsRef) -> std::io::Result<()> { return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e_msg)); } }; - setting.id = id; - serde_json::to_writer(std::fs::File::create(&f_path)?, &setting).unwrap(); + if setting.id != id { + setting.id = id; + serde_json::to_writer(std::fs::File::create(&f_path)?, &setting).unwrap(); + } } } @@ -159,6 +163,15 @@ pub fn setting_folder_by_app_id(root: impl AsRef, steam_app_id: u32) -> Pa .join(steam_app_id.to_string()) } +pub fn setting_folder_by_app_id_tag(root: impl AsRef, steam_app_id: u32, tag: &str) -> PathBuf { + root.as_ref() + .join(SETTING_FOLDER) + .join(APP_ID_FOLDER) + .join(steam_app_id.to_string()) + .join(TAG_FOLDER) + .join(tag) +} + pub fn setting_folder_by_user_id(root: impl AsRef, steam_user_id: u64) -> PathBuf { root.as_ref() .join(SETTING_FOLDER) @@ -166,6 +179,15 @@ pub fn setting_folder_by_user_id(root: impl AsRef, steam_user_id: u64) -> .join(steam_user_id.to_string()) } +pub fn setting_folder_by_user_id_tag(root: impl AsRef, steam_user_id: u64, tag: &str) -> PathBuf { + root.as_ref() + .join(SETTING_FOLDER) + .join(USER_ID_FOLDER) + .join(steam_user_id.to_string()) + .join(TAG_FOLDER) + .join(tag) +} + pub fn setting_folder_by_tag(root: impl AsRef, tag: &str) -> PathBuf { root.as_ref() .join(SETTING_FOLDER)