mirror of
https://github.com/ciromattia/kcc
synced 2025-12-25 15:41:44 +00:00
Full UTF-8 awareness (close #74)
Tested only on Windows. But he had the biggest problems with it.
This commit is contained in:
11
kcc.py
11
kcc.py
@@ -77,7 +77,7 @@ elif sys.platform.startswith('win'):
|
|||||||
|
|
||||||
# Implementing detection of already running KCC instance and forwarding argv to it
|
# Implementing detection of already running KCC instance and forwarding argv to it
|
||||||
class QApplicationMessaging(QtWidgets.QApplication):
|
class QApplicationMessaging(QtWidgets.QApplication):
|
||||||
messageFromOtherInstance = QtCore.pyqtSignal(str)
|
messageFromOtherInstance = QtCore.pyqtSignal(bytes)
|
||||||
|
|
||||||
def __init__(self, argv):
|
def __init__(self, argv):
|
||||||
QtWidgets.QApplication.__init__(self, argv)
|
QtWidgets.QApplication.__init__(self, argv)
|
||||||
@@ -102,7 +102,7 @@ class QApplicationMessaging(QtWidgets.QApplication):
|
|||||||
def handleMessage(self):
|
def handleMessage(self):
|
||||||
socket = self._server.nextPendingConnection()
|
socket = self._server.nextPendingConnection()
|
||||||
if socket.waitForReadyRead(self._timeout):
|
if socket.waitForReadyRead(self._timeout):
|
||||||
self.messageFromOtherInstance.emit(socket.readAll().data().decode('utf8'))
|
self.messageFromOtherInstance.emit(socket.readAll().data())
|
||||||
|
|
||||||
def sendMessage(self, message):
|
def sendMessage(self, message):
|
||||||
if self.isRunning():
|
if self.isRunning():
|
||||||
@@ -110,7 +110,8 @@ class QApplicationMessaging(QtWidgets.QApplication):
|
|||||||
socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly)
|
socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly)
|
||||||
if not socket.waitForConnected(self._timeout):
|
if not socket.waitForConnected(self._timeout):
|
||||||
return False
|
return False
|
||||||
socket.write(message.encode('utf8'))
|
# noinspection PyArgumentList
|
||||||
|
socket.write(bytes(message, 'UTF-8'))
|
||||||
if not socket.waitForBytesWritten(self._timeout):
|
if not socket.waitForBytesWritten(self._timeout):
|
||||||
return False
|
return False
|
||||||
socket.disconnectFromServer()
|
socket.disconnectFromServer()
|
||||||
@@ -133,7 +134,7 @@ if __name__ == "__main__":
|
|||||||
KCCAplication = QApplicationMessaging(sys.argv)
|
KCCAplication = QApplicationMessaging(sys.argv)
|
||||||
if KCCAplication.isRunning():
|
if KCCAplication.isRunning():
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
KCCAplication.sendMessage(sys.argv[1].decode(sys.getfilesystemencoding()))
|
KCCAplication.sendMessage(sys.argv[1])
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
else:
|
else:
|
||||||
messageBox = QtWidgets.QMessageBox()
|
messageBox = QtWidgets.QMessageBox()
|
||||||
@@ -146,5 +147,5 @@ if __name__ == "__main__":
|
|||||||
KCCWindow = QMainWindowKCC()
|
KCCWindow = QMainWindowKCC()
|
||||||
KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow)
|
KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow)
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
KCCUI.handleMessage(sys.argv[1].decode(sys.getfilesystemencoding()))
|
KCCUI.handleMessage(sys.argv[1])
|
||||||
sys.exit(KCCAplication.exec_())
|
sys.exit(KCCAplication.exec_())
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ class WebServerHandler(BaseHTTPRequestHandler):
|
|||||||
'</body>\n'
|
'</body>\n'
|
||||||
'</html>\n', 'UTF-8'))
|
'</html>\n', 'UTF-8'))
|
||||||
elif sendReply:
|
elif sendReply:
|
||||||
outputFile = GUI.completedWork[urllib.parse.unquote(self.path[1:])].decode('utf-8')
|
outputFile = GUI.completedWork[urllib.parse.unquote(self.path[1:])]
|
||||||
fp = open(outputFile, 'rb')
|
fp = open(outputFile, 'rb')
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header('Content-type', mimetype)
|
self.send_header('Content-type', mimetype)
|
||||||
@@ -243,8 +243,7 @@ class KindleGenThread(QtCore.QRunnable):
|
|||||||
kindlegenError = ''
|
kindlegenError = ''
|
||||||
try:
|
try:
|
||||||
if os.path.getsize(self.work) < 367001600:
|
if os.path.getsize(self.work) < 367001600:
|
||||||
output = Popen('kindlegen -locale en "' + self.work.encode(sys.getfilesystemencoding()).decode('utf-8')
|
output = Popen('kindlegen -locale en "' + self.work + '"', stdout=PIPE, stderr=STDOUT, shell=True)
|
||||||
+ '"', stdout=PIPE, stderr=STDOUT, shell=True)
|
|
||||||
for line in output.stdout:
|
for line in output.stdout:
|
||||||
line = line.decode('utf-8')
|
line = line.decode('utf-8')
|
||||||
# ERROR: Generic error
|
# ERROR: Generic error
|
||||||
@@ -486,7 +485,7 @@ class WorkerThread(QtCore.QThread):
|
|||||||
GUI.progress.content = ''
|
GUI.progress.content = ''
|
||||||
mobiPath = item.replace('.epub', '.mobi')
|
mobiPath = item.replace('.epub', '.mobi')
|
||||||
os.remove(mobiPath + '_toclean')
|
os.remove(mobiPath + '_toclean')
|
||||||
GUI.completedWork[os.path.basename(mobiPath).encode('utf-8')] = mobiPath.encode('utf-8')
|
GUI.completedWork[os.path.basename(mobiPath)] = mobiPath
|
||||||
MW.addMessage.emit('Cleaning MOBI files... <b>Done!</b>', 'info', True)
|
MW.addMessage.emit('Cleaning MOBI files... <b>Done!</b>', 'info', True)
|
||||||
else:
|
else:
|
||||||
GUI.progress.content = ''
|
GUI.progress.content = ''
|
||||||
@@ -516,7 +515,7 @@ class WorkerThread(QtCore.QThread):
|
|||||||
False)
|
False)
|
||||||
else:
|
else:
|
||||||
for item in outputPath:
|
for item in outputPath:
|
||||||
GUI.completedWork[os.path.basename(item).encode('utf-8')] = item.encode('utf-8')
|
GUI.completedWork[os.path.basename(item)] = item
|
||||||
GUI.progress.content = ''
|
GUI.progress.content = ''
|
||||||
GUI.progress.stop()
|
GUI.progress.stop()
|
||||||
MW.hideProgressBar.emit()
|
MW.hideProgressBar.emit()
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import zipfile
|
import zipfile
|
||||||
import locale
|
|
||||||
from subprocess import STDOUT, PIPE
|
from subprocess import STDOUT, PIPE
|
||||||
from psutil import Popen
|
from psutil import Popen
|
||||||
from shutil import move
|
from shutil import move
|
||||||
@@ -59,7 +58,7 @@ class CBxArchive:
|
|||||||
cbzFile.extractall(targetdir, filelist)
|
cbzFile.extractall(targetdir, filelist)
|
||||||
|
|
||||||
def extractCBR(self, targetdir):
|
def extractCBR(self, targetdir):
|
||||||
cbrFile = rarfile.RarFile(self.origFileName.encode(locale.getpreferredencoding()))
|
cbrFile = rarfile.RarFile(self.origFileName)
|
||||||
filelist = []
|
filelist = []
|
||||||
for f in cbrFile.namelist():
|
for f in cbrFile.namelist():
|
||||||
if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('thumbs.db'):
|
if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('thumbs.db'):
|
||||||
@@ -70,16 +69,15 @@ class CBxArchive:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass # the dir exists so we are going to extract the images only.
|
pass # the dir exists so we are going to extract the images only.
|
||||||
else:
|
else:
|
||||||
filelist.append(f.encode(locale.getpreferredencoding()))
|
filelist.append(f)
|
||||||
cbrFile.extractall(targetdir, filelist)
|
cbrFile.extractall(targetdir, filelist)
|
||||||
|
|
||||||
def extractCB7(self, targetdir):
|
def extractCB7(self, targetdir):
|
||||||
output = Popen('7za x "' + self.origFileName.encode(locale.getpreferredencoding()) +
|
output = Popen('7za x "' + self.origFileName + '" -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -o"'
|
||||||
'" -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -o"' + targetdir + '"',
|
+ targetdir + '"', stdout=PIPE, stderr=STDOUT, shell=True)
|
||||||
stdout=PIPE, stderr=STDOUT, shell=True)
|
|
||||||
extracted = False
|
extracted = False
|
||||||
for line in output.stdout:
|
for line in output.stdout:
|
||||||
if "Everything is Ok" in line:
|
if b"Everything is Ok" in line:
|
||||||
extracted = True
|
extracted = True
|
||||||
if not extracted:
|
if not extracted:
|
||||||
raise OSError
|
raise OSError
|
||||||
@@ -97,6 +95,10 @@ class CBxArchive:
|
|||||||
adir.remove('ComicInfo.xml')
|
adir.remove('ComicInfo.xml')
|
||||||
if len(adir) == 1 and os.path.isdir(os.path.join(targetdir, adir[0])):
|
if len(adir) == 1 and os.path.isdir(os.path.join(targetdir, adir[0])):
|
||||||
for f in os.listdir(os.path.join(targetdir, adir[0])):
|
for f in os.listdir(os.path.join(targetdir, adir[0])):
|
||||||
|
# If directory names contain UTF-8 chars shutil.move can't clean up the mess alone
|
||||||
|
if os.path.isdir(os.path.join(targetdir, f)):
|
||||||
|
os.rename(os.path.join(targetdir, adir[0], f), os.path.join(targetdir, adir[0], f + '-A'))
|
||||||
|
f += '-A'
|
||||||
move(os.path.join(targetdir, adir[0], f), targetdir)
|
move(os.path.join(targetdir, adir[0], f), targetdir)
|
||||||
os.rmdir(os.path.join(targetdir, adir[0]))
|
os.rmdir(os.path.join(targetdir, adir[0]))
|
||||||
return targetdir
|
return targetdir
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def buildHTML(path, imgfile):
|
|||||||
if not os.path.exists(htmlpath):
|
if not os.path.exists(htmlpath):
|
||||||
os.makedirs(htmlpath)
|
os.makedirs(htmlpath)
|
||||||
htmlfile = os.path.join(htmlpath, filename[0] + '.html')
|
htmlfile = os.path.join(htmlpath, filename[0] + '.html')
|
||||||
f = open(htmlfile, "w")
|
f = open(htmlfile, "w", encoding='UTF-8')
|
||||||
f.writelines(["<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ",
|
f.writelines(["<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ",
|
||||||
"\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n",
|
"\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n",
|
||||||
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n",
|
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n",
|
||||||
@@ -189,9 +189,8 @@ def buildHTML(path, imgfile):
|
|||||||
|
|
||||||
def buildNCX(dstdir, title, chapters):
|
def buildNCX(dstdir, title, chapters):
|
||||||
options.uuid = str(uuid4())
|
options.uuid = str(uuid4())
|
||||||
#options.uuid = options.uuid.encode('utf-8')
|
|
||||||
ncxfile = os.path.join(dstdir, 'OEBPS', 'toc.ncx')
|
ncxfile = os.path.join(dstdir, 'OEBPS', 'toc.ncx')
|
||||||
f = open(ncxfile, "w")
|
f = open(ncxfile, "w", encoding='UTF-8')
|
||||||
f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
|
f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
|
||||||
"<!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\" ",
|
"<!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\" ",
|
||||||
"\"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\">\n",
|
"\"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\">\n",
|
||||||
@@ -227,7 +226,7 @@ def buildOPF(dstdir, title, filelist, cover=None):
|
|||||||
writingmode = "horizontal-rl"
|
writingmode = "horizontal-rl"
|
||||||
else:
|
else:
|
||||||
writingmode = "horizontal-lr"
|
writingmode = "horizontal-lr"
|
||||||
f = open(opffile, "w")
|
f = open(opffile, "w", encoding='UTF-8')
|
||||||
f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
|
f.writelines(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
|
||||||
"<package version=\"2.0\" unique-identifier=\"BookID\" ",
|
"<package version=\"2.0\" unique-identifier=\"BookID\" ",
|
||||||
"xmlns=\"http://www.idpf.org/2007/opf\">\n",
|
"xmlns=\"http://www.idpf.org/2007/opf\">\n",
|
||||||
@@ -284,7 +283,7 @@ def buildOPF(dstdir, title, filelist, cover=None):
|
|||||||
f.write("</spine>\n<guide>\n</guide>\n</package>\n")
|
f.write("</spine>\n<guide>\n</guide>\n</package>\n")
|
||||||
f.close()
|
f.close()
|
||||||
os.mkdir(os.path.join(dstdir, 'META-INF'))
|
os.mkdir(os.path.join(dstdir, 'META-INF'))
|
||||||
f = open(os.path.join(dstdir, 'META-INF', 'container.xml'), 'w')
|
f = open(os.path.join(dstdir, 'META-INF', 'container.xml'), 'w', encoding='UTF-8')
|
||||||
f.writelines(["<?xml version=\"1.0\"?>\n",
|
f.writelines(["<?xml version=\"1.0\"?>\n",
|
||||||
"<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\n",
|
"<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\n",
|
||||||
"<rootfiles>\n",
|
"<rootfiles>\n",
|
||||||
@@ -426,7 +425,7 @@ def genEpubStruct(path):
|
|||||||
cover = None
|
cover = None
|
||||||
_, deviceres, _, _, panelviewsize = options.profileData
|
_, deviceres, _, _, panelviewsize = options.profileData
|
||||||
os.mkdir(os.path.join(path, 'OEBPS', 'Text'))
|
os.mkdir(os.path.join(path, 'OEBPS', 'Text'))
|
||||||
f = open(os.path.join(path, 'OEBPS', 'Text', 'style.css'), 'w')
|
f = open(os.path.join(path, 'OEBPS', 'Text', 'style.css'), 'w', encoding='UTF-8')
|
||||||
# DON'T COMPRESS CSS. KINDLE WILL FAIL TO PARSE IT.
|
# DON'T COMPRESS CSS. KINDLE WILL FAIL TO PARSE IT.
|
||||||
# Generic Panel View support + Margins fix for Non-Kindle devices.
|
# Generic Panel View support + Margins fix for Non-Kindle devices.
|
||||||
f.writelines(["@page {\n",
|
f.writelines(["@page {\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user