plex_api/myplex/sharing/
mod.rs1mod filter;
2mod friend;
3mod server;
4mod shareables;
5
6use crate::{
7 media_container::users::AllowTuners,
8 url::{MYPLEX_INVITES_FRIENDS, MYPLEX_INVITES_INVITE, MYPLEX_INVITES_SHARED_SERVERS},
9 MyPlex, Result,
10};
11use serde::{Deserialize, Serialize};
12
13pub use filter::SharingFilter;
14pub use friend::{Friend, InviteStatus};
15pub use server::SharedServer;
16pub use shareables::*;
17
18#[derive(Debug)]
19pub struct Sharing<'a> {
20 myplex: &'a MyPlex,
21}
22
23#[derive(Debug, Deserialize, Serialize)]
24#[serde(rename_all = "camelCase")]
25pub struct Permissions {
26 pub allow_sync: bool,
27 pub allow_channels: bool,
28 pub allow_tuners: AllowTuners,
29 pub allow_subtitle_admin: bool,
30 pub allow_camera_upload: bool,
31}
32
33impl Default for Permissions {
34 fn default() -> Self {
35 Self {
36 allow_sync: true,
37 allow_channels: true,
38 allow_tuners: AllowTuners::None,
39 allow_subtitle_admin: true,
40 allow_camera_upload: false,
41 }
42 }
43}
44
45#[derive(Default, Debug, Deserialize, Serialize, Clone)]
46pub struct Filters {
47 #[serde(rename = "filterMovies")]
48 pub movies: SharingFilter,
49 #[serde(rename = "filterMusic")]
50 pub music: SharingFilter,
51 #[serde(rename = "filterTelevision")]
52 pub television: SharingFilter,
53 #[serde(rename = "filterPhotos")]
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub photos: Option<SharingFilter>,
56 #[serde(rename = "filterAll", skip)]
57 _all: Option<String>,
58}
59
60#[derive(Serialize, Debug)]
61#[serde(rename_all = "camelCase")]
62struct ShareServerRequest {
63 invited_email: String,
64 settings: server::Settings,
65 library_section_ids: Vec<u32>,
66 machine_identifier: String,
67}
68
69impl<'a> Sharing<'a> {
70 pub fn new(myplex: &'a MyPlex) -> Self {
71 Sharing { myplex }
72 }
73
74 #[tracing::instrument(level = "debug", skip_all, fields(identifier = user.id()))]
76 pub async fn invite<'b>(&self, user: User<'b>) -> Result<friend::Friend> {
77 self.myplex
78 .client()
79 .post(format!(
80 "{}?{}",
81 MYPLEX_INVITES_INVITE,
82 serde_urlencoded::to_string([("identifier", user.id())])?
83 ))
84 .json()
85 .await
86 }
87
88 #[tracing::instrument(level = "debug", skip_all, fields(user_identifier = user.id(), machine_identifier = server.id()))]
90 pub async fn share<'b, 'c, 'd>(
91 &self,
92 user: User<'b>,
93 server: ShareableServer<'c>,
94 sections: &[ShareableLibrary<'d>],
95 permissions: Permissions,
96 filters: Filters,
97 ) -> Result<SharedServer> {
98 let server_info = self.myplex.server_info(server.id()).await?;
99 let sections: Vec<u32> = sections
100 .iter()
101 .filter_map(|s| s.id().parse().ok())
102 .collect();
103 let request = ShareServerRequest {
104 invited_email: user.id().to_owned(),
105 settings: server::Settings {
106 allow_channels: permissions.allow_channels,
107 allow_subtitle_admin: permissions.allow_subtitle_admin,
108 allow_sync: permissions.allow_sync,
109 allow_tuners: permissions.allow_tuners,
110 allow_camera_upload: permissions.allow_camera_upload,
111 filter_movies: Some(filters.movies),
112 filter_television: Some(filters.television),
113 filter_music: Some(filters.music),
114 filter_photos: filters.photos,
115 ..Default::default()
116 },
117 library_section_ids: server_info
118 .library_sections
119 .iter()
120 .filter_map(|s| {
121 if sections.contains(&s.key) {
122 Some(s.id)
123 } else {
124 None
125 }
126 })
127 .collect(),
128 machine_identifier: server.id().to_owned(),
129 };
130
131 self.myplex
132 .client()
133 .post(MYPLEX_INVITES_SHARED_SERVERS)
134 .json_body(&request)?
135 .json()
136 .await
137 }
138
139 #[tracing::instrument(level = "debug", skip(self))]
141 pub async fn friends(&self, status: InviteStatus) -> Result<Vec<friend::Friend>> {
142 let mut friends: Vec<friend::Friend> = self
143 .myplex
144 .client()
145 .get(format!("{}?includeSharedServers=true&includeSharedSources=true&includeSharingSettings=true&status={}", MYPLEX_INVITES_FRIENDS, status))
146 .json()
147 .await?;
148
149 for friend in &mut friends {
150 friend.client = Some(self.myplex.client().clone())
151 }
152
153 Ok(friends)
154 }
155}