feat!: update channel model, addd handle + video_count, remove tv/mobile banner

This commit is contained in:
ThetaDev 2024-08-17 02:44:47 +02:00
parent 5a6b2c3a62
commit e6715700d9
No known key found for this signature in database
GPG key ID: E319D3C5148D65B6
23 changed files with 114 additions and 619 deletions

View file

@ -911,9 +911,10 @@ async fn run() -> anyhow::Result<()> {
Some(format) => print_data(&channel, format, pretty), Some(format) => print_data(&channel, format, pretty),
None => { None => {
anstream::print!( anstream::print!(
"{}\n{} [{}]", "{}\n{} {} [{}]",
format!("[Channel {tab:?}]").on_green().black(), format!("[Channel {tab:?}]").on_green().black(),
channel.name.green().bold(), channel.name.green().bold(),
channel.handle.unwrap_or_default(),
channel.id channel.id
); );
print_verification(channel.verification); print_verification(channel.verification);
@ -925,6 +926,9 @@ async fn run() -> anyhow::Result<()> {
subs subs
); );
} }
if let Some(vids) = channel.video_count {
anstream::println!("{} {}", "Videos:".blue(), vids);
}
print_description(Some(channel.description)); print_description(Some(channel.description));
println!(); println!();
print_entities(&channel.content.items); print_entities(&channel.content.items);
@ -938,9 +942,10 @@ async fn run() -> anyhow::Result<()> {
Some(format) => print_data(&channel, format, pretty), Some(format) => print_data(&channel, format, pretty),
None => { None => {
anstream::println!( anstream::println!(
"{}\n{} [{}]", "{}\n{} {} [{}]",
format!("[Channel {tab:?}]").on_green().black(), format!("[Channel {tab:?}]").on_green().black(),
channel.name.green().bold(), channel.name.green().bold(),
channel.handle.unwrap_or_default(),
channel.id channel.id
); );
print_description(Some(channel.description)); print_description(Some(channel.description));
@ -951,6 +956,9 @@ async fn run() -> anyhow::Result<()> {
subs subs
); );
} }
if let Some(vids) = channel.video_count {
anstream::println!("{} {}", "Videos:".blue(), vids);
}
println!(); println!();
print_entities(&channel.content.items); print_entities(&channel.content.items);
} }
@ -988,6 +996,9 @@ async fn run() -> anyhow::Result<()> {
created created
); );
} }
if let Some(country) = info.country {
anstream::println!("{} {}", "Country:".blue(), country);
}
if !info.links.is_empty() { if !info.links.is_empty() {
print_h2("Links"); print_h2("Links");
for (name, url) in &info.links { for (name, url) in &info.links {

View file

@ -327,7 +327,7 @@ pub async fn channel_page_header(rp: &RustyPipeQuery) -> Result<bool> {
let channel = rp let channel = rp
.channel_videos_tab("UCh8gHdtzO2tXd593_bjErWg", ChannelVideoTab::Shorts) .channel_videos_tab("UCh8gHdtzO2tXd593_bjErWg", ChannelVideoTab::Shorts)
.await?; .await?;
Ok(channel.mobile_banner.is_empty() && channel.tv_banner.is_empty()) Ok(channel.video_count.is_some())
} }
pub async fn music_playlist_two_column(rp: &RustyPipeQuery) -> Result<bool> { pub async fn music_playlist_two_column(rp: &RustyPipeQuery) -> Result<bool> {

View file

@ -158,7 +158,7 @@ impl DownloadVideo {
channel_id: video.channel_id().map(str::to_owned), channel_id: video.channel_id().map(str::to_owned),
channel_name: video channel_name: video
.channel_name() .channel_name()
.map(|n| n.strip_suffix(" - Topic").unwrap_or(n).to_owned()), .map(|n| n.strip_suffix("- Topic").unwrap_or(n).trim().to_owned()),
album_id: None, album_id: None,
album_name: None, album_name: None,
track_nr: None, track_nr: None,

View file

@ -353,18 +353,6 @@ impl MapResponse<ChannelInfo> for response::ChannelAbout {
} }
} }
fn map_vanity_url(url: &str, id: &str) -> Option<String> {
if url.contains(id) {
return None;
}
Url::parse(url).ok().map(|mut parsed_url| {
// The vanity URL from YouTube is http for some reason
_ = parsed_url.set_scheme("https");
parsed_url.to_string()
})
}
struct MapChannelData { struct MapChannelData {
header: Option<response::channel::Header>, header: Option<response::channel::Header>,
metadata: Option<response::channel::Metadata>, metadata: Option<response::channel::Metadata>,
@ -401,10 +389,16 @@ fn map_channel(
))); )));
} }
let vanity_url = metadata let handle = metadata
.vanity_channel_url .vanity_channel_url
.as_ref() .as_ref()
.and_then(|url| map_vanity_url(url, ctx.id)); .and_then(|url| Url::parse(url).ok())
.and_then(|url| {
url.path()
.strip_prefix('/')
.filter(|handle| util::CHANNEL_HANDLE_REGEX.is_match(handle))
.map(str::to_owned)
});
let mut warnings = Vec::new(); let mut warnings = Vec::new();
Ok(MapResult { Ok(MapResult {
@ -412,17 +406,16 @@ fn map_channel(
response::channel::Header::C4TabbedHeaderRenderer(header) => Channel { response::channel::Header::C4TabbedHeaderRenderer(header) => Channel {
id: metadata.external_id, id: metadata.external_id,
name: metadata.title, name: metadata.title,
handle,
subscriber_count: header.subscriber_count_text.and_then(|txt| { subscriber_count: header.subscriber_count_text.and_then(|txt| {
util::parse_large_numstr_or_warn(&txt, ctx.lang, &mut warnings) util::parse_large_numstr_or_warn(&txt, ctx.lang, &mut warnings)
}), }),
video_count: None,
avatar: header.avatar.into(), avatar: header.avatar.into(),
verification: header.badges.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,
banner: header.banner.into(), banner: header.banner.into(),
mobile_banner: header.mobile_banner.into(),
tv_banner: header.tv_banner.into(),
has_shorts: d.has_shorts, has_shorts: d.has_shorts,
has_live: d.has_live, has_live: d.has_live,
visitor_data: d.visitor_data, visitor_data: d.visitor_data,
@ -443,21 +436,20 @@ fn map_channel(
Channel { Channel {
id: metadata.external_id, id: metadata.external_id,
name: metadata.title, name: metadata.title,
handle,
subscriber_count: hdata.as_ref().and_then(|hdata| { subscriber_count: hdata.as_ref().and_then(|hdata| {
hdata.0.as_ref().and_then(|txt| { hdata.0.as_ref().and_then(|txt| {
util::parse_large_numstr_or_warn(txt, ctx.lang, &mut warnings) util::parse_large_numstr_or_warn(txt, ctx.lang, &mut warnings)
}) })
}), }),
video_count: None,
avatar: hdata.map(|hdata| hdata.1.into()).unwrap_or_default(), avatar: hdata.map(|hdata| hdata.1.into()).unwrap_or_default(),
// Since the carousel header is only used for YT-internal channels or special events // Since the carousel header is only used for YT-internal channels or special events
// (World Cup, Coachella, etc.) we can assume the channel to be verified // (World Cup, Coachella, etc.) we can assume the channel to be verified
verification: crate::model::Verification::Verified, verification: crate::model::Verification::Verified,
description: metadata.description, description: metadata.description,
tags: microformat.microformat_data_renderer.tags, tags: microformat.microformat_data_renderer.tags,
vanity_url,
banner: Vec::new(), banner: Vec::new(),
mobile_banner: Vec::new(),
tv_banner: Vec::new(),
has_shorts: d.has_shorts, has_shorts: d.has_shorts,
has_live: d.has_live, has_live: d.has_live,
visitor_data: d.visitor_data, visitor_data: d.visitor_data,
@ -468,19 +460,33 @@ fn map_channel(
let hdata = header.content.page_header_view_model; let hdata = header.content.page_header_view_model;
// channel handle - subscriber count - video count // channel handle - subscriber count - video count
let md_rows = hdata.metadata.content_metadata_view_model.metadata_rows; let md_rows = hdata.metadata.content_metadata_view_model.metadata_rows;
let sub_part = if md_rows.len() > 1 { let (sub_part, vc_part) = if md_rows.len() > 1 {
md_rows.get(1).and_then(|md| md.metadata_parts.first()) let mp = &md_rows[1].metadata_parts;
(mp.first(), mp.get(1))
} else { } else {
md_rows.first().and_then(|md| md.metadata_parts.get(1)) (
md_rows.first().and_then(|md| md.metadata_parts.get(1)),
None,
)
}; };
let subscriber_count = sub_part.and_then(|t| { let subscriber_count = sub_part.and_then(|t| {
util::parse_large_numstr_or_warn::<u64>(&t.text, ctx.lang, &mut warnings) util::parse_large_numstr_or_warn::<u64>(&t.text, ctx.lang, &mut warnings)
}); });
let video_count =
vc_part.and_then(|t| util::parse_numeric_or_warn(&t.text, &mut warnings));
Channel { Channel {
id: metadata.external_id, id: metadata.external_id,
name: metadata.title, name: metadata.title,
handle: handle.or_else(|| {
md_rows
.first()
.and_then(|md| md.metadata_parts.get(1))
.map(|txt| txt.text.to_owned())
.filter(|txt| util::CHANNEL_HANDLE_REGEX.is_match(txt))
}),
subscriber_count, subscriber_count,
video_count,
avatar: hdata avatar: hdata
.image .image
.decorated_avatar_view_model .decorated_avatar_view_model
@ -491,10 +497,7 @@ fn map_channel(
verification: hdata.title.into(), verification: hdata.title.into(),
description: metadata.description, description: metadata.description,
tags: microformat.microformat_data_renderer.tags, tags: microformat.microformat_data_renderer.tags,
vanity_url,
banner: hdata.banner.image_banner_view_model.image.into(), banner: hdata.banner.image_banner_view_model.image.into(),
mobile_banner: Vec::new(),
tv_banner: Vec::new(),
has_shorts: d.has_shorts, has_shorts: d.has_shorts,
has_live: d.has_live, has_live: d.has_live,
visitor_data: d.visitor_data, visitor_data: d.visitor_data,
@ -604,15 +607,14 @@ fn combine_channel_data<T>(channel_data: Channel<()>, content: T) -> Channel<T>
Channel { Channel {
id: channel_data.id, id: channel_data.id,
name: channel_data.name, name: channel_data.name,
handle: channel_data.handle,
subscriber_count: channel_data.subscriber_count, subscriber_count: channel_data.subscriber_count,
video_count: channel_data.video_count,
avatar: channel_data.avatar, avatar: channel_data.avatar,
verification: channel_data.verification, verification: channel_data.verification,
description: channel_data.description, description: channel_data.description,
tags: channel_data.tags, tags: channel_data.tags,
vanity_url: channel_data.vanity_url,
banner: channel_data.banner, banner: channel_data.banner,
mobile_banner: channel_data.mobile_banner,
tv_banner: channel_data.tv_banner,
has_shorts: channel_data.has_shorts, has_shorts: channel_data.has_shorts,
has_live: channel_data.has_live, has_live: channel_data.has_live,
visitor_data: channel_data.visitor_data, visitor_data: channel_data.visitor_data,

View file

@ -95,11 +95,6 @@ pub(crate) struct HeaderRenderer {
pub badges: Vec<ChannelBadge>, pub badges: Vec<ChannelBadge>,
#[serde(default)] #[serde(default)]
pub banner: Thumbnails, pub banner: Thumbnails,
#[serde(default)]
pub mobile_banner: Thumbnails,
/// Fullscreen (16:9) channel banner
#[serde(default)]
pub tv_banner: Thumbnails,
} }
#[serde_as] #[serde_as]

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UC2DjFE7Xf11URZqWBigcVOQ", id: "UC2DjFE7Xf11URZqWBigcVOQ",
name: "EEVblog", name: "EEVblog",
handle: None,
subscriber_count: Some(884000), subscriber_count: Some(884000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj",
@ -55,7 +57,6 @@ Channel(
"dumpster diving", "dumpster diving",
"debunking", "debunking",
], ],
vanity_url: Some("https://www.youtube.com/c/EevblogDave"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -88,60 +89,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: false, has_shorts: false,
has_live: true, has_live: true,
visitor_data: None, visitor_data: None,

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UC2DjFE7Xf11URZqWBigcVOQ", id: "UC2DjFE7Xf11URZqWBigcVOQ",
name: "EEVblog", name: "EEVblog",
handle: None,
subscriber_count: Some(881000), subscriber_count: Some(881000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj",
@ -55,7 +57,6 @@ Channel(
"dumpster diving", "dumpster diving",
"debunking", "debunking",
], ],
vanity_url: Some("https://www.youtube.com/c/EevblogDave"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -88,60 +89,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: false, has_shorts: false,
has_live: false, has_live: false,
visitor_data: Some("CgttaWpyTVpUN1AyZyioqr2ZBg%3D%3D"), visitor_data: Some("CgttaWpyTVpUN1AyZyioqr2ZBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
handle: Some("@Doobydobap"),
subscriber_count: Some(3360000), subscriber_count: Some(3360000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.googleusercontent.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.googleusercontent.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s48-c-k-c0x00ffffff-no-rj",
@ -26,7 +28,6 @@ Channel(
verification: Verified, 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/@Doobydobap"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -59,60 +60,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: true, has_shorts: true,
has_live: false, has_live: false,
visitor_data: Some("CgtHU1dvWkR4cGRfdyjMpt6iBg%3D%3D"), visitor_data: Some("CgtHU1dvWkR4cGRfdyjMpt6iBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
handle: Some("@Doobydobap"),
subscriber_count: Some(3740000), subscriber_count: Some(3740000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.googleusercontent.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s72-c-k-c0x00ffffff-no-rj", url: "https://yt3.googleusercontent.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s72-c-k-c0x00ffffff-no-rj",
@ -26,7 +28,6 @@ Channel(
verification: Verified, 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/@Doobydobap"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.googleusercontent.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -59,8 +60,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [],
tv_banner: [],
has_shorts: true, has_shorts: true,
has_live: false, has_live: false,
visitor_data: None, visitor_data: None,

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
handle: None,
subscriber_count: Some(2930000), subscriber_count: Some(2930000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s48-c-k-c0x00ffffff-no-rj",
@ -26,7 +28,6 @@ Channel(
verification: Verified, 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"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -59,60 +60,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: true, has_shorts: true,
has_live: false, has_live: false,
visitor_data: Some("CgtQdE9zVVR3NVBDbyjz0ZKaBg%3D%3D"), visitor_data: Some("CgtQdE9zVVR3NVBDbyjz0ZKaBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UC2DjFE7Xf11URZqWBigcVOQ", id: "UC2DjFE7Xf11URZqWBigcVOQ",
name: "EEVblog", name: "EEVblog",
handle: None,
subscriber_count: Some(883000), subscriber_count: Some(883000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj",
@ -55,7 +57,6 @@ Channel(
"dumpster diving", "dumpster diving",
"debunking", "debunking",
], ],
vanity_url: Some("https://www.youtube.com/c/EevblogDave"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -88,60 +89,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: false, has_shorts: false,
has_live: true, has_live: true,
visitor_data: Some("Cgs4ZFVmMzVlU1dxbyiBqpeaBg%3D%3D"), visitor_data: Some("Cgs4ZFVmMzVlU1dxbyiBqpeaBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UCHF66aWLOxBW4l6VkSrS3cQ", id: "UCHF66aWLOxBW4l6VkSrS3cQ",
name: "Coachella", name: "Coachella",
handle: Some("@Coachella"),
subscriber_count: Some(2710000), subscriber_count: Some(2710000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "//yt3.googleusercontent.com/RDZ6VWFjHEMFm_QcmCCf-yG_UiGo9YWXEmVRuiHSC8SvP02dgeBEtAjd4CnEKGLo0V2gGdIRDQ=s88-c-k-c0x00ffffff-no-rj-mo", url: "//yt3.googleusercontent.com/RDZ6VWFjHEMFm_QcmCCf-yG_UiGo9YWXEmVRuiHSC8SvP02dgeBEtAjd4CnEKGLo0V2gGdIRDQ=s88-c-k-c0x00ffffff-no-rj-mo",
@ -31,10 +33,7 @@ Channel(
"indio", "indio",
"california", "california",
], ],
vanity_url: Some("https://www.youtube.com/@Coachella"),
banner: [], banner: [],
mobile_banner: [],
tv_banner: [],
has_shorts: true, has_shorts: true,
has_live: true, has_live: true,
visitor_data: Some("CgtjSUhDeVJ6SU5wNCj75uyhBg%3D%3D"), visitor_data: Some("CgtjSUhDeVJ6SU5wNCj75uyhBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UC2DjFE7Xf11URZqWBigcVOQ", id: "UC2DjFE7Xf11URZqWBigcVOQ",
name: "EEVblog", name: "EEVblog",
handle: Some("@EEVblog"),
subscriber_count: Some(933000), subscriber_count: Some(933000),
video_count: Some(19),
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.googleusercontent.com/ytc/AIdro_lagjGDfXbXlQXhznx3CDRitOBdxvebllQd_YP1ag=s72-c-k-c0x00ffffff-no-rj", url: "https://yt3.googleusercontent.com/ytc/AIdro_lagjGDfXbXlQXhznx3CDRitOBdxvebllQd_YP1ag=s72-c-k-c0x00ffffff-no-rj",
@ -55,7 +57,6 @@ Channel(
"dumpster diving", "dumpster diving",
"debunking", "debunking",
], ],
vanity_url: Some("https://www.youtube.com/@EEVblog"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.googleusercontent.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.googleusercontent.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -88,8 +89,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [],
tv_banner: [],
has_shorts: true, has_shorts: true,
has_live: true, has_live: true,
visitor_data: None, visitor_data: None,

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UC2DjFE7Xf11URZqWBigcVOQ", id: "UC2DjFE7Xf11URZqWBigcVOQ",
name: "EEVblog", name: "EEVblog",
handle: None,
subscriber_count: Some(880000), subscriber_count: Some(880000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj",
@ -55,7 +57,6 @@ Channel(
"dumpster diving", "dumpster diving",
"debunking", "debunking",
], ],
vanity_url: Some("https://www.youtube.com/c/EevblogDave"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -88,60 +89,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: false, has_shorts: false,
has_live: false, has_live: false,
visitor_data: Some("CgszNU5rbDVZS2hMcyim4K2ZBg%3D%3D"), visitor_data: Some("CgszNU5rbDVZS2hMcyim4K2ZBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UCxBa895m48H5idw5li7h-0g", id: "UCxBa895m48H5idw5li7h-0g",
name: "Sebastian Figurroa", name: "Sebastian Figurroa",
handle: None,
subscriber_count: None, subscriber_count: None,
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu_hsZ1XlUXHzXsGNHJw0np79WhWZcC4j8eFdy-tiUCDBKAjJyJOzE5kXFRiqL2S=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/ytc/AMLnZu_hsZ1XlUXHzXsGNHJw0np79WhWZcC4j8eFdy-tiUCDBKAjJyJOzE5kXFRiqL2S=s48-c-k-c0x00ffffff-no-rj",
@ -26,10 +28,7 @@ Channel(
verification: None, verification: None,
description: "", description: "",
tags: [], tags: [],
vanity_url: None,
banner: [], banner: [],
mobile_banner: [],
tv_banner: [],
has_shorts: false, has_shorts: false,
has_live: false, has_live: false,
visitor_data: Some("Cgtvc2s4UllvTGl6byigxseZBg%3D%3D"), visitor_data: Some("Cgtvc2s4UllvTGl6byigxseZBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UChs0pSaEoNLV4mevBFGaoKA", id: "UChs0pSaEoNLV4mevBFGaoKA",
name: "The Good Life Radio x Sensual Musique", name: "The Good Life Radio x Sensual Musique",
handle: None,
subscriber_count: Some(760000), subscriber_count: Some(760000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu_V9mOdHaorjNFqGXCecFeOBZhDWB8tVYG_I8gJwA=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/ytc/AMLnZu_V9mOdHaorjNFqGXCecFeOBZhDWB8tVYG_I8gJwA=s48-c-k-c0x00ffffff-no-rj",
@ -39,7 +41,6 @@ Channel(
"tropical house", "tropical house",
"house music", "house music",
], ],
vanity_url: Some("https://www.youtube.com/c/TheGoodLiferadio"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -72,60 +73,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: false, has_shorts: false,
has_live: false, has_live: false,
visitor_data: Some("CgtkYXJITElwYmd4OCj85a2ZBg%3D%3D"), visitor_data: Some("CgtkYXJITElwYmd4OCj85a2ZBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UC_vmjW5e1xEHhYjY2a0kK1A", id: "UC_vmjW5e1xEHhYjY2a0kK1A",
name: "Oonagh - Topic", name: "Oonagh - Topic",
handle: None,
subscriber_count: None, subscriber_count: None,
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/pqKv4iqSjmMKPxsMCeyklTbpROSyInGNR4XvD1DqKD0AlROlsHzvoAlTvtMTO1g1x2WxaQ2Enxw=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/pqKv4iqSjmMKPxsMCeyklTbpROSyInGNR4XvD1DqKD0AlROlsHzvoAlTvtMTO1g1x2WxaQ2Enxw=s48-c-k-c0x00ffffff-no-rj",
@ -26,7 +28,6 @@ Channel(
verification: None, verification: None,
description: "", description: "",
tags: [], tags: [],
vanity_url: None,
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -59,60 +60,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: false, has_shorts: false,
has_live: false, has_live: false,
visitor_data: Some("CgtCV1l2R2Rzb2ZSZyiu4a2ZBg%3D%3D"), visitor_data: Some("CgtCV1l2R2Rzb2ZSZyiu4a2ZBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UCh8gHdtzO2tXd593_bjErWg", id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap", name: "Doobydobap",
handle: None,
subscriber_count: Some(2840000), subscriber_count: Some(2840000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s48-c-k-c0x00ffffff-no-rj",
@ -26,7 +28,6 @@ Channel(
verification: Verified, 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"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -59,60 +60,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: false, has_shorts: false,
has_live: false, has_live: false,
visitor_data: Some("CgtneXVRbGtSMWtlYyj75a2ZBg%3D%3D"), visitor_data: Some("CgtneXVRbGtSMWtlYyj75a2ZBg%3D%3D"),

View file

@ -5,7 +5,9 @@ expression: map_res.c
Channel( Channel(
id: "UCcvfHa-GHSOHFAjU0-Ie57A", id: "UCcvfHa-GHSOHFAjU0-Ie57A",
name: "Adam Something", name: "Adam Something",
handle: None,
subscriber_count: Some(947000), subscriber_count: Some(947000),
video_count: None,
avatar: [ avatar: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/FzV47fzr2nc8_KOeUO2FSIH-daaxCZaPDGqrgC1_Qp0_zEn0DnKmi7PiMwcssTG4IEDL1XfdTIk=s48-c-k-c0x00ffffff-no-rj", url: "https://yt3.ggpht.com/FzV47fzr2nc8_KOeUO2FSIH-daaxCZaPDGqrgC1_Qp0_zEn0DnKmi7PiMwcssTG4IEDL1XfdTIk=s48-c-k-c0x00ffffff-no-rj",
@ -43,7 +45,6 @@ Channel(
"budapest", "budapest",
"eu", "eu",
], ],
vanity_url: Some("https://www.youtube.com/c/AdamSomething"),
banner: [ banner: [
Thumbnail( Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
@ -76,60 +77,6 @@ Channel(
height: 424, height: 424,
), ),
], ],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/Bk54VHh5FsxlwAAEltJp6rgx3VzBgxbi8naNngh5C4zQni1ijUhgTmVmDrE_I9M95SxtXTnd=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
has_shorts: false, has_shorts: false,
has_live: false, has_live: false,
visitor_data: Some("Cgs4Ri1tLW1KNWozNCjGk8yZBg%3D%3D"), visitor_data: Some("Cgs4Ri1tLW1KNWozNCjGk8yZBg%3D%3D"),

View file

@ -700,11 +700,15 @@ pub struct Channel<T> {
pub id: String, pub id: String,
/// Channel name /// Channel name
pub name: String, pub name: String,
/// YouTube channel handle (e.g. `@EEVblog`)
pub handle: Option<String>,
/// Channel subscriber count /// Channel subscriber count
/// ///
/// [`None`] if the subscriber count was hidden by the owner /// [`None`] if the subscriber count was hidden by the owner
/// or could not be parsed. /// or could not be parsed.
pub subscriber_count: Option<u64>, pub subscriber_count: Option<u64>,
/// Number of videos
pub video_count: Option<u64>,
/// Channel avatar / profile picture /// Channel avatar / profile picture
pub avatar: Vec<Thumbnail>, pub avatar: Vec<Thumbnail>,
/// Channel verification mark /// Channel verification mark
@ -713,15 +717,8 @@ pub struct Channel<T> {
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
pub tags: Vec<String>, pub tags: Vec<String>,
/// Custom URL set by the channel owner
/// (e.g. <https://www.youtube.com/c/EevblogDave>)
pub vanity_url: Option<String>,
/// Banner image shown above the channel /// Banner image shown above the channel
pub banner: Vec<Thumbnail>, pub banner: Vec<Thumbnail>,
/// Banner image shown above the channel (small format for mobile)
pub mobile_banner: Vec<Thumbnail>,
/// Banner image shown above the channel (16:9 fullscreen format for TV)
pub tv_banner: Vec<Thumbnail>,
/// Does the channel have a *Shorts* tab? /// Does the channel have a *Shorts* tab?
pub has_shorts: bool, pub has_shorts: bool,
/// Does the channel have a *Live* tab? /// Does the channel have a *Live* tab?

View file

@ -32,9 +32,10 @@ pub static PLAYLIST_ID_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^(?:PL|RD|OLAK|UU)[A-Za-z0-9_-]{5,50}$").unwrap()); Lazy::new(|| Regex::new(r"^(?:PL|RD|OLAK|UU)[A-Za-z0-9_-]{5,50}$").unwrap());
pub static ALBUM_ID_REGEX: Lazy<Regex> = pub static ALBUM_ID_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^MPREb_[A-Za-z0-9_-]{11}$").unwrap()); Lazy::new(|| Regex::new(r"^MPREb_[A-Za-z0-9_-]{11}$").unwrap());
pub static VANITY_PATH_REGEX: Lazy<Regex> = Lazy::new(|| { pub static VANITY_PATH_REGEX: Lazy<Regex> =
Regex::new(r"^/?(?:(?:c/|user/)?[A-z0-9]{1,100})|(?:@[A-z0-9-_.]{1,100})$").unwrap() Lazy::new(|| Regex::new(r"^/?(?:(?:c/|user/)?[A-z0-9]{1,100})|(?:@[\w\-\.·]{1,30})$").unwrap());
}); pub static CHANNEL_HANDLE_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r#"^@[\w\-\.·]{1,30}$"#).unwrap());
/// Separator string for YouTube Music subtitles /// Separator string for YouTube Music subtitles
pub const DOT_SEPARATOR: &str = ""; pub const DOT_SEPARATOR: &str = "";

View file

@ -11,7 +11,10 @@
//! - The validation functions of this module are meant vor validating specific data (video IDs, //! - The validation functions of this module are meant vor validating specific data (video IDs,
//! channel IDs, playlist IDs) and return [`true`] if the given input is valid //! channel IDs, playlist IDs) and return [`true`] if the given input is valid
use crate::{error::Error, util}; use crate::{
error::Error,
util::{self, CHANNEL_HANDLE_REGEX},
};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::Regex; use regex::Regex;
@ -202,6 +205,32 @@ pub fn track_lyrics_id<S: AsRef<str>>(lyrics_id: S) -> Result<(), Error> {
) )
} }
/// Validate the given channel handle
///
/// YouTube channel handles can be up to 30 characters long and start with an `@`.
/// Allowed characters are letters and numbers (Unicode), underscores (`_`), hyphens (`-`),
/// full stops (`.`) and middle dots (`· U+00B7`)
///
/// There are more fine-grained rules for specific scripts. Verifying these is not implemented.
///
/// Reference: <https://support.google.com/youtube/answer/11585688>
///
/// ```
/// # use rustypipe::validate;
/// assert!(validate::channel_handle("@EEVBlog").is_ok());
/// assert!(validate::channel_handle("@Āll·._-").is_ok());
/// assert!(validate::channel_handle("@한국").is_ok());
///
/// assert!(validate::channel_handle("noat").is_err());
/// assert!(validate::channel_handle("@no space").is_err());
/// ```
pub fn channel_handle<S: AsRef<str>>(channel_handle: S) -> Result<(), Error> {
check(
CHANNEL_HANDLE_REGEX.is_match(channel_handle.as_ref()),
"invalid channel handle",
)
}
fn check(res: bool, msg: &'static str) -> Result<(), Error> { fn check(res: bool, msg: &'static str) -> Result<(), Error> {
if res { if res {
Ok(()) Ok(())

View file

@ -885,16 +885,13 @@ async fn channel_shorts(rp: RustyPipe) {
// dbg!(&channel); // dbg!(&channel);
assert_eq!(channel.id, "UCh8gHdtzO2tXd593_bjErWg"); assert_eq!(channel.id, "UCh8gHdtzO2tXd593_bjErWg");
assert_eq!(channel.name, "Doobydobap"); assert_eq!(channel.name, "Doobydobap");
assert_eq!(channel.handle.as_deref(), Some("@Doobydobap"));
assert_gteo(channel.subscriber_count, 2_800_000, "subscribers"); assert_gteo(channel.subscriber_count, 2_800_000, "subscribers");
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.verification, Verification::Verified);
assert!(channel assert!(channel
.description .description
.contains("Hi, I\u{2019}m Tina, aka Doobydobap")); .contains("Hi, I\u{2019}m Tina, aka Doobydobap"));
assert_eq!(
channel.vanity_url.as_deref(),
Some("https://www.youtube.com/@Doobydobap")
);
assert!(!channel.banner.is_empty(), "got no banners"); assert!(!channel.banner.is_empty(), "got no banners");
assert!( assert!(
@ -994,15 +991,12 @@ async fn channel_search(rp: RustyPipe) {
fn assert_channel_eevblog<T>(channel: &Channel<T>) { fn assert_channel_eevblog<T>(channel: &Channel<T>) {
assert_eq!(channel.id, "UC2DjFE7Xf11URZqWBigcVOQ"); assert_eq!(channel.id, "UC2DjFE7Xf11URZqWBigcVOQ");
assert_eq!(channel.name, "EEVblog"); assert_eq!(channel.name, "EEVblog");
assert_eq!(channel.handle.as_deref(), Some("@EEVblog"));
assert_gteo(channel.subscriber_count, 880_000, "subscribers"); assert_gteo(channel.subscriber_count, 880_000, "subscribers");
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.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!(
channel.vanity_url.as_deref(),
Some("https://www.youtube.com/@EEVblog")
);
assert!(!channel.banner.is_empty(), "got no banners"); assert!(!channel.banner.is_empty(), "got no banners");
} }