about summary refs log tree commit diff
path: root/kindlecomicconverter
diff options
context:
space:
mode:
authorPaweł Jastrzębski <pawelj@iosphe.re>2018-03-08 16:15:42 +0100
committerGitHub <noreply@github.com>2018-03-08 16:15:42 +0100
commit34e2af3389acfdf32f18a06c77e75ce91deed42d (patch)
tree79fb5515fa273c1484b69fd25bbd5e9fd4e3b8e6 /kindlecomicconverter
parentUpdated build enviroment (diff)
parentVersion bump (diff)
downloadkcc-34e2af3389acfdf32f18a06c77e75ce91deed42d.tar.gz
kcc-34e2af3389acfdf32f18a06c77e75ce91deed42d.tar.bz2
kcc-34e2af3389acfdf32f18a06c77e75ce91deed42d.zip
Merge pull request #261 from ciromattia/dev
5.4.4
Diffstat (limited to 'kindlecomicconverter')
-rw-r--r--kindlecomicconverter/KCC_gui.py22
-rw-r--r--kindlecomicconverter/__init__.py4
-rw-r--r--kindlecomicconverter/cbxarchive.py23
-rwxr-xr-xkindlecomicconverter/comic2ebook.py305
-rw-r--r--kindlecomicconverter/comic2panel.py11
-rw-r--r--kindlecomicconverter/dualmetafix.py2
-rwxr-xr-xkindlecomicconverter/image.py60
-rw-r--r--kindlecomicconverter/kindle.py2
-rw-r--r--kindlecomicconverter/metadata.py2
-rw-r--r--kindlecomicconverter/pdfjpgextract.py13
-rw-r--r--kindlecomicconverter/shared.py10
-rw-r--r--kindlecomicconverter/startup.py2
12 files changed, 249 insertions, 207 deletions
diff --git a/kindlecomicconverter/KCC_gui.py b/kindlecomicconverter/KCC_gui.py
index a98585a..71e06de 100644
--- a/kindlecomicconverter/KCC_gui.py
+++ b/kindlecomicconverter/KCC_gui.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 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
@@ -156,8 +156,8 @@ class VersionThread(QtCore.QThread):
                                    '(<a href="https://github.com/ciromattia/kcc/releases/">'
                                    'Changelog</a>)', 'warning', False)
 
-    def setAnswer(self, dialogAnswer):
-        self.answer = dialogAnswer
+    def setAnswer(self, dialoganswer):
+        self.answer = dialoganswer
 
     def getNewVersion(self):
         while self.answer is None:
@@ -180,8 +180,8 @@ class VersionThread(QtCore.QThread):
                 MW.hideProgressBar.emit()
                 MW.modeConvert.emit(1)
 
-    def getNewVersionTick(self, size, blockSize, totalSize):
-        progress = int((size / (totalSize // blockSize)) * 100)
+    def getNewVersionTick(self, size, blocksize, totalsize):
+        progress = int((size / (totalsize // blocksize)) * 100)
         if size == 0:
             MW.progressBarTick.emit('100')
         if progress > self.barProgress:
@@ -667,10 +667,10 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
             self.addMessage('<a href="https://github.com/ciromattia/kcc/wiki/NonKindle-devices">'
                             'List of supported Non-Kindle devices.</a>', 'info')
 
-    def changeFormat(self, outputFormat=None):
+    def changeFormat(self, outputformat=None):
         profile = GUI.profiles[str(GUI.deviceBox.currentText())]
-        if outputFormat is not None:
-            GUI.formatBox.setCurrentIndex(outputFormat)
+        if outputformat is not None:
+            GUI.formatBox.setCurrentIndex(outputformat)
         else:
             GUI.formatBox.setCurrentIndex(profile['DefaultFormat'])
         if not GUI.webtoonBox.isChecked():
@@ -881,10 +881,10 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
                 else:
                     self.addMessage('Download it and place executable in /usr/local/bin directory.', 'error')
 
-    def __init__(self, KCCAplication, KCCWindow):
+    def __init__(self, kccapp, kccwindow):
         global APP, MW, GUI
-        APP = KCCAplication
-        MW = KCCWindow
+        APP = kccapp
+        MW = kccwindow
         GUI = self
         self.setupUi(MW)
         self.editor = KCCGUI_MetaEditor()
diff --git a/kindlecomicconverter/__init__.py b/kindlecomicconverter/__init__.py
index cdb3623..8cb3bad 100644
--- a/kindlecomicconverter/__init__.py
+++ b/kindlecomicconverter/__init__.py
@@ -1,4 +1,4 @@
-__version__ = '5.4.3'
+__version__ = '5.4.4'
 __license__ = 'ISC'
-__copyright__ = '2012-2017, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
+__copyright__ = '2012-2018, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
 __docformat__ = 'restructuredtext en'
diff --git a/kindlecomicconverter/cbxarchive.py b/kindlecomicconverter/cbxarchive.py
index 7aba70f..40ce928 100644
--- a/kindlecomicconverter/cbxarchive.py
+++ b/kindlecomicconverter/cbxarchive.py
@@ -1,5 +1,5 @@
 # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 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
@@ -26,13 +26,13 @@ from .shared import check7ZFile as is_7zfile
 
 
 class CBxArchive:
-    def __init__(self, origFileName):
-        self.origFileName = origFileName
-        if is_zipfile(origFileName):
+    def __init__(self, fname):
+        self.fname = fname
+        if is_zipfile(fname):
             self.compressor = 'zip'
-        elif rarfile.is_rarfile(origFileName):
+        elif rarfile.is_rarfile(fname):
             self.compressor = 'rar'
-        elif is_7zfile(origFileName):
+        elif is_7zfile(fname):
             self.compressor = '7z'
         else:
             self.compressor = None
@@ -41,22 +41,19 @@ class CBxArchive:
         return self.compressor is not None
 
     def extractCBZ(self, targetdir):
-        cbzFile = ZipFile(self.origFileName)
+        cbzFile = ZipFile(self.fname)
         filelist = []
         for f in cbzFile.namelist():
             if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('humbs.db'):
                 pass
             elif f.endswith('/'):
-                try:
-                    os.makedirs(os.path.join(targetdir, f))
-                except Exception:
-                    pass
+                os.makedirs(os.path.join(targetdir, f), exist_ok=True)
             else:
                 filelist.append(f)
         cbzFile.extractall(targetdir, filelist)
 
     def extractCBR(self, targetdir):
-        cbrFile = rarfile.RarFile(self.origFileName)
+        cbrFile = rarfile.RarFile(self.fname)
         cbrFile.extractall(targetdir)
         for root, _, filenames in os.walk(targetdir):
             for filename in filenames:
@@ -64,7 +61,7 @@ class CBxArchive:
                     os.remove(os.path.join(root, filename))
 
     def extractCB7(self, targetdir):
-        output = Popen('7za x "' + self.origFileName + '" -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -xr!Thumbs.db -o"' +
+        output = Popen('7za x "' + self.fname + '" -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -xr!Thumbs.db -o"' +
                        targetdir + '"', stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
         extracted = False
         for line in output.stdout:
diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py
index e27d5e6..7aaf027 100755
--- a/kindlecomicconverter/comic2ebook.py
+++ b/kindlecomicconverter/comic2ebook.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 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
@@ -88,7 +88,7 @@ def buildHTML(path, imgfile, imgfilepath):
     if "BlackBackground" in options.imgMetadata[imgfilepath]:
         additionalStyle = 'background-color:#000000;'
     else:
-        additionalStyle = 'background-color:#FFFFFF;'
+        additionalStyle = ''
     postfix = ''
     backref = 1
     head = path
@@ -198,7 +198,7 @@ def buildHTML(path, imgfile, imgfilepath):
     return path, imgfile
 
 
-def buildNCX(dstdir, title, chapters, chapterNames):
+def buildNCX(dstdir, title, chapters, chapternames):
     ncxfile = os.path.join(dstdir, 'OEBPS', 'toc.ncx')
     f = open(ncxfile, "w", encoding='UTF-8')
     f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
@@ -217,10 +217,10 @@ def buildNCX(dstdir, title, chapters, chapterNames):
         filename = getImageFileName(os.path.join(folder, chapter[1]))
         navID = folder.replace('/', '_').replace('\\', '_')
         if options.chapters:
-            title = chapterNames[chapter[1]]
+            title = chapternames[chapter[1]]
             navID = filename[0].replace('/', '_').replace('\\', '_')
         elif os.path.basename(folder) != "Text":
-            title = chapterNames[os.path.basename(folder)]
+            title = chapternames[os.path.basename(folder)]
         f.write("<navPoint id=\"" + navID + "\"><navLabel><text>" +
                 escape(title) + "</text></navLabel><content src=\"" + filename[0].replace("\\", "/") +
                 ".xhtml\"/></navPoint>\n")
@@ -228,7 +228,7 @@ def buildNCX(dstdir, title, chapters, chapterNames):
     f.close()
 
 
-def buildNAV(dstdir, title, chapters, chapterNames):
+def buildNAV(dstdir, title, chapters, chapternames):
     navfile = os.path.join(dstdir, 'OEBPS', 'nav.xhtml')
     f = open(navfile, "w", encoding='UTF-8')
     f.writelines(["<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
@@ -245,9 +245,9 @@ def buildNAV(dstdir, title, chapters, chapterNames):
         folder = chapter[0].replace(os.path.join(dstdir, 'OEBPS'), '').lstrip('/').lstrip('\\\\')
         filename = getImageFileName(os.path.join(folder, chapter[1]))
         if options.chapters:
-            title = chapterNames[chapter[1]]
+            title = chapternames[chapter[1]]
         elif os.path.basename(folder) != "Text":
-            title = chapterNames[os.path.basename(folder)]
+            title = chapternames[os.path.basename(folder)]
         f.write("<li><a href=\"" + filename[0].replace("\\", "/") + ".xhtml\">" + escape(title) + "</a></li>\n")
     f.writelines(["</ol>\n",
                   "</nav>\n",
@@ -257,9 +257,9 @@ def buildNAV(dstdir, title, chapters, chapterNames):
         folder = chapter[0].replace(os.path.join(dstdir, 'OEBPS'), '').lstrip('/').lstrip('\\\\')
         filename = getImageFileName(os.path.join(folder, chapter[1]))
         if options.chapters:
-            title = chapterNames[chapter[1]]
+            title = chapternames[chapter[1]]
         elif os.path.basename(folder) != "Text":
-            title = chapterNames[os.path.basename(folder)]
+            title = chapternames[os.path.basename(folder)]
         f.write("<li><a href=\"" + filename[0].replace("\\", "/") + ".xhtml\">" + escape(title) + "</a></li>\n")
     f.write("</ol>\n</nav>\n</body>\n</html>")
     f.close()
@@ -287,20 +287,27 @@ def buildOPF(dstdir, title, filelist, cover=None):
     for author in options.authors:
         f.writelines(["<dc:creator>", author, "</dc:creator>\n"])
     f.writelines(["<meta property=\"dcterms:modified\">" + strftime("%Y-%m-%dT%H:%M:%SZ", gmtime()) + "</meta>\n",
-                  "<meta name=\"cover\" content=\"cover\"/>\n",
-                  "<meta property=\"rendition:orientation\">portrait</meta>\n",
-                  "<meta property=\"rendition:spread\">portrait</meta>\n",
-                  "<meta property=\"rendition:layout\">pre-paginated</meta>\n"])
+                  "<meta name=\"cover\" content=\"cover\"/>\n"])
     if options.iskindle and options.profile != 'Custom':
-        f.writelines(["<meta name=\"original-resolution\" content=\"",
+        f.writelines(["<meta name=\"fixed-layout\" content=\"true\"/>\n",
+                      "<meta name=\"original-resolution\" content=\"",
                       str(deviceres[0]) + "x" + str(deviceres[1]) + "\"/>\n",
                       "<meta name=\"book-type\" content=\"comic\"/>\n",
-                      "<meta name=\"RegionMagnification\" content=\"true\"/>\n",
                       "<meta name=\"primary-writing-mode\" content=\"" + writingmode + "\"/>\n",
                       "<meta name=\"zero-gutter\" content=\"true\"/>\n",
                       "<meta name=\"zero-margin\" content=\"true\"/>\n",
-                      "<meta name=\"ke-border-color\" content=\"#ffffff\"/>\n",
+                      "<meta name=\"ke-border-color\" content=\"#FFFFFF\"/>\n",
                       "<meta name=\"ke-border-width\" content=\"0\"/>\n"])
+        if options.kfx:
+            f.writelines(["<meta name=\"orientation-lock\" content=\"none\"/>\n",
+                          "<meta name=\"region-mag\" content=\"false\"/>\n"])
+        else:
+            f.writelines(["<meta name=\"orientation-lock\" content=\"portrait\"/>\n",
+                          "<meta name=\"region-mag\" content=\"true\"/>\n"])
+    else:
+        f.writelines(["<meta property=\"rendition:orientation\">portrait</meta>\n",
+                      "<meta property=\"rendition:spread\">portrait</meta>\n",
+                      "<meta property=\"rendition:layout\">pre-paginated</meta>\n"])
     f.writelines(["</metadata>\n<manifest>\n<item id=\"ncx\" href=\"toc.ncx\" ",
                   "media-type=\"application/x-dtbncx+xml\"/>\n",
                   "<item id=\"nav\" href=\"nav.xhtml\" ",
@@ -331,10 +338,43 @@ def buildOPF(dstdir, title, filelist, cover=None):
     f.write("<item id=\"css\" href=\"Text/style.css\" media-type=\"text/css\"/>\n")
     if options.righttoleft:
         f.write("</manifest>\n<spine page-progression-direction=\"rtl\" toc=\"ncx\">\n")
+        pageside = "right"
     else:
         f.write("</manifest>\n<spine page-progression-direction=\"ltr\" toc=\"ncx\">\n")
-    for entry in reflist:
-        f.write("<itemref idref=\"page_" + entry + "\"/>\n")
+        pageside = "left"
+    if options.iskindle:
+        for entry in reflist:
+            if options.righttoleft:
+                if entry.endswith("-b"):
+                    f.write("<itemref idref=\"page_" + entry + "\" linear=\"yes\" properties=\"page-spread-right\"/>\n")
+                    pageside = "right"
+                elif entry.endswith("-c"):
+                    f.write("<itemref idref=\"page_" + entry + "\" linear=\"yes\" properties=\"page-spread-left\"/>\n")
+                    pageside = "right"
+                else:
+                    f.write("<itemref idref=\"page_" + entry + "\" linear=\"yes\" properties=\"page-spread-" +
+                            pageside + "\"/>\n")
+                    if pageside == "right":
+                        pageside = "left"
+                    else:
+                        pageside = "right"
+            else:
+                if entry.endswith("-b"):
+                    f.write("<itemref idref=\"page_" + entry + "\" linear=\"yes\" properties=\"page-spread-left\"/>\n")
+                    pageside = "left"
+                elif entry.endswith("-c"):
+                    f.write("<itemref idref=\"page_" + entry + "\" linear=\"yes\" properties=\"page-spread-right\"/>\n")
+                    pageside = "left"
+                else:
+                    f.write("<itemref idref=\"page_" + entry + "\" linear=\"yes\" properties=\"page-spread-" +
+                            pageside + "\"/>\n")
+                if pageside == "right":
+                    pageside = "left"
+                else:
+                    pageside = "right"
+    else:
+        for entry in reflist:
+            f.write("<itemref idref=\"page_" + entry + "\">\n")
     f.write("</spine>\n</package>\n")
     f.close()
     os.mkdir(os.path.join(dstdir, 'META-INF'))
@@ -348,7 +388,7 @@ def buildOPF(dstdir, title, filelist, cover=None):
     f.close()
 
 
-def buildEPUB(path, chapterNames, tomeNumber):
+def buildEPUB(path, chapternames, tomenumber):
     filelist = []
     chapterlist = []
     cover = None
@@ -361,71 +401,72 @@ def buildEPUB(path, chapterNames, tomeNumber):
                   "display: block;\n",
                   "margin: 0;\n",
                   "padding: 0;\n",
-                  "}\n",
-                  "#PV {\n",
-                  "position: absolute;\n",
-                  "width: 100%;\n",
-                  "height: 100%;\n",
-                  "top: 0;\n",
-                  "left: 0;\n",
-                  "}\n",
-                  "#PV-T {\n",
-                  "top: 0;\n",
-                  "width: 100%;\n",
-                  "height: 50%;\n",
-                  "}\n",
-                  "#PV-B {\n",
-                  "bottom: 0;\n",
-                  "width: 100%;\n",
-                  "height: 50%;\n",
-                  "}\n",
-                  "#PV-L {\n",
-                  "left: 0;\n",
-                  "width: 49.5%;\n",
-                  "height: 100%;\n",
-                  "float: left;\n",
-                  "}\n",
-                  "#PV-R {\n",
-                  "right: 0;\n",
-                  "width: 49.5%;\n",
-                  "height: 100%;\n",
-                  "float: right;\n",
-                  "}\n",
-                  "#PV-TL {\n",
-                  "top: 0;\n",
-                  "left: 0;\n",
-                  "width: 49.5%;\n",
-                  "height: 50%;\n",
-                  "float: left;\n",
-                  "}\n",
-                  "#PV-TR {\n",
-                  "top: 0;\n",
-                  "right: 0;\n",
-                  "width: 49.5%;\n",
-                  "height: 50%;\n",
-                  "float: right;\n",
-                  "}\n",
-                  "#PV-BL {\n",
-                  "bottom: 0;\n",
-                  "left: 0;\n",
-                  "width: 49.5%;\n",
-                  "height: 50%;\n",
-                  "float: left;\n",
-                  "}\n",
-                  "#PV-BR {\n",
-                  "bottom: 0;\n",
-                  "right: 0;\n",
-                  "width: 49.5%;\n",
-                  "height: 50%;\n",
-                  "float: right;\n",
-                  "}\n",
-                  ".PV-P {\n",
-                  "width: 100%;\n",
-                  "height: 100%;\n",
-                  "top: 0;\n",
-                  "position: absolute;\n",
-                  "display: none;\n",
                   "}\n"])
+    if options.iskindle and options.panelview:
+        f.writelines(["#PV {\n",
+                      "position: absolute;\n",
+                      "width: 100%;\n",
+                      "height: 100%;\n",
+                      "top: 0;\n",
+                      "left: 0;\n",
+                      "}\n",
+                      "#PV-T {\n",
+                      "top: 0;\n",
+                      "width: 100%;\n",
+                      "height: 50%;\n",
+                      "}\n",
+                      "#PV-B {\n",
+                      "bottom: 0;\n",
+                      "width: 100%;\n",
+                      "height: 50%;\n",
+                      "}\n",
+                      "#PV-L {\n",
+                      "left: 0;\n",
+                      "width: 49.5%;\n",
+                      "height: 100%;\n",
+                      "float: left;\n",
+                      "}\n",
+                      "#PV-R {\n",
+                      "right: 0;\n",
+                      "width: 49.5%;\n",
+                      "height: 100%;\n",
+                      "float: right;\n",
+                      "}\n",
+                      "#PV-TL {\n",
+                      "top: 0;\n",
+                      "left: 0;\n",
+                      "width: 49.5%;\n",
+                      "height: 50%;\n",
+                      "float: left;\n",
+                      "}\n",
+                      "#PV-TR {\n",
+                      "top: 0;\n",
+                      "right: 0;\n",
+                      "width: 49.5%;\n",
+                      "height: 50%;\n",
+                      "float: right;\n",
+                      "}\n",
+                      "#PV-BL {\n",
+                      "bottom: 0;\n",
+                      "left: 0;\n",
+                      "width: 49.5%;\n",
+                      "height: 50%;\n",
+                      "float: left;\n",
+                      "}\n",
+                      "#PV-BR {\n",
+                      "bottom: 0;\n",
+                      "right: 0;\n",
+                      "width: 49.5%;\n",
+                      "height: 50%;\n",
+                      "float: right;\n",
+                      "}\n",
+                      ".PV-P {\n",
+                      "width: 100%;\n",
+                      "height: 100%;\n",
+                      "top: 0;\n",
+                      "position: absolute;\n",
+                      "display: none;\n",
+                      "}\n"])
     f.close()
     for dirpath, dirnames, filenames in os.walk(os.path.join(path, 'OEBPS', 'Images')):
         chapter = False
@@ -439,9 +480,9 @@ def buildEPUB(path, chapterNames, tomeNumber):
                 cover = os.path.join(os.path.join(path, 'OEBPS', 'Images'),
                                      'cover' + getImageFileName(filelist[-1][1])[1])
                 options.covers.append((image.Cover(os.path.join(filelist[-1][0], filelist[-1][1]), cover, options,
-                                                   tomeNumber), options.uuid))
+                                                   tomenumber), options.uuid))
     # Overwrite chapternames if tree is flat and ComicInfo.xml has bookmarks
-    if not chapterNames and options.chapters:
+    if not chapternames and options.chapters:
         chapterlist = []
         globaldiff = 0
         for aChapter in options.chapters:
@@ -453,10 +494,10 @@ def buildEPUB(path, chapterNames, tomeNumber):
                 pageid -= 1
             filename = filelist[pageid][1]
             chapterlist.append((filelist[pageid][0].replace('Images', 'Text'), filename))
-            chapterNames[filename] = aChapter[1]
+            chapternames[filename] = aChapter[1]
             globaldiff = pageid - (aChapter[0] + globaldiff)
-    buildNCX(path, options.title, chapterlist, chapterNames)
-    buildNAV(path, options.title, chapterlist, chapterNames)
+    buildNCX(path, options.title, chapterlist, chapternames)
+    buildNAV(path, options.title, chapterlist, chapternames)
     buildOPF(path, options.title, filelist, cover)
 
 
@@ -542,7 +583,7 @@ def getWorkFolder(afile):
             copytree(afile, fullPath)
             sanitizePermissions(fullPath)
             return workdir
-        except:
+        except Exception:
             rmtree(workdir, True)
             raise UserWarning("Failed to prepare a workspace.")
     elif os.path.isfile(afile):
@@ -560,7 +601,7 @@ def getWorkFolder(afile):
             if cbx.isCbxFile():
                 try:
                     path = cbx.extract(workdir)
-                except:
+                except Exception:
                     rmtree(workdir, True)
                     raise UserWarning("Failed to extract archive.")
             else:
@@ -575,7 +616,7 @@ def getWorkFolder(afile):
     return newpath
 
 
-def getOutputFilename(srcpath, wantedname, ext, tomeNumber):
+def getOutputFilename(srcpath, wantedname, ext, tomenumber):
     if srcpath[-1] == os.path.sep:
         srcpath = srcpath[:-1]
     if 'Ko' in options.profile and options.format == 'EPUB':
@@ -589,16 +630,16 @@ def getOutputFilename(srcpath, wantedname, ext, tomeNumber):
             filename = os.path.join(os.path.abspath(options.output),
                                     os.path.basename(os.path.splitext(srcpath)[0]) + ext)
     elif os.path.isdir(srcpath):
-        filename = srcpath + tomeNumber + ext
+        filename = srcpath + tomenumber + ext
     else:
         if 'Ko' in options.profile and options.format == 'EPUB':
             path = srcpath.split(os.path.sep)
-            path[-1] = ''.join(e for e in path[-1].split('.')[0] if e.isalnum()) + tomeNumber + ext
+            path[-1] = ''.join(e for e in path[-1].split('.')[0] if e.isalnum()) + tomenumber + ext
             if not path[-1].split('.')[0]:
-                path[-1] = 'KCCPlaceholder' + tomeNumber + ext
+                path[-1] = 'KCCPlaceholder' + tomenumber + ext
             filename = os.path.sep.join(path)
         else:
-            filename = os.path.splitext(srcpath)[0] + tomeNumber + ext
+            filename = os.path.splitext(srcpath)[0] + tomenumber + ext
     if os.path.isfile(filename):
         counter = 0
         basename = os.path.splitext(filename)[0]
@@ -608,7 +649,7 @@ def getOutputFilename(srcpath, wantedname, ext, tomeNumber):
     return filename
 
 
-def getComicInfo(path, originalPath):
+def getComicInfo(path, originalpath):
     xmlPath = os.path.join(path, 'ComicInfo.xml')
     options.authors = ['KCC']
     options.remoteCovers = {}
@@ -617,10 +658,10 @@ def getComicInfo(path, originalPath):
     titleSuffix = ''
     if options.title == 'defaulttitle':
         defaultTitle = True
-        if os.path.isdir(originalPath):
-            options.title = os.path.basename(originalPath)
+        if os.path.isdir(originalpath):
+            options.title = os.path.basename(originalpath)
         else:
-            options.title = os.path.splitext(os.path.basename(originalPath))[0]
+            options.title = os.path.splitext(os.path.basename(originalpath))[0]
     else:
         defaultTitle = False
     if os.path.exists(xmlPath):
@@ -655,10 +696,10 @@ def getComicInfo(path, originalPath):
         os.remove(xmlPath)
 
 
-def getCoversFromMCB(mangaID):
+def getCoversFromMCB(mangaid):
     covers = {}
     try:
-        jsonRaw = urlopen(Request('http://mcd.iosphe.re/api/v1/series/' + mangaID + '/',
+        jsonRaw = urlopen(Request('http://mcd.iosphe.re/api/v1/series/' + mangaid + '/',
                                   headers={'User-Agent': 'KindleComicConverter/' + __version__}))
         jsonData = loads(jsonRaw.read().decode('utf-8'))
         for volume in jsonData['Covers']['a']:
@@ -683,9 +724,9 @@ def getTopMargin(deviceres, size):
     return str(round(y, 1))
 
 
-def getPanelViewResolution(imageSize, deviceRes):
-    scale = float(deviceRes[0]) / float(imageSize[0])
-    return int(deviceRes[0]), int(scale * imageSize[1])
+def getPanelViewResolution(imagesize, deviceres):
+    scale = float(deviceres[0]) / float(imagesize[0])
+    return int(deviceres[0]), int(scale * imagesize[1])
 
 
 def getPanelViewSize(deviceres, size):
@@ -804,19 +845,19 @@ def splitProcess(path, mode):
     return output
 
 
-def detectCorruption(tmpPath, orgPath):
+def detectCorruption(tmppath, orgpath):
     imageNumber = 0
     imageSmaller = 0
     alreadyProcessed = False
-    for root, _, files in os.walk(tmpPath, False):
+    for root, _, files in os.walk(tmppath, False):
         for name in files:
             if getImageFileName(name) is not None:
                 if not alreadyProcessed and getImageFileName(name)[0].endswith('-kcc'):
                     alreadyProcessed = True
                 path = os.path.join(root, name)
-                pathOrg = orgPath + path.split('OEBPS' + os.path.sep + 'Images')[1]
+                pathOrg = orgpath + path.split('OEBPS' + os.path.sep + 'Images')[1]
                 if os.path.getsize(path) == 0:
-                    rmtree(os.path.join(tmpPath, '..', '..'), True)
+                    rmtree(os.path.join(tmppath, '..', '..'), True)
                     raise RuntimeError('Image file %s is corrupted.' % pathOrg)
                 try:
                     img = Image.open(path)
@@ -827,7 +868,7 @@ def detectCorruption(tmpPath, orgPath):
                     if options.profileData[1][0] > img.size[0] and options.profileData[1][1] > img.size[1]:
                         imageSmaller += 1
                 except Exception as err:
-                    rmtree(os.path.join(tmpPath, '..', '..'), True)
+                    rmtree(os.path.join(tmppath, '..', '..'), True)
                     if 'decoder' in str(err) and 'not available' in str(err):
                         raise RuntimeError('Pillow was compiled without JPG and/or PNG decoder.')
                     else:
@@ -856,28 +897,28 @@ def createNewTome():
     return tomePath, tomePathRoot
 
 
-def slugify(value, isDir):
-    if isDir:
-        value = slugifyExt(value, regex_pattern=r'[^-a-z0-9_\.]+')
+def slugify(value, isdir):
+    if isdir:
+        value = slugifyExt(value, regex_pattern=r'[^-a-z0-9_\.]+').strip('.')
     else:
-        value = slugifyExt(value)
+        value = slugifyExt(value).strip('.')
     value = sub(r'0*([0-9]{4,})', r'\1', sub(r'([0-9]+)', r'0000\1', value, count=2))
     return value
 
 
-def makeZIP(zipFilename, baseDir, isEPUB=False):
-    zipFilename = os.path.abspath(zipFilename) + '.zip'
-    zipOutput = ZipFile(zipFilename, 'w', ZIP_DEFLATED)
-    if isEPUB:
+def makeZIP(zipfilename, basedir, isepub=False):
+    zipfilename = os.path.abspath(zipfilename) + '.zip'
+    zipOutput = ZipFile(zipfilename, 'w', ZIP_DEFLATED)
+    if isepub:
         zipOutput.writestr('mimetype', 'application/epub+zip', ZIP_STORED)
-    for dirpath, _, filenames in os.walk(baseDir):
+    for dirpath, _, filenames in os.walk(basedir):
         for name in filenames:
             path = os.path.normpath(os.path.join(dirpath, name))
-            aPath = os.path.normpath(os.path.join(dirpath.replace(baseDir, ''), name))
+            aPath = os.path.normpath(os.path.join(dirpath.replace(basedir, ''), name))
             if os.path.isfile(path):
                 zipOutput.write(path, aPath)
     zipOutput.close()
-    return zipFilename
+    return zipfilename
 
 
 def makeParser():
@@ -906,7 +947,7 @@ def makeParser():
     outputOptions.add_option("-t", "--title", action="store", dest="title", default="defaulttitle",
                              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]")
+                             help="Output format (Available options: Auto, MOBI, EPUB, CBZ, KFX) [Default=Auto]")
     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]")
@@ -953,6 +994,7 @@ def checkOptions():
     options.panelview = True
     options.iskindle = False
     options.bordersColor = None
+    options.kfx = False
     if options.format == 'Auto':
         if options.profile in ['K1', 'K2', 'K34', 'K578', 'KPW', 'KV', 'KO']:
             options.format = 'MOBI'
@@ -967,7 +1009,7 @@ def checkOptions():
     if options.black_borders:
         options.bordersColor = 'black'
     # Splitting MOBI is not optional
-    if options.format == 'MOBI' and options.batchsplit != 2:
+    if (options.format == 'MOBI' or options.format == 'KFX') 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 == 'K34' or options.profile == 'KDX':
@@ -989,6 +1031,11 @@ def checkOptions():
     # CBZ files on Kindle DX/DXG support higher resolution
     if options.profile == 'KDX' and options.format == 'CBZ':
         options.customheight = 1200
+    # KFX output create EPUB that might be can be by jhowell KFX Output Calibre plugin
+    if options.format == 'KFX':
+        options.format = 'EPUB'
+        options.kfx = True
+        options.panelview = False
     # Override profile data
     if options.customwidth != 0 or options.customheight != 0:
         X = image.ProfileData.Profiles[options.profile][1][0]
@@ -1039,13 +1086,13 @@ def checkPre(source):
     try:
         with TemporaryFile(prefix='KCC-', dir=src):
             pass
-    except:
+    except Exception:
         raise UserWarning("Target directory is not writable.")
 
 
-def makeBook(source, qtGUI=None):
+def makeBook(source, qtgui=None):
     global GUI
-    GUI = qtGUI
+    GUI = qtgui
     if GUI:
         GUI.progressBarTick.emit('1')
     else:
@@ -1061,7 +1108,7 @@ def makeBook(source, qtGUI=None):
             y = 1024
         else:
             y = image.ProfileData.Profiles[options.profile][1][1]
-        comic2panel.main(['-y ' + str(y), '-i', '-m', path], qtGUI)
+        comic2panel.main(['-y ' + str(y), '-i', '-m', path], qtgui)
     print("Processing images...")
     if GUI:
         GUI.progressBarTick.emit('Processing images')
@@ -1192,9 +1239,9 @@ def makeMOBIWorker(item):
         return [kindlegenErrorCode, kindlegenError, item]
 
 
-def makeMOBI(work, qtGUI=None):
+def makeMOBI(work, qtgui=None):
     global GUI, makeMOBIWorkerPool, makeMOBIWorkerOutput
-    GUI = qtGUI
+    GUI = qtgui
     makeMOBIWorkerOutput = []
     availableMemory = virtual_memory().total / 1000000000
     if availableMemory <= 2:
diff --git a/kindlecomicconverter/comic2panel.py b/kindlecomicconverter/comic2panel.py
index 14b3294..c3d9e1c 100644
--- a/kindlecomicconverter/comic2panel.py
+++ b/kindlecomicconverter/comic2panel.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 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
@@ -93,6 +93,7 @@ def splitImageTick(output):
             splitWorkerPool.terminate()
 
 
+# noinspection PyUnboundLocalVariable
 def splitImage(work):
     try:
         path = work[0]
@@ -140,9 +141,7 @@ def splitImage(work):
 
             if opt.debug:
                 for panel in panelsProcessed:
-                    # noinspection PyUnboundLocalVariable
                     draw.rectangle([(0, panel[0]), (widthImg, panel[1])], (0, 255, 0, 128), (0, 0, 255, 255))
-                # noinspection PyUnboundLocalVariable
                 debugImage = Image.alpha_composite(imgOrg.convert(mode='RGBA'), drawImg)
                 debugImage.save(os.path.join(path, os.path.splitext(name)[0] + '-debug.png'), 'PNG')
 
@@ -185,7 +184,7 @@ def splitImage(work):
         return str(sys.exc_info()[1]), sanitizeTrace(sys.exc_info()[2])
 
 
-def main(argv=None, qtGUI=None):
+def main(argv=None, qtgui=None):
     global options, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput
     parser = OptionParser(usage="Usage: kcc-c2p [options] comic_folder", add_help_option=False)
     mainOptions = OptionGroup(parser, "MANDATORY")
@@ -203,8 +202,8 @@ def main(argv=None, qtGUI=None):
     parser.add_option_group(mainOptions)
     parser.add_option_group(otherOptions)
     options, args = parser.parse_args(argv)
-    if qtGUI:
-        GUI = qtGUI
+    if qtgui:
+        GUI = qtgui
     else:
         GUI = None
     if len(args) != 1:
diff --git a/kindlecomicconverter/dualmetafix.py b/kindlecomicconverter/dualmetafix.py
index 566ceb5..e6be255 100644
--- a/kindlecomicconverter/dualmetafix.py
+++ b/kindlecomicconverter/dualmetafix.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 # Based on initial version of DualMetaFix. Copyright (C) 2013 Kevin Hendricks
-# Changes for KCC Copyright (C) 2014-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Changes for KCC Copyright (C) 2014-2018 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
diff --git a/kindlecomicconverter/image.py b/kindlecomicconverter/image.py
index e7f29a4..d7c05ec 100755
--- a/kindlecomicconverter/image.py
+++ b/kindlecomicconverter/image.py
@@ -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-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 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
@@ -273,17 +273,17 @@ class ComicPage:
             method = Image.BICUBIC
         else:
             method = Image.LANCZOS
-        if self.opt.stretch:
+        if self.opt.stretch or (self.opt.kfx and ('-KCC-B' in self.targetPath or '-KCC-C' in self.targetPath)):
             self.image = self.image.resize(self.size, method)
         elif self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1] and not self.opt.upscale:
-            if self.opt.format == 'CBZ':
+            if self.opt.format == 'CBZ' or self.opt.kfx:
                 borderw = int((self.size[0] - self.image.size[0]) / 2)
                 borderh = int((self.size[1] - self.image.size[1]) / 2)
                 self.image = ImageOps.expand(self.image, border=(borderw, borderh), fill=self.fill)
                 if self.image.size[0] != self.size[0] or self.image.size[1] != self.size[1]:
                     self.image = ImageOps.fit(self.image, self.size, method=Image.BICUBIC, centering=(0.5, 0.5))
         else:
-            if self.opt.format == 'CBZ':
+            if self.opt.format == 'CBZ' or self.opt.kfx:
                 ratioDev = float(self.size[0]) / float(self.size[1])
                 if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev:
                     diff = int(self.image.size[1] * ratioDev) - self.image.size[0]
@@ -299,53 +299,53 @@ class ComicPage:
                 if self.image.size[0] > self.size[0] or self.image.size[1] > self.size[1]:
                     self.image.thumbnail(self.size, Image.LANCZOS)
 
-    def getBoundingBox(self, tmpImg):
-        min_margin = [int(0.005 * i + 0.5) for i in tmpImg.size]
-        max_margin = [int(0.1 * i + 0.5) for i in tmpImg.size]
-        bbox = tmpImg.getbbox()
+    def getBoundingBox(self, tmptmg):
+        min_margin = [int(0.005 * i + 0.5) for i in tmptmg.size]
+        max_margin = [int(0.1 * i + 0.5) for i in tmptmg.size]
+        bbox = tmptmg.getbbox()
         bbox = (
             max(0, min(max_margin[0], bbox[0] - min_margin[0])),
             max(0, min(max_margin[1], bbox[1] - min_margin[1])),
-            min(tmpImg.size[0],
-                max(tmpImg.size[0] - max_margin[0], bbox[2] + min_margin[0])),
-            min(tmpImg.size[1],
-                max(tmpImg.size[1] - max_margin[1], bbox[3] + min_margin[1])),
+            min(tmptmg.size[0],
+                max(tmptmg.size[0] - max_margin[0], bbox[2] + min_margin[0])),
+            min(tmptmg.size[1],
+                max(tmptmg.size[1] - max_margin[1], bbox[3] + min_margin[1])),
         )
         return bbox
 
     def cropPageNumber(self, power):
         if self.fill != 'white':
-            tmpImg = self.image.convert(mode='L')
+            tmptmg = self.image.convert(mode='L')
         else:
-            tmpImg = ImageOps.invert(self.image.convert(mode='L'))
-        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 >= 16 * power) and x)
-        self.image = self.image.crop(tmpImg.getbbox()) if tmpImg.getbbox() else self.image
+            tmptmg = ImageOps.invert(self.image.convert(mode='L'))
+        tmptmg = tmptmg.point(lambda x: x and 255)
+        tmptmg = tmptmg.filter(ImageFilter.MinFilter(size=3))
+        tmptmg = tmptmg.filter(ImageFilter.GaussianBlur(radius=5))
+        tmptmg = tmptmg.point(lambda x: (x >= 16 * power) and x)
+        self.image = self.image.crop(tmptmg.getbbox()) if tmptmg.getbbox() else self.image
 
     def cropMargin(self, power):
         if self.fill != 'white':
-            tmpImg = self.image.convert(mode='L')
+            tmptmg = self.image.convert(mode='L')
         else:
-            tmpImg = ImageOps.invert(self.image.convert(mode='L'))
-        tmpImg = tmpImg.filter(ImageFilter.GaussianBlur(radius=3))
-        tmpImg = tmpImg.point(lambda x: (x >= 16 * power) and x)
-        self.image = self.image.crop(self.getBoundingBox(tmpImg)) if tmpImg.getbbox() else self.image
+            tmptmg = ImageOps.invert(self.image.convert(mode='L'))
+        tmptmg = tmptmg.filter(ImageFilter.GaussianBlur(radius=3))
+        tmptmg = tmptmg.point(lambda x: (x >= 16 * power) and x)
+        self.image = self.image.crop(self.getBoundingBox(tmptmg)) if tmptmg.getbbox() else self.image
 
 
 class Cover:
-    def __init__(self, source, target, opt, tomeNumber):
+    def __init__(self, source, target, opt, tomeid):
         self.options = opt
         self.source = source
         self.target = target
-        if tomeNumber == 0:
-            self.tomeNumber = 1
+        if tomeid == 0:
+            self.tomeid = 1
         else:
-            self.tomeNumber = tomeNumber
-        if self.tomeNumber in self.options.remoteCovers:
+            self.tomeid = tomeid
+        if self.tomeid in self.options.remoteCovers:
             try:
-                source = urlopen(Request(quote(self.options.remoteCovers[self.tomeNumber]).replace('%3A', ':', 1),
+                source = urlopen(Request(quote(self.options.remoteCovers[self.tomeid]).replace('%3A', ':', 1),
                                          headers={'User-Agent': 'KindleComicConverter/' + __version__})).read()
                 self.image = Image.open(BytesIO(source))
             except Exception:
diff --git a/kindlecomicconverter/kindle.py b/kindlecomicconverter/kindle.py
index 1eea63c..f9595f6 100644
--- a/kindlecomicconverter/kindle.py
+++ b/kindlecomicconverter/kindle.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 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
diff --git a/kindlecomicconverter/metadata.py b/kindlecomicconverter/metadata.py
index 714dcd1..da16718 100644
--- a/kindlecomicconverter/metadata.py
+++ b/kindlecomicconverter/metadata.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 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
diff --git a/kindlecomicconverter/pdfjpgextract.py b/kindlecomicconverter/pdfjpgextract.py
index 90d0643..250cf35 100644
--- a/kindlecomicconverter/pdfjpgextract.py
+++ b/kindlecomicconverter/pdfjpgextract.py
@@ -1,5 +1,5 @@
 # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 Pawel Jastrzebski <pawelj@iosphe.re>
 #
 # Based upon the code snippet by Ned Batchelder
 # (http://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html)
@@ -25,17 +25,16 @@ from string import ascii_uppercase, digits
 
 
 class PdfJpgExtract:
-    def __init__(self, origFileName):
-        self.origFileName = origFileName
-        self.filename = os.path.splitext(origFileName)
-        # noinspection PyUnusedLocal
-        self.path = self.filename[0] + "-KCC-" + ''.join(choice(ascii_uppercase + digits) for x in range(3))
+    def __init__(self, fname):
+        self.fname = fname
+        self.filename = os.path.splitext(fname)
+        self.path = self.filename[0] + "-KCC-" + ''.join(choice(ascii_uppercase + digits) for _ in range(3))
 
     def getPath(self):
         return self.path
 
     def extract(self):
-        pdf = open(self.origFileName, "rb").read()
+        pdf = open(self.fname, "rb").read()
         startmark = b"\xff\xd8"
         startfix = 0
         endmark = b"\xff\xd9"
diff --git a/kindlecomicconverter/shared.py b/kindlecomicconverter/shared.py
index c2a8ecf..6778621 100644
--- a/kindlecomicconverter/shared.py
+++ b/kindlecomicconverter/shared.py
@@ -1,5 +1,5 @@
 # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 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
@@ -73,8 +73,8 @@ def walkLevel(some_dir, level=1):
             del dirs[:]
 
 
-def md5Checksum(filePath):
-    with open(filePath, 'rb') as fh:
+def md5Checksum(fpath):
+    with open(fpath, 'rb') as fh:
         m = md5()
         while True:
             data = fh.read(8192)
@@ -84,8 +84,8 @@ def md5Checksum(filePath):
         return m.hexdigest()
 
 
-def check7ZFile(filePath):
-    with open(filePath, 'rb') as fh:
+def check7ZFile(fpath):
+    with open(fpath, 'rb') as fh:
         header = fh.read(6)
     return header == b"7z\xbc\xaf'\x1c"
 
diff --git a/kindlecomicconverter/startup.py b/kindlecomicconverter/startup.py
index aa78a0a..deb6313 100644
--- a/kindlecomicconverter/startup.py
+++ b/kindlecomicconverter/startup.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 # Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
-# Copyright (c) 2013-2017 Pawel Jastrzebski <pawelj@iosphe.re>
+# Copyright (c) 2013-2018 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