From baf7d04dbf28cbd4178f23db1bacb8f8d136a9f3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 3 May 2023 21:56:51 +0530 Subject: [PATCH 01/12] string changes --- src/calibre/db/cache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index d2b2b1b62a..c4fa065c01 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -2401,7 +2401,7 @@ class Cache: Example: Assume author A has link X, author B has link Y, tag S has link F, and tag T has link G. If book 1 has author A and tag T, - this method returns {'authors':{'A':'X'}, 'tags':{'T', 'G'}} + this method returns {'authors':{'A':'X'}, 'tags':{'T', 'G'}}. If book 2's author is neither A nor B and has no tags, this method returns {}. :param book_id: the book id in question. From 4ff5af7576f9d75bbe0270289171c6f3f7224edc Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Wed, 3 May 2023 19:21:29 +0200 Subject: [PATCH 02/12] regex tweaks --- .../gui2/markdown_syntax_highlighter.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/calibre/gui2/markdown_syntax_highlighter.py b/src/calibre/gui2/markdown_syntax_highlighter.py index adb280a7e4..5bb0c5d10a 100644 --- a/src/calibre/gui2/markdown_syntax_highlighter.py +++ b/src/calibre/gui2/markdown_syntax_highlighter.py @@ -20,19 +20,19 @@ class MarkdownHighlighter(QSyntaxHighlighter): 'uBold': re.compile(r'(?__)(?P.+?)(?P=delim)'), 'uItalic': re.compile(r'(?_)(?!_)(?P([^_]{2,}?|[^_]))(?___)(?P([^_]{2,}?|[^_]))(?+[ \t]?'), + 'Link': re.compile(r'(?+[ \t]?'), + 'CodeBlock': re.compile('^([ ]{4,}|[ ]*\t).*'), 'CodeSpan': re.compile(r'(?`+).+?(?P=delim)'), 'HeaderLine': re.compile(r'(?u)^(-|=)+\s*$'), 'HR': re.compile(r'(?u)^(\s*(\*|-|_)\s*){3,}$'), - 'Html': re.compile(r'<.+?(?') + 'Html': re.compile(r'(?u)') } key_theme_maps = { @@ -147,7 +147,7 @@ class MarkdownHighlighter(QSyntaxHighlighter): def highlightBlockQuote(self, text, cursor, bf): found = False - mo = re.search(self.MARKDOWN_KEYS_REGEX['BlockQuote'],text) + mo = re.match(self.MARKDOWN_KEYS_REGEX['BlockQuote'],text) if mo: self.setFormat(self.offset+ mo.start(), mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['BlockQuote']) self.offset += mo.end() @@ -290,7 +290,7 @@ class MarkdownHighlighter(QSyntaxHighlighter): found = False for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['CodeBlock'],text): stripped = text.lstrip() - if stripped[0] not in ('*','-','+','>') and not re.match(r'\d+\.', stripped): + if stripped[0] not in ('*','-','+') and not re.match(self.MARKDOWN_KEYS_REGEX['OrderedList'], stripped): self.setFormat(self.offset+ mo.start(), mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['CodeBlock']) found = True return found From 4c16604a9dfc429beaa50a122d71f8fab4c28652 Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Wed, 3 May 2023 19:34:55 +0200 Subject: [PATCH 03/12] ... --- src/calibre/gui2/markdown_syntax_highlighter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/markdown_syntax_highlighter.py b/src/calibre/gui2/markdown_syntax_highlighter.py index 5bb0c5d10a..c481773647 100644 --- a/src/calibre/gui2/markdown_syntax_highlighter.py +++ b/src/calibre/gui2/markdown_syntax_highlighter.py @@ -22,13 +22,13 @@ class MarkdownHighlighter(QSyntaxHighlighter): 'uBoldItalic': re.compile(r'(?___)(?P([^_]{2,}?|[^_]))(?+[ \t]?'), - 'CodeBlock': re.compile('^([ ]{4,}|[ ]*\t).*'), + 'CodeBlock': re.compile(r'^([ ]{4,}|[ ]*\t).*'), 'CodeSpan': re.compile(r'(?`+).+?(?P=delim)'), 'HeaderLine': re.compile(r'(?u)^(-|=)+\s*$'), 'HR': re.compile(r'(?u)^(\s*(\*|-|_)\s*){3,}$'), From 074bdd33302b11c491e96c25c5e133916ffc8639 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 4 May 2023 08:22:05 +0530 Subject: [PATCH 04/12] Replace use of deprecated API --- src/calibre/utils/run_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/utils/run_tests.py b/src/calibre/utils/run_tests.py index a38815d5b2..65c432a518 100644 --- a/src/calibre/utils/run_tests.py +++ b/src/calibre/utils/run_tests.py @@ -53,7 +53,7 @@ class TestResult(unittest.TextTestResult): def find_tests_in_package(package, excludes=('main.py',)): - items = list(importlib.resources.contents(package)) + items = [path.name for path in importlib.resources.files(package).iterdir()] suits = [] excludes = set(excludes) | {x + 'c' for x in excludes} seen = set() From cd888703b868e62b5528f5a7e37ab659164e1809 Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Thu, 4 May 2023 10:06:13 +0200 Subject: [PATCH 05/12] add HTML entity highlighter --- src/calibre/gui2/markdown_editor.py | 2 +- .../gui2/markdown_syntax_highlighter.py | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/markdown_editor.py b/src/calibre/gui2/markdown_editor.py index 37bcd43a30..6d946c746c 100644 --- a/src/calibre/gui2/markdown_editor.py +++ b/src/calibre/gui2/markdown_editor.py @@ -183,7 +183,7 @@ if __name__ == '__main__': w.setWindowFlag(Qt.WindowType.Dialog) w.show() w.markdown = '''\ -test *italic* **bold** ***bold-italic*** `code` [link](https://calibre-ebook.com) span +normal& *italic&* **bold&** ***bold-italic*** `code` [link](https://calibre-ebook.com) span > Blockquotes diff --git a/src/calibre/gui2/markdown_syntax_highlighter.py b/src/calibre/gui2/markdown_syntax_highlighter.py index c481773647..2220c840d0 100644 --- a/src/calibre/gui2/markdown_syntax_highlighter.py +++ b/src/calibre/gui2/markdown_syntax_highlighter.py @@ -32,7 +32,8 @@ class MarkdownHighlighter(QSyntaxHighlighter): 'CodeSpan': re.compile(r'(?`+).+?(?P=delim)'), 'HeaderLine': re.compile(r'(?u)^(-|=)+\s*$'), 'HR': re.compile(r'(?u)^(\s*(\*|-|_)\s*){3,}$'), - 'Html': re.compile(r'(?u)') + 'Html': re.compile(r'(?u)'), + 'Entity': re.compile(r'&([A-z]{2,7}|#\d{1,7}|#x[\dA-Fa-f]{1,6});'), } key_theme_maps = { @@ -55,6 +56,7 @@ class MarkdownHighlighter(QSyntaxHighlighter): 'CodeSpan': "codespan", 'HR': "line", 'Html': "html", + 'Entity': "entity", } light_theme = { @@ -70,7 +72,8 @@ class MarkdownHighlighter(QSyntaxHighlighter): "codespan": {"color":"#ff5800", "font-weight":"normal", "font-style":"normal"}, "codeblock": {"color":"#ff5800", "font-weight":"normal", "font-style":"normal"}, "line": {"color":"#2aa198", "font-weight":"normal", "font-style":"normal"}, - "html": {"color":"#c000c0", "font-weight":"normal", "font-style":"normal"} + "html": {"color":"#c000c0", "font-weight":"normal", "font-style":"normal"}, + "entity": {"color":"#006496", "font-weight":"normal", "font-style":"normal"}, } dark_theme = { @@ -86,7 +89,8 @@ class MarkdownHighlighter(QSyntaxHighlighter): "codespan": {"color":"#90ee90", "font-weight":"normal", "font-style":"normal"}, "codeblock": {"color":"#ff9900", "font-weight":"normal", "font-style":"normal"}, "line": {"color":"#2aa198", "font-weight":"normal", "font-style":"normal"}, - "html": {"color":"#F653A6", "font-weight":"normal", "font-style":"normal"} + "html": {"color":"#f653a6", "font-weight":"normal", "font-style":"normal"}, + "entity": {"color":"#ff82ac", "font-weight":"normal", "font-style":"normal"}, } def __init__(self, parent): @@ -141,6 +145,8 @@ class MarkdownHighlighter(QSyntaxHighlighter): self.highlightImage(text, cursor, bf) + self.highlightEntity(text, cursor, bf) + self.highlightCodeSpan(text, cursor, bf) self.highlightCodeBlock(text, cursor, bf) @@ -295,6 +301,13 @@ class MarkdownHighlighter(QSyntaxHighlighter): found = True return found + def highlightEntity(self, text, cursor, bf): + found = False + for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Entity'],text): + self.setFormat(self.offset+ mo.start(), mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['Entity']) + found = True + return found + def highlightHtml(self, text): for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Html'], text): self.setFormat(mo.start(), mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['Html']) From f57cd0d7a7e1dcf0f5b5db282fcd000330406af8 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Thu, 4 May 2023 09:10:30 +0100 Subject: [PATCH 06/12] Enhancement #2018423: Manage Authors: Resize rows and add alternating row colouring. The two dialogs share the row height data. Changing it in one changes the other. --- src/calibre/gui2/dialogs/edit_authors_dialog.py | 16 +++++++++++++++- src/calibre/gui2/dialogs/tag_list_editor.py | 10 ++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/calibre/gui2/dialogs/edit_authors_dialog.py b/src/calibre/gui2/dialogs/edit_authors_dialog.py index 7f3dfb657b..0688161703 100644 --- a/src/calibre/gui2/dialogs/edit_authors_dialog.py +++ b/src/calibre/gui2/dialogs/edit_authors_dialog.py @@ -88,9 +88,10 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(_('&OK')) self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(_('&Cancel')) self.buttonBox.accepted.connect(self.accepted) + self.buttonBox.rejected.connect(self.rejected) self.apply_vl_checkbox.stateChanged.connect(self.use_vl_changed) - # Set up the heading for sorting + self.table.setAlternatingRowColors(True) self.table.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection) self.find_aut_func = find_aut_func @@ -112,6 +113,10 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): hh.sectionClicked.connect(self.do_sort) hh.setSortIndicatorShown(True) + vh = self.table.verticalHeader() + vh.setDefaultSectionSize(gprefs.get('general_category_editor_row_height', vh.defaultSectionSize())) + vh.sectionResized.connect(self.row_height_changed) + # set up the search & filter boxes self.find_box.initialize('manage_authors_search') le = self.find_box.lineEdit() @@ -271,10 +276,16 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): self.start_find_pos = -1 self.table.blockSignals(False) + def row_height_changed(self, row, old, new): + self.table.verticalHeader().blockSignals(True) + self.table.verticalHeader().setDefaultSectionSize(new) + self.table.verticalHeader().blockSignals(False) + def save_state(self): self.table_column_widths = [] for c in range(0, self.table.columnCount()): self.table_column_widths.append(self.table.columnWidth(c)) + gprefs['general_category_editor_row_height'] = self.table.verticalHeader().sectionSize(0) gprefs['manage_authors_table_widths'] = self.table_column_widths self.save_geometry(gprefs, 'manage_authors_dialog_geometry') @@ -451,6 +462,9 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): if orig != v: self.result.append((id_, orig['name'], v['name'], v['sort'], v['link'])) + def rejected(self): + self.save_state() + def do_recalc_author_sort(self): with self.no_cell_changed(): for row in range(0,self.table.rowCount()): diff --git a/src/calibre/gui2/dialogs/tag_list_editor.py b/src/calibre/gui2/dialogs/tag_list_editor.py index 98faaa910a..74d5bc274d 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.py +++ b/src/calibre/gui2/dialogs/tag_list_editor.py @@ -386,6 +386,10 @@ class TagListEditor(QDialog, Ui_TagListEditor): hh.sectionClicked.connect(self.record_sort) hh.setSortIndicatorShown(True) + vh = self.table.verticalHeader() + vh.setDefaultSectionSize(gprefs.get('general_category_editor_row_height', vh.defaultSectionSize())) + vh.sectionResized.connect(self.row_height_changed) + self.table.setColumnCount(4) for col,width in enumerate(self.table_column_widths): self.table.setColumnWidth(col, width) @@ -421,6 +425,11 @@ class TagListEditor(QDialog, Ui_TagListEditor): self.table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.table.customContextMenuRequested.connect(self.show_context_menu) + def row_height_changed(self, row, old, new): + self.table.verticalHeader().blockSignals(True) + self.table.verticalHeader().setDefaultSectionSize(new) + self.table.verticalHeader().blockSignals(False) + def fill_in_table(self, tags, tag_to_match, ttm_is_first_letter): self.create_table() @@ -552,6 +561,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): self.table.setColumnWidth(c, w) def save_geometry(self): + gprefs['general_category_editor_row_height'] = self.table.verticalHeader().sectionSize(0) gprefs['tag_list_editor_table_widths'] = self.table_column_widths super().save_geometry(gprefs, 'tag_list_editor_dialog_geometry') From c451efbd4257103417ebf5c6f4aa71f65e45009e Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Thu, 4 May 2023 10:58:39 +0200 Subject: [PATCH 07/12] apply local bold/italic to Entity --- .../gui2/markdown_syntax_highlighter.py | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/markdown_syntax_highlighter.py b/src/calibre/gui2/markdown_syntax_highlighter.py index 2220c840d0..693f43d6b9 100644 --- a/src/calibre/gui2/markdown_syntax_highlighter.py +++ b/src/calibre/gui2/markdown_syntax_highlighter.py @@ -73,7 +73,7 @@ class MarkdownHighlighter(QSyntaxHighlighter): "codeblock": {"color":"#ff5800", "font-weight":"normal", "font-style":"normal"}, "line": {"color":"#2aa198", "font-weight":"normal", "font-style":"normal"}, "html": {"color":"#c000c0", "font-weight":"normal", "font-style":"normal"}, - "entity": {"color":"#006496", "font-weight":"normal", "font-style":"normal"}, + "entity": {"color":"#006496"}, } dark_theme = { @@ -90,7 +90,7 @@ class MarkdownHighlighter(QSyntaxHighlighter): "codeblock": {"color":"#ff9900", "font-weight":"normal", "font-style":"normal"}, "line": {"color":"#2aa198", "font-weight":"normal", "font-style":"normal"}, "html": {"color":"#f653a6", "font-weight":"normal", "font-style":"normal"}, - "entity": {"color":"#ff82ac", "font-weight":"normal", "font-style":"normal"}, + "entity": {"color":"#ff82ac"}, } def __init__(self, parent): @@ -102,6 +102,16 @@ class MarkdownHighlighter(QSyntaxHighlighter): self.theme = theme self.MARKDOWN_KWS_FORMAT = {} + for k in ['Bold', 'Italic','BoldItalic']: + # generate dynamically keys and theme for EntityBold, EntityItalic, EntityBoldItalic + t = self.key_theme_maps[k] + newtheme = theme['entity'].copy() + newtheme.update(theme[t]) + newthemekey = 'entity'+t + newmapkey = 'Entity'+k + theme[newthemekey] = newtheme + self.key_theme_maps[newmapkey] = newthemekey + for k,t in self.key_theme_maps.items(): subtheme = theme[t] format = QTextCharFormat() @@ -304,7 +314,18 @@ class MarkdownHighlighter(QSyntaxHighlighter): def highlightEntity(self, text, cursor, bf): found = False for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Entity'],text): - self.setFormat(self.offset+ mo.start(), mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['Entity']) + charformat = self.format(self.offset+ mo.start()) + charbold = charformat.fontWeight() == QFont.Weight.Bold + charitalic = charformat.fontItalic() + if charbold and charitalic: + format = self.MARKDOWN_KWS_FORMAT['EntityBoldItalic'] + elif charbold and not charitalic: + format = self.MARKDOWN_KWS_FORMAT['EntityBold'] + elif not charbold and charitalic: + format = self.MARKDOWN_KWS_FORMAT['EntityItalic'] + else: + format = self.MARKDOWN_KWS_FORMAT['Entity'] + self.setFormat(self.offset+ mo.start(), mo.end() - mo.start(), format) found = True return found From 0126be0ca4944ce8036b913e7d821e58875b6d60 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 4 May 2023 17:04:35 +0530 Subject: [PATCH 08/12] ... --- src/calibre/gui2/toc/main.py | 2 +- src/calibre/gui2/tweak_book/toc.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/toc/main.py b/src/calibre/gui2/toc/main.py index 9f422c9365..476ea6512c 100644 --- a/src/calibre/gui2/toc/main.py +++ b/src/calibre/gui2/toc/main.py @@ -1070,7 +1070,7 @@ class TOCEditor(QDialog): # {{{ def workaround_macos_mouse_with_webview_bug(self): # macOS is weird: https://bugs.launchpad.net/calibre/+bug/2004639 # needed as of Qt 6.4.2 - d = info_dialog(self, _('Loading...'), _('Loading view, please wait...'), show_copy_button=False) + d = info_dialog(self, _('Loading...'), _('Loading table of contents view, please wait...'), show_copy_button=False) QTimer.singleShot(0, d.reject) d.exec() diff --git a/src/calibre/gui2/tweak_book/toc.py b/src/calibre/gui2/tweak_book/toc.py index 5f085f15dd..19097a8e29 100644 --- a/src/calibre/gui2/tweak_book/toc.py +++ b/src/calibre/gui2/tweak_book/toc.py @@ -68,7 +68,7 @@ class TOCEditor(QDialog): def workaround_macos_mouse_with_webview_bug(self): # macOS is weird: https://bugs.launchpad.net/calibre/+bug/2004639 # needed as of Qt 6.4.2 - d = info_dialog(self, _('Loading...'), _('Loading view, please wait...'), show_copy_button=False) + d = info_dialog(self, _('Loading...'), _('Loading table of contents view, please wait...'), show_copy_button=False) QTimer.singleShot(0, d.reject) d.exec() From 1cc6f9eb7ba4b686960279f0eaa19080e4833f3b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 4 May 2023 17:05:32 +0530 Subject: [PATCH 09/12] string changes --- src/calibre/gui2/trash.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/trash.py b/src/calibre/gui2/trash.py index 7ca44dacc3..aa210d3b6b 100644 --- a/src/calibre/gui2/trash.py +++ b/src/calibre/gui2/trash.py @@ -250,7 +250,7 @@ class TrashView(Dialog): return det_msg = [] for (entry, exc, tb) in failures: - det_msg.append(_('Failed for {} with error:').format(entry.title)) + det_msg.append(_('Failed for the book {} with error:').format(entry.title)) det_msg.append(tb) det_msg.append('-' * 40) det_msg.append('') From 4f364dc351d1cabf61d3383d10a355cd639e4166 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 4 May 2023 22:15:17 +0530 Subject: [PATCH 10/12] Better error when serializing catalog to XML fails --- src/calibre/library/catalogs/csv_xml.py | 111 ++++++++++++------------ 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/src/calibre/library/catalogs/csv_xml.py b/src/calibre/library/catalogs/csv_xml.py index 9e192620de..dae26bf0cd 100644 --- a/src/calibre/library/catalogs/csv_xml.py +++ b/src/calibre/library/catalogs/csv_xml.py @@ -177,72 +177,75 @@ class CSV_XML(CatalogPlugin): else: root = E.calibredb() for r in data: - record = E.record() - root.append(record) + try: + record = E.record() + root.append(record) - for field in fields: - if field.startswith('#'): - val = db.get_field(r['id'], field, index_is_id=True) - if not isinstance(val, str): - val = str(val) - item = getattr(E, field.replace('#', '_'))(val) - record.append(item) + for field in fields: + if field.startswith('#'): + val = db.get_field(r['id'], field, index_is_id=True) + if not isinstance(val, str): + val = str(val) + item = getattr(E, field.replace('#', '_'))(val) + record.append(item) - for field in ('id', 'uuid', 'publisher', 'rating', 'size', - 'isbn', 'ondevice', 'identifiers'): - if field in fields: - val = r[field] - if not val: - continue - if not isinstance(val, (bytes, str)): - if (fm.get(field, {}).get('datatype', None) == - 'rating' and val): - val = '%.2g' % (val / 2) - val = str(val) - item = getattr(E, field)(val) - record.append(item) + for field in ('id', 'uuid', 'publisher', 'rating', 'size', + 'isbn', 'ondevice', 'identifiers'): + if field in fields: + val = r[field] + if not val: + continue + if not isinstance(val, (bytes, str)): + if (fm.get(field, {}).get('datatype', None) == + 'rating' and val): + val = '%.2g' % (val / 2) + val = str(val) + item = getattr(E, field)(val) + record.append(item) - if 'title' in fields: - title = E.title(r['title'], sort=r['sort']) - record.append(title) + if 'title' in fields: + title = E.title(r['title'], sort=r['sort']) + record.append(title) - if 'authors' in fields: - aus = E.authors(sort=r['author_sort']) - for au in r['authors']: - aus.append(E.author(au)) - record.append(aus) + if 'authors' in fields: + aus = E.authors(sort=r['author_sort']) + for au in r['authors']: + aus.append(E.author(au)) + record.append(aus) - for field in ('timestamp', 'pubdate'): - if field in fields: - record.append(getattr(E, field)(isoformat(r[field], as_utc=False))) + for field in ('timestamp', 'pubdate'): + if field in fields: + record.append(getattr(E, field)(isoformat(r[field], as_utc=False))) - if 'tags' in fields and r['tags']: - tags = E.tags() - for tag in r['tags']: - tags.append(E.tag(tag)) - record.append(tags) + if 'tags' in fields and r['tags']: + tags = E.tags() + for tag in r['tags']: + tags.append(E.tag(tag)) + record.append(tags) - if 'comments' in fields and r['comments']: - record.append(E.comments(r['comments'])) + if 'comments' in fields and r['comments']: + record.append(E.comments(r['comments'])) - if 'series' in fields and r['series']: - record.append(E.series(r['series'], - index=str(r['series_index']))) + if 'series' in fields and r['series']: + record.append(E.series(r['series'], + index=str(r['series_index']))) - if 'languages' in fields and r['languages']: - record.append(E.languages(r['languages'])) + if 'languages' in fields and r['languages']: + record.append(E.languages(r['languages'])) - if 'cover' in fields and r['cover']: - record.append(E.cover(r['cover'].replace(os.sep, '/'))) + if 'cover' in fields and r['cover']: + record.append(E.cover(r['cover'].replace(os.sep, '/'))) - if 'formats' in fields and r['formats']: - fmt = E.formats() - for f in r['formats']: - fmt.append(E.format(f.replace(os.sep, '/'))) - record.append(fmt) + if 'formats' in fields and r['formats']: + fmt = E.formats() + for f in r['formats']: + fmt.append(E.format(f.replace(os.sep, '/'))) + record.append(fmt) - if 'library_name' in fields: - record.append(E.library_name(current_library)) + if 'library_name' in fields: + record.append(E.library_name(current_library)) + except Exception as e: + raise Exception('Failed to convert {} to XML with error: {}'.format(r['title'], e)) from e with open(path_to_output, 'wb') as f: f.write(etree.tostring(root, encoding='utf-8', From 14a331526a17feb443b64633eae0720a39d6a728 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Fri, 5 May 2023 10:26:51 +0100 Subject: [PATCH 11/12] Bug #2018548: NoneType error when trying to open category manager --- src/calibre/gui2/dialogs/tag_list_editor.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/calibre/gui2/dialogs/tag_list_editor.py b/src/calibre/gui2/dialogs/tag_list_editor.py index 74d5bc274d..0c78e25cab 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.py +++ b/src/calibre/gui2/dialogs/tag_list_editor.py @@ -165,12 +165,6 @@ class TagListEditor(QDialog, Ui_TagListEditor): self.setWindowFlags(self.windowFlags()&(~Qt.WindowType.WindowContextHelpButtonHint)) self.setWindowIcon(icon) - # Get saved geometry info - try: - self.table_column_widths = gprefs.get('tag_list_editor_table_widths', None) - except: - pass - # initialization self.to_rename = {} self.to_delete = set() @@ -370,6 +364,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): # I'm not sure if this is standard Qt behavior or behavior triggered by # something in this class, but replacing the table fixes it. if self.table is not None: + self.save_geometry() self.gridlayout.removeWidget(self.table) sip.delete(self.table) self.table = TleTableWidget(self) @@ -391,8 +386,6 @@ class TagListEditor(QDialog, Ui_TagListEditor): vh.sectionResized.connect(self.row_height_changed) self.table.setColumnCount(4) - for col,width in enumerate(self.table_column_widths): - self.table.setColumnWidth(col, width) self.edit_delegate = EditColumnDelegate(self.table, self.check_for_deleted_items) self.edit_delegate.editing_finished.connect(self.stop_editing) @@ -420,7 +413,12 @@ class TagListEditor(QDialog, Ui_TagListEditor): self.not_found_label_timer_event, type=Qt.ConnectionType.QueuedConnection) self.table.setEditTriggers(QAbstractItemView.EditTrigger.EditKeyPressed) + self.restore_geometry(gprefs, 'tag_list_editor_dialog_geometry') + self.table_column_widths = gprefs.get('tag_list_editor_table_widths', None) + if self.table_column_widths is not None: + for col,width in enumerate(self.table_column_widths): + self.table.setColumnWidth(col, width) self.table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.table.customContextMenuRequested.connect(self.show_context_menu) @@ -541,7 +539,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): def do_filter(self): self.fill_in_table(None, None, False) - def table_column_resized(self, col, old, new): + def table_column_resized(self, *args): self.table_column_widths = [] for c in range(0, self.table.columnCount()): self.table_column_widths.append(self.table.columnWidth(c)) From a5969493e12f626d2f08254f3ec5c75137044c8e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 5 May 2023 20:47:40 +0530 Subject: [PATCH 12/12] A couple more feeds for Irish Independent --- recipes/irish_independent.recipe | 2 ++ 1 file changed, 2 insertions(+) diff --git a/recipes/irish_independent.recipe b/recipes/irish_independent.recipe index 681e62646b..105260fd02 100644 --- a/recipes/irish_independent.recipe +++ b/recipes/irish_independent.recipe @@ -25,7 +25,9 @@ class IrishIndependent(BasicNewsRecipe): ] feeds = [ + ('Frontpage News', 'http://www.independent.ie/rss'), ('News', 'http://www.independent.ie/rss'), + ('World News', 'http://www.independent.ie/world-news/rss'), ('Opinion', 'http://www.independent.ie/opinion/rss'), ('Business', 'http://www.independent.ie/business/rss'), ('Sport', 'http://www.independent.ie/sport/rss'),