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)