aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-11-18 12:08:34 +0100
committermetamuffin <metamuffin@disroot.org>2025-11-18 12:08:34 +0100
commitbac47e456085ea153ae6ae1b1e28e41868693c9c (patch)
tree062c157d66faa3935c1175433732d30c07d1cd5b /common
parentf3af9263b0472bcef3207906ce0e4d1d4aa3595b (diff)
downloadjellything-bac47e456085ea153ae6ae1b1e28e41868693c9c.tar
jellything-bac47e456085ea153ae6ae1b1e28e41868693c9c.tar.bz2
jellything-bac47e456085ea153ae6ae1b1e28e41868693c9c.tar.zst
start reworking model
Diffstat (limited to 'common')
-rw-r--r--common/Cargo.toml1
-rw-r--r--common/src/helpers.rs91
-rw-r--r--common/src/impl.rs18
-rw-r--r--common/src/lib.rs232
-rw-r--r--common/src/routes.rs4
-rw-r--r--common/src/user.rs15
6 files changed, 202 insertions, 159 deletions
diff --git a/common/Cargo.toml b/common/Cargo.toml
index cbe940b..37e9c6c 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2021"
[dependencies]
serde = { version = "1.0.228", features = ["derive", "rc"] }
-bincode = { version = "2.0.1", features = ["derive"] }
chrono = { version = "0.4.42", features = ["serde"] }
blake3 = "1.8.2"
hex = "0.4.3"
diff --git a/common/src/helpers.rs b/common/src/helpers.rs
index 18b8e2b..44e9468 100644
--- a/common/src/helpers.rs
+++ b/common/src/helpers.rs
@@ -3,7 +3,9 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
-use std::ops::Deref;
+
+use crate::{CreditCategory, IdentifierType};
+use std::{fmt::Display, ops::Deref, str::FromStr};
#[derive(PartialEq)]
pub struct SortAnyway<T>(pub T);
@@ -29,3 +31,90 @@ impl<T> Deref for SortAnyway<T> {
&self.0
}
}
+
+impl Display for CreditCategory {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.write_str(match self {
+ CreditCategory::Cast => "cast",
+ CreditCategory::Writing => "writing",
+ CreditCategory::Directing => "directing",
+ CreditCategory::Art => "art",
+ CreditCategory::Sound => "sound",
+ CreditCategory::Camera => "camera",
+ CreditCategory::Lighting => "lighting",
+ CreditCategory::Crew => "crew",
+ CreditCategory::Editing => "editing",
+ CreditCategory::Production => "production",
+ CreditCategory::Vfx => "vfx",
+ CreditCategory::CostumeMakeup => "costume_makeup",
+ CreditCategory::CreatedBy => "created_by",
+ CreditCategory::Performance => "performance",
+ CreditCategory::Instrument => "instrument",
+ CreditCategory::Vocal => "vocal",
+ CreditCategory::Arranger => "arranger",
+ CreditCategory::Producer => "producer",
+ CreditCategory::Engineer => "engineer",
+ })
+ }
+}
+impl FromStr for CreditCategory {
+ type Err = ();
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "cast" => CreditCategory::Cast,
+ "writing" => CreditCategory::Writing,
+ "directing" => CreditCategory::Directing,
+ "art" => CreditCategory::Art,
+ "sound" => CreditCategory::Sound,
+ "camera" => CreditCategory::Camera,
+ "lighting" => CreditCategory::Lighting,
+ "crew" => CreditCategory::Crew,
+ "editing" => CreditCategory::Editing,
+ "production" => CreditCategory::Production,
+ "vfx" => CreditCategory::Vfx,
+ "costume_makeup" => CreditCategory::CostumeMakeup,
+ "created_by" => CreditCategory::CreatedBy,
+ "performance" => CreditCategory::Performance,
+ "instrument" => CreditCategory::Instrument,
+ "vocal" => CreditCategory::Vocal,
+ "arranger" => CreditCategory::Arranger,
+ "producer" => CreditCategory::Producer,
+ "engineer" => CreditCategory::Engineer,
+ _ => return Err(()),
+ })
+ }
+}
+impl Display for IdentifierType {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.write_str(match self {
+ IdentifierType::MusicbrainzRecording => "musicbrainz_recording",
+ IdentifierType::MusicbrainzArtist => "musicbrainz_artist",
+ IdentifierType::MusicbrainzRelease => "musicbrainz_release",
+ IdentifierType::MusicbrainzReleaseGroup => "musicbrainz_release_group",
+ IdentifierType::Isrc => "isrc",
+ IdentifierType::Trakt => "trakt",
+ IdentifierType::Imdb => "imdb",
+ IdentifierType::Tmdb => "tmdb",
+ IdentifierType::Tvdb => "tvdb",
+ IdentifierType::Omdb => "omdb",
+ })
+ }
+}
+impl FromStr for IdentifierType {
+ type Err = ();
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "musicbrainz_recording" => IdentifierType::MusicbrainzRecording,
+ "musicbrainz_artist" => IdentifierType::MusicbrainzArtist,
+ "musicbrainz_release" => IdentifierType::MusicbrainzRelease,
+ "musicbrainz_release_group" => IdentifierType::MusicbrainzReleaseGroup,
+ "isrc" => IdentifierType::Isrc,
+ "trakt" => IdentifierType::Trakt,
+ "imdb" => IdentifierType::Imdb,
+ "tmdb" => IdentifierType::Tmdb,
+ "tvdb" => IdentifierType::Tvdb,
+ "omdb" => IdentifierType::Omdb,
+ _ => return Err(()),
+ })
+ }
+}
diff --git a/common/src/impl.rs b/common/src/impl.rs
index d4c863e..ef1a874 100644
--- a/common/src/impl.rs
+++ b/common/src/impl.rs
@@ -4,7 +4,8 @@
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
use crate::{
- Node, NodeID, NodeIDOrSlug, ObjectIds, SourceTrack, SourceTrackKind, TmdbKind, TraktKind,
+ IdentifierType, Identifiers, Node, NodeID, NodeIDOrSlug, SourceTrack, SourceTrackKind,
+ TmdbKind, TraktKind,
};
use serde::{Deserialize, Serialize};
use std::{fmt::Display, str::FromStr};
@@ -86,24 +87,21 @@ impl Display for TraktKind {
})
}
}
-impl Display for ObjectIds {
+impl Display for Identifiers {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- if let Some(id) = self.trakt {
+ if let Some(id) = self.0.get(&IdentifierType::Trakt) {
f.write_fmt(format_args!("trakt={}", id))?;
}
- if let Some(_id) = &self.slug {
- f.write_str(",slug")?;
- }
- if let Some(id) = self.tmdb {
+ if let Some(id) = &self.0.get(&IdentifierType::Tmdb) {
f.write_fmt(format_args!(",tmdb={}", id))?;
}
- if let Some(_id) = &self.imdb {
+ if let Some(_id) = &self.0.get(&IdentifierType::Imdb) {
f.write_str(",imdb")?;
}
- if let Some(_id) = &self.tvdb {
+ if let Some(_id) = &self.0.get(&IdentifierType::Tvdb) {
f.write_str(",tvdb")?;
}
- if let Some(_id) = &self.omdb {
+ if let Some(_id) = &self.0.get(&IdentifierType::Omdb) {
f.write_str(",omdb")?;
}
Ok(())
diff --git a/common/src/lib.rs b/common/src/lib.rs
index 0cc9ab5..d09153e 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -15,7 +15,6 @@ pub use jellystream_types as stream;
pub use chrono;
-use bincode::{Decode, Encode};
use serde::{Deserialize, Serialize};
use std::{
collections::{BTreeMap, BTreeSet},
@@ -46,7 +45,7 @@ macro_rules! url_enum {
};
}
-#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NodeID(pub [u8; 32]);
pub enum NodeIDOrSlug {
@@ -54,15 +53,11 @@ pub enum NodeIDOrSlug {
Slug(String),
}
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct Node {
- #[serde(default)]
pub slug: String,
- #[serde(default)]
pub parents: BTreeSet<NodeID>,
pub kind: NodeKind,
- pub poster: Option<Asset>,
- pub backdrop: Option<Asset>,
pub title: Option<String>,
pub subtitle: Option<String>,
pub tagline: Option<String>,
@@ -70,94 +65,78 @@ pub struct Node {
pub release_date: Option<i64>, // in unix millis
pub index: Option<usize>,
pub media: Option<MediaInfo>,
- #[serde(default)]
- pub ratings: BTreeMap<Rating, f64>,
pub federated: Option<String>,
- #[serde(default)]
pub tags: BTreeSet<String>,
- #[serde(default)]
- pub people: BTreeMap<PeopleGroup, Vec<Appearance>>,
- #[serde(default)]
- pub external_ids: BTreeMap<String, String>,
- #[serde(default)]
+ pub ratings: BTreeMap<RatingType, f64>,
+ pub pictures: BTreeMap<PictureSlot, Asset>,
+ pub credits: BTreeMap<CreditCategory, Vec<Appearance>>,
+ pub identifiers: Identifiers,
pub visibility: Visibility,
- #[serde(default)]
pub storage_size: u64,
}
-#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize, Default)]
+pub struct Identifiers(pub BTreeMap<IdentifierType, String>);
+
+#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
+#[serde(rename_all = "snake_case")]
+pub enum PictureSlot {
+ Poster,
+ Cover,
+ Backdrop,
+ Headshot,
+}
+
+#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
+#[serde(rename_all = "snake_case")]
+pub enum IdentifierType {
+ MusicbrainzRecording,
+ MusicbrainzArtist,
+ MusicbrainzRelease,
+ MusicbrainzReleaseGroup,
+ Isrc,
+ Trakt,
+ Imdb,
+ Tmdb,
+ Tvdb,
+ Omdb,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct Asset(pub String);
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Appearance {
- #[serde(default)]
pub jobs: Vec<String>,
- #[serde(default)]
pub characters: Vec<String>,
- pub person: Person,
-}
-
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
-pub struct Person {
- pub name: String,
- pub headshot: Option<Asset>,
- pub ids: ObjectIds,
+ pub node: NodeID,
}
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
-pub struct ObjectIds {
- pub trakt: Option<u64>,
- pub slug: Option<String>,
- pub imdb: Option<String>,
- pub tmdb: Option<u64>,
- pub omdb: Option<u64>,
- pub tvdb: Option<u64>,
+#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
+#[serde(rename_all = "snake_case")]
+pub enum CreditCategory {
+ Cast,
+ Writing,
+ Directing,
+ Art,
+ Sound,
+ Camera,
+ Lighting,
+ Crew,
+ Editing,
+ Production,
+ Vfx,
+ CostumeMakeup,
+ CreatedBy,
+ Performance,
+ Instrument,
+ Vocal,
+ Arranger,
+ Producer,
+ Engineer,
}
-url_enum!(
- #[derive(
- Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Encode, Decode,
- )]
- #[serde(rename_all = "snake_case")]
- enum PeopleGroup {
- Cast = "cast",
- Writing = "writing",
- Directing = "directing",
- Art = "art",
- Sound = "sound",
- Camera = "camera",
- Lighting = "lighting",
- Crew = "crew",
- Editing = "editing",
- Production = "production",
- Vfx = "vfx",
- CostumeMakeup = "costume_makeup",
- CreatedBy = "created_by",
- // https://musicbrainz.org/relationships/artist-recording
- // modelling after this, but its too many categories
- Performance = "performance",
- Instrument = "instrument",
- Vocal = "vocal",
- Arranger = "arranger",
- Producer = "producer",
- Engineer = "engineer",
- }
-);
-
-#[derive(
- Debug,
- Clone,
- Copy,
- Deserialize,
- Serialize,
- PartialEq,
- Eq,
- PartialOrd,
- Ord,
- Encode,
- Decode,
- Default,
-)]
+#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Default)]
#[serde(rename_all = "snake_case")]
pub enum Visibility {
Hidden,
@@ -166,39 +145,24 @@ pub enum Visibility {
Visible,
}
-url_enum!(
- #[derive(
- Debug,
- Clone,
- Copy,
- Deserialize,
- Serialize,
- PartialEq,
- Eq,
- Default,
- Encode,
- Decode,
- PartialOrd,
- Ord,
- )]
- #[serde(rename_all = "snake_case")]
- enum NodeKind {
- #[default]
- Unknown = "unknown",
- Movie = "movie",
- Video = "video",
- Music = "music",
- ShortFormVideo = "short_form_video",
- Collection = "collection",
- Channel = "channel",
- Show = "show",
- Series = "series",
- Season = "season",
- Episode = "episode",
- }
-);
+#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Default, PartialOrd, Ord)]
+#[serde(rename_all = "snake_case")]
+pub enum NodeKind {
+ #[default]
+ Unknown,
+ Movie,
+ Video,
+ Music,
+ ShortFormVideo,
+ Collection,
+ Channel,
+ Show,
+ Series,
+ Season,
+ Episode,
+}
-#[derive(Debug, Clone, Deserialize, Serialize, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum TrackSource {
Local(Asset),
@@ -207,13 +171,13 @@ pub enum TrackSource {
pub type TrackID = usize;
-#[derive(Debug, Clone, Deserialize, Serialize, Hash, Encode, Decode, PartialEq, Eq)]
+#[derive(Debug, Clone, Deserialize, Serialize, Hash, PartialEq, Eq)]
pub struct LocalTrack {
pub path: PathBuf,
pub track: TrackID,
}
-#[derive(Debug, Clone, Deserialize, Serialize, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct MediaInfo {
pub duration: f64, // in seconds
pub tracks: Vec<SourceTrack>,
@@ -221,14 +185,14 @@ pub struct MediaInfo {
pub chapters: Vec<Chapter>,
}
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct Chapter {
pub time_start: Option<f64>,
pub time_end: Option<f64>,
pub labels: Vec<(String, String)>,
}
-#[derive(Debug, Clone, Deserialize, Serialize, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SourceTrack {
pub source: TrackSource,
pub kind: SourceTrackKind,
@@ -239,32 +203,25 @@ pub struct SourceTrack {
pub federated: Vec<String>,
}
-url_enum!(
- #[derive(
- Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode,
- )]
- #[serde(rename_all = "snake_case")]
- enum Rating {
- Imdb = "imdb",
- Tmdb = "tmdb",
- RottenTomatoes = "rotten_tomatoes",
- Metacritic = "metacritic",
- YoutubeViews = "youtube_views",
- YoutubeLikes = "youtube_likes",
- YoutubeFollowers = "youtube_followers",
- Trakt = "trakt",
- }
-);
+#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[serde(rename_all = "snake_case")]
+pub enum RatingType {
+ Imdb,
+ Tmdb,
+ RottenTomatoes,
+ Metacritic,
+ YoutubeViews,
+ YoutubeLikes,
+ YoutubeFollowers,
+ Trakt,
+}
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Encode, Decode)]
+#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum SourceTrackKind {
Video {
width: u64,
height: u64,
- display_width: Option<u64>,
- display_height: Option<u64>,
- display_unit: u64,
fps: Option<f64>,
},
Audio {
@@ -275,7 +232,8 @@ pub enum SourceTrackKind {
Subtitle,
}
-#[derive(Debug, Serialize, Deserialize, Clone, Copy, Hash, PartialEq, Encode, Decode)]
+// TODO move this somewhere else
+#[derive(Debug, Serialize, Deserialize, Clone, Copy, Hash, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum TraktKind {
Movie,
diff --git a/common/src/routes.rs b/common/src/routes.rs
index 3e8682b..f78c7f0 100644
--- a/common/src/routes.rs
+++ b/common/src/routes.rs
@@ -3,7 +3,7 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
-use crate::{api::NodeFilterSort, user::ApiWatchedState, NodeID, PeopleGroup};
+use crate::{api::NodeFilterSort, user::ApiWatchedState, NodeID, CreditCategory};
pub fn u_home() -> String {
"/home".to_owned()
@@ -31,7 +31,7 @@ pub fn u_node_slug_watched(node: &str, state: ApiWatchedState) -> String {
}
pub fn u_node_slug_person_asset(
node: &str,
- group: PeopleGroup,
+ group: CreditCategory,
index: usize,
width: usize,
) -> String {
diff --git a/common/src/user.rs b/common/src/user.rs
index c6da166..481732b 100644
--- a/common/src/user.rs
+++ b/common/src/user.rs
@@ -3,7 +3,6 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
-use bincode::{Decode, Encode};
use serde::{Deserialize, Serialize};
use std::{
collections::{HashMap, HashSet},
@@ -13,7 +12,7 @@ use std::{
use crate::url_enum;
#[rustfmt::skip]
-#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, Default)]
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct User {
pub name: String,
pub display_name: String,
@@ -25,14 +24,14 @@ pub struct User {
pub permissions: PermissionSet,
}
-#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)]
+#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeUserData {
pub watched: WatchedState,
#[serde(default)]
pub rating: i32,
}
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Encode, Decode)]
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum WatchedState {
None,
@@ -60,7 +59,7 @@ pub struct CreateSessionParams {
}
url_enum!(
- #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)]
+ #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
enum Theme {
#[default]
@@ -72,7 +71,7 @@ url_enum!(
);
url_enum!(
- #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)]
+ #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
enum PlayerKind {
#[default]
@@ -82,10 +81,10 @@ url_enum!(
}
);
-#[derive(Debug, Clone, Serialize, Deserialize, Default, Encode, Decode)]
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PermissionSet(pub HashMap<UserPermission, bool>);
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Encode, Decode)]
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum UserPermission {
Admin,