From 36f8c82eaf2a539bb4571bf97309f9a30a4f0926 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Tue, 30 Dec 2014 11:00:21 +0100
Subject: [PATCH 01/12] Fixed OSX race condition
---
kcc.py | 42 +++++++++++++++++++++---------------------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/kcc.py b/kcc.py
index 296714a..0c963d3 100755
--- a/kcc.py
+++ b/kcc.py
@@ -24,10 +24,31 @@ __copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jas
__docformat__ = 'restructuredtext en'
import sys
+import os
if sys.version_info[0] != 3:
print('ERROR: This is Python 3 script!')
exit(1)
+# OS specific PATH variable workarounds
+if sys.platform.startswith('darwin') and 'RESOURCEPATH' not in os.environ:
+ os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/:' + os.environ['PATH']
+elif sys.platform.startswith('win'):
+ if getattr(sys, 'frozen', False):
+ os.chdir(os.path.dirname(os.path.abspath(sys.executable)))
+
+ # Implementing dummy stdout and stderr for frozen Windows release
+ class FakeSTD(object):
+ def write(self, string):
+ pass
+
+ def flush(self):
+ pass
+ sys.stdout = FakeSTD()
+ sys.stderr = FakeSTD()
+ else:
+ os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/;' + os.environ['PATH']
+ os.chdir(os.path.dirname(os.path.abspath(__file__)))
+
# Dependency check
missing = []
try:
@@ -69,30 +90,9 @@ if len(missing) > 0:
print('ERROR: ' + ', '.join(missing) + ' is not installed!')
exit(1)
-import os
from multiprocessing import freeze_support
from kcc import KCC_gui
-# OS specific PATH variable workarounds
-if sys.platform.startswith('darwin') and 'RESOURCEPATH' not in os.environ:
- os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/:' + os.environ['PATH']
-elif sys.platform.startswith('win'):
- if getattr(sys, 'frozen', False):
- os.chdir(os.path.dirname(os.path.abspath(sys.executable)))
-
- # Implementing dummy stdout and stderr for frozen Windows release
- class FakeSTD(object):
- def write(self, string):
- pass
-
- def flush(self):
- pass
- sys.stdout = FakeSTD()
- sys.stderr = FakeSTD()
- else:
- os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/;' + os.environ['PATH']
- os.chdir(os.path.dirname(os.path.abspath(__file__)))
-
# Implementing detection of already running KCC instance and forwarding argv to it
class QApplicationMessaging(QtWidgets.QApplication):
From 68b4b7114dea8dc668682f129f6be0ca0d982b97 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Tue, 30 Dec 2014 11:07:11 +0100
Subject: [PATCH 02/12] Added RAR5 support
---
kcc/rarfile.py | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/kcc/rarfile.py b/kcc/rarfile.py
index 6eefdb4..567f5ce 100644
--- a/kcc/rarfile.py
+++ b/kcc/rarfile.py
@@ -1,6 +1,6 @@
# rarfile.py
#
-# Copyright (c) 2005-2013 Marko Kreen
+# Copyright (c) 2005-2014 Marko Kreen
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -74,7 +74,7 @@ For more details, refer to source.
"""
-__version__ = '2.6'
+__version__ = '2.7-kcc'
# export only interesting items
__all__ = ['is_rarfile', 'RarInfo', 'RarFile', 'RarExtFile']
@@ -196,7 +196,7 @@ ALT_TEST_ARGS = ('-t', '-f')
ALT_CHECK_ARGS = ('--help',)
#: whether to speed up decompression by using tmp archive
-USE_EXTRACT_HACK = 1
+USE_EXTRACT_HACK = 0
#: limit the filesize for tmp archive usage
HACK_SIZE_LIMIT = 20*1024*1024
@@ -295,6 +295,7 @@ RAR_M5 = 0x35
##
RAR_ID = bytes("Rar!\x1a\x07\x00", 'ascii')
+RAR5_ID = bytes("Rar!\x1a\x07\x01", 'ascii')
ZERO = bytes("\0", 'ascii')
EMPTY = bytes("", 'ascii')
@@ -362,7 +363,10 @@ def is_rarfile(xfile):
fd = XFile(xfile)
buf = fd.read(len(RAR_ID))
fd.close()
- return buf == RAR_ID
+ if buf == RAR_ID or buf == RAR5_ID:
+ return True
+ else:
+ return False
class RarInfo(object):
@@ -785,7 +789,7 @@ class RarFile(object):
fd = XFile(self.rarfile)
self._fd = fd
id = fd.read(len(RAR_ID))
- if id != RAR_ID:
+ if id != RAR_ID and id != RAR5_ID:
raise NotRarFile("Not a Rar archive: "+self.rarfile)
volume = 0 # first vol (.rar) is 0
From f66c83425c0f1dfd870247f7ada5661427438055 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Thu, 1 Jan 2015 15:24:59 +0100
Subject: [PATCH 03/12] PyQT 5.4 update
---
KCC-Linux.ui | 6 ------
KCC-OSX.ui | 6 ------
KCC.ui | 6 ------
kcc/KCC_gui.py | 4 ++++
kcc/KCC_ui.py | 2 --
kcc/KCC_ui_linux.py | 2 --
kcc/KCC_ui_osx.py | 2 --
7 files changed, 4 insertions(+), 24 deletions(-)
diff --git a/KCC-Linux.ui b/KCC-Linux.ui
index 6c6c2f8..727d3e4 100644
--- a/KCC-Linux.ui
+++ b/KCC-Linux.ui
@@ -457,12 +457,6 @@
18
-
- QAbstractItemView::ScrollPerPixel
-
-
- QAbstractItemView::ScrollPerPixel
-
diff --git a/KCC-OSX.ui b/KCC-OSX.ui
index 28e1daa..da3690a 100644
--- a/KCC-OSX.ui
+++ b/KCC-OSX.ui
@@ -456,12 +456,6 @@
QAbstractItemView::NoSelection
-
- QAbstractItemView::ScrollPerPixel
-
-
- QAbstractItemView::ScrollPerPixel
-
diff --git a/KCC.ui b/KCC.ui
index 28b7cd9..15a9443 100644
--- a/KCC.ui
+++ b/KCC.ui
@@ -391,12 +391,6 @@
QAbstractItemView::NoSelection
-
- QAbstractItemView::ScrollPerPixel
-
-
- QAbstractItemView::ScrollPerPixel
-
diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py
index 1fd8a7f..9e18389 100644
--- a/kcc/KCC_gui.py
+++ b/kcc/KCC_gui.py
@@ -525,6 +525,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
dname = dname.replace('/', '\\')
self.lastPath = os.path.abspath(os.path.join(dname, os.pardir))
GUI.JobList.addItem(dname)
+ GUI.JobList.scrollToBottom()
def selectFile(self):
if self.needClean:
@@ -550,6 +551,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
fname = fname.replace('/', '\\')
self.lastPath = os.path.abspath(os.path.join(fname, os.pardir))
GUI.JobList.addItem(fname)
+ GUI.JobList.scrollToBottom()
def clearJobs(self):
GUI.JobList.clear()
@@ -954,10 +956,12 @@ class KCCGUI(KCC_ui.Ui_KCC):
formats = ['.cbz', '.zip', '.pdf']
if os.path.isdir(message):
GUI.JobList.addItem(message)
+ GUI.JobList.scrollToBottom()
elif os.path.isfile(message):
extension = os.path.splitext(message)
if extension[1].lower() in formats:
GUI.JobList.addItem(message)
+ GUI.JobList.scrollToBottom()
else:
self.addMessage('This file type is unsupported!', 'error')
diff --git a/kcc/KCC_ui.py b/kcc/KCC_ui.py
index 612009a..c8c6f47 100644
--- a/kcc/KCC_ui.py
+++ b/kcc/KCC_ui.py
@@ -141,8 +141,6 @@ class Ui_KCC(object):
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
self.JobList.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
- self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
- self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setObjectName("JobList")
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
diff --git a/kcc/KCC_ui_linux.py b/kcc/KCC_ui_linux.py
index cdc0661..009977c 100644
--- a/kcc/KCC_ui_linux.py
+++ b/kcc/KCC_ui_linux.py
@@ -182,8 +182,6 @@ class Ui_KCC(object):
self.JobList.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.JobList.setIconSize(QtCore.QSize(18, 18))
- self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
- self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setObjectName("JobList")
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
diff --git a/kcc/KCC_ui_osx.py b/kcc/KCC_ui_osx.py
index 4bc9848..09fed61 100644
--- a/kcc/KCC_ui_osx.py
+++ b/kcc/KCC_ui_osx.py
@@ -188,8 +188,6 @@ class Ui_KCC(object):
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
self.JobList.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
- self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
- self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setObjectName("JobList")
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
self.BasicModeButton.setGeometry(QtCore.QRect(5, 10, 210, 41))
From b629b45d461be473c3d1a38bd8e921ef493b80c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Fri, 2 Jan 2015 09:27:54 +0100
Subject: [PATCH 04/12] Pillow update
---
kcc-c2e.py | 6 +++---
kcc-c2p.py | 6 +++---
kcc.py | 6 +++---
kcc/comic2ebook.py | 2 +-
kcc/comic2panel.py | 6 +++---
kcc/image.py | 32 ++++++++++++++++----------------
kcc/shared.py | 14 ++++----------
7 files changed, 33 insertions(+), 39 deletions(-)
diff --git a/kcc-c2e.py b/kcc-c2e.py
index 01ab86e..bbc22b2 100755
--- a/kcc-c2e.py
+++ b/kcc-c2e.py
@@ -40,10 +40,10 @@ except ImportError:
try:
# noinspection PyUnresolvedReferences
import PIL
- if tuple(map(int, ('2.5.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
- missing.append('Pillow 2.5.0+')
+ if tuple(map(int, ('2.7.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
+ missing.append('Pillow 2.7.0+')
except ImportError:
- missing.append('Pillow 2.5.0+')
+ missing.append('Pillow 2.7.0+')
try:
# noinspection PyUnresolvedReferences
import slugify
diff --git a/kcc-c2p.py b/kcc-c2p.py
index 57acd33..7388f7f 100755
--- a/kcc-c2p.py
+++ b/kcc-c2p.py
@@ -33,10 +33,10 @@ missing = []
try:
# noinspection PyUnresolvedReferences
import PIL
- if tuple(map(int, ('2.5.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
- missing.append('Pillow 2.5.0+')
+ if tuple(map(int, ('2.7.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
+ missing.append('Pillow 2.7.0+')
except ImportError:
- missing.append('Pillow 2.5.0+')
+ missing.append('Pillow 2.7.0+')
if len(missing) > 0:
try:
# noinspection PyUnresolvedReferences
diff --git a/kcc.py b/kcc.py
index 0c963d3..f7fc51f 100755
--- a/kcc.py
+++ b/kcc.py
@@ -68,10 +68,10 @@ except ImportError:
try:
# noinspection PyUnresolvedReferences
import PIL
- if tuple(map(int, ('2.5.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
- missing.append('Pillow 2.5.0+')
+ if tuple(map(int, ('2.7.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
+ missing.append('Pillow 2.7.0+')
except ImportError:
- missing.append('Pillow 2.5.0+')
+ missing.append('Pillow 2.7.0+')
try:
# noinspection PyUnresolvedReferences
import slugify
diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py
index b658c2b..7401e45 100755
--- a/kcc/comic2ebook.py
+++ b/kcc/comic2ebook.py
@@ -552,7 +552,7 @@ def imgFileProcessing(work):
if opt.quality == 2:
img2 = image.ComicPage(os.path.join(dirpath, afile), opt.profileData, img.fill)
if img.rotated:
- img2.image = img2.image.rotate(90)
+ img2.image = img2.image.rotate(90, Image.BICUBIC, True)
img2.rotated = True
imgOptimization(img2, opt, img)
output.append(img2.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py
index fff58ec..3b42258 100644
--- a/kcc/comic2panel.py
+++ b/kcc/comic2panel.py
@@ -77,7 +77,7 @@ def mergeDirectory(work):
y += img.size[1]
os.remove(i)
savePath = os.path.split(imagesClear[0])
- result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG')
+ result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG', optimize=1)
except Exception:
return str(sys.exc_info()[1])
@@ -165,7 +165,7 @@ def splitImage(work):
panels.append(panel)
if opt.debug:
# noinspection PyUnboundLocalVariable
- debugImage.save(os.path.join(path, fileExpanded[0] + '-debug.png'), 'PNG')
+ debugImage.save(os.path.join(path, fileExpanded[0] + '-debug.png'), 'PNG', optimize=1)
# Create virtual pages
pages = []
@@ -200,7 +200,7 @@ def splitImage(work):
newPage.paste(panelImg, (0, targetHeight))
targetHeight += panels[panel][2]
newPage.save(os.path.join(path, fileExpanded[0] + '-' +
- str(pageNumber) + '.png'), 'PNG')
+ str(pageNumber) + '.png'), 'PNG', optimize=1)
pageNumber += 1
os.remove(filePath)
except Exception:
diff --git a/kcc/image.py b/kcc/image.py
index b32bb74..212feda 100755
--- a/kcc/image.py
+++ b/kcc/image.py
@@ -144,14 +144,14 @@ class ComicPage:
if self.noVPV:
flags.append('NoVerticalPanelView')
if self.border:
- flags.append("Margins-" + str(self.border[0]) + "-" + str(self.border[1]) + "-"
- + str(self.border[2]) + "-" + str(self.border[3]))
+ flags.append('Margins-' + str(self.border[0]) + '-' + str(self.border[1]) + '-'
+ + str(self.border[2]) + '-' + str(self.border[3]))
if forcepng:
- filename += ".png"
- self.image.save(filename, "PNG", optimize=1)
+ filename += '.png'
+ self.image.save(filename, 'PNG', optimize=1)
else:
- filename += ".jpg"
- self.image.save(filename, "JPEG", optimize=1)
+ filename += '.jpg'
+ self.image.save(filename, 'JPEG', optimize=1, quality=80)
return [md5Checksum(filename), flags]
else:
return None
@@ -243,7 +243,7 @@ class ComicPage:
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]:
method = Image.BICUBIC
else:
- method = Image.ANTIALIAS
+ method = Image.LANCZOS
self.image = self.image.resize(size, method)
return self.image
# If image is smaller than target resolution and upscale is off - Just expand it by adding margins
@@ -269,7 +269,7 @@ class ComicPage:
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]:
method = Image.BICUBIC
else:
- method = Image.ANTIALIAS
+ method = Image.LANCZOS
self.image = ImageOps.fit(self.image, size, method=method, centering=(0.5, 0.5))
return self.image
@@ -279,7 +279,7 @@ class ComicPage:
# Only split if origin is not oriented the same as target
if (width > height) != (dstwidth > dstheight):
if rotate:
- self.image = self.image.rotate(90)
+ self.image = self.image.rotate(90, Image.BICUBIC, True)
self.rotated = True
return None
else:
@@ -292,9 +292,9 @@ class ComicPage:
# Source is portrait and target is landscape, so split by the height
leftbox = (0, 0, width, int(height / 2))
rightbox = (0, int(height / 2), width, height)
- filename = os.path.splitext(self.filename)
- fileone = targetdir + '/' + filename[0] + '-A' + filename[1]
- filetwo = targetdir + '/' + filename[0] + '-B' + filename[1]
+ filename = os.path.splitext(self.filename)[0]
+ fileone = targetdir + '/' + filename + '-AAA.png'
+ filetwo = targetdir + '/' + filename + '-BBB.png'
try:
if righttoleft:
pageone = self.image.crop(rightbox)
@@ -302,8 +302,8 @@ class ComicPage:
else:
pageone = self.image.crop(leftbox)
pagetwo = self.image.crop(rightbox)
- pageone.save(fileone)
- pagetwo.save(filetwo)
+ pageone.save(fileone, 'PNG', optimize=1)
+ pagetwo.save(filetwo, 'PNG', optimize=1)
except IOError as e:
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
return fileone, filetwo
@@ -498,7 +498,7 @@ class Cover:
def processExternal(self):
self.image = self.image.convert('RGB')
- self.image.thumbnail(self.options.profileData[1], Image.ANTIALIAS)
+ self.image.thumbnail(self.options.profileData[1], Image.LANCZOS)
self.save(True)
def trim(self):
@@ -520,6 +520,6 @@ class Cover:
if os.path.splitext(source)[1].lower() == '.png':
self.image.save(self.target, "PNG", optimize=1)
else:
- self.image.save(self.target, "JPEG", optimize=1)
+ self.image.save(self.target, "JPEG", optimize=1, quality=80)
except IOError:
raise RuntimeError('Failed to save cover')
diff --git a/kcc/shared.py b/kcc/shared.py
index 7ac5163..418abf1 100644
--- a/kcc/shared.py
+++ b/kcc/shared.py
@@ -25,17 +25,11 @@ from hashlib import md5
def getImageFileName(imgfile):
- filename = os.path.splitext(imgfile)
- if filename[0].startswith('.') or\
- (filename[1].lower() != '.png' and
- filename[1].lower() != '.jpg' and
- filename[1].lower() != '.gif' and
- filename[1].lower() != '.tif' and
- filename[1].lower() != '.tiff' and
- filename[1].lower() != '.bmp' and
- filename[1].lower() != '.jpeg'):
+ name, ext = os.path.splitext(imgfile)
+ ext = ext.lower()
+ if name.startswith('.') or (ext != '.png' and ext != '.jpg' and ext != '.jpeg' and ext != '.gif'):
return None
- return filename
+ return [name, ext]
def walkLevel(some_dir, level=1):
From 2768e622f2d5253c570d86963b0d9538afdd9de1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Fri, 2 Jan 2015 11:51:14 +0100
Subject: [PATCH 05/12] PyQT 5.4 workarounds
---
KCC-Linux.ui | 9 +++++++++
KCC-OSX.ui | 9 +++++++++
KCC.ui | 9 +++++++++
kcc/KCC_ui.py | 3 +++
kcc/KCC_ui_linux.py | 3 +++
kcc/KCC_ui_osx.py | 3 +++
6 files changed, 36 insertions(+)
diff --git a/KCC-Linux.ui b/KCC-Linux.ui
index 727d3e4..7c41928 100644
--- a/KCC-Linux.ui
+++ b/KCC-Linux.ui
@@ -445,6 +445,9 @@
QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}
+
+ Qt::ScrollBarAlwaysOn
+
false
@@ -457,6 +460,12 @@
18
+
+ QAbstractItemView::ScrollPerPixel
+
+
+ QAbstractItemView::ScrollPerPixel
+
diff --git a/KCC-OSX.ui b/KCC-OSX.ui
index da3690a..e73c93d 100644
--- a/KCC-OSX.ui
+++ b/KCC-OSX.ui
@@ -450,12 +450,21 @@
QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}
+
+ Qt::ScrollBarAlwaysOn
+
false
QAbstractItemView::NoSelection
+
+ QAbstractItemView::ScrollPerPixel
+
+
+ QAbstractItemView::ScrollPerPixel
+
diff --git a/KCC.ui b/KCC.ui
index 15a9443..883a351 100644
--- a/KCC.ui
+++ b/KCC.ui
@@ -385,12 +385,21 @@
QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}
+
+ Qt::ScrollBarAlwaysOn
+
false
QAbstractItemView::NoSelection
+
+ QAbstractItemView::ScrollPerPixel
+
+
+ QAbstractItemView::ScrollPerPixel
+
diff --git a/kcc/KCC_ui.py b/kcc/KCC_ui.py
index c8c6f47..dd36744 100644
--- a/kcc/KCC_ui.py
+++ b/kcc/KCC_ui.py
@@ -138,6 +138,9 @@ class Ui_KCC(object):
self.JobList = QtWidgets.QListWidget(self.Form)
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
+ self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
+ self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
+ self.JobList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
self.JobList.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
diff --git a/kcc/KCC_ui_linux.py b/kcc/KCC_ui_linux.py
index 009977c..d077804 100644
--- a/kcc/KCC_ui_linux.py
+++ b/kcc/KCC_ui_linux.py
@@ -178,6 +178,9 @@ class Ui_KCC(object):
font.setItalic(False)
self.JobList.setFont(font)
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
+ self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
+ self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
+ self.JobList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
self.JobList.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
diff --git a/kcc/KCC_ui_osx.py b/kcc/KCC_ui_osx.py
index 09fed61..fb12b70 100644
--- a/kcc/KCC_ui_osx.py
+++ b/kcc/KCC_ui_osx.py
@@ -185,6 +185,9 @@ class Ui_KCC(object):
font.setPointSize(11)
self.JobList.setFont(font)
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
+ self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
+ self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
+ self.JobList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
self.JobList.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
From 180123fee2640fe9639249dd01f0f4decda6af73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Sat, 3 Jan 2015 09:17:00 +0100
Subject: [PATCH 06/12] Improved 7zip detection
---
kcc/cbxarchive.py | 3 ++-
kcc/shared.py | 6 ++++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/kcc/cbxarchive.py b/kcc/cbxarchive.py
index 216c1fa..6a7c598 100644
--- a/kcc/cbxarchive.py
+++ b/kcc/cbxarchive.py
@@ -27,6 +27,7 @@ from subprocess import STDOUT, PIPE
from psutil import Popen
from shutil import move, copy
from . import rarfile
+from .shared import check7ZFile as is_7zfile
class CBxArchive:
@@ -36,7 +37,7 @@ class CBxArchive:
self.compressor = 'zip'
elif rarfile.is_rarfile(origFileName):
self.compressor = 'rar'
- elif origFileName.endswith('.7z') or origFileName.endswith('.cb7'):
+ elif is_7zfile(origFileName):
self.compressor = '7z'
else:
self.compressor = None
diff --git a/kcc/shared.py b/kcc/shared.py
index 418abf1..dbbdd44 100644
--- a/kcc/shared.py
+++ b/kcc/shared.py
@@ -52,3 +52,9 @@ def md5Checksum(filePath):
break
m.update(data)
return m.hexdigest()
+
+
+def check7ZFile(filePath):
+ with open(filePath, 'rb') as fh:
+ header = fh.read(6)
+ return header == b"7z\xbc\xaf'\x1c"
\ No newline at end of file
From 147d815057a5d0dfbeab2de54e7f9730f72dce13 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Sat, 3 Jan 2015 09:41:07 +0100
Subject: [PATCH 07/12] Code cleanup
---
LICENSE.txt | 2 +-
kcc-c2e.py | 39 ++------------
kcc-c2p.py | 29 ++--------
kcc.iss | 2 +-
kcc.py | 124 +++++--------------------------------------
kcc/KCC_gui.py | 80 +++++++++++++++++++++-------
kcc/__init__.py | 2 +-
kcc/cbxarchive.py | 4 +-
kcc/comic2ebook.py | 4 +-
kcc/comic2panel.py | 4 +-
kcc/dualmetafix.py | 2 +-
kcc/image.py | 4 +-
kcc/pdfjpgextract.py | 4 +-
kcc/shared.py | 61 +++++++++++++++++++--
setup.py | 4 +-
15 files changed, 157 insertions(+), 208 deletions(-)
diff --git a/LICENSE.txt b/LICENSE.txt
index c32421a..b0eadda 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,7 +1,7 @@
ISC LICENSE
Copyright (c) 2012-2014 Ciro Mattia Gonano
-Copyright (c) 2013-2014 Paweł Jastrzębski
+Copyright (c) 2013-2015 Paweł Jastrzębski
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
diff --git a/kcc-c2e.py b/kcc-c2e.py
index bbc22b2..5bc3680 100755
--- a/kcc-c2e.py
+++ b/kcc-c2e.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -20,7 +20,7 @@
__version__ = '4.3.1'
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import sys
@@ -28,39 +28,8 @@ if sys.version_info[0] != 3:
print('ERROR: This is Python 3 script!')
exit(1)
-# Dependency check
-missing = []
-try:
- # noinspection PyUnresolvedReferences
- import psutil
- if tuple(map(int, ('2.0.0'.split(".")))) > tuple(map(int, psutil.version_info)):
- missing.append('psutil 2.0.0+')
-except ImportError:
- missing.append('psutil 2.0.0+')
-try:
- # noinspection PyUnresolvedReferences
- import PIL
- if tuple(map(int, ('2.7.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
- missing.append('Pillow 2.7.0+')
-except ImportError:
- missing.append('Pillow 2.7.0+')
-try:
- # noinspection PyUnresolvedReferences
- import slugify
-except ImportError:
- missing.append('python-slugify')
-if len(missing) > 0:
- try:
- # noinspection PyUnresolvedReferences
- import tkinter
- # noinspection PyUnresolvedReferences
- import tkinter.messagebox
- importRoot = tkinter.Tk()
- importRoot.withdraw()
- tkinter.messagebox.showerror('KCC - Error', 'ERROR: ' + ', '.join(missing) + ' is not installed!')
- except ImportError:
- print('ERROR: ' + ', '.join(missing) + ' is not installed!')
- exit(1)
+from kcc.shared import dependencyCheck
+dependencyCheck(2)
from multiprocessing import freeze_support
from kcc.comic2ebook import main
diff --git a/kcc-c2p.py b/kcc-c2p.py
index 7388f7f..53216a4 100755
--- a/kcc-c2p.py
+++ b/kcc-c2p.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -20,7 +20,7 @@
__version__ = '4.3.1'
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import sys
@@ -28,33 +28,14 @@ if sys.version_info[0] != 3:
print('ERROR: This is Python 3 script!')
exit(1)
-# Dependency check
-missing = []
-try:
- # noinspection PyUnresolvedReferences
- import PIL
- if tuple(map(int, ('2.7.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
- missing.append('Pillow 2.7.0+')
-except ImportError:
- missing.append('Pillow 2.7.0+')
-if len(missing) > 0:
- try:
- # noinspection PyUnresolvedReferences
- import tkinter
- # noinspection PyUnresolvedReferences
- import tkinter.messagebox
- importRoot = tkinter.Tk()
- importRoot.withdraw()
- tkinter.messagebox.showerror('KCC - Error', 'ERROR: ' + ', '.join(missing) + ' is not installed!')
- except ImportError:
- print('ERROR: ' + ', '.join(missing) + ' is not installed!')
- exit(1)
+from kcc.shared import dependencyCheck
+dependencyCheck(1)
from multiprocessing import freeze_support
from kcc.comic2panel import main
if __name__ == "__main__":
freeze_support()
- print(('comic2ebook v%(__version__)s. Written by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals()))
+ print(('comic2panel v%(__version__)s. Written by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals()))
main(sys.argv[1:])
sys.exit(0)
\ No newline at end of file
diff --git a/kcc.iss b/kcc.iss
index f40959d..f05ab56 100644
--- a/kcc.iss
+++ b/kcc.iss
@@ -12,7 +12,7 @@ AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
-AppCopyright=Copyright (C) 2012-2014 Ciro Mattia Gonano and Paweł Jastrzębski
+AppCopyright=Copyright (C) 2012-2015 Ciro Mattia Gonano and Paweł Jastrzębski
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
diff --git a/kcc.py b/kcc.py
index f7fc51f..119cd13 100755
--- a/kcc.py
+++ b/kcc.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -20,16 +20,16 @@
__version__ = '4.3.1'
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import sys
-import os
if sys.version_info[0] != 3:
print('ERROR: This is Python 3 script!')
exit(1)
# OS specific PATH variable workarounds
+import os
if sys.platform.startswith('darwin') and 'RESOURCEPATH' not in os.environ:
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/:' + os.environ['PATH']
elif sys.platform.startswith('win'):
@@ -49,123 +49,23 @@ elif sys.platform.startswith('win'):
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/;' + os.environ['PATH']
os.chdir(os.path.dirname(os.path.abspath(__file__)))
-# Dependency check
-missing = []
-try:
- # noinspection PyUnresolvedReferences
- from PyQt5 import QtCore, QtNetwork, QtWidgets
- if tuple(map(int, ('5.2.0'.split(".")))) > tuple(map(int, (QtCore.qVersion().split(".")))):
- missing.append('PyQt5 5.2.0+')
-except ImportError:
- missing.append('PyQt5 5.2.0+')
-try:
- # noinspection PyUnresolvedReferences
- import psutil
- if tuple(map(int, ('2.0.0'.split(".")))) > tuple(map(int, psutil.version_info)):
- missing.append('psutil 2.0.0+')
-except ImportError:
- missing.append('psutil 2.0.0+')
-try:
- # noinspection PyUnresolvedReferences
- import PIL
- if tuple(map(int, ('2.7.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
- missing.append('Pillow 2.7.0+')
-except ImportError:
- missing.append('Pillow 2.7.0+')
-try:
- # noinspection PyUnresolvedReferences
- import slugify
-except ImportError:
- missing.append('python-slugify')
-if len(missing) > 0:
- try:
- # noinspection PyUnresolvedReferences
- import tkinter
- # noinspection PyUnresolvedReferences
- import tkinter.messagebox
- importRoot = tkinter.Tk()
- importRoot.withdraw()
- tkinter.messagebox.showerror('KCC - Error', 'ERROR: ' + ', '.join(missing) + ' is not installed!')
- except ImportError:
- print('ERROR: ' + ', '.join(missing) + ' is not installed!')
- exit(1)
+from kcc.shared import dependencyCheck
+dependencyCheck(3)
from multiprocessing import freeze_support
from kcc import KCC_gui
-
-# Implementing detection of already running KCC instance and forwarding argv to it
-class QApplicationMessaging(QtWidgets.QApplication):
- messageFromOtherInstance = QtCore.pyqtSignal(bytes)
-
- def __init__(self, argv):
- QtWidgets.QApplication.__init__(self, argv)
- self._key = 'KCC'
- self._timeout = 1000
- self._locked = False
- socket = QtNetwork.QLocalSocket(self)
- socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly)
- if not socket.waitForConnected(self._timeout):
- self._server = QtNetwork.QLocalServer(self)
- # noinspection PyUnresolvedReferences
- self._server.newConnection.connect(self.handleMessage)
- self._server.listen(self._key)
- else:
- self._locked = True
- socket.disconnectFromServer()
-
- def __del__(self):
- if not self._locked:
- self._server.close()
-
- def event(self, e):
- if e.type() == QtCore.QEvent.FileOpen:
- self.messageFromOtherInstance.emit(bytes(e.file(), 'UTF-8'))
- return True
- else:
- return QtWidgets.QApplication.event(self, e)
-
- def isRunning(self):
- return self._locked
-
- def handleMessage(self):
- socket = self._server.nextPendingConnection()
- if socket.waitForReadyRead(self._timeout):
- self.messageFromOtherInstance.emit(socket.readAll().data())
-
- def sendMessage(self, message):
- socket = QtNetwork.QLocalSocket(self)
- socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly)
- socket.waitForConnected(self._timeout)
- socket.write(bytes(message, 'UTF-8'))
- socket.waitForBytesWritten(self._timeout)
- socket.disconnectFromServer()
-
-
-# Adding signals to QMainWindow
-class QMainWindowKCC(QtWidgets.QMainWindow):
- progressBarTick = QtCore.pyqtSignal(str)
- modeConvert = QtCore.pyqtSignal(int)
- addMessage = QtCore.pyqtSignal(str, str, bool)
- addTrayMessage = QtCore.pyqtSignal(str, str)
- showDialog = QtCore.pyqtSignal(str, str)
- hideProgressBar = QtCore.pyqtSignal()
- forceShutdown = QtCore.pyqtSignal()
- dialogAnswer = QtCore.pyqtSignal(int)
-
-
if __name__ == "__main__":
freeze_support()
- KCCAplication = QApplicationMessaging(sys.argv)
+ KCCAplication = KCC_gui.QApplicationMessaging(sys.argv)
if KCCAplication.isRunning():
if len(sys.argv) > 1:
KCCAplication.sendMessage(sys.argv[1])
- sys.exit(0)
else:
KCCAplication.sendMessage('ARISE')
- sys.exit(0)
- KCCWindow = QMainWindowKCC()
- KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow)
- if len(sys.argv) > 1:
- KCCUI.handleMessage(sys.argv[1])
- sys.exit(KCCAplication.exec_())
+ else:
+ KCCWindow = KCC_gui.QMainWindowKCC()
+ KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow)
+ if len(sys.argv) > 1:
+ KCCUI.handleMessage(sys.argv[1])
+ sys.exit(KCCAplication.exec_())
diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py
index 9e18389..42eb9b9 100644
--- a/kcc/KCC_gui.py
+++ b/kcc/KCC_gui.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -19,7 +19,7 @@
__version__ = '4.3.1'
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import os
@@ -33,12 +33,11 @@ from shutil import move
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
from subprocess import STDOUT, PIPE
-from PyQt5 import QtGui, QtCore, QtWidgets
+from PyQt5 import QtGui, QtCore, QtWidgets, QtNetwork
from xml.dom.minidom import parse
-from html.parser import HTMLParser
from psutil import Popen, Process
from copy import copy
-from .shared import md5Checksum
+from .shared import md5Checksum, HTMLStripper
from . import comic2ebook
from . import KCC_rc_web
if sys.platform.startswith('darwin'):
@@ -49,6 +48,64 @@ else:
from . import KCC_ui
+class QApplicationMessaging(QtWidgets.QApplication):
+ messageFromOtherInstance = QtCore.pyqtSignal(bytes)
+
+ def __init__(self, argv):
+ QtWidgets.QApplication.__init__(self, argv)
+ self._key = 'KCC'
+ self._timeout = 1000
+ self._locked = False
+ socket = QtNetwork.QLocalSocket(self)
+ socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly)
+ if not socket.waitForConnected(self._timeout):
+ self._server = QtNetwork.QLocalServer(self)
+ # noinspection PyUnresolvedReferences
+ self._server.newConnection.connect(self.handleMessage)
+ self._server.listen(self._key)
+ else:
+ self._locked = True
+ socket.disconnectFromServer()
+
+ def __del__(self):
+ if not self._locked:
+ self._server.close()
+
+ def event(self, e):
+ if e.type() == QtCore.QEvent.FileOpen:
+ self.messageFromOtherInstance.emit(bytes(e.file(), 'UTF-8'))
+ return True
+ else:
+ return QtWidgets.QApplication.event(self, e)
+
+ def isRunning(self):
+ return self._locked
+
+ def handleMessage(self):
+ socket = self._server.nextPendingConnection()
+ if socket.waitForReadyRead(self._timeout):
+ self.messageFromOtherInstance.emit(socket.readAll().data())
+
+ def sendMessage(self, message):
+ socket = QtNetwork.QLocalSocket(self)
+ socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly)
+ socket.waitForConnected(self._timeout)
+ socket.write(bytes(message, 'UTF-8'))
+ socket.waitForBytesWritten(self._timeout)
+ socket.disconnectFromServer()
+
+
+class QMainWindowKCC(QtWidgets.QMainWindow):
+ progressBarTick = QtCore.pyqtSignal(str)
+ modeConvert = QtCore.pyqtSignal(int)
+ addMessage = QtCore.pyqtSignal(str, str, bool)
+ addTrayMessage = QtCore.pyqtSignal(str, str)
+ showDialog = QtCore.pyqtSignal(str, str)
+ hideProgressBar = QtCore.pyqtSignal()
+ forceShutdown = QtCore.pyqtSignal()
+ dialogAnswer = QtCore.pyqtSignal(int)
+
+
class Icons:
def __init__(self):
self.deviceKindle = QtGui.QIcon()
@@ -76,19 +133,6 @@ class Icons:
self.programIcon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
-class HTMLStripper(HTMLParser):
- def __init__(self):
- HTMLParser.__init__(self)
- self.reset()
- self.fed = []
-
- def handle_data(self, d):
- self.fed.append(d)
-
- def get_data(self):
- return ''.join(self.fed)
-
-
class WebServerHandler(BaseHTTPRequestHandler):
# noinspection PyAttributeOutsideInit, PyArgumentList
def do_GET(self):
diff --git a/kcc/__init__.py b/kcc/__init__.py
index 49174f8..72fa985 100644
--- a/kcc/__init__.py
+++ b/kcc/__init__.py
@@ -1,4 +1,4 @@
__version__ = '4.3.1'
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
\ No newline at end of file
diff --git a/kcc/cbxarchive.py b/kcc/cbxarchive.py
index 6a7c598..cdca253 100644
--- a/kcc/cbxarchive.py
+++ b/kcc/cbxarchive.py
@@ -1,5 +1,5 @@
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -17,7 +17,7 @@
#
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import sys
diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py
index 7401e45..dfd0702 100755
--- a/kcc/comic2ebook.py
+++ b/kcc/comic2ebook.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -20,7 +20,7 @@
__version__ = '4.3.1'
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import os
diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py
index 3b42258..22c783f 100644
--- a/kcc/comic2panel.py
+++ b/kcc/comic2panel.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -20,7 +20,7 @@
__version__ = '4.3.1'
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import os
diff --git a/kcc/dualmetafix.py b/kcc/dualmetafix.py
index 1c80b58..5889d68 100644
--- a/kcc/dualmetafix.py
+++ b/kcc/dualmetafix.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Based on initial version of DualMetaFix. Copyright (C) 2013 Kevin Hendricks
-# Changes for KCC Copyright (C) 2014 Pawel Jastrzebski
+# Changes for KCC Copyright (C) 2014-2015 Pawel Jastrzebski
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/kcc/image.py b/kcc/image.py
index 212feda..9eff741 100755
--- a/kcc/image.py
+++ b/kcc/image.py
@@ -1,7 +1,7 @@
# Copyright (C) 2010 Alex Yatskov
# Copyright (C) 2011 Stanislav (proDOOMman) Kosolapov
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
__version__ = '4.3.1'
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import os
diff --git a/kcc/pdfjpgextract.py b/kcc/pdfjpgextract.py
index 4531fa7..7ebae06 100644
--- a/kcc/pdfjpgextract.py
+++ b/kcc/pdfjpgextract.py
@@ -1,5 +1,5 @@
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# Based upon the code snippet by Ned Batchelder
# (http://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html)
@@ -20,7 +20,7 @@
#
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import os
diff --git a/kcc/shared.py b/kcc/shared.py
index dbbdd44..b8c7334 100644
--- a/kcc/shared.py
+++ b/kcc/shared.py
@@ -1,5 +1,5 @@
# Copyright (c) 2012-2014 Ciro Mattia Gonano
-# Copyright (c) 2013-2014 Pawel Jastrzebski
+# Copyright (c) 2013-2015 Pawel Jastrzebski
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -17,11 +17,27 @@
#
__license__ = 'ISC'
-__copyright__ = '2012-2014, Ciro Mattia Gonano , Pawel Jastrzebski '
+__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
import os
from hashlib import md5
+from html.parser import HTMLParser
+
+
+class HTMLStripper(HTMLParser):
+ def __init__(self):
+ HTMLParser.__init__(self)
+ self.reset()
+ self.strict = False
+ self.convert_charrefs = True
+ self.fed = []
+
+ def handle_data(self, d):
+ self.fed.append(d)
+
+ def get_data(self):
+ return ''.join(self.fed)
def getImageFileName(imgfile):
@@ -57,4 +73,43 @@ def md5Checksum(filePath):
def check7ZFile(filePath):
with open(filePath, 'rb') as fh:
header = fh.read(6)
- return header == b"7z\xbc\xaf'\x1c"
\ No newline at end of file
+ return header == b"7z\xbc\xaf'\x1c"
+
+
+# noinspection PyUnresolvedReferences
+def dependencyCheck(level):
+ missing = []
+ if level > 2:
+ try:
+ from PyQt5 import QtCore, QtNetwork, QtWidgets
+ if tuple(map(int, ('5.2.0'.split(".")))) > tuple(map(int, (QtCore.qVersion().split(".")))):
+ missing.append('PyQt5 5.2.0+')
+ except ImportError:
+ missing.append('PyQt5 5.2.0+')
+ if level > 1:
+ try:
+ import psutil
+ if tuple(map(int, ('2.0.0'.split(".")))) > tuple(map(int, psutil.version_info)):
+ missing.append('psutil 2.0.0+')
+ except ImportError:
+ missing.append('psutil 2.0.0+')
+ try:
+ import slugify
+ except ImportError:
+ missing.append('python-slugify')
+ try:
+ import PIL
+ if tuple(map(int, ('2.7.0'.split(".")))) > tuple(map(int, (PIL.PILLOW_VERSION.split(".")))):
+ missing.append('Pillow 2.7.0+')
+ except ImportError:
+ missing.append('Pillow 2.7.0+')
+ if len(missing) > 0:
+ try:
+ import tkinter
+ import tkinter.messagebox
+ importRoot = tkinter.Tk()
+ importRoot.withdraw()
+ tkinter.messagebox.showerror('KCC - Error', 'ERROR: ' + ', '.join(missing) + ' is not installed!')
+ except ImportError:
+ print('ERROR: ' + ', '.join(missing) + ' is not installed!')
+ exit(1)
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 9476d3e..99bd3f5 100755
--- a/setup.py
+++ b/setup.py
@@ -33,7 +33,7 @@ if platform == "darwin":
CFBundleName=NAME,
CFBundleShortVersionString=VERSION,
CFBundleGetInfoString=NAME + " " + VERSION +
- ", written 2012-2014 by Ciro Mattia Gonano and Pawel Jastrzebski",
+ ", written 2012-2015 by Ciro Mattia Gonano and Pawel Jastrzebski",
CFBundleExecutable=NAME,
CFBundleIdentifier='com.github.ciromattia.kcc',
CFBundleSignature='dplt',
@@ -81,7 +81,7 @@ elif platform == "win32":
windows=[{"script": MAIN,
"dest_base": "KCC",
"version": VERSION,
- "copyright": "Ciro Mattia Gonano, Pawel Jastrzebski © 2014",
+ "copyright": "Ciro Mattia Gonano, Pawel Jastrzebski © 2012-2015",
"legal_copyright": "ISC License (ISCL)",
"product_version": VERSION,
"product_name": "Kindle Comic Converter",
From b9276e9edec837f27d7bf156e3b5ed18eed78fb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Sun, 4 Jan 2015 09:11:46 +0100
Subject: [PATCH 08/12] WebToon processing improvements
---
kcc/comic2ebook.py | 12 ++++++++----
kcc/comic2panel.py | 38 ++++++++++++++++++++------------------
2 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py
index dfd0702..98feb17 100755
--- a/kcc/comic2ebook.py
+++ b/kcc/comic2ebook.py
@@ -824,11 +824,15 @@ def splitProcess(path, mode):
output = []
currentSize = 0
currentTarget = path
+ if options.webtoon:
+ targetSize = 104857600
+ else:
+ targetSize = 419430400
if mode == 0:
for root, dirs, files in walkLevel(path, 0):
for name in files:
size = os.path.getsize(os.path.join(root, name))
- if currentSize + size > 419430400:
+ if currentSize + size > targetSize:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
currentSize = size
@@ -840,7 +844,7 @@ def splitProcess(path, mode):
for root, dirs, files in walkLevel(path, 0):
for name in dirs:
size = getDirectorySize(os.path.join(root, name))
- if currentSize + size > 419430400:
+ if currentSize + size > targetSize:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
currentSize = size
@@ -854,7 +858,7 @@ def splitProcess(path, mode):
for name in dirs:
size = getDirectorySize(os.path.join(root, name))
currentSize = 0
- if size > 419430400:
+ if size > targetSize:
if not firstTome:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
@@ -863,7 +867,7 @@ def splitProcess(path, mode):
for rootInside, dirsInside, filesInside in walkLevel(os.path.join(root, name), 0):
for nameInside in dirsInside:
size = getDirectorySize(os.path.join(rootInside, nameInside))
- if currentSize + size > 419430400:
+ if currentSize + size > targetSize:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
currentSize = size
diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py
index 22c783f..16a88be 100644
--- a/kcc/comic2panel.py
+++ b/kcc/comic2panel.py
@@ -28,7 +28,7 @@ import sys
from shutil import rmtree, copytree, move
from optparse import OptionParser, OptionGroup
from multiprocessing import Pool
-from PIL import Image, ImageStat
+from PIL import Image, ImageStat, ImageOps
from .shared import getImageFileName, walkLevel
try:
from PyQt5 import QtCore
@@ -50,9 +50,9 @@ def mergeDirectory(work):
try:
directory = work[0]
images = []
- imagesClear = []
+ imagesValid = []
sizes = []
- h = 0
+ targetHeight = 0
for root, dirs, files in walkLevel(directory, 0):
for name in files:
if getImageFileName(name) is not None:
@@ -60,31 +60,34 @@ def mergeDirectory(work):
images.append([os.path.join(root, name), i.size[0], i.size[1]])
sizes.append(i.size[0])
if len(images) > 0:
- mw = max(set(sizes), key=sizes.count)
+ targetWidth = max(set(sizes), key=sizes.count)
for i in images:
- if i[1] == mw:
- h += i[2]
- imagesClear.append(i[0])
+ if i[1] <= targetWidth:
+ targetHeight += i[2]
+ imagesValid.append(i[0])
# Silently drop directories that contain too many images
- if h > 262144:
+ # 131072 = GIMP_MAX_IMAGE_SIZE / 4
+ if targetHeight > 131072:
return None
- result = Image.new('RGB', (mw, h))
+ result = Image.new('RGB', (targetWidth, targetHeight))
y = 0
- for i in imagesClear:
+ for i in imagesValid:
img = Image.open(i)
img = img.convert('RGB')
+ if img.size[0] < targetWidth:
+ img = ImageOps.fit(img, (targetWidth, img.size[1]), method=Image.BICUBIC, centering=(0.5, 0.5))
result.paste(img, (0, y))
y += img.size[1]
os.remove(i)
- savePath = os.path.split(imagesClear[0])
- result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG', optimize=1)
+ savePath = os.path.split(imagesValid[0])
+ result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG')
except Exception:
return str(sys.exc_info()[1])
def sanitizePanelSize(panel, opt):
newPanels = []
- if panel[2] > 8 * opt.height:
+ if panel[2] > 6 * opt.height:
diff = int(panel[2] / 8)
newPanels.append([panel[0], panel[1] - diff*7, diff])
newPanels.append([panel[1] - diff*7, panel[1] - diff*6, diff])
@@ -94,13 +97,13 @@ def sanitizePanelSize(panel, opt):
newPanels.append([panel[1] - diff*3, panel[1] - diff*2, diff])
newPanels.append([panel[1] - diff*2, panel[1] - diff, diff])
newPanels.append([panel[1] - diff, panel[1], diff])
- elif panel[2] > 4 * opt.height:
+ elif panel[2] > 3 * opt.height:
diff = int(panel[2] / 4)
newPanels.append([panel[0], panel[1] - diff*3, diff])
newPanels.append([panel[1] - diff*3, panel[1] - diff*2, diff])
newPanels.append([panel[1] - diff*2, panel[1] - diff, diff])
newPanels.append([panel[1] - diff, panel[1], diff])
- elif panel[2] > 2 * opt.height:
+ elif panel[2] > 1.5 * opt.height:
newPanels.append([panel[0], panel[1] - int(panel[2] / 2), int(panel[2] / 2)])
newPanels.append([panel[1] - int(panel[2] / 2), panel[1], int(panel[2] / 2)])
else:
@@ -165,7 +168,7 @@ def splitImage(work):
panels.append(panel)
if opt.debug:
# noinspection PyUnboundLocalVariable
- debugImage.save(os.path.join(path, fileExpanded[0] + '-debug.png'), 'PNG', optimize=1)
+ debugImage.save(os.path.join(path, fileExpanded[0] + '-debug.png'), 'PNG')
# Create virtual pages
pages = []
@@ -199,8 +202,7 @@ def splitImage(work):
panelImg = image.crop([0, panels[panel][0], widthImg, panels[panel][1]])
newPage.paste(panelImg, (0, targetHeight))
targetHeight += panels[panel][2]
- newPage.save(os.path.join(path, fileExpanded[0] + '-' +
- str(pageNumber) + '.png'), 'PNG', optimize=1)
+ newPage.save(os.path.join(path, fileExpanded[0] + '-' + str(pageNumber) + '.png'), 'PNG')
pageNumber += 1
os.remove(filePath)
except Exception:
From 3187ebb0544716215bf421449ab3d42d91d09f0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Sun, 4 Jan 2015 09:13:20 +0100
Subject: [PATCH 09/12] Generic processing improvements
---
kcc/comic2ebook.py | 32 ++++++++++++++++----------------
kcc/image.py | 45 +++++++++++++++++++++++++++++----------------
2 files changed, 45 insertions(+), 32 deletions(-)
diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py
index 98feb17..2a9aade 100755
--- a/kcc/comic2ebook.py
+++ b/kcc/comic2ebook.py
@@ -444,12 +444,12 @@ def imgOptimization(img, opt, hqImage=None):
img.cropWhiteSpace()
if opt.cutpagenumbers and not opt.webtoon:
img.cutPageNumber()
- img.optimizeImage(opt.gamma)
+ img.optimizeImage()
if hqImage:
- img.resizeImage(opt.upscale, opt.stretch, opt.bordersColor, 0)
+ img.resizeImage(0)
img.calculateBorder(hqImage, True)
else:
- img.resizeImage(opt.upscale, opt.stretch, opt.bordersColor, opt.quality)
+ img.resizeImage()
if opt.panelview:
if opt.quality == 0:
img.calculateBorder(img)
@@ -515,7 +515,7 @@ def imgFileProcessing(work):
dirpath = work[1]
opt = work[2]
output = []
- img = image.ComicPage(os.path.join(dirpath, afile), opt.profileData)
+ img = image.ComicPage(os.path.join(dirpath, afile), opt)
if opt.quality == 2:
wipe = False
else:
@@ -523,39 +523,39 @@ def imgFileProcessing(work):
if opt.nosplitrotate:
splitter = None
else:
- splitter = img.splitPage(dirpath, opt.righttoleft, opt.rotate)
+ splitter = img.splitPage(dirpath)
if splitter is not None:
- img0 = image.ComicPage(splitter[0], opt.profileData)
+ img0 = image.ComicPage(splitter[0], opt)
imgOptimization(img0, opt)
- output.append(img0.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
- img1 = image.ComicPage(splitter[1], opt.profileData)
+ output.append(img0.saveToDir(dirpath))
+ img1 = image.ComicPage(splitter[1], opt)
imgOptimization(img1, opt)
- output.append(img1.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
+ output.append(img1.saveToDir(dirpath))
if wipe:
output.append(img0.origFileName)
output.append(img1.origFileName)
if opt.quality == 2:
- img0b = image.ComicPage(splitter[0], opt.profileData, img0.fill)
+ img0b = image.ComicPage(splitter[0], opt, img0.fill)
imgOptimization(img0b, opt, img0)
- output.append(img0b.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
- img1b = image.ComicPage(splitter[1], opt.profileData, img1.fill)
+ output.append(img0b.saveToDir(dirpath))
+ img1b = image.ComicPage(splitter[1], opt, img1.fill)
imgOptimization(img1b, opt, img1)
- output.append(img1b.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
+ output.append(img1b.saveToDir(dirpath))
output.append(img0.origFileName)
output.append(img1.origFileName)
output.append(img.origFileName)
else:
imgOptimization(img, opt)
- output.append(img.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
+ output.append(img.saveToDir(dirpath))
if wipe:
output.append(img.origFileName)
if opt.quality == 2:
- img2 = image.ComicPage(os.path.join(dirpath, afile), opt.profileData, img.fill)
+ img2 = image.ComicPage(os.path.join(dirpath, afile), opt, img.fill)
if img.rotated:
img2.image = img2.image.rotate(90, Image.BICUBIC, True)
img2.rotated = True
imgOptimization(img2, opt, img)
- output.append(img2.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
+ output.append(img2.saveToDir(dirpath))
output.append(img.origFileName)
return output
except Exception:
diff --git a/kcc/image.py b/kcc/image.py
index 9eff741..f8cc4af 100755
--- a/kcc/image.py
+++ b/kcc/image.py
@@ -102,16 +102,15 @@ class ProfileData:
class ComicPage:
- def __init__(self, source, device, fill=None):
+ def __init__(self, source, options, fill=None):
try:
- self.profile_label, self.size, self.palette, self.gamma, self.panelviewsize = device
+ self.profile_label, self.size, self.palette, self.gamma, self.panelviewsize = options.profileData
except KeyError:
- raise RuntimeError('Unexpected output device %s' % device)
+ raise RuntimeError('Unexpected output device %s' % options.profileData)
self.origFileName = source
self.filename = os.path.basename(self.origFileName)
self.image = Image.open(source)
self.image = self.image.convert('RGB')
- self.color = self.isImageColor()
self.rotated = None
self.border = None
self.noHPV = None
@@ -119,17 +118,22 @@ class ComicPage:
self.noPV = None
self.purge = False
self.hq = False
+ self.opt = options
if fill:
self.fill = fill
else:
self.fill = None
+ if options.webtoon:
+ self.color = True
+ else:
+ self.color = self.isImageColor()
- def saveToDir(self, targetdir, forcepng, color):
+ def saveToDir(self, targetdir):
try:
if not self.purge:
flags = []
filename = os.path.join(targetdir, os.path.splitext(self.filename)[0]) + '-KCC'
- if not color and not forcepng:
+ if not self.opt.forcecolor and not self.opt.forcepng:
self.image = self.image.convert('L')
if self.rotated:
flags.append('Rotated')
@@ -146,7 +150,7 @@ class ComicPage:
if self.border:
flags.append('Margins-' + str(self.border[0]) + '-' + str(self.border[1]) + '-'
+ str(self.border[2]) + '-' + str(self.border[3]))
- if forcepng:
+ if self.opt.forcepng:
filename += '.png'
self.image.save(filename, 'PNG', optimize=1)
else:
@@ -158,7 +162,8 @@ class ComicPage:
except IOError as e:
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
- def optimizeImage(self, gamma):
+ def optimizeImage(self):
+ gamma = self.opt.gamma
if gamma < 0.1:
gamma = self.gamma
if self.gamma != 1.0 and self.color:
@@ -215,7 +220,12 @@ class ComicPage:
self.noHPV = True
self.noVPV = True
- def resizeImage(self, upscale=False, stretch=False, bordersColor=None, qualityMode=0):
+ def resizeImage(self, qualityMode=None):
+ upscale = self.opt.upscale
+ stretch = self.opt.stretch
+ bordersColor = self.opt.bordersColor
+ if qualityMode is None:
+ qualityMode = self.opt.quality
if bordersColor:
fill = bordersColor
else:
@@ -273,12 +283,12 @@ class ComicPage:
self.image = ImageOps.fit(self.image, size, method=method, centering=(0.5, 0.5))
return self.image
- def splitPage(self, targetdir, righttoleft=False, rotate=False):
+ def splitPage(self, targetdir):
width, height = self.image.size
dstwidth, dstheight = self.size
# Only split if origin is not oriented the same as target
if (width > height) != (dstwidth > dstheight):
- if rotate:
+ if self.opt.rotate:
self.image = self.image.rotate(90, Image.BICUBIC, True)
self.rotated = True
return None
@@ -296,7 +306,7 @@ class ComicPage:
fileone = targetdir + '/' + filename + '-AAA.png'
filetwo = targetdir + '/' + filename + '-BBB.png'
try:
- if righttoleft:
+ if self.opt.righttoleft:
pageone = self.image.crop(rightbox)
pagetwo = self.image.crop(leftbox)
else:
@@ -417,13 +427,16 @@ class ComicPage:
imageBoxB = ImageChops.invert(bw).getbbox()
if imageBoxA is None or imageBoxB is None:
surfaceB, surfaceW = 0, 0
+ diff = 0
else:
surfaceB = (imageBoxA[2] - imageBoxA[0]) * (imageBoxA[3] - imageBoxA[1])
surfaceW = (imageBoxB[2] - imageBoxB[0]) * (imageBoxB[3] - imageBoxB[1])
- if surfaceW < surfaceB:
- self.fill = 'white'
- elif surfaceW > surfaceB:
- self.fill = 'black'
+ diff = ((max(surfaceB, surfaceW) - min(surfaceB, surfaceW)) / min(surfaceB, surfaceW)) * 100
+ if diff > 0.5:
+ if surfaceW < surfaceB:
+ self.fill = 'white'
+ elif surfaceW > surfaceB:
+ self.fill = 'black'
else:
fill = 0
startY = 0
From 917eaef5484c070d0a392a14519f42c93a7d5a2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Sun, 4 Jan 2015 10:27:13 +0100
Subject: [PATCH 10/12] GUI tweaks
---
KCC-Linux.ui | 24 +++++++++++++++---------
KCC-OSX.ui | 18 ++++++++++++------
KCC.ui | 14 ++++++++++----
kcc/KCC_gui.py | 2 +-
kcc/KCC_ui.py | 20 +++++++++++---------
kcc/KCC_ui_linux.py | 30 ++++++++++++++++--------------
kcc/KCC_ui_osx.py | 24 +++++++++++++-----------
7 files changed, 78 insertions(+), 54 deletions(-)
diff --git a/KCC-Linux.ui b/KCC-Linux.ui
index 7c41928..edf8fa4 100644
--- a/KCC-Linux.ui
+++ b/KCC-Linux.ui
@@ -71,7 +71,7 @@
Qt::NoFocus
- <html><head/><body><p style='white-space:pre'>Disable image optimizations.<br/>Input images must be already resized.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Disable image optimizations.<br/><span style=" font-weight:600;">Input images must be already resized.</span></p></body></html>
No optimisation
@@ -110,7 +110,7 @@
Qt::NoFocus
- <html><head/><body><p>Enable auto-splitting of webtoons like <span style=" font-style:italic;">Tower of God</span> or <span style=" font-style:italic;">Noblesse</span>.<br/>This mode was created for pages with a low width, high height and vertical panel flow.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Enable special parsing mode for WebToons.</p></body></html>
Webtoon mode
@@ -167,7 +167,7 @@
Qt::NoFocus
- <html><head/><body><p style='white-space:pre'>Disable splitting and rotation.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Disable page splitting and rotation.</p></body></html>
No split/rotate
@@ -241,7 +241,7 @@
Qt::NoFocus
- <html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory.</p></body></html>
Convert
@@ -269,6 +269,9 @@
Qt::NoFocus
+
+ <html><head/><body><p style='white-space:pre'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=" font-weight:600;">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html>
+
Add directory
@@ -295,6 +298,9 @@
Qt::NoFocus
+
+ <html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>
+
Add file
@@ -386,7 +392,7 @@
Qt::NoFocus
- <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode</span><br/>Maximal quality of images but very poor magnification quality.<br/>Use it only when zoom is not needed or output files needs to be small.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - High quality mode</span><br/>In most cases high quality of images and magnification.<br/>Overall quality highly depends on the resolution of source files.<br/>On Kindle models older than Paperwhite non-zoomed images might be a little blurred.<br/><br/><span style=" font-weight:600; text-decoration: underline;">Checked - Ultra quality mode</span><br/>Highest possible quality. Output files will be big.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Quality of Panel View/zoom. Highly impact size of output file.<br/><span style=" font-weight:600;">This option control only quality of magnification!</span></p></body></html>
High/Ultra quality
@@ -664,7 +670,7 @@
- <html><head/><body><p>Resolution of target device.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html>
Custom width:
@@ -697,7 +703,7 @@
false
- <html><head/><body><p>Resolution of target device.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html>
0000
@@ -715,7 +721,7 @@
- <html><head/><body><p>Resolution of target device.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html>
Custom height:
@@ -748,7 +754,7 @@
false
- <html><head/><body><p>Resolution of target device.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html>
0000
diff --git a/KCC-OSX.ui b/KCC-OSX.ui
index e73c93d..77a9079 100644
--- a/KCC-OSX.ui
+++ b/KCC-OSX.ui
@@ -69,7 +69,7 @@
Qt::NoFocus
- <html><head/><body><p style='white-space:pre'>Disable image optimizations.<br/>Input images must be already resized.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Disable image optimizations.<br/><span style=" font-weight:600;">Input images must be already resized.</span></p></body></html>
No optimisation
@@ -110,7 +110,7 @@
Qt::NoFocus
- <html><head/><body><p>Enable auto-splitting of webtoons like <span style=" font-style:italic;">Tower of God </span>or <span style=" font-style:italic;">Noblesse</span>.<br/>This mode was created for pages with a low width, high height and vertical panel flow.</p><p><br/></p></body></html>
+ <html><head/><body><p style='white-space:pre'>Enable special parsing mode for WebToons.</p></body></html>
Webtoon mode
@@ -170,7 +170,7 @@
Qt::NoFocus
- <html><head/><body><p style='white-space:pre'>Disable splitting and rotation.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Disable page splitting and rotation.</p></body></html>
No split/rotate
@@ -220,7 +220,7 @@
Qt::NoFocus
- <html><head/><body><p style='white-space:pre'>Output format.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Output format.</p></body></html>
@@ -244,7 +244,7 @@
Qt::NoFocus
- <html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory.</p></body></html>
Convert
@@ -272,6 +272,9 @@
Qt::NoFocus
+
+ <html><head/><body><p style='white-space:pre'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=" font-weight:600;">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html>
+
Add directory
@@ -298,6 +301,9 @@
Qt::NoFocus
+
+ <html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>
+
Add file
@@ -391,7 +397,7 @@
Qt::NoFocus
- <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode</span><br/>Maximal quality of images but very poor magnification quality.<br/>Use it only when zoom is not needed or output files needs to be small.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - High quality mode</span><br/>In most cases high quality of images and magnification.<br/>Overall quality highly depends on the resolution of source files.<br/>On Kindle models older than Paperwhite non-zoomed images might be a little blurred.</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Ultra quality mode</span><br/>Highest possible quality. Output files will be big.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Quality of Panel View/zoom. Highly impact size of output file.<br/><span style=" font-weight:600;">This option control only quality of magnification!</span></p></body></html>
High/Ultra quality
diff --git a/KCC.ui b/KCC.ui
index 883a351..9e83cf7 100644
--- a/KCC.ui
+++ b/KCC.ui
@@ -65,7 +65,7 @@
Qt::NoFocus
- <html><head/><body><p style='white-space:pre'>Disable image optimizations.<br/>Input images must be already resized.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Disable image optimizations.<br/><span style=" font-weight:600;">Input images must be already resized.</span></p></body></html>
No optimisation
@@ -94,7 +94,7 @@
Qt::NoFocus
- <html><head/><body><p style="white-space:pre">Enable auto-splitting of webtoons like <span style=" font-style:italic;">Tower of God</span> or <span style=" font-style:italic;">Noblesse</span>.<br/>This mode is created for pages with a low width, high height and vertical panel flow.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Enable special parsing mode for WebToons.</p></body></html>
Webtoon mode
@@ -136,7 +136,7 @@
Qt::NoFocus
- <html><head/><body><p style='white-space:pre'>Disable splitting and rotation.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Disable page splitting and rotation.</p></body></html>
No split/rotate
@@ -234,6 +234,9 @@
Qt::NoFocus
+
+ <html><head/><body><p style='white-space:pre'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=" font-weight:600;">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html>
+
Add directory
@@ -259,6 +262,9 @@
Qt::NoFocus
+
+ <html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>
+
Add file
@@ -338,7 +344,7 @@
Qt::NoFocus
- <html><head/><body><p style="white-space:pre"><span style=" font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode<br/></span>Maximal quality of images but very poor magnification quality.<br/>Use it only when zoom is not needed or output files needs to be small.</p><p style="white-space:pre"><span style=" font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br/></span>In most cases high quality of images and magnification.<br/>Overall quality highly depends on the resolution of source files.<br/>On Kindle models older than Paperwhite non-zoomed images might be a little blurred.</p><p style="white-space:pre"><span style=" font-weight:600; text-decoration: underline;">Checked - Ultra quality mode<br/></span>Highest possible quality. Output files will be big.</p></body></html>
+ <html><head/><body><p style='white-space:pre'>Quality of Panel View/zoom. Highly impact size of output file.<br/><span style=" font-weight:600;">This option control only quality of magnification!</span></p></body></html>
High/Ultra quality
diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py
index 42eb9b9..74dc7f6 100644
--- a/kcc/KCC_gui.py
+++ b/kcc/KCC_gui.py
@@ -1070,7 +1070,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
elif sys.platform.startswith('linux'):
self.listFontSize = 8
self.statusBarFontSize = 8
- self.statusBarStyle = 'QLabel{padding-top:5px;padding-bottom:3px;}'
+ self.statusBarStyle = 'QLabel{padding-top:3px;padding-bottom:3px;}'
self.statusBar.setStyleSheet('QStatusBar::item{border:0px;border-top:2px solid #C2C7CB;}')
else:
self.listFontSize = 9
diff --git a/kcc/KCC_ui.py b/kcc/KCC_ui.py
index dd36744..4de51be 100644
--- a/kcc/KCC_ui.py
+++ b/kcc/KCC_ui.py
@@ -2,8 +2,8 @@
# Form implementation generated from reading ui file 'KCC.ui'
#
-# Created: Sun May 18 09:08:27 2014
-# by: PyQt5 UI code generator 5.2.1
+# Created: Sun Jan 4 09:58:25 2015
+# by: PyQt5 UI code generator 5.4
#
# WARNING! All changes made in this file will be lost!
@@ -138,12 +138,12 @@ class Ui_KCC(object):
self.JobList = QtWidgets.QListWidget(self.Form)
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
- self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
- self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
- self.JobList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
+ self.JobList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.JobList.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
+ self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
+ self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setObjectName("JobList")
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
@@ -261,28 +261,30 @@ class Ui_KCC(object):
def retranslateUi(self, KCC):
_translate = QtCore.QCoreApplication.translate
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
- self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.
Input images must be already resized.
"))
+ self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.
Input images must be already resized.
"))
self.ProcessingBox.setText(_translate("KCC", "No optimisation"))
self.UpscaleBox.setToolTip(_translate("KCC", "Unchecked - Nothing
Images smaller than device resolution will not be resized.
Indeterminate - Stretching
Images smaller than device resolution will be resized. Aspect ratio will be not preserved.
Checked - Upscaling
Images smaller than device resolution will be resized. Aspect ratio will be preserved.
"))
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
- self.WebtoonBox.setToolTip(_translate("KCC", "Enable auto-splitting of webtoons like Tower of God or Noblesse.
This mode is created for pages with a low width, high height and vertical panel flow.
"))
+ self.WebtoonBox.setToolTip(_translate("KCC", "Enable special parsing mode for WebToons.
"))
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
self.NoDitheringBox.setToolTip(_translate("KCC", "Create PNG files instead JPEG.
Quality increase is not noticeable on most of devices.
Output files might be smaller.
MOBI conversion will be much slower.
"))
self.NoDitheringBox.setText(_translate("KCC", "PNG output"))
self.BorderBox.setToolTip(_translate("KCC", "Unchecked - Autodetection
Color of margins fill will be detected automatically.
Indeterminate - White
Margins will be filled with white color.
Checked - Black
Margins will be filled with black color.
"))
self.BorderBox.setText(_translate("KCC", "W/B margins"))
- self.NoRotateBox.setToolTip(_translate("KCC", "
Disable splitting and rotation.
"))
+ self.NoRotateBox.setToolTip(_translate("KCC", "Disable page splitting and rotation.
"))
self.NoRotateBox.setText(_translate("KCC", "No split/rotate"))
self.DeviceBox.setToolTip(_translate("KCC", "Target device.
"))
self.FormatBox.setToolTip(_translate("KCC", "Output format.
"))
self.ConvertButton.setToolTip(_translate("KCC", "Shift+Click to select the output directory.
"))
self.ConvertButton.setText(_translate("KCC", "Convert"))
+ self.DirectoryButton.setToolTip(_translate("KCC", "Add directory containing JPG, PNG or GIF files to queue.
CBR, CBZ and CB7 files inside will not be processed!
"))
self.DirectoryButton.setText(_translate("KCC", "Add directory"))
+ self.FileButton.setToolTip(_translate("KCC", "Add CBR, CBZ, CB7 or PDF file to queue.
"))
self.FileButton.setText(_translate("KCC", "Add file"))
self.ClearButton.setText(_translate("KCC", "Clear list"))
self.MangaBox.setToolTip(_translate("KCC", "Enable right-to-left reading.
"))
self.MangaBox.setText(_translate("KCC", "Manga mode"))
- self.QualityBox.setToolTip(_translate("KCC", "Unchecked - Normal quality mode
Maximal quality of images but very poor magnification quality.
Use it only when zoom is not needed or output files needs to be small.
Indeterminate - High quality mode
In most cases high quality of images and magnification.
Overall quality highly depends on the resolution of source files.
On Kindle models older than Paperwhite non-zoomed images might be a little blurred.
Checked - Ultra quality mode
Highest possible quality. Output files will be big.
"))
+ self.QualityBox.setToolTip(_translate("KCC", "Quality of Panel View/zoom. Highly impact size of output file.
This option control only quality of magnification!
"))
self.QualityBox.setText(_translate("KCC", "High/Ultra quality"))
self.RotateBox.setToolTip(_translate("KCC", "Disable splitting of two-page spreads.
They will be rotated instead.
"))
self.RotateBox.setText(_translate("KCC", "Horizontal mode"))
diff --git a/kcc/KCC_ui_linux.py b/kcc/KCC_ui_linux.py
index d077804..eabddc6 100644
--- a/kcc/KCC_ui_linux.py
+++ b/kcc/KCC_ui_linux.py
@@ -2,8 +2,8 @@
# Form implementation generated from reading ui file 'KCC-Linux.ui'
#
-# Created: Sun May 18 09:08:37 2014
-# by: PyQt5 UI code generator 5.2.1
+# Created: Sun Jan 4 10:06:14 2015
+# by: PyQt5 UI code generator 5.4
#
# WARNING! All changes made in this file will be lost!
@@ -178,13 +178,13 @@ class Ui_KCC(object):
font.setItalic(False)
self.JobList.setFont(font)
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
- self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
- self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
- self.JobList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
+ self.JobList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.JobList.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.JobList.setIconSize(QtCore.QSize(18, 18))
+ self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
+ self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setObjectName("JobList")
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
@@ -330,28 +330,30 @@ class Ui_KCC(object):
def retranslateUi(self, KCC):
_translate = QtCore.QCoreApplication.translate
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
- self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.
Input images must be already resized.
"))
+ self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.
Input images must be already resized.
"))
self.ProcessingBox.setText(_translate("KCC", "No optimisation"))
self.UpscaleBox.setToolTip(_translate("KCC", "Unchecked - Nothing
Images smaller than device resolution will not be resized.
Indeterminate - Stretching
Images smaller than device resolution will be resized. Aspect ratio will be not preserved.
Checked - Upscaling
Images smaller than device resolution will be resized. Aspect ratio will be preserved.
"))
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
- self.WebtoonBox.setToolTip(_translate("KCC", "Enable auto-splitting of webtoons like Tower of God or Noblesse.
This mode was created for pages with a low width, high height and vertical panel flow.
"))
+ self.WebtoonBox.setToolTip(_translate("KCC", "Enable special parsing mode for WebToons.
"))
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
self.NoDitheringBox.setToolTip(_translate("KCC", "Create PNG files instead JPEG.
Quality increase is not noticeable on most of devices.
Output files might be smaller.
MOBI conversion will be much slower.
"))
self.NoDitheringBox.setText(_translate("KCC", "PNG output"))
self.BorderBox.setToolTip(_translate("KCC", "Unchecked - Autodetection
Color of margins fill will be detected automatically.
Indeterminate - White
Margins will be filled with white color.
Checked - Black
Margins will be filled with black color.
"))
self.BorderBox.setText(_translate("KCC", "W/B margins"))
- self.NoRotateBox.setToolTip(_translate("KCC", "Disable splitting and rotation.
"))
+ self.NoRotateBox.setToolTip(_translate("KCC", "Disable page splitting and rotation.
"))
self.NoRotateBox.setText(_translate("KCC", "No split/rotate"))
self.DeviceBox.setToolTip(_translate("KCC", "Target device.
"))
self.FormatBox.setToolTip(_translate("KCC", "Output format.
"))
- self.ConvertButton.setToolTip(_translate("KCC", "Shift+Click to select the output directory.
"))
+ self.ConvertButton.setToolTip(_translate("KCC", "Shift+Click to select the output directory.
"))
self.ConvertButton.setText(_translate("KCC", "Convert"))
+ self.DirectoryButton.setToolTip(_translate("KCC", "Add directory containing JPG, PNG or GIF files to queue.
CBR, CBZ and CB7 files inside will not be processed!
"))
self.DirectoryButton.setText(_translate("KCC", "Add directory"))
+ self.FileButton.setToolTip(_translate("KCC", "Add CBR, CBZ, CB7 or PDF file to queue.
"))
self.FileButton.setText(_translate("KCC", "Add file"))
self.ClearButton.setText(_translate("KCC", "Clear list"))
self.MangaBox.setToolTip(_translate("KCC", "Enable right-to-left reading.
"))
self.MangaBox.setText(_translate("KCC", "Manga mode"))
- self.QualityBox.setToolTip(_translate("KCC", "Unchecked - Normal quality mode
Maximal quality of images but very poor magnification quality.
Use it only when zoom is not needed or output files needs to be small.
Indeterminate - High quality mode
In most cases high quality of images and magnification.
Overall quality highly depends on the resolution of source files.
On Kindle models older than Paperwhite non-zoomed images might be a little blurred.
Checked - Ultra quality mode
Highest possible quality. Output files will be big.
"))
+ self.QualityBox.setToolTip(_translate("KCC", "Quality of Panel View/zoom. Highly impact size of output file.
This option control only quality of magnification!
"))
self.QualityBox.setText(_translate("KCC", "High/Ultra quality"))
self.RotateBox.setToolTip(_translate("KCC", "Disable splitting of two-page spreads.
They will be rotated instead.
"))
self.RotateBox.setText(_translate("KCC", "Horizontal mode"))
@@ -360,13 +362,13 @@ class Ui_KCC(object):
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
self.ColorBox.setToolTip(_translate("KCC", "Don\'t convert images to grayscale.
"))
self.ColorBox.setText(_translate("KCC", "Color mode"))
- self.wLabel.setToolTip(_translate("KCC", "Resolution of target device.
"))
+ self.wLabel.setToolTip(_translate("KCC", "Resolution of target device.
"))
self.wLabel.setText(_translate("KCC", "Custom width: "))
- self.customWidth.setToolTip(_translate("KCC", "Resolution of target device.
"))
+ self.customWidth.setToolTip(_translate("KCC", "Resolution of target device.
"))
self.customWidth.setInputMask(_translate("KCC", "0000"))
- self.hLabel.setToolTip(_translate("KCC", "Resolution of target device.
"))
+ self.hLabel.setToolTip(_translate("KCC", "Resolution of target device.
"))
self.hLabel.setText(_translate("KCC", "Custom height: "))
- self.customHeight.setToolTip(_translate("KCC", "Resolution of target device.
"))
+ self.customHeight.setToolTip(_translate("KCC", "Resolution of target device.
"))
self.customHeight.setInputMask(_translate("KCC", "0000"))
self.ActionBasic.setText(_translate("KCC", "Basic"))
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
diff --git a/kcc/KCC_ui_osx.py b/kcc/KCC_ui_osx.py
index fb12b70..775ecc8 100644
--- a/kcc/KCC_ui_osx.py
+++ b/kcc/KCC_ui_osx.py
@@ -2,8 +2,8 @@
# Form implementation generated from reading ui file 'KCC-OSX.ui'
#
-# Created: Sun May 18 09:08:44 2014
-# by: PyQt5 UI code generator 5.2.1
+# Created: Sun Jan 4 10:26:09 2015
+# by: PyQt5 UI code generator 5.4
#
# WARNING! All changes made in this file will be lost!
@@ -185,12 +185,12 @@ class Ui_KCC(object):
font.setPointSize(11)
self.JobList.setFont(font)
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
- self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
- self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
- self.JobList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
+ self.JobList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.JobList.setProperty("showDropIndicator", False)
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
+ self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
+ self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.JobList.setObjectName("JobList")
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
self.BasicModeButton.setGeometry(QtCore.QRect(5, 10, 210, 41))
@@ -353,28 +353,30 @@ class Ui_KCC(object):
def retranslateUi(self, KCC):
_translate = QtCore.QCoreApplication.translate
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
- self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.
Input images must be already resized.
"))
+ self.ProcessingBox.setToolTip(_translate("KCC", "Disable image optimizations.
Input images must be already resized.
"))
self.ProcessingBox.setText(_translate("KCC", "No optimisation"))
self.UpscaleBox.setToolTip(_translate("KCC", "Unchecked - Nothing
Images smaller than device resolution will not be resized.
Indeterminate - Stretching
Images smaller than device resolution will be resized. Aspect ratio will be not preserved.
Checked - Upscaling
Images smaller than device resolution will be resized. Aspect ratio will be preserved.
"))
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
- self.WebtoonBox.setToolTip(_translate("KCC", "Enable auto-splitting of webtoons like Tower of God or Noblesse.
This mode was created for pages with a low width, high height and vertical panel flow.
"))
+ self.WebtoonBox.setToolTip(_translate("KCC", "Enable special parsing mode for WebToons.
"))
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
self.NoDitheringBox.setToolTip(_translate("KCC", "Create PNG files instead JPEG.
Quality increase is not noticeable on most of devices.
Output files might be smaller.
MOBI conversion will be much slower.
"))
self.NoDitheringBox.setText(_translate("KCC", "PNG output"))
self.BorderBox.setToolTip(_translate("KCC", "Unchecked - Autodetection
Color of margins fill will be detected automatically.
Indeterminate - White
Margins will be filled with white color.
Checked - Black
Margins will be filled with black color.
"))
self.BorderBox.setText(_translate("KCC", "W/B margins"))
- self.NoRotateBox.setToolTip(_translate("KCC", "Disable splitting and rotation.
"))
+ self.NoRotateBox.setToolTip(_translate("KCC", "Disable page splitting and rotation.
"))
self.NoRotateBox.setText(_translate("KCC", "No split/rotate"))
self.DeviceBox.setToolTip(_translate("KCC", "Target device.
"))
- self.FormatBox.setToolTip(_translate("KCC", "Output format.
"))
- self.ConvertButton.setToolTip(_translate("KCC", "Shift+Click to select the output directory.
"))
+ self.FormatBox.setToolTip(_translate("KCC", "Output format.
"))
+ self.ConvertButton.setToolTip(_translate("KCC", "Shift+Click to select the output directory.
"))
self.ConvertButton.setText(_translate("KCC", "Convert"))
+ self.DirectoryButton.setToolTip(_translate("KCC", "Add directory containing JPG, PNG or GIF files to queue.
CBR, CBZ and CB7 files inside will not be processed!
"))
self.DirectoryButton.setText(_translate("KCC", "Add directory"))
+ self.FileButton.setToolTip(_translate("KCC", "Add CBR, CBZ, CB7 or PDF file to queue.
"))
self.FileButton.setText(_translate("KCC", "Add file"))
self.ClearButton.setText(_translate("KCC", "Clear list"))
self.MangaBox.setToolTip(_translate("KCC", "Enable right-to-left reading.
"))
self.MangaBox.setText(_translate("KCC", "Manga mode"))
- self.QualityBox.setToolTip(_translate("KCC", "Unchecked - Normal quality mode
Maximal quality of images but very poor magnification quality.
Use it only when zoom is not needed or output files needs to be small.
Indeterminate - High quality mode
In most cases high quality of images and magnification.
Overall quality highly depends on the resolution of source files.
On Kindle models older than Paperwhite non-zoomed images might be a little blurred.
Checked - Ultra quality mode
Highest possible quality. Output files will be big.
"))
+ self.QualityBox.setToolTip(_translate("KCC", "Quality of Panel View/zoom. Highly impact size of output file.
This option control only quality of magnification!
"))
self.QualityBox.setText(_translate("KCC", "High/Ultra quality"))
self.RotateBox.setToolTip(_translate("KCC", "Disable splitting of two-page spreads.
They will be rotated instead.
"))
self.RotateBox.setText(_translate("KCC", "Horizontal mode"))
From b5bc2f8e00dde644d65395080d90ce5ead4611a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Sun, 4 Jan 2015 10:49:59 +0100
Subject: [PATCH 11/12] Updated README + version bump
---
README.md | 380 +++++++++++++++++++++++----------------------
kcc-c2e.py | 2 +-
kcc-c2p.py | 2 +-
kcc.iss | 2 +-
kcc.py | 2 +-
kcc/KCC_gui.py | 2 +-
kcc/__init__.py | 2 +-
kcc/comic2ebook.py | 2 +-
kcc/comic2panel.py | 2 +-
kcc/image.py | 2 +-
setup.py | 2 +-
setup.sh | 2 +-
12 files changed, 204 insertions(+), 198 deletions(-)
diff --git a/README.md b/README.md
index 98f9811..6660277 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,7 @@ _KC2_ in no way is a replacement for **KCC** so you can be quite confident we'll
### Issues / new features / donations
If you have general questions about usage, feedback etc. please [post it here](http://www.mobileread.com/forums/showthread.php?t=207461).
If you have some **technical** problems using KCC please [file an issue here](https://github.com/ciromattia/kcc/issues/new).
-If you can fix an open issue, fork & make a pull request.
-If you want more chances an issue is fixes or your wanted feature added, consider [placing a bounty](https://www.bountysource.com/trackers/65571-ciromattia-kcc)!
+If you can fix an open issue, fork & make a pull request.
If you find **KCC** valuable you can consider donating to the authors:
- Ciro Mattia Gonano:
@@ -32,7 +31,7 @@ You can find the latest released binary at the following links:
## INPUT FORMATS
**KCC** can understand and convert, at the moment, the following input types:
-- Folders containing: PNG, JPG, GIF, TIFF or BMP files
+- Folders containing: PNG, JPG or GIF files
- CBZ, ZIP
- CBR, RAR *(With `unrar` executable)*
- CB7, 7Z *(With `7za` executable)*
@@ -46,19 +45,19 @@ You can find the latest released binary at the following links:
### For running from source:
- Python 3.3+
- [PyQt5](http://www.riverbankcomputing.co.uk/software/pyqt/download5) 5.2.0+
-- [Pillow](http://pypi.python.org/pypi/Pillow/) 2.5.0+
+- [Pillow](http://pypi.python.org/pypi/Pillow/) 2.7.0+
- [psutil](https://pypi.python.org/pypi/psutil) 2.0+
- [python-slugify](http://pypi.python.org/pypi/python-slugify)
On Debian based distributions these two commands should install all dependencies:
```
-sudo apt-get install python3 python3-dev python3-pip python3-pyqt5 libtiff-dev libpng-dev libjpeg-dev p7zip-full unrar
+sudo apt-get install python3 python3-dev python3-pip python3-pyqt5 libpng-dev libjpeg-dev p7zip-full unrar
sudo pip3 install pillow python-slugify psutil
```
### For freezing code:
-- Windows - [py2exe](https://pypi.python.org/pypi/py2exe) 0.9.2+
-- OS X - [py2app](https://bitbucket.org/ronaldoussoren/py2app) 0.8.0+
+- Windows - [py2exe](https://pypi.python.org/pypi/py2exe) 0.9.2.2+
+- OS X - [py2app](https://bitbucket.org/ronaldoussoren/py2app) 0.9.0+
## USAGE
@@ -143,7 +142,7 @@ This script born as a cross-platform alternative to `KindleComicParser` by **Dc5
The app relies and includes the following scripts:
- `DualMetaFix` script by **K. Hendricks**. Released with GPL-3 License.
- - `rarfile.py` script © 2005-2011 **Marko Kreen** . Released with ISC License.
+ - `rarfile.py` script © 2005-2014 **Marko Kreen** . Released with ISC License.
- `image.py` class from **Alex Yatskov**'s [Mangle](https://github.com/FooSoft/mangle/) with subsequent [proDOOMman](https://github.com/proDOOMman/Mangle)'s and [Birua](https://github.com/Birua/Mangle)'s patches.
- Icon is by **Nikolay Verin** ([http://ncrow.deviantart.com/](http://ncrow.deviantart.com/)) and released under [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/) License.
@@ -159,113 +158,115 @@ The app relies and includes the following scripts:
* [Kobo Aura H2O](http://kcc.iosphe.re/Samples/Ubunchu!-KoAH2O.cbz)
## CHANGELOG
-####1.0
-* Initial version
+####4.4:
+* Improved speed and quality of conversion
+* Added RAR5 support
+* Dropped BMP and TIFF support
+* Fixed some WebToon mode bugs
+* Fixed CBR parsing on OSX
-####1.1
-* Added support for CBZ/CBR files in comic2ebook.py
+####4.3.1:
+* Fixed Kindle Voyage profile
+* Fixed some bugs in OS X release
+* CLI version now support multiple input files at once
+* Disabled MCB support
+* Other minor tweaks
-####1.1.1
-* Added support for CBZ/CBR files in Kindle Comic Converter
+####4.3:
+* Added profiles for Kindle Voyage and Kobo Aura H2O
+* Added missing features to CLI version
+* Other minor bug fixes
-####1.2
-* Comic optimizations! Split pages not target-oriented (landscape with portrait target or portrait with landscape target), add palette and other image optimizations from Mangle. WARNING: PIL is required for all image mangling!
+####4.2.1:
+* Improved margin color detection
+* Fixed random crashes of MOBI processing step
+* Fixed resizing problems in high quality mode
+* Fixed some MCD support bugs
+* Default output format for Kindle DX is now CBZ
-####1.3
-* Fixed an issue in OPF generation for device resolution
-* Reworked options system (call with -h option to get the inline help)
+####4.2:
+* Added [Manga Cover Database](http://manga.joentjuh.nl/) support
+* Officially dropped Windows XP support
+* Fixed _Other_ profile
+* Fixed problems with page order on stock KOBO CBZ reader
+* Many other small bug fixes and tweaks
-####1.4
-* Added some options for controlling image optimization
-* Further optimization (ImageOps, page numbering cut, autocontrast)
+####4.1:
+* Thanks to code contributed by Kevin Hendricks speed of MOBI creation was greatly increased
+* Improved performance on Windows
+* Improved MOBI splitting and changed maximal size of output file
+* Fixed _No optimization_ mode
+* Multiple small tweaks nad minor bug fixes
-####1.4.1
-* Fixed a serious bug on resizing when img ratio was bigger than device one
+####4.0.2:
+* Fixed some Windows and OSX specific bugs
+* Fixed problem with marigns when using HQ mode
-####1.5
-* Added subfolder support for multiple chapters.
+####4.0.1:
+* Fixed file lock problems that plagued some Windows users
+* Fixed content server failing to start on Windows
+* Improved performance of WebToon splitter
+* Tweaked margin color detection
-####2.0
-* GUI! AppleScript is gone and Tk is used to provide cross-platform GUI support.
+####4.0:
+* KCC now use Python 3.3 and Qt 5.2
+* Full UTF-8 awareness
+* CBZ output now support Manga mode
+* Improved Panel View support and margin color detection
+* Added drag&drop support
+* Output directory can be now selected
+* Windows release now have auto-updater
+* Names of chapters on Kindle should be now more user friendly
+* Fixed OSX file association support
+* Many extensive internal changes and tweaks
-####2.1
-* Added basic error reporting
+####3.7.2:
+* Fixed problems with HQ mode
-####2.2:
-* Added (valid!) EPUB 2.0 output
-* Rename .zip files to .cbz to avoid overwriting
+####3.7.1:
+* Hotfixed Kobo profiles
-####2.3
-* Fixed win32 EPUB generation, folder handling, filenames with spaces and subfolders
+####3.7:
+* Added profiles for KOBO devices
+* Improved Panel View support
+* Improved WebToon splitter
+* Improved margin color autodetection
+* Tweaked EPUB output
+* Fixed stretching option
+* GUI tweaks and minor bugfixes
-####2.4
-* Use temporary directory as workdir (fixes converting from external volumes and zipfiles renaming)
-* Fixed "add folders" from GUI.
+####3.6.2:
+* Fixed previous PNG output fix
+* Fixed Panel View anomalies
-####2.5
-* Added --black-borders option to set added borders black when page's ratio is not the device's one (#11).
-* Fixes EPUB containing zipped itself (#10)
+####3.6.1:
+* Fixed PNG output
-####2.6
-* Added --rotate option to rotate landscape images instead of splitting them (#16, #24)
-* Added --output option to customize EPUB output dir/file (#22)
-* Add rendition:layout and rendition:orientation EPUB meta tags (supported by new kindlegen 2.8)
-* Fixed natural sorting for files (#18)
+####3.6:
+* Increased quality of Panel View zoom
+* Creation of multipart MOBI output is now faster on machines with 4GB+ RAM
+* Automatic gamma correction now distinguishes color and grayscale images
+* Added ComicRack metadata parser
+* Implemented new method to detect border color in non-webtoon comics
+* Upscaling is now enabled by default for Kindle Fire HD/HDX
+* Windows nad Linux releases now have tray icon
+* Fixed Kindle Fire HDX 7" output
+* Increased target resolution for Kindle DX/DXG CBZ output
-####2.7
-* Lots of GUI improvements (#27, #13)
-* Added gamma support within --gamma option (defaults to profile-specified gamma) (#26, #27)
-* Added --nodithering option to prevent dithering optimizations (#27)
-* EPUB margins support (#30)
-* Fixed no file added if file has no spaces on Windows (#25)
-* Gracefully exit if unrar missing (#15)
-* Do not call kindlegen if source EPUB is bigger than 320MB (#17)
-* Get filetype from magic number (#14)
-* PDF conversion works again
+####3.5:
+* Added simple content server - Converted files can be now delivered wireless
+* Added proper Windows installer
+* Improved multiprocessing speed
+* GUI tweaks and minor bug fixes
-####2.8
-* Updated rarfile library
-* Panel View support + HQ support (#36) - new option: --nopanelviewhq
-* Split profiles for K4NT and K4T
-* Rewrite of Landscape Mode support (huge readability improvement for KPW)
-* Upscale use now BILINEAR method
-* Added generic CSS file
-* Optimized archive extraction for zip/rar files (#40)
-
-####2.9
-* Added support for generating a plain CBZ (skipping all the EPUB/MOBI generation) (#45)
-* Prevent output file overwriting the source one: if a duplicate name is detected, append _kcc to the name
-* Rarfile library updated to 2.6
-* Added GIF, TIFF and BMP to supported formats (#42)
-* Filenames slugifications (#28, #31, #9, #8)
-
-####2.10:
-* Multiprocessing support
-* Kindle Fire support (color EPUB/MOBI)
-* Panel View support for horizontal content
-* Fixed panel order for horizontal pages when --rotate is enabled
-* Disabled cropping and page number cutting for blank pages
-* Fixed some slugify issues with specific file naming conventions (#50, #51)
-
-####3.0:
-* New QT GUI
-* Merge with AWKCC
-* Added ultra quality mode
-* Added support for custom width/height
-* Added option to disable color conversion
-
-####3.1:
-* Added profile: Kindle for Android
-* Add file/directory dialogs now support multiselect
-* Many small fixes and tweaks
-
-####3.2:
-* Too big EPUB files are now splitted before conversion to MOBI
-* Added experimental parser of manga webtoons
-* Improved error handling
-
-####3.2.1:
-* Hotfixed crash occurring on OS with Russian locale
+####3.4:
+* Improved PNG output
+* Increased quality of upscaling
+* Added support of file association - KCC can now open CBZ, CBR, CB7, ZIP, RAR, 7Z and PDF files directly
+* Paths that contain UTF-8 characters are now supported
+* Migrated to new version of Pillow library
+* Merged DX and DXG profiles
+* Many other minor bug fixes and GUI tweaks
####3.3:
* Margins are now automatically omitted in Panel View mode
@@ -281,112 +282,117 @@ The app relies and includes the following scripts:
* Windows release is now bundled with UnRAR and 7za
* Small GUI tweaks
-####3.4:
-* Improved PNG output
-* Increased quality of upscaling
-* Added support of file association - KCC can now open CBZ, CBR, CB7, ZIP, RAR, 7Z and PDF files directly
-* Paths that contain UTF-8 characters are now supported
-* Migrated to new version of Pillow library
-* Merged DX and DXG profiles
-* Many other minor bug fixes and GUI tweaks
+####3.2:
+* Too big EPUB files are now splitted before conversion to MOBI
+* Added experimental parser of manga webtoons
+* Improved error handling
-####3.5:
-* Added simple content server - Converted files can be now delivered wireless
-* Added proper Windows installer
-* Improved multiprocessing speed
-* GUI tweaks and minor bug fixes
+####3.2.1:
+* Hotfixed crash occurring on OS with Russian locale
-####3.6:
-* Increased quality of Panel View zoom
-* Creation of multipart MOBI output is now faster on machines with 4GB+ RAM
-* Automatic gamma correction now distinguishes color and grayscale images
-* Added ComicRack metadata parser
-* Implemented new method to detect border color in non-webtoon comics
-* Upscaling is now enabled by default for Kindle Fire HD/HDX
-* Windows nad Linux releases now have tray icon
-* Fixed Kindle Fire HDX 7" output
-* Increased target resolution for Kindle DX/DXG CBZ output
+####3.1:
+* Added profile: Kindle for Android
+* Add file/directory dialogs now support multiselect
+* Many small fixes and tweaks
-####3.6.1:
-* Fixed PNG output
+####3.0:
+* New QT GUI
+* Merge with AWKCC
+* Added ultra quality mode
+* Added support for custom width/height
+* Added option to disable color conversion
-####3.6.2:
-* Fixed previous PNG output fix
-* Fixed Panel View anomalies
+####2.10:
+* Multiprocessing support
+* Kindle Fire support (color EPUB/MOBI)
+* Panel View support for horizontal content
+* Fixed panel order for horizontal pages when --rotate is enabled
+* Disabled cropping and page number cutting for blank pages
+* Fixed some slugify issues with specific file naming conventions (#50, #51)
-####3.7:
-* Added profiles for KOBO devices
-* Improved Panel View support
-* Improved WebToon splitter
-* Improved margin color autodetection
-* Tweaked EPUB output
-* Fixed stretching option
-* GUI tweaks and minor bugfixes
+####2.9
+* Added support for generating a plain CBZ (skipping all the EPUB/MOBI generation) (#45)
+* Prevent output file overwriting the source one: if a duplicate name is detected, append _kcc to the name
+* Rarfile library updated to 2.6
+* Added GIF, TIFF and BMP to supported formats (#42)
+* Filenames slugifications (#28, #31, #9, #8)
-####3.7.1:
-* Hotfixed Kobo profiles
+####2.8
+* Updated rarfile library
+* Panel View support + HQ support (#36) - new option: --nopanelviewhq
+* Split profiles for K4NT and K4T
+* Rewrite of Landscape Mode support (huge readability improvement for KPW)
+* Upscale use now BILINEAR method
+* Added generic CSS file
+* Optimized archive extraction for zip/rar files (#40)
-####3.7.2:
-* Fixed problems with HQ mode
+####2.7
+* Lots of GUI improvements (#27, #13)
+* Added gamma support within --gamma option (defaults to profile-specified gamma) (#26, #27)
+* Added --nodithering option to prevent dithering optimizations (#27)
+* EPUB margins support (#30)
+* Fixed no file added if file has no spaces on Windows (#25)
+* Gracefully exit if unrar missing (#15)
+* Do not call kindlegen if source EPUB is bigger than 320MB (#17)
+* Get filetype from magic number (#14)
+* PDF conversion works again
-####4.0:
-* KCC now use Python 3.3 and Qt 5.2
-* Full UTF-8 awareness
-* CBZ output now support Manga mode
-* Improved Panel View support and margin color detection
-* Added drag&drop support
-* Output directory can be now selected
-* Windows release now have auto-updater
-* Names of chapters on Kindle should be now more user friendly
-* Fixed OSX file association support
-* Many extensive internal changes and tweaks
+####2.6
+* Added --rotate option to rotate landscape images instead of splitting them (#16, #24)
+* Added --output option to customize EPUB output dir/file (#22)
+* Add rendition:layout and rendition:orientation EPUB meta tags (supported by new kindlegen 2.8)
+* Fixed natural sorting for files (#18)
-####4.0.1:
-* Fixed file lock problems that plagued some Windows users
-* Fixed content server failing to start on Windows
-* Improved performance of WebToon splitter
-* Tweaked margin color detection
+####2.5
+* Added --black-borders option to set added borders black when page's ratio is not the device's one (#11).
+* Fixes EPUB containing zipped itself (#10)
-####4.0.2:
-* Fixed some Windows and OSX specific bugs
-* Fixed problem with marigns when using HQ mode
+####2.4
+* Use temporary directory as workdir (fixes converting from external volumes and zipfiles renaming)
+* Fixed "add folders" from GUI.
-####4.1:
-* Thanks to code contributed by Kevin Hendricks speed of MOBI creation was greatly increased
-* Improved performance on Windows
-* Improved MOBI splitting and changed maximal size of output file
-* Fixed _No optimization_ mode
-* Multiple small tweaks nad minor bug fixes
+####2.3
+* Fixed win32 EPUB generation, folder handling, filenames with spaces and subfolders
-####4.2:
-* Added [Manga Cover Database](http://manga.joentjuh.nl/) support
-* Officially dropped Windows XP support
-* Fixed _Other_ profile
-* Fixed problems with page order on stock KOBO CBZ reader
-* Many other small bug fixes and tweaks
+####2.2:
+* Added (valid!) EPUB 2.0 output
+* Rename .zip files to .cbz to avoid overwriting
-####4.2.1:
-* Improved margin color detection
-* Fixed random crashes of MOBI processing step
-* Fixed resizing problems in high quality mode
-* Fixed some MCD support bugs
-* Default output format for Kindle DX is now CBZ
+####2.1
+* Added basic error reporting
-####4.3:
-* Added profiles for Kindle Voyage and Kobo Aura H2O
-* Added missing features to CLI version
-* Other minor bug fixes
+####2.0
+* GUI! AppleScript is gone and Tk is used to provide cross-platform GUI support.
-####4.3.1:
-* Fixed Kindle Voyage profile
-* Fixed some bugs in OS X release
-* CLI version now support multiple input files at once
-* Disabled MCB support
-* Other minor tweaks
+####1.5
+* Added subfolder support for multiple chapters.
+
+####1.4.1
+* Fixed a serious bug on resizing when img ratio was bigger than device one
+
+####1.4
+* Added some options for controlling image optimization
+* Further optimization (ImageOps, page numbering cut, autocontrast)
+
+####1.3
+* Fixed an issue in OPF generation for device resolution
+* Reworked options system (call with -h option to get the inline help)
+
+####1.2
+* Comic optimizations! Split pages not target-oriented (landscape with portrait target or portrait with landscape target), add palette and other image optimizations from Mangle. WARNING: PIL is required for all image mangling!
+
+####1.1.1
+* Added support for CBZ/CBR files in Kindle Comic Converter
+
+####1.1
+* Added support for CBZ/CBR files in comic2ebook.py
+
+####1.0
+* Initial version
## KNOWN ISSUES
Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues).
## COPYRIGHT
-Copyright (c) 2012-2014 Ciro Mattia Gonano and Paweł Jastrzębski.
+Copyright (c) 2012-2015 Ciro Mattia Gonano and Paweł Jastrzębski.
**KCC** is released under ISC LICENSE; see LICENSE.txt for further details.
diff --git a/kcc-c2e.py b/kcc-c2e.py
index 5bc3680..cbc5f20 100755
--- a/kcc-c2e.py
+++ b/kcc-c2e.py
@@ -18,7 +18,7 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-__version__ = '4.3.1'
+__version__ = '4.4'
__license__ = 'ISC'
__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
diff --git a/kcc-c2p.py b/kcc-c2p.py
index 53216a4..674e67f 100755
--- a/kcc-c2p.py
+++ b/kcc-c2p.py
@@ -18,7 +18,7 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-__version__ = '4.3.1'
+__version__ = '4.4'
__license__ = 'ISC'
__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
diff --git a/kcc.iss b/kcc.iss
index f05ab56..8c6b275 100644
--- a/kcc.iss
+++ b/kcc.iss
@@ -1,5 +1,5 @@
#define MyAppName "Kindle Comic Converter"
-#define MyAppVersion "4.3.1"
+#define MyAppVersion "4.4"
#define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski"
#define MyAppURL "http://kcc.iosphe.re/"
#define MyAppExeName "KCC.exe"
diff --git a/kcc.py b/kcc.py
index 119cd13..edd3151 100755
--- a/kcc.py
+++ b/kcc.py
@@ -18,7 +18,7 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-__version__ = '4.3.1'
+__version__ = '4.4'
__license__ = 'ISC'
__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py
index 74dc7f6..ddf1e6c 100644
--- a/kcc/KCC_gui.py
+++ b/kcc/KCC_gui.py
@@ -17,7 +17,7 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-__version__ = '4.3.1'
+__version__ = '4.4'
__license__ = 'ISC'
__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
diff --git a/kcc/__init__.py b/kcc/__init__.py
index 72fa985..7b32d0a 100644
--- a/kcc/__init__.py
+++ b/kcc/__init__.py
@@ -1,4 +1,4 @@
-__version__ = '4.3.1'
+__version__ = '4.4'
__license__ = 'ISC'
__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
\ No newline at end of file
diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py
index 2a9aade..8cb2edd 100755
--- a/kcc/comic2ebook.py
+++ b/kcc/comic2ebook.py
@@ -18,7 +18,7 @@
# PERFORMANCE OF THIS SOFTWARE.
#
-__version__ = '4.3.1'
+__version__ = '4.4'
__license__ = 'ISC'
__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py
index 16a88be..a9462ca 100644
--- a/kcc/comic2panel.py
+++ b/kcc/comic2panel.py
@@ -18,7 +18,7 @@
# PERFORMANCE OF THIS SOFTWARE.
#
-__version__ = '4.3.1'
+__version__ = '4.4'
__license__ = 'ISC'
__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
diff --git a/kcc/image.py b/kcc/image.py
index f8cc4af..228bbae 100755
--- a/kcc/image.py
+++ b/kcc/image.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-__version__ = '4.3.1'
+__version__ = '4.4'
__license__ = 'ISC'
__copyright__ = '2012-2015, Ciro Mattia Gonano , Pawel Jastrzebski '
__docformat__ = 'restructuredtext en'
diff --git a/setup.py b/setup.py
index 99bd3f5..a75f07f 100755
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,7 @@ if version_info[0] != 3:
exit(1)
NAME = "KindleComicConverter"
-VERSION = "4.3.1"
+VERSION = "4.4"
MAIN = "kcc.py"
if platform == "darwin":
diff --git a/setup.sh b/setup.sh
index 20708fa..01ea98f 100755
--- a/setup.sh
+++ b/setup.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# Linux Python package build script
-VERSION="4.3.1"
+VERSION="4.4"
cp kcc.py __main__.py
zip kcc.zip __main__.py kcc/*.py
From bfba66d47dbb766f34035fac063223376ce23df4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?=
Date: Sun, 4 Jan 2015 14:23:03 +0100
Subject: [PATCH 12/12] Improved KindleGen detection
---
kcc/KCC_gui.py | 75 ++++++++++++++++++++++++++++++--------------------
1 file changed, 45 insertions(+), 30 deletions(-)
diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py
index ddf1e6c..2a3780e 100644
--- a/kcc/KCC_gui.py
+++ b/kcc/KCC_gui.py
@@ -931,15 +931,19 @@ class KCCGUI(KCC_ui.Ui_KCC):
self.addMessage('Target resolution is not set!', 'error')
self.needClean = True
return
- if str(GUI.FormatBox.currentText()) == 'MOBI' and not GUI.KindleGen:
- self.addMessage('Cannot find '
- 'KindleGen! MOBI conversion is not possible!', 'error')
- if sys.platform.startswith('win'):
- self.addMessage('Download it and place EXE in KCC directory.', 'error')
- else:
- self.addMessage('Download it, and place executable in /usr/local/bin directory.', 'error')
- self.needClean = True
- return
+ if str(GUI.FormatBox.currentText()) == 'MOBI' and not self.KindleGen:
+ self.detectKindleGen()
+ if not self.KindleGen:
+ GUI.JobList.clear()
+ self.addMessage('Cannot find KindleGen!'
+ ' MOBI conversion is unavailable!', 'error')
+ if sys.platform.startswith('win'):
+ self.addMessage('Download it and place EXE in KCC directory.', 'error')
+ else:
+ self.addMessage('Download it and place executable in /usr/local/bin directory.', 'error')
+ self.needClean = True
+ return
self.worker.start()
def hideProgressBar(self):
@@ -1027,6 +1031,36 @@ class KCCGUI(KCC_ui.Ui_KCC):
self.saveSettings(None)
sys.exit(0)
+ def detectKindleGen(self, startup=False):
+ if not sys.platform.startswith('win'):
+ try:
+ os.chmod('/usr/local/bin/kindlegen', 0o755)
+ except Exception:
+ pass
+ kindleGenExitCode = Popen('kindlegen -locale en', stdout=PIPE, stderr=STDOUT, shell=True)
+ if kindleGenExitCode.wait() == 0:
+ self.KindleGen = True
+ versionCheck = Popen('kindlegen -locale en', stdout=PIPE, stderr=STDOUT, shell=True)
+ for line in versionCheck.stdout:
+ line = line.decode("utf-8")
+ if 'Amazon kindlegen' in line:
+ versionCheck = line.split('V')[1].split(' ')[0]
+ if tuple(map(int, (versionCheck.split(".")))) < tuple(map(int, ('2.9'.split(".")))):
+ self.addMessage('Your KindleGen is outdated! Creating MOBI might fail.'
+ ' Please update KindleGen from Amazon\'s website.', 'warning')
+ break
+ else:
+ self.KindleGen = False
+ if startup:
+ self.addMessage('Cannot find '
+ 'KindleGen! MOBI conversion will be unavailable!', 'error')
+ if sys.platform.startswith('win'):
+ self.addMessage('Download it and place EXE in KCC directory.', 'error')
+ else:
+ self.addMessage('Download it and place executable in /usr/local/bin directory.', 'error')
+
# noinspection PyArgumentList
def __init__(self, KCCAplication, KCCWindow):
global APP, MW, GUI
@@ -1057,6 +1091,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
self.tray = SystemTrayIcon()
self.conversionAlive = False
self.needClean = True
+ self.KindleGen = False
self.GammaValue = 1.0
self.completedWork = {}
self.targetDirectory = ''
@@ -1158,27 +1193,6 @@ class KCCGUI(KCC_ui.Ui_KCC):
self.addMessage('Since you are new user of KCC please see few '
'important tips.',
'info')
- if not sys.platform.startswith('win'):
- try:
- os.chmod('/usr/local/bin/kindlegen', 0o755)
- except Exception:
- pass
- kindleGenExitCode = Popen('kindlegen -locale en', stdout=PIPE, stderr=STDOUT, shell=True)
- if kindleGenExitCode.wait() == 0:
- self.KindleGen = True
- versionCheck = Popen('kindlegen -locale en', stdout=PIPE, stderr=STDOUT, shell=True)
- for line in versionCheck.stdout:
- line = line.decode("utf-8")
- if 'Amazon kindlegen' in line:
- versionCheck = line.split('V')[1].split(' ')[0]
- if tuple(map(int, (versionCheck.split(".")))) < tuple(map(int, ('2.9'.split(".")))):
- self.addMessage('Your kindlegen is outdated! Creating MOBI might fail.'
- ' Please update kindlegen from Amazon\'s website.', 'warning')
- break
- else:
- self.KindleGen = False
rarExitCode = Popen('unrar', stdout=PIPE, stderr=STDOUT, shell=True)
rarExitCode = rarExitCode.wait()
if rarExitCode == 0 or rarExitCode == 7:
@@ -1195,6 +1209,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
self.sevenza = False
self.addMessage('Cannot find 7za!'
' Processing of CB7/7Z files will be disabled.', 'warning')
+ self.detectKindleGen(True)
APP.messageFromOtherInstance.connect(self.handleMessage)
GUI.BasicModeButton.clicked.connect(self.modeBasic)