about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaweł Jastrzębski <pawelj@iosphe.re>2014-11-24 20:13:17 +0100
committerPaweł Jastrzębski <pawelj@iosphe.re>2014-11-24 20:13:17 +0100
commitbd665c326198f0c44a43fb844dd7a994c34f4649 (patch)
tree697e1a8a0f42ac1d05c9441aa59ca996fca3be1d
parentMerge pull request #113 from ciromattia/4.x (diff)
parentVersion bump (diff)
downloadkcc-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.md7
-rwxr-xr-xkcc-c2e.py2
-rwxr-xr-xkcc-c2p.py2
-rw-r--r--kcc.iss2
-rwxr-xr-xkcc.py9
-rw-r--r--kcc/KCC_gui.py28
-rw-r--r--kcc/__init__.py2
-rwxr-xr-xkcc/comic2ebook.py43
-rw-r--r--kcc/comic2panel.py2
-rwxr-xr-xkcc/image.py4
-rw-r--r--kcc/rarfile.py79
-rwxr-xr-xsetup.py4
-rwxr-xr-xsetup.sh2
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