feat(services/autumn): download and preview files

This commit is contained in:
Paul Makles
2024-09-01 13:58:11 +01:00
parent 78757ac7f1
commit ebbbb5e174
21 changed files with 1119 additions and 81 deletions

View File

@@ -1,5 +1,6 @@
use crate::Database;
use crate::{Database, FileHash, Metadata};
use iso8601_timestamp::Timestamp;
use revolt_result::Result;
auto_derived_partial!(
@@ -12,13 +13,16 @@ auto_derived_partial!(
pub tag: String,
/// Original filename
pub filename: String,
/// Parsed metadata of this file
pub metadata: Metadata,
/// Raw content type of this file
pub content_type: String,
/// Size of this file (in bytes)
pub size: isize,
/// Hash of this file
pub hash: Option<String>, // these are Option<>s to not break file uploads on legacy Autumn
/// When this file was uploaded
pub uploaded_at: Option<Timestamp>, // these are Option<>s to not break file uploads on legacy Autumn
/// ID of user who uploaded this file
pub uploaded_id: Option<String>, // these are Option<>s to not break file uploads on legacy Autumn
// TODO: used_for: field
//
/// Whether this file was deleted
#[serde(skip_serializing_if = "Option::is_none")]
pub deleted: Option<bool>,
@@ -26,6 +30,14 @@ auto_derived_partial!(
#[serde(skip_serializing_if = "Option::is_none")]
pub reported: Option<bool>,
// !!! DEPRECATED:
/// Parsed metadata of this file
pub metadata: Metadata,
/// Raw content type of this file
pub content_type: String,
/// Size of this file (in bytes)
pub size: isize,
// TODO: migrate this mess to having:
// - author_id
// - parent: Parent { Message(id), User(id), etc }
@@ -43,26 +55,12 @@ auto_derived_partial!(
"PartialFile"
);
auto_derived!(
/// Metadata associated with a file
#[serde(tag = "type")]
#[derive(Default)]
pub enum Metadata {
/// File is just a generic uncategorised file
#[default]
File,
/// File contains textual data and should be displayed as such
Text,
/// File is an image with specific dimensions
Image { width: isize, height: isize },
/// File is a video with specific dimensions
Video { width: isize, height: isize },
/// File is audio
Audio,
}
);
impl File {
/// Get the hash entry for this file
pub async fn as_hash(&self, db: &Database) -> Result<FileHash> {
db.fetch_attachment_hash(self.hash.as_ref().unwrap()).await
}
/// Use a file for a message attachment
pub async fn use_attachment(db: &Database, id: &str, parent: &str) -> Result<File> {
db.find_and_use_attachment(id, "attachments", "message", parent)

View File

@@ -10,6 +10,9 @@ pub trait AbstractAttachments: Sync + Send {
/// Insert attachment into database.
async fn insert_attachment(&self, attachment: &File) -> Result<()>;
/// Fetch an attachment by its id.
async fn fetch_attachment(&self, tag: &str, file_id: &str) -> Result<File>;
/// Find an attachment by its details and mark it as used by a given parent.
async fn find_and_use_attachment(
&self,

View File

@@ -15,6 +15,20 @@ impl AbstractAttachments for MongoDb {
query!(self, insert_one, COL, &attachment).map(|_| ())
}
/// Fetch an attachment by its id.
async fn fetch_attachment(&self, tag: &str, file_id: &str) -> Result<File> {
query!(
self,
find_one,
COL,
doc! {
"_id": file_id,
"tag": tag
}
)?
.ok_or_else(|| create_error!(NotFound))
}
/// Find an attachment by its details and mark it as used by a given parent.
async fn find_and_use_attachment(
&self,

View File

@@ -18,6 +18,20 @@ impl AbstractAttachments for ReferenceDb {
}
}
/// Fetch an attachment by its id.
async fn fetch_attachment(&self, tag: &str, file_id: &str) -> Result<File> {
let files = self.files.lock().await;
if let Some(file) = files.get(file_id) {
if file.tag == tag {
Ok(file.clone())
} else {
Err(create_error!(NotFound))
}
} else {
Err(create_error!(NotFound))
}
}
/// Find an attachment by its details and mark it as used by a given parent.
async fn find_and_use_attachment(
&self,