added copy wallpaper functionality

This commit is contained in:
Vomitblood 2024-08-08 03:52:19 +08:00
parent 69332f1655
commit 8f184cb72f
7 changed files with 147 additions and 45 deletions

View file

@ -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<String, String> {
}
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");
}

93
src-tauri/src/fs.rs Normal file
View file

@ -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(|_| ())
}

View file

@ -1 +1,3 @@
pub mod fs;
pub mod paths;
pub mod wallpaper;

View file

@ -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");
}

20
src-tauri/src/paths.rs Normal file
View file

@ -0,0 +1,20 @@
pub fn get_app_data_dir() -> Result<std::path::PathBuf, String> {
// 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()),
}
}

View file

@ -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<String, String> {
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<bool, String> {
.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<String, String> {
file_path
.extension()
.and_then(|extension| extension.to_str())
.map(|extension| extension.to_lowercase())
.ok_or_else(|| "Failed to get file extension".to_string())
}

View file

@ -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);
}