From 42a50ed6701bf2c8deaee031e0277f2b8463b640 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 12:04:38 -0700 Subject: [PATCH 01/19] Bump actions/upload-artifact from 6 to 7 (#1256) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/package-linux.yml | 2 +- .github/workflows/package-macos.yml | 2 +- .github/workflows/package-osx-legacy.yml | 2 +- .github/workflows/package-windows.yml | 2 +- .github/workflows/package-windows7.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/package-linux.yml b/.github/workflows/package-linux.yml index b1d22d8..33c6557 100644 --- a/.github/workflows/package-linux.yml +++ b/.github/workflows/package-linux.yml @@ -59,7 +59,7 @@ jobs: env: UPDATE_INFO: gh-releases-zsync|ciromattia|kcc|latest|*x86_64.AppImage.zsync - name: upload artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: AppImage path: './*.AppImage*' diff --git a/.github/workflows/package-macos.yml b/.github/workflows/package-macos.yml index 7d56f76..5338a55 100644 --- a/.github/workflows/package-macos.yml +++ b/.github/workflows/package-macos.yml @@ -80,7 +80,7 @@ jobs: run: | python setup.py build_binary - name: upload build - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: mac-os-build-${{ runner.arch }} path: dist/*.dmg diff --git a/.github/workflows/package-osx-legacy.yml b/.github/workflows/package-osx-legacy.yml index 8094d3b..2bda33a 100644 --- a/.github/workflows/package-osx-legacy.yml +++ b/.github/workflows/package-osx-legacy.yml @@ -51,7 +51,7 @@ jobs: run: | python3 setup.py build_binary - name: upload build - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: osx-build-${{ runner.arch }} path: dist/*.dmg diff --git a/.github/workflows/package-windows.yml b/.github/workflows/package-windows.yml index 7653218..4bc84cf 100644 --- a/.github/workflows/package-windows.yml +++ b/.github/workflows/package-windows.yml @@ -53,7 +53,7 @@ jobs: python setup.py ${{ matrix.command }} - name: upload-unsigned-artifact id: upload-unsigned-artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: windows-build-${{ matrix.entry }} path: dist/*.exe diff --git a/.github/workflows/package-windows7.yml b/.github/workflows/package-windows7.yml index 5e55c27..4263fe7 100644 --- a/.github/workflows/package-windows7.yml +++ b/.github/workflows/package-windows7.yml @@ -46,7 +46,7 @@ jobs: python setup.py build_binary - name: upload-unsigned-artifact id: upload-unsigned-artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: windows7-build path: dist/*.exe From d72983997603d2421cb628c1ed6efc21a76f68ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 12:04:51 -0700 Subject: [PATCH 02/19] Bump docker/setup-buildx-action from 3 to 4 (#1260) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 650a55b..3de8d7b 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -34,7 +34,7 @@ jobs: uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Set Release Date id: release_date From 53ae057cbb9017be5597ab74ac3f18a80a40a772 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 12:05:05 -0700 Subject: [PATCH 03/19] Bump docker/metadata-action from 5 to 6 (#1261) Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/v5...v6) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 3de8d7b..bc61f4f 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -43,7 +43,7 @@ jobs: - name: Docker meta id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: ghcr.io/${{ github.repository_owner }}/kcc # Always creates the "latest" tag From f42e6aea5c79ced61e365c9b2f3dfb506873756d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 12:05:16 -0700 Subject: [PATCH 04/19] Bump docker/login-action from 3 to 4 (#1262) Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index bc61f4f..b4a3569 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v6 - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.repository_owner }} From 0db788589d65e09cdeb30a9e9b1bb1dfbcf97b35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 12:05:27 -0700 Subject: [PATCH 05/19] Bump docker/setup-qemu-action from 3 to 4 (#1263) Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index b4a3569..80afa74 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -31,7 +31,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 From 60d41b25e48e8c1d703269f8121507cf0d2013e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 10 May 2026 18:59:42 -0700 Subject: [PATCH 06/19] Bump softprops/action-gh-release from 2 to 3 (#1335) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: '3' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/package-linux.yml | 2 +- .github/workflows/package-macos.yml | 2 +- .github/workflows/package-osx-legacy.yml | 2 +- .github/workflows/package-windows.yml | 2 +- .github/workflows/package-windows7.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/package-linux.yml b/.github/workflows/package-linux.yml index 33c6557..a862ee2 100644 --- a/.github/workflows/package-linux.yml +++ b/.github/workflows/package-linux.yml @@ -64,7 +64,7 @@ jobs: name: AppImage path: './*.AppImage*' - name: Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@v3 if: startsWith(github.ref, 'refs/tags/') with: prerelease: true diff --git a/.github/workflows/package-macos.yml b/.github/workflows/package-macos.yml index 5338a55..7bdf9ea 100644 --- a/.github/workflows/package-macos.yml +++ b/.github/workflows/package-macos.yml @@ -85,7 +85,7 @@ jobs: name: mac-os-build-${{ runner.arch }} path: dist/*.dmg - name: Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@v3 if: startsWith(github.ref, 'refs/tags/') with: prerelease: true diff --git a/.github/workflows/package-osx-legacy.yml b/.github/workflows/package-osx-legacy.yml index 2bda33a..57c0118 100644 --- a/.github/workflows/package-osx-legacy.yml +++ b/.github/workflows/package-osx-legacy.yml @@ -56,7 +56,7 @@ jobs: name: osx-build-${{ runner.arch }} path: dist/*.dmg - name: Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@v3 if: startsWith(github.ref, 'refs/tags/') with: prerelease: true diff --git a/.github/workflows/package-windows.yml b/.github/workflows/package-windows.yml index 4bc84cf..215aaa7 100644 --- a/.github/workflows/package-windows.yml +++ b/.github/workflows/package-windows.yml @@ -69,7 +69,7 @@ jobs: wait-for-completion: true output-artifact-directory: 'dist/' - name: Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@v3 if: startsWith(github.ref, 'refs/tags/') with: prerelease: true diff --git a/.github/workflows/package-windows7.yml b/.github/workflows/package-windows7.yml index 4263fe7..5919782 100644 --- a/.github/workflows/package-windows7.yml +++ b/.github/workflows/package-windows7.yml @@ -62,7 +62,7 @@ jobs: wait-for-completion: true output-artifact-directory: 'dist/' - name: Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@v3 if: startsWith(github.ref, 'refs/tags/') with: prerelease: true From 75d0342fe159719a7f82f0191738db89eba96c31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 10 May 2026 18:59:54 -0700 Subject: [PATCH 07/19] Bump docker/build-push-action from 6 to 7 (#1336) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6...v7) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 80afa74..2d2a801 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -54,7 +54,7 @@ jobs: type=raw,value=${{ steps.release_date.outputs.release_date }} - name: Build and push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: platforms: linux/amd64,linux/arm64,linux/arm/v7 context: . From a49181081066af0424c46f4ab00181d62bb2feed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 10 May 2026 19:00:05 -0700 Subject: [PATCH 08/19] Bump signpath/github-action-submit-signing-request from 2.0 to 2.2 (#1337) Bumps [signpath/github-action-submit-signing-request](https://github.com/signpath/github-action-submit-signing-request) from 2.0 to 2.2. - [Release notes](https://github.com/signpath/github-action-submit-signing-request/releases) - [Commits](https://github.com/signpath/github-action-submit-signing-request/compare/v2.0...v2.2) --- updated-dependencies: - dependency-name: signpath/github-action-submit-signing-request dependency-version: '2.2' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/package-windows.yml | 2 +- .github/workflows/package-windows7.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package-windows.yml b/.github/workflows/package-windows.yml index 215aaa7..6dfbd73 100644 --- a/.github/workflows/package-windows.yml +++ b/.github/workflows/package-windows.yml @@ -58,7 +58,7 @@ jobs: name: windows-build-${{ matrix.entry }} path: dist/*.exe - id: optional_step_id - uses: signpath/github-action-submit-signing-request@v2.0 + uses: signpath/github-action-submit-signing-request@v2.2 if: ${{ github.repository == 'ciromattia/kcc' }} with: api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' diff --git a/.github/workflows/package-windows7.yml b/.github/workflows/package-windows7.yml index 5919782..adbb476 100644 --- a/.github/workflows/package-windows7.yml +++ b/.github/workflows/package-windows7.yml @@ -51,7 +51,7 @@ jobs: name: windows7-build path: dist/*.exe - id: optional_step_id - uses: signpath/github-action-submit-signing-request@v2.0 + uses: signpath/github-action-submit-signing-request@v2.2 if: ${{ github.repository == 'ciromattia/kcc' }} with: api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' From 4a6e4622edc7346ca379718e3e99d7c5e3b129fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=AB=E3=82=BF=E3=83=BC=E3=83=9A?= =?UTF-8?q?=E3=83=BC=E3=83=91=E3=83=BC?= <76888457+filterpaper@users.noreply.github.com> Date: Tue, 21 Apr 2026 14:20:46 +0800 Subject: [PATCH 09/19] Use tempdir option for fusion path * Update makeFusion to use the same temporary directory location * Avoid creating an orphan "KCC-" in TMPDIR when --tempdir is set --- kindlecomicconverter/comic2ebook.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index 8cd316c..7491c8a 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -1632,10 +1632,13 @@ def makeFusion(sources: List[str]): raise UserWarning('Fusion requires at least 2 sources. Did you forget to uncheck fusion?') start = perf_counter() first_path = Path(sources[0]) + fusion_parent = Path(gettempdir()) + if options.tempdir: + fusion_parent = first_path.parent if first_path.is_file(): - fusion_path = first_path.parent.joinpath(first_path.stem + ' [fused]') + fusion_path = fusion_parent.joinpath(first_path.stem + ' [fused]') else: - fusion_path = first_path.parent.joinpath(first_path.name + ' [fused]') + fusion_path = fusion_parent.joinpath(first_path.name + ' [fused]') print("Running Fusion") # Check if prefix is needed when user-specified ordering differs from OS natural sorting From b95bb12393b6c1a46a1095bda4c275a11e7bd585 Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Mon, 11 May 2026 11:53:20 -0700 Subject: [PATCH 10/19] honor temp directory option in all locations --- kindlecomicconverter/comic2ebook.py | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index 7491c8a..a232471 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -30,8 +30,8 @@ from glob import glob, escape from re import sub from stat import S_IWRITE, S_IREAD, S_IEXEC from typing import List -from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED -from tempfile import mkdtemp, gettempdir, TemporaryFile +from zipfile import ZipFile, ZIP_STORED +from tempfile import mkdtemp, gettempdir from shutil import move, copytree, rmtree, copyfile from multiprocessing import Pool, cpu_count from uuid import uuid4 @@ -892,9 +892,12 @@ def getWorkFolder(afile, workdir=None): fullPath = os.path.join(workdir, 'OEBPS', 'Images') else: fullPath = workdir - check_path = gettempdir() + if options.tempdir: check_path = os.path.dirname(afile) + else: + check_path = gettempdir() + if os.path.isdir(afile): if disk_usage(check_path)[2] < getDirectorySize(afile) * 2.5: raise UserWarning("Not enough disk space to perform conversion.") @@ -1615,26 +1618,18 @@ def checkPre(source): for tempdir in dirs: if tempdir.startswith('KCC-'): rmtree(os.path.join(root, tempdir), True) - # Make sure that target directory is writable - if os.path.isdir(source): - src = os.path.abspath(os.path.join(source, '..')) - else: - src = os.path.dirname(source) - try: - with TemporaryFile(prefix='KCC-', dir=src): - pass - except Exception: - raise UserWarning("Target directory is not writable.") - def makeFusion(sources: List[str]): if len(sources) < 2: raise UserWarning('Fusion requires at least 2 sources. Did you forget to uncheck fusion?') start = perf_counter() first_path = Path(sources[0]) - fusion_parent = Path(gettempdir()) + if options.tempdir: fusion_parent = first_path.parent + else: + fusion_parent = Path(gettempdir()) + if first_path.is_file(): fusion_path = fusion_parent.joinpath(first_path.stem + ' [fused]') else: From ffeaaeca190d1f080bde03135bc4966e06555210 Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Mon, 11 May 2026 16:34:11 -0700 Subject: [PATCH 11/19] clean up temp files better --- kindlecomicconverter/KCC_gui.py | 1 + kindlecomicconverter/comic2ebook.py | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/kindlecomicconverter/KCC_gui.py b/kindlecomicconverter/KCC_gui.py index 9d9fb5b..566bc3b 100644 --- a/kindlecomicconverter/KCC_gui.py +++ b/kindlecomicconverter/KCC_gui.py @@ -564,6 +564,7 @@ class WorkerThread(QThread): os.remove(path) elif os.path.isdir(path): rmtree(path, True) + comic2ebook.checkPre('LLL-') GUI.progress.content = '' GUI.progress.stop() MW.hideProgressBar.emit() diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index a232471..6a92f1a 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -90,6 +90,7 @@ def main(argv=None): os.remove(path) elif os.path.isdir(path): rmtree(path, True) + checkPre('LLL-') return 0 @@ -1612,11 +1613,11 @@ def checkTools(source): sys.exit(1) -def checkPre(source): +def checkPre(source='KCC-'): # Make sure that all temporary files are gone for root, dirs, _ in walkLevel(gettempdir(), 0): for tempdir in dirs: - if tempdir.startswith('KCC-'): + if tempdir.startswith(source): rmtree(os.path.join(root, tempdir), True) def makeFusion(sources: List[str]): @@ -1628,7 +1629,9 @@ def makeFusion(sources: List[str]): if options.tempdir: fusion_parent = first_path.parent else: - fusion_parent = Path(gettempdir()) + # LLL is after KCC + checkPre('LLL-') + fusion_parent = Path(mkdtemp('', 'LLL-')) if first_path.is_file(): fusion_path = fusion_parent.joinpath(first_path.stem + ' [fused]') @@ -1642,7 +1645,6 @@ def makeFusion(sources: List[str]): for index, source in enumerate(sources, start=1): print(f"Processing {source}...") - checkPre(source) print("Checking images...") source_path = Path(source) # Add the fusion_0001_ prefix to maintain user-specified order if needed @@ -1674,7 +1676,9 @@ def makeBook(source, qtgui=None, job_progress=''): GUI.progressBarTick.emit('1') else: checkTools(source) - checkPre(source) + checkPre() + if not options.filefusion: + checkPre('LLL-') print(f"{job_progress}Preparing source images...") path = getWorkFolder(source) print(f"{job_progress}Checking images...") From 1af24b394fdf4b5bb4b664cac7a78e50dc5fef33 Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Thu, 14 May 2026 22:04:20 -0700 Subject: [PATCH 12/19] remove raven (#1341) * remove raven * remove raven README --- .gitignore | 1 - README.md | 1 - kindlecomicconverter/KCC_gui.py | 6 ------ kindlecomicconverter/shared.py | 4 ---- requirements-osx-legacy.txt | 1 - requirements-win7.txt | 1 - requirements.txt | 1 - setup.py | 1 - 8 files changed, 16 deletions(-) diff --git a/.gitignore b/.gitignore index 0f952a0..a27db6f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ Pipfile Pipfile.lock setup.bat -kindlecomicconverter/sentry.py other/windows/kindlegen.exe dist/ build/ diff --git a/README.md b/README.md index 7624d58..ca7b327 100644 --- a/README.md +++ b/README.md @@ -442,7 +442,6 @@ Older links (dead): ## PRIVACY **KCC** is initiating internet connections in two cases: * During startup - Version check and announcement check. -* When error occurs - Automatic reporting on Windows and macOS. ## KNOWN ISSUES Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues). diff --git a/kindlecomicconverter/KCC_gui.py b/kindlecomicconverter/KCC_gui.py index 566bc3b..c25c290 100644 --- a/kindlecomicconverter/KCC_gui.py +++ b/kindlecomicconverter/KCC_gui.py @@ -38,7 +38,6 @@ from xml.sax.saxutils import escape from psutil import Process from copy import copy from packaging.version import Version -from raven import Client from tempfile import gettempdir from .shared import HTMLStripper, sanitizeTrace, walkLevel, subprocess_run @@ -445,8 +444,6 @@ class WorkerThread(QThread): _, _, traceback = sys.exc_info() MW.showDialog.emit("Error during conversion %s:\n\n%s\n\nTraceback:\n%s" % (jobargv[-1], str(err), sanitizeTrace(traceback)), 'error') - if ' is corrupted.' not in str(err): - GUI.sentry.captureException() MW.addMessage.emit('Error during conversion! Please consult ' 'wiki ' 'for more details.', 'error', False) @@ -682,7 +679,6 @@ class KCCGUI(KCC_ui.Ui_mainWindow): self.editor.loadData(sname) except Exception as err: _, _, traceback = sys.exc_info() - GUI.sentry.captureException() self.showDialog("Failed to parse metadata!\n\n%s\n\nTraceback:\n%s" % (str(err), sanitizeTrace(traceback)), 'error') else: @@ -1211,7 +1207,6 @@ class KCCGUI(KCC_ui.Ui_mainWindow): self.croppingPowerValue = 1.0 self.currentMode = 1 self.targetDirectory = '' - self.sentry = Client(release=__version__) if sys.platform.startswith('win'): # noinspection PyUnresolvedReferences from psutil import BELOW_NORMAL_PRIORITY_CLASS @@ -1581,7 +1576,6 @@ class KCCGUI_MetaEditor(KCC_ui_editor.Ui_editorDialog): self.parser.saveXML() except Exception as err: _, _, traceback = sys.exc_info() - GUI.sentry.captureException() GUI.showDialog("Failed to save metadata!\n\n%s\n\nTraceback:\n%s" % (str(err), sanitizeTrace(traceback)), 'error') self.ui.close() diff --git a/kindlecomicconverter/shared.py b/kindlecomicconverter/shared.py index 857b6cc..1214317 100644 --- a/kindlecomicconverter/shared.py +++ b/kindlecomicconverter/shared.py @@ -122,10 +122,6 @@ def dependencyCheck(level): missing.append('PySide 6.0.0') except ImportError: missing.append('PySide 6.0.0+') - try: - import raven - except ImportError: - missing.append('raven 6.0.0+') if level > 1: try: from psutil import __version__ as psutilVersion diff --git a/requirements-osx-legacy.txt b/requirements-osx-legacy.txt index 6e4d643..8a09165 100644 --- a/requirements-osx-legacy.txt +++ b/requirements-osx-legacy.txt @@ -3,7 +3,6 @@ Pillow>=11.3.0 psutil>=5.9.5 requests>=2.31.0 python-slugify>=1.2.1 -raven>=6.0.0 packaging>=23.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 diff --git a/requirements-win7.txt b/requirements-win7.txt index 47717d4..7122ec4 100644 --- a/requirements-win7.txt +++ b/requirements-win7.txt @@ -3,7 +3,6 @@ Pillow>=9 psutil>=5.9.5 requests>=2.31.0 python-slugify>=1.2.1 -raven>=6.0.0 packaging>=23.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 diff --git a/requirements.txt b/requirements.txt index 8edccd8..a12a78f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,6 @@ Pillow>=11.3.0 psutil>=5.9.5 requests>=2.31.0 python-slugify>=1.2.1,<9.0.0 -raven>=6.0.0 packaging>=23.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 diff --git a/setup.py b/setup.py index f791414..38dc48e 100644 --- a/setup.py +++ b/setup.py @@ -153,7 +153,6 @@ setuptools.setup( 'psutil>=5.9.5', 'requests>=2.31.0', 'python-slugify>=1.2.1,<9.0.0', - 'raven>=6.0.0', 'mozjpeg-lossless-optimization>=1.2.0', 'natsort>=8.4.0', 'distro>=1.8.0', From 868a31cb002f30f954ef8579016fc3531638fca3 Mon Sep 17 00:00:00 2001 From: Flavio Mello Date: Fri, 15 May 2026 02:07:38 -0300 Subject: [PATCH 13/19] Update setup.py (#1339) Include packaging in setup.py install_requires --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 38dc48e..daf2276 100644 --- a/setup.py +++ b/setup.py @@ -157,6 +157,7 @@ setuptools.setup( 'natsort>=8.4.0', 'distro>=1.8.0', 'numpy>=1.22.4', + 'packaging>=23.2', 'PyMuPDF>=1.16.1', ], classifiers=[], From 84f69a09505def77e6f9b67d8e414a0806ea85db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 22:12:12 -0700 Subject: [PATCH 14/19] Update packaging requirement from >=23.2 to >=26.2 (#1315) Updates the requirements on [packaging](https://github.com/pypa/packaging) to permit the latest version. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/23.2...26.2) --- updated-dependencies: - dependency-name: packaging dependency-version: '26.2' dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-docker.txt | 2 +- requirements-osx-legacy.txt | 2 +- requirements-win7.txt | 2 +- requirements.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-docker.txt b/requirements-docker.txt index 077a006..f8e40d3 100644 --- a/requirements-docker.txt +++ b/requirements-docker.txt @@ -2,7 +2,7 @@ Pillow>=11.3.0 psutil>=5.9.5 requests>=2.31.0 python-slugify>=1.2.1 -packaging>=23.2 +packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 distro>=1.8.0 diff --git a/requirements-osx-legacy.txt b/requirements-osx-legacy.txt index 8a09165..09377e8 100644 --- a/requirements-osx-legacy.txt +++ b/requirements-osx-legacy.txt @@ -3,7 +3,7 @@ Pillow>=11.3.0 psutil>=5.9.5 requests>=2.31.0 python-slugify>=1.2.1 -packaging>=23.2 +packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 distro>=1.8.0 diff --git a/requirements-win7.txt b/requirements-win7.txt index 7122ec4..611ecbe 100644 --- a/requirements-win7.txt +++ b/requirements-win7.txt @@ -3,7 +3,7 @@ Pillow>=9 psutil>=5.9.5 requests>=2.31.0 python-slugify>=1.2.1 -packaging>=23.2 +packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 distro>=1.8.0 diff --git a/requirements.txt b/requirements.txt index a12a78f..a82de2d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ Pillow>=11.3.0 psutil>=5.9.5 requests>=2.31.0 python-slugify>=1.2.1,<9.0.0 -packaging>=23.2 +packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 distro>=1.8.0 From 949fb0acb4e77090af0cabc6bd7a59fee5ff612a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 22:13:14 -0700 Subject: [PATCH 15/19] Update requests requirement from >=2.31.0 to >=2.34.2 (#1313) Updates the requirements on [requests](https://github.com/psf/requests) to permit the latest version. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.31.0...v2.34.2) --- updated-dependencies: - dependency-name: requests dependency-version: 2.33.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-docker.txt | 2 +- requirements-osx-legacy.txt | 2 +- requirements-win7.txt | 2 +- requirements.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-docker.txt b/requirements-docker.txt index f8e40d3..3b5c1d4 100644 --- a/requirements-docker.txt +++ b/requirements-docker.txt @@ -1,6 +1,6 @@ Pillow>=11.3.0 psutil>=5.9.5 -requests>=2.31.0 +requests>=2.34.2 python-slugify>=1.2.1 packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 diff --git a/requirements-osx-legacy.txt b/requirements-osx-legacy.txt index 09377e8..d809eb6 100644 --- a/requirements-osx-legacy.txt +++ b/requirements-osx-legacy.txt @@ -1,7 +1,7 @@ PySide6==6.4.3 Pillow>=11.3.0 psutil>=5.9.5 -requests>=2.31.0 +requests>=2.34.2 python-slugify>=1.2.1 packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 diff --git a/requirements-win7.txt b/requirements-win7.txt index 611ecbe..60d83fb 100644 --- a/requirements-win7.txt +++ b/requirements-win7.txt @@ -1,7 +1,7 @@ PySide6==6.1.3 Pillow>=9 psutil>=5.9.5 -requests>=2.31.0 +requests>=2.34.2 python-slugify>=1.2.1 packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 diff --git a/requirements.txt b/requirements.txt index a82de2d..3fe6f93 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ PySide6<6.10 Pillow>=11.3.0 psutil>=5.9.5 -requests>=2.31.0 +requests>=2.34.2 python-slugify>=1.2.1,<9.0.0 packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 From 8030884148e9e11e91408f89148791fd4a022804 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 22:15:29 -0700 Subject: [PATCH 16/19] Update python-slugify requirement from >=1.2.1 to >=8.0.4 (#1314) Updates the requirements on [python-slugify](https://github.com/un33k/python-slugify) to permit the latest version. - [Changelog](https://github.com/un33k/python-slugify/blob/master/CHANGELOG.md) - [Commits](https://github.com/un33k/python-slugify/compare/1.2.1...v8.0.4) --- updated-dependencies: - dependency-name: python-slugify dependency-version: 8.0.4 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-docker.txt | 2 +- requirements-osx-legacy.txt | 2 +- requirements-win7.txt | 2 +- requirements.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-docker.txt b/requirements-docker.txt index 3b5c1d4..193bb24 100644 --- a/requirements-docker.txt +++ b/requirements-docker.txt @@ -1,7 +1,7 @@ Pillow>=11.3.0 psutil>=5.9.5 requests>=2.34.2 -python-slugify>=1.2.1 +python-slugify>=8.0.4 packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 diff --git a/requirements-osx-legacy.txt b/requirements-osx-legacy.txt index d809eb6..90eb637 100644 --- a/requirements-osx-legacy.txt +++ b/requirements-osx-legacy.txt @@ -2,7 +2,7 @@ PySide6==6.4.3 Pillow>=11.3.0 psutil>=5.9.5 requests>=2.34.2 -python-slugify>=1.2.1 +python-slugify>=8.0.4 packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 diff --git a/requirements-win7.txt b/requirements-win7.txt index 60d83fb..637f428 100644 --- a/requirements-win7.txt +++ b/requirements-win7.txt @@ -2,7 +2,7 @@ PySide6==6.1.3 Pillow>=9 psutil>=5.9.5 requests>=2.34.2 -python-slugify>=1.2.1 +python-slugify>=8.0.4 packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 diff --git a/requirements.txt b/requirements.txt index 3fe6f93..ca8358b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ PySide6<6.10 Pillow>=11.3.0 psutil>=5.9.5 requests>=2.34.2 -python-slugify>=1.2.1,<9.0.0 +python-slugify>=8.0.4,<9.0.0 packaging>=26.2 mozjpeg-lossless-optimization>=1.2.0 natsort>=8.4.0 From 9827f11944dc9e317ed9aad5d7ad64cea97465bb Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Fri, 15 May 2026 13:24:35 -0700 Subject: [PATCH 17/19] experimental epub input (#1090) * experimental epub input * fix missing spine items * only extract first image on page * re-organize * fallback if naive spine extraction fails * apply legacy extract option for epub too --- README.md | 2 +- gui/KCC.ui | 8 ++-- kindlecomicconverter/KCC_gui.py | 10 ++--- kindlecomicconverter/KCC_ui.py | 12 +++--- kindlecomicconverter/comic2ebook.py | 66 ++++++++++++++++++++++++++--- 5 files changed, 73 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index ca7b327..4a89344 100644 --- a/README.md +++ b/README.md @@ -247,7 +247,7 @@ MAIN: PROCESSING: -n, --noprocessing Do not modify image and ignore any profile or processing option - --pdfextract Use legacy PDF image extraction method from KCC 8 and earlier. + --legacyextract Use legacy PDF/EPUB image extraction method from earlier KCC versions. --pdfwidth Render vector PDFs based on device width instead of height. -u, --upscale Resize images smaller than device's resolution -s, --stretch Stretch images to device's resolution diff --git a/gui/KCC.ui b/gui/KCC.ui index 9cc41d3..fffbe9b 100644 --- a/gui/KCC.ui +++ b/gui/KCC.ui @@ -750,14 +750,12 @@ Higher values are larger and higher quality, and may resolve blank page issues.< - + - Use the PDF image extraction method from KCC 8 and earlier. - -Useful for really weird PDFs. + <html><head/><body><p>Use the PDF/EPUB image extraction method from older KCC versions.</p><p><br/></p><p>Use if standard extraction fails for whatever reason.</p></body></html> - PDF Legacy Extract + Legacy Extract diff --git a/kindlecomicconverter/KCC_gui.py b/kindlecomicconverter/KCC_gui.py index c25c290..802b73d 100644 --- a/kindlecomicconverter/KCC_gui.py +++ b/kindlecomicconverter/KCC_gui.py @@ -326,8 +326,8 @@ class WorkerThread(QThread): options.maximizestrips = True if GUI.disableProcessingBox.isChecked(): options.noprocessing = True - if GUI.pdfExtractBox.isChecked(): - options.pdfextract = True + if GUI.legacyExtractBox.isChecked(): + options.legacyextract = True if GUI.pdfWidthBox.isChecked(): options.pdfwidth = True if GUI.smartCoverCropBox.isChecked(): @@ -625,7 +625,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow): GUI.jobList.clear() if self.tar or self.sevenzip: fnames = QFileDialog.getOpenFileNames(MW, 'Select file', self.lastPath, - 'Comic (*.cbz *.cbr *.cb7 *.zip *.rar *.7z *.pdf);;All (*.*)') + 'Comic (*.cbz *.cbr *.cb7 *.zip *.rar *.7z *.epub *.pdf);;All (*.*)') else: fnames = QFileDialog.getOpenFileNames(MW, 'Select file', self.lastPath, 'Comic (*.pdf);;All (*.*)') @@ -1080,7 +1080,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow): 'colorBox': GUI.colorBox.checkState(), 'eraseRainbowBox': GUI.eraseRainbowBox.checkState(), 'disableProcessingBox': GUI.disableProcessingBox.checkState(), - 'pdfExtractBox': GUI.pdfExtractBox.checkState(), + 'legacyExtractBox': GUI.legacyExtractBox.checkState(), 'pdfWidthBox': GUI.pdfWidthBox.checkState(), 'smartCoverCropBox': GUI.smartCoverCropBox.checkState(), 'coverFillBox': GUI.coverFillBox.checkState(), @@ -1120,7 +1120,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow): GUI.jobList.clear() formats = ['.pdf'] if self.tar or self.sevenzip: - formats.extend(['.cb7', '.7z', '.cbz', '.zip', '.cbr', '.rar']) + formats.extend(['.cb7', '.7z', '.cbz', '.zip', '.cbr', '.rar', '.epub']) if os.path.isdir(message): GUI.jobList.addItem(message) GUI.jobList.scrollToBottom() diff --git a/kindlecomicconverter/KCC_ui.py b/kindlecomicconverter/KCC_ui.py index 62e9d29..c762dab 100644 --- a/kindlecomicconverter/KCC_ui.py +++ b/kindlecomicconverter/KCC_ui.py @@ -389,10 +389,10 @@ class Ui_mainWindow(object): self.gridLayout_2.addWidget(self.qualityBox, 1, 2, 1, 1) - self.pdfExtractBox = QCheckBox(self.optionWidget) - self.pdfExtractBox.setObjectName(u"pdfExtractBox") + self.legacyExtractBox = QCheckBox(self.optionWidget) + self.legacyExtractBox.setObjectName(u"legacyExtractBox") - self.gridLayout_2.addWidget(self.pdfExtractBox, 9, 0, 1, 1) + self.gridLayout_2.addWidget(self.legacyExtractBox, 9, 0, 1, 1) self.colorBox = QCheckBox(self.optionWidget) self.colorBox.setObjectName(u"colorBox") @@ -785,11 +785,9 @@ class Ui_mainWindow(object): #endif // QT_CONFIG(tooltip) self.qualityBox.setText(QCoreApplication.translate("mainWindow", u"Panel View 4/2/HQ", None)) #if QT_CONFIG(tooltip) - self.pdfExtractBox.setToolTip(QCoreApplication.translate("mainWindow", u"Use the PDF image extraction method from KCC 8 and earlier.\n" -"\n" -"Useful for really weird PDFs.", None)) + self.legacyExtractBox.setToolTip(QCoreApplication.translate("mainWindow", u"

Use the PDF/EPUB image extraction method from older KCC versions.


Use if standard extraction fails for whatever reason.

", None)) #endif // QT_CONFIG(tooltip) - self.pdfExtractBox.setText(QCoreApplication.translate("mainWindow", u"PDF Legacy Extract", None)) + self.legacyExtractBox.setText(QCoreApplication.translate("mainWindow", u"Legacy Extract", None)) #if QT_CONFIG(tooltip) self.colorBox.setToolTip(QCoreApplication.translate("mainWindow", u"

Disable conversion to grayscale.

", None)) #endif // QT_CONFIG(tooltip) diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index 6a92f1a..3b084d5 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -22,7 +22,9 @@ from collections import Counter import os import pathlib import re +import shutil import sys +import xml.etree.ElementTree as ET from argparse import ArgumentParser from time import perf_counter, strftime, gmtime from copy import copy @@ -917,7 +919,7 @@ def getWorkFolder(afile, workdir=None): os.makedirs(fullPath) path = workdir sanitizePermissions(path) - if options.pdfextract: + if options.legacyextract: pdf = pdfjpgextract.PdfJpgExtract(afile, fullPath) njpg = pdf.extract() if njpg == 0: @@ -956,11 +958,61 @@ def getWorkFolder(afile, workdir=None): for file in os.listdir(os.path.join(fullPath, tdir[0])): move(os.path.join(fullPath, tdir[0], file), fullPath) os.rmdir(os.path.join(fullPath, tdir[0])) + + if options.legacyextract: + return workdir + + if afile.lower().endswith('.epub'): + container = ET.parse(os.path.join(path, 'META-INF', 'container.xml')) + opf_path = container.find(r'.//{*}rootfile').attrib['full-path'] + opf_path = os.path.join(path, opf_path) + opf = ET.parse(opf_path) + spine = [] + for spine_item in opf.findall(r'.//{*}itemref'): + spine.append(spine_item.attrib.get('idref')) + manifest_dict = {} + for manifest_item in opf.findall(".//*[@media-type='application/xhtml+xml']"): + manifest_dict[manifest_item.attrib.get('id')] = manifest_item.attrib.get('href') + ordered_image_paths = [] + for i, spine_item in enumerate(spine): + if spine_item not in manifest_dict: + continue + page_path = os.path.join(os.path.dirname(opf_path), manifest_dict[spine_item]) + page = ET.parse(page_path) + imgs = page.findall(r'.//{*}img') + page.findall(r'.//{*}image') + img_path = None + # TODO handle more than first image + for img in imgs: + for key in img.attrib: + if 'src' in key or 'href' in key: + img_path = img.attrib[key] + if img_path.startswith('..'): + img_path = os.path.join(os.path.dirname(opf_path), os.path.dirname(manifest_dict[spine_item]), img_path) + else: + img_path = os.path.join(os.path.dirname(opf_path), os.path.dirname(manifest_dict[spine_item]), img_path) + break + # TODO empty image + if img_path: + ordered_image_paths.append(img_path) + # fallback if naive spine extraction fails + if not ordered_image_paths: + return workdir + + if options.tempdir: + workdir2 = mkdtemp('', 'KCC-', os.path.dirname(afile)) + else: + workdir2 = mkdtemp('', 'KCC-') + for i, img_path in enumerate(ordered_image_paths): + _, ext = os.path.splitext(img_path) + fullpath2 = os.path.join(workdir2, 'OEBPS', 'Images') + os.makedirs(fullpath2, exist_ok=True) + shutil.copyfile(img_path, os.path.join(fullpath2, f"{i}{ext}")) + rmtree(workdir, True) + return workdir2 + return workdir - - except OSError as e: - rmtree(workdir, True) - raise UserWarning(e) + finally: + pass else: raise UserWarning("Failed to open source file/directory.") @@ -1406,8 +1458,8 @@ def makeParser(): processing_options.add_argument("-n", "--noprocessing", action="store_true", dest="noprocessing", default=False, help="Do not modify image and ignore any profile or processing option") - processing_options.add_argument("--pdfextract", action="store_true", dest="pdfextract", default=False, - help="Use the legacy PDF image extraction method from KCC 8 and earlier") + processing_options.add_argument("--legacyextract", action="store_true", dest="legacyextract", default=False, + help="Use the legacy PDF/EPUB image extraction method from older KCC versions") processing_options.add_argument("--pdfwidth", action="store_true", dest="pdfwidth", default=False, help="Render vector PDFs to device width instead of height.") processing_options.add_argument("--smartcovercrop", action="store_true", dest="smartcovercrop", default=False, From c385ef7ae073451e0c69c854d0c00c9aaa41baf8 Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Sun, 17 May 2026 09:12:44 -0700 Subject: [PATCH 18/19] epub input: extract biggest image per page (#1342) * extract biggest image on page * fix largest_size location --- kindlecomicconverter/comic2ebook.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index 3b084d5..64667fc 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -980,17 +980,24 @@ def getWorkFolder(afile, workdir=None): page_path = os.path.join(os.path.dirname(opf_path), manifest_dict[spine_item]) page = ET.parse(page_path) imgs = page.findall(r'.//{*}img') + page.findall(r'.//{*}image') + + largest_size = 0 img_path = None - # TODO handle more than first image for img in imgs: for key in img.attrib: if 'src' in key or 'href' in key: - img_path = img.attrib[key] - if img_path.startswith('..'): - img_path = os.path.join(os.path.dirname(opf_path), os.path.dirname(manifest_dict[spine_item]), img_path) + temp_img_path = img.attrib[key] + if temp_img_path.startswith('..'): + temp_img_path = os.path.join(os.path.dirname(opf_path), os.path.dirname(manifest_dict[spine_item]), temp_img_path) else: - img_path = os.path.join(os.path.dirname(opf_path), os.path.dirname(manifest_dict[spine_item]), img_path) - break + temp_img_path = os.path.join(os.path.dirname(opf_path), os.path.dirname(manifest_dict[spine_item]), temp_img_path) + try: + temp_size = os.path.getsize(temp_img_path) + if temp_size > largest_size: + largest_size = temp_size + img_path = temp_img_path + except OSError: + pass # TODO empty image if img_path: ordered_image_paths.append(img_path) From 7ceeb29fae9c99d1a09a0c627808a8541763af8e Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Sun, 17 May 2026 11:55:46 -0700 Subject: [PATCH 19/19] add 1 page landscape option (#1344) --- README.md | 1 + gui/KCC.ui | 12 +++++++++++- kindlecomicconverter/KCC_gui.py | 3 +++ kindlecomicconverter/KCC_ui.py | 11 ++++++++++- kindlecomicconverter/comic2ebook.py | 4 ++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a89344..6ff5197 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,7 @@ OUTPUT SETTINGS: -b BATCHSPLIT, --batchsplit BATCHSPLIT Split output into multiple files. 0: Don't split 1: Automatic mode 2: Consider every subdirectory as separate volume [Default=0] --spreadshift Shift first page to opposite side in landscape for two page spread alignment + --onepagelandscape Show a single centered page in landscape --norotate Do not rotate double page spreads in spread splitter option. --rotateright Rotate double page spreads in opposite direction. --rotatefirst Put rotated spread first in spread splitter option. diff --git a/gui/KCC.ui b/gui/KCC.ui index fffbe9b..17e749d 100644 --- a/gui/KCC.ui +++ b/gui/KCC.ui @@ -883,7 +883,7 @@ Ignored for Kindle EPUB/MOBI and all PDF. - + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Main Drive<br/></span>Use dedicated temporary directory on main OS drive.</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Source File Drive<br/></span>Create temporary file directory on source file drive.</p></body></html> @@ -893,6 +893,16 @@ Ignored for Kindle EPUB/MOBI and all PDF. + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - 2 page landscape<br/></span>2 viewports for left and right pages</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - 1 page landscape<br/></span>A single centered viewport for 1 page</p></body></html> + + + 1 Page Landscape + + + diff --git a/kindlecomicconverter/KCC_gui.py b/kindlecomicconverter/KCC_gui.py index 802b73d..dde7f0d 100644 --- a/kindlecomicconverter/KCC_gui.py +++ b/kindlecomicconverter/KCC_gui.py @@ -344,6 +344,8 @@ class WorkerThread(QThread): options.tempdir = True if GUI.spreadShiftBox.isChecked(): options.spreadshift = True + if GUI.onePageLandscapeBox.isChecked(): + options.onepagelandscape = True if GUI.fileFusionBox.isChecked(): options.filefusion = True else: @@ -1097,6 +1099,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow): 'deleteBox': GUI.deleteBox.checkState(), 'tempDirBox': GUI.tempDirBox.checkState(), 'spreadShiftBox': GUI.spreadShiftBox.checkState(), + 'onePageLandscapeBox': GUI.onePageLandscapeBox.checkState(), 'fileFusionBox': GUI.fileFusionBox.checkState(), 'defaultOutputFolderBox': GUI.defaultOutputFolderBox.checkState(), 'noRotateBox': GUI.noRotateBox.checkState(), diff --git a/kindlecomicconverter/KCC_ui.py b/kindlecomicconverter/KCC_ui.py index c762dab..525fdb2 100644 --- a/kindlecomicconverter/KCC_ui.py +++ b/kindlecomicconverter/KCC_ui.py @@ -453,7 +453,12 @@ class Ui_mainWindow(object): self.tempDirBox = QCheckBox(self.optionWidget) self.tempDirBox.setObjectName(u"tempDirBox") - self.gridLayout_2.addWidget(self.tempDirBox, 12, 1, 1, 1) + self.gridLayout_2.addWidget(self.tempDirBox, 12, 2, 1, 1) + + self.onePageLandscapeBox = QCheckBox(self.optionWidget) + self.onePageLandscapeBox.setObjectName(u"onePageLandscapeBox") + + self.gridLayout_2.addWidget(self.onePageLandscapeBox, 12, 1, 1, 1) self.gridLayout.addWidget(self.optionWidget, 5, 0, 1, 2) @@ -828,6 +833,10 @@ class Ui_mainWindow(object): self.tempDirBox.setToolTip(QCoreApplication.translate("mainWindow", u"

Unchecked - Main Drive
Use dedicated temporary directory on main OS drive.

Checked - Source File Drive
Create temporary file directory on source file drive.

", None)) #endif // QT_CONFIG(tooltip) self.tempDirBox.setText(QCoreApplication.translate("mainWindow", u"Temp Directory", None)) +#if QT_CONFIG(tooltip) + self.onePageLandscapeBox.setToolTip(QCoreApplication.translate("mainWindow", u"

Unchecked - 2 page landscape
2 viewports for left and right pages

Checked - 1 page landscape
A single centered viewport for 1 page

", None)) +#endif // QT_CONFIG(tooltip) + self.onePageLandscapeBox.setText(QCoreApplication.translate("mainWindow", u"1 Page Landscape", None)) #if QT_CONFIG(tooltip) self.convertButton.setToolTip(QCoreApplication.translate("mainWindow", u"

Shift+Click to select the output directory for this list.

", None)) #endif // QT_CONFIG(tooltip) diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index 64667fc..28744d0 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -469,6 +469,8 @@ def buildOPF(dstdir, title, filelist, originalpath, cover=None): pageside = "right" for entry, prop in zip(reflist, page_spread_property_list): + if options.onepagelandscape: + prop = 'center' f.write(f'\n') f.write("\n\n") @@ -1456,6 +1458,8 @@ def makeParser(): "2: Consider every subdirectory as separate volume [Default=0]") output_options.add_argument("--spreadshift", action="store_true", dest="spreadshift", default=False, help="Shift first page to opposite side in landscape for spread alignment") + output_options.add_argument("--onepagelandscape", action="store_true", dest="onepagelandscape", default=False, + help="Show a single centered page in landscape") output_options.add_argument("--norotate", action="store_true", dest="norotate", default=False, help="Do not rotate double page spreads in spread splitter option.") output_options.add_argument("--rotateright", action="store_true", dest="rotateright", default=False,