Move some functions from utils::files to media module
This commit is contained in:
parent
0988c0c91e
commit
2acf50fa01
13 changed files with 98 additions and 96 deletions
|
@ -15,6 +15,7 @@ use mitra::ethereum::{
|
|||
sync::save_current_block_number,
|
||||
utils::key_to_ethereum_address,
|
||||
};
|
||||
use mitra::media::remove_files;
|
||||
use mitra::models::{
|
||||
attachments::queries::delete_unused_attachments,
|
||||
cleanup::find_orphaned_files,
|
||||
|
@ -53,7 +54,6 @@ use mitra::utils::{
|
|||
serialize_private_key,
|
||||
},
|
||||
datetime::{days_before_now, get_min_datetime},
|
||||
files::remove_files,
|
||||
passwords::hash_password,
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ use crate::activitypub::{
|
|||
};
|
||||
use crate::config::Instance;
|
||||
use crate::errors::ValidationError;
|
||||
use crate::media::get_file_url;
|
||||
use crate::models::profiles::types::{
|
||||
ExtraField,
|
||||
IdentityProof,
|
||||
|
@ -29,7 +30,6 @@ use crate::models::profiles::types::{
|
|||
};
|
||||
use crate::models::users::types::User;
|
||||
use crate::utils::crypto_rsa::{deserialize_private_key, get_public_key_pem};
|
||||
use crate::utils::files::get_file_url;
|
||||
use crate::utils::urls::get_hostname;
|
||||
use crate::webfinger::types::ActorAddress;
|
||||
use super::attachments::{
|
||||
|
|
|
@ -26,6 +26,7 @@ use crate::activitypub::{
|
|||
};
|
||||
use crate::config::Instance;
|
||||
use crate::database::{DatabaseClient, DatabaseError};
|
||||
use crate::media::get_file_url;
|
||||
use crate::models::{
|
||||
emojis::types::DbEmoji,
|
||||
posts::queries::get_post_author,
|
||||
|
@ -33,7 +34,6 @@ use crate::models::{
|
|||
relationships::queries::{get_followers, get_subscribers},
|
||||
users::types::User,
|
||||
};
|
||||
use crate::utils::files::get_file_url;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Serialize)]
|
||||
|
|
|
@ -15,11 +15,8 @@ use crate::http_signatures::create::{
|
|||
create_http_signature,
|
||||
HttpSignatureError,
|
||||
};
|
||||
use crate::utils::files::{
|
||||
save_file,
|
||||
sniff_media_type,
|
||||
SUPPORTED_MEDIA_TYPES,
|
||||
};
|
||||
use crate::media::{save_file, SUPPORTED_MEDIA_TYPES};
|
||||
use crate::utils::files::sniff_media_type;
|
||||
use crate::utils::urls::guess_protocol;
|
||||
use crate::webfinger::types::{ActorAddress, JsonResourceDescriptor};
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ pub mod job_queue;
|
|||
mod json_signatures;
|
||||
pub mod logger;
|
||||
pub mod mastodon_api;
|
||||
pub mod media;
|
||||
pub mod models;
|
||||
pub mod monero;
|
||||
pub mod nodeinfo;
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::mastodon_api::{
|
|||
pagination::PageSize,
|
||||
uploads::{save_b64_file, UploadError},
|
||||
};
|
||||
use crate::media::get_file_url;
|
||||
use crate::models::{
|
||||
profiles::types::{
|
||||
DbActorProfile,
|
||||
|
@ -27,10 +28,7 @@ use crate::models::{
|
|||
User,
|
||||
},
|
||||
};
|
||||
use crate::utils::{
|
||||
files::get_file_url,
|
||||
markdown::markdown_basic_to_html,
|
||||
};
|
||||
use crate::utils::markdown::markdown_basic_to_html;
|
||||
|
||||
/// https://docs.joinmastodon.org/entities/field/
|
||||
#[derive(Serialize)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::media::get_file_url;
|
||||
use crate::models::emojis::types::DbEmoji;
|
||||
use crate::utils::files::get_file_url;
|
||||
|
||||
/// https://docs.joinmastodon.org/entities/CustomEmoji/
|
||||
#[derive(Serialize)]
|
||||
|
|
|
@ -12,11 +12,9 @@ use crate::mastodon_api::{
|
|||
MASTODON_API_VERSION,
|
||||
uploads::UPLOAD_MAX_SIZE,
|
||||
};
|
||||
use crate::media::SUPPORTED_MEDIA_TYPES;
|
||||
use crate::models::posts::validators::ATTACHMENTS_MAX_NUM;
|
||||
use crate::utils::{
|
||||
files::SUPPORTED_MEDIA_TYPES,
|
||||
markdown::markdown_to_html,
|
||||
};
|
||||
use crate::utils::markdown::markdown_to_html;
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct InstanceStats {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::media::get_file_url;
|
||||
use crate::models::attachments::types::{
|
||||
AttachmentType,
|
||||
DbMediaAttachment,
|
||||
};
|
||||
use crate::utils::files::get_file_url;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct AttachmentCreateData {
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
use std::path::Path;
|
||||
|
||||
use crate::errors::HttpError;
|
||||
use crate::utils::files::{
|
||||
save_file,
|
||||
sniff_media_type,
|
||||
SUPPORTED_MEDIA_TYPES,
|
||||
};
|
||||
use crate::media::{save_file, SUPPORTED_MEDIA_TYPES};
|
||||
use crate::utils::files::sniff_media_type;
|
||||
|
||||
pub const UPLOAD_MAX_SIZE: usize = 1024 * 1024 * 5;
|
||||
|
||||
|
|
79
src/media.rs
Normal file
79
src/media.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
use std::fs::remove_file;
|
||||
use std::io::Error;
|
||||
use std::path::Path;
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use crate::utils::files::{get_media_type_extension, write_file};
|
||||
|
||||
pub const SUPPORTED_MEDIA_TYPES: [&str; 8] = [
|
||||
"audio/mpeg",
|
||||
"image/apng",
|
||||
"image/gif",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
"video/mp4",
|
||||
"video/webm",
|
||||
];
|
||||
|
||||
/// Generates unique file name based on file contents
|
||||
fn get_file_name(data: &[u8], media_type: Option<&str>) -> String {
|
||||
let digest = Sha256::digest(data);
|
||||
let mut file_name = hex::encode(digest);
|
||||
let maybe_extension = media_type
|
||||
.and_then(get_media_type_extension);
|
||||
if let Some(extension) = maybe_extension {
|
||||
// Append extension for known media types
|
||||
file_name = format!("{}.{}", file_name, extension);
|
||||
};
|
||||
file_name
|
||||
}
|
||||
|
||||
/// Save validated file to specified directory
|
||||
pub fn save_file(
|
||||
data: Vec<u8>,
|
||||
output_dir: &Path,
|
||||
media_type: Option<&str>,
|
||||
) -> Result<String, Error> {
|
||||
let file_name = get_file_name(&data, media_type);
|
||||
let file_path = output_dir.join(&file_name);
|
||||
write_file(&data, &file_path)?;
|
||||
Ok(file_name)
|
||||
}
|
||||
|
||||
pub fn get_file_url(instance_url: &str, file_name: &str) -> String {
|
||||
format!("{}/media/{}", instance_url, file_name)
|
||||
}
|
||||
|
||||
pub fn remove_files(files: Vec<String>, from_dir: &Path) -> () {
|
||||
for file_name in files {
|
||||
let file_path = from_dir.join(file_name);
|
||||
let file_path_str = file_path.to_string_lossy();
|
||||
match remove_file(&file_path) {
|
||||
Ok(_) => log::info!("removed file {}", file_path_str),
|
||||
Err(err) => {
|
||||
log::warn!("failed to remove file {} ({})", file_path_str, err);
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::utils::files::sniff_media_type;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_get_file_name() {
|
||||
let mut data = vec![];
|
||||
data.extend_from_slice(b"\x89PNG\x0D\x0A\x1A\x0A");
|
||||
let media_type = sniff_media_type(&data);
|
||||
let file_name = get_file_name(&data, media_type.as_deref());
|
||||
|
||||
assert_eq!(
|
||||
file_name,
|
||||
"4c4b6a3be1314ab86138bef4314dde022e600960d8689a2c8f8631802d20dab6.png",
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use crate::config::Config;
|
||||
use crate::database::{DatabaseClient, DatabaseError};
|
||||
use crate::ipfs::store as ipfs_store;
|
||||
use crate::utils::files::remove_files;
|
||||
use crate::media::remove_files;
|
||||
|
||||
pub struct DeletionQueue {
|
||||
pub files: Vec<String>,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use std::fs::{
|
||||
remove_file,
|
||||
set_permissions,
|
||||
File,
|
||||
Permissions,
|
||||
|
@ -11,35 +10,15 @@ use std::path::Path;
|
|||
|
||||
use mime_guess::get_mime_extensions_str;
|
||||
use mime_sniffer::MimeTypeSniffer;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
pub const SUPPORTED_MEDIA_TYPES: [&str; 8] = [
|
||||
"audio/mpeg",
|
||||
"image/apng",
|
||||
"image/gif",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
"video/mp4",
|
||||
"video/webm",
|
||||
];
|
||||
|
||||
pub fn sniff_media_type(data: &[u8]) -> Option<String> {
|
||||
data.sniff_mime_type().map(|val| val.to_string())
|
||||
}
|
||||
|
||||
/// Generates unique file name based on file contents
|
||||
fn get_file_name(data: &[u8], media_type: Option<&str>) -> String {
|
||||
let digest = Sha256::digest(data);
|
||||
let mut file_name = hex::encode(digest);
|
||||
let maybe_extension = media_type
|
||||
.and_then(get_mime_extensions_str)
|
||||
.and_then(|extensions| extensions.first());
|
||||
if let Some(extension) = maybe_extension {
|
||||
// Append extension for known media types
|
||||
file_name = format!("{}.{}", file_name, extension);
|
||||
};
|
||||
file_name
|
||||
pub fn get_media_type_extension(media_type: &str) -> Option<String> {
|
||||
get_mime_extensions_str(media_type)
|
||||
.and_then(|extensions| extensions.first())
|
||||
.map(|extension| extension.to_string())
|
||||
}
|
||||
|
||||
pub fn write_file(data: &[u8], file_path: &Path) -> Result<(), Error> {
|
||||
|
@ -53,50 +32,3 @@ pub fn set_file_permissions(file_path: &Path, mode: u32) -> Result<(), Error> {
|
|||
set_permissions(file_path, permissions)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Save validated file to specified directory
|
||||
pub fn save_file(
|
||||
data: Vec<u8>,
|
||||
output_dir: &Path,
|
||||
media_type: Option<&str>,
|
||||
) -> Result<String, Error> {
|
||||
let file_name = get_file_name(&data, media_type);
|
||||
let file_path = output_dir.join(&file_name);
|
||||
write_file(&data, &file_path)?;
|
||||
Ok(file_name)
|
||||
}
|
||||
|
||||
pub fn get_file_url(instance_url: &str, file_name: &str) -> String {
|
||||
format!("{}/media/{}", instance_url, file_name)
|
||||
}
|
||||
|
||||
pub fn remove_files(files: Vec<String>, from_dir: &Path) -> () {
|
||||
for file_name in files {
|
||||
let file_path = from_dir.join(file_name);
|
||||
let file_path_str = file_path.to_string_lossy();
|
||||
match remove_file(&file_path) {
|
||||
Ok(_) => log::info!("removed file {}", file_path_str),
|
||||
Err(err) => {
|
||||
log::warn!("failed to remove file {} ({})", file_path_str, err);
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_get_file_name() {
|
||||
let mut data = vec![];
|
||||
data.extend_from_slice(b"\x89PNG\x0D\x0A\x1A\x0A");
|
||||
let media_type = data.sniff_mime_type();
|
||||
let file_name = get_file_name(&data, media_type);
|
||||
|
||||
assert_eq!(
|
||||
file_name,
|
||||
"4c4b6a3be1314ab86138bef4314dde022e600960d8689a2c8f8631802d20dab6.png",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue