return Option from media::data::search_file_metadata

This is useful to easily distinguish missing files from corrupted keys.
All existing usage sites have been modified so there is no behavior
change in this commit.
This commit is contained in:
Olivia Lee 2024-12-01 14:59:38 -08:00
parent 861016ce0f
commit f0f81db99b
No known key found for this signature in database
GPG key ID: 54D568A15B9CD1F9
3 changed files with 23 additions and 16 deletions

View file

@ -1,4 +1,4 @@
use ruma::{api::client::error::ErrorKind, OwnedMxcUri};
use ruma::OwnedMxcUri;
use crate::{
database::KeyValueDatabase,
@ -158,21 +158,21 @@ impl service::media::Data for KeyValueDatabase {
mxc: OwnedMxcUri,
width: u32,
height: u32,
) -> Result<(FileMeta, MediaFileKey)> {
) -> Result<Option<(FileMeta, MediaFileKey)>> {
let mut prefix = mxc.as_bytes().to_vec();
prefix.push(0xFF);
prefix.extend_from_slice(&width.to_be_bytes());
prefix.extend_from_slice(&height.to_be_bytes());
prefix.push(0xFF);
let (key, _) =
self.mediaid_file.scan_prefix(prefix).next().ok_or(
Error::BadRequest(ErrorKind::NotFound, "Media not found"),
)?;
let Some((key, _)) = self.mediaid_file.scan_prefix(prefix).next()
else {
return Ok(None);
};
let key = MediaFileKey::new(key);
let parts = MediaFileKeyParts::try_from(&key)?;
Ok((parts.meta, key))
Ok(Some((parts.meta, key)))
}
fn delete_file_metadata(&self, key: MediaFileKey) -> Result<()> {

View file

@ -1,14 +1,17 @@
use std::io::Cursor;
use image::imageops::FilterType;
use ruma::{http_headers::ContentDisposition, OwnedMxcUri};
use ruma::{
api::client::error::ErrorKind, http_headers::ContentDisposition,
OwnedMxcUri,
};
use tokio::{
fs::{self, File},
io::{AsyncReadExt, AsyncWriteExt},
};
use tracing::{debug, warn};
use crate::{services, utils, Result};
use crate::{services, utils, Error, Result};
mod data;
@ -96,7 +99,7 @@ impl Service {
&self,
mxc: OwnedMxcUri,
) -> Result<Option<(FileMeta, Vec<u8>)>> {
if let Ok((meta, key)) = self.db.search_file_metadata(mxc, 0, 0) {
if let Ok(Some((meta, key))) = self.db.search_file_metadata(mxc, 0, 0) {
let path = services().globals.get_media_file(&key);
let mut file_data = Vec::new();
let Ok(mut file) = File::open(path).await else {
@ -114,10 +117,13 @@ impl Service {
/// Deletes a media object and all associated thumbnails.
#[tracing::instrument(skip(self))]
pub(crate) async fn delete(&self, mxc: OwnedMxcUri) -> Result<()> {
let (_, key) =
self.db.search_file_metadata(mxc.clone(), 0, 0).inspect_err(
let (_, key) = self
.db
.search_file_metadata(mxc.clone(), 0, 0)
.inspect_err(
|error| warn!(%error, "Failed to find original media key"),
)?;
)?
.ok_or(Error::BadRequest(ErrorKind::NotFound, "Media not found"))?;
let thumbnails = self.db.search_thumbnails_metadata(mxc)?;
for (_, thumbnail_key) in thumbnails {
@ -292,7 +298,7 @@ impl Service {
let (width, height, crop) =
Self::thumbnail_properties(width, height).unwrap_or((0, 0, false));
if let Ok((meta, key)) =
if let Ok(Some((meta, key))) =
self.db.search_file_metadata(mxc.clone(), width, height)
{
debug!("Using saved thumbnail");
@ -303,7 +309,8 @@ impl Service {
return Ok(Some((meta, file.clone())));
}
let Ok((meta, key)) = self.db.search_file_metadata(mxc.clone(), 0, 0)
let Ok(Some((meta, key))) =
self.db.search_file_metadata(mxc.clone(), 0, 0)
else {
debug!("Original image not found, can't generate thumbnail");
return Ok(None);

View file

@ -17,7 +17,7 @@ pub(crate) trait Data: Send + Sync {
mxc: OwnedMxcUri,
width: u32,
height: u32,
) -> Result<(FileMeta, MediaFileKey)>;
) -> Result<Option<(FileMeta, MediaFileKey)>>;
fn delete_file_metadata(&self, key: MediaFileKey) -> Result<()>;