file download
This commit is contained in:
@ -0,0 +1,72 @@
|
||||
use std::fs::create_dir;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus::fullstack::FileStream;
|
||||
#[cfg(feature = "server")]
|
||||
use httpserver::models::GetFile;
|
||||
#[cfg(feature = "server")]
|
||||
use diesel::prelude::*;
|
||||
#[cfg(feature = "server")]
|
||||
use httpserver::DB;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
use httpserver::schema;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
use crate::config::ServerConfig;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
async fn create_filestream(filename: String, file: &Path) -> Result<FileStream, std::io::Error> {
|
||||
|
||||
let metadata = file.metadata()?;
|
||||
let contents = tokio::fs::File::open(&file).await?;
|
||||
let mime = dioxus_asset_resolver::native::get_mime_from_ext(
|
||||
file.extension().and_then(|s| s.to_str()),
|
||||
);
|
||||
let size = metadata.len();
|
||||
|
||||
let reader_stream = tokio_util::io::ReaderStream::new(contents);
|
||||
|
||||
let body = axum_core::body::Body::from_stream(reader_stream).into_data_stream();
|
||||
Ok(FileStream::from_raw(filename, Some(size), mime.to_string(), body))
|
||||
}
|
||||
|
||||
#[get("/upload/{id}/dl")]
|
||||
async fn download_file(id: String) -> Result<FileStream, HttpError> {
|
||||
use schema::file;
|
||||
let s_config = ServerConfig::load();
|
||||
|
||||
let result = DB.with(|pool| schema::file::table.select((file::filename))
|
||||
.filter(file::stored_filename.eq(id.clone()))
|
||||
.filter(file::deleted.eq(false))
|
||||
.load::<(String)>(&mut pool.get().unwrap()));
|
||||
|
||||
if let Err(_) = result {
|
||||
return HttpError::internal_server_error("Database request failed");
|
||||
}
|
||||
|
||||
let db_file = result.unwrap();
|
||||
|
||||
if db_file.len() == 0 {
|
||||
return HttpError::internal_server_error("The requested file does not exist");
|
||||
}
|
||||
|
||||
let file_path = s_config.upload_folder + &id;
|
||||
let path = Path::new(&file_path);
|
||||
|
||||
// create a filestream from raw to set the filename to the uploaded filename
|
||||
let fstream = create_filestream(db_file[0].clone(), path.into()).await;
|
||||
|
||||
match fstream {
|
||||
Ok(stream) => {
|
||||
Ok(stream)
|
||||
},
|
||||
Err(err) => {
|
||||
tracing::info!("Failed to open a file err : {err}");
|
||||
HttpError::internal_server_error(format!("Failed to open the file"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ struct FetchedInfo {
|
||||
}
|
||||
|
||||
|
||||
#[post("/api/upload/info")]
|
||||
#[get("/api/upload/info?filename")]
|
||||
async fn get_file_info(filename: String) -> Result<FetchedInfo, HttpError> {
|
||||
use schema::file;
|
||||
let result = DB.with(|pool| schema::file::table.select((file::filename, file::file_size, file::created_at))
|
||||
|
||||
@ -3,3 +3,6 @@ pub use create::UploadFile;
|
||||
|
||||
mod info;
|
||||
pub use info::FileInfo;
|
||||
|
||||
mod get;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user