f
This commit is contained in:
95
CLI.py
95
CLI.py
@@ -33,7 +33,13 @@ from rich.panel import Panel
|
|||||||
from rich.markdown import Markdown
|
from rich.markdown import Markdown
|
||||||
from rich.bar import Bar
|
from rich.bar import Bar
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from SYS.rich_display import stderr_console, stdout_console
|
from SYS.rich_display import (
|
||||||
|
IMAGE_EXTENSIONS,
|
||||||
|
render_image_to_console,
|
||||||
|
render_item_details_panel,
|
||||||
|
stderr_console,
|
||||||
|
stdout_console,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _install_rich_traceback(*, show_locals: bool = False) -> None:
|
def _install_rich_traceback(*, show_locals: bool = False) -> None:
|
||||||
@@ -4138,6 +4144,93 @@ class PipelineExecutor:
|
|||||||
ctx.set_last_result_items_only(items)
|
ctx.set_last_result_items_only(items)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Special-case: selecting a single image should show it directly.
|
||||||
|
if len(items) == 1:
|
||||||
|
item = items[0]
|
||||||
|
|
||||||
|
# Try to get hash and store to resolve through the backend
|
||||||
|
file_hash = None
|
||||||
|
store_name = None
|
||||||
|
if isinstance(item, dict):
|
||||||
|
file_hash = item.get("hash")
|
||||||
|
store_name = item.get("store")
|
||||||
|
else:
|
||||||
|
if hasattr(item, "hash"):
|
||||||
|
file_hash = getattr(item, "hash", None)
|
||||||
|
if hasattr(item, "store"):
|
||||||
|
store_name = getattr(item, "store", None)
|
||||||
|
|
||||||
|
# Try to resolve the file through the Store backend if we have hash + store
|
||||||
|
resolved_file_path = None
|
||||||
|
if file_hash and store_name:
|
||||||
|
try:
|
||||||
|
from Store import Store
|
||||||
|
storage = Store(config=config or {})
|
||||||
|
backend = storage[str(store_name)]
|
||||||
|
|
||||||
|
# Call get_file to resolve the hash to an actual file path
|
||||||
|
maybe_path = backend.get_file(str(file_hash))
|
||||||
|
|
||||||
|
if isinstance(maybe_path, Path):
|
||||||
|
resolved_file_path = maybe_path
|
||||||
|
elif isinstance(maybe_path, str) and maybe_path:
|
||||||
|
# Only treat as a Path if it doesn't look like a URL
|
||||||
|
if not maybe_path.startswith(("http://", "https://")):
|
||||||
|
resolved_file_path = Path(maybe_path)
|
||||||
|
except Exception:
|
||||||
|
# Fallback: try using the path field from the item
|
||||||
|
pass
|
||||||
|
|
||||||
|
# If backend resolution failed, try the path field
|
||||||
|
if not resolved_file_path:
|
||||||
|
path_str = None
|
||||||
|
if isinstance(item, dict):
|
||||||
|
path_str = (
|
||||||
|
item.get("path")
|
||||||
|
or item.get("PATH")
|
||||||
|
or item.get("target")
|
||||||
|
or item.get("filename")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Try attributes for PipeObject/SearchResult/etc.
|
||||||
|
for attr in ("path", "PATH", "target", "filename"):
|
||||||
|
if hasattr(item, attr):
|
||||||
|
val = getattr(item, attr)
|
||||||
|
if val and isinstance(val, (str, Path)):
|
||||||
|
path_str = val
|
||||||
|
break
|
||||||
|
|
||||||
|
if path_str:
|
||||||
|
from SYS.utils import expand_path
|
||||||
|
resolved_file_path = expand_path(path_str).resolve()
|
||||||
|
|
||||||
|
# Now check if it's an image and render it
|
||||||
|
is_image = False
|
||||||
|
if resolved_file_path:
|
||||||
|
try:
|
||||||
|
if resolved_file_path.suffix.lower() in IMAGE_EXTENSIONS and resolved_file_path.exists():
|
||||||
|
# Use our image renderer
|
||||||
|
stdout_console().print()
|
||||||
|
render_image_to_console(resolved_file_path)
|
||||||
|
is_image = True
|
||||||
|
elif resolved_file_path.suffix.lower() in IMAGE_EXTENSIONS and not resolved_file_path.exists():
|
||||||
|
stdout_console().print(f"[yellow]Warning: Image file not found at {resolved_file_path}[/yellow]")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Render the comprehensive details panel for the item in either case
|
||||||
|
item_to_details = item if isinstance(item, dict) else (
|
||||||
|
item.to_dict() if hasattr(item, "to_dict") else vars(item)
|
||||||
|
)
|
||||||
|
# Ensure we include the resolved path if we found one
|
||||||
|
if resolved_file_path and "path" not in item_to_details:
|
||||||
|
item_to_details["path"] = str(resolved_file_path)
|
||||||
|
|
||||||
|
render_item_details_panel(item_to_details)
|
||||||
|
|
||||||
|
ctx.set_last_result_items_only(items)
|
||||||
|
return
|
||||||
|
|
||||||
table = ResultTable("Selection Result")
|
table = ResultTable("Selection Result")
|
||||||
for item in items:
|
for item in items:
|
||||||
table.add_result(item)
|
table.add_result(item)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ from typing import Any, Iterator, Sequence, TextIO
|
|||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
from rich.text import Text
|
from rich.text import Text
|
||||||
|
from pathlib import Path
|
||||||
|
from SYS.utils import expand_path
|
||||||
|
|
||||||
# Configure Rich pretty-printing to avoid truncating long strings (hashes/paths).
|
# Configure Rich pretty-printing to avoid truncating long strings (hashes/paths).
|
||||||
# This is version-safe: older Rich versions may not support the max_* arguments.
|
# This is version-safe: older Rich versions may not support the max_* arguments.
|
||||||
@@ -93,3 +95,170 @@ def show_store_config_panel(
|
|||||||
"""Show a Rich panel explaining how to configure a storage backend."""
|
"""Show a Rich panel explaining how to configure a storage backend."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".tiff"}
|
||||||
|
|
||||||
|
|
||||||
|
def render_image_to_console(image_path: str | Path, max_width: int | None = None) -> None:
|
||||||
|
"""Render an image to the console using Rich and half-block characters.
|
||||||
|
|
||||||
|
Requires Pillow (PIL). If not available or loading fails, does nothing.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
from PIL import Image
|
||||||
|
from rich.color import Color
|
||||||
|
from rich.style import Style
|
||||||
|
from rich.text import Text
|
||||||
|
|
||||||
|
# Ensure we expand environment variables and resolve to an absolute path.
|
||||||
|
path = expand_path(image_path).resolve()
|
||||||
|
if not path.exists() or not path.is_file():
|
||||||
|
# If absolute path fails, try relative to current directory as a last resort.
|
||||||
|
path = Path(image_path).resolve()
|
||||||
|
if not path.exists() or not path.is_file():
|
||||||
|
return
|
||||||
|
|
||||||
|
with Image.open(path) as img:
|
||||||
|
img = img.convert("RGB")
|
||||||
|
orig_w, orig_h = img.size
|
||||||
|
|
||||||
|
# Determine target dimensions
|
||||||
|
console = stdout_console()
|
||||||
|
if max_width is None:
|
||||||
|
max_width = console.width - 4
|
||||||
|
|
||||||
|
# Ensure max_width is at least something reasonable
|
||||||
|
if max_width < 10:
|
||||||
|
max_width = 80
|
||||||
|
|
||||||
|
# Terminal cells are approx 2x taller than wide.
|
||||||
|
# Half-block characters (upper half block) let us treat one cell as two vertical pixels.
|
||||||
|
aspect = orig_h / orig_w
|
||||||
|
target_w = min(orig_w, max_width)
|
||||||
|
|
||||||
|
# Ensure target_h is even so we always have pairs of vertical pixels
|
||||||
|
target_h = int(target_w * aspect)
|
||||||
|
if target_h < 2:
|
||||||
|
target_h = 2
|
||||||
|
target_h = (target_h // 2) * 2
|
||||||
|
|
||||||
|
# Ensure we don't exceed a reasonable height either (e.g. 40 characters)
|
||||||
|
max_height_chars = 40
|
||||||
|
if (target_h // 2) > max_height_chars:
|
||||||
|
target_h = max_height_chars * 2
|
||||||
|
target_w = int(target_h / aspect)
|
||||||
|
target_h = (target_h // 2) * 2 # Re-ensure even
|
||||||
|
|
||||||
|
if target_w < 1: target_w = 1
|
||||||
|
|
||||||
|
img = img.resize((target_w, target_h), Image.Resampling.BILINEAR)
|
||||||
|
pixels = img.load()
|
||||||
|
|
||||||
|
# Render using upper half block (U+2580)
|
||||||
|
# Each character row in terminal represents 2 pixel rows in image.
|
||||||
|
for y in range(0, target_h - 1, 2):
|
||||||
|
line = Text()
|
||||||
|
for x in range(target_w):
|
||||||
|
r1, g1, b1 = pixels[x, y]
|
||||||
|
r2, g2, b2 = pixels[x, y + 1]
|
||||||
|
# Foreground is top pixel, background is bottom pixel
|
||||||
|
line.append(
|
||||||
|
"▀",
|
||||||
|
style=Style(
|
||||||
|
color=Color.from_rgb(r1, g1, b1),
|
||||||
|
bgcolor=Color.from_rgb(r2, g2, b2),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
console.print(line)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
# Silently fail if image cannot be rendered (e.g. missing PIL or corrupted file)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def render_item_details_panel(item: Dict[str, Any]) -> None:
|
||||||
|
"""Render a comprehensive details panel for a result item."""
|
||||||
|
from rich.table import Table
|
||||||
|
from rich.columns import Columns
|
||||||
|
|
||||||
|
title = (
|
||||||
|
item.get("title")
|
||||||
|
or item.get("name")
|
||||||
|
or item.get("TITLE")
|
||||||
|
or "Unnamed Item"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Main layout table for the panel
|
||||||
|
details_table = Table.grid(expand=True)
|
||||||
|
details_table.add_column(style="cyan", no_wrap=True, width=15)
|
||||||
|
details_table.add_column(style="white")
|
||||||
|
|
||||||
|
# Basic Info
|
||||||
|
details_table.add_row("Title", f"[bold]{title}[/bold]")
|
||||||
|
|
||||||
|
if "store" in item:
|
||||||
|
details_table.add_row("Store", str(item["store"]))
|
||||||
|
|
||||||
|
if "hash" in item:
|
||||||
|
details_table.add_row("Hash", str(item["hash"]))
|
||||||
|
|
||||||
|
# Metadata / Path
|
||||||
|
if "path" in item or "target" in item:
|
||||||
|
path = item.get("path") or item.get("target")
|
||||||
|
details_table.add_row("Path", str(path))
|
||||||
|
|
||||||
|
if "ext" in item or "extension" in item:
|
||||||
|
ext = item.get("ext") or item.get("extension")
|
||||||
|
details_table.add_row("Extension", str(ext))
|
||||||
|
|
||||||
|
if "size_bytes" in item or "size" in item:
|
||||||
|
size = item.get("size_bytes") or item.get("size")
|
||||||
|
if isinstance(size, (int, float)):
|
||||||
|
if size > 1024 * 1024 * 1024:
|
||||||
|
size_str = f"{size / (1024*1024*1024):.1f} GB"
|
||||||
|
elif size > 1024 * 1024:
|
||||||
|
size_str = f"{size / (1024*1024):.1f} MB"
|
||||||
|
elif size > 1024:
|
||||||
|
size_str = f"{size / 1024:.1f} KB"
|
||||||
|
else:
|
||||||
|
size_str = f"{size} bytes"
|
||||||
|
details_table.add_row("Size", size_str)
|
||||||
|
|
||||||
|
# URL(s)
|
||||||
|
urls = item.get("url") or item.get("URL") or []
|
||||||
|
if isinstance(urls, str):
|
||||||
|
urls = [urls]
|
||||||
|
if isinstance(urls, list) and urls:
|
||||||
|
url_text = "\n".join(map(str, urls))
|
||||||
|
details_table.add_row("URL(s)", url_text)
|
||||||
|
|
||||||
|
# Tags
|
||||||
|
tags = item.get("tag") or item.get("tags") or []
|
||||||
|
if isinstance(tags, str):
|
||||||
|
tags = [tags]
|
||||||
|
if isinstance(tags, list) and tags:
|
||||||
|
# Sort and filter tags to look nice
|
||||||
|
tags_sorted = sorted(map(str, tags))
|
||||||
|
# Group tags by namespace if they have them
|
||||||
|
tag_cols = Columns([f"[dim]#[/dim]{t}" for t in tags_sorted], equal=True, expand=True)
|
||||||
|
details_table.add_row("", "") # Spacer
|
||||||
|
details_table.add_row("Tags", tag_cols)
|
||||||
|
|
||||||
|
# Relationships (if any)
|
||||||
|
rels = item.get("relationships") or item.get("rel") or []
|
||||||
|
if isinstance(rels, list) and rels:
|
||||||
|
rel_text = "\n".join([f"[dim]→[/dim] {r}" for r in rels])
|
||||||
|
details_table.add_row("Relations", rel_text)
|
||||||
|
|
||||||
|
panel = Panel(
|
||||||
|
details_table,
|
||||||
|
title=f"[bold green]Item Details[/bold green]",
|
||||||
|
border_style="green",
|
||||||
|
padding=(1, 2),
|
||||||
|
expand=True
|
||||||
|
)
|
||||||
|
|
||||||
|
stdout_console().print()
|
||||||
|
stdout_console().print(panel)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ class HydrusNetwork(Store):
|
|||||||
metadata = client.fetch_file_metadata(
|
metadata = client.fetch_file_metadata(
|
||||||
hashes=[file_hash],
|
hashes=[file_hash],
|
||||||
include_service_keys_to_tags=False,
|
include_service_keys_to_tags=False,
|
||||||
include_file_url=False,
|
include_file_url=True,
|
||||||
include_duration=False,
|
include_duration=False,
|
||||||
include_size=False,
|
include_size=False,
|
||||||
include_mime=False,
|
include_mime=False,
|
||||||
@@ -808,7 +808,7 @@ class HydrusNetwork(Store):
|
|||||||
payload = client.fetch_file_metadata(
|
payload = client.fetch_file_metadata(
|
||||||
file_ids=chunk,
|
file_ids=chunk,
|
||||||
include_service_keys_to_tags=True,
|
include_service_keys_to_tags=True,
|
||||||
include_file_url=False,
|
include_file_url=True,
|
||||||
include_duration=True,
|
include_duration=True,
|
||||||
include_size=True,
|
include_size=True,
|
||||||
include_mime=True,
|
include_mime=True,
|
||||||
@@ -882,11 +882,18 @@ class HydrusNetwork(Store):
|
|||||||
)
|
)
|
||||||
_collect(display_tags)
|
_collect(display_tags)
|
||||||
|
|
||||||
file_url = f"{self.URL.rstrip('/')}/get_files/file?hash={hash_hex}"
|
# Unique tags
|
||||||
|
all_tags = sorted(list(set(all_tags)))
|
||||||
|
|
||||||
|
# Use known URLs (source URLs) from Hydrus if available (matches get-url cmdlet)
|
||||||
|
item_url = meta.get("known_urls") or meta.get("urls") or meta.get("url") or []
|
||||||
|
if not item_url:
|
||||||
|
item_url = meta.get("file_url") or f"{self.URL.rstrip('/')}/view_file?hash={hash_hex}"
|
||||||
|
|
||||||
results.append(
|
results.append(
|
||||||
{
|
{
|
||||||
"hash": hash_hex,
|
"hash": hash_hex,
|
||||||
"url": file_url,
|
"url": item_url,
|
||||||
"name": title,
|
"name": title,
|
||||||
"title": title,
|
"title": title,
|
||||||
"size": size,
|
"size": size,
|
||||||
@@ -912,7 +919,7 @@ class HydrusNetwork(Store):
|
|||||||
metadata = client.fetch_file_metadata(
|
metadata = client.fetch_file_metadata(
|
||||||
file_ids=file_ids,
|
file_ids=file_ids,
|
||||||
include_service_keys_to_tags=True,
|
include_service_keys_to_tags=True,
|
||||||
include_file_url=False,
|
include_file_url=True,
|
||||||
include_duration=True,
|
include_duration=True,
|
||||||
include_size=True,
|
include_size=True,
|
||||||
include_mime=True,
|
include_mime=True,
|
||||||
@@ -922,7 +929,7 @@ class HydrusNetwork(Store):
|
|||||||
metadata = client.fetch_file_metadata(
|
metadata = client.fetch_file_metadata(
|
||||||
hashes=hashes,
|
hashes=hashes,
|
||||||
include_service_keys_to_tags=True,
|
include_service_keys_to_tags=True,
|
||||||
include_file_url=False,
|
include_file_url=True,
|
||||||
include_duration=True,
|
include_duration=True,
|
||||||
include_size=True,
|
include_size=True,
|
||||||
include_mime=True,
|
include_mime=True,
|
||||||
@@ -946,7 +953,7 @@ class HydrusNetwork(Store):
|
|||||||
metadata = client.fetch_file_metadata(
|
metadata = client.fetch_file_metadata(
|
||||||
file_ids=file_ids,
|
file_ids=file_ids,
|
||||||
include_service_keys_to_tags=True,
|
include_service_keys_to_tags=True,
|
||||||
include_file_url=False,
|
include_file_url=True,
|
||||||
include_duration=True,
|
include_duration=True,
|
||||||
include_size=True,
|
include_size=True,
|
||||||
include_mime=True,
|
include_mime=True,
|
||||||
@@ -956,7 +963,7 @@ class HydrusNetwork(Store):
|
|||||||
metadata = client.fetch_file_metadata(
|
metadata = client.fetch_file_metadata(
|
||||||
hashes=hashes,
|
hashes=hashes,
|
||||||
include_service_keys_to_tags=True,
|
include_service_keys_to_tags=True,
|
||||||
include_file_url=False,
|
include_file_url=True,
|
||||||
include_duration=True,
|
include_duration=True,
|
||||||
include_size=True,
|
include_size=True,
|
||||||
include_mime=True,
|
include_mime=True,
|
||||||
@@ -1021,6 +1028,9 @@ class HydrusNetwork(Store):
|
|||||||
top_level_tags = meta.get("tags_flat", []) or meta.get("tags", [])
|
top_level_tags = meta.get("tags_flat", []) or meta.get("tags", [])
|
||||||
_collect(top_level_tags)
|
_collect(top_level_tags)
|
||||||
|
|
||||||
|
# Unique tags
|
||||||
|
all_tags = sorted(list(set(all_tags)))
|
||||||
|
|
||||||
# Prefer Hydrus-provided extension (e.g. ".webm"); fall back to MIME map.
|
# Prefer Hydrus-provided extension (e.g. ".webm"); fall back to MIME map.
|
||||||
mime_type = meta.get("mime")
|
mime_type = meta.get("mime")
|
||||||
ext = str(meta.get("ext") or "").strip().lstrip(".")
|
ext = str(meta.get("ext") or "").strip().lstrip(".")
|
||||||
@@ -1038,14 +1048,18 @@ class HydrusNetwork(Store):
|
|||||||
# Just include what the tag search returned
|
# Just include what the tag search returned
|
||||||
has_namespace = ":" in query_lower
|
has_namespace = ":" in query_lower
|
||||||
|
|
||||||
|
# Use known URLs (source URLs) from Hydrus if available (matches get-url cmdlet)
|
||||||
|
item_url = meta.get("known_urls") or meta.get("urls") or meta.get("url") or []
|
||||||
|
if not item_url:
|
||||||
|
item_url = meta.get("file_url") or f"{self.URL.rstrip('/')}/view_file?hash={hash_hex}"
|
||||||
|
|
||||||
if has_namespace:
|
if has_namespace:
|
||||||
# Explicit namespace search - already filtered by Hydrus tag search
|
# Explicit namespace search - already filtered by Hydrus tag search
|
||||||
# Include this result as-is
|
# Include this result as-is
|
||||||
file_url = f"{self.URL.rstrip('/')}/get_files/file?hash={hash_hex}"
|
|
||||||
results.append(
|
results.append(
|
||||||
{
|
{
|
||||||
"hash": hash_hex,
|
"hash": hash_hex,
|
||||||
"url": file_url,
|
"url": item_url,
|
||||||
"name": title,
|
"name": title,
|
||||||
"title": title,
|
"title": title,
|
||||||
"size": size,
|
"size": size,
|
||||||
@@ -1074,11 +1088,10 @@ class HydrusNetwork(Store):
|
|||||||
break
|
break
|
||||||
|
|
||||||
if match:
|
if match:
|
||||||
file_url = f"{self.URL.rstrip('/')}/get_files/file?hash={hash_hex}"
|
|
||||||
results.append(
|
results.append(
|
||||||
{
|
{
|
||||||
"hash": hash_hex,
|
"hash": hash_hex,
|
||||||
"url": file_url,
|
"url": item_url,
|
||||||
"name": title,
|
"name": title,
|
||||||
"title": title,
|
"title": title,
|
||||||
"size": size,
|
"size": size,
|
||||||
@@ -1113,7 +1126,7 @@ class HydrusNetwork(Store):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
def get_file(self, file_hash: str, **kwargs: Any) -> Path | str | None:
|
def get_file(self, file_hash: str, **kwargs: Any) -> Path | str | None:
|
||||||
"""Return a browser URL for the file.
|
"""Return the local file system path if available, else a browser URL.
|
||||||
|
|
||||||
IMPORTANT: this method must be side-effect free (do not auto-open a browser).
|
IMPORTANT: this method must be side-effect free (do not auto-open a browser).
|
||||||
Only explicit user actions (e.g. the get-file cmdlet) should open files.
|
Only explicit user actions (e.g. the get-file cmdlet) should open files.
|
||||||
@@ -1121,13 +1134,33 @@ class HydrusNetwork(Store):
|
|||||||
|
|
||||||
debug(f"{self._log_prefix()} get_file: start hash={file_hash[:12]}...")
|
debug(f"{self._log_prefix()} get_file: start hash={file_hash[:12]}...")
|
||||||
|
|
||||||
# Build browser URL with access key
|
# Try to get the local disk path if possible (works if Hydrus is on same machine)
|
||||||
|
server_path = None
|
||||||
|
try:
|
||||||
|
path_res = self._client.get_file_path(file_hash)
|
||||||
|
if isinstance(path_res, dict) and "path" in path_res:
|
||||||
|
server_path = path_res["path"]
|
||||||
|
if server_path:
|
||||||
|
local_path = Path(server_path)
|
||||||
|
if local_path.exists():
|
||||||
|
debug(f"{self._log_prefix()} get_file: found local path: {local_path}")
|
||||||
|
return local_path
|
||||||
|
except Exception as e:
|
||||||
|
debug(f"{self._log_prefix()} get_file: could not resolve path from API: {e}")
|
||||||
|
|
||||||
|
# If we found a path on the server but it's not locally accessible,
|
||||||
|
# return it as a string so it can be displayed in metadata panels.
|
||||||
|
if server_path:
|
||||||
|
debug(f"{self._log_prefix()} get_file: returning server path (not local): {server_path}")
|
||||||
|
return server_path
|
||||||
|
|
||||||
|
# Fallback to browser URL with access key
|
||||||
base_url = str(self.URL).rstrip("/")
|
base_url = str(self.URL).rstrip("/")
|
||||||
access_key = str(self.API)
|
access_key = str(self.API)
|
||||||
browser_url = (
|
browser_url = (
|
||||||
f"{base_url}/get_files/file?hash={file_hash}&Hydrus-Client-API-Access-Key={access_key}"
|
f"{base_url}/get_files/file?hash={file_hash}&Hydrus-Client-API-Access-Key={access_key}"
|
||||||
)
|
)
|
||||||
debug(f"{self._log_prefix()} get_file: url={browser_url}")
|
debug(f"{self._log_prefix()} get_file: falling back to url={browser_url}")
|
||||||
return browser_url
|
return browser_url
|
||||||
|
|
||||||
def download_to_temp(
|
def download_to_temp(
|
||||||
@@ -1449,7 +1482,7 @@ class HydrusNetwork(Store):
|
|||||||
payload = client.fetch_file_metadata(
|
payload = client.fetch_file_metadata(
|
||||||
hashes=[file_hash],
|
hashes=[file_hash],
|
||||||
include_service_keys_to_tags=True,
|
include_service_keys_to_tags=True,
|
||||||
include_file_url=False
|
include_file_url=True
|
||||||
)
|
)
|
||||||
|
|
||||||
items = payload.get("metadata") if isinstance(payload, dict) else None
|
items = payload.get("metadata") if isinstance(payload, dict) else None
|
||||||
@@ -1603,7 +1636,7 @@ class HydrusNetwork(Store):
|
|||||||
|
|
||||||
payload = client.fetch_file_metadata(
|
payload = client.fetch_file_metadata(
|
||||||
hashes=[file_hash],
|
hashes=[file_hash],
|
||||||
include_file_url=False
|
include_file_url=True
|
||||||
)
|
)
|
||||||
items = payload.get("metadata") if isinstance(payload, dict) else None
|
items = payload.get("metadata") if isinstance(payload, dict) else None
|
||||||
if not isinstance(items, list) or not items:
|
if not isinstance(items, list) or not items:
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
####REMOVE THIS####
|
|
||||||
####place config information below, rename this file to config.conf####
|
|
||||||
####REMOVE THIS####
|
|
||||||
Reference in New Issue
Block a user