157 lines
3.9 KiB
Rust
157 lines
3.9 KiB
Rust
use serde::Deserialize;
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct YoutubeChannel {
|
|
pub contents: ChannelContents,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct ChannelContents {
|
|
pub twoColumnBrowseResultsRenderer: TwoColumns,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct TwoColumns {
|
|
pub tabs: Vec<ChannelTab>
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct ChannelTab {
|
|
pub tabRenderer: Option<TabRenderer>
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct TabRenderer {
|
|
pub title: String,
|
|
pub endpoint: TabEndpoint,
|
|
pub content: Option<TabContent>
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct SectionListRenderer{
|
|
pub contents: Option<Vec<Content>>
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct Content {
|
|
pub itemSectionRenderer: Option<ItemSectionRenderer>
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct ItemSectionRenderer {
|
|
pub contents: Vec<ItemSectionContent>
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct ItemSectionContent {
|
|
pub gridRenderer: GridRenderer
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct GridRenderer {
|
|
pub items: Vec<GridItem>
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct GridItem {
|
|
pub lockupViewModel: LookUpViewModel
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct LookUpViewModel {
|
|
pub metadata: ModelMetadata
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct ModelMetadata {
|
|
pub lockupMetadataViewModel: LockupMetadataViewModel
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct LockupMetadataViewModel {
|
|
pub title: PlaylistTitle,
|
|
pub metadata: PlaylistMetadata,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct PlaylistMetadata {
|
|
pub contentMetadataViewModel: ContentMetadataViewModel
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct ContentMetadataViewModel {
|
|
pub metadataRows: Vec<MetadataRow>
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct MetadataRow {
|
|
pub metadataParts: Vec<PlaylistTitle>
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct PlaylistTitle {
|
|
pub content: Option<String>,
|
|
pub commandRuns: Option<Vec<CommandRun>>,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct CommandRun {
|
|
onTap: OnTap
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct OnTap {
|
|
innertubeCommand: InnertubeCommand
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct InnertubeCommand {
|
|
pub browseEndpoint: BrowseEndpoint,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct TabContent {
|
|
pub sectionListRenderer: SectionListRenderer
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct TabEndpoint {
|
|
pub browseEndpoint: BrowseEndpoint,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct BrowseEndpoint {
|
|
pub browseId: String,
|
|
pub params: Option<String>,
|
|
}
|
|
|
|
impl YoutubeChannel {
|
|
pub fn get_playlists_request_str(&self) -> Option<String> {
|
|
for tab in &self.contents.twoColumnBrowseResultsRenderer.tabs {
|
|
if let Some(t) = &tab.tabRenderer {
|
|
if t.title == String::from("Playlists") {
|
|
return Some(t.endpoint.browseEndpoint.params.as_ref().unwrap().clone());
|
|
}
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
pub fn get_playlists(&self) -> Vec<(String, String)> {
|
|
let mut arr = Vec::new();
|
|
for tab in &self.contents.twoColumnBrowseResultsRenderer.tabs {
|
|
if let Some(t) = &tab.tabRenderer {
|
|
if t.title == String::from("Playlists") {
|
|
for item in &t.content.as_ref().unwrap().sectionListRenderer.contents.as_ref().unwrap()[0].itemSectionRenderer.as_ref().unwrap().contents[0].gridRenderer.items {
|
|
let title = item.lockupViewModel.metadata.lockupMetadataViewModel.title.content.clone().unwrap_or("!".to_string());
|
|
println!("{:#?}", item.lockupViewModel.metadata.lockupMetadataViewModel.metadata.contentMetadataViewModel.metadataRows[1].metadataParts[0]);
|
|
let url = item.lockupViewModel.metadata.lockupMetadataViewModel.metadata.contentMetadataViewModel.metadataRows[1].metadataParts[0].commandRuns.as_ref().unwrap()[0].onTap.innertubeCommand.browseEndpoint.browseId.clone();
|
|
arr.push((title, url));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
arr
|
|
}
|
|
} |