javtiful fix

This commit is contained in:
Simon
2026-04-30 06:04:51 +00:00
committed by ForgeCode
parent 698644c5f8
commit 6a4fc98720
3 changed files with 70 additions and 61 deletions

View File

@@ -154,7 +154,7 @@ impl JavtifulProvider {
}; };
if page > 1 if page > 1
&& !text.contains(&format!( && !text.contains(&format!(
"<li class=\"page-item active\"><span class=\"page-link\">{}</span>", "<a class=\"front-pagination-link is-active\" href=\"/videos\" aria-current=\"page\">{}</a>",
page page
)) ))
{ {
@@ -222,7 +222,7 @@ impl JavtifulProvider {
}; };
if page > 1 if page > 1
&& !text.contains(&format!( && !text.contains(&format!(
"<li class=\"page-item active\"><span class=\"page-link\">{}</span>", "<a class=\"front-pagination-link is-active\" href=\"/videos\" aria-current=\"page\">{}</a>",
page page
)) ))
{ {
@@ -250,10 +250,11 @@ impl JavtifulProvider {
return vec![]; return vec![];
} }
let block = match html.split("pagination ").next().and_then(|s| { let block = match html
s.split("row row-cols-1 row-cols-sm-2 row-cols-lg-3 row-cols-xl-4") .split("front-pagination")
.nth(1) .next()
}) { .and_then(|s| s.split("front-video-grid").nth(1))
{
Some(b) => b, Some(b) => b,
None => { None => {
eprint!("Javtiful Provider: Failed to get block from html"); eprint!("Javtiful Provider: Failed to get block from html");
@@ -273,9 +274,9 @@ impl JavtifulProvider {
}; };
let futures = block let futures = block
.split("card ") .split("\"front-video-card\"")
.skip(1) .skip(1)
.filter(|seg| !seg.contains("SPONSOR")) .filter(|seg| !seg.contains("front-ad-card"))
.map(|el| self.get_video_item(el.to_string(), requester.clone(), options)); .map(|el| self.get_video_item(el.to_string(), requester.clone(), options));
join_all(futures) join_all(futures)
@@ -313,20 +314,33 @@ impl JavtifulProvider {
mut requester: Requester, mut requester: Requester,
options: &ServerOptions, options: &ServerOptions,
) -> Result<VideoItem> { ) -> Result<VideoItem> {
let video_url = seg let video_url = format!(
.split(" href=\"") "{}{}",
self.url,
seg.split(" href=\"")
.nth(1) .nth(1)
.and_then(|s| s.split('"').next()) .and_then(|s| s.split('"').next())
.ok_or_else(|| ErrorKind::Parse("video url\n\n{seg}".into()))? .ok_or_else(|| ErrorKind::Parse(format!("video url\n\n{seg}")))?
.to_string(); .to_string()
);
let mut title = seg let mut title = match seg.contains("front-video-title") {
.split(" alt=\"") true => seg
.split("front-video-title")
.nth(1) .nth(1)
.and_then(|s| s.split('"').next()) .and_then(|s| s.split('>').nth(1))
.ok_or_else(|| ErrorKind::Parse(format!("video title\n\n{seg}").into()))? .and_then(|s| s.split('<').next())
.ok_or_else(|| ErrorKind::Parse(format!("video title\n\n{seg}")))?
.trim() .trim()
.to_string(); .to_string(),
false => seg
.split("alt=\"")
.nth(1)
.and_then(|s| s.split('\"').next())
.ok_or_else(|| ErrorKind::Parse(format!("video title\n\n{seg}")))?
.trim()
.to_string(),
};
title = decode(title.as_bytes()) title = decode(title.as_bytes())
.to_string() .to_string()
@@ -334,21 +348,22 @@ impl JavtifulProvider {
.titlecase(); .titlecase();
let id = video_url let id = video_url
.split('/') .split('/')
.nth(5) .filter(|s| !s.is_empty())
.nth(2)
.and_then(|s| s.split('.').next()) .and_then(|s| s.split('.').next())
.ok_or_else(|| ErrorKind::Parse("video id\n\n{seg}".into()))? .ok_or_else(|| ErrorKind::Parse(format!("video id\n\n{seg}")))?
.to_string(); .to_string();
let thumb_block = seg let thumb_block = seg.split("<img ").nth(1);
.split("<img ")
.nth(1)
.ok_or_else(|| ErrorKind::Parse("thumb block\n\n{seg}".into()))?;
let thumb = thumb_block let thumb = match thumb_block {
.split("data-src=\"") Some(block) => format!("{}{}", self.url,block
.split("src=\"")
.nth(1) .nth(1)
.and_then(|s| s.split('"').next()) .and_then(|s| s.split('"').next())
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string()),
None => "".to_string(),
};
let mut preview = seg let mut preview = seg
.split("data-trailer=\"") .split("data-trailer=\"")
.nth(1) .nth(1)
@@ -356,7 +371,7 @@ impl JavtifulProvider {
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
let raw_duration = seg let raw_duration = seg
.split("label-duration\">") .split("class=\"front-duration-tag\">")
.nth(1) .nth(1)
.and_then(|s| s.split('<').next()) .and_then(|s| s.split('<').next())
.unwrap_or("") .unwrap_or("")
@@ -367,7 +382,11 @@ impl JavtifulProvider {
if preview.len() == 0 { if preview.len() == 0 {
preview = format!("https://trailers.jav.si/preview/{id}.mp4"); preview = format!("https://trailers.jav.si/preview/{id}.mp4");
} }
let proxy_url = build_proxy_url(options, "javtiful", &strip_url_scheme(&video_url)); let proxy_url = build_proxy_url(
options,
"javtiful",
&strip_url_scheme(video_url.clone().as_str()),
);
let video_item = VideoItem::new(id, title, proxy_url, "javtiful".into(), thumb, duration) let video_item = VideoItem::new(id, title, proxy_url, "javtiful".into(), thumb, duration)
.tags(tags) .tags(tags)
.preview(preview) .preview(preview)

View File

@@ -653,6 +653,7 @@ pub fn strip_url_scheme(url: &str) -> String {
#[allow(dead_code)] #[allow(dead_code)]
pub fn build_proxy_url(options: &ServerOptions, proxy: &str, target: &str) -> String { pub fn build_proxy_url(options: &ServerOptions, proxy: &str, target: &str) -> String {
println!("Building proxy URL with options={:?}, proxy={}, target={}", options, proxy, target);
let target = target.trim_start_matches('/'); let target = target.trim_start_matches('/');
let base = options let base = options
.public_url_base .public_url_base
@@ -660,6 +661,10 @@ pub fn build_proxy_url(options: &ServerOptions, proxy: &str, target: &str) -> St
.unwrap_or("") .unwrap_or("")
.trim_end_matches('/'); .trim_end_matches('/');
if target.starts_with("http://") || target.starts_with("https://") {
return format!("/proxy/{target}");
}
if base.is_empty() { if base.is_empty() {
format!("/proxy/{proxy}/{target}") format!("/proxy/{proxy}/{target}")
} else { } else {

View File

@@ -89,10 +89,13 @@ impl JavtifulProxy {
url: String, url: String,
requester: web::types::State<Requester>, requester: web::types::State<Requester>,
) -> String { ) -> String {
println!("JavtifulProxy: Getting video URL for {url}");
let mut requester = requester.get_ref().clone(); let mut requester = requester.get_ref().clone();
let Some((detail_url, video_id)) = Self::normalize_detail_request(&url) else { let Some((detail_url, video_id)) = Self::normalize_detail_request(&url) else {
println!("JavtifulProxy: Invalid detail URL: {url}");
return String::new(); return String::new();
}; };
println!("Normalized detail URL: {detail_url}, video ID: {video_id}");
let html = requester.get(&detail_url, Some(Version::HTTP_11)).await; let html = requester.get(&detail_url, Some(Version::HTTP_11)).await;
let Ok(html) = html else { let Ok(html) = html else {
@@ -101,33 +104,15 @@ impl JavtifulProxy {
if html.is_empty() { if html.is_empty() {
return String::new(); return String::new();
} }
println!("Fetched HTML content for {detail_url} (length: {})", html.len());
let Some(token) = Self::extract_token(&html) else { let media_url = format!("https://javtiful.com{}", html.split("playerSources\":[{\"src\":\"")
return String::new(); .nth(1)
}; .and_then(|s| s.split('"').next())
.map(str::trim)
let form = wreq::multipart::Form::new() .map(ToOwned::to_owned).unwrap_or_default());
.text("video_id", video_id) println!("{media_url}");
.text("pid_c", "".to_string()) media_url
.text("token", token);
let resp = match requester
.post_multipart(
"https://javtiful.com/ajax/get_cdn",
form,
vec![
("Referer".to_string(), detail_url),
("Origin".to_string(), "https://javtiful.com".to_string()),
("Accept".to_string(), "*/*".to_string()),
],
Some(Version::HTTP_11),
)
.await
{
Ok(r) => r,
Err(_) => return String::new(),
};
let payload = resp.text().await.unwrap_or_default();
Self::extract_playlist_url(&payload).unwrap_or_default()
} }
} }