1
0
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:
Paweł Jastrzębski
2014-01-16 11:40:49 +01:00
parent d76a624a82
commit 921511dcf2
4 changed files with 24 additions and 23 deletions

11
kcc.py
View File

@@ -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_())

View File

@@ -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()

View File

@@ -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

View File

@@ -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",