diff options
author | Paweł Jastrzębski <pawelj@iosphe.re> | 2014-11-24 20:13:17 +0100 |
---|---|---|
committer | Paweł Jastrzębski <pawelj@iosphe.re> | 2014-11-24 20:13:17 +0100 |
commit | bd665c326198f0c44a43fb844dd7a994c34f4649 (patch) | |
tree | 697e1a8a0f42ac1d05c9441aa59ca996fca3be1d | |
parent | Merge pull request #113 from ciromattia/4.x (diff) | |
parent | Version bump (diff) | |
download | kcc-bd665c326198f0c44a43fb844dd7a994c34f4649.tar.gz kcc-bd665c326198f0c44a43fb844dd7a994c34f4649.tar.bz2 kcc-bd665c326198f0c44a43fb844dd7a994c34f4649.zip |
Merge pull request #119 from ciromattia/4.x
4.3.1
-rw-r--r-- | README.md | 7 | ||||
-rwxr-xr-x | kcc-c2e.py | 2 | ||||
-rwxr-xr-x | kcc-c2p.py | 2 | ||||
-rw-r--r-- | kcc.iss | 2 | ||||
-rwxr-xr-x | kcc.py | 9 | ||||
-rw-r--r-- | kcc/KCC_gui.py | 28 | ||||
-rw-r--r-- | kcc/__init__.py | 2 | ||||
-rwxr-xr-x | kcc/comic2ebook.py | 43 | ||||
-rw-r--r-- | kcc/comic2panel.py | 2 | ||||
-rwxr-xr-x | kcc/image.py | 4 | ||||
-rw-r--r-- | kcc/rarfile.py | 79 | ||||
-rwxr-xr-x | setup.py | 4 | ||||
-rwxr-xr-x | setup.sh | 2 |
13 files changed, 128 insertions, 58 deletions
diff --git a/README.md b/README.md index a8c9efe..98f9811 100644 --- a/README.md +++ b/README.md @@ -377,6 +377,13 @@ The app relies and includes the following scripts: * Added missing features to CLI version * Other minor bug fixes +####4.3.1: +* Fixed Kindle Voyage profile +* Fixed some bugs in OS X release +* CLI version now support multiple input files at once +* Disabled MCB support +* Other minor tweaks + ## KNOWN ISSUES Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues). diff --git a/kcc-c2e.py b/kcc-c2e.py index fea68dd..01ab86e 100755 --- a/kcc-c2e.py +++ b/kcc-c2e.py @@ -18,7 +18,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -__version__ = '4.3' +__version__ = '4.3.1' __license__ = 'ISC' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __docformat__ = 'restructuredtext en' diff --git a/kcc-c2p.py b/kcc-c2p.py index 2112a1c..57acd33 100755 --- a/kcc-c2p.py +++ b/kcc-c2p.py @@ -18,7 +18,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -__version__ = '4.3' +__version__ = '4.3.1' __license__ = 'ISC' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __docformat__ = 'restructuredtext en' diff --git a/kcc.iss b/kcc.iss index 3f6e619..f40959d 100644 --- a/kcc.iss +++ b/kcc.iss @@ -1,5 +1,5 @@ #define MyAppName "Kindle Comic Converter" -#define MyAppVersion "4.3" +#define MyAppVersion "4.3.1" #define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski" #define MyAppURL "http://kcc.iosphe.re/" #define MyAppExeName "KCC.exe" diff --git a/kcc.py b/kcc.py index c59f2ad..296714a 100755 --- a/kcc.py +++ b/kcc.py @@ -18,7 +18,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -__version__ = '4.3' +__version__ = '4.3.1' __license__ = 'ISC' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __docformat__ = 'restructuredtext en' @@ -74,11 +74,8 @@ from multiprocessing import freeze_support from kcc import KCC_gui # OS specific PATH variable workarounds -if sys.platform.startswith('darwin'): - if 'RESOURCEPATH' in os.environ: - os.environ['PATH'] = os.environ['RESOURCEPATH'] + ':' + os.environ['PATH'] - else: - os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/:' + os.environ['PATH'] +if sys.platform.startswith('darwin') and 'RESOURCEPATH' not in os.environ: + os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/:' + os.environ['PATH'] elif sys.platform.startswith('win'): if getattr(sys, 'frozen', False): os.chdir(os.path.dirname(os.path.abspath(sys.executable))) diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py index 1cb465f..1fd8a7f 100644 --- a/kcc/KCC_gui.py +++ b/kcc/KCC_gui.py @@ -17,7 +17,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -__version__ = '4.3' +__version__ = '4.3.1' __license__ = 'ISC' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __docformat__ = 'restructuredtext en' @@ -111,15 +111,15 @@ class WebServerHandler(BaseHTTPRequestHandler): self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(bytes('<!DOCTYPE html>\n' - '<html lang="en">\n' - '<head><meta charset="utf-8">\n' - '<link href="' + GUI.webContent.favicon + '" rel="icon" type="image/x-icon" />\n' - '<title>Kindle Comic Converter</title>\n' - '</head>\n' - '<body>\n' - '<div style="text-align: center; font-size:25px">\n' - '<p style="font-size:50px">- <img style="vertical-align: middle" ' - 'alt="KCC Logo" src="' + GUI.webContent.logo + '" /> -</p>\n', 'UTF-8')) + '<html lang="en">\n' + '<head><meta charset="utf-8">\n' + '<link href="' + GUI.webContent.favicon + '" rel="icon" type="image/x-icon" />\n' + '<title>Kindle Comic Converter</title>\n' + '</head>\n' + '<body>\n' + '<div style="text-align: center; font-size:25px">\n' + '<p style="font-size:50px">- <img style="vertical-align: middle" ' + 'alt="KCC Logo" src="' + GUI.webContent.logo + '" /> -</p>\n', 'UTF-8')) if len(GUI.completedWork) > 0 and not GUI.conversionAlive: for key in sorted(GUI.completedWork.keys()): self.wfile.write(bytes('<p><a href="' + key + '">' + key.split('.')[0] + '</a></p>\n', 'UTF-8')) @@ -127,8 +127,8 @@ class WebServerHandler(BaseHTTPRequestHandler): self.wfile.write(bytes('<p style="font-weight: bold">No downloads are available.<br/>' 'Convert some files and refresh this page.</p>\n', 'UTF-8')) self.wfile.write(bytes('</div>\n' - '</body>\n' - '</html>\n', 'UTF-8')) + '</body>\n' + '</html>\n', 'UTF-8')) elif sendReply: outputFile = GUI.completedWork[unquote(self.path[1:])] fp = open(outputFile, 'rb') @@ -1016,7 +1016,9 @@ class KCCGUI(KCC_ui.Ui_KCC): self.listFontSize = 11 self.statusBarFontSize = 10 self.statusBarStyle = 'QLabel{padding-top:2px;padding-bottom:3px;}' - self.ProgressBar.setStyleSheet('QProgressBar{padding-top:5px;text-align:center;}') + self.ProgressBar.setStyleSheet('QProgressBar{font-size:13px;text-align:center;' + 'border:2px solid grey;border-radius:5px;}' + 'QProgressBar::chunk{background-color:steelblue;width:20px;}') elif sys.platform.startswith('linux'): self.listFontSize = 8 self.statusBarFontSize = 8 diff --git a/kcc/__init__.py b/kcc/__init__.py index 4742e6e..49174f8 100644 --- a/kcc/__init__.py +++ b/kcc/__init__.py @@ -1,4 +1,4 @@ -__version__ = '4.3' +__version__ = '4.3.1' __license__ = 'ISC' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __docformat__ = 'restructuredtext en' \ No newline at end of file diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 94d50e7..b658c2b 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -18,16 +18,18 @@ # PERFORMANCE OF THIS SOFTWARE. # -__version__ = '4.3' +__version__ = '4.3.1' __license__ = 'ISC' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __docformat__ = 'restructuredtext en' import os import sys +from copy import copy +from glob import glob from json import loads from urllib.request import Request, urlopen -from re import split, sub, compile +from re import split, sub from stat import S_IWRITE, S_IREAD, S_IEXEC from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED from tempfile import mkdtemp @@ -55,12 +57,21 @@ from . import dualmetafix def main(argv=None): global options parser = makeParser() - options, args = parser.parse_args(argv) - checkOptions() - if len(args) != 1: + optionstemplate, args = parser.parse_args(argv) + if len(args) == 0: parser.print_help() return - outputPath = makeBook(args[0]) + sources = set([source for arg in args for source in glob(arg)]) + outputPath = [] + if len(sources) == 0: + print('No matching files found.') + return + for source in sources: + options = copy(optionstemplate) + checkOptions() + if len(sources) > 1: + print('\nWorking on ' + source) + outputPath = makeBook(source) return outputPath @@ -409,7 +420,7 @@ def buildEPUB(path, chapterNames, tomeNumber): chapter = False for afile in filenames: filename = getImageFileName(afile) - if not '-kcc-hq' in filename[0]: + if '-kcc-hq' not in filename[0]: filelist.append(buildHTML(dirpath, afile, os.path.join(dirpath, afile))) if not chapter: chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1])) @@ -667,11 +678,12 @@ def getComicInfo(path, originalPath): options.authors.sort() else: options.authors = ['KCC'] - if len(xml.getElementsByTagName('ScanInformation')) != 0: - coverId = xml.getElementsByTagName('ScanInformation')[0].firstChild.nodeValue - coverId = compile('(MCD\\()(\\d+)(\\))').search(coverId) - if coverId: - options.remoteCovers = getCoversFromMCB(coverId.group(2)) + # Disabled due to closure of MCD + # if len(xml.getElementsByTagName('ScanInformation')) != 0: + # coverId = xml.getElementsByTagName('ScanInformation')[0].firstChild.nodeValue + # coverId = compile('(MCD\\()(\\d+)(\\))').search(coverId) + # if coverId: + # options.remoteCovers = getCoversFromMCB(coverId.group(2)) os.remove(xmlPath) @@ -1144,7 +1156,10 @@ def makeBook(source, qtGUI=None): GUI.progressBarTick.emit('tick') options.baseTitle = options.title for tome in tomes: - if len(tomes) > 1: + if len(tomes) > 9: + tomeNumber += 1 + options.title = options.baseTitle + ' [' + str(tomeNumber).zfill(2) + '/' + str(len(tomes)).zfill(2) + ']' + elif len(tomes) > 1: tomeNumber += 1 options.title = options.baseTitle + ' [' + str(tomeNumber) + '/' + str(len(tomes)) + ']' if options.format == 'CBZ': @@ -1254,4 +1269,4 @@ def makeMOBI(work, qtGUI=None): makeMOBIWorkerPool.apply_async(func=makeMOBIWorker, args=(i, ), callback=makeMOBIWorkerTick) makeMOBIWorkerPool.close() makeMOBIWorkerPool.join() - return makeMOBIWorkerOutput \ No newline at end of file + return makeMOBIWorkerOutput diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py index 72d2f72..fff58ec 100644 --- a/kcc/comic2panel.py +++ b/kcc/comic2panel.py @@ -18,7 +18,7 @@ # PERFORMANCE OF THIS SOFTWARE. # -__version__ = '4.3' +__version__ = '4.3.1' __license__ = 'ISC' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __docformat__ = 'restructuredtext en' diff --git a/kcc/image.py b/kcc/image.py index 6a0aad8..b32bb74 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -__version__ = '4.3' +__version__ = '4.3.1' __license__ = 'ISC' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __docformat__ = 'restructuredtext en' @@ -87,7 +87,7 @@ class ProfileData: 'K345': ("Kindle", (600, 800), Palette16, 1.8, (900, 1200)), 'KDX': ("Kindle DX/DXG", (824, 1000), Palette16, 1.8, (1236, 1500)), 'KPW': ("Kindle Paperwhite", (758, 1024), Palette16, 1.8, (1137, 1536)), - 'KV': ("Kindle Voyage", (1080, 1440), Palette16, 1.8, (1620, 2160)), + 'KV': ("Kindle Voyage", (1072, 1448), Palette16, 1.8, (1608, 2172)), 'KFHD': ("K. Fire HD", (800, 1280), PalleteNull, 1.0, (1200, 1920)), 'KFHDX': ("K. Fire HDX", (1200, 1920), PalleteNull, 1.0, (1800, 2880)), 'KFHDX8': ("K. Fire HDX 8.9", (1600, 2560), PalleteNull, 1.0, (2400, 3840)), diff --git a/kcc/rarfile.py b/kcc/rarfile.py index 63fdcf7..6eefdb4 100644 --- a/kcc/rarfile.py +++ b/kcc/rarfile.py @@ -178,6 +178,23 @@ EXTRACT_ARGS = ('x', '-y', '-idq') #: args for testrar() TEST_ARGS = ('t', '-idq') +# +# Allow use of tool that is not compatible with unrar. +# +# By default use 'bsdtar' which is 'tar' program that +# sits on top of libarchive. +# +# Problems with libarchive RAR backend: +# - Does not support solid archives. +# - Does not support password-protected archives. +# + +ALT_TOOL = 'bsdtar' +ALT_OPEN_ARGS = ('-x', '--to-stdout', '-f') +ALT_EXTRACT_ARGS = ('-x', '-f') +ALT_TEST_ARGS = ('-t', '-f') +ALT_CHECK_ARGS = ('--help',) + #: whether to speed up decompression by using tmp archive USE_EXTRACT_HACK = 1 @@ -336,6 +353,8 @@ class RarUnknownError(RarExecError): """Unknown exit code""" class RarSignalExit(RarExecError): """Unrar exited with signal""" +class RarCannotExec(RarExecError): + """Executable not found.""" def is_rarfile(xfile): @@ -693,10 +712,7 @@ class RarFile(object): """Let 'unrar' test the archive. """ cmd = [UNRAR_TOOL] + list(TEST_ARGS) - if self._password is not None: - cmd.append('-p' + self._password) - else: - cmd.append('-p-') + add_password_arg(cmd, self._password) cmd.append(self.rarfile) p = custom_popen(cmd) output = p.communicate()[0] @@ -1172,8 +1188,7 @@ class RarFile(object): if is_filelike(rarfile): raise ValueError("Cannot use unrar directly on memory buffer") cmd = [UNRAR_TOOL] + list(OPEN_ARGS) - if psw is not None: - cmd.append("-p" + psw) + add_password_arg(cmd, psw) cmd.append(rarfile) # not giving filename avoids encoding related problems @@ -1205,10 +1220,7 @@ class RarFile(object): # pasoword psw = psw or self._password - if psw is not None: - cmd.append('-p' + psw) - else: - cmd.append('-p-') + add_password_arg(cmd, psw) # rar file cmd.append(self.rarfile) @@ -1830,10 +1842,7 @@ def rar_decompress(vers, meth, data, declen=0, flags=0, crc=0, psw=None, salt=No tmpf.close() cmd = [UNRAR_TOOL] + list(OPEN_ARGS) - if psw is not None and (flags & RAR_FILE_PASSWORD): - cmd.append("-p" + psw) - else: - cmd.append("-p-") + add_password_arg(cmd, psw, (flags & RAR_FILE_PASSWORD)) cmd.append(tmpname) p = custom_popen(cmd) @@ -1902,10 +1911,27 @@ def custom_popen(cmd): except OSError: ex = sys.exc_info()[1] if ex.errno == errno.ENOENT: - raise RarExecError("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL) + raise RarCannotExec("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL) raise return p +def custom_check(cmd, ignore_retcode=False): + """Run command, collect output, raise error if needed.""" + p = custom_popen(cmd) + out, err = p.communicate() + if p.returncode and not ignore_retcode: + raise RarExecError("Check-run failed") + return out + +def add_password_arg(cmd, psw, required=False): + """Append password switch to commandline.""" + if UNRAR_TOOL == ALT_TOOL: + return + if psw is not None: + cmd.append('-p' + psw) + else: + cmd.append('-p-') + def check_returncode(p, out): """Raise exception according to unrar exit code""" @@ -1920,6 +1946,8 @@ def check_returncode(p, out): RarWarning, RarFatalError, RarCRCError, RarLockedArchiveError, RarWriteError, RarOpenError, RarUserError, RarMemoryError, RarCreateError, RarNoFilesError] # codes from rar.txt + if UNRAR_TOOL == ALT_TOOL: + errmap = [None] if code > 0 and code < len(errmap): exc = errmap[code] elif code == 255: @@ -1936,3 +1964,24 @@ def check_returncode(p, out): msg = "%s [%d]" % (exc.__doc__, p.returncode) raise exc(msg) + +# +# Check if unrar works +# + +try: + # does UNRAR_TOOL work? + custom_check([UNRAR_TOOL], True) +except RarCannotExec: + try: + # does ALT_TOOL work? + custom_check([ALT_TOOL] + list(ALT_CHECK_ARGS), True) + # replace config + UNRAR_TOOL = ALT_TOOL + OPEN_ARGS = ALT_OPEN_ARGS + EXTRACT_ARGS = ALT_EXTRACT_ARGS + TEST_ARGS = ALT_TEST_ARGS + except RarCannotExec: + # no usable tool, only uncompressed archives work + pass + diff --git a/setup.py b/setup.py index 396d6d7..9476d3e 100755 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ if version_info[0] != 3: exit(1) NAME = "KindleComicConverter" -VERSION = "4.3" +VERSION = "4.3.1" MAIN = "kcc.py" if platform == "darwin": @@ -47,7 +47,7 @@ if platform == "darwin": ], LSMinimumSystemVersion='10.8.0', LSEnvironment=dict( - PATH='/usr/local/bin:/usr/bin:/bin' + PATH='./../Resources:/usr/local/bin:/usr/bin:/bin' ), NSHumanReadableCopyright='ISC License (ISCL)' ) diff --git a/setup.sh b/setup.sh index e1947dd..20708fa 100755 --- a/setup.sh +++ b/setup.sh @@ -1,7 +1,7 @@ #!/bin/bash # Linux Python package build script -VERSION="4.3" +VERSION="4.3.1" cp kcc.py __main__.py zip kcc.zip __main__.py kcc/*.py |