mirror of
https://github.com/ciromattia/kcc
synced 2026-07-01 10:35:29 +00:00
Moved conversion to separate thread. No more UI freezes.
This commit is contained in:
+119
-110
@@ -33,6 +33,120 @@ from subprocess import call, STDOUT, PIPE
|
|||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
|
class WorkerThread(QtCore.QThread):
|
||||||
|
def __init__(self, parent):
|
||||||
|
QtCore.QThread.__init__(self)
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
if self.parent.needClean:
|
||||||
|
self.parent.needClean = False
|
||||||
|
GUI.JobList.clear()
|
||||||
|
if GUI.JobList.count() == 0:
|
||||||
|
self.parent.addMessage('No files selected! Please choose files to convert.', self.parent.errorIcon)
|
||||||
|
self.parent.needClean = True
|
||||||
|
return
|
||||||
|
self.parent.modeConvert(False)
|
||||||
|
profile = ProfileData.ProfileLabels[str(GUI.DeviceBox.currentText())]
|
||||||
|
argv = ["--profile=" + profile]
|
||||||
|
currentJobs = []
|
||||||
|
global errors
|
||||||
|
if GUI.MangaBox.isChecked():
|
||||||
|
argv.append("--manga-style")
|
||||||
|
if GUI.RotateBox.isChecked():
|
||||||
|
argv.append("--rotate")
|
||||||
|
if not GUI.HQPVBox.isChecked():
|
||||||
|
argv.append("--nopanelviewhq")
|
||||||
|
if GUI.ProcessingBox.isChecked():
|
||||||
|
argv.append("--noprocessing")
|
||||||
|
if GUI.UpscaleBox.isChecked() and not GUI.StretchBox.isChecked():
|
||||||
|
argv.append("--upscale")
|
||||||
|
if GUI.NoRotateBox.isChecked():
|
||||||
|
argv.append("--nosplitrotate")
|
||||||
|
if GUI.BorderBox.isChecked():
|
||||||
|
argv.append("--blackborders")
|
||||||
|
if GUI.StretchBox.isChecked():
|
||||||
|
argv.append("--stretch")
|
||||||
|
if GUI.NoDitheringBox.isChecked():
|
||||||
|
argv.append("--nodithering")
|
||||||
|
if self.parent.GammaValue > 0.09:
|
||||||
|
argv.append("--gamma=" + self.parent.GammaValue)
|
||||||
|
if str(GUI.FormatBox.currentText()) == 'CBZ':
|
||||||
|
argv.append("--cbz-output")
|
||||||
|
if str(GUI.customWidth.text()) != '':
|
||||||
|
argv.append("--customwidth=" + str(GUI.customWidth.text()))
|
||||||
|
if str(GUI.customHeight.text()) != '':
|
||||||
|
argv.append("--customheight=" + str(GUI.customHeight.text()))
|
||||||
|
for i in range(GUI.JobList.count()):
|
||||||
|
currentJobs.append(str(GUI.JobList.item(i).text()))
|
||||||
|
GUI.JobList.clear()
|
||||||
|
for job in currentJobs:
|
||||||
|
errors = False
|
||||||
|
self.parent.addMessage('Source: ' + job, self.parent.infoIcon)
|
||||||
|
if str(GUI.FormatBox.currentText()) == 'CBZ':
|
||||||
|
self.parent.addMessage('Creating CBZ file...', self.parent.infoIcon)
|
||||||
|
else:
|
||||||
|
self.parent.addMessage('Creating EPUB file...', self.parent.infoIcon)
|
||||||
|
jobargv = list(argv)
|
||||||
|
jobargv.append(job)
|
||||||
|
try:
|
||||||
|
outputPath = comic2ebook.main(jobargv)
|
||||||
|
except Exception as err:
|
||||||
|
errors = True
|
||||||
|
type_, value_, traceback_ = sys.exc_info()
|
||||||
|
QtGui.QMessageBox.critical(MainWindow, 'KCC Error',
|
||||||
|
"Error on file %s:\n%s\nTraceback:\n%s"
|
||||||
|
% (jobargv[-1], str(err), traceback.format_tb(traceback_)),
|
||||||
|
QtGui.QMessageBox.Ok)
|
||||||
|
self.parent.addMessage('KCC failed to create EPUB!', self.parent.errorIcon)
|
||||||
|
continue
|
||||||
|
if not errors:
|
||||||
|
if str(GUI.FormatBox.currentText()) == 'CBZ':
|
||||||
|
self.parent.addMessage('Creating CBZ file... Done!', self.parent.infoIcon, True)
|
||||||
|
else:
|
||||||
|
self.parent.addMessage('Creating EPUB file... Done!', self.parent.infoIcon, True)
|
||||||
|
if str(GUI.FormatBox.currentText()) == 'MOBI':
|
||||||
|
if not os.path.getsize(outputPath) > 314572800:
|
||||||
|
self.parent.addMessage('Creating MOBI file...', self.parent.infoIcon)
|
||||||
|
retcode = call('kindlegen "' + outputPath + '"', stdout=PIPE, stderr=STDOUT, shell=True)
|
||||||
|
if retcode == 0:
|
||||||
|
self.parent.addMessage('Creating MOBI file... Done!', self.parent.infoIcon, True)
|
||||||
|
self.parent.addMessage('Removing SRCS header...', self.parent.infoIcon)
|
||||||
|
os.remove(outputPath)
|
||||||
|
mobiPath = outputPath.replace('.epub', '.mobi')
|
||||||
|
shutil.move(mobiPath, mobiPath + '_tostrip')
|
||||||
|
try:
|
||||||
|
kindlestrip.main((mobiPath + '_tostrip', mobiPath))
|
||||||
|
except Exception:
|
||||||
|
errors = True
|
||||||
|
continue
|
||||||
|
if not errors:
|
||||||
|
os.remove(mobiPath + '_tostrip')
|
||||||
|
self.parent.addMessage('Removing SRCS header... Done!', self.parent.infoIcon, True)
|
||||||
|
else:
|
||||||
|
shutil.move(mobiPath + '_tostrip', mobiPath)
|
||||||
|
self.parent.addMessage('KindleStrip failed to remove SRCS header!',
|
||||||
|
self.parent.warningIcon)
|
||||||
|
self.parent.addMessage('MOBI file will work correctly but it will be highly oversized.',
|
||||||
|
self.parent.warningIcon)
|
||||||
|
else:
|
||||||
|
os.remove(outputPath)
|
||||||
|
os.remove(outputPath.replace('.epub', '.mobi'))
|
||||||
|
self.parent.addMessage('KindleGen failed to create MOBI!', self.parent.errorIcon)
|
||||||
|
self.parent.addMessage('Try converting smaller batch.', self.parent.errorIcon)
|
||||||
|
else:
|
||||||
|
os.remove(outputPath)
|
||||||
|
self.parent.addMessage('Created EPUB file is too big for KindleGen!', self.parent.errorIcon)
|
||||||
|
self.parent.addMessage('Try converting smaller batch.', self.parent.errorIcon)
|
||||||
|
self.parent.needClean = True
|
||||||
|
self.parent.addMessage('All jobs completed.', self.parent.warningIcon)
|
||||||
|
self.parent.modeConvert(True)
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyBroadException
|
# noinspection PyBroadException
|
||||||
class Ui_KCC(object):
|
class Ui_KCC(object):
|
||||||
def selectDir(self):
|
def selectDir(self):
|
||||||
@@ -127,7 +241,6 @@ class Ui_KCC(object):
|
|||||||
GUI.AdvModeButton.setStyleSheet('font-weight:Normal;')
|
GUI.AdvModeButton.setStyleSheet('font-weight:Normal;')
|
||||||
GUI.ExpertModeButton.setStyleSheet('font-weight:Bold;')
|
GUI.ExpertModeButton.setStyleSheet('font-weight:Bold;')
|
||||||
GUI.OptionsExpert.setEnabled(True)
|
GUI.OptionsExpert.setEnabled(True)
|
||||||
self.addMessage('WARNING! Options in this mode are highly experimental!', self.warningIcon)
|
|
||||||
|
|
||||||
def modeConvert(self, enable):
|
def modeConvert(self, enable):
|
||||||
GUI.BasicModeButton.setEnabled(enable)
|
GUI.BasicModeButton.setEnabled(enable)
|
||||||
@@ -161,114 +274,9 @@ class Ui_KCC(object):
|
|||||||
if replace:
|
if replace:
|
||||||
GUI.JobList.takeItem(GUI.JobList.count()-1)
|
GUI.JobList.takeItem(GUI.JobList.count()-1)
|
||||||
GUI.JobList.addItem(item)
|
GUI.JobList.addItem(item)
|
||||||
MainWindow.repaint()
|
|
||||||
|
|
||||||
def convertStart(self):
|
def convertStart(self):
|
||||||
if self.needClean:
|
self.thread.start()
|
||||||
self.needClean = False
|
|
||||||
GUI.JobList.clear()
|
|
||||||
if GUI.JobList.count() == 0:
|
|
||||||
self.addMessage('No files selected! Please choose files to convert.', self.errorIcon)
|
|
||||||
self.needClean = True
|
|
||||||
return
|
|
||||||
self.modeConvert(False)
|
|
||||||
profile = ProfileData.ProfileLabels[str(GUI.DeviceBox.currentText())]
|
|
||||||
argv = ["--profile=" + profile]
|
|
||||||
currentJobs = []
|
|
||||||
global errors
|
|
||||||
if GUI.MangaBox.isChecked():
|
|
||||||
argv.append("--manga-style")
|
|
||||||
if GUI.RotateBox.isChecked():
|
|
||||||
argv.append("--rotate")
|
|
||||||
if not GUI.HQPVBox.isChecked():
|
|
||||||
argv.append("--nopanelviewhq")
|
|
||||||
if GUI.ProcessingBox.isChecked():
|
|
||||||
argv.append("--noprocessing")
|
|
||||||
if GUI.UpscaleBox.isChecked() and not GUI.StretchBox.isChecked():
|
|
||||||
argv.append("--upscale")
|
|
||||||
if GUI.NoRotateBox.isChecked():
|
|
||||||
argv.append("--nosplitrotate")
|
|
||||||
if GUI.BorderBox.isChecked():
|
|
||||||
argv.append("--blackborders")
|
|
||||||
if GUI.StretchBox.isChecked():
|
|
||||||
argv.append("--stretch")
|
|
||||||
if GUI.NoDitheringBox.isChecked():
|
|
||||||
argv.append("--nodithering")
|
|
||||||
if self.GammaValue > 0.09:
|
|
||||||
argv.append("--gamma=" + self.GammaValue)
|
|
||||||
if str(GUI.FormatBox.currentText()) == 'CBZ':
|
|
||||||
argv.append("--cbz-output")
|
|
||||||
if str(GUI.customWidth.text()) != '':
|
|
||||||
argv.append("--customwidth=" + str(GUI.customWidth.text()))
|
|
||||||
if str(GUI.customHeight.text()) != '':
|
|
||||||
argv.append("--customheight=" + str(GUI.customHeight.text()))
|
|
||||||
for i in range(GUI.JobList.count()):
|
|
||||||
currentJobs.append(str(GUI.JobList.item(i).text()))
|
|
||||||
GUI.JobList.clear()
|
|
||||||
for job in currentJobs:
|
|
||||||
errors = False
|
|
||||||
self.addMessage('Source: ' + job, self.infoIcon)
|
|
||||||
if str(GUI.FormatBox.currentText()) == 'CBZ':
|
|
||||||
self.addMessage('Creating CBZ file...', self.infoIcon)
|
|
||||||
else:
|
|
||||||
self.addMessage('Creating EPUB file...', self.infoIcon)
|
|
||||||
jobargv = list(argv)
|
|
||||||
jobargv.append(job)
|
|
||||||
MainWindow.repaint()
|
|
||||||
try:
|
|
||||||
outputPath = comic2ebook.main(jobargv)
|
|
||||||
except Exception as err:
|
|
||||||
errors = True
|
|
||||||
type_, value_, traceback_ = sys.exc_info()
|
|
||||||
QtGui.QMessageBox.critical(MainWindow, 'KCC Error',
|
|
||||||
"Error on file %s:\n%s\nTraceback:\n%s"
|
|
||||||
% (jobargv[-1], str(err), traceback.format_tb(traceback_)),
|
|
||||||
QtGui.QMessageBox.Ok)
|
|
||||||
self.addMessage('KCC failed to create EPUB!', self.errorIcon)
|
|
||||||
continue
|
|
||||||
MainWindow.repaint()
|
|
||||||
if not errors:
|
|
||||||
if str(GUI.FormatBox.currentText()) == 'CBZ':
|
|
||||||
self.addMessage('Creating CBZ file... Done!', self.infoIcon, True)
|
|
||||||
else:
|
|
||||||
self.addMessage('Creating EPUB file... Done!', self.infoIcon, True)
|
|
||||||
if str(GUI.FormatBox.currentText()) == 'MOBI':
|
|
||||||
if not os.path.getsize(outputPath) > 314572800:
|
|
||||||
self.addMessage('Creating MOBI file...', self.infoIcon)
|
|
||||||
MainWindow.repaint()
|
|
||||||
retcode = call('kindlegen "' + outputPath + '"', stdout=PIPE, stderr=STDOUT, shell=True)
|
|
||||||
MainWindow.repaint()
|
|
||||||
if retcode == 0:
|
|
||||||
self.addMessage('Creating MOBI file... Done!', self.infoIcon, True)
|
|
||||||
self.addMessage('Removing SRCS header...', self.infoIcon)
|
|
||||||
mobiPath = outputPath.replace('.epub', '.mobi')
|
|
||||||
shutil.move(mobiPath, mobiPath + '_tostrip')
|
|
||||||
MainWindow.repaint()
|
|
||||||
try:
|
|
||||||
kindlestrip.main((mobiPath + '_tostrip', mobiPath))
|
|
||||||
except Exception:
|
|
||||||
errors = True
|
|
||||||
continue
|
|
||||||
MainWindow.repaint()
|
|
||||||
if not errors:
|
|
||||||
os.remove(mobiPath + '_tostrip')
|
|
||||||
self.addMessage('Removing SRCS header... Done!', self.infoIcon, True)
|
|
||||||
else:
|
|
||||||
shutil.move(mobiPath + '_tostrip', mobiPath)
|
|
||||||
self.addMessage('KindleStrip failed to remove SRCS header!', self.warningIcon)
|
|
||||||
self.addMessage('MOBI file will work correctly but it will be highly oversized.',
|
|
||||||
self.warningIcon)
|
|
||||||
else:
|
|
||||||
os.remove(outputPath)
|
|
||||||
self.addMessage('KindleGen failed to create MOBI!', self.errorIcon)
|
|
||||||
self.addMessage('Try converting smaller batch.', self.errorIcon)
|
|
||||||
else:
|
|
||||||
os.remove(outputPath)
|
|
||||||
self.addMessage('Created EPUB file is too big for KindleGen!', self.errorIcon)
|
|
||||||
self.addMessage('Try converting smaller batch.', self.errorIcon)
|
|
||||||
self.needClean = True
|
|
||||||
self.addMessage('All jobs completed.', self.warningIcon)
|
|
||||||
self.modeConvert(True)
|
|
||||||
|
|
||||||
def __init__(self, ui, KCC):
|
def __init__(self, ui, KCC):
|
||||||
global GUI, MainWindow
|
global GUI, MainWindow
|
||||||
@@ -277,6 +285,7 @@ class Ui_KCC(object):
|
|||||||
profiles = sorted(ProfileData.ProfileLabels.iterkeys())
|
profiles = sorted(ProfileData.ProfileLabels.iterkeys())
|
||||||
kindleIcon = QtGui.QIcon()
|
kindleIcon = QtGui.QIcon()
|
||||||
kindleIcon.addPixmap(QtGui.QPixmap(":/Devices/icons/Kindle.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
kindleIcon.addPixmap(QtGui.QPixmap(":/Devices/icons/Kindle.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
|
self.thread = WorkerThread(self)
|
||||||
self.needClean = True
|
self.needClean = True
|
||||||
self.GammaValue = 0
|
self.GammaValue = 0
|
||||||
self.infoIcon = QtGui.QIcon()
|
self.infoIcon = QtGui.QIcon()
|
||||||
@@ -287,19 +296,19 @@ class Ui_KCC(object):
|
|||||||
self.errorIcon.addPixmap(QtGui.QPixmap(":/Status/icons/error.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
self.errorIcon.addPixmap(QtGui.QPixmap(":/Status/icons/error.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
|
|
||||||
self.addMessage('Welcome!', self.infoIcon)
|
self.addMessage('Welcome!', self.infoIcon)
|
||||||
self.addMessage('All of options have additional informations in their tooltips.', self.infoIcon)
|
self.addMessage('Remember: All options have additional informations in tooltips.', self.infoIcon)
|
||||||
if call('kindlegen', stdout=PIPE, stderr=STDOUT, shell=True) == 0:
|
if call('kindlegen', stdout=PIPE, stderr=STDOUT, shell=True) == 0:
|
||||||
self.KindleGen = True
|
self.KindleGen = True
|
||||||
formats = ['MOBI', 'EPUB', 'CBZ']
|
formats = ['MOBI', 'EPUB', 'CBZ']
|
||||||
else:
|
else:
|
||||||
self.KindleGen = False
|
self.KindleGen = False
|
||||||
formats = ['EPUB', 'CBZ']
|
formats = ['EPUB', 'CBZ']
|
||||||
self.addMessage('Failed to detect KindleGen! Creating MOBI files is disabled.', self.warningIcon)
|
self.addMessage('Not found KindleGen! Creating MOBI files is disabled.', self.warningIcon)
|
||||||
if call('unrar', stdout=PIPE, stderr=STDOUT, shell=True) == 0:
|
if call('unrar', stdout=PIPE, stderr=STDOUT, shell=True) == 0:
|
||||||
self.UnRAR = True
|
self.UnRAR = True
|
||||||
else:
|
else:
|
||||||
self.UnRAR = False
|
self.UnRAR = False
|
||||||
self.addMessage('Failed to detect UnRAR! Processing of CBR/RAR files is disabled.', self.warningIcon)
|
self.addMessage('Not found UnRAR! Processing of CBR/RAR files is disabled.', self.warningIcon)
|
||||||
|
|
||||||
GUI.BasicModeButton.clicked.connect(self.modeBasic)
|
GUI.BasicModeButton.clicked.connect(self.modeBasic)
|
||||||
GUI.AdvModeButton.clicked.connect(self.modeAdvanced)
|
GUI.AdvModeButton.clicked.connect(self.modeAdvanced)
|
||||||
|
|||||||
Reference in New Issue
Block a user