From 8f184cb72fe2b0103f04bdcd137786698dd0bfab Mon Sep 17 00:00:00 2001 From: Vomitblood Date: Thu, 8 Aug 2024 03:52:19 +0800 Subject: [PATCH] added copy wallpaper functionality --- src-tauri/src/bin/testing.rs | 26 ++-------- src-tauri/src/fs.rs | 93 ++++++++++++++++++++++++++++++++++++ src-tauri/src/lib.rs | 2 + src-tauri/src/main.rs | 6 +-- src-tauri/src/paths.rs | 20 ++++++++ src-tauri/src/wallpaper.rs | 42 ++++++++-------- src/pages/testing.tsx | 3 +- 7 files changed, 147 insertions(+), 45 deletions(-) create mode 100644 src-tauri/src/fs.rs create mode 100644 src-tauri/src/paths.rs diff --git a/src-tauri/src/bin/testing.rs b/src-tauri/src/bin/testing.rs index 6ad8553..2f6ae0a 100644 --- a/src-tauri/src/bin/testing.rs +++ b/src-tauri/src/bin/testing.rs @@ -1,3 +1,5 @@ +use app::fs::move_file; + #[derive(Debug, PartialEq)] enum ImageType { Jpeg, @@ -87,26 +89,8 @@ fn process_wallpaper_image(file_path_string: String) -> Result { } fn main() { - // Example usage - let path = std::path::Path::new("/home/vomitblood/Downloads/background.jpg"); - match determine_image_type(path) { - Ok(image_type) => { - // convert the image type to a string extension for printing - let extension = match image_type { - ImageType::Jpeg => "jpeg", - ImageType::Png => "png", - ImageType::Gif => "gif", - ImageType::WebP => "webp", - ImageType::AnimatedWebP => "webp", - ImageType::Unsupported => "", - }; - println!("Image extension: {extension}"); - } - Err(e) => println!("Error determining image type: {e}"), - } + let target_path = std::path::Path::new("/home/vomitblood/Downloads/asdf.csv"); + let destination_path = std::path::Path::new("/home/vomitblood/Downloads/asdf2.csv"); - match get_file_extension(path) { - Ok(extension) => println!("File extension: {extension}"), - Err(e) => println!("Error getting file extension: {e}"), - } + move_file(target_path, destination_path, true).expect("Failed to move file"); } diff --git a/src-tauri/src/fs.rs b/src-tauri/src/fs.rs new file mode 100644 index 0000000..d98d382 --- /dev/null +++ b/src-tauri/src/fs.rs @@ -0,0 +1,93 @@ +pub fn move_file( + target: &std::path::Path, + destination: &std::path::Path, + create_dirs: bool, +) -> std::io::Result<()> { + // check if the target file exists + if !target.exists() { + return Err(std::io::Error::new( + std::io::ErrorKind::NotFound, + format!("Source file not found: {:?}", target), + )); + } + + // determine the final destination path + let final_destination = if destination.is_dir() { + // if the destination is a directory, then append the target file name to the destination path + let mut dest_path = destination.to_path_buf(); + if let Some(file_name) = target.file_name() { + dest_path.push(file_name); + } + dest_path + } else { + // if destination is already a file path, then use it directly + destination.to_path_buf() + }; + + // create the necessary directories if the flag is set + if create_dirs { + if let Some(parent) = final_destination.parent() { + std::fs::create_dir_all(parent)?; + } + } + + // attempt to rename (move) the file + match std::fs::rename(target, &final_destination) { + Ok(_) => Ok(()), + Err(e) => { + eprintln!("Failed to rename file: {:?}. Trying fallback method...", e); + // if rename fails, try to copy the file instead + if let Err(copy_error) = std::fs::copy(target, &final_destination) { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Failed to copy file: {:?}", copy_error), + )); + } + if let Err(remove_error) = std::fs::remove_file(target) { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Failed to remove original file: {:?}", remove_error), + )); + } + Ok(()) + } + } +} + +pub fn copy_file( + target: &std::path::Path, + destination: &std::path::Path, + create_dirs: bool, +) -> std::io::Result<()> { + // check if the target file exists + if !target.exists() { + return Err(std::io::Error::new( + std::io::ErrorKind::NotFound, + format!("Source file not found: {:?}", target), + )); + } + + // determine the final destination path + let final_destination = if destination.is_dir() { + // if the destination is a directory, append the target file name + let mut dest_path = destination.to_path_buf(); + if let Some(file_name) = target.file_name() { + dest_path.push(file_name); + } + dest_path + } else { + // if destination is a file path, use it directly + destination.to_path_buf() + }; + + // create the necessary directories if the flag is set + if create_dirs { + if let Some(parent) = final_destination.parent() { + std::fs::create_dir_all(parent)?; + } + } + + // copy the file + // why need to use map??? + std::fs::copy(target, &final_destination).map(|_| ()) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5a20f26..1f72919 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1 +1,3 @@ +pub mod fs; +pub mod paths; pub mod wallpaper; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 923a243..77073e8 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,11 +1,11 @@ // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] -use app::wallpaper; - fn main() { tauri::Builder::default() - .invoke_handler(tauri::generate_handler![wallpaper::process_wallpaper_image]) + .invoke_handler(tauri::generate_handler![ + app::wallpaper::process_wallpaper_image + ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/src-tauri/src/paths.rs b/src-tauri/src/paths.rs new file mode 100644 index 0000000..de8b5a6 --- /dev/null +++ b/src-tauri/src/paths.rs @@ -0,0 +1,20 @@ +pub fn get_app_data_dir() -> Result { + // attempt to get the app data directory + match tauri::api::path::data_dir() { + Some(data_dir) => { + let app_data_dir = data_dir.join("stort/"); + // ensure the directory exists + if !app_data_dir.exists() { + // attempt to create the directory + std::fs::create_dir_all(&app_data_dir).map_err(|e| { + format!( + "Failed to create app data directory {:?}: {}", + app_data_dir, e + ) + })?; + } + Ok(app_data_dir) + } + None => Err("Failed to get app data directory".to_string()), + } +} diff --git a/src-tauri/src/wallpaper.rs b/src-tauri/src/wallpaper.rs index f5f08cc..c9d1849 100644 --- a/src-tauri/src/wallpaper.rs +++ b/src-tauri/src/wallpaper.rs @@ -10,24 +10,36 @@ enum ImageType { /// function to interface with the tauri api on the javascript side #[tauri::command] -pub fn process_wallpaper_image(file_path_string: String) -> Result { +pub fn process_wallpaper_image(file_path_string: String) -> Result<(), String> { // convert the string to a path let file_path = std::path::Path::new(&file_path_string); - // determine the image type - match determine_image_type(file_path) { + // determine the image type and get the file extension + let file_extension = match determine_image_type(file_path) { Ok(image_type) => match image_type { - ImageType::Jpeg => Ok("jpeg".to_string()), - ImageType::Png => Ok("png".to_string()), - ImageType::Gif => Ok("gif".to_string()), - ImageType::WebP => Ok("webp".to_string()), - ImageType::AnimatedWebP => Ok("webp".to_string()), + ImageType::Jpeg => "jpeg".to_string(), + ImageType::Png => "png".to_string(), + ImageType::Gif => "gif".to_string(), + ImageType::WebP => "webp".to_string(), + ImageType::AnimatedWebP => "webp".to_string(), ImageType::Unsupported => { - Err("Unsupported image type (accepts webp, jpg, jpeg, png, gif)".to_string()) + return Err("Unsupported image type (accepts webp, jpg, jpeg, png, gif)".to_string()) } }, - Err(e) => Err(format!("Error determining image type: {e}")), - } + Err(e) => return Err(format!("Error determining image type: {e}")), + }; + + let app_data_dir = crate::paths::get_app_data_dir() + .map_err(|e| format!("Failed to get app data directory: {e}"))?; + + // construct the destination path + let destination_path = app_data_dir.join(format!("wallpaper.{}", file_extension)); + + // move the file to the destination + crate::fs::copy_file(file_path, &destination_path, true) + .map_err(|e| format!("Failed to move file: {e}"))?; + + Ok(()) } /// determines the image type of a file that is passed in using the filepath @@ -76,11 +88,3 @@ fn is_animated_webp(file_path: &std::path::Path) -> Result { .map(|anim| anim.has_animation()) .map_err(|_| "File is not a valid WebP image".to_string()) } - -fn get_file_extension(file_path: &std::path::Path) -> Result { - file_path - .extension() - .and_then(|extension| extension.to_str()) - .map(|extension| extension.to_lowercase()) - .ok_or_else(|| "Failed to get file extension".to_string()) -} diff --git a/src/pages/testing.tsx b/src/pages/testing.tsx index 7b62afa..6dced9d 100644 --- a/src/pages/testing.tsx +++ b/src/pages/testing.tsx @@ -51,9 +51,8 @@ export default function Testing() { onClick={async () => { try { const bruh = await invoke("process_wallpaper_image", { - filePathString: "/home/vomitblood/Downloads/9fd62bc7_2024-08-07_7.csv", + filePathString: "/home/vomitblood/Downloads/asasdf.gif", }); - console.log(bruh); } catch (error) { console.error("deec nuts", error); }