dynamic base url
This commit is contained in:
16
src/api.rs
16
src/api.rs
@@ -119,6 +119,7 @@ async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> {
|
|||||||
.and_then(|h| h.to_str().ok())
|
.and_then(|h| h.to_str().ok())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_string();
|
.to_string();
|
||||||
|
let public_url_base = format!("{}://{}", req.connection_info().scheme(), host);
|
||||||
let mut status = Status::new();
|
let mut status = Status::new();
|
||||||
|
|
||||||
for (provider_name, provider) in ALL_PROVIDERS.iter() {
|
for (provider_name, provider) in ALL_PROVIDERS.iter() {
|
||||||
@@ -126,7 +127,12 @@ async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> {
|
|||||||
provider.get_channel(clientversion.clone())
|
provider.get_channel(clientversion.clone())
|
||||||
}));
|
}));
|
||||||
match channel_result {
|
match channel_result {
|
||||||
Ok(Some(channel)) => status.add_channel(channel),
|
Ok(Some(mut channel)) => {
|
||||||
|
if channel.favicon.starts_with('/') {
|
||||||
|
channel.favicon = format!("{}{}", public_url_base, channel.favicon);
|
||||||
|
}
|
||||||
|
status.add_channel(channel)
|
||||||
|
}
|
||||||
Ok(None) => {}
|
Ok(None) => {}
|
||||||
Err(payload) => {
|
Err(payload) => {
|
||||||
let panic_msg = panic_payload_to_string(payload);
|
let panic_msg = panic_payload_to_string(payload);
|
||||||
@@ -134,7 +140,7 @@ async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status.iconUrl = format!("http://{}/favicon.ico", host).to_string();
|
status.iconUrl = format!("{}/favicon.ico", public_url_base).to_string();
|
||||||
Ok(web::HttpResponse::Ok().json(&status))
|
Ok(web::HttpResponse::Ok().json(&status))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,12 +251,18 @@ async fn videos_post(
|
|||||||
.to_string();
|
.to_string();
|
||||||
let duration = video_request.duration.as_deref().unwrap_or("").to_string();
|
let duration = video_request.duration.as_deref().unwrap_or("").to_string();
|
||||||
let sexuality = video_request.sexuality.as_deref().unwrap_or("").to_string();
|
let sexuality = video_request.sexuality.as_deref().unwrap_or("").to_string();
|
||||||
|
let public_url_base = format!(
|
||||||
|
"{}://{}",
|
||||||
|
req.connection_info().scheme(),
|
||||||
|
req.connection_info().host()
|
||||||
|
);
|
||||||
let options = ServerOptions {
|
let options = ServerOptions {
|
||||||
featured: Some(featured),
|
featured: Some(featured),
|
||||||
category: Some(category),
|
category: Some(category),
|
||||||
sites: Some(sites),
|
sites: Some(sites),
|
||||||
filter: Some(filter),
|
filter: Some(filter),
|
||||||
language: Some(language),
|
language: Some(language),
|
||||||
|
public_url_base: Some(public_url_base),
|
||||||
requester: Some(requester),
|
requester: Some(requester),
|
||||||
network: Some(network),
|
network: Some(network),
|
||||||
stars: Some(stars),
|
stars: Some(stars),
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ impl Provider for AllProvider {
|
|||||||
name: "All".to_string(),
|
name: "All".to_string(),
|
||||||
description: "Query from all sites of this Server".to_string(),
|
description: "Query from all sites of this Server".to_string(),
|
||||||
premium: false,
|
premium: false,
|
||||||
favicon: "https://hottub.spacemoehre.de/favicon.ico".to_string(),
|
favicon: "/favicon.ico".to_string(),
|
||||||
status: "active".to_string(),
|
status: "active".to_string(),
|
||||||
categories: vec![],
|
categories: vec![],
|
||||||
options: vec![ChannelOption {
|
options: vec![ChannelOption {
|
||||||
|
|||||||
@@ -213,9 +213,10 @@ impl HanimeProvider {
|
|||||||
drop(conn);
|
drop(conn);
|
||||||
let id = hit.id.to_string();
|
let id = hit.id.to_string();
|
||||||
let title = hit.name;
|
let title = hit.name;
|
||||||
let thumb = hit.cover_url.replace(
|
let thumb = crate::providers::build_proxy_url(
|
||||||
"https://hanime-cdn.com",
|
&options,
|
||||||
"https://hottub.spacemoehre.de/proxy/hanime-cdn",
|
"hanime-cdn",
|
||||||
|
&crate::providers::strip_url_scheme(&hit.cover_url),
|
||||||
);
|
);
|
||||||
let duration = (hit.duration_in_ms / 1000) as u32; // Convert ms to seconds
|
let duration = (hit.duration_in_ms / 1000) as u32; // Convert ms to seconds
|
||||||
let channel = "hanime".to_string(); // Placeholder, adjust as needed
|
let channel = "hanime".to_string(); // Placeholder, adjust as needed
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ impl HqpornerProvider {
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| Error::from(format!("Request failed: {}", e)))?;
|
.map_err(|e| Error::from(format!("Request failed: {}", e)))?;
|
||||||
|
|
||||||
let video_items = self.get_video_items_from_html(text, &mut requester).await;
|
let video_items = self.get_video_items_from_html(text, &mut requester, &options).await;
|
||||||
if !video_items.is_empty() {
|
if !video_items.is_empty() {
|
||||||
cache.insert(video_url, video_items.clone());
|
cache.insert(video_url, video_items.clone());
|
||||||
}
|
}
|
||||||
@@ -234,7 +234,7 @@ impl HqpornerProvider {
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| Error::from(format!("Request failed: {}", e)))?;
|
.map_err(|e| Error::from(format!("Request failed: {}", e)))?;
|
||||||
|
|
||||||
let video_items = self.get_video_items_from_html(text, &mut requester).await;
|
let video_items = self.get_video_items_from_html(text, &mut requester, &options).await;
|
||||||
if !video_items.is_empty() {
|
if !video_items.is_empty() {
|
||||||
cache.insert(video_url, video_items.clone());
|
cache.insert(video_url, video_items.clone());
|
||||||
}
|
}
|
||||||
@@ -245,6 +245,7 @@ impl HqpornerProvider {
|
|||||||
&self,
|
&self,
|
||||||
html: String,
|
html: String,
|
||||||
requester: &mut Requester,
|
requester: &mut Requester,
|
||||||
|
options: &ServerOptions,
|
||||||
) -> Vec<VideoItem> {
|
) -> Vec<VideoItem> {
|
||||||
if html.is_empty() || html.contains("404 Not Found") {
|
if html.is_empty() || html.contains("404 Not Found") {
|
||||||
return vec![];
|
return vec![];
|
||||||
@@ -273,7 +274,7 @@ impl HqpornerProvider {
|
|||||||
let Some(seg) = iter.next() else {
|
let Some(seg) = iter.next() else {
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
in_flight.push(self.get_video_item(seg, requester.clone()));
|
in_flight.push(self.get_video_item(seg, requester.clone(), options));
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(result) = in_flight.next().await else {
|
let Some(result) = in_flight.next().await else {
|
||||||
@@ -312,7 +313,12 @@ impl HqpornerProvider {
|
|||||||
items
|
items
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_video_item(&self, seg: String, mut requester: Requester) -> Result<VideoItem> {
|
async fn get_video_item(
|
||||||
|
&self,
|
||||||
|
seg: String,
|
||||||
|
mut requester: Requester,
|
||||||
|
options: &ServerOptions,
|
||||||
|
) -> Result<VideoItem> {
|
||||||
let video_url = format!(
|
let video_url = format!(
|
||||||
"{}{}",
|
"{}{}",
|
||||||
self.url,
|
self.url,
|
||||||
@@ -351,7 +357,7 @@ impl HqpornerProvider {
|
|||||||
format!("https://{}", thumb_raw.trim_start_matches('/'))
|
format!("https://{}", thumb_raw.trim_start_matches('/'))
|
||||||
};
|
};
|
||||||
let thumb = match thumb_abs.strip_prefix("https://") {
|
let thumb = match thumb_abs.strip_prefix("https://") {
|
||||||
Some(path) => format!("https://hottub.spacemoehre.de/proxy/hqporner-thumb/{path}"),
|
Some(path) => crate::providers::build_proxy_url(options, "hqporner-thumb", path),
|
||||||
None => thumb_abs,
|
None => thumb_abs,
|
||||||
};
|
};
|
||||||
let raw_duration = seg
|
let raw_duration = seg
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ impl JavtifulProvider {
|
|||||||
return Ok(vec![]);
|
return Ok(vec![]);
|
||||||
}
|
}
|
||||||
let video_items: Vec<VideoItem> = self
|
let video_items: Vec<VideoItem> = self
|
||||||
.get_video_items_from_html(text.clone(), &mut requester)
|
.get_video_items_from_html(text.clone(), &mut requester, &options)
|
||||||
.await;
|
.await;
|
||||||
if !video_items.is_empty() {
|
if !video_items.is_empty() {
|
||||||
cache.remove(&video_url);
|
cache.remove(&video_url);
|
||||||
@@ -223,7 +223,7 @@ impl JavtifulProvider {
|
|||||||
return Ok(vec![]);
|
return Ok(vec![]);
|
||||||
}
|
}
|
||||||
let video_items: Vec<VideoItem> = self
|
let video_items: Vec<VideoItem> = self
|
||||||
.get_video_items_from_html(text.clone(), &mut requester)
|
.get_video_items_from_html(text.clone(), &mut requester, &options)
|
||||||
.await;
|
.await;
|
||||||
if !video_items.is_empty() {
|
if !video_items.is_empty() {
|
||||||
cache.remove(&video_url);
|
cache.remove(&video_url);
|
||||||
@@ -238,6 +238,7 @@ impl JavtifulProvider {
|
|||||||
&self,
|
&self,
|
||||||
html: String,
|
html: String,
|
||||||
requester: &mut Requester,
|
requester: &mut Requester,
|
||||||
|
options: &ServerOptions,
|
||||||
) -> Vec<VideoItem> {
|
) -> Vec<VideoItem> {
|
||||||
if html.is_empty() || html.contains("404 Not Found") {
|
if html.is_empty() || html.contains("404 Not Found") {
|
||||||
return vec![];
|
return vec![];
|
||||||
@@ -269,7 +270,7 @@ impl JavtifulProvider {
|
|||||||
.split("card ")
|
.split("card ")
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.filter(|seg| !seg.contains("SPONSOR"))
|
.filter(|seg| !seg.contains("SPONSOR"))
|
||||||
.map(|el| self.get_video_item(el.to_string(), requester.clone()));
|
.map(|el| self.get_video_item(el.to_string(), requester.clone(), options));
|
||||||
|
|
||||||
join_all(futures)
|
join_all(futures)
|
||||||
.await
|
.await
|
||||||
@@ -300,7 +301,12 @@ impl JavtifulProvider {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_video_item(&self, seg: String, mut requester: Requester) -> Result<VideoItem> {
|
async fn get_video_item(
|
||||||
|
&self,
|
||||||
|
seg: String,
|
||||||
|
mut requester: Requester,
|
||||||
|
options: &ServerOptions,
|
||||||
|
) -> Result<VideoItem> {
|
||||||
let video_url = seg
|
let video_url = seg
|
||||||
.split(" href=\"")
|
.split(" href=\"")
|
||||||
.nth(1)
|
.nth(1)
|
||||||
@@ -350,7 +356,7 @@ impl JavtifulProvider {
|
|||||||
.unwrap_or("")
|
.unwrap_or("")
|
||||||
.to_string();
|
.to_string();
|
||||||
let duration = parse_time_to_seconds(&raw_duration).unwrap_or(0) as u32;
|
let duration = parse_time_to_seconds(&raw_duration).unwrap_or(0) as u32;
|
||||||
let (tags, formats, views) = self.extract_media(&video_url, &mut requester).await?;
|
let (tags, formats, views) = self.extract_media(&video_url, &mut requester, options).await?;
|
||||||
|
|
||||||
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");
|
||||||
@@ -367,6 +373,7 @@ impl JavtifulProvider {
|
|||||||
&self,
|
&self,
|
||||||
url: &str,
|
url: &str,
|
||||||
requester: &mut Requester,
|
requester: &mut Requester,
|
||||||
|
options: &ServerOptions,
|
||||||
) -> Result<(Vec<String>, Vec<VideoFormat>, u32)> {
|
) -> Result<(Vec<String>, Vec<VideoFormat>, u32)> {
|
||||||
let text = requester
|
let text = requester
|
||||||
.get(url, Some(Version::HTTP_2))
|
.get(url, Some(Version::HTTP_2))
|
||||||
@@ -413,7 +420,11 @@ impl JavtifulProvider {
|
|||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
let quality = "1080p".to_string();
|
let quality = "1080p".to_string();
|
||||||
let video_url = url.replace("javtiful.com", "hottub.spacemoehre.de/proxy/javtiful");
|
let video_url = crate::providers::build_proxy_url(
|
||||||
|
options,
|
||||||
|
"javtiful",
|
||||||
|
&crate::providers::strip_url_scheme(url),
|
||||||
|
);
|
||||||
Ok((
|
Ok((
|
||||||
tags,
|
tags,
|
||||||
vec![VideoFormat::new(video_url, quality, "video/mp4".into())],
|
vec![VideoFormat::new(video_url, quality, "video/mp4".into())],
|
||||||
|
|||||||
@@ -286,6 +286,25 @@ pub fn requester_or_default(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn strip_url_scheme(url: &str) -> String {
|
||||||
|
url.strip_prefix("https://")
|
||||||
|
.or_else(|| url.strip_prefix("http://"))
|
||||||
|
.unwrap_or(url)
|
||||||
|
.trim_start_matches('/')
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_proxy_url(options: &ServerOptions, proxy: &str, target: &str) -> String {
|
||||||
|
let target = target.trim_start_matches('/');
|
||||||
|
let base = options.public_url_base.as_deref().unwrap_or("").trim_end_matches('/');
|
||||||
|
|
||||||
|
if base.is_empty() {
|
||||||
|
format!("/proxy/{proxy}/{target}")
|
||||||
|
} else {
|
||||||
|
format!("{base}/proxy/{proxy}/{target}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Provider: Send + Sync {
|
pub trait Provider: Send + Sync {
|
||||||
async fn get_videos(
|
async fn get_videos(
|
||||||
|
|||||||
@@ -80,7 +80,8 @@ impl NoodlemagazineProvider {
|
|||||||
.await
|
.await
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let items = self.get_video_items_from_html(text);
|
let proxy_base_url = options.public_url_base.as_deref().unwrap_or_default();
|
||||||
|
let items = self.get_video_items_from_html(text, proxy_base_url);
|
||||||
|
|
||||||
if items.is_empty() {
|
if items.is_empty() {
|
||||||
Ok(old_items)
|
Ok(old_items)
|
||||||
@@ -117,7 +118,8 @@ impl NoodlemagazineProvider {
|
|||||||
.await
|
.await
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let items = self.get_video_items_from_html(text);
|
let proxy_base_url = options.public_url_base.as_deref().unwrap_or_default();
|
||||||
|
let items = self.get_video_items_from_html(text, proxy_base_url);
|
||||||
|
|
||||||
if items.is_empty() {
|
if items.is_empty() {
|
||||||
Ok(old_items)
|
Ok(old_items)
|
||||||
@@ -128,7 +130,7 @@ impl NoodlemagazineProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_video_items_from_html(&self, html: String) -> Vec<VideoItem> {
|
fn get_video_items_from_html(&self, html: String, proxy_base_url: &str) -> Vec<VideoItem> {
|
||||||
if html.is_empty() || html.contains("404 Not Found") {
|
if html.is_empty() || html.contains("404 Not Found") {
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
@@ -148,21 +150,29 @@ impl NoodlemagazineProvider {
|
|||||||
|
|
||||||
list.split("<div class=\"item\">")
|
list.split("<div class=\"item\">")
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.filter_map(|segment| self.get_video_item(segment.to_string()).ok())
|
.filter_map(|segment| self.get_video_item(segment.to_string(), proxy_base_url).ok())
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn proxy_url(&self, video_url: &str) -> String {
|
fn proxy_url(&self, proxy_base_url: &str, video_url: &str) -> String {
|
||||||
let target = video_url
|
let target = video_url
|
||||||
.strip_prefix("https://")
|
.strip_prefix("https://")
|
||||||
.or_else(|| video_url.strip_prefix("http://"))
|
.or_else(|| video_url.strip_prefix("http://"))
|
||||||
.unwrap_or(video_url)
|
.unwrap_or(video_url)
|
||||||
.trim_start_matches('/');
|
.trim_start_matches('/');
|
||||||
|
|
||||||
format!("https://hottub.spacemoehre.de/proxy/noodlemagazine/{target}")
|
if proxy_base_url.is_empty() {
|
||||||
|
return format!("/proxy/noodlemagazine/{target}");
|
||||||
|
}
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"{}/proxy/noodlemagazine/{}",
|
||||||
|
proxy_base_url.trim_end_matches('/'),
|
||||||
|
target
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_video_item(&self, video_segment: String) -> Result<VideoItem> {
|
fn get_video_item(&self, video_segment: String, proxy_base_url: &str) -> Result<VideoItem> {
|
||||||
let href = video_segment
|
let href = video_segment
|
||||||
.split("<a href=\"")
|
.split("<a href=\"")
|
||||||
.nth(1)
|
.nth(1)
|
||||||
@@ -212,7 +222,7 @@ impl NoodlemagazineProvider {
|
|||||||
.and_then(|s| s.split('<').next())
|
.and_then(|s| s.split('<').next())
|
||||||
.and_then(|v| parse_abbreviated_number(v.trim()))
|
.and_then(|v| parse_abbreviated_number(v.trim()))
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
let proxy_url = self.proxy_url(&video_url);
|
let proxy_url = self.proxy_url(proxy_base_url, &video_url);
|
||||||
|
|
||||||
Ok(VideoItem::new(
|
Ok(VideoItem::new(
|
||||||
id,
|
id,
|
||||||
@@ -273,8 +283,11 @@ mod tests {
|
|||||||
let provider = NoodlemagazineProvider::new();
|
let provider = NoodlemagazineProvider::new();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
provider.proxy_url("https://noodlemagazine.com/watch/-123_456"),
|
provider.proxy_url(
|
||||||
"https://hottub.spacemoehre.de/proxy/noodlemagazine/noodlemagazine.com/watch/-123_456"
|
"https://example.com",
|
||||||
|
"https://noodlemagazine.com/watch/-123_456"
|
||||||
|
),
|
||||||
|
"https://example.com/proxy/noodlemagazine/noodlemagazine.com/watch/-123_456"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,12 +307,12 @@ mod tests {
|
|||||||
>Show more</div>
|
>Show more</div>
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let items = provider.get_video_items_from_html(html.to_string());
|
let items = provider.get_video_items_from_html(html.to_string(), "https://example.com");
|
||||||
|
|
||||||
assert_eq!(items.len(), 1);
|
assert_eq!(items.len(), 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
items[0].url,
|
items[0].url,
|
||||||
"https://hottub.spacemoehre.de/proxy/noodlemagazine/noodlemagazine.com/watch/-123_456"
|
"https://example.com/proxy/noodlemagazine/noodlemagazine.com/watch/-123_456"
|
||||||
);
|
);
|
||||||
assert_eq!(items[0].formats.as_ref().map(|f| f.len()), Some(1));
|
assert_eq!(items[0].formats.as_ref().map(|f| f.len()), Some(1));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,12 +172,18 @@ impl SpankbangProvider {
|
|||||||
format!("{}/{}", self.url, url.trim_start_matches("./"))
|
format!("{}/{}", self.url, url.trim_start_matches("./"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn proxy_url(&self, url: &str) -> String {
|
fn proxy_url(&self, proxy_base_url: &str, url: &str) -> String {
|
||||||
let path = url
|
let path = url
|
||||||
.strip_prefix(&self.url)
|
.strip_prefix(&self.url)
|
||||||
.unwrap_or(url)
|
.unwrap_or(url)
|
||||||
.trim_start_matches('/');
|
.trim_start_matches('/');
|
||||||
format!("https://hottub.spacemoehre.de/proxy/spankbang/{path}")
|
if proxy_base_url.is_empty() {
|
||||||
|
return format!("/proxy/spankbang/{path}");
|
||||||
|
}
|
||||||
|
format!(
|
||||||
|
"{}/proxy/spankbang/{path}",
|
||||||
|
proxy_base_url.trim_end_matches('/')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_html(text: &str) -> String {
|
fn decode_html(text: &str) -> String {
|
||||||
@@ -258,6 +264,7 @@ impl SpankbangProvider {
|
|||||||
views_selector: &Selector,
|
views_selector: &Selector,
|
||||||
rating_selector: &Selector,
|
rating_selector: &Selector,
|
||||||
meta_link_selector: &Selector,
|
meta_link_selector: &Selector,
|
||||||
|
proxy_base_url: &str,
|
||||||
) -> Option<VideoItem> {
|
) -> Option<VideoItem> {
|
||||||
let card_html = card.html();
|
let card_html = card.html();
|
||||||
let card_text = Self::collapse_whitespace(&card.text().collect::<Vec<_>>().join(" "));
|
let card_text = Self::collapse_whitespace(&card.text().collect::<Vec<_>>().join(" "));
|
||||||
@@ -312,7 +319,7 @@ impl SpankbangProvider {
|
|||||||
let mut item = VideoItem::new(
|
let mut item = VideoItem::new(
|
||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
self.proxy_url(&href),
|
self.proxy_url(proxy_base_url, &href),
|
||||||
"spankbang".to_string(),
|
"spankbang".to_string(),
|
||||||
thumb,
|
thumb,
|
||||||
duration,
|
duration,
|
||||||
@@ -344,7 +351,7 @@ impl SpankbangProvider {
|
|||||||
Some(item)
|
Some(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_video_items_from_html(&self, html: String) -> Vec<VideoItem> {
|
fn get_video_items_from_html(&self, html: String, proxy_base_url: &str) -> Vec<VideoItem> {
|
||||||
let document = Html::parse_document(&html);
|
let document = Html::parse_document(&html);
|
||||||
let video_list_selector = Selector::parse(r#"[data-testid="video-list"]"#).unwrap();
|
let video_list_selector = Selector::parse(r#"[data-testid="video-list"]"#).unwrap();
|
||||||
let card_selector = Selector::parse(r#"[data-testid="video-item"]"#).unwrap();
|
let card_selector = Selector::parse(r#"[data-testid="video-item"]"#).unwrap();
|
||||||
@@ -378,6 +385,7 @@ impl SpankbangProvider {
|
|||||||
&views_selector,
|
&views_selector,
|
||||||
&rating_selector,
|
&rating_selector,
|
||||||
&meta_link_selector,
|
&meta_link_selector,
|
||||||
|
proxy_base_url,
|
||||||
) {
|
) {
|
||||||
items.push(item);
|
items.push(item);
|
||||||
}
|
}
|
||||||
@@ -432,7 +440,8 @@ impl SpankbangProvider {
|
|||||||
return Ok(old_items);
|
return Ok(old_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
let video_items = self.get_video_items_from_html(text);
|
let proxy_base_url = options.public_url_base.as_deref().unwrap_or_default();
|
||||||
|
let video_items = self.get_video_items_from_html(text, proxy_base_url);
|
||||||
if !video_items.is_empty() {
|
if !video_items.is_empty() {
|
||||||
cache.remove(&video_url);
|
cache.remove(&video_url);
|
||||||
cache.insert(video_url.clone(), video_items.clone());
|
cache.insert(video_url.clone(), video_items.clone());
|
||||||
@@ -489,7 +498,8 @@ impl SpankbangProvider {
|
|||||||
return Ok(old_items);
|
return Ok(old_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
let video_items = self.get_video_items_from_html(text);
|
let proxy_base_url = options.public_url_base.as_deref().unwrap_or_default();
|
||||||
|
let video_items = self.get_video_items_from_html(text, proxy_base_url);
|
||||||
if !video_items.is_empty() {
|
if !video_items.is_empty() {
|
||||||
cache.remove(&video_url);
|
cache.remove(&video_url);
|
||||||
cache.insert(video_url.clone(), video_items.clone());
|
cache.insert(video_url.clone(), video_items.clone());
|
||||||
@@ -634,13 +644,13 @@ mod tests {
|
|||||||
</div>
|
</div>
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let items = provider.get_video_items_from_html(html.to_string());
|
let items = provider.get_video_items_from_html(html.to_string(), "https://example.com");
|
||||||
assert_eq!(items.len(), 1);
|
assert_eq!(items.len(), 1);
|
||||||
assert_eq!(items[0].id, "6597754");
|
assert_eq!(items[0].id, "6597754");
|
||||||
assert_eq!(items[0].title, "Adriana's Fleshlight Insertion");
|
assert_eq!(items[0].title, "Adriana's Fleshlight Insertion");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
items[0].url,
|
items[0].url,
|
||||||
"https://hottub.spacemoehre.de/proxy/spankbang/3xeuy/video/adriana+s+fleshlight+insertion"
|
"https://example.com/proxy/spankbang/3xeuy/video/adriana+s+fleshlight+insertion"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
items[0].thumb,
|
items[0].thumb,
|
||||||
@@ -691,7 +701,7 @@ mod tests {
|
|||||||
</div>
|
</div>
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let items = provider.get_video_items_from_html(html.to_string());
|
let items = provider.get_video_items_from_html(html.to_string(), "https://example.com");
|
||||||
assert_eq!(items.len(), 1);
|
assert_eq!(items.len(), 1);
|
||||||
assert_eq!(items[0].id, "2");
|
assert_eq!(items[0].id, "2");
|
||||||
assert_eq!(items[0].title, "Free video");
|
assert_eq!(items[0].title, "Free video");
|
||||||
@@ -728,7 +738,7 @@ mod tests {
|
|||||||
</div>
|
</div>
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let items = provider.get_video_items_from_html(html.to_string());
|
let items = provider.get_video_items_from_html(html.to_string(), "https://example.com");
|
||||||
assert_eq!(items.len(), 1);
|
assert_eq!(items.len(), 1);
|
||||||
assert_eq!(items[0].id, "222");
|
assert_eq!(items[0].id, "222");
|
||||||
assert_eq!(items[0].title, "Right result");
|
assert_eq!(items[0].title, "Right result");
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ impl SxyprnProvider {
|
|||||||
};
|
};
|
||||||
// Pass a reference to options if needed, or reconstruct as needed
|
// Pass a reference to options if needed, or reconstruct as needed
|
||||||
let video_items = match self
|
let video_items = match self
|
||||||
.get_video_items_from_html(text.clone(), pool, requester)
|
.get_video_items_from_html(text.clone(), pool, requester, &options)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(items) => items,
|
Ok(items) => items,
|
||||||
@@ -247,7 +247,7 @@ impl SxyprnProvider {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let video_items = match self
|
let video_items = match self
|
||||||
.get_video_items_from_html(text.clone(), pool, requester)
|
.get_video_items_from_html(text.clone(), pool, requester, &options)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(items) => items,
|
Ok(items) => items,
|
||||||
@@ -284,6 +284,7 @@ impl SxyprnProvider {
|
|||||||
html: String,
|
html: String,
|
||||||
_pool: DbPool,
|
_pool: DbPool,
|
||||||
_requester: Requester,
|
_requester: Requester,
|
||||||
|
options: &ServerOptions,
|
||||||
) -> Result<Vec<VideoItem>> {
|
) -> Result<Vec<VideoItem>> {
|
||||||
if html.is_empty() {
|
if html.is_empty() {
|
||||||
return Ok(vec![]);
|
return Ok(vec![]);
|
||||||
@@ -313,7 +314,8 @@ impl SxyprnProvider {
|
|||||||
.ok_or_else(|| ErrorKind::Parse("failed to extract /post/ url".into()))?
|
.ok_or_else(|| ErrorKind::Parse("failed to extract /post/ url".into()))?
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
let video_url = format!("https://hottub.spacemoehre.de/proxy/sxyprn/post/{}", url);
|
let video_url =
|
||||||
|
crate::providers::build_proxy_url(options, "sxyprn", &format!("post/{}", url));
|
||||||
|
|
||||||
// title parts
|
// title parts
|
||||||
let title_parts = video_segment
|
let title_parts = video_segment
|
||||||
@@ -421,7 +423,7 @@ impl SxyprnProvider {
|
|||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
let video_item_url = stream_urls.first().cloned().unwrap_or_else(|| {
|
let video_item_url = stream_urls.first().cloned().unwrap_or_else(|| {
|
||||||
format!("https://hottub.spacemoehre.de/proxy/sxyprn/post/{}", id)
|
crate::providers::build_proxy_url(options, "sxyprn", &format!("post/{}", id))
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut video_item = VideoItem::new(
|
let mut video_item = VideoItem::new(
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ pub struct ServerOptions {
|
|||||||
pub sites: Option<String>, //
|
pub sites: Option<String>, //
|
||||||
pub filter: Option<String>,
|
pub filter: Option<String>,
|
||||||
pub language: Option<String>, // "en"
|
pub language: Option<String>, // "en"
|
||||||
|
pub public_url_base: Option<String>,
|
||||||
pub requester: Option<Requester>,
|
pub requester: Option<Requester>,
|
||||||
pub network: Option<String>, //
|
pub network: Option<String>, //
|
||||||
pub stars: Option<String>, //
|
pub stars: Option<String>, //
|
||||||
|
|||||||
Reference in New Issue
Block a user