fix: support AB3 (channel handles in search results)

This commit is contained in:
ThetaDev 2022-11-22 01:30:30 +01:00
parent 73fa0295bf
commit aaffc6404d
14 changed files with 5855 additions and 50 deletions

View file

@ -399,7 +399,7 @@ impl<T> YouTubeListMapper<T> {
}
}
fn map_video(&self, video: VideoRenderer) -> VideoItem {
fn map_video(&mut self, video: VideoRenderer) -> VideoItem {
let mut tn_overlays = video.thumbnail_overlays;
let length_text = video.length_text.or_else(|| {
tn_overlays
@ -434,10 +434,9 @@ impl<T> YouTubeListMapper<T> {
.as_ref()
.and_then(|upc| OffsetDateTime::from_unix_timestamp(upc.start_time).ok())
.or_else(|| {
video
.published_time_text
.as_ref()
.and_then(|txt| timeago::parse_timeago_to_dt(self.lang, txt))
video.published_time_text.as_ref().and_then(|txt| {
timeago::parse_timeago_dt_or_warn(self.lang, txt, &mut self.warnings)
})
}),
publish_date_txt: video.published_time_text,
view_count: video
@ -453,7 +452,7 @@ impl<T> YouTubeListMapper<T> {
}
}
fn map_short_video(&self, video: ReelItemRenderer) -> VideoItem {
fn map_short_video(&mut self, video: ReelItemRenderer) -> VideoItem {
static ACCESSIBILITY_SEP_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(" [-\u{2013}] (.+) [-\u{2013}] ").unwrap());
@ -476,16 +475,20 @@ impl<T> YouTubeListMapper<T> {
.flatten()
.and_then(|cap| {
cap.get(1).and_then(|c| {
timeago::parse_timeago(self.lang, c.as_str())
.map(|ta| Duration::from(ta).whole_seconds() as u32)
timeago::parse_timeago_or_warn(
self.lang,
c.as_str(),
&mut self.warnings,
)
.map(|ta| Duration::from(ta).whole_seconds() as u32)
})
})
}),
thumbnail: video.thumbnail.into(),
channel: self.channel.clone(),
publish_date: pub_date_txt
.as_ref()
.and_then(|txt| timeago::parse_timeago_to_dt(self.lang, txt)),
publish_date: pub_date_txt.as_ref().and_then(|txt| {
timeago::parse_timeago_dt_or_warn(self.lang, txt, &mut self.warnings)
}),
publish_date_txt: pub_date_txt,
view_count: video
.view_count_text
@ -526,19 +529,27 @@ impl<T> YouTubeListMapper<T> {
}
}
fn map_channel(channel: ChannelRenderer) -> ChannelItem {
fn map_channel(&mut self, channel: ChannelRenderer) -> ChannelItem {
// channel handle instead of subscriber count (A/B test 3)
let (sc_txt, vc_text) = match channel
.subscriber_count_text
.as_ref()
.map(|txt| txt.starts_with('@'))
.unwrap_or_default()
{
true => (channel.video_count_text, None),
false => (channel.subscriber_count_text, channel.video_count_text),
};
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(),
subscriber_count: sc_txt
.and_then(|txt| util::parse_numeric_or_warn(&txt, &mut self.warnings)),
video_count: vc_text
.and_then(|txt| util::parse_numeric_or_warn(&txt, &mut self.warnings)),
short_description: channel.description_snippet,
}
}
@ -548,18 +559,20 @@ impl YouTubeListMapper<YouTubeItem> {
fn map_item(&mut self, item: YouTubeListItem) {
match item {
YouTubeListItem::VideoRenderer(video) => {
self.items.push(YouTubeItem::Video(self.map_video(video)));
let mapped = YouTubeItem::Video(self.map_video(video));
self.items.push(mapped);
}
YouTubeListItem::ReelItemRenderer(video) => {
self.items
.push(YouTubeItem::Video(self.map_short_video(video)));
let mapped = self.map_short_video(video);
self.items.push(YouTubeItem::Video(mapped));
}
YouTubeListItem::PlaylistRenderer(playlist) => {
let mapped = YouTubeItem::Playlist(self.map_playlist(playlist));
self.items.push(mapped);
}
YouTubeListItem::PlaylistRenderer(playlist) => self
.items
.push(YouTubeItem::Playlist(self.map_playlist(playlist))),
YouTubeListItem::ChannelRenderer(channel) => {
self.items
.push(YouTubeItem::Channel(Self::map_channel(channel)));
let mapped = YouTubeItem::Channel(self.map_channel(channel));
self.items.push(mapped);
}
YouTubeListItem::ContinuationItemRenderer {
continuation_endpoint,
@ -588,10 +601,12 @@ impl YouTubeListMapper<VideoItem> {
fn map_item(&mut self, item: YouTubeListItem) {
match item {
YouTubeListItem::VideoRenderer(video) => {
self.items.push(self.map_video(video));
let mapped = self.map_video(video);
self.items.push(mapped);
}
YouTubeListItem::ReelItemRenderer(video) => {
self.items.push(self.map_short_video(video));
let mapped = self.map_short_video(video);
self.items.push(mapped);
}
YouTubeListItem::ContinuationItemRenderer {
continuation_endpoint,
@ -620,7 +635,8 @@ impl YouTubeListMapper<PlaylistItem> {
fn map_item(&mut self, item: YouTubeListItem) {
match item {
YouTubeListItem::PlaylistRenderer(playlist) => {
self.items.push(self.map_playlist(playlist))
let mapped = self.map_playlist(playlist);
self.items.push(mapped)
}
YouTubeListItem::ContinuationItemRenderer {
continuation_endpoint,

View file

@ -138,7 +138,8 @@ mod tests {
#[rstest]
#[case::default("default")]
#[case::playlists("playlists")]
#[case::playlists("empty")]
#[case::empty("empty")]
#[case::ab3_channel_handles("20221121_AB3_channel_handles")]
fn t_map_search(#[case] name: &str) {
let filename = format!("testfiles/search/{}.json", name);
let json_path = Path::new(&filename);

View file

@ -0,0 +1,415 @@
---
source: src/client/search.rs
expression: map_res.c
---
SearchResult(
items: Paginator(
count: Some(476743),
items: [
Channel(ChannelItem(
id: "UCMwePVHRpDdfeUcwtDZu2Dw",
name: "Monstafluff Music",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/ytc/AMLnZu9YhTzdAoL6P4PYq51PCF076ITDrgLitxSDPqv6sw=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/ytc/AMLnZu9YhTzdAoL6P4PYq51PCF076ITDrgLitxSDPqv6sw=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(582),
video_count: None,
short_description: "Music Submissions: https://monstafluff.edmdistrict.com/",
)),
Channel(ChannelItem(
id: "UCLxAS02eWvfZK4icRNzWD_g",
name: "Music Travel Love",
avatar: [
Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu9njNDLU_VtFjfGUaTArBp4AJFhJIxb_CxP7knf3A=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu9njNDLU_VtFjfGUaTArBp4AJFhJIxb_CxP7knf3A=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Artist,
subscriber_count: Some(403),
video_count: None,
short_description: "Welcome to the official Music Travel Love YouTube channel! We travel the world making music, friends, videos and memories!",
)),
Channel(ChannelItem(
id: "UCxKxjNPyL9UO5LRWHzp5JxA",
name: "Black&White Music",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/FDjW2-Cb6tFbtNv02D1UX4XtvP7P3eEWB93hGimeP4pb2TadVhAgxSVMZLZDp5NiBWGLT5eprA=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/FDjW2-Cb6tFbtNv02D1UX4XtvP7P3eEWB93hGimeP4pb2TadVhAgxSVMZLZDp5NiBWGLT5eprA=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(167),
video_count: None,
short_description: "MUSIC IN HARMONY WITH YOUR LIFE!!! If any producer, label, artist or photographer has an issue with any of the music or\u{a0}...",
)),
Channel(ChannelItem(
id: "UCGIygiYkKxn7g7fFNFdXskg",
name: "HAEVN MUSIC",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/EYlGIfqhvwtfkCyi5vpqfY_kDHr6L3OeCmkudNiAyhvz6UCnTZQOQaM-8PelFDGofdIqeF7Mb4E=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/EYlGIfqhvwtfkCyi5vpqfY_kDHr6L3OeCmkudNiAyhvz6UCnTZQOQaM-8PelFDGofdIqeF7Mb4E=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Artist,
subscriber_count: Some(411),
video_count: None,
short_description: "The official YouTube channel of HAEVN Music. Receiving a piano from his grandfather had a great impact on Jorrit\'s life.",
)),
Channel(ChannelItem(
id: "UClvNJkDHdc1gvFGN_Fr_qPw",
name: "Artemis Music",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/rGXIwYAhI49rKBQmw_pKFMv9yEt4euHnmXOE0OOCD6ApdQXGnuPmEv7TK7cDjrjt0rUXYHuw=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/rGXIwYAhI49rKBQmw_pKFMv9yEt4euHnmXOE0OOCD6ApdQXGnuPmEv7TK7cDjrjt0rUXYHuw=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: None,
subscriber_count: Some(312),
video_count: None,
short_description: "Hello and welcome to \"Artemis Music\"! Music can play an effective role in helping us lead a better and more productive life.",
)),
Channel(ChannelItem(
id: "UC5r3j8tQsB3MYZiwQFGKrdA",
name: "Disco Music",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/5nqhAdf26KoSKbfUB8kvhJo6rpMQw3XS345h8ZNmeXScqlB1KjJAM0T371r3QcS1mA1LZg9B1Po=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/5nqhAdf26KoSKbfUB8kvhJo6rpMQw3XS345h8ZNmeXScqlB1KjJAM0T371r3QcS1mA1LZg9B1Po=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(372),
video_count: None,
short_description: "Music is the only language in which you cannot say a mean or sarcastic thing. Have fun listening to music.",
)),
Channel(ChannelItem(
id: "UCNZYpcqym8gHcNg2GWcC6nQ",
name: "S!X - Music",
avatar: [
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu_1NOzbZUJWZjtmD4NTsb9BR-TNIAzNoajv0TisvQ=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu_1NOzbZUJWZjtmD4NTsb9BR-TNIAzNoajv0TisvQ=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(178),
video_count: None,
short_description: "S!X - Music is an independent Hip-Hop label. Soundcloud : https://soundcloud.com/s1xmusic Facebook\u{a0}...",
)),
Channel(ChannelItem(
id: "UCoEryX-WO7IHBGqTAC5r9Zw",
name: "Shake Music",
avatar: [
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu9fMXUALsloNUJ_wLpqCS0ovprvc5W-XwfrpmWqIw=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu9fMXUALsloNUJ_wLpqCS0ovprvc5W-XwfrpmWqIw=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(104),
video_count: None,
short_description: "Welcome to Shake Music, a Trap & Bass Channel / Record Label dedicated to bringing you the best tracks. All tracks on Shake\u{a0}...",
)),
Channel(ChannelItem(
id: "UCTJ9Qg-1vBu2pP_YrWUfGnQ",
name: "Miracle Music",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/3RMarDSmUSIexCXWCpMUkqV64uiHDXTidBLwsObHstx5-AbB8h_n8Zy1W9JymURd7ivzlDEGFw=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/3RMarDSmUSIexCXWCpMUkqV64uiHDXTidBLwsObHstx5-AbB8h_n8Zy1W9JymURd7ivzlDEGFw=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(822),
video_count: None,
short_description: "Welcome to Miracle Music! On this channel you will find a wide variety of different Deep House, Tropical House, Chill Out, EDM,.",
)),
Channel(ChannelItem(
id: "UCp6_KuNhT0kcFk-jXw9Tivg",
name: "Magic Music",
avatar: [
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu-fgSc_lceD4fRL_y0b3MKd2k54DF-laDAR3Avbuw=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu-fgSc_lceD4fRL_y0b3MKd2k54DF-laDAR3Avbuw=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(462),
video_count: None,
short_description: "",
)),
Channel(ChannelItem(
id: "UCe55Gy-hFDvLZp8C8BZhBnw",
name: "Nightblue Music",
avatar: [
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu-29SYt5qpqMP9Xi2A98mqL8ymI5Lg7Vzx-qpY09w=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu-29SYt5qpqMP9Xi2A98mqL8ymI5Lg7Vzx-qpY09w=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(105),
video_count: None,
short_description: "BRINGING YOU ONLY THE BEST EDM - TRAP Submit your own track for promotion here:\u{a0}...",
)),
Channel(ChannelItem(
id: "UC2fVSthyWxWSjsiEAHPzriQ",
name: "Mr_MoMo Music",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/7YG4jSrhx_Mfi2TsV0rJFlFARaR8kl7ilcIyzs6gSeNjwn-J88DvDWD8PSNd5o03qJRzpvhs=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/7YG4jSrhx_Mfi2TsV0rJFlFARaR8kl7ilcIyzs6gSeNjwn-J88DvDWD8PSNd5o03qJRzpvhs=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(709),
video_count: None,
short_description: "Hey there! I am Mr MoMo My channel focus on Japan music, lofi, trap & bass type beat and Japanese instrumental. I mindfully\u{a0}...",
)),
Channel(ChannelItem(
id: "UCN31w7dRjjz8CeP0GfSIo8A",
name: "Danit Music Official",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/ytc/AMLnZu9rUKtDsY-aSoE5WEwAQxvQTXiuAPYMBoJQ2mYTUA=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/ytc/AMLnZu9rUKtDsY-aSoE5WEwAQxvQTXiuAPYMBoJQ2mYTUA=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: None,
subscriber_count: Some(544),
video_count: None,
short_description: "",
)),
Channel(ChannelItem(
id: "UCpEHWiTMk1eEBAdzBnAb3rA",
name: "Energy Transformation Relaxing Music ",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/RR7upyAvT7N0_qlZWfLlDSRPhLufX4W4X6-qahWvuvDCLn2cWCs0yh_HXB2iwGbk_MTwSqwWEQ=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/RR7upyAvT7N0_qlZWfLlDSRPhLufX4W4X6-qahWvuvDCLn2cWCs0yh_HXB2iwGbk_MTwSqwWEQ=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: None,
subscriber_count: Some(359),
video_count: None,
short_description: "Welcome to our Energy Transformation Relaxing Music . This chakra music channel will focus on developing the best chakra\u{a0}...",
)),
Channel(ChannelItem(
id: "UCqswUMaC5yWUrkQszr8fuBA",
name: "Nonstop Music",
avatar: [
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu9vLN62RxNbnpa20r5XreWRlVjHXbHf7BMcvSBxoQ=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu9vLN62RxNbnpa20r5XreWRlVjHXbHf7BMcvSBxoQ=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(416),
video_count: None,
short_description: "Nonstop Music - Home of 1h videos of your favourite songs and mixes. Nonstop Genres: Pop • Chillout • Tropical House • Deep\u{a0}...",
)),
Channel(ChannelItem(
id: "UChO8h2G8UjOVc081rgYU8XQ",
name: "Vibe Music",
avatar: [
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu9Br5pt87kuDLRFbh1MqMXeFlCLbUrwFlDIzU4s=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu9Br5pt87kuDLRFbh1MqMXeFlCLbUrwFlDIzU4s=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: Verified,
subscriber_count: Some(3),
video_count: None,
short_description: "Vibe Music strives to bring the best lyric videos of popular Rap & Hip Hop songs. Be sure to Subscribe to see new videos we\u{a0}...",
)),
Channel(ChannelItem(
id: "UClV8b2EhIhIASKw-etzegyw",
name: "Suits Music",
avatar: [
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu9Aj5RtZZMdK_B_YD-8rOfi9c5ddFw5t1s4GYEeOQ=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu9Aj5RtZZMdK_B_YD-8rOfi9c5ddFw5t1s4GYEeOQ=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: None,
subscriber_count: Some(120),
video_count: None,
short_description: "",
)),
Channel(ChannelItem(
id: "UCI2hwz3r5phXpOtViIA5inA",
name: "Rock Music Collection",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/kB4gWvROUIWFuJN8xwIqmPl1QV2_gXMat6COAJjXZT07E3xomc4b2JwGtDg05t1MmhgqImSifhc=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/kB4gWvROUIWFuJN8xwIqmPl1QV2_gXMat6COAJjXZT07E3xomc4b2JwGtDg05t1MmhgqImSifhc=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: None,
subscriber_count: Some(817),
video_count: None,
short_description: "",
)),
Channel(ChannelItem(
id: "UC9w8My3S7h-bQZ-4R-0ZPsw",
name: "Helios Music",
avatar: [
Thumbnail(
url: "//yt3.ggpht.com/bi08T8zuYI1PlbM8M5fyZzjVvNJRJFFcQoonRQvS30opJ-OqGIq5OPrZ19qga29PIAit7OO3=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.ggpht.com/bi08T8zuYI1PlbM8M5fyZzjVvNJRJFFcQoonRQvS30opJ-OqGIq5OPrZ19qga29PIAit7OO3=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: None,
subscriber_count: Some(53),
video_count: None,
short_description: "Welcome to my channel - Helios Music. I created this channel to help people have the most relaxing, refreshing and comfortable\u{a0}...",
)),
Channel(ChannelItem(
id: "UC_ODKC5gTs2LvdHXDRdDm0w",
name: "Music On",
avatar: [
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu8lUOYw4RdRwQf2Kz8RCExSmuWC78oetXF7VL67SA=s88-c-k-c0x00ffffff-no-rj-mo",
width: 88,
height: 88,
),
Thumbnail(
url: "//yt3.googleusercontent.com/ytc/AMLnZu8lUOYw4RdRwQf2Kz8RCExSmuWC78oetXF7VL67SA=s176-c-k-c0x00ffffff-no-rj-mo",
width: 176,
height: 176,
),
],
verification: None,
subscriber_count: Some(129),
video_count: None,
short_description: "Music On (UNOFFICIAL CHANNEL)",
)),
],
ctoken: Some("Eu4FEgVtdXNpYxrkBUVnSVFBa2dVZ2dFWVZVTk5kMlZRVmtoU2NFUmtabVZWWTNkMFJGcDFNa1IzZ2dFWVZVTk1lRUZUTURKbFYzWm1Xa3MwYVdOU1RucFhSRjluZ2dFWVZVTjRTM2hxVGxCNVREbFZUelZNVWxkSWVuQTFTbmhCZ2dFWVZVTkhTWGxuYVZsclMzaHVOMmMzWmtaT1JtUlljMnRuZ2dFWVZVTnNkazVLYTBSSVpHTXhaM1pHUjA1ZlJuSmZjVkIzZ2dFWVZVTTFjak5xT0hSUmMwSXpUVmxhYVhkUlJrZExjbVJCZ2dFWVZVTk9XbGx3WTNGNWJUaG5TR05PWnpKSFYyTkRObTVSZ2dFWVZVTnZSWEo1V0MxWFR6ZEpTRUpIY1ZSQlF6VnlPVnAzZ2dFWVZVTlVTamxSWnkweGRrSjFNbkJRWDFseVYxVm1SMjVSZ2dFWVZVTndObDlMZFU1b1ZEQnJZMFpyTFdwWWR6bFVhWFpuZ2dFWVZVTmxOVFZIZVMxb1JrUjJURnB3T0VNNFFscG9RbTUzZ2dFWVZVTXlabFpUZEdoNVYzaFhVMnB6YVVWQlNGQjZjbWxSZ2dFWVZVTk9NekYzTjJSU2FtcDZPRU5sVURCSFpsTkpiemhCZ2dFWVZVTndSVWhYYVZSTmF6RmxSVUpCWkhwQ2JrRmlNM0pCZ2dFWVZVTnhjM2RWVFdGRE5YbFhWWEpyVVhONmNqaG1kVUpCZ2dFWVZVTm9UemhvTWtjNFZXcFBWbU13T0RGeVoxbFZPRmhSZ2dFWVZVTnNWamhpTWtWb1NXaEpRVk5MZHkxbGRIcGxaM2wzZ2dFWVZVTkpNbWgzZWpOeU5YQm9XSEJQZEZacFNVRTFhVzVCZ2dFWVZVTTVkemhOZVROVE4yZ3RZbEZhTFRSU0xUQmFVSE4zZ2dFWVZVTmZUMFJMUXpWblZITXlUSFprU0ZoRVVtUkViVEIzc2dFR0NnUUlGUkFDGIHg6BgiC3NlYXJjaC1mZWVk"),
endpoint: search,
),
corrected_query: None,
visitor_data: None,
)

View file

@ -23,7 +23,7 @@ SearchResult(
],
verification: Verified,
subscriber_count: Some(292),
video_count: 219,
video_count: Some(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}...",
)),
Video(VideoItem(

View file

@ -946,7 +946,7 @@ pub struct ChannelItem {
/// [`None`] if hidden by the owner or not present.
pub subscriber_count: Option<u64>,
/// Number of videos from the channel
pub video_count: u64,
pub video_count: Option<u64>,
/// Abbreviated channel description
pub short_description: String,
}

View file

@ -192,6 +192,30 @@ pub fn parse_timeago_to_dt(lang: Language, textual_date: &str) -> Option<OffsetD
parse_timeago(lang, textual_date).map(|ta| ta.into())
}
pub(crate) fn parse_timeago_or_warn(
lang: Language,
textual_date: &str,
warnings: &mut Vec<String>,
) -> Option<TimeAgo> {
let res = parse_timeago(lang, textual_date);
if res.is_none() {
warnings.push(format!("could not parse timeago `{}`", textual_date));
}
res
}
pub(crate) fn parse_timeago_dt_or_warn(
lang: Language,
textual_date: &str,
warnings: &mut Vec<String>,
) -> Option<OffsetDateTime> {
let res = parse_timeago_to_dt(lang, textual_date);
if res.is_none() {
warnings.push(format!("could not parse timeago `{}`", textual_date));
}
res
}
/// Parse a textual date (e.g. "29 minutes ago" or "Jul 2, 2014") into a ParsedDate object.
///
/// Returns None if the date could not be parsed.
@ -254,7 +278,7 @@ pub(crate) fn parse_textual_date_or_warn(
) -> Option<OffsetDateTime> {
let res = parse_textual_date_to_dt(lang, textual_date);
if res.is_none() {
warnings.push(format!("could not parse timeago `{}`", textual_date));
warnings.push(format!("could not parse textual date `{}`", textual_date));
}
res
}