1mod feature;
2pub mod library;
3
4pub use self::feature::Feature;
5use self::library::ContentDirectory;
6use crate::media_container::helpers::StringWithSeparatorOrList;
7use serde::Deserialize;
8use serde_plain::derive_fromstr_from_deserialize;
9use serde_with::{formats::CommaSeparator, serde_as, StringWithSeparator};
10use time::OffsetDateTime;
11
12#[derive(Debug, Deserialize, Clone)]
13#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
14#[serde(rename_all = "camelCase")]
15pub struct Action {
16 pub id: String,
17 pub key: String,
18 pub reverse_key: Option<String>,
19}
20
21#[derive(Debug, Deserialize, Clone)]
22#[serde(tag = "type", rename_all = "camelCase")]
23pub struct GridChannelFilter {
24 pub key: String,
25 pub title: String,
26 pub genre_rating_key: String,
27}
28
29#[derive(Debug, Deserialize, Clone)]
30#[serde(tag = "type", rename_all = "lowercase")]
31pub enum MediaProviderFeature {
32 Content {
33 key: String,
34 #[serde(rename = "Directory")]
35 directory: Vec<ContentDirectory>,
36 },
37 Search {
38 key: String,
39 },
40 #[serde(rename = "universalsearch")]
41 UniversalSearch {
42 key: String,
43 },
44 Match {
45 key: String,
46 },
47 Metadata {
48 key: String,
49 },
50 Rate {
51 key: String,
52 },
53 ImageTranscoder {
54 key: String,
55 public: Option<bool>,
56 },
57 Promoted {
58 key: String,
59 },
60 ContinueWatching {
61 key: String,
62 },
63 Availability {
64 key: String,
65 },
66 #[serde(rename = "availability-platforms")]
67 AvailabilityPlatforms {
68 key: String,
69 },
70 Actions {
71 key: Option<String>,
72 #[serde(rename = "Action")]
73 actions: Vec<Action>,
74 },
75 Playlist {
76 key: String,
77 flavor: String,
78 },
79 PlayQueue {
80 key: String,
81 flavor: String,
82 },
83 #[serde(rename = "collection")]
84 Collections {
85 key: String,
86 },
87 #[serde(rename_all = "camelCase")]
88 Timeline {
89 key: String,
90 scrobble_key: Option<String>,
91 unscrobble_key: Option<String>,
92 },
93 Manage,
94 #[serde(rename = "queryParser")]
95 QueryParser,
96 Subscribe {
97 flavor: String,
98 },
99 Grid {
100 key: String,
101 #[serde(rename = "GridChannelFilter")]
102 grid_channel_filter: Vec<GridChannelFilter>,
103 },
104 Settings {
105 key: String,
106 },
107 #[cfg(not(feature = "tests_deny_unknown_fields"))]
108 #[serde(other)]
109 Unknown,
110}
111
112#[derive(Debug, Deserialize, Clone, Copy)]
113#[serde(rename_all = "lowercase")]
114pub enum MediaProviderProtocol {
115 Stream,
116 Download,
117 #[serde(rename = "livetv")]
118 LiveTv,
119 #[cfg(not(feature = "tests_deny_unknown_fields"))]
120 #[serde(other)]
121 Unknown,
122}
123
124derive_fromstr_from_deserialize!(MediaProviderProtocol);
125
126#[derive(Debug, Deserialize, Clone, Copy)]
127#[serde(rename_all = "lowercase")]
128pub enum MediaProviderType {
129 Video,
130 Audio,
131 Photo,
132 #[cfg(not(feature = "tests_deny_unknown_fields"))]
133 #[serde(other)]
134 Unknown,
135}
136
137derive_fromstr_from_deserialize!(MediaProviderType);
138
139#[derive(Deserialize)]
140#[serde(rename_all = "PascalCase")]
141pub(crate) struct MediaProviderWrapper {
142 pub(crate) media_provider: MediaProvider,
143}
144
145#[serde_as]
146#[derive(Debug, Deserialize, Clone)]
147#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
148#[serde(rename_all = "camelCase")]
149pub struct MediaProvider {
150 pub identifier: String,
151 pub id: Option<u32>,
152 #[serde_as(as = "StringWithSeparatorOrList::<CommaSeparator, MediaProviderProtocol>")]
153 pub protocols: Vec<MediaProviderProtocol>,
154 pub title: String,
155 #[serde_as(as = "StringWithSeparator::<CommaSeparator, MediaProviderType>")]
156 #[serde(default)]
157 pub types: Vec<MediaProviderType>,
158 #[serde(rename = "Feature")]
159 pub features: Vec<MediaProviderFeature>,
160 #[serde(rename = "parentID")]
161 pub parent_id: Option<u32>,
162 pub provider_identifier: Option<String>,
163 pub epg_source: Option<String>,
164 pub friendly_name: Option<String>,
165 pub icon: Option<String>,
166 pub version: Option<String>,
167}
168
169#[derive(Debug, Deserialize, Clone, Copy)]
170#[serde(rename_all = "camelCase")]
171pub enum StartState {
172 StartingPlugins,
173 #[cfg(not(feature = "tests_deny_unknown_fields"))]
174 #[serde(other)]
175 Other,
176}
177
178#[serde_as]
179#[derive(Debug, Deserialize, Clone)]
180#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
181#[serde(rename_all = "camelCase")]
182pub struct Server {
183 pub size: u32,
184 pub allow_camera_upload: bool,
185 pub allow_channel_access: bool,
186 pub allow_media_deletion: Option<bool>,
187 pub allow_sharing: bool,
188 pub allow_sync: bool,
189 pub allow_tuners: bool,
190 pub background_processing: bool,
191 pub certificate: Option<bool>,
192 pub companion_proxy: bool,
193 pub country_code: Option<String>,
194 #[serde_as(as = "StringWithSeparator::<CommaSeparator, Diagnostics>")]
195 pub diagnostics: Vec<Diagnostics>,
196 pub event_stream: bool,
197 pub friendly_name: String,
198 pub livetv: u8,
199 pub machine_identifier: String,
200 pub music_analysis: Option<u8>,
201 pub my_plex: bool,
202 pub my_plex_mapping_state: MappingState,
203 pub my_plex_mapping_error: Option<MappingError>,
204 pub my_plex_signin_state: MyPlexSignInState,
205 pub my_plex_subscription: bool,
206 pub my_plex_username: Option<String>,
207 pub offline_transcode: Option<u8>,
208 #[serde_as(as = "StringWithSeparator::<CommaSeparator, Feature>")]
209 pub owner_features: Vec<Feature>,
210 pub photo_auto_tag: bool,
211 pub platform: String,
212 pub platform_version: String,
213 pub plugin_host: bool,
214 pub push_notifications: bool,
215 pub read_only_libraries: bool,
216 pub start_state: Option<StartState>,
217 #[serde(rename = "streamingBrainABRVersion")]
218 pub streaming_brain_abr_version: u8,
219 pub streaming_brain_version: u8,
220 pub sync: bool,
221 pub transcoder_active_video_sessions: u8,
222 pub transcoder_audio: bool,
223 pub transcoder_lyrics: bool,
224 pub transcoder_subtitles: bool,
225 pub transcoder_video: bool,
226 #[serde_as(as = "StringWithSeparator::<CommaSeparator, u32>")]
227 pub transcoder_video_bitrates: Vec<u32>,
228 #[serde_as(as = "StringWithSeparator::<CommaSeparator, u8>")]
229 pub transcoder_video_qualities: Vec<u8>,
230 #[serde_as(as = "StringWithSeparator::<CommaSeparator, u16>")]
231 pub transcoder_video_resolutions: Vec<u16>,
232 #[serde(with = "time::serde::timestamp")]
233 pub updated_at: OffsetDateTime,
234 pub updater: bool,
235 pub version: String,
236 pub voice_search: bool,
237 #[serde(rename = "MediaProvider")]
238 pub media_providers: Vec<MediaProvider>,
239}
240
241#[derive(Debug, Deserialize, Clone, Copy)]
242#[serde(rename_all = "lowercase")]
243pub enum Diagnostics {
244 Logs,
245 Databases,
246 StreamingLogs,
247 #[cfg(not(feature = "tests_deny_unknown_fields"))]
248 #[serde(other)]
249 UnknownValue,
250}
251
252derive_fromstr_from_deserialize!(Diagnostics);
253
254#[derive(Debug, Deserialize, Clone, Copy)]
255#[serde(rename_all = "camelCase")]
256pub enum MappingState {
257 Unknown,
258 Waiting,
259 Mapped,
260 Failed,
261 #[cfg(not(feature = "tests_deny_unknown_fields"))]
262 #[serde(other)]
263 UnknownValue,
264}
265
266#[derive(Debug, Deserialize, Clone, Copy)]
267#[serde(rename_all = "camelCase")]
268pub enum MappingError {
269 Badauth,
270 Unreachable,
271 #[serde(rename = "myplexgone")]
272 MyplexGone,
273 #[serde(rename = "publisherror")]
274 PublishError,
275 #[serde(rename = "doublenat")]
276 DoubleNat,
277 #[serde(rename = "jumboframes")]
278 JumboFrames,
279 #[cfg(not(feature = "tests_deny_unknown_fields"))]
280 #[serde(other)]
281 UnknownValue,
282}
283
284#[derive(Debug, Deserialize, Clone, Copy)]
285#[serde(rename_all = "camelCase")]
286pub enum MyPlexSignInState {
287 Unknown,
288 None,
289 Invalid,
290 Ok,
291 #[cfg(not(feature = "tests_deny_unknown_fields"))]
292 #[serde(other)]
293 UnknownValue,
294}