diff options
author | metamuffin <metamuffin@disroot.org> | 2025-04-28 21:50:51 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-04-28 21:50:51 +0200 |
commit | 73d2d5eb01fceae9e0b1c58afb648822000c878a (patch) | |
tree | 8fd0279949251245e2086ad28e99b114eac1bf14 /common | |
parent | 51761cbdefa39107b9e1f931f1aa8df6aebb2a94 (diff) | |
download | jellything-73d2d5eb01fceae9e0b1c58afb648822000c878a.tar jellything-73d2d5eb01fceae9e0b1c58afb648822000c878a.tar.bz2 jellything-73d2d5eb01fceae9e0b1c58afb648822000c878a.tar.zst |
yes
Diffstat (limited to 'common')
-rw-r--r-- | common/src/api.rs | 26 | ||||
-rw-r--r-- | common/src/impl.rs | 98 | ||||
-rw-r--r-- | common/src/lib.rs | 170 | ||||
-rw-r--r-- | common/src/routes.rs | 63 | ||||
-rw-r--r-- | common/src/user.rs | 70 |
5 files changed, 204 insertions, 223 deletions
diff --git a/common/src/api.rs b/common/src/api.rs index a58c445..aaff940 100644 --- a/common/src/api.rs +++ b/common/src/api.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::{user::NodeUserData, Node, NodeKind}; +use crate::{url_enum, user::NodeUserData, Node, NodeKind}; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, sync::Arc, time::Duration}; @@ -53,32 +53,14 @@ pub struct StatsBin { } #[derive(Debug, Default, Clone)] -#[cfg_attr(feature = "rocket", derive(FromForm, UriDisplayQuery))] pub struct NodeFilterSort { pub sort_by: Option<SortProperty>, pub filter_kind: Option<Vec<FilterProperty>>, pub sort_order: Option<SortOrder>, } - -pub trait UrlEnum: Sized { - fn to_str(&self) -> &'static str; - fn from_str(s: &str) -> Option<Self>; -} -macro_rules! url_enum { - (enum $i:ident { $($vi:ident = $vk:literal),*, }) => { - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "rocket", derive(FromFormField, UriDisplayQuery))] - pub enum $i { $(#[cfg_attr(feature = "rocket", field(value = $vk))] $vi),* } - impl $i { pub const ALL: &'static [$i] = &[$($i::$vi),*]; } - impl UrlEnum for $i { - fn to_str(&self) -> &'static str { match self { $(Self::$vi => $vk),* } } - fn from_str(s: &str) -> Option<Self> { match s { $($vk => Some(Self::$vi) ),*, _ => None } } - } - }; -} - url_enum!( + #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum FilterProperty { FederationLocal = "fed_local", FederationRemote = "fed_remote", @@ -98,6 +80,7 @@ url_enum!( } ); url_enum!( + #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum SortProperty { ReleaseDate = "release_date", Title = "title", @@ -115,8 +98,9 @@ url_enum!( } ); url_enum!( + #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum SortOrder { Ascending = "ascending", Descending = "descending", - } + } ); diff --git a/common/src/impl.rs b/common/src/impl.rs index 5b35be3..690a189 100644 --- a/common/src/impl.rs +++ b/common/src/impl.rs @@ -4,10 +4,8 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ use crate::{ - Node, NodeID, NodeIDOrSlug, ObjectIds, PeopleGroup, SourceTrack, SourceTrackKind, TmdbKind, - TraktKind, + Node, NodeID, NodeIDOrSlug, ObjectIds, SourceTrack, SourceTrackKind, TmdbKind, TraktKind, }; -use hex::FromHexError; use serde::{Deserialize, Serialize}; use std::{fmt::Display, str::FromStr}; @@ -111,58 +109,6 @@ impl Display for ObjectIds { Ok(()) } } -impl Display for PeopleGroup { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - PeopleGroup::Cast => "Cast", - PeopleGroup::Writing => "Writing", - PeopleGroup::Directing => "Directing", - PeopleGroup::Art => "Art", - PeopleGroup::Sound => "Sound", - PeopleGroup::Camera => "Camera", - PeopleGroup::Lighting => "Lighting", - PeopleGroup::Crew => "Crew", - PeopleGroup::Editing => "Editing", - PeopleGroup::Production => "Production", - PeopleGroup::Vfx => "Visual Effects", - PeopleGroup::CostumeMakeup => "Costume & Makeup", - PeopleGroup::CreatedBy => "Created by:", - PeopleGroup::Performance => "Performance", - PeopleGroup::Instrument => "Instrument", - PeopleGroup::Vocal => "Vocal", - PeopleGroup::Arranger => "Arranger", - PeopleGroup::Producer => "Producer", - PeopleGroup::Engineer => "Engineer", - }) - } -} -impl FromStr for PeopleGroup { - type Err = (); - fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok(match s { - "Cast" => PeopleGroup::Cast, - "Writing" => PeopleGroup::Writing, - "Directing" => PeopleGroup::Directing, - "Art" => PeopleGroup::Art, - "Sound" => PeopleGroup::Sound, - "Camera" => PeopleGroup::Camera, - "Lighting" => PeopleGroup::Lighting, - "Crew" => PeopleGroup::Crew, - "Editing" => PeopleGroup::Editing, - "Production" => PeopleGroup::Production, - "Visual Effects" => PeopleGroup::Vfx, - "Costume & Makeup" => PeopleGroup::CostumeMakeup, - "Created by:" => PeopleGroup::CreatedBy, - "Performance" => PeopleGroup::Performance, - "Instrument" => PeopleGroup::Instrument, - "Vocal" => PeopleGroup::Vocal, - "Arranger" => PeopleGroup::Arranger, - "Producer" => PeopleGroup::Producer, - "Engineer" => PeopleGroup::Engineer, - _ => return Err(()), - }) - } -} impl NodeID { pub fn from_slug(slug: &str) -> Self { @@ -186,50 +132,18 @@ impl NodeID { pub const MAX: NodeID = NodeID([255; 32]); } -#[cfg(feature = "rocket")] -impl<'a> rocket::request::FromParam<'a> for NodeID { - type Error = FromHexError; - fn from_param(param: &'a str) -> Result<Self, Self::Error> { - if let Some(id) = param.strip_prefix("+") { +impl FromStr for NodeID { + type Err = hex::FromHexError; + fn from_str(s: &str) -> Result<Self, Self::Err> { + if let Some(id) = s.strip_prefix("+") { let mut k = [0; 32]; hex::decode_to_slice(id, &mut k)?; Ok(NodeID(k)) } else { - Ok(NodeID::from_slug(param)) + Ok(NodeID::from_slug(s)) } } } -#[cfg(feature = "rocket")] -impl rocket::http::uri::fmt::FromUriParam<rocket::http::uri::fmt::Path, NodeID> for NodeID { - type Target = NodeID; - fn from_uri_param(param: NodeID) -> Self::Target { - param - } -} -#[cfg(feature = "rocket")] -impl<'a> rocket::http::uri::fmt::FromUriParam<rocket::http::uri::fmt::Path, &'a String> for NodeID { - type Target = &'a str; - fn from_uri_param(param: &'a String) -> Self::Target { - param.as_str() - } -} -#[cfg(feature = "rocket")] -impl<'a> rocket::http::uri::fmt::FromUriParam<rocket::http::uri::fmt::Path, &'a str> for NodeID { - type Target = &'a str; - fn from_uri_param(param: &'a str) -> Self::Target { - param - } -} -#[cfg(feature = "rocket")] -impl rocket::http::uri::fmt::UriDisplay<rocket::http::uri::fmt::Path> for NodeID { - fn fmt( - &self, - f: &mut rocket::http::uri::fmt::Formatter<'_, rocket::http::uri::fmt::Path>, - ) -> std::fmt::Result { - f.write_value(format!("+{}", hex::encode(self.0)))?; - Ok(()) - } -} impl Display for NodeID { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("+")?; diff --git a/common/src/lib.rs b/common/src/lib.rs index c606b86..26bf361 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -9,9 +9,9 @@ pub mod config; pub mod helpers; pub mod r#impl; pub mod jhls; +pub mod routes; pub mod stream; pub mod user; -pub mod routes; pub use chrono; @@ -22,6 +22,30 @@ use std::{ path::PathBuf, }; +#[macro_export] +macro_rules! url_enum { + ($(#[$a:meta])* enum $i:ident { $($(#[$va:meta])* $vi:ident = $vk:literal),*, }) => { + $(#[$a])* + pub enum $i { $($(#[$va])* $vi),* } + impl $i { + pub const ALL: &'static [$i] = &[$($i::$vi),*]; + pub fn to_str(&self) -> &'static str { match self { $(Self::$vi => $vk),* } } + pub fn from_str(s: &str) -> Option<Self> { match s { $($vk => Some(Self::$vi) ),*, _ => None } } + } + impl std::fmt::Display for $i { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.to_str()) + } + } + impl std::str::FromStr for $i { + type Err = (); + fn from_str(s: &str) -> Result<Self, Self::Err> { + Self::from_str(s).ok_or(()) + } + } + }; +} + #[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct NodeID(pub [u8; 32]); @@ -90,31 +114,35 @@ pub struct ObjectIds { pub tvdb: Option<u64>, } -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Encode, Decode)] -#[serde(rename_all = "snake_case")] -pub enum PeopleGroup { - Cast, - Writing, - Directing, - Art, - Sound, - Camera, - Lighting, - Crew, - Editing, - Production, - Vfx, - CostumeMakeup, - CreatedBy, - // https://musicbrainz.org/relationships/artist-recording - // modelling after this, but its too many categories - 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, @@ -138,35 +166,37 @@ pub enum Visibility { Visible, } -#[derive( - Debug, - Clone, - Copy, - Deserialize, - Serialize, - PartialEq, - Eq, - Default, - Encode, - Decode, - PartialOrd, - Ord, -)] -#[serde(rename_all = "snake_case")] -pub enum NodeKind { - #[default] - Unknown, - Movie, - Video, - Music, - ShortFormVideo, - Collection, - Channel, - Show, - Series, - Season, - Episode, -} +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, Deserialize, Serialize, Encode, Decode)] #[serde(rename_all = "snake_case")] @@ -213,20 +243,22 @@ pub struct SourceTrack { pub federated: Vec<String>, } -#[derive( - Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode, -)] -#[serde(rename_all = "snake_case")] -pub enum Rating { - Imdb, - Tmdb, - RottenTomatoes, - Metacritic, - YoutubeViews, - YoutubeLikes, - YoutubeFollowers, - Trakt, -} +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, PartialEq, Deserialize, Serialize, Encode, Decode)] #[serde(rename_all = "snake_case")] diff --git a/common/src/routes.rs b/common/src/routes.rs index 71ca3fa..e510e22 100644 --- a/common/src/routes.rs +++ b/common/src/routes.rs @@ -3,15 +3,70 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin <metamuffin.org> */ - -use crate::NodeID; +use crate::{user::ApiWatchedState, NodeID, PeopleGroup}; pub fn u_home() -> String { "/home".to_owned() } pub fn u_node_id(node: NodeID) -> String { - format!("/n/{}", node) + format!("/n/{node}") } pub fn u_node_slug(node: &str) -> String { - format!("/n/{}", node) + format!("/n/{node}") +} +pub fn u_node_slug_player(node: &str) -> String { + format!("/n/{node}/player") +} +pub fn u_node_slug_player_time(node: &str, time: f64) -> String { + format!("/n/{node}/player?t={time}") +} +pub fn u_node_slug_poster(node: &str, width: usize) -> String { + format!("/n/{node}/poster?width={width}") +} +pub fn u_node_slug_backdrop(node: &str, width: usize) -> String { + format!("/n/{node}/backdrop?width={width}") +} +pub fn u_node_slug_watched(node: &str, state: ApiWatchedState) -> String { + format!("/n/{node}/watched?state={state}") +} +pub fn u_node_slug_person_asset( + node: &str, + group: PeopleGroup, + index: usize, + width: usize, +) -> String { + format!("/n/{node}/person/{index}/asset?group={group}&width={width}") +} +pub fn u_node_slug_thumbnail(node: &str, time: f64, width: usize) -> String { + format!("/n/{node}/thumbnail?t={time}&width={width}") +} +pub fn u_node_slug_update_rating(node: &str) -> String { + format!("/n/{node}/update_rating") +} +pub fn u_node_slug_progress(node: &str, time: f64) -> String { + format!("/n/{node}/progress?t={time}") +} +pub fn u_account_register() -> String { + "/account/register".to_owned() +} +pub fn u_account_login() -> String { + "/account/login".to_owned() +} +pub fn u_account_logout() -> String { + "/account/logout".to_owned() +} +pub fn u_admin_dashboard() -> String { + "/admin/dashboard".to_owned() +} +pub fn u_account_settings() -> String { + "/account/settings".to_owned() +} +pub fn u_stats() -> String { + "/stats".to_owned() +} +pub fn u_search() -> String { + "/search".to_owned() +} +pub fn u_items() -> String { + "/items".to_owned() } diff --git a/common/src/user.rs b/common/src/user.rs index e0e7a0d..c6da166 100644 --- a/common/src/user.rs +++ b/common/src/user.rs @@ -4,14 +4,14 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ use bincode::{Decode, Encode}; -#[cfg(feature = "rocket")] -use rocket::{FromFormField, UriDisplayQuery}; use serde::{Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, fmt::Display, }; +use crate::url_enum; + #[rustfmt::skip] #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, Default)] pub struct User { @@ -41,6 +41,16 @@ pub enum WatchedState { Pending, } +url_enum!( + #[derive(Debug, Clone, Serialize, Deserialize)] + #[serde(rename_all = "snake_case")] + enum ApiWatchedState { + None = "none", + Watched = "watched", + Pending = "pending", + } +); + #[derive(Debug, Serialize, Deserialize)] pub struct CreateSessionParams { pub username: String, @@ -49,42 +59,28 @@ pub struct CreateSessionParams { pub drop_permissions: Option<HashSet<UserPermission>>, } -#[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "rocket", derive(FromFormField, UriDisplayQuery))] -#[serde(rename_all = "snake_case")] -pub enum Theme { - #[default] - Dark, - Light, - Purple, - Black, -} - -#[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "rocket", derive(FromFormField, UriDisplayQuery))] -#[serde(rename_all = "snake_case")] -pub enum PlayerKind { - #[default] - Browser, - Native, - NativeFullscreen, -} +url_enum!( + #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)] + #[serde(rename_all = "snake_case")] + enum Theme { + #[default] + Dark = "dark", + Light = "light", + Purple = "purple", + Black = "black", + } +); -impl Theme { - pub const LIST: &'static [(Theme, &'static str)] = &[ - (Theme::Dark, "Dark"), - (Theme::Light, "Light"), - (Theme::Purple, "Purple"), - (Theme::Black, "Black"), - ]; -} -impl PlayerKind { - pub const LIST: &'static [(PlayerKind, &'static str)] = &[ - (PlayerKind::Browser, "In-Browser"), - (PlayerKind::Native, "Native"), - (PlayerKind::NativeFullscreen, "Native (Fullscreen)"), - ]; -} +url_enum!( + #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)] + #[serde(rename_all = "snake_case")] + enum PlayerKind { + #[default] + Browser = "browser", + Native = "native", + NativeFullscreen = "native_fullscreen", + } +); #[derive(Debug, Clone, Serialize, Deserialize, Default, Encode, Decode)] pub struct PermissionSet(pub HashMap<UserPermission, bool>); |