1
0
mirror of https://github.com/ciromattia/kcc synced 2026-04-15 13:38:46 +00:00

Compare commits

...

19 Commits
5.2 ... 5.3

Author SHA1 Message Date
Paweł Jastrzębski
4647fd1f1d Merge pull request #224 from ciromattia/dev
5.3.0
2017-02-12 09:13:12 +01:00
Paweł Jastrzębski
010ad3c88c Updated README + version bump 2017-02-12 09:11:18 +01:00
Paweł Jastrzębski
4b0a94a8a0 Revert "Force admin rights for Windows version"
This reverts commit e1470cca15.
2017-02-06 19:21:33 +01:00
Paweł Jastrzębski
807a2d1dff Tweaked cover parsing 2017-02-05 08:53:09 +01:00
Paweł Jastrzębski
e1470cca15 Force admin rights for Windows version 2017-02-05 08:35:34 +01:00
Paweł Jastrzębski
02b9081e37 Improved compatibility with non-Kindle devices 2017-02-04 19:05:31 +01:00
Paweł Jastrzębski
495db88a9e Re-enabled Panel View support for Kindle Keyboard 2017-02-01 17:32:48 +01:00
Paweł Jastrzębski
2bea546a9d Re-enabled OS X file association mechanism 2017-01-21 22:34:39 +01:00
Paweł Jastrzębski
ee042ef98d Update build environment 2017-01-21 22:21:58 +01:00
bakatrouble
aea7c0fafb Fix unreadable text with dark qt themes
Fix unreadable text with dark qt themes #2 (file list)

Tweaks
2017-01-20 09:54:32 +01:00
Paweł Jastrzębski
45c1afcad4 Update build environment 2017-01-20 09:44:21 +01:00
Paweł Jastrzębski
b8e314f6ca Improved processing of credit pages 2016-12-08 10:36:05 +01:00
Paweł Jastrzębski
d76eea9f43 Merge pull request #216 from ciromattia/dev
5.2.1
2016-11-26 18:13:08 +01:00
Paweł Jastrzębski
2e55f22355 Updated README + version bump 2016-11-26 18:12:29 +01:00
Paweł Jastrzębski
30b8770e34 Improved error reporting 2016-11-26 17:59:40 +01:00
Paweł Jastrzębski
9ad161489f Decreased ferocity of margin cropping 2016-11-26 14:56:51 +01:00
Paweł Jastrzębski
bdb459cfab Code cleanup 2016-11-26 09:23:39 +01:00
Paweł Jastrzębski
2e85556543 GUI update 2016-11-25 18:57:42 +01:00
Paweł Jastrzębski
93ebbbd0af Refactored and improved output splitting 2016-11-25 18:05:05 +01:00
27 changed files with 201 additions and 273 deletions

3
.gitignore vendored
View File

@@ -12,5 +12,6 @@ kindlegen*
*.spec
setup.bat
setup.sh
kcc/sentry.py
kindlecomicconverter/sentry.py
build/
.python-version

View File

@@ -1,7 +1,7 @@
ISC LICENSE
Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
Copyright (c) 2013-2016 Paweł Jastrzębski <pawelj@iosphe.re>
Copyright (c) 2013-2017 Paweł Jastrzębski <pawelj@iosphe.re>
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the

View File

@@ -90,7 +90,10 @@ Options:
-f FORMAT, --format=FORMAT
Output format (Available options: Auto, MOBI, EPUB,
CBZ) [Default=Auto]
-b, --batchsplit Split output into multiple files
-b BATCHSPLIT, --batchsplit=BATCHSPLIT
Split output into multiple files. 0: Don't split 1:
Automatic mode 2: Consider every subdirectory as
separate volume [Default=0]
PROCESSING:
-u, --upscale Resize images smaller than device's resolution
@@ -160,6 +163,18 @@ The app relies and includes the following scripts:
* [Kobo Aura ONE](http://kcc.iosphe.re/Samples/Ubunchu-KoAO.kepub.epub)
## CHANGELOG
####5.3:
* Vastly improved output compatibility for non-Kindle devices
* Enabled old pinch zoom for Kindle devices
* Re-enabled Panel View support for Kindle Keyboard
* Partially re-enabled OS X file association mechanism
* Fixed multiple smaller issues
####5.2.1:
* Improved directory parsing
* Tweaked margin detection algorithm
* Improved error reporting
####5.2:
* Added new Panel View options
* Implemented new margin detection algorithm
@@ -487,5 +502,5 @@ The app relies and includes the following scripts:
Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues).
## COPYRIGHT
Copyright (c) 2012-2016 Ciro Mattia Gonano and Paweł Jastrzębski.
Copyright (c) 2012-2017 Ciro Mattia Gonano and Paweł Jastrzębski.
**KCC** is released under ISC LICENSE; see LICENSE.txt for further details.

View File

@@ -2,7 +2,7 @@
set -e
pip3 install --upgrade pip setuptools wheel
pip3 install pillow python-slugify psutil pyinstaller==3.1.1 raven pyqt5 certifi
pip3 install pillow python-slugify psutil pyinstaller raven pyqt5 certifi
gem install fpm
cd /app

View File

@@ -6,12 +6,9 @@ ADD ./Build /Build
RUN printf "deb http://httpredir.debian.org/debian stretch main" > /etc/apt/sources.list.d/stretch.list
RUN printf "Package: *\nPin: release a=testing\nPin-Priority: 400\n" > /etc/apt/preferences.d/stretch.pref
RUN printf "deb http://httpredir.debian.org/debian sid main" > /etc/apt/sources.list.d/sid.list
RUN printf "Package: *\nPin: release a=testing\nPin-Priority: 300\n" > /etc/apt/preferences.d/sid.pref
RUN apt-get update && apt-get -y dist-upgrade
RUN apt-get -y install build-essential curl ruby ruby-dev libpng-dev libjpeg-dev
RUN apt-get -y -t testing install python3 python3-dev
RUN apt-get -y -t unstable install python3-pyqt5
RUN apt-get -y -t testing install python3 python3-dev python3-pyqt5
RUN curl https://bootstrap.pypa.io/get-pip.py | python3
RUN apt-get clean -y && apt-get autoclean -y && apt-get autoremove -y && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

View File

@@ -47,7 +47,7 @@
<item row="2" column="0" colspan="2">
<widget class="QListWidget" name="jobList">
<property name="styleSheet">
<string notr="true">QListWidget#jobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}</string>
<string notr="true">QListWidget#jobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;color:rgb(0,0,0);}</string>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
@@ -66,16 +66,7 @@
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="2">
@@ -136,16 +127,7 @@
<item row="4" column="0" colspan="2">
<widget class="QWidget" name="optionWidget" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -228,12 +210,12 @@
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="noDitheringBox">
<widget class="QCheckBox" name="outputSplit">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Create PNG files instead JPEG.&lt;br/&gt;Quality increase is not noticeable on most of devices.&lt;br/&gt;Output files &lt;span style=&quot; font-weight:600;&quot;&gt;might&lt;/span&gt; be smaller.&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;MOBI conversion will be much slower.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - Automatic mode&lt;br/&gt;&lt;/span&gt;Output will be splitted automatically.&lt;/p&gt;&lt;p style='white-space:pre'&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Volume mode&lt;br/&gt;&lt;/span&gt;Every subdirectory will be considered as separate volume.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>PNG output</string>
<string>Output split</string>
</property>
</widget>
</item>
@@ -256,16 +238,7 @@
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item>
@@ -294,16 +267,7 @@
<item row="0" column="0" colspan="2">
<widget class="QWidget" name="toolWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item>
@@ -352,16 +316,7 @@
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -510,7 +465,7 @@
<tabstop>upscaleBox</tabstop>
<tabstop>gammaBox</tabstop>
<tabstop>borderBox</tabstop>
<tabstop>noDitheringBox</tabstop>
<tabstop>outputSplit</tabstop>
<tabstop>colorBox</tabstop>
<tabstop>editorButton</tabstop>
<tabstop>wikiButton</tabstop>

View File

@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -23,12 +23,12 @@ if sys.version_info[0] != 3:
print('ERROR: This is Python 3 script!')
exit(1)
from kcc.shared import dependencyCheck
from kindlecomicconverter.shared import dependencyCheck
dependencyCheck(2)
from multiprocessing import freeze_support
from kcc import __version__
from kcc.comic2ebook import main
from kindlecomicconverter import __version__
from kindlecomicconverter.comic2ebook import main
if __name__ == "__main__":
freeze_support()

View File

@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -23,12 +23,12 @@ if sys.version_info[0] != 3:
print('ERROR: This is Python 3 script!')
exit(1)
from kcc.shared import dependencyCheck
from kindlecomicconverter.shared import dependencyCheck
dependencyCheck(1)
from multiprocessing import freeze_support
from kcc import __version__
from kcc.comic2panel import main
from kindlecomicconverter import __version__
from kindlecomicconverter.comic2panel import main
if __name__ == "__main__":
freeze_support()

View File

@@ -1,5 +1,5 @@
#define MyAppName "Kindle Comic Converter"
#define MyAppVersion "5.2"
#define MyAppVersion "5.3.0"
#define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski"
#define MyAppURL "http://kcc.iosphe.re/"
#define MyAppExeName "KCC.exe"
@@ -12,7 +12,7 @@ AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
AppCopyright=Copyright (C) 2012-2016 Ciro Mattia Gonano and Paweł Jastrzębski
AppCopyright=Copyright (C) 2012-2017 Ciro Mattia Gonano and Paweł Jastrzębski
ArchitecturesAllowed=x64
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}

8
kcc.py
View File

@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -59,15 +59,15 @@ elif sys.platform.startswith('win'):
# Load additional Sentry configuration
if getattr(sys, 'frozen', False):
try:
import kcc.sentry
import kindlecomicconverter.sentry
except:
pass
from kcc.shared import dependencyCheck
from kindlecomicconverter.shared import dependencyCheck
dependencyCheck(3)
from multiprocessing import freeze_support
from kcc import KCC_gui
from kindlecomicconverter import KCC_gui
if __name__ == "__main__":
freeze_support()

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -21,17 +21,15 @@ import os
import sys
from urllib.parse import unquote
from urllib.request import urlopen, urlretrieve, Request
from time import sleep, time
from datetime import datetime
from time import sleep
from shutil import move
from subprocess import STDOUT, PIPE
from PyQt5 import QtGui, QtCore, QtWidgets, QtNetwork
from xml.dom.minidom import parse, Document
from xml.dom.minidom import parse
from psutil import Popen, Process
from copy import copy
from distutils.version import StrictVersion
from xml.sax.saxutils import escape
from platform import platform
from raven import Client
from .shared import md5Checksum, HTMLStripper, sanitizeTrace, saferRemove
from . import __version__
@@ -270,8 +268,8 @@ class WorkerThread(QtCore.QThread):
options.white_borders = True
elif GUI.borderBox.checkState() == 2:
options.black_borders = True
if GUI.noDitheringBox.isChecked():
options.forcepng = True
if GUI.outputSplit.isChecked():
options.batchsplit = 2
if GUI.colorBox.isChecked():
options.forcecolor = True
if GUI.currentMode > 2:
@@ -319,10 +317,15 @@ class WorkerThread(QtCore.QThread):
GUI.progress.content = ''
self.errors = True
_, _, traceback = sys.exc_info()
if len(err.args) == 1:
MW.showDialog.emit("Error during conversion %s:\n\n%s\n\nTraceback:\n%s"
% (jobargv[-1], str(err), sanitizeTrace(traceback)), 'error')
else:
MW.showDialog.emit("Error during conversion %s:\n\n%s\n\nTraceback:\n%s"
% (jobargv[-1], str(err.args[0]), err.args[1]), 'error')
GUI.sentry.extra_context({'realTraceback': err.args[1]})
if ' is corrupted.' not in str(err):
GUI.sentry.captureException()
MW.showDialog.emit("Error during conversion %s:\n\n%s\n\nTraceback:\n%s"
% (jobargv[-1], str(err), sanitizeTrace(traceback)), 'error')
MW.addMessage.emit('Error during conversion! Please consult '
'<a href="https://github.com/ciromattia/kcc/wiki/Error-messages">wiki</a> '
'for more details.', 'error', False)
@@ -528,7 +531,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
def clearJobs(self):
GUI.jobList.clear()
# noinspection PyCallByClass,PyTypeChecker,PyArgumentList
# noinspection PyCallByClass,PyTypeChecker
def openWiki(self):
QtGui.QDesktopServices.openUrl(QtCore.QUrl('https://github.com/ciromattia/kcc/wiki'))
@@ -646,6 +649,11 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
else:
GUI.formatBox.setCurrentIndex(profile['DefaultFormat'])
GUI.qualityBox.setEnabled(profile['PVOptions'])
if str(GUI.formatBox.currentText()) == 'MOBI/AZW3':
GUI.outputSplit.setEnabled(True)
else:
GUI.outputSplit.setEnabled(False)
GUI.outputSplit.setChecked(False)
def stripTags(self, html):
s = HTMLStripper()
@@ -664,7 +672,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
# We still fill original text field with transparent content to trigger creation of horizontal scrollbar
item.setForeground(QtGui.QColor('transparent'))
label = QtWidgets.QLabel(message)
label.setStyleSheet('background-image:url('');background-color:rgba(0,0,0,0);')
label.setStyleSheet('background-image:url('');background-color:rgba(0,0,0,0);color:rgb(0,0,0);')
label.setOpenExternalLinks(True)
GUI.jobList.addItem(item)
GUI.jobList.setItemWidget(item, label)
@@ -700,7 +708,6 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
self.conversionAlive = False
self.worker.sync()
else:
# noinspection PyArgumentList
if QtWidgets.QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier:
dname = QtWidgets.QFileDialog.getExistingDirectory(MW, 'Select output directory', self.lastPath)
if dname != '':
@@ -762,7 +769,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
'upscaleBox': GUI.upscaleBox.checkState(),
'borderBox': GUI.borderBox.checkState(),
'webtoonBox': GUI.webtoonBox.checkState(),
'noDitheringBox': GUI.noDitheringBox.checkState(),
'outputSplit': GUI.outputSplit.checkState(),
'colorBox': GUI.colorBox.checkState(),
'widthBox': GUI.widthBox.value(),
'heightBox': GUI.heightBox.value(),
@@ -848,7 +855,6 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
else:
self.addMessage('Download it and place executable in /usr/local/bin directory.', 'error')
# noinspection PyArgumentList
def __init__(self, KCCAplication, KCCWindow):
global APP, MW, GUI
APP = KCCAplication
@@ -928,7 +934,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
'DefaultUpscale': False, 'Label': 'K1'},
"Kindle 2": {'PVOptions': False, 'ForceExpert': False, 'DefaultFormat': 0,
'DefaultUpscale': False, 'Label': 'K2'},
"Kindle 3": {'PVOptions': False, 'ForceExpert': False, 'DefaultFormat': 0,
"Kindle 3": {'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0,
'DefaultUpscale': False, 'Label': 'K3'},
}
profilesGUI = [

View File

@@ -31,7 +31,7 @@ class Ui_mainWindow(object):
self.progressBar.setObjectName("progressBar")
self.gridLayout.addWidget(self.progressBar, 1, 0, 1, 2)
self.jobList = QtWidgets.QListWidget(self.centralWidget)
self.jobList.setStyleSheet("QListWidget#jobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}")
self.jobList.setStyleSheet("QListWidget#jobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;color:rgb(0,0,0);}")
self.jobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.jobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.jobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
@@ -97,9 +97,9 @@ class Ui_mainWindow(object):
self.borderBox.setTristate(True)
self.borderBox.setObjectName("borderBox")
self.gridLayout_2.addWidget(self.borderBox, 2, 0, 1, 1)
self.noDitheringBox = QtWidgets.QCheckBox(self.optionWidget)
self.noDitheringBox.setObjectName("noDitheringBox")
self.gridLayout_2.addWidget(self.noDitheringBox, 2, 1, 1, 1)
self.outputSplit = QtWidgets.QCheckBox(self.optionWidget)
self.outputSplit.setObjectName("outputSplit")
self.gridLayout_2.addWidget(self.outputSplit, 2, 1, 1, 1)
self.colorBox = QtWidgets.QCheckBox(self.optionWidget)
self.colorBox.setObjectName("colorBox")
self.gridLayout_2.addWidget(self.colorBox, 2, 2, 1, 1)
@@ -219,8 +219,8 @@ class Ui_mainWindow(object):
mainWindow.setTabOrder(self.webtoonBox, self.upscaleBox)
mainWindow.setTabOrder(self.upscaleBox, self.gammaBox)
mainWindow.setTabOrder(self.gammaBox, self.borderBox)
mainWindow.setTabOrder(self.borderBox, self.noDitheringBox)
mainWindow.setTabOrder(self.noDitheringBox, self.colorBox)
mainWindow.setTabOrder(self.borderBox, self.outputSplit)
mainWindow.setTabOrder(self.outputSplit, self.colorBox)
mainWindow.setTabOrder(self.colorBox, self.editorButton)
mainWindow.setTabOrder(self.editorButton, self.wikiButton)
mainWindow.setTabOrder(self.wikiButton, self.jobList)
@@ -251,8 +251,8 @@ class Ui_mainWindow(object):
self.gammaBox.setText(_translate("mainWindow", "Custom gamma"))
self.borderBox.setToolTip(_translate("mainWindow", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>"))
self.borderBox.setText(_translate("mainWindow", "W/B margins"))
self.noDitheringBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=\" font-weight:600;\">might</span> be smaller.<br/><span style=\" font-weight:600;\">MOBI conversion will be much slower.</span></p></body></html>"))
self.noDitheringBox.setText(_translate("mainWindow", "PNG output"))
self.outputSplit.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Automatic mode<br/></span>Output will be splitted automatically.</p><p style=\'white-space:pre\'><span style=\" font-weight:600; text-decoration: underline;\">Checked - Volume mode<br/></span>Every subdirectory will be considered as separate volume.</p></body></html>"))
self.outputSplit.setText(_translate("mainWindow", "Output split"))
self.colorBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Disable conversion to grayscale.</p></body></html>"))
self.colorBox.setText(_translate("mainWindow", "Color mode"))
self.gammaLabel.setText(_translate("mainWindow", "Gamma: Auto"))

View File

@@ -1,4 +1,4 @@
__version__ = '5.2'
__version__ = '5.3.0'
__license__ = 'ISC'
__copyright__ = '2012-2016, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__copyright__ = '2012-2017, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__docformat__ = 'restructuredtext en'

View File

@@ -1,5 +1,5 @@
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -46,7 +46,7 @@ try:
from scandir import walk
except ImportError:
walk = os.walk
from .shared import md5Checksum, getImageFileName, walkSort, walkLevel, saferReplace, saferRemove
from .shared import md5Checksum, getImageFileName, walkSort, walkLevel, saferReplace, saferRemove, sanitizeTrace
from . import comic2panel
from . import image
from . import cbxarchive
@@ -93,7 +93,6 @@ def buildHTML(path, imgfile, imgfilepath):
additionalStyle = 'background-color:#000000;'
else:
additionalStyle = 'background-color:#FFFFFF;'
htmlpath = ''
postfix = ''
backref = 1
head = path
@@ -107,6 +106,7 @@ def buildHTML(path, imgfile, imgfilepath):
if not os.path.exists(htmlpath):
os.makedirs(htmlpath)
htmlfile = os.path.join(htmlpath, filename[0] + '.xhtml')
imgsize = Image.open(os.path.join(head, "Images", postfix, imgfile)).size
f = open(htmlfile, "w", encoding='UTF-8')
f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE html>\n",
@@ -117,14 +117,15 @@ def buildHTML(path, imgfile, imgfilepath):
"<meta name=\"viewport\" "
"content=\"width=" + str(deviceres[0]) + ", height=" + str(deviceres[1]) + "\"/>\n"
"</head>\n",
"<body style=\"background-image: ",
"url('", "../" * backref, "Images/", postfix, imgfile, "'); " + additionalStyle + "\">\n"])
"<body style=\"" + additionalStyle + "\">\n",
"<div style=\"text-align:center;top:" + getTopMargin(deviceres, imgsize) + "%;\">\n",
"<img width=\"" + str(imgsize[0]) + "\" height=\"" + str(imgsize[1]) + "\" ",
"src=\"", "../" * backref, "Images/", postfix, imgfile, "\"/>\n</div>\n"])
if options.iskindle and options.panelview:
sizeTmp = Image.open(os.path.join(head, "Images", postfix, imgfile)).size
if options.autoscale:
size = (getPanelViewResolution(sizeTmp, deviceres))
size = (getPanelViewResolution(imgsize, deviceres))
else:
size = (int(sizeTmp[0] * 1.5), int(sizeTmp[1] * 1.5))
size = (int(imgsize[0] * 1.5), int(imgsize[1] * 1.5))
if size[0] - deviceres[0] < deviceres[0] * 0.01:
noHorizontalPV = True
else:
@@ -357,9 +358,6 @@ def buildEPUB(path, chapterNames, tomeNumber):
"display: block;\n",
"margin: 0;\n",
"padding: 0;\n",
"background-position: center center;\n",
"background-repeat: no-repeat;\n",
"background-size: auto auto;\n",
"}\n",
"#PV {\n",
"position: absolute;\n",
@@ -483,7 +481,7 @@ def imgDirectoryProcessing(path):
raise UserWarning("Conversion interrupted.")
if len(workerOutput) > 0:
rmtree(os.path.join(path, '..', '..'), True)
raise RuntimeError("One of workers crashed. Cause: " + workerOutput[0])
raise RuntimeError("One of workers crashed. Cause: " + workerOutput[0][0], workerOutput[0][1])
for file in options.imgPurgeIndex:
if os.path.isfile(file):
saferRemove(file)
@@ -493,7 +491,7 @@ def imgDirectoryProcessing(path):
def imgFileProcessingTick(output):
if isinstance(output, str):
if isinstance(output, tuple):
workerOutput.append(output)
workerPool.terminate()
else:
@@ -527,7 +525,7 @@ def imgFileProcessing(work):
output.append(img.saveToDir())
return output
except Exception:
return str(sys.exc_info()[:2])
return str(sys.exc_info()[1]), sanitizeTrace(sys.exc_info()[2])
def getWorkFolder(afile):
@@ -672,6 +670,11 @@ def getDirectorySize(start_path='.'):
return total_size
def getTopMargin(deviceres, size):
y = int((deviceres[1] - size[1]) / 2) / deviceres[1] * 100
return str(round(y, 1))
def getPanelViewResolution(imageSize, deviceRes):
scale = float(deviceRes[0]) / float(imageSize[0])
return int(deviceRes[0]), int(scale * imageSize[1])
@@ -734,63 +737,25 @@ def sanitizePermissions(filetree):
os.chmod(os.path.join(root, name), S_IWRITE | S_IREAD | S_IEXEC)
# noinspection PyUnboundLocalVariable
def splitDirectory(path):
# Detect directory stucture
for root, dirs, files in walkLevel(os.path.join(path, 'OEBPS', 'Images'), 0):
subdirectoryNumber = len(dirs)
filesNumber = len(files)
if subdirectoryNumber == 0:
# No subdirectories
mode = 0
level = -1
for root, _, files in os.walk(os.path.join(path, 'OEBPS', 'Images')):
for f in files:
if f.endswith('.jpg') or f.endswith('.jpeg') or f.endswith('.png') or f.endswith('.gif'):
newLevel = os.path.join(root, f).replace(os.path.join(path, 'OEBPS', 'Images'), '').count(os.sep)
if level != -1 and level != newLevel:
level = 0
break
else:
level = newLevel
if level > 0:
splitter = splitProcess(os.path.join(path, 'OEBPS', 'Images'), level)
path = [path]
for tome in splitter:
path.append(tome)
return path
else:
if filesNumber > 0:
print('WARNING: Automatic output splitting failed.')
if GUI:
GUI.addMessage.emit('Automatic output splitting failed. <a href='
'"https://github.com/ciromattia/kcc/wiki'
'/Automatic-output-splitting">'
'More details.</a>', 'warning', False)
GUI.addMessage.emit('', '', False)
return [path]
detectedSubSubdirectories = False
detectedFilesInSubdirectories = False
for root, dirs, files in walkLevel(os.path.join(path, 'OEBPS', 'Images'), 1):
if root != os.path.join(path, 'OEBPS', 'Images'):
if len(dirs) != 0:
detectedSubSubdirectories = True
elif len(dirs) == 0 and detectedSubSubdirectories:
print('WARNING: Automatic output splitting failed.')
if GUI:
GUI.addMessage.emit('Automatic output splitting failed. <a href='
'"https://github.com/ciromattia/kcc/wiki'
'/Automatic-output-splitting">'
'More details.</a>', 'warning', False)
GUI.addMessage.emit('', '', False)
return [path]
if len(files) != 0:
detectedFilesInSubdirectories = True
if detectedSubSubdirectories:
# Two levels of subdirectories
mode = 2
else:
# One level of subdirectories
mode = 1
if detectedFilesInSubdirectories and detectedSubSubdirectories:
print('WARNING: Automatic output splitting failed.')
if GUI:
GUI.addMessage.emit('Automatic output splitting failed. <a href='
'"https://github.com/ciromattia/kcc/wiki'
'/Automatic-output-splitting">'
'More details.</a>', 'warning', False)
GUI.addMessage.emit('', '', False)
return [path]
# Split directories
splitter = splitProcess(os.path.join(path, 'OEBPS', 'Images'), mode)
path = [path]
for tome in splitter:
path.append(tome)
return path
raise UserWarning('Unsupported directory structure.')
def splitProcess(path, mode):
@@ -801,10 +766,15 @@ def splitProcess(path, mode):
targetSize = 104857600
else:
targetSize = 419430400
if mode == 0:
if options.batchsplit == 2 and mode == 2:
mode = 3
if mode < 3:
for root, dirs, files in walkLevel(path, 0):
for name in files:
size = os.path.getsize(os.path.join(root, name))
for name in files if mode == 1 else dirs:
if mode == 1:
size = os.path.getsize(os.path.join(root, name))
else:
size = getDirectorySize(os.path.join(root, name))
if currentSize + size > targetSize:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
@@ -813,48 +783,16 @@ def splitProcess(path, mode):
currentSize += size
if path != currentTarget:
move(os.path.join(root, name), os.path.join(currentTarget, name))
elif mode == 1:
for root, dirs, files in walkLevel(path, 0):
for name in dirs:
size = getDirectorySize(os.path.join(root, name))
if currentSize + size > targetSize:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
currentSize = size
else:
currentSize += size
if path != currentTarget:
move(os.path.join(root, name), os.path.join(currentTarget, name))
elif mode == 2:
else:
firstTome = True
for root, dirs, files in walkLevel(path, 0):
for name in dirs:
size = getDirectorySize(os.path.join(root, name))
currentSize = 0
if size > targetSize:
if not firstTome:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
else:
firstTome = False
for rootInside, dirsInside, filesInside in walkLevel(os.path.join(root, name), 0):
for nameInside in dirsInside:
size = getDirectorySize(os.path.join(rootInside, nameInside))
if currentSize + size > targetSize:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
currentSize = size
else:
currentSize += size
if path != currentTarget:
move(os.path.join(rootInside, nameInside), os.path.join(currentTarget, nameInside))
if not firstTome:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
move(os.path.join(root, name), os.path.join(currentTarget, name))
else:
if not firstTome:
currentTarget, pathRoot = createNewTome()
output.append(pathRoot)
move(os.path.join(root, name), os.path.join(currentTarget, name))
else:
firstTome = False
firstTome = False
return output
@@ -886,10 +824,10 @@ def detectCorruption(tmpPath, orgPath):
else:
saferRemove(os.path.join(root, name))
if imageSmaller > imageNumber * 0.25 and not options.upscale and not options.stretch:
print("WARNING: More than 1/4 of images are smaller than target device resolution. "
print("WARNING: More than 25% of images are smaller than target device resolution. "
"Consider enabling stretching or upscaling to improve readability.")
if GUI:
GUI.addMessage.emit('More than 1/4 of images are smaller than target device resolution.', 'warning', False)
GUI.addMessage.emit('More than 25% of images are smaller than target device resolution.', 'warning', False)
GUI.addMessage.emit('Consider enabling stretching or upscaling to improve readability.', 'warning', False)
GUI.addMessage.emit('', '', False)
@@ -947,8 +885,9 @@ def makeParser():
help="Comic title [Default=filename or directory name]")
outputOptions.add_option("-f", "--format", action="store", dest="format", default="Auto",
help="Output format (Available options: Auto, MOBI, EPUB, CBZ) [Default=Auto]")
outputOptions.add_option("-b", "--batchsplit", action="store_true", dest="batchsplit", default=False,
help="Split output into multiple files"),
outputOptions.add_option("-b", "--batchsplit", type="int", dest="batchsplit", default="0",
help="Split output into multiple files. 0: Don't split 1: Automatic mode "
"2: Consider every subdirectory as separate volume [Default=0]")
processingOptions.add_option("-u", "--upscale", action="store_true", dest="upscale", default=False,
help="Resize images smaller than device's resolution")
@@ -1006,10 +945,10 @@ def checkOptions():
if options.black_borders:
options.bordersColor = 'black'
# Splitting MOBI is not optional
if options.format == 'MOBI':
options.batchsplit = True
# Older Kindle don't need higher resolution files due lack of Panel View.
if options.profile == 'K1' or options.profile == 'K2' or options.profile == 'K3' or options.profile == 'KDX':
if options.format == 'MOBI' and options.batchsplit != 2:
options.batchsplit = 1
# Older Kindle models don't support Panel View.
if options.profile == 'K1' or options.profile == 'K2' or options.profile == 'KDX':
options.panelview = False
# Webtoon mode mandatory options
if options.webtoon:
@@ -1092,8 +1031,8 @@ def makeBook(source, qtGUI=None):
getComicInfo(os.path.join(path, "OEBPS", "Images"), source)
detectCorruption(os.path.join(path, "OEBPS", "Images"), source)
if options.webtoon:
if image.ProfileData.Profiles[options.profile][1][1] > 1000:
y = 1000
if image.ProfileData.Profiles[options.profile][1][1] > 1024:
y = 1024
else:
y = image.ProfileData.Profiles[options.profile][1][1]
comic2panel.main(['-y ' + str(y), '-i', '-m', path], qtGUI)
@@ -1106,7 +1045,7 @@ def makeBook(source, qtGUI=None):
chapterNames = sanitizeTree(os.path.join(path, 'OEBPS', 'Images'))
if 'Ko' in options.profile and options.format == 'CBZ':
sanitizeTreeKobo(os.path.join(path, 'OEBPS', 'Images'))
if options.batchsplit:
if options.batchsplit > 0:
tomes = splitDirectory(path)
else:
tomes = [path]

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -24,7 +24,7 @@ from shutil import rmtree, copytree, move
from optparse import OptionParser, OptionGroup
from multiprocessing import Pool
from PIL import Image, ImageStat, ImageOps
from .shared import getImageFileName, walkLevel, walkSort, saferRemove
from .shared import getImageFileName, walkLevel, walkSort, saferRemove, sanitizeTrace
try:
from PyQt5 import QtCore
except ImportError:
@@ -81,7 +81,7 @@ def mergeDirectory(work):
savePath = os.path.split(imagesValid[0])
result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG')
except Exception:
return str(sys.exc_info()[1])
return str(sys.exc_info()[1]), sanitizeTrace(sys.exc_info()[2])
def sanitizePanelSize(panel, opt):
@@ -205,7 +205,7 @@ def splitImage(work):
pageNumber += 1
saferRemove(filePath)
except Exception:
return str(sys.exc_info()[1])
return str(sys.exc_info()[1]), sanitizeTrace(sys.exc_info()[2])
def main(argv=None, qtGUI=None):
@@ -267,7 +267,7 @@ def main(argv=None, qtGUI=None):
raise UserWarning("Conversion interrupted.")
if len(mergeWorkerOutput) > 0:
rmtree(options.targetDir, True)
raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0])
raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0][0], mergeWorkerOutput[0][1])
print("Splitting images...")
for root, dirs, files in walk(options.targetDir, False):
for name in files:
@@ -290,7 +290,7 @@ def main(argv=None, qtGUI=None):
raise UserWarning("Conversion interrupted.")
if len(splitWorkerOutput) > 0:
rmtree(options.targetDir, True)
raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0])
raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0][0], splitWorkerOutput[0][1])
if options.inPlace:
rmtree(options.sourceDir)
move(options.targetDir, options.sourceDir)

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Based on initial version of DualMetaFix. Copyright (C) 2013 Kevin Hendricks
# Changes for KCC Copyright (C) 2014-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Changes for KCC Copyright (C) 2014-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# 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

View File

@@ -2,7 +2,7 @@
# Copyright (C) 2011 Stanislav (proDOOMman) Kosolapov <prodoomman@gmail.com>
# Copyright (c) 2016 Alberto Planas <aplanas@gmail.com>
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# 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
@@ -119,15 +119,15 @@ class ComicPageParser:
def splitCheck(self):
width, height = self.image.size
dstwidth, dstheight = self.size
# Only split if origin is not oriented the same as target
if (width > height) != (dstwidth > dstheight) and not self.opt.webtoon:
if (width > height) != (dstwidth > dstheight) and width <= dstheight and height <= dstwidth \
and not self.opt.webtoon:
self.payload.append(['R', self.source, self.image.rotate(90, Image.BICUBIC, True), self.color, self.fill])
elif (width > height) != (dstwidth > dstheight) and not self.opt.webtoon:
if self.opt.splitter != 1:
if width > height:
# Source is landscape, so split by the width
leftbox = (0, 0, int(width / 2), height)
rightbox = (int(width / 2), 0, width, height)
else:
# Source is portrait and target is landscape, so split by the height
leftbox = (0, 0, width, int(height / 2))
rightbox = (0, int(height / 2), width, height)
if self.opt.righttoleft:
@@ -318,7 +318,7 @@ class ComicPage:
tmpImg = tmpImg.point(lambda x: x and 255)
tmpImg = tmpImg.filter(ImageFilter.MinFilter(size=3))
tmpImg = tmpImg.filter(ImageFilter.GaussianBlur(radius=5))
tmpImg = tmpImg.point(lambda x: (x >= 48 * power) and x)
tmpImg = tmpImg.point(lambda x: (x >= 16 * power) and x)
self.image = self.image.crop(tmpImg.getbbox()) if tmpImg.getbbox() else self.image
def cropMargin(self, power):
@@ -345,34 +345,20 @@ class Cover:
source = urlopen(Request(quote(self.options.remoteCovers[self.tomeNumber]).replace('%3A', ':', 1),
headers={'User-Agent': 'KindleComicConverter/' + __version__})).read()
self.image = Image.open(BytesIO(source))
self.processExternal()
except Exception:
self.image = Image.open(source)
self.processInternal()
else:
self.image = Image.open(source)
self.processInternal()
self.process()
def processInternal(self):
self.image = self.image.convert('RGB')
self.image = self.trim()
self.save()
def processExternal(self):
def process(self):
self.image = self.image.convert('RGB')
self.image = ImageOps.autocontrast(self.image)
if not self.options.forcecolor:
self.image = self.image.convert('L')
self.image.thumbnail(self.options.profileData[1], Image.LANCZOS)
self.save()
def trim(self):
bg = Image.new(self.image.mode, self.image.size, self.image.getpixel((0, 0)))
diff = ImageChops.difference(self.image, bg)
diff = ImageChops.add(diff, diff, 2.0, -100)
bbox = diff.getbbox()
if bbox:
return self.image.crop(bbox)
else:
return self.image
def save(self):
try:
self.image.save(self.target, "JPEG", optimize=1, quality=80)
@@ -380,7 +366,7 @@ class Cover:
raise RuntimeError('Failed to process downloaded cover.')
def saveToKindle(self, kindle, asin):
self.image = self.image.resize((300, 470), Image.ANTIALIAS).convert('L')
self.image = self.image.resize((300, 470), Image.ANTIALIAS)
try:
self.image.save(os.path.join(kindle.path.split('documents')[0], 'system', 'thumbnails',
'thumbnail_' + asin + '_EBOK_portrait.jpg'), 'JPEG')

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the

View File

@@ -1,5 +1,5 @@
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Based upon the code snippet by Ned Batchelder
# (http://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html)
@@ -61,7 +61,6 @@ class PdfJpgExtract:
iend += endfix
jpg = pdf[istart:iend]
jpgfile = open(self.path + "/jpg%d.jpg" % njpg, "wb")
# noinspection PyTypeChecker
jpgfile.write(jpg)
jpgfile.close()
njpg += 1

View File

@@ -1,5 +1,5 @@
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
# Copyright (c) 2013-2016 Pawel Jastrzebski <pawelj@iosphe.re>
# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
@@ -144,7 +144,10 @@ def removeFromZIP(zipfname, *filenames):
def sanitizeTrace(traceback):
return ''.join(format_tb(traceback))\
.replace('C:\\Users\\Pawel\\Documents\\Projekty\\KCC\\', '') \
.replace('C:/Users/Pawel/Documents/Projekty/KCC/', '')\
.replace('C:/Python35/', '')\
.replace('c:/python35/', '')\
.replace('C:\\Users\\Pawel\\Documents\\Projekty\\KCC\\', '')\
.replace('C:\\Python35\\', '')\
.replace('c:\\python35\\', '')

View File

@@ -6,10 +6,31 @@
<string>English</string>
<key>CFBundleDisplayName</key>
<string>Kindle Comic Converter</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>cbz</string>
<string>cbr</string>
<string>cb7</string>
<string>zip</string>
<string>rar</string>
<string>7z</string>
<string>pdf</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>comic2ebook.icns</string>
<key>CFBundleTypeName</key>
<string>Comics</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>MacOS/Kindle Comic Converter</string>
<key>CFBundleGetInfoString</key>
<string>KindleComicConverter 5.2, written 2012-2016 by Ciro Mattia Gonano and Pawel Jastrzebski</string>
<string>KindleComicConverter 5.3.0, written 2012-2017 by Ciro Mattia Gonano and Pawel Jastrzebski</string>
<key>CFBundleIconFile</key>
<string>comic2ebook.icns</string>
<key>CFBundleIdentifier</key>
@@ -21,11 +42,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>5.2.0</string>
<string>5.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>5.2.0</string>
<string>5.3.0</string>
<key>LSEnvironment</key>
<dict>
<key>PATH</key>

View File

@@ -15,7 +15,7 @@ import shutil
import setuptools
import distutils.cmd
from distutils.command.build import build
from kcc import __version__
from kindlecomicconverter import __version__
NAME = 'KindleComicConverter'
MAIN = 'kcc.py'
@@ -38,7 +38,10 @@ class BuildBinaryCommand(distutils.cmd.Command):
def run(self):
if sys.platform == 'darwin':
os.system('pyinstaller -y -F -i icons/comic2ebook.icns -n "Kindle Comic Converter" -w -s --noupx kcc.py')
if os.path.isfile('Kindle Comic Converter.spec'):
os.system('pyinstaller "Kindle Comic Converter.spec"')
else:
os.system('pyinstaller -y -F -i icons/comic2ebook.icns -n "Kindle Comic Converter" -w -s --noupx kcc.py')
shutil.copy('other/osx/7za', 'dist/Kindle Comic Converter.app/Contents/Resources')
shutil.copy('other/osx/unrar', 'dist/Kindle Comic Converter.app/Contents/Resources')
shutil.copy('other/osx/Info.plist', 'dist/Kindle Comic Converter.app/Contents')
@@ -51,7 +54,10 @@ class BuildBinaryCommand(distutils.cmd.Command):
os.system('appdmg kcc.json dist/KindleComicConverter_osx_' + VERSION + '.dmg')
exit(0)
elif sys.platform == 'win32':
os.system('pyinstaller -y -F -i icons\comic2ebook.ico -n KCC -w --noupx kcc.py')
if os.path.isfile('KCC.spec'):
os.system('pyinstaller KCC.spec')
else:
os.system('pyinstaller -y -F -i icons\comic2ebook.ico -n KCC -w --noupx kcc.py')
if os.path.isfile('setup.bat'):
os.system('setup.bat')
exit(0)
@@ -59,19 +65,19 @@ class BuildBinaryCommand(distutils.cmd.Command):
if self.pyz:
script = '''
cp kcc.py __main__.py
zip kcc.zip __main__.py kcc/*.py
zip kcc.zip __main__.py kindlecomicconverter/*.py
echo "#!/usr/bin/env python3" > kcc-bin
cat kcc.zip >> kcc-bin
chmod +x kcc-bin
cp kcc-c2e.py __main__.py
zip kcc-c2e.zip __main__.py kcc/*.py
zip kcc-c2e.zip __main__.py kindlecomicconverter/*.py
echo "#!/usr/bin/env python3" > kcc-c2e-bin
cat kcc-c2e.zip >> kcc-c2e-bin
chmod +x kcc-c2e-bin
cp kcc-c2p.py __main__.py
zip kcc-c2p.zip __main__.py kcc/*.py
zip kcc-c2p.zip __main__.py kindlecomicconverter/*.py
echo "#!/usr/bin/env python3" > kcc-c2p-bin
cat kcc-c2p.zip >> kcc-c2p-bin
chmod +x kcc-c2p-bin