1
0
mirror of https://github.com/ciromattia/kcc synced 2025-12-12 17:26:23 +00:00

Experimental Windows 7 support (#1069)

* win7

* windows-2022

* downgrade

* bat

* lower requirements

* downgrade pyside6

* downgrade pyside6 more

* delete

* fix win7

* don't crash when settings load fails

* remove with_stem
This commit is contained in:
Alex Xu
2025-08-27 16:10:03 -07:00
committed by GitHub
parent 2f0c9ae95d
commit 4cecf6fc4d
7 changed files with 70 additions and 44 deletions

1
.gitignore vendored
View File

@@ -8,6 +8,7 @@ dist/
build/ build/
KindleComicConverter*.egg-info/ KindleComicConverter*.egg-info/
.idea/ .idea/
win7
/venv/ /venv/
/kindlegen* /kindlegen*
/kcc.bat /kcc.bat

View File

@@ -249,11 +249,19 @@ class WorkerThread(QThread):
options.gamma = float(GUI.gammaValue) options.gamma = float(GUI.gammaValue)
if GUI.autoLevelBox.isChecked(): if GUI.autoLevelBox.isChecked():
options.autolevel = True options.autolevel = True
options.cropping = GUI.croppingBox.checkState().value if GUI.croppingBox.isChecked():
if GUI.croppingBox.checkState() == Qt.CheckState.PartiallyChecked:
options.cropping = 1
else:
options.cropping = 2
if GUI.croppingBox.checkState() != Qt.CheckState.Unchecked: if GUI.croppingBox.checkState() != Qt.CheckState.Unchecked:
options.croppingp = float(GUI.croppingPowerValue) options.croppingp = float(GUI.croppingPowerValue)
options.preservemargin = GUI.preserveMarginBox.value() options.preservemargin = GUI.preserveMarginBox.value()
options.interpanelcrop = GUI.interPanelCropBox.checkState().value if GUI.interPanelCropBox.isChecked():
if GUI.interPanelCropBox.checkState() == Qt.CheckState.PartiallyChecked:
options.interpanelcrop = 1
else:
options.interpanelcrop = 2
if GUI.borderBox.checkState() == Qt.CheckState.PartiallyChecked: if GUI.borderBox.checkState() == Qt.CheckState.PartiallyChecked:
options.white_borders = True options.white_borders = True
elif GUI.borderBox.checkState() == Qt.CheckState.Checked: elif GUI.borderBox.checkState() == Qt.CheckState.Checked:
@@ -866,35 +874,35 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
self.settings.setValue('currentFormat', GUI.formatBox.currentIndex()) self.settings.setValue('currentFormat', GUI.formatBox.currentIndex())
self.settings.setValue('startNumber', self.startNumber + 1) self.settings.setValue('startNumber', self.startNumber + 1)
self.settings.setValue('windowSize', str(MW.size().width()) + 'x' + str(MW.size().height())) self.settings.setValue('windowSize', str(MW.size().width()) + 'x' + str(MW.size().height()))
self.settings.setValue('options', {'mangaBox': GUI.mangaBox.checkState().value, self.settings.setValue('options', {'mangaBox': GUI.mangaBox.checkState(),
'rotateBox': GUI.rotateBox.checkState().value, 'rotateBox': GUI.rotateBox.checkState(),
'qualityBox': GUI.qualityBox.checkState().value, 'qualityBox': GUI.qualityBox.checkState(),
'gammaBox': GUI.gammaBox.checkState().value, 'gammaBox': GUI.gammaBox.checkState(),
'autoLevelBox': GUI.autoLevelBox.checkState().value, 'autoLevelBox': GUI.autoLevelBox.checkState(),
'croppingBox': GUI.croppingBox.checkState().value, 'croppingBox': GUI.croppingBox.checkState(),
'croppingPowerSlider': float(self.croppingPowerValue) * 100, 'croppingPowerSlider': float(self.croppingPowerValue) * 100,
'preserveMarginBox': self.preserveMarginBox.value(), 'preserveMarginBox': self.preserveMarginBox.value(),
'interPanelCropBox': GUI.interPanelCropBox.checkState().value, 'interPanelCropBox': GUI.interPanelCropBox.checkState(),
'upscaleBox': GUI.upscaleBox.checkState().value, 'upscaleBox': GUI.upscaleBox.checkState(),
'borderBox': GUI.borderBox.checkState().value, 'borderBox': GUI.borderBox.checkState(),
'webtoonBox': GUI.webtoonBox.checkState().value, 'webtoonBox': GUI.webtoonBox.checkState(),
'outputSplit': GUI.outputSplit.checkState().value, 'outputSplit': GUI.outputSplit.checkState(),
'colorBox': GUI.colorBox.checkState().value, 'colorBox': GUI.colorBox.checkState(),
'eraseRainbowBox': GUI.eraseRainbowBox.checkState().value, 'eraseRainbowBox': GUI.eraseRainbowBox.checkState(),
'disableProcessingBox': GUI.disableProcessingBox.checkState().value, 'disableProcessingBox': GUI.disableProcessingBox.checkState(),
'metadataTitleBox': GUI.metadataTitleBox.checkState().value, 'metadataTitleBox': GUI.metadataTitleBox.checkState(),
'mozJpegBox': GUI.mozJpegBox.checkState().value, 'mozJpegBox': GUI.mozJpegBox.checkState(),
'widthBox': GUI.widthBox.value(), 'widthBox': GUI.widthBox.value(),
'heightBox': GUI.heightBox.value(), 'heightBox': GUI.heightBox.value(),
'deleteBox': GUI.deleteBox.checkState().value, 'deleteBox': GUI.deleteBox.checkState(),
'spreadShiftBox': GUI.spreadShiftBox.checkState().value, 'spreadShiftBox': GUI.spreadShiftBox.checkState(),
'fileFusionBox': GUI.fileFusionBox.checkState().value, 'fileFusionBox': GUI.fileFusionBox.checkState(),
'defaultOutputFolderBox': GUI.defaultOutputFolderBox.checkState().value, 'defaultOutputFolderBox': GUI.defaultOutputFolderBox.checkState(),
'noRotateBox': GUI.noRotateBox.checkState().value, 'noRotateBox': GUI.noRotateBox.checkState(),
'rotateFirstBox': GUI.rotateFirstBox.checkState().value, 'rotateFirstBox': GUI.rotateFirstBox.checkState(),
'maximizeStrips': GUI.maximizeStrips.checkState().value, 'maximizeStrips': GUI.maximizeStrips.checkState(),
'gammaSlider': float(self.gammaValue) * 100, 'gammaSlider': float(self.gammaValue) * 100,
'chunkSizeCheckBox': GUI.chunkSizeCheckBox.checkState().value, 'chunkSizeCheckBox': GUI.chunkSizeCheckBox.checkState(),
'chunkSizeBox': GUI.chunkSizeBox.value()}) 'chunkSizeBox': GUI.chunkSizeBox.value()})
self.settings.sync() self.settings.sync()
self.tray.hide() self.tray.hide()
@@ -969,7 +977,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
self.setupUi(MW) self.setupUi(MW)
self.editor = KCCGUI_MetaEditor() self.editor = KCCGUI_MetaEditor()
self.icons = Icons() self.icons = Icons()
self.settings = QSettings('ciromattia', 'kcc') self.settings = QSettings('ciromattia', 'kcc9')
self.settingsVersion = self.settings.value('settingsVersion', '', type=str) self.settingsVersion = self.settings.value('settingsVersion', '', type=str)
self.lastPath = self.settings.value('lastPath', '', type=str) self.lastPath = self.settings.value('lastPath', '', type=str)
self.defaultOutputFolder = str(self.settings.value('defaultOutputFolder', '', type=str)) self.defaultOutputFolder = str(self.settings.value('defaultOutputFolder', '', type=str))
@@ -979,7 +987,11 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
self.currentFormat = self.settings.value('currentFormat', 0, type=int) self.currentFormat = self.settings.value('currentFormat', 0, type=int)
self.startNumber = self.settings.value('startNumber', 0, type=int) self.startNumber = self.settings.value('startNumber', 0, type=int)
self.windowSize = self.settings.value('windowSize', '0x0', type=str) self.windowSize = self.settings.value('windowSize', '0x0', type=str)
self.options = self.settings.value('options', {'gammaSlider': 0, 'croppingBox': 2, 'croppingPowerSlider': 100}) default_options = {'gammaSlider': 0, 'croppingBox': 2, 'croppingPowerSlider': 100}
try:
self.options = self.settings.value('options', default_options)
except Exception:
self.options = default_options
self.worker = WorkerThread() self.worker = WorkerThread()
self.versionCheck = VersionThread() self.versionCheck = VersionThread()
self.progress = ProgressThread() self.progress = ProgressThread()

View File

@@ -528,6 +528,7 @@ def buildEPUB(path, chapternames, tomenumber, ischunked, cover: image.Cover, len
f.close() f.close()
build_html_start = perf_counter() build_html_start = perf_counter()
cover.save_to_epub(os.path.join(path, 'OEBPS', 'Images', 'cover.jpg'), tomenumber, len_tomes) cover.save_to_epub(os.path.join(path, 'OEBPS', 'Images', 'cover.jpg'), tomenumber, len_tomes)
dot_clean(path)
options.covers.append((cover, options.uuid)) options.covers.append((cover, options.uuid))
for dirpath, dirnames, filenames in os.walk(os.path.join(path, 'OEBPS', 'Images')): for dirpath, dirnames, filenames in os.walk(os.path.join(path, 'OEBPS', 'Images')):
chapter = False chapter = False

View File

@@ -495,9 +495,6 @@ class Cover:
stroke_width=25 stroke_width=25
) )
copy.save(target, "JPEG", optimize=1, quality=85) copy.save(target, "JPEG", optimize=1, quality=85)
dot_cover = Path(target).with_stem('._' + Path(target).stem)
if os.path.exists(dot_cover):
os.remove(dot_cover)
except IOError: except IOError:
raise RuntimeError('Failed to save cover.') raise RuntimeError('Failed to save cover.')

View File

@@ -98,10 +98,10 @@ def dependencyCheck(level):
if level > 2: if level > 2:
try: try:
from PySide6.QtCore import qVersion as qtVersion from PySide6.QtCore import qVersion as qtVersion
if Version('6.5.1') > Version(qtVersion()): if Version('6.0.0') > Version(qtVersion()):
missing.append('PySide 6.5.1+') missing.append('PySide 6.0.0')
except ImportError: except ImportError:
missing.append('PySide 6.5.1+') missing.append('PySide 6.0.0+')
try: try:
import raven import raven
except ImportError: except ImportError:
@@ -124,16 +124,16 @@ def dependencyCheck(level):
missing.append('python-slugify 1.2.1+') missing.append('python-slugify 1.2.1+')
try: try:
from PIL import __version__ as pillowVersion from PIL import __version__ as pillowVersion
if Version('11.3.0') > Version(pillowVersion): if Version('8.3.0') > Version(pillowVersion):
missing.append('Pillow 11.3.0+') missing.append('Pillow 8.3.0+')
except ImportError: except ImportError:
missing.append('Pillow 11.3.0+') missing.append('Pillow 8.3.0+')
try: try:
from pymupdf import __version__ as pymupdfVersion from pymupdf import __version__ as pymupdfVersion
if Version('1.26.1') > Version(pymupdfVersion): if Version('1.16.1') > Version(pymupdfVersion):
missing.append('PyMuPDF 1.26.1+') missing.append('PyMuPDF 1.16.1+')
except ImportError: except ImportError:
missing.append('PyMuPDF 1.26.1+') missing.append('PyMuPDF 1.16.1+')
if len(missing) > 0: if len(missing) > 0:
print('ERROR: ' + ', '.join(missing) + ' is not installed!') print('ERROR: ' + ', '.join(missing) + ' is not installed!')
sys.exit(1) sys.exit(1)

12
requirements-win7.txt Normal file
View File

@@ -0,0 +1,12 @@
PySide6==6.1.3
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
distro>=1.8.0
numpy==1.23.0
PyMuPDF>=1.16

View File

@@ -45,7 +45,10 @@ class BuildBinaryCommand(setuptools.Command):
os.system(f'appdmg kcc.json dist/kcc_macos_{platform.processor()}_{VERSION}.dmg') os.system(f'appdmg kcc.json dist/kcc_macos_{platform.processor()}_{VERSION}.dmg')
sys.exit(0) sys.exit(0)
elif sys.platform == 'win32': elif sys.platform == 'win32':
os.system('pyinstaller --hidden-import=_cffi_backend -y -F -i icons\\comic2ebook.ico -n KCC_' + VERSION + ' -w --noupx kcc.py') if os.getenv('WINDOWS_7'):
os.system('pyinstaller --hidden-import=_cffi_backend -y -F -i icons\\comic2ebook.ico -n kcc_win7_' + VERSION + ' -w --noupx kcc.py')
else:
os.system('pyinstaller --hidden-import=_cffi_backend -y -F -i icons\\comic2ebook.ico -n KCC_' + VERSION + ' -w --noupx kcc.py')
sys.exit(0) sys.exit(0)
elif sys.platform == 'linux': elif sys.platform == 'linux':
os.system( os.system(
@@ -78,8 +81,8 @@ setuptools.setup(
}, },
packages=['kindlecomicconverter'], packages=['kindlecomicconverter'],
install_requires=[ install_requires=[
'pyside6>=6.5.1', 'pyside6>=6.0.0',
'Pillow>=11.3.0', 'Pillow>=9.3.0',
'PyMuPDF>=1.18.0', 'PyMuPDF>=1.18.0',
'psutil>=5.9.5', 'psutil>=5.9.5',
'python-slugify>=1.2.1,<9.0.0', 'python-slugify>=1.2.1,<9.0.0',
@@ -89,7 +92,7 @@ setuptools.setup(
'natsort>=8.4.0', 'natsort>=8.4.0',
'distro', 'distro',
'numpy>=1.22.4', 'numpy>=1.22.4',
'PyMuPDF>=1.26.1', 'PyMuPDF>=1.16.1',
], ],
classifiers=[], classifiers=[],
zip_safe=False, zip_safe=False,