use std::collections::HashMap; use crate::util::requester::Requester; #[derive(serde::Serialize, serde::Deserialize, Debug)] pub struct VideosRequest { //"versionInstallDate":"2025-06-03T18:20:20Z","languageCode":"en","appInstallDate":"2025-06-03T18:20:20Z","server":"spacemoehre","sexu pub clientHash: Option, // "a07b23c9b07813c65050e2a4041ca777", pub blockedKeywords: Option, // "kittens", pub countryCode: Option, // "DE", pub clientVersion: Option, // "2.1.4-22b", pub timestamp: Option, // "1748976686", pub blockedUploaders: Option, // "", pub anonId: Option, // "1AB8A060-A47D-47EF-B9CB-63980ED84C8A", pub debugTools: Option, // false, pub versionInstallDate: Option, // "2025-06-03T18:20:20Z", pub languageCode: Option, // "en", pub appInstallDate: Option, // "2025-06-03T18:20:20Z", pub server: Option, // "spacemoehre", pub sexuality: Option, // "straight", pub channel: Option, //"youtube", pub sort: Option, //"new", pub query: Option, //"kittens", pub page: Option, //1, pub perPage: Option, //10, // Your server's global options will be sent in the videos request // pub flavor: "mint chocolate chip" pub featured: Option, // "featured", pub category: Option, // "pmv" pub sites: Option, // pub filter: Option, // pub language: Option, // pub networks: Option, // pub stars: Option, // pub categories: Option, pub duration: Option, } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] pub struct ServerOptions { pub featured: Option, // "featured", pub category: Option, // "pmv" pub sites: Option, // pub filter: Option, pub language: Option, // "en" pub requester: Option, pub network: Option, // pub stars: Option, // pub categories: Option, // pub duration: Option, // pub sort: Option, // } #[derive(serde::Serialize, Debug)] pub struct PageInfo { pub hasNextPage: bool, // true, pub resultsPerPage: u32, // 10 } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] pub struct VideoEmbed { pub html: String, pub source: String, } impl VideoEmbed { pub fn new(html: String, source: String) -> Self { VideoEmbed { html, source } } } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] pub struct VideoItem { pub duration: u32, // 110, #[serde(skip_serializing_if = "Option::is_none")] pub views: Option, // 14622653, #[serde(skip_serializing_if = "Option::is_none")] pub rating: Option, // 0.0, pub id: String, // "c85017ca87477168d648727753c4ded8a35f173e22ef93743e707b296becb299", pub title: String, // "20 Minutes of Adorable Kittens BEST Compilation", pub url: String, // "https://www.youtube.com/watch?v=y0sF5xhGreA", pub channel: String, // "youtube", pub thumb: String, // "https://i.ytimg.com/vi/y0sF5xhGreA/hqdefault.jpg", #[serde(skip_serializing_if = "Option::is_none")] pub uploader: Option, // "The Pet Collective", #[serde(skip_serializing_if = "Option::is_none")] pub uploaderUrl: Option, // "https://www.youtube.com/@petcollective", #[serde(skip_serializing_if = "Option::is_none")] pub verified: Option, // false, #[serde(skip_serializing_if = "Option::is_none")] pub tags: Option>, // [], #[serde(skip_serializing_if = "Option::is_none")] pub uploadedAt: Option, // 1741142954 #[serde(skip_serializing_if = "Option::is_none")] pub formats: Option>, // Additional HTTP headers if needed #[serde(skip_serializing_if = "Option::is_none")] pub embed: Option, // Optional embed information #[serde(skip_serializing_if = "Option::is_none")] pub preview: Option, #[serde(skip_serializing_if = "Option::is_none")] pub aspectRatio: Option, } #[allow(dead_code)] impl VideoItem { pub fn new( id: String, title: String, url: String, channel: String, thumb: String, duration: u32, ) -> Self { VideoItem { duration: duration, // Placeholder, adjust as needed views: None, // Placeholder, adjust as needed rating: None, // Placeholder, adjust as needed id, title, url, channel, thumb, uploader: None, uploaderUrl: None, verified: None, tags: None, // Placeholder, adjust as needed uploadedAt: None, formats: None, // Placeholder for formats embed: None, // Placeholder for embed information preview: None, aspectRatio: None, } } pub fn tags(mut self, tags: Vec) -> Self { if tags.is_empty(){ return self; } self.tags = Some(tags); self } pub fn uploader(mut self, uploader: String) -> Self { self.uploader = Some(uploader); self } pub fn uploader_url(mut self, uploader_url: String) -> Self { self.uploaderUrl = Some(uploader_url); self } pub fn verified(mut self, verified: bool) -> Self { self.verified = Some(verified); self } pub fn views(mut self, views: u32) -> Self { self.views = Some(views); self } pub fn rating(mut self, rating: f32) -> Self { self.rating = Some(rating); self } pub fn uploaded_at(mut self, uploaded_at: u64) -> Self { self.uploadedAt = Some(uploaded_at); self } pub fn formats(mut self, formats: Vec) -> Self { if formats.is_empty(){ return self; } self.formats = Some(formats); self } pub fn add_format(mut self, format: VideoFormat) { if let Some(formats) = self.formats.as_mut() { formats.push(format); } else { self.formats = Some(vec![format]); } } pub fn embed(mut self, embed: VideoEmbed) -> Self { self.embed = Some(embed); self } pub fn preview(mut self, preview: String) -> Self { self.preview = Some(preview); self } pub fn aspect_ratio(mut self, aspect_ratio: f32) -> Self { self.aspectRatio = Some(aspect_ratio); self } } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] pub struct VideoFormat { pub url: String, quality: String, format: String, #[serde(skip_serializing_if = "Option::is_none")] format_id: Option, #[serde(skip_serializing_if = "Option::is_none")] format_note: Option, #[serde(skip_serializing_if = "Option::is_none")] filesize: Option, #[serde(skip_serializing_if = "Option::is_none")] asr: Option, #[serde(skip_serializing_if = "Option::is_none")] fps: Option, #[serde(skip_serializing_if = "Option::is_none")] width: Option, #[serde(skip_serializing_if = "Option::is_none")] height: Option, #[serde(skip_serializing_if = "Option::is_none")] tbr: Option, #[serde(skip_serializing_if = "Option::is_none")] language: Option, #[serde(skip_serializing_if = "Option::is_none")] language_preference: Option, #[serde(skip_serializing_if = "Option::is_none")] ext: Option, #[serde(skip_serializing_if = "Option::is_none")] vcodec: Option, #[serde(skip_serializing_if = "Option::is_none")] acodec: Option, #[serde(skip_serializing_if = "Option::is_none")] dynamic_range: Option, #[serde(skip_serializing_if = "Option::is_none")] abr: Option, #[serde(skip_serializing_if = "Option::is_none")] vbr: Option, #[serde(skip_serializing_if = "Option::is_none")] container: Option, #[serde(skip_serializing_if = "Option::is_none")] protocol: Option, #[serde(skip_serializing_if = "Option::is_none")] audio_ext: Option, #[serde(skip_serializing_if = "Option::is_none")] video_ext: Option, #[serde(skip_serializing_if = "Option::is_none")] resolution: Option, #[serde(skip_serializing_if = "Option::is_none")] http_headers: Option>, } impl VideoFormat { pub fn new(url: String, quality: String, format: String) -> Self { let _ = format; VideoFormat { url, quality, format: format, // Default format format_id: Some("mp4-1080".to_string()), format_note: None, filesize: None, asr: None, fps: None, width: None, height: None, tbr: None, language: None, language_preference: None, ext: Some("mp4".to_string()), vcodec: None, acodec: None, dynamic_range: None, abr: None, vbr: None, container: None, protocol: Some("m3u8_native".to_string()), audio_ext: Some("none".to_string()), video_ext: Some("mp4".to_string()), resolution: None, http_headers: None, } } pub fn add_http_header(&mut self, key: String, value: String) { if self.http_headers.is_none() { self.http_headers = Some(HashMap::new()); } if let Some(headers) = &mut self.http_headers { headers.insert(key, value); } } pub fn http_header(&mut self, key: String, value: String) -> Self { if self.http_headers.is_none() { self.http_headers = Some(HashMap::new()); } if let Some(headers) = &mut self.http_headers { headers.insert(key, value); } self.to_owned() } pub fn format_id(mut self, format_id: String) -> Self { self.format_id = Some(format_id); self } pub fn format_note(mut self, format_note: String) -> Self { self.format_note = Some(format_note); self } // pub fn filesize(mut self, filesize: u32) -> Self { // self.filesize = Some(filesize); // self // } // pub fn asr(mut self, asr: u32) -> Self { // self.asr = Some(asr); // self // } // pub fn fps(mut self, fps: u32) -> Self { // self.fps = Some(fps); // self // } // pub fn width(mut self, width: u32) -> Self { // self.width = Some(width); // self // } // pub fn height(mut self, height: u32) -> Self { // self.height = Some(height); // self // } // pub fn tbr(mut self, tbr: u32) -> Self { // self.tbr = Some(tbr); // self // } // pub fn language(mut self, language: String) -> Self { // self.language = Some(language); // self // } // pub fn language_preference(mut self, language_preference: u32) -> Self { // self.language_preference = Some(language_preference); // self // } // pub fn ext(mut self, ext: String) -> Self { // self.ext = Some(ext); // self // } // pub fn vcodec(mut self, vcodec: String) -> Self { // self.vcodec = Some(vcodec); // self // } // pub fn acodec(mut self, acodec: String) -> Self { // self.acodec = Some(acodec); // self // } // pub fn dynamic_range(mut self, dynamic_range: String) -> Self { // self.dynamic_range = Some(dynamic_range); // self // } // pub fn abr(mut self, abr: u32) -> Self { // self.abr = Some(abr); // self // } // pub fn vbr(mut self, vbr: u32) -> Self { // self.vbr = Some(vbr); // self // } // pub fn container(mut self, container: String) -> Self { // self.container = Some(container); // self // } // pub fn protocol(mut self, protocol: String) -> Self { // self.protocol = Some(protocol); // self // } // pub fn audio_ext(mut self, audio_ext: String) -> Self { // self.audio_ext = Some(audio_ext); // self // } // pub fn video_ext(mut self, video_ext: String) -> Self { // self.video_ext = Some(video_ext); // self // } // pub fn resolution(mut self, resolution: String) -> Self { // self.resolution = Some(resolution); // self // } // pub fn http_headers(mut self, http_headers: HashMap) -> Self { // self.http_headers = Some(http_headers); // self // } } #[derive(serde::Serialize, Debug)] pub struct Videos { pub pageInfo: PageInfo, pub items: Vec, }