diff --git a/Cargo.toml b/Cargo.toml index a561c0c..d55bb6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,8 +37,9 @@ winit = "0.30.0" # load icon image = "0.25.1" # load icon copypasta = "0.10.1" # copy to clipboard -winapi = "0.3.9" +winapi = { version = "0.3.9", features = ["wincon"] } windows = { version = "0.56.0", features = ["Win32", "Win32_UI", "Win32_UI_WindowsAndMessaging"]} +homedir = "0.3.4" [build-dependencies] winres = "0.1" # give the exe an icon diff --git a/src/cli.rs b/src/cli.rs index 43bb03a..8c71a34 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,7 @@ +use crate::portable; use clap::Parser; +use homedir; +use std::fs; use std::fs::File; use std::io::{Read, Write}; use std::{env, path::PathBuf, process::Command}; @@ -177,6 +180,11 @@ If you'd like help, take a screenshot of this message and your recipe and come o Some(arg) => arg, None => "".to_string(), }; + // Fix scoping issues + let ini_path: PathBuf; + let home_dir: PathBuf; + let mut config_path: PathBuf = Default::default(); + let mut local_path: PathBuf = Default::default(); let current_exe = env::current_exe().expect("Could not determine exe"); let current_exe_path = current_exe @@ -187,17 +195,17 @@ If you'd like help, take a screenshot of this message and your recipe and come o .parent() .expect("Could not get directory of directory's executable??"); - let mut last_args = current_exe_path_dir.join("last_args.txt"); + let mut last_args = portable::get_last_args_path(); + if !last_args.exists() { if File::create(&last_args).is_err() { - panic!("Failed to create last_args.txt at {current_exe_path_dir:?}") + panic!("Failed to create last_args.txt at {last_args:?}") }; } match first_arg.as_ref() { "enc" | "encoding" | "presets" | "encpresets" | "macros" => { - let presets_path = current_exe_path.join("..").join("encoding_presets.ini"); - + let presets_path = portable::get_encoding_presets_path(); if !presets_path.exists() { panic!( "Could not find encoding presets (expected at {})", @@ -207,8 +215,8 @@ If you'd like help, take a screenshot of this message and your recipe and come o let ini_path = presets_path.canonicalize().unwrap().display().to_string(); - match opener::open(&ini_path){ - Ok(()) =>{ + match opener::open(&ini_path) { + Ok(()) => { std::process::exit(0); } Err(e) => { @@ -217,7 +225,7 @@ If you'd like help, take a screenshot of this message and your recipe and come o } } "def" | "default" | "defaults" => { - let presets_path = current_exe_path.join("..").join("defaults.ini"); + let presets_path = portable::get_defaults_path(); if !presets_path.exists() { panic!( @@ -228,9 +236,8 @@ If you'd like help, take a screenshot of this message and your recipe and come o let ini_path = presets_path.canonicalize().unwrap().display().to_string(); - - match opener::open(&ini_path){ - Ok(()) =>{ + match opener::open(&ini_path) { + Ok(()) => { std::process::exit(0); } Err(e) => { @@ -239,22 +246,21 @@ If you'd like help, take a screenshot of this message and your recipe and come o } } "rc" | "recipe" | "conf" | "config" => { - let ini_path = current_exe_path.join("..").join("recipe.ini"); - + let ini_path = portable::get_recipe_path(); if !ini_path.exists() { panic!("Could not find recipe at {}", ini_path.display()) } let ini_path = ini_path.canonicalize().unwrap().display().to_string(); - match opener::open(&ini_path){ - Ok(()) =>{ + match opener::open(&ini_path) { + Ok(()) => { std::process::exit(0); } Err(e) => { panic!("Error {e}\n\nFailed opening file {:?}", ini_path); } - } + } } "root" | "dir" | "folder" => { if cfg!(target_os = "windows") { diff --git a/src/main.rs b/src/main.rs index f3b3e5d..312853b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ mod smgui; // mod ffpb; // mod ffpb2; mod parse; +mod portable; mod recipe; mod render; mod utils; diff --git a/src/parse.rs b/src/parse.rs index 2cc58bb..829526b 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,11 +1,11 @@ use crate::cli::Arguments; +use crate::portable; use crate::recipe::{parse_recipe, Recipe}; use crate::verb; use color_eyre::owo_colors::OwoColorize; use colored::Colorize; use serde::Deserialize; use std::env; -use std::env::current_exe; use std::time::Duration; use ureq::{Agent, Error as uReqError}; @@ -18,19 +18,12 @@ pub fn parse_encoding_args(args: &Arguments, rc: &Recipe) -> String { let mut enc_arg_presets: Recipe = Recipe::new(); parse_recipe( - current_exe() - .expect("Failed getting exe path") - .parent() - .expect("Failed getting exe parent path") - .parent() - .unwrap() - .join("encoding_presets.ini"), + portable::get_encoding_presets_path(), None, &mut enc_arg_presets, &mut None, false, ); - // dbg!(&enc_arg_presets); let mut codec = String::new(); // e.g H264, H265 let mut ret = String::new(); diff --git a/src/portable.rs b/src/portable.rs new file mode 100644 index 0000000..e00861e --- /dev/null +++ b/src/portable.rs @@ -0,0 +1,87 @@ +use std::{env, path::PathBuf, fs}; +use homedir; + +const DEFAULT_RECIPE: &str = include_str!("../target/recipe.ini"); +const DEFAULT_ENCODING_PRESETS: &str = include_str!("../target/encoding_presets.ini"); + +fn get_target_path() -> PathBuf { + let current_exe = env::current_exe().expect("Could not determine exe"); + let target_dir = current_exe.parent() + .expect("Could not get directory of executable") + .parent() + .expect("Could not get directory of directory's executable??"); + return target_dir.to_path_buf(); +} + +fn is_portable() -> bool { + let portable = get_target_path().join("linux-portable-enable"); + return portable.exists(); +} + +pub fn get_config_path() -> PathBuf { + let config_path: PathBuf; + + if cfg!(target_os = "windows") || is_portable() { + config_path = get_target_path(); + } else { + let home_dir = homedir::my_home() + .unwrap() + .expect("How do you not have a user dir?"); + config_path = home_dir.join(".config/smoothie-rs"); + if !config_path.exists() { + fs::create_dir_all(&config_path) + .expect("Failed to create config folder"); + } + } + + return config_path; +} + +pub fn get_recipe_path_custom(recipe_name : &str) -> PathBuf { + let recipe_path = get_config_path().join(recipe_name); + return recipe_path; +} + +pub fn get_recipe_path() -> PathBuf { + let recipe_path = get_recipe_path_custom("recipe.ini"); + if !recipe_path.exists() { + fs::write(&recipe_path, DEFAULT_RECIPE).unwrap(); + } + return recipe_path; +} + +pub fn get_encoding_presets_path() -> PathBuf { + let encoding_presets_path = get_config_path().join("encoding_presets.ini"); + if !encoding_presets_path.exists() { + fs::write(&encoding_presets_path, DEFAULT_ENCODING_PRESETS).unwrap(); + } + return encoding_presets_path; +} + +pub fn get_defaults_path() -> PathBuf { + return get_target_path().join("defaults.ini"); +} + +pub fn get_last_args_path() -> PathBuf { + let last_args: PathBuf; + + if cfg!(target_os = "windows") || is_portable() { + last_args = get_target_path() + .join("last_args.txt"); + } else { + let home_dir = homedir::my_home() + .unwrap() + .expect("How do you not have a user dir?"); + last_args = home_dir.join(".local/share/smoothie-rs/last_args.txt"); + if !last_args.exists() { + fs::create_dir_all( + last_args + .parent() + .unwrap()) + .expect("Failed to create local folder" + ); + } + } + + return last_args; +} diff --git a/src/recipe.rs b/src/recipe.rs index 1056c6c..c51690a 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -1,6 +1,7 @@ use crate::cli::Arguments; use crate::verb; use crate::{NO, YES}; +use crate::portable; use indexmap::map::Entry; use indexmap::map::IndexMap; use indexmap::map::Keys; @@ -397,7 +398,7 @@ pub fn get_recipe(args: &mut Arguments) -> (Recipe, WidgetMetadata) { let rc_path = if PathBuf::from(&args.recipe).exists() { PathBuf::from(&args.recipe) } else { - let cur_dir_rc = bin_dir.join(&args.recipe); + let cur_dir_rc = portable::get_recipe_path_custom(&args.recipe); if !cur_dir_rc.exists() { panic!( "Recipe filepath does not exist (expected at {})",