This commit is contained in:
2026-01-04 02:23:50 -08:00
parent 3acf21a673
commit 8545367e28
6 changed files with 2925 additions and 94 deletions

View File

@@ -2,9 +2,13 @@ from __future__ import annotations
import re
import sys
import tempfile
import shutil
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple
from urllib.parse import quote
import httpx
from SYS.logger import debug, log
@@ -1099,6 +1103,94 @@ class HydrusNetwork(Store):
debug(f"{self._log_prefix()} get_file: url={browser_url}")
return browser_url
def download_to_temp(
self,
file_hash: str,
*,
temp_root: Optional[Path] = None,
) -> Optional[Path]:
"""Download a Hydrus file to a temporary path for downstream uploads."""
try:
client = self._client
if client is None:
return None
h = str(file_hash or "").strip().lower()
if len(h) != 64 or not all(ch in "0123456789abcdef" for ch in h):
return None
created_tmp = False
base_tmp = Path(temp_root) if temp_root is not None else Path(
tempfile.mkdtemp(prefix="hydrus-file-")
)
if temp_root is None:
created_tmp = True
base_tmp.mkdir(parents=True, exist_ok=True)
def _safe_filename(raw: str) -> str:
cleaned = re.sub(r"[\\/:*?\"<>|]", "_", str(raw or "")).strip()
if not cleaned:
return h
cleaned = cleaned.strip(". ") or h
return cleaned
# Prefer ext/title from metadata when available.
fname = h
ext_val = ""
try:
meta = self.get_metadata(h) or {}
if isinstance(meta, dict):
title_val = str(meta.get("title") or "").strip()
if title_val:
fname = _safe_filename(title_val)
ext_val = str(meta.get("ext") or "").strip().lstrip(".")
except Exception:
pass
if not fname:
fname = h
if ext_val and not fname.lower().endswith(f".{ext_val.lower()}"):
fname = f"{fname}.{ext_val}"
try:
file_url = client.file_url(h)
except Exception:
file_url = f"{self.URL.rstrip('/')}/get_files/file?hash={quote(h)}"
dest_path = base_tmp / fname
with httpx.stream(
"GET",
file_url,
headers={"Hydrus-Client-API-Access-Key": self.API},
follow_redirects=True,
timeout=60.0,
verify=False,
) as resp:
resp.raise_for_status()
with dest_path.open("wb") as fh:
for chunk in resp.iter_bytes():
if chunk:
fh.write(chunk)
if dest_path.exists():
return dest_path
if created_tmp:
try:
shutil.rmtree(base_tmp, ignore_errors=True)
except Exception:
pass
return None
except Exception as exc:
log(f"{self._log_prefix()} download_to_temp failed: {exc}", file=sys.stderr)
try:
if temp_root is None and "base_tmp" in locals():
shutil.rmtree(base_tmp, ignore_errors=True) # type: ignore[arg-type]
except Exception:
pass
return None
def delete_file(self, file_identifier: str, **kwargs: Any) -> bool:
"""Delete a file from Hydrus, then clear the deletion record.