plex_api/player/
mod.rs

1use crate::{
2    media_container::player::ResourcesMediaContainer,
3    url::{CLIENT_RESOURCES, SERVER_SYSTEM_PROXY},
4    HttpClient, HttpClientBuilder, MyPlex, Result, Server,
5};
6use http::{uri::PathAndQuery, Uri};
7use std::fmt::{Debug, Display};
8
9#[derive(Debug, Clone)]
10pub struct Player {
11    client: HttpClient,
12    _media_container: ResourcesMediaContainer,
13    _last_command_id: u64,
14    pub myplex_api_url: Uri,
15}
16
17impl Player {
18    #[tracing::instrument(level = "debug", skip(client))]
19    pub async fn new<U>(url: U, client: HttpClient) -> Result<Self>
20    where
21        U: Debug,
22        Uri: TryFrom<U>,
23        <Uri as TryFrom<U>>::Error: Into<http::Error>,
24    {
25        let myplex_api_url = client.api_url.clone();
26        Ok(Self {
27            _media_container: client
28                .get(CLIENT_RESOURCES)
29                .header("Accept", "application/xml")
30                .xml()
31                .await?,
32            client,
33            myplex_api_url,
34            _last_command_id: 0,
35        })
36    }
37
38    #[tracing::instrument(level = "debug", skip(server))]
39    pub async fn via_proxy<U>(url: U, server: &Server) -> Result<Self>
40    where
41        U: Display + Debug,
42        Uri: TryFrom<U>,
43        <Uri as TryFrom<U>>::Error: Into<http::Error>,
44    {
45        let mut client = server.client().clone();
46
47        let path_and_query =
48            PathAndQuery::try_from(CLIENT_RESOURCES).map_err(Into::<http::Error>::into)?;
49        let mut uri_parts = Uri::try_from(url)
50            .map_err(Into::<http::Error>::into)?
51            .into_parts();
52        uri_parts.path_and_query = Some(path_and_query);
53        let uri = Uri::from_parts(uri_parts).map_err(Into::<http::Error>::into)?;
54
55        let media_container: ResourcesMediaContainer = client
56            .get(SERVER_SYSTEM_PROXY)
57            .header("X-Plex-Url", format!("{uri}"))
58            .xml()
59            .await?;
60        client
61            .x_plex_target_client_identifier
62            .clone_from(&media_container.player.machine_identifier);
63        Ok(Self {
64            _media_container: media_container,
65            client,
66            myplex_api_url: server.myplex_api_url.clone(),
67            _last_command_id: 0,
68        })
69    }
70
71    pub fn myplex(&self) -> Result<MyPlex> {
72        self.myplex_with_api_url(self.myplex_api_url.clone())
73    }
74
75    pub fn myplex_with_api_url<U>(&self, api_url: U) -> Result<MyPlex>
76    where
77        Uri: TryFrom<U>,
78        <Uri as TryFrom<U>>::Error: Into<http::Error>,
79    {
80        Ok(MyPlex::new(
81            HttpClientBuilder::from(self.client.clone())
82                .set_api_url(api_url)
83                .build()?,
84        ))
85    }
86
87    pub fn client(&self) -> &HttpClient {
88        &self.client
89    }
90}