spankbang
This commit is contained in:
@@ -1,16 +1,19 @@
|
||||
use ntex::web;
|
||||
|
||||
use crate::proxies::spankbang::SpankbangProxy;
|
||||
use crate::{proxies::sxyprn::SxyprnProxy, util::requester::Requester};
|
||||
|
||||
pub mod hanimecdn;
|
||||
pub mod hqpornerthumb;
|
||||
pub mod javtiful;
|
||||
pub mod spankbang;
|
||||
pub mod sxyprn;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AnyProxy {
|
||||
Sxyprn(SxyprnProxy),
|
||||
Javtiful(javtiful::JavtifulProxy),
|
||||
Spankbang(SpankbangProxy),
|
||||
}
|
||||
|
||||
pub trait Proxy {
|
||||
@@ -22,6 +25,7 @@ impl Proxy for AnyProxy {
|
||||
match self {
|
||||
AnyProxy::Sxyprn(p) => p.get_video_url(url, requester).await,
|
||||
AnyProxy::Javtiful(p) => p.get_video_url(url, requester).await,
|
||||
AnyProxy::Spankbang(p) => p.get_video_url(url, requester).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
105
src/proxies/spankbang.rs
Normal file
105
src/proxies/spankbang.rs
Normal file
@@ -0,0 +1,105 @@
|
||||
use ntex::web;
|
||||
use regex::Regex;
|
||||
use wreq::Version;
|
||||
|
||||
use crate::util::requester::Requester;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SpankbangProxy {}
|
||||
|
||||
impl SpankbangProxy {
|
||||
pub fn new() -> Self {
|
||||
SpankbangProxy {}
|
||||
}
|
||||
|
||||
fn request_headers() -> Vec<(String, String)> {
|
||||
vec![("Referer".to_string(), "https://spankbang.com/".to_string())]
|
||||
}
|
||||
|
||||
fn extract_stream_data(text: &str) -> Option<&str> {
|
||||
let marker = "var stream_data = ";
|
||||
let start = text.find(marker)? + marker.len();
|
||||
let rest = &text[start..];
|
||||
let end = rest.find("};")?;
|
||||
Some(&rest[..=end])
|
||||
}
|
||||
|
||||
fn extract_first_stream_url(stream_data: &str, key: &str) -> Option<String> {
|
||||
let pattern = format!(r"'{}'\s*:\s*\[\s*'([^']+)'", regex::escape(key));
|
||||
let regex = Regex::new(&pattern).ok()?;
|
||||
regex
|
||||
.captures(stream_data)
|
||||
.and_then(|captures| captures.get(1))
|
||||
.map(|value| value.as_str().to_string())
|
||||
}
|
||||
|
||||
fn select_best_stream_url(stream_data: &str) -> Option<String> {
|
||||
for key in [
|
||||
"m3u8", "4k", "1080p", "720p", "480p", "320p", "240p", "main",
|
||||
] {
|
||||
if let Some(url) = Self::extract_first_stream_url(stream_data, key) {
|
||||
return Some(url);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub async fn get_video_url(
|
||||
&self,
|
||||
url: String,
|
||||
requester: web::types::State<Requester>,
|
||||
) -> String {
|
||||
let mut requester = requester.get_ref().clone();
|
||||
let url = format!("https://spankbang.com/{}", url.trim_start_matches('/'));
|
||||
let text = requester
|
||||
.get_with_headers(&url, Self::request_headers(), Some(Version::HTTP_2))
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
if text.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
let Some(stream_data) = Self::extract_stream_data(&text) else {
|
||||
return String::new();
|
||||
};
|
||||
|
||||
Self::select_best_stream_url(stream_data).unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::SpankbangProxy;
|
||||
|
||||
#[test]
|
||||
fn prefers_m3u8_when_present() {
|
||||
assert_eq!(
|
||||
SpankbangProxy::request_headers(),
|
||||
vec![("Referer".to_string(), "https://spankbang.com/".to_string())]
|
||||
);
|
||||
|
||||
let data = r#"
|
||||
var stream_data = {'240p': ['https://cdn.example/240.mp4'], '720p': ['https://cdn.example/720.mp4'], 'm3u8': ['https://cdn.example/master.m3u8'], 'main': ['https://cdn.example/720.mp4']};
|
||||
"#;
|
||||
|
||||
let stream_data = SpankbangProxy::extract_stream_data(data).unwrap();
|
||||
assert_eq!(
|
||||
SpankbangProxy::select_best_stream_url(stream_data).as_deref(),
|
||||
Some("https://cdn.example/master.m3u8")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn falls_back_to_highest_quality_mp4() {
|
||||
let data = r#"
|
||||
var stream_data = {'240p': ['https://cdn.example/240.mp4'], '480p': ['https://cdn.example/480.mp4'], '720p': ['https://cdn.example/720.mp4'], '1080p': [], '4k': [], 'm3u8': [], 'main': ['https://cdn.example/480.mp4']};
|
||||
"#;
|
||||
|
||||
let stream_data = SpankbangProxy::extract_stream_data(data).unwrap();
|
||||
assert_eq!(
|
||||
SpankbangProxy::select_best_stream_url(stream_data).as_deref(),
|
||||
Some("https://cdn.example/720.mp4")
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user