diff options
Diffstat (limited to 'import')
| -rw-r--r-- | import/src/lib.rs | 113 | ||||
| -rw-r--r-- | import/src/tmdb.rs | 14 | ||||
| -rw-r--r-- | import/src/trakt.rs | 7 | 
3 files changed, 57 insertions, 77 deletions
| diff --git a/import/src/lib.rs b/import/src/lib.rs index d1605fe..c30fe37 100644 --- a/import/src/lib.rs +++ b/import/src/lib.rs @@ -13,15 +13,16 @@ use anyhow::{anyhow, bail, Context, Ok};  use async_recursion::async_recursion;  use futures::{stream::FuturesUnordered, StreamExt};  use jellybase::{ +    assetfed::AssetInner,      cache::{async_cache_file, cache_memory},      database::{DataAcid, ReadableTable, Ser, T_NODE, T_NODE_EXTENDED, T_NODE_IMPORT},      federation::Federation, -    AssetLocationExt, CONF, SECRETS, +    CONF, SECRETS,  };  use jellyclient::Session;  use jellycommon::{ -    AssetLocation, AssetRole, ExtendedNode, ImportOptions, ImportSource, MediaInfo, Node, NodeKind, -    NodePrivate, NodePublic, PeopleGroup, Rating, SourceTrack, TrackSource, +    ExtendedNode, ImportOptions, ImportSource, MediaInfo, Node, NodeKind, NodePrivate, NodePublic, +    PeopleGroup, Rating, SourceTrack, TrackSource,  };  use jellymatroska::read::EbmlReader;  use jellyremuxer::import::import_metadata; @@ -325,13 +326,16 @@ async fn process_source(                          node_ext.people.entry(group.a()).or_default().push(p.a())                      }                  } +                // TODO lazy assets                  for (_, ps) in &mut node_ext.people {                      for p in ps {                          if let Some(id) = p.person.ids.tmdb {                              if let Some(tmdb) = &ap.tmdb {                                  let k = tmdb.person_image(id).await?;                                  if let Some(prof) = k.profiles.get(0) { -                                    p.person.asset = Some(tmdb.image(&prof.file_path).await?); +                                    p.person.headshot = Some( +                                        AssetInner::Cache(tmdb.image(&prof.file_path).await?).ser(), +                                    );                                  }                              }                          } @@ -367,11 +371,12 @@ async fn process_source(              let mut node = Node::default(); +            // TODO lazy assets              if let Some(poster) = &details.poster_path { -                node.private.poster = Some(tmdb.image(&poster).await?); +                node.public.poster = Some(AssetInner::Cache(tmdb.image(&poster).await?).ser());              }              if let Some(backdrop) = &details.backdrop_path { -                node.private.backdrop = Some(tmdb.image(&backdrop).await?); +                node.public.backdrop = Some(AssetInner::Cache(tmdb.image(&backdrop).await?).ser());              }              node.public.tagline = details.tagline.clone(); @@ -388,16 +393,19 @@ async fn process_source(              insert_node(&id, node)?;          }          ImportSource::Media { -            location, +            path: mpath,              ignore_attachments,              ignore_chapters,              ignore_metadata,          } => { -            info!("media import {location:?}"); -            let media_path = location.path(); -            if media_path.is_dir() { +            info!("media import {mpath:?}"); +            let abspath = CONF.media_path.join(&mpath); +            if !abspath.exists() { +                bail!("media missing at {abspath:?}"); +            } +            if abspath.is_dir() {                  let mut node = Node::default(); -                for f in media_path.read_dir()? { +                for f in abspath.read_dir()? {                      let f = f?;                      let child_path = f.path();                      if child_path.is_dir() @@ -411,12 +419,7 @@ async fn process_source(                          process_source(                              inf_id.clone(),                              ImportSource::Media { -                                location: match &location { -                                    AssetLocation::Media(p) => { -                                        AssetLocation::Media(p.join(f.file_name())) -                                    } -                                    _ => bail!("non media path media"), -                                }, +                                path: mpath.join(f.file_name()),                                  ignore_attachments,                                  ignore_chapters,                                  ignore_metadata, @@ -433,25 +436,21 @@ async fn process_source(                      }                  }                  insert_node(&id, node)?; -            } else if media_path.is_file() { +            } else if abspath.is_file() {                  let _permit = SEM_IMPORT.acquire().await.unwrap(); -                let location_path = location.path();                  let metadata = { +                    let abspath = abspath.clone();                      spawn_blocking(move || { -                        cache_memory( -                            &["mkv-probe", location.path().to_str().unwrap()], -                            move || { -                                let input = BufReader::new( -                                    File::open(&location.path()).context("opening media file")?, -                                ); -                                let mut input = EbmlReader::new(input); -                                import_metadata(&mut input) -                            }, -                        ) +                        cache_memory(&["mkv-probe", abspath.to_str().unwrap()], || { +                            let input = +                                BufReader::new(File::open(&abspath).context("opening media file")?); +                            let mut input = EbmlReader::new(input); +                            import_metadata(&mut input) +                        })                      })                  }                  .await? -                .context(anyhow!("probing {location_path:?}"))? +                .context(anyhow!("probing {abspath:?}"))?                  .deref()                  .to_owned(); @@ -476,7 +475,7 @@ async fn process_source(                          .track_sources                          .into_iter()                          .map(|mut ts| { -                            ts.path = media_path.to_owned(); +                            ts.path = mpath.to_owned();                              TrackSource::Local(ts)                          })                          .collect(), @@ -484,16 +483,19 @@ async fn process_source(                  if !ignore_attachments {                      if let Some((filename, data)) = metadata.cover { -                        node.private.poster = Some( -                            async_cache_file( -                                &["att-cover", media_path.to_str().unwrap(), &filename], -                                |mut f| async move { -                                    f.write_all(&data).await?; -                                    Ok(()) -                                }, +                        node.public.poster = Some( +                            AssetInner::Cache( +                                async_cache_file( +                                    &["att-cover", mpath.to_str().unwrap(), &filename], +                                    |mut f| async move { +                                        f.write_all(&data).await?; +                                        Ok(()) +                                    }, +                                ) +                                .await?,                              ) -                            .await?, -                        ); +                            .ser(), +                        )                      };                      if let Some(infojson) = metadata.infojson { @@ -521,7 +523,7 @@ async fn process_source(                  drop(_permit);                  insert_node(&id, node)?;              } else { -                warn!("non file/dir import ignored: {media_path:?}") +                warn!("non file/dir import ignored: {abspath:?}")              }          }          ImportSource::Federated { host } => { @@ -618,6 +620,7 @@ fn merge_node(x: Node, y: Node) -> anyhow::Result<Node> {              title: x.public.title.or(y.public.title),              id: x.public.id.or(y.public.id),              path: vec![], +              children: merge_children(x.public.children, y.public.children),              tagline: x.public.tagline.or(y.public.tagline),              description: x.public.description.or(y.public.description), @@ -631,11 +634,11 @@ fn merge_node(x: Node, y: Node) -> anyhow::Result<Node> {                  .chain(y.public.ratings)                  .collect(),              federated: x.public.federated.or(y.public.federated), +            poster: x.public.poster.or(y.public.poster), +            backdrop: x.public.backdrop.or(y.public.backdrop),          },          private: NodePrivate {              id: x.private.id.or(y.private.id), -            poster: x.private.poster.or(y.private.poster), -            backdrop: x.private.backdrop.or(y.private.backdrop),              source,          },      }) @@ -754,18 +757,11 @@ async fn import_remote(          None      }; -    // TODO maybe use lazy download -    let poster = cache_federation_asset(session.to_owned(), id.clone(), AssetRole::Poster).await?; -    let backdrop = -        cache_federation_asset(session.to_owned(), id.clone(), AssetRole::Backdrop).await?; -      drop(_permit);      let node = Node {          public: node.clone(),          private: NodePrivate { -            backdrop: Some(backdrop), -            poster: Some(poster),              id: None,              source: track_sources,          }, @@ -788,20 +784,3 @@ async fn import_remote(      Ok(())  } - -async fn cache_federation_asset( -    session: Arc<Session>, -    identifier: String, -    role: AssetRole, -) -> anyhow::Result<AssetLocation> { -    async_cache_file( -        &["fed-asset", role.as_str(), &identifier.clone()], -        move |out| async move { -            let session = session; -            session -                .node_asset(out, identifier.as_str(), role, 1024) -                .await -        }, -    ) -    .await -} diff --git a/import/src/tmdb.rs b/import/src/tmdb.rs index 5dbc335..3470b90 100644 --- a/import/src/tmdb.rs +++ b/import/src/tmdb.rs @@ -1,23 +1,19 @@ -use std::{fmt::Display, sync::Arc}; -  /*      This file is part of jellything (https://codeberg.org/metamuffin/jellything)      which is licensed under the GNU Affero General Public License (version 3); see /COPYING. -    Copyright (C) 2023 metamuffin <metamuffin.org> +    Copyright (C) 2024 metamuffin <metamuffin.org>  */  use anyhow::{anyhow, bail, Context};  use bincode::{Decode, Encode}; -use jellybase::cache::{async_cache_file, async_cache_memory}; -use jellycommon::{ -    chrono::{format::Parsed, Utc}, -    AssetLocation, -}; +use jellybase::cache::{async_cache_file, async_cache_memory, CachePath}; +use jellycommon::chrono::{format::Parsed, Utc};  use log::info;  use reqwest::{      header::{HeaderMap, HeaderName, HeaderValue},      Client, ClientBuilder,  };  use serde::Deserialize; +use std::{fmt::Display, sync::Arc};  use tokio::io::AsyncWriteExt;  pub struct Tmdb { @@ -99,7 +95,7 @@ impl Tmdb {          })          .await      } -    pub async fn image(&self, path: &str) -> anyhow::Result<AssetLocation> { +    pub async fn image(&self, path: &str) -> anyhow::Result<CachePath> {          async_cache_file(&["api-tmdb-image", path], |mut file| async move {              info!("downloading image {path:?}");              let mut res = self diff --git a/import/src/trakt.rs b/import/src/trakt.rs index 08962c6..2bec992 100644 --- a/import/src/trakt.rs +++ b/import/src/trakt.rs @@ -1,3 +1,8 @@ +/* +    This file is part of jellything (https://codeberg.org/metamuffin/jellything) +    which is licensed under the GNU Affero General Public License (version 3); see /COPYING. +    Copyright (C) 2024 metamuffin <metamuffin.org> +*/  use bincode::{Decode, Encode};  use jellybase::cache::async_cache_memory;  use jellycommon::{Appearance, ObjectIds, PeopleGroup, Person, TraktKind}; @@ -226,7 +231,7 @@ impl TraktAppearance {              characters: self.characters.to_owned(),              person: Person {                  name: self.person.name.to_owned(), -                asset: None, +                headshot: None,                  ids: self.person.ids.to_owned(),              },          } | 
