Compress images only for NIP-96 endpoint
This commit is contained in:
parent
423fbfdb77
commit
8a58cfe825
11
README.md
Normal file
11
README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# void-cat-rs
|
||||
|
||||
Image hosting service
|
||||
|
||||
## Features
|
||||
- NIP-96 Support
|
||||
- Blossom Support
|
||||
- Image compression to WebP (FFMPEG)
|
||||
|
||||
## Planned
|
||||
- Torrent seed V2
|
@ -44,15 +44,31 @@ impl FileStore {
|
||||
}
|
||||
|
||||
/// Store a new file
|
||||
pub async fn put<TStream>(&self, mut stream: TStream, mime_type: &str) -> Result<FileSystemResult, Error>
|
||||
pub async fn put<TStream>(&self, stream: TStream, mime_type: &str, compress: bool) -> Result<FileSystemResult, Error>
|
||||
where
|
||||
TStream: AsyncRead + Unpin,
|
||||
{
|
||||
let result = self.store_compress_file(stream, mime_type, compress).await?;
|
||||
let dst_path = self.map_path(&result.sha256);
|
||||
fs::create_dir_all(dst_path.parent().unwrap())?;
|
||||
if let Err(e) = fs::copy(&result.path, &dst_path) {
|
||||
fs::remove_file(&result.path)?;
|
||||
Err(Error::from(e))
|
||||
} else {
|
||||
fs::remove_file(result.path)?;
|
||||
Ok(FileSystemResult {
|
||||
path: dst_path,
|
||||
..result
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn store_compress_file<TStream>(&self, mut stream: TStream, mime_type: &str, compress: bool) -> Result<FileSystemResult, Error>
|
||||
where
|
||||
TStream: AsyncRead + Unpin,
|
||||
{
|
||||
let random_id = uuid::Uuid::new_v4();
|
||||
|
||||
let mut mime_type = mime_type.to_string();
|
||||
let (n, hash, tmp_path, width, height, blur_hash) = {
|
||||
let mut tmp_path = FileStore::map_temp(random_id);
|
||||
let tmp_path = FileStore::map_temp(random_id);
|
||||
let mut file = File::options()
|
||||
.create(true)
|
||||
.write(true)
|
||||
@ -63,13 +79,13 @@ impl FileStore {
|
||||
|
||||
info!("File saved to temp path: {}", tmp_path.to_str().unwrap());
|
||||
|
||||
if compress {
|
||||
let start = SystemTime::now();
|
||||
let proc_result = {
|
||||
let mut p_lock = self.processor.lock().expect("asd");
|
||||
p_lock.process_file(tmp_path.clone(), &mime_type)?
|
||||
};
|
||||
if let FileProcessorResult::NewFile(new_temp) = proc_result {
|
||||
mime_type = new_temp.mime_type;
|
||||
let old_size = tmp_path.metadata()?.len();
|
||||
let new_size = new_temp.result.metadata()?.len();
|
||||
info!("Compressed media: ratio={:.2}x, old_size={:.3}kb, new_size={:.3}kb, duration={:.2}ms",
|
||||
@ -89,31 +105,29 @@ impl FileStore {
|
||||
.await?;
|
||||
let n = file.metadata().await?.len();
|
||||
let hash = FileStore::hash_file(&mut file).await?;
|
||||
(n, hash, new_temp.result, Some(new_temp.width), Some(new_temp.height), Some(new_temp.blur_hash))
|
||||
} else {
|
||||
let n = file.metadata().await?.len();
|
||||
let hash = FileStore::hash_file(&mut file).await?;
|
||||
(n, hash, tmp_path, None, None, None)
|
||||
}
|
||||
};
|
||||
let dst_path = self.map_path(&hash);
|
||||
fs::create_dir_all(dst_path.parent().unwrap())?;
|
||||
if let Err(e) = fs::copy(&tmp_path, &dst_path) {
|
||||
fs::remove_file(&tmp_path)?;
|
||||
Err(Error::from(e))
|
||||
} else {
|
||||
fs::remove_file(tmp_path)?;
|
||||
Ok(FileSystemResult {
|
||||
return Ok(FileSystemResult {
|
||||
size: n,
|
||||
sha256: hash,
|
||||
path: dst_path,
|
||||
mime_type,
|
||||
width,
|
||||
height,
|
||||
blur_hash,
|
||||
})
|
||||
path: new_temp.result,
|
||||
width: Some(new_temp.width),
|
||||
height: Some(new_temp.height),
|
||||
blur_hash: Some(new_temp.blur_hash),
|
||||
mime_type: new_temp.mime_type,
|
||||
});
|
||||
}
|
||||
}
|
||||
let n = file.metadata().await?.len();
|
||||
let hash = FileStore::hash_file(&mut file).await?;
|
||||
Ok(FileSystemResult {
|
||||
path: tmp_path,
|
||||
sha256: hash,
|
||||
size: n,
|
||||
mime_type: mime_type.to_string(),
|
||||
width: None,
|
||||
height: None,
|
||||
blur_hash: None,
|
||||
})
|
||||
}
|
||||
|
||||
async fn hash_file(file: &mut File) -> Result<Vec<u8>, Error> {
|
||||
let mut hasher = Sha256::new();
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::sync::{Mutex, RwLock};
|
||||
|
||||
use chrono::Utc;
|
||||
use log::error;
|
||||
use nostr::prelude::hex;
|
||||
@ -108,7 +106,7 @@ async fn upload(
|
||||
.unwrap_or("application/octet-stream".to_string());
|
||||
|
||||
match fs
|
||||
.put(data.open(ByteUnit::from(settings.max_upload_bytes)), &mime_type)
|
||||
.put(data.open(ByteUnit::from(settings.max_upload_bytes)), &mime_type, false)
|
||||
.await
|
||||
{
|
||||
Ok(blob) => {
|
||||
|
@ -1,9 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use chrono::Utc;
|
||||
use rocket::{FromForm, Responder, Route, routes, State};
|
||||
use rocket::data::ByteUnit;
|
||||
use rocket::form::Form;
|
||||
use rocket::fs::TempFile;
|
||||
use rocket::serde::json::Json;
|
||||
@ -161,7 +159,7 @@ async fn upload(
|
||||
let mime_type = form.media_type
|
||||
.unwrap_or("application/octet-stream");
|
||||
match fs
|
||||
.put(file, mime_type)
|
||||
.put(file, mime_type, true)
|
||||
.await
|
||||
{
|
||||
Ok(blob) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user