From 658bf1570b179342c2288007376012a7ca18724a Mon Sep 17 00:00:00 2001 From: Ryan Galloway Date: Sun, 5 Apr 2026 11:10:30 -0700 Subject: [PATCH 1/4] Move scanning into a guarded subprocess worker --- CHANGELOG.md | 6 + README.md | 21 +++ pyproject.toml | 2 +- sview/__init__.py | 2 +- sview/config.py | 60 ++++++++- sview/model.py | 39 ++++++ sview/qt/app.py | 9 +- sview/qt/main_window.py | 278 +++++++++++++++++++++++++++++----------- sview/scanner.py | 31 ++++- sview/worker.py | 135 +++++++++++++++++++ tests/test_scanner.py | 21 ++- 11 files changed, 519 insertions(+), 85 deletions(-) create mode 100644 sview/worker.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 24cbeee..e934839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.1.2 - 2026-04-05 + +- Moved directory scanning into a subprocess worker for safer cancellation +- Added scan worker guardrails including priority, memory, and timeout controls +- Improved scan error reporting with dialogs and optional `--debug` terminal output + ## 0.1.1 - 2026-04-05 - Improved scanner responsiveness and stop/cancel behavior diff --git a/README.md b/README.md index 222f577..fee6467 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,12 @@ Print the version: sview --version ``` +Run with scanner debug output in the terminal: + +```bash +sview --debug +``` + ## Configuration On first launch, `sview` writes a user config file to: @@ -42,3 +48,18 @@ On first launch, `sview` writes a user config file to: This file controls default file and sequence handlers, including custom commands for double-click actions. + +It also contains scanner worker safety settings such as process priority and +memory limit: + +```json +{ + "scanner": { + "worker": { + "nice_increment": 15, + "memory_limit_mb": 2048, + "timeout_seconds": 30 + } + } +} +``` diff --git a/pyproject.toml b/pyproject.toml index 983e3b1..2a1422b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "sview" -version = "0.1.1" +version = "0.1.2" description = "Sequence-aware filesystem browser" readme = "README.md" requires-python = ">=3.8" diff --git a/sview/__init__.py b/sview/__init__.py index 8eccb03..e961ee1 100644 --- a/sview/__init__.py +++ b/sview/__init__.py @@ -35,4 +35,4 @@ on usability and a clean interface. """ -__version__ = "0.1.1" +__version__ = "0.1.2" diff --git a/sview/config.py b/sview/config.py index 904d081..197461d 100644 --- a/sview/config.py +++ b/sview/config.py @@ -53,36 +53,60 @@ class HandlerConfig: command: str = "" +@dataclass +class ScanWorkerConfig: + nice_increment: int = 15 + memory_limit_mb: int | None = 2048 + timeout_seconds: int | None = 30 + + @dataclass class AppConfig: file_handler: HandlerConfig sequence_handler: HandlerConfig + scan_worker: ScanWorkerConfig @classmethod def default(cls) -> "AppConfig": return cls( file_handler=HandlerConfig(mode="system"), sequence_handler=HandlerConfig(mode="expand"), + scan_worker=ScanWorkerConfig(), ) @classmethod def load(cls) -> "AppConfig": if not CONFIG_PATH.exists(): config = cls.default() - config.save() + try: + config.save() + except OSError: + pass return config try: data = json.loads(CONFIG_PATH.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): config = cls.default() - config.save() + try: + config.save() + except OSError: + pass return config handlers = data.get("handlers", {}) + scanner = data.get("scanner", {}) + worker = scanner.get("worker", {}) + needs_save = ( + "scanner" not in data + or "worker" not in scanner + or "nice_increment" not in worker + or "memory_limit_mb" not in worker + or "timeout_seconds" not in worker + ) file_handler = handlers.get("file", {}) sequence_handler = handlers.get("sequence", {}) - return cls( + config = cls( file_handler=HandlerConfig( mode=file_handler.get("mode", "system"), command=file_handler.get("command", ""), @@ -91,7 +115,28 @@ def load(cls) -> "AppConfig": mode=sequence_handler.get("mode", "expand"), command=sequence_handler.get("command", ""), ), + scan_worker=ScanWorkerConfig( + nice_increment=int(worker.get("nice_increment", 15)), + memory_limit_mb=( + int(worker["memory_limit_mb"]) + if "memory_limit_mb" in worker + and worker.get("memory_limit_mb") is not None + else (None if "memory_limit_mb" in worker else 2048) + ), + timeout_seconds=( + int(worker["timeout_seconds"]) + if "timeout_seconds" in worker + and worker.get("timeout_seconds") is not None + else (None if "timeout_seconds" in worker else 30) + ), + ), ) + if needs_save: + try: + config.save() + except OSError: + pass + return config def save(self) -> None: CONFIG_DIR.mkdir(parents=True, exist_ok=True) @@ -105,7 +150,14 @@ def save(self) -> None: "mode": self.sequence_handler.mode, "command": self.sequence_handler.command, }, - } + }, + "scanner": { + "worker": { + "nice_increment": self.scan_worker.nice_increment, + "memory_limit_mb": self.scan_worker.memory_limit_mb, + "timeout_seconds": self.scan_worker.timeout_seconds, + } + }, } CONFIG_PATH.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8") diff --git a/sview/model.py b/sview/model.py index d909c06..5ead5f3 100644 --- a/sview/model.py +++ b/sview/model.py @@ -62,3 +62,42 @@ class BrowserItem: @property def missing_count(self) -> int: return len(self.missing or []) + + def to_dict(self) -> dict[str, object]: + return { + "path": self.path, + "item_type": self.item_type.value, + "name": self.name, + "display_name": self.display_name, + "frame_range": self.frame_range, + "pad": self.pad, + "count": self.count, + "missing": list(self.missing) if self.missing is not None else None, + "size_bytes": self.size_bytes, + "modified_time": self.modified_time, + "child_paths": list(self.child_paths) + if self.child_paths is not None + else None, + } + + @classmethod + def from_dict(cls, data: dict[str, object]) -> BrowserItem: + return cls( + path=str(data["path"]), + item_type=ItemType(str(data["item_type"])), + name=str(data["name"]), + display_name=str(data["display_name"]), + frame_range=str(data["frame_range"]) + if data["frame_range"] is not None + else None, + pad=str(data["pad"]) if data["pad"] is not None else None, + count=int(data["count"]), + missing=[int(value) for value in data["missing"]] + if data["missing"] is not None + else None, + size_bytes=int(data["size_bytes"]), + modified_time=float(data["modified_time"]), + child_paths=[str(value) for value in data["child_paths"]] + if data["child_paths"] is not None + else None, + ) diff --git a/sview/qt/app.py b/sview/qt/app.py index 0acc022..5b7bcaa 100644 --- a/sview/qt/app.py +++ b/sview/qt/app.py @@ -51,6 +51,7 @@ def main() -> int: print(__version__) return 0 + debug = _wants_debug(sys.argv[1:]) app = QApplication(sys.argv) try: ensure_pyseq_available() @@ -63,13 +64,13 @@ def main() -> int: app.setStyle("Fusion") _apply_dark_theme(app) initial_path = _parse_initial_path(sys.argv[1:]) - window = MainWindow(initial_path=initial_path) + window = MainWindow(initial_path=initial_path, debug=debug) window.show() return app.exec() def _parse_initial_path(args: list[str]) -> str | None: - filtered_args = [arg for arg in args if arg not in {"--version", "-V"}] + filtered_args = [arg for arg in args if arg not in {"--version", "-V", "--debug"}] if not filtered_args: return None candidate = Path(filtered_args[0]).expanduser() @@ -80,6 +81,10 @@ def _wants_version(args: list[str]) -> bool: return any(arg in {"--version", "-V"} for arg in args) +def _wants_debug(args: list[str]) -> bool: + return "--debug" in args + + def _apply_dark_theme(app: QApplication) -> None: palette = QPalette() palette.setColor(QPalette.ColorRole.Window, QColor("#232528")) diff --git a/sview/qt/main_window.py b/sview/qt/main_window.py index ce9091f..a0086aa 100644 --- a/sview/qt/main_window.py +++ b/sview/qt/main_window.py @@ -35,14 +35,12 @@ from __future__ import annotations -from pathlib import Path -from queue import Empty, Queue import json +from pathlib import Path import subprocess import sys -from threading import Event, Thread -from PySide6.QtCore import QTimer, Qt, QUrl +from PySide6.QtCore import QProcess, QTimer, Qt, QUrl from PySide6.QtGui import QAction, QCloseEvent, QDesktopServices, QGuiApplication from PySide6.QtWidgets import ( QFileDialog, @@ -66,7 +64,7 @@ from sview.qt.inspector import InspectorPanel from sview.qt.table import ContentsTable from sview.qt.tree import DirectoryTree -from sview.scanner import DirectoryScanner, ScanCancelled, ScanResult +from sview.scanner import ScanResult class MainWindow(QMainWindow): @@ -74,10 +72,12 @@ def __init__( self, controller: BrowserController | None = None, initial_path: str | Path | None = None, + debug: bool = False, ) -> None: super().__init__() self._controller = controller or BrowserController() self._config = AppConfig.load() + self._debug = debug self._initial_path = ( self._normalize_path(initial_path) if initial_path is not None @@ -88,10 +88,12 @@ def __init__( self._history_index = -1 self._pending_request: tuple[str, bool] | None = None self._active_request: tuple[str, bool] | None = None - self._load_thread: Thread | None = None - self._load_cancel_event: Event | None = None - self._load_queue: Queue[tuple[str, int, object]] = Queue() - self._load_token = 0 + self._load_process: QProcess | None = None + self._load_stdout_buffer = bytearray() + self._load_stderr_buffer = "" + self._load_stderr_partial = "" + self._load_cancelled = False + self._load_timed_out = False self.setWindowTitle("sview") self.resize(1400, 800) @@ -105,11 +107,12 @@ def __init__( self._main_splitter: QSplitter | None = None self._progress_timer = QTimer(self) - self._progress_timer.setInterval(50) - self._progress_timer.timeout.connect(self._process_worker_messages) self._busy_timer = QTimer(self) self._busy_timer.setInterval(30) self._busy_timer.timeout.connect(self._advance_busy_indicator) + self._scan_timeout_timer = QTimer(self) + self._scan_timeout_timer.setSingleShot(True) + self._scan_timeout_timer.timeout.connect(self._handle_scan_timeout) self._busy_value = 0 self._busy_direction = 1 @@ -284,10 +287,9 @@ def _connect_signals(self) -> None: def closeEvent(self, event: QCloseEvent) -> None: self._pending_request = None - if self._load_cancel_event is not None: - self._load_cancel_event.set() - if self._load_thread is not None and self._load_thread.is_alive(): - self._load_thread.join(timeout=0.5) + if self._load_process is not None: + self._load_process.kill() + self._load_process.waitForFinished(500) event.accept() def _choose_directory(self) -> None: @@ -357,76 +359,128 @@ def _handle_tree_selection(self) -> None: self._request_directory(path, add_to_history=True) def _request_directory(self, path: str | Path, add_to_history: bool) -> None: - requested_path = str(Path(path).expanduser()) - if self._load_thread is not None and self._load_thread.is_alive(): + requested_path = str(self._normalize_path(path)) + if self._is_loading(): self._pending_request = (requested_path, add_to_history) self.statusBar().showMessage(f"Queued {requested_path}") return self._active_request = (requested_path, add_to_history) self._set_loading_state(True, requested_path) - self._load_token += 1 - token = self._load_token - cancel_event = Event() - self._load_cancel_event = cancel_event - self._load_thread = Thread( - target=self._scan_directory_worker, - args=(requested_path, token, cancel_event), - daemon=True, - ) - self._progress_timer.start() - self._load_thread.start() - - def _scan_directory_worker( - self, path: str, token: int, cancel_event: Event - ) -> None: - scanner = DirectoryScanner() + self._load_cancelled = False + self._load_timed_out = False + self._load_stdout_buffer = bytearray() + self._load_stderr_buffer = "" + self._load_stderr_partial = "" + + process = QProcess(self) + process.setProgram(sys.executable) + arguments = ["-u", "-m", "sview.worker"] + if self._debug: + arguments.append("--debug") + arguments.append(requested_path) + process.setArguments(arguments) + process.readyReadStandardOutput.connect( + lambda process=process: self._read_scan_stdout(process) + ) + process.readyReadStandardError.connect( + lambda process=process: self._read_scan_stderr(process) + ) + process.errorOccurred.connect( + lambda error, process=process: self._handle_scan_process_error( + process, error + ) + ) + process.finished.connect( + lambda exit_code, exit_status, process=process: self._handle_scan_process_finished( + process, exit_code, exit_status + ) + ) + self._load_process = process + process.start() + timeout_seconds = self._config.scan_worker.timeout_seconds + if timeout_seconds is not None and timeout_seconds > 0: + self._scan_timeout_timer.start(timeout_seconds * 1000) - def send_progress(message: str) -> None: - self._load_queue.put(("progress", token, message)) + def _read_scan_stdout(self, process: QProcess) -> None: + if process is not self._load_process: + return + self._load_stdout_buffer.extend(bytes(process.readAllStandardOutput())) - try: - result = scanner.scan( - path, - cancel_check=cancel_event.is_set, - progress_callback=send_progress, - ) - except ScanCancelled: - self._load_queue.put(("cancelled", token, None)) + def _read_scan_stderr(self, process: QProcess) -> None: + if process is not self._load_process: + return + chunk = bytes(process.readAllStandardError()).decode("utf-8", "replace") + if not chunk: return - except Exception as exc: # pragma: no cover - UI failure path - self._load_queue.put(("failed", token, str(exc))) + self._load_stderr_buffer += chunk + self._load_stderr_partial += chunk + lines = self._load_stderr_partial.splitlines(keepends=True) + if lines and not lines[-1].endswith(("\n", "\r")): + self._load_stderr_partial = lines.pop() + else: + self._load_stderr_partial = "" + for line in lines: + text = line.strip() + if text: + if self._debug: + print(f"[sview scan] {text}", file=sys.stderr, flush=True) + self.statusBar().showMessage(text) + + def _handle_scan_process_error( + self, process: QProcess, error: QProcess.ProcessError + ) -> None: + if process is not self._load_process or self._load_cancelled: return - self._load_queue.put(("finished", token, result)) + if error is QProcess.ProcessError.FailedToStart: + message = process.errorString() or "Failed to start scan worker." + self._clear_scan_process() + self._handle_failed_scan(message) - def _process_worker_messages(self) -> None: - handled = False - while True: - try: - message_type, token, payload = self._load_queue.get_nowait() - except Empty: - break + def _handle_scan_process_finished( + self, process: QProcess, exit_code: int, exit_status: QProcess.ExitStatus + ) -> None: + if process is not self._load_process: + return + self._read_scan_stdout(process) + self._read_scan_stderr(process) - handled = True - if token != self._load_token: - continue + response_text = ( + bytes(self._load_stdout_buffer).decode("utf-8", "replace").strip() + ) + error_text = f"{self._load_stderr_buffer}{self._load_stderr_partial}".strip() + cancelled = self._load_cancelled + timed_out = self._load_timed_out - if message_type == "progress": - self.statusBar().showMessage(str(payload)) - elif message_type == "finished": - self._handle_finished_scan(payload) - elif message_type == "failed": - self._handle_failed_scan(str(payload)) - elif message_type == "cancelled": - self._handle_cancelled_scan() + self._clear_scan_process() - if handled and self._load_thread is None: - self._progress_timer.stop() + if timed_out: + self._handle_timed_out_scan(error_text) + return + if cancelled: + self._handle_cancelled_scan() + return + if exit_status is QProcess.ExitStatus.CrashExit: + self._handle_failed_scan(error_text or "Scan worker crashed.") + return + if exit_code != 0: + self._handle_failed_scan( + error_text or f"Scan worker exited with code {exit_code}." + ) + return + if not response_text: + self._handle_failed_scan("Scan worker returned no data.") + return + + try: + result = ScanResult.from_dict(json.loads(response_text)) + except (TypeError, ValueError, json.JSONDecodeError) as exc: + self._handle_failed_scan(f"Invalid scan response: {exc}") + return + self._handle_finished_scan(result) def _handle_finished_scan(self, result: object) -> None: request = self._active_request - self._load_thread = None - self._load_cancel_event = None self._set_loading_state(False) if request is None or not isinstance(result, ScanResult): return @@ -441,21 +495,55 @@ def _handle_finished_scan(self, result: object) -> None: self._drain_pending_request() def _handle_failed_scan(self, error_message: str) -> None: - self._load_thread = None - self._load_cancel_event = None self._active_request = None self._set_loading_state(False) + if self._debug and error_message: + print(f"[sview error] {error_message}", file=sys.stderr, flush=True) self.statusBar().showMessage(f"Failed to load directory: {error_message}", 5000) + dialog = QMessageBox(self) + dialog.setIcon(QMessageBox.Icon.Warning) + dialog.setWindowTitle("Scan failed") + dialog.setText("Failed to load directory.") + dialog.setInformativeText(self._summarize_error_message(error_message)) + details = error_message.strip() + if details and details != dialog.informativeText(): + dialog.setDetailedText(details) + dialog.exec() self._drain_pending_request() def _handle_cancelled_scan(self) -> None: - self._load_thread = None - self._load_cancel_event = None self._active_request = None self._set_loading_state(False) self.statusBar().showMessage("Scan cancelled", 3000) self._drain_pending_request() + def _handle_timed_out_scan(self, error_message: str) -> None: + self._active_request = None + self._set_loading_state(False) + timeout_seconds = self._config.scan_worker.timeout_seconds + summary = ( + f"Scan exceeded {timeout_seconds} seconds and was stopped." + if timeout_seconds is not None + else "Scan timed out and was stopped." + ) + if self._debug: + print(f"[sview error] {summary}", file=sys.stderr, flush=True) + if error_message: + print(error_message, file=sys.stderr, flush=True) + self.statusBar().showMessage(summary, 5000) + dialog = QMessageBox(self) + dialog.setIcon(QMessageBox.Icon.Warning) + dialog.setWindowTitle("Scan timed out") + dialog.setText(summary) + dialog.setInformativeText( + "This scan worker was terminated to protect system responsiveness." + ) + details = error_message.strip() + if details: + dialog.setDetailedText(details) + dialog.exec() + self._drain_pending_request() + def _apply_filter(self, text: str) -> None: needle = text.strip().lower() if not needle: @@ -688,7 +776,7 @@ def _push_history(self, path: str) -> None: self._update_navigation_buttons() def _update_navigation_buttons(self) -> None: - loading = self._load_thread is not None and self._load_thread.is_alive() + loading = self._is_loading() self._back_button.setEnabled(not loading and self._history_index > 0) self._up_button.setEnabled( not loading @@ -744,11 +832,26 @@ def _drain_pending_request(self) -> None: def _cancel_scan(self) -> None: self._pending_request = None - if self._load_cancel_event is None: + if self._load_process is None: return - self._load_cancel_event.set() + self._load_cancelled = True self._stop_button.setEnabled(False) self.statusBar().showMessage("Cancelling scan...") + self._load_process.kill() + + def _handle_scan_timeout(self) -> None: + if self._load_process is None: + return + self._load_timed_out = True + self._stop_button.setEnabled(False) + self.statusBar().showMessage("Scan timed out, stopping worker...") + if self._debug: + print( + "[sview scan] timeout reached, killing worker", + file=sys.stderr, + flush=True, + ) + self._load_process.kill() def _update_status_bar(self) -> None: count = len(self._visible_items) @@ -797,6 +900,23 @@ def _collapse_expanded_sequence(self) -> bool: ) return True + def _is_loading(self) -> bool: + return ( + self._load_process is not None + and self._load_process.state() != QProcess.ProcessState.NotRunning + ) + + def _clear_scan_process(self) -> None: + self._scan_timeout_timer.stop() + if self._load_process is not None: + self._load_process.deleteLater() + self._load_process = None + self._load_stdout_buffer = bytearray() + self._load_stderr_buffer = "" + self._load_stderr_partial = "" + self._load_cancelled = False + self._load_timed_out = False + def _open_repo_page(self) -> None: QDesktopServices.openUrl(QUrl(get_repository_url())) @@ -867,3 +987,11 @@ def _format_size(size_bytes: int) -> str: break size /= 1024.0 return f"{size:.1f} {unit}" + + @staticmethod + def _summarize_error_message(error_message: str) -> str: + lines = [line.strip() for line in error_message.splitlines() if line.strip()] + for line in reversed(lines): + if line.startswith("ERROR:"): + return line.removeprefix("ERROR:").strip() + return lines[-1] if lines else "Unknown scan error." diff --git a/sview/scanner.py b/sview/scanner.py index 7ca5341..2b7758b 100644 --- a/sview/scanner.py +++ b/sview/scanner.py @@ -58,6 +58,23 @@ class ScanResult: grouped_items: list[BrowserItem] raw_items: list[BrowserItem] + def to_dict(self) -> dict[str, object]: + return { + "path": str(self.path), + "grouped_items": [item.to_dict() for item in self.grouped_items], + "raw_items": [item.to_dict() for item in self.raw_items], + } + + @classmethod + def from_dict(cls, data: dict[str, object]) -> ScanResult: + grouped_items = [BrowserItem.from_dict(item) for item in data["grouped_items"]] + raw_items = [BrowserItem.from_dict(item) for item in data["raw_items"]] + return cls( + path=Path(str(data["path"])), + grouped_items=grouped_items, + raw_items=raw_items, + ) + def ensure_pyseq_available() -> None: if pyseq is None: @@ -178,7 +195,7 @@ def _build_grouped_items( frame_range=frame_range, pad=pad_value, count=len(sequence), - missing=list(sequence.missing()), + missing=self._normalize_missing(sequence.missing()), size_bytes=int(sequence.size), modified_time=float(sequence.mtime), child_paths=child_paths, @@ -202,3 +219,15 @@ def _build_grouped_items( def _raise_if_cancelled(cancel_check: Callable[[], bool] | None) -> None: if cancel_check is not None and cancel_check(): raise ScanCancelled() + + @staticmethod + def _normalize_missing(values: object) -> list[int]: + normalized: list[int] = [] + if values is None: + return normalized + for value in values: + if isinstance(value, range): + normalized.extend(int(frame) for frame in value) + else: + normalized.append(int(value)) + return normalized diff --git a/sview/worker.py b/sview/worker.py new file mode 100644 index 0000000..31a9631 --- /dev/null +++ b/sview/worker.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2026, Ryan Galloway (ryan@rsgalloway.com) +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# - Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# - Neither the name of the software nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# ----------------------------------------------------------------------------- + +""" +Runs directory scans in a subprocess and emits JSON results for the main UI. +""" + +from __future__ import annotations + +import json +import os +import sys +import traceback + +try: + import resource +except ImportError: # pragma: no cover - platform-dependent + resource = None + +from sview.config import AppConfig +from sview.scanner import DirectoryScanner + + +def main(argv: list[str] | None = None) -> int: + args = list(sys.argv[1:] if argv is None else argv) + debug = False + if "--debug" in args: + debug = True + args = [arg for arg in args if arg != "--debug"] + + if len(args) != 1: + print("Usage: python -m sview.worker [--debug] ", file=sys.stderr) + return 2 + + path = args[0] + config = AppConfig.load() + _apply_worker_limits(config, debug=debug) + scanner = DirectoryScanner() + try: + result = scanner.scan(path, progress_callback=_emit_progress) + except MemoryError: + print( + "ERROR: scan worker exceeded its configured memory limit.", + file=sys.stderr, + flush=True, + ) + if debug: + traceback.print_exc(file=sys.stderr) + return 1 + except Exception as exc: + print(f"ERROR: {exc}", file=sys.stderr, flush=True) + if debug: + traceback.print_exc(file=sys.stderr) + return 1 + + sys.stdout.write(json.dumps(result.to_dict())) + sys.stdout.flush() + return 0 + + +def _emit_progress(message: str) -> None: + print(message, file=sys.stderr, flush=True) + + +def _apply_worker_limits(config: AppConfig, debug: bool = False) -> None: + worker = config.scan_worker + + if worker.nice_increment: + try: + os.nice(worker.nice_increment) + if debug: + print( + f"[sview scan] applied nice increment {worker.nice_increment}", + file=sys.stderr, + flush=True, + ) + except (AttributeError, OSError): # pragma: no cover - platform-dependent + if debug: + print( + "[sview scan] could not adjust process priority", + file=sys.stderr, + flush=True, + ) + + if resource is None or worker.memory_limit_mb is None: + return + + limit_bytes = int(worker.memory_limit_mb) * 1024 * 1024 + try: + resource.setrlimit(resource.RLIMIT_AS, (limit_bytes, limit_bytes)) + if debug: + print( + f"[sview scan] applied memory limit {worker.memory_limit_mb} MB", + file=sys.stderr, + flush=True, + ) + except (OSError, ValueError): # pragma: no cover - platform-dependent + if debug: + print( + "[sview scan] could not apply memory limit", + file=sys.stderr, + flush=True, + ) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/test_scanner.py b/tests/test_scanner.py index d8b36ac..2407c38 100644 --- a/tests/test_scanner.py +++ b/tests/test_scanner.py @@ -6,7 +6,7 @@ from sview.controller import BrowserController from sview.model import ItemType -from sview.scanner import DirectoryScanner +from sview.scanner import DirectoryScanner, ScanResult def _touch(path: Path) -> None: @@ -82,6 +82,25 @@ def test_controller_can_expand_and_collapse_sequence(self) -> None: self.assertEqual(len(collapsed_items), 1) self.assertIs(collapsed_items[0].item_type, ItemType.SEQUENCE) + def test_scan_result_round_trip_serialization(self) -> None: + with tempfile.TemporaryDirectory() as tmp_dir: + root = Path(tmp_dir) + _touch(root / "plate.0001.jpg") + _touch(root / "plate.0002.jpg") + + result = DirectoryScanner().scan(root) + restored = ScanResult.from_dict(result.to_dict()) + + self.assertEqual(restored.path, result.path) + self.assertEqual( + [item.display_name for item in restored.grouped_items], + [item.display_name for item in result.grouped_items], + ) + self.assertEqual( + [item.path for item in restored.raw_items], + [item.path for item in result.raw_items], + ) + if __name__ == "__main__": unittest.main() From d298484fb472bf2fb4c41b2fec6c170e604cd911 Mon Sep 17 00:00:00 2001 From: Ryan Galloway Date: Sun, 5 Apr 2026 11:32:02 -0700 Subject: [PATCH 2/4] Move scanning to a subprocess worker and streamline first paint --- CHANGELOG.md | 1 + README.md | 5 ++- sview/config.py | 25 +++++++++---- sview/controller.py | 11 ++++++ sview/qt/inspector.py | 2 ++ sview/qt/main_window.py | 78 ++++++++++++++++++++++++++++++++++++++++- sview/qt/table.py | 20 +++++++++++ sview/scanner.py | 48 +++++++++++-------------- tests/test_scanner.py | 4 +-- 9 files changed, 156 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e934839..8dde810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Moved directory scanning into a subprocess worker for safer cancellation - Added scan worker guardrails including priority, memory, and timeout controls - Improved scan error reporting with dialogs and optional `--debug` terminal output +- Disabled the default worker memory cap to avoid false positives on normal scans ## 0.1.1 - 2026-04-05 diff --git a/README.md b/README.md index fee6467..f7035ce 100644 --- a/README.md +++ b/README.md @@ -57,9 +57,12 @@ memory limit: "scanner": { "worker": { "nice_increment": 15, - "memory_limit_mb": 2048, + "memory_limit_mb": null, "timeout_seconds": 30 } } } ``` + +`memory_limit_mb` is opt-in. Leave it as `null` unless you specifically want a hard +address-space cap on the worker process. diff --git a/sview/config.py b/sview/config.py index 197461d..2234e21 100644 --- a/sview/config.py +++ b/sview/config.py @@ -56,7 +56,7 @@ class HandlerConfig: @dataclass class ScanWorkerConfig: nice_increment: int = 15 - memory_limit_mb: int | None = 2048 + memory_limit_mb: int | None = None timeout_seconds: int | None = 30 @@ -97,6 +97,7 @@ def load(cls) -> "AppConfig": handlers = data.get("handlers", {}) scanner = data.get("scanner", {}) worker = scanner.get("worker", {}) + memory_limit_mb = cls._load_memory_limit(worker) needs_save = ( "scanner" not in data or "worker" not in scanner @@ -117,12 +118,7 @@ def load(cls) -> "AppConfig": ), scan_worker=ScanWorkerConfig( nice_increment=int(worker.get("nice_increment", 15)), - memory_limit_mb=( - int(worker["memory_limit_mb"]) - if "memory_limit_mb" in worker - and worker.get("memory_limit_mb") is not None - else (None if "memory_limit_mb" in worker else 2048) - ), + memory_limit_mb=memory_limit_mb, timeout_seconds=( int(worker["timeout_seconds"]) if "timeout_seconds" in worker @@ -161,6 +157,21 @@ def save(self) -> None: } CONFIG_PATH.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8") + @staticmethod + def _load_memory_limit(worker: dict[str, object]) -> int | None: + if "memory_limit_mb" not in worker: + return None + + value = worker.get("memory_limit_mb") + if value is None: + return None + + memory_limit_mb = int(value) + # Treat the old 0.1.2 default as "unset" because RLIMIT_AS proved too blunt. + if memory_limit_mb == 2048: + return None + return memory_limit_mb + def build_command(command_template: str, path: str) -> list[str]: return shlex.split(command_template.format(path=path)) diff --git a/sview/controller.py b/sview/controller.py index 270e8d3..ec619d7 100644 --- a/sview/controller.py +++ b/sview/controller.py @@ -107,6 +107,17 @@ def apply_scan_result(self, result: ScanResult) -> list[BrowserItem]: self._refresh_current_items() return self.current_items + def update_sequence_metadata( + self, item_path: str, size_bytes: int, modified_time: float + ) -> BrowserItem | None: + for item in self._grouped_items: + if item.path != item_path: + continue + item.size_bytes = size_bytes + item.modified_time = modified_time + return item + return None + def _refresh_current_items(self) -> None: self._current_items = ( self._grouped_items if self._grouped_view else self._raw_items diff --git a/sview/qt/inspector.py b/sview/qt/inspector.py index cbb4c22..744c049 100644 --- a/sview/qt/inspector.py +++ b/sview/qt/inspector.py @@ -194,4 +194,6 @@ def _format_size(size_bytes: int) -> str: def _format_modified(timestamp: float) -> str: from datetime import datetime + if timestamp <= 0: + return "-" return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M") diff --git a/sview/qt/main_window.py b/sview/qt/main_window.py index a0086aa..238f7bf 100644 --- a/sview/qt/main_window.py +++ b/sview/qt/main_window.py @@ -35,8 +35,10 @@ from __future__ import annotations +from concurrent.futures import ThreadPoolExecutor import json from pathlib import Path +from queue import Empty, Queue import subprocess import sys @@ -68,6 +70,8 @@ class MainWindow(QMainWindow): + SEQUENCE_METADATA_WORKERS = 4 + def __init__( self, controller: BrowserController | None = None, @@ -94,6 +98,13 @@ def __init__( self._load_stderr_partial = "" self._load_cancelled = False self._load_timed_out = False + self._metadata_executor = ThreadPoolExecutor( + max_workers=self.SEQUENCE_METADATA_WORKERS, + thread_name_prefix="sview-seqmeta", + ) + self._metadata_queue: Queue[tuple[int, str, int, float]] = Queue() + self._metadata_token = 0 + self._metadata_pending_count = 0 self.setWindowTitle("sview") self.resize(1400, 800) @@ -110,6 +121,9 @@ def __init__( self._busy_timer = QTimer(self) self._busy_timer.setInterval(30) self._busy_timer.timeout.connect(self._advance_busy_indicator) + self._metadata_timer = QTimer(self) + self._metadata_timer.setInterval(30) + self._metadata_timer.timeout.connect(self._process_sequence_metadata_updates) self._scan_timeout_timer = QTimer(self) self._scan_timeout_timer.setSingleShot(True) self._scan_timeout_timer.timeout.connect(self._handle_scan_timeout) @@ -290,6 +304,7 @@ def closeEvent(self, event: QCloseEvent) -> None: if self._load_process is not None: self._load_process.kill() self._load_process.waitForFinished(500) + self._metadata_executor.shutdown(wait=False) event.accept() def _choose_directory(self) -> None: @@ -360,6 +375,8 @@ def _handle_tree_selection(self) -> None: def _request_directory(self, path: str | Path, add_to_history: bool) -> None: requested_path = str(self._normalize_path(path)) + self._metadata_token += 1 + self._metadata_pending_count = 0 if self._is_loading(): self._pending_request = (requested_path, add_to_history) self.statusBar().showMessage(f"Queued {requested_path}") @@ -487,6 +504,7 @@ def _handle_finished_scan(self, result: object) -> None: items = self._controller.apply_scan_result(result) self._visible_items = items + self._start_sequence_metadata_enrichment(result) if request[1]: self._push_history(str(result.path)) self._active_request = None @@ -864,6 +882,64 @@ def _update_status_bar(self) -> None: ) self._update_navigation_buttons() + def _start_sequence_metadata_enrichment(self, result: ScanResult) -> None: + self._metadata_pending_count = 0 + self._metadata_timer.stop() + return + + def _compute_sequence_metadata( + self, + token: int, + item_path: str, + child_paths: list[str], + raw_lookup: dict[str, BrowserItem], + ) -> None: + size_bytes = 0 + modified_time = 0.0 + for child_path in child_paths: + raw_item = raw_lookup.get(child_path) + if raw_item is None: + continue + size_bytes += raw_item.size_bytes + if raw_item.modified_time > modified_time: + modified_time = raw_item.modified_time + self._metadata_queue.put((token, item_path, size_bytes, modified_time)) + + def _process_sequence_metadata_updates(self) -> None: + handled = False + while True: + try: + ( + token, + item_path, + size_bytes, + modified_time, + ) = self._metadata_queue.get_nowait() + except Empty: + break + + handled = True + if token != self._metadata_token: + continue + + self._metadata_pending_count = max(0, self._metadata_pending_count - 1) + item = self._controller.update_sequence_metadata( + item_path, size_bytes, modified_time + ) + if item is None: + continue + self._table.update_item(item) + if ( + self._inspector.current_item is not None + and self._inspector.current_item.path == item.path + ): + self._inspector.set_item(item) + + if handled: + self._update_status_bar() + if self._metadata_pending_count == 0: + self._metadata_timer.stop() + def _advance_busy_indicator(self) -> None: self._busy_value += self._busy_direction * 4 if self._busy_value >= 100: @@ -993,5 +1069,5 @@ def _summarize_error_message(error_message: str) -> str: lines = [line.strip() for line in error_message.splitlines() if line.strip()] for line in reversed(lines): if line.startswith("ERROR:"): - return line.removeprefix("ERROR:").strip() + return line[len("ERROR:") :].strip() return lines[-1] if lines else "Unknown scan error." diff --git a/sview/qt/table.py b/sview/qt/table.py index 96c8152..86ae82c 100644 --- a/sview/qt/table.py +++ b/sview/qt/table.py @@ -155,6 +155,24 @@ def current_browser_item(self) -> BrowserItem | None: return None return selected[0].data(Qt.ItemDataRole.UserRole) + def update_item(self, item: BrowserItem) -> None: + for row in range(self.rowCount()): + row_item = self.item(row, 0) + if row_item is None: + continue + row_browser_item = row_item.data(Qt.ItemDataRole.UserRole) + if row_browser_item is None or row_browser_item.path != item.path: + continue + size_item = self.item(row, 5) + modified_item = self.item(row, 6) + if size_item is not None: + size_item.setText(self._format_size(item.size_bytes)) + size_item.setData(Qt.ItemDataRole.UserRole, item) + if modified_item is not None: + modified_item.setText(self._format_mtime(item.modified_time)) + modified_item.setData(Qt.ItemDataRole.UserRole, item) + return + def _emit_context_request(self, position) -> None: item = None table_item = self.itemAt(position) @@ -207,4 +225,6 @@ def _format_size(size_bytes: int) -> str: @staticmethod def _format_mtime(timestamp: float) -> str: + if timestamp <= 0: + return "" return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M") diff --git a/sview/scanner.py b/sview/scanner.py index 2b7758b..d9f1f0f 100644 --- a/sview/scanner.py +++ b/sview/scanner.py @@ -130,11 +130,6 @@ def _build_raw_items( for entry in entries: self._raise_if_cancelled(cancel_check) - try: - stat = entry.stat() - except OSError: - continue - is_directory = entry.is_dir() items.append( BrowserItem( @@ -146,8 +141,8 @@ def _build_raw_items( pad=None, count=0 if is_directory else 1, missing=None, - size_bytes=0 if is_directory else stat.st_size, - modified_time=stat.st_mtime, + size_bytes=0, + modified_time=0.0, child_paths=None, ) ) @@ -183,21 +178,32 @@ def _build_grouped_items( child_paths = [str(member.path) for member in members] consumed_paths.update(child_paths) - frame_range = sequence.format("%R").strip("[]") + start_frame = int(getattr(members[0], "frame", 0) or 0) + end_frame = int(getattr(members[-1], "frame", 0) or 0) + if start_frame and end_frame: + frame_range = ( + str(start_frame) + if start_frame == end_frame + else f"{start_frame}-{end_frame}" + ) + else: + frame_range = None pad_width = len(getattr(members[0], "digits", [""])[0]) if members else 0 - pad_value = f"%0{pad_width}d" if pad_width else sequence.format("%p") + pad_value = f"%0{pad_width}d" if pad_width else "%d" + head = members[0].head + tail = members[0].tail grouped.append( BrowserItem( - path=str(sequence.path()), + path=str(directory / f"{head}{pad_value}{tail}"), item_type=ItemType.SEQUENCE, - name=f"{sequence.head()}{pad_value}{sequence.tail()}", - display_name=f"{sequence.head()}{pad_value}{sequence.tail()}", + name=f"{head}{pad_value}{tail}", + display_name=f"{head}{pad_value}{tail}", frame_range=frame_range, pad=pad_value, count=len(sequence), - missing=self._normalize_missing(sequence.missing()), - size_bytes=int(sequence.size), - modified_time=float(sequence.mtime), + missing=None, + size_bytes=0, + modified_time=0.0, child_paths=child_paths, ) ) @@ -219,15 +225,3 @@ def _build_grouped_items( def _raise_if_cancelled(cancel_check: Callable[[], bool] | None) -> None: if cancel_check is not None and cancel_check(): raise ScanCancelled() - - @staticmethod - def _normalize_missing(values: object) -> list[int]: - normalized: list[int] = [] - if values is None: - return normalized - for value in values: - if isinstance(value, range): - normalized.extend(int(frame) for frame in value) - else: - normalized.append(int(value)) - return normalized diff --git a/tests/test_scanner.py b/tests/test_scanner.py index 2407c38..edb0f32 100644 --- a/tests/test_scanner.py +++ b/tests/test_scanner.py @@ -32,9 +32,9 @@ def test_sequence_grouping_and_missing_frames(self) -> None: if item.item_type is ItemType.SEQUENCE ) self.assertEqual(sequence.display_name, "shotA.%04d.exr") - self.assertEqual(sequence.frame_range, "1001-1002, 1004") + self.assertEqual(sequence.frame_range, "1001-1004") self.assertEqual(sequence.count, 3) - self.assertEqual(sequence.missing, [1003]) + self.assertIsNone(sequence.missing) self.assertEqual( sequence.child_paths, [ From a5be93fca4c38b7a792afc7653d35f5f055b5ce1 Mon Sep 17 00:00:00 2001 From: Ryan Galloway Date: Sun, 5 Apr 2026 13:15:45 -0700 Subject: [PATCH 3/4] Polish browser UI with icon mode, sidebar controls, and theme updates --- README.md | 6 + sview.png | Bin 136970 -> 67785 bytes sview/config.py | 16 ++ sview/qt/app.py | 106 +++++++----- sview/qt/icon_view.py | 184 +++++++++++++++++++++ sview/qt/inspector.py | 10 ++ sview/qt/main_window.py | 357 +++++++++++++++++++++++++++++++++------- sview/qt/table.py | 27 ++- 8 files changed, 590 insertions(+), 116 deletions(-) create mode 100644 sview/qt/icon_view.py diff --git a/README.md b/README.md index f7035ce..5088625 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,12 @@ On first launch, `sview` writes a user config file to: ~/.config/sview/config.json ``` +It also stores lightweight UI state in: + +```bash +~/.config/sview/ui_state.json +``` + This file controls default file and sequence handlers, including custom commands for double-click actions. diff --git a/sview.png b/sview.png index 84f1423dd0824bfcd25f14fb578d6bb7be78b2b6..e3c05739d87ce40e420286368f8af846c58bcd27 100644 GIT binary patch literal 67785 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 z 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 S!)$vs6C5VB?mms*WS}ol;z2$gV4I2R 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 tpFg%&_ZAsZ+{luBR(A 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
sEM~8U(=uml2e3NRMg>c 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

>zC2F+e%c5tdK5HW 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 LDqHc|IPhNpIZ5pB diff --git a/sview/config.py b/sview/config.py index 2234e21..0cf793f 100644 --- a/sview/config.py +++ b/sview/config.py @@ -44,6 +44,7 @@ CONFIG_DIR = Path.home() / ".config" / "sview" CONFIG_PATH = CONFIG_DIR / "config.json" +UI_STATE_PATH = CONFIG_DIR / "ui_state.json" DEFAULT_REPOSITORY_URL = "https://github.com/rsgalloway/sview" @@ -191,3 +192,18 @@ def get_repository_url() -> str: return url.strip() return DEFAULT_REPOSITORY_URL + + +def load_ui_state() -> dict[str, object]: + if not UI_STATE_PATH.exists(): + return {} + try: + data = json.loads(UI_STATE_PATH.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + return {} + return data if isinstance(data, dict) else {} + + +def save_ui_state(state: dict[str, object]) -> None: + CONFIG_DIR.mkdir(parents=True, exist_ok=True) + UI_STATE_PATH.write_text(json.dumps(state, indent=2) + "\n", encoding="utf-8") diff --git a/sview/qt/app.py b/sview/qt/app.py index 5b7bcaa..545fe89 100644 --- a/sview/qt/app.py +++ b/sview/qt/app.py @@ -87,95 +87,110 @@ def _wants_debug(args: list[str]) -> bool: def _apply_dark_theme(app: QApplication) -> None: palette = QPalette() - palette.setColor(QPalette.ColorRole.Window, QColor("#232528")) - palette.setColor(QPalette.ColorRole.WindowText, QColor("#e4e6e8")) - palette.setColor(QPalette.ColorRole.Base, QColor("#191b1e")) - palette.setColor(QPalette.ColorRole.AlternateBase, QColor("#202327")) - palette.setColor(QPalette.ColorRole.ToolTipBase, QColor("#191b1e")) - palette.setColor(QPalette.ColorRole.ToolTipText, QColor("#f2f3f5")) - palette.setColor(QPalette.ColorRole.Text, QColor("#e4e6e8")) - palette.setColor(QPalette.ColorRole.Button, QColor("#2c2f34")) - palette.setColor(QPalette.ColorRole.ButtonText, QColor("#edf0f2")) - palette.setColor(QPalette.ColorRole.Highlight, QColor("#454b53")) + palette.setColor(QPalette.ColorRole.Window, QColor("#14191e")) + palette.setColor(QPalette.ColorRole.WindowText, QColor("#dbe2e8")) + palette.setColor(QPalette.ColorRole.Base, QColor("#11161b")) + palette.setColor(QPalette.ColorRole.AlternateBase, QColor("#171d22")) + palette.setColor(QPalette.ColorRole.ToolTipBase, QColor("#11161b")) + palette.setColor(QPalette.ColorRole.ToolTipText, QColor("#f2f5f8")) + palette.setColor(QPalette.ColorRole.Text, QColor("#dbe2e8")) + palette.setColor(QPalette.ColorRole.Button, QColor("#1f262d")) + palette.setColor(QPalette.ColorRole.ButtonText, QColor("#edf2f7")) + palette.setColor(QPalette.ColorRole.Highlight, QColor("#313b44")) palette.setColor(QPalette.ColorRole.HighlightedText, QColor("#ffffff")) - palette.setColor(QPalette.ColorRole.PlaceholderText, QColor("#808790")) + palette.setColor(QPalette.ColorRole.PlaceholderText, QColor("#75818d")) app.setPalette(palette) app.setStyleSheet( """ QWidget { font-size: 12px; } - QMainWindow, QTreeView, QTableWidget, QLineEdit, QPushButton, QLabel { - background-color: #25282c; - color: #e4e6e8; + QTreeView, QTableWidget, QLineEdit, QPushButton, QLabel, QListWidget { + background-color: #1e252c; + color: #dbe2e8; + } + QMainWindow, QWidget#mainContent { + background-color: #13191f; + color: #dbe2e8; } QHeaderView::section { - background-color: #2d3136; - color: #d9dde1; + background-color: #1e252c; + color: #d4dde4; padding: 4px 6px; border: 0; - border-right: 1px solid #3d4248; + border-right: 1px solid #29333c; } - QTreeView, QTableWidget, QLineEdit { - background-color: #1d2024; - border: 1px solid #30343a; + QTreeView, QTableWidget, QLineEdit, QListWidget { + background-color: #161d23; + border: 1px solid #222c34; border-radius: 3px; } + QTreeView { + background-color: #171f26; + } QScrollBar:vertical { - background: #1b1e22; + background: #10161a; width: 10px; margin: 2px; } QScrollBar::handle:vertical { - background: #474c53; + background: #36424c; min-height: 28px; border-radius: 4px; } QScrollBar::handle:vertical:hover { - background: #5a6068; + background: #414f5a; } QScrollBar:horizontal { - background: #1b1e22; + background: #10161a; height: 10px; margin: 2px; } QScrollBar::handle:horizontal { - background: #474c53; + background: #36424c; min-width: 28px; border-radius: 4px; } QScrollBar::handle:horizontal:hover { - background: #5a6068; + background: #414f5a; } QScrollBar::add-line, QScrollBar::sub-line, QScrollBar::add-page, QScrollBar::sub-page { background: transparent; border: none; } QTableWidget::item:selected, QTreeView::item:selected { - background-color: #40454d; + background-color: #2c353d; color: white; } QPushButton { - background-color: #2f3338; - border: 1px solid #393e45; + background-color: #20282f; + border: 1px solid #29333c; border-radius: 3px; padding: 4px 9px; min-height: 24px; } QPushButton:checked { - background-color: #3b4047; - border-color: #474d55; + background-color: #2b3640; + border-color: #34414d; } QPushButton:disabled { - color: #727881; - background-color: #272b30; + color: #697581; + background-color: #1a2127; + } + QToolButton { + background: transparent; + border: 0; + color: #83919e; + } + QToolButton:hover { + color: #d6dde4; } QStatusBar { - background-color: #1d2024; - color: #bfc4ca; + background-color: #141b20; + color: #b6c1ca; } QSplitter::handle { - background-color: #4a4f56; + background-color: #36414a; width: 1px; } QLabel#inspectorTitle { @@ -183,9 +198,26 @@ def _apply_dark_theme(app: QApplication) -> None: font-weight: 600; } QLabel#inspectorSubtitle { - color: #959ca5; + color: #8998a5; margin-bottom: 6px; } + QWidget#iconCard { + background-color: #1c232a; + border: 1px solid #252f37; + border-radius: 6px; + } + QWidget#iconCard:hover { + background-color: #212a32; + border-color: #2f3b45; + } + QLabel#iconCardTitle { + font-size: 13px; + font-weight: 600; + color: #eef3f7; + } + QLabel#iconCardSubtitle { + color: #99a8b3; + } """ ) diff --git a/sview/qt/icon_view.py b/sview/qt/icon_view.py new file mode 100644 index 0000000..58c6120 --- /dev/null +++ b/sview/qt/icon_view.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2026, Ryan Galloway (ryan@rsgalloway.com) +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# - Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# - Neither the name of the software nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# ----------------------------------------------------------------------------- + +""" +Contains an icon-based center-pane browser for sview. +""" + +from __future__ import annotations + +from datetime import datetime + +from PySide6.QtCore import QSize, Qt, Signal +from PySide6.QtWidgets import ( + QHBoxLayout, + QLabel, + QListWidget, + QListWidgetItem, + QStyle, + QVBoxLayout, + QWidget, +) + +from sview.model import BrowserItem, ItemType + + +class ContentsIconView(QListWidget): + context_requested = Signal(object, object) + CARD_WIDTH = 270 + CARD_HEIGHT = 88 + + def __init__(self) -> None: + super().__init__() + self.setViewMode(QListWidget.ViewMode.IconMode) + self.setResizeMode(QListWidget.ResizeMode.Adjust) + self.setMovement(QListWidget.Movement.Static) + self.setWrapping(True) + self.setSelectionMode(QListWidget.SelectionMode.SingleSelection) + self.setSpacing(14) + self.setIconSize(QSize(44, 44)) + self.setGridSize(QSize(self.CARD_WIDTH, self.CARD_HEIGHT)) + self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) + self.customContextMenuRequested.connect(self._emit_context_request) + + def set_items(self, items: list[BrowserItem]) -> None: + self.clear() + for item in items: + list_item = QListWidgetItem() + list_item.setData(Qt.ItemDataRole.UserRole, item) + list_item.setSizeHint(QSize(self.CARD_WIDTH - 12, self.CARD_HEIGHT - 10)) + self.addItem(list_item) + self.setItemWidget(list_item, self._build_card(item)) + + def current_browser_item(self) -> BrowserItem | None: + current = self.currentItem() + if current is None: + return None + return current.data(Qt.ItemDataRole.UserRole) + + def update_item(self, item: BrowserItem) -> None: + for row in range(self.count()): + list_item = self.item(row) + if list_item is None: + continue + browser_item = list_item.data(Qt.ItemDataRole.UserRole) + if browser_item is None or browser_item.path != item.path: + continue + list_item.setData(Qt.ItemDataRole.UserRole, item) + self.setItemWidget(list_item, self._build_card(item)) + return + + def _emit_context_request(self, position) -> None: + item = self.itemAt(position) + browser_item = item.data(Qt.ItemDataRole.UserRole) if item is not None else None + if item is not None: + self.setCurrentItem(item) + self.context_requested.emit(browser_item, self.viewport().mapToGlobal(position)) + + def _icon(self, item: BrowserItem): + if item.item_type is ItemType.DIRECTORY: + return self.style().standardIcon(QStyle.StandardPixmap.SP_DirIcon) + if item.item_type is ItemType.SEQUENCE: + return self.style().standardIcon( + QStyle.StandardPixmap.SP_FileDialogDetailedView + ) + return self.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon) + + def _build_card(self, item: BrowserItem) -> QWidget: + card = QWidget() + card.setObjectName("iconCard") + layout = QHBoxLayout(card) + layout.setContentsMargins(14, 12, 14, 12) + layout.setSpacing(12) + + icon_label = QLabel() + icon_label.setPixmap(self._icon(item).pixmap(self.iconSize())) + icon_label.setFixedSize(48, 48) + icon_label.setAlignment(Qt.AlignmentFlag.AlignCenter) + + name_label = QLabel(item.display_name) + name_label.setObjectName("iconCardTitle") + name_label.setWordWrap(True) + + subtitle_label = QLabel(self._secondary_text(item)) + subtitle_label.setObjectName("iconCardSubtitle") + subtitle_label.setWordWrap(True) + + text_layout = QVBoxLayout() + text_layout.setContentsMargins(0, 0, 0, 0) + text_layout.setSpacing(2) + text_layout.addWidget(name_label) + text_layout.addWidget(subtitle_label) + text_layout.addStretch(1) + + layout.addWidget(icon_label, 0, Qt.AlignmentFlag.AlignTop) + layout.addLayout(text_layout, 1) + return card + + def _secondary_text(self, item: BrowserItem) -> str: + if item.item_type is ItemType.DIRECTORY: + return self._format_mtime(item.modified_time) or "Folder" + if item.item_type is ItemType.SEQUENCE: + parts = [item.frame_range or f"{item.count} frames"] + size_text = self._format_size(item.size_bytes) + if size_text: + parts.append(size_text) + modified_text = self._format_mtime(item.modified_time) + if modified_text: + parts.append(modified_text) + return " · ".join(parts) + parts = [] + size_text = self._format_size(item.size_bytes) + if size_text: + parts.append(size_text) + modified_text = self._format_mtime(item.modified_time) + if modified_text: + parts.append(modified_text) + return " · ".join(parts) or "File" + + @staticmethod + def _format_size(size_bytes: int) -> str: + if size_bytes <= 0: + return "" + units = ["B", "KB", "MB", "GB", "TB"] + size = float(size_bytes) + unit = units[0] + for unit in units: + if size < 1024.0 or unit == units[-1]: + break + size /= 1024.0 + return f"{size:.1f} {unit}" + + @staticmethod + def _format_mtime(timestamp: float) -> str: + if timestamp <= 0: + return "" + return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M") diff --git a/sview/qt/inspector.py b/sview/qt/inspector.py index 744c049..540ec15 100644 --- a/sview/qt/inspector.py +++ b/sview/qt/inspector.py @@ -70,6 +70,8 @@ def __init__(self) -> None: self.copy_path_button = QPushButton("Copy Path") self.copy_pattern_button = QPushButton("Copy Pattern") + self.find_missing_button = QPushButton("Find Missing") + self.get_size_button = QPushButton("Get Size") self.expand_button = QPushButton("Expand Sequence") self.close_button = QPushButton() self.close_button.setIcon( @@ -110,6 +112,10 @@ def __init__(self) -> None: button_row.addWidget(self.copy_path_button) button_row.addWidget(self.copy_pattern_button) layout.addLayout(button_row) + metadata_row = QHBoxLayout() + metadata_row.addWidget(self.find_missing_button) + metadata_row.addWidget(self.get_size_button) + layout.addLayout(metadata_row) layout.addWidget(self.expand_button) self.clear_details() @@ -130,6 +136,8 @@ def clear_details(self) -> None: label.setText("-") self.copy_path_button.setEnabled(False) self.copy_pattern_button.setEnabled(False) + self.find_missing_button.setEnabled(False) + self.get_size_button.setEnabled(False) self.expand_button.setEnabled(False) self.expand_button.setText("Expand Sequence") @@ -150,6 +158,8 @@ def set_item(self, item: BrowserItem) -> None: self.copy_path_button.setEnabled(True) self.copy_pattern_button.setEnabled(item.item_type is ItemType.SEQUENCE) + self.find_missing_button.setEnabled(item.item_type is ItemType.SEQUENCE) + self.get_size_button.setEnabled(item.item_type is ItemType.SEQUENCE) self.expand_button.setEnabled(item.item_type is ItemType.SEQUENCE) self.expand_button.setText( "Expand Sequence" diff --git a/sview/qt/main_window.py b/sview/qt/main_window.py index 238f7bf..b4d3dab 100644 --- a/sview/qt/main_window.py +++ b/sview/qt/main_window.py @@ -47,6 +47,7 @@ from PySide6.QtWidgets import ( QFileDialog, QHBoxLayout, + QLabel, QLineEdit, QMainWindow, QMenu, @@ -54,15 +55,24 @@ QProgressBar, QPushButton, QSplitter, + QStackedWidget, QStyle, + QToolButton, QVBoxLayout, QWidget, ) from sview import __version__ -from sview.config import AppConfig, build_command, get_repository_url +from sview.config import ( + AppConfig, + build_command, + get_repository_url, + load_ui_state, + save_ui_state, +) from sview.controller import BrowserController from sview.model import BrowserItem, ItemType +from sview.qt.icon_view import ContentsIconView from sview.qt.inspector import InspectorPanel from sview.qt.table import ContentsTable from sview.qt.tree import DirectoryTree @@ -71,6 +81,7 @@ class MainWindow(QMainWindow): SEQUENCE_METADATA_WORKERS = 4 + SIDEBAR_WIDTH = 280 def __init__( self, @@ -81,6 +92,7 @@ def __init__( super().__init__() self._controller = controller or BrowserController() self._config = AppConfig.load() + self._ui_state = load_ui_state() self._debug = debug self._initial_path = ( self._normalize_path(initial_path) @@ -113,9 +125,17 @@ def __init__( self._filter_input.setPlaceholderText("Search") self._table = ContentsTable() + self._icon_view = ContentsIconView() + self._center_stack = QStackedWidget() self._inspector = InspectorPanel() + self._tree_title = QLabel("Folders") + self._tree_toggle = QToolButton() self._tree = DirectoryTree(self._initial_path) self._main_splitter: QSplitter | None = None + self._sidebar_expanded = bool(self._ui_state.get("sidebar_expanded", True)) + self._sidebar_restore_width = ( + self._coerce_int(self._ui_state.get("sidebar_width")) or self.SIDEBAR_WIDTH + ) self._progress_timer = QTimer(self) self._busy_timer = QTimer(self) @@ -181,21 +201,24 @@ def _build_toolbar(self) -> None: ) self._refresh_button.setToolTip("Refresh") self._refresh_button.setFixedWidth(32) - self._group_toggle = QPushButton() - self._group_toggle.setIcon( + self._content_mode_toggle = QPushButton() + self._content_mode_toggle.setIcon( + self.style().standardIcon(QStyle.StandardPixmap.SP_FileDialogDetailedView) + ) + self._content_mode_toggle.setToolTip("Sequence View") + self._content_mode_toggle.setCheckable(True) + self._content_mode_toggle.setChecked(True) + self._content_mode_toggle.setFixedWidth(32) + self._layout_mode_toggle = QPushButton() + self._layout_mode_toggle.setIcon( self.style().standardIcon(QStyle.StandardPixmap.SP_FileDialogDetailedView) ) - self._group_toggle.setToolTip("Sequence View") - self._group_toggle.setCheckable(True) - self._group_toggle.setChecked(True) - self._group_toggle.setFixedWidth(32) - self._raw_toggle = QPushButton() - self._raw_toggle.setIcon( - self.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon) + self._layout_mode_toggle.setToolTip("Detail View") + self._layout_mode_toggle.setCheckable(True) + self._layout_mode_toggle.setChecked( + self._ui_state.get("center_view", "details") != "icons" ) - self._raw_toggle.setToolTip("File View") - self._raw_toggle.setCheckable(True) - self._raw_toggle.setFixedWidth(32) + self._layout_mode_toggle.setFixedWidth(32) self._stop_button = QPushButton() self._stop_button.setIcon( self.style().standardIcon(QStyle.StandardPixmap.SP_BrowserStop) @@ -243,8 +266,9 @@ def _build_layout(self) -> None: toolbar_row.addWidget(self._open_button) toolbar_row.addWidget(self._refresh_button) toolbar_row.addSpacing(6) - toolbar_row.addWidget(self._group_toggle) - toolbar_row.addWidget(self._raw_toggle) + toolbar_row.addWidget(self._content_mode_toggle) + toolbar_row.addSpacing(6) + toolbar_row.addWidget(self._layout_mode_toggle) toolbar_row.addWidget(self._stop_button) toolbar_row.addWidget(self._progress_bar) toolbar_row.addStretch(1) @@ -253,18 +277,62 @@ def _build_layout(self) -> None: root_layout.addLayout(toolbar_row) splitter = QSplitter(Qt.Orientation.Horizontal) - splitter.addWidget(self._tree) - splitter.addWidget(self._table) + sidebar = QWidget() + sidebar.setMinimumWidth(0) + sidebar.setMaximumWidth(self.SIDEBAR_WIDTH) + sidebar_layout = QVBoxLayout(sidebar) + sidebar_layout.setContentsMargins(0, 0, 0, 0) + sidebar_layout.setSpacing(6) + sidebar_header = QHBoxLayout() + sidebar_header.setContentsMargins(2, 0, 2, 0) + sidebar_header.addWidget(self._tree_title) + sidebar_header.addStretch(1) + self._tree_toggle.setCheckable(True) + self._tree_toggle.setChecked(self._sidebar_expanded) + self._tree_toggle.setAutoRaise(True) + self._tree_toggle.setFixedSize(18, 18) + self._tree_toggle.setArrowType( + Qt.ArrowType.LeftArrow + if self._sidebar_expanded + else Qt.ArrowType.RightArrow + ) + self._tree_toggle.setToolTip( + "Collapse folders" if self._sidebar_expanded else "Expand folders" + ) + sidebar_header.addWidget(self._tree_toggle) + sidebar_layout.addLayout(sidebar_header) + sidebar_layout.addWidget(self._tree, 1) + self._center_stack.addWidget(self._table) + self._center_stack.addWidget(self._icon_view) + self._center_stack.setCurrentWidget( + self._icon_view if not self._layout_mode_toggle.isChecked() else self._table + ) + + splitter.addWidget(sidebar) + splitter.addWidget(self._center_stack) splitter.addWidget(self._inspector) - splitter.setStretchFactor(0, 2) + splitter.setStretchFactor(0, 0) splitter.setStretchFactor(1, 5) splitter.setStretchFactor(2, 3) self._main_splitter = splitter - splitter.setSizes([260, 900, 0]) + splitter.setCollapsible(0, True) + splitter.setSizes( + self._coerce_splitter_sizes( + self._ui_state.get("main_splitter_sizes"), + [self._sidebar_restore_width, 900, 0], + ) + ) + if not self._sidebar_expanded: + self._apply_sidebar_state(False) root_layout.addWidget(splitter, 1) self.setCentralWidget(center) + center.setObjectName("mainContent") self.statusBar().showMessage("Ready") + width = self._coerce_int(self._ui_state.get("window_width")) + height = self._coerce_int(self._ui_state.get("window_height")) + if width and height: + self.resize(width, height) def _connect_signals(self) -> None: self._open_action.triggered.connect(self._choose_directory) @@ -283,17 +351,27 @@ def _connect_signals(self) -> None: self._home_button.clicked.connect(self._go_home) self._up_button.clicked.connect(self._go_up) self._stop_button.clicked.connect(self._cancel_scan) - self._group_toggle.toggled.connect(self._toggle_grouped_view) - self._raw_toggle.toggled.connect(self._toggle_raw_view) + self._content_mode_toggle.toggled.connect(self._toggle_content_mode) self._filter_input.textChanged.connect(self._apply_filter) self._table.itemSelectionChanged.connect(self._sync_inspector) self._table.itemDoubleClicked.connect(self._activate_selected_item) self._table.context_requested.connect(self._show_item_context_menu) + self._icon_view.itemSelectionChanged.connect(self._sync_inspector) + self._icon_view.itemActivated.connect(self._activate_selected_item) + self._icon_view.context_requested.connect(self._show_item_context_menu) self._tree.selectionModel().selectionChanged.connect( self._handle_tree_selection ) + self._layout_mode_toggle.toggled.connect(self._toggle_layout_mode) + self._tree_toggle.toggled.connect(self._toggle_sidebar) self._inspector.copy_path_button.clicked.connect(self._copy_selected_path) self._inspector.copy_pattern_button.clicked.connect(self._copy_selected_pattern) + self._inspector.find_missing_button.clicked.connect( + self._find_missing_for_selected_sequence + ) + self._inspector.get_size_button.clicked.connect( + self._get_size_for_selected_sequence + ) self._inspector.expand_button.clicked.connect( self._expand_or_collapse_selected_sequence ) @@ -305,6 +383,7 @@ def closeEvent(self, event: QCloseEvent) -> None: self._load_process.kill() self._load_process.waitForFinished(500) self._metadata_executor.shutdown(wait=False) + self._save_ui_state() event.accept() def _choose_directory(self) -> None: @@ -345,27 +424,35 @@ def _go_home(self) -> None: self._sync_tree_to_path(str(home)) self._request_directory(home, add_to_history=True) - def _toggle_grouped_view(self, enabled: bool) -> None: - if not enabled and not self._raw_toggle.isChecked(): - self._group_toggle.setChecked(True) - return - self._controller.set_grouped_view(enabled) - self._raw_toggle.blockSignals(True) - self._raw_toggle.setChecked(not enabled) - self._raw_toggle.blockSignals(False) + def _toggle_content_mode(self, sequence_view: bool) -> None: + self._controller.set_grouped_view(sequence_view) + self._content_mode_toggle.setIcon( + self.style().standardIcon( + QStyle.StandardPixmap.SP_FileDialogDetailedView + if sequence_view + else QStyle.StandardPixmap.SP_FileIcon + ) + ) + self._content_mode_toggle.setToolTip( + "Sequence View" if sequence_view else "File View" + ) self._apply_filter(self._filter_input.text()) - def _toggle_raw_view(self, enabled: bool) -> None: - if not enabled and not self._group_toggle.isChecked(): - self._raw_toggle.setChecked(True) - return - if enabled == (not self._controller.grouped_view): - return - self._group_toggle.blockSignals(True) - self._group_toggle.setChecked(not enabled) - self._group_toggle.blockSignals(False) - self._controller.set_grouped_view(not enabled) - self._apply_filter(self._filter_input.text()) + def _toggle_layout_mode(self, detail_view: bool) -> None: + self._layout_mode_toggle.setIcon( + self.style().standardIcon( + QStyle.StandardPixmap.SP_FileDialogDetailedView + if detail_view + else QStyle.StandardPixmap.SP_FileDialogListView + ) + ) + self._layout_mode_toggle.setToolTip( + "Detail View" if detail_view else "Icon View" + ) + self._center_stack.setCurrentWidget( + self._table if detail_view else self._icon_view + ) + self._save_ui_state() def _handle_tree_selection(self) -> None: index = self._tree.currentIndex() @@ -575,11 +662,12 @@ def _apply_filter(self, text: str) -> None: self._visible_items = filtered self._table.set_items(filtered) + self._icon_view.set_items(filtered) self._inspector.clear_details() self._update_status_bar() def _sync_inspector(self) -> None: - item = self._table.current_browser_item() + item = self._current_browser_item() if item is None: self._inspector.clear_details() return @@ -588,13 +676,13 @@ def _sync_inspector(self) -> None: self._inspector.expand_button.setText("Collapse Sequence") def _activate_selected_item(self, *_args) -> None: - item = self._table.current_browser_item() + item = self._current_browser_item() if item is None: return self._activate_item(item) def _expand_or_collapse_selected_sequence(self) -> None: - item = self._inspector.current_item or self._table.current_browser_item() + item = self._inspector.current_item or self._current_browser_item() if item is None or item.item_type is not ItemType.SEQUENCE: return if ( @@ -612,21 +700,53 @@ def _expand_or_collapse_selected_sequence(self) -> None: ) def _copy_selected_path(self) -> None: - item = self._inspector.current_item or self._table.current_browser_item() + item = self._inspector.current_item or self._current_browser_item() if item is None: return QGuiApplication.clipboard().setText(item.path) self.statusBar().showMessage(f"Copied path for {item.display_name}", 3000) def _copy_selected_pattern(self) -> None: - item = self._inspector.current_item or self._table.current_browser_item() + item = self._inspector.current_item or self._current_browser_item() if item is None or item.item_type is not ItemType.SEQUENCE: return QGuiApplication.clipboard().setText(item.display_name) self.statusBar().showMessage(f"Copied pattern {item.display_name}", 3000) + def _find_missing_for_selected_sequence(self) -> None: + item = self._inspector.current_item or self._current_browser_item() + if item is None or item.item_type is not ItemType.SEQUENCE: + return + data = self._run_sstat_json(item) + if data is None: + return + missing = self._coerce_missing_list(data.get("missing")) + item.missing = missing or None + self._table.update_item(item) + self._inspector.set_item(item) + self.statusBar().showMessage( + f"Loaded missing-frame data for {item.display_name}", 3000 + ) + + def _get_size_for_selected_sequence(self) -> None: + item = self._inspector.current_item or self._current_browser_item() + if item is None or item.item_type is not ItemType.SEQUENCE: + return + data = self._run_sstat_json(item) + if data is None: + return + size_bytes = self._coerce_int(data.get("size_bytes")) or self._coerce_int( + data.get("size") + ) + if size_bytes is not None: + item.size_bytes = size_bytes + self._table.update_item(item) + self._inspector.set_item(item) + self._update_status_bar() + self.statusBar().showMessage(f"Loaded size for {item.display_name}", 3000) + def _open_selected_properties(self) -> None: - item = self._inspector.current_item or self._table.current_browser_item() + item = self._inspector.current_item or self._current_browser_item() if item is None: return self._open_properties(item) @@ -718,21 +838,10 @@ def _expand_or_collapse_item(self, item: BrowserItem) -> None: self._expand_or_collapse_selected_sequence() def _run_sequence_sstat(self, item: BrowserItem) -> None: - executable = self._tool_path("sstat") - if executable is None: + data = self._run_sstat_json(item) + if data is None: return - completed = subprocess.run( - [executable, item.path, "--json"], - capture_output=True, - text=True, - check=False, - ) - if completed.returncode != 0: - QMessageBox.warning( - self, "sstat failed", completed.stderr.strip() or "sstat failed." - ) - return - text = self._format_sstat_output(completed.stdout.strip()) + text = self._format_sstat_output(json.dumps(data)) QMessageBox.information(self, "Properties", text or "No output.") def _run_sequence_transfer(self, item: BrowserItem, tool_name: str) -> None: @@ -821,8 +930,8 @@ def _set_loading_state(self, loading: bool, path: str | None = None) -> None: not loading and self._controller.current_path.parent != self._controller.current_path ) - self._group_toggle.setEnabled(not loading) - self._raw_toggle.setEnabled(not loading) + self._content_mode_toggle.setEnabled(not loading) + self._layout_mode_toggle.setEnabled(not loading) self._open_button.setEnabled(not loading) self._refresh_button.setEnabled(not loading) self._filter_input.setEnabled(not loading) @@ -929,6 +1038,7 @@ def _process_sequence_metadata_updates(self) -> None: if item is None: continue self._table.update_item(item) + self._icon_view.update_item(item) if ( self._inspector.current_item is not None and self._inspector.current_item.path == item.path @@ -940,6 +1050,56 @@ def _process_sequence_metadata_updates(self) -> None: if self._metadata_pending_count == 0: self._metadata_timer.stop() + def _run_sstat_json(self, item: BrowserItem) -> dict[str, object] | None: + executable = self._tool_path("sstat") + if executable is None: + return None + completed = subprocess.run( + [executable, item.path, "--json"], + capture_output=True, + text=True, + check=False, + ) + if completed.returncode != 0: + QMessageBox.warning( + self, "sstat failed", completed.stderr.strip() or "sstat failed." + ) + return None + try: + return json.loads(completed.stdout.strip()) + except json.JSONDecodeError: + QMessageBox.warning( + self, "sstat failed", "Received invalid JSON from sstat." + ) + return None + + @staticmethod + def _coerce_int(value: object) -> int | None: + try: + if value is None: + return None + return int(value) + except (TypeError, ValueError): + return None + + @classmethod + def _coerce_missing_list(cls, value: object) -> list[int]: + if not isinstance(value, list): + return [] + frames: list[int] = [] + for item in value: + if isinstance(item, list) and len(item) == 2: + start = cls._coerce_int(item[0]) + end = cls._coerce_int(item[1]) + if start is None or end is None: + continue + frames.extend(range(start, end + 1)) + continue + coerced = cls._coerce_int(item) + if coerced is not None: + frames.append(coerced) + return frames + def _advance_busy_indicator(self) -> None: self._busy_value += self._busy_direction * 4 if self._busy_value >= 100: @@ -960,6 +1120,7 @@ def _close_inspector(self) -> None: sizes[1] += reclaimed sizes[2] = 0 self._main_splitter.setSizes(sizes) + self._save_ui_state() def _collapse_tree(self) -> None: self._tree.collapseAll() @@ -993,6 +1154,78 @@ def _clear_scan_process(self) -> None: self._load_cancelled = False self._load_timed_out = False + def _save_ui_state(self) -> None: + sidebar_width = self._sidebar_restore_width + if self._main_splitter is not None: + sizes = self._main_splitter.sizes() + if sizes and sizes[0] > 0: + sidebar_width = sizes[0] + state = { + "window_width": self.width(), + "window_height": self.height(), + "main_splitter_sizes": self._main_splitter.sizes() + if self._main_splitter is not None + else [self.SIDEBAR_WIDTH, 900, 0], + "center_view": "icons" + if not self._layout_mode_toggle.isChecked() + else "details", + "sidebar_expanded": self._sidebar_expanded, + "sidebar_width": sidebar_width, + } + try: + save_ui_state(state) + except OSError: + pass + + @staticmethod + def _coerce_splitter_sizes(value: object, default: list[int]) -> list[int]: + if not isinstance(value, list) or len(value) != len(default): + return list(default) + sizes: list[int] = [] + for item in value: + try: + sizes.append(max(0, int(item))) + except (TypeError, ValueError): + return list(default) + return sizes + + def _current_browser_item(self) -> BrowserItem | None: + if self._center_stack.currentWidget() is self._icon_view: + return self._icon_view.current_browser_item() + return self._table.current_browser_item() + + def _toggle_sidebar(self, expanded: bool) -> None: + self._apply_sidebar_state(expanded) + self._save_ui_state() + + def _apply_sidebar_state(self, expanded: bool) -> None: + if self._main_splitter is None: + self._sidebar_expanded = expanded + return + self._sidebar_expanded = expanded + self._tree_toggle.blockSignals(True) + self._tree_toggle.setChecked(expanded) + self._tree_toggle.blockSignals(False) + self._tree_toggle.setArrowType( + Qt.ArrowType.LeftArrow if expanded else Qt.ArrowType.RightArrow + ) + self._tree_toggle.setToolTip( + "Collapse folders" if expanded else "Expand folders" + ) + sizes = self._main_splitter.sizes() + if len(sizes) < 3: + return + if expanded: + target = min(self.SIDEBAR_WIDTH, max(220, self._sidebar_restore_width)) + sizes[1] = max(0, sizes[1] - target) + sizes[0] = target + else: + if sizes[0] > 0: + self._sidebar_restore_width = sizes[0] + sizes[1] += sizes[0] + sizes[0] = 0 + self._main_splitter.setSizes(sizes) + def _open_repo_page(self) -> None: QDesktopServices.openUrl(QUrl(get_repository_url())) diff --git a/sview/qt/table.py b/sview/qt/table.py index 86ae82c..1d03230 100644 --- a/sview/qt/table.py +++ b/sview/qt/table.py @@ -67,22 +67,16 @@ def __init__(self) -> None: self.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers) self.verticalHeader().setVisible(False) self.horizontalHeader().setStretchLastSection(True) - self.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch) - self.horizontalHeader().setSectionResizeMode( - 1, QHeaderView.ResizeMode.ResizeToContents - ) - self.horizontalHeader().setSectionResizeMode( - 2, QHeaderView.ResizeMode.ResizeToContents - ) - self.horizontalHeader().setSectionResizeMode( - 3, QHeaderView.ResizeMode.ResizeToContents - ) - self.horizontalHeader().setSectionResizeMode( - 4, QHeaderView.ResizeMode.ResizeToContents - ) - self.horizontalHeader().setSectionResizeMode( - 5, QHeaderView.ResizeMode.ResizeToContents - ) + header = self.horizontalHeader() + for column in range(len(self.HEADERS)): + header.setSectionResizeMode(column, QHeaderView.ResizeMode.Interactive) + self.setColumnWidth(0, 320) + self.setColumnWidth(1, 90) + self.setColumnWidth(2, 110) + self.setColumnWidth(3, 70) + self.setColumnWidth(4, 110) + self.setColumnWidth(5, 90) + self.setColumnWidth(6, 140) self.setShowGrid(False) self.setAlternatingRowColors(False) self.setFocusPolicy(Qt.FocusPolicy.NoFocus) @@ -147,7 +141,6 @@ def _render_next_batch(self) -> None: self.setSortingEnabled(True) self.sortItems(0, Qt.SortOrder.AscendingOrder) self.horizontalHeader().setSortIndicator(0, Qt.SortOrder.AscendingOrder) - self.resizeColumnsToContents() def current_browser_item(self) -> BrowserItem | None: selected = self.selectedItems() From 022d2d4fc1fe8bcfc06dc135d6186dc5f3d2dd2e Mon Sep 17 00:00:00 2001 From: Ryan Galloway Date: Sun, 5 Apr 2026 13:30:35 -0700 Subject: [PATCH 4/4] Harden scan parsing and config handling for PR feedback --- sview/config.py | 33 +++++++++++++--- sview/qt/main_window.py | 84 ++++------------------------------------- sview/scanner.py | 13 +++++-- tests/test_scanner.py | 57 ++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 87 deletions(-) diff --git a/sview/config.py b/sview/config.py index 0cf793f..91cee63 100644 --- a/sview/config.py +++ b/sview/config.py @@ -118,13 +118,13 @@ def load(cls) -> "AppConfig": command=sequence_handler.get("command", ""), ), scan_worker=ScanWorkerConfig( - nice_increment=int(worker.get("nice_increment", 15)), + nice_increment=cls._coerce_int(worker.get("nice_increment"), 15), memory_limit_mb=memory_limit_mb, timeout_seconds=( - int(worker["timeout_seconds"]) + None if "timeout_seconds" in worker - and worker.get("timeout_seconds") is not None - else (None if "timeout_seconds" in worker else 30) + and worker.get("timeout_seconds") is None + else cls._coerce_int(worker.get("timeout_seconds"), 30) ), ), ) @@ -167,12 +167,33 @@ def _load_memory_limit(worker: dict[str, object]) -> int | None: if value is None: return None - memory_limit_mb = int(value) - # Treat the old 0.1.2 default as "unset" because RLIMIT_AS proved too blunt. + memory_limit_mb = AppConfig._coerce_optional_int(value, None) + if memory_limit_mb is None: + return None + # Treat the old default memory cap from early 0.1.2 development as "unset" + # because RLIMIT_AS proved too blunt for normal scans. if memory_limit_mb == 2048: return None return memory_limit_mb + @staticmethod + def _coerce_int(value: object, default: int) -> int: + try: + if value is None: + return default + return int(value) + except (TypeError, ValueError): + return default + + @staticmethod + def _coerce_optional_int(value: object, default: int | None) -> int | None: + try: + if value is None: + return default + return int(value) + except (TypeError, ValueError): + return default + def build_command(command_template: str, path: str) -> list[str]: return shlex.split(command_template.format(path=path)) diff --git a/sview/qt/main_window.py b/sview/qt/main_window.py index b4d3dab..c8336bd 100644 --- a/sview/qt/main_window.py +++ b/sview/qt/main_window.py @@ -35,10 +35,8 @@ from __future__ import annotations -from concurrent.futures import ThreadPoolExecutor import json from pathlib import Path -from queue import Empty, Queue import subprocess import sys @@ -80,7 +78,6 @@ class MainWindow(QMainWindow): - SEQUENCE_METADATA_WORKERS = 4 SIDEBAR_WIDTH = 280 def __init__( @@ -110,13 +107,6 @@ def __init__( self._load_stderr_partial = "" self._load_cancelled = False self._load_timed_out = False - self._metadata_executor = ThreadPoolExecutor( - max_workers=self.SEQUENCE_METADATA_WORKERS, - thread_name_prefix="sview-seqmeta", - ) - self._metadata_queue: Queue[tuple[int, str, int, float]] = Queue() - self._metadata_token = 0 - self._metadata_pending_count = 0 self.setWindowTitle("sview") self.resize(1400, 800) @@ -141,9 +131,6 @@ def __init__( self._busy_timer = QTimer(self) self._busy_timer.setInterval(30) self._busy_timer.timeout.connect(self._advance_busy_indicator) - self._metadata_timer = QTimer(self) - self._metadata_timer.setInterval(30) - self._metadata_timer.timeout.connect(self._process_sequence_metadata_updates) self._scan_timeout_timer = QTimer(self) self._scan_timeout_timer.setSingleShot(True) self._scan_timeout_timer.timeout.connect(self._handle_scan_timeout) @@ -382,7 +369,6 @@ def closeEvent(self, event: QCloseEvent) -> None: if self._load_process is not None: self._load_process.kill() self._load_process.waitForFinished(500) - self._metadata_executor.shutdown(wait=False) self._save_ui_state() event.accept() @@ -462,8 +448,6 @@ def _handle_tree_selection(self) -> None: def _request_directory(self, path: str | Path, add_to_history: bool) -> None: requested_path = str(self._normalize_path(path)) - self._metadata_token += 1 - self._metadata_pending_count = 0 if self._is_loading(): self._pending_request = (requested_path, add_to_history) self.statusBar().showMessage(f"Queued {requested_path}") @@ -578,7 +562,13 @@ def _handle_scan_process_finished( try: result = ScanResult.from_dict(json.loads(response_text)) - except (TypeError, ValueError, json.JSONDecodeError) as exc: + except ( + TypeError, + ValueError, + KeyError, + AttributeError, + json.JSONDecodeError, + ) as exc: self._handle_failed_scan(f"Invalid scan response: {exc}") return self._handle_finished_scan(result) @@ -591,7 +581,6 @@ def _handle_finished_scan(self, result: object) -> None: items = self._controller.apply_scan_result(result) self._visible_items = items - self._start_sequence_metadata_enrichment(result) if request[1]: self._push_history(str(result.path)) self._active_request = None @@ -991,65 +980,6 @@ def _update_status_bar(self) -> None: ) self._update_navigation_buttons() - def _start_sequence_metadata_enrichment(self, result: ScanResult) -> None: - self._metadata_pending_count = 0 - self._metadata_timer.stop() - return - - def _compute_sequence_metadata( - self, - token: int, - item_path: str, - child_paths: list[str], - raw_lookup: dict[str, BrowserItem], - ) -> None: - size_bytes = 0 - modified_time = 0.0 - for child_path in child_paths: - raw_item = raw_lookup.get(child_path) - if raw_item is None: - continue - size_bytes += raw_item.size_bytes - if raw_item.modified_time > modified_time: - modified_time = raw_item.modified_time - self._metadata_queue.put((token, item_path, size_bytes, modified_time)) - - def _process_sequence_metadata_updates(self) -> None: - handled = False - while True: - try: - ( - token, - item_path, - size_bytes, - modified_time, - ) = self._metadata_queue.get_nowait() - except Empty: - break - - handled = True - if token != self._metadata_token: - continue - - self._metadata_pending_count = max(0, self._metadata_pending_count - 1) - item = self._controller.update_sequence_metadata( - item_path, size_bytes, modified_time - ) - if item is None: - continue - self._table.update_item(item) - self._icon_view.update_item(item) - if ( - self._inspector.current_item is not None - and self._inspector.current_item.path == item.path - ): - self._inspector.set_item(item) - - if handled: - self._update_status_bar() - if self._metadata_pending_count == 0: - self._metadata_timer.stop() - def _run_sstat_json(self, item: BrowserItem) -> dict[str, object] | None: executable = self._tool_path("sstat") if executable is None: diff --git a/sview/scanner.py b/sview/scanner.py index d9f1f0f..6f74f8a 100644 --- a/sview/scanner.py +++ b/sview/scanner.py @@ -130,7 +130,10 @@ def _build_raw_items( for entry in entries: self._raise_if_cancelled(cancel_check) - is_directory = entry.is_dir() + try: + is_directory = entry.is_dir(follow_symlinks=False) + except OSError: + continue items.append( BrowserItem( path=entry.path, @@ -178,9 +181,11 @@ def _build_grouped_items( child_paths = [str(member.path) for member in members] consumed_paths.update(child_paths) - start_frame = int(getattr(members[0], "frame", 0) or 0) - end_frame = int(getattr(members[-1], "frame", 0) or 0) - if start_frame and end_frame: + start_frame = getattr(members[0], "frame", None) + end_frame = getattr(members[-1], "frame", None) + if start_frame is not None and end_frame is not None: + start_frame = int(start_frame) + end_frame = int(end_frame) frame_range = ( str(start_frame) if start_frame == end_frame diff --git a/tests/test_scanner.py b/tests/test_scanner.py index edb0f32..27369c5 100644 --- a/tests/test_scanner.py +++ b/tests/test_scanner.py @@ -4,6 +4,7 @@ import unittest from pathlib import Path +from sview import config as config_module from sview.controller import BrowserController from sview.model import ItemType from sview.scanner import DirectoryScanner, ScanResult @@ -59,6 +60,21 @@ def test_single_numbered_file_stays_a_file(self) -> None: self.assertEqual(len(result.grouped_items), 1) self.assertIs(result.grouped_items[0].item_type, ItemType.FILE) + def test_sequence_range_handles_frame_zero(self) -> None: + with tempfile.TemporaryDirectory() as tmp_dir: + root = Path(tmp_dir) + _touch(root / "plate.0000.jpg") + _touch(root / "plate.0001.jpg") + + result = DirectoryScanner().scan(root) + + sequence = next( + item + for item in result.grouped_items + if item.item_type is ItemType.SEQUENCE + ) + self.assertEqual(sequence.frame_range, "0-1") + def test_controller_can_expand_and_collapse_sequence(self) -> None: with tempfile.TemporaryDirectory() as tmp_dir: root = Path(tmp_dir) @@ -102,5 +118,46 @@ def test_scan_result_round_trip_serialization(self) -> None: ) +class AppConfigTests(unittest.TestCase): + def test_load_tolerates_invalid_worker_values(self) -> None: + with tempfile.TemporaryDirectory() as tmp_dir: + config_dir = Path(tmp_dir) + config_path = config_dir / "config.json" + ui_state_path = config_dir / "ui_state.json" + config_dir.mkdir(parents=True, exist_ok=True) + config_path.write_text( + """ +{ + "scanner": { + "worker": { + "nice_increment": "not-a-number", + "memory_limit_mb": "also-bad", + "timeout_seconds": "still-bad" + } + } +} +""".strip() + + "\n", + encoding="utf-8", + ) + + original_dir = config_module.CONFIG_DIR + original_config_path = config_module.CONFIG_PATH + original_ui_state_path = config_module.UI_STATE_PATH + config_module.CONFIG_DIR = config_dir + config_module.CONFIG_PATH = config_path + config_module.UI_STATE_PATH = ui_state_path + try: + loaded = config_module.AppConfig.load() + finally: + config_module.CONFIG_DIR = original_dir + config_module.CONFIG_PATH = original_config_path + config_module.UI_STATE_PATH = original_ui_state_path + + self.assertEqual(loaded.scan_worker.nice_increment, 15) + self.assertIsNone(loaded.scan_worker.memory_limit_mb) + self.assertEqual(loaded.scan_worker.timeout_seconds, 30) + + if __name__ == "__main__": unittest.main()