From c57b88beb663d99cbfae030d24f7acd279d2579a Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Wed, 1 Oct 2025 20:29:43 +0200 Subject: [PATCH] Checks malformed formats --- src/calibre/gui2/dialogs/check_library.py | 12 ++++++++++++ src/calibre/library/check_library.py | 15 +++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/dialogs/check_library.py b/src/calibre/gui2/dialogs/check_library.py index fc609a7547..06834267d6 100644 --- a/src/calibre/gui2/dialogs/check_library.py +++ b/src/calibre/gui2/dialogs/check_library.py @@ -566,6 +566,18 @@ class CheckLibraryDialog(QDialog): if not dirnames and not filenames: os.rmdir(path_ath_lib) + def fix_malformed_formats(self): + tl = self.top_level_items['malformed_formats'] + child_count = tl.childCount() + for i in range(child_count): + item = tl.child(i) + id_ = int(item.data(0, Qt.ItemDataRole.UserRole)) + lib_path = item.text(2) + book_path = os.path.join(*lib_path.split(os.sep)[:-1]) + ext = os.path.splitext(lib_path)[1].strip('.') + filename = self.db.new_api.format_files(id_)[ext.upper()] +'.'+ ext.lower() + os.rename(os.path.join((self.db.library_path, lib_path)), os.path.join((self.db.library_path, book_path, filename))) + def fix_items(self): for check in CHECKS: attr = check[0] diff --git a/src/calibre/library/check_library.py b/src/calibre/library/check_library.py index bd20276980..f5f45342e7 100644 --- a/src/calibre/library/check_library.py +++ b/src/calibre/library/check_library.py @@ -41,6 +41,7 @@ CHECKS = [('invalid_titles', _('Invalid titles'), True, False), ('extra_files', _('Unknown files in books'), True, False), ('missing_covers', _('Missing cover files'), False, True), ('extra_covers', _('Cover files not in database'), True, True), + ('malformed_formats', _('Malformed formats'), False, True), # need to be perform before malformed_paths ('malformed_paths', _('Malformed book paths'), False, True), ('failed_folders', _('Folders raising exception'), False, False), ] @@ -68,6 +69,7 @@ class CheckLibrary: self.malformed_paths = [] self.malformed_paths_ids = set() + self.malformed_formats = [] self.invalid_authors = [] self.extra_authors = [] @@ -194,12 +196,15 @@ class CheckLibrary: f == COVER_FILE_NAME)) book_id = int(book_id) formats = frozenset(filter(self.is_ebook_file, filenames)) + formats_lower = frozenset(map(str.lower, filenames)) book_formats = frozenset(x[0]+'.'+x[1].lower() for x in self.db.format_files(book_id, index_is_id=True)) if self.is_case_sensitive: unknowns = frozenset(filenames-formats-NORMALS) missing = book_formats - formats + missing_lower = frozenset(map(str.lower, missing)) + # Check: any books that aren't formats or normally there? for fn in unknowns: if fn in missing: # An unknown format correctly registered @@ -210,12 +215,18 @@ class CheckLibrary: for fn in missing: if fn in unknowns: # An unknown format correctly registered continue - self.missing_formats.append((title_dir, os.path.join(db_path, fn), book_id)) + if fn.lower() in formats_lower: # An known format that is malformed + pass + else: + self.missing_formats.append((title_dir, os.path.join(db_path, fn), book_id)) # Check: any book formats that shouldn't be there? extra = formats - book_formats - NORMALS for e in extra: - self.extra_formats.append((title_dir, os.path.join(db_path, e), book_id)) + if e.lower() in missing_lower: + self.malformed_formats.append((title_dir, os.path.join(db_path, e), book_id)) + else: + self.extra_formats.append((title_dir, os.path.join(db_path, e), book_id)) else: def lc_map(fnames, fset): fn = {}