Add torrents-csv and YTS as TPB search fallbacks
apibay has been timing out and the configured 1337x mirrors are all Cloudflare 521, so general-content search was failing closed. TPB stays primary; on failure or empty results, movies try YTS then torrents-csv then 1337x, and TV tries torrents-csv then 1337x. Both new sources are JSON hash-to-magnet, same grab shape as TPB. Prepend a working 1337x mirror (1337xx.to) to the default ring.
This commit is contained in:
parent
7ab28d30a7
commit
6059d77065
9 changed files with 600 additions and 171 deletions
|
|
@ -1,6 +1,8 @@
|
|||
pub mod rss;
|
||||
pub mod scrape;
|
||||
pub mod torrents_csv;
|
||||
pub mod tpb;
|
||||
pub mod yts;
|
||||
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
|
|
@ -25,6 +27,39 @@ pub trait ReleaseSource {
|
|||
async fn fetch(&self, query: Option<&str>) -> Result<Vec<RawReleaseItem>>;
|
||||
}
|
||||
|
||||
/// Trackers attached to every magnet we synthesize from an info-hash
|
||||
/// (TPB, torrents-csv, YTS). Same set the TPB client has used since it
|
||||
/// landed — qBittorrent needs *some* announce list or the torrent sits
|
||||
/// hash-only until DHT finds peers.
|
||||
const MAGNET_TRACKERS: &[&str] = &[
|
||||
"udp://tracker.opentrackr.org:1337/announce",
|
||||
"udp://open.stealth.si:80/announce",
|
||||
"udp://tracker.torrent.eu.org:451/announce",
|
||||
"udp://tracker.openbittorrent.com:6969/announce",
|
||||
"udp://exodus.desync.com:6969/announce",
|
||||
];
|
||||
|
||||
/// A valid BitTorrent v1 info_hash: 40 hex chars or 32 base32 chars — same
|
||||
/// shape `qbit::extract_btih` accepts out of a magnet URI. Shared by every
|
||||
/// hash-to-magnet source so a malformed value can't silently produce a
|
||||
/// magnet the grab path then fails to parse back.
|
||||
pub(crate) fn is_valid_info_hash(hash: &str) -> bool {
|
||||
(hash.len() == 40 && hash.bytes().all(|b| b.is_ascii_hexdigit()))
|
||||
|| (hash.len() == 32
|
||||
&& hash
|
||||
.bytes()
|
||||
.all(|b| matches!(b, b'2'..=b'7' | b'a'..=b'z' | b'A'..=b'Z')))
|
||||
}
|
||||
|
||||
pub(crate) fn build_magnet(info_hash: &str, name: &str) -> String {
|
||||
let mut magnet = format!("magnet:?xt=urn:btih:{info_hash}&dn={}", urlencode(name));
|
||||
for t in MAGNET_TRACKERS {
|
||||
magnet.push_str("&tr=");
|
||||
magnet.push_str(&urlencode(t));
|
||||
}
|
||||
magnet
|
||||
}
|
||||
|
||||
pub(crate) fn urlencode(s: &str) -> String {
|
||||
s.chars()
|
||||
.map(|c| {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue