archivebate: verified app clients get the proxy URL as item url and no formats
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUYdCh2nCVsQYgJAT7gwSi
This commit is contained in:
@@ -815,49 +815,19 @@ impl ArchivebateProvider {
|
|||||||
item
|
item
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For Hot Tub app clients: resolve every item's real media URL at the same
|
/// For verified Hot Tub app clients: no `formats` at all. The item's `url`
|
||||||
/// time (one task per item, no concurrency cap) and hand the app that URL
|
/// is the lazy `/proxy/archivebate` redirect, which the app plays directly
|
||||||
/// with the headers the CDN is played with, instead of the lazy
|
/// (it resolves the media at playback time).
|
||||||
/// `/proxy/archivebate` redirect. Items that fail or time out keep the
|
fn proxy_as_item_url(videos: Vec<VideoItem>, options: &ServerOptions) -> Vec<VideoItem> {
|
||||||
/// proxied format, which re-resolves at playback time.
|
|
||||||
async fn resolve_direct_formats(
|
|
||||||
videos: Vec<VideoItem>,
|
|
||||||
options: &ServerOptions,
|
|
||||||
) -> Vec<VideoItem> {
|
|
||||||
let tasks: Vec<_> = videos
|
|
||||||
.iter()
|
|
||||||
.map(|video| {
|
|
||||||
let detail_url = video.url.clone();
|
|
||||||
let mut requester =
|
|
||||||
requester_or_default(options, CHANNEL_ID, "archivebate.resolve_direct");
|
|
||||||
tokio::spawn(async move {
|
|
||||||
timeout(
|
|
||||||
StdDuration::from_secs(25),
|
|
||||||
crate::proxies::archivebate::resolve_media(&mut requester, &detail_url),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.ok()
|
|
||||||
.flatten()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let resolved = futures::future::join_all(tasks).await;
|
|
||||||
videos
|
videos
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(resolved)
|
.map(|mut video| {
|
||||||
.map(|(mut video, resolved)| match resolved.ok().flatten() {
|
let proxy_url = Self::proxied_video(options, &video.url);
|
||||||
Some(media) => {
|
if !proxy_url.is_empty() {
|
||||||
video.formats = Some(vec![Self::video_format_with_headers(
|
video.url = proxy_url;
|
||||||
VideoFormat::new(media.media_url, "source".to_string(), "mp4".to_string()),
|
|
||||||
vec![
|
|
||||||
("Referer".to_string(), media.embed_url),
|
|
||||||
("User-Agent".to_string(), FIREFOX_UA.to_string()),
|
|
||||||
],
|
|
||||||
)]);
|
|
||||||
video
|
|
||||||
}
|
}
|
||||||
None => Self::with_default_format(video, options),
|
video.formats = None;
|
||||||
|
video
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@@ -1261,7 +1231,7 @@ impl Provider for ArchivebateProvider {
|
|||||||
.map(ClientVersion::is_verified_hottub)
|
.map(ClientVersion::is_verified_hottub)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if is_app_client {
|
if is_app_client {
|
||||||
return Self::resolve_direct_formats(videos, &options).await;
|
return Self::proxy_as_item_url(videos, &options);
|
||||||
}
|
}
|
||||||
stream::iter(videos.into_iter().map(|video| {
|
stream::iter(videos.into_iter().map(|video| {
|
||||||
let provider = self.clone();
|
let provider = self.clone();
|
||||||
@@ -1293,3 +1263,52 @@ impl Provider for ArchivebateProvider {
|
|||||||
Some(self.build_channel(clientversion))
|
Some(self.build_channel(clientversion))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn options() -> ServerOptions {
|
||||||
|
ServerOptions {
|
||||||
|
client_version: None,
|
||||||
|
featured: None,
|
||||||
|
category: None,
|
||||||
|
sites: None,
|
||||||
|
filter: None,
|
||||||
|
language: None,
|
||||||
|
public_url_base: Some("http://hottub.example".to_string()),
|
||||||
|
requester: None,
|
||||||
|
network: None,
|
||||||
|
stars: None,
|
||||||
|
categories: None,
|
||||||
|
duration: None,
|
||||||
|
sort: None,
|
||||||
|
sexuality: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn app_clients_get_the_proxy_url_and_no_formats() {
|
||||||
|
let mut item = VideoItem::new(
|
||||||
|
"archivebate:1".to_string(),
|
||||||
|
"t".to_string(),
|
||||||
|
"https://archivebate.com/watch/1".to_string(),
|
||||||
|
CHANNEL_ID.to_string(),
|
||||||
|
"https://cdn.example/t.jpg".to_string(),
|
||||||
|
10,
|
||||||
|
);
|
||||||
|
item.formats = Some(vec![VideoFormat::new(
|
||||||
|
"x".to_string(),
|
||||||
|
"source".to_string(),
|
||||||
|
"mp4".to_string(),
|
||||||
|
)]);
|
||||||
|
|
||||||
|
let out = ArchivebateProvider::proxy_as_item_url(vec![item], &options());
|
||||||
|
assert_eq!(out.len(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
out[0].url,
|
||||||
|
"http://hottub.example/proxy/archivebate/archivebate.com/watch/1"
|
||||||
|
);
|
||||||
|
assert!(out[0].formats.is_none());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user