Skip to content

Commit

Permalink
Make search code DRYer
Browse files Browse the repository at this point in the history
  • Loading branch information
ping committed Sep 10, 2023
1 parent b9d7ae1 commit 0085513
Show file tree
Hide file tree
Showing 4 changed files with 336 additions and 507 deletions.
245 changes: 18 additions & 227 deletions calibre-plugin/dialog/advanced_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,43 @@
# See https://github.com/ping/libby-calibre-plugin for more
# information
#
import copy
from threading import Lock
from typing import Dict, List

from calibre.constants import DEBUG
from qt.core import (
QAbstractItemView,
QButtonGroup,
QCursor,
QFormLayout,
QGridLayout,
QHBoxLayout,
QIcon,
QLineEdit,
QMenu,
QRadioButton,
QThread,
QWidget,
Qt,
)

from .base import BaseDialogMixin
from .base_search import SearchBaseDialog
from .widgets import DefaultQPushButton, DefaultQTableView
from .. import DEMO_MODE
from ..compat import (
QHeaderView_ResizeMode_ResizeToContents,
QHeaderView_ResizeMode_Stretch,
_c,
)
from ..config import (
BorrowActions,
MAX_SEARCH_LIBRARIES,
PREFS,
PreferenceKeys,
SearchMode,
)
from ..libby import LibbyClient, LibbyFormats
from ..libby import LibbyFormats
from ..models import (
LibbySearchModel,
LibbySearchSortFilterModel,
get_media_title,
truncate_for_display,
)
from ..overdrive import LibraryMediaSearchParams
from ..utils import PluginImages, obfuscate_name
from ..utils import PluginImages
from ..workers import OverDriveLibraryMediaSearchWorker

# noinspection PyUnreachableCode
Expand All @@ -61,7 +53,7 @@
load_translations()


class AdvancedSearchDialogMixin(BaseDialogMixin):
class AdvancedSearchDialogMixin(SearchBaseDialog):
def __init__(self, *args):
super().__init__(*args)

Expand Down Expand Up @@ -266,214 +258,18 @@ def hold_removed_advsearch(self, hold: Dict):
self.adv_search_results_view.selectionModel().clearSelection()

def adv_search_results_view_selection_model_selectionchanged(self):
selection_model = self.adv_search_results_view.selectionModel()
if not selection_model.hasSelection():
# selection cleared
self.adv_search_borrow_btn.borrow_menu = None
self.adv_search_borrow_btn.setMenu(None)
self.adv_hold_btn.borrow_menu = None
self.adv_hold_btn.setMenu(None)
return

indices = selection_model.selectedRows()
media = indices[-1].data(Qt.UserRole)
self.status_bar.showMessage(get_media_title(media, include_subtitle=True), 3000)

borrow_action_default_is_borrow = PREFS[
PreferenceKeys.LAST_BORROW_ACTION
] == BorrowActions.BORROW or not hasattr(self, "download_loan")

available_sites = self.get_available_sites(media, self.adv_search_model)

borrow_sites = [
s
for s in available_sites
if s.get("isAvailable") or s.get("luckyDayAvailableCopies")
]
hold_sites = [
s
for s in available_sites
if not (s.get("isAvailable") or s.get("luckyDayAvailableCopies"))
]
if borrow_sites:
borrow_menu = QMenu()
borrow_menu.setToolTipsVisible(True)
for site in borrow_sites:
cards = self.adv_search_model.get_cards_for_library_key(
site["advantageKey"]
)
for card in cards:
card_action = borrow_menu.addAction(
QIcon(self.get_card_pixmap(site["__library"])),
truncate_for_display(
f'{card["advantageKey"]}: {card["cardName"] or ""}',
font=borrow_menu.font(),
),
)
if not LibbyClient.can_borrow(card):
card_action.setToolTip(
self._wrap_for_rich_text(
"<br>".join(
[
f'<b>{site["__library"]["name"]}</b>',
_("This card is out of loans."),
]
)
)
)
card_action.setEnabled(False)
continue

if self.adv_search_model.has_loan(media["id"], card["cardId"]):
card_action.setToolTip(
self._wrap_for_rich_text(
"<br>".join(
[
f'<b>{site["__library"]["name"]}</b>',
_("You already have a loan for this title."),
]
)
)
)
card_action.setEnabled(False)
continue

card_action.setToolTip(self._borrow_tooltip(media, site))
media_for_borrow = copy.deepcopy(media)
media_for_borrow["cardId"] = card["cardId"]
card_action.triggered.connect(
# this is from the holds tab
lambda checked, m=media_for_borrow, s=site: self.borrow_hold(
m,
availability=s,
do_download=not borrow_action_default_is_borrow,
)
)
self.adv_search_borrow_btn.setEnabled(True)
self.adv_search_borrow_btn.borrow_menu = borrow_menu
self.adv_search_borrow_btn.setMenu(borrow_menu)
else:
self.adv_search_borrow_btn.borrow_menu = None
self.adv_search_borrow_btn.setMenu(None)
self.adv_search_borrow_btn.setEnabled(False)

if hold_sites:
hold_menu = QMenu()
hold_menu.setToolTipsVisible(True)
for site in hold_sites:
cards = self.adv_search_model.get_cards_for_library_key(
site["advantageKey"]
)
for card in cards:
card_action = hold_menu.addAction(
QIcon(self.get_card_pixmap(site["__library"])),
truncate_for_display(
f'{card["advantageKey"]}: {card["cardName"] or ""}',
font=hold_menu.font(),
),
)
if not LibbyClient.can_place_hold(card):
card_action.setToolTip(
self._wrap_for_rich_text(
"<br>".join(
[
f'<b>{site["__library"]["name"]}</b>',
_("This card is out of holds."),
]
)
)
)
card_action.setEnabled(False)
continue
if self.adv_search_model.has_hold(media["id"], card["cardId"]):
card_action.setToolTip(
self._wrap_for_rich_text(
"<br>".join(
[
f'<b>{site["__library"]["name"]}</b>',
_("You already have a hold for this title."),
]
)
)
)
card_action.setEnabled(False)
continue

card_action.setToolTip(self._hold_tooltip(media, site))
card_action.triggered.connect(
lambda checked, m=media, c=card: self.create_hold(m, c)
)
self.adv_hold_btn.setEnabled(True)
self.adv_hold_btn.hold_menu = hold_menu
self.adv_hold_btn.setMenu(hold_menu)
else:
self.adv_hold_btn.borrow_menu = None
self.adv_hold_btn.setMenu(None)
self.adv_hold_btn.setEnabled(False)
self.view_selection_model_selectionchanged(
self.adv_search_borrow_btn,
self.adv_hold_btn,
self.adv_search_results_view,
self.adv_search_model,
)

def adv_search_results_view_context_menu_requested(self, pos):
selection_model = self.adv_search_results_view.selectionModel()
if not selection_model.hasSelection():
return
mi = self.adv_search_results_view.indexAt(pos)
media = mi.data(Qt.UserRole)

menu = QMenu(self)
menu.setToolTipsVisible(True)
available_sites = self.get_available_sites(media, self.adv_search_model)
view_in_libby_menu = QMenu(_("View in Libby"))
view_in_libby_menu.setIcon(self.resources[PluginImages.ExternalLink])
view_in_libby_menu.setToolTipsVisible(True)
for site in available_sites:
_card = site["__card"]
library = site["__library"]
libby_action = view_in_libby_menu.addAction(
QIcon(self.get_card_pixmap(site["__library"])),
_card["advantageKey"]
if not DEMO_MODE
else obfuscate_name(_card["advantageKey"]),
)
libby_action.setToolTip(library["name"])
libby_action.triggered.connect(
lambda checked, c=_card: self.view_in_libby_action_triggered(
[mi], self.adv_search_model, c
)
)
menu.addMenu(view_in_libby_menu)
view_in_overdrive_menu = QMenu(_("View in OverDrive"))
view_in_overdrive_menu.setIcon(self.resources[PluginImages.ExternalLink])
view_in_overdrive_menu.setToolTipsVisible(True)
for site in available_sites:
_card = site["__card"]
library = site["__library"]
overdrive_action = view_in_overdrive_menu.addAction(
QIcon(self.get_card_pixmap(site["__library"])),
_card["advantageKey"]
if not DEMO_MODE
else obfuscate_name(_card["advantageKey"]),
)
overdrive_action.setToolTip(library["name"])
overdrive_action.triggered.connect(
lambda checked, c=_card: self.view_in_overdrive_action_triggered(
[mi], self.adv_search_model, c
)
)
menu.addMenu(view_in_overdrive_menu)

selected_search = self.adv_search_results_view.indexAt(pos).data(Qt.UserRole)
# view book details
self.add_view_book_details_menu_action(menu, selected_search)
# copy share link
self.add_copy_share_link_menu_action(menu, selected_search)
# find calibre matches
self.add_find_library_match_menu_action(menu, selected_search)
# search for author
self.add_search_for_title_menu_action(
menu, selected_search, search_for_author=True
self.view_context_menu_requested(
pos, self.adv_search_results_view, self.adv_search_model
)

menu.exec(QCursor.pos())

def _adv_reset_borrow_hold_buttons(self):
self.adv_search_borrow_btn.borrow_menu = None
self.adv_search_borrow_btn.setMenu(None)
Expand Down Expand Up @@ -532,18 +328,13 @@ def adv_search_btn_clicked(self):
self.adv_search_btn.setText(_c("Searching..."))
self.adv_search_btn.setEnabled(False)
self.setCursor(Qt.WaitCursor)
all_library_keys = self.adv_search_model.library_keys()
library_keys = [
lib
for lib in all_library_keys
if lib in PREFS[PreferenceKeys.SEARCH_LIBRARIES]
]
if not library_keys:
library_keys = all_library_keys

library_keys = library_keys[:MAX_SEARCH_LIBRARIES]
library_keys = self.adv_search_model.limited_library_keys()
self.status_bar.showMessage(
_("Searching across {n} libraries...").format(n=len(library_keys))
ngettext(
"Searching across {n} library...",
"Searching across {n} libraries...",
len(library_keys),
).format(n=len(library_keys))
)
self._lib_search_threads = []
self._lib_search_result_sets = {}
Expand Down

0 comments on commit 0085513

Please sign in to comment.