youtube_api/src/objects.rs
alterwain d0422a7ad9 modified: Cargo.lock
modified:   Cargo.toml
	modified:   src/main.rs
	new file:   src/objects.rs
2025-02-25 15:26:22 +03:00

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
}
}