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