mirror of
https://github.com/Xevion/factorio-achievements-fixer.git
synced 2025-12-15 18:11:47 -06:00
Separate large lib.rs into dirs.rs & format.rs
This commit is contained in:
161
src-tauri/src/dirs.rs
Normal file
161
src-tauri/src/dirs.rs
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
use human_bytes::human_bytes;
|
||||||
|
use humanize_duration::prelude::DurationExt;
|
||||||
|
use humanize_duration::Truncate;
|
||||||
|
use serde::Serialize;
|
||||||
|
use simple_home_dir::home_dir;
|
||||||
|
use std::fs;
|
||||||
|
use std::fs::metadata;
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn get_save_directories() -> Vec<String> {
|
||||||
|
let mut save_directories: Vec<String> = Vec::new();
|
||||||
|
|
||||||
|
if let Some(home_dir) = home_dir() {
|
||||||
|
let save_path = home_dir.join("AppData\\Roaming\\Factorio\\saves");
|
||||||
|
if save_path.exists() {
|
||||||
|
save_directories.push(save_path.to_str().unwrap().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_directories
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn get_save_directories() -> Vec<String> {
|
||||||
|
let mut save_directories = Vec::new();
|
||||||
|
|
||||||
|
if let Some(home_dir) = home_dir() {
|
||||||
|
let normal_save_path = home_dir.join(".factorio/saves");
|
||||||
|
if normal_save_path.exists() {
|
||||||
|
save_directories.push(save_path.to_str().unwrap().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let flatpak_save_path = home_dir.join(".var/app/com.valvesoftware.Steam/.factorio/saves");
|
||||||
|
if flatpak_save_path.exists() {
|
||||||
|
save_directories.push(flatpak_save_path.to_str().unwrap().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_directories
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn get_save_directories() -> Vec<String> {
|
||||||
|
let mut save_directories = Vec::new();
|
||||||
|
|
||||||
|
if let Some(home_dir) = home_dir() {
|
||||||
|
let save_path = home_dir.join("Library/Application Support/factorio/saves");
|
||||||
|
if save_path.exists() {
|
||||||
|
save_directories.push(save_path.to_str().unwrap().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_directories
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn find_save_files() -> Vec<SaveFile> {
|
||||||
|
let save_directories = get_save_directories();
|
||||||
|
let mut save_files = Vec::new();
|
||||||
|
|
||||||
|
// Collect all save files
|
||||||
|
for dir in save_directories {
|
||||||
|
println!("Save directory found: {}", dir);
|
||||||
|
if let Ok(entries) = fs::read_dir(dir) {
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
if let Some(file_name) = entry.file_name().to_str() {
|
||||||
|
if !file_name.ends_with(".zip") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let file_path = entry.path();
|
||||||
|
if let Ok(metadata) = metadata(&file_path) {
|
||||||
|
let modified = metadata.modified();
|
||||||
|
if modified.is_err() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let modified_elapsed = match modified.unwrap().elapsed() {
|
||||||
|
Ok(elapsed) => elapsed,
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
let modified_elapsed_secs = modified_elapsed.as_secs();
|
||||||
|
|
||||||
|
let human_last_modified = if modified_elapsed_secs < 60 {
|
||||||
|
if modified_elapsed_secs < 10 {
|
||||||
|
"just now".to_string()
|
||||||
|
} else {
|
||||||
|
"< 1min".to_string()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
modified_elapsed
|
||||||
|
.human_with_format(
|
||||||
|
match modified_elapsed_secs / 60 {
|
||||||
|
m if m < 60 => Truncate::Minute,
|
||||||
|
m if m < 60 * 36 => Truncate::Hour,
|
||||||
|
m if m < 60 * 24 * 31 => Truncate::Day,
|
||||||
|
m if m < 60 * 24 * 31 * 18 => Truncate::Month,
|
||||||
|
_ => Truncate::Year,
|
||||||
|
},
|
||||||
|
crate::format::SlimFormatter,
|
||||||
|
)
|
||||||
|
.to_string()
|
||||||
|
.replace(" ", "")
|
||||||
|
+ " ago"
|
||||||
|
};
|
||||||
|
|
||||||
|
save_files.push(SaveFile {
|
||||||
|
name: file_name.to_string(),
|
||||||
|
size: human_bytes(metadata.len() as f64),
|
||||||
|
path: file_path.to_str().unwrap().to_string(),
|
||||||
|
last_modified: human_last_modified,
|
||||||
|
modified_delta: modified_elapsed_secs as usize,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the save files by last modified time
|
||||||
|
save_files.sort_by(|a, b| a.modified_delta.cmp(&b.modified_delta));
|
||||||
|
|
||||||
|
save_files
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
pub struct SaveFile {
|
||||||
|
name: String,
|
||||||
|
path: String,
|
||||||
|
size: String,
|
||||||
|
last_modified: String,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
modified_delta: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn choose_best_save_directory() -> Option<String> {
|
||||||
|
let save_directories = get_save_directories();
|
||||||
|
let mut best_directory: Option<String> = None;
|
||||||
|
let mut max_zip_files = 0;
|
||||||
|
|
||||||
|
for dir in save_directories {
|
||||||
|
if let Ok(entries) = fs::read_dir(&dir) {
|
||||||
|
let zip_file_count = entries
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.filter(|entry| {
|
||||||
|
entry
|
||||||
|
.file_name()
|
||||||
|
.to_str()
|
||||||
|
.map_or(false, |name| name.ends_with(".zip"))
|
||||||
|
})
|
||||||
|
.count();
|
||||||
|
if zip_file_count > max_zip_files {
|
||||||
|
max_zip_files = zip_file_count;
|
||||||
|
best_directory = Some(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
best_directory
|
||||||
|
}
|
||||||
39
src-tauri/src/format.rs
Normal file
39
src-tauri/src/format.rs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
use humanize_duration::Unit;
|
||||||
|
use humanize_duration::{types::DurationParts, unit, Formatter, Truncate};
|
||||||
|
|
||||||
|
pub struct SlimFormatter;
|
||||||
|
|
||||||
|
unit!(MyYear, "y", "y");
|
||||||
|
unit!(MyMonth, "mon", "mon");
|
||||||
|
unit!(MyDay, "d", "d");
|
||||||
|
unit!(MyHour, "h", "h");
|
||||||
|
unit!(MyMinute, "m", "m");
|
||||||
|
unit!(MySecond, "s", "s");
|
||||||
|
unit!(MyMillis, "ms", "ms");
|
||||||
|
unit!(MyMicro, "mms", "mms");
|
||||||
|
unit!(MyNano, "ns", "ns");
|
||||||
|
|
||||||
|
impl Formatter for SlimFormatter {
|
||||||
|
fn get(&self, truncate: Truncate) -> Box<dyn Unit> {
|
||||||
|
match truncate {
|
||||||
|
Truncate::Nano => Box::new(MyNano),
|
||||||
|
Truncate::Micro => Box::new(MyMicro),
|
||||||
|
Truncate::Millis => Box::new(MyMillis),
|
||||||
|
Truncate::Second => Box::new(MySecond),
|
||||||
|
Truncate::Minute => Box::new(MyMinute),
|
||||||
|
Truncate::Hour => Box::new(MyHour),
|
||||||
|
Truncate::Day => Box::new(MyDay),
|
||||||
|
Truncate::Month => Box::new(MyMonth),
|
||||||
|
Truncate::Year => Box::new(MyYear),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format(
|
||||||
|
&self,
|
||||||
|
f: &mut std::fmt::Formatter<'_>,
|
||||||
|
parts: DurationParts,
|
||||||
|
truncate: Truncate,
|
||||||
|
) -> std::fmt::Result {
|
||||||
|
self.format_default(f, parts, truncate)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,203 +1,5 @@
|
|||||||
use human_bytes::human_bytes;
|
mod dirs;
|
||||||
use humanize_duration::prelude::DurationExt;
|
mod format;
|
||||||
use humanize_duration::Unit;
|
|
||||||
use humanize_duration::{types::DurationParts, unit, Formatter, Truncate};
|
|
||||||
use serde::Serialize;
|
|
||||||
use simple_home_dir::home_dir;
|
|
||||||
use std::fs;
|
|
||||||
use std::fs::metadata;
|
|
||||||
|
|
||||||
struct SlimFormatter;
|
|
||||||
|
|
||||||
unit!(MyYear, "y", "y");
|
|
||||||
unit!(MyMonth, "mon", "mon");
|
|
||||||
unit!(MyDay, "d", "d");
|
|
||||||
unit!(MyHour, "h", "h");
|
|
||||||
unit!(MyMinute, "m", "m");
|
|
||||||
unit!(MySecond, "s", "s");
|
|
||||||
unit!(MyMillis, "ms", "ms");
|
|
||||||
unit!(MyMicro, "mms", "mms");
|
|
||||||
unit!(MyNano, "ns", "ns");
|
|
||||||
|
|
||||||
impl Formatter for SlimFormatter {
|
|
||||||
fn get(&self, truncate: Truncate) -> Box<dyn Unit> {
|
|
||||||
match truncate {
|
|
||||||
Truncate::Nano => Box::new(MyNano),
|
|
||||||
Truncate::Micro => Box::new(MyMicro),
|
|
||||||
Truncate::Millis => Box::new(MyMillis),
|
|
||||||
Truncate::Second => Box::new(MySecond),
|
|
||||||
Truncate::Minute => Box::new(MyMinute),
|
|
||||||
Truncate::Hour => Box::new(MyHour),
|
|
||||||
Truncate::Day => Box::new(MyDay),
|
|
||||||
Truncate::Month => Box::new(MyMonth),
|
|
||||||
Truncate::Year => Box::new(MyYear),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format(
|
|
||||||
&self,
|
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
|
||||||
parts: DurationParts,
|
|
||||||
truncate: Truncate,
|
|
||||||
) -> std::fmt::Result {
|
|
||||||
self.format_default(f, parts, truncate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
fn get_save_directories() -> Vec<String> {
|
|
||||||
let mut save_directories: Vec<String> = Vec::new();
|
|
||||||
|
|
||||||
if let Some(home_dir) = home_dir() {
|
|
||||||
let save_path = home_dir.join("AppData\\Roaming\\Factorio\\saves");
|
|
||||||
if save_path.exists() {
|
|
||||||
save_directories.push(save_path.to_str().unwrap().to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save_directories
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
fn get_save_directories() -> Vec<String> {
|
|
||||||
let mut save_directories = Vec::new();
|
|
||||||
|
|
||||||
if let Some(home_dir) = home_dir() {
|
|
||||||
let normal_save_path = home_dir.join(".factorio/saves");
|
|
||||||
if normal_save_path.exists() {
|
|
||||||
save_directories.push(save_path.to_str().unwrap().to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let flatpak_save_path = home_dir.join(".var/app/com.valvesoftware.Steam/.factorio/saves");
|
|
||||||
if flatpak_save_path.exists() {
|
|
||||||
save_directories.push(flatpak_save_path.to_str().unwrap().to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save_directories
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
fn get_save_directories() -> Vec<String> {
|
|
||||||
let mut save_directories = Vec::new();
|
|
||||||
|
|
||||||
if let Some(home_dir) = home_dir() {
|
|
||||||
let save_path = home_dir.join("Library/Application Support/factorio/saves");
|
|
||||||
if save_path.exists() {
|
|
||||||
save_directories.push(save_path.to_str().unwrap().to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save_directories
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Debug)]
|
|
||||||
struct SaveFile {
|
|
||||||
name: String,
|
|
||||||
path: String,
|
|
||||||
size: String,
|
|
||||||
last_modified: String,
|
|
||||||
#[serde(skip_serializing)]
|
|
||||||
modified_delta: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn choose_best_save_directory() -> Option<String> {
|
|
||||||
let save_directories = get_save_directories();
|
|
||||||
let mut best_directory: Option<String> = None;
|
|
||||||
let mut max_zip_files = 0;
|
|
||||||
|
|
||||||
for dir in save_directories {
|
|
||||||
if let Ok(entries) = fs::read_dir(&dir) {
|
|
||||||
let zip_file_count = entries
|
|
||||||
.filter_map(Result::ok)
|
|
||||||
.filter(|entry| {
|
|
||||||
entry
|
|
||||||
.file_name()
|
|
||||||
.to_str()
|
|
||||||
.map_or(false, |name| name.ends_with(".zip"))
|
|
||||||
})
|
|
||||||
.count();
|
|
||||||
if zip_file_count > max_zip_files {
|
|
||||||
max_zip_files = zip_file_count;
|
|
||||||
best_directory = Some(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
best_directory
|
|
||||||
}
|
|
||||||
|
|
||||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
|
||||||
#[tauri::command]
|
|
||||||
fn find_save_files() -> Vec<SaveFile> {
|
|
||||||
let save_directories = get_save_directories();
|
|
||||||
let mut save_files = Vec::new();
|
|
||||||
|
|
||||||
// Collect all save files
|
|
||||||
for dir in save_directories {
|
|
||||||
println!("Save directory found: {}", dir);
|
|
||||||
if let Ok(entries) = fs::read_dir(dir) {
|
|
||||||
for entry in entries.flatten() {
|
|
||||||
if let Some(file_name) = entry.file_name().to_str() {
|
|
||||||
if !file_name.ends_with(".zip") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_path = entry.path();
|
|
||||||
if let Ok(metadata) = metadata(&file_path) {
|
|
||||||
let modified = metadata.modified();
|
|
||||||
if modified.is_err() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let modified_elapsed = match modified.unwrap().elapsed() {
|
|
||||||
Ok(elapsed) => elapsed,
|
|
||||||
Err(_) => continue,
|
|
||||||
};
|
|
||||||
let modified_elapsed_secs = modified_elapsed.as_secs();
|
|
||||||
|
|
||||||
let human_last_modified = if modified_elapsed_secs < 60 {
|
|
||||||
if modified_elapsed_secs < 10 {
|
|
||||||
"just now".to_string()
|
|
||||||
} else {
|
|
||||||
"< 1min".to_string()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
modified_elapsed
|
|
||||||
.human_with_format(
|
|
||||||
match modified_elapsed_secs / 60 {
|
|
||||||
m if m < 60 => Truncate::Minute,
|
|
||||||
m if m < 60 * 36 => Truncate::Hour,
|
|
||||||
m if m < 60 * 24 * 31 => Truncate::Day,
|
|
||||||
m if m < 60 * 24 * 31 * 18 => Truncate::Month,
|
|
||||||
_ => Truncate::Year,
|
|
||||||
},
|
|
||||||
SlimFormatter,
|
|
||||||
)
|
|
||||||
.to_string()
|
|
||||||
.replace(" ", "")
|
|
||||||
+ " ago"
|
|
||||||
};
|
|
||||||
|
|
||||||
save_files.push(SaveFile {
|
|
||||||
name: file_name.to_string(),
|
|
||||||
size: human_bytes(metadata.len() as f64),
|
|
||||||
path: file_path.to_str().unwrap().to_string(),
|
|
||||||
last_modified: human_last_modified,
|
|
||||||
modified_delta: modified_elapsed_secs as usize,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the save files by last modified time
|
|
||||||
save_files.sort_by(|a, b| a.modified_delta.cmp(&b.modified_delta));
|
|
||||||
|
|
||||||
save_files
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
@@ -206,8 +8,8 @@ pub fn run() {
|
|||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
find_save_files,
|
dirs::find_save_files,
|
||||||
choose_best_save_directory
|
dirs::choose_best_save_directory,
|
||||||
])
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
|
|||||||
Reference in New Issue
Block a user