From aa652ff6c04e9f039d6bd0c6e440ea6e5a9633cf Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Tue, 15 Sep 2026 15:43:09 -0700 Subject: [PATCH] refactor kindlegen check --- kcc.py | 1 + kindlecomicconverter/KCC_gui.py | 39 ++++++----------------------- kindlecomicconverter/comic2ebook.py | 37 +++++++++++++++++++++------ 3 files changed, 37 insertions(+), 40 deletions(-) diff --git a/kcc.py b/kcc.py index 5a53c509..b0083166 100755 --- a/kcc.py +++ b/kcc.py @@ -69,6 +69,7 @@ def modify_path(): os.path.expandvars('%LOCALAPPDATA%\\Amazon\\KC2'), os.path.expandvars('%LOCALAPPDATA%\\Amazon\\Kindle Previewer 3\\lib\\fc\\bin\\'), os.path.expandvars('%UserProfile%\\Kindle Previewer 3\\lib\\fc\\bin\\'), + 'C:\\Tools', 'C:\\Program Files\\WindowsApps\\KindlePreviewerApp_4.0.0.0_x64__ek06e0aw29nma\\KindlePreviewerApp\\resources\\KFXGen\\bin', 'C:\\Apps\\Kindle Previewer 3\\lib\\fc\\bin', 'D:\\Apps\\Kindle Previewer 3\\lib\\fc\\bin', diff --git a/kindlecomicconverter/KCC_gui.py b/kindlecomicconverter/KCC_gui.py index a2392b23..9ff7449c 100644 --- a/kindlecomicconverter/KCC_gui.py +++ b/kindlecomicconverter/KCC_gui.py @@ -32,7 +32,6 @@ import sys from urllib.parse import unquote from time import sleep from shutil import move, rmtree -from subprocess import STDOUT, PIPE, CalledProcessError import requests from xml.sax.saxutils import escape @@ -45,9 +44,9 @@ from PIL.Image import Dither from .KCC_spread_label import LabelSpreadsDialog -from .shared import HTMLStripper, sanitizeTrace, walkLevel, subprocess_run +from .shared import HTMLStripper, sanitizeTrace, walkLevel from .comicarchive import SEVENZIP, TAR, available_archive_tools -from .comic2ebook import OS_SORT_KEY, flattenTree, getWorkFolder, removeNonImages, sanitizeTree +from .comic2ebook import OS_SORT_KEY, flattenTree, getWorkFolder, removeNonImages, sanitizeTree, detectKindleGen from . import __version__ from . import comic2ebook from . import metadata @@ -1255,8 +1254,8 @@ class KCCGUI(KCC_ui.Ui_mainWindow): self.needClean = True return if 'MOBI' in GUI.formats[str(GUI.formatBox.currentText())]['format'] and not self.kindleGen: - self.detectKindleGen() - if not self.kindleGen: + if not detectKindleGen(GUI): + self.progress.stop() GUI.jobList.clear() self.display_kindlegen_missing() self.needClean = True @@ -1384,32 +1383,6 @@ class KCCGUI(KCC_ui.Ui_mainWindow): self.saveSettings(None) sys.exit(0) - def detectKindleGen(self, startup=False): - if not sys.platform.startswith('win'): - try: - os.chmod('/usr/local/bin/kindlegen', 0o755) - except Exception: - pass - try: - versionCheck = subprocess_run(['kindlegen', '-locale', 'en'], stdout=PIPE, stderr=STDOUT, encoding='UTF-8', errors='ignore', check=True) - self.kindleGen = True - for line in versionCheck.stdout.splitlines(): - if 'Amazon kindlegen' in line: - versionCheck = line.split('V')[1].split(' ')[0] - if Version(versionCheck) < Version('2.9'): - self.addMessage('Your KindleGen' - ' is outdated! MOBI conversion might fail.', 'warning') - break - except (FileNotFoundError, CalledProcessError): - self.kindleGen = False - if startup: - self.display_kindlegen_missing() - except OSError as e: - self.kindleGen = False - if startup: - error = f"kindlegen: {e.strerror}\n\n Re-install or re-open Rosetta/Kindle Previewer/other Intel app?" - self.showDialog(error, 'error') - def __init__(self, kccapp, kccwindow): global APP, MW, GUI APP = kccapp @@ -1442,8 +1415,11 @@ class KCCGUI(KCC_ui.Ui_mainWindow): except Exception: self.options = default_options self.worker = WorkerThread() + self.worker.setObjectName('worker') self.versionCheck = VersionThread(self.startNumber2) + self.versionCheck.setObjectName('version') self.progress = ProgressThread() + self.progress.setObjectName('progress') self.tray = SystemTrayIcon() self.conversionAlive = False self.needClean = True @@ -1674,7 +1650,6 @@ class KCCGUI(KCC_ui.Ui_mainWindow): if not any([self.tar, self.sevenzip]): self.addMessage('Install 7z (link)' ' to enable CBZ/CBR/ZIP/etc processing.', 'warning') - self.detectKindleGen(True) APP.messageFromOtherInstance.connect(self.handleMessage) GUI.defaultOutputFolderButton.clicked.connect(self.selectDefaultOutputFolder) diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index 4b4ebcc8..255300eb 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -40,6 +40,7 @@ from shutil import move, copytree, rmtree from multiprocessing import Pool, cpu_count from uuid import uuid4 from natsort import os_sort_keygen, os_sorted +from packaging.version import Version from slugify import slugify as slugify_ext from PIL import Image, ImageFile, ImageOps from pathlib import Path @@ -1749,16 +1750,36 @@ def checkTools(source): print('ERROR: 7z is missing!') sys.exit(1) if options.format == 'MOBI': - try: - subprocess_run(['kindlegen', '-locale', 'en'], stdout=PIPE, stderr=STDOUT, check=True) - except (FileNotFoundError, CalledProcessError): - print('ERROR: KindleGen is missing!') - sys.exit(1) - except OSError as e: - print(f"kindlegen: {e.strerror}") - print('Re-install or re-open Rosetta/Kindle Previewer/other Intel app?') + if not detectKindleGen(): sys.exit(1) +def detectKindleGen(GUI=None): + if not sys.platform.startswith('win'): + try: + os.chmod('/usr/local/bin/kindlegen', 0o755) + except Exception: + pass + try: + versionCheck = subprocess_run(['kindlegen', '-locale', 'en'], stdout=PIPE, stderr=STDOUT, encoding='UTF-8', errors='ignore', check=True) + for line in versionCheck.stdout.splitlines(): + if 'Amazon kindlegen' in line: + versionCheck = line.split('V')[1].split(' ')[0] + if Version(versionCheck) < Version('2.9'): + if GUI: + GUI.addMessage('Your KindleGen' + ' is outdated! MOBI conversion might fail.', 'warning') + break + return True + except (FileNotFoundError, CalledProcessError): + print('ERROR: KindleGen is missing!') + return False + except OSError as e: + print(f"kindlegen: {e.strerror}") + print('Re-install or re-open Rosetta/Kindle Previewer/other Intel app?') + if GUI: + error = f"kindlegen: {e.strerror}\n\n Re-install or re-open Rosetta/Kindle Previewer/other Intel app?" + GUI.showDialog(error, 'error') + return False def checkPre(source='KCC-'): # Make sure that all temporary files are gone