feat: add ChannelRss

- add documentation
- small model refactor: rename player VideoPlayerDetails.thumbnails to thumbnail
This commit is contained in:
ThetaDev 2022-09-27 15:23:09 +02:00
parent 6ac5bc3782
commit 305c3ee70e
29 changed files with 2222 additions and 118 deletions

View file

@ -1,3 +1,5 @@
//! YouTube API Client
mod channel;
mod pagination;
mod player;
@ -5,6 +7,9 @@ mod playlist;
mod response;
mod video_details;
#[cfg(feature = "rss")]
mod channel_rss;
use std::fmt::Debug;
use std::sync::Arc;
@ -14,7 +19,7 @@ use fancy_regex::Regex;
use log::{error, warn};
use once_cell::sync::Lazy;
use rand::Rng;
use reqwest::{header, Client, ClientBuilder, Method, Request, RequestBuilder, Response};
use reqwest::{header, Client, ClientBuilder, Request, RequestBuilder, Response};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use tokio::sync::Mutex;
@ -787,24 +792,16 @@ impl RustyPipeQuery {
/// - `ctype`: Client type (`Desktop`, `DesktopMusic`, `Android`, ...)
/// - `method`: HTTP method
/// - `endpoint`: YouTube API endpoint (`https://www.youtube.com/youtubei/v1/<XYZ>?key=...`)
async fn request_builder(
&self,
ctype: ClientType,
method: Method,
endpoint: &str,
) -> RequestBuilder {
async fn request_builder(&self, ctype: ClientType, endpoint: &str) -> RequestBuilder {
match ctype {
ClientType::Desktop => self
.client
.inner
.http
.request(
method,
format!(
"{}{}?key={}{}",
YOUTUBEI_V1_URL, endpoint, DESKTOP_API_KEY, DISABLE_PRETTY_PRINT_PARAMETER
),
)
.post(format!(
"{}{}?key={}{}",
YOUTUBEI_V1_URL, endpoint, DESKTOP_API_KEY, DISABLE_PRETTY_PRINT_PARAMETER
))
.header(header::ORIGIN, "https://www.youtube.com")
.header(header::REFERER, "https://www.youtube.com")
.header(header::COOKIE, self.client.inner.consent_cookie.to_owned())
@ -817,16 +814,13 @@ impl RustyPipeQuery {
.client
.inner
.http
.request(
method,
format!(
"{}{}?key={}{}",
YOUTUBE_MUSIC_V1_URL,
endpoint,
DESKTOP_MUSIC_API_KEY,
DISABLE_PRETTY_PRINT_PARAMETER
),
)
.post(format!(
"{}{}?key={}{}",
YOUTUBE_MUSIC_V1_URL,
endpoint,
DESKTOP_MUSIC_API_KEY,
DISABLE_PRETTY_PRINT_PARAMETER
))
.header(header::ORIGIN, "https://music.youtube.com")
.header(header::REFERER, "https://music.youtube.com")
.header(header::COOKIE, self.client.inner.consent_cookie.to_owned())
@ -839,13 +833,10 @@ impl RustyPipeQuery {
.client
.inner
.http
.request(
method,
format!(
"{}{}?key={}{}",
YOUTUBEI_V1_URL, endpoint, DESKTOP_API_KEY, DISABLE_PRETTY_PRINT_PARAMETER
),
)
.post(format!(
"{}{}?key={}{}",
YOUTUBEI_V1_URL, endpoint, DESKTOP_API_KEY, DISABLE_PRETTY_PRINT_PARAMETER
))
.header(header::ORIGIN, "https://www.youtube.com")
.header(header::REFERER, "https://www.youtube.com")
.header("X-YouTube-Client-Name", "1")
@ -854,16 +845,13 @@ impl RustyPipeQuery {
.client
.inner
.http
.request(
method,
format!(
"{}{}?key={}{}",
YOUTUBEI_V1_GAPIS_URL,
endpoint,
ANDROID_API_KEY,
DISABLE_PRETTY_PRINT_PARAMETER
),
)
.post(format!(
"{}{}?key={}{}",
YOUTUBEI_V1_GAPIS_URL,
endpoint,
ANDROID_API_KEY,
DISABLE_PRETTY_PRINT_PARAMETER
))
.header(
header::USER_AGENT,
format!(
@ -876,16 +864,10 @@ impl RustyPipeQuery {
.client
.inner
.http
.request(
method,
format!(
"{}{}?key={}{}",
YOUTUBEI_V1_GAPIS_URL,
endpoint,
IOS_API_KEY,
DISABLE_PRETTY_PRINT_PARAMETER
),
)
.post(format!(
"{}{}?key={}{}",
YOUTUBEI_V1_GAPIS_URL, endpoint, IOS_API_KEY, DISABLE_PRETTY_PRINT_PARAMETER
))
.header(
header::USER_AGENT,
format!(
@ -911,7 +893,6 @@ impl RustyPipeQuery {
/// - `endpoint`: YouTube API endpoint (`https://www.youtube.com/youtubei/v1/<XYZ>?key=...`)
/// - `body`: Serializable request body to be sent in json format
/// - `deobf`: Deobfuscator (is passed to the mapper to deobfuscate stream URLs).
#[allow(clippy::too_many_arguments)]
async fn execute_request_deobf<
R: DeserializeOwned + MapResponse<M> + Debug,
M,
@ -921,13 +902,12 @@ impl RustyPipeQuery {
ctype: ClientType,
operation: &str,
id: &str,
method: Method,
endpoint: &str,
body: &B,
deobf: Option<&Deobfuscator>,
) -> Result<M> {
let request = self
.request_builder(ctype, method.clone(), endpoint)
.request_builder(ctype, endpoint)
.await
.json(body)
.build()?;
@ -943,9 +923,7 @@ impl RustyPipeQuery {
let create_report = |level: Level, error: Option<String>, msgs: Vec<String>| {
if let Some(reporter) = &self.client.inner.reporter {
let report = Report {
package: "rustypipe".to_owned(),
version: "0.1.0".to_owned(),
date: chrono::Local::now(),
info: Default::default(),
level,
operation: format!("{}({})", operation, id),
error,
@ -953,7 +931,7 @@ impl RustyPipeQuery {
deobf_data: deobf.map(Deobfuscator::get_data),
http_request: crate::report::HTTPRequest {
url: request_url,
method: method.to_string(),
method: "POST".to_string(),
req_header: request_headers
.iter()
.map(|(k, v)| {
@ -1030,11 +1008,10 @@ impl RustyPipeQuery {
ctype: ClientType,
operation: &str,
id: &str,
method: Method,
endpoint: &str,
body: &B,
) -> Result<M> {
self.execute_request_deobf::<R, M, B>(ctype, operation, id, method, endpoint, body, None)
self.execute_request_deobf::<R, M, B>(ctype, operation, id, endpoint, body, None)
.await
}
}