mirror of
https://github.com/Xevion/factorio-achievements-fixer.git
synced 2025-12-10 10:07:15 -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;
|
||||
use humanize_duration::prelude::DurationExt;
|
||||
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
|
||||
}
|
||||
mod dirs;
|
||||
mod format;
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
@@ -206,8 +8,8 @@ pub fn run() {
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
find_save_files,
|
||||
choose_best_save_directory
|
||||
dirs::find_save_files,
|
||||
dirs::choose_best_save_directory,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
Reference in New Issue
Block a user