Compress images only for NIP-96 endpoint
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
kieran 2024-05-14 10:04:42 +01:00
parent 423fbfdb77
commit 8a58cfe825
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
4 changed files with 63 additions and 42 deletions

11
README.md Normal file
View 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

View File

@ -44,32 +44,48 @@ 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 tmp_path = FileStore::map_temp(random_id);
let mut file = File::options()
.create(true)
.write(true)
.read(true)
.open(tmp_path.clone())
.await?;
tokio::io::copy(&mut stream, &mut file).await?;
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 mut file = File::options()
.create(true)
.write(true)
.read(true)
.open(tmp_path.clone())
.await?;
tokio::io::copy(&mut stream, &mut file).await?;
info!("File saved to temp path: {}", tmp_path.to_str().unwrap());
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,30 +105,28 @@ 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)
return Ok(FileSystemResult {
size: n,
sha256: 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 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 {
size: n,
sha256: hash,
path: dst_path,
mime_type,
width,
height,
blur_hash,
})
}
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> {

View File

@ -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) => {

View File

@ -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) => {