fix in download torrents
This commit is contained in:
@@ -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 ""
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user