Fix fullpornerorg: drop deleted hoster files, keep myvidplay host
Deleted lulustream files stayed listed and 502'd. myvidplay embeds lost their host and were resolved against lulustream; route them through the doodstream proxy (now allowing myvidplay/playmogo) with the host kept. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUYdCh2nCVsQYgJAT7gwSi
This commit is contained in:
@@ -11,6 +11,8 @@ use futures::stream::{self, StreamExt};
|
||||
use regex::Regex;
|
||||
use scraper::{Html, Selector};
|
||||
|
||||
const DELETED_EMBED: &str = "hoster file deleted";
|
||||
|
||||
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
|
||||
crate::providers::ProviderChannelMetadata {
|
||||
group_id: "mainstream-tube",
|
||||
@@ -311,8 +313,28 @@ impl FullpornerorgProvider {
|
||||
None
|
||||
}
|
||||
|
||||
/// Builds the lulustream proxy URL for a given embed ID.
|
||||
fn build_proxy_url(embed_id: &str, options: &ServerOptions) -> String {
|
||||
/// The hoster serves a tiny stub page for removed files. Listings on
|
||||
/// fullporner.org keep pointing at them, so detect it and skip the item.
|
||||
fn embed_is_deleted(html: &str) -> bool {
|
||||
let lower = html.to_ascii_lowercase();
|
||||
lower.contains("no longer available")
|
||||
|| lower.contains("has been deleted")
|
||||
// DoodStream-protocol hosts (myvidplay.com) title the stub this way.
|
||||
|| lower.contains("<title>video not found")
|
||||
}
|
||||
|
||||
/// Builds the proxy URL for an embed. The ID alone is only unique per
|
||||
/// hoster: `myvidplay.com` is a DoodStream-protocol host, so those embeds
|
||||
/// must keep their host and go through the doodstream proxy; resolving the
|
||||
/// same ID on lulustream finds nothing (or a different, deleted file).
|
||||
fn build_proxy_url(embed_url: &str, embed_id: &str, options: &ServerOptions) -> String {
|
||||
if embed_url.contains("myvidplay.com/") {
|
||||
return crate::providers::build_proxy_url(
|
||||
options,
|
||||
"doodstream",
|
||||
&format!("myvidplay.com/e/{embed_id}"),
|
||||
);
|
||||
}
|
||||
crate::providers::build_proxy_url(options, "lulustream", embed_id)
|
||||
}
|
||||
|
||||
@@ -324,9 +346,17 @@ impl FullpornerorgProvider {
|
||||
let embed_id = Self::extract_embed_id(&embed_url)
|
||||
.ok_or_else(|| Error::from(format!("could not parse embed id from {embed_url}")))?;
|
||||
|
||||
// Skip files the hoster has already removed (fail open if the probe
|
||||
// itself is blocked or times out).
|
||||
if let Ok(embed_html) = Self::fetch_html(options, &embed_url, BASE_URL).await {
|
||||
if Self::embed_is_deleted(&embed_html) {
|
||||
return Err(Error::from(DELETED_EMBED));
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: build the proxy URL (will hit /proxy/lulustream/{embed_id} which
|
||||
// resolves the actual HLS URL via the lulustream proxy).
|
||||
let proxy_url = Self::build_proxy_url(&embed_id, options);
|
||||
let proxy_url = Self::build_proxy_url(&embed_url, &embed_id, options);
|
||||
|
||||
// Build the format. The proxy will return a redirect to the actual HLS URL.
|
||||
let mut format = VideoFormat::m3u8(proxy_url, "auto".to_string(), "m3u8".to_string());
|
||||
@@ -371,11 +401,13 @@ impl FullpornerorgProvider {
|
||||
match Self::enrich_card(stub, &options).await {
|
||||
Ok(item) => Some(item),
|
||||
Err(error) => {
|
||||
report_provider_error_background(
|
||||
CHANNEL_ID,
|
||||
"fetch_page.enrich_card",
|
||||
&error.to_string(),
|
||||
);
|
||||
if error.to_string() != DELETED_EMBED {
|
||||
report_provider_error_background(
|
||||
CHANNEL_ID,
|
||||
"fetch_page.enrich_card",
|
||||
&error.to_string(),
|
||||
);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -482,6 +514,36 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn myvidplay_embeds_route_to_doodstream_with_host() {
|
||||
let options = ServerOptions {
|
||||
client_version: None, featured: None, category: None, sites: None, filter: None,
|
||||
language: None, public_url_base: None, requester: None, network: None, stars: None,
|
||||
categories: None, duration: None, sort: None, sexuality: None,
|
||||
};
|
||||
assert_eq!(
|
||||
FullpornerorgProvider::build_proxy_url("https://myvidplay.com/e/abc123", "abc123", &options),
|
||||
"/proxy/doodstream/myvidplay.com/e/abc123"
|
||||
);
|
||||
assert_eq!(
|
||||
FullpornerorgProvider::build_proxy_url("https://luluvdo.com/e/abc123", "abc123", &options),
|
||||
"/proxy/lulustream/abc123"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detects_deleted_embed_stub() {
|
||||
assert!(FullpornerorgProvider::embed_is_deleted(
|
||||
"<body>File is no longer available as it expired or has been deleted.</body>"
|
||||
));
|
||||
assert!(FullpornerorgProvider::embed_is_deleted(
|
||||
"<html><head><title>Video not found | DoodStream</title></head></html>"
|
||||
));
|
||||
assert!(!FullpornerorgProvider::embed_is_deleted(
|
||||
"<html><title>Payton Preslee - Lulustream.mp4</title><script>eval(function(p,a,c,k,e,d){}</script></html>"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn picks_search_for_query() {
|
||||
match FullpornerorgProvider::pick_target(Some("test")) {
|
||||
|
||||
@@ -63,6 +63,10 @@ impl DoodstreamProxy {
|
||||
| "www.streamhg.com"
|
||||
| "doodstream.com"
|
||||
| "www.doodstream.com"
|
||||
| "myvidplay.com"
|
||||
| "www.myvidplay.com"
|
||||
| "playmogo.com"
|
||||
| "www.playmogo.com"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user