diff --git a/src/database/mod.rs b/src/database/mod.rs index e05991d9..0eae027c 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -880,6 +880,27 @@ impl KeyValueDatabase { warn!("Migration: 11 -> 12 finished"); } + if services().globals.database_version()? < 13 { + // Move old media files to new names + for (key, _) in db.mediaid_file.iter() { + // we know that this method is deprecated, but we need to use it to migrate the old files + // to the new location + // + // TODO: remove this once we're sure that all users have migrated + #[allow(deprecated)] + let old_path = services().globals.get_media_file_old(&key); + let path = services().globals.get_media_file(&key); + // move the file to the new location + if old_path.exists() { + tokio::fs::rename(&old_path, &path).await?; + } + } + + services().globals.bump_database_version(13)?; + + warn!("Migration: 12 -> 13 finished"); + } + assert_eq!( services().globals.database_version().unwrap(), latest_database_version diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index 9206d43f..769a37a9 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -3,6 +3,7 @@ pub use data::Data; use ruma::{ OwnedDeviceId, OwnedEventId, OwnedRoomId, OwnedServerName, OwnedServerSigningKeyId, OwnedUserId, }; +use sha2::Digest; use crate::api::server_server::FedDest; @@ -14,14 +15,16 @@ use ruma::{ }, DeviceId, RoomVersionId, ServerName, UserId, }; -use std::sync::atomic::{self, AtomicBool}; use std::{ collections::{BTreeMap, HashMap}, fs, future::Future, net::{IpAddr, SocketAddr}, path::PathBuf, - sync::{Arc, Mutex, RwLock}, + sync::{ + atomic::{self, AtomicBool}, + Arc, Mutex, RwLock, + }, time::{Duration, Instant}, }; use tokio::sync::{broadcast, watch::Receiver, Mutex as TokioMutex, Semaphore}; @@ -339,6 +342,24 @@ impl Service { } pub fn get_media_file(&self, key: &[u8]) -> PathBuf { + let mut r = PathBuf::new(); + r.push(self.config.database_path.clone()); + r.push("media"); + r.push(base64::encode_config( + // Using the hash of the key as the filename + // This is to prevent the total length of the path from exceeding the maximum length + sha2::Sha256::digest(key), + base64::URL_SAFE_NO_PAD, + )); + r + } + + /// This is the old version of `get_media_file` that uses the key as the filename. + /// + /// This is deprecated and will be removed in a future release. + /// Please use `get_media_file` instead. + #[deprecated(note = "Use get_media_file instead")] + pub fn get_media_file_old(&self, key: &[u8]) -> PathBuf { let mut r = PathBuf::new(); r.push(self.config.database_path.clone()); r.push("media"); diff --git a/src/service/media/mod.rs b/src/service/media/mod.rs index 4f9c35b6..1b243392 100644 --- a/src/service/media/mod.rs +++ b/src/service/media/mod.rs @@ -269,9 +269,9 @@ mod tests { fn search_file_metadata( &self, - mxc: String, - width: u32, - height: u32, + _mxc: String, + _width: u32, + _height: u32, ) -> Result<(Option, Option, Vec)> { todo!() }