Fix pornmz: match contentUrl meta case-insensitively, bound enrichment
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUYdCh2nCVsQYgJAT7gwSi
This commit is contained in:
@@ -22,7 +22,7 @@ Status: `[ ]` open, `[~]` in progress, `[x]` fixed and verified, `[-]` not repro
|
||||
| | Channel | Symptom | Notes |
|
||||
|---|---|---|---|
|
||||
| [x] | `thaiporntv` | page URL "Unsupported URL", no `formats` | player attribute renamed `data-enc` -> `data-video-sources` (reversed base64 JSON `{quality,url}`); decoder handles both. 3 formats/item, yt-dlp OK, check.py passes |
|
||||
| [ ] | `pornmz` | page URL "Unsupported URL", no `formats` | populate formats from detail page |
|
||||
| [x] | `pornmz` | page URL "Unsupported URL", no `formats` | site changed `itemprop="contentURL"` -> `contentUrl`; selector now case-insensitive. Enrichment concurrency 10 + 25s per-item timeout. Origin is slow (15s+/detail) so first feed 25-50s. check.py passes |
|
||||
| [ ] | `coomer` | page URL "Unsupported URL"; media host CF-gated here | check whether `formats` are populated for videos |
|
||||
| [ ] | `tube8` | page URL 404; `/proxy/tube8/{id}` 502 | |
|
||||
| [ ] | `hypnotube` | page URLs 404 on all sampled items | URL construction |
|
||||
|
||||
@@ -835,7 +835,8 @@ impl PornmzProvider {
|
||||
}
|
||||
|
||||
fn meta_itemprop(document: &Html, itemprop: &str) -> Option<String> {
|
||||
let selector = Self::selector(&format!("meta[itemprop=\"{itemprop}\"]")).ok()?;
|
||||
// The site mixes `contentURL` / `contentUrl`; match the value case-insensitively.
|
||||
let selector = Self::selector(&format!("meta[itemprop=\"{itemprop}\" i]")).ok()?;
|
||||
document
|
||||
.select(&selector)
|
||||
.next()
|
||||
@@ -1016,9 +1017,21 @@ impl PornmzProvider {
|
||||
let enriched = stream::iter(items.into_iter().map(|item| {
|
||||
let provider = self.clone();
|
||||
let options = options.clone();
|
||||
async move { provider.enrich_item(item, &options).await }
|
||||
async move {
|
||||
// Detail pages are slow (~15s); don't let one hung page stall the list.
|
||||
let fallback = item.clone();
|
||||
match tokio::time::timeout(
|
||||
std::time::Duration::from_secs(25),
|
||||
provider.enrich_item(item, &options),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(enriched) => enriched,
|
||||
Err(_) => fallback,
|
||||
}
|
||||
}
|
||||
}))
|
||||
.buffer_unordered(6)
|
||||
.buffer_unordered(10)
|
||||
.collect::<Vec<_>>()
|
||||
.await;
|
||||
|
||||
@@ -1239,6 +1252,23 @@ mod tests {
|
||||
assert!(item.uploadedAt.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_lowercase_content_url_meta() {
|
||||
let provider = PornmzProvider::new();
|
||||
let item = VideoItem::new(
|
||||
"pm1".to_string(),
|
||||
"T".to_string(),
|
||||
"https://pornmz.com/video/id=pm1".to_string(),
|
||||
CHANNEL_ID.to_string(),
|
||||
String::new(),
|
||||
0,
|
||||
);
|
||||
let html = r#"<div class="entry-content"><meta itemprop="contentUrl" content="https://video.twimg.com/x/pl/a.m3u8" /></div>"#;
|
||||
let item = provider.apply_detail_video(item, html).expect("detail");
|
||||
assert_eq!(item.url, "https://video.twimg.com/x/pl/a.m3u8");
|
||||
assert_eq!(item.formats.as_ref().map(|f| f.len()), Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derives_mp4_media_extension() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user