diff --git a/examples/channel.rs b/examples/channel.rs index 0919422..d767ca6 100644 --- a/examples/channel.rs +++ b/examples/channel.rs @@ -1,16 +1,13 @@ use piped::PipedClient; -use reqwest::ClientBuilder; +use reqwest::Client; + +const INSTANCE: &'static str = "https://pipedapi.kavin.rocks"; #[tokio::main] async fn main() { - let httpclient = ClientBuilder::new() - .user_agent("Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0") - .build() - .unwrap(); + let httpclient = Client::new(); - let instance = "https://pipedapi.kavin.rocks".to_string(); - - let client = PipedClient::new(httpclient, instance); + let client = PipedClient::new(&httpclient, INSTANCE); let channel = client .channel_from_id("UCXuqSBlHAE6Xw-yeJA0Tunw".to_string()) diff --git a/examples/comments.rs b/examples/comments.rs index 98d869f..e12a1f8 100644 --- a/examples/comments.rs +++ b/examples/comments.rs @@ -1,16 +1,13 @@ use piped::PipedClient; -use reqwest::ClientBuilder; +use reqwest::Client; + +const INSTANCE: &'static str = "https://pipedapi.kavin.rocks"; #[tokio::main] async fn main() { - let httpclient = ClientBuilder::new() - .user_agent("Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0") - .build() - .unwrap(); + let httpclient = Client::new(); - let instance = "https://pipedapi.kavin.rocks".to_string(); - - let client = PipedClient::new(httpclient, instance); + let client = PipedClient::new(&httpclient, INSTANCE); let comments = client .comments_from_id("__hYx6ZzFbQ".to_string()) diff --git a/examples/playlist.rs b/examples/playlist.rs index 45a2887..cd3def6 100644 --- a/examples/playlist.rs +++ b/examples/playlist.rs @@ -1,16 +1,13 @@ use piped::PipedClient; -use reqwest::ClientBuilder; +use reqwest::Client; + +const INSTANCE: &'static str = "https://pipedapi.kavin.rocks"; #[tokio::main] async fn main() { - let httpclient = ClientBuilder::new() - .user_agent("Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0") - .build() - .unwrap(); + let httpclient = Client::new(); - let instance = "https://pipedapi.kavin.rocks".to_string(); - - let client = PipedClient::new(httpclient, instance); + let client = PipedClient::new(&httpclient, INSTANCE); let playlist = client .playlist_from_id("PLQSoWXSpjA38FIQCvwnVNPlGPVA63WTD8".to_string()) diff --git a/examples/search_suggestions.rs b/examples/search_suggestions.rs index e3f237a..9c1ecc3 100644 --- a/examples/search_suggestions.rs +++ b/examples/search_suggestions.rs @@ -1,16 +1,13 @@ use piped::PipedClient; -use reqwest::ClientBuilder; +use reqwest::Client; + +const INSTANCE: &'static str = "https://pipedapi.kavin.rocks"; #[tokio::main] async fn main() { - let httpclient = ClientBuilder::new() - .user_agent("Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0") - .build() - .unwrap(); + let httpclient = Client::new(); - let instance = "https://pipedapi.kavin.rocks".to_string(); - - let client = PipedClient::new(httpclient, instance); + let client = PipedClient::new(&httpclient, INSTANCE); let suggestions = client .search_suggestions("techlore".to_string()) diff --git a/examples/trending.rs b/examples/trending.rs index a7fb0f1..4575362 100644 --- a/examples/trending.rs +++ b/examples/trending.rs @@ -1,16 +1,13 @@ use piped::PipedClient; -use reqwest::ClientBuilder; +use reqwest::Client; + +const INSTANCE: &'static str = "https://pipedapi.kavin.rocks"; #[tokio::main] async fn main() { - let httpclient = ClientBuilder::new() - .user_agent("Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0") - .build() - .unwrap(); + let httpclient = Client::new(); - let instance = "https://pipedapi.kavin.rocks".to_string(); - - let client = PipedClient::new(httpclient, instance); + let client = PipedClient::new(&httpclient, INSTANCE); let streams = client.trending("US".to_string()).await.unwrap(); diff --git a/examples/video.rs b/examples/video.rs index 72a0e17..922465d 100644 --- a/examples/video.rs +++ b/examples/video.rs @@ -1,16 +1,13 @@ use piped::PipedClient; -use reqwest::ClientBuilder; +use reqwest::Client; + +const INSTANCE: &'static str = "https://pipedapi.kavin.rocks"; #[tokio::main] async fn main() { - let httpclient = ClientBuilder::new() - .user_agent("Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0") - .build() - .unwrap(); + let httpclient = Client::new(); - let instance = "https://pipedapi.kavin.rocks".to_string(); - - let client = PipedClient::new(httpclient, instance); + let client = PipedClient::new(&httpclient, INSTANCE); let video = client .video_from_id("__hYx6ZzFbQ".to_string()) diff --git a/piped/Cargo.toml b/piped/Cargo.toml index 95046d4..8d7a808 100644 --- a/piped/Cargo.toml +++ b/piped/Cargo.toml @@ -12,5 +12,8 @@ version = "0.0.0" [dependencies] reqwest = "^0.11" +url = "^2.2" serde = {version = "^1.0", features = ["derive"]} serde_json = "^1.0" + +thiserror = "^1.0" diff --git a/piped/src/client.rs b/piped/src/client.rs index ddd096e..0a43abf 100644 --- a/piped/src/client.rs +++ b/piped/src/client.rs @@ -1,38 +1,46 @@ use reqwest::{Client, Url}; -use crate::{Channel, CommentsInfo, Playlist, RelatedStream, StreamsPage, VideoInfo}; +use crate::{Channel, CommentsInfo, Playlist, RelatedStream, Result, StreamsPage, VideoInfo}; pub struct PipedClient { pub httpclient: Client, pub instance: String, } +const USER_AGENT: &'static str = + "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0"; + impl PipedClient { - pub fn new(httpclient: Client, instance: String) -> PipedClient { + pub fn new>(httpclient: &Client, instance: S) -> PipedClient { PipedClient { - httpclient, - instance, + httpclient: httpclient.clone(), + instance: instance.as_ref().to_string(), } } - pub async fn trending( - &self, - region: String, - ) -> Result, Box> { + pub async fn trending>(&self, region: S) -> Result> { let mut url = Url::parse(format!("{}/trending", &self.instance).as_str())?; - url.query_pairs_mut().append_pair("region", region.as_str()); + url.query_pairs_mut().append_pair("region", region.as_ref()); - let resp = &self.httpclient.get(url).send().await?.text().await?; + let resp = &self + .httpclient + .get(url) + .header("User-Agent", USER_AGENT) + .send() + .await? + .text() + .await?; - let streams: Vec = serde_json::from_str(resp.as_str())?; + let streams: Vec = serde_json::from_str(resp.as_ref())?; Ok(streams) } - pub async fn channel_from_id(&self, id: String) -> Result> { + pub async fn channel_from_id>(&self, id: S) -> Result { let resp = &self .httpclient - .get(format!("{}/channel/{}", &self.instance, id)) + .get(format!("{}/channel/{}", &self.instance, id.as_ref())) + .header("User-Agent", USER_AGENT) .send() .await? .text() @@ -43,63 +51,78 @@ impl PipedClient { Ok(channel) } - pub async fn channel_continuation( + pub async fn channel_continuation>( &self, - id: String, - nexturl: String, - nextbody: String, - ) -> Result> { - let mut url = Url::parse(format!("{}/nextpage/channels/{}", &self.instance, id).as_str())?; + id: S, + nexturl: S, + nextbody: S, + ) -> Result { + let mut url = + Url::parse(format!("{}/nextpage/channels/{}", &self.instance, id.as_ref()).as_str())?; url.query_pairs_mut() - .append_pair("url", nexturl.as_str()) - .append_pair("id", nextbody.as_str()); + .append_pair("url", nexturl.as_ref()) + .append_pair("id", nextbody.as_ref()); - let resp = &self.httpclient.get(url).send().await?.text().await?; - - let streams: StreamsPage = serde_json::from_str(resp.as_str())?; - - Ok(streams) - } - - pub async fn playlist_from_id( - &self, - id: String, - ) -> Result> { let resp = &self .httpclient - .get(format!("{}/playlists/{}", &self.instance, id)) + .get(url) + .header("User-Agent", USER_AGENT) .send() .await? .text() .await?; - let playlist: Playlist = serde_json::from_str(resp.as_str())?; + let streams: StreamsPage = serde_json::from_str(resp.as_ref())?; + + Ok(streams) + } + + pub async fn playlist_from_id>(&self, id: S) -> Result { + let resp = &self + .httpclient + .get(format!("{}/playlists/{}", &self.instance, id.as_ref())) + .header("User-Agent", USER_AGENT) + .send() + .await? + .text() + .await?; + + let playlist: Playlist = serde_json::from_str(resp.as_ref())?; Ok(playlist) } - pub async fn playlist_continuation( + pub async fn playlist_continuation>( &self, - id: String, - nexturl: String, - nextbody: String, - ) -> Result> { - let mut url = Url::parse(format!("{}/nextpage/playlists/{}", &self.instance, id).as_str())?; + id: S, + nexturl: S, + nextbody: S, + ) -> Result { + let mut url = + Url::parse(format!("{}/nextpage/playlists/{}", &self.instance, id.as_ref()).as_str())?; url.query_pairs_mut() - .append_pair("url", nexturl.as_str()) - .append_pair("id", nextbody.as_str()); + .append_pair("url", nexturl.as_ref()) + .append_pair("id", nextbody.as_ref()); - let resp = &self.httpclient.get(url).send().await?.text().await?; + let resp = &self + .httpclient + .get(url) + .header("User-Agent", USER_AGENT) + .send() + .await? + .text() + .await?; let streams: StreamsPage = serde_json::from_str(resp.as_str())?; Ok(streams) } - pub async fn video_from_id(&self, id: String) -> Result> { + pub async fn video_from_id>(&self, id: S) -> Result { let resp = &self .httpclient - .get(format!("{}/streams/{}", &self.instance, id)) + .get(format!("{}/streams/{}", &self.instance, id.as_ref())) + .header("User-Agent", USER_AGENT) .send() .await? .text() @@ -110,48 +133,58 @@ impl PipedClient { Ok(video) } - pub async fn search_suggestions( - &self, - q: String, - ) -> Result, Box> { + pub async fn search_suggestions>(&self, q: S) -> Result> { let mut url = Url::parse(format!("{}/suggestions", &self.instance).as_str())?; - url.query_pairs_mut().append_pair("query", q.as_str()); + url.query_pairs_mut().append_pair("query", q.as_ref()); - let resp = &self.httpclient.get(url).send().await?.text().await?; - - let suggestions: Vec = serde_json::from_str(resp.as_str())?; - - Ok(suggestions) - } - - pub async fn comments_from_id( - &self, - id: String, - ) -> Result> { let resp = &self .httpclient - .get(format!("{}/comments/{}", &self.instance, id)) + .get(url) + .header("User-Agent", USER_AGENT) .send() .await? .text() .await?; - let comments: CommentsInfo = serde_json::from_str(resp.as_str())?; + let suggestions: Vec = serde_json::from_str(resp.as_ref())?; + + Ok(suggestions) + } + + pub async fn comments_from_id>(&self, id: S) -> Result { + let resp = &self + .httpclient + .get(format!("{}/comments/{}", &self.instance, id.as_ref())) + .header("User-Agent", USER_AGENT) + .send() + .await? + .text() + .await?; + + let comments: CommentsInfo = serde_json::from_str(resp.as_ref())?; Ok(comments) } - pub async fn comments_continuation( + pub async fn comments_continuation>( &self, - id: String, - nexturl: String, - ) -> Result> { - let mut url = Url::parse(format!("{}/nextpage/comments/{}", &self.instance, id).as_str())?; - url.query_pairs_mut().append_pair("url", nexturl.as_str()); + id: S, + nexturl: S, + ) -> Result { + let mut url = + Url::parse(format!("{}/nextpage/comments/{}", &self.instance, id.as_ref()).as_str())?; + url.query_pairs_mut().append_pair("url", nexturl.as_ref()); - let resp = &self.httpclient.get(url).send().await?.text().await?; + let resp = &self + .httpclient + .get(url) + .header("User-Agent", USER_AGENT) + .send() + .await? + .text() + .await?; - let comments: CommentsInfo = serde_json::from_str(resp.as_str())?; + let comments: CommentsInfo = serde_json::from_str(resp.as_ref())?; Ok(comments) } diff --git a/piped/src/error.rs b/piped/src/error.rs new file mode 100644 index 0000000..7e71a96 --- /dev/null +++ b/piped/src/error.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +pub type Result = std::result::Result; + +#[derive(Error, Debug)] +pub enum Error { + #[error("{0}")] + Network(#[from] reqwest::Error), + #[error("{0}")] + ParseResponse(#[from] serde_json::error::Error), + #[error("{0}")] + Parseurl(#[from] url::ParseError), +} diff --git a/piped/src/lib.rs b/piped/src/lib.rs index ea36297..4575039 100644 --- a/piped/src/lib.rs +++ b/piped/src/lib.rs @@ -1,5 +1,7 @@ mod client; +mod error; mod structure; pub use client::PipedClient; +pub use error::{Error, Result}; pub use structure::*;