Compare commits

...

12 commits

61 changed files with 28570 additions and 4776 deletions

View file

@ -16,6 +16,7 @@ pub async fn download_testfiles(project_root: &Path) {
player(&testfiles).await; player(&testfiles).await;
player_model(&testfiles).await; player_model(&testfiles).await;
playlist(&testfiles).await; playlist(&testfiles).await;
playlist_cont(&testfiles).await;
video_details(&testfiles).await; video_details(&testfiles).await;
comments_top(&testfiles).await; comments_top(&testfiles).await;
comments_latest(&testfiles).await; comments_latest(&testfiles).await;
@ -141,6 +142,25 @@ async fn playlist(testfiles: &Path) {
} }
} }
async fn playlist_cont(testfiles: &Path) {
let mut json_path = testfiles.to_path_buf();
json_path.push("playlist");
json_path.push("playlist_cont.json");
if json_path.exists() {
return;
}
let rp = RustyPipe::new();
let playlist = rp
.query()
.playlist("PL5dDx681T4bR7ZF1IuWzOv1omlRbE7PiJ")
.await
.unwrap();
let rp = rp_testfile(&json_path);
playlist.videos.next(rp.query()).await.unwrap().unwrap();
}
async fn video_details(testfiles: &Path) { async fn video_details(testfiles: &Path) {
for (name, id) in [ for (name, id) in [
("music", "XuM2onMGvTI"), ("music", "XuM2onMGvTI"),
@ -174,9 +194,11 @@ async fn comments_top(testfiles: &Path) {
let details = rp.query().video_details("ZeerrnuLi5E").await.unwrap(); let details = rp.query().video_details("ZeerrnuLi5E").await.unwrap();
let rp = rp_testfile(&json_path); let rp = rp_testfile(&json_path);
rp.query() details
.video_comments(&details.top_comments.ctoken.unwrap()) .top_comments
.next(rp.query())
.await .await
.unwrap()
.unwrap(); .unwrap();
} }
@ -192,9 +214,11 @@ async fn comments_latest(testfiles: &Path) {
let details = rp.query().video_details("ZeerrnuLi5E").await.unwrap(); let details = rp.query().video_details("ZeerrnuLi5E").await.unwrap();
let rp = rp_testfile(&json_path); let rp = rp_testfile(&json_path);
rp.query() details
.video_comments(&details.latest_comments.ctoken.unwrap()) .latest_comments
.next(rp.query())
.await .await
.unwrap()
.unwrap(); .unwrap();
} }
@ -280,10 +304,7 @@ async fn channel_videos_cont(testfiles: &Path) {
.unwrap(); .unwrap();
let rp = rp_testfile(&json_path); let rp = rp_testfile(&json_path);
rp.query() videos.content.next(rp.query()).await.unwrap().unwrap();
.channel_videos_continuation(&videos.content.ctoken.unwrap())
.await
.unwrap();
} }
async fn channel_playlists_cont(testfiles: &Path) { async fn channel_playlists_cont(testfiles: &Path) {
@ -302,10 +323,7 @@ async fn channel_playlists_cont(testfiles: &Path) {
.unwrap(); .unwrap();
let rp = rp_testfile(&json_path); let rp = rp_testfile(&json_path);
rp.query() playlists.content.next(rp.query()).await.unwrap().unwrap();
.channel_playlists_continuation(&playlists.content.ctoken.unwrap())
.await
.unwrap();
} }
async fn search(testfiles: &Path) { async fn search(testfiles: &Path) {

View file

@ -3,17 +3,14 @@ use url::Url;
use crate::{ use crate::{
error::{Error, ExtractionError}, error::{Error, ExtractionError},
model::{Channel, ChannelInfo, ChannelPlaylist, ChannelVideo, Paginator}, model::{Channel, ChannelInfo, Paginator, PlaylistItem, VideoItem},
param::{ChannelOrder, Language}, param::{ChannelOrder, Language},
serializer::MapResult, serializer::MapResult,
timeago, timeago,
util::{self, TryRemove}, util::{self, TryRemove},
}; };
use super::{ use super::{response, ClientType, MapResponse, RustyPipeQuery, YTContext};
response::{self, FromWLang},
ClientType, MapResponse, QContinuation, RustyPipeQuery, YTContext,
};
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -41,7 +38,7 @@ impl RustyPipeQuery {
pub async fn channel_videos( pub async fn channel_videos(
self, self,
channel_id: &str, channel_id: &str,
) -> Result<Channel<Paginator<ChannelVideo>>, Error> { ) -> Result<Channel<Paginator<VideoItem>>, Error> {
self.channel_videos_ordered(channel_id, ChannelOrder::default()) self.channel_videos_ordered(channel_id, ChannelOrder::default())
.await .await
} }
@ -50,7 +47,7 @@ impl RustyPipeQuery {
self, self,
channel_id: &str, channel_id: &str,
order: ChannelOrder, order: ChannelOrder,
) -> Result<Channel<Paginator<ChannelVideo>>, Error> { ) -> Result<Channel<Paginator<VideoItem>>, Error> {
let context = self.get_context(ClientType::Desktop, true).await; let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QChannel { let request_body = QChannel {
context, context,
@ -72,30 +69,10 @@ impl RustyPipeQuery {
.await .await
} }
pub async fn channel_videos_continuation(
self,
ctoken: &str,
) -> Result<Paginator<ChannelVideo>, Error> {
let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QContinuation {
context,
continuation: ctoken,
};
self.execute_request::<response::ChannelCont, _, _>(
ClientType::Desktop,
"channel_videos_continuation",
ctoken,
"browse",
&request_body,
)
.await
}
pub async fn channel_playlists( pub async fn channel_playlists(
self, self,
channel_id: &str, channel_id: &str,
) -> Result<Channel<Paginator<ChannelPlaylist>>, Error> { ) -> Result<Channel<Paginator<PlaylistItem>>, Error> {
let context = self.get_context(ClientType::Desktop, true).await; let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QChannel { let request_body = QChannel {
context, context,
@ -113,26 +90,6 @@ impl RustyPipeQuery {
.await .await
} }
pub async fn channel_playlists_continuation(
self,
ctoken: &str,
) -> Result<Paginator<ChannelPlaylist>, Error> {
let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QContinuation {
context,
continuation: ctoken,
};
self.execute_request::<response::ChannelCont, _, _>(
ClientType::Desktop,
"channel_playlists_continuation",
ctoken,
"browse",
&request_body,
)
.await
}
pub async fn channel_info(&self, channel_id: &str) -> Result<Channel<ChannelInfo>, Error> { pub async fn channel_info(&self, channel_id: &str) -> Result<Channel<ChannelInfo>, Error> {
let context = self.get_context(ClientType::Desktop, true).await; let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QChannel { let request_body = QChannel {
@ -152,13 +109,13 @@ impl RustyPipeQuery {
} }
} }
impl MapResponse<Channel<Paginator<ChannelVideo>>> for response::Channel { impl MapResponse<Channel<Paginator<VideoItem>>> for response::Channel {
fn map_response( fn map_response(
self, self,
id: &str, id: &str,
lang: Language, lang: Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>, _deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Channel<Paginator<ChannelVideo>>>, ExtractionError> { ) -> Result<MapResult<Channel<Paginator<VideoItem>>>, ExtractionError> {
let content = map_channel_content(self.contents, id, self.alerts)?; let content = map_channel_content(self.contents, id, self.alerts)?;
let grid = match content { let grid = match content {
response::channel::ChannelContent::GridRenderer { items } => Some(items), response::channel::ChannelContent::GridRenderer { items } => Some(items),
@ -181,20 +138,22 @@ impl MapResponse<Channel<Paginator<ChannelVideo>>> for response::Channel {
} }
} }
impl MapResponse<Channel<Paginator<ChannelPlaylist>>> for response::Channel { impl MapResponse<Channel<Paginator<PlaylistItem>>> for response::Channel {
fn map_response( fn map_response(
self, self,
id: &str, id: &str,
lang: Language, lang: Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>, _deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Channel<Paginator<ChannelPlaylist>>>, ExtractionError> { ) -> Result<MapResult<Channel<Paginator<PlaylistItem>>>, ExtractionError> {
let content = map_channel_content(self.contents, id, self.alerts)?; let content = map_channel_content(self.contents, id, self.alerts)?;
let grid = match content { let grid = match content {
response::channel::ChannelContent::GridRenderer { items } => Some(items), response::channel::ChannelContent::GridRenderer { items } => Some(items),
_ => None, _ => None,
}; };
let p_res = grid.map(map_playlists).unwrap_or_default(); let p_res = grid
.map(|item| map_playlists(item, lang))
.unwrap_or_default();
Ok(MapResult { Ok(MapResult {
c: map_channel( c: map_channel(
@ -267,98 +226,29 @@ impl MapResponse<Channel<ChannelInfo>> for response::Channel {
} }
} }
impl MapResponse<Paginator<ChannelVideo>> for response::ChannelCont {
fn map_response(
self,
_id: &str,
lang: Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Paginator<ChannelVideo>>, ExtractionError> {
let mut actions = self.on_response_received_actions;
let res = actions
.try_swap_remove(0)
.ok_or(ExtractionError::Retry)?
.append_continuation_items_action
.continuation_items;
Ok(map_videos(res, lang))
}
}
impl MapResponse<Paginator<ChannelPlaylist>> for response::ChannelCont {
fn map_response(
self,
_id: &str,
_lang: Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Paginator<ChannelPlaylist>>, ExtractionError> {
let mut actions = self.on_response_received_actions;
let res = actions
.try_swap_remove(0)
.ok_or(ExtractionError::Retry)?
.append_continuation_items_action
.continuation_items;
Ok(map_playlists(res))
}
}
fn map_videos( fn map_videos(
res: MapResult<Vec<response::VideoListItem>>, res: MapResult<Vec<response::YouTubeListItem>>,
lang: Language, lang: Language,
) -> MapResult<Paginator<ChannelVideo>> { ) -> MapResult<Paginator<VideoItem>> {
let mut ctoken = None; let mut mapper = response::YouTubeListMapper::<VideoItem>::new(lang);
let videos = res mapper.map_response(res);
.c
.into_iter()
.filter_map(|item| match item {
response::VideoListItem::GridVideoRenderer(video) => {
Some(ChannelVideo::from_w_lang(video, lang))
}
response::VideoListItem::RichItemRenderer {
content: response::RichItem::VideoRenderer(video),
} => Some(ChannelVideo::from_w_lang(video, lang)),
response::VideoListItem::ContinuationItemRenderer {
continuation_endpoint,
} => {
ctoken = Some(continuation_endpoint.continuation_command.token);
None
}
_ => None,
})
.collect();
MapResult { MapResult {
c: Paginator::new(None, videos, ctoken), c: Paginator::new(None, mapper.items, mapper.ctoken),
warnings: res.warnings, warnings: mapper.warnings,
} }
} }
fn map_playlists( fn map_playlists(
res: MapResult<Vec<response::VideoListItem>>, res: MapResult<Vec<response::YouTubeListItem>>,
) -> MapResult<Paginator<ChannelPlaylist>> { lang: Language,
let mut ctoken = None; ) -> MapResult<Paginator<PlaylistItem>> {
let playlists = res let mut mapper = response::YouTubeListMapper::<PlaylistItem>::new(lang);
.c mapper.map_response(res);
.into_iter()
.filter_map(|item| match item {
response::VideoListItem::GridPlaylistRenderer(playlist) => Some(playlist.into()),
response::VideoListItem::RichItemRenderer {
content: response::RichItem::PlaylistRenderer(playlist),
} => Some(playlist.into()),
response::VideoListItem::ContinuationItemRenderer {
continuation_endpoint,
} => {
ctoken = Some(continuation_endpoint.continuation_command.token);
None
}
_ => None,
})
.collect();
MapResult { MapResult {
c: Paginator::new(None, playlists, ctoken), c: Paginator::new(None, mapper.items, mapper.ctoken),
warnings: res.warnings, warnings: mapper.warnings,
} }
} }
@ -410,6 +300,7 @@ fn map_channel<T>(
.subscriber_count_text .subscriber_count_text
.and_then(|txt| util::parse_large_numstr(&txt, lang)), .and_then(|txt| util::parse_large_numstr(&txt, lang)),
avatar: header.avatar.into(), avatar: header.avatar.into(),
verification: header.badges.into(),
description: metadata.description, description: metadata.description,
tags: microformat.microformat_data_renderer.tags, tags: microformat.microformat_data_renderer.tags,
vanity_url, vanity_url,
@ -443,6 +334,7 @@ fn map_channel<T>(
.and_then(|txt| util::parse_large_numstr(txt, lang)) .and_then(|txt| util::parse_large_numstr(txt, lang))
}), }),
avatar: hdata.map(|hdata| hdata.1.into()).unwrap_or_default(), avatar: hdata.map(|hdata| hdata.1.into()).unwrap_or_default(),
verification: crate::model::Verification::None,
description: metadata.description, description: metadata.description,
tags: microformat.microformat_data_renderer.tags, tags: microformat.microformat_data_renderer.tags,
vanity_url, vanity_url,
@ -516,7 +408,7 @@ mod tests {
use crate::{ use crate::{
client::{response, MapResponse}, client::{response, MapResponse},
model::{Channel, ChannelInfo, ChannelPlaylist, ChannelVideo, Paginator}, model::{Channel, ChannelInfo, Paginator, PlaylistItem, VideoItem},
param::Language, param::Language,
serializer::MapResult, serializer::MapResult,
}; };
@ -537,7 +429,7 @@ mod tests {
let channel: response::Channel = let channel: response::Channel =
serde_json::from_reader(BufReader::new(json_file)).unwrap(); serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Channel<Paginator<ChannelVideo>>> = let map_res: MapResult<Channel<Paginator<VideoItem>>> =
channel.map_response(id, Language::En, None).unwrap(); channel.map_response(id, Language::En, None).unwrap();
assert!( assert!(
@ -557,27 +449,6 @@ mod tests {
} }
} }
#[test]
fn map_channel_videos_cont() {
let json_path = Path::new("testfiles/channel/channel_videos_cont.json");
let json_file = File::open(json_path).unwrap();
let channel: response::ChannelCont =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Paginator<ChannelVideo>> = channel
.map_response("UC2DjFE7Xf11URZqWBigcVOQ", Language::En, None)
.unwrap();
assert!(
map_res.warnings.is_empty(),
"deserialization/mapping warnings: {:?}",
map_res.warnings
);
insta::assert_ron_snapshot!("map_channel_videos_cont", map_res.c, {
".items[].publish_date" => "[date]",
});
}
#[test] #[test]
fn map_channel_playlists() { fn map_channel_playlists() {
let json_path = Path::new("testfiles/channel/channel_playlists.json"); let json_path = Path::new("testfiles/channel/channel_playlists.json");
@ -585,7 +456,7 @@ mod tests {
let channel: response::Channel = let channel: response::Channel =
serde_json::from_reader(BufReader::new(json_file)).unwrap(); serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Channel<Paginator<ChannelPlaylist>>> = channel let map_res: MapResult<Channel<Paginator<PlaylistItem>>> = channel
.map_response("UC2DjFE7Xf11URZqWBigcVOQ", Language::En, None) .map_response("UC2DjFE7Xf11URZqWBigcVOQ", Language::En, None)
.unwrap(); .unwrap();
@ -597,25 +468,6 @@ mod tests {
insta::assert_ron_snapshot!("map_channel_playlists", map_res.c); insta::assert_ron_snapshot!("map_channel_playlists", map_res.c);
} }
#[test]
fn map_channel_playlists_cont() {
let json_path = Path::new("testfiles/channel/channel_playlists_cont.json");
let json_file = File::open(json_path).unwrap();
let channel: response::ChannelCont =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Paginator<ChannelPlaylist>> = channel
.map_response("UC2DjFE7Xf11URZqWBigcVOQ", Language::En, None)
.unwrap();
assert!(
map_res.warnings.is_empty(),
"deserialization/mapping warnings: {:?}",
map_res.warnings
);
insta::assert_ron_snapshot!("map_channel_playlists_cont", map_res.c);
}
#[test] #[test]
fn map_channel_info() { fn map_channel_info() {
let json_path = Path::new("testfiles/channel/channel_info.json"); let json_path = Path::new("testfiles/channel/channel_info.json");

View file

@ -182,7 +182,6 @@ struct RustyPipeRef {
storage: Option<Box<dyn CacheStorage>>, storage: Option<Box<dyn CacheStorage>>,
reporter: Option<Box<dyn Reporter>>, reporter: Option<Box<dyn Reporter>>,
n_http_retries: u32, n_http_retries: u32,
n_query_retries: u32,
consent_cookie: String, consent_cookie: String,
cache: CacheHolder, cache: CacheHolder,
default_opts: RustyPipeOpts, default_opts: RustyPipeOpts,
@ -200,7 +199,6 @@ pub struct RustyPipeBuilder {
storage: Option<Box<dyn CacheStorage>>, storage: Option<Box<dyn CacheStorage>>,
reporter: Option<Box<dyn Reporter>>, reporter: Option<Box<dyn Reporter>>,
n_http_retries: u32, n_http_retries: u32,
n_query_retries: u32,
user_agent: String, user_agent: String,
default_opts: RustyPipeOpts, default_opts: RustyPipeOpts,
} }
@ -291,8 +289,7 @@ impl RustyPipeBuilder {
default_opts: RustyPipeOpts::default(), default_opts: RustyPipeOpts::default(),
storage: Some(Box::new(FileStorage::default())), storage: Some(Box::new(FileStorage::default())),
reporter: Some(Box::new(FileReporter::default())), reporter: Some(Box::new(FileReporter::default())),
n_http_retries: 3, n_http_retries: 2,
n_query_retries: 2,
user_agent: DEFAULT_UA.to_owned(), user_agent: DEFAULT_UA.to_owned(),
} }
} }
@ -328,7 +325,6 @@ impl RustyPipeBuilder {
storage: self.storage, storage: self.storage,
reporter: self.reporter, reporter: self.reporter,
n_http_retries: self.n_http_retries, n_http_retries: self.n_http_retries,
n_query_retries: self.n_query_retries,
consent_cookie: format!( consent_cookie: format!(
"{}={}{}", "{}={}{}",
CONSENT_COOKIE, CONSENT_COOKIE,
@ -382,18 +378,8 @@ impl RustyPipeBuilder {
/// The waiting time is doubled for subsequent attempts (including a bit of /// The waiting time is doubled for subsequent attempts (including a bit of
/// random jitter to be less predictable). /// random jitter to be less predictable).
/// ///
/// **Default value**: 3
pub fn n_http_retries(mut self, n_retries: u32) -> Self {
self.n_http_retries = n_retries;
self
}
/// Set the number of retries for YouTube API queries.
///
/// If a YouTube API requests returns invalid data, the request is repeated.
///
/// **Default value**: 2 /// **Default value**: 2
pub fn n_query_retries(mut self, n_retries: u32) -> Self { pub fn n_http_retries(mut self, n_retries: u32) -> Self {
self.n_http_retries = n_retries; self.n_http_retries = n_retries;
self self
} }
@ -481,7 +467,7 @@ impl RustyPipe {
/// Execute the given http request. /// Execute the given http request.
async fn http_request(&self, request: Request) -> Result<Response, reqwest::Error> { async fn http_request(&self, request: Request) -> Result<Response, reqwest::Error> {
let mut last_res = None; let mut last_res = None;
for n in 0..self.inner.n_http_retries { for n in 0..=self.inner.n_http_retries {
let res = self.inner.http.execute(request.try_clone().unwrap()).await; let res = self.inner.http.execute(request.try_clone().unwrap()).await;
let emsg = match &res { let emsg = match &res {
Ok(response) => { Ok(response) => {
@ -974,62 +960,6 @@ impl RustyPipeQuery {
endpoint: &str, endpoint: &str,
body: &B, body: &B,
deobf: Option<&Deobfuscator>, deobf: Option<&Deobfuscator>,
) -> Result<M, Error> {
for n in 0..self.client.inner.n_query_retries.saturating_sub(1) {
let res = self
._try_execute_request_deobf::<R, M, B>(
ctype,
operation,
id,
endpoint,
body,
deobf,
n == 0,
)
.await;
let emsg = match res {
Ok(res) => return Ok(res),
Err(error) => match &error {
Error::Extraction(e) => match e {
ExtractionError::Deserialization(_)
| ExtractionError::InvalidData(_)
| ExtractionError::WrongResult(_)
| ExtractionError::Retry => e.to_string(),
_ => return Err(error),
},
_ => return Err(error),
},
};
warn!("{} retry attempt #{}. Error: {}.", operation, n, emsg);
}
self._try_execute_request_deobf::<R, M, B>(
ctype,
operation,
id,
endpoint,
body,
deobf,
self.client.inner.n_query_retries < 2,
)
.await
}
/// Single try of `execute_request_deobf`
#[allow(clippy::too_many_arguments)]
async fn _try_execute_request_deobf<
R: DeserializeOwned + MapResponse<M> + Debug,
M,
B: Serialize + ?Sized,
>(
&self,
ctype: ClientType,
operation: &str,
id: &str,
endpoint: &str,
body: &B,
deobf: Option<&Deobfuscator>,
report: bool,
) -> Result<M, Error> { ) -> Result<M, Error> {
let request = self let request = self
.request_builder(ctype, endpoint) .request_builder(ctype, endpoint)
@ -1049,32 +979,30 @@ impl RustyPipeQuery {
// println!("{}", &resp_str); // println!("{}", &resp_str);
let create_report = |level: Level, error: Option<String>, msgs: Vec<String>| { let create_report = |level: Level, error: Option<String>, msgs: Vec<String>| {
if report { if let Some(reporter) = &self.client.inner.reporter {
if let Some(reporter) = &self.client.inner.reporter { let report = Report {
let report = Report { info: Default::default(),
info: Default::default(), level,
level, operation: format!("{}({})", operation, id),
operation: format!("{}({})", operation, id), error,
error, msgs,
msgs, deobf_data: deobf.map(Deobfuscator::get_data),
deobf_data: deobf.map(Deobfuscator::get_data), http_request: crate::report::HTTPRequest {
http_request: crate::report::HTTPRequest { url: request_url,
url: request_url, method: "POST".to_string(),
method: "POST".to_string(), req_header: request_headers
req_header: request_headers .iter()
.iter() .map(|(k, v)| {
.map(|(k, v)| { (k.to_string(), v.to_str().unwrap_or_default().to_owned())
(k.to_string(), v.to_str().unwrap_or_default().to_owned()) })
}) .collect(),
.collect(), req_body: serde_json::to_string(body).unwrap_or_default(),
req_body: serde_json::to_string(body).unwrap_or_default(), status: status.into(),
status: status.into(), resp_body: resp_str.to_owned(),
resp_body: resp_str.to_owned(), },
}, };
};
reporter.report(&report); reporter.report(&report);
}
} }
}; };
@ -1115,8 +1043,7 @@ impl RustyPipeQuery {
match e { match e {
ExtractionError::VideoUnavailable(_, _) ExtractionError::VideoUnavailable(_, _)
| ExtractionError::VideoAgeRestricted | ExtractionError::VideoAgeRestricted
| ExtractionError::ContentUnavailable(_) | ExtractionError::ContentUnavailable(_) => (),
| ExtractionError::Retry => (),
_ => create_report(Level::ERR, Some(e.to_string()), Vec::new()), _ => create_report(Level::ERR, Some(e.to_string()), Vec::new()),
} }
Err(e.into()) Err(e.into())
@ -1181,8 +1108,3 @@ trait MapResponse<T> {
deobf: Option<&Deobfuscator>, deobf: Option<&Deobfuscator>,
) -> Result<MapResult<T>, ExtractionError>; ) -> Result<MapResult<T>, ExtractionError>;
} }
#[cfg(test)]
mod tests {
// use super::*;
}

View file

@ -1,83 +1,92 @@
use crate::error::Error; use crate::error::{Error, ExtractionError};
use crate::model::{ use crate::model::{Comment, Paginator, PlaylistVideo, YouTubeItem};
ChannelPlaylist, ChannelVideo, Comment, Paginator, PlaylistVideo, RecommendedVideo, SearchItem, use crate::param::ContinuationEndpoint;
SearchVideo, use crate::serializer::MapResult;
}; use crate::util::TryRemove;
use super::RustyPipeQuery; use super::{response, ClientType, MapResponse, QContinuation, RustyPipeQuery};
macro_rules! paginator { impl RustyPipeQuery {
($entity_type:ty, $cont_function:path) => { pub async fn continuation<T: TryFrom<YouTubeItem>>(
impl Paginator<$entity_type> { self,
pub async fn next(&self, query: RustyPipeQuery) -> Result<Option<Self>, Error> { ctoken: &str,
Ok(match &self.ctoken { endpoint: ContinuationEndpoint,
Some(ctoken) => Some($cont_function(query, ctoken).await?), visitor_data: Option<&str>,
None => None, ) -> Result<Paginator<T>, Error> {
}) let mut context = self.get_context(ClientType::Desktop, true).await;
} context.client.visitor_data = visitor_data.map(str::to_owned);
let request_body = QContinuation {
context,
continuation: ctoken,
};
pub async fn extend(&mut self, query: RustyPipeQuery) -> Result<bool, Error> { let p = self
match self.next(query).await { .execute_request::<response::Continuation, Paginator<YouTubeItem>, _>(
Ok(Some(paginator)) => { ClientType::Desktop,
let mut items = paginator.items; "continuation",
self.items.append(&mut items); ctoken,
self.ctoken = paginator.ctoken; endpoint.as_str(),
Ok(true) &request_body,
} )
Ok(None) => Ok(false), .await?;
Err(e) => Err(e),
}
}
pub async fn extend_pages( Ok(Paginator {
&mut self, count: p.count,
query: RustyPipeQuery, items: p
n_pages: usize, .items
) -> Result<(), Error> { .into_iter()
for _ in 0..n_pages { .filter_map(|item| T::try_from(item).ok())
match self.extend(query.clone()).await { .collect(),
Ok(false) => break, ctoken: p.ctoken,
Err(e) => return Err(e), visitor_data: p.visitor_data,
_ => {} endpoint,
} })
} }
Ok(())
}
pub async fn extend_limit(
&mut self,
query: RustyPipeQuery,
n_items: usize,
) -> Result<(), Error> {
while self.items.len() < n_items {
match self.extend(query.clone()).await {
Ok(false) => break,
Err(e) => return Err(e),
_ => {}
}
}
Ok(())
}
}
};
} }
paginator!(PlaylistVideo, RustyPipeQuery::playlist_continuation); impl<T: TryFrom<YouTubeItem>> MapResponse<Paginator<T>> for response::Continuation {
paginator!(RecommendedVideo, RustyPipeQuery::video_recommendations); fn map_response(
paginator!(Comment, RustyPipeQuery::video_comments); self,
paginator!(ChannelVideo, RustyPipeQuery::channel_videos_continuation); _id: &str,
paginator!( lang: crate::param::Language,
ChannelPlaylist, _deobf: Option<&crate::deobfuscate::Deobfuscator>,
RustyPipeQuery::channel_playlists_continuation ) -> Result<MapResult<Paginator<T>>, ExtractionError> {
); let mut actions = self.on_response_received_actions;
paginator!(SearchItem, RustyPipeQuery::search_continuation); let items = some_or_bail!(
actions.try_swap_remove(0),
Err(ExtractionError::InvalidData(
"no item section renderer".into()
))
)
.append_continuation_items_action
.continuation_items;
impl Paginator<SearchVideo> { let mut mapper = response::YouTubeListMapper::<YouTubeItem>::new(lang);
mapper.map_response(items);
Ok(MapResult {
c: Paginator::new(
self.estimated_results,
mapper
.items
.into_iter()
.filter_map(|item| T::try_from(item).ok())
.collect(),
mapper.ctoken,
),
warnings: mapper.warnings,
})
}
}
impl<T: TryFrom<YouTubeItem>> Paginator<T> {
pub async fn next(&self, query: RustyPipeQuery) -> Result<Option<Self>, Error> { pub async fn next(&self, query: RustyPipeQuery) -> Result<Option<Self>, Error> {
Ok(match (&self.ctoken, &self.visitor_data) { Ok(match &self.ctoken {
(Some(ctoken), Some(visitor_data)) => { Some(ctoken) => Some(
Some(query.startpage_continuation(ctoken, visitor_data).await?) query
} .continuation(ctoken, self.endpoint, self.visitor_data.as_deref())
.await?,
),
_ => None, _ => None,
}) })
} }
@ -125,3 +134,135 @@ impl Paginator<SearchVideo> {
Ok(()) Ok(())
} }
} }
impl Paginator<Comment> {
pub async fn next(&self, query: RustyPipeQuery) -> Result<Option<Self>, Error> {
Ok(match &self.ctoken {
Some(ctoken) => Some(
query
.video_comments(ctoken, self.visitor_data.as_deref())
.await?,
),
_ => None,
})
}
}
impl Paginator<PlaylistVideo> {
pub async fn next(&self, query: RustyPipeQuery) -> Result<Option<Self>, Error> {
Ok(match &self.ctoken {
Some(ctoken) => Some(query.playlist_continuation(ctoken).await?),
None => None,
})
}
}
macro_rules! paginator {
($entity_type:ty) => {
impl Paginator<$entity_type> {
pub async fn extend(&mut self, query: RustyPipeQuery) -> Result<bool, Error> {
match self.next(query).await {
Ok(Some(paginator)) => {
let mut items = paginator.items;
self.items.append(&mut items);
self.ctoken = paginator.ctoken;
Ok(true)
}
Ok(None) => Ok(false),
Err(e) => Err(e),
}
}
pub async fn extend_pages(
&mut self,
query: RustyPipeQuery,
n_pages: usize,
) -> Result<(), Error> {
for _ in 0..n_pages {
match self.extend(query.clone()).await {
Ok(false) => break,
Err(e) => return Err(e),
_ => {}
}
}
Ok(())
}
pub async fn extend_limit(
&mut self,
query: RustyPipeQuery,
n_items: usize,
) -> Result<(), Error> {
while self.items.len() < n_items {
match self.extend(query.clone()).await {
Ok(false) => break,
Err(e) => return Err(e),
_ => {}
}
}
Ok(())
}
}
};
}
paginator!(Comment);
paginator!(PlaylistVideo);
#[cfg(test)]
mod tests {
use std::{fs::File, io::BufReader, path::Path};
use rstest::rstest;
use crate::{
client::{response, MapResponse},
model::{Paginator, PlaylistItem, YouTubeItem},
param::Language,
serializer::MapResult,
};
#[rstest]
#[case("search", "search/cont")]
#[case("startpage", "trends/startpage_cont")]
#[case("recommendations", "video_details/recommendations")]
fn map_continuation_items(#[case] name: &str, #[case] path: &str) {
let filename = format!("testfiles/{}.json", path);
let json_path = Path::new(&filename);
let json_file = File::open(json_path).unwrap();
let items: response::Continuation =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Paginator<YouTubeItem>> =
items.map_response("", Language::En, None).unwrap();
assert!(
map_res.warnings.is_empty(),
"deserialization/mapping warnings: {:?}",
map_res.warnings
);
insta::assert_ron_snapshot!(format!("map_{}", name), map_res.c, {
".items.*.publish_date" => "[date]",
});
}
#[rstest]
#[case("channel_playlists", "channel/channel_playlists_cont")]
fn map_continuation_playlists(#[case] name: &str, #[case] path: &str) {
let filename = format!("testfiles/{}.json", path);
let json_path = Path::new(&filename);
let json_file = File::open(json_path).unwrap();
let items: response::Continuation =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Paginator<PlaylistItem>> =
items.map_response("", Language::En, None).unwrap();
assert!(
map_res.warnings.is_empty(),
"deserialization/mapping warnings: {:?}",
map_res.warnings
);
insta::assert_ron_snapshot!(format!("map_{}", name), map_res.c);
}
}

View file

@ -185,7 +185,9 @@ impl MapResponse<Paginator<PlaylistVideo>> for response::PlaylistCont {
_deobf: Option<&Deobfuscator>, _deobf: Option<&Deobfuscator>,
) -> Result<MapResult<Paginator<PlaylistVideo>>, ExtractionError> { ) -> Result<MapResult<Paginator<PlaylistVideo>>, ExtractionError> {
let mut actions = self.on_response_received_actions; let mut actions = self.on_response_received_actions;
let action = actions.try_swap_remove(0).ok_or(ExtractionError::Retry)?; let action = actions
.try_swap_remove(0)
.ok_or_else(|| ExtractionError::InvalidData("no onResponseReceivedAction".into()))?;
let (items, ctoken) = let (items, ctoken) =
map_playlist_items(action.append_continuation_items_action.continuation_items.c); map_playlist_items(action.append_continuation_items_action.continuation_items.c);
@ -200,30 +202,23 @@ impl MapResponse<Paginator<PlaylistVideo>> for response::PlaylistCont {
} }
} }
fn map_playlist_items(items: Vec<response::VideoListItem>) -> (Vec<PlaylistVideo>, Option<String>) { fn map_playlist_items(
items: Vec<response::playlist::PlaylistItem>,
) -> (Vec<PlaylistVideo>, Option<String>) {
let mut ctoken: Option<String> = None; let mut ctoken: Option<String> = None;
let videos = items let videos = items
.into_iter() .into_iter()
.filter_map(|it| match it { .filter_map(|it| match it {
response::VideoListItem::PlaylistVideoRenderer(video) => { response::playlist::PlaylistItem::PlaylistVideoRenderer(video) => {
match ChannelId::try_from(video.channel) { PlaylistVideo::try_from(video).ok()
Ok(channel) => Some(PlaylistVideo {
id: video.video_id,
title: video.title,
length: video.length_seconds,
thumbnail: video.thumbnail.into(),
channel,
}),
Err(_) => None,
}
} }
response::VideoListItem::ContinuationItemRenderer { response::playlist::PlaylistItem::ContinuationItemRenderer {
continuation_endpoint, continuation_endpoint,
} => { } => {
ctoken = Some(continuation_endpoint.continuation_command.token); ctoken = Some(continuation_endpoint.continuation_command.token);
None None
} }
_ => None, response::playlist::PlaylistItem::None => None,
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
(videos, ctoken) (videos, ctoken)
@ -259,4 +254,21 @@ mod tests {
".last_update" => "[date]" ".last_update" => "[date]"
}); });
} }
#[test]
fn map_playlist_cont() {
let json_path = Path::new("testfiles/playlist/playlist_cont.json");
let json_file = File::open(json_path).unwrap();
let playlist: response::PlaylistCont =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res = playlist.map_response("", Language::En, None).unwrap();
assert!(
map_res.warnings.is_empty(),
"deserialization/mapping warnings: {:?}",
map_res.warnings
);
insta::assert_ron_snapshot!("map_playlist_cont", map_res.c);
}
} }

View file

@ -3,16 +3,16 @@ use serde_with::serde_as;
use serde_with::{DefaultOnError, VecSkipError}; use serde_with::{DefaultOnError, VecSkipError};
use super::url_endpoint::NavigationEndpoint; use super::url_endpoint::NavigationEndpoint;
use super::Thumbnails;
use super::{Alert, ChannelBadge}; use super::{Alert, ChannelBadge};
use super::{ContentRenderer, ContentsRenderer, VideoListItem}; use super::{ContentRenderer, ContentsRenderer};
use super::{Thumbnails, YouTubeListItem};
use crate::serializer::ignore_any; use crate::serializer::ignore_any;
use crate::serializer::{text::Text, MapResult, VecLogError}; use crate::serializer::{text::Text, MapResult, VecLogError};
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Channel { pub(crate) struct Channel {
#[serde(default)] #[serde(default)]
#[serde_as(as = "DefaultOnError")] #[serde_as(as = "DefaultOnError")]
pub header: Option<Header>, pub header: Option<Header>,
@ -23,18 +23,9 @@ pub struct Channel {
pub alerts: Option<Vec<Alert>>, pub alerts: Option<Vec<Alert>>,
} }
#[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ChannelCont { pub(crate) struct Contents {
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub on_response_received_actions: Vec<OnResponseReceivedAction>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Contents {
pub two_column_browse_results_renderer: TabsRenderer, pub two_column_browse_results_renderer: TabsRenderer,
} }
@ -43,21 +34,21 @@ pub struct Contents {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TabsRenderer { pub(crate) struct TabsRenderer {
#[serde_as(as = "VecSkipError<_>")] #[serde_as(as = "VecSkipError<_>")]
pub tabs: Vec<TabRendererWrap>, pub tabs: Vec<TabRendererWrap>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TabRendererWrap { pub(crate) struct TabRendererWrap {
pub tab_renderer: ContentRenderer<TabContent>, pub tab_renderer: ContentRenderer<TabContent>,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TabContent { pub(crate) struct TabContent {
#[serde(default)] #[serde(default)]
#[serde_as(as = "DefaultOnError")] #[serde_as(as = "DefaultOnError")]
pub section_list_renderer: Option<SectionListRenderer>, pub section_list_renderer: Option<SectionListRenderer>,
@ -69,7 +60,7 @@ pub struct TabContent {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SectionListRenderer { pub(crate) struct SectionListRenderer {
pub contents: Vec<ItemSectionRendererWrap>, pub contents: Vec<ItemSectionRendererWrap>,
/// - **Videos**: browse-feedUC2DjFE7Xf11URZqWBigcVOQvideos (...) /// - **Videos**: browse-feedUC2DjFE7Xf11URZqWBigcVOQvideos (...)
/// - **Playlists**: browse-feedUC2DjFE7Xf11URZqWBigcVOQplaylists104 (...) /// - **Playlists**: browse-feedUC2DjFE7Xf11URZqWBigcVOQplaylists104 (...)
@ -81,9 +72,9 @@ pub struct SectionListRenderer {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RichGridRenderer { pub(crate) struct RichGridRenderer {
#[serde_as(as = "VecLogError<_>")] #[serde_as(as = "VecLogError<_>")]
pub contents: MapResult<Vec<VideoListItem>>, pub contents: MapResult<Vec<YouTubeListItem>>,
/// - **Videos**: browse-feedUC2DjFE7Xf11URZqWBigcVOQvideos (...) /// - **Videos**: browse-feedUC2DjFE7Xf11URZqWBigcVOQvideos (...)
/// - **Playlists**: browse-feedUC2DjFE7Xf11URZqWBigcVOQplaylists104 (...) /// - **Playlists**: browse-feedUC2DjFE7Xf11URZqWBigcVOQplaylists104 (...)
/// - **Info**: None /// - **Info**: None
@ -92,17 +83,17 @@ pub struct RichGridRenderer {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ItemSectionRendererWrap { pub(crate) struct ItemSectionRendererWrap {
pub item_section_renderer: ContentsRenderer<ChannelContent>, pub item_section_renderer: ContentsRenderer<ChannelContent>,
} }
#[serde_as] #[serde_as]
#[derive(Default, Debug, Deserialize)] #[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum ChannelContent { pub(crate) enum ChannelContent {
GridRenderer { GridRenderer {
#[serde_as(as = "VecLogError<_>")] #[serde_as(as = "VecLogError<_>")]
items: MapResult<Vec<VideoListItem>>, items: MapResult<Vec<YouTubeListItem>>,
}, },
ChannelAboutFullMetadataRenderer(ChannelFullMetadata), ChannelAboutFullMetadataRenderer(ChannelFullMetadata),
#[default] #[default]
@ -112,7 +103,7 @@ pub enum ChannelContent {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum Header { pub(crate) enum Header {
C4TabbedHeaderRenderer(HeaderRenderer), C4TabbedHeaderRenderer(HeaderRenderer),
/// Used for special channels like YouTube Music /// Used for special channels like YouTube Music
CarouselHeaderRenderer(ContentsRenderer<CarouselHeaderRendererItem>), CarouselHeaderRenderer(ContentsRenderer<CarouselHeaderRendererItem>),
@ -121,7 +112,7 @@ pub enum Header {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct HeaderRenderer { pub(crate) struct HeaderRenderer {
/// Approximate subscriber count (e.g. `880K subscribers`), depends on language. /// Approximate subscriber count (e.g. `880K subscribers`), depends on language.
/// ///
/// `None` if the subscriber count is hidden. /// `None` if the subscriber count is hidden.
@ -129,8 +120,9 @@ pub struct HeaderRenderer {
pub subscriber_count_text: Option<String>, pub subscriber_count_text: Option<String>,
#[serde(default)] #[serde(default)]
pub avatar: Thumbnails, pub avatar: Thumbnails,
#[serde_as(as = "Option<VecSkipError<_>>")] #[serde(default)]
pub badges: Option<Vec<ChannelBadge>>, #[serde_as(as = "VecSkipError<_>")]
pub badges: Vec<ChannelBadge>,
#[serde(default)] #[serde(default)]
pub banner: Thumbnails, pub banner: Thumbnails,
#[serde(default)] #[serde(default)]
@ -143,7 +135,7 @@ pub struct HeaderRenderer {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum CarouselHeaderRendererItem { pub(crate) enum CarouselHeaderRendererItem {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
TopicChannelDetailsRenderer { TopicChannelDetailsRenderer {
#[serde_as(as = "Option<Text>")] #[serde_as(as = "Option<Text>")]
@ -157,13 +149,13 @@ pub enum CarouselHeaderRendererItem {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Metadata { pub(crate) struct Metadata {
pub channel_metadata_renderer: ChannelMetadataRenderer, pub channel_metadata_renderer: ChannelMetadataRenderer,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ChannelMetadataRenderer { pub(crate) struct ChannelMetadataRenderer {
pub title: String, pub title: String,
/// Channel ID /// Channel ID
pub external_id: String, pub external_id: String,
@ -173,13 +165,13 @@ pub struct ChannelMetadataRenderer {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Microformat { pub(crate) struct Microformat {
pub microformat_data_renderer: MicroformatDataRenderer, pub microformat_data_renderer: MicroformatDataRenderer,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MicroformatDataRenderer { pub(crate) struct MicroformatDataRenderer {
#[serde(default)] #[serde(default)]
pub tags: Vec<String>, pub tags: Vec<String>,
} }
@ -187,7 +179,7 @@ pub struct MicroformatDataRenderer {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ChannelFullMetadata { pub(crate) struct ChannelFullMetadata {
#[serde_as(as = "Text")] #[serde_as(as = "Text")]
pub joined_date_text: String, pub joined_date_text: String,
#[serde_as(as = "Option<Text>")] #[serde_as(as = "Option<Text>")]
@ -200,22 +192,8 @@ pub struct ChannelFullMetadata {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PrimaryLink { pub(crate) struct PrimaryLink {
#[serde_as(as = "Text")] #[serde_as(as = "Text")]
pub title: String, pub title: String,
pub navigation_endpoint: NavigationEndpoint, pub navigation_endpoint: NavigationEndpoint,
} }
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OnResponseReceivedAction {
pub append_continuation_items_action: AppendAction,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AppendAction {
#[serde_as(as = "VecLogError<_>")]
pub continuation_items: MapResult<Vec<VideoListItem>>,
}

View file

@ -4,7 +4,7 @@ use serde::Deserialize;
use super::Thumbnail; use super::Thumbnail;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct ChannelRss { pub(crate) struct ChannelRss {
#[serde(rename = "$unflatten=yt:channelId")] #[serde(rename = "$unflatten=yt:channelId")]
pub channel_id: String, pub channel_id: String,
#[serde(rename = "$unflatten=title")] #[serde(rename = "$unflatten=title")]
@ -15,7 +15,7 @@ pub struct ChannelRss {
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Entry { pub(crate) struct Entry {
#[serde(rename = "$unflatten=yt:videoId")] #[serde(rename = "$unflatten=yt:videoId")]
pub video_id: String, pub video_id: String,
#[serde(rename = "$unflatten=title")] #[serde(rename = "$unflatten=title")]
@ -29,7 +29,7 @@ pub struct Entry {
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct MediaGroup { pub(crate) struct MediaGroup {
#[serde(rename = "$unflatten=media:thumbnail")] #[serde(rename = "$unflatten=media:thumbnail")]
pub thumbnail: Thumbnail, pub thumbnail: Thumbnail,
#[serde(rename = "$unflatten=media:description")] #[serde(rename = "$unflatten=media:description")]
@ -39,7 +39,7 @@ pub struct MediaGroup {
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Community { pub(crate) struct Community {
#[serde(rename = "$unflatten=media:starRating")] #[serde(rename = "$unflatten=media:starRating")]
pub rating: Rating, pub rating: Rating,
#[serde(rename = "$unflatten=media:statistics")] #[serde(rename = "$unflatten=media:statistics")]
@ -47,12 +47,12 @@ pub struct Community {
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Rating { pub(crate) struct Rating {
pub count: u64, pub count: u64,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Statistics { pub(crate) struct Statistics {
pub views: u64, pub views: u64,
} }

View file

@ -1,66 +1,55 @@
pub mod channel; pub(crate) mod channel;
pub mod player; pub(crate) mod player;
pub mod playlist; pub(crate) mod playlist;
pub mod playlist_music; // pub(crate) mod playlist_music;
pub mod search; pub(crate) mod search;
pub mod trends; pub(crate) mod trends;
pub mod url_endpoint; pub(crate) mod url_endpoint;
pub mod video_details; pub(crate) mod video_details;
pub(crate) mod video_item;
pub use channel::Channel; pub(crate) use channel::Channel;
pub use channel::ChannelCont; pub(crate) use player::Player;
pub use player::Player; pub(crate) use playlist::Playlist;
pub use playlist::Playlist; pub(crate) use playlist::PlaylistCont;
pub use playlist::PlaylistCont; // pub(crate) use playlist_music::PlaylistMusic;
pub use playlist_music::PlaylistMusic; pub(crate) use search::Search;
pub use search::Search; pub(crate) use trends::Startpage;
pub use search::SearchCont; pub(crate) use trends::Trending;
pub use trends::Startpage; pub(crate) use url_endpoint::ResolvedUrl;
pub use trends::StartpageCont; pub(crate) use video_details::VideoComments;
pub use trends::Trending; pub(crate) use video_details::VideoDetails;
pub use url_endpoint::ResolvedUrl; pub(crate) use video_item::YouTubeListItem;
pub use video_details::VideoComments; pub(crate) use video_item::YouTubeListMapper;
pub use video_details::VideoDetails;
pub use video_details::VideoRecommendations;
#[cfg(feature = "rss")] #[cfg(feature = "rss")]
pub mod channel_rss; pub(crate) mod channel_rss;
#[cfg(feature = "rss")] #[cfg(feature = "rss")]
pub use channel_rss::ChannelRss; pub(crate) use channel_rss::ChannelRss;
use chrono::TimeZone;
use serde::Deserialize; use serde::Deserialize;
use serde_with::{json::JsonString, serde_as, DefaultOnError, VecSkipError}; use serde_with::{json::JsonString, serde_as, VecSkipError};
use crate::error::ExtractionError; use crate::error::ExtractionError;
use crate::model;
use crate::param::Language;
use crate::serializer::MapResult; use crate::serializer::MapResult;
use crate::serializer::{ use crate::serializer::{text::Text, VecLogError};
ignore_any,
text::{Text, TextComponent},
VecLogError,
};
use crate::timeago;
use crate::util::MappingError;
use crate::util::{self, TryRemove};
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ContentRenderer<T> { pub(crate) struct ContentRenderer<T> {
pub content: T, pub content: T,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ContentsRenderer<T> { pub(crate) struct ContentsRenderer<T> {
#[serde(alias = "tabs")] #[serde(alias = "tabs")]
pub contents: Vec<T>, pub contents: Vec<T>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ThumbnailsWrap { pub(crate) struct ThumbnailsWrap {
#[serde(default)] #[serde(default)]
pub thumbnail: Thumbnails, pub thumbnail: Thumbnails,
} }
@ -69,276 +58,47 @@ pub struct ThumbnailsWrap {
/// Not only used for thumbnails, but also for avatars and banners. /// Not only used for thumbnails, but also for avatars and banners.
#[derive(Default, Debug, Deserialize)] #[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Thumbnails { pub(crate) struct Thumbnails {
#[serde(default)] #[serde(default)]
pub thumbnails: Vec<Thumbnail>, pub thumbnails: Vec<Thumbnail>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Thumbnail { pub(crate) struct Thumbnail {
pub url: String, pub url: String,
pub width: u32, pub width: u32,
pub height: u32, pub height: u32,
} }
#[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum VideoListItem { pub(crate) struct ContinuationItemRenderer {
/// Video on channel page
GridVideoRenderer(GridVideoRenderer),
/// Video in recommendations
CompactVideoRenderer(CompactVideoRenderer),
/// Video in playlist
PlaylistVideoRenderer(PlaylistVideoRenderer),
/// Playlist on channel page
GridPlaylistRenderer(GridPlaylistRenderer),
/// Video on startpage
///
/// Seems to be currently A/B tested on the channel page,
/// as of 11.10.2022
RichItemRenderer { content: RichItem },
/// Seems to be currently A/B tested on the video details page,
/// as of 11.10.2022
ItemSectionRenderer {
#[serde_as(as = "VecLogError<_>")]
contents: MapResult<Vec<VideoListItem>>,
},
/// Continauation items are located at the end of a list
/// and contain the continuation token for progressive loading
#[serde(rename_all = "camelCase")]
ContinuationItemRenderer {
continuation_endpoint: ContinuationEndpoint,
},
/// No video list item (e.g. ad) or unimplemented item
///
/// Unimplemented:
/// - compactPlaylistRenderer (recommended playlists)
/// - compactRadioRenderer (recommended mix)
#[serde(other, deserialize_with = "ignore_any")]
None,
}
/// Video displayed on a channel page
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GridVideoRenderer {
pub video_id: String,
pub thumbnail: Thumbnails,
#[serde_as(as = "Text")]
pub title: String,
#[serde_as(as = "Option<Text>")]
pub published_time_text: Option<String>,
/// Contains `No views` if the view count is zero
#[serde_as(as = "Option<Text>")]
pub view_count_text: Option<String>,
/// Contains video length and Short/Live tag
#[serde_as(as = "VecSkipError<_>")]
pub thumbnail_overlays: Vec<TimeOverlay>,
/// Release date for upcoming videos
pub upcoming_event_data: Option<UpcomingEventData>,
}
/// Video displayed in recommendations
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CompactVideoRenderer {
pub video_id: String,
pub thumbnail: Thumbnails,
#[serde_as(as = "Text")]
pub title: String,
#[serde(rename = "shortBylineText")]
pub channel: TextComponent,
pub channel_thumbnail: Thumbnails,
/// Channel verification badge
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub owner_badges: Vec<ChannelBadge>,
#[serde_as(as = "Option<Text>")]
pub length_text: Option<String>,
/// (e.g. `11 months ago`)
#[serde_as(as = "Option<Text>")]
pub published_time_text: Option<String>,
/// Contains `No views` if the view count is zero
#[serde_as(as = "Option<Text>")]
pub view_count_text: Option<String>,
/// Badges are displayed on the video thumbnail and
/// show certain video properties (e.g. active livestream)
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub badges: Vec<VideoBadge>,
/// Contains Short/Live tag
#[serde_as(as = "VecSkipError<_>")]
pub thumbnail_overlays: Vec<TimeOverlay>,
}
/// Video displayed in search results
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VideoRenderer {
pub video_id: String,
pub thumbnail: Thumbnails,
#[serde_as(as = "Text")]
pub title: String,
#[serde(rename = "shortBylineText")]
pub channel: Option<TextComponent>,
pub channel_thumbnail_supported_renderers: Option<ChannelThumbnailSupportedRenderers>,
#[serde_as(as = "Option<Text>")]
pub published_time_text: Option<String>,
#[serde_as(as = "Option<Text>")]
pub length_text: Option<String>,
/// Contains `No views` if the view count is zero
#[serde_as(as = "Option<Text>")]
pub view_count_text: Option<String>,
/// Channel verification badge
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub owner_badges: Vec<ChannelBadge>,
/// Contains Short/Live tag
#[serde_as(as = "VecSkipError<_>")]
pub thumbnail_overlays: Vec<TimeOverlay>,
/// Abbreviated video description (on startpage)
#[serde_as(as = "Option<Text>")]
pub description_snippet: Option<String>,
/// Contains abbreviated video description (on search page)
#[serde_as(as = "Option<VecSkipError<_>>")]
pub detailed_metadata_snippets: Option<Vec<DetailedMetadataSnippet>>,
/// Release date for upcoming videos
pub upcoming_event_data: Option<UpcomingEventData>,
}
/// Playlist displayed in search results
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PlaylistRenderer {
pub playlist_id: String,
#[serde_as(as = "Text")]
pub title: String,
/// The first item of this list contains the playlist thumbnail,
/// subsequent items contain very small thumbnails of the next playlist videos
pub thumbnails: Vec<Thumbnails>,
#[serde_as(as = "JsonString")]
pub video_count: u64,
#[serde(rename = "shortBylineText")]
pub channel: TextComponent,
/// Channel verification badge
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub owner_badges: Vec<ChannelBadge>,
/// First 2 videos
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub videos: Vec<ChildVideoRendererWrap>,
}
/// Video displayed in a playlist
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PlaylistVideoRenderer {
pub video_id: String,
pub thumbnail: Thumbnails,
#[serde_as(as = "Text")]
pub title: String,
#[serde(rename = "shortBylineText")]
pub channel: TextComponent,
#[serde_as(as = "JsonString")]
pub length_seconds: u32,
}
/// Channel displayed in search results
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChannelRenderer {
pub channel_id: String,
#[serde_as(as = "Text")]
pub title: String,
pub thumbnail: Thumbnails,
/// Abbreviated channel description
///
/// Not present if the channel has no description
#[serde(default)]
#[serde_as(as = "Text")]
pub description_snippet: String,
/// Not present if the channel has no videos
#[serde_as(as = "Option<Text>")]
pub video_count_text: Option<String>,
#[serde_as(as = "Option<Text>")]
pub subscriber_count_text: Option<String>,
/// Channel verification badge
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub owner_badges: Vec<ChannelBadge>,
}
/// Playlist displayed on a channel page
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GridPlaylistRenderer {
pub playlist_id: String,
#[serde_as(as = "Text")]
pub title: String,
pub thumbnail: Thumbnails,
#[serde_as(as = "Text")]
pub video_count_short_text: String,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
#[allow(clippy::large_enum_variant)]
pub enum RichItem {
VideoRenderer(VideoRenderer),
PlaylistRenderer(GridPlaylistRenderer),
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UpcomingEventData {
/// Unixtime in seconds
#[serde_as(as = "JsonString")]
pub start_time: i64,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ContinuationItemRenderer {
pub continuation_endpoint: ContinuationEndpoint, pub continuation_endpoint: ContinuationEndpoint,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ContinuationEndpoint { pub(crate) struct ContinuationEndpoint {
pub continuation_command: ContinuationCommand, pub continuation_command: ContinuationCommand,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ContinuationCommand { pub(crate) struct ContinuationCommand {
pub token: String, pub token: String,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Icon { pub(crate) struct Icon {
pub icon_type: IconType, pub icon_type: IconType,
} }
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum IconType { pub(crate) enum IconType {
/// Checkmark for verified channels /// Checkmark for verified channels
Check, Check,
/// Music note for verified artists /// Music note for verified artists
@ -349,151 +109,81 @@ pub enum IconType {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct VideoOwner { pub(crate) struct ChannelBadge {
pub video_owner_renderer: VideoOwnerRenderer,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VideoOwnerRenderer {
pub title: TextComponent,
pub thumbnail: Thumbnails,
#[serde_as(as = "Option<Text>")]
pub subscriber_count_text: Option<String>,
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub badges: Vec<ChannelBadge>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChannelBadge {
pub metadata_badge_renderer: ChannelBadgeRenderer, pub metadata_badge_renderer: ChannelBadgeRenderer,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ChannelBadgeRenderer { pub(crate) struct ChannelBadgeRenderer {
pub style: ChannelBadgeStyle, pub style: ChannelBadgeStyle,
} }
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ChannelBadgeStyle { pub(crate) enum ChannelBadgeStyle {
BadgeStyleTypeVerified, BadgeStyleTypeVerified,
BadgeStyleTypeVerifiedArtist, BadgeStyleTypeVerifiedArtist,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TimeOverlay { pub(crate) struct Alert {
pub thumbnail_overlay_time_status_renderer: TimeOverlayRenderer,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TimeOverlayRenderer {
/// `29:54`
///
/// Is `LIVE` in case of a livestream and `SHORTS` in case of a short video
#[serde_as(as = "Text")]
pub text: String,
#[serde(default)]
#[serde_as(deserialize_as = "DefaultOnError")]
pub style: TimeOverlayStyle,
}
#[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum TimeOverlayStyle {
#[default]
Default,
Live,
Shorts,
}
/// Badges are displayed on the video thumbnail and
/// show certain video properties (e.g. active livestream)
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VideoBadge {
pub metadata_badge_renderer: VideoBadgeRenderer,
}
/// Badges are displayed on the video thumbnail and
/// show certain video properties (e.g. active livestream)
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VideoBadgeRenderer {
pub style: VideoBadgeStyle,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum VideoBadgeStyle {
/// Active livestream
BadgeStyleTypeLiveNow,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Alert {
pub alert_renderer: AlertRenderer, pub alert_renderer: AlertRenderer,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AlertRenderer { pub(crate) struct AlertRenderer {
#[serde_as(as = "Text")] #[serde_as(as = "Text")]
pub text: String, pub text: String,
} }
// CONTINUATION
#[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ChannelThumbnailSupportedRenderers { pub(crate) struct Continuation {
pub channel_thumbnail_with_link_renderer: ChannelThumbnailWithLinkRenderer, /// Number of search results
#[serde_as(as = "Option<JsonString>")]
pub estimated_results: Option<u64>,
#[serde(
alias = "onResponseReceivedCommands",
alias = "onResponseReceivedEndpoints"
)]
#[serde_as(as = "VecSkipError<_>")]
pub on_response_received_actions: Vec<ContinuationActionWrap>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ChannelThumbnailWithLinkRenderer { pub(crate) struct ContinuationActionWrap {
pub thumbnail: Thumbnails, pub append_continuation_items_action: ContinuationAction,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct DetailedMetadataSnippet { pub(crate) struct ContinuationAction {
#[serde_as(as = "Text")] #[serde_as(as = "VecLogError<_>")]
pub snippet_text: String, pub continuation_items: MapResult<Vec<YouTubeListItem>>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ChildVideoRendererWrap { pub(crate) struct ResponseContext {
pub child_video_renderer: ChildVideoRenderer, pub visitor_data: Option<String>,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChildVideoRenderer {
pub video_id: String,
#[serde_as(as = "Text")]
pub title: String,
#[serde_as(as = "Option<Text>")]
pub length_text: Option<String>,
} }
// YouTube Music // YouTube Music
/*
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MusicItem { pub(crate) struct MusicItem {
pub thumbnail: MusicThumbnailRenderer, pub thumbnail: MusicThumbnailRenderer,
#[serde(default)] #[serde(default)]
#[serde_as(deserialize_as = "DefaultOnError")] #[serde_as(deserialize_as = "DefaultOnError")]
@ -506,28 +196,28 @@ pub struct MusicItem {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MusicThumbnailRenderer { pub(crate) struct MusicThumbnailRenderer {
#[serde(alias = "croppedSquareThumbnailRenderer")] #[serde(alias = "croppedSquareThumbnailRenderer")]
pub music_thumbnail_renderer: ThumbnailsWrap, pub music_thumbnail_renderer: ThumbnailsWrap,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PlaylistItemData { pub(crate) struct PlaylistItemData {
pub video_id: String, pub video_id: String,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MusicContentsRenderer<T> { pub(crate) struct MusicContentsRenderer<T> {
pub contents: Vec<T>, pub contents: Vec<T>,
#[serde_as(as = "Option<VecSkipError<_>>")] #[serde_as(as = "Option<VecSkipError<_>>")]
pub continuations: Option<Vec<MusicContinuation>>, pub continuations: Option<Vec<MusicContinuation>>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct MusicColumn { pub(crate) struct MusicColumn {
#[serde( #[serde(
rename = "musicResponsiveListItemFlexColumnRenderer", rename = "musicResponsiveListItemFlexColumnRenderer",
alias = "musicResponsiveListItemFixedColumnRenderer" alias = "musicResponsiveListItemFixedColumnRenderer"
@ -537,19 +227,20 @@ pub struct MusicColumn {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct MusicColumnRenderer { pub(crate) struct MusicColumnRenderer {
pub text: TextComponent, pub text: TextComponent,
} }
*/
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MusicContinuation { pub(crate) struct MusicContinuation {
pub next_continuation_data: MusicContinuationData, pub next_continuation_data: MusicContinuationData,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MusicContinuationData { pub(crate) struct MusicContinuationData {
pub continuation: String, pub continuation: String,
} }
@ -601,39 +292,7 @@ impl From<Icon> for crate::model::Verification {
} }
} }
pub trait IsLive { pub(crate) fn alerts_to_err(alerts: Option<Vec<Alert>>) -> ExtractionError {
fn is_live(&self) -> bool;
}
pub trait IsShort {
fn is_short(&self) -> bool;
}
impl IsLive for Vec<VideoBadge> {
fn is_live(&self) -> bool {
self.iter().any(|badge| {
badge.metadata_badge_renderer.style == VideoBadgeStyle::BadgeStyleTypeLiveNow
})
}
}
impl IsLive for Vec<TimeOverlay> {
fn is_live(&self) -> bool {
self.iter().any(|overlay| {
overlay.thumbnail_overlay_time_status_renderer.style == TimeOverlayStyle::Live
})
}
}
impl IsShort for Vec<TimeOverlay> {
fn is_short(&self) -> bool {
self.iter().any(|overlay| {
overlay.thumbnail_overlay_time_status_renderer.style == TimeOverlayStyle::Shorts
})
}
}
pub fn alerts_to_err(alerts: Option<Vec<Alert>>) -> ExtractionError {
match alerts { match alerts {
Some(alerts) => ExtractionError::ContentUnavailable( Some(alerts) => ExtractionError::ContentUnavailable(
alerts alerts
@ -646,234 +305,3 @@ pub fn alerts_to_err(alerts: Option<Vec<Alert>>) -> ExtractionError {
None => ExtractionError::ContentUnavailable("content not found".into()), None => ExtractionError::ContentUnavailable("content not found".into()),
} }
} }
pub trait FromWLang<T> {
fn from_w_lang(from: T, lang: Language) -> Self;
}
pub trait TryFromWLang<T>: Sized {
fn from_w_lang(from: T, lang: Language) -> Result<Self, util::MappingError>;
}
impl FromWLang<GridVideoRenderer> for model::ChannelVideo {
fn from_w_lang(video: GridVideoRenderer, lang: Language) -> Self {
let mut toverlays = video.thumbnail_overlays;
let is_live = toverlays.is_live();
let is_short = toverlays.is_short();
let to = toverlays.try_swap_remove(0);
Self {
id: video.video_id,
title: video.title,
// Time text is `LIVE` for livestreams, so we ignore parse errors
length: to.and_then(|to| {
util::parse_video_length(&to.thumbnail_overlay_time_status_renderer.text)
}),
thumbnail: video.thumbnail.into(),
publish_date: video
.upcoming_event_data
.as_ref()
.map(|upc| {
chrono::Local.from_utc_datetime(&chrono::NaiveDateTime::from_timestamp(
upc.start_time,
0,
))
})
.or_else(|| {
video
.published_time_text
.as_ref()
.and_then(|txt| timeago::parse_timeago_to_dt(lang, txt))
}),
publish_date_txt: video.published_time_text,
view_count: video
.view_count_text
.and_then(|txt| util::parse_numeric(&txt).ok())
.unwrap_or_default(),
is_live,
is_short,
is_upcoming: video.upcoming_event_data.is_some(),
}
}
}
impl FromWLang<VideoRenderer> for model::ChannelVideo {
fn from_w_lang(video: VideoRenderer, lang: Language) -> Self {
let mut toverlays = video.thumbnail_overlays;
let is_live = toverlays.is_live();
let is_short = toverlays.is_short();
let to = toverlays.try_swap_remove(0);
Self {
id: video.video_id,
title: video.title,
// Time text is `LIVE` for livestreams, so we ignore parse errors
length: to.and_then(|to| {
util::parse_video_length(&to.thumbnail_overlay_time_status_renderer.text)
}),
thumbnail: video.thumbnail.into(),
publish_date: video
.upcoming_event_data
.as_ref()
.map(|upc| {
chrono::Local.from_utc_datetime(&chrono::NaiveDateTime::from_timestamp(
upc.start_time,
0,
))
})
.or_else(|| {
video
.published_time_text
.as_ref()
.and_then(|txt| timeago::parse_timeago_to_dt(lang, txt))
}),
publish_date_txt: video.published_time_text,
view_count: video
.view_count_text
.and_then(|txt| util::parse_numeric(&txt).ok())
.unwrap_or_default(),
is_live,
is_short,
is_upcoming: video.upcoming_event_data.is_some(),
}
}
}
impl From<GridPlaylistRenderer> for model::ChannelPlaylist {
fn from(playlist: GridPlaylistRenderer) -> Self {
Self {
id: playlist.playlist_id,
name: playlist.title,
thumbnail: playlist.thumbnail.into(),
video_count: util::parse_numeric(&playlist.video_count_short_text).ok(),
}
}
}
impl TryFromWLang<CompactVideoRenderer> for model::RecommendedVideo {
fn from_w_lang(
video: CompactVideoRenderer,
lang: Language,
) -> Result<Self, util::MappingError> {
let channel = model::ChannelId::try_from(video.channel)?;
Ok(Self {
id: video.video_id,
title: video.title,
length: video
.length_text
.and_then(|txt| util::parse_video_length(&txt)),
thumbnail: video.thumbnail.into(),
channel: model::ChannelTag {
id: channel.id,
name: channel.name,
avatar: video.channel_thumbnail.into(),
verification: video.owner_badges.into(),
subscriber_count: None,
},
publish_date: video
.published_time_text
.as_ref()
.and_then(|txt| timeago::parse_timeago_to_dt(lang, txt)),
publish_date_txt: video.published_time_text,
view_count: video
.view_count_text
.and_then(|txt| util::parse_numeric(&txt).ok())
.unwrap_or_default(),
is_live: video.badges.is_live(),
is_short: video.thumbnail_overlays.is_short(),
})
}
}
impl TryFromWLang<VideoRenderer> for model::SearchVideo {
fn from_w_lang(video: VideoRenderer, lang: Language) -> Result<Self, util::MappingError> {
let channel = model::ChannelId::try_from(
video
.channel
.ok_or_else(|| MappingError("no video channel".into()))?,
)?;
let channel_thumbnail = video
.channel_thumbnail_supported_renderers
.ok_or_else(|| MappingError("no video channel thumbnail".into()))?;
Ok(Self {
id: video.video_id,
title: video.title,
length: video
.length_text
.and_then(|txt| util::parse_video_length(&txt)),
thumbnail: video.thumbnail.into(),
channel: model::ChannelTag {
id: channel.id,
name: channel.name,
avatar: channel_thumbnail
.channel_thumbnail_with_link_renderer
.thumbnail
.into(),
verification: video.owner_badges.into(),
subscriber_count: None,
},
publish_date: video
.published_time_text
.as_ref()
.and_then(|txt| timeago::parse_timeago_to_dt(lang, txt)),
publish_date_txt: video.published_time_text,
view_count: video
.view_count_text
.and_then(|txt| util::parse_numeric(&txt).ok())
.unwrap_or_default(),
is_live: video.thumbnail_overlays.is_live(),
is_short: video.thumbnail_overlays.is_short(),
short_description: video
.detailed_metadata_snippets
.and_then(|mut snippets| snippets.try_swap_remove(0).map(|s| s.snippet_text))
.or(video.description_snippet)
.unwrap_or_default(),
})
}
}
impl From<PlaylistRenderer> for model::SearchPlaylist {
fn from(playlist: PlaylistRenderer) -> Self {
let mut thumbnails = playlist.thumbnails;
Self {
id: playlist.playlist_id,
name: playlist.title,
thumbnail: thumbnails.try_swap_remove(0).unwrap_or_default().into(),
video_count: playlist.video_count,
first_videos: playlist
.videos
.into_iter()
.map(|v| model::SearchPlaylistVideo {
id: v.child_video_renderer.video_id,
title: v.child_video_renderer.title,
length: v
.child_video_renderer
.length_text
.and_then(|txt| util::parse_video_length(&txt)),
})
.collect(),
}
}
}
impl From<ChannelRenderer> for model::SearchChannel {
fn from(channel: ChannelRenderer) -> Self {
Self {
id: channel.channel_id,
name: channel.title,
avatar: channel.thumbnail.into(),
verification: channel.owner_badges.into(),
subscriber_count: channel
.subscriber_count_text
.and_then(|txt| util::parse_numeric(&txt).ok()),
video_count: channel
.video_count_text
.and_then(|txt| util::parse_numeric(&txt).ok())
.unwrap_or_default(),
short_description: channel.description_snippet,
}
}
}

View file

@ -9,7 +9,7 @@ use crate::serializer::{text::Text, MapResult, VecLogError};
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Player { pub(crate) struct Player {
pub playability_status: PlayabilityStatus, pub playability_status: PlayabilityStatus,
pub streaming_data: Option<StreamingData>, pub streaming_data: Option<StreamingData>,
pub captions: Option<Captions>, pub captions: Option<Captions>,
@ -18,7 +18,7 @@ pub struct Player {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(tag = "status", rename_all = "SCREAMING_SNAKE_CASE")] #[serde(tag = "status", rename_all = "SCREAMING_SNAKE_CASE")]
pub enum PlayabilityStatus { pub(crate) enum PlayabilityStatus {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
Ok { live_streamability: Option<Empty> }, Ok { live_streamability: Option<Empty> },
/// Video cant be played because of DRM / Geoblock /// Video cant be played because of DRM / Geoblock
@ -35,12 +35,12 @@ pub enum PlayabilityStatus {
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Empty {} pub(crate) struct Empty {}
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct StreamingData { pub(crate) struct StreamingData {
#[serde_as(as = "JsonString")] #[serde_as(as = "JsonString")]
pub expires_in_seconds: u32, pub expires_in_seconds: u32,
#[serde(default)] #[serde(default)]
@ -58,7 +58,7 @@ pub struct StreamingData {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Format { pub(crate) struct Format {
pub itag: u32, pub itag: u32,
pub url: Option<String>, pub url: Option<String>,
@ -94,8 +94,6 @@ pub struct Format {
pub audio_quality: Option<AudioQuality>, pub audio_quality: Option<AudioQuality>,
#[serde_as(as = "Option<JsonString>")] #[serde_as(as = "Option<JsonString>")]
pub audio_sample_rate: Option<u32>, pub audio_sample_rate: Option<u32>,
pub audio_channels: Option<u8>,
pub loudness_db: Option<f64>,
pub audio_track: Option<AudioTrack>, pub audio_track: Option<AudioTrack>,
pub signature_cipher: Option<String>, pub signature_cipher: Option<String>,
@ -119,7 +117,7 @@ impl Format {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum Quality { pub(crate) enum Quality {
Tiny, Tiny,
Small, Small,
Medium, Medium,
@ -132,7 +130,7 @@ pub enum Quality {
} }
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum AudioQuality { pub(crate) enum AudioQuality {
#[serde(rename = "AUDIO_QUALITY_LOW", alias = "low")] #[serde(rename = "AUDIO_QUALITY_LOW", alias = "low")]
Low, Low,
#[serde(rename = "AUDIO_QUALITY_MEDIUM", alias = "medium")] #[serde(rename = "AUDIO_QUALITY_MEDIUM", alias = "medium")]
@ -143,7 +141,7 @@ pub enum AudioQuality {
#[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)] #[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum FormatType { pub(crate) enum FormatType {
#[default] #[default]
Default, Default,
/// This stream only works via DASH and not via progressive HTTP. /// This stream only works via DASH and not via progressive HTTP.
@ -152,13 +150,13 @@ pub enum FormatType {
#[derive(Default, Debug, Deserialize)] #[derive(Default, Debug, Deserialize)]
#[serde(default, rename_all = "camelCase")] #[serde(default, rename_all = "camelCase")]
pub struct ColorInfo { pub(crate) struct ColorInfo {
pub primaries: Primaries, pub primaries: Primaries,
} }
#[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)] #[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Primaries { pub(crate) enum Primaries {
#[default] #[default]
ColorPrimariesBt709, ColorPrimariesBt709,
ColorPrimariesBt2020, ColorPrimariesBt2020,
@ -166,7 +164,7 @@ pub enum Primaries {
#[derive(Default, Debug, Deserialize)] #[derive(Default, Debug, Deserialize)]
#[serde(default, rename_all = "camelCase")] #[serde(default, rename_all = "camelCase")]
pub struct AudioTrack { pub(crate) struct AudioTrack {
pub id: String, pub id: String,
pub display_name: String, pub display_name: String,
pub audio_is_default: bool, pub audio_is_default: bool,
@ -174,20 +172,20 @@ pub struct AudioTrack {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Captions { pub(crate) struct Captions {
pub player_captions_tracklist_renderer: PlayerCaptionsTracklistRenderer, pub player_captions_tracklist_renderer: PlayerCaptionsTracklistRenderer,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PlayerCaptionsTracklistRenderer { pub(crate) struct PlayerCaptionsTracklistRenderer {
pub caption_tracks: Vec<CaptionTrack>, pub caption_tracks: Vec<CaptionTrack>,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CaptionTrack { pub(crate) struct CaptionTrack {
pub base_url: String, pub base_url: String,
#[serde_as(as = "Text")] #[serde_as(as = "Text")]
pub name: String, pub name: String,
@ -197,7 +195,7 @@ pub struct CaptionTrack {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct VideoDetails { pub(crate) struct VideoDetails {
pub video_id: String, pub video_id: String,
pub title: String, pub title: String,
#[serde_as(as = "JsonString")] #[serde_as(as = "JsonString")]

View file

@ -1,16 +1,18 @@
use serde::Deserialize; use serde::Deserialize;
use serde_with::serde_as; use serde_with::{json::JsonString, serde_as, DefaultOnError, VecSkipError};
use serde_with::{DefaultOnError, VecSkipError};
use crate::serializer::text::{Text, TextComponent}; use crate::serializer::text::{Text, TextComponent};
use crate::serializer::{MapResult, VecLogError}; use crate::serializer::{ignore_any, MapResult, VecLogError};
use crate::util::MappingError;
use super::{Alert, ContentRenderer, ContentsRenderer, ThumbnailsWrap, VideoListItem}; use super::{
Alert, ContentRenderer, ContentsRenderer, ContinuationEndpoint, Thumbnails, ThumbnailsWrap,
};
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Playlist { pub(crate) struct Playlist {
pub contents: Option<Contents>, pub contents: Option<Contents>,
pub header: Option<Header>, pub header: Option<Header>,
pub sidebar: Option<Sidebar>, pub sidebar: Option<Sidebar>,
@ -21,7 +23,7 @@ pub struct Playlist {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PlaylistCont { pub(crate) struct PlaylistCont {
#[serde(default)] #[serde(default)]
#[serde_as(as = "VecSkipError<_>")] #[serde_as(as = "VecSkipError<_>")]
pub on_response_received_actions: Vec<OnResponseReceivedAction>, pub on_response_received_actions: Vec<OnResponseReceivedAction>,
@ -29,52 +31,52 @@ pub struct PlaylistCont {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Contents { pub(crate) struct Contents {
pub two_column_browse_results_renderer: ContentsRenderer<Tab>, pub two_column_browse_results_renderer: ContentsRenderer<Tab>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Tab { pub(crate) struct Tab {
pub tab_renderer: ContentRenderer<SectionList>, pub tab_renderer: ContentRenderer<SectionList>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SectionList { pub(crate) struct SectionList {
pub section_list_renderer: ContentsRenderer<ItemSection>, pub section_list_renderer: ContentsRenderer<ItemSection>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ItemSection { pub(crate) struct ItemSection {
pub item_section_renderer: ContentsRenderer<PlaylistVideoListRenderer>, pub item_section_renderer: ContentsRenderer<PlaylistVideoListRenderer>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PlaylistVideoListRenderer { pub(crate) struct PlaylistVideoListRenderer {
pub playlist_video_list_renderer: PlaylistVideoList, pub playlist_video_list_renderer: PlaylistVideoList,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PlaylistVideoList { pub(crate) struct PlaylistVideoList {
#[serde_as(as = "VecLogError<_>")] #[serde_as(as = "VecLogError<_>")]
pub contents: MapResult<Vec<VideoListItem>>, pub contents: MapResult<Vec<PlaylistItem>>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Header { pub(crate) struct Header {
pub playlist_header_renderer: HeaderRenderer, pub playlist_header_renderer: HeaderRenderer,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct HeaderRenderer { pub(crate) struct HeaderRenderer {
pub playlist_id: String, pub playlist_id: String,
#[serde_as(as = "Text")] #[serde_as(as = "Text")]
pub title: String, pub title: String,
@ -93,48 +95,48 @@ pub struct HeaderRenderer {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PlaylistHeaderBanner { pub(crate) struct PlaylistHeaderBanner {
pub hero_playlist_thumbnail_renderer: ThumbnailsWrap, pub hero_playlist_thumbnail_renderer: ThumbnailsWrap,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Byline { pub(crate) struct Byline {
pub playlist_byline_renderer: BylineRenderer, pub playlist_byline_renderer: BylineRenderer,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BylineRenderer { pub(crate) struct BylineRenderer {
#[serde_as(as = "Text")] #[serde_as(as = "Text")]
pub text: String, pub text: String,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Sidebar { pub(crate) struct Sidebar {
pub playlist_sidebar_renderer: SidebarRenderer, pub playlist_sidebar_renderer: SidebarRenderer,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SidebarRenderer { pub(crate) struct SidebarRenderer {
#[serde_as(as = "VecSkipError<_>")] #[serde_as(as = "VecSkipError<_>")]
pub items: Vec<SidebarItemPrimary>, pub items: Vec<SidebarItemPrimary>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SidebarItemPrimary { pub(crate) struct SidebarItemPrimary {
pub playlist_sidebar_primary_info_renderer: SidebarPrimaryInfoRenderer, pub playlist_sidebar_primary_info_renderer: SidebarPrimaryInfoRenderer,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SidebarPrimaryInfoRenderer { pub(crate) struct SidebarPrimaryInfoRenderer {
pub thumbnail_renderer: PlaylistThumbnailRenderer, pub thumbnail_renderer: PlaylistThumbnailRenderer,
/// - `"495", " videos"` /// - `"495", " videos"`
/// - `"3,310,996 views"` /// - `"3,310,996 views"`
@ -145,22 +147,70 @@ pub struct SidebarPrimaryInfoRenderer {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PlaylistThumbnailRenderer { pub(crate) struct PlaylistThumbnailRenderer {
// the alternative field name is used by YTM playlists // the alternative field name is used by YTM playlists
#[serde(alias = "playlistCustomThumbnailRenderer")] #[serde(alias = "playlistCustomThumbnailRenderer")]
pub playlist_video_thumbnail_renderer: ThumbnailsWrap, pub playlist_video_thumbnail_renderer: ThumbnailsWrap,
} }
#[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct OnResponseReceivedAction { pub(crate) enum PlaylistItem {
/// Video in playlist
PlaylistVideoRenderer(PlaylistVideoRenderer),
/// Continauation items are located at the end of a list
/// and contain the continuation token for progressive loading
#[serde(rename_all = "camelCase")]
ContinuationItemRenderer {
continuation_endpoint: ContinuationEndpoint,
},
/// No video list item (e.g. ad) or unimplemented item
#[serde(other, deserialize_with = "ignore_any")]
None,
}
/// Video displayed in a playlist
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct PlaylistVideoRenderer {
pub video_id: String,
pub thumbnail: Thumbnails,
#[serde_as(as = "Text")]
pub title: String,
#[serde(rename = "shortBylineText")]
pub channel: TextComponent,
#[serde_as(as = "JsonString")]
pub length_seconds: u32,
}
impl TryFrom<PlaylistVideoRenderer> for crate::model::PlaylistVideo {
type Error = MappingError;
fn try_from(video: PlaylistVideoRenderer) -> Result<Self, Self::Error> {
Ok(Self {
id: video.video_id,
title: video.title,
length: video.length_seconds,
thumbnail: video.thumbnail.into(),
channel: crate::model::ChannelId::try_from(video.channel)?,
})
}
}
// Continuation
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct OnResponseReceivedAction {
pub append_continuation_items_action: AppendAction, pub append_continuation_items_action: AppendAction,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AppendAction { pub(crate) struct AppendAction {
#[serde_as(as = "VecLogError<_>")] #[serde_as(as = "VecLogError<_>")]
pub continuation_items: MapResult<Vec<VideoListItem>>, pub continuation_items: MapResult<Vec<PlaylistItem>>,
} }

View file

@ -11,33 +11,33 @@ use super::{
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PlaylistMusic { pub(crate) struct PlaylistMusic {
pub contents: Contents, pub contents: Contents,
pub header: Header, pub header: Header,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Contents { pub(crate) struct Contents {
pub single_column_browse_results_renderer: ContentsRenderer<Tab>, pub single_column_browse_results_renderer: ContentsRenderer<Tab>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Tab { pub(crate) struct Tab {
pub tab_renderer: ContentRenderer<SectionList>, pub tab_renderer: ContentRenderer<SectionList>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SectionList { pub(crate) struct SectionList {
/// Includes a continuation token for fetching recommendations /// Includes a continuation token for fetching recommendations
pub section_list_renderer: MusicContentsRenderer<ItemSection>, pub section_list_renderer: MusicContentsRenderer<ItemSection>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ItemSection { pub(crate) struct ItemSection {
#[serde(alias = "musicPlaylistShelfRenderer")] #[serde(alias = "musicPlaylistShelfRenderer")]
pub music_shelf_renderer: MusicShelf, pub music_shelf_renderer: MusicShelf,
} }
@ -45,7 +45,7 @@ pub struct ItemSection {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MusicShelf { pub(crate) struct MusicShelf {
/// Playlist ID (only for playlists) /// Playlist ID (only for playlists)
pub playlist_id: Option<String>, pub playlist_id: Option<String>,
#[serde_as(as = "VecSkipError<_>")] #[serde_as(as = "VecSkipError<_>")]
@ -57,20 +57,20 @@ pub struct MusicShelf {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PlaylistMusicItem { pub(crate) struct PlaylistMusicItem {
pub music_responsive_list_item_renderer: MusicItem, pub music_responsive_list_item_renderer: MusicItem,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Header { pub(crate) struct Header {
pub music_detail_header_renderer: HeaderRenderer, pub music_detail_header_renderer: HeaderRenderer,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct HeaderRenderer { pub(crate) struct HeaderRenderer {
#[serde_as(as = "crate::serializer::text::Text")] #[serde_as(as = "crate::serializer::text::Text")]
pub title: String, pub title: String,
/// Content type + Channel/Artist + Year. /// Content type + Channel/Artist + Year.

View file

@ -1,100 +1,25 @@
use serde::Deserialize; use serde::Deserialize;
use serde_with::json::JsonString; use serde_with::{json::JsonString, serde_as};
use serde_with::{serde_as, VecSkipError};
use crate::serializer::ignore_any; use super::video_item::YouTubeListRendererWrap;
use crate::serializer::{text::Text, MapResult, VecLogError};
use super::{
ChannelRenderer, ContentsRenderer, ContinuationEndpoint, PlaylistRenderer, VideoRenderer,
};
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Search { pub(crate) struct Search {
#[serde_as(as = "Option<JsonString>")] #[serde_as(as = "Option<JsonString>")]
pub estimated_results: Option<u64>, pub estimated_results: Option<u64>,
pub contents: Contents, pub contents: Contents,
} }
#[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SearchCont { pub(crate) struct Contents {
#[serde_as(as = "Option<JsonString>")]
pub estimated_results: Option<u64>,
#[serde_as(as = "VecSkipError<_>")]
pub on_response_received_commands: Vec<SearchContCommand>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SearchContCommand {
pub append_continuation_items_action: SearchContAction,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SearchContAction {
pub continuation_items: Vec<SectionListItem>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Contents {
pub two_column_search_results_renderer: TwoColumnSearchResultsRenderer, pub two_column_search_results_renderer: TwoColumnSearchResultsRenderer,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TwoColumnSearchResultsRenderer { pub(crate) struct TwoColumnSearchResultsRenderer {
pub primary_contents: PrimaryContents, pub primary_contents: YouTubeListRendererWrap,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PrimaryContents {
pub section_list_renderer: ContentsRenderer<SectionListItem>,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum SectionListItem {
#[serde(rename_all = "camelCase")]
ItemSectionRenderer {
#[serde_as(as = "VecLogError<_>")]
contents: MapResult<Vec<SearchItem>>,
},
/// Continuation token to fetch more search results
#[serde(rename_all = "camelCase")]
ContinuationItemRenderer {
continuation_endpoint: ContinuationEndpoint,
},
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum SearchItem {
/// Video in search results
VideoRenderer(VideoRenderer),
/// Playlist in search results
PlaylistRenderer(PlaylistRenderer),
/// Channel displayed in search results
ChannelRenderer(ChannelRenderer),
/// Corrected search query
#[serde(rename_all = "camelCase")]
ShowingResultsForRenderer {
#[serde_as(as = "Text")]
corrected_query: String,
},
/// No search result item (e.g. ad) or unimplemented item
///
/// Unimplemented:
/// - shelfRenderer (e.g. Latest from channel, For you)
#[serde(other, deserialize_with = "ignore_any")]
None,
} }

View file

@ -1,133 +1,37 @@
use serde::Deserialize; use serde::Deserialize;
use serde_with::{serde_as, VecSkipError}; use serde_with::{serde_as, VecSkipError};
use crate::serializer::{ignore_any, MapResult, VecLogError}; use super::{video_item::YouTubeListRendererWrap, ContentRenderer, ResponseContext};
use super::{ContentRenderer, ContentsRenderer, VideoListItem, VideoRenderer};
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Startpage { pub(crate) struct Startpage {
pub contents: Contents<BrowseResultsStartpage>, pub contents: Contents,
pub response_context: ResponseContext, pub response_context: ResponseContext,
} }
#[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct StartpageCont { pub(crate) struct Trending {
#[serde(default)] pub contents: Contents,
#[serde_as(as = "VecSkipError<_>")]
pub on_response_received_actions: Vec<OnResponseReceivedAction>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Contents<T> { pub(crate) struct Contents {
pub two_column_browse_results_renderer: T, pub two_column_browse_results_renderer: BrowseResults,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BrowseResultsStartpage { pub(crate) struct BrowseResults {
#[serde_as(as = "VecSkipError<_>")] #[serde_as(as = "VecSkipError<_>")]
pub tabs: Vec<Tab<StartpageTabContent>>, pub tabs: Vec<Tab<YouTubeListRendererWrap>>,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BrowseResultsTrends {
#[serde_as(as = "VecSkipError<_>")]
pub tabs: Vec<Tab<TrendingTabContent>>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Tab<T> { pub(crate) struct Tab<T> {
pub tab_renderer: ContentRenderer<T>, pub tab_renderer: ContentRenderer<T>,
} }
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct StartpageTabContent {
pub rich_grid_renderer: RichGridRenderer,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RichGridRenderer {
#[serde_as(as = "VecLogError<_>")]
pub contents: MapResult<Vec<VideoListItem>>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Trending {
pub contents: Contents<BrowseResultsTrends>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TrendingTabContent {
pub section_list_renderer: ContentsRenderer<ItemSectionRenderer>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ItemSectionRenderer {
pub item_section_renderer: ContentsRenderer<ShelfRenderer>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShelfRenderer {
pub shelf_renderer: ContentRenderer<ShelfContents>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShelfContents {
pub expanded_shelf_contents_renderer: Option<ShelfContentsRenderer>,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShelfContentsRenderer {
#[serde_as(as = "VecLogError<_>")]
pub items: MapResult<Vec<TrendingListItem>>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ResponseContext {
pub visitor_data: Option<String>,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
#[allow(clippy::large_enum_variant)]
pub enum TrendingListItem {
VideoRenderer(VideoRenderer),
#[serde(other, deserialize_with = "ignore_any")]
None,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OnResponseReceivedAction {
pub append_continuation_items_action: AppendAction,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AppendAction {
#[serde_as(as = "VecLogError<_>")]
pub continuation_items: MapResult<Vec<VideoListItem>>,
}

View file

@ -6,14 +6,14 @@ use crate::model::UrlTarget;
/// navigation/resolve_url response model /// navigation/resolve_url response model
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ResolvedUrl { pub(crate) struct ResolvedUrl {
pub endpoint: NavigationEndpoint, pub endpoint: NavigationEndpoint,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize, Default)] #[derive(Debug, Deserialize, Default)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct NavigationEndpoint { pub(crate) struct NavigationEndpoint {
#[serde(default)] #[serde(default)]
#[serde_as(deserialize_as = "DefaultOnError")] #[serde_as(deserialize_as = "DefaultOnError")]
pub watch_endpoint: Option<WatchEndpoint>, pub watch_endpoint: Option<WatchEndpoint>,
@ -30,7 +30,7 @@ pub struct NavigationEndpoint {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct WatchEndpoint { pub(crate) struct WatchEndpoint {
pub video_id: String, pub video_id: String,
#[serde(default)] #[serde(default)]
pub start_time_seconds: u32, pub start_time_seconds: u32,
@ -38,43 +38,43 @@ pub struct WatchEndpoint {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BrowseEndpoint { pub(crate) struct BrowseEndpoint {
pub browse_id: String, pub browse_id: String,
pub browse_endpoint_context_supported_configs: Option<BrowseEndpointConfig>, pub browse_endpoint_context_supported_configs: Option<BrowseEndpointConfig>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct UrlEndpoint { pub(crate) struct UrlEndpoint {
pub url: String, pub url: String,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BrowseEndpointConfig { pub(crate) struct BrowseEndpointConfig {
pub browse_endpoint_context_music_config: BrowseEndpointMusicConfig, pub browse_endpoint_context_music_config: BrowseEndpointMusicConfig,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BrowseEndpointMusicConfig { pub(crate) struct BrowseEndpointMusicConfig {
pub page_type: PageType, pub page_type: PageType,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommandMetadata { pub(crate) struct CommandMetadata {
pub web_command_metadata: WebCommandMetadata, pub web_command_metadata: WebCommandMetadata,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct WebCommandMetadata { pub(crate) struct WebCommandMetadata {
pub web_page_type: PageType, pub web_page_type: PageType,
} }
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Eq)]
pub enum PageType { pub(crate) enum PageType {
#[serde(rename = "MUSIC_PAGE_TYPE_ARTIST")] #[serde(rename = "MUSIC_PAGE_TYPE_ARTIST")]
Artist, Artist,
#[serde(rename = "MUSIC_PAGE_TYPE_ALBUM")] #[serde(rename = "MUSIC_PAGE_TYPE_ALBUM")]
@ -89,7 +89,7 @@ pub enum PageType {
} }
impl PageType { impl PageType {
pub fn to_url_target(self, id: String) -> UrlTarget { pub(crate) fn to_url_target(self, id: String) -> UrlTarget {
match self { match self {
PageType::Artist => UrlTarget::Channel { id }, PageType::Artist => UrlTarget::Channel { id },
PageType::Album => UrlTarget::Playlist { id }, PageType::Album => UrlTarget::Playlist { id },

View file

@ -4,6 +4,7 @@ use serde::Deserialize;
use serde_with::serde_as; use serde_with::serde_as;
use serde_with::{DefaultOnError, VecSkipError}; use serde_with::{DefaultOnError, VecSkipError};
use crate::serializer::text::TextComponent;
use crate::serializer::{ use crate::serializer::{
ignore_any, ignore_any,
text::{AccessibilityText, AttributedText, Text, TextComponents}, text::{AccessibilityText, AttributedText, Text, TextComponents},
@ -12,8 +13,9 @@ use crate::serializer::{
use super::{ use super::{
url_endpoint::BrowseEndpoint, ContinuationEndpoint, ContinuationItemRenderer, Icon, url_endpoint::BrowseEndpoint, ContinuationEndpoint, ContinuationItemRenderer, Icon,
MusicContinuation, Thumbnails, VideoListItem, VideoOwner, MusicContinuation, Thumbnails,
}; };
use super::{ChannelBadge, ResponseContext, YouTubeListItem};
/* /*
#VIDEO DETAILS #VIDEO DETAILS
@ -23,7 +25,7 @@ use super::{
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct VideoDetails { pub(crate) struct VideoDetails {
/// Video metadata + recommended videos /// Video metadata + recommended videos
pub contents: Option<Contents>, pub contents: Option<Contents>,
/// Video ID /// Video ID
@ -31,18 +33,19 @@ pub struct VideoDetails {
/// Video chapters + comment section /// Video chapters + comment section
#[serde_as(as = "VecLogError<_>")] #[serde_as(as = "VecLogError<_>")]
pub engagement_panels: MapResult<Vec<EngagementPanel>>, pub engagement_panels: MapResult<Vec<EngagementPanel>>,
pub response_context: ResponseContext,
} }
/// Video details main object, contains video metadata and recommended videos /// Video details main object, contains video metadata and recommended videos
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Contents { pub(crate) struct Contents {
pub two_column_watch_next_results: TwoColumnWatchNextResults, pub two_column_watch_next_results: TwoColumnWatchNextResults,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TwoColumnWatchNextResults { pub(crate) struct TwoColumnWatchNextResults {
/// Metadata about the video /// Metadata about the video
pub results: VideoResultsWrap, pub results: VideoResultsWrap,
/// Video recommendations /// Video recommendations
@ -54,7 +57,7 @@ pub struct TwoColumnWatchNextResults {
/// Metadata about the video /// Metadata about the video
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct VideoResultsWrap { pub(crate) struct VideoResultsWrap {
pub results: VideoResults, pub results: VideoResults,
} }
@ -62,7 +65,7 @@ pub struct VideoResultsWrap {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct VideoResults { pub(crate) struct VideoResults {
#[serde_as(as = "VecLogError<_>")] #[serde_as(as = "VecLogError<_>")]
pub contents: MapResult<Vec<VideoResultsItem>>, pub contents: MapResult<Vec<VideoResultsItem>>,
} }
@ -71,7 +74,7 @@ pub struct VideoResults {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum VideoResultsItem { pub(crate) enum VideoResultsItem {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
VideoPrimaryInfoRenderer { VideoPrimaryInfoRenderer {
#[serde_as(as = "Text")] #[serde_as(as = "Text")]
@ -105,14 +108,14 @@ pub enum VideoResultsItem {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ViewCount { pub(crate) struct ViewCount {
pub video_view_count_renderer: ViewCountRenderer, pub video_view_count_renderer: ViewCountRenderer,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ViewCountRenderer { pub(crate) struct ViewCountRenderer {
/// View count (`232,975,196 views`) /// View count (`232,975,196 views`)
#[serde_as(as = "Text")] #[serde_as(as = "Text")]
pub view_count: String, pub view_count: String,
@ -123,7 +126,7 @@ pub struct ViewCountRenderer {
/// Like/Dislike buttons /// Like/Dislike buttons
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct VideoActions { pub(crate) struct VideoActions {
pub menu_renderer: VideoActionsMenu, pub menu_renderer: VideoActionsMenu,
} }
@ -131,7 +134,7 @@ pub struct VideoActions {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct VideoActionsMenu { pub(crate) struct VideoActionsMenu {
#[serde_as(as = "VecSkipError<_>")] #[serde_as(as = "VecSkipError<_>")]
pub top_level_buttons: Vec<TopLevelButton>, pub top_level_buttons: Vec<TopLevelButton>,
} }
@ -144,7 +147,7 @@ pub struct VideoActionsMenu {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum TopLevelButton { pub(crate) enum TopLevelButton {
ToggleButtonRenderer(ToggleButton), ToggleButtonRenderer(ToggleButton),
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
SegmentedLikeDislikeButtonRenderer { SegmentedLikeDislikeButtonRenderer {
@ -155,7 +158,7 @@ pub enum TopLevelButton {
/// Like/Dislike button /// Like/Dislike button
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ToggleButtonWrap { pub(crate) struct ToggleButtonWrap {
pub toggle_button_renderer: ToggleButton, pub toggle_button_renderer: ToggleButton,
} }
@ -163,7 +166,7 @@ pub struct ToggleButtonWrap {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ToggleButton { pub(crate) struct ToggleButton {
/// Icon type: `LIKE` / `DISLIKE` /// Icon type: `LIKE` / `DISLIKE`
pub default_icon: Icon, pub default_icon: Icon,
/// Number of likes (`like this video along with 4,010,156 other people`) /// Number of likes (`like this video along with 4,010,156 other people`)
@ -173,11 +176,32 @@ pub struct ToggleButton {
pub accessibility_data: String, pub accessibility_data: String,
} }
/// Video channel information
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct VideoOwner {
pub video_owner_renderer: VideoOwnerRenderer,
}
/// Video channel information
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct VideoOwnerRenderer {
pub title: TextComponent,
pub thumbnail: Thumbnails,
#[serde_as(as = "Option<Text>")]
pub subscriber_count_text: Option<String>,
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub badges: Vec<ChannelBadge>,
}
/// Shows additional video metadata. Its only known use is for /// Shows additional video metadata. Its only known use is for
/// the Creative Commonse License. /// the Creative Commonse License.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MetadataRowContainer { pub(crate) struct MetadataRowContainer {
pub metadata_row_container_renderer: MetadataRowContainerRenderer, pub metadata_row_container_renderer: MetadataRowContainerRenderer,
} }
@ -185,14 +209,14 @@ pub struct MetadataRowContainer {
/// the Creative Commonse License. /// the Creative Commonse License.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MetadataRowContainerRenderer { pub(crate) struct MetadataRowContainerRenderer {
pub rows: Vec<MetadataRow>, pub rows: Vec<MetadataRow>,
} }
/// Additional video metadata item (Creative Commons License) /// Additional video metadata item (Creative Commons License)
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MetadataRow { pub(crate) struct MetadataRow {
pub metadata_row_renderer: MetadataRowRenderer, pub metadata_row_renderer: MetadataRowRenderer,
} }
@ -200,7 +224,7 @@ pub struct MetadataRow {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MetadataRowRenderer { pub(crate) struct MetadataRowRenderer {
// `License` // `License`
// #[serde_as(as = "Text")] // #[serde_as(as = "Text")]
// pub title: String, // pub title: String,
@ -215,13 +239,13 @@ pub struct MetadataRowRenderer {
/// Contains current video ID /// Contains current video ID
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CurrentVideoEndpoint { pub(crate) struct CurrentVideoEndpoint {
pub watch_endpoint: CurrentVideoWatchEndpoint, pub watch_endpoint: CurrentVideoWatchEndpoint,
} }
/// Contains current video ID /// Contains current video ID
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CurrentVideoWatchEndpoint { pub(crate) struct CurrentVideoWatchEndpoint {
pub video_id: String, pub video_id: String,
} }
@ -232,7 +256,7 @@ pub struct CurrentVideoWatchEndpoint {
#[serde_as] #[serde_as]
#[derive(Default, Debug, Deserialize)] #[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "kebab-case", tag = "sectionIdentifier")] #[serde(rename_all = "kebab-case", tag = "sectionIdentifier")]
pub enum ItemSection { pub(crate) enum ItemSection {
CommentsEntryPoint { CommentsEntryPoint {
#[serde_as(as = "VecSkipError<_>")] #[serde_as(as = "VecSkipError<_>")]
contents: Vec<ItemSectionCommentCount>, contents: Vec<ItemSectionCommentCount>,
@ -248,7 +272,7 @@ pub enum ItemSection {
/// Item section containing comment count /// Item section containing comment count
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ItemSectionCommentCount { pub(crate) struct ItemSectionCommentCount {
pub comments_entry_point_header_renderer: CommentsEntryPointHeaderRenderer, pub comments_entry_point_header_renderer: CommentsEntryPointHeaderRenderer,
} }
@ -256,7 +280,7 @@ pub struct ItemSectionCommentCount {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentsEntryPointHeaderRenderer { pub(crate) struct CommentsEntryPointHeaderRenderer {
#[serde_as(as = "Text")] #[serde_as(as = "Text")]
pub comment_count: String, pub comment_count: String,
} }
@ -264,14 +288,14 @@ pub struct CommentsEntryPointHeaderRenderer {
/// Item section containing comments ctoken /// Item section containing comments ctoken
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ItemSectionComments { pub(crate) struct ItemSectionComments {
pub continuation_item_renderer: ContinuationItemRenderer, pub continuation_item_renderer: ContinuationItemRenderer,
} }
/// Video recommendations /// Video recommendations
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RecommendationResultsWrap { pub(crate) struct RecommendationResultsWrap {
pub secondary_results: RecommendationResults, pub secondary_results: RecommendationResults,
} }
@ -279,10 +303,10 @@ pub struct RecommendationResultsWrap {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RecommendationResults { pub(crate) struct RecommendationResults {
/// Can be `None` for age-restricted videos /// Can be `None` for age-restricted videos
#[serde_as(as = "Option<VecLogError<_>>")] #[serde_as(as = "Option<VecLogError<_>>")]
pub results: Option<MapResult<Vec<VideoListItem>>>, pub results: Option<MapResult<Vec<YouTubeListItem>>>,
#[serde_as(as = "Option<VecSkipError<_>>")] #[serde_as(as = "Option<VecSkipError<_>>")]
pub continuations: Option<Vec<MusicContinuation>>, pub continuations: Option<Vec<MusicContinuation>>,
} }
@ -291,7 +315,7 @@ pub struct RecommendationResults {
/// and the comment section. /// and the comment section.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct EngagementPanel { pub(crate) struct EngagementPanel {
pub engagement_panel_section_list_renderer: EngagementPanelRenderer, pub engagement_panel_section_list_renderer: EngagementPanelRenderer,
} }
@ -299,7 +323,7 @@ pub struct EngagementPanel {
/// and the comment section. /// and the comment section.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "kebab-case", tag = "targetId")] #[serde(rename_all = "kebab-case", tag = "targetId")]
pub enum EngagementPanelRenderer { pub(crate) enum EngagementPanelRenderer {
/// Chapter markers /// Chapter markers
EngagementPanelMacroMarkersDescriptionChapters { content: ChapterMarkersContent }, EngagementPanelMacroMarkersDescriptionChapters { content: ChapterMarkersContent },
/// Comment section (contains no comments, but the /// Comment section (contains no comments, but the
@ -318,7 +342,7 @@ pub enum EngagementPanelRenderer {
/// Chapter markers /// Chapter markers
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ChapterMarkersContent { pub(crate) struct ChapterMarkersContent {
pub macro_markers_list_renderer: MacroMarkersListRenderer, pub macro_markers_list_renderer: MacroMarkersListRenderer,
} }
@ -326,7 +350,7 @@ pub struct ChapterMarkersContent {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MacroMarkersListRenderer { pub(crate) struct MacroMarkersListRenderer {
#[serde_as(as = "VecLogError<_>")] #[serde_as(as = "VecLogError<_>")]
pub contents: MapResult<Vec<MacroMarkersListItem>>, pub contents: MapResult<Vec<MacroMarkersListItem>>,
} }
@ -334,7 +358,7 @@ pub struct MacroMarkersListRenderer {
/// Chapter marker /// Chapter marker
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MacroMarkersListItem { pub(crate) struct MacroMarkersListItem {
pub macro_markers_list_item_renderer: MacroMarkersListItemRenderer, pub macro_markers_list_item_renderer: MacroMarkersListItemRenderer,
} }
@ -342,7 +366,7 @@ pub struct MacroMarkersListItem {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MacroMarkersListItemRenderer { pub(crate) struct MacroMarkersListItemRenderer {
/// Contains chapter start time in seconds /// Contains chapter start time in seconds
pub on_tap: MacroMarkersListItemOnTap, pub on_tap: MacroMarkersListItemOnTap,
#[serde(default)] #[serde(default)]
@ -355,13 +379,13 @@ pub struct MacroMarkersListItemRenderer {
/// Contains chapter start time in seconds /// Contains chapter start time in seconds
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MacroMarkersListItemOnTap { pub(crate) struct MacroMarkersListItemOnTap {
pub watch_endpoint: MacroMarkersListItemWatchEndpoint, pub watch_endpoint: MacroMarkersListItemWatchEndpoint,
} }
/// Contains chapter start time in seconds /// Contains chapter start time in seconds
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MacroMarkersListItemWatchEndpoint { pub(crate) struct MacroMarkersListItemWatchEndpoint {
/// Chapter start time in seconds /// Chapter start time in seconds
pub start_time_seconds: u32, pub start_time_seconds: u32,
} }
@ -370,7 +394,7 @@ pub struct MacroMarkersListItemWatchEndpoint {
/// (contains continuation tokens for fetching top/latest comments) /// (contains continuation tokens for fetching top/latest comments)
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentItemSectionHeader { pub(crate) struct CommentItemSectionHeader {
pub engagement_panel_title_header_renderer: CommentItemSectionHeaderRenderer, pub engagement_panel_title_header_renderer: CommentItemSectionHeaderRenderer,
} }
@ -379,21 +403,14 @@ pub struct CommentItemSectionHeader {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentItemSectionHeaderRenderer { pub(crate) struct CommentItemSectionHeaderRenderer {
/// Approximate comment count (e.g. `81`, `2.2K`, `705K`)
///
/// The accurate count is included in the first comment response.
///
/// Is `None` if there are no comments.
#[serde_as(as = "Option<Text>")]
pub contextual_info: Option<String>,
pub menu: CommentItemSectionHeaderMenu, pub menu: CommentItemSectionHeaderMenu,
} }
/// Comment section menu /// Comment section menu
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentItemSectionHeaderMenu { pub(crate) struct CommentItemSectionHeaderMenu {
pub sort_filter_sub_menu_renderer: CommentItemSectionHeaderMenuRenderer, pub sort_filter_sub_menu_renderer: CommentItemSectionHeaderMenuRenderer,
} }
@ -404,48 +421,18 @@ pub struct CommentItemSectionHeaderMenu {
/// - Latest comments /// - Latest comments
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentItemSectionHeaderMenuRenderer { pub(crate) struct CommentItemSectionHeaderMenuRenderer {
pub sub_menu_items: Vec<CommentItemSectionHeaderMenuItem>, pub sub_menu_items: Vec<CommentItemSectionHeaderMenuItem>,
} }
/// Comment section menu item /// Comment section menu item
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentItemSectionHeaderMenuItem { pub(crate) struct CommentItemSectionHeaderMenuItem {
/// Continuation token for fetching comments /// Continuation token for fetching comments
pub service_endpoint: ContinuationEndpoint, pub service_endpoint: ContinuationEndpoint,
} }
/*
#RECOMMENDATIONS CONTINUATION
*/
/// Video recommendations continuation response
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VideoRecommendations {
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub on_response_received_endpoints: Vec<RecommendationsContItem>,
}
/// Video recommendations continuation
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RecommendationsContItem {
pub append_continuation_items_action: AppendRecommendations,
}
/// Video recommendations continuation
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AppendRecommendations {
#[serde_as(as = "VecLogError<_>")]
pub continuation_items: MapResult<Vec<VideoListItem>>,
}
/* /*
#COMMENTS CONTINUATION #COMMENTS CONTINUATION
*/ */
@ -454,7 +441,7 @@ pub struct AppendRecommendations {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct VideoComments { pub(crate) struct VideoComments {
/// - Initial response: 2*reloadContinuationItemsCommand /// - Initial response: 2*reloadContinuationItemsCommand
/// - 1*commentsHeaderRenderer: number of comments /// - 1*commentsHeaderRenderer: number of comments
/// - n*commentThreadRenderer, continuationItemRenderer: /// - n*commentThreadRenderer, continuationItemRenderer:
@ -465,14 +452,14 @@ pub struct VideoComments {
/// - Comment replies: appendContinuationItemsAction /// - Comment replies: appendContinuationItemsAction
/// - n*commentRenderer, continuationItemRenderer: /// - n*commentRenderer, continuationItemRenderer:
/// replies + continuation /// replies + continuation
#[serde_as(as = "Option<VecLogError<_>>")] #[serde_as(as = "VecLogError<_>")]
pub on_response_received_endpoints: Option<MapResult<Vec<CommentsContItem>>>, pub on_response_received_endpoints: MapResult<Vec<CommentsContItem>>,
} }
/// Video comments continuation /// Video comments continuation
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentsContItem { pub(crate) struct CommentsContItem {
#[serde(alias = "reloadContinuationItemsCommand")] #[serde(alias = "reloadContinuationItemsCommand")]
pub append_continuation_items_action: AppendComments, pub append_continuation_items_action: AppendComments,
} }
@ -481,7 +468,7 @@ pub struct CommentsContItem {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AppendComments { pub(crate) struct AppendComments {
#[serde_as(as = "VecLogError<_>")] #[serde_as(as = "VecLogError<_>")]
pub continuation_items: MapResult<Vec<CommentListItem>>, pub continuation_items: MapResult<Vec<CommentListItem>>,
} }
@ -489,7 +476,7 @@ pub struct AppendComments {
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum CommentListItem { pub(crate) enum CommentListItem {
/// Top-level comment /// Top-level comment
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
CommentThreadRenderer { CommentThreadRenderer {
@ -519,14 +506,14 @@ pub enum CommentListItem {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Comment { pub(crate) struct Comment {
pub comment_renderer: CommentRenderer, pub comment_renderer: CommentRenderer,
} }
#[serde_as] #[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentRenderer { pub(crate) struct CommentRenderer {
/// Author name /// Author name
/// ///
/// There may be comments with missing authors (possibly deleted users?) /// There may be comments with missing authors (possibly deleted users?)
@ -557,13 +544,13 @@ pub struct CommentRenderer {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AuthorEndpoint { pub(crate) struct AuthorEndpoint {
pub browse_endpoint: BrowseEndpoint, pub browse_endpoint: BrowseEndpoint,
} }
#[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq)] #[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum CommentPriority { pub(crate) enum CommentPriority {
/// Default rendering priority /// Default rendering priority
#[default] #[default]
RenderingPriorityUnknown, RenderingPriorityUnknown,
@ -575,7 +562,7 @@ pub enum CommentPriority {
/// for fetching them. /// for fetching them.
#[derive(Default, Debug, Deserialize)] #[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Replies { pub(crate) struct Replies {
pub comment_replies_renderer: RepliesRenderer, pub comment_replies_renderer: RepliesRenderer,
} }
@ -584,7 +571,7 @@ pub struct Replies {
#[serde_as] #[serde_as]
#[derive(Default, Debug, Deserialize)] #[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RepliesRenderer { pub(crate) struct RepliesRenderer {
#[serde_as(as = "VecSkipError<_>")] #[serde_as(as = "VecSkipError<_>")]
pub contents: Vec<CommentListItem>, pub contents: Vec<CommentListItem>,
} }
@ -593,7 +580,7 @@ pub struct RepliesRenderer {
/// Contains the CreatorHeart. /// Contains the CreatorHeart.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentActionButtons { pub(crate) struct CommentActionButtons {
pub comment_action_buttons_renderer: CommentActionButtonsRenderer, pub comment_action_buttons_renderer: CommentActionButtonsRenderer,
} }
@ -601,7 +588,7 @@ pub struct CommentActionButtons {
/// Contains the CreatorHeart. /// Contains the CreatorHeart.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CommentActionButtonsRenderer { pub(crate) struct CommentActionButtonsRenderer {
pub like_button: ToggleButtonWrap, pub like_button: ToggleButtonWrap,
pub creator_heart: Option<CreatorHeart>, pub creator_heart: Option<CreatorHeart>,
} }
@ -609,27 +596,27 @@ pub struct CommentActionButtonsRenderer {
/// Video creators can endorse comments by marking them with a ❤️. /// Video creators can endorse comments by marking them with a ❤️.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CreatorHeart { pub(crate) struct CreatorHeart {
pub creator_heart_renderer: CreatorHeartRenderer, pub creator_heart_renderer: CreatorHeartRenderer,
} }
/// Video creators can endorse comments by marking them with a ❤️. /// Video creators can endorse comments by marking them with a ❤️.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CreatorHeartRenderer { pub(crate) struct CreatorHeartRenderer {
pub is_hearted: bool, pub is_hearted: bool,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AuthorCommentBadge { pub(crate) struct AuthorCommentBadge {
pub author_comment_badge_renderer: AuthorCommentBadgeRenderer, pub author_comment_badge_renderer: AuthorCommentBadgeRenderer,
} }
/// YouTube channel badge (verified) of the comment author /// YouTube channel badge (verified) of the comment author
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AuthorCommentBadgeRenderer { pub(crate) struct AuthorCommentBadgeRenderer {
/// Verified: `CHECK` /// Verified: `CHECK`
/// ///
/// Artist: `OFFICIAL_ARTIST_BADGE` /// Artist: `OFFICIAL_ARTIST_BADGE`

View file

@ -0,0 +1,507 @@
use chrono::TimeZone;
use serde::Deserialize;
use serde_with::{json::JsonString, serde_as, DefaultOnError, VecSkipError};
use super::{ChannelBadge, ContinuationEndpoint, Thumbnails};
use crate::{
model::{ChannelId, ChannelItem, ChannelTag, PlaylistItem, VideoItem, YouTubeItem},
param::Language,
serializer::{
ignore_any,
text::{Text, TextComponent},
MapResult, VecLogError,
},
timeago,
util::{self, TryRemove},
};
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) enum YouTubeListItem {
#[serde(alias = "gridVideoRenderer", alias = "compactVideoRenderer")]
VideoRenderer(VideoRenderer),
#[serde(alias = "gridPlaylistRenderer")]
PlaylistRenderer(PlaylistRenderer),
ChannelRenderer(ChannelRenderer),
/// Continauation items are located at the end of a list
/// and contain the continuation token for progressive loading
#[serde(rename_all = "camelCase")]
ContinuationItemRenderer {
continuation_endpoint: ContinuationEndpoint,
},
/// Corrected search query
#[serde(rename_all = "camelCase")]
ShowingResultsForRenderer {
#[serde_as(as = "Text")]
corrected_query: String,
},
/// Contains video on startpage
///
/// Seems to be currently A/B tested on the channel page,
/// as of 11.10.2022
#[serde(alias = "shelfRenderer")]
RichItemRenderer {
content: Box<YouTubeListItem>,
},
/// Contains search results
///
/// Seems to be currently A/B tested on the video details page,
/// as of 11.10.2022
#[serde(alias = "expandedShelfContentsRenderer")]
ItemSectionRenderer {
#[serde(alias = "items")]
#[serde_as(as = "VecLogError<_>")]
contents: MapResult<Vec<YouTubeListItem>>,
},
/// No video list item (e.g. ad) or unimplemented item
///
/// Unimplemented:
/// - compactPlaylistRenderer (recommended playlists)
/// - compactRadioRenderer (recommended mix)
#[serde(other, deserialize_with = "ignore_any")]
None,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct VideoRenderer {
pub video_id: String,
pub thumbnail: Thumbnails,
#[serde_as(as = "Text")]
pub title: String,
#[serde(rename = "shortBylineText")]
pub channel: Option<TextComponent>,
pub channel_thumbnail: Option<Thumbnails>,
pub channel_thumbnail_supported_renderers: Option<ChannelThumbnailSupportedRenderers>,
#[serde_as(as = "Option<Text>")]
pub published_time_text: Option<String>,
#[serde_as(as = "Option<Text>")]
pub length_text: Option<String>,
/// Contains `No views` if the view count is zero
#[serde_as(as = "Option<Text>")]
pub view_count_text: Option<String>,
/// Channel verification badge
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub owner_badges: Vec<ChannelBadge>,
/// Contains live tag for recommended videos
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub badges: Vec<VideoBadge>,
/// Contains Short/Live tag
#[serde_as(as = "VecSkipError<_>")]
pub thumbnail_overlays: Vec<TimeOverlay>,
/// Abbreviated video description (on startpage)
#[serde_as(as = "Option<Text>")]
pub description_snippet: Option<String>,
/// Contains abbreviated video description (on search page)
#[serde_as(as = "Option<VecSkipError<_>>")]
pub detailed_metadata_snippets: Option<Vec<DetailedMetadataSnippet>>,
/// Release date for upcoming videos
pub upcoming_event_data: Option<UpcomingEventData>,
}
/// Playlist displayed in search results
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct PlaylistRenderer {
pub playlist_id: String,
#[serde_as(as = "Text")]
pub title: String,
pub thumbnail: Option<Thumbnails>,
/// Used by playlists from search page
///
/// The first item of this list contains the playlist thumbnail,
/// subsequent items contain very small thumbnails of the next playlist videos
pub thumbnails: Option<Vec<Thumbnails>>,
#[serde_as(as = "Option<JsonString>")]
pub video_count: Option<u64>,
#[serde_as(as = "Option<Text>")]
pub video_count_short_text: Option<String>,
#[serde(rename = "shortBylineText")]
pub channel: Option<TextComponent>,
/// Channel verification badge
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub owner_badges: Vec<ChannelBadge>,
}
/// Channel displayed in search results
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct ChannelRenderer {
pub channel_id: String,
#[serde_as(as = "Text")]
pub title: String,
pub thumbnail: Thumbnails,
/// Abbreviated channel description
///
/// Not present if the channel has no description
#[serde(default)]
#[serde_as(as = "Text")]
pub description_snippet: String,
/// Not present if the channel has no videos
#[serde_as(as = "Option<Text>")]
pub video_count_text: Option<String>,
#[serde_as(as = "Option<Text>")]
pub subscriber_count_text: Option<String>,
/// Channel verification badge
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub owner_badges: Vec<ChannelBadge>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct YouTubeListRendererWrap {
#[serde(alias = "richGridRenderer")]
pub section_list_renderer: YouTubeListRenderer,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct YouTubeListRenderer {
#[serde_as(as = "VecLogError<_>")]
pub contents: MapResult<Vec<YouTubeListItem>>,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct UpcomingEventData {
/// Unixtime in seconds
#[serde_as(as = "JsonString")]
pub start_time: i64,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct TimeOverlay {
pub thumbnail_overlay_time_status_renderer: TimeOverlayRenderer,
}
/// Badges are displayed on the video thumbnail and
/// show certain video properties (e.g. active livestream)
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct VideoBadge {
pub metadata_badge_renderer: VideoBadgeRenderer,
}
/// Badges are displayed on the video thumbnail and
/// show certain video properties (e.g. active livestream)
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct VideoBadgeRenderer {
pub style: VideoBadgeStyle,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub(crate) enum VideoBadgeStyle {
/// Active livestream
BadgeStyleTypeLiveNow,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct TimeOverlayRenderer {
/// `29:54`
///
/// Is `LIVE` in case of a livestream and `SHORTS` in case of a short video
#[serde_as(as = "Text")]
pub text: String,
#[serde(default)]
#[serde_as(deserialize_as = "DefaultOnError")]
pub style: TimeOverlayStyle,
}
#[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub(crate) enum TimeOverlayStyle {
#[default]
Default,
Live,
Shorts,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DetailedMetadataSnippet {
#[serde_as(as = "Text")]
pub snippet_text: String,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct ChannelThumbnailSupportedRenderers {
pub channel_thumbnail_with_link_renderer: ChannelThumbnailWithLinkRenderer,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct ChannelThumbnailWithLinkRenderer {
pub thumbnail: Thumbnails,
}
trait IsLive {
fn is_live(&self) -> bool;
}
trait IsShort {
fn is_short(&self) -> bool;
}
impl IsLive for Vec<VideoBadge> {
fn is_live(&self) -> bool {
self.iter().any(|badge| {
badge.metadata_badge_renderer.style == VideoBadgeStyle::BadgeStyleTypeLiveNow
})
}
}
impl IsLive for Vec<TimeOverlay> {
fn is_live(&self) -> bool {
self.iter().any(|overlay| {
overlay.thumbnail_overlay_time_status_renderer.style == TimeOverlayStyle::Live
})
}
}
impl IsShort for Vec<TimeOverlay> {
fn is_short(&self) -> bool {
self.iter().any(|overlay| {
overlay.thumbnail_overlay_time_status_renderer.style == TimeOverlayStyle::Shorts
})
}
}
/// Result of mapping a list of different YouTube enities
/// (videos, channels, playlists)
#[derive(Debug)]
pub(crate) struct YouTubeListMapper<T> {
lang: Language,
pub items: Vec<T>,
pub warnings: Vec<String>,
pub ctoken: Option<String>,
pub corrected_query: Option<String>,
}
impl<T> YouTubeListMapper<T> {
pub fn new(lang: Language) -> Self {
Self {
lang,
items: Vec::new(),
warnings: Vec::new(),
ctoken: None,
corrected_query: None,
}
}
fn map_video(&self, video: VideoRenderer) -> VideoItem {
let mut tn_overlays = video.thumbnail_overlays;
let length_text = video.length_text.or_else(|| {
tn_overlays
.try_swap_remove(0)
.map(|overlay| overlay.thumbnail_overlay_time_status_renderer.text)
});
VideoItem {
id: video.video_id,
title: video.title,
length: length_text.and_then(|txt| util::parse_video_length(&txt)),
thumbnail: video.thumbnail.into(),
channel: video.channel.and_then(|c| {
ChannelId::try_from(c).ok().map(|c| ChannelTag {
id: c.id,
name: c.name,
avatar: video
.channel_thumbnail_supported_renderers
.map(|tn| tn.channel_thumbnail_with_link_renderer.thumbnail)
.or(video.channel_thumbnail)
.unwrap_or_default()
.into(),
verification: video.owner_badges.into(),
subscriber_count: None,
})
}),
publish_date: video
.upcoming_event_data
.as_ref()
.map(|upc| {
chrono::Local.from_utc_datetime(&chrono::NaiveDateTime::from_timestamp(
upc.start_time,
0,
))
})
.or_else(|| {
video
.published_time_text
.as_ref()
.and_then(|txt| timeago::parse_timeago_to_dt(self.lang, txt))
}),
publish_date_txt: video.published_time_text,
view_count: video
.view_count_text
.map(|txt| util::parse_numeric(&txt).unwrap_or_default()),
is_live: tn_overlays.is_live() || video.badges.is_live(),
is_short: tn_overlays.is_short(),
is_upcoming: video.upcoming_event_data.is_some(),
short_description: video
.detailed_metadata_snippets
.and_then(|mut snippets| snippets.try_swap_remove(0).map(|s| s.snippet_text))
.or(video.description_snippet),
}
}
fn map_playlist(playlist: PlaylistRenderer) -> PlaylistItem {
PlaylistItem {
id: playlist.playlist_id,
name: playlist.title,
thumbnail: playlist
.thumbnail
.or_else(|| playlist.thumbnails.and_then(|mut t| t.try_swap_remove(0)))
.unwrap_or_default()
.into(),
channel: playlist.channel.and_then(|c| {
ChannelId::try_from(c).ok().map(|c| ChannelTag {
id: c.id,
name: c.name,
avatar: Vec::new(),
verification: playlist.owner_badges.into(),
subscriber_count: None,
})
}),
video_count: playlist.video_count.or_else(|| {
playlist
.video_count_short_text
.and_then(|txt| util::parse_numeric(&txt).ok())
}),
}
}
fn map_channel(channel: ChannelRenderer) -> ChannelItem {
ChannelItem {
id: channel.channel_id,
name: channel.title,
avatar: channel.thumbnail.into(),
verification: channel.owner_badges.into(),
subscriber_count: channel
.subscriber_count_text
.and_then(|txt| util::parse_numeric(&txt).ok()),
video_count: channel
.video_count_text
.and_then(|txt| util::parse_numeric(&txt).ok())
.unwrap_or_default(),
short_description: channel.description_snippet,
}
}
}
impl YouTubeListMapper<YouTubeItem> {
fn map_item(&mut self, item: YouTubeListItem) {
match item {
YouTubeListItem::VideoRenderer(video) => {
self.items.push(YouTubeItem::Video(self.map_video(video)));
}
YouTubeListItem::PlaylistRenderer(playlist) => self
.items
.push(YouTubeItem::Playlist(Self::map_playlist(playlist))),
YouTubeListItem::ChannelRenderer(channel) => {
self.items
.push(YouTubeItem::Channel(Self::map_channel(channel)));
}
YouTubeListItem::ContinuationItemRenderer {
continuation_endpoint,
} => self.ctoken = Some(continuation_endpoint.continuation_command.token),
YouTubeListItem::ShowingResultsForRenderer { corrected_query } => {
self.corrected_query = Some(corrected_query);
}
YouTubeListItem::RichItemRenderer { content } => {
self.map_item(*content);
}
YouTubeListItem::ItemSectionRenderer { mut contents } => {
self.warnings.append(&mut contents.warnings);
contents.c.into_iter().for_each(|it| self.map_item(it));
}
YouTubeListItem::None => {}
}
}
pub(crate) fn map_response(&mut self, mut res: MapResult<Vec<YouTubeListItem>>) {
self.warnings.append(&mut res.warnings);
res.c.into_iter().for_each(|item| self.map_item(item));
}
}
impl YouTubeListMapper<VideoItem> {
fn map_item(&mut self, item: YouTubeListItem) {
match item {
YouTubeListItem::VideoRenderer(video) => {
self.items.push(self.map_video(video));
}
YouTubeListItem::ContinuationItemRenderer {
continuation_endpoint,
} => self.ctoken = Some(continuation_endpoint.continuation_command.token),
YouTubeListItem::ShowingResultsForRenderer { corrected_query } => {
self.corrected_query = Some(corrected_query);
}
YouTubeListItem::RichItemRenderer { content } => {
self.map_item(*content);
}
YouTubeListItem::ItemSectionRenderer { mut contents } => {
self.warnings.append(&mut contents.warnings);
contents.c.into_iter().for_each(|it| self.map_item(it));
}
_ => {}
}
}
pub(crate) fn map_response(&mut self, mut res: MapResult<Vec<YouTubeListItem>>) {
self.warnings.append(&mut res.warnings);
res.c.into_iter().for_each(|item| self.map_item(item));
}
}
impl YouTubeListMapper<PlaylistItem> {
fn map_item(&mut self, item: YouTubeListItem) {
match item {
YouTubeListItem::PlaylistRenderer(playlist) => {
self.items.push(Self::map_playlist(playlist))
}
YouTubeListItem::ContinuationItemRenderer {
continuation_endpoint,
} => self.ctoken = Some(continuation_endpoint.continuation_command.token),
YouTubeListItem::ShowingResultsForRenderer { corrected_query } => {
self.corrected_query = Some(corrected_query);
}
YouTubeListItem::RichItemRenderer { content } => {
self.map_item(*content);
}
YouTubeListItem::ItemSectionRenderer { mut contents } => {
self.warnings.append(&mut contents.warnings);
contents.c.into_iter().for_each(|it| self.map_item(it));
}
_ => {}
}
}
pub(crate) fn map_response(&mut self, mut res: MapResult<Vec<YouTubeListItem>>) {
self.warnings.append(&mut res.warnings);
res.c.into_iter().for_each(|item| self.map_item(item));
}
}

View file

@ -3,15 +3,11 @@ use serde::{de::IgnoredAny, Serialize};
use crate::{ use crate::{
deobfuscate::Deobfuscator, deobfuscate::Deobfuscator,
error::{Error, ExtractionError}, error::{Error, ExtractionError},
model::{Paginator, SearchItem, SearchResult, SearchVideo}, model::{Paginator, SearchResult, YouTubeItem},
param::{search_filter::SearchFilter, Language}, param::{search_filter::SearchFilter, Language},
util::TryRemove,
}; };
use super::{ use super::{response, ClientType, MapResponse, MapResult, RustyPipeQuery, YTContext};
response::{self, TryFromWLang},
ClientType, MapResponse, MapResult, QContinuation, RustyPipeQuery, YTContext,
};
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -63,23 +59,6 @@ impl RustyPipeQuery {
.await .await
} }
pub async fn search_continuation(self, ctoken: &str) -> Result<Paginator<SearchItem>, Error> {
let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QContinuation {
context,
continuation: ctoken,
};
self.execute_request::<response::SearchCont, _, _>(
ClientType::Desktop,
"search_continuation",
ctoken,
"search",
&request_body,
)
.await
}
pub async fn search_suggestion(self, query: &str) -> Result<Vec<String>, Error> { pub async fn search_suggestion(self, query: &str) -> Result<Vec<String>, Error> {
let url = url::Url::parse_with_params("https://suggestqueries-clients6.youtube.com/complete/search?client=youtube&gs_rn=64&gs_ri=youtube&ds=yt&cp=1&gs_id=4&xhr=t&xssi=t", let url = url::Url::parse_with_params("https://suggestqueries-clients6.youtube.com/complete/search?client=youtube&gs_rn=64&gs_ri=youtube&ds=yt&cp=1&gs_id=4&xhr=t&xssi=t",
&[("hl", self.opts.lang.to_string()), ("gl", self.opts.country.to_string()), ("q", query.to_string())] &[("hl", self.opts.lang.to_string()), ("gl", self.opts.country.to_string()), ("q", query.to_string())]
@ -114,135 +93,33 @@ impl MapResponse<SearchResult> for response::Search {
lang: Language, lang: Language,
_deobf: Option<&Deobfuscator>, _deobf: Option<&Deobfuscator>,
) -> Result<MapResult<SearchResult>, ExtractionError> { ) -> Result<MapResult<SearchResult>, ExtractionError> {
let section_list_items = self let items = self
.contents .contents
.two_column_search_results_renderer .two_column_search_results_renderer
.primary_contents .primary_contents
.section_list_renderer .section_list_renderer
.contents; .contents;
let (items, ctoken) = map_section_list_items(section_list_items)?; let mut mapper = response::YouTubeListMapper::<YouTubeItem>::new(lang);
mapper.map_response(items);
let mut warnings = items.warnings;
let (mut mapped, corrected_query) = map_search_items(items.c, lang);
warnings.append(&mut mapped.warnings);
Ok(MapResult { Ok(MapResult {
c: SearchResult { c: SearchResult {
items: Paginator::new(self.estimated_results, mapped.c, ctoken), items: Paginator::new(self.estimated_results, mapper.items, mapper.ctoken),
corrected_query, corrected_query: mapper.corrected_query,
}, },
warnings, warnings: mapper.warnings,
}) })
} }
} }
impl MapResponse<Paginator<SearchItem>> for response::SearchCont {
fn map_response(
self,
_id: &str,
lang: Language,
_deobf: Option<&Deobfuscator>,
) -> Result<MapResult<Paginator<SearchItem>>, ExtractionError> {
let mut commands = self.on_response_received_commands;
let cont_command = some_or_bail!(
commands.try_swap_remove(0),
Err(ExtractionError::InvalidData(
"no item section renderer".into()
))
);
let (items, ctoken) = map_section_list_items(
cont_command
.append_continuation_items_action
.continuation_items,
)?;
let mut warnings = items.warnings;
let (mut mapped, _) = map_search_items(items.c, lang);
warnings.append(&mut mapped.warnings);
Ok(MapResult {
c: Paginator::new(self.estimated_results, mapped.c, ctoken),
warnings,
})
}
}
fn map_section_list_items(
section_list_items: Vec<response::search::SectionListItem>,
) -> Result<(MapResult<Vec<response::search::SearchItem>>, Option<String>), ExtractionError> {
let mut items = None;
let mut ctoken = None;
section_list_items.into_iter().for_each(|item| match item {
response::search::SectionListItem::ItemSectionRenderer { contents } => {
items = Some(contents);
}
response::search::SectionListItem::ContinuationItemRenderer {
continuation_endpoint,
} => {
ctoken = Some(continuation_endpoint.continuation_command.token);
}
});
let items = some_or_bail!(
items,
Err(ExtractionError::InvalidData(
"no item section renderer".into()
))
);
Ok((items, ctoken))
}
fn map_search_items(
items: Vec<response::search::SearchItem>,
lang: Language,
) -> (MapResult<Vec<SearchItem>>, Option<String>) {
let mut warnings = Vec::new();
let mut c_query = None;
let mapped_items = items
.into_iter()
.filter_map(|item| match item {
response::search::SearchItem::VideoRenderer(video) => {
match SearchVideo::from_w_lang(video, lang) {
Ok(video) => Some(SearchItem::Video(video)),
Err(e) => {
warnings.push(e.to_string());
None
}
}
}
response::search::SearchItem::PlaylistRenderer(playlist) => {
Some(SearchItem::Playlist(playlist.into()))
}
response::search::SearchItem::ChannelRenderer(channel) => {
Some(SearchItem::Channel(channel.into()))
}
response::search::SearchItem::ShowingResultsForRenderer { corrected_query } => {
c_query = Some(corrected_query);
None
}
response::search::SearchItem::None => None,
})
.collect();
(
MapResult {
c: mapped_items,
warnings,
},
c_query,
)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{fs::File, io::BufReader, path::Path}; use std::{fs::File, io::BufReader, path::Path};
use crate::{ use crate::{
client::{response, MapResponse}, client::{response, MapResponse},
model::{Paginator, SearchItem, SearchResult}, model::SearchResult,
param::Language, param::Language,
serializer::MapResult, serializer::MapResult,
}; };
@ -271,26 +148,4 @@ mod tests {
".items.items.*.publish_date" => "[date]", ".items.items.*.publish_date" => "[date]",
}); });
} }
#[test]
fn t_map_search_cont() {
let filename = format!("testfiles/search/cont.json");
let json_path = Path::new(&filename);
let json_file = File::open(json_path).unwrap();
let search_cont: response::SearchCont =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Paginator<SearchItem>> =
search_cont.map_response("", Language::En, None).unwrap();
assert!(
map_res.warnings.is_empty(),
"deserialization/mapping warnings: {:?}",
map_res.warnings
);
insta::assert_ron_snapshot!("map_search_cont", map_res.c, {
".items.*.publish_date" => "[date]",
});
}
} }

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: Verified,
description: "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON\'T DO PAID VIDEO SPONSORSHIPS, DON\'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don\'t be offended if I don\'t have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA", description: "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON\'T DO PAID VIDEO SPONSORSHIPS, DON\'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don\'t be offended if I don\'t have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA",
tags: [ tags: [
"electronics", "electronics",

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: Verified,
description: "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON\'T DO PAID VIDEO SPONSORSHIPS, DON\'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don\'t be offended if I don\'t have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA", description: "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON\'T DO PAID VIDEO SPONSORSHIPS, DON\'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don\'t be offended if I don\'t have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA",
tags: [ tags: [
"electronics", "electronics",
@ -144,7 +145,7 @@ Channel(
content: Paginator( content: Paginator(
count: None, count: None,
items: [ items: [
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtOV3AEwhuea4TnviddKfAj", id: "PLvOlSehNtuHtOV3AEwhuea4TnviddKfAj",
name: "MacGyver Project", name: "MacGyver Project",
thumbnail: [ thumbnail: [
@ -154,9 +155,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(2), video_count: Some(2),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHuvHE5GQrQJxWXHdmW2l5IF", id: "PLvOlSehNtuHuvHE5GQrQJxWXHdmW2l5IF",
name: "Calculators", name: "Calculators",
thumbnail: [ thumbnail: [
@ -166,9 +168,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(1), video_count: Some(1),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHs6wRwVSaErU0BEnLiHfnKJ", id: "PLvOlSehNtuHs6wRwVSaErU0BEnLiHfnKJ",
name: "BM235", name: "BM235",
thumbnail: [ thumbnail: [
@ -178,9 +181,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(9), video_count: Some(9),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHu4k0ZkKFLsysSB5iava6Qu", id: "PLvOlSehNtuHu4k0ZkKFLsysSB5iava6Qu",
name: "Vibration Measurement", name: "Vibration Measurement",
thumbnail: [ thumbnail: [
@ -190,9 +194,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(2), video_count: Some(2),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtdQF-m5UFZ5GEjABadI3kI", id: "PLvOlSehNtuHtdQF-m5UFZ5GEjABadI3kI",
name: "Component Selection", name: "Component Selection",
thumbnail: [ thumbnail: [
@ -202,9 +207,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(4), video_count: Some(4),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtlndPUSOPgsujUdq1c5Mr9", id: "PLvOlSehNtuHtlndPUSOPgsujUdq1c5Mr9",
name: "Solar Roadways", name: "Solar Roadways",
thumbnail: [ thumbnail: [
@ -214,9 +220,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(18), video_count: Some(18),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvD6M_7WeN071OVsZFE0_q-", id: "PLvOlSehNtuHvD6M_7WeN071OVsZFE0_q-",
name: "Electronics Tutorials - AC Theory Series", name: "Electronics Tutorials - AC Theory Series",
thumbnail: [ thumbnail: [
@ -226,9 +233,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(3), video_count: Some(3),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtVLq2MDPIz82BWMIZcuwhK", id: "PLvOlSehNtuHtVLq2MDPIz82BWMIZcuwhK",
name: "Electronics Tutorial - DC Fundamentals", name: "Electronics Tutorial - DC Fundamentals",
thumbnail: [ thumbnail: [
@ -238,9 +246,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(8), video_count: Some(8),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvIDfW3x2p4BY6l4RYgfBJE", id: "PLvOlSehNtuHvIDfW3x2p4BY6l4RYgfBJE",
name: "Oscilloscope Probing", name: "Oscilloscope Probing",
thumbnail: [ thumbnail: [
@ -250,9 +259,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(13), video_count: Some(13),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHu6Jjb8U82eKQfvKhJVl0Bu", id: "PLvOlSehNtuHu6Jjb8U82eKQfvKhJVl0Bu",
name: "Thermal Design", name: "Thermal Design",
thumbnail: [ thumbnail: [
@ -262,9 +272,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(9), video_count: Some(9),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHs-X2Awg33PCBNrP2BGFVhC", id: "PLvOlSehNtuHs-X2Awg33PCBNrP2BGFVhC",
name: "Electric Cars", name: "Electric Cars",
thumbnail: [ thumbnail: [
@ -274,9 +285,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(7), video_count: Some(7),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHuLODLTeq3PM-OJRP2nzNUa", id: "PLvOlSehNtuHuLODLTeq3PM-OJRP2nzNUa",
name: "Designing a better uCurrent", name: "Designing a better uCurrent",
thumbnail: [ thumbnail: [
@ -286,9 +298,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(3), video_count: Some(3),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtvTKP4RTNW1-08Kmzy1pvA", id: "PLvOlSehNtuHtvTKP4RTNW1-08Kmzy1pvA",
name: "EMC Compliance & Measurement", name: "EMC Compliance & Measurement",
thumbnail: [ thumbnail: [
@ -298,9 +311,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(8), video_count: Some(8),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHuUTpCrTVX7BdU68l2aVqMv", id: "PLvOlSehNtuHuUTpCrTVX7BdU68l2aVqMv",
name: "Power Counter Display Project", name: "Power Counter Display Project",
thumbnail: [ thumbnail: [
@ -310,9 +324,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(2), video_count: Some(2),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvm120Tq40nKrM5SUBlolN3", id: "PLvOlSehNtuHvm120Tq40nKrM5SUBlolN3",
name: "Live - Ask Dave", name: "Live - Ask Dave",
thumbnail: [ thumbnail: [
@ -322,9 +337,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(3), video_count: Some(3),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHsiF93KOLoF1KAHArmIW9lC", id: "PLvOlSehNtuHsiF93KOLoF1KAHArmIW9lC",
name: "Padauk Microcontroller", name: "Padauk Microcontroller",
thumbnail: [ thumbnail: [
@ -334,9 +350,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(10), video_count: Some(10),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvxTzBLwUFw4My4rtrNFzED", id: "PLvOlSehNtuHvxTzBLwUFw4My4rtrNFzED",
name: "Other Debunking Videos", name: "Other Debunking Videos",
thumbnail: [ thumbnail: [
@ -346,9 +363,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(1), video_count: Some(1),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHt2pJ7X5tumuM4Wa3r1OC7Q", id: "PLvOlSehNtuHt2pJ7X5tumuM4Wa3r1OC7Q",
name: "Audio & Speakers", name: "Audio & Speakers",
thumbnail: [ thumbnail: [
@ -358,9 +376,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(9), video_count: Some(9),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtX7OearWdmqGzqiu4DHKWi", id: "PLvOlSehNtuHtX7OearWdmqGzqiu4DHKWi",
name: "Cameras", name: "Cameras",
thumbnail: [ thumbnail: [
@ -370,9 +389,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(16), video_count: Some(16),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHu-TaNRp27_PiXjBG5wY9Gv", id: "PLvOlSehNtuHu-TaNRp27_PiXjBG5wY9Gv",
name: "Cryptocurrency", name: "Cryptocurrency",
thumbnail: [ thumbnail: [
@ -382,9 +402,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(7), video_count: Some(7),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvmK-VGcZ33ZuATmcNB8tvH", id: "PLvOlSehNtuHvmK-VGcZ33ZuATmcNB8tvH",
name: "LCD Tutorial", name: "LCD Tutorial",
thumbnail: [ thumbnail: [
@ -394,9 +415,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(6), video_count: Some(6),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvbV8x_bWQBKEg4IshWjG3U", id: "PLvOlSehNtuHvbV8x_bWQBKEg4IshWjG3U",
name: "Guest Videos", name: "Guest Videos",
thumbnail: [ thumbnail: [
@ -406,9 +428,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(12), video_count: Some(12),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHs5tuhiqdxQeegsLDP7TM8V", id: "PLvOlSehNtuHs5tuhiqdxQeegsLDP7TM8V",
name: "Software Development", name: "Software Development",
thumbnail: [ thumbnail: [
@ -418,9 +441,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(1), video_count: Some(1),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHu328BlpUOUDsv9Kf1Ri8Tg", id: "PLvOlSehNtuHu328BlpUOUDsv9Kf1Ri8Tg",
name: "John Kenny - Keysight", name: "John Kenny - Keysight",
thumbnail: [ thumbnail: [
@ -430,9 +454,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(5), video_count: Some(5),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvj_E5KUBluJJupXmideiZk", id: "PLvOlSehNtuHvj_E5KUBluJJupXmideiZk",
name: "General Tech Information", name: "General Tech Information",
thumbnail: [ thumbnail: [
@ -442,9 +467,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(2), video_count: Some(2),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHsWHPg1KlSd8agKbrcn3Dwn", id: "PLvOlSehNtuHsWHPg1KlSd8agKbrcn3Dwn",
name: "Microscope", name: "Microscope",
thumbnail: [ thumbnail: [
@ -454,9 +480,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(4), video_count: Some(4),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHuQb5djEVLzwBSTT27p2dXB", id: "PLvOlSehNtuHuQb5djEVLzwBSTT27p2dXB",
name: "The Signal Path", name: "The Signal Path",
thumbnail: [ thumbnail: [
@ -466,9 +493,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(1), video_count: Some(1),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHstMIbtLqlEiidVjj8ob0xp", id: "PLvOlSehNtuHstMIbtLqlEiidVjj8ob0xp",
name: "Thermal Imaging", name: "Thermal Imaging",
thumbnail: [ thumbnail: [
@ -478,9 +506,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(2), video_count: Some(2),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHugqRHdt46SN9Bmoh-D5Gp2", id: "PLvOlSehNtuHugqRHdt46SN9Bmoh-D5Gp2",
name: "EEVacademy", name: "EEVacademy",
thumbnail: [ thumbnail: [
@ -490,9 +519,10 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(9), video_count: Some(9),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtqqYM7ON99sbyiokMKrwwI", id: "PLvOlSehNtuHtqqYM7ON99sbyiokMKrwwI",
name: "Brainstorming", name: "Brainstorming",
thumbnail: [ thumbnail: [
@ -502,9 +532,11 @@ Channel(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(1), video_count: Some(1),
), ),
], ],
ctoken: Some("4qmFsgLCARIYVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RGnRFZ2x3YkdGNWJHbHpkSE1ZQXlBQk1BRTRBZW9EUEVOblRrUlJhbEZUU2tKSmFWVkZlREpVTW5oVVdsZG9UMlJJVmtsa1NFWjRWMVV3TTFRd05EVlBXRTVwWlZkc2RtRXdNVXhqYm1RelUxTm5PQSUzRCUzRJoCL2Jyb3dzZS1mZWVkVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RcGxheWxpc3RzMTA0"), ctoken: Some("4qmFsgLCARIYVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RGnRFZ2x3YkdGNWJHbHpkSE1ZQXlBQk1BRTRBZW9EUEVOblRrUlJhbEZUU2tKSmFWVkZlREpVTW5oVVdsZG9UMlJJVmtsa1NFWjRWMVV3TTFRd05EVlBXRTVwWlZkc2RtRXdNVXhqYm1RelUxTm5PQSUzRCUzRJoCL2Jyb3dzZS1mZWVkVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RcGxheWxpc3RzMTA0"),
endpoint: browse,
), ),
) )

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: Verified,
description: "Hi, Im Tina, aka Doobydobap!\n\nFood is the medium I use to tell stories and connect with people who share the same passion as I do. Whether its because youre hungry at midnight or trying to learn how to cook, I hope you enjoy watching my content and recipes. Don\'t yuck my yum!\n\nwww.doobydobap.com\n", description: "Hi, Im Tina, aka Doobydobap!\n\nFood is the medium I use to tell stories and connect with people who share the same passion as I do. Whether its because youre hungry at midnight or trying to learn how to cook, I hope you enjoy watching my content and recipes. Don\'t yuck my yum!\n\nwww.doobydobap.com\n",
tags: [], tags: [],
vanity_url: Some("https://www.youtube.com/c/Doobydobap"), vanity_url: Some("https://www.youtube.com/c/Doobydobap"),
@ -115,7 +116,7 @@ Channel(
content: Paginator( content: Paginator(
count: None, count: None,
items: [ items: [
ChannelVideo( VideoItem(
id: "EIcmfSzeaKk", id: "EIcmfSzeaKk",
title: "our new normal", title: "our new normal",
length: Some(1106), length: Some(1106),
@ -141,14 +142,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("9 hours ago"), publish_date_txt: Some("9 hours ago"),
view_count: 142423, view_count: Some(142423),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("I\'ve been really enjoying cooking more lately (′ꈍωꈍ‵)\nWas so cool to see my makgeolli fermenting, I can\'t wait to show you the progress update in my next vlog. \n\nThank you again doobies!..."),
), ),
ChannelVideo( VideoItem(
id: "9NuhKCv3crg", id: "9NuhKCv3crg",
title: "the end.", title: "the end.",
length: Some(982), length: Some(982),
@ -174,14 +177,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 days ago"), publish_date_txt: Some("7 days ago"),
view_count: 989763, view_count: Some(989763),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("or the start of something new~~~~~\n\nThank you for your patience on the vlog, it took some time to adjust to my new normal. Excited for change and I\'ll always try my best to make the best content..."),
), ),
ChannelVideo( VideoItem(
id: "38Gd6TdmNVs", id: "38Gd6TdmNVs",
title: "KOREAN BARBECUE l doob gourmand ep.3", title: "KOREAN BARBECUE l doob gourmand ep.3",
length: Some(525), length: Some(525),
@ -207,14 +212,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 355470, view_count: Some(355470),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("I haven\'t done a doob gourmand series in so so long! I hope you enjoyed it, let me know what kind of food you\'re interested in seeing in these series! :)\n\nLove you doobies!\n\nInstagram @doobydobap..."),
), ),
ChannelVideo( VideoItem(
id: "l9TiwunjzgA", id: "l9TiwunjzgA",
title: "long distance", title: "long distance",
length: Some(1043), length: Some(1043),
@ -240,14 +247,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 697188, view_count: Some(697188),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("exciting changes are about to come! \ndoob gourmand kbbq coming out on Thursday this week :)\n\nInstagram @doobydobap \nJoin my discord! 😈\nhttps://discord.gg/doobyverse\nwww.doobydobap.com for..."),
), ),
ChannelVideo( VideoItem(
id: "pRVSdUxdsVw", id: "pRVSdUxdsVw",
title: "Repairing...", title: "Repairing...",
length: Some(965), length: Some(965),
@ -273,14 +282,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 weeks ago"), publish_date_txt: Some("4 weeks ago"),
view_count: 529586, view_count: Some(529586),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("The word repair stems from the Latin word reparare, from re- back and parare make ready.\' And I feel that\'s exactly how I feel about this week\'s vlog-- I feel like I\'m repairing my..."),
), ),
ChannelVideo( VideoItem(
id: "2FJVhdOO0F0", id: "2FJVhdOO0F0",
title: "a health scare", title: "a health scare",
length: Some(1238), length: Some(1238),
@ -306,14 +317,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 1066729, view_count: Some(1066729),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("https://www.nationalbreastcancer.org/about-breast-cancer/\nI\'m really thankful that my results came out okay. This really was one of the worst / scariest weeks of my life, but an important one..."),
), ),
ChannelVideo( VideoItem(
id: "CutR_1SDDzY", id: "CutR_1SDDzY",
title: "feels good to be back", title: "feels good to be back",
length: Some(1159), length: Some(1159),
@ -339,14 +352,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 525663, view_count: Some(525663),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("I missed you guys. Happy to see you guys back. \nI\'ve really been working on my mental health, educating myself with different food cultures, and focusing on being happy the last month. \nThank..."),
), ),
ChannelVideo( VideoItem(
id: "KUz7oArksR4", id: "KUz7oArksR4",
title: "running away", title: "running away",
length: Some(1023), length: Some(1023),
@ -372,14 +387,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 717806, view_count: Some(717806),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("for now... more adventures to come! \n\n\n\n\nMusic by Mark Generous - A Summer Day - https://thmatc.co/?l=CF6C5FFF\nInstagram @doobydobap \nJoin my discord! 😈\nhttps://discord.gg/doobyverse\nwww.doobyd..."),
), ),
ChannelVideo( VideoItem(
id: "sPb2gyN-hnE", id: "sPb2gyN-hnE",
title: "worth fighting for", title: "worth fighting for",
length: Some(1232), length: Some(1232),
@ -405,14 +422,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 624673, view_count: Some(624673),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Please be respectful in the comments section! \nI will not be tolerating any hateful/derogatory speech 👹👹👹 *barking noise*\n\nMusic \nMarie - Howard Harper-Barnes\nMusic by Monét Ngo -..."),
), ),
ChannelVideo( VideoItem(
id: "PXsK9-CFoH4", id: "PXsK9-CFoH4",
title: "waiting...", title: "waiting...",
length: Some(1455), length: Some(1455),
@ -438,14 +457,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 924135, view_count: Some(924135),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("👀☂\u{fe0f}🕴\u{fe0f}\ntuna kimchi jook \n2 cups cooked rice \n3 cups water \n1 cup kimchi \n320g canned tuna \n1 tbsp perilla seed oil \n1 onion\n1 tbsp gochujang\n1 tbsp soy sauce \n½ tsp salt (to taste)..."),
), ),
ChannelVideo( VideoItem(
id: "r2ye6zW0nbM", id: "r2ye6zW0nbM",
title: "a wedding", title: "a wedding",
length: Some(1207), length: Some(1207),
@ -471,14 +492,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 1053353, view_count: Some(1053353),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Ginger Pork Recipe!\nhttps://doobydobap.com/recipe/ginger-pork-shogayaki\n-\nInstagram @doobydobap \nJoin my discord! 😈\nhttps://discord.gg/doobyverse\nwww.doobydobap.com for recipes & stories..."),
), ),
ChannelVideo( VideoItem(
id: "rriwHj8U664", id: "rriwHj8U664",
title: "my seoul apartment tour", title: "my seoul apartment tour",
length: Some(721), length: Some(721),
@ -504,14 +527,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 697242, view_count: Some(697242),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Korea has an interesting rent structure called junseh where you pay a higher security deposit in turn for lower rent! And before anyone starts accusing me, no, it\'s all with my own money!!!..."),
), ),
ChannelVideo( VideoItem(
id: "FKJtrUeol3o", id: "FKJtrUeol3o",
title: "with quantity comes quality", title: "with quantity comes quality",
length: Some(1140), length: Some(1140),
@ -537,14 +562,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 1086097, view_count: Some(1086097),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("A busy, but calm week for me here in Seoul living alone. \nPlanning on exploring more parts of Korea, please let me know in the comments what you\'d wanna see!\n\nFried Eggplants with Doubanjiang..."),
), ),
ChannelVideo( VideoItem(
id: "zYHB38UlzE0", id: "zYHB38UlzE0",
title: "Q&A l relationships, burnout, privilege, college advice, living alone, and life after youtube?", title: "Q&A l relationships, burnout, privilege, college advice, living alone, and life after youtube?",
length: Some(775), length: Some(775),
@ -570,14 +597,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 528979, view_count: Some(528979),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("So many questions I wasn\'t able to answer, but if you comment below I\'ll try and answer every single one of them!!!!\n\nA little bit of audio issues, it was my first time using this mic, \nsowwy..."),
), ),
ChannelVideo( VideoItem(
id: "hGbQ2WM9nOo", id: "hGbQ2WM9nOo",
title: "Why does everything bad for you taste good ㅣ CHILI OIL RAMEN", title: "Why does everything bad for you taste good ㅣ CHILI OIL RAMEN",
length: Some(428), length: Some(428),
@ -603,14 +632,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 1036890, view_count: Some(1036890),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("https://partner.bokksu.com/doobydobap use code DOOBYDOBAP to get $15 off your first bokksu order! \n\nInstagram @doobydobap \nJoin my discord! 😈\nhttps://discord.gg/doobyverse\nwww.doobydobap.com..."),
), ),
ChannelVideo( VideoItem(
id: "PxGmP4v_A38", id: "PxGmP4v_A38",
title: "Alone and Thriving l late night korean convenience store, muji kitchenware haul, spring cleaning!", title: "Alone and Thriving l late night korean convenience store, muji kitchenware haul, spring cleaning!",
length: Some(1437), length: Some(1437),
@ -636,14 +667,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 832542, view_count: Some(832542),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("I could palpably feel how I\'m so much happier than before when I was reviewing my footage 🥺🥺🥺 \n\nAll the finalized recipes will be updated on my Instagram or my website! \n\nMusic\nMusic..."),
), ),
ChannelVideo( VideoItem(
id: "8t-WyYcpEDE", id: "8t-WyYcpEDE",
title: "What I hate most", title: "What I hate most",
length: Some(61), length: Some(61),
@ -669,14 +702,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 1342882, view_count: Some(1342882),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("#shorts #cooking \nhttps://doobydobap.com/recipe/ginger-pork-shogayaki\n\nInstagram @doobydobap \nJoin my discord! 😈\nhttps://discord.gg/doobyverse\nwww.doobydobap.com for recipes & stories"),
), ),
ChannelVideo( VideoItem(
id: "RroYpLxxNjY", id: "RroYpLxxNjY",
title: "I\'m Back. ㅣ cooking korean food, eating alone, working out, and 2M!", title: "I\'m Back. ㅣ cooking korean food, eating alone, working out, and 2M!",
length: Some(1313), length: Some(1313),
@ -702,14 +737,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 1076848, view_count: Some(1076848),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Annyoung doobies! It has been a while since I\'ve sat down and spoken to you all. I\'m thrilled to be back, and I finally feel like I\'m in my element after a much-needed break. \n\nThank you so..."),
), ),
ChannelVideo( VideoItem(
id: "l47QuudsZ34", id: "l47QuudsZ34",
title: "We ate our way through Florence (ft. mamadooby)", title: "We ate our way through Florence (ft. mamadooby)",
length: Some(1109), length: Some(1109),
@ -735,14 +772,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 months ago"), publish_date_txt: Some("5 months ago"),
view_count: 562349, view_count: Some(562349),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Annyoung doobies :)\nI\'m back after a hiatus, I\'ve been travelling and putting my mental health first so I don\'t burn out!!! Much needed break to be inspired & grow for more content to come!..."),
), ),
ChannelVideo( VideoItem(
id: "1VW7iXRIrc8", id: "1VW7iXRIrc8",
title: "Alone, in the City of Love", title: "Alone, in the City of Love",
length: Some(1875), length: Some(1875),
@ -768,14 +807,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 531938, view_count: Some(531938),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("I know it\'s a little long, but I hope you enjoyed this Paris vlog :}\n\nLocation📍\nUdon Restaurant: Sanukiya\n9 Rue d\'Argenteuil, Paris\nCoffee: Telescope Cafe\n5 Rue Villédo, 75001 Paris, France..."),
), ),
ChannelVideo( VideoItem(
id: "6c58-749p6Y", id: "6c58-749p6Y",
title: "Old Friends & New", title: "Old Friends & New",
length: Some(774), length: Some(774),
@ -801,14 +842,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 426469, view_count: Some(426469),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Realized I have a typo that says perogis instead of peroni oop \nBut for real, I\'m so thankful for Bobbi bc she was one of the few/ only people that welcomed me to a new school/country where..."),
), ),
ChannelVideo( VideoItem(
id: "Q2G53LuEUaU", id: "Q2G53LuEUaU",
title: "Where we stand", title: "Where we stand",
length: Some(858), length: Some(858),
@ -834,14 +877,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 448915, view_count: Some(448915),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Thank you to BetterHelp for sponsoring this video! \nGo to https://www.betterhelp.com/doobydobap to get 10% off your first month :)\n\nLocations 📍\nThis is Dover btw\nhttps://www.google.com/maps/plac..."),
), ),
ChannelVideo( VideoItem(
id: "8rAOeowNQrI", id: "8rAOeowNQrI",
title: "That\'s so last year", title: "That\'s so last year",
length: Some(1286), length: Some(1286),
@ -867,14 +912,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 675443, view_count: Some(675443),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Location 📍\nScience Museum\nhttps://goo.gl/maps/dPPSZwmSrMzhEh9Y7\nNatural History Museum \nhttps://goo.gl/maps/XSu2EZN9XP8rGVWg6\nJoy King Lau - Dim Sum \nhttps://goo.gl/maps/D3rgoN1raQocyQPM6..."),
), ),
ChannelVideo( VideoItem(
id: "0RGIdIKkbSI", id: "0RGIdIKkbSI",
title: "The Muffin Man", title: "The Muffin Man",
length: Some(1052), length: Some(1052),
@ -900,14 +947,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 426465, view_count: Some(426465),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Use code DOOBYDOBAP16 for up to 16 FREE MEALS + 3 Surprise Gifts across 6 HelloFresh boxes plus free shipping at https://bit.ly/3Kiz0qb!\n\nMusic\nindolore - je rêve d\'é ( moow edit ) https://soundc..."),
), ),
ChannelVideo( VideoItem(
id: "NudTbo2CJMY", id: "NudTbo2CJMY",
title: "Flying to London", title: "Flying to London",
length: Some(1078), length: Some(1078),
@ -933,14 +982,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 1137831, view_count: Some(1137831),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Tomato Beef Curry\n1 packet Japanese Curry Roux\n250g thinly sliced beef \n2 large onions\n2 tbsp butter\n2 tbsp neutral oil \n1 can whole tomatoes\n500mL water\n2 tbsp ketchup \n\n1. Melt 1 tbsp butter..."),
), ),
ChannelVideo( VideoItem(
id: "8mJk1ncGZig", id: "8mJk1ncGZig",
title: "(not so) Teenage Angst", title: "(not so) Teenage Angst",
length: Some(1376), length: Some(1376),
@ -966,14 +1017,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 612275, view_count: Some(612275),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Again, I hope you guys know that my vlogs are a visual diary of whats happening in my life and what Im feeling that week. Im not speaking for everyone, so take with a grain o salt!..."),
), ),
ChannelVideo( VideoItem(
id: "qvgCi2WpbfE", id: "qvgCi2WpbfE",
title: "can\'t smell :s", title: "can\'t smell :s",
length: Some(875), length: Some(875),
@ -999,14 +1052,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 396397, view_count: Some(396397),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Kimchi Jeon \nParmesan Kimchi Jeon or regular, both works\nIngredients\n* 1 cup kimchi + 2 tbsp juice\n* 1 tsp gochujang (optional for extra heat)\n* ⅓ cup parmesan, grated + extra parmesan for..."),
), ),
ChannelVideo( VideoItem(
id: "Sm4Yqtqr9f8", id: "Sm4Yqtqr9f8",
title: "I have covid", title: "I have covid",
length: Some(814), length: Some(814),
@ -1032,14 +1087,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 599030, view_count: Some(599030),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("I had a bit too much fun with the intro.\nI actually didn\'t realize I shot it in slow-mo. \nThank you all for the supportive messages, donno what I did to deserve you all. Eternally thankful...."),
), ),
ChannelVideo( VideoItem(
id: "ZRtf4ksF3qs", id: "ZRtf4ksF3qs",
title: "Everything I ate in Busan & make up tutorial??", title: "Everything I ate in Busan & make up tutorial??",
length: Some(1026), length: Some(1026),
@ -1065,14 +1122,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 530192, view_count: Some(530192),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("I\'m okay btw!! I got overwhelmed a bit this past weekend in Busan and was really... anxious the entire time I was on my trip :(\nI\'ll still be sharing where I went from last weekend soon as..."),
), ),
ChannelVideo( VideoItem(
id: "oG4Wth1oVBQ", id: "oG4Wth1oVBQ",
title: "On the other side", title: "On the other side",
length: Some(1592), length: Some(1592),
@ -1098,14 +1157,17 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 months ago"), publish_date_txt: Some("8 months ago"),
view_count: 567604, view_count: Some(567604),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Gochujang Pasta Recipe Link\nhttps://doobydobap.com/recipe/gochujang-pasta-with-prawns\nI just didn\'t put any prawns bc I didn\'t have any!\n\nLocation\ndanil seoul \n66-33 Wangsimni-ro, Seongsu-dong..."),
), ),
], ],
ctoken: Some("4qmFsgKhARIYVUNoOGdIZHR6TzJ0WGQ1OTNfYmpFcldnGoQBOGdaZ0dsNTZYQXBZQ2pCRlozTkpiRXRwYURZdFNGZG9ZbVZuUVZObmVVMUJSVFJJYTBsTVExQlFVbXR3YjBkRlMwUnBkVmRhU1VGV1FVRVNKRFl6TkRnd056Wm1MVEF3TURBdE1tRXhaUzA0TnpRNUxXUTBaalUwTjJZNE16a3pZeGdC"), ctoken: Some("4qmFsgKhARIYVUNoOGdIZHR6TzJ0WGQ1OTNfYmpFcldnGoQBOGdaZ0dsNTZYQXBZQ2pCRlozTkpiRXRwYURZdFNGZG9ZbVZuUVZObmVVMUJSVFJJYTBsTVExQlFVbXR3YjBkRlMwUnBkVmRhU1VGV1FVRVNKRFl6TkRnd056Wm1MVEF3TURBdE1tRXhaUzA0TnpRNUxXUTBaalUwTjJZNE16a3pZeGdC"),
endpoint: browse,
), ),
) )

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: Verified,
description: "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON\'T DO PAID VIDEO SPONSORSHIPS, DON\'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don\'t be offended if I don\'t have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA", description: "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON\'T DO PAID VIDEO SPONSORSHIPS, DON\'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don\'t be offended if I don\'t have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA",
tags: [ tags: [
"electronics", "electronics",
@ -144,7 +145,7 @@ Channel(
content: Paginator( content: Paginator(
count: None, count: None,
items: [ items: [
ChannelVideo( VideoItem(
id: "4EcQYK_no5M", id: "4EcQYK_no5M",
title: "EEVblog 1506 - History of Electricity with Kathy Loves Physics", title: "EEVblog 1506 - History of Electricity with Kathy Loves Physics",
length: Some(6143), length: Some(6143),
@ -170,14 +171,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 day ago"), publish_date_txt: Some("1 day ago"),
view_count: 8813, view_count: Some(8813),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Talking about the history of electricity and physics with Kathy Joseph from Kathey Loves Physics, and her new book:\nThe Lightning Tamers: True Stories of the Dreamers and Schemers Who Harnessed..."),
), ),
ChannelVideo( VideoItem(
id: "zEzjVUzNAFA", id: "zEzjVUzNAFA",
title: "EEVblog 1505 - 120W Home Phantom Power? Audit Time!", title: "EEVblog 1505 - 120W Home Phantom Power? Audit Time!",
length: Some(1464), length: Some(1464),
@ -203,14 +206,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 days ago"), publish_date_txt: Some("6 days ago"),
view_count: 48599, view_count: Some(48599),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("My home takes 120W phantom standby power. Let\'s do a complete audit and see what is consuming the most power, and how it can be reduced.\n\nHow bad product design kills the environment: https://www.y..."),
), ),
ChannelVideo( VideoItem(
id: "YIbQ3nudCA0", id: "YIbQ3nudCA0",
title: "EEVblog 1504 - The COOL thing you MISSED at Tesla AI Day 2022", title: "EEVblog 1504 - The COOL thing you MISSED at Tesla AI Day 2022",
length: Some(1021), length: Some(1021),
@ -236,14 +241,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("10 days ago"), publish_date_txt: Some("10 days ago"),
view_count: 74126, view_count: Some(74126),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("A very cool bit of electronics failure mode analysis that you missed at the 2022 Tesla AI Day presentation. And it\'s got nothing to do with the Optimus Tesla Bot!\n\nA look at how ceramic capacitor..."),
), ),
ChannelVideo( VideoItem(
id: "W1Jl0rMRGSg", id: "W1Jl0rMRGSg",
title: "EEVblog 1503 - Rigol HDO4000 12bit Oscilloscope TEARDOWN", title: "EEVblog 1503 - Rigol HDO4000 12bit Oscilloscope TEARDOWN",
length: Some(1798), length: Some(1798),
@ -269,14 +276,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 days ago"), publish_date_txt: Some("11 days ago"),
view_count: 36129, view_count: Some(36129),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Teardown of the new Rigol HDO4000 12bit ultra low noise oscilloscope\n\nPSU teardown: https://www.youtube.com/watch?v=muMjiao5i0k\n\nForum: https://www.eevblog.com/forum/testgear/rigol-hdo1000-and-hdo4..."),
), ),
ChannelVideo( VideoItem(
id: "YFKu_emNzpk", id: "YFKu_emNzpk",
title: "EEVblog 1502 - Is Home Battery Storage Financially Viable?", title: "EEVblog 1502 - Is Home Battery Storage Financially Viable?",
length: Some(1199), length: Some(1199),
@ -302,14 +311,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 87357, view_count: Some(87357),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Running through the numbers to see if home battery storage is viable on my home. \nAnd comparing Tesla Powerwall, Enphase IQ Battery, BYD LVS, and Greenbank battery pricing.\n\nAll my solar videos:..."),
), ),
ChannelVideo( VideoItem(
id: "gremHHvqYTE", id: "gremHHvqYTE",
title: "EEVblog 1501 - Rigol HDO4000 Low Noise 12bit Oscilloscope Unboxing & First Impression", title: "EEVblog 1501 - Rigol HDO4000 Low Noise 12bit Oscilloscope Unboxing & First Impression",
length: Some(1794), length: Some(1794),
@ -335,14 +346,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 48259, view_count: Some(48259),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Rigol\'s new HDO4000 Series ultra low noise 12bit oscilloscope with Centaur chipset.\nUnboxing, first impression, and noise measurements.\n\nAC RMS noise measurement: https://www.youtube.com/watch?v=G8..."),
), ),
ChannelVideo( VideoItem(
id: "WHO8NBfpaO0", id: "WHO8NBfpaO0",
title: "eevBLAB 102 - Last Mile Autonomous Robot Deliveries WILL FAIL", title: "eevBLAB 102 - Last Mile Autonomous Robot Deliveries WILL FAIL",
length: Some(742), length: Some(742),
@ -368,14 +381,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 27509, view_count: Some(27509),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Four reasons why autonomous pizza delivery robots will FAIL.\nAnd nope, they won\'t save the environment either.\nBut maybe I\'m wrong?\nMagna are trialing a pizza delivery robot in Manhatten.\n..."),
), ),
ChannelVideo( VideoItem(
id: "W1Q8CxL95_Y", id: "W1Q8CxL95_Y",
title: "EEVblog 1500 - Automatic Transfer Switch REVERSE ENGINEERED", title: "EEVblog 1500 - Automatic Transfer Switch REVERSE ENGINEERED",
length: Some(1770), length: Some(1770),
@ -401,14 +416,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 57925, view_count: Some(57925),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Automatic AC transfer switches are pretty cool devices. A look at what they do, a practical demo, teardown, and then reverse engineering to explain how it does it with a direct one-to-one schematic..."),
), ),
ChannelVideo( VideoItem(
id: "lagxSrPeoYg", id: "lagxSrPeoYg",
title: "EEVblog 1499 - EcoFlow Delta Pro 3.6kWh Portable Battery TEARDOWN!", title: "EEVblog 1499 - EcoFlow Delta Pro 3.6kWh Portable Battery TEARDOWN!",
length: Some(2334), length: Some(2334),
@ -434,14 +451,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 77907, view_count: Some(77907),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Teardown of the EcoFlow Delta Pro 3.6kWh portable/home LiFePO4 battery solar inverter/generator.\nBack in the old EEVblog garage!\n\nTeardown photos: https://www.eevblog.com/2022/09/08/eevblog-1499-ec..."),
), ),
ChannelVideo( VideoItem(
id: "qTctWW9_FmE", id: "qTctWW9_FmE",
title: "EEVblog 1498 - TransPod Fluxjet Hyperloop $550M Boondoggle!", title: "EEVblog 1498 - TransPod Fluxjet Hyperloop $550M Boondoggle!",
length: Some(2399), length: Some(2399),
@ -467,14 +486,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 63421, view_count: Some(63421),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("The Transpod FluxJet is Hyperloop based on the \"New physics\" of \"Veillance Flux\"!\nAnd plasma arc power transfer!\n$550M to create a reduced pressure Fluxjet link from Calgary to Edmonton in..."),
), ),
ChannelVideo( VideoItem(
id: "3t9G80wk0pk", id: "3t9G80wk0pk",
title: "eevBLAB 101 - Why Are Tektronix Oscilloscopes So Expensive?", title: "eevBLAB 101 - Why Are Tektronix Oscilloscopes So Expensive?",
length: Some(1423), length: Some(1423),
@ -500,14 +521,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 73052, view_count: Some(73052),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Answering the question of why Tektronix and the other top tier manufactuer\'s oscilloscopes are so expensive? Why don\'t they just make a low cost scope?\nHere is a list of 16 reasons, can you..."),
), ),
ChannelVideo( VideoItem(
id: "7dze5CnZnmk", id: "7dze5CnZnmk",
title: "EEVblog 1497 - RIP Fluke. Thanks Energizer. NOT.", title: "EEVblog 1497 - RIP Fluke. Thanks Energizer. NOT.",
length: Some(1168), length: Some(1168),
@ -533,14 +556,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 93529, view_count: Some(93529),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("RIP this Fluke 3000 wireless multimeter. Thanks Energizer for the alkaline battery leakage!\n\nPART 2 Repair: https://www.youtube.com/watch?v=qmcSEJehqZM\n\nEnergizer battery leakage in liquid..."),
), ),
ChannelVideo( VideoItem(
id: "6XnrZpPYgBg", id: "6XnrZpPYgBg",
title: "EEVblog 1496 - Winning Mailbag", title: "EEVblog 1496 - Winning Mailbag",
length: Some(3139), length: Some(3139),
@ -566,14 +591,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 41569, view_count: Some(41569),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Meet 13yo Josh, the winner of the Jaycar $5 scope, and designer of Framework laptop boards!\nhttps://lectronz.com/products/uart-expansion-card\nHis Patreon: https://www.patreon.com/i2clabs\nMore..."),
), ),
ChannelVideo( VideoItem(
id: "Psp3ltpFvws", id: "Psp3ltpFvws",
title: "eevBLAB 100 - Reuters Attacks Odysee - LOL", title: "eevBLAB 100 - Reuters Attacks Odysee - LOL",
length: Some(855), length: Some(855),
@ -599,14 +626,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 22842, view_count: Some(22842),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Reuters attacks Odysee for hosting conspiracy and violent content and gets OWNED, LOL.\nLet\'s actually take look to see if that\'s the case. SPOILER: It\'s not, Odysee is fantastic.\nWatch an an..."),
), ),
ChannelVideo( VideoItem(
id: "taVYTYz5vLE", id: "taVYTYz5vLE",
title: "EEVblog 1495 - Quaze Wireless Power (AGAIN!) but for GAMING!", title: "EEVblog 1495 - Quaze Wireless Power (AGAIN!) but for GAMING!",
length: Some(2592), length: Some(2592),
@ -632,14 +661,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 41621, view_count: Some(41621),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Yes, wireless power is BACK! And this time they are targetting gaming rigs.\nQuaze want to power gaming rigs up to 500W with 15MHz resonant RF wireless desktop power. Let\'s take a look! How..."),
), ),
ChannelVideo( VideoItem(
id: "Y6cZrieFw-k", id: "Y6cZrieFw-k",
title: "EEVblog 1494 - FIVE Ways to Open a CHEAP SAFE!", title: "EEVblog 1494 - FIVE Ways to Open a CHEAP SAFE!",
length: Some(1194), length: Some(1194),
@ -665,14 +696,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 77542, view_count: Some(77542),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("FIVE different easy methods to crack into a cheap Sandleford safe found in the dumpster, WITHOUT using physical force. Including a bonus 6th method that doesn\'t work on this one.\nDon\'t buy..."),
), ),
ChannelVideo( VideoItem(
id: "Kr2XyhpUdUI", id: "Kr2XyhpUdUI",
title: "EEVblog 1493 - MacGyver Project - Part 2", title: "EEVblog 1493 - MacGyver Project - Part 2",
length: Some(1785), length: Some(1785),
@ -698,14 +731,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 34947, view_count: Some(34947),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Powering up the Banshee ultrasonic leak detector LED display to see how the display is multiplexed turned out to be very interesting!\nWith special guest debugger, Sagan, who invents a new industry..."),
), ),
ChannelVideo( VideoItem(
id: "rxGafdgkal8", id: "rxGafdgkal8",
title: "EEVblog 1492 - $5 Oscilloscope Repaired! + Oz GIVEAWAY", title: "EEVblog 1492 - $5 Oscilloscope Repaired! + Oz GIVEAWAY",
length: Some(1163), length: Some(1163),
@ -731,14 +766,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 45618, view_count: Some(45618),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("The $5 Hantek oscilloscope is repaired, and I\'m giving it away to a youngster in Australia.\n\nIf you want the scope, enter here:\nhttps://www.eevblog.com/forum/contests/giveaway-(oz-only)-hantek-osci..."),
), ),
ChannelVideo( VideoItem(
id: "4yosozyeIP4", id: "4yosozyeIP4",
title: "EEVblog 1491 - The MacGyver Project - Part 1", title: "EEVblog 1491 - The MacGyver Project - Part 1",
length: Some(1706), length: Some(1706),
@ -764,14 +801,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 34868, view_count: Some(34868),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Part 1 reverse engineering the interface on the LED display of the Banshee Ultrasonic gas leak detector to make a MacGyver type countdown timer THING (for demonetisation purposes).\nThis will..."),
), ),
ChannelVideo( VideoItem(
id: "06JtC2DC_dQ", id: "06JtC2DC_dQ",
title: "EEVblog 1490 - Insane Jaycar Dumpster Sale! 2022", title: "EEVblog 1490 - Insane Jaycar Dumpster Sale! 2022",
length: Some(1700), length: Some(1700),
@ -797,14 +836,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 64336, view_count: Some(64336),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Insane Jaycar dumpster relocation sale!\n\nSupport the EEVblog on:\nPatreon: http://www.patreon.com/eevblog\nOdysee: https://odysee.com/@eevblog:7\nWeb Site: http://www.eevblog.com\nEEVblog2: http://www...."),
), ),
ChannelVideo( VideoItem(
id: "piquT76w9TI", id: "piquT76w9TI",
title: "EEVblog 1489 - Mystery Teardown!", title: "EEVblog 1489 - Mystery Teardown!",
length: Some(1466), length: Some(1466),
@ -830,14 +871,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 150958, view_count: Some(150958),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Teardown of a bizarre looking Banshee 343 Ultrasonic Gas Leak Detector\n\nThumbs up this video and pinned comment if you want to see a countdown timer refit project!\n\nDatasheet: https://www.instrumar..."),
), ),
ChannelVideo( VideoItem(
id: "pKuUKT-zU-g", id: "pKuUKT-zU-g",
title: "EEVblog 1488 - Tilt Five Augmented Reality AR Glasses - First Reaction!", title: "EEVblog 1488 - Tilt Five Augmented Reality AR Glasses - First Reaction!",
length: Some(2152), length: Some(2152),
@ -863,14 +906,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 30903, view_count: Some(30903),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Dave tries Jeri Ellsworth\'s Tilt Five augmented reality AR glasses for the first time!\nUnboxing, first reaction, and a bit of a first user review.\n\n00:00 - Tilt Five AR Kickstarter Glasses..."),
), ),
ChannelVideo( VideoItem(
id: "_R4wQQNSO6k", id: "_R4wQQNSO6k",
title: "EEVblog 1487 - Do Solar Micro Inverters Take Power at Night?", title: "EEVblog 1487 - Do Solar Micro Inverters Take Power at Night?",
length: Some(2399), length: Some(2399),
@ -896,14 +941,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 48669, view_count: Some(48669),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("How much power do Enphase and other solar micro inverters draw at night time when switched off? It\'s actually a very interesting question involving real and apparent/reactive power, the system..."),
), ),
ChannelVideo( VideoItem(
id: "ikp5BorIo_M", id: "ikp5BorIo_M",
title: "EEVblog 1486 - What you DIDN\'T KNOW About Film Capacitor FAILURES!", title: "EEVblog 1486 - What you DIDN\'T KNOW About Film Capacitor FAILURES!",
length: Some(1792), length: Some(1792),
@ -929,14 +976,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 83505, view_count: Some(83505),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("You might think you know how film capacitors fail and degrade in capacitance over time - self-healing due to surges, right? WRONG!\nCapacitor expert and AVX Fellow Ron Demcko confirms what\'s..."),
), ),
ChannelVideo( VideoItem(
id: "7O-QckjCXNo", id: "7O-QckjCXNo",
title: "eevBLAB 99 - AI SPAM BOT Youtube Space/Science/Tech Channels? - WTF", title: "eevBLAB 99 - AI SPAM BOT Youtube Space/Science/Tech Channels? - WTF",
length: Some(592), length: Some(592),
@ -962,14 +1011,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 42843, view_count: Some(42843),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("WTF are these random mash content spam space/science/tech Youtube channels? Are they auto-generated AI bots?\nThese channels get over 1M views a day!\nhttps://www.youtube.com/channel/UC2jAc3ifBNVT03i..."),
), ),
ChannelVideo( VideoItem(
id: "VutdTxF4E-0", id: "VutdTxF4E-0",
title: "RIP The Old Garage Lab", title: "RIP The Old Garage Lab",
length: Some(115), length: Some(115),
@ -995,14 +1046,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 26036, view_count: Some(26036),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("RIP The old EEVblog garage lab.\nA slightly extended tour of the old lab: https://odysee.com/@eevblog:7/2021-06-11-Old-Lab-Tour:2\nSecret feature of the EEVblog lab bench: https://www.youtube.com/wat..."),
), ),
ChannelVideo( VideoItem(
id: "o7xfGuRaq94", id: "o7xfGuRaq94",
title: "EEVblog 1485 - PedalCell CadenceX Bike Generator LOL FAIL!", title: "EEVblog 1485 - PedalCell CadenceX Bike Generator LOL FAIL!",
length: Some(1026), length: Some(1026),
@ -1028,14 +1081,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 63729, view_count: Some(63729),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("The failed PedalCell CadenceX Bike Generator from the previous mailbag video is tested, torn down, analysed, hilrariously laughed at, and dodgily repaired.\nhttps://pedalcell.com/\n\n00:00 - Failed..."),
), ),
ChannelVideo( VideoItem(
id: "3WSIfHOv3fc", id: "3WSIfHOv3fc",
title: "EEVblog 1484 - Kaba Mas X-09 High Security Electronic Lock Teardown", title: "EEVblog 1484 - Kaba Mas X-09 High Security Electronic Lock Teardown",
length: Some(1106), length: Some(1106),
@ -1061,14 +1116,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 22920, view_count: Some(22920),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Extended version of the Mailbag 1483 teardown of the Kaba Mas X-09 High Security Electronic Lock Teardown\n\nSupport the EEVblog on:\nPatreon: http://www.patreon.com/eevblog\nOdysee: https://odysee.com..."),
), ),
ChannelVideo( VideoItem(
id: "8yXZJZCKImI", id: "8yXZJZCKImI",
title: "EEVblog 1483 - Holy Mailbag Bomb Batman!", title: "EEVblog 1483 - Holy Mailbag Bomb Batman!",
length: Some(3373), length: Some(3373),
@ -1094,14 +1151,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 66042, view_count: Some(66042),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("Bumper Mailbag!\n\nForum: https://www.eevblog.com/forum/blog/eevblog-1483-holy-mailbag-bomb-batman/\n\nSPOILERS:\n00:00 - Contact Harald Covid Bluetooth Tracing \n04:24 - Kaba Mas X09 High Security..."),
), ),
ChannelVideo( VideoItem(
id: "vJ4pW6LKJWU", id: "vJ4pW6LKJWU",
title: "EEVblog 1482 - Mains Capacitor Zener Regulator Circuit", title: "EEVblog 1482 - Mains Capacitor Zener Regulator Circuit",
length: Some(1132), length: Some(1132),
@ -1127,14 +1186,17 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 52065, view_count: Some(52065),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: Some("A follow up to the previous video on repairing the heater.\nA viewer asked how the capacitor diode rectifier gave a 24V output. The key is in the zener regulator, so this vidoe looks at how..."),
), ),
], ],
ctoken: Some("4qmFsgKhARIYVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RGoQBOGdaZ0dsNTZYQXBZQ2pCRlozTkpOV054YjJ4eWNYSnBjeTA0UVZObmVVMUJSVFJJYTBsTVEwbEhjV3cxYjBkRlVHcHlYM2hTU1VGV1FVRVNKRFl6TkRZMVlqZzFMVEF3TURBdE1qTXlOaTA1WTJSbUxUTmpNamcyWkRReU1tWTNOaGdC"), ctoken: Some("4qmFsgKhARIYVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RGoQBOGdaZ0dsNTZYQXBZQ2pCRlozTkpOV054YjJ4eWNYSnBjeTA0UVZObmVVMUJSVFJJYTBsTVEwbEhjV3cxYjBkRlVHcHlYM2hTU1VGV1FVRVNKRFl6TkRZMVlqZzFMVEF3TURBdE1qTXlOaTA1WTJSbUxUTmpNamcyWkRReU1tWTNOaGdC"),
endpoint: browse,
), ),
) )

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: Verified,
description: "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON\'T DO PAID VIDEO SPONSORSHIPS, DON\'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don\'t be offended if I don\'t have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA", description: "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON\'T DO PAID VIDEO SPONSORSHIPS, DON\'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don\'t be offended if I don\'t have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA",
tags: [ tags: [
"electronics", "electronics",
@ -144,7 +145,7 @@ Channel(
content: Paginator( content: Paginator(
count: None, count: None,
items: [ items: [
ChannelVideo( VideoItem(
id: "gremHHvqYTE", id: "gremHHvqYTE",
title: "EEVblog 1501 - Rigol HDO4000 Low Noise 12bit Oscilloscope Unboxing & First Impression", title: "EEVblog 1501 - Rigol HDO4000 Low Noise 12bit Oscilloscope Unboxing & First Impression",
length: Some(1794), length: Some(1794),
@ -170,14 +171,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("20 hours ago"), publish_date_txt: Some("20 hours ago"),
view_count: 19739, view_count: Some(19739),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "WHO8NBfpaO0", id: "WHO8NBfpaO0",
title: "eevBLAB 102 - Last Mile Autonomous Robot Deliveries WILL FAIL", title: "eevBLAB 102 - Last Mile Autonomous Robot Deliveries WILL FAIL",
length: Some(742), length: Some(742),
@ -203,14 +206,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 days ago"), publish_date_txt: Some("5 days ago"),
view_count: 24194, view_count: Some(24194),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "W1Q8CxL95_Y", id: "W1Q8CxL95_Y",
title: "EEVblog 1500 - Automatic Transfer Switch REVERSE ENGINEERED", title: "EEVblog 1500 - Automatic Transfer Switch REVERSE ENGINEERED",
length: Some(1770), length: Some(1770),
@ -236,14 +241,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 days ago"), publish_date_txt: Some("7 days ago"),
view_count: 51443, view_count: Some(51443),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "lagxSrPeoYg", id: "lagxSrPeoYg",
title: "EEVblog 1499 - EcoFlow Delta Pro 3.6kWh Portable Battery TEARDOWN!", title: "EEVblog 1499 - EcoFlow Delta Pro 3.6kWh Portable Battery TEARDOWN!",
length: Some(2334), length: Some(2334),
@ -269,14 +276,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("13 days ago"), publish_date_txt: Some("13 days ago"),
view_count: 72324, view_count: Some(72324),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "qTctWW9_FmE", id: "qTctWW9_FmE",
title: "EEVblog 1498 - TransPod Fluxjet Hyperloop $550M Boondoggle!", title: "EEVblog 1498 - TransPod Fluxjet Hyperloop $550M Boondoggle!",
length: Some(2399), length: Some(2399),
@ -302,14 +311,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 57348, view_count: Some(57348),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "3t9G80wk0pk", id: "3t9G80wk0pk",
title: "eevBLAB 101 - Why Are Tektronix Oscilloscopes So Expensive?", title: "eevBLAB 101 - Why Are Tektronix Oscilloscopes So Expensive?",
length: Some(1423), length: Some(1423),
@ -335,14 +346,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 68645, view_count: Some(68645),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "7dze5CnZnmk", id: "7dze5CnZnmk",
title: "EEVblog 1497 - RIP Fluke. Thanks Energizer. NOT.", title: "EEVblog 1497 - RIP Fluke. Thanks Energizer. NOT.",
length: Some(1168), length: Some(1168),
@ -368,14 +381,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 91388, view_count: Some(91388),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "6XnrZpPYgBg", id: "6XnrZpPYgBg",
title: "EEVblog 1496 - Winning Mailbag", title: "EEVblog 1496 - Winning Mailbag",
length: Some(3139), length: Some(3139),
@ -401,14 +416,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 39993, view_count: Some(39993),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "Psp3ltpFvws", id: "Psp3ltpFvws",
title: "eevBLAB 100 - Reuters Attacks Odysee - LOL", title: "eevBLAB 100 - Reuters Attacks Odysee - LOL",
length: Some(855), length: Some(855),
@ -434,14 +451,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 weeks ago"), publish_date_txt: Some("4 weeks ago"),
view_count: 22512, view_count: Some(22512),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "taVYTYz5vLE", id: "taVYTYz5vLE",
title: "EEVblog 1495 - Quaze Wireless Power (AGAIN!) but for GAMING!", title: "EEVblog 1495 - Quaze Wireless Power (AGAIN!) but for GAMING!",
length: Some(2592), length: Some(2592),
@ -467,14 +486,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 40137, view_count: Some(40137),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "Y6cZrieFw-k", id: "Y6cZrieFw-k",
title: "EEVblog 1494 - FIVE Ways to Open a CHEAP SAFE!", title: "EEVblog 1494 - FIVE Ways to Open a CHEAP SAFE!",
length: Some(1194), length: Some(1194),
@ -500,14 +521,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 74510, view_count: Some(74510),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "Kr2XyhpUdUI", id: "Kr2XyhpUdUI",
title: "EEVblog 1493 - MacGyver Project - Part 2", title: "EEVblog 1493 - MacGyver Project - Part 2",
length: Some(1785), length: Some(1785),
@ -533,14 +556,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 34487, view_count: Some(34487),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "rxGafdgkal8", id: "rxGafdgkal8",
title: "EEVblog 1492 - $5 Oscilloscope Repaired! + Oz GIVEAWAY", title: "EEVblog 1492 - $5 Oscilloscope Repaired! + Oz GIVEAWAY",
length: Some(1163), length: Some(1163),
@ -566,14 +591,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 44928, view_count: Some(44928),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "4yosozyeIP4", id: "4yosozyeIP4",
title: "EEVblog 1491 - The MacGyver Project - Part 1", title: "EEVblog 1491 - The MacGyver Project - Part 1",
length: Some(1706), length: Some(1706),
@ -599,14 +626,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 34324, view_count: Some(34324),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "06JtC2DC_dQ", id: "06JtC2DC_dQ",
title: "EEVblog 1490 - Insane Jaycar Dumpster Sale! 2022", title: "EEVblog 1490 - Insane Jaycar Dumpster Sale! 2022",
length: Some(1700), length: Some(1700),
@ -632,14 +661,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 63763, view_count: Some(63763),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "piquT76w9TI", id: "piquT76w9TI",
title: "EEVblog 1489 - Mystery Teardown!", title: "EEVblog 1489 - Mystery Teardown!",
length: Some(1466), length: Some(1466),
@ -665,14 +696,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 149186, view_count: Some(149186),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "pKuUKT-zU-g", id: "pKuUKT-zU-g",
title: "EEVblog 1488 - Tilt Five Augmented Reality AR Glasses - First Reaction!", title: "EEVblog 1488 - Tilt Five Augmented Reality AR Glasses - First Reaction!",
length: Some(2152), length: Some(2152),
@ -698,14 +731,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 30130, view_count: Some(30130),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "_R4wQQNSO6k", id: "_R4wQQNSO6k",
title: "EEVblog 1487 - Do Solar Micro Inverters Take Power at Night?", title: "EEVblog 1487 - Do Solar Micro Inverters Take Power at Night?",
length: Some(2399), length: Some(2399),
@ -731,14 +766,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 48037, view_count: Some(48037),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "ikp5BorIo_M", id: "ikp5BorIo_M",
title: "EEVblog 1486 - What you DIDN\'T KNOW About Film Capacitor FAILURES!", title: "EEVblog 1486 - What you DIDN\'T KNOW About Film Capacitor FAILURES!",
length: Some(1792), length: Some(1792),
@ -764,14 +801,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 81958, view_count: Some(81958),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "7O-QckjCXNo", id: "7O-QckjCXNo",
title: "eevBLAB 99 - AI SPAM BOT Youtube Space/Science/Tech Channels? - WTF", title: "eevBLAB 99 - AI SPAM BOT Youtube Space/Science/Tech Channels? - WTF",
length: Some(592), length: Some(592),
@ -797,14 +836,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 42635, view_count: Some(42635),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "VutdTxF4E-0", id: "VutdTxF4E-0",
title: "RIP The Old Garage Lab", title: "RIP The Old Garage Lab",
length: Some(115), length: Some(115),
@ -830,14 +871,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 25860, view_count: Some(25860),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "o7xfGuRaq94", id: "o7xfGuRaq94",
title: "EEVblog 1485 - PedalCell CadenceX Bike Generator LOL FAIL!", title: "EEVblog 1485 - PedalCell CadenceX Bike Generator LOL FAIL!",
length: Some(1026), length: Some(1026),
@ -863,14 +906,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 63035, view_count: Some(63035),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "3WSIfHOv3fc", id: "3WSIfHOv3fc",
title: "EEVblog 1484 - Kaba Mas X-09 High Security Electronic Lock Teardown", title: "EEVblog 1484 - Kaba Mas X-09 High Security Electronic Lock Teardown",
length: Some(1106), length: Some(1106),
@ -896,14 +941,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 22731, view_count: Some(22731),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "8yXZJZCKImI", id: "8yXZJZCKImI",
title: "EEVblog 1483 - Holy Mailbag Bomb Batman!", title: "EEVblog 1483 - Holy Mailbag Bomb Batman!",
length: Some(3373), length: Some(3373),
@ -929,14 +976,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 65765, view_count: Some(65765),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "vJ4pW6LKJWU", id: "vJ4pW6LKJWU",
title: "EEVblog 1482 - Mains Capacitor Zener Regulator Circuit", title: "EEVblog 1482 - Mains Capacitor Zener Regulator Circuit",
length: Some(1132), length: Some(1132),
@ -962,14 +1011,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 51555, view_count: Some(51555),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "myqiqUE00fo", id: "myqiqUE00fo",
title: "EEVblog 1481 - Dodgy Dangerous Heater REPAIR", title: "EEVblog 1481 - Dodgy Dangerous Heater REPAIR",
length: Some(1622), length: Some(1622),
@ -995,14 +1046,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 46638, view_count: Some(46638),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "xIokNnjuam8", id: "xIokNnjuam8",
title: "EEVblog 1480 - Lightyear Zero Solar Powered Electric Car", title: "EEVblog 1480 - Lightyear Zero Solar Powered Electric Car",
length: Some(1196), length: Some(1196),
@ -1028,14 +1081,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 62921, view_count: Some(62921),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "S3R4r2xvVYQ", id: "S3R4r2xvVYQ",
title: "EEVblog 1479 - Is Your Calculator WRONG?", title: "EEVblog 1479 - Is Your Calculator WRONG?",
length: Some(1066), length: Some(1066),
@ -1061,14 +1116,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 66895, view_count: Some(66895),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "RlwcdUnRw6w", id: "RlwcdUnRw6w",
title: "EEVblog 1478 - Waveform Update Rate Shootout - Tek 2 Series vs Others", title: "EEVblog 1478 - Waveform Update Rate Shootout - Tek 2 Series vs Others",
length: Some(1348), length: Some(1348),
@ -1094,14 +1151,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 25894, view_count: Some(25894),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "R2fw2g6WFbg", id: "R2fw2g6WFbg",
title: "EEVblog 1477 - TEARDOWN! - NEW Tektronix 2 Series Oscilloscope", title: "EEVblog 1477 - TEARDOWN! - NEW Tektronix 2 Series Oscilloscope",
length: Some(2718), length: Some(2718),
@ -1127,14 +1186,17 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 80173, view_count: Some(80173),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("4qmFsgKrARIYVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RGmBFZ1oyYVdSbGIzTVlBeUFBTUFFNEFlb0RNRVZuYjBsMVMzWlpPVXREWWw5TVRraExSRWwzUVZSblpWRm5kMGx3ZFVOMGJWRlpVVjlOUjA1d2QwcEpRVlpCUVElM0QlM0SaAixicm93c2UtZmVlZFVDMkRqRkU3WGYxMVVSWnFXQmlnY1ZPUXZpZGVvczEwMg%3D%3D"), ctoken: Some("4qmFsgKrARIYVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RGmBFZ1oyYVdSbGIzTVlBeUFBTUFFNEFlb0RNRVZuYjBsMVMzWlpPVXREWWw5TVRraExSRWwzUVZSblpWRm5kMGx3ZFVOMGJWRlpVVjlOUjA1d2QwcEpRVlpCUVElM0QlM0SaAixicm93c2UtZmVlZFVDMkRqRkU3WGYxMVVSWnFXQmlnY1ZPUXZpZGVvczEwMg%3D%3D"),
endpoint: browse,
), ),
) )

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: None,
description: "", description: "",
tags: [], tags: [],
vanity_url: None, vanity_url: None,
@ -33,5 +34,6 @@ Channel(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
) )

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: Verified,
description: "Welcome to The Good Life by Sensual Musique.\nThe second official channel of Sensual Musique. You can find a lot of music, live streams and some other things on this channel. Stay tuned :)\n\nSubmit your music here: submit.sensualmusiquenetwork@gmail.com", description: "Welcome to The Good Life by Sensual Musique.\nThe second official channel of Sensual Musique. You can find a lot of music, live streams and some other things on this channel. Stay tuned :)\n\nSubmit your music here: submit.sensualmusiquenetwork@gmail.com",
tags: [ tags: [
"live radio", "live radio",
@ -128,7 +129,7 @@ Channel(
content: Paginator( content: Paginator(
count: Some(21), count: Some(21),
items: [ items: [
ChannelVideo( VideoItem(
id: "csP93FGy0bs", id: "csP93FGy0bs",
title: "Chill Out Music Mix • 24/7 Live Radio | Relaxing Deep House, Chillout Lounge, Vocal & Instrumental", title: "Chill Out Music Mix • 24/7 Live Radio | Relaxing Deep House, Chillout Lounge, Vocal & Instrumental",
length: None, length: None,
@ -154,14 +155,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 94, view_count: Some(94),
is_live: true, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "19hKXI1ENrY", id: "19hKXI1ENrY",
title: "Deep House Radio | Relaxing & Chill House, Best Summer Mix 2022, Gym & Workout Music", title: "Deep House Radio | Relaxing & Chill House, Best Summer Mix 2022, Gym & Workout Music",
length: None, length: None,
@ -187,14 +190,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 381, view_count: Some(381),
is_live: true, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "CqMUC5eXX7c", id: "CqMUC5eXX7c",
title: "Back To School / Work 📚 Deep Focus Chillout Mix | The Good Life Radio #4", title: "Back To School / Work 📚 Deep Focus Chillout Mix | The Good Life Radio #4",
length: Some(4667), length: Some(4667),
@ -220,14 +225,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 241528, view_count: Some(241528),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "A77SYlXKQEM", id: "A77SYlXKQEM",
title: "Chillout Lounge 🏖\u{fe0f} Calm & Relaxing Background Music | The Good Life Radio #3", title: "Chillout Lounge 🏖\u{fe0f} Calm & Relaxing Background Music | The Good Life Radio #3",
length: Some(1861), length: Some(1861),
@ -253,14 +260,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 118351, view_count: Some(118351),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "72vkRHQfjbk", id: "72vkRHQfjbk",
title: "Summer Lovers 💖 A Beautiful & Relaxing Chillout Deep House Mix | The Good Life Radio #2", title: "Summer Lovers 💖 A Beautiful & Relaxing Chillout Deep House Mix | The Good Life Radio #2",
length: Some(1832), length: Some(1832),
@ -286,14 +295,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 157971, view_count: Some(157971),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "AMWMDhibROw", id: "AMWMDhibROw",
title: "Relaxing & Chill House 🌴 Summer \'21 Chill-Out Mix | The Good Life Radio #1", title: "Relaxing & Chill House 🌴 Summer \'21 Chill-Out Mix | The Good Life Radio #1",
length: Some(1949), length: Some(1949),
@ -319,14 +330,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 82309, view_count: Some(82309),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "9UMxZofMNbA", id: "9UMxZofMNbA",
title: "Chillout Lounge - Calm & Relaxing Background Music | Study, Work, Sleep, Meditation, Chill", title: "Chillout Lounge - Calm & Relaxing Background Music | Study, Work, Sleep, Meditation, Chill",
length: None, length: None,
@ -352,14 +365,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 2043, view_count: Some(2043),
is_live: true, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "a2sEYVwBvX4", id: "a2sEYVwBvX4",
title: "Paratone - Heaven Is A Place On Earth (feat. kaii)", title: "Paratone - Heaven Is A Place On Earth (feat. kaii)",
length: Some(161), length: Some(161),
@ -385,14 +400,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 186475, view_count: Some(186475),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "JAY-prtJnGY", id: "JAY-prtJnGY",
title: "Joseph Feinstein - Where I Belong", title: "Joseph Feinstein - Where I Belong",
length: Some(126), length: Some(126),
@ -418,14 +435,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 66425, view_count: Some(66425),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "DySa8OrQDi4", id: "DySa8OrQDi4",
title: "LA Vision & Gigi D\'Agostino - Hollywood", title: "LA Vision & Gigi D\'Agostino - Hollywood",
length: Some(200), length: Some(200),
@ -451,14 +470,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 1520020, view_count: Some(1520020),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "NqzXULaB8MA", id: "NqzXULaB8MA",
title: "LO - Home", title: "LO - Home",
length: Some(163), length: Some(163),
@ -484,14 +505,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 37549, view_count: Some(37549),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "UGzy6uhZkmw", id: "UGzy6uhZkmw",
title: "Luca - Sunset", title: "Luca - Sunset",
length: Some(153), length: Some(153),
@ -517,14 +540,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 33002, view_count: Some(33002),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "iuvapHKpW8A", id: "iuvapHKpW8A",
title: "nourii - Better Off (feat. BCS)", title: "nourii - Better Off (feat. BCS)",
length: Some(126), length: Some(126),
@ -550,14 +575,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 42036, view_count: Some(42036),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "n_1Nwht-Gh4", id: "n_1Nwht-Gh4",
title: "Deep House Covers & Remixes of Popular Songs 2020 🌴 Deep House, G-House, Chill-Out Music Playlist", title: "Deep House Covers & Remixes of Popular Songs 2020 🌴 Deep House, G-House, Chill-Out Music Playlist",
length: Some(2940), length: Some(2940),
@ -583,14 +610,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 322935, view_count: Some(322935),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "6TptI5BtP5U", id: "6TptI5BtP5U",
title: "The Good Life Radio Mix #2 | Summer Memories ☀\u{fe0f} (Chill Music Playlist 2020)", title: "The Good Life Radio Mix #2 | Summer Memories ☀\u{fe0f} (Chill Music Playlist 2020)",
length: Some(3448), length: Some(3448),
@ -616,14 +645,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 91980, view_count: Some(91980),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "36YnV9STBqc", id: "36YnV9STBqc",
title: "The Good Life Radio\u{a0}•\u{a0}24/7 Live Radio | Best Relax House, Chillout, Study, Running, Gym, Happy Music", title: "The Good Life Radio\u{a0}•\u{a0}24/7 Live Radio | Best Relax House, Chillout, Study, Running, Gym, Happy Music",
length: None, length: None,
@ -649,14 +680,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 4030, view_count: Some(4030),
is_live: true, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "7x6ii2TcsPE", id: "7x6ii2TcsPE",
title: "The Good Life Radio Mix #1 | Relaxing & Chill House Music Playlist 2020", title: "The Good Life Radio Mix #1 | Relaxing & Chill House Music Playlist 2020",
length: Some(2726), length: Some(2726),
@ -682,14 +715,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 288098, view_count: Some(288098),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "mxV5MBZYYDE", id: "mxV5MBZYYDE",
title: "Christmas Music with Vocals 🎅 Best Relaxing Christmas Songs 2020", title: "Christmas Music with Vocals 🎅 Best Relaxing Christmas Songs 2020",
length: Some(5863), length: Some(5863),
@ -715,14 +750,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 50818, view_count: Some(50818),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "hh2AOoPoAIo", id: "hh2AOoPoAIo",
title: "The Good Life Radio Mix 2019 🎅 Winter & Christmas Relax House Playlist [Best of Part 1]", title: "The Good Life Radio Mix 2019 🎅 Winter & Christmas Relax House Playlist [Best of Part 1]",
length: Some(2530), length: Some(2530),
@ -748,14 +785,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 98431, view_count: Some(98431),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "aFlvhtWsJ0g", id: "aFlvhtWsJ0g",
title: "Chillout Playlist | Relaxing Summer Music Mix 2019 [Deep & Tropical House]", title: "Chillout Playlist | Relaxing Summer Music Mix 2019 [Deep & Tropical House]",
length: Some(2483), length: Some(2483),
@ -781,14 +820,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 572456, view_count: Some(572456),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "cD-d7u6fnEI", id: "cD-d7u6fnEI",
title: "Chill House Playlist | Relaxing Summer Music 2019", title: "Chill House Playlist | Relaxing Summer Music 2019",
length: Some(3165), length: Some(3165),
@ -814,14 +855,17 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 3114909, view_count: Some(3114909),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
) )

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: None,
description: "", description: "",
tags: [], tags: [],
vanity_url: None, vanity_url: None,
@ -116,5 +117,6 @@ Channel(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
) )

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: Verified,
description: "Hi, Im Tina, aka Doobydobap!\n\nFood is the medium I use to tell stories and connect with people who share the same passion as I do. Whether its because youre hungry at midnight or trying to learn how to cook, I hope you enjoy watching my content and recipes. Don\'t yuck my yum!\n\nwww.doobydobap.com\n", description: "Hi, Im Tina, aka Doobydobap!\n\nFood is the medium I use to tell stories and connect with people who share the same passion as I do. Whether its because youre hungry at midnight or trying to learn how to cook, I hope you enjoy watching my content and recipes. Don\'t yuck my yum!\n\nwww.doobydobap.com\n",
tags: [], tags: [],
vanity_url: Some("https://www.youtube.com/c/Doobydobap"), vanity_url: Some("https://www.youtube.com/c/Doobydobap"),
@ -115,7 +116,7 @@ Channel(
content: Paginator( content: Paginator(
count: None, count: None,
items: [ items: [
ChannelVideo( VideoItem(
id: "JBUZE0mIlg8", id: "JBUZE0mIlg8",
title: "small but sure joy", title: "small but sure joy",
length: None, length: None,
@ -126,14 +127,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 day ago"), publish_date_txt: Some("1 day ago"),
view_count: 443549, view_count: Some(443549),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "SRrvxFc2b2c", id: "SRrvxFc2b2c",
title: "i don\'t believe in long distance relationships", title: "i don\'t believe in long distance relationships",
length: None, length: None,
@ -144,14 +147,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 days ago"), publish_date_txt: Some("2 days ago"),
view_count: 1154962, view_count: Some(1154962),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "l9TiwunjzgA", id: "l9TiwunjzgA",
title: "long distance", title: "long distance",
length: Some(1043), length: Some(1043),
@ -177,14 +182,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 days ago"), publish_date_txt: Some("3 days ago"),
view_count: 477460, view_count: Some(477460),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "cNx0ql9gnf4", id: "cNx0ql9gnf4",
title: "come over :)", title: "come over :)",
length: None, length: None,
@ -195,14 +202,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 days ago"), publish_date_txt: Some("6 days ago"),
view_count: 1388173, view_count: Some(1388173),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "fGQUWI4o__A", id: "fGQUWI4o__A",
title: "Baskin Robbins in South Korea", title: "Baskin Robbins in South Korea",
length: None, length: None,
@ -213,14 +222,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 days ago"), publish_date_txt: Some("7 days ago"),
view_count: 1738301, view_count: Some(1738301),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "Q73VTjdqVA8", id: "Q73VTjdqVA8",
title: "dry hot pot", title: "dry hot pot",
length: None, length: None,
@ -231,14 +242,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("9 days ago"), publish_date_txt: Some("9 days ago"),
view_count: 1316594, view_count: Some(1316594),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "pRVSdUxdsVw", id: "pRVSdUxdsVw",
title: "Repairing...", title: "Repairing...",
length: Some(965), length: Some(965),
@ -264,14 +277,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("10 days ago"), publish_date_txt: Some("10 days ago"),
view_count: 478703, view_count: Some(478703),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "gTG2WDbiYGo", id: "gTG2WDbiYGo",
title: "time machine", title: "time machine",
length: None, length: None,
@ -282,14 +297,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 days ago"), publish_date_txt: Some("11 days ago"),
view_count: 1412213, view_count: Some(1412213),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "y5JK5YFp92g", id: "y5JK5YFp92g",
title: "tiramissu", title: "tiramissu",
length: None, length: None,
@ -300,14 +317,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("13 days ago"), publish_date_txt: Some("13 days ago"),
view_count: 1513305, view_count: Some(1513305),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "pvSWHm4wlxY", id: "pvSWHm4wlxY",
title: "having kids", title: "having kids",
length: None, length: None,
@ -318,14 +337,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 8936223, view_count: Some(8936223),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "2FJVhdOO0F0", id: "2FJVhdOO0F0",
title: "a health scare", title: "a health scare",
length: Some(1238), length: Some(1238),
@ -351,14 +372,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 987083, view_count: Some(987083),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "CqFGACRrWJE", id: "CqFGACRrWJE",
title: "just do it", title: "just do it",
length: None, length: None,
@ -369,14 +392,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 2769717, view_count: Some(2769717),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "CutR_1SDDzY", id: "CutR_1SDDzY",
title: "feels good to be back", title: "feels good to be back",
length: Some(1159), length: Some(1159),
@ -402,14 +427,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 497660, view_count: Some(497660),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "DdGr6t2NqKc", id: "DdGr6t2NqKc",
title: "coming soon", title: "coming soon",
length: None, length: None,
@ -420,14 +447,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 572107, view_count: Some(572107),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "jKS44NMWuXw", id: "jKS44NMWuXw",
title: "adult money", title: "adult money",
length: None, length: None,
@ -438,14 +467,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 1707132, view_count: Some(1707132),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "kx1YtJM_vbI", id: "kx1YtJM_vbI",
title: "a fig\'s journey", title: "a fig\'s journey",
length: None, length: None,
@ -456,14 +487,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 933094, view_count: Some(933094),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "Sdbzs-1WWH0", id: "Sdbzs-1WWH0",
title: "How to.. Mozzarella 🧀", title: "How to.. Mozzarella 🧀",
length: None, length: None,
@ -474,14 +507,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 5985184, view_count: Some(5985184),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "9qBHyJIDous", id: "9qBHyJIDous",
title: "how to drink like a real korean", title: "how to drink like a real korean",
length: None, length: None,
@ -492,14 +527,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 14741387, view_count: Some(14741387),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "mBeFDb4gp8s", id: "mBeFDb4gp8s",
title: "mr. krabs soup", title: "mr. krabs soup",
length: None, length: None,
@ -510,14 +547,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 2511322, view_count: Some(2511322),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "b38r1UYqoBQ", id: "b38r1UYqoBQ",
title: "in five years", title: "in five years",
length: None, length: None,
@ -528,14 +567,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 2364408, view_count: Some(2364408),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "KUz7oArksR4", id: "KUz7oArksR4",
title: "running away", title: "running away",
length: Some(1023), length: Some(1023),
@ -561,14 +602,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 706059, view_count: Some(706059),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "RdFk4WaifEo", id: "RdFk4WaifEo",
title: "a weeknight dinner", title: "a weeknight dinner",
length: None, length: None,
@ -579,14 +622,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 1947627, view_count: Some(1947627),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "GuyGyzZcumI", id: "GuyGyzZcumI",
title: "McDonald\'s Michelin Burger", title: "McDonald\'s Michelin Burger",
length: None, length: None,
@ -597,14 +642,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 4763839, view_count: Some(4763839),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "07Zipsb3-qU", id: "07Zipsb3-qU",
title: "cwispy potato pancake", title: "cwispy potato pancake",
length: None, length: None,
@ -615,14 +662,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 1915695, view_count: Some(1915695),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "3kaePnU6Clo", id: "3kaePnU6Clo",
title: "authenticity is overrated", title: "authenticity is overrated",
length: None, length: None,
@ -633,14 +682,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 7268944, view_count: Some(7268944),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "rt4rXMftnpg", id: "rt4rXMftnpg",
title: "you can kimchi anything (T&C applies)", title: "you can kimchi anything (T&C applies)",
length: None, length: None,
@ -651,14 +702,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 2539103, view_count: Some(2539103),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "DTyLUvbf128", id: "DTyLUvbf128",
title: "egg, soy, and perfect pot rice", title: "egg, soy, and perfect pot rice",
length: None, length: None,
@ -669,14 +722,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 5545680, view_count: Some(5545680),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "DzjLBgIe_aI", id: "DzjLBgIe_aI",
title: "love language", title: "love language",
length: None, length: None,
@ -687,14 +742,16 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 2202314, view_count: Some(2202314),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "sPb2gyN-hnE", id: "sPb2gyN-hnE",
title: "worth fighting for", title: "worth fighting for",
length: Some(1232), length: Some(1232),
@ -720,14 +777,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 613416, view_count: Some(613416),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "9JboRKeJ2m4", id: "9JboRKeJ2m4",
title: "Rating Italian McDonald\'s", title: "Rating Italian McDonald\'s",
length: None, length: None,
@ -738,14 +797,17 @@ Channel(
height: 720, height: 720,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 6443699, view_count: Some(6443699),
is_live: false, is_live: false,
is_short: true, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("4qmFsgKrARIYVUNoOGdIZHR6TzJ0WGQ1OTNfYmpFcldnGmBFZ1oyYVdSbGIzTVlBeUFBTUFFNEFlb0RNRVZuYzBrM2NsTnVkazF4U1hWemRqQkJVMmQ1VFVGRk5FaHJTVXhEVUhac2NscHJSMFZKWVhWd016RkpRVlpCUVElM0QlM0SaAixicm93c2UtZmVlZFVDaDhnSGR0ek8ydFhkNTkzX2JqRXJXZ3ZpZGVvczEwMg%3D%3D"), ctoken: Some("4qmFsgKrARIYVUNoOGdIZHR6TzJ0WGQ1OTNfYmpFcldnGmBFZ1oyYVdSbGIzTVlBeUFBTUFFNEFlb0RNRVZuYzBrM2NsTnVkazF4U1hWemRqQkJVMmQ1VFVGRk5FaHJTVXhEVUhac2NscHJSMFZKWVhWd016RkpRVlpCUVElM0QlM0SaAixicm93c2UtZmVlZFVDaDhnSGR0ek8ydFhkNTkzX2JqRXJXZ3ZpZGVvczEwMg%3D%3D"),
endpoint: browse,
), ),
) )

View file

@ -23,6 +23,7 @@ Channel(
height: 176, height: 176,
), ),
], ],
verification: Verified,
description: "BRAND NEW SECOND CHANNEL: https://youtube.com/channel/UCcsQYra-bISsFxNqnd6Javw\n\nJoin my Discord: https://discord.gg/2YcarWsc8S\n", description: "BRAND NEW SECOND CHANNEL: https://youtube.com/channel/UCcsQYra-bISsFxNqnd6Javw\n\nJoin my Discord: https://discord.gg/2YcarWsc8S\n",
tags: [ tags: [
"politics", "politics",
@ -132,7 +133,7 @@ Channel(
content: Paginator( content: Paginator(
count: None, count: None,
items: [ items: [
ChannelVideo( VideoItem(
id: "B-KjpyR4n5Q", id: "B-KjpyR4n5Q",
title: "The Online Manosphere", title: "The Online Manosphere",
length: None, length: None,
@ -158,14 +159,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: Some("2022-09-27T18:00:00+02:00"), publish_date: Some("2022-09-27T18:00:00+02:00"),
publish_date_txt: None, publish_date_txt: None,
view_count: 237, view_count: Some(237),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: true, is_upcoming: true,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "umDsCyZ67J0", id: "umDsCyZ67J0",
title: "Ukraine - The Beginning of the End", title: "Ukraine - The Beginning of the End",
length: Some(614), length: Some(614),
@ -191,14 +194,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("13 days ago"), publish_date_txt: Some("13 days ago"),
view_count: 742284, view_count: Some(742284),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "dNgKGL8lQck", id: "dNgKGL8lQck",
title: "Honest Russian Military Recruitment Video", title: "Honest Russian Military Recruitment Video",
length: Some(62), length: Some(62),
@ -224,14 +229,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 420368, view_count: Some(420368),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "UVWciFJeFNA", id: "UVWciFJeFNA",
title: "Self-Driving Cars Will Only Make Traffic Worse", title: "Self-Driving Cars Will Only Make Traffic Worse",
length: Some(458), length: Some(458),
@ -257,14 +264,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 528718, view_count: Some(528718),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "vyWaax07_ks", id: "vyWaax07_ks",
title: "NEOM Is The Parody Of The Future", title: "NEOM Is The Parody Of The Future",
length: Some(636), length: Some(636),
@ -290,14 +299,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 897237, view_count: Some(897237),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "onQ0ICkLEJw", id: "onQ0ICkLEJw",
title: "I Got An Email From \"The Dubai Sheikh\'s Personal Friend\"", title: "I Got An Email From \"The Dubai Sheikh\'s Personal Friend\"",
length: Some(211), length: Some(211),
@ -323,14 +334,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 526638, view_count: Some(526638),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "yDEL1pTYOhs", id: "yDEL1pTYOhs",
title: "The \"Meritocracy\" Isn\'t Real", title: "The \"Meritocracy\" Isn\'t Real",
length: Some(385), length: Some(385),
@ -356,14 +369,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 368801, view_count: Some(368801),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "EnVvlhhqWtw", id: "EnVvlhhqWtw",
title: "City Review - Prague: Beautiful and Disappointing", title: "City Review - Prague: Beautiful and Disappointing",
length: Some(834), length: Some(834),
@ -389,14 +404,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 286737, view_count: Some(286737),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "Oxz4oY0T85Y", id: "Oxz4oY0T85Y",
title: "European International Rail SUCKS, Here\'s Why", title: "European International Rail SUCKS, Here\'s Why",
length: Some(810), length: Some(810),
@ -422,14 +439,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 664499, view_count: Some(664499),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "lxUEuOkblws", id: "lxUEuOkblws",
title: "Why the Straddling Bus Failed", title: "Why the Straddling Bus Failed",
length: Some(614), length: Some(614),
@ -455,14 +474,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 592227, view_count: Some(592227),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "UG8jiKOtedk", id: "UG8jiKOtedk",
title: "How Canadian Ukrainian Volunteer Got Exposed", title: "How Canadian Ukrainian Volunteer Got Exposed",
length: Some(538), length: Some(538),
@ -488,14 +509,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 396946, view_count: Some(396946),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "bQld7iJJSyk", id: "bQld7iJJSyk",
title: "Why Roads ALWAYS Fill Up, No Matter How Much We Widen Them", title: "Why Roads ALWAYS Fill Up, No Matter How Much We Widen Them",
length: Some(159), length: Some(159),
@ -521,14 +544,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 778430, view_count: Some(778430),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "WUK0K5mdQ_s", id: "WUK0K5mdQ_s",
title: "Egypt\'s New Capital is an Ozymandian Nightmare", title: "Egypt\'s New Capital is an Ozymandian Nightmare",
length: Some(870), length: Some(870),
@ -554,14 +579,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 2118499, view_count: Some(2118499),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "LB-vsT1Sl68", id: "LB-vsT1Sl68",
title: "Why Car-Centric Cities are a GREAT Idea", title: "Why Car-Centric Cities are a GREAT Idea",
length: Some(369), length: Some(369),
@ -587,14 +614,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 525824, view_count: Some(525824),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "p8NiM_p8n5A", id: "p8NiM_p8n5A",
title: "HE FIXED TRAFFIC", title: "HE FIXED TRAFFIC",
length: Some(157), length: Some(157),
@ -620,14 +649,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 1097056, view_count: Some(1097056),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "U9YdnzOf4NQ", id: "U9YdnzOf4NQ",
title: "Why a Mars Colony is a Stupid and Dangerous Idea", title: "Why a Mars Colony is a Stupid and Dangerous Idea",
length: Some(1000), length: Some(1000),
@ -653,14 +684,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 1532114, view_count: Some(1532114),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "CH55WpJxF1s", id: "CH55WpJxF1s",
title: "What #Elongate Is Really About", title: "What #Elongate Is Really About",
length: Some(122), length: Some(122),
@ -686,14 +719,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 511601, view_count: Some(511601),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "PPcsZwUv350", id: "PPcsZwUv350",
title: "Vladimir Putin\'s Three Choices", title: "Vladimir Putin\'s Three Choices",
length: Some(505), length: Some(505),
@ -719,14 +754,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 662099, view_count: Some(662099),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "B78-FgNqdc8", id: "B78-FgNqdc8",
title: "Was I WRONG About Electric Buses?", title: "Was I WRONG About Electric Buses?",
length: Some(1536), length: Some(1536),
@ -752,14 +789,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 549826, view_count: Some(549826),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "JCXLwOMSDxk", id: "JCXLwOMSDxk",
title: "If We Treated Afghanistan Like Ukraine", title: "If We Treated Afghanistan Like Ukraine",
length: Some(92), length: Some(92),
@ -785,14 +824,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 538197, view_count: Some(538197),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "IpIWswLYAbA", id: "IpIWswLYAbA",
title: "Who\'s Winning the War for Ukraine?", title: "Who\'s Winning the War for Ukraine?",
length: Some(646), length: Some(646),
@ -818,14 +859,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 months ago"), publish_date_txt: Some("5 months ago"),
view_count: 536648, view_count: Some(536648),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "NIItoD1Ebh0", id: "NIItoD1Ebh0",
title: "Old Habits Die Hard", title: "Old Habits Die Hard",
length: Some(107), length: Some(107),
@ -851,14 +894,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 months ago"), publish_date_txt: Some("5 months ago"),
view_count: 724630, view_count: Some(724630),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "pENUV9DLa2g", id: "pENUV9DLa2g",
title: "Anarcho-Capitalism In Practice III - The Final Attempt", title: "Anarcho-Capitalism In Practice III - The Final Attempt",
length: Some(600), length: Some(600),
@ -884,14 +929,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 months ago"), publish_date_txt: Some("5 months ago"),
view_count: 426960, view_count: Some(426960),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "gFGQI8P9BMg", id: "gFGQI8P9BMg",
title: "How The Gravel Institute Lies To You About Ukraine", title: "How The Gravel Institute Lies To You About Ukraine",
length: Some(2472), length: Some(2472),
@ -917,14 +964,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 735941, view_count: Some(735941),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "AVLevneWvaE", id: "AVLevneWvaE",
title: "Why Russia Can\'t Achieve Air Supremacy In Ukraine", title: "Why Russia Can\'t Achieve Air Supremacy In Ukraine",
length: Some(188), length: Some(188),
@ -950,14 +999,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 502205, view_count: Some(502205),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "MfRcY90OccY", id: "MfRcY90OccY",
title: "Can Ukraine Actually WIN This?", title: "Can Ukraine Actually WIN This?",
length: Some(606), length: Some(606),
@ -983,14 +1034,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 718668, view_count: Some(718668),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "dQXwreYzJ40", id: "dQXwreYzJ40",
title: "Here\'s What Will Happen To Ukraine [Update: yep, called it]", title: "Here\'s What Will Happen To Ukraine [Update: yep, called it]",
length: Some(397), length: Some(397),
@ -1016,14 +1069,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 775830, view_count: Some(775830),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "-OO3RiNMDB8", id: "-OO3RiNMDB8",
title: "Assessing The Russian Invasion Threat", title: "Assessing The Russian Invasion Threat",
length: Some(655), length: Some(655),
@ -1049,14 +1104,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 480357, view_count: Some(480357),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "obMTYs30E9A", id: "obMTYs30E9A",
title: "Ukraine - The Country That Defied Vladimir Putin", title: "Ukraine - The Country That Defied Vladimir Putin",
length: Some(2498), length: Some(2498),
@ -1082,14 +1139,16 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 460878, view_count: Some(460878),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
ChannelVideo( VideoItem(
id: "4-2bR1iFlhk", id: "4-2bR1iFlhk",
title: "\"Wait, Russia isn\'t in NATO?!\" Insane Debate on Ukraine, US Politics, and more!", title: "\"Wait, Russia isn\'t in NATO?!\" Insane Debate on Ukraine, US Politics, and more!",
length: Some(12151), length: Some(12151),
@ -1115,14 +1174,17 @@ Channel(
height: 188, height: 188,
), ),
], ],
channel: None,
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 228151, view_count: Some(228151),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false, is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("4qmFsgKnARIYVUNjdmZIYS1HSFNPSEZBalUwLUllNTdBGlxFZ1oyYVdSbGIzTVlBeUFBTUFFNEFlb0RNa1ZuYzBsdFlYbFhlRkJZYnpWMlltcEJVMmQ1VFVGRk5FaHJTVTFEVFdGVWVrcHJSMFZPUzJzMmNqQkNVMEZHVVVGQpoCLGJyb3dzZS1mZWVkVUNjdmZIYS1HSFNPSEZBalUwLUllNTdBdmlkZW9zMTAy"), ctoken: Some("4qmFsgKnARIYVUNjdmZIYS1HSFNPSEZBalUwLUllNTdBGlxFZ1oyYVdSbGIzTVlBeUFBTUFFNEFlb0RNa1ZuYzBsdFlYbFhlRkJZYnpWMlltcEJVMmQ1VFVGRk5FaHJTVTFEVFdGVWVrcHJSMFZPUzJzMmNqQkNVMEZHVVVGQpoCLGJyb3dzZS1mZWVkVUNjdmZIYS1HSFNPSEZBalUwLUllNTdBdmlkZW9zMTAy"),
endpoint: browse,
), ),
) )

View file

@ -1,11 +1,11 @@
--- ---
source: src/client/channel.rs source: src/client/pagination.rs
expression: map_res.c expression: map_res.c
--- ---
Paginator( Paginator(
count: None, count: None,
items: [ items: [
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHutdg1kZkG7aAYhjoJnk2fc", id: "PLvOlSehNtuHutdg1kZkG7aAYhjoJnk2fc",
name: "Nixie Tube Display Project", name: "Nixie Tube Display Project",
thumbnail: [ thumbnail: [
@ -15,9 +15,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(9), video_count: Some(9),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHujYmL_-5CBUg-za2osSUVI", id: "PLvOlSehNtuHujYmL_-5CBUg-za2osSUVI",
name: "Mystery Teardown", name: "Mystery Teardown",
thumbnail: [ thumbnail: [
@ -27,9 +28,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(16), video_count: Some(16),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHuGQmy-eJgqB28b2AWKteuG", id: "PLvOlSehNtuHuGQmy-eJgqB28b2AWKteuG",
name: "EEVsmoke", name: "EEVsmoke",
thumbnail: [ thumbnail: [
@ -39,9 +41,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(2), video_count: Some(2),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHuSab0CmpulB2Wv8Kz0985m", id: "PLvOlSehNtuHuSab0CmpulB2Wv8Kz0985m",
name: "EEVcomments", name: "EEVcomments",
thumbnail: [ thumbnail: [
@ -51,9 +54,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(1), video_count: Some(1),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvtQ5FxEivbCGxp4t3W8zKE", id: "PLvOlSehNtuHvtQ5FxEivbCGxp4t3W8zKE",
name: "Spectrum Analyser", name: "Spectrum Analyser",
thumbnail: [ thumbnail: [
@ -63,9 +67,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(11), video_count: Some(11),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHuJUxiTbVKHzWjvIVf1NVOl", id: "PLvOlSehNtuHuJUxiTbVKHzWjvIVf1NVOl",
name: "Space", name: "Space",
thumbnail: [ thumbnail: [
@ -75,9 +80,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(5), video_count: Some(5),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtTXTVCXVDIRKV442ynD7Pz", id: "PLvOlSehNtuHtTXTVCXVDIRKV442ynD7Pz",
name: "Lunar Rover", name: "Lunar Rover",
thumbnail: [ thumbnail: [
@ -87,9 +93,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(1), video_count: Some(1),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHsma5qL7piUiM5N4IOyuQyx", id: "PLvOlSehNtuHsma5qL7piUiM5N4IOyuQyx",
name: "Wayback Wednesday", name: "Wayback Wednesday",
thumbnail: [ thumbnail: [
@ -99,9 +106,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(1), video_count: Some(1),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvLb_HJBKqbgZ9IvEX-pVOF", id: "PLvOlSehNtuHvLb_HJBKqbgZ9IvEX-pVOF",
name: "Magazines", name: "Magazines",
thumbnail: [ thumbnail: [
@ -111,9 +119,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(4), video_count: Some(4),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHugE85Y_LckT4EhrKwo7WQe", id: "PLvOlSehNtuHugE85Y_LckT4EhrKwo7WQe",
name: "Embedded Computing", name: "Embedded Computing",
thumbnail: [ thumbnail: [
@ -123,9 +132,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(4), video_count: Some(4),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHu3GsTHwHoAXlWVcL3c3dA0", id: "PLvOlSehNtuHu3GsTHwHoAXlWVcL3c3dA0",
name: "High Speed Camera", name: "High Speed Camera",
thumbnail: [ thumbnail: [
@ -135,9 +145,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(2), video_count: Some(2),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvTyDxI-_RDK8UlPbJ5FNf9", id: "PLvOlSehNtuHvTyDxI-_RDK8UlPbJ5FNf9",
name: "Announcements & Misc", name: "Announcements & Misc",
thumbnail: [ thumbnail: [
@ -147,9 +158,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(28), video_count: Some(28),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtT17_AeYMe-EOS_GXCBQQ1", id: "PLvOlSehNtuHtT17_AeYMe-EOS_GXCBQQ1",
name: "Interviews", name: "Interviews",
thumbnail: [ thumbnail: [
@ -159,9 +171,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(9), video_count: Some(9),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHsCTtj-T_vkpTTbBXW4sB51", id: "PLvOlSehNtuHsCTtj-T_vkpTTbBXW4sB51",
name: "Oscilloscope Tutorials", name: "Oscilloscope Tutorials",
thumbnail: [ thumbnail: [
@ -171,9 +184,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(38), video_count: Some(38),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHsKCtJJ_rlRP5qE7lN-1EMX", id: "PLvOlSehNtuHsKCtJJ_rlRP5qE7lN-1EMX",
name: "Anti-Static ESD", name: "Anti-Static ESD",
thumbnail: [ thumbnail: [
@ -183,9 +197,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(7), video_count: Some(7),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvFf9a2swL8QVMwji0wT3ha", id: "PLvOlSehNtuHvFf9a2swL8QVMwji0wT3ha",
name: "Unboxing", name: "Unboxing",
thumbnail: [ thumbnail: [
@ -195,9 +210,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(2), video_count: Some(2),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtn9n6n-uB8VNCTrERwYxLZ", id: "PLvOlSehNtuHtn9n6n-uB8VNCTrERwYxLZ",
name: "Power Supplies", name: "Power Supplies",
thumbnail: [ thumbnail: [
@ -207,9 +223,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(43), video_count: Some(43),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHuo-6paPTh3ji7AEMpnSna6", id: "PLvOlSehNtuHuo-6paPTh3ji7AEMpnSna6",
name: "CNC Milling Machine", name: "CNC Milling Machine",
thumbnail: [ thumbnail: [
@ -219,9 +236,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(1), video_count: Some(1),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvpVeLXSGlS7EBlY3zKfIXh", id: "PLvOlSehNtuHvpVeLXSGlS7EBlY3zKfIXh",
name: "Capacitors", name: "Capacitors",
thumbnail: [ thumbnail: [
@ -231,9 +249,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(15), video_count: Some(15),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHsNGit9YgkuxsFtFNJxwgot", id: "PLvOlSehNtuHsNGit9YgkuxsFtFNJxwgot",
name: "PCB Assembly", name: "PCB Assembly",
thumbnail: [ thumbnail: [
@ -243,9 +262,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(5), video_count: Some(5),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvsggk5TwGdR2BZcoKRkQ2I", id: "PLvOlSehNtuHvsggk5TwGdR2BZcoKRkQ2I",
name: "3D Printing", name: "3D Printing",
thumbnail: [ thumbnail: [
@ -255,9 +275,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(6), video_count: Some(6),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtH_DR5hAIGQ-Ty6f9TZWNV", id: "PLvOlSehNtuHtH_DR5hAIGQ-Ty6f9TZWNV",
name: "Video Editing / PC Builds", name: "Video Editing / PC Builds",
thumbnail: [ thumbnail: [
@ -267,9 +288,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(3), video_count: Some(3),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvPZ1-dDC449w_r2M0R4jtc", id: "PLvOlSehNtuHvPZ1-dDC449w_r2M0R4jtc",
name: "Solar Power Systems", name: "Solar Power Systems",
thumbnail: [ thumbnail: [
@ -279,9 +301,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(19), video_count: Some(19),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHtolTr61FnHtvZb6tRPrs8m", id: "PLvOlSehNtuHtolTr61FnHtvZb6tRPrs8m",
name: "EEVblab", name: "EEVblab",
thumbnail: [ thumbnail: [
@ -291,9 +314,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(101), video_count: Some(101),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHsc8y1buFPJZaD1kKzIxpWL", id: "PLvOlSehNtuHsc8y1buFPJZaD1kKzIxpWL",
name: "Repairs", name: "Repairs",
thumbnail: [ thumbnail: [
@ -303,9 +327,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(78), video_count: Some(78),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvBpmbLABRmSKv2b0C4LWV_", id: "PLvOlSehNtuHvBpmbLABRmSKv2b0C4LWV_",
name: "Debunking", name: "Debunking",
thumbnail: [ thumbnail: [
@ -315,9 +340,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(73), video_count: Some(73),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHs_8iObryqVCeqLIo5KTFQ-", id: "PLvOlSehNtuHs_8iObryqVCeqLIo5KTFQ-",
name: "Lab Bench Builds + ESD Mats", name: "Lab Bench Builds + ESD Mats",
thumbnail: [ thumbnail: [
@ -327,9 +353,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(9), video_count: Some(9),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvatF_8oJ2qpKxi_wWw6YN4", id: "PLvOlSehNtuHvatF_8oJ2qpKxi_wWw6YN4",
name: "Reverse Engineering", name: "Reverse Engineering",
thumbnail: [ thumbnail: [
@ -339,9 +366,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(10), video_count: Some(10),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvwQR69zYRyxSkujQs2SgLl", id: "PLvOlSehNtuHvwQR69zYRyxSkujQs2SgLl",
name: "Scams", name: "Scams",
thumbnail: [ thumbnail: [
@ -351,9 +379,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(5), video_count: Some(5),
), ),
ChannelPlaylist( PlaylistItem(
id: "PLvOlSehNtuHvRvEU3VebO2JHa1I_iIAQD", id: "PLvOlSehNtuHvRvEU3VebO2JHa1I_iIAQD",
name: "Hacking / Experiments", name: "Hacking / Experiments",
thumbnail: [ thumbnail: [
@ -363,8 +392,10 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: None,
video_count: Some(63), video_count: Some(63),
), ),
], ],
ctoken: Some("4qmFsgLCARIYVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RGnRFZ2x3YkdGNWJHbHpkSE1ZQXlBQk1BRTRBZW9EUEVOblRrUlJhbEZUU2tKSmFWVkZlREpVTW5oVVdsZG9UMlJJVmtsa2JFb3lVbFpWZWxadFZtbFVla3BMVTBkRmVGTldPWEJUVlVaU1VrTm5PQSUzRCUzRJoCL2Jyb3dzZS1mZWVkVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RcGxheWxpc3RzMTA0"), ctoken: Some("4qmFsgLCARIYVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RGnRFZ2x3YkdGNWJHbHpkSE1ZQXlBQk1BRTRBZW9EUEVOblRrUlJhbEZUU2tKSmFWVkZlREpVTW5oVVdsZG9UMlJJVmtsa2JFb3lVbFpWZWxadFZtbFVla3BMVTBkRmVGTldPWEJUVlVaU1VrTm5PQSUzRCUzRJoCL2Jyb3dzZS1mZWVkVUMyRGpGRTdYZjExVVJacVdCaWdjVk9RcGxheWxpc3RzMTA0"),
endpoint: browse,
) )

View file

@ -1,11 +1,11 @@
--- ---
source: src/client/video_details.rs source: src/client/pagination.rs
expression: map_res.c expression: map_res.c
--- ---
Paginator( Paginator(
count: None, count: None,
items: [ items: [
RecommendedVideo( Video(VideoItem(
id: "WPdWvnAAurg", id: "WPdWvnAAurg",
title: "aespa 에스파 \'Savage\' MV", title: "aespa 에스파 \'Savage\' MV",
length: Some(259), length: Some(259),
@ -21,7 +21,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -31,16 +31,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 months ago"), publish_date_txt: Some("11 months ago"),
view_count: 216222873, view_count: Some(216222873),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "Y8JFxS1HlDo", id: "Y8JFxS1HlDo",
title: "IVE 아이브 \'LOVE DIVE\' MV", title: "IVE 아이브 \'LOVE DIVE\' MV",
length: Some(179), length: Some(179),
@ -56,7 +58,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCYDmx2Sfpnaxg488yBpZIGg", id: "UCYDmx2Sfpnaxg488yBpZIGg",
name: "starshipTV", name: "starshipTV",
avatar: [ avatar: [
@ -66,16 +68,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 months ago"), publish_date_txt: Some("5 months ago"),
view_count: 155106313, view_count: Some(155106313),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "NoYKBAajoyo", id: "NoYKBAajoyo",
title: "EVERGLOW (에버글로우) - DUN DUN MV", title: "EVERGLOW (에버글로우) - DUN DUN MV",
length: Some(209), length: Some(209),
@ -91,7 +95,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC_pwIXKXNm5KGhdEVzmY60A", id: "UC_pwIXKXNm5KGhdEVzmY60A",
name: "Stone Music Entertainment", name: "Stone Music Entertainment",
avatar: [ avatar: [
@ -101,16 +105,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 265238677, view_count: Some(265238677),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "yQUU29NwNF4", id: "yQUU29NwNF4",
title: "aespa(에스파) - Black Mamba @인기가요 inkigayo 20201122", title: "aespa(에스파) - Black Mamba @인기가요 inkigayo 20201122",
length: Some(213), length: Some(213),
@ -126,7 +132,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCS_hnpJLQTvBkqALgapi_4g", id: "UCS_hnpJLQTvBkqALgapi_4g",
name: "스브스케이팝 X INKIGAYO", name: "스브스케이팝 X INKIGAYO",
avatar: [ avatar: [
@ -136,16 +142,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 9989591, view_count: Some(9989591),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "NU611fxGyPU", id: "NU611fxGyPU",
title: "aespa 에스파 \'Black Mamba\' Dance Practice", title: "aespa 에스파 \'Black Mamba\' Dance Practice",
length: Some(175), length: Some(175),
@ -161,7 +169,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg", id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa", name: "aespa",
avatar: [ avatar: [
@ -171,16 +179,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 34588526, view_count: Some(34588526),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "EaswWiwMVs8", id: "EaswWiwMVs8",
title: "Stray Kids \"소리꾼(Thunderous)\" M/V", title: "Stray Kids \"소리꾼(Thunderous)\" M/V",
length: Some(199), length: Some(199),
@ -196,7 +206,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -206,16 +216,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 242737870, view_count: Some(242737870),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "Ujb-gvqsoi0", id: "Ujb-gvqsoi0",
title: "Red Velvet - IRENE & SEULGI \'Monster\' MV", title: "Red Velvet - IRENE & SEULGI \'Monster\' MV",
length: Some(182), length: Some(182),
@ -231,7 +243,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -241,16 +253,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 126677200, view_count: Some(126677200),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "gQlMMD8auMs", id: "gQlMMD8auMs",
title: "BLACKPINK - Pink Venom M/V", title: "BLACKPINK - Pink Venom M/V",
length: Some(194), length: Some(194),
@ -266,7 +280,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -276,16 +290,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 335903776, view_count: Some(335903776),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "BL-aIpCLWnU", id: "BL-aIpCLWnU",
title: "Black Mamba", title: "Black Mamba",
length: Some(175), length: Some(175),
@ -301,7 +317,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg", id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa", name: "aespa",
avatar: [ avatar: [
@ -311,16 +327,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 86125645, view_count: Some(86125645),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "Jh4QFaPmdss", id: "Jh4QFaPmdss",
title: "(G)I-DLE - \'TOMBOY\' Official Music Video", title: "(G)I-DLE - \'TOMBOY\' Official Music Video",
length: Some(198), length: Some(198),
@ -336,7 +354,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCritGVo7pLJLUS8wEu32vow", id: "UCritGVo7pLJLUS8wEu32vow",
name: "(G)I-DLE (여자)아이들 (Official YouTube Channel)", name: "(G)I-DLE (여자)아이들 (Official YouTube Channel)",
avatar: [ avatar: [
@ -346,16 +364,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 170016610, view_count: Some(170016610),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "Fc-fa6cAe2c", id: "Fc-fa6cAe2c",
title: "KAI 카이 \'음 (Mmmh)\' MV", title: "KAI 카이 \'음 (Mmmh)\' MV",
length: Some(207), length: Some(207),
@ -371,7 +391,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -381,16 +401,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 123861096, view_count: Some(123861096),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "dYRITmpFbJ4", id: "dYRITmpFbJ4",
title: "aespa 에스파 \'Girls\' MV", title: "aespa 에스파 \'Girls\' MV",
length: Some(269), length: Some(269),
@ -406,7 +428,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -416,16 +438,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 101968219, view_count: Some(101968219),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "mH0_XpSHkZo", id: "mH0_XpSHkZo",
title: "TWICE \"MORE & MORE\" M/V", title: "TWICE \"MORE & MORE\" M/V",
length: Some(241), length: Some(241),
@ -441,7 +465,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -451,16 +475,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 322510403, view_count: Some(322510403),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "uR8Mrt1IpXg", id: "uR8Mrt1IpXg",
title: "Red Velvet 레드벨벳 \'Psycho\' MV", title: "Red Velvet 레드벨벳 \'Psycho\' MV",
length: Some(216), length: Some(216),
@ -476,7 +502,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -486,16 +512,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 345491789, view_count: Some(345491789),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "f5_wn8mexmM", id: "f5_wn8mexmM",
title: "TWICE \"The Feels\" M/V", title: "TWICE \"The Feels\" M/V",
length: Some(232), length: Some(232),
@ -511,7 +539,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -521,16 +549,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 months ago"), publish_date_txt: Some("11 months ago"),
view_count: 314744776, view_count: Some(314744776),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "Ky5RT5oGg0w", id: "Ky5RT5oGg0w",
title: "aespa 에스파 \'Black Mamba\' The Debut Stage", title: "aespa 에스파 \'Black Mamba\' The Debut Stage",
length: Some(287), length: Some(287),
@ -546,7 +576,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg", id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa", name: "aespa",
avatar: [ avatar: [
@ -556,16 +586,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 18830758, view_count: Some(18830758),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "gU2HqP4NxUs", id: "gU2HqP4NxUs",
title: "BLACKPINK - Pretty Savage 1011 SBS Inkigayo", title: "BLACKPINK - Pretty Savage 1011 SBS Inkigayo",
length: Some(208), length: Some(208),
@ -581,7 +613,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -591,16 +623,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 282957370, view_count: Some(282957370),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "KhTeiaCezwM", id: "KhTeiaCezwM",
title: "[MV] MAMAMOO (마마무) - HIP", title: "[MV] MAMAMOO (마마무) - HIP",
length: Some(211), length: Some(211),
@ -616,7 +650,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCuhAUMLzJxlP1W7mEk0_6lA", id: "UCuhAUMLzJxlP1W7mEk0_6lA",
name: "MAMAMOO", name: "MAMAMOO",
avatar: [ avatar: [
@ -626,16 +660,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 355203298, view_count: Some(355203298),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
RecommendedVideo( short_description: None,
)),
Video(VideoItem(
id: "uxmP4b2a0uY", id: "uxmP4b2a0uY",
title: "EXO 엑소 \'Obsession\' MV", title: "EXO 엑소 \'Obsession\' MV",
length: Some(220), length: Some(220),
@ -651,7 +687,7 @@ Paginator(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -661,15 +697,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 157400947, view_count: Some(157400947),
is_live: false, is_live: false,
is_short: false, is_short: false,
), is_upcoming: false,
short_description: None,
)),
], ],
ctoken: Some("CCgSExILWmVlcnJudUxpNUXAAQHIAQEYACrLDDJzNkw2d3l4Q1FxdUNRb0Q4ajRBQ2czQ1Bnb0l4LUM1djltdnBwZ3lDZ1B5UGdBS0RjSS1DZ2pxM0xYRXpkNk00VUVLQV9JLUFBb093ajRMQ1Bqc19JLUVsWTI5MWdFS0FfSS1BQW93MGo0dENpdFNSRU5NUVVzMWRYbGZhekkzZFhVdFJYUlJYMkkxVlRKeU1qWkVUa1JhVDIxT2NVZGtZMk5WU1VkUkNnUHlQZ0FLRHNJLUN3amZ2czJMbjRUcG5iUUJDZ1B5UGdBS0V0SS1Ed29OVWtSYVpXVnljbTUxVEdrMVJRb0Q4ajRBQ2c3Q1Bnc0kzYmJTdThMRy1wS1VBUW9EOGo0QUNnN0NQZ3NJX2JYd2lmQzJ0WlczQVFvRDhqNEFDZzdDUGdzSXpZckE3b0RHbzlMUUFRb0Q4ajRBQ2czQ1Bnb0l0N212dk9fUjVJUnZDZ1B5UGdBS0RjSS1DZ2lBcDdMWDBlYWxyaW9LQV9JLUFBb053ajRLQ0luanlmalZ0dUwxWHdvRDhqNEFDZzNDUGdvSXBKZmozYVR5X2MwZkNnUHlQZ0FLRGNJLUNnamJtNW1MbGRLQTV3Z0tBX0ktQUFvT3dqNExDTFRhOF9UNjE3U3UyQUVLQV9JLUFBb053ajRLQ05xMHBhdXZzS1BDZEFvRDhqNEFDZzdDUGdzSTVQR3E5WTIybWNXZ0FRb0Q4ajRBQ2c3Q1Bnc0lnNkdPN3JidzJjR0tBUW9EOGo0QUNnN0NQZ3NJenEtbWxQUy01SnJoQVFvRDhqNEFDZzdDUGdzSXZNbnBqSUtUeXBYX0FRb0Q4ajRBQ2czQ1Bnb0l1UFdDZ09mWDFmdFlDZ1B5UGdBS0g5SS1IQW9hVWtSRlRWUnVTbmxSZDJsamFHMW5lbm96VGxKSlVIVmxWMUVLQV9JLUFBb053ajRLQ0xxb251clN1SkhoWXdvRDhqNEFDZzNDUGdvSXFzYU90Y0RBZ3NNMkNnUHlQZ0FLRHNJLUN3amU2TUNidlp2Rmdza0JDZ1B5UGdBS0RjSS1DZ2oxa1p2aTM3cXRwelVLQV9JLUFBb053ajRLQ00tdHNlQ2lpOHpWRVFvRDhqNEFDZzNDUGdvSXJjU3kxYV9RdjV0U0NnUHlQZ0FLRHNJLUN3akw4ZXI0ZzRiVGhJRUJDZ1B5UGdBS0RjSS1DZ2oxdEsyRXFjVG0zd1FLQV9JLUFBb053ajRLQ012dG1aX2Fnb1NQSmdvRDhqNEFDZzNDUGdvSTVfYUJ1THJ0NS1jVkNnUHlQZ0FLRGNJLUNnaWUyWlhTNW9tU3duVUtBX0ktQUFvT3dqNExDSnFqbnFUcDY4LS1tQUVLQV9JLUFBb093ajRMQ1BqS291cnRsY09QdVFFS0FfSS1BQW9Od2o0S0NPT00tOHo4a196UGZ3b0Q4ajRBQ2czQ1Bnb0l6SWFhMFBtcGxKY3JDZ1B5UGdBS0RzSS1Dd2pMaXJmd2pfWGhwb0VCQ2dQeVBnQUtEY0ktQ2dpRG52dUVtdEczaWlvS0FfSS1BQW9Pd2o0TENPYWw2LXliX09PTXV3RVNLQUFDQkFZSUNnd09FQklVRmhnYUhCNGdJaVFtS0Nvc0xqQXlORFk0T2p3LVFFSkVSa2hLVEU0YUJBZ0FFQUVhQkFnQ0VBTWFCQWdFRUFVYUJBZ0dFQWNhQkFnSUVBa2FCQWdLRUFzYUJBZ01FQTBhQkFnT0VBOGFCQWdRRUJFYUJBZ1NFQk1hQkFnVUVCVWFCQWdXRUJjYUJBZ1lFQmthQkFnYUVCc2FCQWdjRUIwYUJBZ2VFQjhhQkFnZ0VDRWFCQWdpRUNNYUJBZ2tFQ1VhQkFnbUVDY2FCQWdvRUNrYUJBZ3FFQ3NhQkFnc0VDMGFCQWd1RUM4YUJBZ3dFREVhQkFneUVETWFCQWcwRURVYUJBZzJFRGNhQkFnNEVEa2FCQWc2RURzYUJBZzhFRDBhQkFnLUVEOGFCQWhBRUVFYUJBaENFRU1hQkFoRUVFVWFCQWhHRUVjYUJBaElFRWthQkFoS0VFc2FCQWhNRUUwYUJBaE9FRThxS0FBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbUtDb3NMakF5TkRZNE9qdy1RRUpFUmtoS1RFNGoPd2F0Y2gtbmV4dC1mZWVkcgA%3D"), ctoken: Some("CCgSExILWmVlcnJudUxpNUXAAQHIAQEYACrLDDJzNkw2d3l4Q1FxdUNRb0Q4ajRBQ2czQ1Bnb0l4LUM1djltdnBwZ3lDZ1B5UGdBS0RjSS1DZ2pxM0xYRXpkNk00VUVLQV9JLUFBb093ajRMQ1Bqc19JLUVsWTI5MWdFS0FfSS1BQW93MGo0dENpdFNSRU5NUVVzMWRYbGZhekkzZFhVdFJYUlJYMkkxVlRKeU1qWkVUa1JhVDIxT2NVZGtZMk5WU1VkUkNnUHlQZ0FLRHNJLUN3amZ2czJMbjRUcG5iUUJDZ1B5UGdBS0V0SS1Ed29OVWtSYVpXVnljbTUxVEdrMVJRb0Q4ajRBQ2c3Q1Bnc0kzYmJTdThMRy1wS1VBUW9EOGo0QUNnN0NQZ3NJX2JYd2lmQzJ0WlczQVFvRDhqNEFDZzdDUGdzSXpZckE3b0RHbzlMUUFRb0Q4ajRBQ2czQ1Bnb0l0N212dk9fUjVJUnZDZ1B5UGdBS0RjSS1DZ2lBcDdMWDBlYWxyaW9LQV9JLUFBb053ajRLQ0luanlmalZ0dUwxWHdvRDhqNEFDZzNDUGdvSXBKZmozYVR5X2MwZkNnUHlQZ0FLRGNJLUNnamJtNW1MbGRLQTV3Z0tBX0ktQUFvT3dqNExDTFRhOF9UNjE3U3UyQUVLQV9JLUFBb053ajRLQ05xMHBhdXZzS1BDZEFvRDhqNEFDZzdDUGdzSTVQR3E5WTIybWNXZ0FRb0Q4ajRBQ2c3Q1Bnc0lnNkdPN3JidzJjR0tBUW9EOGo0QUNnN0NQZ3NJenEtbWxQUy01SnJoQVFvRDhqNEFDZzdDUGdzSXZNbnBqSUtUeXBYX0FRb0Q4ajRBQ2czQ1Bnb0l1UFdDZ09mWDFmdFlDZ1B5UGdBS0g5SS1IQW9hVWtSRlRWUnVTbmxSZDJsamFHMW5lbm96VGxKSlVIVmxWMUVLQV9JLUFBb053ajRLQ0xxb251clN1SkhoWXdvRDhqNEFDZzNDUGdvSXFzYU90Y0RBZ3NNMkNnUHlQZ0FLRHNJLUN3amU2TUNidlp2Rmdza0JDZ1B5UGdBS0RjSS1DZ2oxa1p2aTM3cXRwelVLQV9JLUFBb053ajRLQ00tdHNlQ2lpOHpWRVFvRDhqNEFDZzNDUGdvSXJjU3kxYV9RdjV0U0NnUHlQZ0FLRHNJLUN3akw4ZXI0ZzRiVGhJRUJDZ1B5UGdBS0RjSS1DZ2oxdEsyRXFjVG0zd1FLQV9JLUFBb053ajRLQ012dG1aX2Fnb1NQSmdvRDhqNEFDZzNDUGdvSTVfYUJ1THJ0NS1jVkNnUHlQZ0FLRGNJLUNnaWUyWlhTNW9tU3duVUtBX0ktQUFvT3dqNExDSnFqbnFUcDY4LS1tQUVLQV9JLUFBb093ajRMQ1BqS291cnRsY09QdVFFS0FfSS1BQW9Od2o0S0NPT00tOHo4a196UGZ3b0Q4ajRBQ2czQ1Bnb0l6SWFhMFBtcGxKY3JDZ1B5UGdBS0RzSS1Dd2pMaXJmd2pfWGhwb0VCQ2dQeVBnQUtEY0ktQ2dpRG52dUVtdEczaWlvS0FfSS1BQW9Pd2o0TENPYWw2LXliX09PTXV3RVNLQUFDQkFZSUNnd09FQklVRmhnYUhCNGdJaVFtS0Nvc0xqQXlORFk0T2p3LVFFSkVSa2hLVEU0YUJBZ0FFQUVhQkFnQ0VBTWFCQWdFRUFVYUJBZ0dFQWNhQkFnSUVBa2FCQWdLRUFzYUJBZ01FQTBhQkFnT0VBOGFCQWdRRUJFYUJBZ1NFQk1hQkFnVUVCVWFCQWdXRUJjYUJBZ1lFQmthQkFnYUVCc2FCQWdjRUIwYUJBZ2VFQjhhQkFnZ0VDRWFCQWdpRUNNYUJBZ2tFQ1VhQkFnbUVDY2FCQWdvRUNrYUJBZ3FFQ3NhQkFnc0VDMGFCQWd1RUM4YUJBZ3dFREVhQkFneUVETWFCQWcwRURVYUJBZzJFRGNhQkFnNEVEa2FCQWc2RURzYUJBZzhFRDBhQkFnLUVEOGFCQWhBRUVFYUJBaENFRU1hQkFoRUVFVWFCQWhHRUVjYUJBaElFRWthQkFoS0VFc2FCQWhNRUUwYUJBaE9FRThxS0FBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbUtDb3NMakF5TkRZNE9qdy1RRUpFUmtoS1RFNGoPd2F0Y2gtbmV4dC1mZWVkcgA%3D"),
endpoint: browse,
) )

View file

@ -1,11 +1,11 @@
--- ---
source: src/client/search.rs source: src/client/pagination.rs
expression: map_res.c expression: map_res.c
--- ---
Paginator( Paginator(
count: Some(7250), count: Some(7250),
items: [ items: [
Video(SearchVideo( Video(VideoItem(
id: "N5AKQflK1TU", id: "N5AKQflK1TU",
title: "When you impulse buy...", title: "When you impulse buy...",
length: Some(60), length: Some(60),
@ -16,7 +16,7 @@ Paginator(
height: 720, height: 720,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -26,17 +26,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 day ago"), publish_date_txt: Some("1 day ago"),
view_count: 859366, view_count: Some(859366),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "shorts #jam https://doobydobap.com/recipe/hongsi_jam Instagram @doobydobap Join my discord!", is_upcoming: false,
short_description: Some("shorts #jam https://doobydobap.com/recipe/hongsi_jam Instagram @doobydobap Join my discord!"),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "OzIFALQ_YtA", id: "OzIFALQ_YtA",
title: "taste testing gam!", title: "taste testing gam!",
length: Some(60), length: Some(60),
@ -47,7 +48,7 @@ Paginator(
height: 720, height: 720,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -57,17 +58,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 days ago"), publish_date_txt: Some("3 days ago"),
view_count: 1000402, view_count: Some(1000402),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "shorts #fruit #mukbang Instagram @doobydobap Join my discord! https://discord.gg/doobyverse www.doobydobap.com for\u{a0}...", is_upcoming: false,
short_description: Some("shorts #fruit #mukbang Instagram @doobydobap Join my discord! https://discord.gg/doobyverse www.doobydobap.com for\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "zYHB38UlzE0", id: "zYHB38UlzE0",
title: "Q&A l relationships, burnout, privilege, college advice, living alone, and life after youtube?", title: "Q&A l relationships, burnout, privilege, college advice, living alone, and life after youtube?",
length: Some(775), length: Some(775),
@ -83,7 +85,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -93,17 +95,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 528795, view_count: Some(528795),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "So many questions I wasn\'t able to answer, but if you comment below I\'ll try and answer every single one of them!!!! A little bit of\u{a0}...", is_upcoming: false,
short_description: Some("So many questions I wasn\'t able to answer, but if you comment below I\'ll try and answer every single one of them!!!! A little bit of\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "GvutfmW26JQ", id: "GvutfmW26JQ",
title: "👹stay sour 🍋", title: "👹stay sour 🍋",
length: Some(52), length: Some(52),
@ -114,7 +117,7 @@ Paginator(
height: 720, height: 720,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -124,17 +127,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 days ago"), publish_date_txt: Some("8 days ago"),
view_count: 1096055, view_count: Some(1096055),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "Ingredients: ** Citrus Filling** 1 cup mandarin juice or any orange-y citrus in season! 6 eggs 1 1/2 cup sugar ⅓ cup flour zest of 1\u{a0}...", is_upcoming: false,
short_description: Some("Ingredients: ** Citrus Filling** 1 cup mandarin juice or any orange-y citrus in season! 6 eggs 1 1/2 cup sugar ⅓ cup flour zest of 1\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "gK-jLnvVsb0", id: "gK-jLnvVsb0",
title: "Contradicting myself", title: "Contradicting myself",
length: Some(1381), length: Some(1381),
@ -150,7 +154,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -160,17 +164,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 months ago"), publish_date_txt: Some("8 months ago"),
view_count: 928968, view_count: Some(928968),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Sesame Granola Recipe 2 cups old-fashioned instant oats 2 cups mixture of seeds / nuts of your choice (I used ½ cup each of\u{a0}...", is_upcoming: false,
short_description: Some("Sesame Granola Recipe 2 cups old-fashioned instant oats 2 cups mixture of seeds / nuts of your choice (I used ½ cup each of\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "NudTbo2CJMY", id: "NudTbo2CJMY",
title: "Flying to London", title: "Flying to London",
length: Some(1078), length: Some(1078),
@ -186,7 +191,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -196,17 +201,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 1137138, view_count: Some(1137138),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Tomato Beef Curry 1 packet Japanese Curry Roux 250g thinly sliced beef 2 large onions 2 tbsp butter 2 tbsp neutral oil 1 can\u{a0}...", is_upcoming: false,
short_description: Some("Tomato Beef Curry 1 packet Japanese Curry Roux 250g thinly sliced beef 2 large onions 2 tbsp butter 2 tbsp neutral oil 1 can\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "Nc0HzyDRjm0", id: "Nc0HzyDRjm0",
title: "Stekki-don ㅣ After Hours ep.2", title: "Stekki-don ㅣ After Hours ep.2",
length: Some(749), length: Some(749),
@ -222,7 +228,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -232,17 +238,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 months ago"), publish_date_txt: Some("8 months ago"),
view_count: 462437, view_count: Some(462437),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Stekki-Don (for two, or for one very hungry person) 500g Ribeye 1 tsp Kosher salt 2 tbsp unsalted butter Sauce 4 tbsp light soy\u{a0}...", is_upcoming: false,
short_description: Some("Stekki-Don (for two, or for one very hungry person) 500g Ribeye 1 tsp Kosher salt 2 tbsp unsalted butter Sauce 4 tbsp light soy\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "pvSWHm4wlxY", id: "pvSWHm4wlxY",
title: "having kids", title: "having kids",
length: Some(60), length: Some(60),
@ -253,7 +260,7 @@ Paginator(
height: 720, height: 720,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -263,17 +270,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 11285067, view_count: Some(11285067),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "shorts Instagram @doobydobap Join my discord! https://discord.gg/doobyverse www.doobydobap.com for recipes & stories.", is_upcoming: false,
short_description: Some("shorts Instagram @doobydobap Join my discord! https://discord.gg/doobyverse www.doobydobap.com for recipes & stories."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "fGQUWI4o__A", id: "fGQUWI4o__A",
title: "Baskin Robbins in South Korea", title: "Baskin Robbins in South Korea",
length: Some(53), length: Some(53),
@ -284,7 +292,7 @@ Paginator(
height: 720, height: 720,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -294,17 +302,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 2415040, view_count: Some(2415040),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "shorts #icecream Instagram @doobydobap Join my discord! https://discord.gg/doobyverse www.doobydobap.com for recipes\u{a0}...", is_upcoming: false,
short_description: Some("shorts #icecream Instagram @doobydobap Join my discord! https://discord.gg/doobyverse www.doobydobap.com for recipes\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "GuyGyzZcumI", id: "GuyGyzZcumI",
title: "McDonald\'s Michelin Burger", title: "McDonald\'s Michelin Burger",
length: Some(59), length: Some(59),
@ -315,7 +324,7 @@ Paginator(
height: 720, height: 720,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -325,17 +334,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 5100787, view_count: Some(5100787),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "mcdonalds #michelin #fastfood Instagram @doobydobap Join my discord! https://discord.gg/doobyverse\u{a0}...", is_upcoming: false,
short_description: Some("mcdonalds #michelin #fastfood Instagram @doobydobap Join my discord! https://discord.gg/doobyverse\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "6VGG19W08UQ", id: "6VGG19W08UQ",
title: "Nostalgia is a powerful ingredient", title: "Nostalgia is a powerful ingredient",
length: Some(52), length: Some(52),
@ -346,7 +356,7 @@ Paginator(
height: 480, height: 480,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -356,17 +366,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("10 months ago"), publish_date_txt: Some("10 months ago"),
view_count: 55308394, view_count: Some(55308394),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "shorts ASMR version on my Instagram @doobydobap Join my discord! https://discord.gg/doobyverse www.doobydobap.com\u{a0}...", is_upcoming: false,
short_description: Some("shorts ASMR version on my Instagram @doobydobap Join my discord! https://discord.gg/doobyverse www.doobydobap.com\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "p3Xhx6aQEXo", id: "p3Xhx6aQEXo",
title: "Jjajangmyun ㅣ Doob Gourmand ep.2", title: "Jjajangmyun ㅣ Doob Gourmand ep.2",
length: Some(664), length: Some(664),
@ -382,7 +393,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -392,17 +403,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 months ago"), publish_date_txt: Some("8 months ago"),
view_count: 774061, view_count: Some(774061),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Stay on for bloopers! Vlog coming on Tuesday!! Location 의천각 Uicheongag 수정구 신흥동 6907번지 성남시 경기도 KR\u{a0}...", is_upcoming: false,
short_description: Some("Stay on for bloopers! Vlog coming on Tuesday!! Location 의천각 Uicheongag 수정구 신흥동 6907번지 성남시 경기도 KR\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "35Gu3Q6qEn4", id: "35Gu3Q6qEn4",
title: "Deal Breakers", title: "Deal Breakers",
length: Some(60), length: Some(60),
@ -413,7 +425,7 @@ Paginator(
height: 480, height: 480,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -423,17 +435,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 months ago"), publish_date_txt: Some("8 months ago"),
view_count: 12314192, view_count: Some(12314192),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "shorts another deal breaker: people who like chocolate chip banana bread over regular-- you heard me Recipe: Wet: 3 very ripe\u{a0}...", is_upcoming: false,
short_description: Some("shorts another deal breaker: people who like chocolate chip banana bread over regular-- you heard me Recipe: Wet: 3 very ripe\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "JoUdBrUpBN0", id: "JoUdBrUpBN0",
title: "Jjambbong, jjajangmyeon\'s biggest rival", title: "Jjambbong, jjajangmyeon\'s biggest rival",
length: Some(56), length: Some(56),
@ -444,7 +457,7 @@ Paginator(
height: 480, height: 480,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -454,17 +467,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 4266748, view_count: Some(4266748),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "shorts Recipe on my website at www.doobydobap.com/recipe.", is_upcoming: false,
short_description: Some("shorts Recipe on my website at www.doobydobap.com/recipe."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "l76ovWsPLi8", id: "l76ovWsPLi8",
title: "Jjagglee, Ricotta Persimmon Toast, Plants, and Pringles! l Home Alone All Day Vlog", title: "Jjagglee, Ricotta Persimmon Toast, Plants, and Pringles! l Home Alone All Day Vlog",
length: Some(673), length: Some(673),
@ -480,7 +494,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -490,17 +504,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("9 months ago"), publish_date_txt: Some("9 months ago"),
view_count: 439888, view_count: Some(439888),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Ingredients for jjaglee 1 cup pork belly 1 cup fermented kimchi ½ onion 1 leek 1 firm tofu 1.5 tbsp gochujang 2 tbsp coarse\u{a0}...", is_upcoming: false,
short_description: Some("Ingredients for jjaglee 1 cup pork belly 1 cup fermented kimchi ½ onion 1 leek 1 firm tofu 1.5 tbsp gochujang 2 tbsp coarse\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "zt1Lx9L619w", id: "zt1Lx9L619w",
title: "The biggest privilege my rich friends have", title: "The biggest privilege my rich friends have",
length: Some(58), length: Some(58),
@ -511,7 +526,7 @@ Paginator(
height: 480, height: 480,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -521,16 +536,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 9312774, view_count: Some(9312774),
is_live: false, is_live: false,
is_short: true, is_short: true,
short_description: "shorts #japanese #curry Tomato Beef Curry 1 packet Japanese Curry Roux 250g thinly sliced beef 2 large onions 2 tbsp butter 2\u{a0}...", is_upcoming: false,
short_description: Some("shorts #japanese #curry Tomato Beef Curry 1 packet Japanese Curry Roux 250g thinly sliced beef 2 large onions 2 tbsp butter 2\u{a0}..."),
)), )),
], ],
ctoken: Some("EpMDEgpkb29ieWRvYmFwGoQDU0NpQ0FRdE9OVUZMVVdac1N6RlVWWUlCQzA5NlNVWkJURkZmV1hSQmdnRUxjako1WlRaNlZ6QnVZazJDQVF0NldVaENNemhWYkhwRk1JSUJDMGQyZFhSbWJWY3lOa3BSZ2dFTFVuSnZXWEJNZUhoT2FsbUNBUXRzTkRkUmRYVmtjMW96TklJQkMyZExMV3BNYm5aV2MySXdnZ0VMVG5Wa1ZHSnZNa05LVFZtQ0FRdE9ZekJJZW5sRVVtcHRNSUlCQzNCMlUxZEliVFIzYkhoWmdnRUxaa2RSVlZkSk5HOWZYMEdDQVF0UWVFZHRVRFIyWDBFek9JSUJDMGQxZVVkNWVscGpkVzFKZ2dFTE5sWkhSekU1VnpBNFZWR0NBUXR3TTFob2VEWmhVVVZZYjRJQkN6TTFSM1V6VVRaeFJXNDBnZ0VMU205VlpFSnlWWEJDVGpDQ0FRdHNOelp2ZGxkelVFeHBPSUlCQzNwME1VeDRPVXcyTVRsM3NnRUdDZ1FJSnhBRBiB4OgYIgtzZWFyY2gtZmVlZA%3D%3D"), ctoken: Some("EpMDEgpkb29ieWRvYmFwGoQDU0NpQ0FRdE9OVUZMVVdac1N6RlVWWUlCQzA5NlNVWkJURkZmV1hSQmdnRUxjako1WlRaNlZ6QnVZazJDQVF0NldVaENNemhWYkhwRk1JSUJDMGQyZFhSbWJWY3lOa3BSZ2dFTFVuSnZXWEJNZUhoT2FsbUNBUXRzTkRkUmRYVmtjMW96TklJQkMyZExMV3BNYm5aV2MySXdnZ0VMVG5Wa1ZHSnZNa05LVFZtQ0FRdE9ZekJJZW5sRVVtcHRNSUlCQzNCMlUxZEliVFIzYkhoWmdnRUxaa2RSVlZkSk5HOWZYMEdDQVF0UWVFZHRVRFIyWDBFek9JSUJDMGQxZVVkNWVscGpkVzFKZ2dFTE5sWkhSekU1VnpBNFZWR0NBUXR3TTFob2VEWmhVVVZZYjRJQkN6TTFSM1V6VVRaeFJXNDBnZ0VMU205VlpFSnlWWEJDVGpDQ0FRdHNOelp2ZGxkelVFeHBPSUlCQzNwME1VeDRPVXcyTVRsM3NnRUdDZ1FJSnhBRBiB4OgYIgtzZWFyY2gtZmVlZA%3D%3D"),
endpoint: browse,
) )

View file

@ -1,11 +1,11 @@
--- ---
source: src/client/trends.rs source: src/client/pagination.rs
expression: map_res.c expression: map_res.c
--- ---
Paginator( Paginator(
count: None, count: None,
items: [ items: [
SearchVideo( Video(VideoItem(
id: "mRmlXh7Hams", id: "mRmlXh7Hams",
title: "Extra 3 vom 12.10.2022 im NDR | extra 3 | NDR", title: "Extra 3 vom 12.10.2022 im NDR | extra 3 | NDR",
length: Some(1839), length: Some(1839),
@ -16,7 +16,7 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCjhkuC_Pi85wGjnB0I1ydxw", id: "UCjhkuC_Pi85wGjnB0I1ydxw",
name: "extra 3", name: "extra 3",
avatar: [ avatar: [
@ -26,17 +26,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 days ago"), publish_date_txt: Some("2 days ago"),
view_count: 585257, view_count: Some(585257),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Niedersachsen nach der Wahl: Schuld ist immer die Ampel | Die Grünen: Partei der erneuerbaren Prinzipien | Verhütung? Ist Frauensache! | Youtube: Handwerk mit goldenem Boden - Christian Ehring...", is_upcoming: false,
), short_description: Some("Niedersachsen nach der Wahl: Schuld ist immer die Ampel | Die Grünen: Partei der erneuerbaren Prinzipien | Verhütung? Ist Frauensache! | Youtube: Handwerk mit goldenem Boden - Christian Ehring..."),
SearchVideo( )),
Video(VideoItem(
id: "LsXC5r64Pvc", id: "LsXC5r64Pvc",
title: "Most Rarest Plays In Baseball History", title: "Most Rarest Plays In Baseball History",
length: Some(1975), length: Some(1975),
@ -47,7 +48,7 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCRfKJZ7LHueFudiDgAJDr9Q", id: "UCRfKJZ7LHueFudiDgAJDr9Q",
name: "Top All Sports", name: "Top All Sports",
avatar: [ avatar: [
@ -57,17 +58,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 985521, view_count: Some(985521),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "#baseball #mlb #mlbb", is_upcoming: false,
), short_description: Some("#baseball #mlb #mlbb"),
SearchVideo( )),
Video(VideoItem(
id: "dwPmd1GqQHE", id: "dwPmd1GqQHE",
title: "90S RAP & HIPHOP MIX - Notorious B I G , Dr Dre, 50 Cent, Snoop Dogg, 2Pac, DMX, Lil Jon and more", title: "90S RAP & HIPHOP MIX - Notorious B I G , Dr Dre, 50 Cent, Snoop Dogg, 2Pac, DMX, Lil Jon and more",
length: Some(5457), length: Some(5457),
@ -78,7 +80,7 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCKICAAGtBLJJ5zRdIxn_B4g", id: "UCKICAAGtBLJJ5zRdIxn_B4g",
name: "#Hip Hop 2022", name: "#Hip Hop 2022",
avatar: [ avatar: [
@ -88,17 +90,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 months ago"), publish_date_txt: Some("5 months ago"),
view_count: 1654055, view_count: Some(1654055),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "", is_upcoming: false,
), short_description: None,
SearchVideo( )),
Video(VideoItem(
id: "qxI-Ob8lpLE", id: "qxI-Ob8lpLE",
title: "Schlatt\'s Chips Tier List", title: "Schlatt\'s Chips Tier List",
length: Some(1071), length: Some(1071),
@ -114,7 +117,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2mP7il3YV7TxM_3m6U0bwA", id: "UC2mP7il3YV7TxM_3m6U0bwA",
name: "jschlattLIVE", name: "jschlattLIVE",
avatar: [ avatar: [
@ -124,17 +127,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 9029628, view_count: Some(9029628),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Schlatt ranks every chip ever made.\nCREATE YOUR OWN TIER LIST: https://tiermaker.com/create/chips-for-big-guy-1146620\n\nSubscribe to me on Twitch:\nhttps://twitch.tv/jschlatt\n\nFollow me on Twitter:...", is_upcoming: false,
), short_description: Some("Schlatt ranks every chip ever made.\nCREATE YOUR OWN TIER LIST: https://tiermaker.com/create/chips-for-big-guy-1146620\n\nSubscribe to me on Twitch:\nhttps://twitch.tv/jschlatt\n\nFollow me on Twitter:..."),
SearchVideo( )),
Video(VideoItem(
id: "qmrzTUmZ4UU", id: "qmrzTUmZ4UU",
title: "850€ für den Verrat am System - UCS AT-AT LEGO® Star Wars 75313", title: "850€ für den Verrat am System - UCS AT-AT LEGO® Star Wars 75313",
length: Some(2043), length: Some(2043),
@ -150,7 +154,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC_EZd3lsmxudu3IQzpTzOgw", id: "UC_EZd3lsmxudu3IQzpTzOgw",
name: "Held der Steine Inh. Thomas Panke", name: "Held der Steine Inh. Thomas Panke",
avatar: [ avatar: [
@ -160,17 +164,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 days ago"), publish_date_txt: Some("6 days ago"),
view_count: 600516, view_count: Some(600516),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Star Wars - erschienen 2021 - 6749 Teile\n\nDieses Set bei Amazon*:\nhttps://amzn.to/3yu9dHX\n\nErwähnt im Video*:\nTassen https://bit.ly/HdSBausteinecke\nBig Boy https://bit.ly/BBLokBigBoy\nBurg...", is_upcoming: false,
), short_description: Some("Star Wars - erschienen 2021 - 6749 Teile\n\nDieses Set bei Amazon*:\nhttps://amzn.to/3yu9dHX\n\nErwähnt im Video*:\nTassen https://bit.ly/HdSBausteinecke\nBig Boy https://bit.ly/BBLokBigBoy\nBurg..."),
SearchVideo( )),
Video(VideoItem(
id: "4q4vpQCIZ6w", id: "4q4vpQCIZ6w",
title: "🌉 Manhattan Jazz 💖 l Relaxing Jazz Piano Music l Background Music", title: "🌉 Manhattan Jazz 💖 l Relaxing Jazz Piano Music l Background Music",
length: Some(23229), length: Some(23229),
@ -186,7 +191,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCBnMxlW70f0SB4ZTJx124lw", id: "UCBnMxlW70f0SB4ZTJx124lw",
name: "몽키비지엠 MONKEYBGM", name: "몽키비지엠 MONKEYBGM",
avatar: [ avatar: [
@ -196,17 +201,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 2343407, view_count: Some(2343407),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "- Please Subscribe!\n\n🔺Disney OST Collection part 1 \n ➡\u{fe0f} https://youtu.be/lrzKFu85nhE\n\n🔺Disney OST Collection part 2 \n ➡\u{fe0f} https://youtu.be/EtE09lowIbk\n\n🔺Studio Ghibli...", is_upcoming: false,
), short_description: Some("- Please Subscribe!\n\n🔺Disney OST Collection part 1 \n ➡\u{fe0f} https://youtu.be/lrzKFu85nhE\n\n🔺Disney OST Collection part 2 \n ➡\u{fe0f} https://youtu.be/EtE09lowIbk\n\n🔺Studio Ghibli..."),
SearchVideo( )),
Video(VideoItem(
id: "Z_k31kqZxaE", id: "Z_k31kqZxaE",
title: "1 in 1,000,000 NBA Moments", title: "1 in 1,000,000 NBA Moments",
length: Some(567), length: Some(567),
@ -222,7 +228,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCpyoYVlp67N16Lg1_N4VnVw", id: "UCpyoYVlp67N16Lg1_N4VnVw",
name: "dime", name: "dime",
avatar: [ avatar: [
@ -232,17 +238,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 4334298, view_count: Some(4334298),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "• Instagram - https://instagram.com/dime_nba\n• TikTok - https://tiktok.com/@dime_nba\n\ndime is a Swedish brand, founded in 2022. We produce some of the most entertaining NBA content on YouTube...", is_upcoming: false,
), short_description: Some("• Instagram - https://instagram.com/dime_nba\n• TikTok - https://tiktok.com/@dime_nba\n\ndime is a Swedish brand, founded in 2022. We produce some of the most entertaining NBA content on YouTube..."),
SearchVideo( )),
Video(VideoItem(
id: "zE-a5eqvlv8", id: "zE-a5eqvlv8",
title: "Dua Lipa, Coldplay, Martin Garrix & Kygo, The Chainsmokers Style - Feeling Me", title: "Dua Lipa, Coldplay, Martin Garrix & Kygo, The Chainsmokers Style - Feeling Me",
length: None, length: None,
@ -258,7 +265,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCX-USfenzQlhrEJR1zD5IYw", id: "UCX-USfenzQlhrEJR1zD5IYw",
name: "Deep Mood.", name: "Deep Mood.",
avatar: [ avatar: [
@ -268,17 +275,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 889, view_count: Some(889),
is_live: false, is_live: true,
is_short: false, is_short: false,
short_description: "#Summermix #DeepHouse #DeepHouseSummerMix\nDua Lipa, Coldplay, Martin Garrix & Kygo, The Chainsmokers Style - Feeling Me\n\n🎵 All songs in this spotify playlist: https://spoti.fi/2TJ4Dyj\nSubmit...", is_upcoming: false,
), short_description: Some("#Summermix #DeepHouse #DeepHouseSummerMix\nDua Lipa, Coldplay, Martin Garrix & Kygo, The Chainsmokers Style - Feeling Me\n\n🎵 All songs in this spotify playlist: https://spoti.fi/2TJ4Dyj\nSubmit..."),
SearchVideo( )),
Video(VideoItem(
id: "gNlOk0LXi5M", id: "gNlOk0LXi5M",
title: "Soll ich dir 1g GOLD schenken? oder JEMAND anderen DOPPELT?", title: "Soll ich dir 1g GOLD schenken? oder JEMAND anderen DOPPELT?",
length: Some(704), length: Some(704),
@ -294,7 +302,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCqcWNPTUVATZt0Dlr2jV0Wg", id: "UCqcWNPTUVATZt0Dlr2jV0Wg",
name: "Mois", name: "Mois",
avatar: [ avatar: [
@ -304,17 +312,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 days ago"), publish_date_txt: Some("8 days ago"),
view_count: 463834, view_count: Some(463834),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Je mehr Menschen mich abonnieren desto mehr Menschen werde ich glücklich machen \n\n24 std ab, viel Glück \n\nhttps://I-Clip.com/?sPartner=Mois", is_upcoming: false,
), short_description: Some("Je mehr Menschen mich abonnieren desto mehr Menschen werde ich glücklich machen \n\n24 std ab, viel Glück \n\nhttps://I-Clip.com/?sPartner=Mois"),
SearchVideo( )),
Video(VideoItem(
id: "dbMvZjs8Yc8", id: "dbMvZjs8Yc8",
title: "Brad Pitt- Die Revanche eines Sexsymbols | Doku HD | ARTE", title: "Brad Pitt- Die Revanche eines Sexsymbols | Doku HD | ARTE",
length: Some(3137), length: Some(3137),
@ -330,7 +339,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCsygZtQQSplGF6JA3XWvsdg", id: "UCsygZtQQSplGF6JA3XWvsdg",
name: "Irgendwas mit ARTE und Kultur", name: "Irgendwas mit ARTE und Kultur",
avatar: [ avatar: [
@ -340,17 +349,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 days ago"), publish_date_txt: Some("5 days ago"),
view_count: 293878, view_count: Some(293878),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Vom „People“-Magazin wurde er mehrfach zum „Sexiest Man Alive“ gekrönt. Aber sein Aussehen ist nicht alles: In 30 Jahren Karriere drehte Brad Pitt eine Vielzahl herausragender Filme....", is_upcoming: false,
), short_description: Some("Vom „People“-Magazin wurde er mehrfach zum „Sexiest Man Alive“ gekrönt. Aber sein Aussehen ist nicht alles: In 30 Jahren Karriere drehte Brad Pitt eine Vielzahl herausragender Filme...."),
SearchVideo( )),
Video(VideoItem(
id: "mFxi3lOAcFs", id: "mFxi3lOAcFs",
title: "Craziest Soviet Machines You Won\'t Believe Exist - Part 1", title: "Craziest Soviet Machines You Won\'t Believe Exist - Part 1",
length: Some(1569), length: Some(1569),
@ -366,7 +376,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCkQO3QsgTpNTsOw6ujimT5Q", id: "UCkQO3QsgTpNTsOw6ujimT5Q",
name: "BE AMAZED", name: "BE AMAZED",
avatar: [ avatar: [
@ -376,17 +386,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 14056843, view_count: Some(14056843),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Coming up are some crazy Soviet-era machines you won\'t believe exist!\nPart 2: https://youtu.be/MBZVOJrhuHY\nSuggest a topic here to be turned into a video: http://bit.ly/2kwqhuh\nSubscribe for...", is_upcoming: false,
), short_description: Some("Coming up are some crazy Soviet-era machines you won\'t believe exist!\nPart 2: https://youtu.be/MBZVOJrhuHY\nSuggest a topic here to be turned into a video: http://bit.ly/2kwqhuh\nSubscribe for..."),
SearchVideo( )),
Video(VideoItem(
id: "eu7ubm7g59E", id: "eu7ubm7g59E",
title: "People Hated Me For Using This Slab", title: "People Hated Me For Using This Slab",
length: Some(1264), length: Some(1264),
@ -402,7 +413,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC6I0KzAD7uFTL1qzxyunkvA", id: "UC6I0KzAD7uFTL1qzxyunkvA",
name: "Blacktail Studio", name: "Blacktail Studio",
avatar: [ avatar: [
@ -412,17 +423,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 2845035, view_count: Some(2845035),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Some people were furious I used this slab, and I actually understand why. \nBlacktail bow tie jig (limited first run): https://www.blacktailstudio.com/bowtie-jig\nBlacktail epoxy table workshop:...", is_upcoming: false,
), short_description: Some("Some people were furious I used this slab, and I actually understand why. \nBlacktail bow tie jig (limited first run): https://www.blacktailstudio.com/bowtie-jig\nBlacktail epoxy table workshop:..."),
SearchVideo( )),
Video(VideoItem(
id: "TRGHIN2PGIA", id: "TRGHIN2PGIA",
title: "Christian Bale Breaks Down His Most Iconic Characters | GQ", title: "Christian Bale Breaks Down His Most Iconic Characters | GQ",
length: Some(1381), length: Some(1381),
@ -438,7 +450,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCsEukrAd64fqA7FjwkmZ_Dw", id: "UCsEukrAd64fqA7FjwkmZ_Dw",
name: "GQ", name: "GQ",
avatar: [ avatar: [
@ -448,17 +460,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("9 days ago"), publish_date_txt: Some("9 days ago"),
view_count: 8044465, view_count: Some(8044465),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Christian Bale breaks down a few of his most iconic characters from \'American Psycho,\' \'The Dark Knight\' Trilogy, \'The Fighter,\' \'The Machinist,\' \'The Big Short,\' \'Vice,\' \'Empire of the Sun,\'...", is_upcoming: false,
), short_description: Some("Christian Bale breaks down a few of his most iconic characters from \'American Psycho,\' \'The Dark Knight\' Trilogy, \'The Fighter,\' \'The Machinist,\' \'The Big Short,\' \'Vice,\' \'Empire of the Sun,\'..."),
SearchVideo( )),
Video(VideoItem(
id: "w3tENzcssDU", id: "w3tENzcssDU",
title: "NFL Trick Plays But They Get Increasingly Higher IQ", title: "NFL Trick Plays But They Get Increasingly Higher IQ",
length: Some(599), length: Some(599),
@ -474,7 +487,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCJka5SDh36_N4pjJd69efkg", id: "UCJka5SDh36_N4pjJd69efkg",
name: "Savage Brick Sports", name: "Savage Brick Sports",
avatar: [ avatar: [
@ -484,17 +497,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 1172372, view_count: Some(1172372),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "NFL Trick Plays But They Get Increasingly Higher IQ\nCredit to CoshReport for starting this trend.\n\n(if any of the links don\'t work, check most recent video)\nTalkSports Discord: https://discord.gg/n...", is_upcoming: false,
), short_description: Some("NFL Trick Plays But They Get Increasingly Higher IQ\nCredit to CoshReport for starting this trend.\n\n(if any of the links don\'t work, check most recent video)\nTalkSports Discord: https://discord.gg/n..."),
SearchVideo( )),
Video(VideoItem(
id: "gUAd2XXzH7w", id: "gUAd2XXzH7w",
title: "⚓\u{fe0f}Found ABANDONED SHIP!!! Big CRUISE SHIP on a desert island☠\u{fe0f} Where did the people go?!?", title: "⚓\u{fe0f}Found ABANDONED SHIP!!! Big CRUISE SHIP on a desert island☠\u{fe0f} Where did the people go?!?",
length: Some(2949), length: Some(2949),
@ -510,7 +524,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UClUZos7yKYtrmr0-azaD8pw", id: "UClUZos7yKYtrmr0-azaD8pw",
name: "Kreosan English", name: "Kreosan English",
avatar: [ avatar: [
@ -520,17 +534,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 1883533, view_count: Some(1883533),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "We are preparing a continuation of the cruise ship for you! Very soon you will be able to see the next part. If you would like to help us make a video:\n\n► Support us - https://www.patreon.com/k...", is_upcoming: false,
), short_description: Some("We are preparing a continuation of the cruise ship for you! Very soon you will be able to see the next part. If you would like to help us make a video:\n\n► Support us - https://www.patreon.com/k..."),
SearchVideo( )),
Video(VideoItem(
id: "YpGjaJ1ettI", id: "YpGjaJ1ettI",
title: "[Working BGM] Comfortable music that makes you feel positive -- Morning Mood -- Daily Routine", title: "[Working BGM] Comfortable music that makes you feel positive -- Morning Mood -- Daily Routine",
length: Some(3651), length: Some(3651),
@ -546,7 +561,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCpxY9-3iB5Hyho31uBgzh7w", id: "UCpxY9-3iB5Hyho31uBgzh7w",
name: "Daily Routine", name: "Daily Routine",
avatar: [ avatar: [
@ -556,17 +571,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 1465389, view_count: Some(1465389),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Hello everyone. It\'s me again. I will stay at home and study . It\'s full of fun energy today, so it\'s ready to spread to everyone with hilarious music. 🔥🔥🔥\nHave fun together 😊😊😊...", is_upcoming: false,
), short_description: Some("Hello everyone. It\'s me again. I will stay at home and study . It\'s full of fun energy today, so it\'s ready to spread to everyone with hilarious music. 🔥🔥🔥\nHave fun together 😊😊😊..."),
SearchVideo( )),
Video(VideoItem(
id: "rPAhFD8hKxQ", id: "rPAhFD8hKxQ",
title: "Survival Camping 9ft/3m Under Snow - Giant Winter Bushcraft Shelter and Quinzee", title: "Survival Camping 9ft/3m Under Snow - Giant Winter Bushcraft Shelter and Quinzee",
length: Some(1301), length: Some(1301),
@ -582,7 +598,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCfpCQ89W9wjkHc8J_6eTbBg", id: "UCfpCQ89W9wjkHc8J_6eTbBg",
name: "Outdoor Boys", name: "Outdoor Boys",
avatar: [ avatar: [
@ -592,17 +608,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 20488431, view_count: Some(20488431),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Solo winter camping and bushcraft 9 feet (3 meters) under the snow. I hiked high up into the mountains during a snow storm with 30 mph/48 kmh winds to build a deep snow bushcraft survival shelter...", is_upcoming: false,
), short_description: Some("Solo winter camping and bushcraft 9 feet (3 meters) under the snow. I hiked high up into the mountains during a snow storm with 30 mph/48 kmh winds to build a deep snow bushcraft survival shelter..."),
SearchVideo( )),
Video(VideoItem(
id: "2rye4u-cCNk", id: "2rye4u-cCNk",
title: "Pink Panther Fights Off Pests | 54 Minute Compilation | The Pink Panther Show", title: "Pink Panther Fights Off Pests | 54 Minute Compilation | The Pink Panther Show",
length: Some(3158), length: Some(3158),
@ -618,7 +635,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCFeUyPY6W8qX8w2o6oSiRmw", id: "UCFeUyPY6W8qX8w2o6oSiRmw",
name: "Official Pink Panther", name: "Official Pink Panther",
avatar: [ avatar: [
@ -628,17 +645,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 months ago"), publish_date_txt: Some("11 months ago"),
view_count: 27357653, view_count: Some(27357653),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "(1) Pink Pest Control\n(2) Pink-a-Boo\n(3) Little Beaux Pink\n(4) The Pink Package Plot\n(5) Come On In! The Water\'s Pink\n(6) Psychedelic Pink\n(7) Pink Posies\n(8) G.I. Pink\n\nThe Pink Panther is...", is_upcoming: false,
), short_description: Some("(1) Pink Pest Control\n(2) Pink-a-Boo\n(3) Little Beaux Pink\n(4) The Pink Package Plot\n(5) Come On In! The Water\'s Pink\n(6) Psychedelic Pink\n(7) Pink Posies\n(8) G.I. Pink\n\nThe Pink Panther is..."),
SearchVideo( )),
Video(VideoItem(
id: "O0xAlfSaBNQ", id: "O0xAlfSaBNQ",
title: "FC Nantes vs. SC Freiburg Highlights & Tore | UEFA Europa League", title: "FC Nantes vs. SC Freiburg Highlights & Tore | UEFA Europa League",
length: Some(326), length: Some(326),
@ -654,7 +672,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC8WYi3XQXsf-6FNvqoEvxag", id: "UC8WYi3XQXsf-6FNvqoEvxag",
name: "RTL Sport", name: "RTL Sport",
avatar: [ avatar: [
@ -664,17 +682,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 hours ago"), publish_date_txt: Some("11 hours ago"),
view_count: 117395, view_count: Some(117395),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "UEFA Europa League: https://www.rtlplus.com/shows/uefa-europa-league-19818?utm_source=youtube&utm_medium=editorial&utm_campaign=beschreibung&utm_term=rtlsport \nFC Nantes vs. SC Freiburg ...", is_upcoming: false,
), short_description: Some("UEFA Europa League: https://www.rtlplus.com/shows/uefa-europa-league-19818?utm_source=youtube&utm_medium=editorial&utm_campaign=beschreibung&utm_term=rtlsport \nFC Nantes vs. SC Freiburg ..."),
SearchVideo( )),
Video(VideoItem(
id: "Mhs9Sbnw19o", id: "Mhs9Sbnw19o",
title: "Dramatisches Duell: 400 Jahre altes Kästchen erzielt zig-fachen Wunschpreis! | Bares für Rares XXL", title: "Dramatisches Duell: 400 Jahre altes Kästchen erzielt zig-fachen Wunschpreis! | Bares für Rares XXL",
length: Some(744), length: Some(744),
@ -690,7 +709,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC53bIpnef1pwAx69ERmmOLA", id: "UC53bIpnef1pwAx69ERmmOLA",
name: "Bares für Rares", name: "Bares für Rares",
avatar: [ avatar: [
@ -700,17 +719,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 days ago"), publish_date_txt: Some("11 days ago"),
view_count: 836333, view_count: Some(836333),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Du hast Schätze im Keller, die du unseren Expert*innen präsentieren möchtest? Hier geht\'s zum Bewerbungsformular: kurz.zdf.de/lSJ/\n\nEin einmaliges Bieterduell treibt den Preis für dieses...", is_upcoming: false,
), short_description: Some("Du hast Schätze im Keller, die du unseren Expert*innen präsentieren möchtest? Hier geht\'s zum Bewerbungsformular: kurz.zdf.de/lSJ/\n\nEin einmaliges Bieterduell treibt den Preis für dieses..."),
SearchVideo( )),
Video(VideoItem(
id: "Bzzp5Cay7DI", id: "Bzzp5Cay7DI",
title: "Sweet Jazz - Cool autumn Bossa Nova & October Jazz Positive Mood", title: "Sweet Jazz - Cool autumn Bossa Nova & October Jazz Positive Mood",
length: None, length: None,
@ -726,7 +746,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCoGlllJE7aYe_VzIGP3s_wA", id: "UCoGlllJE7aYe_VzIGP3s_wA",
name: "Smooth Jazz Music", name: "Smooth Jazz Music",
avatar: [ avatar: [
@ -736,17 +756,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 1216, view_count: Some(1216),
is_live: false, is_live: true,
is_short: false, is_short: false,
short_description: "Sweet Jazz - Cool autumn Bossa Nova & October Jazz Positive Mood\nhttps://youtu.be/Bzzp5Cay7DI\n********************************************\nSounds available on: Jazz Bossa Nova\nOFFICIAL VIDEO:...", is_upcoming: false,
), short_description: Some("Sweet Jazz - Cool autumn Bossa Nova & October Jazz Positive Mood\nhttps://youtu.be/Bzzp5Cay7DI\n********************************************\nSounds available on: Jazz Bossa Nova\nOFFICIAL VIDEO:..."),
SearchVideo( )),
Video(VideoItem(
id: "SlskTqc9CEc", id: "SlskTqc9CEc",
title: "The Chick-Fil-A Full Menu Challenge", title: "The Chick-Fil-A Full Menu Challenge",
length: Some(613), length: Some(613),
@ -762,7 +783,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCd1fLoVFooPeWqCEYVUJZqg", id: "UCd1fLoVFooPeWqCEYVUJZqg",
name: "Matt Stonie", name: "Matt Stonie",
avatar: [ avatar: [
@ -772,17 +793,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 39286403, view_count: Some(39286403),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Good Video? Like/Fav & Share!!\n\nTBH this is really my 1st time trying Chick-Fil-A, legitimately. My verdict is torn, but that sauce is BOMB!\n\nChallenge\n+ Chick-Fil-A Deluxe\n+ Spicy Deluxe\n+...", is_upcoming: false,
), short_description: Some("Good Video? Like/Fav & Share!!\n\nTBH this is really my 1st time trying Chick-Fil-A, legitimately. My verdict is torn, but that sauce is BOMB!\n\nChallenge\n+ Chick-Fil-A Deluxe\n+ Spicy Deluxe\n+..."),
SearchVideo( )),
Video(VideoItem(
id: "CwRvM2TfYbs", id: "CwRvM2TfYbs",
title: "Gentle healing music of health and to calm the nervous system, deep relaxation! Say Life Yes", title: "Gentle healing music of health and to calm the nervous system, deep relaxation! Say Life Yes",
length: None, length: None,
@ -798,7 +820,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC6jH5GNi0iOR17opA1Vowhw", id: "UC6jH5GNi0iOR17opA1Vowhw",
name: "Lucid Dream", name: "Lucid Dream",
avatar: [ avatar: [
@ -808,17 +830,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 1416, view_count: Some(1416),
is_live: false, is_live: true,
is_short: false, is_short: false,
short_description: "🌿 Music for relaxation, meditation, study, reading, massage, spa or sleep. This music is ideal for dealing with anxiety, stress or insomnia as it promotes relaxation and helps eliminate...", is_upcoming: false,
), short_description: Some("🌿 Music for relaxation, meditation, study, reading, massage, spa or sleep. This music is ideal for dealing with anxiety, stress or insomnia as it promotes relaxation and helps eliminate..."),
SearchVideo( )),
Video(VideoItem(
id: "7jz0pXSe_kI", id: "7jz0pXSe_kI",
title: "Craziest \"Fine...I\'ll Do it Myself\" Moments in Sports History (PART 2)", title: "Craziest \"Fine...I\'ll Do it Myself\" Moments in Sports History (PART 2)",
length: Some(1822), length: Some(1822),
@ -834,7 +857,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCd5hdemikI6GxwGKhJCwzww", id: "UCd5hdemikI6GxwGKhJCwzww",
name: "Highlight Reel", name: "Highlight Reel",
avatar: [ avatar: [
@ -844,16 +867,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("10 months ago"), publish_date_txt: Some("10 months ago"),
view_count: 11601863, view_count: Some(11601863),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "(PART 2) of 👉🏼 Craziest \"Fine...I\'ll Do It Myself\" Moments in Sports History \n\nBIBLE VERSE OF THE DAY: Luke 12:40", is_upcoming: false,
), short_description: Some("(PART 2) of 👉🏼 Craziest \"Fine...I\'ll Do It Myself\" Moments in Sports History \n\nBIBLE VERSE OF THE DAY: Luke 12:40"),
)),
], ],
ctoken: Some("4qmFsgKxAxIPRkV3aGF0X3RvX3dhdGNoGoADQ0RCNmxnSkhUWFpRYzJOVU1UUm1iME5OWjNOSmQzWjZOM0JPWlZWMldqZDFRVlp3ZEVOdGMwdEhXR3d3V0ROQ2FGb3lWbVpqTWpWb1kwaE9iMkl6VW1aamJWWnVZVmM1ZFZsWGQxTklNVlUwVDFSU1dXUXhUbXhXTTBaeVdsaGtSRkpGYkZCWk0yaDZWbXMxTlV4VmVGbE1XRnBSVlcxallVeFJRVUZhVnpSQlFWWldWRUZCUmtWU1VVRkNRVVZhUm1ReWFHaGtSamt3WWpFNU0xbFlVbXBoUVVGQ1FVRkZRa0ZCUVVKQlFVVkJRVUZGUWtGSFNrSkRRVUZUUlROQ2FGb3lWbVpqTWpWb1kwaE9iMkl6VW1aa1J6bHlXbGMwWVVWM2Ftb3hPRkJGT1dWSU5rRm9WVlpZWlVGTFNGaHVSMEp2ZDJsRmQycERObkZmUlRsbFNEWkJhRmRIZG1RMFMwaGxaMGhDTlZnMmJrMWxPVU5SU1VsTlVRJTNEJTNEmgIaYnJvd3NlLWZlZWRGRXdoYXRfdG9fd2F0Y2g%3D"), ctoken: Some("4qmFsgKxAxIPRkV3aGF0X3RvX3dhdGNoGoADQ0RCNmxnSkhUWFpRYzJOVU1UUm1iME5OWjNOSmQzWjZOM0JPWlZWMldqZDFRVlp3ZEVOdGMwdEhXR3d3V0ROQ2FGb3lWbVpqTWpWb1kwaE9iMkl6VW1aamJWWnVZVmM1ZFZsWGQxTklNVlUwVDFSU1dXUXhUbXhXTTBaeVdsaGtSRkpGYkZCWk0yaDZWbXMxTlV4VmVGbE1XRnBSVlcxallVeFJRVUZhVnpSQlFWWldWRUZCUmtWU1VVRkNRVVZhUm1ReWFHaGtSamt3WWpFNU0xbFlVbXBoUVVGQ1FVRkZRa0ZCUVVKQlFVVkJRVUZGUWtGSFNrSkRRVUZUUlROQ2FGb3lWbVpqTWpWb1kwaE9iMkl6VW1aa1J6bHlXbGMwWVVWM2Ftb3hPRkJGT1dWSU5rRm9WVlpZWlVGTFNGaHVSMEp2ZDJsRmQycERObkZmUlRsbFNEWkJhRmRIZG1RMFMwaGxaMGhDTlZnMmJrMWxPVU5SU1VsTlVRJTNEJTNEmgIaYnJvd3NlLWZlZWRGRXdoYXRfdG9fd2F0Y2g%3D"),
endpoint: browse,
) )

File diff suppressed because it is too large Load diff

View file

@ -3110,6 +3110,7 @@ Playlist(
), ),
], ],
ctoken: Some("4qmFsgJhEiRWTFBMNWREeDY4MVQ0YlI3WkYxSXVXek92MW9tbFJiRTdQaUoaFENBRjZCbEJVT2tOSFdRJTNEJTNEmgIiUEw1ZER4NjgxVDRiUjdaRjFJdVd6T3Yxb21sUmJFN1BpSg%3D%3D"), ctoken: Some("4qmFsgJhEiRWTFBMNWREeDY4MVQ0YlI3WkYxSXVXek92MW9tbFJiRTdQaUoaFENBRjZCbEJVT2tOSFdRJTNEJTNEmgIiUEw1ZER4NjgxVDRiUjdaRjFJdVd6T3Yxb21sUmJFN1BpSg%3D%3D"),
endpoint: browse,
), ),
video_count: 495, video_count: 495,
thumbnail: [ thumbnail: [

View file

@ -2056,6 +2056,7 @@ Playlist(
), ),
], ],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
video_count: 66, video_count: 66,
thumbnail: [ thumbnail: [

View file

@ -3017,6 +3017,7 @@ Playlist(
), ),
], ],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
video_count: 97, video_count: 97,
thumbnail: [ thumbnail: [

View file

@ -6,7 +6,7 @@ SearchResult(
items: Paginator( items: Paginator(
count: Some(7499), count: Some(7499),
items: [ items: [
Channel(SearchChannel( Channel(ChannelItem(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -21,12 +21,12 @@ SearchResult(
height: 176, height: 176,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: Some(292), subscriber_count: Some(292),
video_count: 219, video_count: 219,
short_description: "Hi, I\'m Tina, aka Doobydobap! Food is the medium I use to tell stories and connect with people who share the same passion as I\u{a0}...", short_description: "Hi, I\'m Tina, aka Doobydobap! Food is the medium I use to tell stories and connect with people who share the same passion as I\u{a0}...",
)), )),
Video(SearchVideo( Video(VideoItem(
id: "1VW7iXRIrc8", id: "1VW7iXRIrc8",
title: "Alone, in the City of Love", title: "Alone, in the City of Love",
length: Some(1875), length: Some(1875),
@ -42,7 +42,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -52,17 +52,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 531580, view_count: Some(531580),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "I know it\'s a little long, but I hope you enjoyed this Paris vlog :} Location Udon Restaurant: Sanukiya 9 Rue d\'Argenteuil, Paris\u{a0}...", is_upcoming: false,
short_description: Some("I know it\'s a little long, but I hope you enjoyed this Paris vlog :} Location Udon Restaurant: Sanukiya 9 Rue d\'Argenteuil, Paris\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "9NuhKCv3crg", id: "9NuhKCv3crg",
title: "the end.", title: "the end.",
length: Some(982), length: Some(982),
@ -78,7 +79,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -88,17 +89,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 days ago"), publish_date_txt: Some("7 days ago"),
view_count: 974475, view_count: Some(974475),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "or the start of something new~~~~~ Thank you for your patience on the vlog, it took some time to adjust to my new normal. Excited\u{a0}...", is_upcoming: false,
short_description: Some("or the start of something new~~~~~ Thank you for your patience on the vlog, it took some time to adjust to my new normal. Excited\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "hGbQ2WM9nOo", id: "hGbQ2WM9nOo",
title: "Why does everything bad for you taste good ㅣ CHILI OIL RAMEN", title: "Why does everything bad for you taste good ㅣ CHILI OIL RAMEN",
length: Some(428), length: Some(428),
@ -114,7 +116,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -124,17 +126,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 1034415, view_count: Some(1034415),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "https://partner.bokksu.com/doobydobap use code DOOBYDOBAP to get $15 off your first bokksu order! Instagram @doobydobap\u{a0}...", is_upcoming: false,
short_description: Some("https://partner.bokksu.com/doobydobap use code DOOBYDOBAP to get $15 off your first bokksu order! Instagram @doobydobap\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "PxGmP4v_A38", id: "PxGmP4v_A38",
title: "Alone and Thriving l late night korean convenience store, muji kitchenware haul, spring cleaning!", title: "Alone and Thriving l late night korean convenience store, muji kitchenware haul, spring cleaning!",
length: Some(1437), length: Some(1437),
@ -150,7 +153,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -160,17 +163,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 831908, view_count: Some(831908),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "I could palpably feel how I\'m so much happier than before when I was reviewing my footage All the finalized recipes will be\u{a0}...", is_upcoming: false,
short_description: Some("I could palpably feel how I\'m so much happier than before when I was reviewing my footage All the finalized recipes will be\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "38Gd6TdmNVs", id: "38Gd6TdmNVs",
title: "KOREAN BARBECUE l doob gourmand ep.3", title: "KOREAN BARBECUE l doob gourmand ep.3",
length: Some(525), length: Some(525),
@ -186,7 +190,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -196,17 +200,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 354486, view_count: Some(354486),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "I haven\'t done a doob gourmand series in so so long! I hope you enjoyed it, let me know what kind of food you\'re interested in\u{a0}...", is_upcoming: false,
short_description: Some("I haven\'t done a doob gourmand series in so so long! I hope you enjoyed it, let me know what kind of food you\'re interested in\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "CutR_1SDDzY", id: "CutR_1SDDzY",
title: "feels good to be back", title: "feels good to be back",
length: Some(1159), length: Some(1159),
@ -222,7 +227,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -232,17 +237,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 524950, view_count: Some(524950),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "I missed you guys. Happy to see you guys back. I\'ve really been working on my mental health, educating myself with different food\u{a0}...", is_upcoming: false,
short_description: Some("I missed you guys. Happy to see you guys back. I\'ve really been working on my mental health, educating myself with different food\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "pRVSdUxdsVw", id: "pRVSdUxdsVw",
title: "Repairing...", title: "Repairing...",
length: Some(965), length: Some(965),
@ -258,7 +264,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -268,17 +274,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 weeks ago"), publish_date_txt: Some("4 weeks ago"),
view_count: 528595, view_count: Some(528595),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "The word repair stems from the Latin word reparare, from re- \'back\' and parare \'make ready.\' And I feel that\'s exactly how I feel\u{a0}...", is_upcoming: false,
short_description: Some("The word repair stems from the Latin word reparare, from re- \'back\' and parare \'make ready.\' And I feel that\'s exactly how I feel\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "KUz7oArksR4", id: "KUz7oArksR4",
title: "running away", title: "running away",
length: Some(1023), length: Some(1023),
@ -294,7 +301,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -304,17 +311,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 717515, view_count: Some(717515),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "for now... more adventures to come! Music by Mark Generous - A Summer Day - https://thmatc.co/?l=CF6C5FFF Instagram\u{a0}...", is_upcoming: false,
short_description: Some("for now... more adventures to come! Music by Mark Generous - A Summer Day - https://thmatc.co/?l=CF6C5FFF Instagram\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "sPb2gyN-hnE", id: "sPb2gyN-hnE",
title: "worth fighting for", title: "worth fighting for",
length: Some(1232), length: Some(1232),
@ -330,7 +338,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -340,17 +348,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 624386, view_count: Some(624386),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Please be respectful in the comments section! I will not be tolerating any hateful/derogatory speech *barking noise* Music\u{a0}...", is_upcoming: false,
short_description: Some("Please be respectful in the comments section! I will not be tolerating any hateful/derogatory speech *barking noise* Music\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "rriwHj8U664", id: "rriwHj8U664",
title: "my seoul apartment tour", title: "my seoul apartment tour",
length: Some(721), length: Some(721),
@ -366,7 +375,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -376,17 +385,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 696942, view_count: Some(696942),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Korea has an interesting rent structure called junseh where you pay a higher security deposit in turn for lower rent! And before\u{a0}...", is_upcoming: false,
short_description: Some("Korea has an interesting rent structure called junseh where you pay a higher security deposit in turn for lower rent! And before\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "PXsK9-CFoH4", id: "PXsK9-CFoH4",
title: "waiting...", title: "waiting...",
length: Some(1455), length: Some(1455),
@ -402,7 +412,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -412,17 +422,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 923749, view_count: Some(923749),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "tuna kimchi jook 2 cups cooked rice 3 cups water 1 cup kimchi 320g canned tuna 1 tbsp perilla seed oil 1 onion 1 tbsp gochujang\u{a0}...", is_upcoming: false,
short_description: Some("tuna kimchi jook 2 cups cooked rice 3 cups water 1 cup kimchi 320g canned tuna 1 tbsp perilla seed oil 1 onion 1 tbsp gochujang\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "bXbmYelTnhw", id: "bXbmYelTnhw",
title: "Doobydobap rates British desserts!", title: "Doobydobap rates British desserts!",
length: Some(865), length: Some(865),
@ -438,7 +449,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOgGAfSUy5LvEyVS_LF5kdw", id: "UCOgGAfSUy5LvEyVS_LF5kdw",
name: "JOLLY", name: "JOLLY",
avatar: [ avatar: [
@ -448,17 +459,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 1282467, view_count: Some(1282467),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Today we introduce @Doobydobap to the best of British desserts! Massive thanks to Dooby for joining us for this episode.", is_upcoming: false,
short_description: Some("Today we introduce @Doobydobap to the best of British desserts! Massive thanks to Dooby for joining us for this episode."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "0onVbAuBGWI", id: "0onVbAuBGWI",
title: "Out of Control", title: "Out of Control",
length: Some(1125), length: Some(1125),
@ -474,7 +486,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -484,17 +496,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 months ago"), publish_date_txt: Some("8 months ago"),
view_count: 1649656, view_count: Some(1649656),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Hey doobies, I know I promised a cookie recipe in my last vlog, but I haven\'t yet developed one of my own just yet-- still recipe\u{a0}...", is_upcoming: false,
short_description: Some("Hey doobies, I know I promised a cookie recipe in my last vlog, but I haven\'t yet developed one of my own just yet-- still recipe\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "FKJtrUeol3o", id: "FKJtrUeol3o",
title: "with quantity comes quality", title: "with quantity comes quality",
length: Some(1140), length: Some(1140),
@ -510,7 +523,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -520,17 +533,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 months ago"), publish_date_txt: Some("4 months ago"),
view_count: 1085725, view_count: Some(1085725),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "A busy, but calm week for me here in Seoul living alone. Planning on exploring more parts of Korea, please let me know in the\u{a0}...", is_upcoming: false,
short_description: Some("A busy, but calm week for me here in Seoul living alone. Planning on exploring more parts of Korea, please let me know in the\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "dkMtSrjDLO0", id: "dkMtSrjDLO0",
title: "How to make Naruto\'s favorite ramen", title: "How to make Naruto\'s favorite ramen",
length: Some(802), length: Some(802),
@ -546,7 +560,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -556,17 +570,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("10 months ago"), publish_date_txt: Some("10 months ago"),
view_count: 1327833, view_count: Some(1327833),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Broth * 1 large chicken * 1 leek & ½ onion charred * 1 leek & ½ onion * 1 tbsp ginger * 6 garlic cloves Tare * leftover cha shu\u{a0}...", is_upcoming: false,
short_description: Some("Broth * 1 large chicken * 1 leek & ½ onion charred * 1 leek & ½ onion * 1 tbsp ginger * 6 garlic cloves Tare * leftover cha shu\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "r2ye6zW0nbM", id: "r2ye6zW0nbM",
title: "a wedding", title: "a wedding",
length: Some(1207), length: Some(1207),
@ -582,7 +597,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -592,17 +607,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 1052801, view_count: Some(1052801),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Ginger Pork Recipe! https://doobydobap.com/recipe/ginger-pork-shogayaki - Instagram @doobydobap Join my discord!", is_upcoming: false,
short_description: Some("Ginger Pork Recipe! https://doobydobap.com/recipe/ginger-pork-shogayaki - Instagram @doobydobap Join my discord!"),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "NudTbo2CJMY", id: "NudTbo2CJMY",
title: "Flying to London", title: "Flying to London",
length: Some(1078), length: Some(1078),
@ -618,7 +634,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -628,17 +644,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 1137136, view_count: Some(1137136),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Tomato Beef Curry 1 packet Japanese Curry Roux 250g thinly sliced beef 2 large onions 2 tbsp butter 2 tbsp neutral oil 1 can\u{a0}...", is_upcoming: false,
short_description: Some("Tomato Beef Curry 1 packet Japanese Curry Roux 250g thinly sliced beef 2 large onions 2 tbsp butter 2 tbsp neutral oil 1 can\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "gK-jLnvVsb0", id: "gK-jLnvVsb0",
title: "Contradicting myself", title: "Contradicting myself",
length: Some(1381), length: Some(1381),
@ -654,7 +671,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -664,17 +681,18 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 months ago"), publish_date_txt: Some("8 months ago"),
view_count: 928967, view_count: Some(928967),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Sesame Granola Recipe 2 cups old-fashioned instant oats 2 cups mixture of seeds / nuts of your choice (I used ½ cup each of\u{a0}...", is_upcoming: false,
short_description: Some("Sesame Granola Recipe 2 cups old-fashioned instant oats 2 cups mixture of seeds / nuts of your choice (I used ½ cup each of\u{a0}..."),
)), )),
Video(SearchVideo( Video(VideoItem(
id: "fAFFTOpUNWo", id: "fAFFTOpUNWo",
title: "Come Grocery Shopping with Me", title: "Come Grocery Shopping with Me",
length: Some(1126), length: Some(1126),
@ -690,7 +708,7 @@ SearchResult(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
avatar: [ avatar: [
@ -700,18 +718,20 @@ SearchResult(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 months ago"), publish_date_txt: Some("8 months ago"),
view_count: 1077297, view_count: Some(1077297),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Pecan Banana Bread with Coffee Liquor Recipe https://doobydobap.com/recipe/pecan-banana-bread-with-coffee-liquor Music\u{a0}...", is_upcoming: false,
short_description: Some("Pecan Banana Bread with Coffee Liquor Recipe https://doobydobap.com/recipe/pecan-banana-bread-with-coffee-liquor Music\u{a0}..."),
)), )),
], ],
ctoken: Some("EqsDEgpkb29ieWRvYmFwGpwDU0JTQ0FSaFZRMmc0WjBoa2RIcFBNblJZWkRVNU0xOWlha1Z5VjJlQ0FRc3hWbGMzYVZoU1NYSmpPSUlCQ3psT2RXaExRM1l6WTNKbmdnRUxhRWRpVVRKWFRUbHVUMi1DQVF0UWVFZHRVRFIyWDBFek9JSUJDek00UjJRMlZHUnRUbFp6Z2dFTFEzVjBVbDh4VTBSRWVsbUNBUXR3VWxaVFpGVjRaSE5XZDRJQkMwdFZlamR2UVhKcmMxSTBnZ0VMYzFCaU1tZDVUaTFvYmtXQ0FRdHljbWwzU0dvNFZUWTJOSUlCQzFCWWMwczVMVU5HYjBnMGdnRUxZbGhpYlZsbGJGUnVhSGVDQVFzd2IyNVdZa0YxUWtkWFNZSUJDMFpMU25SeVZXVnZiRE52Z2dFTFpHdE5kRk55YWtSTVR6Q0NBUXR5TW5sbE5ucFhNRzVpVFlJQkMwNTFaRlJpYnpKRFNrMVpnZ0VMWjBzdGFreHVkbFp6WWpDQ0FRdG1RVVpHVkU5d1ZVNVhiN0lCQmdvRUNCY1FBZyUzRCUzRBiB4OgYIgtzZWFyY2gtZmVlZA%3D%3D"), ctoken: Some("EqsDEgpkb29ieWRvYmFwGpwDU0JTQ0FSaFZRMmc0WjBoa2RIcFBNblJZWkRVNU0xOWlha1Z5VjJlQ0FRc3hWbGMzYVZoU1NYSmpPSUlCQ3psT2RXaExRM1l6WTNKbmdnRUxhRWRpVVRKWFRUbHVUMi1DQVF0UWVFZHRVRFIyWDBFek9JSUJDek00UjJRMlZHUnRUbFp6Z2dFTFEzVjBVbDh4VTBSRWVsbUNBUXR3VWxaVFpGVjRaSE5XZDRJQkMwdFZlamR2UVhKcmMxSTBnZ0VMYzFCaU1tZDVUaTFvYmtXQ0FRdHljbWwzU0dvNFZUWTJOSUlCQzFCWWMwczVMVU5HYjBnMGdnRUxZbGhpYlZsbGJGUnVhSGVDQVFzd2IyNVdZa0YxUWtkWFNZSUJDMFpMU25SeVZXVnZiRE52Z2dFTFpHdE5kRk55YWtSTVR6Q0NBUXR5TW5sbE5ucFhNRzVpVFlJQkMwNTFaRlJpYnpKRFNrMVpnZ0VMWjBzdGFreHVkbFp6WWpDQ0FRdG1RVVpHVkU5d1ZVNVhiN0lCQmdvRUNCY1FBZyUzRCUzRBiB4OgYIgtzZWFyY2gtZmVlZA%3D%3D"),
endpoint: browse,
), ),
corrected_query: Some("doobydobap"), corrected_query: Some("doobydobap"),
) )

View file

@ -7,6 +7,7 @@ SearchResult(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
corrected_query: None, corrected_query: None,
) )

View file

@ -6,7 +6,7 @@ SearchResult(
items: Paginator( items: Paginator(
count: Some(18932046), count: Some(18932046),
items: [ items: [
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_nmS3YoxSwVVQk9lEQJ0UX4ZCjXsW_psU8", id: "RDCLAK5uy_nmS3YoxSwVVQk9lEQJ0UX4ZCjXsW_psU8",
name: "Pop\'s Biggest Hits", name: "Pop\'s Biggest Hits",
thumbnail: [ thumbnail: [
@ -31,21 +31,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 225, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "XfEMj-z3TtA", avatar: [],
title: "STAY", verification: None,
length: Some(142), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(225),
id: "MozAXGgC1Mc",
title: "Sugar",
length: Some(236),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_mVJ3RRi_YBfUJnZnQxLAedQQcXHujbUcg", id: "RDCLAK5uy_mVJ3RRi_YBfUJnZnQxLAedQQcXHujbUcg",
name: "Pump-Up Pop", name: "Pump-Up Pop",
thumbnail: [ thumbnail: [
@ -70,21 +65,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 100, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "J7p4bzqLvCw", avatar: [],
title: "Blinding Lights", verification: None,
length: Some(202), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(100),
id: "G1ej5up7JG0",
title: "Shivers",
length: Some(208),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_mfdqvCAl8wodlx2P2_Ai2gNkiRDAufkkI", id: "RDCLAK5uy_mfdqvCAl8wodlx2P2_Ai2gNkiRDAufkkI",
name: "Happy Pop Hits", name: "Happy Pop Hits",
thumbnail: [ thumbnail: [
@ -109,21 +99,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 59, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "52QG9C9dnLM", avatar: [],
title: "Better Days", verification: None,
length: Some(161), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(59),
id: "ntG3GQdY_Ok",
title: "Light Switch",
length: Some(186),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_nHSqCJjDrW9HBhCNdF6tWPdnOMngOv0wA", id: "RDCLAK5uy_nHSqCJjDrW9HBhCNdF6tWPdnOMngOv0wA",
name: "Pop Gold", name: "Pop Gold",
thumbnail: [ thumbnail: [
@ -148,21 +133,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 100, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "XqoanTj5pNY", avatar: [],
title: "Someone Like You", verification: None,
length: Some(286), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(100),
id: "th92jw2CFOA",
title: "When I Was Your Man",
length: Some(214),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_lb6CVU6S4uVugLVNTU9WhqfaomWAgnho4", id: "RDCLAK5uy_lb6CVU6S4uVugLVNTU9WhqfaomWAgnho4",
name: "Shout-Out Pop Hits", name: "Shout-Out Pop Hits",
thumbnail: [ thumbnail: [
@ -187,21 +167,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 50, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "cTr-aGK-LpA", avatar: [],
title: "My Head & My Heart", verification: None,
length: Some(175), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(50),
id: "xn0-IZZ6YO4",
title: "abcdefu",
length: Some(169),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_nDL8KeBrUagwyISwNmyEiSfYgz1gVCesg", id: "RDCLAK5uy_nDL8KeBrUagwyISwNmyEiSfYgz1gVCesg",
name: "Mellow Pop Classics", name: "Mellow Pop Classics",
thumbnail: [ thumbnail: [
@ -226,21 +201,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 50, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "fdz_cabS9BU", avatar: [],
title: "Thinking out Loud", verification: None,
length: Some(282), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(50),
id: "BRbTpCrHv4o",
title: "Broken Strings",
length: Some(251),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "PLDIoUOhQQPlVr3qepMVRsDe4T8vNQsvno", id: "PLDIoUOhQQPlVr3qepMVRsDe4T8vNQsvno",
name: "Türkçe Pop Şarkılar 2022 - Yeni Hit Şarkılar 2022", name: "Türkçe Pop Şarkılar 2022 - Yeni Hit Şarkılar 2022",
thumbnail: [ thumbnail: [
@ -265,21 +235,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 220, channel: Some(ChannelTag(
first_videos: [ id: "UCX9oPuvJYZsG8wnHTwOBVPA",
SearchPlaylistVideo( name: "Chillax",
id: "zU2_jPxz9q4", avatar: [],
title: "Ara - Zeynep Bastık (Paro Official ZB Version) | Music Video", verification: None,
length: Some(201), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(220),
id: "vHIf_Gk8GLg",
title: "Mustafa Ceceli & Indira Elemes - İlla",
length: Some(153),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_nfs_t4FUu00E5ED6lveEBBX1VMYe1mFjk", id: "RDCLAK5uy_nfs_t4FUu00E5ED6lveEBBX1VMYe1mFjk",
name: "Dance-Pop Bangers", name: "Dance-Pop Bangers",
thumbnail: [ thumbnail: [
@ -304,21 +269,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 100, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "hJWSZDJb-W4", avatar: [],
title: "Bad Habits", verification: None,
length: Some(231), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(100),
id: "c5l4CGQozWY",
title: "Work from Home",
length: Some(215),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_m_0U5VQNyyzwwH1lRi7cPAAGXqNQnAOqY", id: "RDCLAK5uy_m_0U5VQNyyzwwH1lRi7cPAAGXqNQnAOqY",
name: "Laid-Back Sofa Pop", name: "Laid-Back Sofa Pop",
thumbnail: [ thumbnail: [
@ -343,21 +303,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 67, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "T7iuw9Qx7t4", avatar: [],
title: "Astronomy", verification: None,
length: Some(244), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(67),
id: "p-IXgwqhfmg",
title: "Love Yourself",
length: Some(234),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_mHW5bcduhjB-PkTePAe6EoRMj1xNT8gzY", id: "RDCLAK5uy_mHW5bcduhjB-PkTePAe6EoRMj1xNT8gzY",
name: "K-Pop Girl Crush", name: "K-Pop Girl Crush",
thumbnail: [ thumbnail: [
@ -382,21 +337,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 78, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "18nDrsoii5M", avatar: [],
title: "붐바야 (Boombayah)", verification: None,
length: Some(241), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(78),
id: "miqQAzOXPBo",
title: "달라달라 DALLA DALLA",
length: Some(200),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_kPqJ_FiGk-lbXtgM4IF42uokskSJZiVTI", id: "RDCLAK5uy_kPqJ_FiGk-lbXtgM4IF42uokskSJZiVTI",
name: "Cardio Pop", name: "Cardio Pop",
thumbnail: [ thumbnail: [
@ -421,21 +371,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 80, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "G1ej5up7JG0", avatar: [],
title: "Shivers", verification: None,
length: Some(208), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(80),
id: "vgn-b0ksX4g",
title: "Heaven Takes You Home",
length: Some(215),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "PLI_7Mg2Z_-4Lf7IYeiTEOV8HBn-nMqz5N", id: "PLI_7Mg2Z_-4Lf7IYeiTEOV8HBn-nMqz5N",
name: "Pop 2022 ♫ Mix Pop En Ingles (English Pop Songs 2022)", name: "Pop 2022 ♫ Mix Pop En Ingles (English Pop Songs 2022)",
thumbnail: [ thumbnail: [
@ -460,21 +405,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 70, channel: Some(ChannelTag(
first_videos: [ id: "UC8Ojfs-1VLiAO_MosLwvjpQ",
SearchPlaylistVideo( name: "Redlist - Ultimate Music",
id: "a7GITgqwDVg", avatar: [],
title: "Charlie Puth - Left And Right (feat. Jung Kook of BTS) [Official Video]", verification: None,
length: Some(160), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(70),
id: "H5v3kku4y6Q",
title: "Harry Styles - As It Was (Official Video)",
length: Some(166),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "PLX6L4t7t6ZanfCJ1wBxRdGZ_mk9ygmKqo", id: "PLX6L4t7t6ZanfCJ1wBxRdGZ_mk9ygmKqo",
name: "Deutsch Pop Hits NEU 2022", name: "Deutsch Pop Hits NEU 2022",
thumbnail: [ thumbnail: [
@ -499,21 +439,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 164, channel: Some(ChannelTag(
first_videos: [ id: "UCesP91XKnuZVd6OJN06hokg",
SearchPlaylistVideo( name: "Startup Records",
id: "oE7Fe8QBw1Y", avatar: [],
title: "Johannes Oerding - Kaleidoskop", verification: None,
length: Some(217), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(164),
id: "JvqMO-tWlrU",
title: "Tim Bendzko - DAS LEBEN WIEDER LIEBEN (Offizielles Musikvideo)",
length: Some(169),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "PLMC9KNkIncKtPzgY-5rmhvj7fax8fdxoj", id: "PLMC9KNkIncKtPzgY-5rmhvj7fax8fdxoj",
name: "Pop Music Playlist - Timeless Pop Songs (Updated Weekly 2022)", name: "Pop Music Playlist - Timeless Pop Songs (Updated Weekly 2022)",
thumbnail: [ thumbnail: [
@ -538,21 +473,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 200, channel: Some(ChannelTag(
first_videos: [ id: "UCs72iRpTEuwV3y6pdWYLgiw",
SearchPlaylistVideo( name: "Redlist - Just Hits",
id: "U0CGsw6h60k", avatar: [],
title: "Rihanna - What\'s My Name? ft. Drake", verification: None,
length: Some(265), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(200),
id: "OPf0YbXqDm0",
title: "Mark Ronson - Uptown Funk (Official Video) ft. Bruno Mars",
length: Some(271),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "PLgRdph0qPLy53IhYrQLPpATDDA2TpFey5", id: "PLgRdph0qPLy53IhYrQLPpATDDA2TpFey5",
name: "Teen-Pop 90-2000", name: "Teen-Pop 90-2000",
thumbnail: [ thumbnail: [
@ -577,21 +507,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 50, channel: Some(ChannelTag(
first_videos: [ id: "UCv9O2E_G8U46Paz8828THJw",
SearchPlaylistVideo( name: "Victor Vaz",
id: "4fndeDfaWCg", avatar: [],
title: "Backstreet Boys - I Want It That Way (Official HD Video)", verification: None,
length: Some(220), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(50),
id: "gJLIiF15wjQ",
title: "Spice Girls - Wannabe (Official Music Video)",
length: Some(236),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_nCVF_zUZizzRcojIUuYmaXxMoPgg2WMDo", id: "RDCLAK5uy_nCVF_zUZizzRcojIUuYmaXxMoPgg2WMDo",
name: "Klangfarbe: German Pop Hits", name: "Klangfarbe: German Pop Hits",
thumbnail: [ thumbnail: [
@ -616,21 +541,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 52, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "jBFcbfteBDU", avatar: [],
title: "Ich hass dich", verification: None,
length: Some(194), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(52),
id: "CjV7rkhQ66I",
title: "ROSES",
length: Some(148),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_lY6JFrs7W9yIhFjUN_yxQ_ubkjcrqQaVs", id: "RDCLAK5uy_lY6JFrs7W9yIhFjUN_yxQ_ubkjcrqQaVs",
name: "Bedroom Pop", name: "Bedroom Pop",
thumbnail: [ thumbnail: [
@ -655,21 +575,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 178, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "r23tQvESL7w", avatar: [],
title: "Picture in my mind", verification: None,
length: Some(177), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(178),
id: "4DyV0hWOdQw",
title: "we fell in love in october",
length: Some(185),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_l7K78k4EkjcFojhd1617rmUjY-aet6-t0", id: "RDCLAK5uy_l7K78k4EkjcFojhd1617rmUjY-aet6-t0",
name: "K-Pop Party Hits", name: "K-Pop Party Hits",
thumbnail: [ thumbnail: [
@ -694,21 +609,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 87, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "LCpjdohpuEE", avatar: [],
title: "Permission to Dance", verification: None,
length: Some(188), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(87),
id: "8mA6jIeojnk",
title: "How You Like That",
length: Some(182),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "RDCLAK5uy_lj-zBExVYl7YN_NxXboDIh4A-wKGfgzNY", id: "RDCLAK5uy_lj-zBExVYl7YN_NxXboDIh4A-wKGfgzNY",
name: "I-Pop Hits!", name: "I-Pop Hits!",
thumbnail: [ thumbnail: [
@ -733,21 +643,16 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 50, channel: Some(ChannelTag(
first_videos: [ id: "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
SearchPlaylistVideo( name: "YouTube Music",
id: "g-7u06NK1mo", avatar: [],
title: "Killer Haseena", verification: None,
length: Some(161), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(50),
id: "v0Q56geMlkk",
title: "Kesariyo Rang",
length: Some(194),
),
],
)), )),
Playlist(SearchPlaylist( Playlist(PlaylistItem(
id: "PLDIoUOhQQPlXqz5QZ3dx-lh_p6RcPeKjv", id: "PLDIoUOhQQPlXqz5QZ3dx-lh_p6RcPeKjv",
name: "POP Music Playlist 2022 - New POP Songs - Pop Songs 2022 Playlist", name: "POP Music Playlist 2022 - New POP Songs - Pop Songs 2022 Playlist",
thumbnail: [ thumbnail: [
@ -772,22 +677,18 @@ SearchResult(
height: 188, height: 188,
), ),
], ],
video_count: 100, channel: Some(ChannelTag(
first_videos: [ id: "UCX9oPuvJYZsG8wnHTwOBVPA",
SearchPlaylistVideo( name: "Chillax",
id: "WcIcVapfqXw", avatar: [],
title: "Rema, Selena Gomez - Calm Down (Official Music Video)", verification: None,
length: Some(240), subscriber_count: None,
), )),
SearchPlaylistVideo( video_count: Some(100),
id: "a7GITgqwDVg",
title: "Charlie Puth - Left And Right (feat. Jung Kook of BTS) [Official Video]",
length: Some(160),
),
],
)), )),
], ],
ctoken: Some("EqIJEgNwb3AamglFZ0lRQTBnVWdnRXJVa1JEVEVGTE5YVjVYMjV0VXpOWmIzaFRkMVpXVVdzNWJFVlJTakJWV0RSYVEycFljMWRmY0hOVk9JSUJLMUpFUTB4QlN6VjFlVjl0VmtvelVsSnBYMWxDWmxWS2JscHVVWGhNUVdWa1VWRmpXRWgxYW1KVlkyZUNBU3RTUkVOTVFVczFkWGxmYldaa2NYWkRRV3c0ZDI5a2JIZ3lVREpmUVdreVowNXJhVkpFUVhWbWEydEpnZ0VyVWtSRFRFRkxOWFY1WDI1SVUzRkRTbXBFY2xjNVNFSm9RMDVrUmpaMFYxQmtiazlOYm1kUGRqQjNRWUlCSzFKRVEweEJTelYxZVY5c1lqWkRWbFUyVXpSMVZuVm5URlpPVkZVNVYyaHhabUZ2YlZkQloyNW9ielNDQVN0U1JFTk1RVXMxZFhsZmJrUk1PRXRsUW5KVllXZDNlVWxUZDA1dGVVVnBVMlpaWjNveFoxWkRaWE5uZ2dFaVVFeEVTVzlWVDJoUlVWQnNWbkl6Y1dWd1RWWlNjMFJsTkZRNGRrNVJjM1p1YjRJQksxSkVRMHhCU3pWMWVWOXVabk5mZERSR1ZYVXdNRVUxUlVRMmJIWmxSVUpDV0RGV1RWbGxNVzFHYW11Q0FTdFNSRU5NUVVzMWRYbGZiVjh3VlRWV1VVNTVlWHAzZDBneGJGSnBOMk5RUVVGSFdIRk9VVzVCVDNGWmdnRXJVa1JEVEVGTE5YVjVYMjFJVnpWaVkyUjFhR3BDTFZCclZHVlFRV1UyUlc5U1RXb3hlRTVVT0dkNldZSUJLMUpFUTB4QlN6VjFlVjlyVUhGS1gwWnBSMnN0YkdKWWRHZE5ORWxHTkRKMWIydHphMU5LV21sV1ZFbUNBU0pRVEVsZk4wMW5NbHBmTFRSTVpqZEpXV1ZwVkVWUFZqaElRbTR0YmsxeGVqVk9nZ0VpVUV4WU5rdzBkRGQwTmxwaGJtWkRTakYzUW5oU1pFZGFYMjFyT1hsbmJVdHhiNElCSWxCTVRVTTVTMDVyU1c1alMzUlFlbWRaTFRWeWJXaDJhamRtWVhnNFptUjRiMnFDQVNKUVRHZFNaSEJvTUhGUVRIazFNMGxvV1hKUlRGQndRVlJFUkVFeVZIQkdaWGsxZ2dFclVrUkRURUZMTlhWNVgyNURWa1pmZWxWYWFYcDZVbU52YWtsVmRWbHRZVmg0VFc5UVoyY3lWMDFFYjRJQksxSkVRMHhCU3pWMWVWOXNXVFpLUm5Kek4xYzVlVWxvUm1wVlRsOTVlRkZmZFdKcmFtTnljVkZoVm5PQ0FTdFNSRU5NUVVzMWRYbGZiRGRMTnpock5FVnJhbU5HYjJwb1pERTJNVGR5YlZWcVdTMWhaWFEyTFhRd2dnRXJVa1JEVEVGTE5YVjVYMnhxTFhwQ1JYaFdXV3czV1U1ZlRuaFlZbTlFU1dnMFFTMTNTMGRtWjNwT1dZSUJJbEJNUkVsdlZVOW9VVkZRYkZoeGVqVlJXak5rZUMxc2FGOXdObEpqVUdWTGFuYXlBUVlLQkFnVkVBSSUzRBiB4OgYIgtzZWFyY2gtZmVlZA%3D%3D"), ctoken: Some("EqIJEgNwb3AamglFZ0lRQTBnVWdnRXJVa1JEVEVGTE5YVjVYMjV0VXpOWmIzaFRkMVpXVVdzNWJFVlJTakJWV0RSYVEycFljMWRmY0hOVk9JSUJLMUpFUTB4QlN6VjFlVjl0VmtvelVsSnBYMWxDWmxWS2JscHVVWGhNUVdWa1VWRmpXRWgxYW1KVlkyZUNBU3RTUkVOTVFVczFkWGxmYldaa2NYWkRRV3c0ZDI5a2JIZ3lVREpmUVdreVowNXJhVkpFUVhWbWEydEpnZ0VyVWtSRFRFRkxOWFY1WDI1SVUzRkRTbXBFY2xjNVNFSm9RMDVrUmpaMFYxQmtiazlOYm1kUGRqQjNRWUlCSzFKRVEweEJTelYxZVY5c1lqWkRWbFUyVXpSMVZuVm5URlpPVkZVNVYyaHhabUZ2YlZkQloyNW9ielNDQVN0U1JFTk1RVXMxZFhsZmJrUk1PRXRsUW5KVllXZDNlVWxUZDA1dGVVVnBVMlpaWjNveFoxWkRaWE5uZ2dFaVVFeEVTVzlWVDJoUlVWQnNWbkl6Y1dWd1RWWlNjMFJsTkZRNGRrNVJjM1p1YjRJQksxSkVRMHhCU3pWMWVWOXVabk5mZERSR1ZYVXdNRVUxUlVRMmJIWmxSVUpDV0RGV1RWbGxNVzFHYW11Q0FTdFNSRU5NUVVzMWRYbGZiVjh3VlRWV1VVNTVlWHAzZDBneGJGSnBOMk5RUVVGSFdIRk9VVzVCVDNGWmdnRXJVa1JEVEVGTE5YVjVYMjFJVnpWaVkyUjFhR3BDTFZCclZHVlFRV1UyUlc5U1RXb3hlRTVVT0dkNldZSUJLMUpFUTB4QlN6VjFlVjlyVUhGS1gwWnBSMnN0YkdKWWRHZE5ORWxHTkRKMWIydHphMU5LV21sV1ZFbUNBU0pRVEVsZk4wMW5NbHBmTFRSTVpqZEpXV1ZwVkVWUFZqaElRbTR0YmsxeGVqVk9nZ0VpVUV4WU5rdzBkRGQwTmxwaGJtWkRTakYzUW5oU1pFZGFYMjFyT1hsbmJVdHhiNElCSWxCTVRVTTVTMDVyU1c1alMzUlFlbWRaTFRWeWJXaDJhamRtWVhnNFptUjRiMnFDQVNKUVRHZFNaSEJvTUhGUVRIazFNMGxvV1hKUlRGQndRVlJFUkVFeVZIQkdaWGsxZ2dFclVrUkRURUZMTlhWNVgyNURWa1pmZWxWYWFYcDZVbU52YWtsVmRWbHRZVmg0VFc5UVoyY3lWMDFFYjRJQksxSkVRMHhCU3pWMWVWOXNXVFpLUm5Kek4xYzVlVWxvUm1wVlRsOTVlRkZmZFdKcmFtTnljVkZoVm5PQ0FTdFNSRU5NUVVzMWRYbGZiRGRMTnpock5FVnJhbU5HYjJwb1pERTJNVGR5YlZWcVdTMWhaWFEyTFhRd2dnRXJVa1JEVEVGTE5YVjVYMnhxTFhwQ1JYaFdXV3czV1U1ZlRuaFlZbTlFU1dnMFFTMTNTMGRtWjNwT1dZSUJJbEJNUkVsdlZVOW9VVkZRYkZoeGVqVlJXak5rZUMxc2FGOXdObEpqVUdWTGFuYXlBUVlLQkFnVkVBSSUzRBiB4OgYIgtzZWFyY2gtZmVlZA%3D%3D"),
endpoint: browse,
), ),
corrected_query: None, corrected_query: None,
) )

View file

@ -5,7 +5,7 @@ expression: map_res.c
Paginator( Paginator(
count: None, count: None,
items: [ items: [
SearchVideo( VideoItem(
id: "_cyJhGsXDDM", id: "_cyJhGsXDDM",
title: "Ultimate Criminal Canal Found Magnet Fishing! Police on the Hunt", title: "Ultimate Criminal Canal Found Magnet Fishing! Police on the Hunt",
length: Some(1096), length: Some(1096),
@ -21,7 +21,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCMLXec9-wpON8tZegnDsYLw", id: "UCMLXec9-wpON8tZegnDsYLw",
name: "Bondi Treasure Hunter", name: "Bondi Treasure Hunter",
avatar: [ avatar: [
@ -31,17 +31,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 day ago"), publish_date_txt: Some("1 day ago"),
view_count: 700385, view_count: Some(700385),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Subscribe for more Treasure Hunting videos: https://tinyurl.com/yyl3zerk\n\nMy Magnet! (Use Discount code \'BONDI\'): https://magnetarmagnets.com/\nMy Dive System! (Use Bonus code \'BONDI\'): https://lddy...", is_upcoming: false,
short_description: Some("Subscribe for more Treasure Hunting videos: https://tinyurl.com/yyl3zerk\n\nMy Magnet! (Use Discount code \'BONDI\'): https://magnetarmagnets.com/\nMy Dive System! (Use Bonus code \'BONDI\'): https://lddy..."),
), ),
SearchVideo( VideoItem(
id: "36YnV9STBqc", id: "36YnV9STBqc",
title: "The Good Life Radio\u{a0}•\u{a0}24/7 Live Radio | Best Relax House, Chillout, Study, Running, Gym, Happy Music", title: "The Good Life Radio\u{a0}•\u{a0}24/7 Live Radio | Best Relax House, Chillout, Study, Running, Gym, Happy Music",
length: None, length: None,
@ -57,7 +58,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UChs0pSaEoNLV4mevBFGaoKA", id: "UChs0pSaEoNLV4mevBFGaoKA",
name: "The Good Life Radio x Sensual Musique", name: "The Good Life Radio x Sensual Musique",
avatar: [ avatar: [
@ -67,17 +68,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 7202, view_count: Some(7202),
is_live: false, is_live: true,
is_short: false, is_short: false,
short_description: "The Good Life is live streaming the best of Relaxing & Chill House Music, Deep House, Tropical House, EDM, Dance & Pop as well as Music for Sleep, Focus, Study, Workout, Gym, Running etc. in...", is_upcoming: false,
short_description: Some("The Good Life is live streaming the best of Relaxing & Chill House Music, Deep House, Tropical House, EDM, Dance & Pop as well as Music for Sleep, Focus, Study, Workout, Gym, Running etc. in..."),
), ),
SearchVideo( VideoItem(
id: "YYD1qgH5qC4", id: "YYD1qgH5qC4",
title: "چند شنبه با سینــا | فصل چهـارم | قسمت 5 | با حضور نازنین انصاری مدیر روزنامه کیهان لندن", title: "چند شنبه با سینــا | فصل چهـارم | قسمت 5 | با حضور نازنین انصاری مدیر روزنامه کیهان لندن",
length: Some(3261), length: Some(3261),
@ -93,7 +95,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCzH_7hfL6Jd1H0WpNO_eryQ", id: "UCzH_7hfL6Jd1H0WpNO_eryQ",
name: "MBC PERSIA", name: "MBC PERSIA",
avatar: [ avatar: [
@ -103,17 +105,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("14 hours ago"), publish_date_txt: Some("14 hours ago"),
view_count: 104344, view_count: Some(104344),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "#mbcpersia\n#chandshanbeh\n#چندشنبه\n\nشبكه ام بى سى پرشيا را از حساب هاى مختلف در شبكه هاى اجتماعى دنبال كنيد\n►MBCPERSIA on Facebook:...", is_upcoming: false,
short_description: Some("#mbcpersia\n#chandshanbeh\n#چندشنبه\n\nشبكه ام بى سى پرشيا را از حساب هاى مختلف در شبكه هاى اجتماعى دنبال كنيد\n►MBCPERSIA on Facebook:..."),
), ),
SearchVideo( VideoItem(
id: "BeJqgI6rw9k", id: "BeJqgI6rw9k",
title: "your city is full of fake buildings, here\'s why", title: "your city is full of fake buildings, here\'s why",
length: Some(725), length: Some(725),
@ -129,7 +132,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCqVEHtQoXHmUCfJ-9smpTSg", id: "UCqVEHtQoXHmUCfJ-9smpTSg",
name: "Answer in Progress", name: "Answer in Progress",
avatar: [ avatar: [
@ -139,17 +142,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 days ago"), publish_date_txt: Some("7 days ago"),
view_count: 1447008, view_count: Some(1447008),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Save 33% on your first Native Deodorant Pack - normally $39, youll get it for $26! Click here https://bit.ly/nativeanswer1 and use my code ANSWER #AD\n\nSomewhere on your street there may...", is_upcoming: false,
short_description: Some("Save 33% on your first Native Deodorant Pack - normally $39, youll get it for $26! Click here https://bit.ly/nativeanswer1 and use my code ANSWER #AD\n\nSomewhere on your street there may..."),
), ),
SearchVideo( VideoItem(
id: "ma28eWd1oyA", id: "ma28eWd1oyA",
title: "Post Malone, Maroon 5, Adele, Taylor Swift, Ed Sheeran, Shawn Mendes, Pop Hits 2020 Part 6", title: "Post Malone, Maroon 5, Adele, Taylor Swift, Ed Sheeran, Shawn Mendes, Pop Hits 2020 Part 6",
length: Some(29989), length: Some(29989),
@ -160,7 +164,7 @@ Paginator(
height: 270, height: 270,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCldQuUMYTUGrjvcU2vaPSFQ", id: "UCldQuUMYTUGrjvcU2vaPSFQ",
name: "Music Library", name: "Music Library",
avatar: [ avatar: [
@ -170,17 +174,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("Streamed 2 years ago"), publish_date_txt: Some("Streamed 2 years ago"),
view_count: 1861814, view_count: Some(1861814),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Post Malone, Maroon 5, Adele, Taylor Swift, Ed Sheeran, Shawn Mendes, Charlie Puth Pop Hits 2020\nPost Malone, Maroon 5, Adele, Taylor Swift, Ed Sheeran, Shawn Mendes, Charlie Puth Pop Hits...", is_upcoming: false,
short_description: Some("Post Malone, Maroon 5, Adele, Taylor Swift, Ed Sheeran, Shawn Mendes, Charlie Puth Pop Hits 2020\nPost Malone, Maroon 5, Adele, Taylor Swift, Ed Sheeran, Shawn Mendes, Charlie Puth Pop Hits..."),
), ),
SearchVideo( VideoItem(
id: "mL2LBRM5GBI", id: "mL2LBRM5GBI",
title: "Salahs 6-Minuten-Hattrick & Firmino-Gala: Rangers - FC Liverpool 1:7 | UEFA Champions League | DAZN", title: "Salahs 6-Minuten-Hattrick & Firmino-Gala: Rangers - FC Liverpool 1:7 | UEFA Champions League | DAZN",
length: Some(355), length: Some(355),
@ -196,7 +201,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCB-GdMjyokO9lZkKU_oIK6g", id: "UCB-GdMjyokO9lZkKU_oIK6g",
name: "DAZN UEFA Champions League", name: "DAZN UEFA Champions League",
avatar: [ avatar: [
@ -206,17 +211,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 days ago"), publish_date_txt: Some("2 days ago"),
view_count: 1471667, view_count: Some(1471667),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "In der Liga läuft es für die Reds weiterhin nicht rund. Am vergangenen Spieltag gab es gegen Arsenal eine 2:3-Niederlage, am Sonntag trifft man auf Man City. Die Champions League soll für...", is_upcoming: false,
short_description: Some("In der Liga läuft es für die Reds weiterhin nicht rund. Am vergangenen Spieltag gab es gegen Arsenal eine 2:3-Niederlage, am Sonntag trifft man auf Man City. Die Champions League soll für..."),
), ),
SearchVideo( VideoItem(
id: "Ang18qz2IeQ", id: "Ang18qz2IeQ",
title: "Satisfying Videos of Workers Doing Their Job Perfectly", title: "Satisfying Videos of Workers Doing Their Job Perfectly",
length: Some(1186), length: Some(1186),
@ -232,7 +238,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCYenDLnIHsoqQ6smwKXQ7Hg", id: "UCYenDLnIHsoqQ6smwKXQ7Hg",
name: "#Mind Warehouse", name: "#Mind Warehouse",
avatar: [ avatar: [
@ -242,17 +248,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 days ago"), publish_date_txt: Some("2 days ago"),
view_count: 173121, view_count: Some(173121),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "TechZone ► https://goo.gl/Gj3wZs \n\n #incrediblemoments #mindwarehouse #IncredibleMoments #CaughtOnCamera #InterestingFacts \n\nYou can endlessly watch how others work, but in this selection,...", is_upcoming: false,
short_description: Some("TechZone ► https://goo.gl/Gj3wZs \n\n #incrediblemoments #mindwarehouse #IncredibleMoments #CaughtOnCamera #InterestingFacts \n\nYou can endlessly watch how others work, but in this selection,..."),
), ),
SearchVideo( VideoItem(
id: "fjHN4jsJnEU", id: "fjHN4jsJnEU",
title: "I Made 200 Players Simulate Survival Island in Minecraft...", title: "I Made 200 Players Simulate Survival Island in Minecraft...",
length: Some(2361), length: Some(2361),
@ -268,7 +275,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCqt4mmAqLmH-AwXz31URJsw", id: "UCqt4mmAqLmH-AwXz31URJsw",
name: "Sword4000", name: "Sword4000",
avatar: [ avatar: [
@ -278,17 +285,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 days ago"), publish_date_txt: Some("7 days ago"),
view_count: 751909, view_count: Some(751909),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "200 Players Simulate Survival Island Civilizations in Minecraft...\n-------------------------------------------------------------------\nI invited 200 Players to a Survival Island and let them...", is_upcoming: false,
short_description: Some("200 Players Simulate Survival Island Civilizations in Minecraft...\n-------------------------------------------------------------------\nI invited 200 Players to a Survival Island and let them..."),
), ),
SearchVideo( VideoItem(
id: "FI1XrdBJIUI", id: "FI1XrdBJIUI",
title: "Epic Construction Fails | Expensive Fails Compilation | FailArmy", title: "Epic Construction Fails | Expensive Fails Compilation | FailArmy",
length: Some(631), length: Some(631),
@ -304,7 +312,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCPDis9pjXuqyI7RYLJ-TTSA", id: "UCPDis9pjXuqyI7RYLJ-TTSA",
name: "FailArmy", name: "FailArmy",
avatar: [ avatar: [
@ -314,17 +322,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 days ago"), publish_date_txt: Some("2 days ago"),
view_count: 2226471, view_count: Some(2226471),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "I don\'t think so, Tim. ►►► Submit your videos for the chance to be featured 🔗 https://www.failarmy.com/pages/submit-video ▼ Follow us for more fails! https://linktr.ee/failarmy\n#fails...", is_upcoming: false,
short_description: Some("I don\'t think so, Tim. ►►► Submit your videos for the chance to be featured 🔗 https://www.failarmy.com/pages/submit-video ▼ Follow us for more fails! https://linktr.ee/failarmy\n#fails..."),
), ),
SearchVideo( VideoItem(
id: "MXdplejK8vU", id: "MXdplejK8vU",
title: "Chilly autumn Jazz ☕ Smooth September Jazz & Bossa Nova for a great relaxing weekend", title: "Chilly autumn Jazz ☕ Smooth September Jazz & Bossa Nova for a great relaxing weekend",
length: Some(86403), length: Some(86403),
@ -340,7 +349,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCeGJ6v6KQt0s88hGKMfybuw", id: "UCeGJ6v6KQt0s88hGKMfybuw",
name: "Cozy Jazz Music", name: "Cozy Jazz Music",
avatar: [ avatar: [
@ -350,17 +359,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 148743, view_count: Some(148743),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Chilly autumn Jazz ☕ Smooth September Jazz & Bossa Nova for a great relaxing weekend\nhttps://youtu.be/MXdplejK8vU\n*******************************************\nSounds available on: Jazz Bossa...", is_upcoming: false,
short_description: Some("Chilly autumn Jazz ☕ Smooth September Jazz & Bossa Nova for a great relaxing weekend\nhttps://youtu.be/MXdplejK8vU\n*******************************************\nSounds available on: Jazz Bossa..."),
), ),
SearchVideo( VideoItem(
id: "Jri4_9vBFiQ", id: "Jri4_9vBFiQ",
title: "Top 100 Best Classic Rock Songs Of All Time 🔥 R.E.M, Queen, Metallica,Guns N Roses,Bon Jovi, U2,CCR", title: "Top 100 Best Classic Rock Songs Of All Time 🔥 R.E.M, Queen, Metallica,Guns N Roses,Bon Jovi, U2,CCR",
length: None, length: None,
@ -376,7 +386,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCiIWdzEVNH8okhlapR9a-xA", id: "UCiIWdzEVNH8okhlapR9a-xA",
name: "Rock Music", name: "Rock Music",
avatar: [ avatar: [
@ -386,17 +396,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 192, view_count: Some(192),
is_live: false, is_live: true,
is_short: false, is_short: false,
short_description: "Top 100 Best Classic Rock Songs Of All Time 🔥 R.E.M, Queen, Metallica,Guns N Roses,Bon Jovi, U2,CCR\nTop 100 Best Classic Rock Songs Of All Time 🔥 R.E.M, Queen, Metallica,Guns N...", is_upcoming: false,
short_description: Some("Top 100 Best Classic Rock Songs Of All Time 🔥 R.E.M, Queen, Metallica,Guns N Roses,Bon Jovi, U2,CCR\nTop 100 Best Classic Rock Songs Of All Time 🔥 R.E.M, Queen, Metallica,Guns N..."),
), ),
SearchVideo( VideoItem(
id: "ll4d5Lt-Ie8", id: "ll4d5Lt-Ie8",
title: "Relaxing Music Healing Stress, Anxiety and Depressive States Heal Mind, Body and Soul | Sleep music", title: "Relaxing Music Healing Stress, Anxiety and Depressive States Heal Mind, Body and Soul | Sleep music",
length: Some(42896), length: Some(42896),
@ -412,7 +423,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCNS3dqFGBPhxHmOigehpBeg", id: "UCNS3dqFGBPhxHmOigehpBeg",
name: "Love YourSelf", name: "Love YourSelf",
avatar: [ avatar: [
@ -422,17 +433,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("Streamed 5 months ago"), publish_date_txt: Some("Streamed 5 months ago"),
view_count: 5363904, view_count: Some(5363904),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "The study found that listening to relaxing music of the patient\'s choice resulted in \"significant pain relief and increased mobility.\" Researchers believe that music relieves pain because listening...", is_upcoming: false,
short_description: Some("The study found that listening to relaxing music of the patient\'s choice resulted in \"significant pain relief and increased mobility.\" Researchers believe that music relieves pain because listening..."),
), ),
SearchVideo( VideoItem(
id: "Dx2wbKLokuQ", id: "Dx2wbKLokuQ",
title: "W. Putin: Die Sehnsucht nach dem Imperium | Mit offenen Karten | ARTE", title: "W. Putin: Die Sehnsucht nach dem Imperium | Mit offenen Karten | ARTE",
length: Some(729), length: Some(729),
@ -448,7 +460,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCLLibJTCy3sXjHLVaDimnpQ", id: "UCLLibJTCy3sXjHLVaDimnpQ",
name: "ARTEde", name: "ARTEde",
avatar: [ avatar: [
@ -458,17 +470,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 539838, view_count: Some(539838),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Jede Woche untersucht „Mit offenen Karten“ die politischen Kräfteverhältnisse in der ganzen Welt anhand detaillierter geografischer Karten \n\nIm Februar 2022 rechtfertigte Wladimir Putin...", is_upcoming: false,
short_description: Some("Jede Woche untersucht „Mit offenen Karten“ die politischen Kräfteverhältnisse in der ganzen Welt anhand detaillierter geografischer Karten \n\nIm Februar 2022 rechtfertigte Wladimir Putin..."),
), ),
SearchVideo( VideoItem(
id: "jfKfPfyJRdk", id: "jfKfPfyJRdk",
title: "lofi hip hop radio - beats to relax/study to", title: "lofi hip hop radio - beats to relax/study to",
length: None, length: None,
@ -484,7 +497,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCSJ4gkVC6NrvII8umztf0Ow", id: "UCSJ4gkVC6NrvII8umztf0Ow",
name: "Lofi Girl", name: "Lofi Girl",
avatar: [ avatar: [
@ -494,17 +507,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 21262, view_count: Some(21262),
is_live: false, is_live: true,
is_short: false, is_short: false,
short_description: "🤗 Thank you for listening, I hope you will have a good time here\n\n💽 | Get the latest vinyl (limited edition)\n→ https://vinyl-lofirecords.com/\n\n🎼 | Listen on Spotify, Apple music...", is_upcoming: false,
short_description: Some("🤗 Thank you for listening, I hope you will have a good time here\n\n💽 | Get the latest vinyl (limited edition)\n→ https://vinyl-lofirecords.com/\n\n🎼 | Listen on Spotify, Apple music..."),
), ),
SearchVideo( VideoItem(
id: "qmrzTUmZ4UU", id: "qmrzTUmZ4UU",
title: "850€ für den Verrat am System - UCS AT-AT LEGO® Star Wars 75313", title: "850€ für den Verrat am System - UCS AT-AT LEGO® Star Wars 75313",
length: Some(2043), length: Some(2043),
@ -520,7 +534,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC_EZd3lsmxudu3IQzpTzOgw", id: "UC_EZd3lsmxudu3IQzpTzOgw",
name: "Held der Steine Inh. Thomas Panke", name: "Held der Steine Inh. Thomas Panke",
avatar: [ avatar: [
@ -530,17 +544,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 days ago"), publish_date_txt: Some("6 days ago"),
view_count: 600150, view_count: Some(600150),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Star Wars - erschienen 2021 - 6749 Teile\n\nDieses Set bei Amazon*:\nhttps://amzn.to/3yu9dHX\n\nErwähnt im Video*:\nTassen https://bit.ly/HdSBausteinecke\nBig Boy https://bit.ly/BBLokBigBoy\nBurg...", is_upcoming: false,
short_description: Some("Star Wars - erschienen 2021 - 6749 Teile\n\nDieses Set bei Amazon*:\nhttps://amzn.to/3yu9dHX\n\nErwähnt im Video*:\nTassen https://bit.ly/HdSBausteinecke\nBig Boy https://bit.ly/BBLokBigBoy\nBurg..."),
), ),
SearchVideo( VideoItem(
id: "t0Q2otsqC4I", id: "t0Q2otsqC4I",
title: "Tom & Jerry | Tom & Jerry in Full Screen | Classic Cartoon Compilation | WB Kids", title: "Tom & Jerry | Tom & Jerry in Full Screen | Classic Cartoon Compilation | WB Kids",
length: Some(1298), length: Some(1298),
@ -556,7 +571,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC9trsD1jCTXXtN3xIOIU8gg", id: "UC9trsD1jCTXXtN3xIOIU8gg",
name: "WB Kids", name: "WB Kids",
avatar: [ avatar: [
@ -566,17 +581,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("10 months ago"), publish_date_txt: Some("10 months ago"),
view_count: 252381571, view_count: Some(252381571),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "Did you know that there are only 25 classic Tom & Jerry episodes that were displayed in a widescreen CinemaScope from the 1950s? Enjoy a compilation filled with some of the best moments from...", is_upcoming: false,
short_description: Some("Did you know that there are only 25 classic Tom & Jerry episodes that were displayed in a widescreen CinemaScope from the 1950s? Enjoy a compilation filled with some of the best moments from..."),
), ),
SearchVideo( VideoItem(
id: "zE-a5eqvlv8", id: "zE-a5eqvlv8",
title: "Dua Lipa, Coldplay, Martin Garrix & Kygo, The Chainsmokers Style - Feeling Me", title: "Dua Lipa, Coldplay, Martin Garrix & Kygo, The Chainsmokers Style - Feeling Me",
length: None, length: None,
@ -592,7 +608,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCX-USfenzQlhrEJR1zD5IYw", id: "UCX-USfenzQlhrEJR1zD5IYw",
name: "Deep Mood.", name: "Deep Mood.",
avatar: [ avatar: [
@ -602,17 +618,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 955, view_count: Some(955),
is_live: false, is_live: true,
is_short: false, is_short: false,
short_description: "#Summermix #DeepHouse #DeepHouseSummerMix\nDua Lipa, Coldplay, Martin Garrix & Kygo, The Chainsmokers Style - Feeling Me\n\n🎵 All songs in this spotify playlist: https://spoti.fi/2TJ4Dyj\nSubmit...", is_upcoming: false,
short_description: Some("#Summermix #DeepHouse #DeepHouseSummerMix\nDua Lipa, Coldplay, Martin Garrix & Kygo, The Chainsmokers Style - Feeling Me\n\n🎵 All songs in this spotify playlist: https://spoti.fi/2TJ4Dyj\nSubmit..."),
), ),
SearchVideo( VideoItem(
id: "HxCcKzRAGWk", id: "HxCcKzRAGWk",
title: "(Music for Man ) Relaxing Whiskey Blues Music - Modern Electric Guitar Blues - JAZZ & BLUES", title: "(Music for Man ) Relaxing Whiskey Blues Music - Modern Electric Guitar Blues - JAZZ & BLUES",
length: Some(42899), length: Some(42899),
@ -628,7 +645,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCGr-rTYtP1m-r_-ncspdVQQ", id: "UCGr-rTYtP1m-r_-ncspdVQQ",
name: "JAZZ & BLUES", name: "JAZZ & BLUES",
avatar: [ avatar: [
@ -638,17 +655,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("Streamed 3 months ago"), publish_date_txt: Some("Streamed 3 months ago"),
view_count: 3156236, view_count: Some(3156236),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "-----------------------------------------------------------------------------------\n✔Thanks for watching! Have a nice day!\n✔Don\'t forget LIKE - SHARE - COMMENT\n#bluesmusic#slowblues#bluesrock...", is_upcoming: false,
short_description: Some("-----------------------------------------------------------------------------------\n✔Thanks for watching! Have a nice day!\n✔Don\'t forget LIKE - SHARE - COMMENT\n#bluesmusic#slowblues#bluesrock..."),
), ),
SearchVideo( VideoItem(
id: "HlHYOdZePSE", id: "HlHYOdZePSE",
title: "Healing Music for Anxiety Disorders, Fears, Depression and Eliminate Negative Thoughts", title: "Healing Music for Anxiety Disorders, Fears, Depression and Eliminate Negative Thoughts",
length: None, length: None,
@ -664,7 +682,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCqNYK5QArQRZSIR8v6_FCfA", id: "UCqNYK5QArQRZSIR8v6_FCfA",
name: "Tranquil Music", name: "Tranquil Music",
avatar: [ avatar: [
@ -674,17 +692,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 1585, view_count: Some(1585),
is_live: false, is_live: true,
is_short: false, is_short: false,
short_description: "Healing Music for Anxiety Disorders, Fears, Depression and Eliminate Negative Thoughts\n#HealingMusic #RelaxingMusic #TranquilMusic\n__________________________________\nMusic for:\nChakra healing....", is_upcoming: false,
short_description: Some("Healing Music for Anxiety Disorders, Fears, Depression and Eliminate Negative Thoughts\n#HealingMusic #RelaxingMusic #TranquilMusic\n__________________________________\nMusic for:\nChakra healing...."),
), ),
SearchVideo( VideoItem(
id: "CJ2AH3LJeic", id: "CJ2AH3LJeic",
title: "Coldplay Greatest Hits Full Album 2022 New Songs of Coldplay 2022", title: "Coldplay Greatest Hits Full Album 2022 New Songs of Coldplay 2022",
length: Some(7781), length: Some(7781),
@ -700,7 +719,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCdK2lzwelugXGhR9SCWuEew", id: "UCdK2lzwelugXGhR9SCWuEew",
name: "PLAY MUSIC", name: "PLAY MUSIC",
avatar: [ avatar: [
@ -710,17 +729,18 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 5595965, view_count: Some(5595965),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬\nSubscribe channel for more videos:\n🔔Subscribe: https://bit.ly/2UbIZFv\n⚡Facebook: https://bitly.com.vn/gXDsC...", is_upcoming: false,
short_description: Some("▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬\nSubscribe channel for more videos:\n🔔Subscribe: https://bit.ly/2UbIZFv\n⚡Facebook: https://bitly.com.vn/gXDsC..."),
), ),
SearchVideo( VideoItem(
id: "KJwzKxQ81iA", id: "KJwzKxQ81iA",
title: "Handmade Candy Making Collection / 수제 사탕 만들기 모음 / Korean Candy Store", title: "Handmade Candy Making Collection / 수제 사탕 만들기 모음 / Korean Candy Store",
length: Some(3152), length: Some(3152),
@ -736,7 +756,7 @@ Paginator(
height: 404, height: 404,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCdGwDjTgbSwQDZ8dYOdrplg", id: "UCdGwDjTgbSwQDZ8dYOdrplg",
name: "Soon Films 순필름", name: "Soon Films 순필름",
avatar: [ avatar: [
@ -746,17 +766,19 @@ Paginator(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 3127238, view_count: Some(3127238),
is_live: false, is_live: false,
is_short: false, is_short: false,
short_description: "00:00 Handmade Candy Making\n13:43 Delicate Handmade Candy Making\n28:33 Rainbow Lollipop Handmade Candy Making\n39:10 Cute Handmade Candy Making", is_upcoming: false,
short_description: Some("00:00 Handmade Candy Making\n13:43 Delicate Handmade Candy Making\n28:33 Rainbow Lollipop Handmade Candy Making\n39:10 Cute Handmade Candy Making"),
), ),
], ],
ctoken: Some("4qmFsgKbAxIPRkV3aGF0X3RvX3dhdGNoGuoCQ0JoNmlBSk5aMjlKYjB0NmVtOWlTR3hxVFRSdlYyMHdTMkYzYjFwbFdGSm1ZMGRHYmxwV09YcGliVVozWXpKb2RtUkdPWGxhVjJSd1lqSTFhR0pDU1daWFZFSXhUbFpuZDFSV09YSldNRlp0WkRCT1JWTlZPV3BsU0U1WFZHNWtiRXhWY0ZSa1ZrSlRXbmh2ZEVGQlFteGlaMEZDVmxaTlFVRlZVa1pCUVVWQlVtdFdNMkZIUmpCWU0xSjJXRE5rYUdSSFRtOUJRVVZCUVZGRlFVRkJSVUZCVVVGQlFWRkZRVmxyUlVsQlFrbFVZMGRHYmxwV09YcGliVVozWXpKb2RtUkdPVEJpTW5Sc1ltaHZWRU5MVDNJeFpuSjROR1p2UTBaU1YwSm1RVzlrVkZWSlN6RnBTVlJEUzA5eU1XWnllRFJtYjBOR1VsZENaa0Z2WkZSVlNVc3hkbkZqZURjd1NrRm5aMW8lM0SaAhpicm93c2UtZmVlZEZFd2hhdF90b193YXRjaA%3D%3D"), ctoken: Some("4qmFsgKbAxIPRkV3aGF0X3RvX3dhdGNoGuoCQ0JoNmlBSk5aMjlKYjB0NmVtOWlTR3hxVFRSdlYyMHdTMkYzYjFwbFdGSm1ZMGRHYmxwV09YcGliVVozWXpKb2RtUkdPWGxhVjJSd1lqSTFhR0pDU1daWFZFSXhUbFpuZDFSV09YSldNRlp0WkRCT1JWTlZPV3BsU0U1WFZHNWtiRXhWY0ZSa1ZrSlRXbmh2ZEVGQlFteGlaMEZDVmxaTlFVRlZVa1pCUVVWQlVtdFdNMkZIUmpCWU0xSjJXRE5rYUdSSFRtOUJRVVZCUVZGRlFVRkJSVUZCVVVGQlFWRkZRVmxyUlVsQlFrbFVZMGRHYmxwV09YcGliVVozWXpKb2RtUkdPVEJpTW5Sc1ltaHZWRU5MVDNJeFpuSjROR1p2UTBaU1YwSm1RVzlrVkZWSlN6RnBTVlJEUzA5eU1XWnllRFJtYjBOR1VsZENaa0Z2WkZSVlNVc3hkbkZqZURjd1NrRm5aMW8lM0SaAhpicm93c2UtZmVlZEZFd2hhdF90b193YXRjaA%3D%3D"),
visitor_data: Some("CgtjTXNGWnhNcjdORSiq8qmaBg%3D%3D"), visitor_data: Some("CgtjTXNGWnhNcjdORSiq8qmaBg%3D%3D"),
endpoint: browse,
) )

View file

@ -34,7 +34,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -45,6 +45,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -75,7 +76,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -86,6 +87,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -117,7 +119,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -128,6 +130,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -162,7 +165,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -173,6 +176,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -203,7 +207,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -214,6 +218,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -244,7 +249,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -255,6 +260,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -285,7 +291,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -296,6 +302,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -326,7 +333,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -337,6 +344,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -367,7 +375,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -378,6 +386,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -408,7 +417,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -419,6 +428,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -449,7 +459,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -460,6 +470,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -490,7 +501,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -501,6 +512,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -531,7 +543,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -542,6 +554,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -572,7 +585,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -583,6 +596,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -613,7 +627,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -624,6 +638,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -654,7 +669,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -665,6 +680,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -695,7 +711,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -706,6 +722,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -736,7 +753,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -747,6 +764,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -754,4 +772,5 @@ Paginator(
), ),
], ],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyiwEKT0FEU0pfaTBhMTViQk5vTE9UTHFhUTBoZHB4VTN5SUdfYmhQTzhzM1pGQXQybzdnaVMwajVoSkRNSTl5MGs5M2l4SkM5VGdSbHBVa0xxQ0EiESILWmVlcnJudUxpNUUwAXgBKBIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyiwEKT0FEU0pfaTBhMTViQk5vTE9UTHFhUTBoZHB4VTN5SUdfYmhQTzhzM1pGQXQybzdnaVMwajVoSkRNSTl5MGs5M2l4SkM5VGdSbHBVa0xxQ0EiESILWmVlcnJudUxpNUUwAXgBKBIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"),
endpoint: browse,
) )

View file

@ -33,7 +33,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -44,6 +44,7 @@ Paginator(
count: Some(3), count: Some(3),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3djVTczT0JWOE9tU0JPS3J0NEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3djVTczT0JWOE9tU0JPS3J0NEFhQUJBZw%3D%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3djVTczT0JWOE9tU0JPS3J0NEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3djVTczT0JWOE9tU0JPS3J0NEFhQUJBZw%3D%3D"),
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -74,7 +75,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -85,6 +86,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -115,7 +117,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -126,6 +128,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -156,7 +159,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -167,6 +170,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -197,7 +201,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -208,6 +212,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -243,7 +248,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -254,6 +259,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -290,7 +296,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -301,6 +307,7 @@ Paginator(
count: Some(2), count: Some(2),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3puZDRLcVU1azhBN2F4QjdWNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3puZDRLcVU1azhBN2F4QjdWNEFhQUJBZw%3D%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3puZDRLcVU1azhBN2F4QjdWNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3puZDRLcVU1azhBN2F4QjdWNEFhQUJBZw%3D%3D"),
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -331,7 +338,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -342,6 +349,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -372,7 +380,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -383,6 +391,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -413,7 +422,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -424,6 +433,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -456,7 +466,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -467,6 +477,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -497,7 +508,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -508,6 +519,7 @@ Paginator(
count: Some(2), count: Some(2),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3lUbFpfa2tYNnJydDV3S0VwNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3lUbFpfa2tYNnJydDV3S0VwNEFhQUJBZw%3D%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3lUbFpfa2tYNnJydDV3S0VwNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3lUbFpfa2tYNnJydDV3S0VwNEFhQUJBZw%3D%3D"),
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -538,7 +550,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -549,6 +561,7 @@ Paginator(
count: Some(2), count: Some(2),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3lnM0Q5ZFVJRXJKNHlfTDJsNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3lnM0Q5ZFVJRXJKNHlfTDJsNEFhQUJBZw%3D%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3lnM0Q5ZFVJRXJKNHlfTDJsNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3lnM0Q5ZFVJRXJKNHlfTDJsNEFhQUJBZw%3D%3D"),
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -579,7 +592,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -590,6 +603,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -620,7 +634,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -631,6 +645,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -661,7 +676,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -672,6 +687,7 @@ Paginator(
count: Some(1), count: Some(1),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3hZcVlrRkFnV2IzSmFUSFl0NEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3hZcVlrRkFnV2IzSmFUSFl0NEFhQUJBZw%3D%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3hZcVlrRkFnV2IzSmFUSFl0NEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3hZcVlrRkFnV2IzSmFUSFl0NEFhQUJBZw%3D%3D"),
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -702,7 +718,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -713,6 +729,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -743,7 +760,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -754,6 +771,7 @@ Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -784,7 +802,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -795,6 +813,7 @@ Paginator(
count: Some(4), count: Some(4),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3pvWmY5bkc3VkJOaGNETFJGNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3pvWmY5bkc3VkJOaGNETFJGNEFhQUJBZw%3D%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3pvWmY5bkc3VkJOaGNETFJGNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3pvWmY5bkc3VkJOaGNETFJGNEFhQUJBZw%3D%3D"),
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -827,7 +846,7 @@ Paginator(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
)), )),
publish_date: "[date]", publish_date: "[date]",
@ -838,6 +857,7 @@ Paginator(
count: Some(1), count: Some(1),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3lNZXExV0RoU1lBSUozSlFoNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3lNZXExV0RoU1lBSUozSlFoNEFhQUJBZw%3D%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyfhpLEhpVZ3lNZXExV0RoU1lBSUozSlFoNEFhQUJBZyICCAAqGFVDRWZfQmMtS1ZkN29uU2VpZlMzcHk5ZzILWmVlcnJudUxpNUVAAUgKQi9jb21tZW50LXJlcGxpZXMtaXRlbS1VZ3lNZXExV0RoU1lBSUozSlFoNEFhQUJBZw%3D%3D"),
endpoint: browse,
), ),
by_owner: false, by_owner: false,
pinned: false, pinned: false,
@ -845,4 +865,5 @@ Paginator(
), ),
], ],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYy7QIKwwJnZXRfcmFua2VkX3N0cmVhbXMtLUNxY0JDSUFFRlJlMzBUZ2FuQUVLbHdFSTJGOFFnQVFZQnlLTUFidGhsd05sb1pHVEg0ZWRnUlVOc2dUX2pFRFYxOThSRmxGZFJTMVJiQ1hBUl9CTFNGREZKZ2FuS2FoMUVyeERGQU1xY1lnMThmSGdVSnBtZklqV2tER0FscUN1QzJLdU1FQjJYT25sVTZrd3ZBUjY5OHA2a2VGV3hLckxscGdtalZtelg4RHdPaDk1cGlMLVROOTl5YTZ1TDlpb0Y1LWc2Q3dqellGS1RPbnduRTF4V3lVSVdOUjlsRllZRUJRU0JRaUpJQmdBRWdVSWhpQVlBQklIQ0pjZ0VBOFlBUklGQ0lnZ0dBQVNCUWlISUJnQUVnY0loU0FRQnhnQkVnY0loQ0FRQkJnQkdBQSIRIgtaZWVycm51TGk1RTAAeAEoFEIQY29tbWVudHMtc2VjdGlvbg%3D%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYy7QIKwwJnZXRfcmFua2VkX3N0cmVhbXMtLUNxY0JDSUFFRlJlMzBUZ2FuQUVLbHdFSTJGOFFnQVFZQnlLTUFidGhsd05sb1pHVEg0ZWRnUlVOc2dUX2pFRFYxOThSRmxGZFJTMVJiQ1hBUl9CTFNGREZKZ2FuS2FoMUVyeERGQU1xY1lnMThmSGdVSnBtZklqV2tER0FscUN1QzJLdU1FQjJYT25sVTZrd3ZBUjY5OHA2a2VGV3hLckxscGdtalZtelg4RHdPaDk1cGlMLVROOTl5YTZ1TDlpb0Y1LWc2Q3dqellGS1RPbnduRTF4V3lVSVdOUjlsRllZRUJRU0JRaUpJQmdBRWdVSWhpQVlBQklIQ0pjZ0VBOFlBUklGQ0lnZ0dBQVNCUWlISUJnQUVnY0loU0FRQnhnQkVnY0loQ0FRQkJnQkdBQSIRIgtaZWVycm51TGk1RTAAeAEoFEIQY29tbWVudHMtc2VjdGlvbg%3D%3D"),
endpoint: browse,
) )

View file

@ -91,7 +91,7 @@ VideoDetails(
height: 176, height: 176,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: Some(30900000), subscriber_count: Some(30900000),
), ),
view_count: 233243423, view_count: 233243423,
@ -104,7 +104,7 @@ VideoDetails(
recommended: Paginator( recommended: Paginator(
count: None, count: None,
items: [ items: [
RecommendedVideo( VideoItem(
id: "aRpkasmB6so", id: "aRpkasmB6so",
title: "18 de setembro de 2022", title: "18 de setembro de 2022",
length: Some(184), length: Some(184),
@ -120,7 +120,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCQYl87Oi9aWzz-CLhTw3Rzg", id: "UCQYl87Oi9aWzz-CLhTw3Rzg",
name: "Allan Nascimento", name: "Allan Nascimento",
avatar: [ avatar: [
@ -130,16 +130,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 days ago"), publish_date_txt: Some("5 days ago"),
view_count: 996, view_count: Some(996),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "lCXqNCd0m10", id: "lCXqNCd0m10",
title: "aespa(エスパ) Savage + Next Level + Black Mamba💕Stage Mix Compilation🔥에스파 무대모음 KBS Music Bank", title: "aespa(エスパ) Savage + Next Level + Black Mamba💕Stage Mix Compilation🔥에스파 무대모음 KBS Music Bank",
length: Some(898), length: Some(898),
@ -155,7 +157,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCgqMjKxRWAKUvgYqgomighw", id: "UCgqMjKxRWAKUvgYqgomighw",
name: "KBS충북", name: "KBS충북",
avatar: [ avatar: [
@ -165,16 +167,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 months ago"), publish_date_txt: Some("7 months ago"),
view_count: 7684395, view_count: Some(7684395),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "tDukIfFzX18", id: "tDukIfFzX18",
title: "[MV] Hwa Sa(화사) _ Maria(마리아)", title: "[MV] Hwa Sa(화사) _ Maria(마리아)",
length: Some(231), length: Some(231),
@ -190,7 +194,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCweOkPb1wVVH0Q0Tlj4a5Pw", id: "UCweOkPb1wVVH0Q0Tlj4a5Pw",
name: "1theK (원더케이)", name: "1theK (원더케이)",
avatar: [ avatar: [
@ -200,16 +204,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 260984648, view_count: Some(260984648),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "e-ORhEE9VVg", id: "e-ORhEE9VVg",
title: "Taylor Swift - Blank Space", title: "Taylor Swift - Blank Space",
length: Some(273), length: Some(273),
@ -225,7 +231,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCqECaJ8Gagnn7YCbPEzWH6g", id: "UCqECaJ8Gagnn7YCbPEzWH6g",
name: "Taylor Swift", name: "Taylor Swift",
avatar: [ avatar: [
@ -235,16 +241,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 years ago"), publish_date_txt: Some("7 years ago"),
view_count: 3035220118, view_count: Some(3035220118),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "qfVuRQX0ydQ", id: "qfVuRQX0ydQ",
title: "[MV] Weeekly(위클리) _ After School", title: "[MV] Weeekly(위클리) _ After School",
length: Some(225), length: Some(225),
@ -260,7 +268,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCweOkPb1wVVH0Q0Tlj4a5Pw", id: "UCweOkPb1wVVH0Q0Tlj4a5Pw",
name: "1theK (원더케이)", name: "1theK (원더케이)",
avatar: [ avatar: [
@ -270,16 +278,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 138451832, view_count: Some(138451832),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "tyrVtwE8Gv0", id: "tyrVtwE8Gv0",
title: "NCT U 엔시티 유 \'Make A Wish (Birthday Song)\' MV", title: "NCT U 엔시티 유 \'Make A Wish (Birthday Song)\' MV",
length: Some(249), length: Some(249),
@ -295,7 +305,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -305,16 +315,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 255458628, view_count: Some(255458628),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "X-uJtV8ScYk", id: "X-uJtV8ScYk",
title: "Stray Kids \"Back Door\" M/V", title: "Stray Kids \"Back Door\" M/V",
length: Some(218), length: Some(218),
@ -330,7 +342,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -340,16 +352,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 274719671, view_count: Some(274719671),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "MjCZfZfucEc", id: "MjCZfZfucEc",
title: "ITZY “LOCO” M/V @ITZY", title: "ITZY “LOCO” M/V @ITZY",
length: Some(233), length: Some(233),
@ -365,7 +379,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -375,16 +389,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 203129706, view_count: Some(203129706),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "2FzSv66c7TQ", id: "2FzSv66c7TQ",
title: "A E S P A (에스파) ALL SONGS PLAYLIST 2022 | 에스파 노래 모음", title: "A E S P A (에스파) ALL SONGS PLAYLIST 2022 | 에스파 노래 모음",
length: Some(3441), length: Some(3441),
@ -400,7 +416,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCK8S6QMrTk1G8TYQwIyDo-w", id: "UCK8S6QMrTk1G8TYQwIyDo-w",
name: "LQ K-POP", name: "LQ K-POP",
avatar: [ avatar: [
@ -410,16 +426,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 531757, view_count: Some(531757),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "CevxZvSJLk8", id: "CevxZvSJLk8",
title: "Katy Perry - Roar (Official)", title: "Katy Perry - Roar (Official)",
length: Some(270), length: Some(270),
@ -435,7 +453,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCYvmuw-JtVrTZQ-7Y4kd63Q", id: "UCYvmuw-JtVrTZQ-7Y4kd63Q",
name: "Katy Perry", name: "Katy Perry",
avatar: [ avatar: [
@ -445,16 +463,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("9 years ago"), publish_date_txt: Some("9 years ago"),
view_count: 3656394146, view_count: Some(3656394146),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "bwmSjveL3Lc", id: "bwmSjveL3Lc",
title: "BLACKPINK - \'붐바야 (BOOMBAYAH)\' M/V", title: "BLACKPINK - \'붐바야 (BOOMBAYAH)\' M/V",
length: Some(244), length: Some(244),
@ -470,7 +490,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -480,16 +500,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 years ago"), publish_date_txt: Some("6 years ago"),
view_count: 1479871637, view_count: Some(1479871637),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "CM4CkVFmTds", id: "CM4CkVFmTds",
title: "TWICE \"I CAN\'T STOP ME\" M/V", title: "TWICE \"I CAN\'T STOP ME\" M/V",
length: Some(221), length: Some(221),
@ -505,7 +527,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -515,16 +537,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 456763969, view_count: Some(456763969),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "ioNng23DkIM", id: "ioNng23DkIM",
title: "BLACKPINK - \'How You Like That\' M/V", title: "BLACKPINK - \'How You Like That\' M/V",
length: Some(184), length: Some(184),
@ -540,7 +564,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -550,16 +574,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 1149727787, view_count: Some(1149727787),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "BL-aIpCLWnU", id: "BL-aIpCLWnU",
title: "Black Mamba", title: "Black Mamba",
length: Some(175), length: Some(175),
@ -575,7 +601,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg", id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa", name: "aespa",
avatar: [ avatar: [
@ -585,16 +611,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 86080254, view_count: Some(86080254),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Jh4QFaPmdss", id: "Jh4QFaPmdss",
title: "(G)I-DLE - \'TOMBOY\' Official Music Video", title: "(G)I-DLE - \'TOMBOY\' Official Music Video",
length: Some(198), length: Some(198),
@ -610,7 +638,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCritGVo7pLJLUS8wEu32vow", id: "UCritGVo7pLJLUS8wEu32vow",
name: "(G)I-DLE (여자)아이들 (Official YouTube Channel)", name: "(G)I-DLE (여자)아이들 (Official YouTube Channel)",
avatar: [ avatar: [
@ -620,16 +648,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 169858302, view_count: Some(169858302),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "WPdWvnAAurg", id: "WPdWvnAAurg",
title: "aespa 에스파 \'Savage\' MV", title: "aespa 에스파 \'Savage\' MV",
length: Some(259), length: Some(259),
@ -645,7 +675,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -655,16 +685,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 months ago"), publish_date_txt: Some("11 months ago"),
view_count: 216164610, view_count: Some(216164610),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Z7yNvMzz2zg", id: "Z7yNvMzz2zg",
title: "Red Velvet 레드벨벳 \'Psycho\' Performance Video", title: "Red Velvet 레드벨벳 \'Psycho\' Performance Video",
length: Some(216), length: Some(216),
@ -680,7 +712,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCk9GmdlDTBfgGRb7vXeRMoQ", id: "UCk9GmdlDTBfgGRb7vXeRMoQ",
name: "Red Velvet", name: "Red Velvet",
avatar: [ avatar: [
@ -690,26 +722,32 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 135093083, view_count: Some(135093083),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("CBQSExILWmVlcnJudUxpNUXAAQHIAQEYACreBjJzNkw2d3pfQkFyOEJBb0Q4ajRBQ2czQ1Bnb0l5dFdIekt5Tm1ZMXBDZ1B5UGdBS0o5SS1KQW9pVUV4eU1UUldiR05sYkRKVE16UlpSMmw1WlZkRU1rOW9jbU4wVGt4Q1psVk9PUW9EOGo0QUNoTFNQZzhLRFZKRVdtVmxjbkp1ZFV4cE5VVUtBX0ktQUFvT3dqNExDTjIyMHJ2Q3h2cVNsQUVLQV9JLUFBb3cwajR0Q2l0U1JFTk1RVXMxZFhsZmF6STNkWFV0UlhSUlgySTFWVEp5TWpaRVRrUmFUMjFPY1Vka1kyTlZTVWRSQ2dQeVBnQUtEc0ktQ3dqZnZzMkxuNFRwbmJRQkNnUHlQZ0FLRGNJLUNnallxdldKeExEazhYc0tBX0ktQUFvT3dqNExDTlNUMDZfUXlOdjZxUUVLQV9JLUFBb093ajRMQ1AyMThJbnd0cldWdHdFS0FfSS1BQW9Od2o0S0NJbmp5ZmpWdHVMMVh3b0Q4ajRBQ2czQ1Bnb0l4LUM1djltdnBwZ3lDZ1B5UGdBS0RzSS1Dd2kwMnZQMC10ZTBydGdCQ2dQeVBnQUtEY0ktQ2dqUDNLU2s3Nno4OVFrS0FfSS1BQW9Od2o0S0NMZTVyN3p2MGVTRWJ3b0Q4ajRBQ2czQ1Bnb0kyNXVaaTVYU2dPY0lDZ1B5UGdBS0RzSS1Dd2lEb1k3dXR2RFp3WW9CQ2dQeVBnQUtEY0ktQ2dqMXRLMkVxY1RtM3dRS0FfSS1BQW9Od2o0S0NNdnRtWl9hZ29TUEpnb0Q4ajRBQ2czQ1Bnb0l1UFdDZ09mWDFmdFlDZ1B5UGdBS0RjSS1DZ2k0dHNfbnpMZWozbWNTRkFBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbUdnUUlBQkFCR2dRSUFoQURHZ1FJQkJBRkdnUUlCaEFIR2dRSUNCQUpHZ1FJQ2hBTEdnUUlEQkFOR2dRSURoQVBHZ1FJRUJBUkdnUUlFaEFUR2dRSUZCQVZHZ1FJRmhBWEdnUUlHQkFaR2dRSUdoQWJHZ1FJSEJBZEdnUUlIaEFmR2dRSUlCQWhHZ1FJSWhBakdnUUlKQkFsR2dRSUpoQW5LaFFBQWdRR0NBb01EaEFTRkJZWUdod2VJQ0lrSmdqD3dhdGNoLW5leHQtZmVlZA%3D%3D"), ctoken: Some("CBQSExILWmVlcnJudUxpNUXAAQHIAQEYACreBjJzNkw2d3pfQkFyOEJBb0Q4ajRBQ2czQ1Bnb0l5dFdIekt5Tm1ZMXBDZ1B5UGdBS0o5SS1KQW9pVUV4eU1UUldiR05sYkRKVE16UlpSMmw1WlZkRU1rOW9jbU4wVGt4Q1psVk9PUW9EOGo0QUNoTFNQZzhLRFZKRVdtVmxjbkp1ZFV4cE5VVUtBX0ktQUFvT3dqNExDTjIyMHJ2Q3h2cVNsQUVLQV9JLUFBb3cwajR0Q2l0U1JFTk1RVXMxZFhsZmF6STNkWFV0UlhSUlgySTFWVEp5TWpaRVRrUmFUMjFPY1Vka1kyTlZTVWRSQ2dQeVBnQUtEc0ktQ3dqZnZzMkxuNFRwbmJRQkNnUHlQZ0FLRGNJLUNnallxdldKeExEazhYc0tBX0ktQUFvT3dqNExDTlNUMDZfUXlOdjZxUUVLQV9JLUFBb093ajRMQ1AyMThJbnd0cldWdHdFS0FfSS1BQW9Od2o0S0NJbmp5ZmpWdHVMMVh3b0Q4ajRBQ2czQ1Bnb0l4LUM1djltdnBwZ3lDZ1B5UGdBS0RzSS1Dd2kwMnZQMC10ZTBydGdCQ2dQeVBnQUtEY0ktQ2dqUDNLU2s3Nno4OVFrS0FfSS1BQW9Od2o0S0NMZTVyN3p2MGVTRWJ3b0Q4ajRBQ2czQ1Bnb0kyNXVaaTVYU2dPY0lDZ1B5UGdBS0RzSS1Dd2lEb1k3dXR2RFp3WW9CQ2dQeVBnQUtEY0ktQ2dqMXRLMkVxY1RtM3dRS0FfSS1BQW9Od2o0S0NNdnRtWl9hZ29TUEpnb0Q4ajRBQ2czQ1Bnb0l1UFdDZ09mWDFmdFlDZ1B5UGdBS0RjSS1DZ2k0dHNfbnpMZWozbWNTRkFBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbUdnUUlBQkFCR2dRSUFoQURHZ1FJQkJBRkdnUUlCaEFIR2dRSUNCQUpHZ1FJQ2hBTEdnUUlEQkFOR2dRSURoQVBHZ1FJRUJBUkdnUUlFaEFUR2dRSUZCQVZHZ1FJRmhBWEdnUUlHQkFaR2dRSUdoQWJHZ1FJSEJBZEdnUUlIaEFmR2dRSUlCQWhHZ1FJSWhBakdnUUlKQkFsR2dRSUpoQW5LaFFBQWdRR0NBb01EaEFTRkJZWUdod2VJQ0lrSmdqD3dhdGNoLW5leHQtZmVlZA%3D%3D"),
visitor_data: Some("CgtCeURHR09uNlJ5TSjOiLqZBg%3D%3D"),
endpoint: next,
), ),
top_comments: Paginator( top_comments: Paginator(
count: Some(705000), count: Some(705000),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyJSIRIgtaZWVycm51TGk1RTAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyJSIRIgtaZWVycm51TGk1RTAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"),
endpoint: next,
), ),
latest_comments: Paginator( latest_comments: Paginator(
count: Some(705000), count: Some(705000),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyOCIRIgtaZWVycm51TGk1RTABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyOCIRIgtaZWVycm51TGk1RTABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"),
endpoint: next,
), ),
) )

View file

@ -91,7 +91,7 @@ VideoDetails(
height: 176, height: 176,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: Some(31000000), subscriber_count: Some(31000000),
), ),
view_count: 234258725, view_count: 234258725,
@ -104,7 +104,7 @@ VideoDetails(
recommended: Paginator( recommended: Paginator(
count: None, count: None,
items: [ items: [
RecommendedVideo( VideoItem(
id: "WPdWvnAAurg", id: "WPdWvnAAurg",
title: "aespa 에스파 \'Savage\' MV", title: "aespa 에스파 \'Savage\' MV",
length: Some(259), length: Some(259),
@ -120,7 +120,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -130,16 +130,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 218055265, view_count: Some(218055265),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "4TWR90KJl84", id: "4TWR90KJl84",
title: "aespa 에스파 \'Next Level\' MV", title: "aespa 에스파 \'Next Level\' MV",
length: Some(236), length: Some(236),
@ -155,7 +157,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -165,16 +167,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 248023999, view_count: Some(248023999),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "uR8Mrt1IpXg", id: "uR8Mrt1IpXg",
title: "Red Velvet 레드벨벳 \'Psycho\' MV", title: "Red Velvet 레드벨벳 \'Psycho\' MV",
length: Some(216), length: Some(216),
@ -190,7 +194,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -200,16 +204,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 347102621, view_count: Some(347102621),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "UUUWIGx3hDE", id: "UUUWIGx3hDE",
title: "ITZY \"WANNABE\" Performance Video", title: "ITZY \"WANNABE\" Performance Video",
length: Some(198), length: Some(198),
@ -225,7 +231,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCDhM2k2Cua-JdobAh5moMFg", id: "UCDhM2k2Cua-JdobAh5moMFg",
name: "ITZY", name: "ITZY",
avatar: [ avatar: [
@ -235,16 +241,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 97453393, view_count: Some(97453393),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "NoYKBAajoyo", id: "NoYKBAajoyo",
title: "EVERGLOW (에버글로우) - DUN DUN MV", title: "EVERGLOW (에버글로우) - DUN DUN MV",
length: Some(209), length: Some(209),
@ -260,7 +268,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC_pwIXKXNm5KGhdEVzmY60A", id: "UC_pwIXKXNm5KGhdEVzmY60A",
name: "Stone Music Entertainment", name: "Stone Music Entertainment",
avatar: [ avatar: [
@ -270,16 +278,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 266364690, view_count: Some(266364690),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "32si5cfrCNc", id: "32si5cfrCNc",
title: "BLACKPINK - \'How You Like That\' DANCE PERFORMANCE VIDEO", title: "BLACKPINK - \'How You Like That\' DANCE PERFORMANCE VIDEO",
length: Some(181), length: Some(181),
@ -295,7 +305,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -305,16 +315,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 1254749733, view_count: Some(1254749733),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "CM4CkVFmTds", id: "CM4CkVFmTds",
title: "TWICE \"I CAN\'T STOP ME\" M/V", title: "TWICE \"I CAN\'T STOP ME\" M/V",
length: Some(221), length: Some(221),
@ -330,7 +342,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -340,16 +352,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 459831562, view_count: Some(459831562),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "UZPZyd5vE1c", id: "UZPZyd5vE1c",
title: "Shut Down", title: "Shut Down",
length: Some(176), length: Some(176),
@ -365,7 +379,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -375,16 +389,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 7118730, view_count: Some(7118730),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "CKZvWhCqx1s", id: "CKZvWhCqx1s",
title: "ROSÉ - \'On The Ground\' M/V", title: "ROSÉ - \'On The Ground\' M/V",
length: Some(189), length: Some(189),
@ -400,7 +416,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -410,16 +426,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 300492226, view_count: Some(300492226),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "fE2h3lGlOsk", id: "fE2h3lGlOsk",
title: "ITZY \"WANNABE\" M/V @ITZY", title: "ITZY \"WANNABE\" M/V @ITZY",
length: Some(219), length: Some(219),
@ -435,7 +453,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -445,16 +463,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 469178299, view_count: Some(469178299),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Y8JFxS1HlDo", id: "Y8JFxS1HlDo",
title: "IVE 아이브 \'LOVE DIVE\' MV", title: "IVE 아이브 \'LOVE DIVE\' MV",
length: Some(179), length: Some(179),
@ -470,7 +490,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCYDmx2Sfpnaxg488yBpZIGg", id: "UCYDmx2Sfpnaxg488yBpZIGg",
name: "starshipTV", name: "starshipTV",
avatar: [ avatar: [
@ -480,16 +500,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 161053206, view_count: Some(161053206),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "dNCWe_6HAM8", id: "dNCWe_6HAM8",
title: "LISA - \'MONEY\' EXCLUSIVE PERFORMANCE VIDEO", title: "LISA - \'MONEY\' EXCLUSIVE PERFORMANCE VIDEO",
length: Some(171), length: Some(171),
@ -505,7 +527,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -515,16 +537,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 694135299, view_count: Some(694135299),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "tyrVtwE8Gv0", id: "tyrVtwE8Gv0",
title: "NCT U 엔시티 유 \'Make A Wish (Birthday Song)\' MV", title: "NCT U 엔시티 유 \'Make A Wish (Birthday Song)\' MV",
length: Some(249), length: Some(249),
@ -540,7 +564,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -550,16 +574,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 256797155, view_count: Some(256797155),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "gU2HqP4NxUs", id: "gU2HqP4NxUs",
title: "BLACKPINK - Pretty Savage 1011 SBS Inkigayo", title: "BLACKPINK - Pretty Savage 1011 SBS Inkigayo",
length: Some(208), length: Some(208),
@ -575,7 +601,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -585,16 +611,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 285625201, view_count: Some(285625201),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Ujb-gvqsoi0", id: "Ujb-gvqsoi0",
title: "Red Velvet - IRENE & SEULGI \'Monster\' MV", title: "Red Velvet - IRENE & SEULGI \'Monster\' MV",
length: Some(182), length: Some(182),
@ -610,7 +638,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -620,16 +648,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 127297352, view_count: Some(127297352),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "KhTeiaCezwM", id: "KhTeiaCezwM",
title: "[MV] MAMAMOO (마마무) - HIP", title: "[MV] MAMAMOO (마마무) - HIP",
length: Some(211), length: Some(211),
@ -645,7 +675,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCuhAUMLzJxlP1W7mEk0_6lA", id: "UCuhAUMLzJxlP1W7mEk0_6lA",
name: "MAMAMOO", name: "MAMAMOO",
avatar: [ avatar: [
@ -655,16 +685,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 357346135, view_count: Some(357346135),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "XJDPzNzQ3RE", id: "XJDPzNzQ3RE",
title: "Run BTS! 2022 Special Episode - Fly BTS Fly Part 1", title: "Run BTS! 2022 Special Episode - Fly BTS Fly Part 1",
length: Some(2070), length: Some(2070),
@ -680,7 +712,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCLkAepWjdylmXSltofFvsYQ", id: "UCLkAepWjdylmXSltofFvsYQ",
name: "BANGTANTV", name: "BANGTANTV",
avatar: [ avatar: [
@ -690,16 +722,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 hours ago"), publish_date_txt: Some("2 hours ago"),
view_count: 748983, view_count: Some(748983),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "0lXwMdnpoFQ", id: "0lXwMdnpoFQ",
title: "aespa 에스파 \'도깨비불 (Illusion)\' Dance Practice", title: "aespa 에스파 \'도깨비불 (Illusion)\' Dance Practice",
length: Some(210), length: Some(210),
@ -715,7 +749,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC473RoZQE2gtgZJ61ZW0ZDQ", id: "UC473RoZQE2gtgZJ61ZW0ZDQ",
name: "SMP FLOOR", name: "SMP FLOOR",
avatar: [ avatar: [
@ -725,16 +759,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 12347702, view_count: Some(12347702),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "IHNzOHi8sJs", id: "IHNzOHi8sJs",
title: "BLACKPINK - ‘뚜두뚜두 (DDU-DU DDU-DU) M/V", title: "BLACKPINK - ‘뚜두뚜두 (DDU-DU DDU-DU) M/V",
length: Some(216), length: Some(216),
@ -750,7 +786,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -760,26 +796,32 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 years ago"), publish_date_txt: Some("4 years ago"),
view_count: 1964840790, view_count: Some(1964840790),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("CBQSExILWmVlcnJudUxpNUXAAQHIAQEYACqiDDJzNkw2d3lTQ1FxUENRb0Q4ajRBQ2czQ1Bnb0l1UFdDZ09mWDFmdFlDZ1B5UGdBS0RzSS1Dd2pPcjZhVTlMN2ttdUVCQ2dQeVBnQUtFdEktRHdvTlVrUmFaV1Z5Y201MVRHazFSUW9EOGo0QUNnN0NQZ3NJLU1xaTZ1MlZ3NC01QVFvRDhqNEFDZzNDUGdvSXNZamU0NGJFeGFKUkNnUHlQZ0FLRGNJLUNnaXF4bzYxd01DQ3d6WUtBX0ktQUFvT3dqNExDTmVSckxfYzNNaTEzd0VLQV9JLUFBb053ajRLQ051Ym1ZdVYwb0RuQ0FvRDhqNEFDZzNDUGdvSTE2YTg4NTI1OXNsUkNnUHlQZ0FLRGNJLUNnamJqcXVGb2V1YjB3Z0tBX0ktQUFvTndqNEtDTW4xbEkzbHUtaW1mQW9EOGo0QUNnM0NQZ29JdXFpZTZ0SzRrZUZqQ2dQeVBnQUtEY0ktQ2dqUGdaejB2OC1sNkhRS0FfSS1BQW9Pd2o0TENQMjE4SW53dHJXVnR3RUtBX0ktQUFvT3dqNExDTXVLdF9DUDllR21nUUVLQV9JLUFBb053ajRLQ0szRXN0V3YwTC1iVWdvRDhqNEFDZzNDUGdvSWc1NzdoSnJSdDRvcUNnUHlQZ0FLRGNJLUNnaVJ1c1BtemZtenlGd0tBX0ktQUFvT3dqNExDTlRBcHMtZGh2eXEwZ0VLQV9JLUFBb053ajRLQ0p2aDhzV0g1OXk1SUFvRDhqNEFDaF9TUGh3S0dsSkVRVTk2ZFZaM1JWbDNZMUZFTkhWMmNHZEJUbU5JU0ZWM0NoX1NQaHdLR2xKRVFVOWZjQzFWYmpCSGVUbHVXRlZ0Wm1kaE0xTlNYMXAzQ2hfU1Bod0tHbEpFUVU5cFEwaENhR3R1VTBSd09HcFZWekJPUzFoWU9FMVJDaF9TUGh3S0dsSkVRVTlYWjBsd1lVbDZha1p6UVhkeE5GOXhWR2hyTlROQkNoX1NQaHdLR2xKRVFVOXFNVkpuZEhkZmVtZHJibWxSWkdkTU5XTnlVRmxCQ2hfU1Bod0tHbEpFUVU4NWExbHRhMU5KVG5CVGFYVldTalEzUjNkT1RWSm5DaF9TUGh3S0dsSkVRVTlGYjNOTlVtbHlhM1ZKTjNvNE1tSmZia0oyUjNoQkNoX1NQaHdLR2xKRVFVOW1PRlExTURaUVZGcFVWRmxDWm01RVRVNURiR0ZSQ2hfU1Bod0tHbEpFUVU5UllqSlhRWGxLYTBwMlRURmhaMGRYZEhkRkxVOUJDaF9TUGh3S0dsSkVRVTlNWDFGNk1scFJRbUZNUkROTFExTnFWalpYZG5wM0NoX1NQaHdLR2xKRVFVOXpjeTFGWVdSRFpHZzBUVmxYV0hsMGFtWkpabFYzQ2hfU1Bod0tHbEpFUVU4MVRraFVXblJGV0ROSGJIWlhRMjgyYTJOdGFrdDNDaF9TUGh3S0dsSkVRVTlMWDBjMVRVZzFaM0ZJUTNRd1VXdENZVlZJTjJwUkNoX1NQaHdLR2xKRVFVOVpUWEZhWlV4U1RXMXhaRW8zZGs5b09UQXRhME5CQ2hfU1Bod0tHbEpFUVU4eVNGbEJhMFpIYzBGSmFWVmthRE5NVUhGRE5UZG5FaFVBQWdRR0NBb01EaEFTRkJZWUdod2VJQ0lrSmlnYUJBZ0FFQUVhQkFnQ0VBTWFCQWdFRUFVYUJBZ0dFQWNhQkFnSUVBa2FCQWdLRUFzYUJBZ01FQTBhQkFnT0VBOGFCQWdRRUJFYUJBZ1NFQk1hQkFnVUVCVWFCQWdXRUJjYUJBZ1lFQmthQkFnYUVCc2FCQWdjRUIwYUJBZ2VFQjhhQkFnZ0VDRWFCQWdpRUNNYUJBZ2tFQ1VhQkFnbUVDY2FCQWdvRUNrYUJBZ29FQ29hQkFnb0VDc2FCQWdvRUN3YUJBZ29FQzBhQkFnb0VDNGFCQWdvRUM4YUJBZ29FREFhQkFnb0VERWFCQWdvRURJYUJBZ29FRE1hQkFnb0VEUWFCQWdvRURVYUJBZ29FRFlhQkFnb0VEY3FGUUFDQkFZSUNnd09FQklVRmhnYUhCNGdJaVFtS0FqD3dhdGNoLW5leHQtZmVlZA%3D%3D"), ctoken: Some("CBQSExILWmVlcnJudUxpNUXAAQHIAQEYACqiDDJzNkw2d3lTQ1FxUENRb0Q4ajRBQ2czQ1Bnb0l1UFdDZ09mWDFmdFlDZ1B5UGdBS0RzSS1Dd2pPcjZhVTlMN2ttdUVCQ2dQeVBnQUtFdEktRHdvTlVrUmFaV1Z5Y201MVRHazFSUW9EOGo0QUNnN0NQZ3NJLU1xaTZ1MlZ3NC01QVFvRDhqNEFDZzNDUGdvSXNZamU0NGJFeGFKUkNnUHlQZ0FLRGNJLUNnaXF4bzYxd01DQ3d6WUtBX0ktQUFvT3dqNExDTmVSckxfYzNNaTEzd0VLQV9JLUFBb053ajRLQ051Ym1ZdVYwb0RuQ0FvRDhqNEFDZzNDUGdvSTE2YTg4NTI1OXNsUkNnUHlQZ0FLRGNJLUNnamJqcXVGb2V1YjB3Z0tBX0ktQUFvTndqNEtDTW4xbEkzbHUtaW1mQW9EOGo0QUNnM0NQZ29JdXFpZTZ0SzRrZUZqQ2dQeVBnQUtEY0ktQ2dqUGdaejB2OC1sNkhRS0FfSS1BQW9Pd2o0TENQMjE4SW53dHJXVnR3RUtBX0ktQUFvT3dqNExDTXVLdF9DUDllR21nUUVLQV9JLUFBb053ajRLQ0szRXN0V3YwTC1iVWdvRDhqNEFDZzNDUGdvSWc1NzdoSnJSdDRvcUNnUHlQZ0FLRGNJLUNnaVJ1c1BtemZtenlGd0tBX0ktQUFvT3dqNExDTlRBcHMtZGh2eXEwZ0VLQV9JLUFBb053ajRLQ0p2aDhzV0g1OXk1SUFvRDhqNEFDaF9TUGh3S0dsSkVRVTk2ZFZaM1JWbDNZMUZFTkhWMmNHZEJUbU5JU0ZWM0NoX1NQaHdLR2xKRVFVOWZjQzFWYmpCSGVUbHVXRlZ0Wm1kaE0xTlNYMXAzQ2hfU1Bod0tHbEpFUVU5cFEwaENhR3R1VTBSd09HcFZWekJPUzFoWU9FMVJDaF9TUGh3S0dsSkVRVTlYWjBsd1lVbDZha1p6UVhkeE5GOXhWR2hyTlROQkNoX1NQaHdLR2xKRVFVOXFNVkpuZEhkZmVtZHJibWxSWkdkTU5XTnlVRmxCQ2hfU1Bod0tHbEpFUVU4NWExbHRhMU5KVG5CVGFYVldTalEzUjNkT1RWSm5DaF9TUGh3S0dsSkVRVTlGYjNOTlVtbHlhM1ZKTjNvNE1tSmZia0oyUjNoQkNoX1NQaHdLR2xKRVFVOW1PRlExTURaUVZGcFVWRmxDWm01RVRVNURiR0ZSQ2hfU1Bod0tHbEpFUVU5UllqSlhRWGxLYTBwMlRURmhaMGRYZEhkRkxVOUJDaF9TUGh3S0dsSkVRVTlNWDFGNk1scFJRbUZNUkROTFExTnFWalpYZG5wM0NoX1NQaHdLR2xKRVFVOXpjeTFGWVdSRFpHZzBUVmxYV0hsMGFtWkpabFYzQ2hfU1Bod0tHbEpFUVU4MVRraFVXblJGV0ROSGJIWlhRMjgyYTJOdGFrdDNDaF9TUGh3S0dsSkVRVTlMWDBjMVRVZzFaM0ZJUTNRd1VXdENZVlZJTjJwUkNoX1NQaHdLR2xKRVFVOVpUWEZhWlV4U1RXMXhaRW8zZGs5b09UQXRhME5CQ2hfU1Bod0tHbEpFUVU4eVNGbEJhMFpIYzBGSmFWVmthRE5NVUhGRE5UZG5FaFVBQWdRR0NBb01EaEFTRkJZWUdod2VJQ0lrSmlnYUJBZ0FFQUVhQkFnQ0VBTWFCQWdFRUFVYUJBZ0dFQWNhQkFnSUVBa2FCQWdLRUFzYUJBZ01FQTBhQkFnT0VBOGFCQWdRRUJFYUJBZ1NFQk1hQkFnVUVCVWFCQWdXRUJjYUJBZ1lFQmthQkFnYUVCc2FCQWdjRUIwYUJBZ2VFQjhhQkFnZ0VDRWFCQWdpRUNNYUJBZ2tFQ1VhQkFnbUVDY2FCQWdvRUNrYUJBZ29FQ29hQkFnb0VDc2FCQWdvRUN3YUJBZ29FQzBhQkFnb0VDNGFCQWdvRUM4YUJBZ29FREFhQkFnb0VERWFCQWdvRURJYUJBZ29FRE1hQkFnb0VEUWFCQWdvRURVYUJBZ29FRFlhQkFnb0VEY3FGUUFDQkFZSUNnd09FQklVRmhnYUhCNGdJaVFtS0FqD3dhdGNoLW5leHQtZmVlZA%3D%3D"),
visitor_data: Some("Cgs2V0p6ZW5ab1ozTSjkrpaaBg%3D%3D"),
endpoint: next,
), ),
top_comments: Paginator( top_comments: Paginator(
count: Some(705000), count: Some(705000),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyJSIRIgtaZWVycm51TGk1RTAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyJSIRIgtaZWVycm51TGk1RTAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"),
endpoint: next,
), ),
latest_comments: Paginator( latest_comments: Paginator(
count: Some(705000), count: Some(705000),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyOCIRIgtaZWVycm51TGk1RTABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyOCIRIgtaZWVycm51TGk1RTABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"),
endpoint: next,
), ),
) )

View file

@ -287,7 +287,7 @@ VideoDetails(
height: 176, height: 176,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: Some(14900000), subscriber_count: Some(14900000),
), ),
view_count: 1251797, view_count: 1251797,
@ -525,7 +525,7 @@ VideoDetails(
recommended: Paginator( recommended: Paginator(
count: None, count: None,
items: [ items: [
RecommendedVideo( VideoItem(
id: "t03rmc-prJo", id: "t03rmc-prJo",
title: "This PC took 600 HOURS to Build!", title: "This PC took 600 HOURS to Build!",
length: Some(1505), length: Some(1505),
@ -541,7 +541,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -551,16 +551,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 3449572, view_count: Some(3449572),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "4ozYlgOuYis", id: "4ozYlgOuYis",
title: "They told me I was stupid - heating my pool with computers", title: "They told me I was stupid - heating my pool with computers",
length: Some(691), length: Some(691),
@ -576,7 +578,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -586,16 +588,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 3209930, view_count: Some(3209930),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "THxkY59_xko", id: "THxkY59_xko",
title: "Is the fastest GPU ALWAYS the best?", title: "Is the fastest GPU ALWAYS the best?",
length: Some(979), length: Some(979),
@ -611,7 +615,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -621,16 +625,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 hours ago"), publish_date_txt: Some("6 hours ago"),
view_count: 640179, view_count: Some(640179),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "UJ-KZzVUV7U", id: "UJ-KZzVUV7U",
title: "This toaster cost HOW MUCH?? - Revolution InstaGLO R270 Toaster", title: "This toaster cost HOW MUCH?? - Revolution InstaGLO R270 Toaster",
length: Some(880), length: Some(880),
@ -646,7 +652,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCdBK94H6oZT2Q7l0-b0xmMg", id: "UCdBK94H6oZT2Q7l0-b0xmMg",
name: "ShortCircuit", name: "ShortCircuit",
avatar: [ avatar: [
@ -656,16 +662,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 905709, view_count: Some(905709),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "yayAQAC1XiE", id: "yayAQAC1XiE",
title: "Intel PLEASE let me Overclock this!", title: "Intel PLEASE let me Overclock this!",
length: Some(799), length: Some(799),
@ -681,7 +689,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -691,16 +699,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 days ago"), publish_date_txt: Some("7 days ago"),
view_count: 998245, view_count: Some(998245),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "y4T374GtKLI", id: "y4T374GtKLI",
title: "When The Grid Goes Down: How To Power Essential Devices (i.e., Refrigerator)", title: "When The Grid Goes Down: How To Power Essential Devices (i.e., Refrigerator)",
length: Some(1239), length: Some(1239),
@ -716,7 +726,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCmb2QRAjdnkse21CtxAQ-cA", id: "UCmb2QRAjdnkse21CtxAQ-cA",
name: "City Prepping", name: "City Prepping",
avatar: [ avatar: [
@ -726,16 +736,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 132460, view_count: Some(132460),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "b3x28s61q3c", id: "b3x28s61q3c",
title: "The most EXPENSIVE thing I own.", title: "The most EXPENSIVE thing I own.",
length: Some(887), length: Some(887),
@ -751,7 +763,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -761,16 +773,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 2372992, view_count: Some(2372992),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "LQ95XJAwaoc", id: "LQ95XJAwaoc",
title: "My favorite car (sucks) - Lucid Air GT", title: "My favorite car (sucks) - Lucid Air GT",
length: Some(1162), length: Some(1162),
@ -786,7 +800,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCdBK94H6oZT2Q7l0-b0xmMg", id: "UCdBK94H6oZT2Q7l0-b0xmMg",
name: "ShortCircuit", name: "ShortCircuit",
avatar: [ avatar: [
@ -796,16 +810,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 565416, view_count: Some(565416),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "WVjtK71qqXU", id: "WVjtK71qqXU",
title: "I bought a SECOND GPU… but NOT for gaming…", title: "I bought a SECOND GPU… but NOT for gaming…",
length: Some(754), length: Some(754),
@ -821,7 +837,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -831,16 +847,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 day ago"), publish_date_txt: Some("1 day ago"),
view_count: 1199845, view_count: Some(1199845),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "vtvFVH9JdNI", id: "vtvFVH9JdNI",
title: "I bought every Nintendo Console EVER.", title: "I bought every Nintendo Console EVER.",
length: Some(1381), length: Some(1381),
@ -856,7 +874,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCMiJRAwDNSNzuYeN2uWa0pA", id: "UCMiJRAwDNSNzuYeN2uWa0pA",
name: "Mrwhosetheboss", name: "Mrwhosetheboss",
avatar: [ avatar: [
@ -866,16 +884,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 days ago"), publish_date_txt: Some("2 days ago"),
view_count: 1379793, view_count: Some(1379793),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "J6Ga4wciA2k", id: "J6Ga4wciA2k",
title: "THIS Wish.com Gaming PC is WORSE!", title: "THIS Wish.com Gaming PC is WORSE!",
length: Some(1545), length: Some(1545),
@ -891,7 +911,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -901,16 +921,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 2775764, view_count: Some(2775764),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "CsoKWsZ-Tyw", id: "CsoKWsZ-Tyw",
title: "The Personal Gaming Theater - HOLY $H!T Samsung Odyssey Ark", title: "The Personal Gaming Theater - HOLY $H!T Samsung Odyssey Ark",
length: Some(1182), length: Some(1182),
@ -926,7 +948,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -936,16 +958,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 2449262, view_count: Some(2449262),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "9T98VsMe3oo", id: "9T98VsMe3oo",
title: "How are we going to do this?", title: "How are we going to do this?",
length: Some(1124), length: Some(1124),
@ -961,7 +985,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -971,16 +995,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 4321218, view_count: Some(4321218),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "5Hxr9k5Vdc4", id: "5Hxr9k5Vdc4",
title: "Building the $1,000,000 Computer", title: "Building the $1,000,000 Computer",
length: Some(1659), length: Some(1659),
@ -996,7 +1022,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -1006,16 +1032,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 3270062, view_count: Some(3270062),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "12Hcbx33Rb4", id: "12Hcbx33Rb4",
title: "BREAKING NEWS! - EVGA will no longer do business with NVIDIA", title: "BREAKING NEWS! - EVGA will no longer do business with NVIDIA",
length: Some(1262), length: Some(1262),
@ -1031,7 +1059,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCkWQ0gDrqOCarmUKmppD7GQ", id: "UCkWQ0gDrqOCarmUKmppD7GQ",
name: "JayzTwoCents", name: "JayzTwoCents",
avatar: [ avatar: [
@ -1041,16 +1069,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 1274410, view_count: Some(1274410),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "EHkkwCjQzsc", id: "EHkkwCjQzsc",
title: "Prepper (2016) | Full Post-Apocalyptic Thriller Movie HD", title: "Prepper (2016) | Full Post-Apocalyptic Thriller Movie HD",
length: Some(5982), length: Some(5982),
@ -1066,7 +1096,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCRX7UEyE8kp35mPrgC2sosA", id: "UCRX7UEyE8kp35mPrgC2sosA",
name: "JoBlo Movies", name: "JoBlo Movies",
avatar: [ avatar: [
@ -1076,16 +1106,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 209854, view_count: Some(209854),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "AOdp09SYhCc", id: "AOdp09SYhCc",
title: "This Is So Embarrassing! - Building a PC with My Sister", title: "This Is So Embarrassing! - Building a PC with My Sister",
length: Some(1063), length: Some(1063),
@ -1101,7 +1133,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -1111,16 +1143,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 2453269, view_count: Some(2453269),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "CTIpNtHWVtQ", id: "CTIpNtHWVtQ",
title: "Why Pay $1000 for a 25 year old PC! - NIXSYS Windows 98 PC", title: "Why Pay $1000 for a 25 year old PC! - NIXSYS Windows 98 PC",
length: Some(1112), length: Some(1112),
@ -1136,7 +1170,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -1146,16 +1180,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 1478434, view_count: Some(1478434),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "3RIp7CwkBeA", id: "3RIp7CwkBeA",
title: "I Hope You Have a LOT of Money... RTX 4000 Announced", title: "I Hope You Have a LOT of Money... RTX 4000 Announced",
length: Some(569), length: Some(569),
@ -1171,7 +1207,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -1181,16 +1217,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 1816036, view_count: Some(1816036),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "HZiaHEmE9PQ", id: "HZiaHEmE9PQ",
title: "Buying a Chromebook was a BIG MISTAKE", title: "Buying a Chromebook was a BIG MISTAKE",
length: Some(880), length: Some(880),
@ -1206,7 +1244,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -1216,26 +1254,32 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("9 days ago"), publish_date_txt: Some("9 days ago"),
view_count: 1625226, view_count: Some(1625226),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("CBQSExILbkZEQnhCVWZFNzTAAQHIAQEYACqIBjJzNkw2d3lfQkFxOEJBb0Q4ajRBQ2c3Q1Bnc0ltdG1tX1p6ei1xYTNBUW9EOGo0QUNnN0NQZ3NJcThTNW5lQ1N0c2JpQVFvRDhqNEFDZzNDUGdvSXlvel8tN21NbWI1TUNnUHlQZ0FLRGNJLUNnaTFyOUdxODh6aXoxQUtBX0ktQUFvT3dqNExDS0c4MVlXQWlLRFd5UUVLQV9JLUFBb093ajRMQ0xMUnRJMzRfYjNDeXdFS0FfSS1BQW9Od2o0S0NQZlcxdldzM3AyLWJ3b0Q4ajRBQ2czQ1Bnb0loOVhCZ2NtcjNvY3RDZ1B5UGdBS0RjSS1DZ2oxMHFycnU2VzdyRmtLQV9JLUFBb093ajRMQ05McHBmckhxdkh0dmdFS0FfSS1BQW9Od2o0S0NPbUdpTG13M09iUUp3b0Q4ajRBQ2czQ1Bnb0lySjc1czZ6TGd1VUtDZ1B5UGdBS0RzSS1Dd2lLdmZ1WTdJcmZuX1VCQ2dQeVBnQUtEc0ktQ3dqTzY5WHk1UDZhdnVRQkNnUHlQZ0FLRHNJLUN3aS1pOTN2OFkzM3NOY0JDZ1B5UGdBS0RjSS1DZ2pIbmNQR2dwakp2QkFLQV9JLUFBb013ajRKQ0tlSTRxUzl1dHB6Q2dQeVBnQUtEY0ktQ2dqVXJkbU83YWFLbVFrS0FfSS1BQW9Pd2o0TENPQ0xrT0hDdllxSjNRRUtBX0ktQUFvTndqNEtDUFRwazh6RXc2Yk1IUklVQUFJRUJnZ0tEQTRRRWhRV0dCb2NIaUFpSkNZYUJBZ0FFQUVhQkFnQ0VBTWFCQWdFRUFVYUJBZ0dFQWNhQkFnSUVBa2FCQWdLRUFzYUJBZ01FQTBhQkFnT0VBOGFCQWdRRUJFYUJBZ1NFQk1hQkFnVUVCVWFCQWdXRUJjYUJBZ1lFQmthQkFnYUVCc2FCQWdjRUIwYUJBZ2VFQjhhQkFnZ0VDRWFCQWdpRUNNYUJBZ2tFQ1VhQkFnbUVDY3FGQUFDQkFZSUNnd09FQklVRmhnYUhCNGdJaVFtag93YXRjaC1uZXh0LWZlZWQ%3D"), ctoken: Some("CBQSExILbkZEQnhCVWZFNzTAAQHIAQEYACqIBjJzNkw2d3lfQkFxOEJBb0Q4ajRBQ2c3Q1Bnc0ltdG1tX1p6ei1xYTNBUW9EOGo0QUNnN0NQZ3NJcThTNW5lQ1N0c2JpQVFvRDhqNEFDZzNDUGdvSXlvel8tN21NbWI1TUNnUHlQZ0FLRGNJLUNnaTFyOUdxODh6aXoxQUtBX0ktQUFvT3dqNExDS0c4MVlXQWlLRFd5UUVLQV9JLUFBb093ajRMQ0xMUnRJMzRfYjNDeXdFS0FfSS1BQW9Od2o0S0NQZlcxdldzM3AyLWJ3b0Q4ajRBQ2czQ1Bnb0loOVhCZ2NtcjNvY3RDZ1B5UGdBS0RjSS1DZ2oxMHFycnU2VzdyRmtLQV9JLUFBb093ajRMQ05McHBmckhxdkh0dmdFS0FfSS1BQW9Od2o0S0NPbUdpTG13M09iUUp3b0Q4ajRBQ2czQ1Bnb0lySjc1czZ6TGd1VUtDZ1B5UGdBS0RzSS1Dd2lLdmZ1WTdJcmZuX1VCQ2dQeVBnQUtEc0ktQ3dqTzY5WHk1UDZhdnVRQkNnUHlQZ0FLRHNJLUN3aS1pOTN2OFkzM3NOY0JDZ1B5UGdBS0RjSS1DZ2pIbmNQR2dwakp2QkFLQV9JLUFBb013ajRKQ0tlSTRxUzl1dHB6Q2dQeVBnQUtEY0ktQ2dqVXJkbU83YWFLbVFrS0FfSS1BQW9Pd2o0TENPQ0xrT0hDdllxSjNRRUtBX0ktQUFvTndqNEtDUFRwazh6RXc2Yk1IUklVQUFJRUJnZ0tEQTRRRWhRV0dCb2NIaUFpSkNZYUJBZ0FFQUVhQkFnQ0VBTWFCQWdFRUFVYUJBZ0dFQWNhQkFnSUVBa2FCQWdLRUFzYUJBZ01FQTBhQkFnT0VBOGFCQWdRRUJFYUJBZ1NFQk1hQkFnVUVCVWFCQWdXRUJjYUJBZ1lFQmthQkFnYUVCc2FCQWdjRUIwYUJBZ2VFQjhhQkFnZ0VDRWFCQWdpRUNNYUJBZ2tFQ1VhQkFnbUVDY3FGQUFDQkFZSUNnd09FQklVRmhnYUhCNGdJaVFtag93YXRjaC1uZXh0LWZlZWQ%3D"),
visitor_data: Some("Cgtidzg4MlRTb3FKSSiqipeaBg%3D%3D"),
endpoint: next,
), ),
top_comments: Paginator( top_comments: Paginator(
count: Some(3200), count: Some(3200),
items: [], items: [],
ctoken: Some("Eg0SC25GREJ4QlVmRTc0GAYyJSIRIgtuRkRCeEJVZkU3NDAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"), ctoken: Some("Eg0SC25GREJ4QlVmRTc0GAYyJSIRIgtuRkRCeEJVZkU3NDAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"),
endpoint: next,
), ),
latest_comments: Paginator( latest_comments: Paginator(
count: Some(3200), count: Some(3200),
items: [], items: [],
ctoken: Some("Eg0SC25GREJ4QlVmRTc0GAYyOCIRIgtuRkRCeEJVZkU3NDABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"), ctoken: Some("Eg0SC25GREJ4QlVmRTc0GAYyOCIRIgtuRkRCeEJVZkU3NDABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"),
endpoint: next,
), ),
) )

View file

@ -26,7 +26,7 @@ VideoDetails(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: Some(1480), subscriber_count: Some(1480),
), ),
view_count: 205, view_count: 205,
@ -40,15 +40,18 @@ VideoDetails(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: browse,
), ),
top_comments: Paginator( top_comments: Paginator(
count: None, count: None,
items: [], items: [],
ctoken: Some("Eg0SC0hSS3UwY3Zycl9vGAYyJSIRIgtIUkt1MGN2cnJfbzABeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"), ctoken: Some("Eg0SC0hSS3UwY3Zycl9vGAYyJSIRIgtIUkt1MGN2cnJfbzABeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"),
endpoint: next,
), ),
latest_comments: Paginator( latest_comments: Paginator(
count: None, count: None,
items: [], items: [],
ctoken: Some("Eg0SC0hSS3UwY3Zycl9vGAYyOCIRIgtIUkt1MGN2cnJfbzABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"), ctoken: Some("Eg0SC0hSS3UwY3Zycl9vGAYyOCIRIgtIUkt1MGN2cnJfbzABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"),
endpoint: next,
), ),
) )

View file

@ -38,7 +38,7 @@ VideoDetails(
height: 176, height: 176,
), ),
], ],
verification: none, verification: None,
subscriber_count: Some(172000), subscriber_count: Some(172000),
), ),
view_count: 2493983, view_count: 2493983,
@ -51,7 +51,7 @@ VideoDetails(
recommended: Paginator( recommended: Paginator(
count: None, count: None,
items: [ items: [
RecommendedVideo( VideoItem(
id: "-YpwsdRKt8Q", id: "-YpwsdRKt8Q",
title: "SpiegelMining Reverse Engineering von Spiegel-Online (33c3)", title: "SpiegelMining Reverse Engineering von Spiegel-Online (33c3)",
length: Some(3526), length: Some(3526),
@ -67,7 +67,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -77,16 +77,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 years ago"), publish_date_txt: Some("5 years ago"),
view_count: 2749364, view_count: Some(2749364),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "4z3mu63yxII", id: "4z3mu63yxII",
title: "Gregor Gysi & Martin Sonneborn", title: "Gregor Gysi & Martin Sonneborn",
length: Some(5272), length: Some(5272),
@ -102,7 +104,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCBWSgdr27NcLig0XzWLq2gQ", id: "UCBWSgdr27NcLig0XzWLq2gQ",
name: "MISS-VERSTEHEN SIE MICH RICHTIG", name: "MISS-VERSTEHEN SIE MICH RICHTIG",
avatar: [ avatar: [
@ -112,16 +114,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 2266658, view_count: Some(2266658),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "WhgRRpA3b2c", id: "WhgRRpA3b2c",
title: "36C3 - Verkehrswende selber hacken", title: "36C3 - Verkehrswende selber hacken",
length: Some(3176), length: Some(3176),
@ -137,7 +141,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -147,16 +151,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 260941, view_count: Some(260941),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "5qNHtdN07FM", id: "5qNHtdN07FM",
title: "GPN16: Wie baut man eigentlich Raumschiffe (urs)", title: "GPN16: Wie baut man eigentlich Raumschiffe (urs)",
length: Some(5172), length: Some(5172),
@ -172,7 +178,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -182,16 +188,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 years ago"), publish_date_txt: Some("6 years ago"),
view_count: 1229987, view_count: Some(1229987),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "7FeqF1-Z1g0", id: "7FeqF1-Z1g0",
title: "David Kriesel: Traue keinem Scan, den du nicht selbst gefälscht hast", title: "David Kriesel: Traue keinem Scan, den du nicht selbst gefälscht hast",
length: Some(3820), length: Some(3820),
@ -207,7 +215,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -217,16 +225,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 years ago"), publish_date_txt: Some("7 years ago"),
view_count: 6095028, view_count: Some(6095028),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "1vcP9UWrWBI", id: "1vcP9UWrWBI",
title: "Easterhegg 2019 - Kernreaktoren", title: "Easterhegg 2019 - Kernreaktoren",
length: Some(7263), length: Some(7263),
@ -242,7 +252,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -252,16 +262,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 46470, view_count: Some(46470),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "jnp1veXQf7U", id: "jnp1veXQf7U",
title: "Blockchain - Ein außer Kontrolle geratenes Laborexperiment? #GPN19", title: "Blockchain - Ein außer Kontrolle geratenes Laborexperiment? #GPN19",
length: Some(3362), length: Some(3362),
@ -277,7 +289,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -287,16 +299,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 25136, view_count: Some(25136),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "77OlKRkaixo", id: "77OlKRkaixo",
title: "leyrer, MacLemon: E-Mail. Hässlich, aber es funktioniert #eh16", title: "leyrer, MacLemon: E-Mail. Hässlich, aber es funktioniert #eh16",
length: Some(6998), length: Some(6998),
@ -312,7 +326,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -322,16 +336,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 years ago"), publish_date_txt: Some("6 years ago"),
view_count: 44410, view_count: Some(44410),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "u29--YNGMyg", id: "u29--YNGMyg",
title: "Physikalisches Kolloquium 22. Juli 2011 - Vortrag von Prof. Dr. Harald Lesch", title: "Physikalisches Kolloquium 22. Juli 2011 - Vortrag von Prof. Dr. Harald Lesch",
length: Some(6715), length: Some(6715),
@ -347,7 +363,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCvZLsBb-8Og4FvBUom9zPHQ", id: "UCvZLsBb-8Og4FvBUom9zPHQ",
name: "Universität Bayreuth", name: "Universität Bayreuth",
avatar: [ avatar: [
@ -357,16 +373,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 years ago"), publish_date_txt: Some("11 years ago"),
view_count: 4184357, view_count: Some(4184357),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "urt2_ACal9A", id: "urt2_ACal9A",
title: "CCC-Jahresrückblick 2016 (33c3)", title: "CCC-Jahresrückblick 2016 (33c3)",
length: Some(8170), length: Some(8170),
@ -382,7 +400,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -392,16 +410,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 years ago"), publish_date_txt: Some("5 years ago"),
view_count: 36111, view_count: Some(36111),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "PnBs9oH2Lx8", id: "PnBs9oH2Lx8",
title: "Easterhegg 2019 - Wie ich die Regierung gehackt habe", title: "Easterhegg 2019 - Wie ich die Regierung gehackt habe",
length: Some(3147), length: Some(3147),
@ -417,7 +437,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -427,16 +447,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 20322, view_count: Some(20322),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "yaCiVvBD-xc", id: "yaCiVvBD-xc",
title: "Mathias Dalheimer: Wie man einen Blackout verursacht", title: "Mathias Dalheimer: Wie man einen Blackout verursacht",
length: Some(3748), length: Some(3748),
@ -452,7 +474,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -462,16 +484,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 years ago"), publish_date_txt: Some("6 years ago"),
view_count: 482258, view_count: Some(482258),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "1PJnEwoFSXo", id: "1PJnEwoFSXo",
title: "Das Geheimnis der Hieroglyphen | Doku HD | ARTE", title: "Das Geheimnis der Hieroglyphen | Doku HD | ARTE",
length: Some(5541), length: Some(5541),
@ -487,7 +511,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCLLibJTCy3sXjHLVaDimnpQ", id: "UCLLibJTCy3sXjHLVaDimnpQ",
name: "ARTEde", name: "ARTEde",
avatar: [ avatar: [
@ -497,16 +521,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("12 days ago"), publish_date_txt: Some("12 days ago"),
view_count: 427756, view_count: Some(427756),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "iIDZ8pJKLZA", id: "iIDZ8pJKLZA",
title: "36C3 ChaosWest: Bahn API Chaos", title: "36C3 ChaosWest: Bahn API Chaos",
length: Some(3056), length: Some(3056),
@ -522,7 +548,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -532,16 +558,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 26926, view_count: Some(26926),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "PhUQN6fd5O4", id: "PhUQN6fd5O4",
title: "35C3 - Jahresrückblick des CCC 2018", title: "35C3 - Jahresrückblick des CCC 2018",
length: Some(8102), length: Some(8102),
@ -557,7 +585,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -567,16 +595,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 126093, view_count: Some(126093),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "bzr0c8qzQoc", id: "bzr0c8qzQoc",
title: "GPN19 - Beton", title: "GPN19 - Beton",
length: Some(3972), length: Some(3972),
@ -592,7 +622,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -602,16 +632,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 13243, view_count: Some(13243),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "IeX1F-Jjq9E", id: "IeX1F-Jjq9E",
title: "Lars “Pylon” Weiler (DC4LW): Weltraumkommunikation", title: "Lars “Pylon” Weiler (DC4LW): Weltraumkommunikation",
length: Some(5075), length: Some(5075),
@ -627,7 +659,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -637,16 +669,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 years ago"), publish_date_txt: Some("6 years ago"),
view_count: 80624, view_count: Some(80624),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "gsnL4m57MCM", id: "gsnL4m57MCM",
title: "David Kriesel: SpiegelMining Reverse Engineering von Spiegel-Online", title: "David Kriesel: SpiegelMining Reverse Engineering von Spiegel-Online",
length: Some(3526), length: Some(3526),
@ -662,7 +696,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCeO-zvUfuEdPMDoNST6hy1A", id: "UCeO-zvUfuEdPMDoNST6hy1A",
name: "Killuminati ∆", name: "Killuminati ∆",
avatar: [ avatar: [
@ -672,16 +706,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 years ago"), publish_date_txt: Some("5 years ago"),
view_count: 29009, view_count: Some(29009),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "uEEHq6f8RsM", id: "uEEHq6f8RsM",
title: "Leyrer: Moderne Linux Kommandozeilenwerkzeuge - Edition \"Allein zu Haus\"", title: "Leyrer: Moderne Linux Kommandozeilenwerkzeuge - Edition \"Allein zu Haus\"",
length: Some(3716), length: Some(3716),
@ -697,7 +733,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg", id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de", name: "media.ccc.de",
avatar: [ avatar: [
@ -707,26 +743,32 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 months ago"), publish_date_txt: Some("3 months ago"),
view_count: 67538, view_count: Some(67538),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("CBQSExILMHJiOUNmT3ZvamvAAQHIAQEYACqrBjJzNkw2d3paQkFyV0JBb0Q4ajRBQ2c3Q1Bnc0l4Ty1xb3AyV25NWDVBUW9EOGo0QUNnN0NQZ3NJZ29uTDc3clgtWjdqQVFvRDhqNEFDZzNDUGdvSTU5N2RnZW1vaEl4YUNnUHlQZ0FLSWRJLUhnb2NVa1JEVFZWRE1sUlljVjkwTURaSWFtUnlNbWRmUzJSTGNFaFJad29EOGo0QUNnN0NQZ3NJMDlqVG05MzIwZEhtQVFvRDhqNEFDZzdDUGdzSWphem5fUFhDNnF2c0FRb0Q4ajRBQ2c3Q1Bnc0lrckN0cmRULXdfdldBUW9EOGo0QUNnN0NQZ3NJdGZfQnJ0NjNuYjJPQVFvRDhqNEFDZzdDUGdzSW1wYnF5SkdsNmRudkFRb0Q4ajRBQ2c3Q1Bnc0lxT2FZbXBqZjM3ZTdBUW9EOGo0QUNnN0NQZ3NJMEtfcWhNRGYzZDI2QVFvRDhqNEFDZzNDUGdvSW45N1lqLWllbTdnLUNnUHlQZ0FLRHNJLUN3aVg5by1DNzhxbzBNa0JDZ1B5UGdBS0RzSS1Dd2o2a3BYUXNPS1otZFFCQ2dQeVBnQUtEc0ktQ3dpUTI2aVNxYjYyd0lnQkNnUHlQZ0FLRGNJLUNnanV5ZmUtLW9iRWlqNEtBX0ktQUFvTndqNEtDSWVGemRXOGpyMmRid29EOGo0QUNnM0NQZ29JMGRlT2tfNmlfZkloQ2dQeVBnQUtEc0ktQ3dpajRPenpwdnp5NUlJQkNnUHlQZ0FLRHNJLUN3akRqZkdfdXZYQm9MZ0JFaFFBQWdRR0NBb01EaEFTRkJZWUdod2VJQ0lrSmhvRUNBQVFBUm9FQ0FJUUF4b0VDQVFRQlJvRUNBWVFCeG9FQ0FnUUNSb0VDQW9RQ3hvRUNBd1FEUm9FQ0E0UUR4b0VDQkFRRVJvRUNCSVFFeG9FQ0JRUUZSb0VDQllRRnhvRUNCZ1FHUm9FQ0JvUUd4b0VDQndRSFJvRUNCNFFIeG9FQ0NBUUlSb0VDQ0lRSXhvRUNDUVFKUm9FQ0NZUUp5b1VBQUlFQmdnS0RBNFFFaFFXR0JvY0hpQWlKQ1lqD3dhdGNoLW5leHQtZmVlZA%3D%3D"), ctoken: Some("CBQSExILMHJiOUNmT3ZvamvAAQHIAQEYACqrBjJzNkw2d3paQkFyV0JBb0Q4ajRBQ2c3Q1Bnc0l4Ty1xb3AyV25NWDVBUW9EOGo0QUNnN0NQZ3NJZ29uTDc3clgtWjdqQVFvRDhqNEFDZzNDUGdvSTU5N2RnZW1vaEl4YUNnUHlQZ0FLSWRJLUhnb2NVa1JEVFZWRE1sUlljVjkwTURaSWFtUnlNbWRmUzJSTGNFaFJad29EOGo0QUNnN0NQZ3NJMDlqVG05MzIwZEhtQVFvRDhqNEFDZzdDUGdzSWphem5fUFhDNnF2c0FRb0Q4ajRBQ2c3Q1Bnc0lrckN0cmRULXdfdldBUW9EOGo0QUNnN0NQZ3NJdGZfQnJ0NjNuYjJPQVFvRDhqNEFDZzdDUGdzSW1wYnF5SkdsNmRudkFRb0Q4ajRBQ2c3Q1Bnc0lxT2FZbXBqZjM3ZTdBUW9EOGo0QUNnN0NQZ3NJMEtfcWhNRGYzZDI2QVFvRDhqNEFDZzNDUGdvSW45N1lqLWllbTdnLUNnUHlQZ0FLRHNJLUN3aVg5by1DNzhxbzBNa0JDZ1B5UGdBS0RzSS1Dd2o2a3BYUXNPS1otZFFCQ2dQeVBnQUtEc0ktQ3dpUTI2aVNxYjYyd0lnQkNnUHlQZ0FLRGNJLUNnanV5ZmUtLW9iRWlqNEtBX0ktQUFvTndqNEtDSWVGemRXOGpyMmRid29EOGo0QUNnM0NQZ29JMGRlT2tfNmlfZkloQ2dQeVBnQUtEc0ktQ3dpajRPenpwdnp5NUlJQkNnUHlQZ0FLRHNJLUN3akRqZkdfdXZYQm9MZ0JFaFFBQWdRR0NBb01EaEFTRkJZWUdod2VJQ0lrSmhvRUNBQVFBUm9FQ0FJUUF4b0VDQVFRQlJvRUNBWVFCeG9FQ0FnUUNSb0VDQW9RQ3hvRUNBd1FEUm9FQ0E0UUR4b0VDQkFRRVJvRUNCSVFFeG9FQ0JRUUZSb0VDQllRRnhvRUNCZ1FHUm9FQ0JvUUd4b0VDQndRSFJvRUNCNFFIeG9FQ0NBUUlSb0VDQ0lRSXhvRUNDUVFKUm9FQ0NZUUp5b1VBQUlFQmdnS0RBNFFFaFFXR0JvY0hpQWlKQ1lqD3dhdGNoLW5leHQtZmVlZA%3D%3D"),
visitor_data: Some("CgtoY1pQUF8wNW1qayjSjpSZBg%3D%3D"),
endpoint: next,
), ),
top_comments: Paginator( top_comments: Paginator(
count: Some(2200), count: Some(2200),
items: [], items: [],
ctoken: Some("Eg0SCzByYjlDZk92b2prGAYyJSIRIgswcmI5Q2ZPdm9qazAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"), ctoken: Some("Eg0SCzByYjlDZk92b2prGAYyJSIRIgswcmI5Q2ZPdm9qazAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"),
endpoint: next,
), ),
latest_comments: Paginator( latest_comments: Paginator(
count: Some(2200), count: Some(2200),
items: [], items: [],
ctoken: Some("Eg0SCzByYjlDZk92b2prGAYyOCIRIgswcmI5Q2ZPdm9qazABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"), ctoken: Some("Eg0SCzByYjlDZk92b2prGAYyOCIRIgswcmI5Q2ZPdm9qazABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"),
endpoint: next,
), ),
) )

View file

@ -281,7 +281,7 @@ VideoDetails(
height: 176, height: 176,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: Some(14800000), subscriber_count: Some(14800000),
), ),
view_count: 971966, view_count: 971966,
@ -519,7 +519,7 @@ VideoDetails(
recommended: Paginator( recommended: Paginator(
count: None, count: None,
items: [ items: [
RecommendedVideo( VideoItem(
id: "AOdp09SYhCc", id: "AOdp09SYhCc",
title: "This Is So Embarrassing!", title: "This Is So Embarrassing!",
length: Some(1063), length: Some(1063),
@ -535,7 +535,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -545,16 +545,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 days ago"), publish_date_txt: Some("2 days ago"),
view_count: 1862544, view_count: Some(1862544),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "CY3OQh-7wIk", id: "CY3OQh-7wIk",
title: "The Computer I Would Actually BUY", title: "The Computer I Would Actually BUY",
length: Some(6478), length: Some(6478),
@ -570,7 +572,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -580,16 +582,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("Streamed 8 days ago"), publish_date_txt: Some("Streamed 8 days ago"),
view_count: 946996, view_count: Some(946996),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "LQ95XJAwaoc", id: "LQ95XJAwaoc",
title: "My favorite car (sucks)", title: "My favorite car (sucks)",
length: Some(1162), length: Some(1162),
@ -605,7 +609,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCdBK94H6oZT2Q7l0-b0xmMg", id: "UCdBK94H6oZT2Q7l0-b0xmMg",
name: "ShortCircuit", name: "ShortCircuit",
avatar: [ avatar: [
@ -615,16 +619,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 day ago"), publish_date_txt: Some("1 day ago"),
view_count: 349251, view_count: Some(349251),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "mhMQeJ5Qmp0", id: "mhMQeJ5Qmp0",
title: "The Apple Newton MessagePad.", title: "The Apple Newton MessagePad.",
length: Some(758), length: Some(758),
@ -640,7 +646,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC7Jwj9fkrf1adN4fMmTkpug", id: "UC7Jwj9fkrf1adN4fMmTkpug",
name: "DankPods", name: "DankPods",
avatar: [ avatar: [
@ -650,16 +656,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 day ago"), publish_date_txt: Some("1 day ago"),
view_count: 375458, view_count: Some(375458),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "1ctXiZsN6ac", id: "1ctXiZsN6ac",
title: "The Reviewer Got Reviewed - WAN Show September 9, 2022", title: "The Reviewer Got Reviewed - WAN Show September 9, 2022",
length: Some(10265), length: Some(10265),
@ -675,7 +683,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -685,16 +693,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("Streamed 6 days ago"), publish_date_txt: Some("Streamed 6 days ago"),
view_count: 734463, view_count: Some(734463),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "CMR9z9Xr8GM", id: "CMR9z9Xr8GM",
title: "Storing Solar Power on my ROOF!!!", title: "Storing Solar Power on my ROOF!!!",
length: Some(1028), length: Some(1028),
@ -710,7 +720,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCKd49wwdEdIoM-7Fumhwmog", id: "UCKd49wwdEdIoM-7Fumhwmog",
name: "Quint BUILDs", name: "Quint BUILDs",
avatar: [ avatar: [
@ -720,16 +730,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 months ago"), publish_date_txt: Some("11 months ago"),
view_count: 2773698, view_count: Some(2773698),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "fT2KhJ8W-Kg", id: "fT2KhJ8W-Kg",
title: "How gas pumps know when to turn themselves off", title: "How gas pumps know when to turn themselves off",
length: Some(836), length: Some(836),
@ -745,7 +757,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEIwxahdLz7bap-VDs9h35A", id: "UCEIwxahdLz7bap-VDs9h35A",
name: "Steve Mould", name: "Steve Mould",
avatar: [ avatar: [
@ -755,16 +767,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 hours ago"), publish_date_txt: Some("8 hours ago"),
view_count: 219605, view_count: Some(219605),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "12Hcbx33Rb4", id: "12Hcbx33Rb4",
title: "BREAKING NEWS! - EVGA will no longer do business with NVIDIA", title: "BREAKING NEWS! - EVGA will no longer do business with NVIDIA",
length: Some(1262), length: Some(1262),
@ -780,7 +794,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCkWQ0gDrqOCarmUKmppD7GQ", id: "UCkWQ0gDrqOCarmUKmppD7GQ",
name: "JayzTwoCents", name: "JayzTwoCents",
avatar: [ avatar: [
@ -790,16 +804,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 hours ago"), publish_date_txt: Some("4 hours ago"),
view_count: 145345, view_count: Some(145345),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "QW1SsqmaIuE", id: "QW1SsqmaIuE",
title: "I Surprised My Subscriber with his Dream Gaming Setup! - Season 8", title: "I Surprised My Subscriber with his Dream Gaming Setup! - Season 8",
length: Some(2177), length: Some(2177),
@ -815,7 +831,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UChIZGfcnjHI0DG4nweWEduw", id: "UChIZGfcnjHI0DG4nweWEduw",
name: "TechSource", name: "TechSource",
avatar: [ avatar: [
@ -825,16 +841,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 hours ago"), publish_date_txt: Some("6 hours ago"),
view_count: 50033, view_count: Some(50033),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "JAcSNL1T3OA", id: "JAcSNL1T3OA",
title: "Why Did I Drill 1756 Holes in This?", title: "Why Did I Drill 1756 Holes in This?",
length: Some(1293), length: Some(1293),
@ -850,7 +868,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVveEFTOd6khhSXXnRhxJmg", id: "UCVveEFTOd6khhSXXnRhxJmg",
name: "Fireball Tool", name: "Fireball Tool",
avatar: [ avatar: [
@ -860,16 +878,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 month ago"), publish_date_txt: Some("1 month ago"),
view_count: 1163652, view_count: Some(1163652),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "ZVtOss1U7_s", id: "ZVtOss1U7_s",
title: "VW Beetle converted to electric in a day", title: "VW Beetle converted to electric in a day",
length: Some(826), length: Some(826),
@ -885,7 +905,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCq1Oqk1I7zeYlDiJTFWLoFA", id: "UCq1Oqk1I7zeYlDiJTFWLoFA",
name: "Electric Classic Cars", name: "Electric Classic Cars",
avatar: [ avatar: [
@ -895,16 +915,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 3266169, view_count: Some(3266169),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "2kJDTzFtUr4", id: "2kJDTzFtUr4",
title: "How ASML, TSMC And Intel Dominate The Chip Market | CNBC Marathon", title: "How ASML, TSMC And Intel Dominate The Chip Market | CNBC Marathon",
length: Some(3399), length: Some(3399),
@ -920,7 +942,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCvJJ_dzjViJCoLf5uKUTwoA", id: "UCvJJ_dzjViJCoLf5uKUTwoA",
name: "CNBC", name: "CNBC",
avatar: [ avatar: [
@ -930,16 +952,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 678935, view_count: Some(678935),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "0rCbfsuKdYw", id: "0rCbfsuKdYw",
title: "I bought every Playstation Ever.", title: "I bought every Playstation Ever.",
length: Some(1046), length: Some(1046),
@ -955,7 +979,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCMiJRAwDNSNzuYeN2uWa0pA", id: "UCMiJRAwDNSNzuYeN2uWa0pA",
name: "Mrwhosetheboss", name: "Mrwhosetheboss",
avatar: [ avatar: [
@ -965,16 +989,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 7569956, view_count: Some(7569956),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "sbdU7AkH6QM", id: "sbdU7AkH6QM",
title: "Reviewing Free Energy Generators. A Response to My Video \"Nikola Tesla\'s Greatest Invention\"- 102", title: "Reviewing Free Energy Generators. A Response to My Video \"Nikola Tesla\'s Greatest Invention\"- 102",
length: Some(1387), length: Some(1387),
@ -990,7 +1016,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC_SLthyNX_ivd-dmsFgmJVg", id: "UC_SLthyNX_ivd-dmsFgmJVg",
name: "Jeremy Fielding", name: "Jeremy Fielding",
avatar: [ avatar: [
@ -1000,16 +1026,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 months ago"), publish_date_txt: Some("5 months ago"),
view_count: 3374461, view_count: Some(3374461),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "zcchDu7KoYs", id: "zcchDu7KoYs",
title: "AMDs Victory Lap - HOLY $H!T Threadripper Pro 5995WX", title: "AMDs Victory Lap - HOLY $H!T Threadripper Pro 5995WX",
length: Some(872), length: Some(872),
@ -1025,7 +1053,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -1035,16 +1063,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 days ago"), publish_date_txt: Some("5 days ago"),
view_count: 1322625, view_count: Some(1322625),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "pd6DsSjqhFE", id: "pd6DsSjqhFE",
title: "Top Gear Satisfaction Survey Compilation", title: "Top Gear Satisfaction Survey Compilation",
length: Some(986), length: Some(986),
@ -1060,7 +1090,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCupQghOyPai8Hxg4RqMERvA", id: "UCupQghOyPai8Hxg4RqMERvA",
name: "incT", name: "incT",
avatar: [ avatar: [
@ -1070,16 +1100,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 255945, view_count: Some(255945),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "2K5Gqp1cEcM", id: "2K5Gqp1cEcM",
title: "Why our Screwdriver took 3 YEARS", title: "Why our Screwdriver took 3 YEARS",
length: Some(1752), length: Some(1752),
@ -1095,7 +1127,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -1105,16 +1137,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"), publish_date_txt: Some("2 weeks ago"),
view_count: 2930532, view_count: Some(2930532),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "t03rmc-prJo", id: "t03rmc-prJo",
title: "This PC took 600 HOURS to Build!", title: "This PC took 600 HOURS to Build!",
length: Some(1505), length: Some(1505),
@ -1130,7 +1164,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw", id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips", name: "Linus Tech Tips",
avatar: [ avatar: [
@ -1140,16 +1174,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("12 days ago"), publish_date_txt: Some("12 days ago"),
view_count: 2743664, view_count: Some(2743664),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "QTH9m6MDIfc", id: "QTH9m6MDIfc",
title: "One Year Ago I Built an Ecosystem, This Happened", title: "One Year Ago I Built an Ecosystem, This Happened",
length: Some(485), length: Some(485),
@ -1165,7 +1201,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCYmna5rFHIesFteksAvFOfg", id: "UCYmna5rFHIesFteksAvFOfg",
name: "Dr. Plants", name: "Dr. Plants",
avatar: [ avatar: [
@ -1175,26 +1211,32 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"), publish_date_txt: Some("3 weeks ago"),
view_count: 7958495, view_count: Some(7958495),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("CBQSExILbkZEQnhCVWZFNzTAAQHIAQEYACqkBjJzNkw2d3pVQkFyUkJBb0Q4ajRBQ2d6Q1Bna0lwNGppcEwyNjJuTUtBX0ktQUFvTndqNEtDSW1CN18yaHlQUEdDUW9EOGo0QUNnM0NQZ29JaDlYQmdjbXIzb2N0Q2dQeVBnQUtEc0ktQ3dpZHRjTHlpWV9FaVpvQkNnUHlQZ0FLRHNJLUN3aW4wN2ZZbWZIVjVkVUJDZ1B5UGdBS0RjSS1DZ2pqNEstdl9ibWY0Z2dLQV9JLUFBb053ajRLQ0tqeDJfakowT0tlZlFvRDhqNEFDZzdDUGdzSXZvdmQ3X0dOOTdEWEFRb0Q4ajRBQ2czQ1Bnb0k0Y1hvektyVzFMWkJDZ1B5UGdBS0RjSS1DZ2pndWNfcXk4YkVneVFLQV9JLUFBb053ajRLQ1B2ZjAtcXMxdE90WlFvRDhqNEFDaUhTUGg0S0hGSkVRMDFWUTFoMWNWTkNiRWhCUlRaWWR5MTVaVXBCTUZSMWJuY0tBX0ktQUFvT3dqNExDTDZsdFl2ejZaQ2gyZ0VLQV9JLUFBb093ajRMQ0l6cnFkenM3NmJZMGdFS0FfSS1BQW9Pd2o0TENJUFNuOGpBbmRYYnNRRUtBX0ktQUFvT3dqNExDSXZEcXZidW9jamp6UUVLQV9JLUFBb093ajRMQ05HSXFzZVM5cUR2cFFFS0FfSS1BQW9Pd2o0TENNT2o4T3FwMVpIWDJBRUtBX0ktQUFvT3dqNExDSnJacHYyYzhfcW10d0VLQV9JLUFBb053ajRLQ1BmRGpKaTZzXy1ZUVJJVUFBSUVCZ2dLREE0UUVoUVdHQm9jSGlBaUpDWWFCQWdBRUFFYUJBZ0NFQU1hQkFnRUVBVWFCQWdHRUFjYUJBZ0lFQWthQkFnS0VBc2FCQWdNRUEwYUJBZ09FQThhQkFnUUVCRWFCQWdTRUJNYUJBZ1VFQlVhQkFnV0VCY2FCQWdZRUJrYUJBZ2FFQnNhQkFnY0VCMGFCQWdlRUI4YUJBZ2dFQ0VhQkFnaUVDTWFCQWdrRUNVYUJBZ21FQ2NxRkFBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbWoPd2F0Y2gtbmV4dC1mZWVk"), ctoken: Some("CBQSExILbkZEQnhCVWZFNzTAAQHIAQEYACqkBjJzNkw2d3pVQkFyUkJBb0Q4ajRBQ2d6Q1Bna0lwNGppcEwyNjJuTUtBX0ktQUFvTndqNEtDSW1CN18yaHlQUEdDUW9EOGo0QUNnM0NQZ29JaDlYQmdjbXIzb2N0Q2dQeVBnQUtEc0ktQ3dpZHRjTHlpWV9FaVpvQkNnUHlQZ0FLRHNJLUN3aW4wN2ZZbWZIVjVkVUJDZ1B5UGdBS0RjSS1DZ2pqNEstdl9ibWY0Z2dLQV9JLUFBb053ajRLQ0tqeDJfakowT0tlZlFvRDhqNEFDZzdDUGdzSXZvdmQ3X0dOOTdEWEFRb0Q4ajRBQ2czQ1Bnb0k0Y1hvektyVzFMWkJDZ1B5UGdBS0RjSS1DZ2pndWNfcXk4YkVneVFLQV9JLUFBb053ajRLQ1B2ZjAtcXMxdE90WlFvRDhqNEFDaUhTUGg0S0hGSkVRMDFWUTFoMWNWTkNiRWhCUlRaWWR5MTVaVXBCTUZSMWJuY0tBX0ktQUFvT3dqNExDTDZsdFl2ejZaQ2gyZ0VLQV9JLUFBb093ajRMQ0l6cnFkenM3NmJZMGdFS0FfSS1BQW9Pd2o0TENJUFNuOGpBbmRYYnNRRUtBX0ktQUFvT3dqNExDSXZEcXZidW9jamp6UUVLQV9JLUFBb093ajRMQ05HSXFzZVM5cUR2cFFFS0FfSS1BQW9Pd2o0TENNT2o4T3FwMVpIWDJBRUtBX0ktQUFvT3dqNExDSnJacHYyYzhfcW10d0VLQV9JLUFBb053ajRLQ1BmRGpKaTZzXy1ZUVJJVUFBSUVCZ2dLREE0UUVoUVdHQm9jSGlBaUpDWWFCQWdBRUFFYUJBZ0NFQU1hQkFnRUVBVWFCQWdHRUFjYUJBZ0lFQWthQkFnS0VBc2FCQWdNRUEwYUJBZ09FQThhQkFnUUVCRWFCQWdTRUJNYUJBZ1VFQlVhQkFnV0VCY2FCQWdZRUJrYUJBZ2FFQnNhQkFnY0VCMGFCQWdlRUI4YUJBZ2dFQ0VhQkFnaUVDTWFCQWdrRUNVYUJBZ21FQ2NxRkFBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbWoPd2F0Y2gtbmV4dC1mZWVk"),
visitor_data: Some("CgtIV0JjSUtDQm9LQSjUjpSZBg%3D%3D"),
endpoint: next,
), ),
top_comments: Paginator( top_comments: Paginator(
count: Some(2900), count: Some(2900),
items: [], items: [],
ctoken: Some("Eg0SC25GREJ4QlVmRTc0GAYyJSIRIgtuRkRCeEJVZkU3NDAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"), ctoken: Some("Eg0SC25GREJ4QlVmRTc0GAYyJSIRIgtuRkRCeEJVZkU3NDAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"),
endpoint: next,
), ),
latest_comments: Paginator( latest_comments: Paginator(
count: Some(2900), count: Some(2900),
items: [], items: [],
ctoken: Some("Eg0SC25GREJ4QlVmRTc0GAYyOCIRIgtuRkRCeEJVZkU3NDABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"), ctoken: Some("Eg0SC25GREJ4QlVmRTc0GAYyOCIRIgtuRkRCeEJVZkU3NDABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"),
endpoint: next,
), ),
) )

View file

@ -60,7 +60,7 @@ VideoDetails(
height: 176, height: 176,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: Some(5590000), subscriber_count: Some(5590000),
), ),
view_count: 681, view_count: 681,
@ -73,7 +73,7 @@ VideoDetails(
recommended: Paginator( recommended: Paginator(
count: None, count: None,
items: [ items: [
RecommendedVideo( VideoItem(
id: "SGP6Y0Pnhe4", id: "SGP6Y0Pnhe4",
title: "HOW IT WORKS: The International Space Station", title: "HOW IT WORKS: The International Space Station",
length: Some(1738), length: Some(1738),
@ -89,7 +89,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC_sXrcURB-Dh4az_FveeQ0Q", id: "UC_sXrcURB-Dh4az_FveeQ0Q",
name: "DOCUMENTARY TUBE", name: "DOCUMENTARY TUBE",
avatar: [ avatar: [
@ -99,16 +99,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 years ago"), publish_date_txt: Some("7 years ago"),
view_count: 90280310, view_count: Some(90280310),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "ddZu_1Z3BAc", id: "ddZu_1Z3BAc",
title: "NASA LIVE Stream From The ISS - Live Earth & Space Station Views & Audio", title: "NASA LIVE Stream From The ISS - Live Earth & Space Station Views & Audio",
length: None, length: None,
@ -124,7 +126,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCakgsb0w7QB0VHdnCc-OVEA", id: "UCakgsb0w7QB0VHdnCc-OVEA",
name: "Space Videos", name: "Space Videos",
avatar: [ avatar: [
@ -134,16 +136,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 80, view_count: Some(80),
is_live: true, is_live: true,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "oDXBMjg9HKU", id: "oDXBMjg9HKU",
title: "APOD: 2022-09-20 - Star Forming Region NGC 3582 without Stars (Narrated by Amy)", title: "APOD: 2022-09-20 - Star Forming Region NGC 3582 without Stars (Narrated by Amy)",
length: Some(124), length: Some(124),
@ -159,7 +163,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCZepiiyNNbD2XL5sWnJBC_A", id: "UCZepiiyNNbD2XL5sWnJBC_A",
name: "Videotizer", name: "Videotizer",
avatar: [ avatar: [
@ -169,16 +173,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("10 hours ago"), publish_date_txt: Some("10 hours ago"),
view_count: 13, view_count: Some(13),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "aU0vNvVHXa8", id: "aU0vNvVHXa8",
title: "🌎 LIVE ASTEROID Watch Tracking", title: "🌎 LIVE ASTEROID Watch Tracking",
length: None, length: None,
@ -194,7 +200,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCNrGOnduIS9BXIRmDcHasZA", id: "UCNrGOnduIS9BXIRmDcHasZA",
name: "WorldCam", name: "WorldCam",
avatar: [ avatar: [
@ -204,16 +210,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 23, view_count: Some(23),
is_live: true, is_live: true,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "6scCF_8YN70", id: "6scCF_8YN70",
title: "Dramatic footage of the tsunami that hit Japan", title: "Dramatic footage of the tsunami that hit Japan",
length: Some(133), length: Some(133),
@ -229,7 +237,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCelk6aHijZq-GJBBB9YpReA", id: "UCelk6aHijZq-GJBBB9YpReA",
name: "BBC News عربي", name: "BBC News عربي",
avatar: [ avatar: [
@ -239,16 +247,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 years ago"), publish_date_txt: Some("11 years ago"),
view_count: 118635723, view_count: Some(118635723),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "n4IhCSMkADc", id: "n4IhCSMkADc",
title: "EARTH FROM SPACE: Like You\'ve Never Seen Before", title: "EARTH FROM SPACE: Like You\'ve Never Seen Before",
length: Some(766), length: Some(766),
@ -264,7 +274,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC_sXrcURB-Dh4az_FveeQ0Q", id: "UC_sXrcURB-Dh4az_FveeQ0Q",
name: "DOCUMENTARY TUBE", name: "DOCUMENTARY TUBE",
avatar: [ avatar: [
@ -274,16 +284,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("7 years ago"), publish_date_txt: Some("7 years ago"),
view_count: 11226061, view_count: Some(11226061),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "bgbH4FAmAA0", id: "bgbH4FAmAA0",
title: "Winter Cab View from two of the most SCENIC RAILWAYS in the WORLD", title: "Winter Cab View from two of the most SCENIC RAILWAYS in the WORLD",
length: None, length: None,
@ -299,7 +311,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCj-Xm8j6WBgKY8OG7s9r2vQ", id: "UCj-Xm8j6WBgKY8OG7s9r2vQ",
name: "RailCowGirl", name: "RailCowGirl",
avatar: [ avatar: [
@ -309,16 +321,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 108, view_count: Some(108),
is_live: true, is_live: true,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "uD4izuDMUQA", id: "uD4izuDMUQA",
title: "TIMELAPSE OF THE FUTURE: A Journey to the End of Time (4K)", title: "TIMELAPSE OF THE FUTURE: A Journey to the End of Time (4K)",
length: Some(1761), length: Some(1761),
@ -334,7 +348,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCR9sFzaG9Ia_kXJhfxtFMBA", id: "UCR9sFzaG9Ia_kXJhfxtFMBA",
name: "melodysheep", name: "melodysheep",
avatar: [ avatar: [
@ -344,16 +358,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 85240979, view_count: Some(85240979),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Z6DpPQ8QdLg", id: "Z6DpPQ8QdLg",
title: "Earthrise - Planet Earth Seen From The Moon - Real Time Journey Across The Lunar Surface", title: "Earthrise - Planet Earth Seen From The Moon - Real Time Journey Across The Lunar Surface",
length: Some(241), length: Some(241),
@ -369,7 +385,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCakgsb0w7QB0VHdnCc-OVEA", id: "UCakgsb0w7QB0VHdnCc-OVEA",
name: "Space Videos", name: "Space Videos",
avatar: [ avatar: [
@ -379,16 +395,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 years ago"), publish_date_txt: Some("4 years ago"),
view_count: 5405668, view_count: Some(5405668),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "1hNF3Wuw0LI", id: "1hNF3Wuw0LI",
title: "New York City Walk 24/7 Chat Stream", title: "New York City Walk 24/7 Chat Stream",
length: None, length: None,
@ -404,7 +422,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCRI_rCIV69l-PmT3oyD64kw", id: "UCRI_rCIV69l-PmT3oyD64kw",
name: "Afraz Explores", name: "Afraz Explores",
avatar: [ avatar: [
@ -414,16 +432,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 10, view_count: Some(10),
is_live: true, is_live: true,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "ZEyAs3NWH4A", id: "ZEyAs3NWH4A",
title: "New: Mars In 4K", title: "New: Mars In 4K",
length: Some(609), length: Some(609),
@ -439,7 +459,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCZvxw99l3xDC6BIHb8nJKGg", id: "UCZvxw99l3xDC6BIHb8nJKGg",
name: "ElderFox Documentaries", name: "ElderFox Documentaries",
avatar: [ avatar: [
@ -449,16 +469,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 61247221, view_count: Some(61247221),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "NF4LQaWJRDg", id: "NF4LQaWJRDg",
title: "Hiroshima: Dropping the Bomb", title: "Hiroshima: Dropping the Bomb",
length: Some(276), length: Some(276),
@ -474,7 +496,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC2ccm1GajfSujz7T18d7cKA", id: "UC2ccm1GajfSujz7T18d7cKA",
name: "BBC Studios", name: "BBC Studios",
avatar: [ avatar: [
@ -484,16 +506,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("15 years ago"), publish_date_txt: Some("15 years ago"),
view_count: 36276575, view_count: Some(36276575),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "qhOe_PxiNo8", id: "qhOe_PxiNo8",
title: "Imagens, Talvez Inéditas do Tsunami no Japão", title: "Imagens, Talvez Inéditas do Tsunami no Japão",
length: Some(1202), length: Some(1202),
@ -509,7 +533,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCyrM5blUZAQoX9UvObdjtig", id: "UCyrM5blUZAQoX9UvObdjtig",
name: "Valdemar Gomes", name: "Valdemar Gomes",
avatar: [ avatar: [
@ -519,16 +543,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 years ago"), publish_date_txt: Some("5 years ago"),
view_count: 12004917, view_count: Some(12004917),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "zf3bDpdhUNc", id: "zf3bDpdhUNc",
title: "Astronauts accidentally lose a shield in space (GoPro 8K)", title: "Astronauts accidentally lose a shield in space (GoPro 8K)",
length: Some(566), length: Some(566),
@ -544,7 +570,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCgP30k64HHZ0OY1QkEgS6Pw", id: "UCgP30k64HHZ0OY1QkEgS6Pw",
name: "Waa Sop", name: "Waa Sop",
avatar: [ avatar: [
@ -554,16 +580,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 22901662, view_count: Some(22901662),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "mJxsj51d-Pk", id: "mJxsj51d-Pk",
title: "Record breaking space jump - free fall faster than speed of sound - Red Bull Stratos.", title: "Record breaking space jump - free fall faster than speed of sound - Red Bull Stratos.",
length: Some(503), length: Some(503),
@ -579,7 +607,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCBuDzfvztEJvNll_w1E9xFw", id: "UCBuDzfvztEJvNll_w1E9xFw",
name: "The Random Theorizer", name: "The Random Theorizer",
avatar: [ avatar: [
@ -589,16 +617,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 years ago"), publish_date_txt: Some("4 years ago"),
view_count: 42814880, view_count: Some(42814880),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "fr_hXLDLc38", id: "fr_hXLDLc38",
title: "Horizons mission - Soyuz: launch to orbit", title: "Horizons mission - Soyuz: launch to orbit",
length: Some(607), length: Some(607),
@ -614,7 +644,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCIBaDdAbGlFDeS33shmlD0A", id: "UCIBaDdAbGlFDeS33shmlD0A",
name: "European Space Agency, ESA", name: "European Space Agency, ESA",
avatar: [ avatar: [
@ -624,16 +654,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 years ago"), publish_date_txt: Some("4 years ago"),
view_count: 9592134, view_count: Some(9592134),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Jh-qzwdiAGY", id: "Jh-qzwdiAGY",
title: "The Earth 4K - Incredible 4K / UHD Video of Earth From Space", title: "The Earth 4K - Incredible 4K / UHD Video of Earth From Space",
length: Some(3594), length: Some(3594),
@ -649,7 +681,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCakgsb0w7QB0VHdnCc-OVEA", id: "UCakgsb0w7QB0VHdnCc-OVEA",
name: "Space Videos", name: "Space Videos",
avatar: [ avatar: [
@ -659,16 +691,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 years ago"), publish_date_txt: Some("5 years ago"),
view_count: 4463605, view_count: Some(4463605),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "EPyl1LgNtoQ", id: "EPyl1LgNtoQ",
title: "The View from Space - Earth\'s Countries and Coastlines", title: "The View from Space - Earth\'s Countries and Coastlines",
length: Some(227), length: Some(227),
@ -684,7 +718,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC1znqKFL3jeR0eoA0pHpzvw", id: "UC1znqKFL3jeR0eoA0pHpzvw",
name: "SpaceRip", name: "SpaceRip",
avatar: [ avatar: [
@ -694,16 +728,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("10 years ago"), publish_date_txt: Some("10 years ago"),
view_count: 14094460, view_count: Some(14094460),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "7KXGZAEWzn0", id: "7KXGZAEWzn0",
title: "ORBIT - Journey Around Earth in Real Time // 4K Remastered", title: "ORBIT - Journey Around Earth in Real Time // 4K Remastered",
length: Some(5560), length: Some(5560),
@ -719,7 +755,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC28l88GMXXqZYfY0Ru9h50w", id: "UC28l88GMXXqZYfY0Ru9h50w",
name: "Seán Doran", name: "Seán Doran",
avatar: [ avatar: [
@ -729,16 +765,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 9901163, view_count: Some(9901163),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "KTUa9rG08go", id: "KTUa9rG08go",
title: "NASA Artemis I Mon Rocket Testing and Inspection LIVE From Launch Complex 39B", title: "NASA Artemis I Mon Rocket Testing and Inspection LIVE From Launch Complex 39B",
length: None, length: None,
@ -754,7 +792,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCDyeuRnxf_hxEyH1B7aoDQQ", id: "UCDyeuRnxf_hxEyH1B7aoDQQ",
name: "thebhp", name: "thebhp",
avatar: [ avatar: [
@ -764,26 +802,32 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: None, publish_date_txt: None,
view_count: 15, view_count: Some(15),
is_live: true, is_live: true,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("CBQSExILODZZTEZPb2c0R03AAQHIAQEYACrgBzJzNkw2d3poQlFyZUJRb0Q4ajRBQ2czQ1Bnb0k3b3VlbjdUTV9yRklDZ1B5UGdBS0RjSS1DZ2lIaU55ejlkLWI2M1VLQV9JLUFBb093ajRMQ0tXNTlNR2pwdkNhb0FFS0FfSS1BQW9Od2o0S0NLLTduYXJ2NXN1bWFRb0Q4ajRBQ2c3Q1Bnc0l2ZV9nLVBfQ3dPUHFBUW9EOGo0QUNnN0NQZ3NJdDRDUW1aS2hpTUdmQVFvRDhqNEFDZzNDUGdvSWpZQ1lnWVg4c1lOdUNnUHlQZ0FLRHNJLUN3aUFvckdHN3RtSW43Z0JDZ1B5UGdBS0RjSS1DZ2k0NmNINDBLZTYwR2NLQV9JLUFBb093ajRMQ0xLaHc5M1d1OUdKMWdFS0FfSS1BQW9Od2o0S0NJQ18ySnEzbHFDbVpBb0Q4ajRBQ2czQ1Bnb0l1SWlsckpyb2dxODBDZ1B5UGdBS0RzSS1Dd2lQN1lqano5X25pYW9CQ2dQeVBnQUtEc0ktQ3dqWG9ZVzc2ZUgyX3MwQkNnUHlQZ0FLRHNJLUN3ajU4ZmZxLVpHYnpwZ0JDZ1B5UGdBS0RjSS1DZ2pfNXEyR3k2djQzMzRLQV9JLUFBb053ajRLQ09hQWlMdncyZXFQSmdvRDhqNEFDZzNDUGdvSWhPMjJ3TXU2cWY0UUNnUHlQZ0FLRHNJLUN3ajluTnVJd016eDB1d0JDZ1B5UGdBS0RjSS1DZ2lLNU5PTjY5N0dtaWtLQV9JLUFBb2FtajhYQ2hWUGZEazRNek0xTXpjMU5ERTJOVGMzT0RnMk1UY0tHNW9fR0FvV1Qzd3hNekF5TXpnek9UY3hPREk0TXpVMU9EUTFNd29ibWo4WUNoWlBmREUxT0RVek5Ua3dPRGczTURVeE1qVTBOemcwQ2dQeVBnQUtBX0ktQUJJWEFBSUVCZ2dLREE0UUVoUVdHQm9jSGlBaUpDWW9MQzBhQkFnQUVBRWFCQWdDRUFNYUJBZ0VFQVVhQkFnR0VBY2FCQWdJRUFrYUJBZ0tFQXNhQkFnTUVBMGFCQWdPRUE4YUJBZ1FFQkVhQkFnU0VCTWFCQWdVRUJVYUJBZ1dFQmNhQkFnWUVCa2FCQWdhRUJzYUJBZ2NFQjBhQkFnZUVCOGFCQWdnRUNFYUJBZ2lFQ01hQkFna0VDVWFCQWdtRUNjYUJBZ29FQ2thQkFnb0VDb2FCQWdvRUNzYUJBZ3NFQ2thQkFnc0VDb2FCQWdzRUNzYUJBZ3RFQ2thQkFndEVDb2FCQWd0RUNzcUZ3QUNCQVlJQ2d3T0VCSVVGaGdhSEI0Z0lpUW1LQ3d0ag93YXRjaC1uZXh0LWZlZWQ%3D"), ctoken: Some("CBQSExILODZZTEZPb2c0R03AAQHIAQEYACrgBzJzNkw2d3poQlFyZUJRb0Q4ajRBQ2czQ1Bnb0k3b3VlbjdUTV9yRklDZ1B5UGdBS0RjSS1DZ2lIaU55ejlkLWI2M1VLQV9JLUFBb093ajRMQ0tXNTlNR2pwdkNhb0FFS0FfSS1BQW9Od2o0S0NLLTduYXJ2NXN1bWFRb0Q4ajRBQ2c3Q1Bnc0l2ZV9nLVBfQ3dPUHFBUW9EOGo0QUNnN0NQZ3NJdDRDUW1aS2hpTUdmQVFvRDhqNEFDZzNDUGdvSWpZQ1lnWVg4c1lOdUNnUHlQZ0FLRHNJLUN3aUFvckdHN3RtSW43Z0JDZ1B5UGdBS0RjSS1DZ2k0NmNINDBLZTYwR2NLQV9JLUFBb093ajRMQ0xLaHc5M1d1OUdKMWdFS0FfSS1BQW9Od2o0S0NJQ18ySnEzbHFDbVpBb0Q4ajRBQ2czQ1Bnb0l1SWlsckpyb2dxODBDZ1B5UGdBS0RzSS1Dd2lQN1lqano5X25pYW9CQ2dQeVBnQUtEc0ktQ3dqWG9ZVzc2ZUgyX3MwQkNnUHlQZ0FLRHNJLUN3ajU4ZmZxLVpHYnpwZ0JDZ1B5UGdBS0RjSS1DZ2pfNXEyR3k2djQzMzRLQV9JLUFBb053ajRLQ09hQWlMdncyZXFQSmdvRDhqNEFDZzNDUGdvSWhPMjJ3TXU2cWY0UUNnUHlQZ0FLRHNJLUN3ajluTnVJd016eDB1d0JDZ1B5UGdBS0RjSS1DZ2lLNU5PTjY5N0dtaWtLQV9JLUFBb2FtajhYQ2hWUGZEazRNek0xTXpjMU5ERTJOVGMzT0RnMk1UY0tHNW9fR0FvV1Qzd3hNekF5TXpnek9UY3hPREk0TXpVMU9EUTFNd29ibWo4WUNoWlBmREUxT0RVek5Ua3dPRGczTURVeE1qVTBOemcwQ2dQeVBnQUtBX0ktQUJJWEFBSUVCZ2dLREE0UUVoUVdHQm9jSGlBaUpDWW9MQzBhQkFnQUVBRWFCQWdDRUFNYUJBZ0VFQVVhQkFnR0VBY2FCQWdJRUFrYUJBZ0tFQXNhQkFnTUVBMGFCQWdPRUE4YUJBZ1FFQkVhQkFnU0VCTWFCQWdVRUJVYUJBZ1dFQmNhQkFnWUVCa2FCQWdhRUJzYUJBZ2NFQjBhQkFnZUVCOGFCQWdnRUNFYUJBZ2lFQ01hQkFna0VDVWFCQWdtRUNjYUJBZ29FQ2thQkFnb0VDb2FCQWdvRUNzYUJBZ3NFQ2thQkFnc0VDb2FCQWdzRUNzYUJBZ3RFQ2thQkFndEVDb2FCQWd0RUNzcUZ3QUNCQVlJQ2d3T0VCSVVGaGdhSEI0Z0lpUW1LQ3d0ag93YXRjaC1uZXh0LWZlZWQ%3D"),
visitor_data: Some("CgtnQS1WdzlNNkNCSSiSmKiZBg%3D%3D"),
endpoint: next,
), ),
top_comments: Paginator( top_comments: Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: next,
), ),
latest_comments: Paginator( latest_comments: Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: next,
), ),
) )

View file

@ -28,7 +28,7 @@ VideoDetails(
height: 176, height: 176,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: Some(33900), subscriber_count: Some(33900),
), ),
view_count: 20304, view_count: 20304,
@ -41,7 +41,7 @@ VideoDetails(
recommended: Paginator( recommended: Paginator(
count: None, count: None,
items: [ items: [
RecommendedVideo( VideoItem(
id: "XtV_HGppS6A", id: "XtV_HGppS6A",
title: "Vergiss mein nicht", title: "Vergiss mein nicht",
length: Some(263), length: Some(263),
@ -57,7 +57,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -67,16 +67,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 30966, view_count: Some(30966),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "BcqM8Qshx7U", id: "BcqM8Qshx7U",
title: "Kuliko Jana - Eine neue Zeit", title: "Kuliko Jana - Eine neue Zeit",
length: Some(210), length: Some(210),
@ -92,7 +94,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -102,16 +104,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 15269, view_count: Some(15269),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "IUFUIgZOcow", id: "IUFUIgZOcow",
title: "Silmaril - Schöner als die Sterne", title: "Silmaril - Schöner als die Sterne",
length: Some(205), length: Some(205),
@ -127,7 +131,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -137,16 +141,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 29035, view_count: Some(29035),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "UtP9J88Jzg0", id: "UtP9J88Jzg0",
title: "Ruinen im Sand", title: "Ruinen im Sand",
length: Some(195), length: Some(195),
@ -162,7 +168,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -172,16 +178,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 46009, view_count: Some(46009),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "sg6j-zfUF_A", id: "sg6j-zfUF_A",
title: "Eldamar", title: "Eldamar",
length: Some(223), length: Some(223),
@ -197,7 +205,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -207,16 +215,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 7405, view_count: Some(7405),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "u2XCC1rKxV0", id: "u2XCC1rKxV0",
title: "Faolan", title: "Faolan",
length: Some(256), length: Some(256),
@ -232,7 +242,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -242,16 +252,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 19383, view_count: Some(19383),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "oOBBBl3fywU", id: "oOBBBl3fywU",
title: "Aeria - Vom Wind", title: "Aeria - Vom Wind",
length: Some(260), length: Some(260),
@ -267,7 +279,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -277,16 +289,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 years ago"), publish_date_txt: Some("4 years ago"),
view_count: 132472, view_count: Some(132472),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "pI0Rancanz0", id: "pI0Rancanz0",
title: "Vergiss mein nicht", title: "Vergiss mein nicht",
length: Some(263), length: Some(263),
@ -302,7 +316,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -312,16 +326,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 years ago"), publish_date_txt: Some("4 years ago"),
view_count: 367684, view_count: Some(367684),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "DsviLYh1CB0", id: "DsviLYh1CB0",
title: "Eldamar", title: "Eldamar",
length: Some(222), length: Some(222),
@ -337,7 +353,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -347,16 +363,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 years ago"), publish_date_txt: Some("4 years ago"),
view_count: 195958, view_count: Some(195958),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Ctpe9kafn78", id: "Ctpe9kafn78",
title: "So still mein Herz", title: "So still mein Herz",
length: Some(259), length: Some(259),
@ -372,7 +390,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -382,16 +400,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 37702, view_count: Some(37702),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "y252630WbIk", id: "y252630WbIk",
title: "Oonagh und Santiano: Vergiss mein nicht (mit lyrics)", title: "Oonagh und Santiano: Vergiss mein nicht (mit lyrics)",
length: Some(260), length: Some(260),
@ -407,7 +427,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC8mcGChRS6Zm7pCSYbHeoVw", id: "UC8mcGChRS6Zm7pCSYbHeoVw",
name: "princessZelda", name: "princessZelda",
avatar: [ avatar: [
@ -417,16 +437,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("8 years ago"), publish_date_txt: Some("8 years ago"),
view_count: 103494, view_count: Some(103494),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "YgUZtELr_jw", id: "YgUZtELr_jw",
title: "Aulë und Yavanna", title: "Aulë und Yavanna",
length: Some(216), length: Some(216),
@ -442,7 +464,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -452,16 +474,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 19342, view_count: Some(19342),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "ABKSs0aU4C0", id: "ABKSs0aU4C0",
title: "Gäa (Akustik Version)", title: "Gäa (Akustik Version)",
length: Some(235), length: Some(235),
@ -477,7 +501,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -487,16 +511,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 9392, view_count: Some(9392),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "O0I3rJsHikA", id: "O0I3rJsHikA",
title: "Orome (A-Class Remix)", title: "Orome (A-Class Remix)",
length: Some(199), length: Some(199),
@ -512,7 +538,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw", id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic", name: "Sentamusic",
avatar: [ avatar: [
@ -522,26 +548,32 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 22994, view_count: Some(22994),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("CBQSExILWHVNMm9uTUd2VEnAAQHIAQEYACqsBzJzNkw2d3k2QlFxM0JRb0Q4ajRBQ2czQ1Bnb0lvSmVsMDhiajMtcGVDZ1B5UGdBS0o5SS1KQW9pVUV4aGFGSktXRWczV0ZCSWJWZE9TemMwVm5wM1NVWXljWFZYY1dSR1NWZDJjZ29EOGo0QUNpZlNQaVFLSWxCTU5pMTRZV3hIWVZaRmRYQjJlVGxHUVVoZlJYZ3pTRlYxWHpGaFVrRXlialFLQV9JLUFBb1MwajRQQ2cxU1JGaDFUVEp2YmsxSGRsUkpDZ1B5UGdBS0RjSS1DZ2kxajRmWmtKNmo1UVVLQV9JLUFBb053ajRLQ0l6bHViS2doTldnSVFvRDhqNEFDZzNDUGdvSWpaeW4tUHlrXy1sU0NnUHlQZ0FLRHNJLUN3andyOUMtc18tb2g3SUJDZ1B5UGdBS0o5SS1KQW9pVUV3d1dqSlNSVFZsY1dGWlRWRXhiRnBaZGtWalRrOW1UVmx3VFVvelkyTktRd29EOGo0QUNnN0NQZ3NJM1lxcjFyWEI4TEs3QVFvRDhqNEFDZzdDUGdzSWhaYl83dVdna1BDZ0FRb0Q4ajRBQ2c3Q1Bnc0l2YjdxdUtldHhNYWtBUW9EOGo0QUNnM0NQZ29JblpEVXc5akYtT1VPQ2dQeVBnQUtIOUktSEFvYVVrUkZUV1E0VUZwSmRqbERVSE4yZGtWRVltOWZjRlZFTkhjS0FfSS1BQW9Od2o0S0NMLV9fclRrM3BmdENnb0Q4ajRBQ2c3Q1Bnc0lpZG5aNkxmZG5iZkxBUW9EOGo0QUNnM0NQZ29JdlB5dmw4UzJ4b0ppQ2dQeVBnQUtETUktQ1FpdHdOTzB0TmFrQ1FvRDhqNEFDaWZTUGlRS0lsQk1NazR6TjFoVWQxaG5jRlZpYWxSemNXVjFNbEZFZVRCTGIyRnpkMDlZTVZvS0FfSS1BQW9Od2o0S0NNQ1VudGpKOVkyaE94SVVBQUlFQmdnS0RBNFFFaFFXR0JvY0hpQWlKQ1lhQkFnQUVBRWFCQWdDRUFNYUJBZ0VFQVVhQkFnR0VBY2FCQWdJRUFrYUJBZ0tFQXNhQkFnTUVBMGFCQWdPRUE4YUJBZ1FFQkVhQkFnU0VCTWFCQWdVRUJVYUJBZ1dFQmNhQkFnWUVCa2FCQWdhRUJzYUJBZ2NFQjBhQkFnZUVCOGFCQWdnRUNFYUJBZ2lFQ01hQkFna0VDVWFCQWdtRUNjcUZBQUNCQVlJQ2d3T0VCSVVGaGdhSEI0Z0lpUW1qD3dhdGNoLW5leHQtZmVlZA%3D%3D"), ctoken: Some("CBQSExILWHVNMm9uTUd2VEnAAQHIAQEYACqsBzJzNkw2d3k2QlFxM0JRb0Q4ajRBQ2czQ1Bnb0lvSmVsMDhiajMtcGVDZ1B5UGdBS0o5SS1KQW9pVUV4aGFGSktXRWczV0ZCSWJWZE9TemMwVm5wM1NVWXljWFZYY1dSR1NWZDJjZ29EOGo0QUNpZlNQaVFLSWxCTU5pMTRZV3hIWVZaRmRYQjJlVGxHUVVoZlJYZ3pTRlYxWHpGaFVrRXlialFLQV9JLUFBb1MwajRQQ2cxU1JGaDFUVEp2YmsxSGRsUkpDZ1B5UGdBS0RjSS1DZ2kxajRmWmtKNmo1UVVLQV9JLUFBb053ajRLQ0l6bHViS2doTldnSVFvRDhqNEFDZzNDUGdvSWpaeW4tUHlrXy1sU0NnUHlQZ0FLRHNJLUN3andyOUMtc18tb2g3SUJDZ1B5UGdBS0o5SS1KQW9pVUV3d1dqSlNSVFZsY1dGWlRWRXhiRnBaZGtWalRrOW1UVmx3VFVvelkyTktRd29EOGo0QUNnN0NQZ3NJM1lxcjFyWEI4TEs3QVFvRDhqNEFDZzdDUGdzSWhaYl83dVdna1BDZ0FRb0Q4ajRBQ2c3Q1Bnc0l2YjdxdUtldHhNYWtBUW9EOGo0QUNnM0NQZ29JblpEVXc5akYtT1VPQ2dQeVBnQUtIOUktSEFvYVVrUkZUV1E0VUZwSmRqbERVSE4yZGtWRVltOWZjRlZFTkhjS0FfSS1BQW9Od2o0S0NMLV9fclRrM3BmdENnb0Q4ajRBQ2c3Q1Bnc0lpZG5aNkxmZG5iZkxBUW9EOGo0QUNnM0NQZ29JdlB5dmw4UzJ4b0ppQ2dQeVBnQUtETUktQ1FpdHdOTzB0TmFrQ1FvRDhqNEFDaWZTUGlRS0lsQk1NazR6TjFoVWQxaG5jRlZpYWxSemNXVjFNbEZFZVRCTGIyRnpkMDlZTVZvS0FfSS1BQW9Od2o0S0NNQ1VudGpKOVkyaE94SVVBQUlFQmdnS0RBNFFFaFFXR0JvY0hpQWlKQ1lhQkFnQUVBRWFCQWdDRUFNYUJBZ0VFQVVhQkFnR0VBY2FCQWdJRUFrYUJBZ0tFQXNhQkFnTUVBMGFCQWdPRUE4YUJBZ1FFQkVhQkFnU0VCTWFCQWdVRUJVYUJBZ1dFQmNhQkFnWUVCa2FCQWdhRUJzYUJBZ2NFQjBhQkFnZUVCOGFCQWdnRUNFYUJBZ2lFQ01hQkFna0VDVWFCQWdtRUNjcUZBQUNCQVlJQ2d3T0VCSVVGaGdhSEI0Z0lpUW1qD3dhdGNoLW5leHQtZmVlZA%3D%3D"),
visitor_data: Some("CgtzclhqZVpoajVhVSi76qeZBg%3D%3D"),
endpoint: next,
), ),
top_comments: Paginator( top_comments: Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: next,
), ),
latest_comments: Paginator( latest_comments: Paginator(
count: Some(0), count: Some(0),
items: [], items: [],
ctoken: None, ctoken: None,
endpoint: next,
), ),
) )

View file

@ -91,7 +91,7 @@ VideoDetails(
height: 176, height: 176,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: Some(30900000), subscriber_count: Some(30900000),
), ),
view_count: 232792465, view_count: 232792465,
@ -104,7 +104,7 @@ VideoDetails(
recommended: Paginator( recommended: Paginator(
count: None, count: None,
items: [ items: [
RecommendedVideo( VideoItem(
id: "4TWR90KJl84", id: "4TWR90KJl84",
title: "aespa 에스파 \'Next Level\' MV", title: "aespa 에스파 \'Next Level\' MV",
length: Some(236), length: Some(236),
@ -120,7 +120,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -130,16 +130,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 245412217, view_count: Some(245412217),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "WPdWvnAAurg", id: "WPdWvnAAurg",
title: "aespa 에스파 \'Savage\' MV", title: "aespa 에스파 \'Savage\' MV",
length: Some(259), length: Some(259),
@ -155,7 +157,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -165,16 +167,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("11 months ago"), publish_date_txt: Some("11 months ago"),
view_count: 215292736, view_count: Some(215292736),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "NoYKBAajoyo", id: "NoYKBAajoyo",
title: "EVERGLOW (에버글로우) - DUN DUN MV", title: "EVERGLOW (에버글로우) - DUN DUN MV",
length: Some(209), length: Some(209),
@ -190,7 +194,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC_pwIXKXNm5KGhdEVzmY60A", id: "UC_pwIXKXNm5KGhdEVzmY60A",
name: "Stone Music Entertainment", name: "Stone Music Entertainment",
avatar: [ avatar: [
@ -200,16 +204,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 264670229, view_count: Some(264670229),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "KhTeiaCezwM", id: "KhTeiaCezwM",
title: "[MV] MAMAMOO (마마무) - HIP", title: "[MV] MAMAMOO (마마무) - HIP",
length: Some(211), length: Some(211),
@ -225,7 +231,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCuhAUMLzJxlP1W7mEk0_6lA", id: "UCuhAUMLzJxlP1W7mEk0_6lA",
name: "MAMAMOO", name: "MAMAMOO",
avatar: [ avatar: [
@ -235,16 +241,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 354281319, view_count: Some(354281319),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Jh4QFaPmdss", id: "Jh4QFaPmdss",
title: "(G)I-DLE - \'TOMBOY\' Official Music Video", title: "(G)I-DLE - \'TOMBOY\' Official Music Video",
length: Some(198), length: Some(198),
@ -260,7 +268,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCritGVo7pLJLUS8wEu32vow", id: "UCritGVo7pLJLUS8wEu32vow",
name: "(G)I-DLE (여자)아이들 (Official YouTube Channel)", name: "(G)I-DLE (여자)아이들 (Official YouTube Channel)",
avatar: [ avatar: [
@ -270,16 +278,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 months ago"), publish_date_txt: Some("6 months ago"),
view_count: 167648677, view_count: Some(167648677),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "CM4CkVFmTds", id: "CM4CkVFmTds",
title: "TWICE \"I CAN\'T STOP ME\" M/V", title: "TWICE \"I CAN\'T STOP ME\" M/V",
length: Some(221), length: Some(221),
@ -295,7 +305,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -305,16 +315,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 455437333, view_count: Some(455437333),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "uR8Mrt1IpXg", id: "uR8Mrt1IpXg",
title: "Red Velvet 레드벨벳 \'Psycho\' MV", title: "Red Velvet 레드벨벳 \'Psycho\' MV",
length: Some(216), length: Some(216),
@ -330,7 +342,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -340,16 +352,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 344730852, view_count: Some(344730852),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "QslJYDX3o8s", id: "QslJYDX3o8s",
title: "Red Velvet 레드벨벳 \'러시안 룰렛 (Russian Roulette)\' MV", title: "Red Velvet 레드벨벳 \'러시안 룰렛 (Russian Roulette)\' MV",
length: Some(212), length: Some(212),
@ -365,7 +379,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -375,16 +389,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 years ago"), publish_date_txt: Some("6 years ago"),
view_count: 238321583, view_count: Some(238321583),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "EaswWiwMVs8", id: "EaswWiwMVs8",
title: "Stray Kids \"소리꾼(Thunderous)\" M/V", title: "Stray Kids \"소리꾼(Thunderous)\" M/V",
length: Some(199), length: Some(199),
@ -400,7 +416,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -410,16 +426,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 240527435, view_count: Some(240527435),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "pNfTK39k55U", id: "pNfTK39k55U",
title: "ITZY \"달라달라(DALLA DALLA)\" M/V @ITZY", title: "ITZY \"달라달라(DALLA DALLA)\" M/V @ITZY",
length: Some(227), length: Some(227),
@ -435,7 +453,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg", id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment", name: "JYP Entertainment",
avatar: [ avatar: [
@ -445,16 +463,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("3 years ago"), publish_date_txt: Some("3 years ago"),
view_count: 306144594, view_count: Some(306144594),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "dYRITmpFbJ4", id: "dYRITmpFbJ4",
title: "aespa 에스파 \'Girls\' MV", title: "aespa 에스파 \'Girls\' MV",
length: Some(269), length: Some(269),
@ -470,7 +490,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -480,16 +500,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 100128895, view_count: Some(100128895),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "ioNng23DkIM", id: "ioNng23DkIM",
title: "BLACKPINK - \'How You Like That\' M/V", title: "BLACKPINK - \'How You Like That\' M/V",
length: Some(184), length: Some(184),
@ -505,7 +527,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -515,16 +537,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 1146631077, view_count: Some(1146631077),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Ujb-gvqsoi0", id: "Ujb-gvqsoi0",
title: "Red Velvet - IRENE & SEULGI \'Monster\' MV", title: "Red Velvet - IRENE & SEULGI \'Monster\' MV",
length: Some(182), length: Some(182),
@ -540,7 +564,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -550,16 +574,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 years ago"), publish_date_txt: Some("2 years ago"),
view_count: 126406160, view_count: Some(126406160),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "bwmSjveL3Lc", id: "bwmSjveL3Lc",
title: "BLACKPINK - \'붐바야 (BOOMBAYAH)\' M/V", title: "BLACKPINK - \'붐바야 (BOOMBAYAH)\' M/V",
length: Some(244), length: Some(244),
@ -575,7 +601,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A", id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK", name: "BLACKPINK",
avatar: [ avatar: [
@ -585,16 +611,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("6 years ago"), publish_date_txt: Some("6 years ago"),
view_count: 1476093662, view_count: Some(1476093662),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "6uJf2IT2Zh8", id: "6uJf2IT2Zh8",
title: "Red Velvet 레드벨벳 \'피카부 (Peek-A-Boo)\' MV", title: "Red Velvet 레드벨벳 \'피카부 (Peek-A-Boo)\' MV",
length: Some(230), length: Some(230),
@ -610,7 +638,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g", id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN", name: "SMTOWN",
avatar: [ avatar: [
@ -620,16 +648,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("4 years ago"), publish_date_txt: Some("4 years ago"),
view_count: 228968545, view_count: Some(228968545),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "Y8JFxS1HlDo", id: "Y8JFxS1HlDo",
title: "IVE 아이브 \'LOVE DIVE\' MV", title: "IVE 아이브 \'LOVE DIVE\' MV",
length: Some(179), length: Some(179),
@ -645,7 +675,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCYDmx2Sfpnaxg488yBpZIGg", id: "UCYDmx2Sfpnaxg488yBpZIGg",
name: "starshipTV", name: "starshipTV",
avatar: [ avatar: [
@ -655,16 +685,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: verified, verification: Verified,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("5 months ago"), publish_date_txt: Some("5 months ago"),
view_count: 152292435, view_count: Some(152292435),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "2FzSv66c7TQ", id: "2FzSv66c7TQ",
title: "A E S P A (에스파) ALL SONGS PLAYLIST 2022 | 에스파 노래 모음", title: "A E S P A (에스파) ALL SONGS PLAYLIST 2022 | 에스파 노래 모음",
length: Some(3441), length: Some(3441),
@ -680,7 +712,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UCK8S6QMrTk1G8TYQwIyDo-w", id: "UCK8S6QMrTk1G8TYQwIyDo-w",
name: "𝙇𝙌 𝙆𝙋𝙊𝙋", name: "𝙇𝙌 𝙆𝙋𝙊𝙋",
avatar: [ avatar: [
@ -690,16 +722,18 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: none, verification: None,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("2 months ago"), publish_date_txt: Some("2 months ago"),
view_count: 504562, view_count: Some(504562),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
RecommendedVideo( VideoItem(
id: "NU611fxGyPU", id: "NU611fxGyPU",
title: "aespa 에스파 \'Black Mamba\' Dance Practice", title: "aespa 에스파 \'Black Mamba\' Dance Practice",
length: Some(175), length: Some(175),
@ -715,7 +749,7 @@ VideoDetails(
height: 188, height: 188,
), ),
], ],
channel: ChannelTag( channel: Some(ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg", id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa", name: "aespa",
avatar: [ avatar: [
@ -725,26 +759,32 @@ VideoDetails(
height: 68, height: 68,
), ),
], ],
verification: artist, verification: Artist,
subscriber_count: None, subscriber_count: None,
), )),
publish_date: "[date]", publish_date: "[date]",
publish_date_txt: Some("1 year ago"), publish_date_txt: Some("1 year ago"),
view_count: 34445393, view_count: Some(34445393),
is_live: false, is_live: false,
is_short: false, is_short: false,
is_upcoming: false,
short_description: None,
), ),
], ],
ctoken: Some("CBQSExILWmVlcnJudUxpNUXAAQHIAQEYACq7BjJzNkw2d3psQkFyaUJBb0Q4ajRBQ2c3Q1Bnc0l6cS1tbFBTLTVKcmhBUW9EOGo0QUNoTFNQZzhLRFZKRVdtVmxjbkp1ZFV4cE5VVUtBX0ktQUFvdzBqNHRDaXRTUkVOTVFVczFkWGxmYXpJM2RYVXRSWFJSWDJJMVZUSnlNalpFVGtSYVQyMU9jVWRrWTJOVlNVZFJDZ1B5UGdBS0RjSS1DZ2k0OVlLQTU5ZlYtMWdLQV9JLUFBb053ajRLQ0tyR2pyWEF3SUxETmdvRDhqNEFDZzNDUGdvSWc1NzdoSnJSdDRvcUNnUHlQZ0FLRGNJLUNnakw3Wm1mMm9LRWp5WUtBX0ktQUFvTndqNEtDTnVibVl1VjBvRG5DQW9EOGo0QUNnN0NQZ3NJLU1xaTZ1MlZ3NC01QVFvRDhqNEFDZzNDUGdvSXk4ZmVyNE9zMHVSQ0NnUHlQZ0FLRGNJLUNnalByYkhnb292TTFSRUtBX0ktQUFvT3dqNExDSlhQa191MzVmVHJwQUVLQV9JLUFBb053ajRLQ0o3WmxkTG1pWkxDZFFvRDhqNEFDZzdDUGdzSWc2R083cmJ3MmNHS0FRb0Q4ajRBQ2czQ1Bnb0lyY1N5MWFfUXY1dFNDZ1B5UGdBS0RjSS1DZ2kzdWEtODc5SGtoRzhLQV9JLUFBb093ajRMQ0pfTTJhZUktNWZ4NmdFS0FfSS1BQW9Od2o0S0NMcW9udXJTdUpIaFl3b0Q4ajRBQ2c3Q1Bnc0l0TnJ6OVByWHRLN1lBUW9EOGo0QUNnM0NQZ29JOVpHYjR0LTZyYWMxRWhRQUFnUUdDQW9NRGhBU0ZCWVlHaHdlSUNJa0pob0VDQUFRQVJvRUNBSVFBeG9FQ0FRUUJSb0VDQVlRQnhvRUNBZ1FDUm9FQ0FvUUN4b0VDQXdRRFJvRUNBNFFEeG9FQ0JBUUVSb0VDQklRRXhvRUNCUVFGUm9FQ0JZUUZ4b0VDQmdRR1JvRUNCb1FHeG9FQ0J3UUhSb0VDQjRRSHhvRUNDQVFJUm9FQ0NJUUl4b0VDQ1FRSlJvRUNDWVFKeW9VQUFJRUJnZ0tEQTRRRWhRV0dCb2NIaUFpSkNZag93YXRjaC1uZXh0LWZlZWQ%3D"), ctoken: Some("CBQSExILWmVlcnJudUxpNUXAAQHIAQEYACq7BjJzNkw2d3psQkFyaUJBb0Q4ajRBQ2c3Q1Bnc0l6cS1tbFBTLTVKcmhBUW9EOGo0QUNoTFNQZzhLRFZKRVdtVmxjbkp1ZFV4cE5VVUtBX0ktQUFvdzBqNHRDaXRTUkVOTVFVczFkWGxmYXpJM2RYVXRSWFJSWDJJMVZUSnlNalpFVGtSYVQyMU9jVWRrWTJOVlNVZFJDZ1B5UGdBS0RjSS1DZ2k0OVlLQTU5ZlYtMWdLQV9JLUFBb053ajRLQ0tyR2pyWEF3SUxETmdvRDhqNEFDZzNDUGdvSWc1NzdoSnJSdDRvcUNnUHlQZ0FLRGNJLUNnakw3Wm1mMm9LRWp5WUtBX0ktQUFvTndqNEtDTnVibVl1VjBvRG5DQW9EOGo0QUNnN0NQZ3NJLU1xaTZ1MlZ3NC01QVFvRDhqNEFDZzNDUGdvSXk4ZmVyNE9zMHVSQ0NnUHlQZ0FLRGNJLUNnalByYkhnb292TTFSRUtBX0ktQUFvT3dqNExDSlhQa191MzVmVHJwQUVLQV9JLUFBb053ajRLQ0o3WmxkTG1pWkxDZFFvRDhqNEFDZzdDUGdzSWc2R083cmJ3MmNHS0FRb0Q4ajRBQ2czQ1Bnb0lyY1N5MWFfUXY1dFNDZ1B5UGdBS0RjSS1DZ2kzdWEtODc5SGtoRzhLQV9JLUFBb093ajRMQ0pfTTJhZUktNWZ4NmdFS0FfSS1BQW9Od2o0S0NMcW9udXJTdUpIaFl3b0Q4ajRBQ2c3Q1Bnc0l0TnJ6OVByWHRLN1lBUW9EOGo0QUNnM0NQZ29JOVpHYjR0LTZyYWMxRWhRQUFnUUdDQW9NRGhBU0ZCWVlHaHdlSUNJa0pob0VDQUFRQVJvRUNBSVFBeG9FQ0FRUUJSb0VDQVlRQnhvRUNBZ1FDUm9FQ0FvUUN4b0VDQXdRRFJvRUNBNFFEeG9FQ0JBUUVSb0VDQklRRXhvRUNCUVFGUm9FQ0JZUUZ4b0VDQmdRR1JvRUNCb1FHeG9FQ0J3UUhSb0VDQjRRSHhvRUNDQVFJUm9FQ0NJUUl4b0VDQ1FRSlJvRUNDWVFKeW9VQUFJRUJnZ0tEQTRRRWhRV0dCb2NIaUFpSkNZag93YXRjaC1uZXh0LWZlZWQ%3D"),
visitor_data: Some("Cgtjemd0bDVxU1N1QSjRjpSZBg%3D%3D"),
endpoint: next,
), ),
top_comments: Paginator( top_comments: Paginator(
count: Some(705000), count: Some(705000),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyJSIRIgtaZWVycm51TGk1RTAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyJSIRIgtaZWVycm51TGk1RTAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D"),
endpoint: next,
), ),
latest_comments: Paginator( latest_comments: Paginator(
count: Some(705000), count: Some(705000),
items: [], items: [],
ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyOCIRIgtaZWVycm51TGk1RTABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"), ctoken: Some("Eg0SC1plZXJybnVMaTVFGAYyOCIRIgtaZWVycm51TGk1RTABeAIwAUIhZW5nYWdlbWVudC1wYW5lbC1jb21tZW50cy1zZWN0aW9u"),
endpoint: next,
), ),
) )

View file

@ -1,18 +1,15 @@
use crate::{ use crate::{
error::{Error, ExtractionError}, error::{Error, ExtractionError},
model::{Paginator, SearchVideo}, model::{Paginator, VideoItem},
param::Language, param::Language,
serializer::MapResult, serializer::MapResult,
util::TryRemove, util::TryRemove,
}; };
use super::{ use super::{response, ClientType, MapResponse, QBrowse, RustyPipeQuery};
response::{self, TryFromWLang},
ClientType, MapResponse, QBrowse, QContinuation, RustyPipeQuery,
};
impl RustyPipeQuery { impl RustyPipeQuery {
pub async fn startpage(self) -> Result<Paginator<SearchVideo>, Error> { pub async fn startpage(self) -> Result<Paginator<VideoItem>, Error> {
let context = self.get_context(ClientType::Desktop, true).await; let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QBrowse { let request_body = QBrowse {
context, context,
@ -29,33 +26,7 @@ impl RustyPipeQuery {
.await .await
} }
pub async fn startpage_continuation( pub async fn trending(self) -> Result<Vec<VideoItem>, Error> {
self,
ctoken: &str,
visitor_data: &str,
) -> Result<Paginator<SearchVideo>, Error> {
let mut context = self.get_context(ClientType::Desktop, true).await;
context.client.visitor_data = Some(visitor_data.to_owned());
let request_body = QContinuation {
context,
continuation: ctoken,
};
self.execute_request::<response::StartpageCont, _, _>(
ClientType::Desktop,
"startpage_continuation",
ctoken,
"browse",
&request_body,
)
.await
.map(|res| Paginator {
visitor_data: Some(visitor_data.to_owned()),
..res
})
}
pub async fn trending(self) -> Result<Vec<SearchVideo>, Error> {
let context = self.get_context(ClientType::Desktop, true).await; let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QBrowse { let request_body = QBrowse {
context, context,
@ -73,20 +44,20 @@ impl RustyPipeQuery {
} }
} }
impl MapResponse<Paginator<SearchVideo>> for response::Startpage { impl MapResponse<Paginator<VideoItem>> for response::Startpage {
fn map_response( fn map_response(
self, self,
_id: &str, _id: &str,
lang: crate::param::Language, lang: crate::param::Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>, _deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Paginator<SearchVideo>>, ExtractionError> { ) -> Result<MapResult<Paginator<VideoItem>>, ExtractionError> {
let mut contents = self.contents.two_column_browse_results_renderer.tabs; let mut contents = self.contents.two_column_browse_results_renderer.tabs;
let grid = contents let grid = contents
.try_swap_remove(0) .try_swap_remove(0)
.ok_or_else(|| ExtractionError::InvalidData("no contents".into()))? .ok_or_else(|| ExtractionError::InvalidData("no contents".into()))?
.tab_renderer .tab_renderer
.content .content
.rich_grid_renderer .section_list_renderer
.contents; .contents;
Ok(map_startpage_videos( Ok(map_startpage_videos(
@ -97,33 +68,15 @@ impl MapResponse<Paginator<SearchVideo>> for response::Startpage {
} }
} }
impl MapResponse<Paginator<SearchVideo>> for response::StartpageCont { impl MapResponse<Vec<VideoItem>> for response::Trending {
fn map_response( fn map_response(
self, self,
_id: &str, _id: &str,
lang: crate::param::Language, lang: crate::param::Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>, _deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Paginator<SearchVideo>>, ExtractionError> { ) -> Result<MapResult<Vec<VideoItem>>, ExtractionError> {
let mut received_actions = self.on_response_received_actions;
let items = received_actions
.try_swap_remove(0)
.ok_or_else(|| ExtractionError::InvalidData("no contents".into()))?
.append_continuation_items_action
.continuation_items;
Ok(map_startpage_videos(items, lang, None))
}
}
impl MapResponse<Vec<SearchVideo>> for response::Trending {
fn map_response(
self,
_id: &str,
lang: crate::param::Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Vec<SearchVideo>>, ExtractionError> {
let mut contents = self.contents.two_column_browse_results_renderer.tabs; let mut contents = self.contents.two_column_browse_results_renderer.tabs;
let sections = contents let items = contents
.try_swap_remove(0) .try_swap_remove(0)
.ok_or_else(|| ExtractionError::InvalidData("no contents".into()))? .ok_or_else(|| ExtractionError::InvalidData("no contents".into()))?
.tab_renderer .tab_renderer
@ -131,76 +84,33 @@ impl MapResponse<Vec<SearchVideo>> for response::Trending {
.section_list_renderer .section_list_renderer
.contents; .contents;
let mut items = Vec::new(); let mut mapper = response::YouTubeListMapper::<VideoItem>::new(lang);
let mut warnings = Vec::new(); mapper.map_response(items);
for mut section in sections { Ok(MapResult {
let shelf = section c: mapper.items,
.item_section_renderer warnings: mapper.warnings,
.contents })
.try_swap_remove(0)
.and_then(|shelf| {
shelf
.shelf_renderer
.content
.expanded_shelf_contents_renderer
});
if let Some(mut shelf) = shelf {
warnings.append(&mut shelf.items.warnings);
for item in shelf.items.c {
if let response::trends::TrendingListItem::VideoRenderer(video) = item {
match SearchVideo::from_w_lang(video, lang) {
Ok(video) => {
items.push(video);
}
Err(e) => {
warnings.push(e.to_string());
}
}
}
}
}
}
Ok(MapResult { c: items, warnings })
} }
} }
fn map_startpage_videos( fn map_startpage_videos(
videos: MapResult<Vec<response::VideoListItem>>, videos: MapResult<Vec<response::YouTubeListItem>>,
lang: Language, lang: Language,
visitor_data: Option<String>, visitor_data: Option<String>,
) -> MapResult<Paginator<SearchVideo>> { ) -> MapResult<Paginator<VideoItem>> {
let mut warnings = videos.warnings; let mut mapper = response::YouTubeListMapper::<VideoItem>::new(lang);
let mut ctoken = None; mapper.map_response(videos);
let items = videos
.c
.into_iter()
.filter_map(|item| match item {
response::VideoListItem::RichItemRenderer {
content: response::RichItem::VideoRenderer(video),
} => match SearchVideo::from_w_lang(video, lang) {
Ok(video) => Some(video),
Err(e) => {
warnings.push(e.to_string());
None
}
},
response::VideoListItem::ContinuationItemRenderer {
continuation_endpoint,
} => {
ctoken = Some(continuation_endpoint.continuation_command.token);
None
}
_ => None,
})
.collect();
MapResult { MapResult {
c: Paginator::new_with_vdata(None, items, ctoken, visitor_data), c: Paginator::new_ext(
warnings, None,
mapper.items,
mapper.ctoken,
visitor_data,
crate::param::ContinuationEndpoint::Browse,
),
warnings: mapper.warnings,
} }
} }
@ -210,7 +120,7 @@ mod tests {
use crate::{ use crate::{
client::{response, MapResponse}, client::{response, MapResponse},
model::{Paginator, SearchVideo}, model::{Paginator, VideoItem},
param::Language, param::Language,
serializer::MapResult, serializer::MapResult,
}; };
@ -223,7 +133,7 @@ mod tests {
let startpage: response::Startpage = let startpage: response::Startpage =
serde_json::from_reader(BufReader::new(json_file)).unwrap(); serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Paginator<SearchVideo>> = let map_res: MapResult<Paginator<VideoItem>> =
startpage.map_response("", Language::En, None).unwrap(); startpage.map_response("", Language::En, None).unwrap();
assert!( assert!(
@ -237,28 +147,6 @@ mod tests {
}); });
} }
#[test]
fn map_startpage_cont() {
let filename = "testfiles/trends/startpage_cont.json";
let json_path = Path::new(&filename);
let json_file = File::open(json_path).unwrap();
let startpage: response::StartpageCont =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Paginator<SearchVideo>> =
startpage.map_response("", Language::En, None).unwrap();
assert!(
map_res.warnings.is_empty(),
"deserialization/mapping warnings: {:?}",
map_res.warnings
);
insta::assert_ron_snapshot!("map_startpage_cont", map_res.c, {
".items[].publish_date" => "[date]",
});
}
#[test] #[test]
fn map_trending() { fn map_trending() {
let filename = "testfiles/trends/trending.json"; let filename = "testfiles/trends/trending.json";
@ -267,7 +155,7 @@ mod tests {
let startpage: response::Trending = let startpage: response::Trending =
serde_json::from_reader(BufReader::new(json_file)).unwrap(); serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Vec<SearchVideo>> = let map_res: MapResult<Vec<VideoItem>> =
startpage.map_response("", Language::En, None).unwrap(); startpage.map_response("", Language::En, None).unwrap();
assert!( assert!(

View file

@ -2,7 +2,7 @@ use serde::Serialize;
use crate::{ use crate::{
error::{Error, ExtractionError}, error::{Error, ExtractionError},
model::{ChannelTag, Chapter, Comment, Paginator, RecommendedVideo, VideoDetails}, model::{ChannelTag, Chapter, Comment, Paginator, VideoDetails, VideoItem},
param::Language, param::Language,
serializer::MapResult, serializer::MapResult,
timeago, timeago,
@ -10,7 +10,7 @@ use crate::{
}; };
use super::{ use super::{
response::{self, IconType, TryFromWLang}, response::{self, IconType},
ClientType, MapResponse, QContinuation, RustyPipeQuery, YTContext, ClientType, MapResponse, QContinuation, RustyPipeQuery, YTContext,
}; };
@ -45,28 +45,13 @@ impl RustyPipeQuery {
.await .await
} }
pub async fn video_recommendations( pub async fn video_comments(
self, self,
ctoken: &str, ctoken: &str,
) -> Result<Paginator<RecommendedVideo>, Error> { visitor_data: Option<&str>,
let context = self.get_context(ClientType::Desktop, true).await; ) -> Result<Paginator<Comment>, Error> {
let request_body = QContinuation { let mut context = self.get_context(ClientType::Desktop, true).await;
context, context.client.visitor_data = visitor_data.map(str::to_owned);
continuation: ctoken,
};
self.execute_request::<response::VideoRecommendations, _, _>(
ClientType::Desktop,
"video_recommendations",
ctoken,
"next",
&request_body,
)
.await
}
pub async fn video_comments(self, ctoken: &str) -> Result<Paginator<Comment>, Error> {
let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QContinuation { let request_body = QContinuation {
context, context,
continuation: ctoken, continuation: ctoken,
@ -254,7 +239,12 @@ impl MapResponse<VideoDetails> for response::VideoDetails {
.secondary_results .secondary_results
.and_then(|sr| { .and_then(|sr| {
sr.secondary_results.results.map(|r| { sr.secondary_results.results.map(|r| {
let mut res = map_recommendations(r, sr.secondary_results.continuations, lang); let mut res = map_recommendations(
r,
sr.secondary_results.continuations,
self.response_context.visitor_data,
lang,
);
warnings.append(&mut res.warnings); warnings.append(&mut res.warnings);
res.c res.c
}) })
@ -329,32 +319,26 @@ impl MapResponse<VideoDetails> for response::VideoDetails {
is_ccommons, is_ccommons,
chapters, chapters,
recommended, recommended,
top_comments: Paginator::new(comment_count, Vec::new(), comment_ctoken), top_comments: Paginator::new_ext(
latest_comments: Paginator::new(comment_count, Vec::new(), latest_comments_ctoken), comment_count,
Vec::new(),
comment_ctoken,
None,
crate::param::ContinuationEndpoint::Next,
),
latest_comments: Paginator::new_ext(
comment_count,
Vec::new(),
latest_comments_ctoken,
None,
crate::param::ContinuationEndpoint::Next,
),
}, },
warnings, warnings,
}) })
} }
} }
impl MapResponse<Paginator<RecommendedVideo>> for response::VideoRecommendations {
fn map_response(
self,
_id: &str,
lang: Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Paginator<RecommendedVideo>>, ExtractionError> {
let mut endpoints = self.on_response_received_endpoints;
let cont = endpoints.try_swap_remove(0).ok_or(ExtractionError::Retry)?;
Ok(map_recommendations(
cont.append_continuation_items_action.continuation_items,
None,
lang,
))
}
}
impl MapResponse<Paginator<Comment>> for response::VideoComments { impl MapResponse<Paginator<Comment>> for response::VideoComments {
fn map_response( fn map_response(
self, self,
@ -362,9 +346,7 @@ impl MapResponse<Paginator<Comment>> for response::VideoComments {
lang: Language, lang: Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>, _deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Paginator<Comment>>, ExtractionError> { ) -> Result<MapResult<Paginator<Comment>>, ExtractionError> {
let received_endpoints = self let received_endpoints = self.on_response_received_endpoints;
.on_response_received_endpoints
.ok_or(ExtractionError::Retry)?;
let mut warnings = received_endpoints.warnings; let mut warnings = received_endpoints.warnings;
let mut comments = Vec::new(); let mut comments = Vec::new();
@ -419,47 +401,29 @@ impl MapResponse<Paginator<Comment>> for response::VideoComments {
} }
fn map_recommendations( fn map_recommendations(
r: MapResult<Vec<response::VideoListItem>>, r: MapResult<Vec<response::YouTubeListItem>>,
continuations: Option<Vec<response::MusicContinuation>>, continuations: Option<Vec<response::MusicContinuation>>,
visitor_data: Option<String>,
lang: Language, lang: Language,
) -> MapResult<Paginator<RecommendedVideo>> { ) -> MapResult<Paginator<VideoItem>> {
let mut warnings = r.warnings; let mut mapper = response::YouTubeListMapper::<VideoItem>::new(lang);
let mut ctoken = None; mapper.map_response(r);
let mut items = Vec::new();
r.c.into_iter().for_each(|item| match item {
response::VideoListItem::CompactVideoRenderer(video) => {
match RecommendedVideo::from_w_lang(video, lang) {
Ok(video) => items.push(video),
Err(e) => warnings.push(e.to_string()),
}
}
response::VideoListItem::ItemSectionRenderer { contents } => {
let mut x = map_recommendations(contents, None, lang);
items.append(&mut x.c.items);
warnings.append(&mut x.warnings);
if let Some(ct) = x.c.ctoken {
ctoken = Some(ct)
}
}
response::VideoListItem::ContinuationItemRenderer {
continuation_endpoint,
} => {
ctoken = Some(continuation_endpoint.continuation_command.token);
}
_ => {}
});
if let Some(continuations) = continuations { if let Some(continuations) = continuations {
continuations.into_iter().for_each(|c| { continuations.into_iter().for_each(|c| {
ctoken = Some(c.next_continuation_data.continuation); mapper.ctoken = Some(c.next_continuation_data.continuation);
}) })
}; };
MapResult { MapResult {
c: Paginator::new(None, items, ctoken), c: Paginator::new_ext(
warnings, None,
mapper.items,
mapper.ctoken,
visitor_data,
crate::param::ContinuationEndpoint::Next,
),
warnings: mapper.warnings,
} }
} }
@ -600,42 +564,6 @@ mod tests {
)) ))
} }
#[test]
fn t_map_recommendations() {
let json_path = Path::new("testfiles/video_details/recommendations.json");
let json_file = File::open(json_path).unwrap();
let recommendations: response::VideoRecommendations =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res = recommendations
.map_response("", Language::En, None)
.unwrap();
assert!(
map_res.warnings.is_empty(),
"deserialization/mapping warnings: {:?}",
map_res.warnings
);
insta::assert_ron_snapshot!("map_recommendations", map_res.c, {
".items[].publish_date" => "[date]",
});
}
#[test]
fn map_recommendations_empty() {
let filename = format!("testfiles/video_details/recommendations_empty.json");
let json_path = Path::new(&filename);
let json_file = File::open(json_path).unwrap();
let recommendations: response::VideoRecommendations =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let err = recommendations
.map_response("", Language::En, None)
.unwrap_err();
assert!(matches!(err, crate::error::ExtractionError::Retry));
}
#[rstest] #[rstest]
#[case::top("top")] #[case::top("top")]
#[case::latest("latest")] #[case::latest("latest")]

View file

@ -83,6 +83,4 @@ pub enum ExtractionError {
WrongResult(String), WrongResult(String),
#[error("Warnings during deserialization/mapping")] #[error("Warnings during deserialization/mapping")]
DeserializationWarnings, DeserializationWarnings,
#[error("Got no data from YouTube, attempt retry")]
Retry,
} }

View file

@ -530,7 +530,7 @@ pub struct VideoDetails {
/// Recommended videos /// Recommended videos
/// ///
/// Note: Recommendations are not available for age-restricted videos /// Note: Recommendations are not available for age-restricted videos
pub recommended: Paginator<RecommendedVideo>, pub recommended: Paginator<VideoItem>,
/// Paginator to fetch comments (most liked first) /// Paginator to fetch comments (most liked first)
/// ///
/// Is initially empty. /// Is initially empty.
@ -556,42 +556,6 @@ pub struct Chapter {
pub thumbnail: Vec<Thumbnail>, pub thumbnail: Vec<Thumbnail>,
} }
/*
@RECOMMENDATIONS
*/
/// YouTube video fetched from the recommendations next to a video
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct RecommendedVideo {
/// Unique YouTube video ID
pub id: String,
/// Video title
pub title: String,
/// Video length in seconds.
///
/// Is [`None`] for livestreams.
pub length: Option<u32>,
/// Video thumbnail
pub thumbnail: Vec<Thumbnail>,
/// Channel of the video
pub channel: ChannelTag,
/// Video publishing date.
///
/// [`None`] if the date could not be parsed.
pub publish_date: Option<DateTime<Local>>,
/// Textual video publish date (e.g. `11 months ago`, depends on language)
///
/// Is [`None`] for livestreams.
pub publish_date_txt: Option<String>,
/// View count
pub view_count: u64,
/// Is the video an active livestream?
pub is_live: bool,
/// Is the video a YouTube Short video (vertical and <60s)?
pub is_short: bool,
}
/// Channel information attached to a video or comment /// Channel information attached to a video or comment
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive] #[non_exhaustive]
@ -618,7 +582,6 @@ pub struct ChannelTag {
/// Verification status of a channel /// Verification status of a channel
#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] #[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive] #[non_exhaustive]
pub enum Verification { pub enum Verification {
#[default] #[default]
@ -692,6 +655,8 @@ pub struct Channel<T> {
pub subscriber_count: Option<u64>, pub subscriber_count: Option<u64>,
/// Channel avatar / profile picture /// Channel avatar / profile picture
pub avatar: Vec<Thumbnail>, pub avatar: Vec<Thumbnail>,
/// Channel verification mark
pub verification: Verification,
/// Channel description text /// Channel description text
pub description: String, pub description: String,
/// List of words to describe the topic of the channel /// List of words to describe the topic of the channel
@ -709,55 +674,6 @@ pub struct Channel<T> {
pub content: T, pub content: T,
} }
/// Video fetched from a YouTube channel
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChannelVideo {
/// Unique YouTube video ID
pub id: String,
/// Video title
pub title: String,
/// Video length in seconds.
///
/// Is [`None`] for livestreams.
pub length: Option<u32>,
/// Video thumbnail
pub thumbnail: Vec<Thumbnail>,
/// Video publishing date.
///
/// [`None`] if the date could not be parsed.
/// May be in the future for upcoming videos
pub publish_date: Option<DateTime<Local>>,
/// Textual video publish date (e.g. `11 months ago`, depends on language)
///
/// Is [`None`] for livestreams and upcoming videos.
pub publish_date_txt: Option<String>,
/// Number of views / current viewers in case of a livestream.
///
/// [`None`] if it could not be extracted.
pub view_count: u64,
/// Is the video an active livestream?
pub is_live: bool,
/// Is the video a YouTube Short video (vertical and <60s)?
pub is_short: bool,
/// Is the video announced, but not released yet (YouTube Premiere)?
pub is_upcoming: bool,
}
/// Playlist fetched from a YouTube channel
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChannelPlaylist {
/// Unique YouTube Playlist-ID (e.g. `PL5dDx681T4bR7ZF1IuWzOv1omlRbE7PiJ`)
pub id: String,
/// Playlist name
pub name: String,
/// Playlist thumbnail
pub thumbnail: Vec<Thumbnail>,
/// Number of playlist videos
pub video_count: Option<u64>,
}
/// Additional channel metadata fetched from the "About" tab. /// Additional channel metadata fetched from the "About" tab.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive] #[non_exhaustive]
@ -808,23 +724,34 @@ pub struct ChannelRssVideo {
pub like_count: u64, pub like_count: u64,
} }
/// YouTube search result
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SearchResult { pub struct SearchResult {
pub items: Paginator<SearchItem>, /// Search result items
pub items: Paginator<YouTubeItem>,
/// Corrected search query
///
/// If the search term containes a typo, YouTube instead searches
/// for the corrected search term and displays it on top of the
/// search results page.
pub corrected_query: Option<String>, pub corrected_query: Option<String>,
} }
/// YouTube item (Video/Channel/Playlist)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum SearchItem { pub enum YouTubeItem {
Video(SearchVideo), /// YouTube video item
Playlist(SearchPlaylist), Video(VideoItem),
Channel(SearchChannel), /// YouTube playlist item
Playlist(PlaylistItem),
/// YouTube channel item
Channel(ChannelItem),
} }
/// YouTube video from the search results /// YouTube video list item
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive] #[non_exhaustive]
pub struct SearchVideo { pub struct VideoItem {
/// Unique YouTube video ID /// Unique YouTube video ID
pub id: String, pub id: String,
/// Video title /// Video title
@ -836,7 +763,7 @@ pub struct SearchVideo {
/// Video thumbnail /// Video thumbnail
pub thumbnail: Vec<Thumbnail>, pub thumbnail: Vec<Thumbnail>,
/// Channel of the video /// Channel of the video
pub channel: ChannelTag, pub channel: Option<ChannelTag>,
/// Video publishing date. /// Video publishing date.
/// ///
/// [`None`] if the date could not be parsed. /// [`None`] if the date could not be parsed.
@ -848,43 +775,21 @@ pub struct SearchVideo {
/// View count /// View count
/// ///
/// [`None`] if it could not be extracted. /// [`None`] if it could not be extracted.
pub view_count: u64, pub view_count: Option<u64>,
/// Is the video an active livestream? /// Is the video an active livestream?
pub is_live: bool, pub is_live: bool,
/// Is the video a YouTube Short video (vertical and <60s)? /// Is the video a YouTube Short video (vertical and <60s)?
pub is_short: bool, pub is_short: bool,
/// Is the video announced, but not released yet (YouTube Premiere)?
pub is_upcoming: bool,
/// Abbreviated video description /// Abbreviated video description
pub short_description: String, pub short_description: Option<String>,
} }
/// Playlist from the search results /// YouTube channel list item
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive] #[non_exhaustive]
pub struct SearchPlaylist { pub struct ChannelItem {
/// Unique YouTube Playlist-ID (e.g. `PL5dDx681T4bR7ZF1IuWzOv1omlRbE7PiJ`)
pub id: String,
/// Playlist name
pub name: String,
/// Playlist thumbnail
pub thumbnail: Vec<Thumbnail>,
/// Number of playlist videos
pub video_count: u64,
/// First 2 videos
pub first_videos: Vec<SearchPlaylistVideo>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct SearchPlaylistVideo {
pub id: String,
pub title: String,
pub length: Option<u32>,
}
/// Channel from the search results
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct SearchChannel {
/// Unique YouTube channel ID /// Unique YouTube channel ID
pub id: String, pub id: String,
/// Channel name /// Channel name
@ -902,3 +807,52 @@ pub struct SearchChannel {
/// Abbreviated channel description /// Abbreviated channel description
pub short_description: String, pub short_description: String,
} }
/// YouTube playlist list item
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct PlaylistItem {
/// Unique YouTube Playlist-ID (e.g. `PL5dDx681T4bR7ZF1IuWzOv1omlRbE7PiJ`)
pub id: String,
/// Playlist name
pub name: String,
/// Playlist thumbnail
pub thumbnail: Vec<Thumbnail>,
/// Channel of the playlist
pub channel: Option<ChannelTag>,
/// Number of playlist videos
pub video_count: Option<u64>,
}
impl TryFrom<YouTubeItem> for VideoItem {
type Error = ();
fn try_from(value: YouTubeItem) -> Result<Self, Self::Error> {
match value {
YouTubeItem::Video(video) => Ok(video),
_ => Err(()),
}
}
}
impl TryFrom<YouTubeItem> for PlaylistItem {
type Error = ();
fn try_from(value: YouTubeItem) -> Result<Self, Self::Error> {
match value {
YouTubeItem::Playlist(playlist) => Ok(playlist),
_ => Err(()),
}
}
}
impl TryFrom<YouTubeItem> for ChannelItem {
type Error = ();
fn try_from(value: YouTubeItem) -> Result<Self, Self::Error> {
match value {
YouTubeItem::Channel(channel) => Ok(channel),
_ => Err(()),
}
}
}

View file

@ -2,6 +2,8 @@ use std::convert::TryInto;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::param::ContinuationEndpoint;
/// Wrapper around progressively fetched items /// Wrapper around progressively fetched items
/// ///
/// The paginator is a wrapper around a list of items that are fetched /// The paginator is a wrapper around a list of items that are fetched
@ -31,6 +33,8 @@ pub struct Paginator<T> {
/// YouTube visitor data. Required for fetching the startpage /// YouTube visitor data. Required for fetching the startpage
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub visitor_data: Option<String>, pub visitor_data: Option<String>,
/// YouTube API endpoint to fetch continuations from
pub endpoint: ContinuationEndpoint,
} }
impl<T> Default for Paginator<T> { impl<T> Default for Paginator<T> {
@ -40,20 +44,22 @@ impl<T> Default for Paginator<T> {
items: Vec::new(), items: Vec::new(),
ctoken: None, ctoken: None,
visitor_data: None, visitor_data: None,
endpoint: ContinuationEndpoint::Browse,
} }
} }
} }
impl<T> Paginator<T> { impl<T> Paginator<T> {
pub(crate) fn new(count: Option<u64>, items: Vec<T>, ctoken: Option<String>) -> Self { pub(crate) fn new(count: Option<u64>, items: Vec<T>, ctoken: Option<String>) -> Self {
Self::new_with_vdata(count, items, ctoken, None) Self::new_ext(count, items, ctoken, None, ContinuationEndpoint::Browse)
} }
pub(crate) fn new_with_vdata( pub(crate) fn new_ext(
count: Option<u64>, count: Option<u64>,
items: Vec<T>, items: Vec<T>,
ctoken: Option<String>, ctoken: Option<String>,
visitor_data: Option<String>, visitor_data: Option<String>,
endpoint: ContinuationEndpoint,
) -> Self { ) -> Self {
Self { Self {
count: match ctoken { count: match ctoken {
@ -63,6 +69,7 @@ impl<T> Paginator<T> {
items, items,
ctoken, ctoken,
visitor_data, visitor_data,
endpoint,
} }
} }

View file

@ -4,6 +4,7 @@ pub mod locale;
pub mod search_filter; pub mod search_filter;
pub use locale::{Country, Language}; pub use locale::{Country, Language};
use serde::{Deserialize, Serialize};
pub use stream_filter::StreamFilter; pub use stream_filter::StreamFilter;
/// Channel video sort order /// Channel video sort order
@ -18,3 +19,22 @@ pub enum ChannelOrder {
/// Output the most viewed videos first /// Output the most viewed videos first
Popular, Popular,
} }
/// YouTube API endpoint to fetch continuations from
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum ContinuationEndpoint {
Browse,
Search,
Next,
}
impl ContinuationEndpoint {
pub(crate) fn as_str(self) -> &'static str {
match self {
ContinuationEndpoint::Browse => "browse",
ContinuationEndpoint::Search => "search",
ContinuationEndpoint::Next => "next",
}
}
}

View file

@ -42,7 +42,7 @@ use crate::{
#[serde_as] #[serde_as]
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum Text { pub(crate) enum Text {
Simple { Simple {
#[serde(alias = "simpleText")] #[serde(alias = "simpleText")]
text: String, text: String,
@ -86,10 +86,10 @@ impl<'de> DeserializeAs<'de, Vec<String>> for Text {
/// ///
/// Texts with links are mapped as a list of text components. /// Texts with links are mapped as a list of text components.
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct TextComponents(pub Vec<TextComponent>); pub(crate) struct TextComponents(pub Vec<TextComponent>);
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum TextComponent { pub(crate) enum TextComponent {
Video { Video {
text: String, text: String,
video_id: String, video_id: String,
@ -130,7 +130,7 @@ struct RichTextRun {
/// the links. /// the links.
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AttributedText { pub(crate) struct AttributedText {
content: String, content: String,
#[serde(default)] #[serde(default)]
command_runs: Vec<AttributedTextRun>, command_runs: Vec<AttributedTextRun>,
@ -345,7 +345,7 @@ impl From<TextComponents> for crate::model::richtext::RichText {
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AccessibilityText { pub(crate) struct AccessibilityText {
accessibility_data: AccessibilityData, accessibility_data: AccessibilityData,
} }

File diff suppressed because it is too large Load diff

View file

@ -1,94 +0,0 @@
{
"responseContext": {
"visitorData": "CgthSmp5T24zQkRjTSiom5WaBg%3D%3D",
"serviceTrackingParams": [
{
"service": "CSI",
"params": [
{
"key": "c",
"value": "WEB"
},
{
"key": "cver",
"value": "2.20221006.09.00"
},
{
"key": "yt_li",
"value": "0"
},
{
"key": "GetWatchNext_rid",
"value": "0x8836d1dc393da349"
}
]
},
{
"service": "GFEEDBACK",
"params": [
{
"key": "logged_in",
"value": "0"
},
{
"key": "e",
"value": "1714258,23804281,23882503,23885487,23918597,23934970,23940248,23946420,23966208,23983296,23986022,23998056,24001373,24002022,24002025,24004644,24007246,24034168,24036948,24077241,24080738,24108448,24120820,24135310,24140247,24152443,24161116,24162920,24164186,24166867,24169501,24181174,24185614,24187043,24187377,24191629,24197450,24199724,24199774,24211178,24217535,24219713,24223903,24224266,24225483,24226335,24227844,24228638,24229161,24241378,24243988,24248092,24248385,24254502,24255543,24255545,24256985,24259938,24260783,24262346,24263796,24265820,24267564,24267570,24268142,24268812,24268870,24278546,24278596,24279196,24279628,24279727,24280997,24281835,24282957,24283093,24283280,24286003,24286019,24287326,24287795,24288045,24289478,24289901,24289939,24290131,24290276,24290971,24292296,24295099,24295740,24297099,24298640,24298651,24298795,24299688,24299747,24390674,24391537,24392058,24392269,24394618,24590921,39322278,39322399,39322505"
}
]
},
{
"service": "GUIDED_HELP",
"params": [
{
"key": "logged_in",
"value": "0"
}
]
},
{
"service": "ECATCHER",
"params": [
{
"key": "client.version",
"value": "2.20221006"
},
{
"key": "client.name",
"value": "WEB"
},
{
"key": "client.fexp",
"value": "24286003,24298795,24256985,23804281,24001373,23946420,24283280,24289478,24223903,24298651,24286019,23885487,24077241,24265820,23918597,24255545,24036948,24259938,24279196,24199774,24282957,24279628,24268812,24169501,24225483,24590921,24197450,24298640,39322399,24290971,24108448,24287326,24219713,24278596,24002022,24181174,24227844,24287795,24229161,24283093,24162920,24248092,24241378,24166867,24002025,24280997,24391537,24278546,24288045,24034168,24290131,24211178,24289901,24226335,24268870,24295099,24135310,24191629,24394618,24007246,24004644,24243988,24281835,24392058,23998056,24185614,24262346,24187043,24224266,23986022,24228638,23934970,39322278,24292296,24260783,23940248,24263796,24267564,24299688,24390674,24152443,23966208,24267570,24080738,24290276,24217535,23882503,24279727,24164186,24289939,24187377,24268142,24120820,24199724,39322505,24392269,24254502,24255543,24299747,24161116,24140247,1714258,24297099,23983296,24295740,24248385"
}
]
}
],
"mainAppWebResponseContext": {
"loggedOut": true
},
"webResponseContextExtensionData": {
"hasDecorated": true
}
},
"trackingParams": "CAAQg2ciEwjfruPhg9j6AhXW2BEIHd9wAwc=",
"engagementPanels": [
{
"engagementPanelSectionListRenderer": {
"content": {
"adsEngagementPanelContentRenderer": {
"hack": true
}
},
"targetId": "engagement-panel-ads",
"visibility": "ENGAGEMENT_PANEL_VISIBILITY_HIDDEN",
"loggingDirectives": {
"trackingParams": "CAEQ040EGAAiEwjfruPhg9j6AhXW2BEIHd9wAwc=",
"visibility": {
"types": "12"
},
"enableDisplayloggerExperiment": true
}
}
}
]
}

View file

@ -7,7 +7,7 @@ use rustypipe::client::{ClientType, RustyPipe};
use rustypipe::error::{Error, ExtractionError}; use rustypipe::error::{Error, ExtractionError};
use rustypipe::model::richtext::ToPlaintext; use rustypipe::model::richtext::ToPlaintext;
use rustypipe::model::{ use rustypipe::model::{
AudioCodec, AudioFormat, Channel, SearchItem, UrlTarget, Verification, VideoCodec, VideoFormat, AudioCodec, AudioFormat, Channel, UrlTarget, Verification, VideoCodec, VideoFormat, YouTubeItem,
}; };
use rustypipe::param::{ use rustypipe::param::{
search_filter::{self, SearchFilter}, search_filter::{self, SearchFilter},
@ -75,7 +75,7 @@ async fn get_player_from_client(#[case] client_type: ClientType) {
assert_eq!(video.codec, VideoCodec::Vp9); assert_eq!(video.codec, VideoCodec::Vp9);
assert_approx(audio.bitrate as f64, 130685.0); assert_approx(audio.bitrate as f64, 130685.0);
assert_eq!(audio.average_bitrate, 129496); assert_approx(audio.average_bitrate as f64, 129496.0);
assert_eq!(audio.size, 4193863); assert_eq!(audio.size, 4193863);
assert_eq!(audio.mime, "audio/mp4; codecs=\"mp4a.40.2\""); assert_eq!(audio.mime, "audio/mp4; codecs=\"mp4a.40.2\"");
assert_eq!(audio.format, AudioFormat::M4a); assert_eq!(audio.format, AudioFormat::M4a);
@ -154,7 +154,7 @@ async fn get_player_from_client(#[case] client_type: ClientType) {
#[case::live( #[case::live(
"86YLFOog4GM", "86YLFOog4GM",
"🌎 Nasa Live Stream - Earth From Space : Live Views from the ISS", "🌎 Nasa Live Stream - Earth From Space : Live Views from the ISS",
"Live NASA - Views Of Earth from Space", "The station is crewed by NASA astronauts as well as Russian Cosmonauts",
0, 0,
"UCakgsb0w7QB0VHdnCc-OVEA", "UCakgsb0w7QB0VHdnCc-OVEA",
"Space Videos", "Space Videos",
@ -701,7 +701,7 @@ async fn get_video_details_live() {
); );
let desc = details.description.to_plaintext(); let desc = details.description.to_plaintext();
assert!( assert!(
desc.contains("Live NASA - Views Of Earth from Space"), desc.contains("The station is crewed by NASA astronauts as well as Russian Cosmonauts"),
"bad description: {}", "bad description: {}",
desc desc
); );
@ -896,7 +896,7 @@ async fn channel_videos(#[case] order: ChannelOrder) {
} }
ChannelOrder::Popular => { ChannelOrder::Popular => {
assert!( assert!(
first_video.view_count > 2300000, first_video.view_count.unwrap() > 2300000,
"most popular video < 2.3M views" "most popular video < 2.3M views"
) )
} }
@ -984,6 +984,7 @@ fn assert_channel_eevblog<T>(channel: &Channel<T>) {
channel.subscriber_count.unwrap() channel.subscriber_count.unwrap()
); );
assert!(!channel.avatar.is_empty(), "got no thumbnails"); assert!(!channel.avatar.is_empty(), "got no thumbnails");
assert_eq!(channel.verification, Verification::Verified);
assert_eq!(channel.description, "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON'T DO PAID VIDEO SPONSORSHIPS, DON'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don't be offended if I don't have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA"); assert_eq!(channel.description, "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON'T DO PAID VIDEO SPONSORSHIPS, DON'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don't be offended if I don't have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA");
assert!(!channel.tags.is_empty(), "got no tags"); assert!(!channel.tags.is_empty(), "got no tags");
assert_eq!( assert_eq!(
@ -1156,13 +1157,13 @@ async fn search_filter_entity(#[case] entity: search_filter::Entity) {
assert!(!result.items.is_exhausted()); assert!(!result.items.is_exhausted());
result.items.items.iter().for_each(|item| match item { result.items.items.iter().for_each(|item| match item {
SearchItem::Video(_) => { YouTubeItem::Video(_) => {
assert_eq!(entity, search_filter::Entity::Video); assert_eq!(entity, search_filter::Entity::Video);
} }
SearchItem::Channel(_) => { YouTubeItem::Channel(_) => {
assert_eq!(entity, search_filter::Entity::Channel); assert_eq!(entity, search_filter::Entity::Channel);
} }
SearchItem::Playlist(_) => { YouTubeItem::Playlist(_) => {
assert_eq!(entity, search_filter::Entity::Playlist); assert_eq!(entity, search_filter::Entity::Playlist);
} }
}); });