main_window: route _save_as through save_post_file

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.
This commit is contained in:
pax 2026-04-09 17:04:08 -05:00
parent b72f3a54c0
commit b7cb021d1b

View File

@ -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 --