mirror of
https://github.com/ciromattia/kcc
synced 2026-05-14 19:41:48 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
401876da22 | ||
|
|
ffeaaeca19 | ||
|
|
b95bb12393 | ||
|
|
4a6e4622ed | ||
|
|
a491810810 | ||
|
|
75d0342fe1 | ||
|
|
60d41b25e4 | ||
|
|
0db788589d | ||
|
|
f42e6aea5c | ||
|
|
53ae057cbb | ||
|
|
d729839976 | ||
|
|
42a50ed670 | ||
|
|
e6ef7c1732 | ||
|
|
f2a806a42a | ||
|
|
8798d71bfa | ||
|
|
19ce14eeee | ||
|
|
5a1e2dafcb | ||
|
|
f149ae23f3 | ||
|
|
2878e5d41b | ||
|
|
bd691989a9 |
10
.github/workflows/docker-publish.yml
vendored
10
.github/workflows/docker-publish.yml
vendored
@@ -24,17 +24,17 @@ jobs:
|
|||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v4
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v4
|
||||||
|
|
||||||
- name: Set Release Date
|
- name: Set Release Date
|
||||||
id: release_date
|
id: release_date
|
||||||
@@ -43,7 +43,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Docker meta
|
- name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@v5
|
uses: docker/metadata-action@v6
|
||||||
with:
|
with:
|
||||||
images: ghcr.io/${{ github.repository_owner }}/kcc
|
images: ghcr.io/${{ github.repository_owner }}/kcc
|
||||||
# Always creates the "latest" tag
|
# Always creates the "latest" tag
|
||||||
@@ -54,7 +54,7 @@ jobs:
|
|||||||
type=raw,value=${{ steps.release_date.outputs.release_date }}
|
type=raw,value=${{ steps.release_date.outputs.release_date }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v7
|
||||||
with:
|
with:
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||||
context: .
|
context: .
|
||||||
|
|||||||
4
.github/workflows/package-linux.yml
vendored
4
.github/workflows/package-linux.yml
vendored
@@ -59,12 +59,12 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
UPDATE_INFO: gh-releases-zsync|ciromattia|kcc|latest|*x86_64.AppImage.zsync
|
UPDATE_INFO: gh-releases-zsync|ciromattia|kcc|latest|*x86_64.AppImage.zsync
|
||||||
- name: upload artifact
|
- name: upload artifact
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: AppImage
|
name: AppImage
|
||||||
path: './*.AppImage*'
|
path: './*.AppImage*'
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v3
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|||||||
4
.github/workflows/package-macos.yml
vendored
4
.github/workflows/package-macos.yml
vendored
@@ -80,12 +80,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python setup.py build_binary
|
python setup.py build_binary
|
||||||
- name: upload build
|
- name: upload build
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: mac-os-build-${{ runner.arch }}
|
name: mac-os-build-${{ runner.arch }}
|
||||||
path: dist/*.dmg
|
path: dist/*.dmg
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v3
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|||||||
4
.github/workflows/package-osx-legacy.yml
vendored
4
.github/workflows/package-osx-legacy.yml
vendored
@@ -51,12 +51,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python3 setup.py build_binary
|
python3 setup.py build_binary
|
||||||
- name: upload build
|
- name: upload build
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: osx-build-${{ runner.arch }}
|
name: osx-build-${{ runner.arch }}
|
||||||
path: dist/*.dmg
|
path: dist/*.dmg
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v3
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|||||||
6
.github/workflows/package-windows.yml
vendored
6
.github/workflows/package-windows.yml
vendored
@@ -53,12 +53,12 @@ jobs:
|
|||||||
python setup.py ${{ matrix.command }}
|
python setup.py ${{ matrix.command }}
|
||||||
- name: upload-unsigned-artifact
|
- name: upload-unsigned-artifact
|
||||||
id: upload-unsigned-artifact
|
id: upload-unsigned-artifact
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: windows-build-${{ matrix.entry }}
|
name: windows-build-${{ matrix.entry }}
|
||||||
path: dist/*.exe
|
path: dist/*.exe
|
||||||
- id: optional_step_id
|
- 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' }}
|
if: ${{ github.repository == 'ciromattia/kcc' }}
|
||||||
with:
|
with:
|
||||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||||
@@ -69,7 +69,7 @@ jobs:
|
|||||||
wait-for-completion: true
|
wait-for-completion: true
|
||||||
output-artifact-directory: 'dist/'
|
output-artifact-directory: 'dist/'
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v3
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|||||||
6
.github/workflows/package-windows7.yml
vendored
6
.github/workflows/package-windows7.yml
vendored
@@ -46,12 +46,12 @@ jobs:
|
|||||||
python setup.py build_binary
|
python setup.py build_binary
|
||||||
- name: upload-unsigned-artifact
|
- name: upload-unsigned-artifact
|
||||||
id: upload-unsigned-artifact
|
id: upload-unsigned-artifact
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: windows7-build
|
name: windows7-build
|
||||||
path: dist/*.exe
|
path: dist/*.exe
|
||||||
- id: optional_step_id
|
- 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' }}
|
if: ${{ github.repository == 'ciromattia/kcc' }}
|
||||||
with:
|
with:
|
||||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||||
@@ -62,7 +62,7 @@ jobs:
|
|||||||
wait-for-completion: true
|
wait-for-completion: true
|
||||||
output-artifact-directory: 'dist/'
|
output-artifact-directory: 'dist/'
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v3
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|||||||
@@ -199,6 +199,8 @@ sudo apt-get install python3 p7zip-full python3-pil python3-psutil python3-slugi
|
|||||||
'KCS': ("Kindle Colorsoft", (1272, 1696), Palette16, 1.0),
|
'KCS': ("Kindle Colorsoft", (1272, 1696), Palette16, 1.0),
|
||||||
'KS1860': ("Kindle 1860", (1860, 1920), Palette16, 1.0),
|
'KS1860': ("Kindle 1860", (1860, 1920), Palette16, 1.0),
|
||||||
'KS1920': ("Kindle 1920", (1920, 1920), Palette16, 1.0),
|
'KS1920': ("Kindle 1920", (1920, 1920), Palette16, 1.0),
|
||||||
|
'KS1240': ("Kindle 1240", (1240, 1860), Palette16, 1.0),
|
||||||
|
'KS1324': ("Kindle 1324", (1324, 1986), Palette16, 1.0),
|
||||||
'KS': ("Kindle Scribe 1/2", (1860, 2480), Palette16, 1.0),
|
'KS': ("Kindle Scribe 1/2", (1860, 2480), Palette16, 1.0),
|
||||||
'KS3': ("Kindle Scribe 3", (1986, 2648), Palette16, 1.0),
|
'KS3': ("Kindle Scribe 3", (1986, 2648), Palette16, 1.0),
|
||||||
'KSCS': ("Kindle Scribe Colorsoft", (1986, 2648), Palette16, 1.0),
|
'KSCS': ("Kindle Scribe Colorsoft", (1986, 2648), Palette16, 1.0),
|
||||||
@@ -267,7 +269,7 @@ PROCESSING:
|
|||||||
Crop empty sections. 0: Disabled 1: Horizontally 2: Both [Default=0]
|
Crop empty sections. 0: Disabled 1: Horizontally 2: Both [Default=0]
|
||||||
--blackborders Disable autodetection and force black borders
|
--blackborders Disable autodetection and force black borders
|
||||||
--whiteborders Disable autodetection and force white borders
|
--whiteborders Disable autodetection and force white borders
|
||||||
--nosmartcovercrop Disable attempt to crop main cover from wide image
|
--smartcovercrop Attempt to crop main cover from wide image
|
||||||
--coverfill Center-crop only the cover to fill target device screen
|
--coverfill Center-crop only the cover to fill target device screen
|
||||||
--forcecolor Don't convert images to grayscale
|
--forcecolor Don't convert images to grayscale
|
||||||
--forcepng Create PNG files instead JPEG for black and white images
|
--forcepng Create PNG files instead JPEG for black and white images
|
||||||
|
|||||||
@@ -655,12 +655,12 @@ Higher values are larger and higher quality, and may resolve blank page issues.<
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="11" column="1">
|
||||||
<widget class="QCheckBox" name="noSmartCoverCropBox">
|
<widget class="QCheckBox" name="smartCoverCropBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Disable attempt to crop main cover from wide image.</string>
|
<string><html><head/><body><p>Attempt to crop main cover from wide image.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>No Smart Cover Crop</string>
|
<string>Smart Cover Crop</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -331,8 +331,8 @@ class WorkerThread(QThread):
|
|||||||
options.pdfextract = True
|
options.pdfextract = True
|
||||||
if GUI.pdfWidthBox.isChecked():
|
if GUI.pdfWidthBox.isChecked():
|
||||||
options.pdfwidth = True
|
options.pdfwidth = True
|
||||||
if GUI.noSmartCoverCropBox.isChecked():
|
if GUI.smartCoverCropBox.isChecked():
|
||||||
options.nosmartcovercrop = True
|
options.smartcovercrop = True
|
||||||
if GUI.coverFillBox.isChecked():
|
if GUI.coverFillBox.isChecked():
|
||||||
options.coverfill = True
|
options.coverfill = True
|
||||||
if GUI.metadataTitleBox.checkState() == Qt.CheckState.PartiallyChecked:
|
if GUI.metadataTitleBox.checkState() == Qt.CheckState.PartiallyChecked:
|
||||||
@@ -564,6 +564,7 @@ class WorkerThread(QThread):
|
|||||||
os.remove(path)
|
os.remove(path)
|
||||||
elif os.path.isdir(path):
|
elif os.path.isdir(path):
|
||||||
rmtree(path, True)
|
rmtree(path, True)
|
||||||
|
comic2ebook.checkPre('LLL-')
|
||||||
GUI.progress.content = ''
|
GUI.progress.content = ''
|
||||||
GUI.progress.stop()
|
GUI.progress.stop()
|
||||||
MW.hideProgressBar.emit()
|
MW.hideProgressBar.emit()
|
||||||
@@ -948,6 +949,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
|||||||
GUI.chunkSizeCheckBox.setChecked(False)
|
GUI.chunkSizeCheckBox.setChecked(False)
|
||||||
elif GUI.formats[str(GUI.formatBox.currentText())]['format'] == 'KFX':
|
elif GUI.formats[str(GUI.formatBox.currentText())]['format'] == 'KFX':
|
||||||
GUI.mozJpegBox.setCheckState(Qt.CheckState.PartiallyChecked)
|
GUI.mozJpegBox.setCheckState(Qt.CheckState.PartiallyChecked)
|
||||||
|
GUI.upscaleBox.setChecked(True)
|
||||||
elif not GUI.webtoonBox.isChecked():
|
elif not GUI.webtoonBox.isChecked():
|
||||||
GUI.chunkSizeCheckBox.setEnabled(True)
|
GUI.chunkSizeCheckBox.setEnabled(True)
|
||||||
if GUI.formats[str(GUI.formatBox.currentText())]['format'] in ('CBZ', 'PDF') and not GUI.webtoonBox.isChecked():
|
if GUI.formats[str(GUI.formatBox.currentText())]['format'] in ('CBZ', 'PDF') and not GUI.webtoonBox.isChecked():
|
||||||
@@ -1084,7 +1086,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
|||||||
'disableProcessingBox': GUI.disableProcessingBox.checkState(),
|
'disableProcessingBox': GUI.disableProcessingBox.checkState(),
|
||||||
'pdfExtractBox': GUI.pdfExtractBox.checkState(),
|
'pdfExtractBox': GUI.pdfExtractBox.checkState(),
|
||||||
'pdfWidthBox': GUI.pdfWidthBox.checkState(),
|
'pdfWidthBox': GUI.pdfWidthBox.checkState(),
|
||||||
'noSmartCoverCropBox': GUI.noSmartCoverCropBox.checkState(),
|
'smartCoverCropBox': GUI.smartCoverCropBox.checkState(),
|
||||||
'coverFillBox': GUI.coverFillBox.checkState(),
|
'coverFillBox': GUI.coverFillBox.checkState(),
|
||||||
'metadataTitleBox': GUI.metadataTitleBox.checkState(),
|
'metadataTitleBox': GUI.metadataTitleBox.checkState(),
|
||||||
'mozJpegBox': GUI.mozJpegBox.checkState(),
|
'mozJpegBox': GUI.mozJpegBox.checkState(),
|
||||||
@@ -1261,6 +1263,9 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
|||||||
"Kindle 1240x1860": {
|
"Kindle 1240x1860": {
|
||||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS1240',
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS1240',
|
||||||
},
|
},
|
||||||
|
"Kindle 1324x1986": {
|
||||||
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS1324',
|
||||||
|
},
|
||||||
"Kindle Scribe 1/2": {
|
"Kindle Scribe 1/2": {
|
||||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS',
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS',
|
||||||
},
|
},
|
||||||
@@ -1368,6 +1373,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
|||||||
"Separator",
|
"Separator",
|
||||||
"Other",
|
"Other",
|
||||||
"Separator",
|
"Separator",
|
||||||
|
"Kindle 1324x1986",
|
||||||
"Kindle 1920x1920",
|
"Kindle 1920x1920",
|
||||||
"Kindle 1860x1920",
|
"Kindle 1860x1920",
|
||||||
"Kindle 1240x1860",
|
"Kindle 1240x1860",
|
||||||
|
|||||||
@@ -344,10 +344,10 @@ class Ui_mainWindow(object):
|
|||||||
|
|
||||||
self.gridLayout_2.addWidget(self.metadataTitleBox, 7, 0, 1, 1)
|
self.gridLayout_2.addWidget(self.metadataTitleBox, 7, 0, 1, 1)
|
||||||
|
|
||||||
self.noSmartCoverCropBox = QCheckBox(self.optionWidget)
|
self.smartCoverCropBox = QCheckBox(self.optionWidget)
|
||||||
self.noSmartCoverCropBox.setObjectName(u"noSmartCoverCropBox")
|
self.smartCoverCropBox.setObjectName(u"smartCoverCropBox")
|
||||||
|
|
||||||
self.gridLayout_2.addWidget(self.noSmartCoverCropBox, 11, 1, 1, 1)
|
self.gridLayout_2.addWidget(self.smartCoverCropBox, 11, 1, 1, 1)
|
||||||
|
|
||||||
self.rotateFirstBox = QCheckBox(self.optionWidget)
|
self.rotateFirstBox = QCheckBox(self.optionWidget)
|
||||||
self.rotateFirstBox.setObjectName(u"rotateFirstBox")
|
self.rotateFirstBox.setObjectName(u"rotateFirstBox")
|
||||||
@@ -753,9 +753,9 @@ class Ui_mainWindow(object):
|
|||||||
#endif // QT_CONFIG(tooltip)
|
#endif // QT_CONFIG(tooltip)
|
||||||
self.metadataTitleBox.setText(QCoreApplication.translate("mainWindow", u"Metadata Title", None))
|
self.metadataTitleBox.setText(QCoreApplication.translate("mainWindow", u"Metadata Title", None))
|
||||||
#if QT_CONFIG(tooltip)
|
#if QT_CONFIG(tooltip)
|
||||||
self.noSmartCoverCropBox.setToolTip(QCoreApplication.translate("mainWindow", u"Disable attempt to crop main cover from wide image.", None))
|
self.smartCoverCropBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Attempt to crop main cover from wide image.</p></body></html>", None))
|
||||||
#endif // QT_CONFIG(tooltip)
|
#endif // QT_CONFIG(tooltip)
|
||||||
self.noSmartCoverCropBox.setText(QCoreApplication.translate("mainWindow", u"No Smart Cover Crop", None))
|
self.smartCoverCropBox.setText(QCoreApplication.translate("mainWindow", u"Smart Cover Crop", None))
|
||||||
#if QT_CONFIG(tooltip)
|
#if QT_CONFIG(tooltip)
|
||||||
self.rotateFirstBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>When the spread splitter option is partially checked,</p><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Rotate Last<br/></span>Put the rotated 2 page spread after the split spreads.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Rotate First<br/></span>Put the rotated 2 page spread before the split spreads.</p></body></html>", None))
|
self.rotateFirstBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>When the spread splitter option is partially checked,</p><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Rotate Last<br/></span>Put the rotated 2 page spread after the split spreads.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Rotate First<br/></span>Put the rotated 2 page spread before the split spreads.</p></body></html>", None))
|
||||||
#endif // QT_CONFIG(tooltip)
|
#endif // QT_CONFIG(tooltip)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
__version__ = '10.1.1'
|
__version__ = '10.1.3'
|
||||||
__license__ = 'ISC'
|
__license__ = 'ISC'
|
||||||
__copyright__ = '2012-2022, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>, darodi'
|
__copyright__ = '2012-2022, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>, darodi'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ from glob import glob, escape
|
|||||||
from re import sub
|
from re import sub
|
||||||
from stat import S_IWRITE, S_IREAD, S_IEXEC
|
from stat import S_IWRITE, S_IREAD, S_IEXEC
|
||||||
from typing import List
|
from typing import List
|
||||||
from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED
|
from zipfile import ZipFile, ZIP_STORED
|
||||||
from tempfile import mkdtemp, gettempdir, TemporaryFile
|
from tempfile import mkdtemp, gettempdir
|
||||||
from shutil import move, copytree, rmtree, copyfile
|
from shutil import move, copytree, rmtree, copyfile
|
||||||
from multiprocessing import Pool, cpu_count
|
from multiprocessing import Pool, cpu_count
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
@@ -90,6 +90,7 @@ def main(argv=None):
|
|||||||
os.remove(path)
|
os.remove(path)
|
||||||
elif os.path.isdir(path):
|
elif os.path.isdir(path):
|
||||||
rmtree(path, True)
|
rmtree(path, True)
|
||||||
|
checkPre('LLL-')
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@@ -144,7 +145,7 @@ def buildHTML(path, imgfile, imgfilepath, imgfile2=None):
|
|||||||
f.write('<div style="display:none;">.</div>\n')
|
f.write('<div style="display:none;">.</div>\n')
|
||||||
f.write(f'<img width="{imgsize[0]}" height="{imgsize[1]}" src="{"../" * backref}Images/{postfix}{imgfile}"/>\n')
|
f.write(f'<img width="{imgsize[0]}" height="{imgsize[1]}" src="{"../" * backref}Images/{postfix}{imgfile}"/>\n')
|
||||||
if imgfile2:
|
if imgfile2:
|
||||||
f.write(f'<img style="bottom: 0" width="{imgsize2[0]}" height="{imgsize2[1]}" src="{"../" * backref}Images/{postfix}{imgfile2}"/>\n')
|
f.write(f'<img style="top: 1920px" width="{imgsize2[0]}" height="{imgsize2[1]}" src="{"../" * backref}Images/{postfix}{imgfile2}"/>\n')
|
||||||
f.write("</div>\n")
|
f.write("</div>\n")
|
||||||
if options.iskindle and options.panelview:
|
if options.iskindle and options.panelview:
|
||||||
if options.autoscale:
|
if options.autoscale:
|
||||||
@@ -892,9 +893,12 @@ def getWorkFolder(afile, workdir=None):
|
|||||||
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
|
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
|
||||||
else:
|
else:
|
||||||
fullPath = workdir
|
fullPath = workdir
|
||||||
check_path = gettempdir()
|
|
||||||
if options.tempdir:
|
if options.tempdir:
|
||||||
check_path = os.path.dirname(afile)
|
check_path = os.path.dirname(afile)
|
||||||
|
else:
|
||||||
|
check_path = gettempdir()
|
||||||
|
|
||||||
if os.path.isdir(afile):
|
if os.path.isdir(afile):
|
||||||
if disk_usage(check_path)[2] < getDirectorySize(afile) * 2.5:
|
if disk_usage(check_path)[2] < getDirectorySize(afile) * 2.5:
|
||||||
raise UserWarning("Not enough disk space to perform conversion.")
|
raise UserWarning("Not enough disk space to perform conversion.")
|
||||||
@@ -1406,8 +1410,8 @@ def makeParser():
|
|||||||
help="Use the legacy PDF image extraction method from KCC 8 and earlier")
|
help="Use the legacy PDF image extraction method from KCC 8 and earlier")
|
||||||
processing_options.add_argument("--pdfwidth", action="store_true", dest="pdfwidth", default=False,
|
processing_options.add_argument("--pdfwidth", action="store_true", dest="pdfwidth", default=False,
|
||||||
help="Render vector PDFs to device width instead of height.")
|
help="Render vector PDFs to device width instead of height.")
|
||||||
processing_options.add_argument("--nosmartcovercrop", action="store_true", dest="nosmartcovercrop", default=False,
|
processing_options.add_argument("--smartcovercrop", action="store_true", dest="smartcovercrop", default=False,
|
||||||
help="Disable attempt to crop main cover from wide image")
|
help="Attempt to crop main cover from wide image")
|
||||||
processing_options.add_argument("--coverfill", action="store_true", dest="coverfill", default=False,
|
processing_options.add_argument("--coverfill", action="store_true", dest="coverfill", default=False,
|
||||||
help="Crop cover to fill screen")
|
help="Crop cover to fill screen")
|
||||||
processing_options.add_argument("-u", "--upscale", action="store_true", dest="upscale", default=False,
|
processing_options.add_argument("-u", "--upscale", action="store_true", dest="upscale", default=False,
|
||||||
@@ -1609,33 +1613,30 @@ def checkTools(source):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def checkPre(source):
|
def checkPre(source='KCC-'):
|
||||||
# Make sure that all temporary files are gone
|
# Make sure that all temporary files are gone
|
||||||
for root, dirs, _ in walkLevel(gettempdir(), 0):
|
for root, dirs, _ in walkLevel(gettempdir(), 0):
|
||||||
for tempdir in dirs:
|
for tempdir in dirs:
|
||||||
if tempdir.startswith('KCC-'):
|
if tempdir.startswith(source):
|
||||||
rmtree(os.path.join(root, tempdir), True)
|
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]):
|
def makeFusion(sources: List[str]):
|
||||||
if len(sources) < 2:
|
if len(sources) < 2:
|
||||||
raise UserWarning('Fusion requires at least 2 sources. Did you forget to uncheck fusion?')
|
raise UserWarning('Fusion requires at least 2 sources. Did you forget to uncheck fusion?')
|
||||||
start = perf_counter()
|
start = perf_counter()
|
||||||
first_path = Path(sources[0])
|
first_path = Path(sources[0])
|
||||||
if first_path.is_file():
|
|
||||||
fusion_path = first_path.parent.joinpath(first_path.stem + ' [fused]')
|
if options.tempdir:
|
||||||
|
fusion_parent = first_path.parent
|
||||||
else:
|
else:
|
||||||
fusion_path = first_path.parent.joinpath(first_path.name + ' [fused]')
|
# 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]')
|
||||||
|
else:
|
||||||
|
fusion_path = fusion_parent.joinpath(first_path.name + ' [fused]')
|
||||||
print("Running Fusion")
|
print("Running Fusion")
|
||||||
|
|
||||||
# Check if prefix is needed when user-specified ordering differs from OS natural sorting
|
# Check if prefix is needed when user-specified ordering differs from OS natural sorting
|
||||||
@@ -1644,7 +1645,6 @@ def makeFusion(sources: List[str]):
|
|||||||
|
|
||||||
for index, source in enumerate(sources, start=1):
|
for index, source in enumerate(sources, start=1):
|
||||||
print(f"Processing {source}...")
|
print(f"Processing {source}...")
|
||||||
checkPre(source)
|
|
||||||
print("Checking images...")
|
print("Checking images...")
|
||||||
source_path = Path(source)
|
source_path = Path(source)
|
||||||
# Add the fusion_0001_ prefix to maintain user-specified order if needed
|
# Add the fusion_0001_ prefix to maintain user-specified order if needed
|
||||||
@@ -1676,7 +1676,9 @@ def makeBook(source, qtgui=None, job_progress=''):
|
|||||||
GUI.progressBarTick.emit('1')
|
GUI.progressBarTick.emit('1')
|
||||||
else:
|
else:
|
||||||
checkTools(source)
|
checkTools(source)
|
||||||
checkPre(source)
|
checkPre()
|
||||||
|
if not options.filefusion:
|
||||||
|
checkPre('LLL-')
|
||||||
print(f"{job_progress}Preparing source images...")
|
print(f"{job_progress}Preparing source images...")
|
||||||
path = getWorkFolder(source)
|
path = getWorkFolder(source)
|
||||||
print(f"{job_progress}Checking images...")
|
print(f"{job_progress}Checking images...")
|
||||||
@@ -1719,7 +1721,7 @@ def makeBook(source, qtgui=None, job_progress=''):
|
|||||||
|
|
||||||
most_common_res, most_common_count = counter.most_common(1)[0]
|
most_common_res, most_common_count = counter.most_common(1)[0]
|
||||||
options.kfx_resolution = most_common_res
|
options.kfx_resolution = most_common_res
|
||||||
if most_common_count / counter.total() > .6:
|
if most_common_count / sum(counter.values()) > .6:
|
||||||
pass
|
pass
|
||||||
#elif max(aspect_ratios) - min(aspect_ratios) < .2:
|
#elif max(aspect_ratios) - min(aspect_ratios) < .2:
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ class ProfileData:
|
|||||||
'KS1860': ("Kindle 1860", (1860, 1920), Palette16, 1.0),
|
'KS1860': ("Kindle 1860", (1860, 1920), Palette16, 1.0),
|
||||||
'KS1920': ("Kindle 1920", (1920, 1920), Palette16, 1.0),
|
'KS1920': ("Kindle 1920", (1920, 1920), Palette16, 1.0),
|
||||||
'KS1240': ("Kindle 1240", (1240, 1860), Palette16, 1.0),
|
'KS1240': ("Kindle 1240", (1240, 1860), Palette16, 1.0),
|
||||||
|
'KS1324': ("Kindle 1324", (1324, 1986), Palette16, 1.0),
|
||||||
'KS': ("Kindle Scribe 1/2", (1860, 2480), Palette16, 1.0),
|
'KS': ("Kindle Scribe 1/2", (1860, 2480), Palette16, 1.0),
|
||||||
'KCS': ("Kindle Colorsoft", (1272, 1696), Palette16, 1.0),
|
'KCS': ("Kindle Colorsoft", (1272, 1696), Palette16, 1.0),
|
||||||
'KS3': ("Kindle Scribe 3", (1986, 2648), Palette16, 1.0),
|
'KS3': ("Kindle Scribe 3", (1986, 2648), Palette16, 1.0),
|
||||||
@@ -598,7 +599,7 @@ class Cover:
|
|||||||
self.image = ImageOps.autocontrast(self.image, preserve_tone=True)
|
self.image = ImageOps.autocontrast(self.image, preserve_tone=True)
|
||||||
if not self.options.forcecolor:
|
if not self.options.forcecolor:
|
||||||
self.image = self.image.convert('L')
|
self.image = self.image.convert('L')
|
||||||
if not self.options.nosmartcovercrop:
|
if self.options.smartcovercrop:
|
||||||
self.crop_main_cover()
|
self.crop_main_cover()
|
||||||
|
|
||||||
size = list(self.options.profileData[1])
|
size = list(self.options.profileData[1])
|
||||||
|
|||||||
Reference in New Issue
Block a user