use std::io::Error;
use std::path::Path;
use crate::Session;
use actix_web::web;
use actix_web::HttpResponse;
use async_stream::__private::AsyncStream;
use async_stream::try_stream;
use bytes::Bytes;
use std::io::Write;
use uuid::Uuid;
use actix_multipart::Multipart;
use futures::{StreamExt, TryStreamExt};
pub async fn save_local_file(
mut payload: Multipart,
file_path: &Path,
) -> Result<Option<(bool, String)>, Error> {
let mut upload_path: String = "".to_string();
while let Ok(Some(mut field)) = payload.try_next().await {
let content_type = field.content_disposition();
let filename = content_type.get_filename().unwrap_or("");
let uid = Uuid::new_v4().to_string();
let new_name = format!("{}-{}", uid, filename);
let filepath = file_path.join(new_name);
upload_path = filepath.to_str().unwrap().to_string();
let mut f = web::block(|| std::fs::File::create(filepath))
.await
.unwrap()?;
while let Some(chunk) = field.next().await {
let data = chunk.unwrap();
f = web::block(move || f.write_all(&data).map(|_| f))
.await
.unwrap()?;
}
}
println!("file {}", upload_path);
Ok(Some((true, upload_path)))
}
pub async fn save_remote_file(
mut payload: Multipart,
sessiopn: &Session,
file_path: &Path,
) -> Result<Option<(bool, String)>, Error> {
let mut return_write: Vec<Vec<u8>> = vec![];
let mut file_name = String::new();
while let Ok(Some(mut field)) = payload.try_next().await {
let content_type = field.content_disposition();
let filename = content_type.get_filename().unwrap();
let uid = Uuid::new_v4().to_string();
let new_name = format!("{}-{}", uid, filename);
file_name = file_path.join(new_name).to_str().unwrap().to_string();
while let Some(chunk) = field.next().await {
return_write.push(chunk.unwrap()[..].to_vec());
}
}
let flattened = return_write.into_iter().flatten().collect::<Vec<u8>>();
let mut remote_file =
sessiopn.scp_send(Path::new(&file_name), 0o644, flattened.len() as u64, None)?;
remote_file.write_all(&flattened)?;
remote_file.send_eof()?;
remote_file.wait_eof()?;
remote_file.close()?;
remote_file.wait_close()?;
Ok(Some((true, file_name)))
}
pub fn buffer_response(mut x: Vec<u8>) -> HttpResponse {
if x.len() <= 4096 {
HttpResponse::Ok().body(x)
} else {
let stream: AsyncStream<Result<Bytes, Error>, _> = try_stream! {
loop{
if x.len()>4096{
let u:Vec<u8>=x.drain(0..4096).collect();
yield Bytes::copy_from_slice(&u[..4096]);
}else{
let u:Vec<u8>=std::mem::take(&mut x);
if u.is_empty(){
break
}
yield Bytes::copy_from_slice(&u[..u.len()]);
}
}
};
HttpResponse::Ok().streaming(stream)
}
}