Add Move File functionality and endpoint

This commit is contained in:
Cameron Cordes
2024-01-21 21:10:13 -05:00
parent 2f9ad6b24f
commit 419dd7e7e5
3 changed files with 106 additions and 30 deletions

View File

@@ -1,17 +1,19 @@
use std::fmt::Debug;
use std::fs::read_dir;
use std::io;
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
use ::anyhow;
use anyhow::{anyhow, Context};
use actix_web::web::Data;
use actix_web::{
web::{self, Query},
HttpResponse,
};
use log::{debug, error};
use log::{debug, error, info};
use crate::data::{Claims, FilesRequest, FilterMode, PhotosResponse};
use crate::AppState;
@@ -19,6 +21,7 @@ use crate::AppState;
use crate::error::IntoHttpError;
use crate::tags::TagDao;
use path_absolutize::*;
use serde::Deserialize;
pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
_: Claims,
@@ -182,8 +185,49 @@ fn is_path_above_base_dir<P: AsRef<Path> + Debug>(
)
}
pub async fn move_file<FS: FileSystemAccess>(
_: Claims,
file_system: web::Data<FS>,
app_state: Data<AppState>,
request: web::Json<MoveFileRequest>,
) -> HttpResponse {
match is_valid_full_path(&app_state.base_path, &request.source, false)
.and_then(|source| {
is_valid_full_path(&app_state.base_path, &request.destination, true)
.map(|dest| (source, dest))
})
.ok_or(ErrorKind::InvalidData)
.map(|(source, dest)| file_system.move_file(source, dest))
{
Ok(_) => {
info!("Moved file: {} -> {}", request.source, request.destination,);
HttpResponse::Ok().finish()
}
Err(e) => {
error!(
"Error moving file: {} to: {}. {}",
request.source, request.destination, e
);
if e == ErrorKind::InvalidData {
HttpResponse::BadRequest().finish()
} else {
HttpResponse::InternalServerError().finish()
}
}
}
}
#[derive(Deserialize)]
pub struct MoveFileRequest {
source: String,
destination: String,
}
pub trait FileSystemAccess {
fn get_files_for_path(&self, path: &str) -> anyhow::Result<Vec<PathBuf>>;
fn move_file<P: AsRef<Path>>(&self, from: P, destination: P) -> anyhow::Result<()>;
}
pub struct RealFileSystem {
@@ -205,6 +249,17 @@ impl FileSystemAccess for RealFileSystem {
})
.context("Invalid path")
}
fn move_file<P: AsRef<Path>>(&self, from: P, destination: P) -> anyhow::Result<()> {
let name = from
.as_ref()
.file_name()
.map(|n| n.to_str().unwrap_or_default().to_string())
.unwrap_or_default();
std::fs::rename(from, destination)
.with_context(|| format!("Failed to move file: {:?}", name))
}
}
#[cfg(test)]
@@ -248,6 +303,10 @@ mod tests {
}
}
}
fn move_file<P: AsRef<Path>>(&self, from: P, destination: P) -> anyhow::Result<()> {
todo!()
}
}
mod api {