doodstream and lulustream in sxyprn integrated

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Simon
2026-05-06 11:17:25 +00:00
committed by ForgeCode
parent 9e8f326518
commit 5e5786010a
7 changed files with 234 additions and 51 deletions

View File

@@ -7,6 +7,7 @@ use crate::util::discord::format_error_chain;
use crate::util::discord::send_discord_error_report;
use crate::util::requester::Requester;
use crate::util::time::parse_time_to_seconds;
use crate::util::hoster_proxy::{proxy_name_for_url, rewrite_hoster_url};
use crate::videos::ServerOptions;
use crate::videos::VideoFormat;
use crate::videos::VideoItem;
@@ -332,6 +333,13 @@ impl SxyprnProvider {
.and_then(|s| s.split("</div>").next())
.ok_or_else(|| ErrorKind::Parse("failed to extract title_parts".into()))?;
let title_links: Vec<String> = video_segment
.split("href='https://")
.skip(1)
.filter_map(|part| part.split("'").next().map(|u| u.to_string()))
.collect();
let document = Html::parse_document(title_parts);
let selector = Selector::parse("*")
.map_err(|e| ErrorKind::Parse(format!("selector parse failed: {e}")))?;
@@ -358,10 +366,36 @@ impl SxyprnProvider {
.trim()
.to_string();
// De-duplicate repeated titles
let words: Vec<&str> = title.split_whitespace().collect();
if words.len() > 1 {
for pattern_len in (1..=words.len() / 2).rev() {
let pattern = &words[0..pattern_len];
let mut all_match = true;
let mut idx = pattern_len;
while idx < words.len() {
let end = std::cmp::min(idx + pattern_len, words.len());
if &words[idx..end] != &pattern[0..(end - idx)] {
all_match = false;
break;
}
idx += pattern_len;
}
if all_match && words.len() % pattern_len == 0 {
title = pattern.join(" ");
break;
}
}
}
if title.to_ascii_lowercase().starts_with("new ") {
title = title[4..].to_string();
}
println!("{:?}", title_links);
// Extract tags from title (words starting with #)
let mut tags = Vec::new();
let words: Vec<&str> = title.split_whitespace().collect();
@@ -401,7 +435,7 @@ impl SxyprnProvider {
.nth(1)
.and_then(|s| s.split("data-src='").nth(1))
.and_then(|s| s.split('\'').next())
.ok_or_else(|| ErrorKind::Parse("failed to extract thumb".into()))?;
.unwrap_or("");
let thumb = format!("https:{thumb_path}");
@@ -462,29 +496,15 @@ impl SxyprnProvider {
);
// Also collect and transform vidara.so URLs to proxy format and add as formats
let vidara_urls: Vec<String> = video_segment
.split("extlink_icon extlink")
.filter_map(|part| {
part.split("href='")
.last()
.and_then(|s| s.split('\'').next())
.map(|u| u.to_string())
})
.filter(|url| url.contains("vidara.so/v/"))
.filter_map(|url| {
url.split("/v/").last().map(|video_id| {
format!(
"{}/proxy/vidara/e/{}",
options.public_url_base.as_deref().unwrap_or(""),
video_id
)
})
})
let vidara_urls: Vec<String> = title_links
.iter()
.filter(|url| proxy_name_for_url(url).as_deref() == Some("vidara"))
.map(|url| rewrite_hoster_url(options, url))
.collect();
for vidara_url in vidara_urls {
formats.push(
VideoFormat::new(vidara_url.clone(), "1080".to_string(), "m3u8".to_string())
VideoFormat::m3u8(vidara_url.clone(), "1080".to_string(), "m3u8".to_string())
.format_note(
vidara_url
.split("/")
@@ -492,11 +512,39 @@ impl SxyprnProvider {
.unwrap_or("vidara")
.to_string(),
)
.ext("m3u8".to_string())
.format_id("hls".to_string())
.video_ext("m3u8".to_string()),
.format_id("vidara".to_string()),
);
}
let doodstream_urls: Vec<String> = title_links
.iter()
.filter(|url| proxy_name_for_url(url).as_deref() == Some("doodstream"))
.map(|url| rewrite_hoster_url(options, url))
.collect();
for dood_url in doodstream_urls {
formats.push(
VideoFormat::m3u8(dood_url.clone(), "auto".to_string(), "m3u8".to_string())
.format_note("doodstream".to_string())
.format_id("doodstream".to_string()),
);
}
let lulustream_urls: Vec<String> = title_links
.iter()
.filter(|url| proxy_name_for_url(url).as_deref() == Some("lulustream"))
.map(|url| rewrite_hoster_url(options, url))
.collect();
for lulustream_url in lulustream_urls {
formats.push(
VideoFormat::m3u8(lulustream_url.clone(), "auto".to_string(), "m3u8".to_string())
.format_note("lulustream".to_string())
.format_id("lulustream".to_string()),
);
}
let mut video_item = VideoItem::new(
id.clone(),
title,