diff --git a/src/providers/mod.rs b/src/providers/mod.rs index 8cef800..a08060e 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -685,6 +685,7 @@ pub fn requester_or_default( } } +#[allow(dead_code)] pub fn strip_url_scheme(url: &str) -> String { url.strip_prefix("https://") .or_else(|| url.strip_prefix("http://")) @@ -693,6 +694,7 @@ pub fn strip_url_scheme(url: &str) -> String { .to_string() } +#[allow(dead_code)] pub fn build_proxy_url(options: &ServerOptions, proxy: &str, target: &str) -> String { let target = target.trim_start_matches('/'); let base = options diff --git a/src/providers/redtube.rs b/src/providers/redtube.rs index 0e04f2a..4ed95ab 100644 --- a/src/providers/redtube.rs +++ b/src/providers/redtube.rs @@ -144,11 +144,99 @@ impl RedtubeProvider { Ok(video_items) } + fn extract_between<'a>(&self, text: &'a str, start: &str, end: &str) -> Option<&'a str> { + let start_idx = text.find(start)?; + let from = start_idx + start.len(); + let rest = &text[from..]; + let end_idx = rest.find(end)?; + Some(&rest[..end_idx]) + } + + fn parse_video_grid_items(&self, html: &str) -> Vec { + if !html.contains("videos_grid") { + return vec![]; + } + + let listing = html + .split("videos_grid") + .nth(1) + .unwrap_or_default() + .split("") + .next() + .unwrap_or_default(); + + let mut items: Vec = Vec::new(); + for li in listing.split("
  • ", "") + .unwrap_or_default() + .trim() + .to_string(); + let duration = parse_time_to_seconds(&raw_duration).unwrap_or(0) as u32; + + let views_str = self + .extract_between(li, "", "") + .unwrap_or_default() + .trim() + .to_string(); + let views = parse_abbreviated_number(&views_str).unwrap_or(0) as u32; + + let preview = self + .extract_between(li, "data-mediabook=\"", "\"") + .unwrap_or_default() + .replace("&", "&"); + + let video_url = format!("{}/{}", self.url, id); + let video_item = + VideoItem::new(id, title, video_url, "redtube".to_string(), thumb, duration) + .views(views) + .preview(preview); + items.push(video_item); + } + + items + } + fn get_video_items_from_html(&self, html: String) -> Vec { if html.is_empty() { println!("HTML is empty"); return vec![]; } + let card_items = self.parse_video_grid_items(&html); + if !card_items.is_empty() { + return card_items; + } + let mut items: Vec = Vec::new(); let video_listing_content = html .split("