From 4a473e37167f74a82fc8f7dd36b3c5b0babbd7c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Fri, 20 Dec 2013 09:22:15 +0100 Subject: [PATCH 01/27] Changed output extension --- kcc/KCC_gui.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 974976b..344c194 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -109,6 +109,9 @@ class WebServerHandler(BaseHTTPRequestHandler): if self.path.endswith('.mobi'): mimetype = 'application/x-mobipocket-ebook' sendReply = True + if self.path.endswith('.azw3'): + mimetype = 'application/x-mobipocket-ebook' + sendReply = True if self.path.endswith('.epub'): mimetype = 'application/epub+zip' sendReply = True @@ -491,10 +494,11 @@ class WorkerThread(QtCore.QThread): GUI.progress.content = '' mobiPath = item.replace('.epub', '.mobi') os.remove(mobiPath + '_toclean') - GUI.completedWork[os.path.basename(mobiPath).encode('utf-8')] = \ - mobiPath.encode('utf-8') - self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI files... Done!', 'info', - True) + if profile in ['K345', 'KHD', 'KF', 'KFHD', 'KFHD8', 'KFHDX', 'KFHDX8', 'KFA']: + move(mobiPath, mobiPath.replace('.mobi', '.azw3')) + mobiPath = item.replace('.mobi', '.azw3') + GUI.completedWork[os.path.basename(mobiPath).encode('utf-8')] = mobiPath.encode('utf-8') + self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI files... Done!', 'info', True) else: GUI.progress.content = '' for item in outputPath: From 8f10e93c083dc4dcb50a598b671fa0d2e231a016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Tue, 24 Dec 2013 13:47:06 +0100 Subject: [PATCH 02/27] Fixed KindleGen error handling --- kcc/KCC_gui.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 344c194..173155b 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -498,7 +498,8 @@ class WorkerThread(QtCore.QThread): move(mobiPath, mobiPath.replace('.mobi', '.azw3')) mobiPath = item.replace('.mobi', '.azw3') GUI.completedWork[os.path.basename(mobiPath).encode('utf-8')] = mobiPath.encode('utf-8') - self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI files... Done!', 'info', True) + self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI files... Done!', 'info', + True) else: GUI.progress.content = '' for item in outputPath: @@ -522,7 +523,7 @@ class WorkerThread(QtCore.QThread): self.emit(QtCore.SIGNAL("addTrayMessage"), 'KindleGen failed to create MOBI!', 'Critical') if self.kindlegenErrorCode[0] == 1 and self.kindlegenErrorCode[1] != '': self.emit(QtCore.SIGNAL("showDialog"), "KindleGen error:\n\n" + - self.self.kindlegenErrorCode[1]) + self.kindlegenErrorCode[1]) if self.kindlegenErrorCode[0] == 23026: self.emit(QtCore.SIGNAL("addMessage"), 'Created EPUB file was too big.', 'error') From c0f788bd674a9be994f7ad80fc5dd5196f9f2ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Fri, 27 Dec 2013 09:51:15 +0100 Subject: [PATCH 03/27] Added preliminary support for Kobo devices --- KCC.qrc | 1 + README.md | 2 +- icons/Kobo.png | Bin 0 -> 2388 bytes kcc/KCC_gui.py | 25 +++++-- kcc/KCC_rc.py | 173 ++++++++++++++++++++++++++++++++++++++++++--- kcc/comic2ebook.py | 7 +- kcc/image.py | 19 ++++- 7 files changed, 208 insertions(+), 19 deletions(-) create mode 100644 icons/Kobo.png diff --git a/KCC.qrc b/KCC.qrc index fd00909..6795573 100644 --- a/KCC.qrc +++ b/KCC.qrc @@ -3,6 +3,7 @@ icons/comic2ebook.png + icons/Kobo.png icons/Other.png icons/Kindle.png diff --git a/README.md b/README.md index fcf64e5..a815636 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Usage: comic2ebook.py [options] comic_file|comic_folder Options: MAIN: -p PROFILE, --profile=PROFILE - Device profile (Choose one among K1, K2, K345, KDX, KHD, KF, KFHD, KFHD8, KFHDX, KFHDX8, KFA) [Default=KHD] + Device profile (Choose one among K1, K2, K345, KDX, KHD, KF, KFHD, KFHD8, KFHDX, KFHDX8, KFA, KoMT, KoG, KoA, KoAHD) [Default=KHD] -q QUALITY, --quality=QUALITY Quality of Panel View. 0 - Normal 1 - High 2 - Ultra [Default=0] -m, --manga-style Manga style (Right-to-left reading and splitting) diff --git a/icons/Kobo.png b/icons/Kobo.png new file mode 100644 index 0000000000000000000000000000000000000000..c563dfe31c3f8045a3c60d2be4c2a1df6cec3dd1 GIT binary patch literal 2388 zcmV-a39I&rP)CGsZddp${$TFsA*Ih|FDvvso*3KizpoB$8juN;oyF8ce^w5`bY0@Z`qmK<8F87 z$Ma1#d$+f@Gy6QB_j#W8$IJ^Nkw_#Gi9{liNF)-8L?V$W`cgqSiA*Nb0jvT#f%!4A z|8?Lz@K?*Sj>iswOeV7o_#yB)z=(NcJOq5hvaAEuJZPeZ&R+xk3Aj5bk*LP%0KSq= zr*qkC_F$v|$Ye4P0KW(7#qT#oy_uECP5rzEo;(T~{CoI{>9xzgIC>m;xrcidt)2*A)ngWJJyRrCyu( zKf^F?j2nnT5&@>`e7}NFx{DzLpxF7h(sFMUgRX-z5;ATO767Jl{&ZkaN}cihJK-J8KMAM-5w+}t4f{xbqVn3OOSFK%8$dz0zw{O9)da`5=j)OAFDi2SwF0zeq# zxbW2K+vsRXdM+iaGZp*Z?B~F-Va&4DlPR=)9ebc#00_FCUfarj%Nl&&^Sgfxu=DjR z)9&lLxq-l^gV+L)vo#wZY~d3hY`|*)Qo>LiI(eO+@4xI@7=}3=#1eqKqxo!R9$&n- z$usO53c9jmJoEC!nUz#Bb4Y-qx(&ex9pC4sp1bRP0iK zpY!YM6i>f=iK|04ak-IL>;Uj{>{wp2-F5AZw!9OU^wzT-Q%bMFV{^1X-J zeW!&5fRJiVQt_L=_4C@H0nbatbGGJzyBm4rlg&iAB#7-$aGj}mVgF^`_}7r zWM0ZB{dx5U3!6<|`r2ZWWvm$t;`~zN7K9`dnkQaKGSYVn?c{DUyP2ST2oxMUH_AOv zo}BW1jrHM-0+C!1l&VjXO240c-wCukvpaMv1@ltT&6E+Y0TjvRC8&hl5;nd?pfX6# zzY}H1Rq&wzpl~FxJ~>MzlVOrPX|VA)4}SMZBhi51AtPB zI$x$>6e(#cRWOn zWs5Y+DoW-81OSl$AQAvX0)R*W5D5Sx0ic4CVY`6YtJ(kz0=D?IY+Z{K0G4IBz&Y`2 zS#qjjt6J0m`^C3q>F<_h^+yqa9piM1{Ixxjy#ULyj#cZ+g;;+9UX5}$@aw?q;^&e& z4y>~*t13OFL@mByHk)GUf=1F)i2=Mlgz-(KMJmStV7)' 'List of supported Non-Kindle devices', 'info') self.modeExpert() - elif value == 8: + # KFA + elif value == 17: GUI.BasicModeButton.setEnabled(False) GUI.AdvModeButton.setEnabled(False) self.modeExpert(True) @@ -792,26 +796,35 @@ class KCCGUI(KCC_ui.Ui_KCC): GUI.BasicModeButton.setEnabled(True) GUI.AdvModeButton.setEnabled(True) self.modeBasic() - if value in [9, 11, 12, 13]: + # Other, K1, K2, DX/DXG, KoMT, KoG, KoA, KoAHD + if value in [15, 18, 19, 2, 10, 11, 12, 13]: GUI.QualityBox.setChecked(False) GUI.QualityBox.setEnabled(False) self.QualityBoxDisabled = True - if value in [4, 5, 6, 7]: + # KoMT, KoG, KoA, KoAHD + if value in [10, 11, 12, 13]: + GUI.FormatBox.setCurrentIndex(2) + # K. Fire + if value in [5, 6, 7, 8]: if GUI.UpscaleBox.isEnabled(): GUI.UpscaleBox.setChecked(True) else: + # Other, K1, K2, DX/DXG if not GUI.WebtoonBox.isChecked() and not GUI.ProcessingBox.isChecked() \ - and str(GUI.FormatBox.currentText()) != 'CBZ' and value not in [9, 11, 12, 13]: + and str(GUI.FormatBox.currentText()) != 'CBZ' and value not in [15, 18, 19, 2]: GUI.QualityBox.setEnabled(True) self.QualityBoxDisabled = False def changeFormat(self): if str(GUI.FormatBox.currentText()) == 'CBZ': + GUI.MangaBox.setChecked(False) + GUI.MangaBox.setEnabled(False) GUI.QualityBox.setChecked(False) GUI.QualityBox.setEnabled(False) else: if not GUI.WebtoonBox.isChecked() and not GUI.ProcessingBox.isChecked() and not self.QualityBoxDisabled: GUI.QualityBox.setEnabled(True) + GUI.MangaBox.setEnabled(True) def stripTags(self, html): s = HTMLStripper() @@ -1081,6 +1094,8 @@ class KCCGUI(KCC_ui.Ui_KCC): GUI.DeviceBox.addItem(self.icons.deviceOther, profile) elif profile == "Separator": GUI.DeviceBox.insertSeparator(GUI.DeviceBox.count()+1) + elif 'Ko' in profile: + GUI.DeviceBox.addItem(self.icons.deviceKobo, profile) else: GUI.DeviceBox.addItem(self.icons.deviceKindle, profile) if self.lastDevice > GUI.DeviceBox.count(): diff --git a/kcc/KCC_rc.py b/kcc/KCC_rc.py index 844ad65..0bb209e 100644 --- a/kcc/KCC_rc.py +++ b/kcc/KCC_rc.py @@ -2,7 +2,7 @@ # Resource object code # -# Created: N 6. paź 13:26:15 2013 +# Created: Pt 27. gru 09:24:15 2013 # by: The Resource Compiler for PyQt (Qt v4.8.5) # # WARNING! All changes made in this file will be lost! @@ -8358,6 +8358,158 @@ qt_resource_data = "\ \x5f\x00\xdc\x06\xf0\x91\x73\xee\x3b\x8e\x03\x82\x20\x08\x82\x20\ \x08\x82\x20\x08\x82\x20\x08\x62\x23\xf8\x1f\x8e\x96\x1e\x7d\x49\ \xfc\xce\x76\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x09\x54\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x80\x00\x00\x00\x80\x08\x06\x00\x00\x00\xc3\x3e\x61\xcb\ +\x00\x00\x09\x1b\x49\x44\x41\x54\x78\xda\xed\x9d\x7f\x8c\x14\x67\ +\x19\xc7\x3f\xef\xec\xec\x71\xcb\x1d\x72\x77\xd8\xbb\x63\x0f\x7a\ +\xb6\x0d\x28\x98\x6a\xea\x4a\x8c\xa5\x35\xa9\x56\x62\xa2\x89\x11\ +\x88\xd4\xc6\x98\x02\x96\x06\x42\x4d\xda\x44\x8b\xda\x54\x8d\x36\ +\xd5\xc4\x68\x62\xa9\x50\x51\x92\xca\x1f\x4d\x2d\xa8\x69\x54\x1a\ +\xff\xb0\x92\xa0\xa9\xe0\x24\x10\x8b\x28\x1c\xe5\xc7\x71\x2c\x5c\ +\xe1\xe0\x7e\x71\x77\xbb\x33\xf3\xfa\x47\xef\x70\x6f\xd9\x99\xdb\ +\xe3\x6e\x77\xe7\xc7\xf3\x4d\x36\x7b\xb7\xb7\xb7\x33\xfb\x3c\x9f\ +\xf7\x79\x9e\xf7\xc7\xcc\x0b\x22\x91\x48\x24\x12\x89\x44\x22\x91\ +\x48\x24\x12\x89\x44\x22\x91\x28\xfa\x52\x41\x38\x89\x4c\x26\xd3\ +\x01\xac\x02\x3a\x81\xf9\x31\xb2\xff\x75\xe0\x3c\xf0\x57\xcb\xb2\ +\x8e\xc7\x0e\x80\x4c\x26\xb3\x0c\xf8\x21\xf0\x39\xc0\x88\x79\x63\ +\x3c\x04\x7c\xc3\xb2\xac\x03\xd5\x3c\x68\xa2\x86\xce\x5f\x03\xfc\ +\x09\xb8\x3b\x28\x91\xa8\xc6\xea\x00\xbe\x92\x4e\xa7\x73\xd9\x6c\ +\xf6\x60\xa4\x01\xc8\x64\x32\x0f\x00\xbf\x07\xea\xc5\xef\x37\x45\ +\xe4\x07\xd3\xe9\xf4\xe5\x6c\x36\x7b\x38\x92\x29\x20\x93\xc9\xa4\ +\x80\x13\xc0\x22\xf1\xb7\xa7\xc6\x80\xe5\x96\x65\xbd\x5d\xe9\x03\ +\xd5\x22\xef\x3e\x2a\xce\x9f\x52\x73\x80\x6f\x56\xe3\x40\xb5\x00\ +\x60\xad\xf8\xb7\x2c\x7d\x21\x93\xc9\x24\xa2\x08\xc0\x3d\xe2\xdb\ +\xb2\xb4\x60\xbc\x5b\x1c\x1d\x00\x32\x99\x4c\x03\xd0\x28\xbe\x2d\ +\x5b\x6d\x51\x8b\x00\x49\xf1\x69\xb0\xec\x65\x88\x8d\xe3\x2d\x33\ +\x48\x27\x93\x4a\xa5\xe8\xec\x2c\x2f\xed\x29\xf5\x6e\x0f\xd6\x30\ +\x0c\x94\x52\x68\xad\x27\x3d\x82\xae\x91\x91\x11\xce\x9e\x3d\x2b\ +\x00\x14\x6a\xc9\x92\x25\xec\xdc\xb9\x33\x16\x2d\xef\xe8\xd1\xa3\ +\x6c\xde\xbc\x59\x00\x98\x89\x26\xa2\x40\xb1\xc2\x10\x01\x24\x05\ +\xcc\x82\xe3\x0b\x01\x98\x48\x03\x85\x3f\x0b\x08\x11\x04\x40\x29\ +\x35\x09\x80\x62\x08\x0a\x23\x80\x80\x10\x31\x00\x26\x1c\x5e\x0c\ +\x81\xd7\x7b\x0b\x1d\x2f\x10\x44\x2c\x02\x78\x39\xbe\x54\x6a\x70\ +\x5d\x57\x20\x08\x3b\x00\xa5\x5a\xbf\x57\x31\x58\x98\x02\x26\xba\ +\x8a\x5a\x6b\x5c\xd7\x15\x08\x8a\x64\x44\xcd\xf9\xa5\x5e\x9b\xf8\ +\x3f\xc3\x30\x6e\x8c\x1b\x88\x42\x12\x01\xa6\xeb\x7c\xbf\x82\x50\ +\xba\x8b\x21\x03\xa0\xd8\xf9\xb7\xd2\x72\x6f\x14\x83\xae\x83\x32\ +\x12\x32\x6e\x10\x16\x00\xa6\x72\xfe\x74\x60\x50\x4a\xa1\xc7\x9d\ +\x3f\xf1\x59\xa5\x86\x8d\xe3\x08\x82\x19\x34\xa7\xfb\xf5\xfb\x8b\ +\x5b\xed\xb4\x21\x28\x70\xf0\x74\x41\x88\xea\xa8\x63\xa0\x00\x30\ +\x0c\xa3\xac\xae\xde\xad\x16\x71\xc5\x10\x14\x7e\x56\x21\x0c\x85\ +\xf5\xc3\x74\x8e\x15\x46\x18\x02\x1d\x01\xbc\x46\xfa\x66\x7a\x0c\ +\x2f\x08\x8a\x8b\x47\xaf\x88\x54\x1c\x49\xc2\x9c\x46\x02\x19\x01\ +\x26\x0c\xfb\xef\x1e\x87\xbd\x87\xf2\x8c\xd9\x35\x34\xaa\xc6\x7b\ +\xed\xb4\x9e\x78\xd2\x93\x5e\x9b\xf4\x3b\x30\xc7\x54\xac\x59\x61\ +\xb2\x2c\x6d\x08\x00\x7e\x2d\xb3\x30\x05\x1c\xef\x71\xf8\xea\xaf\ +\x46\x22\x53\x6c\xfd\xf9\x2d\x87\x17\xd7\xcf\x09\x1c\x04\x81\x43\ +\x72\x22\xec\xbe\x7a\x28\x1f\xb9\x8a\x7b\xdf\x61\x3b\x70\xe7\x14\ +\x18\x00\x8a\x73\x67\x4d\xc3\x7e\x85\x14\xc4\xef\x14\xa8\x08\x20\ +\x63\xf5\x31\x2f\x02\x67\x6b\xd6\xce\x9d\xe2\xdf\x0d\x99\x0a\x08\ +\x36\x00\x33\x91\xe3\xc2\x86\x95\x39\x96\xb6\xe9\x92\x8e\x3f\x91\ +\x75\xd8\x75\x30\x89\x69\xca\x0a\xf5\xc0\x01\x30\x1b\xe1\xdf\xd5\ +\x70\x7b\xb3\xcb\xf2\x76\xb7\x24\x00\xa3\xa3\x36\xb9\xbe\x33\x98\ +\xb7\x2d\x05\x65\xc6\x1e\x00\x23\x88\x00\x54\xb6\x0e\x70\x41\xbb\ +\xe4\xfa\xba\xfe\xdf\x91\x17\x00\x02\x28\x5d\x31\xca\xc6\x9f\x1d\ +\x72\x57\xfe\x0b\x6e\x5e\x00\x88\x95\x0a\xeb\x0c\xed\x90\xbb\xda\ +\x05\xda\x11\x00\x82\x17\x00\x2a\x14\x02\x8a\x7b\x00\xda\x25\xd7\ +\x77\x32\xb6\xe9\x40\xae\x0d\xbc\x91\x0e\xfe\x53\xf1\x74\xa0\x02\ +\x78\x2b\x24\x01\xa0\x30\x12\xc4\x30\x1d\x08\x00\x31\x4f\x07\x02\ +\x40\x8d\xd2\x81\x00\x10\x8a\x74\xe0\xa2\xc7\xe3\x81\xd7\x23\xec\ +\x92\xa1\x30\x0f\xe5\xf3\x0e\x1f\x6d\xee\xe6\xae\xce\x85\xe0\xb3\ +\x34\xed\xd2\x35\x9b\x83\x6f\xd7\x13\xd6\x4b\x0d\x04\x80\x52\x01\ +\x40\xc3\xa7\x3e\xd4\xc8\xf7\x1f\x6e\x63\x2c\xef\x3d\x87\xdf\xd3\ +\x67\xb3\x71\x7b\x37\x24\xe7\x61\xbe\xe7\x76\x01\x20\x2a\xce\x5f\ +\xfc\xde\x3a\xbe\xb5\xb6\x95\xa1\x51\xef\xc9\x29\x17\xd8\xfa\x8b\ +\x9e\x77\x67\x1e\x73\x83\xe4\xfb\xcf\x92\x9c\xdf\x19\xba\xef\x2b\ +\x35\x40\x91\x16\x36\x27\x79\x61\x53\x1a\xc7\x67\x62\xd2\x76\x34\ +\x1b\x7e\xd6\x3d\x09\x10\x9d\x1f\x24\x7f\xcd\xff\xc6\x9e\x1a\x59\ +\x10\x12\x68\x35\x37\x9a\x6c\xdf\x94\xc6\x4c\x78\x27\x74\x57\xc3\ +\xb6\x3d\x59\x7a\xfb\xed\xa2\xbc\xaf\xd0\xf6\x08\xf6\xc0\x39\x89\ +\x00\x61\x94\x52\xf0\x93\xf5\x0b\x49\xd5\x79\x9b\xc4\x50\xf0\xec\ +\xde\x5e\x8e\x9f\x1f\xf3\x2c\xfa\xdc\xdc\x20\xf9\xfe\x33\x02\x40\ +\x98\x94\x30\x14\x2f\x6e\x5e\x44\x7b\x93\xe9\xeb\xfc\xe7\xf6\xf5\ +\x72\xf0\xf8\xd0\xd4\x75\x44\x7e\x88\xfc\xb5\xd3\x02\x40\x18\xe4\ +\xb8\xf0\xd4\xea\xdb\xe8\x68\x49\x7a\x2e\x25\xab\x33\x15\xfb\xde\ +\xec\xe7\xc0\xb1\x61\xcc\xb2\xd6\x93\x29\xb4\x7d\x1d\x7b\xa0\x5b\ +\x00\x08\xba\x9e\x5e\xdb\xca\x7d\xcb\x1a\x7c\xdf\xf3\xbb\x7f\x0c\ +\xb0\xf3\xf5\x2b\xd3\xee\xeb\xbb\xb9\x81\xc0\xa7\x83\xd8\x02\x90\ +\xb3\x35\x1b\x1f\x6c\xe1\x13\x1f\x6c\xc0\x6b\x01\x52\xc2\x50\x1c\ +\x3a\x79\x9d\x9f\xef\xbf\xec\x5b\x18\x86\x39\x1d\xc4\x12\x80\xbc\ +\xa3\xf9\x6c\x66\x1e\x5f\xbc\xb7\xc9\x33\xec\x1b\x0a\xba\xb2\x63\ +\x3c\xf3\xf2\xc5\x99\x96\x97\x81\x4e\x07\xf1\x03\x40\xc3\xfd\xcb\ +\x1b\x79\x6a\x75\x2b\xb6\xcf\xfa\xf1\x2b\x83\x0e\x8f\xed\x38\x4f\ +\x62\x96\xd6\x90\xbb\xb9\x01\xec\xc1\xf3\x02\x40\x8d\x7d\x4f\x6b\ +\x93\xc9\xb7\xd7\xb6\x32\x96\xf7\x76\xbe\xd6\xb0\x75\x57\x0f\x49\ +\x33\xfa\x17\x10\xc4\x6a\x28\x58\x6b\xe8\x58\x90\xc4\x6f\xd1\x71\ +\xde\xd6\xac\xdf\x7e\x9e\xab\x43\x0e\x71\xb8\x97\x54\xec\x52\x80\ +\x9f\xf3\xeb\xeb\x14\x4f\xbf\x7c\x89\xab\x43\x36\x71\xb9\x91\x58\ +\xec\x00\xf0\x73\xec\x58\x5e\xb3\xe5\x33\x2d\xbe\xb5\x81\x00\x10\ +\x72\xe7\x5f\xee\xb7\x71\x3c\x1c\xac\x35\xdc\xd1\x5a\xc7\x8e\xc7\ +\x16\x49\x04\x88\x24\x00\x40\xf7\xe5\x3c\x3f\x7d\xed\x1d\xea\x3d\ +\xc6\xfc\x5d\x0d\x77\xb6\xd5\xf1\xdd\x75\xed\x8c\xe4\x5c\x01\xa0\ +\x76\xce\x52\x15\xa3\xe0\x0f\xff\x1c\xe4\xf9\x3f\xbe\xe3\x3b\xb8\ +\x73\xef\x07\xe6\xf2\xbd\x87\xda\x7d\xa7\x85\x05\x80\x90\x6a\x4e\ +\x52\xf1\x9b\xbf\xf5\xf3\xda\xa1\x01\xcf\x4b\xc5\x73\xb6\xe6\x81\ +\xbb\x1b\x79\xe4\x93\xcd\x44\xb9\x24\x88\xed\x50\x70\x9d\xa9\x78\ +\x61\xff\x65\xde\xf8\xd7\x90\xe7\x60\x8f\xed\x68\xbe\x74\x7f\x13\ +\x0f\xdd\xd7\xe4\x59\x37\x08\x00\x95\x4c\xd8\x55\xd0\x0f\xf6\xf6\ +\xf2\xc6\x5b\x43\x9e\x45\x9f\xd6\xb0\xe9\xd3\x2d\xac\xfd\x78\x13\ +\x51\xbc\x79\x49\xa0\x00\x98\x6a\x13\x88\x4a\x45\x82\x1f\xfd\xb6\ +\x97\x33\xbd\x39\xcf\x74\x30\x66\x6b\x1e\x5d\xd5\xc2\x47\xee\x4a\ +\xe1\xba\x02\x40\xc5\x54\xcb\xfb\x03\x3d\xbe\xeb\x02\xa7\x7b\x73\ +\x3e\xe7\x06\xcf\x3e\xdc\xce\xc7\x96\xce\x15\x00\x2a\x1d\x01\x6a\ +\x21\xc7\xd5\x3c\xb9\x3b\xcb\x85\x3e\xef\x2b\x82\x34\xf0\xcc\xba\ +\x56\x96\x2f\xae\x8f\x4c\x3a\x90\x08\x50\xa0\xd1\xbc\xcb\x13\xbb\ +\x2f\x70\x7d\xcc\xf5\x2c\x41\x0c\xa5\x78\xee\xcb\xed\xb4\x35\x99\ +\x91\x80\x20\x90\x45\x60\x2d\x41\x18\x1c\x71\x59\xff\x7c\x37\xc3\ +\x63\xde\xc9\xde\x4c\x28\x76\x6d\x59\x44\x5b\x93\x29\x00\x54\x8e\ +\x82\x5a\xa5\x21\x18\x1a\x75\xd9\xb6\x27\xeb\xdb\xc2\xcd\x84\xe2\ +\xc7\x8f\xa4\x69\x98\x63\x84\xfa\x1a\x41\x59\x15\xec\xa1\xae\x8b\ +\x39\xb6\xee\xea\xf1\xed\xff\x2f\x98\x97\x60\xf7\xe3\x8b\x99\x5b\ +\x67\x08\x00\xb3\x1f\x00\x6e\xb5\x5d\x29\x52\x49\x97\xc6\x7a\xe3\ +\xe6\x47\x2a\xe1\xbb\xee\xbf\x78\x18\xe2\xf4\xa5\x1c\xdb\xf6\x5c\ +\x64\x5e\xca\x28\xfd\x79\xf5\x06\x0b\x9b\x4d\x5e\xfa\xda\x62\x92\ +\x65\xac\x19\x0c\xe2\xfc\x52\xe4\x16\x84\x24\x13\x9a\x27\x5e\x49\ +\x32\xd2\x77\x0a\xed\xe4\x6e\x32\xbb\x99\xa0\x7c\x08\x14\x1c\x3b\ +\x37\xca\x3d\x4f\x9e\x9c\xf2\x7d\x8d\xf5\xe1\x8c\x02\x91\x5c\x11\ +\x94\xaa\x4f\x92\x4a\xbf\x9f\x7c\xdf\x09\xb4\x3b\xb3\x3b\x74\x2b\ +\x05\xf3\x52\xd1\xcd\x94\x11\xae\x01\x14\xc9\xe6\x25\xa8\x84\xdc\ +\x12\x36\xbe\x45\xa0\x32\x48\xce\xbf\x13\x65\xc8\x55\xf0\xa1\x00\ +\xa0\x70\x24\xb0\x3e\x39\x4b\x25\x93\x61\x92\x6c\x59\x1a\x08\x08\ +\x82\xb8\xca\x38\xb0\x00\xac\x59\x31\x9b\x0e\x1b\x4f\x07\x46\x6d\ +\xd3\xc1\xea\x95\x6d\x52\x04\x96\x03\x80\x52\x8a\xe5\x1d\x26\xbf\ +\xdc\x68\xb0\xf7\x70\x9e\xb1\xd9\xda\x69\xc5\x5d\x8a\x3d\x7c\xb1\ +\x3a\x5f\xa6\x60\x14\x29\x69\x2a\x56\xaf\x6c\xe3\xc3\x77\x34\x04\ +\x6e\x43\x8c\x40\x6f\x1b\xb7\xac\x23\xc1\x77\x16\x27\x3d\xff\x7e\ +\x6b\x9a\x3f\x73\xc7\x4e\x75\x1e\x5a\xa3\xb5\x03\x2a\x31\x69\x63\ +\x4a\x37\x80\x73\xc9\x32\x12\x78\x2b\xfd\x42\x5f\xdf\x6b\xb4\x76\ +\x27\x45\x80\xe2\x9d\x49\x05\x00\x1f\xe3\xf9\xbd\x16\xf4\xfd\x84\ +\x26\x1c\x9d\xb7\x1d\x30\xcc\x40\x3b\x3e\xd0\x00\xf8\x19\xae\x5a\ +\x06\x2d\xde\xbc\xc2\xef\xb9\xf0\x7c\x95\x52\x98\xa6\xe9\xf9\x77\ +\x29\x02\xa7\x11\x01\x8a\xb7\x68\xf5\x7a\xbd\x78\x9b\xd7\x89\xdf\ +\x67\x6a\xf4\x72\x21\x98\x4e\x44\x13\x00\xca\x34\x58\xb9\x3b\x78\ +\x7b\x39\xa3\x56\xc6\x2f\x6c\xed\x41\x6f\xfd\x81\x03\x60\x3a\x2d\ +\x48\x05\xe8\xda\x2d\x5d\xa2\xe0\xab\xce\xfe\x47\x11\x07\xa0\x94\ +\x71\x55\xc0\x2e\xda\x2b\x15\xb5\xc2\xe2\xfc\x50\x00\xe0\x05\x41\ +\xd0\x8c\x1b\xd6\x2d\xe4\x43\x33\x4b\xe2\x65\xe0\xa0\x44\x84\xb0\ +\x6e\x79\x1b\xfa\x69\x32\xd9\x6b\x38\x42\x00\x0c\x0f\x0f\x73\xe4\ +\xc8\x91\x58\x18\xbe\xab\xab\x4b\x00\x28\xd6\xa9\x53\xa7\xd8\xb2\ +\x65\x8b\x34\xcb\x2a\x4a\xe6\x02\x04\x00\x91\x00\x20\x12\x00\x44\ +\x02\x80\x48\x00\x10\x09\x00\x22\x01\xa0\x82\x92\x61\xbb\x80\xd9\ +\xab\xda\x00\x0c\x02\xb6\xf8\xb5\x6c\x5d\x8b\x14\x00\x96\x65\xb9\ +\xc0\x39\xf1\x6b\x59\x72\xaa\x61\xab\x5a\xd4\x00\xfb\xc5\xb7\x65\ +\xe9\xef\x96\x65\xf5\x47\x11\x80\x1d\xe3\x74\x8b\xfc\xb5\x3d\x92\ +\xbd\x00\xcb\xb2\x8e\x55\xeb\xcb\x85\x58\x7f\x01\x5e\x8d\x72\x37\ +\xf0\xeb\xc0\xeb\xe2\xe7\x92\x3a\x0e\xac\xb3\x2c\xab\x2a\x3d\xa6\ +\x44\x2d\xbe\x61\x36\x9b\x75\xd3\xe9\xf4\x2b\x40\x03\xb0\xa2\x56\ +\xe7\x11\xc0\x2e\xdf\x5e\xe0\xf3\x96\x65\x5d\xad\xd6\x41\x6b\xbe\ +\x9e\x2a\x93\xc9\x2c\x01\x36\x00\xab\x80\xf7\x01\x4d\x31\x72\xfa\ +\x30\xd0\x0d\x1c\x00\x7e\x6d\x59\xd6\x9b\xd2\x0e\x44\x22\x91\x48\ +\x24\x12\x89\x44\x22\x91\x48\x24\x12\x89\x44\x15\xd1\xff\x00\x56\ +\x1c\x01\xcd\xc9\x01\xf3\xd5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\ +\x42\x60\x82\ " qt_resource_name = "\ @@ -8442,33 +8594,38 @@ qt_resource_name = "\ \x0e\xc5\xfa\x07\ \x00\x4f\ \x00\x74\x00\x68\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x08\ +\x05\x92\x5d\x07\ +\x00\x4b\ +\x00\x6f\x00\x62\x00\x6f\x00\x2e\x00\x70\x00\x6e\x00\x67\ " qt_resource_struct = "\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x01\ -\x00\x00\x00\x28\x00\x02\x00\x00\x00\x01\x00\x00\x00\x17\ -\x00\x00\x00\x36\x00\x02\x00\x00\x00\x01\x00\x00\x00\x11\ -\x00\x00\x00\x46\x00\x02\x00\x00\x00\x01\x00\x00\x00\x0d\ +\x00\x00\x00\x28\x00\x02\x00\x00\x00\x01\x00\x00\x00\x18\ +\x00\x00\x00\x36\x00\x02\x00\x00\x00\x01\x00\x00\x00\x12\ +\x00\x00\x00\x46\x00\x02\x00\x00\x00\x01\x00\x00\x00\x0e\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x0a\ \x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x06\ \x00\x00\x00\x58\x00\x02\x00\x00\x00\x03\x00\x00\x00\x07\ \x00\x00\x01\x94\x00\x00\x00\x00\x00\x01\x00\x01\xad\xa7\ \x00\x00\x01\x7e\x00\x00\x00\x00\x00\x01\x00\x01\x91\x58\ \x00\x00\x01\xaa\x00\x00\x00\x00\x00\x01\x00\x01\xcc\xe3\ -\x00\x00\x00\x58\x00\x02\x00\x00\x00\x02\x00\x00\x00\x0b\ +\x00\x00\x00\x58\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0b\ +\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x02\x07\xc9\ \x00\x00\x01\xbe\x00\x00\x00\x00\x00\x01\x00\x01\xf6\xde\ \x00\x00\x01\xd8\x00\x00\x00\x00\x00\x01\x00\x02\x01\xe5\ -\x00\x00\x00\x58\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\ +\x00\x00\x00\x58\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0f\ \x00\x00\x00\x7e\x00\x00\x00\x00\x00\x01\x00\x00\x09\x5d\ \x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x00\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x9a\ -\x00\x00\x00\x58\x00\x02\x00\x00\x00\x05\x00\x00\x00\x12\ +\x00\x00\x00\x58\x00\x02\x00\x00\x00\x05\x00\x00\x00\x13\ \x00\x00\x01\x38\x00\x00\x00\x00\x00\x01\x00\x00\x6a\x71\ \x00\x00\x01\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x46\x38\ \x00\x00\x00\xce\x00\x00\x00\x00\x00\x01\x00\x00\x37\xa3\ \x00\x00\x00\xb2\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x3a\ \x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x02\ -\x00\x00\x00\x58\x00\x02\x00\x00\x00\x01\x00\x00\x00\x18\ +\x00\x00\x00\x58\x00\x02\x00\x00\x00\x01\x00\x00\x00\x19\ \x00\x00\x01\x5a\x00\x00\x00\x00\x00\x01\x00\x00\x73\xc8\ " diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 5499b14..517d2e4 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -865,7 +865,7 @@ def main(argv=None, qtGUI=None): otherOptions = OptionGroup(parser, "OTHER") mainOptions.add_option("-p", "--profile", action="store", dest="profile", default="KHD", help="Device profile (Choose one among K1, K2, K345, KDX, KHD, KF, KFHD, KFHD8, KFHDX," - " KFHDX8, KFA) [Default=KHD]") + " KFHDX8, KFA, KoMT, KoG, KoA, KoAHD) [Default=KHD]") mainOptions.add_option("-q", "--quality", type="int", dest="quality", default="0", help="Quality of Panel View. 0 - Normal 1 - High 2 - Ultra [Default=0]") mainOptions.add_option("-m", "--manga-style", action="store_true", dest="righttoleft", default=False, @@ -1031,9 +1031,12 @@ def checkOptions(): options.quality = 0 options.panelview = False # Disable all Kindle features for other e-readers - if options.profile == 'OTHER': + if options.profile == 'OTHER' or 'Ko' in options.profile: options.panelview = False options.quality = 0 + # Enable 150% zoom for all non-HD Kobo models + if 'Ko' in options.profile and options.profile != "KoAHD": + options.quality = 1 # Kindle for Android profile require target resolution. if options.profile == 'KFA' and (options.customwidth == 0 or options.customheight == 0): print "ERROR: Kindle for Android profile require --customwidth and --customheight options!" diff --git a/kcc/image.py b/kcc/image.py index 3c8a7bf..095021d 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -111,6 +111,10 @@ class ProfileData: 'KFHD8': ("K. Fire HD 8.9\"", (1200, 1920), PalleteNull, 1.0, (1800, 2880)), 'KFHDX': ("K. Fire HDX 7\"", (1200, 1920), PalleteNull, 1.0, (1800, 2880)), 'KFHDX8': ("K. Fire HDX 8.9\"", (1600, 2560), PalleteNull, 1.0, (2400, 3840)), + 'KoMT': ("Kobo Mini/Touch", (600, 800), Palette16, 1.8, (900, 1200)), + 'KoG': ("Kobo Glow", (768, 1024), Palette16, 1.8, (1152, 1536)), + 'KoA': ("Kobo Aura", (758, 1024), Palette16, 1.8, (1137, 1536)), + 'KoAHD': ("Kobo Aura HD", (1080, 1440), Palette16, 1.8, (1620, 2160)), 'KFA': ("Kindle for Android", (0, 0), PalleteNull, 1.0, (0, 0)), 'OTHER': ("Other", (0, 0), Palette16, 1.8, (0, 0)), } @@ -126,6 +130,10 @@ class ProfileData: "K. Fire HD 8.9\"": 'KFHD8', "K. Fire HDX 7\"": 'KFHDX', "K. Fire HDX 8.9\"": 'KFHDX8', + "Kobo Mini/Touch": 'KoMT', + "Kobo Glow": 'KoG', + "Kobo Aura": 'KoA', + "Kobo Aura HD": 'KoAHD', "Kindle for Android": 'KFA', "Other": 'OTHER' } @@ -133,19 +141,24 @@ class ProfileData: ProfileLabelsGUI = [ "Kindle Paperwhite", "Kindle", + "Kindle DX/DXG", "Separator", + "Kindle Fire", "K. Fire HD 7\"", "K. Fire HD 8.9\"", "K. Fire HDX 7\"", "K. Fire HDX 8.9\"", "Separator", - "Kindle for Android", + "Kobo Mini/Touch", + "Kobo Glow", + "Kobo Aura", + "Kobo Aura HD", + "Separator", "Other", "Separator", + "Kindle for Android", "Kindle 1", "Kindle 2", - "Kindle DX/DXG", - "Kindle Fire" ] From 22b7258aa31e1ca33544dcb2efbeee22acb66ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Fri, 27 Dec 2013 14:42:22 +0100 Subject: [PATCH 04/27] GUI: Refactored profile logic --- kcc/KCC_gui.py | 316 ++++++++++++++++++++++++++++++------------------- kcc/image.py | 42 ------- 2 files changed, 192 insertions(+), 166 deletions(-) diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 6ea4690..0e4df22 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -34,7 +34,6 @@ from time import sleep from shutil import move from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer from SocketServer import ThreadingMixIn -from image import ProfileData from subprocess import STDOUT, PIPE from PyQt4 import QtGui, QtCore from xml.dom.minidom import parse @@ -348,7 +347,7 @@ class WorkerThread(QtCore.QThread): def run(self): self.emit(QtCore.SIGNAL("modeConvert"), False) - profile = ProfileData.ProfileLabels[str(GUI.DeviceBox.currentText())] + profile = GUI.profiles[str(GUI.DeviceBox.currentText())]['Label'] argv = ["--profile=" + profile] currentJobs = [] if GUI.MangaBox.isChecked(): @@ -359,6 +358,8 @@ class WorkerThread(QtCore.QThread): argv.append("--quality=1") elif GUI.QualityBox.checkState() == 2: argv.append("--quality=2") + if str(GUI.FormatBox.currentText()) == 'CBZ': + argv.append("--cbz-output") if GUI.currentMode == 1: if profile in ['KFHD', 'KFHD8', 'KFHDX', 'KFHDX8']: argv.append("--upscale") @@ -382,8 +383,6 @@ class WorkerThread(QtCore.QThread): if float(GUI.GammaValue) > 0.09: # noinspection PyTypeChecker argv.append("--gamma=" + GUI.GammaValue) - if str(GUI.FormatBox.currentText()) == 'CBZ': - argv.append("--cbz-output") if str(GUI.FormatBox.currentText()) == 'MOBI': argv.append("--batchsplit") if GUI.currentMode > 2: @@ -625,67 +624,103 @@ class KCCGUI(KCC_ui.Ui_KCC): MW.setMinimumSize(QtCore.QSize(420, 287)) MW.setMaximumSize(QtCore.QSize(420, 287)) MW.resize(420, 287) + GUI.BasicModeButton.setEnabled(True) + GUI.AdvModeButton.setEnabled(True) GUI.BasicModeButton.setStyleSheet('font-weight:Bold;') GUI.AdvModeButton.setStyleSheet('font-weight:Normal;') - GUI.FormatBox.setCurrentIndex(0) GUI.FormatBox.setEnabled(False) - GUI.NoRotateBox.setChecked(False) - GUI.WebtoonBox.setChecked(False) - GUI.ProcessingBox.setChecked(False) + GUI.OptionsBasic.setEnabled(True) + GUI.OptionsBasic.setVisible(True) + GUI.MangaBox.setChecked(False) + GUI.RotateBox.setChecked(False) + GUI.QualityBox.setChecked(False) GUI.OptionsAdvanced.setEnabled(False) + GUI.OptionsAdvanced.setVisible(False) + GUI.ProcessingBox.setChecked(False) + GUI.UpscaleBox.setChecked(False) + GUI.NoRotateBox.setChecked(False) + GUI.BorderBox.setChecked(False) + GUI.WebtoonBox.setChecked(False) + GUI.NoDitheringBox.setChecked(False) GUI.OptionsAdvancedGamma.setEnabled(False) + GUI.OptionsAdvancedGamma.setVisible(False) GUI.OptionsExpert.setEnabled(False) - GUI.ProcessingBox.hide() - GUI.UpscaleBox.hide() - GUI.NoRotateBox.hide() - GUI.MangaBox.setEnabled(True) - self.changeFormat() + GUI.OptionsExpert.setVisible(False) + GUI.ColorBox.setChecked(False) def modeAdvanced(self): self.currentMode = 2 MW.setMinimumSize(QtCore.QSize(420, 365)) MW.setMaximumSize(QtCore.QSize(420, 365)) MW.resize(420, 365) + GUI.BasicModeButton.setEnabled(True) + GUI.AdvModeButton.setEnabled(True) GUI.BasicModeButton.setStyleSheet('font-weight:Normal;') GUI.AdvModeButton.setStyleSheet('font-weight:Bold;') GUI.FormatBox.setEnabled(True) - GUI.ProcessingBox.show() - GUI.UpscaleBox.show() - GUI.NoRotateBox.show() - GUI.OptionsAdvancedGamma.setEnabled(True) + GUI.OptionsBasic.setEnabled(True) + GUI.OptionsBasic.setVisible(True) + GUI.MangaBox.setChecked(False) + GUI.RotateBox.setChecked(False) + GUI.QualityBox.setChecked(False) GUI.OptionsAdvanced.setEnabled(True) - GUI.OptionsExpert.setEnabled(False) - GUI.MangaBox.setEnabled(True) + GUI.OptionsAdvanced.setVisible(True) + GUI.ProcessingBox.setChecked(False) + GUI.UpscaleBox.setChecked(False) + GUI.NoRotateBox.setChecked(False) + GUI.BorderBox.setChecked(False) + GUI.WebtoonBox.setChecked(False) + GUI.NoDitheringBox.setChecked(False) + GUI.OptionsAdvancedGamma.setEnabled(True) + GUI.OptionsAdvancedGamma.setVisible(True) + GUI.OptionsExpert.setEnabled(True) + GUI.OptionsExpert.setVisible(True) + GUI.ColorBox.setChecked(False) - def modeExpert(self, KFA=False): - self.modeAdvanced() + def modeExpert(self): self.currentMode = 3 MW.setMinimumSize(QtCore.QSize(420, 397)) MW.setMaximumSize(QtCore.QSize(420, 397)) MW.resize(420, 397) + GUI.BasicModeButton.setEnabled(False) + GUI.AdvModeButton.setEnabled(False) + GUI.BasicModeButton.setStyleSheet('font-weight:Normal;') + GUI.AdvModeButton.setStyleSheet('font-weight:Normal;') + GUI.FormatBox.setEnabled(True) + GUI.OptionsBasic.setEnabled(True) + GUI.OptionsBasic.setVisible(True) + GUI.MangaBox.setChecked(False) + GUI.RotateBox.setChecked(False) + GUI.QualityBox.setChecked(False) + GUI.OptionsAdvanced.setEnabled(True) + GUI.OptionsAdvanced.setVisible(True) + GUI.ProcessingBox.setChecked(False) + GUI.UpscaleBox.setChecked(False) + GUI.NoRotateBox.setChecked(False) + GUI.BorderBox.setChecked(False) + GUI.WebtoonBox.setChecked(False) + GUI.NoDitheringBox.setChecked(False) + GUI.OptionsAdvancedGamma.setEnabled(True) + GUI.OptionsAdvancedGamma.setVisible(True) GUI.OptionsExpert.setEnabled(True) - if KFA: - GUI.ColorBox.setChecked(True) - GUI.FormatBox.setCurrentIndex(0) - GUI.FormatBox.setEnabled(False) - else: - GUI.FormatBox.setEnabled(True) - GUI.MangaBox.setChecked(False) - GUI.MangaBox.setEnabled(False) + GUI.OptionsExpert.setVisible(True) + GUI.ColorBox.setChecked(False) def modeConvert(self, enable): if self.currentMode != 3: GUI.BasicModeButton.setEnabled(enable) GUI.AdvModeButton.setEnabled(enable) + if self.currentMode != 1: + GUI.FormatBox.setEnabled(enable) GUI.DirectoryButton.setEnabled(enable) GUI.ClearButton.setEnabled(enable) GUI.FileButton.setEnabled(enable) GUI.DeviceBox.setEnabled(enable) - GUI.FormatBox.setEnabled(enable) GUI.OptionsBasic.setEnabled(enable) GUI.OptionsAdvanced.setEnabled(enable) GUI.OptionsAdvancedGamma.setEnabled(enable) GUI.OptionsExpert.setEnabled(enable) + GUI.ConvertButton.setEnabled(True) if enable: self.conversionAlive = False self.worker.sync() @@ -693,13 +728,6 @@ class KCCGUI(KCC_ui.Ui_KCC): icon.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) GUI.ConvertButton.setIcon(icon) GUI.ConvertButton.setText('Convert') - GUI.ConvertButton.setEnabled(True) - if self.currentMode == 1: - self.modeBasic() - elif self.currentMode == 2: - self.modeAdvanced() - elif self.currentMode == 3: - self.modeExpert() else: self.conversionAlive = True self.worker.sync() @@ -707,16 +735,6 @@ class KCCGUI(KCC_ui.Ui_KCC): icon.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) GUI.ConvertButton.setIcon(icon) GUI.ConvertButton.setText('Abort') - GUI.ConvertButton.setEnabled(True) - - def changeGamma(self, value): - value = float(value) - value = '%.2f' % (value/100) - if float(value) <= 0.09: - GUI.GammaLabel.setText('Gamma: Auto') - else: - GUI.GammaLabel.setText('Gamma: ' + str(value)) - self.GammaValue = value def toggleWebtoonBox(self, value): if value: @@ -730,9 +748,8 @@ class KCCGUI(KCC_ui.Ui_KCC): if not GUI.ProcessingBox.isChecked(): GUI.NoRotateBox.setEnabled(True) GUI.QualityBox.setEnabled(True) - GUI.MangaBox.setEnabled(True) - self.changeDevice(GUI.DeviceBox.currentIndex(), False) - self.changeFormat() + if GUI.profiles[str(GUI.DeviceBox.currentText())]['MangaMode']: + GUI.MangaBox.setEnabled(True) def toggleNoSplitRotate(self, value): if value: @@ -741,8 +758,6 @@ class KCCGUI(KCC_ui.Ui_KCC): else: if not GUI.ProcessingBox.isChecked(): GUI.RotateBox.setEnabled(True) - self.changeDevice(GUI.DeviceBox.currentIndex(), False) - self.changeFormat() def toggleProcessingBox(self, value): if value: @@ -766,7 +781,6 @@ class KCCGUI(KCC_ui.Ui_KCC): GUI.GammaLabel.setEnabled(False) else: GUI.RotateBox.setEnabled(True) - GUI.QualityBox.setEnabled(True) GUI.UpscaleBox.setEnabled(True) GUI.NoRotateBox.setEnabled(True) GUI.BorderBox.setEnabled(True) @@ -775,56 +789,62 @@ class KCCGUI(KCC_ui.Ui_KCC): GUI.ColorBox.setEnabled(True) GUI.GammaSlider.setEnabled(True) GUI.GammaLabel.setEnabled(True) - self.changeDevice(GUI.DeviceBox.currentIndex(), False) - self.changeFormat() + if GUI.profiles[str(GUI.DeviceBox.currentText())]['Quality']: + GUI.QualityBox.setEnabled(True) - def changeDevice(self, value, showInfo=True): - # Other - if value == 15: - GUI.BasicModeButton.setEnabled(False) - GUI.AdvModeButton.setEnabled(False) - if showInfo: - self.addMessage('' - 'List of supported Non-Kindle devices', 'info') - self.modeExpert() - # KFA - elif value == 17: - GUI.BasicModeButton.setEnabled(False) - GUI.AdvModeButton.setEnabled(False) - self.modeExpert(True) + def changeGamma(self, value): + value = float(value) + value = '%.2f' % (value/100) + if float(value) <= 0.09: + GUI.GammaLabel.setText('Gamma: Auto') + else: + GUI.GammaLabel.setText('Gamma: ' + str(value)) + self.GammaValue = value + + def changeDevice(self): + if self.currentMode == 1: + self.modeBasic() + elif self.currentMode == 2: + self.modeAdvanced() elif self.currentMode == 3: + self.modeExpert() + profile = GUI.profiles[str(GUI.DeviceBox.currentText())] + if profile['ForceExpert']: + self.modeExpert() + GUI.BasicModeButton.setEnabled(False) + GUI.AdvModeButton.setEnabled(False) + else: GUI.BasicModeButton.setEnabled(True) GUI.AdvModeButton.setEnabled(True) - self.modeBasic() - # Other, K1, K2, DX/DXG, KoMT, KoG, KoA, KoAHD - if value in [15, 18, 19, 2, 10, 11, 12, 13]: - GUI.QualityBox.setChecked(False) - GUI.QualityBox.setEnabled(False) - self.QualityBoxDisabled = True - # KoMT, KoG, KoA, KoAHD - if value in [10, 11, 12, 13]: - GUI.FormatBox.setCurrentIndex(2) - # K. Fire - if value in [5, 6, 7, 8]: - if GUI.UpscaleBox.isEnabled(): - GUI.UpscaleBox.setChecked(True) - else: - # Other, K1, K2, DX/DXG - if not GUI.WebtoonBox.isChecked() and not GUI.ProcessingBox.isChecked() \ - and str(GUI.FormatBox.currentText()) != 'CBZ' and value not in [15, 18, 19, 2]: - GUI.QualityBox.setEnabled(True) - self.QualityBoxDisabled = False + if self.currentMode == 3: + self.modeBasic() + self.changeFormat() + GUI.GammaSlider.setValue(0) + self.changeGamma(0) + if profile['DefaultUpscale']: + GUI.UpscaleBox.setChecked(True) - def changeFormat(self): + def changeFormat(self, outputFormat=None): + profile = GUI.profiles[str(GUI.DeviceBox.currentText())] + if outputFormat is not None: + GUI.FormatBox.setCurrentIndex(outputFormat) + else: + if GUI.FormatBox.count() == 3: + GUI.FormatBox.setCurrentIndex(profile['DefaultFormat']) + else: + if profile['DefaultFormat'] != 0: + tmpFormat = profile['DefaultFormat'] - 1 + else: + tmpFormat = 0 + GUI.FormatBox.setCurrentIndex(tmpFormat) + GUI.MangaBox.setChecked(False) + GUI.QualityBox.setChecked(False) if str(GUI.FormatBox.currentText()) == 'CBZ': - GUI.MangaBox.setChecked(False) GUI.MangaBox.setEnabled(False) - GUI.QualityBox.setChecked(False) GUI.QualityBox.setEnabled(False) else: - if not GUI.WebtoonBox.isChecked() and not GUI.ProcessingBox.isChecked() and not self.QualityBoxDisabled: - GUI.QualityBox.setEnabled(True) - GUI.MangaBox.setEnabled(True) + GUI.MangaBox.setEnabled(profile['MangaMode']) + GUI.QualityBox.setEnabled(profile['Quality']) def stripTags(self, html): s = HTMLStripper() @@ -977,7 +997,6 @@ class KCCGUI(KCC_ui.Ui_KCC): self.progress = ProgressThread() self.conversionAlive = False self.needClean = True - self.QualityBoxDisabled = False self.GammaValue = 1.0 self.completedWork = {} if sys.platform.startswith('darwin'): @@ -995,6 +1014,63 @@ class KCCGUI(KCC_ui.Ui_KCC): self.statusBarStyle = 'QLabel{padding-top:3px;padding-bottom:3px;border-top:2px solid #C2C7CB}' self.tray.show() + self.profiles = { + "Kindle Paperwhite": {'MangaMode': True, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': False, 'Label': 'KHD'}, + "Kindle": {'MangaMode': True, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': False, 'Label': 'K345'}, + "Kindle DX/DXG": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': False, 'Label': 'KDX'}, + "Kindle Fire": {'MangaMode': True, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': False, 'Label': 'KF'}, + "K. Fire HD 7\"": {'MangaMode': True, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': True, 'Label': 'KFHD'}, + "K. Fire HD 8.9\"": {'MangaMode': True, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': True, 'Label': 'KFHD8'}, + "K. Fire HDX 7\"": {'MangaMode': True, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': True, 'Label': 'KFHDX'}, + "K. Fire HDX 8.9\"": {'MangaMode': True, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': True, 'Label': 'KFHDX8'}, + "Kobo Mini/Touch": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 2, + 'DefaultUpscale': False, 'Label': 'KoMT'}, + "Kobo Glow": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 2, + 'DefaultUpscale': False, 'Label': 'KoG'}, + "Kobo Aura": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 2, + 'DefaultUpscale': False, 'Label': 'KoA'}, + "Kobo Aura HD": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 2, + 'DefaultUpscale': False, 'Label': 'KoAHD'}, + "Other": {'MangaMode': False, 'Quality': False, 'ForceExpert': True, 'DefaultFormat': 1, + 'DefaultUpscale': False, 'Label': 'OTHER'}, + "Kindle for Android": {'MangaMode': True, 'Quality': False, 'ForceExpert': True, 'DefaultFormat': 0, + 'DefaultUpscale': False, 'Label': 'KFA'}, + "Kindle 1": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': False, 'Label': 'K1'}, + "Kindle 2": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 0, + 'DefaultUpscale': False, 'Label': 'K2'} + } + profilesGUI = [ + "Kindle Paperwhite", + "Kindle", + "Kindle DX/DXG", + "Separator", + "Kindle Fire", + "K. Fire HD 7\"", + "K. Fire HD 8.9\"", + "K. Fire HDX 7\"", + "K. Fire HDX 8.9\"", + "Separator", + "Kobo Mini/Touch", + "Kobo Glow", + "Kobo Aura", + "Kobo Aura HD", + "Separator", + "Other", + "Separator", + "Kindle for Android", + "Kindle 1", + "Kindle 2", + ] + statusBarLabel = QtGui.QLabel('HOMEPAGE - DONATE' ' - README<' @@ -1072,24 +1148,7 @@ class KCCGUI(KCC_ui.Ui_KCC): MW.connect(self.progress, QtCore.SIGNAL("addMessage"), self.addMessage) MW.closeEvent = self.saveSettings - for f in formats: - GUI.FormatBox.addItem(eval('self.icons.' + f + 'Format'), f) - if self.currentFormat > GUI.FormatBox.count(): - GUI.FormatBox.setCurrentIndex(0) - self.currentFormat = 0 - else: - GUI.FormatBox.setCurrentIndex(self.currentFormat) - for option in self.options: - if str(option) == "customWidth": - GUI.customWidth.setText(str(self.options[option])) - elif str(option) == "customHeight": - GUI.customHeight.setText(str(self.options[option])) - elif str(option) == "GammaSlider": - GUI.GammaSlider.setValue(int(self.options[option])) - self.changeGamma(int(self.options[option])) - else: - eval('GUI.' + str(option)).setCheckState(self.options[option]) - for profile in ProfileData.ProfileLabelsGUI: + for profile in profilesGUI: if profile == "Other": GUI.DeviceBox.addItem(self.icons.deviceOther, profile) elif profile == "Separator": @@ -1098,20 +1157,29 @@ class KCCGUI(KCC_ui.Ui_KCC): GUI.DeviceBox.addItem(self.icons.deviceKobo, profile) else: GUI.DeviceBox.addItem(self.icons.deviceKindle, profile) + for f in formats: + GUI.FormatBox.addItem(eval('self.icons.' + f + 'Format'), f) if self.lastDevice > GUI.DeviceBox.count(): - GUI.DeviceBox.setCurrentIndex(0) self.lastDevice = 0 - else: - GUI.DeviceBox.setCurrentIndex(self.lastDevice) + if self.currentFormat > GUI.FormatBox.count(): + self.currentFormat = 0 + GUI.DeviceBox.setCurrentIndex(self.lastDevice) + self.changeDevice() + for option in self.options: + if str(option) == "customWidth": + GUI.customWidth.setText(str(self.options[option])) + elif str(option) == "customHeight": + GUI.customHeight.setText(str(self.options[option])) + elif str(option) == "GammaSlider": + if GUI.GammaSlider.isEnabled(): + GUI.GammaSlider.setValue(int(self.options[option])) + self.changeGamma(int(self.options[option])) + else: + if eval('GUI.' + str(option)).isEnabled(): + eval('GUI.' + str(option)).setCheckState(self.options[option]) + if self.currentFormat != self.profiles[str(GUI.DeviceBox.currentText())]['DefaultFormat']: + self.changeFormat(self.currentFormat) - if self.currentMode == 1: - self.modeBasic() - elif self.currentMode == 2: - self.modeAdvanced() - elif self.currentMode == 3: - self.modeExpert() - self.changeDevice(self.lastDevice) - self.changeFormat() self.versionCheck.start() self.contentServer.start() self.hideProgressBar() diff --git a/kcc/image.py b/kcc/image.py index 095021d..b54c068 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -119,48 +119,6 @@ class ProfileData: 'OTHER': ("Other", (0, 0), Palette16, 1.8, (0, 0)), } - ProfileLabels = { - "Kindle 1": 'K1', - "Kindle 2": 'K2', - "Kindle": 'K345', - "Kindle Paperwhite": 'KHD', - "Kindle DX/DXG": 'KDX', - "Kindle Fire": 'KF', - "K. Fire HD 7\"": 'KFHD', - "K. Fire HD 8.9\"": 'KFHD8', - "K. Fire HDX 7\"": 'KFHDX', - "K. Fire HDX 8.9\"": 'KFHDX8', - "Kobo Mini/Touch": 'KoMT', - "Kobo Glow": 'KoG', - "Kobo Aura": 'KoA', - "Kobo Aura HD": 'KoAHD', - "Kindle for Android": 'KFA', - "Other": 'OTHER' - } - - ProfileLabelsGUI = [ - "Kindle Paperwhite", - "Kindle", - "Kindle DX/DXG", - "Separator", - "Kindle Fire", - "K. Fire HD 7\"", - "K. Fire HD 8.9\"", - "K. Fire HDX 7\"", - "K. Fire HDX 8.9\"", - "Separator", - "Kobo Mini/Touch", - "Kobo Glow", - "Kobo Aura", - "Kobo Aura HD", - "Separator", - "Other", - "Separator", - "Kindle for Android", - "Kindle 1", - "Kindle 2", - ] - class ComicPage: def __init__(self, source, device, fill=None): From 29f901f92a641182372c25a7f6aab4ed1dc912d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sat, 28 Dec 2013 08:30:37 +0100 Subject: [PATCH 05/27] Fixed PDF queue (close #73) --- kcc/pdfjpgextract.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kcc/pdfjpgextract.py b/kcc/pdfjpgextract.py index d9dad09..34ea74d 100644 --- a/kcc/pdfjpgextract.py +++ b/kcc/pdfjpgextract.py @@ -24,13 +24,16 @@ __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jas __docformat__ = 'restructuredtext en' import os +from random import choice +from string import ascii_uppercase, digits class PdfJpgExtract: def __init__(self, origFileName): self.origFileName = origFileName self.filename = os.path.splitext(origFileName) - self.path = self.filename[0] + "-KCC-TMP" + # noinspection PyUnusedLocal + self.path = self.filename[0] + "-KCC-TMP-" + ''.join(choice(ascii_uppercase + digits) for x in range(3)) def getPath(self): return self.path @@ -63,7 +66,6 @@ class PdfJpgExtract: istart += startfix iend += endfix - print "JPG %d from %d to %d" % (njpg, istart, iend) jpg = pdf[istart:iend] jpgfile = file(self.path + "/jpg%d.jpg" % njpg, "wb") jpgfile.write(jpg) From 72132ea90899fc8d1e94b2388a43631c9eeffdfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sat, 28 Dec 2013 09:06:10 +0100 Subject: [PATCH 06/27] GUI: Tweaked profile logic --- kcc/KCC_gui.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 0e4df22..e0cf643 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -837,14 +837,18 @@ class KCCGUI(KCC_ui.Ui_KCC): else: tmpFormat = 0 GUI.FormatBox.setCurrentIndex(tmpFormat) - GUI.MangaBox.setChecked(False) - GUI.QualityBox.setChecked(False) if str(GUI.FormatBox.currentText()) == 'CBZ': GUI.MangaBox.setEnabled(False) GUI.QualityBox.setEnabled(False) + GUI.MangaBox.setChecked(False) + GUI.QualityBox.setChecked(False) else: GUI.MangaBox.setEnabled(profile['MangaMode']) + if not profile['MangaMode']: + GUI.MangaBox.setChecked(False) GUI.QualityBox.setEnabled(profile['Quality']) + if not profile['Quality']: + GUI.QualityBox.setChecked(False) def stripTags(self, html): s = HTMLStripper() @@ -1165,6 +1169,8 @@ class KCCGUI(KCC_ui.Ui_KCC): self.currentFormat = 0 GUI.DeviceBox.setCurrentIndex(self.lastDevice) self.changeDevice() + if self.currentFormat != self.profiles[str(GUI.DeviceBox.currentText())]['DefaultFormat']: + self.changeFormat(self.currentFormat) for option in self.options: if str(option) == "customWidth": GUI.customWidth.setText(str(self.options[option])) @@ -1177,8 +1183,6 @@ class KCCGUI(KCC_ui.Ui_KCC): else: if eval('GUI.' + str(option)).isEnabled(): eval('GUI.' + str(option)).setCheckState(self.options[option]) - if self.currentFormat != self.profiles[str(GUI.DeviceBox.currentText())]['DefaultFormat']: - self.changeFormat(self.currentFormat) self.versionCheck.start() self.contentServer.start() From c1c44bdf88b4810d50375ba568d11cd1eaa56824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sat, 28 Dec 2013 10:19:43 +0100 Subject: [PATCH 07/27] Reverting output extension changes --- kcc/KCC_gui.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index e0cf643..c39cfd1 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -110,9 +110,6 @@ class WebServerHandler(BaseHTTPRequestHandler): if self.path.endswith('.mobi'): mimetype = 'application/x-mobipocket-ebook' sendReply = True - if self.path.endswith('.azw3'): - mimetype = 'application/x-mobipocket-ebook' - sendReply = True if self.path.endswith('.epub'): mimetype = 'application/epub+zip' sendReply = True @@ -495,12 +492,8 @@ class WorkerThread(QtCore.QThread): GUI.progress.content = '' mobiPath = item.replace('.epub', '.mobi') os.remove(mobiPath + '_toclean') - if profile in ['K345', 'KHD', 'KF', 'KFHD', 'KFHD8', 'KFHDX', 'KFHDX8', 'KFA']: - move(mobiPath, mobiPath.replace('.mobi', '.azw3')) - mobiPath = item.replace('.mobi', '.azw3') GUI.completedWork[os.path.basename(mobiPath).encode('utf-8')] = mobiPath.encode('utf-8') - self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI files... Done!', 'info', - True) + self.emit(QtCore.SIGNAL("addMessage"), 'Cleaning MOBI files... Done!', 'info', True) else: GUI.progress.content = '' for item in outputPath: From 93f5d105cf9706e987d4f7e7f3a95cccfb757fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sat, 28 Dec 2013 10:35:15 +0100 Subject: [PATCH 08/27] Updated README --- README.md | 25 ++++--------------------- kcc/KCC_gui.py | 9 ++++++--- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index a815636..ca49c56 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ You can find the latest released binary at the following links: - **OS X (10.7 or earlier):** Soon™ ## INPUT FORMATS -**KCC** can understand and convert, at the moment, the following file types: +**KCC** can understand and convert, at the moment, the following input types: - PNG, JPG, GIF, TIFF, BMP - Folders - CBZ, ZIP @@ -36,7 +36,7 @@ You can find the latest released binary at the following links: - PDF *(Extracting only contained JPG images)* ## OPTIONAL REQUIREMENTS -- [KindleGen](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211) v2.9+ in a directory reachable by your _PATH_ or in _KCC_ directory *(For .mobi generation)* +- [KindleGen](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211) v2.9+ in a directory reachable by your _PATH_ or in _KCC_ directory *(For MOBI generation)* - [UnRAR](http://www.rarlab.com/download.htm) *(For CBR/RAR support)* - [7za](http://www.7-zip.org/download.html) *(For 7z/CB7 support)* @@ -49,28 +49,11 @@ You can find the latest released binary at the following links: ## USAGE -### Important tips: -* Use high quality source files. **This little detail have a major impact on the final result.** -* Read tooltip of _High/Ultra quality_ option. There are many important informations there. -* When converting images smaller than device resolution remember to enable upscaling. -* Panel View (auto zooming every part of page) can be disabled directly on Kindle. There is no KCC option to do that. -* Check our [wiki](https://github.com/ciromattia/kcc/wiki/Other-devices) for a list of tested Non-Kindle E-Readers. -* The first image found will be set as the comic's cover. -* All files/directories will be added to EPUB in alphabetical order. -* Using high/ultra quality output option with Kindle Fire HD/HDX in most cases is just waste of space. -* ComicRack metadata will be parsed only if they are saved in *ComicInfo.xml* file. - -### Calibre: -* Calibre can be used to upload files created by KCC. -* Uploading KCC output with Calibre will remove *Personal* tag from cover. -* **Don't convert files created by KCC with Calibre!** Any conversion process will corrupt the file! -* Don't use Calibre reader to preview files created by KCC. It can't parse them correctly. - -### GUI - Should be pretty self-explanatory. All options have detailed informations in tooltips. After completed conversion you should find ready file alongside the original input file (same directory). +Please check [our wiki](https://github.com/ciromattia/kcc/wiki/) for more details. + ### Standalone `comic2ebook.py` usage: ``` diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index c39cfd1..b505e2d 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -816,6 +816,9 @@ class KCCGUI(KCC_ui.Ui_KCC): self.changeGamma(0) if profile['DefaultUpscale']: GUI.UpscaleBox.setChecked(True) + if str(GUI.DeviceBox.currentText()) == 'Other': + self.addMessage('' + 'List of supported Non-Kindle devices.', 'info') def changeFormat(self, outputFormat=None): profile = GUI.profiles[str(GUI.DeviceBox.currentText())] @@ -1070,8 +1073,7 @@ class KCCGUI(KCC_ui.Ui_KCC): statusBarLabel = QtGui.QLabel('HOMEPAGE - DONATE' - ' - README<' - '/a> - WIKI') + ' - WIKI') statusBarLabel.setAlignment(QtCore.Qt.AlignCenter) statusBarLabel.setStyleSheet(self.statusBarStyle) statusBarLabel.setOpenExternalLinks(True) @@ -1084,7 +1086,8 @@ class KCCGUI(KCC_ui.Ui_KCC): self.addMessage('Remember: All options have additional informations in tooltips.', 'info') if self.firstStart: self.addMessage('Since you are using KCC for first time please see few ' - 'important tips.', 'info') + 'important tips.', + 'info') kindleGenExitCode = Popen('kindlegen -locale en', stdout=PIPE, stderr=STDOUT, shell=True) if kindleGenExitCode.wait() == 0: self.KindleGen = True From 3cc99c6221434eb63d3095d7c622b21c20da75a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sat, 28 Dec 2013 12:08:33 +0100 Subject: [PATCH 09/27] Margin autodetection improvements --- kcc/comic2ebook.py | 2 +- kcc/image.py | 109 +++++++++++++++++---------------------------- 2 files changed, 42 insertions(+), 69 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 517d2e4..ce64abc 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -310,7 +310,7 @@ def getImageFileName(imgfile): def applyImgOptimization(img, opt, hqImage=None): if not img.fill: - img.getImageFill(opt.webtoon) + img.getImageFill() if not opt.webtoon: img.cropWhiteSpace(10.0) if opt.cutpagenumbers and not opt.webtoon: diff --git a/kcc/image.py b/kcc/image.py index b54c068..8d41196 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -404,7 +404,7 @@ class ComicPage: self.image = self.image.crop((0, 0, widthImg - diff, heightImg)) return self.image - def getImageHistogram(self, image, new=True): + def getImageHistogram(self, image): histogram = image.histogram() RBGW = [] pixelCount = 0 @@ -413,78 +413,51 @@ class ComicPage: RBGW.append(histogram[i] + histogram[256 + i] + histogram[512 + i]) white = 0 black = 0 - for i in range(251, 256): + for i in range(253, 256): white += RBGW[i] - for i in range(5): + for i in range(3): black += RBGW[i] - if new: - if black > 0 and white == 0: - return 1 - elif white > 0 and black == 0: - return -1 - else: - return False + if black > pixelCount*0.5 and white == 0: + return 1 + elif white > pixelCount*0.5 and black == 0: + return -1 else: - if black > white and black > pixelCount*0.5: - return True - else: - return False + return False - def getImageFill(self, isWebToon): - if isWebToon: - fill = 0 - fill += self.getImageHistogram(self.image.crop((0, 0, self.image.size[0], 5)), False) - fill += self.getImageHistogram(self.image.crop((0, self.image.size[1]-5, self.image.size[0], - self.image.size[1])), False) - if fill == 2: - self.fill = 'black' - elif fill == 0: - self.fill = 'white' - else: - fill = 0 - fill += self.getImageHistogram(self.image.crop((0, 0, 5, 5)), False) - fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, 0, self.image.size[0], 5)), False) - fill += self.getImageHistogram(self.image.crop((0, self.image.size[1]-5, 5, self.image.size[1])), False) - fill += self.getImageHistogram(self.image.crop((self.image.size[0]-5, self.image.size[1]-5, - self.image.size[0], self.image.size[1])), False) - if fill > 1: - self.fill = 'black' - else: - self.fill = 'white' + def getImageFill(self): + fill = 0 + # Search fom horizontal solid lines + startY = 0 + stopY = 4 + searching = True + while stopY <= self.image.size[1]: + checkSolid = self.getImageHistogram(self.image.crop((0, startY, self.image.size[0], stopY))) + if checkSolid: + fill += checkSolid + startY = stopY + 1 + stopY = startY + 4 + if stopY > self.image.size[1] and searching: + startY = self.image.size[1] - 4 + stopY = self.image.size[1] + searching = False + # Search fom vertical solid lines + startX = 0 + stopX = 4 + searching = True + while stopX <= self.image.size[0]: + checkSolid = self.getImageHistogram(self.image.crop((startX, 0, stopX, self.image.size[1]))) + if checkSolid: + fill += checkSolid + startX = stopX + 1 + stopX = startX + 4 + if stopX > self.image.size[0] and searching: + startX = self.image.size[0] - 4 + stopX = self.image.size[0] + searching = False + if fill > 0: + self.fill = 'black' else: - fill = 0 - # Search fom horizontal solid lines - startY = 0 - stopY = 3 - searching = True - while stopY <= self.image.size[1]: - checkSolid = self.getImageHistogram(self.image.crop((0, startY, self.image.size[0], stopY))) - if checkSolid: - fill += checkSolid - startY = stopY + 1 - stopY = startY + 3 - if stopY > self.image.size[1] and searching: - startY = self.image.size[1] - 3 - stopY = self.image.size[1] - searching = False - # Search fom vertical solid lines - startX = 0 - stopX = 3 - searching = True - while stopX <= self.image.size[0]: - checkSolid = self.getImageHistogram(self.image.crop((startX, 0, stopX, self.image.size[1]))) - if checkSolid: - fill += checkSolid - startX = stopX + 1 - stopX = startX + 3 - if stopX > self.image.size[0] and searching: - startX = self.image.size[0] - 3 - stopX = self.image.size[0] - searching = False - if fill > 0: - self.fill = 'black' - else: - self.fill = 'white' + self.fill = 'white' def isImageColor(self, image): v = ImageStat.Stat(image).var From d016bade8eb6fd3a2ed4d1fbb797adc48820f1f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sun, 29 Dec 2013 10:01:17 +0100 Subject: [PATCH 10/27] Bundling VCRedist with Windows installer --- kcc.iss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kcc.iss b/kcc.iss index 6b3eeea..1273bab 100644 --- a/kcc.iss +++ b/kcc.iss @@ -66,6 +66,7 @@ Source: "build\exe.win-amd64-2.7\sip.pyd"; DestDir: "{app}"; Flags: ignoreversio Source: "build\exe.win-amd64-2.7\SSLEAY32.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode Source: "build\exe.win-amd64-2.7\unicodedata.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode Source: "build\exe.win-amd64-2.7\_psutil_mswindows.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode +Source: "other\vcredist_x64.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode ; x86 files Source: "build\exe.win32-2.7\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion solidbreak; Check: not Is64BitInstallMode Source: "build\exe.win32-2.7\_ctypes.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode @@ -91,6 +92,7 @@ Source: "build\exe.win32-2.7\sip.pyd"; DestDir: "{app}"; Flags: ignoreversion; C Source: "build\exe.win32-2.7\SSLEAY32.dll"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode Source: "build\exe.win32-2.7\unicodedata.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode Source: "build\exe.win32-2.7\_psutil_mswindows.pyd"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode +Source: "other\vcredist_x86.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode ; Common files Source: "LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion solidbreak Source: "other\Additional-LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion @@ -104,6 +106,8 @@ Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent +Filename: "{tmp}\vcredist_x64.exe"; Parameters: "/passive /Q:a /c:""msiexec /qb /i vcredist.msi"" "; StatusMsg: "Installing Microsoft Visual C++ 2008 Redistributable Package..."; Check: Is64BitInstallMode +Filename: "{tmp}\vcredist_x86.exe"; Parameters: "/passive /Q:a /c:""msiexec /qb /i vcredist.msi"" "; StatusMsg: "Installing Microsoft Visual C++ 2008 Redistributable Package..."; Check: not Is64BitInstallMode [Messages] WelcomeLabel1=Welcome to the KCC Setup Wizard From 7656a8570896f9f9c2e731c3e90ba688de34bade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sun, 29 Dec 2013 17:13:17 +0100 Subject: [PATCH 11/27] Tweaked KindleGen warning --- kcc/KCC_gui.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index b505e2d..504d192 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -575,7 +575,7 @@ class KCCGUI(KCC_ui.Ui_KCC): dnames = "" for dname in dnames: if unicode(dname) != "": - if sys.platform == 'win32': + if sys.platform.startswith('win'): dname = dname.replace('/', '\\') self.lastPath = os.path.abspath(os.path.join(unicode(dname), os.pardir)) GUI.JobList.addItem(dname) @@ -1105,8 +1105,12 @@ class KCCGUI(KCC_ui.Ui_KCC): else: self.KindleGen = False formats = ['EPUB', 'CBZ'] - self.addMessage('Cannot find kindlegen in PATH! MOBI creation will be disabled.', 'warning') + if sys.platform.startswith('win'): + self.addMessage('Cannot find ' + 'kindlegen in KCC directory! MOBI creation will be disabled.', 'warning') + else: + self.addMessage('Cannot find ' + 'kindlegen in PATH! MOBI creation will be disabled.', 'warning') rarExitCode = Popen('unrar', stdout=PIPE, stderr=STDOUT, shell=True) rarExitCode = rarExitCode.wait() if rarExitCode == 0 or rarExitCode == 7: From 6bdb0ab942dc2e591c61872cbf6df74a02c1f7de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Mon, 30 Dec 2013 18:39:53 +0100 Subject: [PATCH 12/27] Panel View improvements --- kcc/comic2ebook.py | 6 +++++- kcc/image.py | 53 +++++++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index ce64abc..c581585 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -52,6 +52,10 @@ def buildHTML(path, imgfile): rotatedPage = True else: rotatedPage = False + if "_kccnpv" in str(filename): + noPV = True + else: + noPV = False if "_kccnh" in str(filename): noHorizontalPV = True else: @@ -89,7 +93,7 @@ def buildHTML(path, imgfile): "
\"",
\n" ]) - if options.panelview: + if options.panelview and not noPV: if not noHorizontalPV and not noVerticalPV: if rotatedPage: if options.righttoleft: diff --git a/kcc/image.py b/kcc/image.py index 8d41196..04895e3 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -151,6 +151,8 @@ class ComicPage: self.border = None self.noHPV = None self.noVPV = None + self.noPV = None + self.purge = False if fill: self.fill = fill else: @@ -167,19 +169,23 @@ class ComicPage: os.remove(os.path.join(targetdir, self.filename)) else: suffix += "_kcchq" - if self.noHPV: - suffix += "_kccnh" - if self.noVPV: - suffix += "_kccnv" - if self.border: - suffix += "_kccxl" + str(self.border[0]) + "_kccyu" + str(self.border[1]) + "_kccxr" +\ - str(self.border[2]) + "_kccyd" + str(self.border[3]) - if forcepng: - self.image.save(os.path.join(targetdir, os.path.splitext(self.filename)[0] + suffix + ".png"), "PNG", - optimize=1) + if self.noPV: + suffix += "_kccnpv" else: - self.image.save(os.path.join(targetdir, os.path.splitext(self.filename)[0] + suffix + ".jpg"), "JPEG", - optimize=1) + if self.noHPV: + suffix += "_kccnh" + if self.noVPV: + suffix += "_kccnv" + if self.border: + suffix += "_kccxl" + str(self.border[0]) + "_kccyu" + str(self.border[1]) + "_kccxr" +\ + str(self.border[2]) + "_kccyd" + str(self.border[3]) + if not self.purge: + if forcepng: + self.image.save(os.path.join(targetdir, os.path.splitext(self.filename)[0] + suffix + ".png"), + "PNG", optimize=1) + else: + self.image.save(os.path.join(targetdir, os.path.splitext(self.filename)[0] + suffix + ".jpg"), + "JPEG", optimize=1) except IOError as e: raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e)) @@ -211,8 +217,12 @@ class ComicPage: return int(round(float(x)/float(img.image.size[1]), 4) * 10000 * 1.5) def calculateBorder(self, sourceImage, isHQ=False): + if isHQ and sourceImage.purge: + self.border = [0, 0, 0, 0] + self.noPV = True + return if self.fill == 'white': - # This code trigger only when sourceImage is already saved. So we can break color quantization. + # Only already saved files can have P mode. So we can break color quantization. if sourceImage.image.mode == 'P': sourceImage.image = sourceImage.image.convert('RGB') border = ImageChops.invert(sourceImage.image).getbbox() @@ -246,10 +256,13 @@ class ComicPage: size = (self.size[0], self.size[1]) else: size = (self.panelviewsize[0], self.panelviewsize[1]) - # If image is smaller than device resolution and upscale is off - Just expand it by adding margins - if self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1] and not upscale: - borderw = (self.size[0] - self.image.size[0]) / 2 - borderh = (self.size[1] - self.image.size[1]) / 2 + # If image is smaller than target resolution and upscale is off - Just expand it by adding margins + if self.image.size[0] <= size[0] and self.image.size[1] <= size[1] and not upscale: + borderw = (size[0] - self.image.size[0]) / 2 + borderh = (size[1] - self.image.size[1]) / 2 + # PV is disabled when source image is smaller than device screen and upscale is off - So we drop HQ image + if qualityMode == 2 and self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1]: + self.purge = True self.image = ImageOps.expand(self.image, border=(borderw, borderh), fill=fill) return self.image # If stretching is on - Resize without other considerations @@ -261,7 +274,7 @@ class ComicPage: self.image = self.image.resize(size, method) return self.image # Otherwise - Upscale/Downscale - ratioDev = float(self.size[0]) / float(self.size[1]) + ratioDev = float(size[0]) / float(size[1]) if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev: diff = int(self.image.size[1] * ratioDev) - self.image.size[0] self.image = ImageOps.expand(self.image, border=(diff / 2, 0), fill=fill) @@ -426,7 +439,7 @@ class ComicPage: def getImageFill(self): fill = 0 - # Search fom horizontal solid lines + # Search for horizontal solid lines startY = 0 stopY = 4 searching = True @@ -440,7 +453,7 @@ class ComicPage: startY = self.image.size[1] - 4 stopY = self.image.size[1] searching = False - # Search fom vertical solid lines + # Search for vertical solid lines startX = 0 stopX = 4 searching = True From 8fbe558f65796b777b15feda1060b7ec5c6844c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sun, 5 Jan 2014 12:13:38 +0100 Subject: [PATCH 13/27] Updated to Pillow 2.3.0 --- README.md | 3 +-- kcc.py | 2 +- kcc/KCC_gui.py | 2 +- kcc/cbxarchive.py | 2 +- kcc/comic2ebook.py | 21 +++++++++++++++++++++ kcc/comic2panel.py | 14 +++++--------- kcc/image.py | 12 ++++-------- 7 files changed, 34 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index ca49c56..c6dcd5c 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ You can find the latest released binary at the following links: - **Windows:** [http://kcc.vulturis.eu/Windows/](http://kcc.vulturis.eu/Windows/) - **Linux:** [http://kcc.vulturis.eu/Linux/](http://kcc.vulturis.eu/Linux/) - **OS X (10.8 or later):** [http://kcc.vulturis.eu/OSX/](http://kcc.vulturis.eu/OSX/) -- **OS X (10.7 or earlier):** Soon™ ## INPUT FORMATS **KCC** can understand and convert, at the moment, the following input types: @@ -43,7 +42,7 @@ You can find the latest released binary at the following links: ### For compiling/running from source: - Python 2.7 - Included in MacOS and Linux, follow the [official documentation](http://www.python.org/getit/windows/) to install on Windows. - [PyQt4](http://www.riverbankcomputing.co.uk/software/pyqt/download) - Please refer to official documentation for installing into your system. -- [Pillow](http://pypi.python.org/pypi/Pillow/) 2.2.1+ - For comic optimizations. Please refer to official documentation for installing into your system. +- [Pillow](http://pypi.python.org/pypi/Pillow/) 2.3.0+ - For comic optimizations. Please refer to official documentation for installing into your system. - [Psutil](https://code.google.com/p/psutil/) - Please refer to official documentation for installing into your system. - **To build OS X release you need a modified QT:** [patch](https://github.com/ciromattia/kcc/blob/master/other/QT-4.8.5-QListWidget.patch) diff --git a/kcc.py b/kcc.py index 84a0bcf..b3f0292 100644 --- a/kcc.py +++ b/kcc.py @@ -26,7 +26,7 @@ __docformat__ = 'restructuredtext en' import sys import os try: - #noinspection PyUnresolvedReferences + # noinspection PyUnresolvedReferences from PyQt4 import QtCore, QtGui, QtNetwork except ImportError: print "ERROR: PyQT4 is not installed!" diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 504d192..65e6756 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -40,7 +40,7 @@ from xml.dom.minidom import parse from HTMLParser import HTMLParser from KCC_rc_web import WebContent try: - #noinspection PyUnresolvedReferences + # noinspection PyUnresolvedReferences from psutil import TOTAL_PHYMEM, Popen except ImportError: print "ERROR: Psutil is not installed!" diff --git a/kcc/cbxarchive.py b/kcc/cbxarchive.py index e054dcf..7d56dfa 100644 --- a/kcc/cbxarchive.py +++ b/kcc/cbxarchive.py @@ -26,7 +26,7 @@ import locale from sys import platform from subprocess import STDOUT, PIPE try: - #noinspection PyUnresolvedReferences + # noinspection PyUnresolvedReferences from psutil import Popen except ImportError: print "ERROR: Psutil is not installed!" diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index c581585..85d4630 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -35,6 +35,27 @@ from optparse import OptionParser, OptionGroup from multiprocessing import Pool, freeze_support from xml.dom.minidom import parse from uuid import uuid4 +try: + # noinspection PyUnresolvedReferences + from PIL import Image + if tuple(map(int, ('2.3.0'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))): + print "ERROR: Pillow 2.3.0 or newer is required!" + if sys.platform.startswith('linux'): + import Tkinter + import tkMessageBox + importRoot = Tkinter.Tk() + importRoot.withdraw() + tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!") + exit(1) +except ImportError: + print "ERROR: Pillow is not installed!" + if sys.platform.startswith('linux'): + import Tkinter + import tkMessageBox + importRoot = Tkinter.Tk() + importRoot.withdraw() + tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!") + exit(1) try: from PyQt4 import QtCore except ImportError: diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py index 466b35e..f84a60a 100644 --- a/kcc/comic2panel.py +++ b/kcc/comic2panel.py @@ -29,29 +29,25 @@ from shutil import rmtree, copytree, move from optparse import OptionParser, OptionGroup from multiprocessing import Pool, freeze_support try: - #noinspection PyUnresolvedReferences + # noinspection PyUnresolvedReferences from PIL import Image, ImageStat - if tuple(map(int, ('2.2.1'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))): - print "ERROR: Pillow 2.2.1 or newer is required!" + if tuple(map(int, ('2.3.0'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))): + print "ERROR: Pillow 2.3.0 or newer is required!" if sys.platform.startswith('linux'): - #noinspection PyUnresolvedReferences import Tkinter - #noinspection PyUnresolvedReferences import tkMessageBox importRoot = Tkinter.Tk() importRoot.withdraw() - tkMessageBox.showerror("KCC - Error", "Pillow 2.2.1 or newer is required!") + tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!") exit(1) except ImportError: print "ERROR: Pillow is not installed!" if sys.platform.startswith('linux'): - #noinspection PyUnresolvedReferences import Tkinter - #noinspection PyUnresolvedReferences import tkMessageBox importRoot = Tkinter.Tk() importRoot.withdraw() - tkMessageBox.showerror("KCC - Error", "Pillow 2.2.1 or newer is required!") + tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!") exit(1) try: from PyQt4 import QtCore diff --git a/kcc/image.py b/kcc/image.py index 04895e3..ab19bcc 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -25,27 +25,23 @@ from sys import platform try: # noinspection PyUnresolvedReferences from PIL import Image, ImageOps, ImageStat, ImageChops - if tuple(map(int, ('2.2.1'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))): - print "ERROR: Pillow 2.2.1 or newer is required!" + if tuple(map(int, ('2.3.0'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))): + print "ERROR: Pillow 2.3.0 or newer is required!" if platform.startswith('linux'): - #noinspection PyUnresolvedReferences import Tkinter - #noinspection PyUnresolvedReferences import tkMessageBox importRoot = Tkinter.Tk() importRoot.withdraw() - tkMessageBox.showerror("KCC - Error", "Pillow 2.2.1 or newer is required!") + tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!") exit(1) except ImportError: print "ERROR: Pillow is not installed!" if platform.startswith('linux'): - #noinspection PyUnresolvedReferences import Tkinter - #noinspection PyUnresolvedReferences import tkMessageBox importRoot = Tkinter.Tk() importRoot.withdraw() - tkMessageBox.showerror("KCC - Error", "Pillow 2.2.1 or newer is required!") + tkMessageBox.showerror("KCC - Error", "Pillow 2.3.0 or newer is required!") exit(1) From 19ff6a51ccd63d98510a310a042034d294ecf3f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sun, 5 Jan 2014 13:41:53 +0100 Subject: [PATCH 14/27] WebToon splitter improvements --- README.md | 1 + kcc/comic2ebook.py | 6 ++-- kcc/comic2panel.py | 82 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c6dcd5c..0285234 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ Options: -y HEIGHT, --height=HEIGHT Height of the target device screen -i, --in-place Overwrite source directory + -m, --merge Combine every directory into a single image before splitting OTHER: -d, --debug Create debug file for every splitted image diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 85d4630..ffab9d4 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -953,12 +953,10 @@ def main(argv=None, qtGUI=None): path = getWorkFolder(args[0]) checkComicInfo(path + "/OEBPS/Images/", args[0]) if options.webtoon: - if GUI: - GUI.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Splitting images') if options.customheight > 0: - comic2panel.main(['-y ' + str(options.customheight), '-i', path], qtGUI) + comic2panel.main(['-y ' + str(options.customheight), '-i', '-m', path], qtGUI) else: - comic2panel.main(['-y ' + str(image.ProfileData.Profiles[options.profile][1][1]), '-i', path], qtGUI) + comic2panel.main(['-y ' + str(image.ProfileData.Profiles[options.profile][1][1]), '-i', '-m', path], qtGUI) if options.imgproc: print "\nProcessing images..." if GUI: diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py index f84a60a..f803ebe 100644 --- a/kcc/comic2panel.py +++ b/kcc/comic2panel.py @@ -69,6 +69,59 @@ def getImageFileName(imgfile): return filename +def walkLevel(some_dir, level=1): + some_dir = some_dir.rstrip(os.path.sep) + assert os.path.isdir(some_dir) + num_sep = some_dir.count(os.path.sep) + for root, dirs, files in os.walk(some_dir): + yield root, dirs, files + num_sep_this = root.count(os.path.sep) + if num_sep + level <= num_sep_this: + del dirs[:] + + +def mergeDirectory_tick(output): + if output: + mergeWorkerOutput.append(output) + mergeWorkerPool.terminate() + if GUI: + GUI.emit(QtCore.SIGNAL("progressBarTick")) + if not GUI.conversionAlive: + mergeWorkerPool.terminate() + + +def mergeDirectory(work): + try: + directory = work[0] + images = [] + imagesClear = [] + sizes = [] + for root, dirs, files in walkLevel(directory, 0): + for name in files: + if getImageFileName(name) is not None: + images.append([Image.open(os.path.join(root, name)), os.path.join(root, name)]) + if len(images) > 0: + for i in images: + sizes.append(i[0].size[0]) + mw = max(set(sizes), key=sizes.count) + for i in images: + if i[0].size[0] == mw: + i[0] = i[0].convert('RGB') + imagesClear.append(i) + h = sum(i[0].size[1] for i in imagesClear) + result = Image.new('RGB', (mw, h)) + y = 0 + for i in imagesClear: + result.paste(i[0], (0, y)) + y += i[0].size[1] + for i in imagesClear: + os.remove(i[1]) + savePath = os.path.split(imagesClear[0][1]) + result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG') + except StandardError: + return str(sys.exc_info()[1]) + + def sanitizePanelSize(panel, opt): newPanels = [] if panel[2] > 8 * opt.height: @@ -216,7 +269,7 @@ def Copyright(): def main(argv=None, qtGUI=None): - global options, GUI, splitWorkerPool, splitWorkerOutput + global options, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput parser = OptionParser(usage="Usage: %prog [options] comic_folder", add_help_option=False) mainOptions = OptionGroup(parser, "MANDATORY") otherOptions = OptionGroup(parser, "OTHER") @@ -224,6 +277,8 @@ def main(argv=None, qtGUI=None): help="Height of the target device screen") mainOptions.add_option("-i", "--in-place", action="store_true", dest="inPlace", default=False, help="Overwrite source directory") + mainOptions.add_option("-m", "--merge", action="store_true", dest="merge", default=False, + help="Combine every directory into a single image before splitting") otherOptions.add_option("-d", "--debug", action="store_true", dest="debug", default=False, help="Create debug file for every splitted image") otherOptions.add_option("-h", "--help", action="help", @@ -249,6 +304,29 @@ def main(argv=None, qtGUI=None): pagenumber = 0 splitWorkerOutput = [] splitWorkerPool = Pool() + if options.merge: + directoryNumer = 1 + mergeWork = [] + mergeWorkerOutput = [] + mergeWorkerPool = Pool() + mergeWork.append([options.targetDir]) + for root, dirs, files in os.walk(options.targetDir, False): + for directory in dirs: + directoryNumer += 1 + mergeWork.append([os.path.join(root, directory)]) + if GUI: + GUI.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Combining images') + GUI.emit(QtCore.SIGNAL("progressBarTick"), directoryNumer) + for i in mergeWork: + mergeWorkerPool.apply_async(func=mergeDirectory, args=(i, ), callback=mergeDirectory_tick) + mergeWorkerPool.close() + mergeWorkerPool.join() + if GUI and not GUI.conversionAlive: + rmtree(options.targetDir, True) + raise UserWarning("Conversion interrupted.") + if len(mergeWorkerOutput) > 0: + rmtree(options.targetDir, True) + raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0]) for root, dirs, files in os.walk(options.targetDir, False): for name in files: if getImageFileName(name) is not None: @@ -257,7 +335,9 @@ def main(argv=None, qtGUI=None): else: os.remove(os.path.join(root, name)) if GUI: + GUI.emit(QtCore.SIGNAL("progressBarTick"), 'status', 'Splitting images') GUI.emit(QtCore.SIGNAL("progressBarTick"), pagenumber) + GUI.emit(QtCore.SIGNAL("progressBarTick")) if len(work) > 0: for i in work: splitWorkerPool.apply_async(func=splitImage, args=(i, ), callback=splitImage_tick) From f9526349715709e808e50d1212477847f275ea62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sun, 5 Jan 2014 13:46:08 +0100 Subject: [PATCH 15/27] Refactored detection of corrupted files --- kcc/comic2ebook.py | 23 ++++++++++++++++++++--- kcc/comic2panel.py | 15 --------------- kcc/image.py | 21 ++------------------- 3 files changed, 22 insertions(+), 37 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index ffab9d4..a3e11c0 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -712,9 +712,6 @@ def sanitizeTreeBeforeConversion(filetree): for root, dirs, files in os.walk(filetree, False): for name in files: os.chmod(os.path.join(root, name), stat.S_IWRITE | stat.S_IREAD) - # Detect corrupted files - Phase 1 - if os.path.getsize(os.path.join(root, name)) == 0: - os.remove(os.path.join(root, name)) for name in dirs: os.chmod(os.path.join(root, name), stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC) @@ -870,6 +867,25 @@ def preSplitDirectory(path): return [path] +def detectCorruption(tmpPath, orgPath): + for root, dirs, files in os.walk(tmpPath, False): + for name in files: + if getImageFileName(name) is not None: + path = os.path.join(root, name) + pathOrg = os.path.join(orgPath, name) + if os.path.getsize(path) == 0: + rmtree(os.path.join(tmpPath, '..', '..'), True) + raise RuntimeError('Image file %s is corrupted.' % pathOrg) + try: + img = Image.open(path) + img.verify() + img = Image.open(path) + img.load() + except: + rmtree(os.path.join(tmpPath, '..', '..'), True) + raise RuntimeError('Image file %s is corrupted.' % pathOrg) + + def Copyright(): print ('comic2ebook v%(__version__)s. ' 'Written 2013 by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals()) @@ -951,6 +967,7 @@ def main(argv=None, qtGUI=None): parser.print_help() return path = getWorkFolder(args[0]) + detectCorruption(path + "/OEBPS/Images/", args[0]) checkComicInfo(path + "/OEBPS/Images/", args[0]) if options.webtoon: if options.customheight > 0: diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py index f803ebe..4fd86ed 100644 --- a/kcc/comic2panel.py +++ b/kcc/comic2panel.py @@ -170,21 +170,6 @@ def splitImage(work): print ".", fileExpanded = os.path.splitext(name) filePath = os.path.join(path, name) - # Detect corrupted files - try: - Image.open(filePath) - except IOError: - raise RuntimeError('Cannot read image file %s' % filePath) - try: - image = Image.open(filePath) - image.verify() - except: - raise RuntimeError('Image file %s is corrupted' % filePath) - try: - image = Image.open(filePath) - image.load() - except: - raise RuntimeError('Image file %s is corrupted' % filePath) image = Image.open(filePath) image = image.convert('RGB') widthImg, heightImg = image.size diff --git a/kcc/image.py b/kcc/image.py index ab19bcc..b1bde19 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -122,25 +122,8 @@ class ComicPage: self.profile_label, self.size, self.palette, self.gamma, self.panelviewsize = device except KeyError: raise RuntimeError('Unexpected output device %s' % device) - # Detect corrupted files - Phase 2 - try: - self.origFileName = source - self.filename = os.path.basename(self.origFileName) - self.image = Image.open(source) - except IOError: - raise RuntimeError('Cannot read image file %s' % source) - # Detect corrupted files - Phase 3 - try: - self.image = Image.open(source) - self.image.verify() - except: - raise RuntimeError('Image file %s is corrupted' % source) - # Detect corrupted files - Phase 4 - try: - self.image = Image.open(source) - self.image.load() - except: - raise RuntimeError('Image file %s is corrupted' % source) + self.origFileName = source + self.filename = os.path.basename(self.origFileName) self.image = Image.open(source) self.image = self.image.convert('RGB') self.rotated = None From e5e53d3aa7b423c10878f0cfd7b0d1046683c2a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sun, 5 Jan 2014 13:55:42 +0100 Subject: [PATCH 16/27] Fixed GUI logic --- kcc/KCC_gui.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 65e6756..82b994e 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -833,7 +833,7 @@ class KCCGUI(KCC_ui.Ui_KCC): else: tmpFormat = 0 GUI.FormatBox.setCurrentIndex(tmpFormat) - if str(GUI.FormatBox.currentText()) == 'CBZ': + if str(GUI.FormatBox.currentText()) == 'CBZ' or GUI.WebtoonBox.isChecked(): GUI.MangaBox.setEnabled(False) GUI.QualityBox.setEnabled(False) GUI.MangaBox.setChecked(False) @@ -845,6 +845,9 @@ class KCCGUI(KCC_ui.Ui_KCC): GUI.QualityBox.setEnabled(profile['Quality']) if not profile['Quality']: GUI.QualityBox.setChecked(False) + if GUI.ProcessingBox.isChecked(): + GUI.QualityBox.setEnabled(False) + GUI.QualityBox.setChecked(False) def stripTags(self, html): s = HTMLStripper() From 42d845cf078372cd69fd4f584a799edc41cd7334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sun, 5 Jan 2014 17:09:32 +0100 Subject: [PATCH 17/27] Image resize fix --- kcc/image.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kcc/image.py b/kcc/image.py index b1bde19..ef798de 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -243,6 +243,9 @@ class ComicPage: if qualityMode == 2 and self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1]: self.purge = True self.image = ImageOps.expand(self.image, border=(borderw, borderh), fill=fill) + # Border can't be float so sometimes image might be 1px too small/large + if self.image.size[0] != size[0] or self.image.size[1] != size[1]: + self.image = ImageOps.fit(self.image, size, method=Image.BICUBIC, centering=(0.5, 0.5)) return self.image # If stretching is on - Resize without other considerations if stretch: From 54f48d215691a46909e066db547cb01fb62cc63b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Tue, 7 Jan 2014 13:27:36 +0100 Subject: [PATCH 18/27] Fixed stretching images smaller than device screen --- kcc/image.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/kcc/image.py b/kcc/image.py index ef798de..b800816 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -235,6 +235,14 @@ class ComicPage: size = (self.size[0], self.size[1]) else: size = (self.panelviewsize[0], self.panelviewsize[1]) + # If stretching is on - Resize without other considerations + if stretch: + if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]: + method = Image.BICUBIC + else: + method = Image.ANTIALIAS + 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 if self.image.size[0] <= size[0] and self.image.size[1] <= size[1] and not upscale: borderw = (size[0] - self.image.size[0]) / 2 @@ -247,14 +255,6 @@ class ComicPage: if self.image.size[0] != size[0] or self.image.size[1] != size[1]: self.image = ImageOps.fit(self.image, size, method=Image.BICUBIC, centering=(0.5, 0.5)) return self.image - # If stretching is on - Resize without other considerations - if stretch: - if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]: - method = Image.BICUBIC - else: - method = Image.ANTIALIAS - self.image = self.image.resize(size, method) - return self.image # Otherwise - Upscale/Downscale ratioDev = float(size[0]) / float(size[1]) if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev: From eaff6cc6333766ec53e5fbbcad456fe6de267903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Tue, 7 Jan 2014 17:33:47 +0100 Subject: [PATCH 19/27] Replaced shutil.make_archive --- kcc/comic2ebook.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index a3e11c0..6f11015 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -29,8 +29,9 @@ import re import stat import string import unicodedata +import zipfile from tempfile import mkdtemp -from shutil import move, copyfile, copytree, rmtree, make_archive +from shutil import move, copyfile, copytree, rmtree from optparse import OptionParser, OptionGroup from multiprocessing import Pool, freeze_support from xml.dom.minidom import parse @@ -258,7 +259,7 @@ def buildOPF(dstdir, title, filelist, cover=None): "en-US\n", "", options.uuid, "\n"]) for author in options.authors: - f.writelines(["", author.encode('utf-8'), "\n"]) + f.writelines(["", author.encode('utf-8'), "\n"]) f.writelines(["\n", "\n", "\n", @@ -305,9 +306,6 @@ def buildOPF(dstdir, title, filelist, cover=None): f.write("\n\n\n\n") f.close() os.mkdir(os.path.join(dstdir, 'META-INF')) - f = open(os.path.join(dstdir, 'mimetype'), 'w') - f.write('application/epub+zip') - f.close() f = open(os.path.join(dstdir, 'META-INF', 'container.xml'), 'w') f.writelines(["\n", "\n", @@ -886,6 +884,21 @@ def detectCorruption(tmpPath, orgPath): raise RuntimeError('Image file %s is corrupted.' % pathOrg) +def makeZIP(zipFilename, baseDir, isEPUB=False): + zipFilename = os.path.abspath(zipFilename) + '.zip' + zipOutput = zipfile.ZipFile(zipFilename, 'w', zipfile.ZIP_DEFLATED) + if isEPUB: + zipOutput.writestr('mimetype', 'application/epub+zip', zipfile.ZIP_STORED) + for dirpath, dirnames, filenames in os.walk(baseDir): + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + aPath = os.path.normpath(os.path.join(dirpath.replace(baseDir, ''), name)) + if os.path.isfile(path): + zipOutput.write(path, aPath) + zipOutput.close() + return zipFilename + + def Copyright(): print ('comic2ebook v%(__version__)s. ' 'Written 2013 by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals()) @@ -1007,7 +1020,7 @@ def main(argv=None, qtGUI=None): filepath.append(getOutputFilename(args[0], options.output, '.cbz', ' ' + str(tomeNumber))) else: filepath.append(getOutputFilename(args[0], options.output, '.cbz', '')) - make_archive(tome + '_comic', 'zip', tome + '/OEBPS/Images') + makeZIP(tome + '_comic', tome + '/OEBPS/Images') else: print "\nCreating EPUB structure..." genEpubStruct(tome) @@ -1016,7 +1029,7 @@ def main(argv=None, qtGUI=None): filepath.append(getOutputFilename(args[0], options.output, '.epub', ' ' + str(tomeNumber))) else: filepath.append(getOutputFilename(args[0], options.output, '.epub', '')) - make_archive(tome + '_comic', 'zip', tome) + makeZIP(tome + '_comic', tome, True) move(tome + '_comic.zip', filepath[-1]) rmtree(tome, True) if GUI: From 34aaeab8b19674f3b8e3ad8dc18a517b4ef28e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Tue, 7 Jan 2014 17:52:51 +0100 Subject: [PATCH 20/27] Fixed GUI bug --- kcc/KCC_gui.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 82b994e..d6b0f03 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -1168,6 +1168,8 @@ class KCCGUI(KCC_ui.Ui_KCC): GUI.FormatBox.addItem(eval('self.icons.' + f + 'Format'), f) if self.lastDevice > GUI.DeviceBox.count(): self.lastDevice = 0 + if profilesGUI[self.lastDevice] == "Separator": + self.lastDevice = 0 if self.currentFormat > GUI.FormatBox.count(): self.currentFormat = 0 GUI.DeviceBox.setCurrentIndex(self.lastDevice) From def9e42a615ec5fcc257001453964f0203b085d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Sat, 11 Jan 2014 16:31:49 +0100 Subject: [PATCH 21/27] =?UTF-8?q?Yet=20another=20Last=E2=84=A2=20update=20?= =?UTF-8?q?of=20margin=20color=20detection=20algorithm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kcc/comic2ebook.py | 2 +- kcc/image.py | 54 ++++++++++++++++++---------------------------- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 6f11015..e756825 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -333,7 +333,7 @@ def getImageFileName(imgfile): def applyImgOptimization(img, opt, hqImage=None): if not img.fill: - img.getImageFill() + img.getImageFill(opt.webtoon) if not opt.webtoon: img.cropWhiteSpace(10.0) if opt.cutpagenumbers and not opt.webtoon: diff --git a/kcc/image.py b/kcc/image.py index b800816..596bccc 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -408,47 +408,35 @@ class ComicPage: RBGW.append(histogram[i] + histogram[256 + i] + histogram[512 + i]) white = 0 black = 0 - for i in range(253, 256): + for i in range(251, 256): white += RBGW[i] - for i in range(3): + for i in range(5): black += RBGW[i] - if black > pixelCount*0.5 and white == 0: + if black > pixelCount*0.8 and white == 0: return 1 - elif white > pixelCount*0.5 and black == 0: + elif white > pixelCount*0.8 and black == 0: return -1 else: return False - def getImageFill(self): + def getImageFill(self, webtoon): fill = 0 - # Search for horizontal solid lines - startY = 0 - stopY = 4 - searching = True - while stopY <= self.image.size[1]: - checkSolid = self.getImageHistogram(self.image.crop((0, startY, self.image.size[0], stopY))) - if checkSolid: - fill += checkSolid - startY = stopY + 1 - stopY = startY + 4 - if stopY > self.image.size[1] and searching: - startY = self.image.size[1] - 4 - stopY = self.image.size[1] - searching = False - # Search for vertical solid lines - startX = 0 - stopX = 4 - searching = True - while stopX <= self.image.size[0]: - checkSolid = self.getImageHistogram(self.image.crop((startX, 0, stopX, self.image.size[1]))) - if checkSolid: - fill += checkSolid - startX = stopX + 1 - stopX = startX + 4 - if stopX > self.image.size[0] and searching: - startX = self.image.size[0] - 4 - stopX = self.image.size[0] - searching = False + if not webtoon and not self.rotated: + # Search for horizontal solid lines + startY = 0 + while startY < self.image.size[1]: + checkSolid = self.getImageHistogram(self.image.crop((0, startY, self.image.size[0], startY+1))) + if checkSolid: + fill += checkSolid + startY += 1 + else: + # Search for vertical solid lines + startX = 0 + while startX < self.image.size[0]: + checkSolid = self.getImageHistogram(self.image.crop((startX, 0, startX+1, self.image.size[1]))) + if checkSolid: + fill += checkSolid + startX += 1 if fill > 0: self.fill = 'black' else: From a38013eabc51a4b068b97c0390d3aed074999bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Mon, 13 Jan 2014 14:03:43 +0100 Subject: [PATCH 22/27] README update + Version bump --- README.md | 24 ++++++++++++++++++------ kcc.iss | 2 +- kcc.py | 2 +- kcc/KCC_gui.py | 6 ++++-- kcc/__init__.py | 2 +- kcc/comic2ebook.py | 2 +- kcc/comic2panel.py | 2 +- kcc/kindlesplit.py | 6 +----- setup.py | 4 ++-- setup.sh | 2 +- 10 files changed, 31 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 0285234..ad985a7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # KCC -**Kindle Comic Converter** is a Python app to convert comic files or folders to ePub or Panel View MOBI. +**Kindle Comic Converter** is a Python app to convert comic files or folders to ePub, Panel View MOBI or E-Ink optimized CBZ. It was initally developed for Kindle but since v2.2 it outputs valid ePub 2.0 so _**despite its name, KCC is actually a comic to EPUB converter that every e-reader owner can happily use**_. It can also optionally optimize images by applying a number of transformations. @@ -11,7 +11,8 @@ Amazon's tool is for comic publishers and involves a lot of manual effort, while _KC2_ in no way is a replacement for **KCC** so you can be quite confident we'll going to carry on developing our little monster ;-) ### Issues / new features / donations -If you have some problems using KCC please [file an issue here](https://github.com/ciromattia/kcc/issues/new). +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)! @@ -23,12 +24,11 @@ If you find **KCC** valuable you can consider donating to the authors: You can find the latest released binary at the following links: - **Windows:** [http://kcc.vulturis.eu/Windows/](http://kcc.vulturis.eu/Windows/) - **Linux:** [http://kcc.vulturis.eu/Linux/](http://kcc.vulturis.eu/Linux/) -- **OS X (10.8 or later):** [http://kcc.vulturis.eu/OSX/](http://kcc.vulturis.eu/OSX/) +- **OS X 10.8+:** [http://kcc.vulturis.eu/OSX/](http://kcc.vulturis.eu/OSX/) ## INPUT FORMATS **KCC** can understand and convert, at the moment, the following input types: -- PNG, JPG, GIF, TIFF, BMP -- Folders +- Folders containing: PNG, JPG, GIF, TIFF or BMP files - CBZ, ZIP - CBR, RAR *(With `unrar` executable)* - CB7, 7Z *(With `7za` executable)* @@ -132,11 +132,14 @@ The app relies and includes the following scripts/binaries: * [Kindle Paperwhite](http://kcc.vulturis.eu/Samples/Ubunchu!-KPW.mobi) * [Kindle](http://kcc.vulturis.eu/Samples/Ubunchu!-K345.mobi) * [Kindle DX/DXG](http://kcc.vulturis.eu/Samples/Ubunchu!-KDX.mobi) -* [Kindle Fire](http://kcc.vulturis.eu/Samples/Ubunchu!-KF.mobi) * [Kindle Fire HD](http://kcc.vulturis.eu/Samples/Ubunchu!-KFHD.mobi) * [Kindle Fire HD 8.9"](http://kcc.vulturis.eu/Samples/Ubunchu!-KFHD8.mobi) * [Kindle Fire HDX](http://kcc.vulturis.eu/Samples/Ubunchu!-KFHDX.mobi) * [Kindle Fire HDX 8.9"](http://kcc.vulturis.eu/Samples/Ubunchu!-KFHDX8.mobi) +* [Kobo Mini/Touch](http://kcc.vulturis.eu/Samples/Ubunchu!-KoMT.cbz) +* [Kobo Glow](http://kcc.vulturis.eu/Samples/Ubunchu!-KoG.cbz) +* [Kobo Aura](http://kcc.vulturis.eu/Samples/Ubunchu!-KoA.cbz) +* [Kobo Aura HD](http://kcc.vulturis.eu/Samples/Ubunchu!-KoAHD.cbz) ## CHANGELOG ####1.0 @@ -294,6 +297,15 @@ The app relies and includes the following scripts/binaries: * Fixed previous PNG output fix * Fixed Panel View anomalies +####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 + ## COPYRIGHT Copyright (c) 2012-2013 Ciro Mattia Gonano and Paweł Jastrzębski. diff --git a/kcc.iss b/kcc.iss index 1273bab..6f18fe2 100644 --- a/kcc.iss +++ b/kcc.iss @@ -1,5 +1,5 @@ #define MyAppName "Kindle Comic Converter" -#define MyAppVersion "3.6.2" +#define MyAppVersion "3.7" #define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski" #define MyAppURL "http://kcc.vulturis.eu/" #define MyAppExeName "KCC.exe" diff --git a/kcc.py b/kcc.py index b3f0292..9037596 100644 --- 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__ = '3.6.2' +__version__ = '3.7' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index d6b0f03..29085b1 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__ = '3.6.2' +__version__ = '3.7' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' @@ -1076,7 +1076,9 @@ class KCCGUI(KCC_ui.Ui_KCC): statusBarLabel = QtGui.QLabel('HOMEPAGE - DONATE' - ' - WIKI') + ' - WIKI' + ' - FORUM' + '') statusBarLabel.setAlignment(QtCore.Qt.AlignCenter) statusBarLabel.setStyleSheet(self.statusBarStyle) statusBarLabel.setOpenExternalLinks(True) diff --git a/kcc/__init__.py b/kcc/__init__.py index 652089e..34a1962 100644 --- a/kcc/__init__.py +++ b/kcc/__init__.py @@ -1,4 +1,4 @@ -__version__ = '3.6.2' +__version__ = '3.7' __license__ = 'ISC' __copyright__ = '2012-2013, 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 e756825..65c1014 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -18,7 +18,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # -__version__ = '3.6.2' +__version__ = '3.7' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py index 4fd86ed..ad0d744 100644 --- a/kcc/comic2panel.py +++ b/kcc/comic2panel.py @@ -18,7 +18,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # -__version__ = '3.6.2' +__version__ = '3.7' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/kcc/kindlesplit.py b/kcc/kindlesplit.py index c8ae74d..c77994f 100644 --- a/kcc/kindlesplit.py +++ b/kcc/kindlesplit.py @@ -1,6 +1,6 @@ # Based on initial version of KindleUnpack. Copyright (C) 2009 Charles M. Hannum # Improvements Copyright (C) 2009-2012 P. Durrant, K. Hendricks, S. Siebert, fandrieu, DiapDealer, nickredding -# Copyright (C) 2013 Pawel Jastrzebski +# Changes for KCC Copyright (C) 2013 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 @@ -15,10 +15,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -__license__ = 'ISC' -__copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' -__docformat__ = 'restructuredtext en' - import struct # from uuid import uuid4 diff --git a/setup.py b/setup.py index 1a36ef9..98b03f1 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ Usage (Windows): from sys import platform NAME = "KindleComicConverter" -VERSION = "3.6.2" +VERSION = "3.7" MAIN = "kcc.py" if platform == "darwin": @@ -44,7 +44,7 @@ if platform == "darwin": CFBundleTypeRole='Viewer', ) ], - LSMinimumSystemVersion='10.6.0', + LSMinimumSystemVersion='10.8.0', LSEnvironment=dict( PATH='/usr/local/bin:/usr/bin:/bin' ), diff --git a/setup.sh b/setup.sh index b4487ca..6a63342 100644 --- a/setup.sh +++ b/setup.sh @@ -1,7 +1,7 @@ #!/bin/bash # Linux Python package build script -VERSION="3.6.2" +VERSION="3.7" cp kcc.py __main__.py zip kcc.zip __main__.py kcc/*.py From d944d6385e9cfdb78c248646850d62b33b589b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Mon, 13 Jan 2014 14:28:37 +0100 Subject: [PATCH 23/27] Updated VCRedist packages From 84d836bf0e4e2c091303b4caf881f2a4eb2708f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Mon, 13 Jan 2014 23:18:18 +0100 Subject: [PATCH 24/27] Temporary disabling HQ output for Kobo --- kcc/comic2ebook.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 65c1014..100b3e4 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -1088,8 +1088,8 @@ def checkOptions(): options.panelview = False options.quality = 0 # Enable 150% zoom for all non-HD Kobo models - if 'Ko' in options.profile and options.profile != "KoAHD": - options.quality = 1 + #if 'Ko' in options.profile and options.profile != "KoAHD": + #options.quality = 1 # Kindle for Android profile require target resolution. if options.profile == 'KFA' and (options.customwidth == 0 or options.customheight == 0): print "ERROR: Kindle for Android profile require --customwidth and --customheight options!" From 20712b6c42e85a40ee472756fe29e882ea197d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Mon, 13 Jan 2014 23:20:55 +0100 Subject: [PATCH 25/27] README update + Version bump --- README.md | 3 +++ kcc.iss | 2 +- kcc.py | 2 +- kcc/KCC_gui.py | 2 +- kcc/__init__.py | 2 +- kcc/comic2ebook.py | 2 +- kcc/comic2panel.py | 2 +- setup.py | 2 +- setup.sh | 2 +- 9 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ad985a7..ccc1d1b 100644 --- a/README.md +++ b/README.md @@ -306,6 +306,9 @@ The app relies and includes the following scripts/binaries: * Fixed stretching option * GUI tweaks and minor bugfixes +####3.7.1: +* Hotfixed Kobo profiles + ## COPYRIGHT Copyright (c) 2012-2013 Ciro Mattia Gonano and Paweł Jastrzębski. diff --git a/kcc.iss b/kcc.iss index 6f18fe2..358aca9 100644 --- a/kcc.iss +++ b/kcc.iss @@ -1,5 +1,5 @@ #define MyAppName "Kindle Comic Converter" -#define MyAppVersion "3.7" +#define MyAppVersion "3.7.1" #define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski" #define MyAppURL "http://kcc.vulturis.eu/" #define MyAppExeName "KCC.exe" diff --git a/kcc.py b/kcc.py index 9037596..3e3050e 100644 --- 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__ = '3.7' +__version__ = '3.7.1' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 29085b1..bdb6ae0 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__ = '3.7' +__version__ = '3.7.1' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/kcc/__init__.py b/kcc/__init__.py index 34a1962..9d699b2 100644 --- a/kcc/__init__.py +++ b/kcc/__init__.py @@ -1,4 +1,4 @@ -__version__ = '3.7' +__version__ = '3.7.1' __license__ = 'ISC' __copyright__ = '2012-2013, 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 100b3e4..613747a 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -18,7 +18,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # -__version__ = '3.7' +__version__ = '3.7.1' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py index ad0d744..d360f1f 100644 --- a/kcc/comic2panel.py +++ b/kcc/comic2panel.py @@ -18,7 +18,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # -__version__ = '3.7' +__version__ = '3.7.1' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/setup.py b/setup.py index 98b03f1..4032bba 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ Usage (Windows): from sys import platform NAME = "KindleComicConverter" -VERSION = "3.7" +VERSION = "3.7.1" MAIN = "kcc.py" if platform == "darwin": diff --git a/setup.sh b/setup.sh index 6a63342..4450a3d 100644 --- a/setup.sh +++ b/setup.sh @@ -1,7 +1,7 @@ #!/bin/bash # Linux Python package build script -VERSION="3.7" +VERSION="3.7.1" cp kcc.py __main__.py zip kcc.zip __main__.py kcc/*.py From 96a8c1d3547919a04f4ecd3680d5834da6f793ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Tue, 14 Jan 2014 15:54:08 +0100 Subject: [PATCH 26/27] Fixed problems with HQ mode (close #77) --- KCC-Linux.ui | 2 +- KCC-OSX.ui | 2 +- KCC.ui | 2 +- kcc/KCC_gui.py | 16 +++++++++++----- kcc/KCC_ui.py | 4 ++-- kcc/KCC_ui_linux.py | 4 ++-- kcc/KCC_ui_osx.py | 4 ++-- kcc/comic2ebook.py | 10 ++++++---- kcc/image.py | 3 +++ 9 files changed, 29 insertions(+), 18 deletions(-) diff --git a/KCC-Linux.ui b/KCC-Linux.ui index 6d8eaba..03bba46 100644 --- a/KCC-Linux.ui +++ b/KCC-Linux.ui @@ -388,7 +388,7 @@ p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode<br /></span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Use it when Panel View support is not needed.</span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;"><br /></span><span style=" font-family:'MS Shell Dlg 2';">- Maximum quality when zoom is not enabled.<br />- Poor quality when zoom is enabled.<br />- Lowest file size.</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br /></span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Not zoomed image </span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; font-style:italic;">might </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">be a little blurry.</span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;"><br /></span><span style=" font-family:'MS Shell Dlg 2';">- Medium/High quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br /></span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Not zoomed image </span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; font-style:italic;">might </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">be a little blurry.<br /></span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Smaller images might be forcefully upscaled in this mode.</span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;"><br /></span><span style=" font-family:'MS Shell Dlg 2';">- Medium/High quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;">Checked - Ultra quality mode<br /></span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Maximum possible quality.</span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600; text-decoration: underline;"><br /></span><span style=" font-family:'MS Shell Dlg 2';">- Maximum quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.<br />- Very high file size.</span></p></body></html> diff --git a/KCC-OSX.ui b/KCC-OSX.ui index 4896197..465af4b 100644 --- a/KCC-OSX.ui +++ b/KCC-OSX.ui @@ -388,7 +388,7 @@ Qt::NoFocus - <html><head/><body><p><span style="font-size:12pt; font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode<br/></span><span style="font-size:12pt; font-style:italic;">Use it when Panel View support is not needed.</span><span style="font-size:12pt; font-weight:600; text-decoration: underline;"><br/></span><span style="font-size:12pt;">- Maximum quality when zoom is not enabled.<br/>- Poor quality when zoom is enabled.<br/>- Lowest file size.</span></p><p><span style="font-size:12pt; font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br/></span><span style="font-size:12pt; font-style:italic;">Not zoomed image </span><span style="font-size:12pt; font-weight:600; font-style:italic;">might </span><span style="font-size:12pt; font-style:italic;">be a little blurry.</span><span style="font-size:12pt; font-weight:600; text-decoration: underline;"><br/></span><span style="font-size:12pt;">- Medium/High quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.</span></p><p><span style="font-size:12pt; font-weight:600; text-decoration: underline;">Checked - Ultra quality mode<br/></span><span style="font-size:12pt; font-style:italic;">Maximum possible quality.</span><span style="font-size:12pt; font-weight:600; text-decoration: underline;"><br/></span><span style="font-size:12pt;">- Maximum quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.<br/>- Very high file size.</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode<br/></span><span style=" font-size:12pt; font-style:italic;">Use it when Panel View support is not needed.</span><span style=" font-size:12pt; font-weight:600; text-decoration: underline;"><br/></span><span style=" font-size:12pt;">- Maximum quality when zoom is not enabled.<br/>- Poor quality when zoom is enabled.<br/>- Lowest file size.</span></p><p><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br/></span><span style=" font-size:12pt; font-style:italic;">Not zoomed image </span><span style=" font-size:12pt; font-weight:600; font-style:italic;">might </span><span style=" font-size:12pt; font-style:italic;">be a little blurry.<br/>Smaller images might be forcefully upscaled in this mode.</span><span style=" font-size:12pt; font-weight:600; text-decoration: underline;"><br/></span><span style=" font-size:12pt;">- Medium/High quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.</span></p><p><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Checked - Ultra quality mode<br/></span><span style=" font-size:12pt; font-style:italic;">Maximum possible quality.</span><span style=" font-size:12pt; font-weight:600; text-decoration: underline;"><br/></span><span style=" font-size:12pt;">- Maximum quality when zoom is not enabled.<br/>- Maximum quality when zoom is enabled.<br/>- Very high file size.</span></p></body></html> High/Ultra quality diff --git a/KCC.ui b/KCC.ui index 6725915..3d2e7b0 100644 --- a/KCC.ui +++ b/KCC.ui @@ -340,7 +340,7 @@ p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Unchecked - Normal quality mode<br /></span><span style=" font-style:italic;">Use it when Panel View support is not needed.</span><span style=" font-weight:600; text-decoration: underline;"><br /></span>- Maximum quality when zoom is not enabled.<br />- Poor quality when zoom is enabled.<br />- Lowest file size.</p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br /></span><span style=" font-style:italic;">Not zoomed image </span><span style=" font-weight:600; font-style:italic;">might </span><span style=" font-style:italic;">be </span><span style=" font-style:italic;">a little blurry.</span><span style=" font-weight:600; text-decoration: underline;"><br /></span>- Medium/High quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Indeterminate - High quality mode<br /></span><span style=" font-style:italic;">Not zoomed image </span><span style=" font-weight:600; font-style:italic;">might </span><span style=" font-style:italic;">be a little blurry.<br />Smaller images might be forcefully upscaled in this mode.</span><span style=" font-weight:600; text-decoration: underline;"><br /></span>- Medium/High quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Checked - Ultra quality mode<br /></span><span style=" font-style:italic;">Maximum possible quality.</span><span style=" font-weight:600; text-decoration: underline;"><br /></span>- Maximum quality when zoom is not enabled.<br />- Maximum quality when zoom is enabled.<br />- Very high file size.</p></body></html> diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index bdb6ae0..3c508f7 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -833,7 +833,8 @@ class KCCGUI(KCC_ui.Ui_KCC): else: tmpFormat = 0 GUI.FormatBox.setCurrentIndex(tmpFormat) - if str(GUI.FormatBox.currentText()) == 'CBZ' or GUI.WebtoonBox.isChecked(): + if (str(GUI.FormatBox.currentText()) == 'CBZ' and not 'Kobo' in str(GUI.DeviceBox.currentText())) or \ + GUI.WebtoonBox.isChecked(): GUI.MangaBox.setEnabled(False) GUI.QualityBox.setEnabled(False) GUI.MangaBox.setChecked(False) @@ -908,6 +909,11 @@ class KCCGUI(KCC_ui.Ui_KCC): self.addMessage('Target resolution is not set!', 'error') self.needClean = True return + if 'Kobo' in str(GUI.DeviceBox.currentText()) and GUI.QualityBox.checkState() == 2: + GUI.JobList.clear() + self.addMessage('Kobo devices can\'t use ultra quality mode!', 'error') + self.needClean = True + return self.worker.start() def hideProgressBar(self): @@ -1034,13 +1040,13 @@ class KCCGUI(KCC_ui.Ui_KCC): 'DefaultUpscale': True, 'Label': 'KFHDX'}, "K. Fire HDX 8.9\"": {'MangaMode': True, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'Label': 'KFHDX8'}, - "Kobo Mini/Touch": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 2, + "Kobo Mini/Touch": {'MangaMode': False, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 2, 'DefaultUpscale': False, 'Label': 'KoMT'}, - "Kobo Glow": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 2, + "Kobo Glow": {'MangaMode': False, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 2, 'DefaultUpscale': False, 'Label': 'KoG'}, - "Kobo Aura": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 2, + "Kobo Aura": {'MangaMode': False, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 2, 'DefaultUpscale': False, 'Label': 'KoA'}, - "Kobo Aura HD": {'MangaMode': False, 'Quality': False, 'ForceExpert': False, 'DefaultFormat': 2, + "Kobo Aura HD": {'MangaMode': False, 'Quality': True, 'ForceExpert': False, 'DefaultFormat': 2, 'DefaultUpscale': False, 'Label': 'KoAHD'}, "Other": {'MangaMode': False, 'Quality': False, 'ForceExpert': True, 'DefaultFormat': 1, 'DefaultUpscale': False, 'Label': 'OTHER'}, diff --git a/kcc/KCC_ui.py b/kcc/KCC_ui.py index 971239a..4a4eebb 100644 --- a/kcc/KCC_ui.py +++ b/kcc/KCC_ui.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'KCC.ui' # -# Created: Fri Dec 13 19:22:05 2013 +# Created: Tue Jan 14 15:50:02 2014 # by: PyQt4 UI code generator 4.10.3 # # WARNING! All changes made in this file will be lost! @@ -298,7 +298,7 @@ class Ui_KCC(object): "p, li { white-space: pre-wrap; }\n" "\n" "

Unchecked - Normal quality mode
Use it when Panel View support is not needed.
- Maximum quality when zoom is not enabled.
- Poor quality when zoom is enabled.
- Lowest file size.

\n" -"

Indeterminate - High quality mode
Not zoomed image might be a little blurry.
- Medium/High quality when zoom is not enabled.
- Maximum quality when zoom is enabled.

\n" +"

Indeterminate - High quality mode
Not zoomed image might be a little blurry.
Smaller images might be forcefully upscaled in this mode.

- Medium/High quality when zoom is not enabled.
- Maximum quality when zoom is enabled.

\n" "

Checked - Ultra quality mode
Maximum possible quality.
- Maximum quality when zoom is not enabled.
- Maximum quality when zoom is enabled.
- Very high file size.

", None)) self.QualityBox.setText(_translate("KCC", "High/Ultra quality", None)) self.RotateBox.setToolTip(_translate("KCC", "

Disable splitting of two-page spreads.
They will be rotated instead.

", None)) diff --git a/kcc/KCC_ui_linux.py b/kcc/KCC_ui_linux.py index 4aba880..55d17ea 100644 --- a/kcc/KCC_ui_linux.py +++ b/kcc/KCC_ui_linux.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'KCC-Linux.ui' # -# Created: Fri Dec 13 19:22:17 2013 +# Created: Tue Jan 14 15:50:14 2014 # by: PyQt4 UI code generator 4.10.3 # # WARNING! All changes made in this file will be lost! @@ -367,7 +367,7 @@ class Ui_KCC(object): "p, li { white-space: pre-wrap; }\n" "\n" "

Unchecked - Normal quality mode
Use it when Panel View support is not needed.
- Maximum quality when zoom is not enabled.
- Poor quality when zoom is enabled.
- Lowest file size.

\n" -"

Indeterminate - High quality mode
Not zoomed image might be a little blurry.
- Medium/High quality when zoom is not enabled.
- Maximum quality when zoom is enabled.

\n" +"

Indeterminate - High quality mode
Not zoomed image might be a little blurry.
Smaller images might be forcefully upscaled in this mode.
- Medium/High quality when zoom is not enabled.
- Maximum quality when zoom is enabled.

\n" "

Checked - Ultra quality mode
Maximum possible quality.
- Maximum quality when zoom is not enabled.
- Maximum quality when zoom is enabled.
- Very high file size.

", None)) self.QualityBox.setText(_translate("KCC", "High/Ultra quality", None)) self.RotateBox.setToolTip(_translate("KCC", "

Disable splitting of two-page spreads.
They will be rotated instead.

", None)) diff --git a/kcc/KCC_ui_osx.py b/kcc/KCC_ui_osx.py index 2c0ddb3..fc705edb5 100644 --- a/kcc/KCC_ui_osx.py +++ b/kcc/KCC_ui_osx.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'KCC-OSX.ui' # -# Created: Fri Dec 13 19:22:27 2013 +# Created: Tue Jan 14 15:50:25 2014 # by: PyQt4 UI code generator 4.10.3 # # WARNING! All changes made in this file will be lost! @@ -386,7 +386,7 @@ class Ui_KCC(object): self.ClearButton.setText(_translate("KCC", "Clear list", None)) self.MangaBox.setToolTip(_translate("KCC", "

Enable right-to-left reading.

", None)) self.MangaBox.setText(_translate("KCC", "Manga mode", None)) - self.QualityBox.setToolTip(_translate("KCC", "

Unchecked - Normal quality mode
Use it when Panel View support is not needed.
- Maximum quality when zoom is not enabled.
- Poor quality when zoom is enabled.
- Lowest file size.

Indeterminate - High quality mode
Not zoomed image might be a little blurry.
- Medium/High quality when zoom is not enabled.
- Maximum quality when zoom is enabled.

Checked - Ultra quality mode
Maximum possible quality.
- Maximum quality when zoom is not enabled.
- Maximum quality when zoom is enabled.
- Very high file size.

", None)) + self.QualityBox.setToolTip(_translate("KCC", "

Unchecked - Normal quality mode
Use it when Panel View support is not needed.
- Maximum quality when zoom is not enabled.
- Poor quality when zoom is enabled.
- Lowest file size.

Indeterminate - High quality mode
Not zoomed image might be a little blurry.
Smaller images might be forcefully upscaled in this mode.

- Medium/High quality when zoom is not enabled.
- Maximum quality when zoom is enabled.

Checked - Ultra quality mode
Maximum possible quality.
- Maximum quality when zoom is not enabled.
- Maximum quality when zoom is enabled.
- Very high file size.

", None)) self.QualityBox.setText(_translate("KCC", "High/Ultra quality", None)) self.RotateBox.setToolTip(_translate("KCC", "

Disable splitting of two-page spreads.
They will be rotated instead.

", None)) self.RotateBox.setText(_translate("KCC", "Horizontal mode", None)) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 613747a..7f69cd3 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -1084,12 +1084,14 @@ def checkOptions(): options.quality = 0 options.panelview = False # Disable all Kindle features for other e-readers - if options.profile == 'OTHER' or 'Ko' in options.profile: + if options.profile == 'OTHER': options.panelview = False options.quality = 0 - # Enable 150% zoom for all non-HD Kobo models - #if 'Ko' in options.profile and options.profile != "KoAHD": - #options.quality = 1 + if 'Ko' in options.profile: + options.panelview = False + # Kobo models can't use ultra quality mode + if options.quality == 2: + options.quality = 1 # Kindle for Android profile require target resolution. if options.profile == 'KFA' and (options.customwidth == 0 or options.customheight == 0): print "ERROR: Kindle for Android profile require --customwidth and --customheight options!" diff --git a/kcc/image.py b/kcc/image.py index 596bccc..87914f5 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -235,6 +235,9 @@ class ComicPage: size = (self.size[0], self.size[1]) else: size = (self.panelviewsize[0], self.panelviewsize[1]) + # If image is small and HQ mode is on we have to force upscaling. Otherwise non-zoomed image will be distorted + if self.image.size[0] <= size[0] and self.image.size[1] <= size[1] and qualityMode == 1 and not stretch: + upscale = True # If stretching is on - Resize without other considerations if stretch: if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]: From cf0b6b348486892140e172fa805519d2fad15569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Tue, 14 Jan 2014 15:57:52 +0100 Subject: [PATCH 27/27] README update + Version bump --- README.md | 3 +++ kcc.iss | 2 +- kcc.py | 2 +- kcc/KCC_gui.py | 2 +- kcc/__init__.py | 2 +- kcc/comic2ebook.py | 2 +- kcc/comic2panel.py | 2 +- setup.py | 2 +- setup.sh | 2 +- 9 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ccc1d1b..5935b47 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,9 @@ The app relies and includes the following scripts/binaries: ####3.7.1: * Hotfixed Kobo profiles +####3.7.2: +* Fixed problems with HQ mode + ## COPYRIGHT Copyright (c) 2012-2013 Ciro Mattia Gonano and Paweł Jastrzębski. diff --git a/kcc.iss b/kcc.iss index 358aca9..12a4115 100644 --- a/kcc.iss +++ b/kcc.iss @@ -1,5 +1,5 @@ #define MyAppName "Kindle Comic Converter" -#define MyAppVersion "3.7.1" +#define MyAppVersion "3.7.2" #define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski" #define MyAppURL "http://kcc.vulturis.eu/" #define MyAppExeName "KCC.exe" diff --git a/kcc.py b/kcc.py index 3e3050e..7785e70 100644 --- 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__ = '3.7.1' +__version__ = '3.7.2' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 3c508f7..5c46f24 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__ = '3.7.1' +__version__ = '3.7.2' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/kcc/__init__.py b/kcc/__init__.py index 9d699b2..e7c557e 100644 --- a/kcc/__init__.py +++ b/kcc/__init__.py @@ -1,4 +1,4 @@ -__version__ = '3.7.1' +__version__ = '3.7.2' __license__ = 'ISC' __copyright__ = '2012-2013, 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 7f69cd3..0bf6379 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -18,7 +18,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # -__version__ = '3.7.1' +__version__ = '3.7.2' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py index d360f1f..26a9cc5 100644 --- a/kcc/comic2panel.py +++ b/kcc/comic2panel.py @@ -18,7 +18,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # -__version__ = '3.7.1' +__version__ = '3.7.2' __license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano , Pawel Jastrzebski ' __docformat__ = 'restructuredtext en' diff --git a/setup.py b/setup.py index 4032bba..26317cb 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ Usage (Windows): from sys import platform NAME = "KindleComicConverter" -VERSION = "3.7.1" +VERSION = "3.7.2" MAIN = "kcc.py" if platform == "darwin": diff --git a/setup.sh b/setup.sh index 4450a3d..04b5fc4 100644 --- a/setup.sh +++ b/setup.sh @@ -1,7 +1,7 @@ #!/bin/bash # Linux Python package build script -VERSION="3.7.1" +VERSION="3.7.2" cp kcc.py __main__.py zip kcc.zip __main__.py kcc/*.py