fix in download torrents

This commit is contained in:
Mateusz Gruszczyński
2026-05-22 13:32:36 +02:00
parent cae6d4163b
commit d383d89994

View File

@@ -541,17 +541,31 @@ def torrent_download_zip_items(profile: dict, torrent_hash: str, indexes: list[i
return items return items
def _remote_file_exists(c: ScgiRtorrentClient, source_path: str) -> bool:
# Note: Export fallback checks candidate .torrent files on the rTorrent host before staging, avoiding stale tied-file paths.
clean = _remote_clean_path(source_path)
if not clean:
return False
script = 'p=$1; [ -f "$p" ] && [ -r "$p" ] && printf OK || true'
try:
return str(_rt_execute(c, "execute.capture", "sh", "-c", script, "pytorrent-file-exists", clean) or "").strip() == "OK"
except Exception:
return False
def _remote_stage_path(c: ScgiRtorrentClient, source_path: str, suffix: str = "") -> str: def _remote_stage_path(c: ScgiRtorrentClient, source_path: str, suffix: str = "") -> str:
token = uuid.uuid4().hex token = uuid.uuid4().hex
safe_suffix = ''.join(ch if ch.isalnum() or ch in '.-_' else '_' for ch in str(suffix or ''))[:80] safe_suffix = ''.join(ch if ch.isalnum() or ch in '.-_' else '_' for ch in str(suffix or ''))[:80]
target = f"{download_tmp_dir().rstrip('/')}/pytorrent-download-{token}{safe_suffix}" target = f"{download_tmp_dir().rstrip('/')}/pytorrent-download-{token}{safe_suffix}"
script = ( script = (
'src=$1; dst=$2; ' 'src=$1; dst=$2; '
'if [ ! -f "$src" ]; then echo "ERR\tmissing source"; exit 0; fi; ' 'if [ ! -f "$src" ]; then printf "ERR\tmissing source: %s\n" "$src"; exit 0; fi; '
'if [ ! -r "$src" ]; then printf "ERR\tsource is not readable: %s\n" "$src"; exit 0; fi; '
'cp -- "$src" "$dst" 2>/tmp/pytorrent-cp-err-$$ || { rc=$?; err=$(cat /tmp/pytorrent-cp-err-$$ 2>/dev/null); rm -f /tmp/pytorrent-cp-err-$$; printf "ERR\t%s\t%s\n" "$rc" "$err"; exit 0; }; ' 'cp -- "$src" "$dst" 2>/tmp/pytorrent-cp-err-$$ || { rc=$?; err=$(cat /tmp/pytorrent-cp-err-$$ 2>/dev/null); rm -f /tmp/pytorrent-cp-err-$$; printf "ERR\t%s\t%s\n" "$rc" "$err"; exit 0; }; '
'rm -f /tmp/pytorrent-cp-err-$$; chmod 0644 "$dst" 2>/dev/null || true; printf "OK\t%s\n" "$dst"' 'rm -f /tmp/pytorrent-cp-err-$$; chmod 0644 "$dst" 2>/dev/null || true; printf "OK\t%s\n" "$dst"'
) )
output = str(_rt_execute(c, "execute.capture", "sh", "-c", script, "pytorrent-stage-file", source_path, target) or "").strip() clean_source = _remote_clean_path(source_path)
output = str(_rt_execute(c, "execute.capture", "sh", "-c", script, "pytorrent-stage-file", clean_source, target) or "").strip()
parts = (output.splitlines()[0] if output else "").split("\t", 2) parts = (output.splitlines()[0] if output else "").split("\t", 2)
if len(parts) >= 2 and parts[0] == "OK": if len(parts) >= 2 and parts[0] == "OK":
return parts[1] return parts[1]
@@ -643,14 +657,48 @@ def _torrent_raw_from_method(c: ScgiRtorrentClient, torrent_hash: str) -> bytes
return None return None
def _torrent_source_file(c: ScgiRtorrentClient, torrent_hash: str) -> str: def _rtorrent_session_path(c: ScgiRtorrentClient) -> str:
for method in ("session.path", "get_session"):
try:
value = str(c.call(method) or "").strip()
except Exception:
continue
if value:
return _remote_clean_path(value)
return ""
def _torrent_source_file_candidates(c: ScgiRtorrentClient, torrent_hash: str) -> list[str]:
# Note: rTorrent may keep stale watch/tied paths; session candidates preserve .torrent export when the original source was moved.
candidates: list[str] = []
for method in ("d.tied_to_file", "d.get_tied_to_file", "d.loaded_file", "d.get_loaded_file", "d.session_file", "d.get_session_file"): for method in ("d.tied_to_file", "d.get_tied_to_file", "d.loaded_file", "d.get_loaded_file", "d.session_file", "d.get_session_file"):
try: try:
value = str(c.call(method, torrent_hash) or "").strip() value = str(c.call(method, torrent_hash) or "").strip()
except Exception: except Exception:
continue continue
if value: if value:
return value candidates.append(value)
session_path = _rtorrent_session_path(c)
hash_values = []
clean_hash = str(torrent_hash or "").strip()
if clean_hash:
hash_values.extend([clean_hash, clean_hash.upper(), clean_hash.lower()])
for h in dict.fromkeys(hash_values):
if session_path:
candidates.append(_remote_join(session_path, f"{h}.torrent"))
candidates.append(f"/tmp/{h}.torrent")
result = []
for item in candidates:
clean = _remote_clean_path(item)
if clean and clean not in result:
result.append(clean)
return result
def _torrent_source_file(c: ScgiRtorrentClient, torrent_hash: str) -> str:
for source in _torrent_source_file_candidates(c, torrent_hash):
if _remote_file_exists(c, source):
return source
return "" return ""