1use secrecy::SecretString;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use serde_repr::Deserialize_repr;
5use serde_with::{json::JsonString, serde_as};
6use std::collections::HashMap;
7use time::OffsetDateTime;
8
9#[derive(Deserialize, Debug, Clone)]
10#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
11#[serde(rename_all = "camelCase")]
12pub struct SubscriptionSummary {
13 pub active: bool,
14 #[serde(with = "time::serde::rfc3339::option")]
15 pub subscribed_at: Option<OffsetDateTime>,
16 pub status: SubscriptionStatus,
17 pub payment_service: Option<String>,
18 pub plan: Option<String>,
19 pub features: Vec<crate::media_container::server::Feature>,
20}
21
22#[derive(Deserialize, Debug, Clone, Copy)]
23pub enum SubscriptionStatus {
24 Active,
25 Inactive,
26 Canceled,
27 PendingCancellation,
28 Ended,
29 Lapsed,
30 #[cfg(not(feature = "tests_deny_unknown_fields"))]
31 #[serde(other)]
32 Unknown,
33}
34
35#[derive(Deserialize_repr, Debug, Clone, Copy)]
36#[repr(u8)]
37pub enum AutoSelectSubtitleMode {
38 ManuallySelected = 0,
39 ShownWithForeignAudio = 1,
40 AlwaysEnabled = 2,
41 #[cfg(not(feature = "tests_deny_unknown_fields"))]
42 #[serde(other)]
43 Unknown,
44}
45
46#[allow(clippy::enum_variant_names)]
47#[derive(Deserialize_repr, Debug, Clone, Copy)]
48#[repr(u8)]
49pub enum DefaultSubtitleAccessibility {
50 PreferNonSdhSubtitles = 0,
51 PreferSdhSubtitles = 1,
52 OnlyShowSdhSubtitles = 2,
53 OnlyShowNonSdhSubtitles = 3,
54 #[cfg(not(feature = "tests_deny_unknown_fields"))]
55 #[serde(other)]
56 Unknown,
57}
58
59#[allow(clippy::enum_variant_names)]
60#[derive(Deserialize_repr, Debug, Clone, Copy)]
61#[repr(u8)]
62pub enum DefaultSubtitleForced {
63 PreferNonForcedSubtitles = 0,
64 PreferForcedSubtitles = 1,
65 OnlyShowForcedSubtitles = 2,
66 OnlyShowNonForcedSubtitles = 3,
67 #[cfg(not(feature = "tests_deny_unknown_fields"))]
68 #[serde(other)]
69 Unknown,
70}
71
72#[derive(Deserialize, Debug, Clone)]
73#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
74#[serde(rename_all = "camelCase")]
75pub struct Profile {
76 pub auto_select_audio: bool,
77 pub auto_select_subtitle: AutoSelectSubtitleMode,
78 pub default_subtitle_accessibility: DefaultSubtitleAccessibility,
79 pub default_subtitle_forced: DefaultSubtitleForced,
80 pub default_audio_language: Option<String>,
81 pub default_subtitle_language: Option<String>,
82}
83
84#[derive(Deserialize, Debug, Clone)]
85#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
86#[serde(rename_all = "camelCase")]
87pub struct Subscription {
88 pub id: Option<i32>,
89 pub mode: String,
90 pub state: String,
91 pub renews_at: Option<OffsetDateTime>,
92 pub ends_at: Option<OffsetDateTime>,
93 pub r#type: Option<String>,
94 pub transfer: Option<bool>,
95 pub billing: Option<Value>,
96 pub canceled: Option<bool>,
97 pub grace_period: Option<bool>,
98 pub on_hold: Option<bool>,
99 pub can_upgrade: Option<bool>,
100 pub can_reactivate: Option<bool>,
101 pub can_downgrade: Option<bool>,
102 pub can_convert: Option<bool>,
103}
104
105#[derive(Deserialize, Debug, Clone)]
106#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
107pub struct Service {
108 pub identifier: String,
109 pub endpoint: String,
110 pub token: Option<SecretString>,
111 pub secret: Option<SecretString>,
112 pub status: String,
113}
114
115#[derive(Deserialize, Debug, Clone)]
116#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
117#[serde(rename_all = "camelCase")]
118pub struct MyPlexAccount {
119 pub id: u64,
120 pub uuid: String,
121 pub username: String,
122 pub friendly_name: String,
123 pub confirmed: bool,
124 pub title: String,
125 pub email: String,
126 pub thumb: String,
127 pub locale: Option<String>,
128 pub email_only_auth: bool,
129 pub has_password: bool,
130 pub cloud_sync_device: Option<String>,
131 pub auth_token: SecretString,
132 pub mailing_list_status: Option<String>,
133 pub mailing_list_active: bool,
134 pub scrobble_types: String,
135 pub pin: Option<String>,
136 pub subscription: SubscriptionSummary,
137 pub subscription_description: Option<String>,
138 pub restricted: bool,
139 pub home: bool,
140 pub guest: bool,
141 pub queue_email: Option<String>,
142 pub queue_uid: Option<HashMap<String, String>>,
143 pub home_size: i32,
144 pub max_home_size: i32,
145 #[serde(with = "time::serde::timestamp::option")]
146 pub remember_expires_at: Option<OffsetDateTime>,
147 pub profile: Profile,
148 pub entitlements: Vec<String>,
149 pub roles: Option<Vec<String>>,
150 pub services: Vec<Service>,
151 pub protected: bool,
152 pub country: String,
153 pub home_admin: bool,
154 pub ads_consent: Option<bool>,
155 #[serde(with = "time::serde::timestamp::option")]
156 pub ads_consent_set_at: Option<OffsetDateTime>,
157 #[serde(with = "time::serde::timestamp::option")]
158 pub ads_consent_reminder_at: Option<OffsetDateTime>,
159 pub anonymous: Option<bool>,
160 pub experimental_features: bool,
161 pub two_factor_enabled: bool,
162 pub backup_codes_created: bool,
163 #[serde(with = "time::serde::timestamp")]
164 pub joined_at: OffsetDateTime,
165
166 pub restriction_profile: Option<RestrictionProfile>,
167 pub mapped_restriction_profile: Option<RestrictionProfile>,
168
169 pub subscriptions: Option<Vec<Subscription>>,
171 pub past_subscriptions: Option<Vec<Subscription>>,
172 pub trials: Option<Vec<Subscription>>,
173
174 pub settings: Option<Vec<Settings>>,
176
177 pub custom_restrictions: Option<CustomRestrictions>,
179 pub providers: Option<Vec<String>>,
180}
181
182#[derive(Deserialize, Debug, Clone)]
183#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
184pub struct CustomRestrictions {
185 pub all: Option<bool>,
186 pub movies: Option<bool>,
187 pub music: Option<bool>,
188 pub photos: Option<bool>,
189 pub television: Option<bool>,
190}
191
192#[derive(Debug, Deserialize, Clone)]
193#[serde(tag = "id", rename_all = "camelCase")]
194pub enum Settings {
195 Experience(ExperienceSettingsContainer),
196 #[cfg(not(feature = "tests_deny_unknown_fields"))]
197 #[serde(other)]
198 Unknown,
199}
200
201#[derive(Debug, Deserialize, Clone)]
202#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
203#[serde(rename_all = "camelCase")]
204pub struct ExperienceSettingsContainer {
205 pub hidden: bool,
206 #[serde(with = "time::serde::timestamp")]
207 pub updated_at: OffsetDateTime,
208
209 #[serde(flatten)]
210 pub settings: ExperienceSettingsFormat,
211}
212
213#[serde_as]
214#[derive(Debug, Deserialize, Clone)]
215#[serde(tag = "type", content = "value", rename_all = "camelCase")]
216pub enum ExperienceSettingsFormat {
217 Json(#[serde_as(as = "JsonString")] ExperienceSettings),
218 #[cfg(not(feature = "tests_deny_unknown_fields"))]
219 #[serde(other)]
220 Unknown,
221}
222
223#[derive(Debug, Deserialize, Clone)]
224#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
225#[serde(rename_all = "camelCase")]
226pub struct ExperienceSettings {
227 pub auto_home_hubs_enabled: bool,
228 pub auto_pinned_providers: Vec<String>,
229 pub schema_version: i32,
230 pub home_settings: ExperienceHomeSettings,
231 pub sidebar_settings: ExperienceSidebarSettings,
232 pub reminders: Vec<String>,
233}
234
235#[derive(Debug, Deserialize, Clone)]
236#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
237#[serde(rename_all = "camelCase")]
238pub struct ExperienceHomeSettings {
239 pub settings_key: String,
240 pub hubs: Vec<String>,
241}
242
243#[derive(Debug, Deserialize, Clone)]
244#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
245#[serde(rename_all = "camelCase")]
246pub struct ExperienceSidebarSettings {
247 pub has_completed_setup: bool,
248 pub pinned_sources: Vec<SidebarSource>,
249}
250
251#[derive(Debug, Deserialize, Clone)]
252#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
253#[serde(rename_all = "camelCase")]
254pub struct SidebarSource {
255 pub key: String,
256 pub source_type: String,
257 pub machine_identifier: String,
258 pub provider_identifier: String,
259 #[serde(rename = "directoryID")]
260 pub directory_id: String,
261 pub directory_icon: String,
262 pub title: String,
263 pub server_friendly_name: String,
264 pub provider_source_title: String,
265 pub is_cloud: bool,
266 pub is_full_owned_server: bool,
267}
268
269#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
270#[serde(rename_all = "snake_case")]
271pub enum RestrictionProfile {
272 LittleKid,
273 OlderKid,
274 Teen,
275 #[cfg(not(feature = "tests_deny_unknown_fields"))]
276 #[serde(other)]
277 Unknown,
278}