about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--LICENSE.txt4
-rw-r--r--README.md2
-rwxr-xr-xkcc-c2e.py6
-rwxr-xr-xkcc-c2p.py6
-rw-r--r--kcc.iss2
-rwxr-xr-xkcc.py6
-rw-r--r--kcc/KCC_gui.py42
-rw-r--r--kcc/__init__.py2
-rw-r--r--kcc/cbxarchive.py13
-rwxr-xr-xkcc/comic2ebook.py81
-rw-r--r--kcc/comic2panel.py33
-rwxr-xr-xkcc/image.py19
-rw-r--r--kcc/kindlesplit.py2
-rw-r--r--kcc/pdfjpgextract.py6
-rw-r--r--kcc/shared.py60
-rwxr-xr-xsetup.py2
16 files changed, 134 insertions, 152 deletions
diff --git a/LICENSE.txt b/LICENSE.txt
index 3c42aaa..ba9aa2e 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,7 +1,7 @@
 ISC LICENSE
 
-Copyright (c) 2013 Ciro Mattia Gonano <ciromattia@gmail.com>
-Copyright (c) 2013 Paweł Jastrzębski <pawelj@vulturis.eu>
+Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+Copyright (c) 2013-2014 Paweł Jastrzębski <pawelj@vulturis.eu>
 
 Permission to use, copy, modify, and/or distribute this software for
 any purpose with or without fee is hereby granted, provided that the
diff --git a/README.md b/README.md
index 26037cd..25499c0 100644
--- a/README.md
+++ b/README.md
@@ -329,5 +329,5 @@ Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues).
 
 ## COPYRIGHT
 
-Copyright (c) 2012-2013 Ciro Mattia Gonano and Paweł Jastrzębski.  
+Copyright (c) 2012-2014 Ciro Mattia Gonano and Paweł Jastrzębski.
 **KCC** is released under ISC LICENSE; see LICENSE.txt for further details.
diff --git a/kcc-c2e.py b/kcc-c2e.py
index 71a3936..d9c548e 100755
--- a/kcc-c2e.py
+++ b/kcc-c2e.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # Permission to use, copy, modify, and/or distribute this software for
 # any purpose with or without fee is hereby granted, provided that the
@@ -20,7 +20,7 @@
 
 __version__ = '4.0'
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
 
 import sys
diff --git a/kcc-c2p.py b/kcc-c2p.py
index cf194d1..c915409 100755
--- a/kcc-c2p.py
+++ b/kcc-c2p.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # Permission to use, copy, modify, and/or distribute this software for
 # any purpose with or without fee is hereby granted, provided that the
@@ -25,7 +25,7 @@ if sys.version_info[0] != 3:
 
 __version__ = '4.0'
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
 
 # Dependiences check
diff --git a/kcc.iss b/kcc.iss
index 8aebf13..798a1d7 100644
--- a/kcc.iss
+++ b/kcc.iss
@@ -12,7 +12,7 @@ AppPublisher={#MyAppPublisher}
 AppPublisherURL={#MyAppURL}
 AppSupportURL={#MyAppURL}
 AppUpdatesURL={#MyAppURL}
-AppCopyright=Copyright (C) 2012-2013 Ciro Mattia Gonano and Paweł Jastrzębski
+AppCopyright=Copyright (C) 2012-2014 Ciro Mattia Gonano and Paweł Jastrzębski
 DefaultDirName={pf}\{#MyAppName}
 DefaultGroupName={#MyAppName}
 AllowNoIcons=yes
diff --git a/kcc.py b/kcc.py
index 2b1edd5..684fda1 100755
--- a/kcc.py
+++ b/kcc.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # Permission to use, copy, modify, and/or distribute this software for
 # any purpose with or without fee is hereby granted, provided that the
@@ -20,7 +20,7 @@
 
 __version__ = '4.0'
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
 
 import sys
diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py
index 5a0c03f..44d2da3 100644
--- a/kcc/KCC_gui.py
+++ b/kcc/KCC_gui.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # Permission to use, copy, modify, and/or distribute this software for
 # any purpose with or without fee is hereby granted, provided that the
@@ -19,15 +19,15 @@
 
 __version__ = '4.0'
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
 
 import os
 import sys
-import traceback
-import urllib.request
-import urllib.parse
-import socket
+from urllib.parse import unquote
+from urllib.request import urlopen, urlretrieve
+from socket import gethostbyname_ex, gethostname
+from traceback import format_tb
 from time import sleep
 from shutil import move
 from http.server import BaseHTTPRequestHandler, HTTPServer
@@ -37,7 +37,7 @@ from PyQt5 import QtGui, QtCore, QtWidgets
 from xml.dom.minidom import parse
 from html.parser import HTMLParser
 from psutil import TOTAL_PHYMEM, Popen
-from hashlib import md5
+from .shared import md5Checksum
 from . import comic2ebook
 from . import kindlesplit
 from . import KCC_rc_web
@@ -130,7 +130,7 @@ class WebServerHandler(BaseHTTPRequestHandler):
                                  '</body>\n'
                                  '</html>\n', 'UTF-8'))
             elif sendReply:
-                outputFile = GUI.completedWork[urllib.parse.unquote(self.path[1:])]
+                outputFile = GUI.completedWork[unquote(self.path[1:])]
                 fp = open(outputFile, 'rb')
                 self.send_response(200)
                 self.send_header('Content-type', mimetype)
@@ -163,7 +163,7 @@ class WebServerThread(QtCore.QThread):
     def run(self):
         try:
             # Sweet cross-platform one-liner to get LAN ip address
-            lIP = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1][0]
+            lIP = [ip for ip in gethostbyname_ex(gethostname())[2] if not ip.startswith("127.")][:1][0]
         except Exception:
             # Sadly it can fail on some Linux configurations
             lIP = None
@@ -193,19 +193,9 @@ class VersionThread(QtCore.QThread):
     def __del__(self):
         self.wait()
 
-    def md5Checksum(self, filePath):
-        with open(filePath, 'rb') as fh:
-            m = md5()
-            while True:
-                data = fh.read(8192)
-                if not data:
-                    break
-                m.update(data)
-            return m.hexdigest()
-
     def run(self):
         try:
-            XML = urllib.request.urlopen('http://kcc.vulturis.eu/Version.php')
+            XML = urlopen('http://kcc.vulturis.eu/Version.php')
             XML = parse(XML)
         except Exception:
             return
@@ -229,9 +219,9 @@ class VersionThread(QtCore.QThread):
             try:
                 MW.modeConvert.emit(-1)
                 MW.progressBarTick.emit('Downloading update')
-                path = urllib.request.urlretrieve('http://kcc.vulturis.eu/Windows/KindleComicConverter_win_' +
-                                                  self.newVersion + '.exe', reporthook=self.getNewVersionTick)
-                if self.md5 != self.md5Checksum(path[0]):
+                path = urlretrieve('http://kcc.vulturis.eu/Windows/KindleComicConverter_win_'
+                                   + self.newVersion + '.exe', reporthook=self.getNewVersionTick)
+                if self.md5 != md5Checksum(path[0]):
                     raise Exception
                 move(path[0], path[0] + '.exe')
                 MW.hideProgressBar.emit()
@@ -462,7 +452,7 @@ class WorkerThread(QtCore.QThread):
                 self.errors = True
                 type_, value_, traceback_ = sys.exc_info()
                 MW.showDialog.emit("Error during conversion %s:\n\n%s\n\nTraceback:\n%s"
-                                   % (jobargv[-1], str(err), traceback.format_tb(traceback_)), 'error')
+                                   % (jobargv[-1], str(err), format_tb(traceback_)), 'error')
                 MW.addMessage.emit('Failed to create EPUB!', 'error', False)
                 MW.addTrayMessage.emit('Failed to create EPUB!', 'Critical')
             if not self.conversionAlive:
@@ -1042,7 +1032,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
 
     def dragAndDropAccepted(self, e):
         for message in e.mimeData().urls():
-            message = urllib.parse.unquote(message.toString().replace('file:///', ''))
+            message = unquote(message.toString().replace('file:///', ''))
             if sys.platform.startswith('win'):
                 message = message.replace('/', '\\')
             else:
diff --git a/kcc/__init__.py b/kcc/__init__.py
index ca08060..56d1258 100644
--- a/kcc/__init__.py
+++ b/kcc/__init__.py
@@ -1,4 +1,4 @@
 __version__ = '4.0'
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
\ No newline at end of file
diff --git a/kcc/cbxarchive.py b/kcc/cbxarchive.py
index ea68cd6..eb2f4da 100644
--- a/kcc/cbxarchive.py
+++ b/kcc/cbxarchive.py
@@ -1,5 +1,5 @@
-# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # Permission to use, copy, modify, and/or distribute this software for
 # any purpose with or without fee is hereby granted, provided that the
@@ -15,13 +15,14 @@
 # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 #
+
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
 
 import sys
 import os
-import zipfile
+from zipfile import is_zipfile, ZipFile
 from subprocess import STDOUT, PIPE
 from psutil import Popen
 from shutil import move, copy
@@ -31,7 +32,7 @@ from . import rarfile
 class CBxArchive:
     def __init__(self, origFileName):
         self.origFileName = origFileName
-        if zipfile.is_zipfile(origFileName):
+        if is_zipfile(origFileName):
             self.compressor = 'zip'
         elif rarfile.is_rarfile(origFileName):
             self.compressor = 'rar'
@@ -44,7 +45,7 @@ class CBxArchive:
         return self.compressor is not None
 
     def extractCBZ(self, targetdir):
-        cbzFile = zipfile.ZipFile(self.origFileName)
+        cbzFile = ZipFile(self.origFileName)
         filelist = []
         for f in cbzFile.namelist():
             if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('thumbs.db'):
diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py
index f0f80ec..6237e19 100755
--- a/kcc/comic2ebook.py
+++ b/kcc/comic2ebook.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # Permission to use, copy, modify, and/or distribute this software for
 # any purpose with or without fee is hereby granted, provided that the
@@ -17,16 +17,17 @@
 # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 #
+
 __version__ = '4.0'
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
 
 import os
 import sys
-import re
-import stat
-import zipfile
+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
 from shutil import move, copyfile, copytree, rmtree
 from optparse import OptionParser, OptionGroup
@@ -35,28 +36,17 @@ from xml.dom.minidom import parse
 from uuid import uuid4
 from slugify import slugify as slugifyExt
 from PIL import Image
-from hashlib import md5
 try:
     from PyQt5 import QtCore
 except ImportError:
     QtCore = None
+from .shared import md5Checksum, getImageFileName, walkLevel
 from . import comic2panel
 from . import image
 from . import cbxarchive
 from . import pdfjpgextract
 
 
-def md5Checksum(filePath):
-    with open(filePath, 'rb') as fh:
-        m = md5()
-        while True:
-            data = fh.read(8192)
-            if not data:
-                break
-            m.update(data)
-        return m.hexdigest()
-
-
 def buildHTML(path, imgfile, imgfilepath):
     imgfilepath = md5Checksum(imgfilepath)
     filename = getImageFileName(imgfile)
@@ -307,20 +297,6 @@ def buildOPF(dstdir, title, filelist, cover=None):
     return
 
 
-def getImageFileName(imgfile):
-    filename = os.path.splitext(imgfile)
-    if filename[0].startswith('.') or\
-            (filename[1].lower() != '.png' and
-             filename[1].lower() != '.jpg' and
-             filename[1].lower() != '.gif' and
-             filename[1].lower() != '.tif' and
-             filename[1].lower() != '.tiff' and
-             filename[1].lower() != '.bmp' and
-             filename[1].lower() != '.jpeg'):
-        return None
-    return filename
-
-
 def applyImgOptimization(img, opt, hqImage=None):
     if not img.fill:
         img.getImageFill(opt.webtoon)
@@ -405,26 +381,26 @@ def fileImgProcess(work):
         else:
             wipe = True
         if opt.nosplitrotate:
-            split = None
+            splitter = None
         else:
-            split = img.splitPage(dirpath, opt.righttoleft, opt.rotate)
-        if split is not None:
+            splitter = img.splitPage(dirpath, opt.righttoleft, opt.rotate)
+        if splitter is not None:
             if opt.verbose:
                 print("Splitted " + afile)
-            img0 = image.ComicPage(split[0], opt.profileData)
+            img0 = image.ComicPage(splitter[0], opt.profileData)
             applyImgOptimization(img0, opt)
             output.append(img0.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
-            img1 = image.ComicPage(split[1], opt.profileData)
+            img1 = image.ComicPage(splitter[1], opt.profileData)
             applyImgOptimization(img1, opt)
             output.append(img1.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
             if wipe:
                 os.remove(img0.origFileName)
                 os.remove(img1.origFileName)
             if opt.quality == 2:
-                img0b = image.ComicPage(split[0], opt.profileData, img0.fill)
+                img0b = image.ComicPage(splitter[0], opt.profileData, img0.fill)
                 applyImgOptimization(img0b, opt, img0)
                 output.append(img0b.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
-                img1b = image.ComicPage(split[1], opt.profileData, img1.fill)
+                img1b = image.ComicPage(splitter[1], opt.profileData, img1.fill)
                 applyImgOptimization(img1b, opt, img1)
                 output.append(img1b.saveToDir(dirpath, opt.forcepng, opt.forcecolor))
                 os.remove(img0.origFileName)
@@ -580,7 +556,7 @@ def genEpubStruct(path, chapterNames):
     buildNCX(path, options.title, chapterlist, chapterNames)
     # Ensure we're sorting files alphabetically
     convert = lambda text: int(text) if text.isdigit() else text
-    alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
+    alphanum_key = lambda key: [convert(c) for c in split('([0-9]+)', key)]
     filelist.sort(key=lambda name: (alphanum_key(name[0].lower()), alphanum_key(name[1].lower())))
     buildOPF(path, options.title, filelist, cover)
 
@@ -679,7 +655,7 @@ def checkComicInfo(path, originalPath):
 
 def slugify(value):
     value = slugifyExt(value)
-    value = re.sub(r'0*([0-9]{4,})', r'\1', re.sub(r'([0-9]+)', r'0000\1', value))
+    value = sub(r'0*([0-9]{4,})', r'\1', sub(r'([0-9]+)', r'0000\1', value))
     return value
 
 
@@ -718,9 +694,9 @@ def sanitizeTree(filetree):
 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)
+            os.chmod(os.path.join(root, name), S_IWRITE | S_IREAD)
         for name in dirs:
-            os.chmod(os.path.join(root, name), stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC)
+            os.chmod(os.path.join(root, name), S_IWRITE | S_IREAD | S_IEXEC)
 
 
 def getDirectorySize(start_path='.'):
@@ -739,17 +715,6 @@ def createNewTome():
     return tomePath, tomePathRoot
 
 
-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 splitDirectory(path, mode):
     output = []
     currentSize = 0
@@ -864,9 +829,9 @@ def preSplitDirectory(path):
                     GUI.addMessage.emit('', '', False)
                 return [path]
         # Split directories
-        split = splitDirectory(os.path.join(path, 'OEBPS', 'Images'), mode)
+        splitter = splitDirectory(os.path.join(path, 'OEBPS', 'Images'), mode)
         path = [path]
-        for tome in split:
+        for tome in splitter:
             path.append(tome)
         return path
     else:
@@ -895,9 +860,9 @@ def detectCorruption(tmpPath, orgPath):
 
 def makeZIP(zipFilename, baseDir, isEPUB=False):
     zipFilename = os.path.abspath(zipFilename) + '.zip'
-    zipOutput = zipfile.ZipFile(zipFilename, 'w', zipfile.ZIP_DEFLATED)
+    zipOutput = ZipFile(zipFilename, 'w', ZIP_DEFLATED)
     if isEPUB:
-        zipOutput.writestr('mimetype', 'application/epub+zip', zipfile.ZIP_STORED)
+        zipOutput.writestr('mimetype', 'application/epub+zip', ZIP_STORED)
     for dirpath, dirnames, filenames in os.walk(baseDir):
         for name in filenames:
             path = os.path.normpath(os.path.join(dirpath, name))
diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py
index 9e92d78..8612ca3 100644
--- a/kcc/comic2panel.py
+++ b/kcc/comic2panel.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # Permission to use, copy, modify, and/or distribute this software for
 # any purpose with or without fee is hereby granted, provided that the
@@ -17,9 +17,10 @@
 # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 #
+
 __version__ = '4.0'
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
 
 import os
@@ -28,37 +29,13 @@ from shutil import rmtree, copytree, move
 from optparse import OptionParser, OptionGroup
 from multiprocessing import Pool
 from PIL import Image, ImageStat
+from .shared import getImageFileName, walkLevel
 try:
     from PyQt5 import QtCore
 except ImportError:
     QtCore = None
 
 
-def getImageFileName(imgfile):
-    filename = os.path.splitext(imgfile)
-    if filename[0].startswith('.') or\
-            (filename[1].lower() != '.png' and
-             filename[1].lower() != '.jpg' and
-             filename[1].lower() != '.gif' and
-             filename[1].lower() != '.tif' and
-             filename[1].lower() != '.tiff' and
-             filename[1].lower() != '.bmp' and
-             filename[1].lower() != '.jpeg'):
-        return None
-    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)
diff --git a/kcc/image.py b/kcc/image.py
index b3016cd..5821e48 100755
--- a/kcc/image.py
+++ b/kcc/image.py
@@ -1,7 +1,7 @@
 # Copyright (C) 2010  Alex Yatskov
 # Copyright (C) 2011  Stanislav (proDOOMman) Kosolapov <prodoomman@gmail.com>
-# Copyright (C) 2012-2013  Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (C) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # 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
@@ -17,24 +17,13 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
 
 import os
-from hashlib import md5
 from functools import reduce
 from PIL import Image, ImageOps, ImageStat, ImageChops
-
-
-def md5Checksum(filePath):
-    with open(filePath, 'rb') as fh:
-        m = md5()
-        while True:
-            data = fh.read(8192)
-            if not data:
-                break
-            m.update(data)
-        return m.hexdigest()
+from .shared import md5Checksum
 
 
 class ProfileData:
diff --git a/kcc/kindlesplit.py b/kcc/kindlesplit.py
index 26e017f..fb7385b 100644
--- a/kcc/kindlesplit.py
+++ b/kcc/kindlesplit.py
@@ -2,7 +2,7 @@
 #
 # Based on initial version of KindleUnpack. Copyright (C) 2009 Charles M. Hannum <root@ihack.net>
 # Improvements Copyright (C) 2009-2012 P. Durrant, K. Hendricks, S. Siebert, fandrieu, DiapDealer, nickredding
-# Changes for KCC Copyright (C) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Changes for KCC Copyright (C) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/kcc/pdfjpgextract.py b/kcc/pdfjpgextract.py
index 96ac979..c004f2d 100644
--- a/kcc/pdfjpgextract.py
+++ b/kcc/pdfjpgextract.py
@@ -1,5 +1,5 @@
-# Copyright (c) 2012-2013 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013 Pawel Jastrzebski <pawelj@vulturis.eu>
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
 #
 # Based upon the code snippet by Ned Batchelder
 # (http://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html)
@@ -20,7 +20,7 @@
 #
 
 __license__ = 'ISC'
-__copyright__ = '2012-2013, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
 __docformat__ = 'restructuredtext en'
 
 import os
diff --git a/kcc/shared.py b/kcc/shared.py
new file mode 100644
index 0000000..a0aba28
--- /dev/null
+++ b/kcc/shared.py
@@ -0,0 +1,60 @@
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2014 Pawel Jastrzebski <pawelj@vulturis.eu>
+#
+# Permission to use, copy, modify, and/or distribute this software for
+# any purpose with or without fee is hereby granted, provided that the
+# above copyright notice and this permission notice appear in all
+# copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+
+__license__ = 'ISC'
+__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@vulturis.eu>'
+__docformat__ = 'restructuredtext en'
+
+import os
+from hashlib import md5
+
+
+def getImageFileName(imgfile):
+    filename = os.path.splitext(imgfile)
+    if filename[0].startswith('.') or\
+            (filename[1].lower() != '.png' and
+             filename[1].lower() != '.jpg' and
+             filename[1].lower() != '.gif' and
+             filename[1].lower() != '.tif' and
+             filename[1].lower() != '.tiff' and
+             filename[1].lower() != '.bmp' and
+             filename[1].lower() != '.jpeg'):
+        return None
+    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 md5Checksum(filePath):
+    with open(filePath, 'rb') as fh:
+        m = md5()
+        while True:
+            data = fh.read(8192)
+            if not data:
+                break
+            m.update(data)
+        return m.hexdigest()
diff --git a/setup.py b/setup.py
index 6ca1a59..f805c66 100755
--- a/setup.py
+++ b/setup.py
@@ -33,7 +33,7 @@ if platform == "darwin":
                     CFBundleName=NAME,
                     CFBundleShortVersionString=VERSION,
                     CFBundleGetInfoString=NAME + " " + VERSION +
-                    ", written 2012-2013 by Ciro Mattia Gonano and Pawel Jastrzebski",
+                    ", written 2012-2014 by Ciro Mattia Gonano and Pawel Jastrzebski",
                     CFBundleExecutable=NAME,
                     CFBundleIdentifier='com.github.ciromattia.kcc',
                     CFBundleSignature='dplt',