Skip to content

Commit

Permalink
Support card renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
ping committed Sep 20, 2023
1 parent c993ec8 commit d9e8e3d
Show file tree
Hide file tree
Showing 9 changed files with 344 additions and 123 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

Unreleased
- New: Rename a card

Version 0.1.9 - 2023-09-19
- Fix: Error on launch for calibre <6.2.0
- New: Option to disable the Magazines tab
Expand Down
145 changes: 136 additions & 9 deletions calibre-plugin/dialog/cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
obfuscate_int,
obfuscate_name,
)
from ..workers import LibbyAuthFormWorker, LibbyVerifyCardWorker
from ..workers import LibbyAuthFormWorker, LibbyRenameCardWorker, LibbyVerifyCardWorker

# noinspection PyUnreachableCode
if False:
Expand Down Expand Up @@ -204,6 +204,19 @@ def errored_out(err: Exception):

return thread

def rename_card_btn_clicked(self, card: Dict, library: Dict, widget):
d = CardRenameDialog(
self,
self.gui,
self.resources,
self.client,
card,
library,
widget,
)
d.setModal(True)
d.open()


class CardWidget(QWidget):
def __init__(self, card, library, tab: CardsDialogMixin, *args, **kwargs):
Expand Down Expand Up @@ -251,6 +264,16 @@ def __init__(self, card, library, tab: CardsDialogMixin, *args, **kwargs):
library_lbl.setToolTip(_("Right-click for shortcuts"))
layout.addWidget(library_lbl, widget_row_pos, 1, 1, 2)

buttons_layout = QHBoxLayout()
self.rename_card_btn = DefaultQPushButton(
"", icon=self.tab.resources[PluginImages.Edit], parent=self
)
self.rename_card_btn.setToolTip(_("Rename Card"))
self.rename_card_btn.setMaximumWidth(self.rename_card_btn.size().height())
self.rename_card_btn.clicked.connect(
lambda: self.tab.rename_card_btn_clicked(self.card, self.library, self)
)
buttons_layout.addWidget(self.rename_card_btn)
self.verify_card_btn = DefaultQPushButton(
_("Verify Card"),
icon=self.tab.resources[PluginImages.Okay],
Expand All @@ -260,9 +283,8 @@ def __init__(self, card, library, tab: CardsDialogMixin, *args, **kwargs):
self.verify_card_btn.clicked.connect(
lambda: self.tab.verify_card_btn_clicked(self.card, self.library, self)
)
layout.addWidget(
self.verify_card_btn, widget_row_pos, 2, alignment=Qt.AlignRight
)
buttons_layout.addWidget(self.verify_card_btn)
layout.addLayout(buttons_layout, widget_row_pos, 2, alignment=Qt.AlignRight)
widget_row_pos += 1

# Card Name
Expand All @@ -271,12 +293,12 @@ def __init__(self, card, library, tab: CardsDialogMixin, *args, **kwargs):
if not DEMO_MODE
else obfuscate_name(card["cardName"] or "")
) or ""
card_lbl = ClickableQLabel("<b>" + _("Card name") + "</b>: " + card_name)
card_lbl.setTextFormat(Qt.RichText)
card_lbl.doubleClicked.connect(
self.card_lbl = ClickableQLabel(self.format_card_name(card_name))
self.card_lbl.setTextFormat(Qt.RichText)
self.card_lbl.doubleClicked.connect(
lambda: self.tab.display_debug("Card", self.card)
)
layout.addWidget(card_lbl, widget_row_pos, 0, 1, 2)
layout.addWidget(self.card_lbl, widget_row_pos, 0, 1, 2)

# Card Number
if card.get("username"):
Expand Down Expand Up @@ -376,6 +398,9 @@ def format_authorized_date(self, authorize_date: str):
)
)

def format_card_name(self, card_name):
return "<b>" + _("Card name") + "</b>: " + card_name

def library_lbl_context_menu_requested(self):
menu = QMenu(self)
menu.addSection(_("Library"))
Expand Down Expand Up @@ -456,14 +481,15 @@ def __init__(
self.library = library
self.card_widget = card_widget
layout = QFormLayout()
layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
self.setLayout(layout)
self.setWindowTitle(_("Verify Card"))
self._verify_card_thread = QThread()

username_field = form.get("local", {}).get("username", {})
password_field = form.get("local", {}).get("password", {})

name_lbl = ClickableQLabel(library["name"])
name_lbl = QLabel(library["name"])
name_lbl.setAlignment(Qt.AlignCenter)
curr_font = name_lbl.font()
curr_font.setPointSizeF(curr_font.pointSizeF() * 1.1)
Expand Down Expand Up @@ -555,3 +581,104 @@ def errored_out(err: Exception):
worker.errored.connect(lambda err: errored_out(err))

return thread


class CardRenameDialog(QDialog):
def __init__(
self,
parent: CardsDialogMixin,
gui,
resources: Dict,
client: Optional[LibbyClient],
card: Dict,
library: Dict,
card_widget: CardWidget,
):
super().__init__(parent)
self.gui = gui
self.resources = resources
self.client = client
self.card = card
self.library = library
self.card_widget = card_widget
layout = QFormLayout()
layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
self.setLayout(layout)
self.setWindowTitle(_("Rename Card"))
self._rename_card_thread = QThread()

name_lbl = QLabel(library["name"])
name_lbl.setAlignment(Qt.AlignCenter)
curr_font = name_lbl.font()
curr_font.setPointSizeF(curr_font.pointSizeF() * 1.1)
name_lbl.setFont(curr_font)
name_lbl.setStyleSheet("font-weight: bold;")
layout.addRow(name_lbl)

self.card_name_txt = QLineEdit(self)
self.card_name_txt.setMinimumWidth(int(self.parent().min_button_width * 1.5))
self.card_name_txt.setText(card.get("cardName", "") or "")
layout.addRow(_("Card name"), self.card_name_txt)

buttons_layout = QHBoxLayout()
self.cancel_btn = DefaultQPushButton(
_c("Cancel"), self.resources[PluginImages.Cancel], self
)
self.cancel_btn.clicked.connect(lambda: self.reject())
buttons_layout.addWidget(self.cancel_btn)

self.update_btn = DefaultQPushButton(
_c("Save"), self.resources[PluginImages.Okay], self
)
self.update_btn.clicked.connect(self.update_btn_clicked)
buttons_layout.addWidget(self.update_btn)
layout.addRow(buttons_layout)

def update_btn_clicked(self):
if not self.card_name_txt.text().strip():
return

if not self._rename_card_thread.isRunning():
self._rename_card_thread = self._get_rename_card_thread(
self.client, self.card, self.card_name_txt.text().strip()
)
self.update_btn.setEnabled(False)
self.setCursor(Qt.WaitCursor)
self._rename_card_thread.start()

def _get_rename_card_thread(
self, client: LibbyClient, card: Dict, new_name: str
) -> QThread:
thread = QThread()
worker = LibbyRenameCardWorker()
worker.setup(client, card, new_name)
worker.moveToThread(thread)
thread.worker = worker
thread.started.connect(worker.run)

def loaded(updated_card: Dict):
thread.quit()
self.unsetCursor()
self.update_btn.setEnabled(True)
if updated_card and updated_card.get("cardName"):
self.card_widget.card_lbl.setText(
self.card_widget.format_card_name(updated_card["cardName"])
)
self.parent().status_bar.showMessage(
_('Updated "{library}" card name').format(
library=updated_card["advantageKey"]
),
5000,
)
self.accept()

def errored_out(err: Exception):
self.unsetCursor()
self.update_btn.setEnabled(True)
thread.quit()
return self.parent().unhandled_exception(err, msg=_("Error verifying card"))

worker.finished.connect(lambda updated_card: loaded(updated_card))
worker.errored.connect(lambda err: errored_out(err))

return thread
16 changes: 16 additions & 0 deletions calibre-plugin/libby/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1319,3 +1319,19 @@ def add_title_tag(
return self.add_title_tag_by_id(
tag["uuid"], tag["name"], title_id, website_id, card_id
)

def update_card_name(self, card_id: str, card_name: str) -> Dict:
"""
Update card name.
:param card_id:
:param card_name:
:return:
"""
res: Dict = self.send_request(
f"card/{card_id}",
query={"card_name": card_name},
method="PUT",
is_form=False,
)
return res
53 changes: 31 additions & 22 deletions calibre-plugin/translations/default.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libby-calibre-plugin 0.1.9\n"
"Report-Msgid-Bugs-To: https://github.com/ping/libby-calibre-plugin/\n"
"POT-Creation-Date: 2023-09-19 15:33+0800\n"
"POT-Creation-Date: 2023-09-20 17:07+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -196,8 +196,8 @@ msgstr ""
msgid "Generate setup code for another device"
msgstr ""

#: calibre-plugin/config.py:269 calibre-plugin/dialog/cards.py:326
#: calibre-plugin/dialog/cards.py:392 calibre-plugin/dialog/loans.py:169
#: calibre-plugin/config.py:269 calibre-plugin/dialog/cards.py:348
#: calibre-plugin/dialog/cards.py:417 calibre-plugin/dialog/loans.py:169
msgid "Loans"
msgstr ""

Expand Down Expand Up @@ -287,7 +287,7 @@ msgid "Loan type, e.g. ebook, audiobook, magazine"
msgstr ""

#: calibre-plugin/config.py:540 calibre-plugin/config.py:542
#: calibre-plugin/dialog/cards.py:348 calibre-plugin/dialog/cards.py:403
#: calibre-plugin/dialog/cards.py:370 calibre-plugin/dialog/cards.py:428
#: calibre-plugin/dialog/holds.py:164 calibre-plugin/dialog/holds.py:203
msgid "Holds"
msgstr ""
Expand Down Expand Up @@ -515,7 +515,7 @@ msgid "Expire Date"
msgstr ""

#: calibre-plugin/models.py:269 calibre-plugin/models.py:546
#: calibre-plugin/models.py:951 calibre-plugin/dialog/cards.py:381
#: calibre-plugin/models.py:951 calibre-plugin/dialog/cards.py:406
msgid "Library"
msgstr ""

Expand Down Expand Up @@ -663,14 +663,14 @@ msgid "Error encountered during search ({library}): {error}"
msgstr ""

#: calibre-plugin/dialog/base.py:233 calibre-plugin/dialog/base_search.py:232
#: calibre-plugin/dialog/cards.py:382 calibre-plugin/dialog/cards.py:393
#: calibre-plugin/dialog/cards.py:404
#: calibre-plugin/dialog/cards.py:407 calibre-plugin/dialog/cards.py:418
#: calibre-plugin/dialog/cards.py:429
msgid "View in Libby"
msgstr ""

#: calibre-plugin/dialog/base.py:238 calibre-plugin/dialog/base_search.py:251
#: calibre-plugin/dialog/cards.py:385 calibre-plugin/dialog/cards.py:396
#: calibre-plugin/dialog/cards.py:407
#: calibre-plugin/dialog/cards.py:410 calibre-plugin/dialog/cards.py:421
#: calibre-plugin/dialog/cards.py:432
msgid "View in OverDrive"
msgstr ""

Expand Down Expand Up @@ -818,48 +818,57 @@ msgstr ""
msgid "Cards"
msgstr ""

#: calibre-plugin/dialog/cards.py:251 calibre-plugin/dialog/cards.py:340
#: calibre-plugin/dialog/cards.py:362
#: calibre-plugin/dialog/cards.py:264 calibre-plugin/dialog/cards.py:362
#: calibre-plugin/dialog/cards.py:384
msgid "Right-click for shortcuts"
msgstr ""

#: calibre-plugin/dialog/cards.py:255 calibre-plugin/dialog/cards.py:460
msgid "Verify Card"
#: calibre-plugin/dialog/cards.py:271 calibre-plugin/dialog/cards.py:607
msgid "Rename Card"
msgstr ""

#: calibre-plugin/dialog/cards.py:274
msgid "Card name"
#: calibre-plugin/dialog/cards.py:278 calibre-plugin/dialog/cards.py:486
msgid "Verify Card"
msgstr ""

#: calibre-plugin/dialog/cards.py:287 calibre-plugin/dialog/cards.py:480
#: calibre-plugin/dialog/cards.py:309 calibre-plugin/dialog/cards.py:506
msgid "Username/Card number"
msgstr ""

#: calibre-plugin/dialog/cards.py:300
#: calibre-plugin/dialog/cards.py:322
msgid "Created date"
msgstr ""

#: calibre-plugin/dialog/cards.py:369
#: calibre-plugin/dialog/cards.py:391
msgid "Verified date"
msgstr ""

#: calibre-plugin/dialog/cards.py:487
#: calibre-plugin/dialog/cards.py:402 calibre-plugin/dialog/cards.py:621
msgid "Card name"
msgstr ""

#: calibre-plugin/dialog/cards.py:513
msgid "Password"
msgstr ""

#: calibre-plugin/dialog/cards.py:497
#: calibre-plugin/dialog/cards.py:523
msgid "Sign In"
msgstr ""

#: calibre-plugin/dialog/cards.py:541
#: calibre-plugin/dialog/cards.py:567
#, python-brace-format
msgid "Verified \"{library}\" card"
msgstr ""

#: calibre-plugin/dialog/cards.py:552
#: calibre-plugin/dialog/cards.py:578 calibre-plugin/dialog/cards.py:679
msgid "Error verifying card"
msgstr ""

#: calibre-plugin/dialog/cards.py:668
#, python-brace-format
msgid "Updated \"{library}\" card name"
msgstr ""

#: calibre-plugin/dialog/holds.py:81
msgid "Get latest holds"
msgstr ""
Expand Down

0 comments on commit d9e8e3d

Please sign in to comment.