diff options
Diffstat (limited to 'server/src/import.rs')
-rw-r--r-- | server/src/import.rs | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/server/src/import.rs b/server/src/import.rs index 2cd1998..a059694 100644 --- a/server/src/import.rs +++ b/server/src/import.rs @@ -6,10 +6,13 @@ use crate::{database::Database, federation::Federation, CONF}; use anyhow::{anyhow, bail, Context, Ok}; use async_recursion::async_recursion; +use base64::Engine; use jellyclient::Session; -use jellycommon::{MediaSource, Node, NodePrivate, RemoteImportOptions}; +use jellycommon::{AssetLocation, MediaSource, Node, NodePrivate, RemoteImportOptions}; use log::{error, info}; -use std::{ffi::OsStr, fs::File, os::unix::prelude::OsStrExt, path::PathBuf, sync::LazyLock}; +use std::{ + ffi::OsStr, fs::File, os::unix::prelude::OsStrExt, path::PathBuf, str::FromStr, sync::LazyLock, +}; use tokio::sync::Semaphore; static IMPORT_SEM: LazyLock<Semaphore> = LazyLock::new(|| Semaphore::new(1)); @@ -125,11 +128,15 @@ async fn import_remote( .node(&opts.id) .await .context("fetching remote node")?; + + let poster = cache_federation_asset(session, &opts.id, "poster").await?; + let backdrop = cache_federation_asset(session, &opts.id, "backdrop").await?; + let mut node = Node { public: node, private: NodePrivate { - backdrop: None, - poster: None, + backdrop: Some(AssetLocation::Cache(backdrop)), + poster: Some(AssetLocation::Cache(poster)), import: None, source: Some(MediaSource::Remote { host: opts.host.clone(), @@ -160,3 +167,36 @@ async fn import_remote( Ok(()) } + +async fn cache_federation_asset( + session: &Session, + identifier: &String, + role: &str, +) -> anyhow::Result<PathBuf> { + let (poster, download) = cache_file(&["federation-asset", role, identifier]); + if let Some(d) = download { + session.node_asset(&identifier, role, d).await?; + } + Ok(poster) +} + +fn cache_file(seed: &[&str]) -> (PathBuf, Option<File>) { + use sha2::Digest; + let mut d = sha2::Sha512::new(); + for s in seed { + d.update(s.as_bytes()); + d.update(b"\0"); + } + let d = d.finalize(); + let fname = base64::engine::general_purpose::URL_SAFE.encode(d); + let fname = &fname[..22]; // about 128 bits + let fullpath = CONF.cache_path.join(fname); + let cachepath = PathBuf::from_str(fname).unwrap(); + + let f = if !fullpath.exists() { + Some(File::create(&fullpath).unwrap()) + } else { + None + }; + (cachepath, f) +} |