mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-20 09:11:24 +01:00
Use MxcData in media service
This commit is contained in:
parent
391fc2e51a
commit
c1ea25e1e0
6 changed files with 89 additions and 91 deletions
|
|
@ -1,14 +1,17 @@
|
|||
use std::io::Cursor;
|
||||
use std::{fmt, io::Cursor};
|
||||
|
||||
use image::imageops::FilterType;
|
||||
use ruma::http_headers::ContentDisposition;
|
||||
use ruma::{
|
||||
api::client::error::ErrorKind, http_headers::ContentDisposition, MxcUri,
|
||||
MxcUriError, OwnedMxcUri,
|
||||
};
|
||||
use tokio::{
|
||||
fs::File,
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
};
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use crate::{services, Result};
|
||||
use crate::{services, Error, Result};
|
||||
|
||||
mod data;
|
||||
|
||||
|
|
@ -37,6 +40,57 @@ impl MediaFileKey {
|
|||
}
|
||||
}
|
||||
|
||||
/// Data that makes up an `mxc://` URL.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub(crate) struct MxcData<'a> {
|
||||
pub(crate) server_name: &'a ruma::ServerName,
|
||||
pub(crate) media_id: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> MxcData<'a> {
|
||||
pub(crate) fn new(
|
||||
server_name: &'a ruma::ServerName,
|
||||
media_id: &'a str,
|
||||
) -> Result<Self> {
|
||||
if !media_id.bytes().all(|b| {
|
||||
matches!(b,
|
||||
b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'-' | b'_'
|
||||
)
|
||||
}) {
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::InvalidParam,
|
||||
"Invalid MXC media id",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
server_name,
|
||||
media_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MxcData<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "mxc://{}/{}", self.server_name, self.media_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MxcData<'_>> for OwnedMxcUri {
|
||||
fn from(value: MxcData<'_>) -> Self {
|
||||
value.to_string().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a MxcUri> for MxcData<'a> {
|
||||
type Error = MxcUriError;
|
||||
|
||||
fn try_from(value: &'a MxcUri) -> Result<Self, Self::Error> {
|
||||
Ok(Self::new(value.server_name()?, value.media_id()?)
|
||||
.expect("validated MxcUri should always be valid MxcData"))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Service {
|
||||
pub(crate) db: &'static dyn Data,
|
||||
}
|
||||
|
|
@ -46,7 +100,7 @@ impl Service {
|
|||
#[tracing::instrument(skip(self, file))]
|
||||
pub(crate) async fn create(
|
||||
&self,
|
||||
mxc: String,
|
||||
mxc: MxcData<'_>,
|
||||
content_disposition: Option<&ContentDisposition>,
|
||||
content_type: Option<String>,
|
||||
file: &[u8],
|
||||
|
|
@ -69,7 +123,7 @@ impl Service {
|
|||
#[tracing::instrument(skip(self, file))]
|
||||
pub(crate) async fn upload_thumbnail(
|
||||
&self,
|
||||
mxc: String,
|
||||
mxc: MxcData<'_>,
|
||||
content_disposition: Option<String>,
|
||||
content_type: Option<String>,
|
||||
width: u32,
|
||||
|
|
@ -93,7 +147,7 @@ impl Service {
|
|||
#[tracing::instrument(skip(self))]
|
||||
pub(crate) async fn get(
|
||||
&self,
|
||||
mxc: String,
|
||||
mxc: MxcData<'_>,
|
||||
) -> Result<Option<(FileMeta, Vec<u8>)>> {
|
||||
if let Ok((meta, key)) = self.db.search_file_metadata(mxc, 0, 0) {
|
||||
let path = services().globals.get_media_file(&key);
|
||||
|
|
@ -224,7 +278,7 @@ impl Service {
|
|||
#[tracing::instrument(skip(self))]
|
||||
pub(crate) async fn get_thumbnail(
|
||||
&self,
|
||||
mxc: String,
|
||||
mxc: MxcData<'_>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Result<Option<(FileMeta, Vec<u8>)>> {
|
||||
|
|
@ -233,7 +287,7 @@ impl Service {
|
|||
Self::thumbnail_properties(width, height).unwrap_or((0, 0, false));
|
||||
|
||||
if let Ok((meta, key)) =
|
||||
self.db.search_file_metadata(mxc.clone(), width, height)
|
||||
self.db.search_file_metadata(mxc, width, height)
|
||||
{
|
||||
debug!("Using saved thumbnail");
|
||||
let path = services().globals.get_media_file(&key);
|
||||
|
|
@ -243,8 +297,7 @@ impl Service {
|
|||
return Ok(Some((meta, file.clone())));
|
||||
}
|
||||
|
||||
let Ok((meta, key)) = self.db.search_file_metadata(mxc.clone(), 0, 0)
|
||||
else {
|
||||
let Ok((meta, key)) = self.db.search_file_metadata(mxc, 0, 0) else {
|
||||
debug!("Original image not found, can't generate thumbnail");
|
||||
return Ok(None);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue