Fix Open in Browser/Default App on bookmarks and library tabs (route per active tab, drop random-cache fallback)

This commit is contained in:
pax 2026-04-07 11:37:24 -05:00
parent 74f948a3e8
commit 389e455ac0
2 changed files with 93 additions and 27 deletions

View File

@ -430,6 +430,9 @@ class BooruApp(QMainWindow):
self._bookmarks_view.bookmark_selected.connect(self._on_bookmark_selected)
self._bookmarks_view.bookmark_activated.connect(self._on_bookmark_activated)
self._bookmarks_view.bookmarks_changed.connect(self._refresh_browse_saved_dots)
self._bookmarks_view.open_in_browser_requested.connect(
lambda site_id, post_id: self._open_post_id_in_browser(post_id, site_id=site_id)
)
self._stack.addWidget(self._bookmarks_view)
self._library_view = LibraryView(db=self._db)
@ -1455,23 +1458,68 @@ class BooruApp(QMainWindow):
self._run_async(_dl)
def _open_preview_in_default(self) -> None:
# Try the currently selected post first
# The preview is shared across tabs but its right-click menu used
# to read browse-tab grid/posts unconditionally and then fell back
# to "open the most recently modified file in the cache", which on
# bookmarks/library tabs opened a completely unrelated image.
# Branch on the active tab and use the right source.
stack_idx = self._stack.currentIndex()
if stack_idx == 1:
# Bookmarks: prefer the bookmark's stored cached_path, fall back
# to deriving the hashed cache filename from file_url in case
# the stored path was set on a different machine or is stale.
favs = self._bookmarks_view._bookmarks
idx = self._bookmarks_view._grid.selected_index
if 0 <= idx < len(favs):
fav = favs[idx]
from ..core.cache import cached_path_for
path = None
if fav.cached_path and Path(fav.cached_path).exists():
path = Path(fav.cached_path)
else:
derived = cached_path_for(fav.file_url)
if derived.exists():
path = derived
if path is not None:
self._preview._video_player.pause()
if self._fullscreen_window and self._fullscreen_window.isVisible():
self._fullscreen_window._video.pause()
QDesktopServices.openUrl(QUrl.fromLocalFile(str(path)))
else:
self._status.showMessage("Bookmark not cached — open it first to download")
return
if stack_idx == 2:
# Library: the preview's current path IS the local library file.
# Don't go through cached_path_for — library files live under
# saved_dir, not the cache.
current = self._preview._current_path
if current and Path(current).exists():
self._preview._video_player.pause()
if self._fullscreen_window and self._fullscreen_window.isVisible():
self._fullscreen_window._video.pause()
QDesktopServices.openUrl(QUrl.fromLocalFile(current))
return
# Browse: original path. Removed the "open random cache file"
# fallback — better to do nothing than to open the wrong image.
idx = self._grid.selected_index
if 0 <= idx < len(self._posts):
self._open_in_default(self._posts[idx])
return
# Fall back to finding any cached image that matches the preview
from ..core.cache import cache_dir
from PySide6.QtGui import QDesktopServices
# Open the most recently modified file in cache
cache = cache_dir()
files = sorted(cache.iterdir(), key=lambda f: f.stat().st_mtime, reverse=True)
for f in files:
if f.is_file() and f.suffix in ('.jpg', '.jpeg', '.png', '.gif', '.webp'):
QDesktopServices.openUrl(QUrl.fromLocalFile(str(f)))
return
def _open_preview_in_browser(self) -> None:
# Same shape as _open_preview_in_default: route per active tab so
# bookmarks open the post page on the bookmark's source site, not
# the search dropdown's currently-selected site.
stack_idx = self._stack.currentIndex()
if stack_idx == 1:
favs = self._bookmarks_view._bookmarks
idx = self._bookmarks_view._grid.selected_index
if 0 <= idx < len(favs):
fav = favs[idx]
self._open_post_id_in_browser(fav.post_id, site_id=fav.site_id)
elif stack_idx == 2:
# Library files have no booru source URL — nothing to open.
return
else:
idx = self._grid.selected_index
if 0 <= idx < len(self._posts):
self._open_in_browser(self._posts[idx])
@ -2102,20 +2150,34 @@ class BooruApp(QMainWindow):
return False
return self._db.is_bookmarked(site_id, self._posts[index].id)
def _open_in_browser(self, post: Post) -> None:
if self._current_site:
base = self._current_site.url
api = self._current_site.api_type
def _open_post_id_in_browser(self, post_id: int, site_id: int | None = None) -> None:
"""Open the post page in the system browser. site_id selects which
site's URL/api scheme to use; defaults to the currently selected
search site. Pass site_id explicitly when the post comes from a
different source than the search dropdown (e.g. bookmarks)."""
site = None
if site_id is not None:
sites = self._db.get_sites()
site = next((s for s in sites if s.id == site_id), None)
if site is None:
site = self._current_site
if not site:
return
base = site.url
api = site.api_type
if api == "danbooru" or api == "e621":
url = f"{base}/posts/{post.id}"
url = f"{base}/posts/{post_id}"
elif api == "gelbooru":
url = f"{base}/index.php?page=post&s=view&id={post.id}"
url = f"{base}/index.php?page=post&s=view&id={post_id}"
elif api == "moebooru":
url = f"{base}/post/show/{post.id}"
url = f"{base}/post/show/{post_id}"
else:
url = f"{base}/posts/{post.id}"
url = f"{base}/posts/{post_id}"
QDesktopServices.openUrl(QUrl(url))
def _open_in_browser(self, post: Post) -> None:
self._open_post_id_in_browser(post.id)
def _open_in_default(self, post: Post) -> None:
from ..core.cache import cached_path_for, is_cached
path = cached_path_for(post.file_url)

View File

@ -40,6 +40,7 @@ class BookmarksView(QWidget):
bookmark_selected = Signal(object)
bookmark_activated = Signal(object)
bookmarks_changed = Signal() # emitted after bookmark add/remove/unsave
open_in_browser_requested = Signal(int, int) # (site_id, post_id)
def __init__(self, db: Database, parent: QWidget | None = None) -> None:
super().__init__(parent)
@ -219,6 +220,7 @@ class BookmarksView(QWidget):
menu = QMenu(self)
open_browser = menu.addAction("Open in Browser")
open_default = menu.addAction("Open in Default App")
menu.addSeparator()
save_as = menu.addAction("Save As...")
@ -286,6 +288,8 @@ class BookmarksView(QWidget):
folder_name = save_lib_folders[id(action)]
self._copy_to_library(fav, folder_name)
self.refresh()
elif action == open_browser:
self.open_in_browser_requested.emit(fav.site_id, fav.post_id)
elif action == open_default:
if fav.cached_path and Path(fav.cached_path).exists():
QDesktopServices.openUrl(QUrl.fromLocalFile(fav.cached_path))