Fix hypnotube search sessions; check.py confirms HEAD failures with GET
The site serves one results page per searchgate POST, so later searches and page 2 returned nothing on the shared cookie session. Use an isolated session per (query, page). check.py now retries a refused HEAD (403/404/ 405/501) with a ranged GET before reporting a URL as unreachable. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUYdCh2nCVsQYgJAT7gwSi
This commit is contained in:
@@ -14,7 +14,11 @@ use htmlentity::entity::{ICodedDataTrait, decode};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::{thread, vec};
|
||||
use titlecase::Titlecase;
|
||||
use wreq::Client;
|
||||
use wreq::Version;
|
||||
use wreq::cookie::Jar;
|
||||
use wreq::redirect::Policy;
|
||||
use wreq_util::Emulation;
|
||||
|
||||
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
|
||||
crate::providers::ProviderChannelMetadata {
|
||||
@@ -246,6 +250,43 @@ impl HypnotubeProvider {
|
||||
video_items
|
||||
}
|
||||
|
||||
/// Fetches one page of search results.
|
||||
///
|
||||
/// The site hands out exactly one results page per `searchgate.php` POST
|
||||
/// (a second GET of the same search, or any later search on the same
|
||||
/// session, comes back empty), so every (query, page) uses its own
|
||||
/// isolated cookie session instead of the shared requester jar. Page 1 is
|
||||
/// the redirect target of the POST; page N>1 is fetched directly.
|
||||
async fn fetch_search_html(&self, query: &str, page: u8) -> Result<String> {
|
||||
let client = Client::builder()
|
||||
.tls_cert_verification(false)
|
||||
.emulation(Emulation::Firefox136)
|
||||
.cookie_provider(Arc::new(Jar::default()))
|
||||
.redirect(if page <= 1 { Policy::default() } else { Policy::none() })
|
||||
.build()?;
|
||||
|
||||
let body = format!("q={}&type=videos", query.trim().replace(' ', "+"));
|
||||
let gate = client
|
||||
.post(format!("{}/searchgate.php", self.url))
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.header("Referer", format!("{}/", self.url))
|
||||
.body(body)
|
||||
.send()
|
||||
.await?;
|
||||
if page <= 1 {
|
||||
return Ok(gate.text().await?);
|
||||
}
|
||||
|
||||
let slug = query.trim().replace(' ', "%20");
|
||||
let page_url = format!("{}/search/videos/{}/page{}.html", self.url, slug, page);
|
||||
let response = client
|
||||
.get(page_url)
|
||||
.header("Referer", format!("{}/search/videos/{}/", self.url, slug))
|
||||
.send()
|
||||
.await?;
|
||||
Ok(response.text().await?)
|
||||
}
|
||||
|
||||
async fn query(
|
||||
&self,
|
||||
cache: VideoCache,
|
||||
@@ -281,41 +322,18 @@ impl HypnotubeProvider {
|
||||
}
|
||||
};
|
||||
|
||||
let mut requester =
|
||||
crate::providers::requester_or_default(&options, module_path!(), "missing_requester");
|
||||
let post_response = match requester
|
||||
.post(
|
||||
format!("{}/searchgate.php", self.url).as_str(),
|
||||
format!("q={}&type=videos", query.replace(" ", "+")).as_str(),
|
||||
vec![("Content-Type", "application/x-www-form-urlencoded")],
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(response) => response,
|
||||
let text = match self.fetch_search_html(query, page).await {
|
||||
Ok(text) => text,
|
||||
Err(e) => {
|
||||
crate::providers::report_provider_error(
|
||||
"hypnotube",
|
||||
"query.search_post",
|
||||
"query.search",
|
||||
&format!("url={video_url}; error={e}"),
|
||||
)
|
||||
.await;
|
||||
return old_items;
|
||||
}
|
||||
};
|
||||
let text = match post_response.text().await {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
eprint!("Hypnotube search POST request failed: {}", e);
|
||||
crate::providers::report_provider_error_background(
|
||||
"hypnotube",
|
||||
"query.search_post.text",
|
||||
&e.to_string(),
|
||||
);
|
||||
return vec![];
|
||||
}
|
||||
};
|
||||
// println!("Hypnotube search POST response status: {}", p.text().await.unwrap_or_default());
|
||||
// let text = requester.get(&video_url, Some(Version::HTTP_11)).await.unwrap();
|
||||
if text.contains("Sorry, no results were found.") {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user