feat(rust): never download .torrent links or torrent files in gofile content

User policy: the channel hosts user-created torrents (one ~2.5 TB); this
tool is for direct-download packs. Torrent links are recorded as done with
a note so they never re-download.
This commit is contained in:
2026-10-10 09:17:00 +02:00
parent eea1260f13
commit ef5cf04c52
+57
View File
@@ -347,6 +347,17 @@ fn is_done(state: &State, gstore: Option<&GlobalStore>, url: &str) -> bool {
state.is_done(url) || gstore.is_some_and(|g| g.is_done(url))
}
/// Torrent links are never downloaded (user policy): the channel hosts huge
/// user-created torrents; this tool is for direct-download packs. A skipped
/// torrent is recorded as done (with a note) so it never comes back.
fn is_torrent_url(url: &str) -> bool {
url.to_ascii_lowercase().ends_with(".torrent")
}
fn is_torrent_file(name: &str) -> bool {
name.to_ascii_lowercase().ends_with(".torrent")
}
/// One channel's pipeline; returns the number of failures (python
/// process_channel).
pub fn process_channel(
@@ -372,6 +383,20 @@ pub fn process_channel(
let found: Vec<FoundUrl> = found
.into_iter()
.filter(|f| {
if is_torrent_url(&f.url) {
log::info!("Skip torrent (never downloaded): {}", f.url);
if let Err(e) = state.mark(&f.url, |r| {
r.status = "ok".into();
r.extra
.insert("note".into(), Value::from("torrent link skipped (policy)"));
}) {
log::error!("Could not record torrent skip for {}: {e}", f.url);
}
return false;
}
true
})
.filter(|f| opts.only.as_ref().is_none_or(|o| o.as_str() == f.host))
.collect();
@@ -619,7 +644,13 @@ pub fn run_gofile(
)));
}
let mut files: Vec<Value> = Vec::new();
let mut skipped_torrents = 0usize;
for (relpath, name, link) in files_spec {
if is_torrent_file(&name) {
skipped_torrents += 1;
log::info!("Skip torrent file in content (policy): {name}");
continue;
}
let dest = out_dir
.join("downloads")
.join("gofile")
@@ -635,6 +666,15 @@ pub fn run_gofile(
}
files.push(entry);
}
if files.is_empty() && skipped_torrents > 0 {
// content holds only torrents: nothing to fetch, ever
log::info!(
"OK {} (0 files, {} torrent(s) skipped by policy)",
f.url,
skipped_torrents
);
return Ok(Vec::new());
}
Ok(files)
})();
match files {
@@ -648,6 +688,14 @@ pub fn run_gofile(
&source,
manifest,
)?;
if files.is_empty() {
state.mark(&f.url, |r| {
r.extra.insert(
"note".into(),
Value::from("only .torrent files - skipped"),
);
})?;
}
if opts.extract {
extract_zips(&files);
}
@@ -1127,6 +1175,15 @@ mod tests {
assert!(parse_since("nonsense").is_err());
}
#[test]
fn torrent_detection() {
assert!(is_torrent_url("https://0807.st/rh0BzdD.torrent"));
assert!(is_torrent_url("https://0807.st/x.TORRENT"));
assert!(!is_torrent_url("https://0807.st/rh0BzdD.zip"));
assert!(is_torrent_file("Lord of Skulls.torrent"));
assert!(!is_torrent_file("Lord of Skulls.rar"));
}
#[test]
fn parse_message_ts_handles_export_formats() {
assert_eq!(