Compare commits
7 Commits
9c2a2cbafd
...
on_ratelim
Author | SHA1 | Date | |
---|---|---|---|
81d89d7905 | |||
5faa6ecfe3 | |||
d01b90a88a | |||
88f11cd3b3 | |||
e481fe5033 | |||
9bc85d95a1 | |||
5256f016b7 |
@ -138,6 +138,7 @@ class ComicSeries:
|
||||
publisher: str
|
||||
start_year: int | None
|
||||
format: str | None
|
||||
web_links: list[Url] = dataclasses.field(default_factory=list)
|
||||
|
||||
def copy(self) -> ComicSeries:
|
||||
return copy.deepcopy(self)
|
||||
|
@ -18,7 +18,6 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import operator
|
||||
from enum import Enum, auto
|
||||
|
||||
import natsort
|
||||
from PyQt6 import QtCore, QtWidgets, uic
|
||||
@ -32,15 +31,12 @@ from comictaggerlib.ui.qtutils import enable_widget
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EditMode(Enum):
|
||||
EDIT = auto()
|
||||
NEW = auto()
|
||||
|
||||
|
||||
class CreditEditorWindow(QtWidgets.QDialog):
|
||||
creditChanged = QtCore.pyqtSignal(Credit, int, EditMode)
|
||||
creditChanged = QtCore.pyqtSignal(Credit, int)
|
||||
|
||||
def __init__(self, parent: QtWidgets.QWidget, tags: list[str], row: int, mode: EditMode, credit: Credit) -> None:
|
||||
def __init__(
|
||||
self, parent: QtWidgets.QWidget, tags: list[str], row: int, credit: Credit, title: str = "New Credit"
|
||||
) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
with (ui_path / "crediteditorwindow.ui").open(encoding="utf-8") as uifile:
|
||||
@ -53,15 +49,11 @@ class CreditEditorWindow(QtWidgets.QDialog):
|
||||
"credits.primary": self.cbPrimary,
|
||||
}
|
||||
|
||||
self.mode = mode
|
||||
self.credit = credit
|
||||
self.row = row
|
||||
self.tags = tags
|
||||
|
||||
if self.mode == EditMode.EDIT:
|
||||
self.setWindowTitle("Edit Credit")
|
||||
else:
|
||||
self.setWindowTitle("New Credit")
|
||||
self.setWindowTitle(title)
|
||||
self.setModal(True)
|
||||
|
||||
# Add the entries to the role combobox
|
||||
@ -129,4 +121,4 @@ class CreditEditorWindow(QtWidgets.QDialog):
|
||||
QtWidgets.QDialog.accept(self)
|
||||
new = self.get_credit()
|
||||
if self.credit != new:
|
||||
self.creditChanged.emit(new, self.row, self.mode)
|
||||
self.creditChanged.emit(new, self.row)
|
||||
|
@ -10,6 +10,7 @@ import types
|
||||
import settngs
|
||||
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.ctversion import version
|
||||
from comictaggerlib.graphics import graphics_path
|
||||
from comictalker.comictalker import ComicTalker
|
||||
|
||||
@ -114,6 +115,9 @@ def open_tagger_window(
|
||||
app.openFileRequest.connect(lambda x: config[0].Runtime_Options__files.append(x.toLocalFile()))
|
||||
# The window Icon needs to be set here. It's also set in taggerwindow.ui but it doesn't seem to matter
|
||||
app.setWindowIcon(QtGui.QIcon(":/graphics/app.png"))
|
||||
app.setApplicationName("ComicTagger")
|
||||
app.setApplicationDisplayName("ComicTagger")
|
||||
app.setApplicationVersion(version)
|
||||
|
||||
if platform.system() == "Windows":
|
||||
# For pure python, tell windows that we're not python,
|
||||
|
@ -40,18 +40,17 @@ class IssueNumberTableWidgetItem(QtWidgets.QTableWidgetItem):
|
||||
|
||||
|
||||
class QueryThread(QtCore.QThread): # TODO: Evaluate thread semantics. Specifically with signals
|
||||
finish = QtCore.pyqtSignal(list)
|
||||
ratelimit = QtCore.pyqtSignal(float, float)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
talker: ComicTalker,
|
||||
series_id: str,
|
||||
finish: QtCore.pyqtSignal,
|
||||
on_ratelimit: QtCore.pyqtSignal,
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.series_id = series_id
|
||||
self.talker = talker
|
||||
self.finish = finish
|
||||
self.on_ratelimit = on_ratelimit
|
||||
|
||||
def run(self) -> None:
|
||||
|
||||
@ -59,7 +58,7 @@ class QueryThread(QtCore.QThread): # TODO: Evaluate thread semantics. Specifica
|
||||
issue_list = [
|
||||
x
|
||||
for x in self.talker.fetch_issues_in_series(
|
||||
self.series_id, on_rate_limit=RLCallBack(lambda x, y: self.on_ratelimit.emit(x, y), 10)
|
||||
self.series_id, on_rate_limit=RLCallBack(lambda x, y: self.ratelimit.emit(x, y), 10)
|
||||
)
|
||||
if x.issue_id is not None
|
||||
]
|
||||
@ -99,9 +98,9 @@ class IssueSelectionWindow(SelectionWindow):
|
||||
self.querythread = QueryThread(
|
||||
self.talker,
|
||||
self.series_id,
|
||||
self.finish,
|
||||
self.ratelimit,
|
||||
)
|
||||
self.querythread.finish.connect(self.finish)
|
||||
self.querythread.ratelimit.connect(self.ratelimit)
|
||||
self.querythread.start()
|
||||
|
||||
def query_finished(self, issues: list[GenericMetadata]) -> None:
|
||||
@ -183,4 +182,17 @@ class IssueSelectionWindow(SelectionWindow):
|
||||
cover = issue._cover_image.URL if issue._cover_image else ""
|
||||
self.cover_widget.set_issue_details(self.issue_id, [cover, *alt_images])
|
||||
self.set_description(self.teDescription, issue.description or "")
|
||||
series_link = ""
|
||||
if issue.web_links:
|
||||
url = (
|
||||
issue.web_links[0]
|
||||
.url.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("'", "'")
|
||||
.replace('"', """)
|
||||
)
|
||||
|
||||
series_link = f'<a href="{url}">Link To Issue</a>'
|
||||
self.lblIssueLink.setText(series_link)
|
||||
return issue
|
||||
|
@ -98,6 +98,7 @@ class OptionalMessageDialog(QtWidgets.QDialog):
|
||||
check_text: str = "",
|
||||
) -> None:
|
||||
d = OptionalMessageDialog(parent, StyleMessage, title, msg, checked=checked, check_text=check_text)
|
||||
d.setModal(True)
|
||||
|
||||
def finished(i: int) -> None:
|
||||
callback(d.theCheckBox.isChecked())
|
||||
@ -117,6 +118,7 @@ class OptionalMessageDialog(QtWidgets.QDialog):
|
||||
check_text: str = "",
|
||||
) -> None:
|
||||
d = OptionalMessageDialog(parent, StyleQuestion, title, msg, checked=checked, check_text=check_text)
|
||||
d.setModal(True)
|
||||
|
||||
def finished(i: int) -> None:
|
||||
callback(i == QtWidgets.QDialog.DialogCode.Accepted, d.theCheckBox.isChecked())
|
||||
@ -130,6 +132,7 @@ class OptionalMessageDialog(QtWidgets.QDialog):
|
||||
parent: QtWidgets.QWidget, title: str, msg: str, *, checked: bool = False, check_text: str = ""
|
||||
) -> None:
|
||||
d = OptionalMessageDialog(parent, StyleMessage, title, msg, checked=checked, check_text=check_text)
|
||||
d.setModal(True)
|
||||
d.theCheckBox.hide()
|
||||
|
||||
d.show()
|
||||
|
@ -405,6 +405,19 @@ class SeriesSelectionWindow(SelectionWindow):
|
||||
except TalkerError:
|
||||
pass
|
||||
self.set_description(self.teDescription, series.description or "")
|
||||
series_link = ""
|
||||
if series.web_links:
|
||||
url = (
|
||||
series.web_links[0]
|
||||
.url.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("'", "'")
|
||||
.replace('"', """)
|
||||
)
|
||||
|
||||
series_link = f'<a href="{url}">Link To Series</a>'
|
||||
self.lblSeriesLink.setText(series_link)
|
||||
self.cover_widget.set_url(series.image_url)
|
||||
return series
|
||||
|
||||
@ -473,7 +486,8 @@ class SeriesSelectionWindow(SelectionWindow):
|
||||
if result == IIResult.single_good_match:
|
||||
return self.update_match(issues[0])
|
||||
|
||||
qmsg = QtWidgets.QMessageBox(parent=self)
|
||||
qmsg = QtWidgets.QMessageBox(parent=self.iddialog)
|
||||
qmsg.setModal(False)
|
||||
qmsg.setIcon(qmsg.Icon.Information)
|
||||
qmsg.setText("Auto-Select Result")
|
||||
qmsg.setInformativeText(" Manual interaction needed :-(")
|
||||
|
@ -47,7 +47,7 @@ from comictaggerlib.autotagprogresswindow import AutoTagProgressWindow, AutoTagT
|
||||
from comictaggerlib.autotagstartwindow import AutoTagSettings, AutoTagStartWindow
|
||||
from comictaggerlib.cbltransformer import CBLTransformer
|
||||
from comictaggerlib.coverimagewidget import CoverImageWidget
|
||||
from comictaggerlib.crediteditorwindow import CreditEditorWindow, EditMode
|
||||
from comictaggerlib.crediteditorwindow import CreditEditorWindow
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.exportwindow import ExportConfig, ExportConflictOpts, ExportWindow
|
||||
from comictaggerlib.fileselectionlist import FileSelectionList
|
||||
@ -249,7 +249,11 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
|
||||
self.scrollAreaWidgetContents.adjustSize()
|
||||
|
||||
self.setWindowIcon(QtGui.QIcon(str(graphics_path / "app.png")))
|
||||
self.qicon = QtGui.QIcon(str(graphics_path / "app.png"))
|
||||
self.setWindowIcon(self.qicon)
|
||||
self.tray = QtWidgets.QSystemTrayIcon(self)
|
||||
self.tray.show()
|
||||
self.tray.hide() # QT doesn't initialize until you call show. on_ratelimit calls .show, .showMessage, and then .hide so that a tray item is not persistent. Specifically macOS will make an invisible tray icon if you keep it visible, even without an icon
|
||||
|
||||
# respect the command line selected tags
|
||||
if config[0].Runtime_Options__tags_write:
|
||||
@ -937,7 +941,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
|
||||
for row, credit in enumerate(md.credits):
|
||||
# if the role-person pair already exists, just skip adding it to the list
|
||||
if self.is_dupe_credit(None, credit.role.title(), credit.person):
|
||||
if self.get_dupe_credit(None, credit.role.title(), credit.person):
|
||||
continue
|
||||
|
||||
self.add_new_credit_entry(row, credit)
|
||||
@ -973,7 +977,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.twCredits.setItem(row, self.md_attributes["credits.primary"], item)
|
||||
self.update_credit_primary_flag(row, credit.primary)
|
||||
|
||||
def is_dupe_credit(self, row: int | None, role: str, name: str) -> bool:
|
||||
def get_dupe_credit(self, row: int | None, role: str, name: str) -> int:
|
||||
for r in range(self.twCredits.rowCount()):
|
||||
if r == row:
|
||||
continue
|
||||
@ -982,9 +986,9 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.twCredits.item(r, self.md_attributes["credits.role"]).text() == role
|
||||
and self.twCredits.item(r, self.md_attributes["credits.person"]).text() == name
|
||||
):
|
||||
return True
|
||||
return r
|
||||
|
||||
return False
|
||||
return -1
|
||||
|
||||
def form_to_metadata(self) -> None:
|
||||
# copy the data from the form into the metadata
|
||||
@ -1206,7 +1210,18 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.metadata_to_form()
|
||||
|
||||
def on_ratelimit(self, full_time: float, sleep_time: float) -> None:
|
||||
self.toast = Toast(QtWidgets.QApplication.activeWindow())
|
||||
if QtWidgets.QSystemTrayIcon.supportsMessages():
|
||||
self.tray.show()
|
||||
self.tray.showMessage(
|
||||
"Rate Limit Hit!",
|
||||
f"Rate limit reached: {full_time:.0f}s until next request. Waiting {sleep_time:.0f}s for ratelimit",
|
||||
self.qicon,
|
||||
abs(int(sleep_time * 1000) + 200),
|
||||
)
|
||||
self.tray.hide()
|
||||
return
|
||||
self.toast = Toast(self)
|
||||
# self.toast.__position_relative_to_widget = self
|
||||
if qtutils.is_dark_mode():
|
||||
self.toast.applyPreset(ToastPreset.WARNING_DARK)
|
||||
else:
|
||||
@ -1220,7 +1235,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.toast.setText(
|
||||
f"Rate limit reached: {full_time:.0f}s until next request. Waiting {sleep_time:.0f}s for ratelimit"
|
||||
)
|
||||
self.toast.setPositionRelativeToWidget(self)
|
||||
self.toast.setAlwaysOnMainScreen(True)
|
||||
self.toast.show()
|
||||
|
||||
def write_tags(self) -> None:
|
||||
@ -1337,15 +1352,29 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.page_list_editor.select_write_tags(self.selected_write_tags)
|
||||
self.toggle_enable_embedding_hashes()
|
||||
|
||||
def cell_double_clicked(self, r: int, c: int) -> None:
|
||||
self.edit_credit()
|
||||
|
||||
def add_credit(self) -> None:
|
||||
self.modify_credits(False)
|
||||
row = self.twCredits.rowCount()
|
||||
editor = CreditEditorWindow(self, self.selected_write_tags, row, Credit())
|
||||
editor.creditChanged.connect(self._credit_added)
|
||||
editor.show()
|
||||
|
||||
def edit_credit(self) -> None:
|
||||
if self.twCredits.currentRow() > -1:
|
||||
self.modify_credits(True)
|
||||
if self.twCredits.currentRow() < 0:
|
||||
return
|
||||
row = self.twCredits.currentRow()
|
||||
lang = str(
|
||||
self.twCredits.item(row, self.md_attributes["credits.language"]).data(QtCore.Qt.ItemDataRole.UserRole)
|
||||
or utils.get_language_iso(self.twCredits.item(row, self.md_attributes["credits.language"]).text())
|
||||
)
|
||||
old = Credit(
|
||||
self.twCredits.item(row, self.md_attributes["credits.person"]).text(),
|
||||
self.twCredits.item(row, self.md_attributes["credits.role"]).text(),
|
||||
self.twCredits.item(row, self.md_attributes["credits.primary"]).text() != "",
|
||||
lang,
|
||||
)
|
||||
editor = CreditEditorWindow(self, self.selected_write_tags, row, old, "Edit Credit")
|
||||
editor.creditChanged.connect(self._credit_changed)
|
||||
editor.show()
|
||||
|
||||
def update_credit_primary_flag(self, row: int, primary: bool) -> None:
|
||||
# if we're clearing a flag do it and quit
|
||||
@ -1366,29 +1395,8 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
# Now set our new primary
|
||||
self.twCredits.item(row, self.md_attributes["credits.primary"]).setText("Yes")
|
||||
|
||||
def modify_credits(self, edit: bool) -> None:
|
||||
row = self.twCredits.rowCount()
|
||||
old = Credit()
|
||||
mode = EditMode.NEW
|
||||
if edit:
|
||||
mode = EditMode.EDIT
|
||||
row = self.twCredits.currentRow()
|
||||
lang = str(
|
||||
self.twCredits.item(row, self.md_attributes["credits.language"]).data(QtCore.Qt.ItemDataRole.UserRole)
|
||||
or utils.get_language_iso(self.twCredits.item(row, self.md_attributes["credits.language"]).text())
|
||||
)
|
||||
old = Credit(
|
||||
self.twCredits.item(row, self.md_attributes["credits.person"]).text(),
|
||||
self.twCredits.item(row, self.md_attributes["credits.role"]).text(),
|
||||
self.twCredits.item(row, self.md_attributes["credits.primary"]).text() != "",
|
||||
lang,
|
||||
)
|
||||
|
||||
editor = CreditEditorWindow(self, self.selected_write_tags, row, mode, old)
|
||||
editor.creditChanged.connect(self._credit_changed)
|
||||
editor.show()
|
||||
|
||||
def _edit_credit(self, credit: Credit, row: int) -> None:
|
||||
def _update_credit(self, credit: Credit, row: int) -> None:
|
||||
assert isinstance(row, int)
|
||||
lang = utils.get_language_from_iso(credit.language) or credit.language
|
||||
self.twCredits.item(row, self.md_attributes["credits.role"]).setText(credit.role)
|
||||
self.twCredits.item(row, self.md_attributes["credits.person"]).setText(credit.person)
|
||||
@ -1409,26 +1417,44 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.update_credit_colors()
|
||||
self.set_dirty_flag()
|
||||
|
||||
def _credit_changed(self, credit: Credit, row: int, mode: EditMode) -> None:
|
||||
def _credit_changed(self, credit: Credit, row: int) -> None:
|
||||
dupe_index = self.get_dupe_credit(row, credit.role, credit.person)
|
||||
if dupe_index < 0:
|
||||
return self._update_credit(credit, row)
|
||||
# delete the dupe credit from list
|
||||
qmsg = QtWidgets.QMessageBox(parent=self)
|
||||
qmsg.setText("Duplicate Credit!")
|
||||
qmsg.setInformativeText(
|
||||
"This will create a duplicate credit entry. Would you like to merge the entries, or create a duplicate?"
|
||||
)
|
||||
qmsg.addButton("Merge", QtWidgets.QMessageBox.ButtonRole.AcceptRole)
|
||||
qmsg.addButton("Duplicate", QtWidgets.QMessageBox.ButtonRole.RejectRole)
|
||||
|
||||
if self.is_dupe_credit(row, credit.role, credit.person):
|
||||
# delete the dupe credit from list
|
||||
qmsg = QtWidgets.QMessageBox()
|
||||
qmsg.setText("Duplicate Credit!")
|
||||
qmsg.setInformativeText(
|
||||
"This will create a duplicate credit entry. Would you like to merge the entries, or create a duplicate?"
|
||||
)
|
||||
qmsg.addButton("Merge", QtWidgets.QMessageBox.ButtonRole.AcceptRole)
|
||||
qmsg.addButton("Duplicate", QtWidgets.QMessageBox.ButtonRole.NoRole)
|
||||
def _merge(credit: Credit, row: int, existing: int) -> None:
|
||||
self.twCredits.removeRow(row)
|
||||
self._update_credit(credit, existing)
|
||||
|
||||
if qmsg.exec() == 0 and mode == EditMode.EDIT:
|
||||
# just remove the row that would be same
|
||||
self.twCredits.removeRow(row)
|
||||
mode = EditMode.NEW
|
||||
qmsg.accepted.connect(functools.partial(_merge, credit, row, dupe_index))
|
||||
qmsg.rejected.connect(functools.partial(self._update_credit, credit, row))
|
||||
|
||||
if mode == EditMode.EDIT:
|
||||
return self._edit_credit(credit, row)
|
||||
self._add_credit(credit)
|
||||
qmsg.show()
|
||||
|
||||
def _credit_added(self, credit: Credit) -> None:
|
||||
dupe_index = self.get_dupe_credit(None, credit.role, credit.person)
|
||||
if dupe_index < 0:
|
||||
self._add_credit(credit)
|
||||
return
|
||||
# delete the dupe credit from list
|
||||
qmsg = QtWidgets.QMessageBox(parent=self)
|
||||
qmsg.setText("Duplicate Credit!")
|
||||
qmsg.setInformativeText(
|
||||
"This will create a duplicate credit entry. Would you like to merge the entries, or create a duplicate?"
|
||||
)
|
||||
qmsg.addButton("Merge", QtWidgets.QMessageBox.ButtonRole.AcceptRole)
|
||||
qmsg.addButton("Duplicate", QtWidgets.QMessageBox.ButtonRole.RejectRole)
|
||||
qmsg.accepted.connect(functools.partial(self._update_credit, credit, dupe_index))
|
||||
qmsg.rejected.connect(functools.partial(self._add_credit, credit))
|
||||
qmsg.show()
|
||||
|
||||
def remove_credit(self) -> None:
|
||||
row = self.twCredits.currentRow()
|
||||
@ -1940,26 +1966,26 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
errorbox.open()
|
||||
|
||||
def dirty_flag_verification(self, title: str, desc: str) -> bool:
|
||||
if self.dirty_flag:
|
||||
reply = QtWidgets.QMessageBox.question(
|
||||
self,
|
||||
title,
|
||||
desc,
|
||||
(
|
||||
QtWidgets.QMessageBox.StandardButton.Save
|
||||
| QtWidgets.QMessageBox.StandardButton.Cancel
|
||||
| QtWidgets.QMessageBox.StandardButton.Discard
|
||||
),
|
||||
QtWidgets.QMessageBox.StandardButton.Cancel,
|
||||
)
|
||||
if not self.dirty_flag:
|
||||
return True
|
||||
reply = QtWidgets.QMessageBox.question(
|
||||
self,
|
||||
title,
|
||||
desc,
|
||||
(
|
||||
QtWidgets.QMessageBox.StandardButton.Save
|
||||
| QtWidgets.QMessageBox.StandardButton.Cancel
|
||||
| QtWidgets.QMessageBox.StandardButton.Discard
|
||||
),
|
||||
QtWidgets.QMessageBox.StandardButton.Cancel,
|
||||
)
|
||||
|
||||
if reply == QtWidgets.QMessageBox.StandardButton.Discard:
|
||||
return True
|
||||
if reply == QtWidgets.QMessageBox.StandardButton.Save:
|
||||
self.write_tags()
|
||||
return True
|
||||
return False
|
||||
return True
|
||||
if reply == QtWidgets.QMessageBox.StandardButton.Discard:
|
||||
return True
|
||||
if reply == QtWidgets.QMessageBox.StandardButton.Save:
|
||||
self.write_tags()
|
||||
return True
|
||||
return False
|
||||
|
||||
def closeEvent(self, event: QtGui.QCloseEvent) -> None:
|
||||
if self.dirty_flag_verification(
|
||||
|
@ -161,6 +161,25 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblIssueLink">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Issue Link:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="imageSourceLogo" native="true">
|
||||
<property name="minimumSize">
|
||||
|
@ -1324,14 +1324,14 @@ class Toast(QDialog):
|
||||
|
||||
if on:
|
||||
self.setWindowFlags(
|
||||
Qt.WindowType.Tool
|
||||
Qt.WindowType.Popup
|
||||
| Qt.WindowType.CustomizeWindowHint
|
||||
| Qt.WindowType.FramelessWindowHint
|
||||
| Qt.WindowType.WindowStaysOnTopHint
|
||||
)
|
||||
else:
|
||||
self.setWindowFlags(
|
||||
Qt.WindowType.Tool | Qt.WindowType.CustomizeWindowHint | Qt.WindowType.FramelessWindowHint
|
||||
Qt.WindowType.Popup | Qt.WindowType.CustomizeWindowHint | Qt.WindowType.FramelessWindowHint
|
||||
)
|
||||
|
||||
def getBorderRadius(self) -> int:
|
||||
|
@ -238,21 +238,21 @@ try:
|
||||
return new_widget
|
||||
|
||||
def critical(parent: QWidget | None, title: str, text: str) -> None:
|
||||
qmsg = QtWidgets.QMessageBox(parent)
|
||||
qmsg = QtWidgets.QMessageBox(parent=parent)
|
||||
qmsg.setIcon(qmsg.Icon.Critical)
|
||||
qmsg.setText(title)
|
||||
qmsg.setInformativeText(text)
|
||||
return qmsg.show()
|
||||
|
||||
def warning(parent: QWidget | None, title: str, text: str) -> None:
|
||||
qmsg = QtWidgets.QMessageBox(parent)
|
||||
qmsg = QtWidgets.QMessageBox(parent=parent)
|
||||
qmsg.setIcon(qmsg.Icon.Warning)
|
||||
qmsg.setText(title)
|
||||
qmsg.setInformativeText(text)
|
||||
return qmsg.show()
|
||||
|
||||
def information(parent: QWidget | None, title: str, text: str) -> None:
|
||||
qmsg = QtWidgets.QMessageBox(parent)
|
||||
qmsg = QtWidgets.QMessageBox(parent=parent)
|
||||
qmsg.setIcon(qmsg.Icon.Information)
|
||||
qmsg.setText(title)
|
||||
qmsg.setInformativeText(text)
|
||||
|
@ -90,6 +90,31 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblSeriesLink">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Series Link:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="imageSourceLogo" native="true">
|
||||
<property name="minimumSize">
|
||||
|
@ -77,9 +77,9 @@ def generate_api_widgets(
|
||||
def call_check_api(*args: Any, tab: TalkerTab, talker: ComicTalker, definitions: settngs.Definitions) -> None:
|
||||
check_text, check_bool = talker.check_status(get_config_from_tab(tab, definitions[group_for_plugin(talker)]))
|
||||
if check_bool:
|
||||
return qtutils.information(TalkerTab.tab, "API Test Success", check_text)
|
||||
return qtutils.information(tab.tab, "API Test Success", check_text)
|
||||
|
||||
qtutils.warning(TalkerTab.tab, "API Test Failed", check_text)
|
||||
qtutils.warning(tab.tab, "API Test Failed", check_text)
|
||||
|
||||
# get the actual config objects in case they have overwritten the default
|
||||
btn_test_row = None
|
||||
|
@ -302,7 +302,7 @@ class ComicVineTalker(ComicTalker):
|
||||
"format": "json",
|
||||
"resources": "volume",
|
||||
"query": search_series_name,
|
||||
"field_list": "volume,name,id,start_year,publisher,image,description,count_of_issues,aliases",
|
||||
"field_list": "volume,name,id,start_year,publisher,image,description,count_of_issues,aliases,site_detail_url",
|
||||
"page": 1,
|
||||
"limit": 100,
|
||||
}
|
||||
@ -801,7 +801,7 @@ class ComicVineTalker(ComicTalker):
|
||||
|
||||
aliases = record.get("aliases") or ""
|
||||
|
||||
return ComicSeries(
|
||||
series = ComicSeries(
|
||||
aliases=set(utils.split(aliases, "\n")),
|
||||
count_of_issues=record.get("count_of_issues"),
|
||||
count_of_volumes=None,
|
||||
@ -813,6 +813,13 @@ class ComicVineTalker(ComicTalker):
|
||||
start_year=start_year,
|
||||
format=None,
|
||||
)
|
||||
url = utils.xlate(record.get("site_detail_url"))
|
||||
if url:
|
||||
try:
|
||||
series.web_links = [parse_url(url)]
|
||||
except LocationParseError:
|
||||
...
|
||||
return series
|
||||
|
||||
def _fetch_issues_in_series(
|
||||
self,
|
||||
|
Reference in New Issue
Block a user