Newer
Older
use crate::static_files::upload::*;
use crate::website::WebSite;
use actix_multipart::Multipart;
use actix_web::{
delete, get, post, web,
web::{Data, Path},
HttpResponse, Responder,
};
use futures::StreamExt;
use std::{
fs::{remove_file, File},
io::Write,
pub async fn favicon(website: web::Data<RwLock<WebSite>>) -> impl Responder {
NamedFile::open(
&website
.read()
.unwrap()
.static_files_manager
.dir
.join("default")
.join("favicon.ico"),
)
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
fn upload_data_from_multipart_field(
field: &actix_multipart::Field,
) -> Result<UploadFileData, String> {
match field.content_disposition().get_filename() {
Some(fname) => match file_ext(&fname.to_string()) {
Ok(ext) => Ok(UploadFileData {
up_type: upload_type_from_file_ext(&ext),
filename: fname.to_owned(),
}),
Err(msg) => return Err(msg),
},
None => Err("Couldn't retrieve file extension".to_string()),
}
}
async fn write_uploaded_file(
website: &WebSite,
field: &mut actix_multipart::Field,
filename: &String,
upload_type: UploadFileType,
) -> Result<String, String> {
let root = &website.static_files_manager.dir;
let sub_dir = dirname_from_type(&upload_type);
let filepath = root.join(sub_dir).join(&filename);
match File::create(&filepath) {
Err(e) => Err(format!("Error creating file {:?} : {:?}", filepath, e)),
Ok(mut f) => {
// Field in turn is stream of *Bytes* object
while let Some(chunk) = field.next().await {
match chunk {
Ok(chunk) => {
if f.write_all(&chunk).is_err() {
remove_file(&filepath).unwrap();
return Err("Error writing chunk".to_string());
}
}
Err(e) => {
return Err(format!("Error writing file {} : {:?}", filename, e));
}
}
}
Ok(filepath.into_os_string().into_string().unwrap())
}
}
}
#[post("/post-files")]
pub async fn post_files(website: Data<RwLock<WebSite>>, mut payload: Multipart) -> impl Responder {
let mut website = website
.write()
.expect("Couldn't acquire write lock for RwLock<WebSite");
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
while let Some(item) = payload.next().await {
match item {
Ok(mut field) => {
let up_data = upload_data_from_multipart_field(&field);
if let Err(msg) = up_data {
return HttpResponse::InternalServerError().body(msg);
}
let up_data = up_data.unwrap();
match write_uploaded_file(&website, &mut field, &up_data.filename, up_data.up_type)
.await
{
Err(msg) => return HttpResponse::InternalServerError().body(msg),
Ok(filepath) => uploaded_filepathes.extend(
website
.static_files_manager
.push_path(std::path::Path::new(&filepath)),
),
}
}
Err(e) => {
return HttpResponse::InternalServerError().body(format!("FIELD ERR {:?}", e))
}
}
}
HttpResponse::Ok().json(uploaded_filepathes)
}
#[get("/static-files-index")]
async fn get_static_files_index(website: Data<RwLock<WebSite>>) -> impl Responder {
HttpResponse::Ok().json(website.read().unwrap().static_files_manager.get_index())
}
#[delete("/delete-file/{category}/{filename}")]
async fn delete_static_file(
fileinfo: Path<(String, String)>,
) -> impl Responder {
let mut website = website
.write()
.expect("Couldn't acquire write lock for RwLock<WebSite");
let (cat, fname) = fileinfo.into_inner();
let fpath = std::path::PathBuf::from(cat).join(fname);
match remove_file(website.static_files_manager.dir.join(&fpath)) {
Ok(_) => {
website
.static_files_manager
.remove_path(fpath.to_string_lossy().into());
HttpResponse::Accepted().body("File was deleted")
}
Err(e) => HttpResponse::InternalServerError().body(format!("Error deleting file {:?}", e)),
}
}