diff --git a/mediarepo-daemon/mediarepo-core/src/file_hash_store.rs b/mediarepo-daemon/mediarepo-core/src/file_hash_store.rs index 231b35a..682d187 100644 --- a/mediarepo-daemon/mediarepo-core/src/file_hash_store.rs +++ b/mediarepo-daemon/mediarepo-core/src/file_hash_store.rs @@ -6,6 +6,8 @@ use tokio::fs; use tokio::fs::{File, OpenOptions}; use tokio::io::{AsyncRead, AsyncReadExt, BufReader}; +static STORE_BASE: Base = Base::Base32Lower; + #[derive(Clone, Debug)] pub struct FileHashStore { path: PathBuf, @@ -17,33 +19,47 @@ impl FileHashStore { } /// Adds a file that can be read to the hash store and returns the resulting hash identifier - pub async fn add_file(&self, mut reader: R) -> RepoResult { + pub async fn add_file( + &self, + mut reader: R, + extension: Option<&str>, + ) -> RepoResult { let mut buf = Vec::new(); reader.read_to_end(&mut buf).await?; let hash: Vec = Code::Sha2_256.digest(&buf).to_bytes(); - let hash: String = multibase::encode(Base::Base64, &hash); + let hash: String = multibase::encode(STORE_BASE, &hash); let folder_path = self.hash_to_folder_path(&hash); if !folder_path.exists() { fs::create_dir(folder_path).await?; } - let file_path = self.hash_to_file_path(&hash); + let mut file_path = self.hash_to_file_path(&hash); + if let Some(extension) = extension { + file_path.set_extension(extension); + } fs::write(file_path, buf).await?; Ok(hash) } - /// Returns the file by hash - pub async fn get_file(&self, mut hash: String) -> RepoResult> { + /// Returns the file extension and a reader for the file by hash + pub async fn get_file( + &self, + mut hash: String, + ) -> RepoResult<(Option, BufReader)> { let (base, data) = multibase::decode(&hash)?; - if base != Base::Base64 { - hash = multibase::encode(Base::Base64, data); + if base != STORE_BASE { + hash = multibase::encode(STORE_BASE, data); } let file_path = self.hash_to_file_path(&hash); + let extension = file_path + .extension() + .and_then(|s| s.to_str()) + .map(|s| s.to_string()); let file = OpenOptions::new().read(true).open(file_path).await?; let reader = BufReader::new(file); - Ok(reader) + Ok((extension, reader)) } fn hash_to_file_path(&self, hash: &str) -> PathBuf {