feat: add video details response model
- add paginator, impl for playlist items - small model refactor - add ignore_any deserializer - removed unnecessary clones in response mapping
This commit is contained in:
parent
17b6844eb0
commit
972288d810
32 changed files with 61791 additions and 5316 deletions
|
|
@ -1,21 +1,27 @@
|
|||
pub mod locale;
|
||||
mod ordering;
|
||||
mod paginator;
|
||||
pub mod stream_filter;
|
||||
|
||||
pub use locale::{Country, Language};
|
||||
pub use paginator::Paginator;
|
||||
|
||||
use std::ops::Range;
|
||||
|
||||
use chrono::{DateTime, Local};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/*
|
||||
#PLAYER
|
||||
*/
|
||||
|
||||
pub trait FileFormat {
|
||||
fn extension(&self) -> &str;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct VideoPlayer {
|
||||
pub info: VideoInfo,
|
||||
pub details: VideoPlayerDetails,
|
||||
pub video_streams: Vec<VideoStream>,
|
||||
pub video_only_streams: Vec<VideoStream>,
|
||||
pub audio_streams: Vec<AudioStream>,
|
||||
|
|
@ -23,28 +29,14 @@ pub struct VideoPlayer {
|
|||
pub expires_in_seconds: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Playlist {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub videos: Vec<Video>,
|
||||
pub n_videos: u32,
|
||||
pub ctoken: Option<String>,
|
||||
pub thumbnails: Vec<Thumbnail>,
|
||||
pub description: Option<String>,
|
||||
pub channel: Option<Channel>,
|
||||
pub last_update: Option<DateTime<Local>>,
|
||||
pub last_update_txt: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct VideoInfo {
|
||||
pub struct VideoPlayerDetails {
|
||||
pub id: String,
|
||||
pub title: String,
|
||||
pub description: Option<String>,
|
||||
pub length: u32,
|
||||
pub thumbnails: Vec<Thumbnail>,
|
||||
pub channel: Channel,
|
||||
pub channel: ChannelId,
|
||||
pub publish_date: Option<DateTime<Local>>,
|
||||
pub view_count: u64,
|
||||
pub keywords: Vec<String>,
|
||||
|
|
@ -182,17 +174,81 @@ pub struct Subtitle {
|
|||
pub auto_generated: bool,
|
||||
}
|
||||
|
||||
/*
|
||||
#PLAYLIST
|
||||
*/
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Playlist {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub videos: Paginator<PlaylistVideo>,
|
||||
pub n_videos: u32,
|
||||
pub thumbnails: Vec<Thumbnail>,
|
||||
pub description: Option<String>,
|
||||
pub channel: Option<ChannelId>,
|
||||
pub last_update: Option<DateTime<Local>>,
|
||||
pub last_update_txt: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Video {
|
||||
pub struct PlaylistVideo {
|
||||
pub id: String,
|
||||
pub title: String,
|
||||
pub length: u32,
|
||||
pub thumbnails: Vec<Thumbnail>,
|
||||
pub channel: Channel,
|
||||
pub channel: ChannelId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct ChannelId {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
/*
|
||||
#VIDEO DETAILS
|
||||
*/
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct VideoDetails {
|
||||
pub id: String,
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
/*
|
||||
@COMMENTS
|
||||
*/
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Channel {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub avatars: Vec<Thumbnail>,
|
||||
pub verified: bool,
|
||||
}
|
||||
|
||||
// TODO: impl popularity comparison
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Comment {
|
||||
/// Unique YouTube Comment-ID (e.g. `UgynScMrsqGSL8qvePl4AaABAg`)
|
||||
pub id: String,
|
||||
/// Comment text
|
||||
pub text: String,
|
||||
/// Comment author
|
||||
///
|
||||
/// There may be comments with missing authors (possibly deleted users?).
|
||||
pub author: Option<Channel>,
|
||||
/// Number of upvotes
|
||||
pub upvotes: u32,
|
||||
/// Number of replies
|
||||
pub n_replies: u32,
|
||||
/// Paginator to fetch comment replies
|
||||
pub replies: Paginator<Comment>,
|
||||
/// Is the comment from the channel owner?
|
||||
pub by_owner: bool,
|
||||
/// Has the channel owner pinned the comment to the top?
|
||||
pub pinned: bool,
|
||||
/// Has the channel owner marked the comment with a ❤️ ?
|
||||
pub hearted: bool,
|
||||
}
|
||||
|
|
|
|||
54
src/model/paginator.rs
Normal file
54
src/model/paginator.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
/// The paginator is a wrapper around a list of items that are fetched
|
||||
/// in pages from the YouTube API (e.g. playlist items,
|
||||
/// video recommendations or comments).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Paginator<T> {
|
||||
/*
|
||||
/// Total number of items if finite and known.
|
||||
///
|
||||
/// Note that this number may not be 100% accurate, as this is the
|
||||
/// number returned by the YouTube API at the initial fetch.
|
||||
///
|
||||
/// It is intended to be shown to the user (e.g. 1261 comments,
|
||||
/// 18 Videos) and for progress estimation.
|
||||
///
|
||||
/// Don't use this number to check if all items were fetched or for
|
||||
/// iterating over the items.
|
||||
pub count: Option<u32>,
|
||||
*/
|
||||
/// Content of the paginator
|
||||
pub items: Vec<T>,
|
||||
/// The continuation token is passed to the YouTube API to fetch
|
||||
/// more items.
|
||||
///
|
||||
/// If it is None, it means that no more items can be fetched.
|
||||
pub ctoken: Option<String>,
|
||||
}
|
||||
|
||||
impl<T> Default for Paginator<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
items: Vec::new(),
|
||||
ctoken: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Paginator<T> {
|
||||
/// Check if the paginator is exhausted, meaning that no more
|
||||
/// items can be fetched.
|
||||
///
|
||||
/// Equivalent to `paginator.ctoken.is_none()`.
|
||||
pub fn is_exhausted(&self) -> bool {
|
||||
self.ctoken.is_none()
|
||||
}
|
||||
|
||||
/// Check if the paginator does not contain any data, meaning that it
|
||||
/// is exhausted and does not contain any items.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.items.is_empty() && self.is_exhausted()
|
||||
}
|
||||
}
|
||||
Reference in a new issue