aboutsummaryrefslogtreecommitdiff
path: root/logic/src/assets.rs
diff options
context:
space:
mode:
Diffstat (limited to 'logic/src/assets.rs')
-rw-r--r--logic/src/assets.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/logic/src/assets.rs b/logic/src/assets.rs
new file mode 100644
index 0000000..7be3845
--- /dev/null
+++ b/logic/src/assets.rs
@@ -0,0 +1,131 @@
+/*
+ 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) 2025 metamuffin <metamuffin.org>
+*/
+
+use crate::{DATABASE, session::Session};
+use anyhow::{Result, anyhow};
+use jellycommon::{Asset, LocalTrack, NodeID, PeopleGroup, SourceTrackKind, TrackSource};
+use jellyimport_asset_token::AssetInner;
+
+pub fn get_node_backdrop(_session: &Session, id: NodeID) -> Result<Asset> {
+ // TODO perm
+ let node = DATABASE
+ .get_node(id)?
+ .ok_or(anyhow!("node does not exist"))?;
+
+ let mut asset = node.backdrop.clone();
+ if asset.is_none() {
+ if let Some(parent) = node.parents.last().copied() {
+ let parent = DATABASE
+ .get_node(parent)?
+ .ok_or(anyhow!("node does not exist"))?;
+ asset = parent.backdrop.clone();
+ }
+ };
+ Ok(asset.unwrap_or_else(|| {
+ AssetInner::Assets(format!("fallback-{:?}.avif", node.kind).into()).ser()
+ }))
+}
+pub fn get_node_poster(_session: &Session, id: NodeID) -> Result<Asset> {
+ // TODO perm
+ let node = DATABASE
+ .get_node(id)?
+ .ok_or(anyhow!("node does not exist"))?;
+
+ let mut asset = node.poster.clone();
+ if asset.is_none() {
+ if let Some(parent) = node.parents.last().copied() {
+ let parent = DATABASE
+ .get_node(parent)?
+ .ok_or(anyhow!("node does not exist"))?;
+ asset = parent.poster.clone();
+ }
+ };
+ Ok(asset.unwrap_or_else(|| {
+ AssetInner::Assets(format!("fallback-{:?}.avif", node.kind).into()).ser()
+ }))
+}
+
+pub fn get_node_person_asset(
+ _session: &Session,
+ id: NodeID,
+ group: PeopleGroup,
+ index: usize,
+) -> Result<Asset> {
+ // TODO perm
+
+ let node = DATABASE
+ .get_node(id)?
+ .ok_or(anyhow!("node does not exist"))?;
+ let app = node
+ .people
+ .get(&group)
+ .ok_or(anyhow!("group has no members"))?
+ .get(index)
+ .ok_or(anyhow!("person does not exist"))?;
+
+ let asset = app
+ .person
+ .headshot
+ .to_owned()
+ .unwrap_or(AssetInner::Assets("fallback-Person.avif".into()).ser());
+
+ Ok(asset)
+}
+
+pub async fn get_node_thumbnail(_session: &Session, id: NodeID, t: f64) -> Result<Asset> {
+ let node = DATABASE
+ .get_node(id)?
+ .ok_or(anyhow!("node does not exist"))?;
+
+ let media = node.media.as_ref().ok_or(anyhow!("no media"))?;
+ let (thumb_track_index, _thumb_track) = media
+ .tracks
+ .iter()
+ .enumerate()
+ .find(|(_i, t)| matches!(t.kind, SourceTrackKind::Video { .. }))
+ .ok_or(anyhow!("no video track to create a thumbnail of"))?;
+ let source = media
+ .tracks
+ .get(thumb_track_index)
+ .ok_or(anyhow!("no source"))?;
+ let thumb_track_source = source.source.clone();
+
+ if t < 0. || t > media.duration {
+ Err(anyhow!("thumbnail instant not within media duration"))?
+ }
+
+ let step = 8.;
+ let t = (t / step).floor() * step;
+
+ let asset = match thumb_track_source {
+ TrackSource::Local(a) => {
+ let AssetInner::LocalTrack(LocalTrack { path, .. }) = AssetInner::deser(&a.0)? else {
+ return Err(anyhow!("track set to wrong asset type").into());
+ };
+ // the track selected might be different from thumb_track
+ jellytranscoder::thumbnail::create_thumbnail(&path, t).await?
+ }
+ TrackSource::Remote(_) => {
+ // // TODO in the new system this is preferrably a property of node ext for regular fed
+ // let session = fed
+ // .get_session(
+ // thumb_track
+ // .federated
+ // .last()
+ // .ok_or(anyhow!("federation broken"))?,
+ // )
+ // .await?;
+
+ // async_cache_file("fed-thumb", (id.0, t as i64), |out| {
+ // session.node_thumbnail(out, id.0.into(), 2048, t)
+ // })
+ // .await?
+ todo!()
+ }
+ };
+
+ Ok(AssetInner::Cache(asset).ser())
+}