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 {
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 {
match self {
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 {
Mp4,
Gif,
@ -38,6 +46,24 @@ impl ValidInputType {
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)]
@ -157,11 +183,11 @@ fn parse_details(s: std::borrow::Cow<'_, str>) -> Result<Details, Error> {
}
let mime_type = match format {
"MP4" => crate::validate::video_mp4(),
"MP4" => video_mp4(),
"GIF" => mime::IMAGE_GIF,
"PNG" => mime::IMAGE_PNG,
"JPEG" => mime::IMAGE_JPEG,
"WEBP" => crate::validate::image_webp(),
"WEBP" => image_webp(),
_ => return Err(UploadError::UnsupportedFormat.into()),
};

View file

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

View file

@ -1,5 +1,6 @@
use crate::{
error::{Error, UploadError},
magick::ValidInputType,
migrate::{alias_id_key, alias_key},
store::Store,
upload_manager::{
@ -142,7 +143,6 @@ where
pub(crate) async fn import(
mut self,
alias: String,
content_type: mime::Mime,
validate: bool,
mut stream: impl Stream<Item = Result<web::Bytes, Error>> + Unpin,
) -> Result<Self, Error> {
@ -197,7 +197,7 @@ where
}
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(),
self.manager.inner.format.clone(),
true,
@ -214,10 +214,10 @@ where
let hash = hasher_reader.finalize_reset().await?;
debug!("Adding alias");
self.add_alias(&hash, content_type.clone()).await?;
self.add_alias(&hash, input_type).await?;
debug!("Saving file");
self.save_upload(&identifier, hash, content_type).await?;
self.save_upload(&identifier, hash, input_type).await?;
// Return alias to file
Ok(self)
@ -228,9 +228,9 @@ where
&self,
identifier: &S::Identifier,
hash: Hash,
content_type: mime::Mime,
input_type: ValidInputType,
) -> 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
if dup.exists() {
@ -246,15 +246,15 @@ where
}
// 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(
&self,
hash: Hash,
content_type: mime::Mime,
input_type: ValidInputType,
) -> Result<(Dup, String), Error> {
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 hash2 = hash.as_slice().to_vec();
@ -287,11 +287,11 @@ where
}
// generate a short filename that isn't already in-use
#[instrument(skip(self, content_type))]
async fn next_file(&self, content_type: mime::Mime) -> Result<String, Error> {
#[instrument(skip(self, input_type))]
async fn next_file(&self, input_type: ValidInputType) -> Result<String, Error> {
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 filename2 = filename.clone();
@ -319,9 +319,9 @@ where
// 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
#[instrument(skip(self, hash, content_type))]
async fn add_alias(&mut self, hash: &Hash, content_type: mime::Mime) -> Result<(), Error> {
let alias = self.next_alias(hash, content_type).await?;
#[instrument(skip(self, hash, input_type))]
async fn add_alias(&mut self, hash: &Hash, input_type: ValidInputType) -> Result<(), Error> {
let alias = self.next_alias(hash, input_type).await?;
self.store_hash_id_alias_mapping(hash, &alias).await?;
@ -365,11 +365,15 @@ where
}
// Generate an alias to the file
#[instrument(skip(self, hash, content_type))]
async fn next_alias(&mut self, hash: &Hash, content_type: mime::Mime) -> Result<String, Error> {
#[instrument(skip(self, hash, input_type))]
async fn next_alias(
&mut self,
hash: &Hash,
input_type: ValidInputType,
) -> Result<String, Error> {
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());
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> {
Ok(format!("{}{}", name, to_ext(content_type)?))
}
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())
}
fn file_name(name: Uuid, input_type: ValidInputType) -> String {
format!("{}{}", name, input_type.to_ext())
}

View file

@ -5,14 +5,6 @@ use actix_web::web::Bytes;
use tokio::io::AsyncRead;
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 {
bytes: Bytes,
written: usize,
@ -45,56 +37,48 @@ pub(crate) async fn validate_image_bytes(
bytes: Bytes,
prescribed_format: Option<Format>,
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?;
if !validate {
let mime_type = match input_type {
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))));
return Ok((input_type, Either::left(UnvalidatedBytes::new(bytes))));
}
match (prescribed_format, input_type) {
(_, ValidInputType::Gif) => Ok((
video_mp4(),
ValidInputType::Mp4,
Either::right(Either::left(crate::ffmpeg::to_mp4_bytes(
bytes,
InputFormat::Gif,
)?)),
)),
(_, ValidInputType::Mp4) => Ok((
video_mp4(),
ValidInputType::Mp4,
Either::right(Either::left(crate::ffmpeg::to_mp4_bytes(
bytes,
InputFormat::Mp4,
)?)),
)),
(Some(Format::Jpeg) | None, ValidInputType::Jpeg) => Ok((
mime::IMAGE_JPEG,
ValidInputType::Jpeg,
Either::right(Either::right(Either::left(
crate::exiftool::clear_metadata_bytes_read(bytes)?,
))),
)),
(Some(Format::Png) | None, ValidInputType::Png) => Ok((
mime::IMAGE_PNG,
ValidInputType::Png,
Either::right(Either::right(Either::left(
crate::exiftool::clear_metadata_bytes_read(bytes)?,
))),
)),
(Some(Format::Webp) | None, ValidInputType::Webp) => Ok((
image_webp(),
ValidInputType::Webp,
Either::right(Either::right(Either::right(Either::left(
crate::magick::clear_metadata_bytes_read(bytes)?,
)))),
)),
(Some(format), _) => Ok((
format.to_mime(),
ValidInputType::from_format(format),
Either::right(Either::right(Either::right(Either::right(
crate::magick::convert_bytes_read(bytes, format)?,
)))),