aboutsummaryrefslogtreecommitdiff
path: root/logic
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-04-28 00:48:52 +0200
committermetamuffin <metamuffin@disroot.org>2025-04-28 00:48:52 +0200
commit80d28b764c95891551e28c395783f5ff9d065743 (patch)
treef25898b1c939a939c63236ca4e8e843e81069947 /logic
parent335ba978dbaf203f3603a815147fd75dbf205723 (diff)
downloadjellything-80d28b764c95891551e28c395783f5ff9d065743.tar
jellything-80d28b764c95891551e28c395783f5ff9d065743.tar.bz2
jellything-80d28b764c95891551e28c395783f5ff9d065743.tar.zst
start with splitting server
Diffstat (limited to 'logic')
-rw-r--r--logic/Cargo.toml10
-rw-r--r--logic/src/home.rs143
-rw-r--r--logic/src/lib.rs7
3 files changed, 160 insertions, 0 deletions
diff --git a/logic/Cargo.toml b/logic/Cargo.toml
new file mode 100644
index 0000000..4107c14
--- /dev/null
+++ b/logic/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "logic"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+jellybase = { path = "../base" }
+jellycommon = { path = "../common" }
+log = "0.4.27"
+anyhow = "1.0.98"
diff --git a/logic/src/home.rs b/logic/src/home.rs
new file mode 100644
index 0000000..f03173e
--- /dev/null
+++ b/logic/src/home.rs
@@ -0,0 +1,143 @@
+/*
+ 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 anyhow::{Context, Result};
+use jellybase::database::Database;
+use jellycommon::{
+ NodeID, NodeKind, Rating, Visibility,
+ api::ApiHomeResponse,
+ chrono::{Datelike, Utc},
+ user::WatchedState,
+};
+
+pub fn home(db: Database) -> Result<ApiHomeResponse> {
+ let mut items = db.list_nodes_with_udata(&sess.user.name)?;
+
+ let mut toplevel = db
+ .get_node_children(NodeID::from_slug("library"))
+ .context("root node missing")?
+ .into_iter()
+ .map(|n| db.get_node_with_userdata(n, &sess))
+ .collect::<anyhow::Result<Vec<_>>>()?;
+ toplevel.sort_by_key(|(n, _)| n.index.unwrap_or(usize::MAX));
+
+ let mut categories = Vec::<(String, Vec<_>)>::new();
+
+ categories.push((
+ "home.bin.continue_watching".to_string(),
+ items
+ .iter()
+ .filter(|(_, u)| matches!(u.watched, WatchedState::Progress(_)))
+ .cloned()
+ .collect(),
+ ));
+ categories.push((
+ "home.bin.watchlist".to_string(),
+ items
+ .iter()
+ .filter(|(_, u)| matches!(u.watched, WatchedState::Pending))
+ .cloned()
+ .collect(),
+ ));
+
+ items.retain(|(n, _)| matches!(n.visibility, Visibility::Visible));
+
+ items.sort_by_key(|(n, _)| n.release_date.map(|d| -d).unwrap_or(i64::MAX));
+
+ categories.push((
+ "home.bin.latest_video".to_string(),
+ items
+ .iter()
+ .filter(|(n, _)| matches!(n.kind, NodeKind::Video))
+ .take(16)
+ .cloned()
+ .collect(),
+ ));
+ categories.push((
+ "home.bin.latest_music".to_string(),
+ items
+ .iter()
+ .filter(|(n, _)| matches!(n.kind, NodeKind::Music))
+ .take(16)
+ .cloned()
+ .collect(),
+ ));
+ categories.push((
+ "home.bin.latest_short_form".to_string(),
+ items
+ .iter()
+ .filter(|(n, _)| matches!(n.kind, NodeKind::ShortFormVideo))
+ .take(16)
+ .cloned()
+ .collect(),
+ ));
+
+ items.sort_by_key(|(n, _)| {
+ n.ratings
+ .get(&Rating::Tmdb)
+ .map(|x| (*x * -1000.) as i32)
+ .unwrap_or(0)
+ });
+
+ categories.push((
+ "home.bin.max_rating".to_string(),
+ items
+ .iter()
+ .take(16)
+ .filter(|(n, _)| n.ratings.contains_key(&Rating::Tmdb))
+ .cloned()
+ .collect(),
+ ));
+
+ items.retain(|(n, _)| {
+ matches!(
+ n.kind,
+ NodeKind::Video | NodeKind::Movie | NodeKind::Episode | NodeKind::Music
+ )
+ });
+
+ categories.push((
+ "home.bin.daily_random".to_string(),
+ (0..16)
+ .flat_map(|i| Some(items[cheap_daily_random(i).checked_rem(items.len())?].clone()))
+ .collect(),
+ ));
+
+ {
+ let mut items = items.clone();
+ items.retain(|(_, u)| matches!(u.watched, WatchedState::Watched));
+ categories.push((
+ "home.bin.watch_again".to_string(),
+ (0..16)
+ .flat_map(|i| Some(items[cheap_daily_random(i).checked_rem(items.len())?].clone()))
+ .collect(),
+ ));
+ }
+
+ items.retain(|(n, _)| matches!(n.kind, NodeKind::Music));
+ categories.push((
+ "home.bin.daily_random_music".to_string(),
+ (0..16)
+ .flat_map(|i| Some(items[cheap_daily_random(i).checked_rem(items.len())?].clone()))
+ .collect(),
+ ));
+
+ Ok(ApiHomeResponse {
+ toplevel,
+ categories,
+ })
+}
+
+fn cheap_daily_random(i: usize) -> usize {
+ xorshift(xorshift(Utc::now().num_days_from_ce() as u64) + i as u64) as usize
+}
+
+fn xorshift(mut x: u64) -> u64 {
+ x ^= x << 13;
+ x ^= x >> 7;
+ x ^= x << 17;
+ x
+}
diff --git a/logic/src/lib.rs b/logic/src/lib.rs
new file mode 100644
index 0000000..cc988d7
--- /dev/null
+++ b/logic/src/lib.rs
@@ -0,0 +1,7 @@
+/*
+ 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>
+*/
+
+pub mod home;