feat: add number_tokens for parsing large nums to dictionary
This commit is contained in:
parent
67ae1eb21d
commit
5d19259a14
21 changed files with 5219 additions and 38 deletions
|
|
@ -72,7 +72,6 @@ impl MapResponse<ChannelVideos> for response::Channel {
|
|||
c: ChannelVideos {
|
||||
id: header.channel_id,
|
||||
name: header.title,
|
||||
subscriber_count_txt: header.subscriber_count_text,
|
||||
},
|
||||
warnings,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -82,12 +82,14 @@ pub struct HeaderRenderer {
|
|||
pub channel_id: String,
|
||||
/// Channel name
|
||||
pub title: String,
|
||||
/// Approximate subscriber count (e.g. `880K subscribers`), depends on language
|
||||
#[serde_as(as = "Text")]
|
||||
pub subscriber_count_text: String,
|
||||
/// Approximate subscriber count (e.g. `880K subscribers`), depends on language.
|
||||
///
|
||||
/// `None` if the subscriber count is hidden.
|
||||
#[serde_as(as = "Option<Text>")]
|
||||
pub subscriber_count_text: Option<String>,
|
||||
pub avatar: Thumbnails,
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub badges: Vec<ChannelBadge>,
|
||||
#[serde_as(as = "Option<VecSkipError<_>>")]
|
||||
pub badges: Option<Vec<ChannelBadge>>,
|
||||
pub banner: Thumbnails,
|
||||
pub mobile_banner: Thumbnails,
|
||||
/// Fullscreen (16:9) channel banner
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ pub struct GridVideoRenderer {
|
|||
pub published_time_text: Option<String>,
|
||||
#[serde_as(as = "Option<Text>")]
|
||||
pub view_count_text: Option<String>,
|
||||
/// Contains video length
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub thumbnail_overlays: Vec<TimeOverlay>,
|
||||
}
|
||||
|
|
@ -397,6 +398,10 @@ pub trait IsLive {
|
|||
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| {
|
||||
|
|
@ -404,3 +409,19 @@ impl IsLive for Vec<VideoBadge> {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1021
src/dictionary.rs
1021
src/dictionary.rs
File diff suppressed because it is too large
Load diff
|
|
@ -310,7 +310,7 @@ pub struct RecommendedVideo {
|
|||
pub publish_date_txt: Option<String>,
|
||||
/// View count
|
||||
///
|
||||
/// Is `None` if it could not be parsed
|
||||
/// `None` if it could not be extracted.
|
||||
pub view_count: Option<u64>,
|
||||
/// Is the video an active livestream?
|
||||
pub is_live: bool,
|
||||
|
|
@ -400,6 +400,43 @@ pub struct ChannelVideos {
|
|||
pub id: String,
|
||||
/// Channel name
|
||||
pub name: String,
|
||||
/// Textual subscriber count (e.g. `2.3M subscribers`), depends on language setting
|
||||
pub subscriber_count_txt: String,
|
||||
/*
|
||||
/// Channel subscriber count
|
||||
///
|
||||
/// `None` if the subscriber count was hidden by the owner
|
||||
/// or could not be parsed.
|
||||
pub subscriber_count: Option<u64>,
|
||||
pub videos: Paginator<ChannelVideo>,
|
||||
*/
|
||||
}
|
||||
|
||||
#[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.
|
||||
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
|
||||
///
|
||||
/// `None` if it could not be extracted.
|
||||
pub view_count: Option<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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ pub trait ToHtml {
|
|||
}
|
||||
|
||||
impl TextComponent {
|
||||
pub fn get_text<'a>(&'a self) -> &'a str {
|
||||
pub fn get_text(&self) -> &str {
|
||||
match self {
|
||||
TextComponent::Text(text) => text,
|
||||
TextComponent::Web { text, .. } => text,
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn t_testfile() {
|
||||
let json_path = Path::new("testfiles/date/timeago_samples.json");
|
||||
let json_path = Path::new("testfiles/dict/timeago_samples.json");
|
||||
|
||||
let expect = [
|
||||
TimeAgo {
|
||||
|
|
@ -430,7 +430,7 @@ mod tests {
|
|||
cases: BTreeMap<String, u8>,
|
||||
}
|
||||
|
||||
let json_path = Path::new("testfiles/date/timeago_table.json");
|
||||
let json_path = Path::new("testfiles/dict/timeago_table.json");
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
let timeago_table: TimeagoTable =
|
||||
serde_json::from_reader(BufReader::new(json_file)).unwrap();
|
||||
|
|
@ -477,7 +477,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn t_parse_date_samples() {
|
||||
let json_path = Path::new("testfiles/date/playlist_samples.json");
|
||||
let json_path = Path::new("testfiles/dict/playlist_samples.json");
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
let date_samples: BTreeMap<Language, BTreeMap<String, String>> =
|
||||
serde_json::from_reader(BufReader::new(json_file)).unwrap();
|
||||
|
|
|
|||
Reference in a new issue