From d33978556893d95a59f246b1e3a04776f5e834b6 Mon Sep 17 00:00:00 2001 From: Schmiddiii Date: Wed, 13 Oct 2021 20:14:39 +0200 Subject: [PATCH] Feature search channel (#3) * Simple search API Initial support for searching for channels. Additionally the parsing of the instance url got improved (e.g accept URLs without protocol). * Fixed crash with negative video amount * Implement search suggestion --- examples/Cargo.toml | 4 ++++ examples/search_channel.rs | 15 +++++++++++++++ piped/src/client.rs | 33 +++++++++++++++++++++++++++++++-- piped/src/structure.rs | 21 +++++++++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 examples/search_channel.rs diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 66d67da..a2cd572 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -29,6 +29,10 @@ path = "video.rs" name = "search_suggestions" path = "search_suggestions.rs" +[[example]] +name = "search_channel" +path = "search_channel.rs" + [[example]] name = "comments" path = "comments.rs" diff --git a/examples/search_channel.rs b/examples/search_channel.rs new file mode 100644 index 0000000..401d071 --- /dev/null +++ b/examples/search_channel.rs @@ -0,0 +1,15 @@ +use piped::PipedClient; +use reqwest::Client; + +const INSTANCE: &'static str = "pipedapi.kavin.rocks"; + +#[tokio::main] +async fn main() { + let httpclient = Client::new(); + + let client = PipedClient::new(&httpclient, INSTANCE); + + let suggestions = client.search_channel("techlore").await.unwrap(); + + println!("{:#?}", suggestions); +} diff --git a/piped/src/client.rs b/piped/src/client.rs index 0a43abf..3a8c511 100644 --- a/piped/src/client.rs +++ b/piped/src/client.rs @@ -1,6 +1,8 @@ use reqwest::{Client, Url}; -use crate::{Channel, CommentsInfo, Playlist, RelatedStream, Result, StreamsPage, VideoInfo}; +use crate::{ + Channel, ChannelSearch, CommentsInfo, Playlist, RelatedStream, Result, StreamsPage, VideoInfo, +}; pub struct PipedClient { pub httpclient: Client, @@ -12,9 +14,17 @@ const USER_AGENT: &'static str = impl PipedClient { pub fn new>(httpclient: &Client, instance: S) -> PipedClient { + // Format url to always have http(s) in the beginning and no ending / + let mut url = instance.as_ref().to_owned(); + if !url.starts_with("http") { + url = format!("https://{}", url); + } + if url.ends_with('/') { + url.pop(); + } PipedClient { httpclient: httpclient.clone(), - instance: instance.as_ref().to_string(), + instance: url, } } @@ -188,4 +198,23 @@ impl PipedClient { Ok(comments) } + + pub async fn search_channel>(&self, name: S) -> Result { + let mut url = Url::parse(format!("{}/search", &self.instance).as_str())?; + url.query_pairs_mut().append_pair("q", name.as_ref()); + url.query_pairs_mut().append_pair("filter", "channels"); + + let resp = &self + .httpclient + .get(url) + .header("User-Agent", USER_AGENT) + .send() + .await? + .text() + .await?; + + let suggestions: ChannelSearch = serde_json::from_str(resp.as_ref())?; + + Ok(suggestions) + } } diff --git a/piped/src/structure.rs b/piped/src/structure.rs index 9b8ab48..5b45910 100644 --- a/piped/src/structure.rs +++ b/piped/src/structure.rs @@ -125,3 +125,24 @@ pub struct Comment { pub pinned: bool, pub verified: bool, } + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ChannelSearch { + pub items: Vec, + pub nextpage: Option, + pub suggestion: Option, + pub corrected: bool, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ChannelSearchItem { + pub name: String, + pub thumbnail: String, + pub url: String, + pub description: Option, + pub subscribers: i32, + pub videos: i32, + pub verified: bool, +}