2023-12-22 21:26:50 +00:00
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
use std::sync::Mutex;
|
|
|
|
|
2024-04-20 03:18:06 +01:00
|
|
|
use crate::consts::*;
|
2023-12-22 21:26:50 +00:00
|
|
|
|
|
|
|
static LAST_SETTING_ID: Mutex<u128> = Mutex::new(0);
|
|
|
|
|
2024-01-06 18:26:35 +00:00
|
|
|
pub fn filename(id: u128, ext: &str) -> String {
|
|
|
|
format!("{}.{}", id, ext)
|
|
|
|
}
|
|
|
|
|
2023-12-22 21:26:50 +00:00
|
|
|
pub fn setting_path_by_id(root: impl AsRef<Path>, id: u128, ext: &str) -> PathBuf {
|
|
|
|
root.as_ref()
|
|
|
|
.join(SETTING_FOLDER)
|
|
|
|
.join(ID_FOLDER)
|
2024-01-06 18:26:35 +00:00
|
|
|
.join(filename(id, ext))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn setting_folder_by_app_id(root: impl AsRef<Path>, steam_app_id: u32) -> PathBuf {
|
|
|
|
root.as_ref()
|
|
|
|
.join(SETTING_FOLDER)
|
|
|
|
.join(APP_ID_FOLDER)
|
|
|
|
.join(steam_app_id.to_string())
|
|
|
|
}
|
|
|
|
|
2024-04-20 03:18:06 +01:00
|
|
|
pub fn setting_tag_folder_by_app_id(root: impl AsRef<Path>, steam_app_id: u32) -> PathBuf {
|
|
|
|
root.as_ref()
|
|
|
|
.join(SETTING_FOLDER)
|
|
|
|
.join(APP_ID_FOLDER)
|
|
|
|
.join(steam_app_id.to_string())
|
|
|
|
.join(TAG_FOLDER)
|
|
|
|
}
|
|
|
|
|
2024-04-13 15:14:02 +01:00
|
|
|
pub fn setting_folder_by_app_id_tag(root: impl AsRef<Path>, 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)
|
|
|
|
}
|
|
|
|
|
2024-01-06 18:26:35 +00:00
|
|
|
pub fn setting_folder_by_user_id(root: impl AsRef<Path>, steam_user_id: u64) -> PathBuf {
|
|
|
|
root.as_ref()
|
|
|
|
.join(SETTING_FOLDER)
|
|
|
|
.join(USER_ID_FOLDER)
|
|
|
|
.join(steam_user_id.to_string())
|
|
|
|
}
|
|
|
|
|
2024-04-20 03:18:06 +01:00
|
|
|
pub fn setting_tag_folder_by_user_id(root: impl AsRef<Path>, steam_user_id: u64) -> PathBuf {
|
|
|
|
root.as_ref()
|
|
|
|
.join(SETTING_FOLDER)
|
|
|
|
.join(USER_ID_FOLDER)
|
|
|
|
.join(steam_user_id.to_string())
|
|
|
|
.join(TAG_FOLDER)
|
|
|
|
}
|
|
|
|
|
2024-04-13 15:14:02 +01:00
|
|
|
pub fn setting_folder_by_user_id_tag(root: impl AsRef<Path>, 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)
|
|
|
|
}
|
|
|
|
|
2024-01-06 18:26:35 +00:00
|
|
|
pub fn setting_folder_by_tag(root: impl AsRef<Path>, tag: &str) -> PathBuf {
|
|
|
|
root.as_ref()
|
|
|
|
.join(SETTING_FOLDER)
|
|
|
|
.join(TAG_FOLDER)
|
|
|
|
.join(tag)
|
2023-12-22 21:26:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn next_setting_id(root: impl AsRef<Path>) -> u128 {
|
|
|
|
let mut lock = LAST_SETTING_ID.lock().unwrap();
|
|
|
|
let mut last_id = *lock;
|
|
|
|
if last_id == 0 {
|
|
|
|
// needs init
|
2024-04-13 02:35:10 +01:00
|
|
|
last_id = 1;
|
2023-12-22 21:26:50 +00:00
|
|
|
let mut path = setting_path_by_id(root.as_ref(), last_id, RON_EXTENSION);
|
|
|
|
while path.exists() {
|
|
|
|
last_id += 1;
|
|
|
|
path = setting_path_by_id(root.as_ref(), last_id, RON_EXTENSION);
|
|
|
|
}
|
2024-04-13 02:35:10 +01:00
|
|
|
*lock = last_id - 1;
|
|
|
|
log::info!("setting id initialized to {}", last_id);
|
2023-12-22 21:26:50 +00:00
|
|
|
}
|
|
|
|
*lock += 1;
|
|
|
|
*lock
|
|
|
|
}
|
2024-04-21 17:34:11 +01:00
|
|
|
|
|
|
|
pub struct ToSymlink {
|
|
|
|
pub ron: Vec<PathBuf>,
|
|
|
|
pub json: Vec<PathBuf>,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn symlinks(root: impl AsRef<Path>, meta: &community_settings_core::v1::Metadata) -> std::io::Result<ToSymlink> {
|
|
|
|
let mut symlink_locations = ToSymlink { ron: Vec::new(), json: Vec::new() };
|
|
|
|
let filename_ron = filename(meta.get_id(), crate::consts::RON_EXTENSION);
|
|
|
|
let filename_json = filename(meta.get_id(), crate::consts::JSON_EXTENSION);
|
|
|
|
// build symlinks to app id folder
|
|
|
|
let app_id_folder = setting_folder_by_app_id(&root, meta.steam_app_id);
|
|
|
|
log::debug!("App id folder {}", app_id_folder.display());
|
|
|
|
if !app_id_folder.exists() {
|
|
|
|
std::fs::create_dir(&app_id_folder)?;
|
|
|
|
std::fs::create_dir(setting_tag_folder_by_app_id(&root, meta.steam_app_id))?;
|
|
|
|
}
|
|
|
|
symlink_locations.ron.push(app_id_folder.join(&filename_ron));
|
|
|
|
symlink_locations.json.push(app_id_folder.join(&filename_json));
|
|
|
|
|
|
|
|
// create symlinks for user id folder
|
|
|
|
let user_id_folder = setting_folder_by_user_id(&root, meta.steam_user_id);
|
|
|
|
if !user_id_folder.exists() {
|
|
|
|
std::fs::create_dir(&user_id_folder)?;
|
|
|
|
std::fs::create_dir(setting_tag_folder_by_user_id(&root, meta.steam_user_id))?;
|
|
|
|
}
|
|
|
|
symlink_locations.ron.push(user_id_folder.join(&filename_ron));
|
|
|
|
symlink_locations.json.push(user_id_folder.join(&filename_json));
|
|
|
|
|
|
|
|
// create symlinks for each tag
|
|
|
|
for tag in meta.tags.iter() {
|
|
|
|
if !str_is_alphanumeric_or_space(&tag){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// create symlinks for general tag folder
|
|
|
|
let tag_folder = setting_folder_by_tag(&root, tag);
|
|
|
|
if !tag_folder.exists() {
|
|
|
|
std::fs::create_dir(&tag_folder)?;
|
|
|
|
}
|
|
|
|
symlink_locations.ron.push(tag_folder.join(&filename_ron));
|
|
|
|
symlink_locations.json.push(tag_folder.join(&filename_json));
|
|
|
|
|
|
|
|
// create symlinks for app id tag folder
|
|
|
|
let app_tag_folder = setting_folder_by_app_id_tag(&root, meta.steam_app_id, tag);
|
|
|
|
if !app_tag_folder.exists() {
|
|
|
|
std::fs::create_dir(&app_tag_folder)?;
|
|
|
|
}
|
|
|
|
symlink_locations.ron.push(app_tag_folder.join(&filename_ron));
|
|
|
|
symlink_locations.json.push(app_tag_folder.join(&filename_json));
|
|
|
|
|
|
|
|
// create symlinks for user id tag folder
|
|
|
|
let user_tag_folder = setting_folder_by_user_id_tag(&root, meta.steam_user_id, tag);
|
|
|
|
if !user_tag_folder.exists() {
|
|
|
|
std::fs::create_dir(&user_tag_folder)?;
|
|
|
|
}
|
|
|
|
symlink_locations.ron.push(user_tag_folder.join(&filename_ron));
|
|
|
|
symlink_locations.json.push(user_tag_folder.join(&filename_json));
|
|
|
|
}
|
|
|
|
Ok(symlink_locations)
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|