From b7cb021d1b4636c60d17e773a8267bd4860a0dd2 Mon Sep 17 00:00:00 2001 From: pax Date: Thu, 9 Apr 2026 17:04:08 -0500 Subject: [PATCH] main_window: route _save_as through save_post_file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Third Phase 2 site migration. Default filename in the dialog now comes from rendering the library_filename_template against the post, so users see their templated name and can edit if they want. Drops the legacy hardcoded "post_" prefix on the default — anyone who wants the prefix can put it in the template. The actual save still routes through save_post_file with explicit_name set to whatever the user typed, so collision resolution runs even on user-chosen filenames (sequential _1/_2 if the picked name already belongs to a different post in the library). behavior change from v0.2.3: Save As into saved_dir() now registers library_meta. Previously Save As never wrote meta regardless of destination. If a file is in the library it should be searchable — this fixes that. --- booru_viewer/gui/main_window.py | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/booru_viewer/gui/main_window.py b/booru_viewer/gui/main_window.py index 770609e..23cc1f0 100644 --- a/booru_viewer/gui/main_window.py +++ b/booru_viewer/gui/main_window.py @@ -2790,18 +2790,40 @@ class BooruApp(QMainWindow): self._run_async(_save) def _save_as(self, post: Post) -> None: + """Open a Save As dialog for a single post and write the file + through the unified save_post_file flow. + + The default name in the dialog comes from rendering the user's + library_filename_template against the post; the user can edit + before confirming. If the chosen destination ends up inside + saved_dir(), save_post_file registers a library_meta row — + a behavior change from v0.2.3 (where Save As never wrote meta + regardless of destination).""" from ..core.cache import cached_path_for + from ..core.config import render_filename_template + from ..core.library_save import save_post_file from .dialogs import save_file + src = cached_path_for(post.file_url) if not src.exists(): self._status.showMessage("Image not cached — double-click to download first") return ext = src.suffix - dest = save_file(self, "Save Image", f"post_{post.id}{ext}", f"Images (*{ext})") - if dest: - import shutil - shutil.copy2(src, dest) - self._status.showMessage(f"Saved to {dest}") + template = self._db.get_setting("library_filename_template") + default_name = render_filename_template(template, post, ext) + dest = save_file(self, "Save Image", default_name, f"Images (*{ext})") + if not dest: + return + dest_path = Path(dest) + try: + actual = save_post_file( + src, post, dest_path.parent, self._db, + explicit_name=dest_path.name, + ) + except Exception as e: + self._status.showMessage(f"Save failed: {e}") + return + self._status.showMessage(f"Saved to {actual}") # -- Batch download --