media info - fix file read

This commit is contained in:
Mateusz Gruszczyński
2026-05-21 10:05:55 +02:00
parent b0b3497eec
commit d0026ab7f9

View File

@@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
from .client import * from .client import *
from ...config import BASE_DIR
def torrent_files(profile: dict, torrent_hash: str) -> list[dict]: def torrent_files(profile: dict, torrent_hash: str) -> list[dict]:
rows = client_for(profile).f.multicall(torrent_hash, "", "f.path=", "f.size_bytes=", "f.completed_chunks=", "f.size_chunks=", "f.priority=") rows = client_for(profile).f.multicall(torrent_hash, "", "f.path=", "f.size_bytes=", "f.completed_chunks=", "f.size_chunks=", "f.priority=")
@@ -131,6 +132,7 @@ _MEDIA_INFO_EXTENSIONS = {
} }
_MEDIA_INFO_SAMPLE_BYTES = 32 * 1024 * 1024 _MEDIA_INFO_SAMPLE_BYTES = 32 * 1024 * 1024
_MEDIA_INFO_CHUNK_BYTES = 1024 * 1024 _MEDIA_INFO_CHUNK_BYTES = 1024 * 1024
_MEDIA_INFO_TMP_DIR = BASE_DIR / "data" / "media-info-samples"
def _media_info_supported(path: str) -> bool: def _media_info_supported(path: str) -> bool:
@@ -138,11 +140,23 @@ def _media_info_supported(path: str) -> bool:
return LocalPath(str(path or "")).suffix.lower() in _MEDIA_INFO_EXTENSIONS return LocalPath(str(path or "")).suffix.lower() in _MEDIA_INFO_EXTENSIONS
def _media_info_sample_suffix(source_path: str) -> str:
suffix = LocalPath(str(source_path or "")).suffix.lower()
if suffix and len(suffix) <= 16 and all(ch.isalnum() or ch in ".-_" for ch in suffix):
return suffix
return ".bin"
def _media_info_temp_sample(profile: dict, source_path: str, max_bytes: int) -> tuple[str, int]: def _media_info_temp_sample(profile: dict, source_path: str, max_bytes: int) -> tuple[str, int]:
# Note: hachoir needs a seekable file, so this writes a bounded sample to disk instead of loading whole media into RAM. # Note: hachoir needs a seekable file, so this writes a bounded sample into the app data directory instead of loading whole media into RAM.
import tempfile import tempfile
fd, tmp_path = tempfile.mkstemp(prefix="pytorrent-mediainfo-", suffix=LocalPath(source_path).suffix) _MEDIA_INFO_TMP_DIR.mkdir(parents=True, exist_ok=True)
fd, tmp_path = tempfile.mkstemp(
prefix="pytorrent-mediainfo-",
suffix=_media_info_sample_suffix(source_path),
dir=str(_MEDIA_INFO_TMP_DIR),
)
written = 0 written = 0
try: try:
with os.fdopen(fd, "wb") as tmp: with os.fdopen(fd, "wb") as tmp:
@@ -283,7 +297,8 @@ def torrent_file_media_info(profile: dict, torrent_hash: str, index: int, max_by
tmp_path = None tmp_path = None
try: try:
tmp_path, written = _media_info_temp_sample(profile, remote_path, max(1024 * 1024, int(max_bytes))) tmp_path, written = _media_info_temp_sample(profile, remote_path, max(1024 * 1024, int(max_bytes)))
parser = createParser(tmp_path, real_filename=LocalPath(name).name) # Note: Do not pass real_filename here; some hachoir versions treat it as an input path and fail for nested torrent file names.
parser = createParser(tmp_path)
if parser is None: if parser is None:
result.update({"sample_bytes": written, "error": "hachoir could not detect this media container."}) result.update({"sample_bytes": written, "error": "hachoir could not detect this media container."})
return result return result