/* 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 */ #![feature(array_try_map)] pub mod api; pub mod config; pub mod helpers; pub mod r#impl; pub mod jhls; pub mod routes; pub mod user; pub use jellystream_types as stream; pub use chrono; use serde::{Deserialize, Serialize}; use std::{ collections::{BTreeMap, BTreeSet}, 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_opt(s: &str) -> Option { 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::from_str_opt(s).ok_or(()) } } }; } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct NodeID(pub [u8; 32]); pub enum NodeIDOrSlug { ID(NodeID), Slug(String), } #[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct Node { pub slug: String, pub parents: BTreeSet, pub kind: NodeKind, pub title: Option, pub subtitle: Option, pub tagline: Option, pub description: Option, pub release_date: Option, // in unix millis pub index: Option, pub media: Option, pub federated: Option, pub tags: BTreeSet, pub ratings: BTreeMap, pub pictures: BTreeMap, pub credits: BTreeMap>, pub identifiers: BTreeMap, pub visibility: Visibility, pub storage_size: u64, } #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "snake_case")] pub enum PictureSlot { Cover, Backdrop, } #[repr(u8)] #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "snake_case")] pub enum IdentifierType { MusicbrainzRecording, MusicbrainzArtist, MusicbrainzRelease, MusicbrainzReleaseGroup, AcoustIdTrack, YoutubeVideo, YoutubeChannel, YoutubeChannelHandle, Bandcamp, Isrc, Barcode, TraktMovie, TraktShow, TraktSeason, TraktEpisode, Imdb, Tmdb, Tvdb, Omdb, VgmdbArtist, } #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Hash)] pub struct Asset(pub String); #[derive(Debug, Clone, Deserialize, Serialize)] pub struct Appearance { pub jobs: Vec, pub characters: Vec, pub node: NodeID, } #[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, } #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Default)] #[serde(rename_all = "snake_case")] pub enum Visibility { Hidden, Reduced, #[default] Visible, } #[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)] #[serde(rename_all = "snake_case")] pub enum TrackSource { Local(PathBuf, u64), Remote(usize), } pub type TrackID = usize; #[derive(Debug, Clone, Deserialize, Serialize, Hash, PartialEq, Eq)] pub struct LocalTrack { pub path: PathBuf, pub track: TrackID, } #[derive(Debug, Clone, Deserialize, Serialize)] pub struct MediaInfo { pub duration: f64, // in seconds pub tracks: Vec, #[serde(default)] pub chapters: Vec, } #[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct Chapter { pub time_start: Option, pub time_end: Option, pub labels: Vec<(String, String)>, } #[derive(Debug, Clone, Deserialize, Serialize)] pub struct SourceTrack { pub source: TrackSource, pub kind: SourceTrackKind, pub name: String, pub codec: String, pub language: String, #[serde(default)] pub federated: Vec, } #[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)] #[serde(rename_all = "snake_case")] pub enum SourceTrackKind { Video { width: u64, height: u64, fps: Option, }, Audio { channels: usize, sample_rate: f64, bit_depth: Option, }, Subtitle, }