/* 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) 2024 metamuffin */ use crate::{stream::StreamFormat, user}; use bincode::{Decode, Encode}; #[cfg(feature = "rocket")] use rocket::{FromFormField, UriDisplayQuery}; use serde::{Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, fmt::Display, }; #[rustfmt::skip] #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, Default)] pub struct User { pub name: String, pub display_name: String, pub password: Vec, pub admin: bool, #[serde(default)] pub theme: Theme, #[serde(default)] pub player_preference: PlayerKind, #[serde(default)] pub native_secret: String, pub permissions: PermissionSet, } #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct NodeUserData { pub watched: WatchedState, #[serde(default)] pub rating: i32, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Encode, Decode)] #[serde(rename_all = "snake_case")] pub enum WatchedState { None, Progress(f64), Watched, Pending, } #[derive(Debug, Serialize, Deserialize)] pub struct CreateSessionParams { pub username: String, pub password: String, pub expire: Option, pub drop_permissions: Option>, } #[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, } #[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, } impl Theme { pub const LIST: &'static [(Theme, &'static str)] = &[ (Theme::Dark, "Dark"), (Theme::Light, "Light"), (Theme::Purple, "Purple"), ]; } impl PlayerKind { pub const LIST: &'static [(PlayerKind, &'static str)] = &[ (PlayerKind::Browser, "In-Browser"), (PlayerKind::Native, "Native"), (PlayerKind::NativeFullscreen, "Native (Fullscreen)"), ]; } #[derive(Debug, Clone, Serialize, Deserialize, Default, Encode, Decode)] pub struct PermissionSet(pub HashMap); #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Encode, Decode)] #[serde(rename_all = "snake_case")] pub enum UserPermission { Admin, // ManageUsers, // GenerateInvite, ManageSelf, AccessNode(String), StreamFormat(StreamFormat), Transcode, FederatedContent, } impl UserPermission { pub const ALL_ENUMERABLE: &'static [UserPermission] = { use UserPermission::*; &[ Admin, Transcode, ManageSelf, FederatedContent, StreamFormat(user::StreamFormat::Original), ] }; pub fn default_value(&self) -> bool { use user::StreamFormat::*; use UserPermission::*; matches!( self, Transcode | ManageSelf | FederatedContent | StreamFormat( JhlsIndex | Jvtt | HlsMaster | HlsVariant | Matroska | Fragment | Webvtt ) ) } } impl Display for UserPermission { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&match self { UserPermission::ManageSelf => "manage self (password, display name, etc.)".to_string(), UserPermission::FederatedContent => "access to federated content".to_string(), UserPermission::Admin => "administrative rights".to_string(), UserPermission::StreamFormat(StreamFormat::Original) => { "downloading the original media".to_string() } UserPermission::StreamFormat(StreamFormat::Matroska) => { "downloading a remuxed WebM/Matroska version of the media ".to_string() } UserPermission::StreamFormat(x) => { format!("downloading media via {x:?}") } UserPermission::Transcode => "transcoding".to_string(), // UserPermission::ManageUsers => format!("management of all users"), // UserPermission::GenerateInvite => format!("inviting new users"), UserPermission::AccessNode(s) => format!("access to library node {s:?}"), }) } } impl Default for NodeUserData { fn default() -> Self { Self { watched: WatchedState::None, rating: 0, } } }