diff --git a/README.md b/README.md
index fd88bc9..8ae29c0 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ You can find the latest released binary at the following links:
### For compiling/running from source:
- Python 2.7 - Included in MacOS and Linux, follow the [official documentation](http://www.python.org/getit/windows/) to install on Windows.
- PyQt4 - Please refer to official documentation for installing into your system.
-- [Pillow](http://pypi.python.org/pypi/Pillow/) - For comic optimizations. Please refer to official documentation for installing into your system.
+- [Pillow](http://pypi.python.org/pypi/Pillow/) 2.2.1+ - For comic optimizations. Please refer to official documentation for installing into your system.
## USAGE
diff --git a/kcc.py b/kcc.py
index dec47c2..ca1efe6 100644
--- a/kcc.py
+++ b/kcc.py
@@ -27,7 +27,7 @@ import sys
import os
try:
# noinspection PyUnresolvedReferences
- from PyQt4 import QtGui
+ from PyQt4 import QtCore, QtGui, QtNetwork
except ImportError:
print "ERROR: PyQT4 is not installed!"
exit(1)
@@ -41,13 +41,67 @@ elif sys.platform.startswith('linux'):
else:
from kcc import KCC_ui
+
+class QApplicationMessaging(QtGui.QApplication):
+ def __init__(self, argv):
+ QtGui.QApplication.__init__(self, argv)
+ self._memory = QtCore.QSharedMemory(self)
+ self._memory.setKey('KCC')
+ if self._memory.attach():
+ self._running = True
+ else:
+ self._running = False
+ if not self._memory.create(1):
+ raise RuntimeError(self._memory.errorString().toLocal8Bit().data())
+ self._key = 'KCC'
+ self._timeout = 1000
+ self._server = QtNetwork.QLocalServer(self)
+ if not self.isRunning():
+ self._server.newConnection.connect(self.handleMessage)
+ self._server.listen(self._key)
+
+ def isRunning(self):
+ return self._running
+
+ def handleMessage(self):
+ socket = self._server.nextPendingConnection()
+ if socket.waitForReadyRead(self._timeout):
+ self.emit(QtCore.SIGNAL('messageFromOtherInstance'), socket.readAll().data())
+
+ def sendMessage(self, message):
+ if self.isRunning():
+ socket = QtNetwork.QLocalSocket(self)
+ socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly)
+ if not socket.waitForConnected(self._timeout):
+ return False
+ socket.write(message.encode('utf8'))
+ if not socket.waitForBytesWritten(self._timeout):
+ return False
+ socket.disconnectFromServer()
+ return True
+ return False
+
freeze_support()
-APP = QtGui.QApplication(sys.argv)
+APP = QApplicationMessaging(sys.argv)
+if APP.isRunning():
+ if len(sys.argv) > 1:
+ APP.sendMessage('Araise!')
+ APP.sendMessage(sys.argv[1].decode(sys.getfilesystemencoding()))
+ sys.exit(0)
+ else:
+ messageBox = QtGui.QMessageBox()
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(':/Icon/icons/comic2ebook.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ messageBox.setWindowIcon(icon)
+ QtGui.QMessageBox.critical(messageBox, 'KCC - Error', 'KCC is already running!', QtGui.QMessageBox.Ok)
+ sys.exit(1)
KCC = QtGui.QMainWindow()
UI = KCC_ui.Ui_KCC()
UI.setupUi(KCC)
-GUI = KCC_gui.Ui_KCC(UI, KCC)
+GUI = KCC_gui.Ui_KCC(UI, KCC, APP)
KCC.setWindowTitle("Kindle Comic Converter " + __version__)
KCC.show()
KCC.raise_()
+if len(sys.argv) > 1:
+ GUI.handleMessage(sys.argv[1].decode(sys.getfilesystemencoding()))
sys.exit(APP.exec_())
diff --git a/kcc/KCC_gui.py b/kcc/KCC_gui.py
index ece60ba..3740699 100644
--- a/kcc/KCC_gui.py
+++ b/kcc/KCC_gui.py
@@ -159,7 +159,7 @@ class WorkerThread(QtCore.QThread):
argv.append("--forcecolor")
for i in range(GUI.JobList.count()):
if GUI.JobList.item(i).icon().isNull():
- currentJobs.append(str(GUI.JobList.item(i).text()))
+ currentJobs.append(unicode(GUI.JobList.item(i).text()))
GUI.JobList.clear()
for job in currentJobs:
time.sleep(0.5)
@@ -215,8 +215,8 @@ class WorkerThread(QtCore.QThread):
try:
self.kindlegenErrorCode = 0
if os.path.getsize(item) < 367001600:
- output = Popen('kindlegen -locale en "' + item + '"', stdout=PIPE, stderr=STDOUT,
- shell=True)
+ output = Popen('kindlegen -locale en "' + item.encode(sys.getfilesystemencoding()) +
+ '"', stdout=PIPE, stderr=STDOUT, shell=True)
for line in output.stdout:
# ERROR: Generic error
if "Error(" in line:
@@ -312,18 +312,11 @@ class Ui_KCC(object):
dnames = dirDialog.selectedFiles()
else:
dnames = ""
- # Lame UTF-8 security measure
for dname in dnames:
- try:
- str(dname)
- except Exception:
- QtGui.QMessageBox.critical(MainWindow, 'KCC Error', "Path cannot contain non-ASCII characters.",
- QtGui.QMessageBox.Ok)
- return
- if str(dname) != "":
+ if unicode(dname) != "":
if sys.platform == 'win32':
dname = dname.replace('/', '\\')
- self.lastPath = os.path.abspath(os.path.join(str(dname), os.pardir))
+ self.lastPath = os.path.abspath(os.path.join(unicode(dname), os.pardir))
GUI.JobList.addItem(dname)
def selectFile(self):
@@ -344,16 +337,9 @@ class Ui_KCC(object):
else:
fnames = QtGui.QFileDialog.getOpenFileNames(MainWindow, 'Select file', self.lastPath,
'*.cbz *.zip *.pdf')
- # Lame UTF-8 security measure
for fname in fnames:
- try:
- str(fname)
- except Exception:
- QtGui.QMessageBox.critical(MainWindow, 'KCC Error', "Path cannot contain non-ASCII characters.",
- QtGui.QMessageBox.Ok)
- return
- if str(fname) != "":
- self.lastPath = os.path.abspath(os.path.join(str(fname), os.pardir))
+ if unicode(fname) != "":
+ self.lastPath = os.path.abspath(os.path.join(unicode(fname), os.pardir))
GUI.JobList.addItem(fname)
def clearJobs(self):
@@ -577,7 +563,7 @@ class Ui_KCC(object):
GUI.JobList.scrollToBottom()
def showDialog(self, message):
- QtGui.QMessageBox.critical(MainWindow, 'KCC Error', message, QtGui.QMessageBox.Ok)
+ QtGui.QMessageBox.critical(MainWindow, 'KCC - Error', message, QtGui.QMessageBox.Ok)
def updateProgressbar(self, new=False, status=False):
if new == "status":
@@ -643,7 +629,11 @@ class Ui_KCC(object):
'GammaSlider': float(self.GammaValue)*100}))
self.settings.sync()
- def __init__(self, UI, KCC):
+ def handleMessage(self, message):
+ #TODO
+ print message
+
+ def __init__(self, UI, KCC, APP):
global GUI, MainWindow
GUI = UI
MainWindow = KCC
@@ -714,6 +704,7 @@ class Ui_KCC(object):
self.addMessage('Cannot find 7za!'
' Processing of CB7/7Z files will be disabled.', 'warning')
+ APP.connect(APP, QtCore.SIGNAL('messageFromOtherInstance'), self.handleMessage)
GUI.BasicModeButton.clicked.connect(self.modeBasic)
GUI.AdvModeButton.clicked.connect(self.modeAdvanced)
GUI.DirectoryButton.clicked.connect(self.selectDir)
diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py
index 3361d7d..408b470 100755
--- a/kcc/comic2ebook.py
+++ b/kcc/comic2ebook.py
@@ -184,7 +184,7 @@ def buildNCX(dstdir, title, chapters):
"\n",
"\n",
"\n",
- "", title, "\n",
+ "", title.encode('utf-8'), "\n",
""
])
for chapter in chapters:
@@ -192,8 +192,9 @@ def buildNCX(dstdir, title, chapters):
if os.path.basename(folder) != "Text":
title = os.path.basename(folder)
filename = getImageFileName(os.path.join(folder, chapter[1]))
- f.write("" + title
- + "\n")
+ f.write(""
+ + title.encode('utf-8') + "\n")
f.write("\n")
f.close()
return
@@ -213,7 +214,7 @@ def buildOPF(dstdir, title, filelist, cover=None):
"xmlns=\"http://www.idpf.org/2007/opf\">\n",
"\n",
- "", title, "\n",
+ "", title.encode('utf-8'), "\n",
"en-US\n",
"", options.uuid, "\n",
"KCC\n",
diff --git a/kcc/comic2panel.py b/kcc/comic2panel.py
index 705dffe..c5ae4db 100644
--- a/kcc/comic2panel.py
+++ b/kcc/comic2panel.py
@@ -32,6 +32,9 @@ from multiprocessing import Pool, Queue, freeze_support
try:
# noinspection PyUnresolvedReferences
from PIL import Image, ImageStat
+ if tuple(map(int, ('2.2.1'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))):
+ print "ERROR: Pillow 2.2.1 or newer is required!"
+ exit(1)
except ImportError:
print "ERROR: Pillow is not installed!"
exit(1)
diff --git a/kcc/image.py b/kcc/image.py
index 1e56221..bc3c7fe 100755
--- a/kcc/image.py
+++ b/kcc/image.py
@@ -24,6 +24,9 @@ import os
try:
# noinspection PyUnresolvedReferences
from PIL import Image, ImageOps, ImageStat, ImageChops
+ if tuple(map(int, ('2.2.1'.split(".")))) > tuple(map(int, (Image.PILLOW_VERSION.split(".")))):
+ print "ERROR: Pillow 2.2.1 or newer is required!"
+ exit(1)
except ImportError:
print "ERROR: Pillow is not installed!"
exit(1)