2
0
Fork 0
mirror of https://git.asonix.dog/asonix/pict-rs synced 2024-11-14 00:13:59 +00:00

Remove unneeded mime conversions

This commit is contained in:
Aode (lion) 2021-10-23 12:35:07 -05:00
parent e720ed6af2
commit 6f04595c3b
5 changed files with 62 additions and 73 deletions

View file

@ -140,14 +140,6 @@ pub(crate) enum Format {
} }
impl Format { impl Format {
pub(crate) fn to_mime(&self) -> mime::Mime {
match self {
Format::Jpeg => mime::IMAGE_JPEG,
Format::Png => mime::IMAGE_PNG,
Format::Webp => "image/webp".parse().unwrap(),
}
}
pub(crate) fn to_magick_format(&self) -> &'static str { pub(crate) fn to_magick_format(&self) -> &'static str {
match self { match self {
Format::Jpeg => "JPEG", Format::Jpeg => "JPEG",

View file

@ -19,7 +19,15 @@ pub(crate) fn details_hint(filename: &str) -> Option<ValidInputType> {
} }
} }
#[derive(Debug)] pub(crate) fn image_webp() -> mime::Mime {
"image/webp".parse().unwrap()
}
pub(crate) fn video_mp4() -> mime::Mime {
"video/mp4".parse().unwrap()
}
#[derive(Copy, Clone, Debug)]
pub(crate) enum ValidInputType { pub(crate) enum ValidInputType {
Mp4, Mp4,
Gif, Gif,
@ -38,6 +46,24 @@ impl ValidInputType {
Self::Webp => "WEBP", Self::Webp => "WEBP",
} }
} }
pub(crate) fn to_ext(&self) -> &'static str {
match self {
Self::Mp4 => ".mp4",
Self::Gif => ".gif",
Self::Png => ".png",
Self::Jpeg => ".jpeg",
Self::Webp => ".webp",
}
}
pub(crate) fn from_format(format: Format) -> Self {
match format {
Format::Jpeg => ValidInputType::Jpeg,
Format::Png => ValidInputType::Png,
Format::Webp => ValidInputType::Webp,
}
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -157,11 +183,11 @@ fn parse_details(s: std::borrow::Cow<'_, str>) -> Result<Details, Error> {
} }
let mime_type = match format { let mime_type = match format {
"MP4" => crate::validate::video_mp4(), "MP4" => video_mp4(),
"GIF" => mime::IMAGE_GIF, "GIF" => mime::IMAGE_GIF,
"PNG" => mime::IMAGE_PNG, "PNG" => mime::IMAGE_PNG,
"JPEG" => mime::IMAGE_JPEG, "JPEG" => mime::IMAGE_JPEG,
"WEBP" => crate::validate::image_webp(), "WEBP" => image_webp(),
_ => return Err(UploadError::UnsupportedFormat.into()), _ => return Err(UploadError::UnsupportedFormat.into()),
}; };

View file

@ -52,7 +52,6 @@ use self::{
migrate::LatestDb, migrate::LatestDb,
store::Store, store::Store,
upload_manager::{Details, UploadManager, UploadManagerSession}, upload_manager::{Details, UploadManager, UploadManagerSession},
validate::{image_webp, video_mp4},
}; };
const MEGABYTES: usize = 1024 * 1024; const MEGABYTES: usize = 1024 * 1024;
@ -740,7 +739,7 @@ where
.transform_error(transform_error) .transform_error(transform_error)
.field( .field(
"images", "images",
Field::array(Field::file(move |filename, content_type, stream| { Field::array(Field::file(move |filename, _, stream| {
let manager = manager2.clone(); let manager = manager2.clone();
let span = tracing::info_span!("file-import", ?filename); let span = tracing::info_span!("file-import", ?filename);
@ -752,7 +751,6 @@ where
.session() .session()
.import( .import(
filename, filename,
content_type,
validate_imports, validate_imports,
map_error::map_crate_error(stream), map_error::map_crate_error(stream),
) )
@ -837,7 +835,6 @@ async fn main() -> anyhow::Result<()> {
let manager = UploadManager::new(store, db, CONFIG.format()).await?; let manager = UploadManager::new(store, db, CONFIG.format()).await?;
// TODO: move restructure to FileStore
manager.restructure().await?; manager.restructure().await?;
launch(manager).await launch(manager).await
} }

View file

@ -1,5 +1,6 @@
use crate::{ use crate::{
error::{Error, UploadError}, error::{Error, UploadError},
magick::ValidInputType,
migrate::{alias_id_key, alias_key}, migrate::{alias_id_key, alias_key},
store::Store, store::Store,
upload_manager::{ upload_manager::{
@ -142,7 +143,6 @@ where
pub(crate) async fn import( pub(crate) async fn import(
mut self, mut self,
alias: String, alias: String,
content_type: mime::Mime,
validate: bool, validate: bool,
mut stream: impl Stream<Item = Result<web::Bytes, Error>> + Unpin, mut stream: impl Stream<Item = Result<web::Bytes, Error>> + Unpin,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
@ -197,7 +197,7 @@ where
} }
debug!("Validating bytes"); debug!("Validating bytes");
let (content_type, validated_reader) = crate::validate::validate_image_bytes( let (input_type, validated_reader) = crate::validate::validate_image_bytes(
bytes_mut.freeze(), bytes_mut.freeze(),
self.manager.inner.format.clone(), self.manager.inner.format.clone(),
true, true,
@ -214,10 +214,10 @@ where
let hash = hasher_reader.finalize_reset().await?; let hash = hasher_reader.finalize_reset().await?;
debug!("Adding alias"); debug!("Adding alias");
self.add_alias(&hash, content_type.clone()).await?; self.add_alias(&hash, input_type).await?;
debug!("Saving file"); debug!("Saving file");
self.save_upload(&identifier, hash, content_type).await?; self.save_upload(&identifier, hash, input_type).await?;
// Return alias to file // Return alias to file
Ok(self) Ok(self)
@ -228,9 +228,9 @@ where
&self, &self,
identifier: &S::Identifier, identifier: &S::Identifier,
hash: Hash, hash: Hash,
content_type: mime::Mime, input_type: ValidInputType,
) -> Result<(), Error> { ) -> Result<(), Error> {
let (dup, name) = self.check_duplicate(hash, content_type).await?; let (dup, name) = self.check_duplicate(hash, input_type).await?;
// bail early with alias to existing file if this is a duplicate // bail early with alias to existing file if this is a duplicate
if dup.exists() { if dup.exists() {
@ -246,15 +246,15 @@ where
} }
// check for an already-uploaded image with this hash, returning the path to the target file // check for an already-uploaded image with this hash, returning the path to the target file
#[instrument(skip(self, hash, content_type))] #[instrument(skip(self, hash, input_type))]
async fn check_duplicate( async fn check_duplicate(
&self, &self,
hash: Hash, hash: Hash,
content_type: mime::Mime, input_type: ValidInputType,
) -> Result<(Dup, String), Error> { ) -> Result<(Dup, String), Error> {
let main_tree = self.manager.inner.main_tree.clone(); let main_tree = self.manager.inner.main_tree.clone();
let filename = self.next_file(content_type).await?; let filename = self.next_file(input_type).await?;
let filename2 = filename.clone(); let filename2 = filename.clone();
let hash2 = hash.as_slice().to_vec(); let hash2 = hash.as_slice().to_vec();
@ -287,11 +287,11 @@ where
} }
// generate a short filename that isn't already in-use // generate a short filename that isn't already in-use
#[instrument(skip(self, content_type))] #[instrument(skip(self, input_type))]
async fn next_file(&self, content_type: mime::Mime) -> Result<String, Error> { async fn next_file(&self, input_type: ValidInputType) -> Result<String, Error> {
loop { loop {
debug!("Filename generation loop"); debug!("Filename generation loop");
let filename = file_name(Uuid::new_v4(), content_type.clone())?; let filename = file_name(Uuid::new_v4(), input_type);
let identifier_tree = self.manager.inner.identifier_tree.clone(); let identifier_tree = self.manager.inner.identifier_tree.clone();
let filename2 = filename.clone(); let filename2 = filename.clone();
@ -319,9 +319,9 @@ where
// Add an alias to an existing file // Add an alias to an existing file
// //
// This will help if multiple 'users' upload the same file, and one of them wants to delete it // This will help if multiple 'users' upload the same file, and one of them wants to delete it
#[instrument(skip(self, hash, content_type))] #[instrument(skip(self, hash, input_type))]
async fn add_alias(&mut self, hash: &Hash, content_type: mime::Mime) -> Result<(), Error> { async fn add_alias(&mut self, hash: &Hash, input_type: ValidInputType) -> Result<(), Error> {
let alias = self.next_alias(hash, content_type).await?; let alias = self.next_alias(hash, input_type).await?;
self.store_hash_id_alias_mapping(hash, &alias).await?; self.store_hash_id_alias_mapping(hash, &alias).await?;
@ -365,11 +365,15 @@ where
} }
// Generate an alias to the file // Generate an alias to the file
#[instrument(skip(self, hash, content_type))] #[instrument(skip(self, hash, input_type))]
async fn next_alias(&mut self, hash: &Hash, content_type: mime::Mime) -> Result<String, Error> { async fn next_alias(
&mut self,
hash: &Hash,
input_type: ValidInputType,
) -> Result<String, Error> {
loop { loop {
debug!("Alias gen loop"); debug!("Alias gen loop");
let alias = file_name(Uuid::new_v4(), content_type.clone())?; let alias = file_name(Uuid::new_v4(), input_type);
self.alias = Some(alias.clone()); self.alias = Some(alias.clone());
let res = self.save_alias_hash_mapping(hash, &alias).await?; let res = self.save_alias_hash_mapping(hash, &alias).await?;
@ -407,20 +411,6 @@ where
} }
} }
fn file_name(name: Uuid, content_type: mime::Mime) -> Result<String, Error> { fn file_name(name: Uuid, input_type: ValidInputType) -> String {
Ok(format!("{}{}", name, to_ext(content_type)?)) format!("{}{}", name, input_type.to_ext())
}
fn to_ext(mime: mime::Mime) -> Result<&'static str, Error> {
if mime == mime::IMAGE_PNG {
Ok(".png")
} else if mime == mime::IMAGE_JPEG {
Ok(".jpg")
} else if mime == crate::video_mp4() {
Ok(".mp4")
} else if mime == crate::image_webp() {
Ok(".webp")
} else {
Err(UploadError::UnsupportedFormat.into())
}
} }

View file

@ -5,14 +5,6 @@ use actix_web::web::Bytes;
use tokio::io::AsyncRead; use tokio::io::AsyncRead;
use tracing::instrument; use tracing::instrument;
pub(crate) fn image_webp() -> mime::Mime {
"image/webp".parse().unwrap()
}
pub(crate) fn video_mp4() -> mime::Mime {
"video/mp4".parse().unwrap()
}
struct UnvalidatedBytes { struct UnvalidatedBytes {
bytes: Bytes, bytes: Bytes,
written: usize, written: usize,
@ -45,56 +37,48 @@ pub(crate) async fn validate_image_bytes(
bytes: Bytes, bytes: Bytes,
prescribed_format: Option<Format>, prescribed_format: Option<Format>,
validate: bool, validate: bool,
) -> Result<(mime::Mime, impl AsyncRead + Unpin), Error> { ) -> Result<(ValidInputType, impl AsyncRead + Unpin), Error> {
let input_type = crate::magick::input_type_bytes(bytes.clone()).await?; let input_type = crate::magick::input_type_bytes(bytes.clone()).await?;
if !validate { if !validate {
let mime_type = match input_type { return Ok((input_type, Either::left(UnvalidatedBytes::new(bytes))));
ValidInputType::Gif => video_mp4(),
ValidInputType::Mp4 => mime::IMAGE_GIF,
ValidInputType::Jpeg => mime::IMAGE_JPEG,
ValidInputType::Png => mime::IMAGE_PNG,
ValidInputType::Webp => image_webp(),
};
return Ok((mime_type, Either::left(UnvalidatedBytes::new(bytes))));
} }
match (prescribed_format, input_type) { match (prescribed_format, input_type) {
(_, ValidInputType::Gif) => Ok(( (_, ValidInputType::Gif) => Ok((
video_mp4(), ValidInputType::Mp4,
Either::right(Either::left(crate::ffmpeg::to_mp4_bytes( Either::right(Either::left(crate::ffmpeg::to_mp4_bytes(
bytes, bytes,
InputFormat::Gif, InputFormat::Gif,
)?)), )?)),
)), )),
(_, ValidInputType::Mp4) => Ok(( (_, ValidInputType::Mp4) => Ok((
video_mp4(), ValidInputType::Mp4,
Either::right(Either::left(crate::ffmpeg::to_mp4_bytes( Either::right(Either::left(crate::ffmpeg::to_mp4_bytes(
bytes, bytes,
InputFormat::Mp4, InputFormat::Mp4,
)?)), )?)),
)), )),
(Some(Format::Jpeg) | None, ValidInputType::Jpeg) => Ok(( (Some(Format::Jpeg) | None, ValidInputType::Jpeg) => Ok((
mime::IMAGE_JPEG, ValidInputType::Jpeg,
Either::right(Either::right(Either::left( Either::right(Either::right(Either::left(
crate::exiftool::clear_metadata_bytes_read(bytes)?, crate::exiftool::clear_metadata_bytes_read(bytes)?,
))), ))),
)), )),
(Some(Format::Png) | None, ValidInputType::Png) => Ok(( (Some(Format::Png) | None, ValidInputType::Png) => Ok((
mime::IMAGE_PNG, ValidInputType::Png,
Either::right(Either::right(Either::left( Either::right(Either::right(Either::left(
crate::exiftool::clear_metadata_bytes_read(bytes)?, crate::exiftool::clear_metadata_bytes_read(bytes)?,
))), ))),
)), )),
(Some(Format::Webp) | None, ValidInputType::Webp) => Ok(( (Some(Format::Webp) | None, ValidInputType::Webp) => Ok((
image_webp(), ValidInputType::Webp,
Either::right(Either::right(Either::right(Either::left( Either::right(Either::right(Either::right(Either::left(
crate::magick::clear_metadata_bytes_read(bytes)?, crate::magick::clear_metadata_bytes_read(bytes)?,
)))), )))),
)), )),
(Some(format), _) => Ok(( (Some(format), _) => Ok((
format.to_mime(), ValidInputType::from_format(format),
Either::right(Either::right(Either::right(Either::right( Either::right(Either::right(Either::right(Either::right(
crate::magick::convert_bytes_read(bytes, format)?, crate::magick::convert_bytes_read(bytes, format)?,
)))), )))),