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
This commit is contained in:
Schmiddiii 2021-10-13 20:14:39 +02:00 committed by GitHub
parent 8a7a87824f
commit d339785568
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 2 deletions

View File

@ -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"

View File

@ -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);
}

View File

@ -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<S: AsRef<str>>(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<S: AsRef<str>>(&self, name: S) -> Result<ChannelSearch> {
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)
}
}

View File

@ -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<ChannelSearchItem>,
pub nextpage: Option<String>,
pub suggestion: Option<String>,
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<String>,
pub subscribers: i32,
pub videos: i32,
pub verified: bool,
}