Merge branch 'master' of github.com:ciromattia/kcc

This commit is contained in:
Ciro Mattia Gonano
2013-11-08 17:21:42 +01:00
3 changed files with 120 additions and 38 deletions
+50 -8
View File
@@ -205,6 +205,30 @@ class VersionThread(QtCore.QThread):
'Changelog</a>)', 'warning') 'Changelog</a>)', 'warning')
class ProgressThread(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
self.running = False
self.content = None
self.progress = 0
def __del__(self):
self.wait()
def run(self):
self.running = True
while self.running:
sleep(1)
if self.content:
self.emit(QtCore.SIGNAL("addMessage"), self.content + self.progress * '.', 'info', True)
self.progress += 1
if self.progress == 4:
self.progress = 0
def stop(self):
self.running = False
class WorkerSignals(QtCore.QObject): class WorkerSignals(QtCore.QObject):
result = QtCore.pyqtSignal(list) result = QtCore.pyqtSignal(list)
@@ -296,6 +320,8 @@ class WorkerThread(QtCore.QThread):
self.conversionAlive = GUIMain.conversionAlive self.conversionAlive = GUIMain.conversionAlive
def clean(self): def clean(self):
GUIMain.progress.content = ''
GUIMain.progress.stop()
GUIMain.needClean = True GUIMain.needClean = True
self.emit(QtCore.SIGNAL("hideProgressBar")) self.emit(QtCore.SIGNAL("hideProgressBar"))
self.emit(QtCore.SIGNAL("addMessage"), '<b>Conversion interrupted.</b>', 'error') self.emit(QtCore.SIGNAL("addMessage"), '<b>Conversion interrupted.</b>', 'error')
@@ -359,9 +385,11 @@ class WorkerThread(QtCore.QThread):
self.errors = False self.errors = False
self.emit(QtCore.SIGNAL("addMessage"), '<b>Source:</b> ' + job, 'info') self.emit(QtCore.SIGNAL("addMessage"), '<b>Source:</b> ' + job, 'info')
if str(GUI.FormatBox.currentText()) == 'CBZ': if str(GUI.FormatBox.currentText()) == 'CBZ':
self.emit(QtCore.SIGNAL("addMessage"), 'Creating CBZ file...', 'info') self.emit(QtCore.SIGNAL("addMessage"), 'Creating CBZ files', 'info')
GUIMain.progress.content = 'Creating CBZ files'
else: else:
self.emit(QtCore.SIGNAL("addMessage"), 'Creating EPUB file...', 'info') self.emit(QtCore.SIGNAL("addMessage"), 'Creating EPUB files', 'info')
GUIMain.progress.content = 'Creating EPUB files'
jobargv = list(argv) jobargv = list(argv)
jobargv.append(job) jobargv.append(job)
try: try:
@@ -372,10 +400,12 @@ class WorkerThread(QtCore.QThread):
self.clean() self.clean()
return return
else: else:
GUIMain.progress.content = ''
self.errors = True self.errors = True
self.emit(QtCore.SIGNAL("addMessage"), str(warn), 'warning') self.emit(QtCore.SIGNAL("addMessage"), str(warn), 'warning')
self.emit(QtCore.SIGNAL("addMessage"), 'Failed to create output file!', 'warning') self.emit(QtCore.SIGNAL("addMessage"), 'Failed to create output file!', 'warning')
except Exception as err: except Exception as err:
GUIMain.progress.content = ''
self.errors = True self.errors = True
type_, value_, traceback_ = sys.exc_info() type_, value_, traceback_ = sys.exc_info()
self.emit(QtCore.SIGNAL("showDialog"), "Error during conversion %s:\n\n%s\n\nTraceback:\n%s" self.emit(QtCore.SIGNAL("showDialog"), "Error during conversion %s:\n\n%s\n\nTraceback:\n%s"
@@ -388,15 +418,17 @@ class WorkerThread(QtCore.QThread):
self.clean() self.clean()
return return
if not self.errors: if not self.errors:
GUIMain.progress.content = ''
if str(GUI.FormatBox.currentText()) == 'CBZ': if str(GUI.FormatBox.currentText()) == 'CBZ':
self.emit(QtCore.SIGNAL("addMessage"), 'Creating CBZ file... <b>Done!</b>', 'info', True) self.emit(QtCore.SIGNAL("addMessage"), 'Creating CBZ files... <b>Done!</b>', 'info', True)
else: else:
self.emit(QtCore.SIGNAL("addMessage"), 'Creating EPUB file... <b>Done!</b>', 'info', True) self.emit(QtCore.SIGNAL("addMessage"), 'Creating EPUB files... <b>Done!</b>', 'info', True)
if str(GUI.FormatBox.currentText()) == 'MOBI': if str(GUI.FormatBox.currentText()) == 'MOBI':
self.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Creating MOBI files') self.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Creating MOBI files')
self.emit(QtCore.SIGNAL("progressBarTick"), len(outputPath)*2+1) self.emit(QtCore.SIGNAL("progressBarTick"), len(outputPath)*2+1)
self.emit(QtCore.SIGNAL("progressBarTick")) self.emit(QtCore.SIGNAL("progressBarTick"))
self.emit(QtCore.SIGNAL("addMessage"), 'Creating MOBI file...', 'info') self.emit(QtCore.SIGNAL("addMessage"), 'Creating MOBI files', 'info')
GUIMain.progress.content = 'Creating MOBI files'
self.workerOutput = [] self.workerOutput = []
# Number of KindleGen threads depends on the size of RAM # Number of KindleGen threads depends on the size of RAM
self.pool.setMaxThreadCount(self.threadNumber) self.pool.setMaxThreadCount(self.threadNumber)
@@ -420,8 +452,10 @@ class WorkerThread(QtCore.QThread):
self.clean() self.clean()
return return
if self.kindlegenErrorCode[0] == 0: if self.kindlegenErrorCode[0] == 0:
self.emit(QtCore.SIGNAL("addMessage"), 'Creating MOBI file... <b>Done!</b>', 'info', True) GUIMain.progress.content = ''
self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI file...', 'info') self.emit(QtCore.SIGNAL("addMessage"), 'Creating MOBI files... <b>Done!</b>', 'info', True)
self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI files', 'info')
GUIMain.progress.content = 'Cleaning MOBI files'
self.workerOutput = [] self.workerOutput = []
# Multithreading KindleUnpack in current form is a waste of resources. # Multithreading KindleUnpack in current form is a waste of resources.
# Unless we higly optimise KindleUnpack or drop 32bit support this will not change. # Unless we higly optimise KindleUnpack or drop 32bit support this will not change.
@@ -438,13 +472,15 @@ class WorkerThread(QtCore.QThread):
break break
if not self.errors: if not self.errors:
for item in outputPath: for item in outputPath:
GUIMain.progress.content = ''
mobiPath = item.replace('.epub', '.mobi') mobiPath = item.replace('.epub', '.mobi')
os.remove(mobiPath + '_toclean') os.remove(mobiPath + '_toclean')
GUIMain.completedWork[os.path.basename(mobiPath).encode('utf-8')] = \ GUIMain.completedWork[os.path.basename(mobiPath).encode('utf-8')] = \
mobiPath.encode('utf-8') mobiPath.encode('utf-8')
self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI file... <b>Done!</b>', 'info', self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI files... <b>Done!</b>', 'info',
True) True)
else: else:
GUIMain.progress.content = ''
for item in outputPath: for item in outputPath:
mobiPath = item.replace('.epub', '.mobi') mobiPath = item.replace('.epub', '.mobi')
if os.path.exists(mobiPath): if os.path.exists(mobiPath):
@@ -453,6 +489,7 @@ class WorkerThread(QtCore.QThread):
os.remove(mobiPath + '_toclean') os.remove(mobiPath + '_toclean')
self.emit(QtCore.SIGNAL("addMessage"), 'KindleUnpack failed to clean MOBI file!', 'error') self.emit(QtCore.SIGNAL("addMessage"), 'KindleUnpack failed to clean MOBI file!', 'error')
else: else:
GUIMain.progress.content = ''
epubSize = (os.path.getsize(self.kindlegenErrorCode[2]))/1024/1024 epubSize = (os.path.getsize(self.kindlegenErrorCode[2]))/1024/1024
for item in outputPath: for item in outputPath:
if os.path.exists(item): if os.path.exists(item):
@@ -471,6 +508,8 @@ class WorkerThread(QtCore.QThread):
else: else:
for item in outputPath: for item in outputPath:
GUIMain.completedWork[os.path.basename(item).encode('utf-8')] = item.encode('utf-8') GUIMain.completedWork[os.path.basename(item).encode('utf-8')] = item.encode('utf-8')
GUIMain.progress.content = ''
GUIMain.progress.stop()
self.emit(QtCore.SIGNAL("hideProgressBar")) self.emit(QtCore.SIGNAL("hideProgressBar"))
GUIMain.needClean = True GUIMain.needClean = True
self.emit(QtCore.SIGNAL("addMessage"), '<b>All jobs completed.</b>', 'info') self.emit(QtCore.SIGNAL("addMessage"), '<b>All jobs completed.</b>', 'info')
@@ -769,6 +808,7 @@ class Ui_KCC(object):
self.conversionAlive = False self.conversionAlive = False
self.worker.sync() self.worker.sync()
else: else:
self.progress.start()
if self.needClean: if self.needClean:
self.needClean = False self.needClean = False
GUI.JobList.clear() GUI.JobList.clear()
@@ -868,6 +908,7 @@ class Ui_KCC(object):
self.worker = WorkerThread() self.worker = WorkerThread()
self.versionCheck = VersionThread() self.versionCheck = VersionThread()
self.contentServer = WebServerThread() self.contentServer = WebServerThread()
self.progress = ProgressThread()
self.conversionAlive = False self.conversionAlive = False
self.needClean = True self.needClean = True
self.QualityBoxDisabled = False self.QualityBoxDisabled = False
@@ -941,6 +982,7 @@ class Ui_KCC(object):
KCC.connect(self.worker, QtCore.SIGNAL("hideProgressBar"), self.hideProgressBar) KCC.connect(self.worker, QtCore.SIGNAL("hideProgressBar"), self.hideProgressBar)
KCC.connect(self.versionCheck, QtCore.SIGNAL("addMessage"), self.addMessage) KCC.connect(self.versionCheck, QtCore.SIGNAL("addMessage"), self.addMessage)
KCC.connect(self.contentServer, QtCore.SIGNAL("addMessage"), self.addMessage) KCC.connect(self.contentServer, QtCore.SIGNAL("addMessage"), self.addMessage)
KCC.connect(self.progress, QtCore.SIGNAL("addMessage"), self.addMessage)
KCC.closeEvent = self.saveSettings KCC.closeEvent = self.saveSettings
for f in formats: for f in formats:
+5 -4
View File
@@ -296,7 +296,8 @@ def getImageFileName(imgfile):
def applyImgOptimization(img, opt, overrideQuality=5): def applyImgOptimization(img, opt, overrideQuality=5):
img.getImageFill(opt.webtoon) if not img.fill:
img.getImageFill(opt.webtoon)
if not opt.webtoon: if not opt.webtoon:
img.cropWhiteSpace(10.0) img.cropWhiteSpace(10.0)
if opt.cutpagenumbers and not opt.webtoon: if opt.cutpagenumbers and not opt.webtoon:
@@ -377,17 +378,17 @@ def fileImgProcess(work):
applyImgOptimization(img1, opt) applyImgOptimization(img1, opt)
img1.saveToDir(dirpath, opt.forcepng, opt.forcecolor, wipe) img1.saveToDir(dirpath, opt.forcepng, opt.forcecolor, wipe)
if opt.quality == 2: if opt.quality == 2:
img3 = image.ComicPage(split[0], opt.profileData) img3 = image.ComicPage(split[0], opt.profileData, img0.fill)
applyImgOptimization(img3, opt, 0) applyImgOptimization(img3, opt, 0)
img3.saveToDir(dirpath, opt.forcepng, opt.forcecolor, True) img3.saveToDir(dirpath, opt.forcepng, opt.forcecolor, True)
img4 = image.ComicPage(split[1], opt.profileData) img4 = image.ComicPage(split[1], opt.profileData, img1.fill)
applyImgOptimization(img4, opt, 0) applyImgOptimization(img4, opt, 0)
img4.saveToDir(dirpath, opt.forcepng, opt.forcecolor, True) img4.saveToDir(dirpath, opt.forcepng, opt.forcecolor, True)
else: else:
applyImgOptimization(img, opt) applyImgOptimization(img, opt)
img.saveToDir(dirpath, opt.forcepng, opt.forcecolor, wipe) img.saveToDir(dirpath, opt.forcepng, opt.forcecolor, wipe)
if opt.quality == 2: if opt.quality == 2:
img2 = image.ComicPage(os.path.join(dirpath, afile), opt.profileData) img2 = image.ComicPage(os.path.join(dirpath, afile), opt.profileData, img.fill)
if img.rotated: if img.rotated:
img2.image = img2.image.rotate(90) img2.image = img2.image.rotate(90)
img2.rotated = True img2.rotated = True
+65 -26
View File
@@ -142,7 +142,7 @@ class ProfileData:
class ComicPage: class ComicPage:
def __init__(self, source, device): def __init__(self, source, device, fill=None):
try: try:
self.profile_label, self.size, self.palette, self.gamma, self.panelviewsize = device self.profile_label, self.size, self.palette, self.gamma, self.panelviewsize = device
except KeyError: except KeyError:
@@ -172,7 +172,10 @@ class ComicPage:
self.border = None self.border = None
self.noHPV = None self.noHPV = None
self.noVPV = None self.noVPV = None
self.fill = None if fill:
self.fill = fill
else:
self.fill = None
def saveToDir(self, targetdir, forcepng, color, wipe): def saveToDir(self, targetdir, forcepng, color, wipe):
try: try:
@@ -428,7 +431,7 @@ class ComicPage:
self.image = self.image.crop((0, 0, widthImg - diff, heightImg)) self.image = self.image.crop((0, 0, widthImg - diff, heightImg))
return self.image return self.image
def getImageHistogram(self, image): def getImageHistogram(self, image, new=True):
histogram = image.histogram() histogram = image.histogram()
RBGW = [] RBGW = []
pixelCount = 0 pixelCount = 0
@@ -437,37 +440,73 @@ class ComicPage:
RBGW.append(histogram[i] + histogram[256 + i] + histogram[512 + i]) RBGW.append(histogram[i] + histogram[256 + i] + histogram[512 + i])
white = 0 white = 0
black = 0 black = 0
for i in range(245, 256): for i in range(251, 256):
white += RBGW[i] white += RBGW[i]
for i in range(11): for i in range(5):
black += RBGW[i] black += RBGW[i]
if black > white and black > pixelCount*0.5: if new:
return True if black > 0 and white == 0:
return 1
elif white > 0 and black == 0:
return -1
else:
return False
else: else:
return False if black > white and black > pixelCount*0.5:
return True
else:
return False
def getImageFill(self, isWebToon): def getImageFill(self, isWebToon):
fill = 0 if isWebToon:
if isWebToon or self.rotated: fill = 0
fill += self.getImageHistogram(self.image.crop((0, 0, self.image.size[0], 5))) fill += self.getImageHistogram(self.image.crop((0, 0, self.image.size[0], 5)), False)
fill += self.getImageHistogram(self.image.crop((0, self.image.size[1]-5, self.image.size[0], fill += self.getImageHistogram(self.image.crop((0, self.image.size[1]-5, self.image.size[0],
self.image.size[1]))) self.image.size[1])), False)
else: if fill == 2:
fill += self.getImageHistogram(self.image.crop((0, 0, 5, self.image.size[1]))) self.fill = 'black'
fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, 0, self.image.size[0], elif fill == 0:
self.image.size[1]))) self.fill = 'white'
if fill == 2: else:
self.fill = 'black' fill = 0
elif fill == 0: fill += self.getImageHistogram(self.image.crop((0, 0, 5, 5)), False)
self.fill = 'white' fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, 0, self.image.size[0], 5)), False)
fill += self.getImageHistogram(self.image.crop((0, self.image.size[1]-5, 5, self.image.size[1])), False)
fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, self.image.size[1]-5,
self.image.size[0], self.image.size[1])), False)
if fill > 1:
self.fill = 'black'
else:
self.fill = 'white'
else: else:
fill = 0 fill = 0
fill += self.getImageHistogram(self.image.crop((0, 0, 5, 5))) # Search fom horizontal solid lines
fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, 0, self.image.size[0], 5))) startY = 0
fill += self.getImageHistogram(self.image.crop((0, self.image.size[1]-5, 5, self.image.size[1]))) stopY = 3
fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, self.image.size[1]-5, searching = True
self.image.size[0], self.image.size[1]))) while stopY <= self.image.size[1]:
if fill > 1: checkSolid = self.getImageHistogram(self.image.crop((0, startY, self.image.size[0], stopY)))
if checkSolid:
fill += checkSolid
startY = stopY + 1
stopY = startY + 3
if stopY > self.image.size[1] and searching:
stopY = self.image.size[1]
searching = False
# Search fom vertical solid lines
startX = 0
stopX = 3
searching = True
while stopX <= self.image.size[0]:
checkSolid = self.getImageHistogram(self.image.crop((startX, 0, stopX, self.image.size[1])))
if checkSolid:
fill += checkSolid
startX = stopX + 1
stopX = startX + 3
if stopX > self.image.size[0] and searching:
stopX = self.image.size[0]
searching = False
if fill > 0:
self.fill = 'black' self.fill = 'black'
else: else:
self.fill = 'white' self.fill = 'white'