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