Compare commits

..

2 Commits
v1.1 ... v1.4

Author SHA1 Message Date
Apprentice Alf
6fb13373cf tools v1.4 2015-03-02 07:41:20 +00:00
Apprentice Alf
dce51ae232 tools v1.3 2015-03-02 07:35:40 +00:00
25 changed files with 542 additions and 96 deletions

View File

@@ -0,0 +1,123 @@
#! /usr/bin/env python
# ineptkeymac.py, version 1
# This program runs on Mac OS X, version 10.6.2 and probably several other
# versions. It uses Python 2.6, but it probably also runs on all versions
# 2.x with x >= 5.
# This program extracts the private RSA key for your ADE account in a
# standard binary form (DER format) in a file of your choosing. Its purpose
# is to make a backup of that key so that your legally bought ADE encoded
# ebooks can be salvaged in case they would no longer be supported by ADE
# software. No other usages are intended.
# It has been tested with the key storage structure of ADE 1.7.1 and 1.7.2
# and Sony Reader Library.
# This software does not contain any encryption code. Its only use of
# external encryption software is the use of openssl for the conversion of
# the private key from pem to der format. It doesn't use encryption or
# decryption, however.
# You can run this program from the command line (python ineptkeymac.py
# filename), or by doubleclicking when it has been associated with
# Pythonlauncher. When no filename is given it will show a dialog to obtain one.
from __future__ import with_statement
__license__ = 'GPL v3'
import sys
import os
import xml.etree.ElementTree as etree
from contextlib import closing
import Tkinter
import Tkconstants
import tkFileDialog
from tkMessageBox import showerror
from subprocess import Popen, PIPE
import textwrap
NS = 'http://ns.adobe.com/adept'
ACTFILE = '~/Library/Application Support/Adobe/Digital Editions/activation.dat'
HEADER = '-----BEGIN PRIVATE KEY-----\n'
FOOTER = '\n-----END PRIVATE KEY-----\n'
Gui = False
def get_key():
'''Returns the private key as a binary string (DER format)'''
try:
filename = os.path.expanduser(ACTFILE)
tree = etree.parse(filename)
xpath = '//{%s}credentials/{%s}privateLicenseKey' % (NS, NS)
b64key = tree.findtext(xpath)
pemkey = HEADER + textwrap.fill(b64key, 64) + FOOTER
cmd = ['openssl', 'rsa', '-outform', 'der']
proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = proc.communicate(pemkey)
if proc.returncode != 0:
error("openssl error: " + stderr)
return None
return stdout
except IOError:
error("Can find keyfile. Maybe you should activate your Adobe ID.")
sys.exit(1)
def store_key(key, keypath):
'''Store the key in the file given as keypath. If no keypath is given a
dialog will ask for one.'''
try:
if keypath is None:
keypath = get_keypath()
if not keypath: # Cancelled
return
with closing(open(keypath, 'wb')) as outf:
outf.write(key)
except IOError, e:
error("Can write keyfile: " + str(e))
def get_keypath():
keypath = tkFileDialog.asksaveasfilename(
parent = None, title = 'Select file to store ADEPT key',
initialdir = os.path.expanduser('~/Desktop'),
initialfile = 'adeptkey.der',
defaultextension = '.der', filetypes = [('DER-encoded files', '.der'),
('All Files', '.*')])
if keypath:
keypath = os.path.normpath(keypath)
return keypath
def error(text):
print text
if Gui: showerror('Error!', text)
def gui_main():
root = Tkinter.Tk()
root.iconify()
global Gui
Gui = True
store_key(get_key(), None)
return 0
def main(argv=sys.argv):
progname = os.path.basename(argv[0])
if len(argv) == 1: # assume GUI if no argument given
return gui_main()
if len(argv) != 2:
print "usage: %s KEYFILE" % (progname,)
return 1
store_key(get_key(), argv[1])
if __name__ == '__main__':
sys.exit(main())

View File

@@ -73,6 +73,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -88,7 +89,7 @@ class MainDialog(Tkinter.Frame):
cmdline = 'python lib\kindlepid.py "' + serial + '"' cmdline = 'python lib\kindlepid.py "' + serial + '"'
else : else :
cmdline = 'lib\kindlepid.py "' + serial + '"' cmdline = 'lib\kindlepid.py "' + serial + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
@@ -113,6 +114,7 @@ class MainDialog(Tkinter.Frame):
log += 'Serial = "' + serial + '"\n' log += 'Serial = "' + serial + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n\n' log += 'Please Wait ...\n\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.pidrdr(serial) self.p2 = self.pidrdr(serial)

View File

@@ -30,7 +30,9 @@ class MainDialog(Tkinter.Frame):
Tkinter.Label(body, text='Mobi eBook input file').grid(row=0, sticky=Tkconstants.E) Tkinter.Label(body, text='Mobi eBook input file').grid(row=0, sticky=Tkconstants.E)
self.mobipath = Tkinter.Entry(body, width=50) self.mobipath = Tkinter.Entry(body, width=50)
self.mobipath.grid(row=0, column=1, sticky=sticky) self.mobipath.grid(row=0, column=1, sticky=sticky)
self.mobipath.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.mobipath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_mobipath) button = Tkinter.Button(body, text="...", command=self.get_mobipath)
button.grid(row=0, column=2) button.grid(row=0, column=2)
@@ -80,6 +82,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -96,6 +99,7 @@ class MainDialog(Tkinter.Frame):
else : else :
cmdline = 'lib\kindlefix.py "' + infile + '" "' + pidnum + '"' cmdline = 'lib\kindlefix.py "' + infile + '" "' + pidnum + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
@@ -138,6 +142,7 @@ class MainDialog(Tkinter.Frame):
log += 'PID = "' + pidnum + '"\n' log += 'PID = "' + pidnum + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n\n' log += 'Please Wait ...\n\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.krdr(mobipath, pidnum) self.p2 = self.krdr(mobipath, pidnum)

View File

@@ -30,7 +30,9 @@ class MainDialog(Tkinter.Frame):
Tkinter.Label(body, text='Mobi eBook input file').grid(row=0, sticky=Tkconstants.E) Tkinter.Label(body, text='Mobi eBook input file').grid(row=0, sticky=Tkconstants.E)
self.mobipath = Tkinter.Entry(body, width=50) self.mobipath = Tkinter.Entry(body, width=50)
self.mobipath.grid(row=0, column=1, sticky=sticky) self.mobipath.grid(row=0, column=1, sticky=sticky)
self.mobipath.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.mobipath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_mobipath) button = Tkinter.Button(body, text="...", command=self.get_mobipath)
button.grid(row=0, column=2) button.grid(row=0, column=2)
@@ -87,6 +89,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -103,6 +106,7 @@ class MainDialog(Tkinter.Frame):
else : else :
cmdline = 'lib\mobidedrm.py "' + infile + '" "' + outfile + '" "' + pidnum + '"' cmdline = 'lib\mobidedrm.py "' + infile + '" "' + outfile + '" "' + pidnum + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
@@ -167,6 +171,7 @@ class MainDialog(Tkinter.Frame):
log += 'PID = "' + pidnum + '"\n' log += 'PID = "' + pidnum + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n\n' log += 'Please Wait ...\n\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.mobirdr(mobipath, outpath, pidnum) self.p2 = self.mobirdr(mobipath, outpath, pidnum)

View File

@@ -25,15 +25,16 @@
# import filter it works when importing unencrypted files. # import filter it works when importing unencrypted files.
# Also now handles encrypted files that don't need a specific PID. # Also now handles encrypted files that don't need a specific PID.
# 0.11 - use autoflushed stdout and proper return values # 0.11 - use autoflushed stdout and proper return values
# 0.12 - Fix for problems with metadata import as Calibre plugin, report errors
class Unbuffered: class Unbuffered:
def __init__(self, stream): def __init__(self, stream):
self.stream = stream self.stream = stream
def write(self, data): def write(self, data):
self.stream.write(data) self.stream.write(data)
self.stream.flush() self.stream.flush()
def __getattr__(self, attr): def __getattr__(self, attr):
return getattr(self.stream, attr) return getattr(self.stream, attr)
import sys import sys
sys.stdout=Unbuffered(sys.stdout) sys.stdout=Unbuffered(sys.stdout)
@@ -45,37 +46,37 @@ class DrmException(Exception):
#implementation of Pukall Cipher 1 #implementation of Pukall Cipher 1
def PC1(key, src, decryption=True): def PC1(key, src, decryption=True):
sum1 = 0; sum1 = 0;
sum2 = 0; sum2 = 0;
keyXorVal = 0; keyXorVal = 0;
if len(key)!=16: if len(key)!=16:
print "Bad key length!" print "Bad key length!"
return None return None
wkey = [] wkey = []
for i in xrange(8): for i in xrange(8):
wkey.append(ord(key[i*2])<<8 | ord(key[i*2+1])) wkey.append(ord(key[i*2])<<8 | ord(key[i*2+1]))
dst = "" dst = ""
for i in xrange(len(src)): for i in xrange(len(src)):
temp1 = 0; temp1 = 0;
byteXorVal = 0; byteXorVal = 0;
for j in xrange(8): for j in xrange(8):
temp1 ^= wkey[j] temp1 ^= wkey[j]
sum2 = (sum2+j)*20021 + sum1 sum2 = (sum2+j)*20021 + sum1
sum1 = (temp1*346)&0xFFFF sum1 = (temp1*346)&0xFFFF
sum2 = (sum2+sum1)&0xFFFF sum2 = (sum2+sum1)&0xFFFF
temp1 = (temp1*20021+1)&0xFFFF temp1 = (temp1*20021+1)&0xFFFF
byteXorVal ^= temp1 ^ sum2 byteXorVal ^= temp1 ^ sum2
curByte = ord(src[i]) curByte = ord(src[i])
if not decryption: if not decryption:
keyXorVal = curByte * 257; keyXorVal = curByte * 257;
curByte = ((curByte ^ (byteXorVal >> 8)) ^ byteXorVal) & 0xFF curByte = ((curByte ^ (byteXorVal >> 8)) ^ byteXorVal) & 0xFF
if decryption: if decryption:
keyXorVal = curByte * 257; keyXorVal = curByte * 257;
for j in xrange(8): for j in xrange(8):
wkey[j] ^= keyXorVal; wkey[j] ^= keyXorVal;
dst+=chr(curByte) dst+=chr(curByte)
return dst return dst
def checksumPid(s): def checksumPid(s):
letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789" letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789"
@@ -234,40 +235,46 @@ if not __name__ == "__main__":
description = 'Removes DRM from secure Mobi files' description = 'Removes DRM from secure Mobi files'
supported_platforms = ['linux', 'osx', 'windows'] # Platforms this plugin will run on supported_platforms = ['linux', 'osx', 'windows'] # Platforms this plugin will run on
author = 'The Dark Reverser' # The author of this plugin author = 'The Dark Reverser' # The author of this plugin
version = (0, 1, 0) # The version number of this plugin version = (0, 1, 2) # The version number of this plugin
file_types = set(['prc','mobi','azw']) # The file types that this plugin will be applied to file_types = set(['prc','mobi','azw']) # The file types that this plugin will be applied to
on_import = True # Run this plugin during the import on_import = True # Run this plugin during the import
def run(self, path_to_ebook): def run(self, path_to_ebook):
of = self.temporary_file('.mobi') from calibre.gui2 import is_ok_to_use_qt
from PyQt4.Qt import QMessageBox
PID = self.site_customization PID = self.site_customization
data_file = file(path_to_ebook, 'rb').read() data_file = file(path_to_ebook, 'rb').read()
ar = PID.split(',') ar = PID.split(',')
for i in ar: for i in ar:
try: try:
file(of.name, 'wb').write(DrmStripper(data_file, i).getResult()) unlocked_file = DrmStripper(data_file, i).getResult()
except DrmException: except DrmException:
# Hm, we should display an error dialog here. # ignore the error
# Dunno how though. pass
# Ignore the dirty hack behind the curtain.
# strexcept = 'echo exception: %s > /dev/tty' % e
# subprocess.call(strexcept,shell=True)
print i + ": not PID for book"
else: else:
of = self.temporary_file('.mobi')
of.write(unlocked_file)
of.close()
return of.name return of.name
if is_ok_to_use_qt():
d = QMessageBox(QMessageBox.Warning, "MobiDeDRM Plugin", "Couldn't decode: %s\n\nImporting encrypted version." % path_to_ebook)
d.show()
d.raise_()
d.exec_()
return path_to_ebook
def customization_help(self, gui=False): def customization_help(self, gui=False):
return 'Enter PID (separate multiple PIDs with comma)' return 'Enter PID (separate multiple PIDs with comma)'
if __name__ == "__main__": if __name__ == "__main__":
print "MobiDeDrm v0.11. Copyright (c) 2008 The Dark Reverser" print "MobiDeDrm v0.12. Copyright (c) 2008 The Dark Reverser"
if len(sys.argv)<4: if len(sys.argv)<4:
print "Removes protection from Mobipocket books" print "Removes protection from Mobipocket books"
print "Usage:" print "Usage:"
print " mobidedrm infile.mobi outfile.mobi (PID)" print " mobidedrm infile.mobi outfile.mobi (PID)"
sys.exit(1) sys.exit(1)
else: else:
infile = sys.argv[1] infile = sys.argv[1]
outfile = sys.argv[2] outfile = sys.argv[2]
pid = sys.argv[3] pid = sys.argv[3]

View File

@@ -31,14 +31,18 @@ class MainDialog(Tkinter.Frame):
Tkinter.Label(body, text='Topaz eBook input file').grid(row=0, sticky=Tkconstants.E) Tkinter.Label(body, text='Topaz eBook input file').grid(row=0, sticky=Tkconstants.E)
self.tpzpath = Tkinter.Entry(body, width=50) self.tpzpath = Tkinter.Entry(body, width=50)
self.tpzpath.grid(row=0, column=1, sticky=sticky) self.tpzpath.grid(row=0, column=1, sticky=sticky)
self.tpzpath.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.tpzpath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_tpzpath) button = Tkinter.Button(body, text="...", command=self.get_tpzpath)
button.grid(row=0, column=2) button.grid(row=0, column=2)
Tkinter.Label(body, text='Output Directory').grid(row=1, sticky=Tkconstants.E) Tkinter.Label(body, text='Output Directory').grid(row=1, sticky=Tkconstants.E)
self.outpath = Tkinter.Entry(body, width=50) self.outpath = Tkinter.Entry(body, width=50)
self.outpath.grid(row=1, column=1, sticky=sticky) self.outpath.grid(row=1, column=1, sticky=sticky)
self.outpath.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.outpath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_outpath) button = Tkinter.Button(body, text="...", command=self.get_outpath)
button.grid(row=1, column=2) button.grid(row=1, column=2)
@@ -88,6 +92,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -108,6 +113,7 @@ class MainDialog(Tkinter.Frame):
else : else :
cmdline = 'lib\cmbtc_dump.py -v -d ' + pidoption + outoption + '"' + infile + '"' cmdline = 'lib\cmbtc_dump.py -v -d ' + pidoption + outoption + '"' + infile + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
@@ -124,9 +130,11 @@ class MainDialog(Tkinter.Frame):
return return
def get_outpath(self): def get_outpath(self):
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
outpath = tkFileDialog.askdirectory( outpath = tkFileDialog.askdirectory(
parent=None, title='Directory to Extract Files into', parent=None, title='Directory to Extract Files into',
initialdir=os.getcwd(), initialfile=None) initialdir=cwd, initialfile=None)
if outpath: if outpath:
outpath = os.path.normpath(outpath) outpath = os.path.normpath(outpath)
self.outpath.delete(0, Tkconstants.END) self.outpath.delete(0, Tkconstants.END)
@@ -168,6 +176,7 @@ class MainDialog(Tkinter.Frame):
log += 'First 8 chars of PID = "' + pidnum + '"\n' log += 'First 8 chars of PID = "' + pidnum + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n' log += 'Please Wait ...\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.topazrdr(tpzpath, outpath, pidnum) self.p2 = self.topazrdr(tpzpath, outpath, pidnum)

View File

@@ -31,14 +31,18 @@ class MainDialog(Tkinter.Frame):
Tkinter.Label(body, text='Topaz eBook input file').grid(row=0, sticky=Tkconstants.E) Tkinter.Label(body, text='Topaz eBook input file').grid(row=0, sticky=Tkconstants.E)
self.tpzpath = Tkinter.Entry(body, width=50) self.tpzpath = Tkinter.Entry(body, width=50)
self.tpzpath.grid(row=0, column=1, sticky=sticky) self.tpzpath.grid(row=0, column=1, sticky=sticky)
self.tpzpath.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.tpzpath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_tpzpath) button = Tkinter.Button(body, text="...", command=self.get_tpzpath)
button.grid(row=0, column=2) button.grid(row=0, column=2)
Tkinter.Label(body, text='Output Directory').grid(row=1, sticky=Tkconstants.E) Tkinter.Label(body, text='Output Directory').grid(row=1, sticky=Tkconstants.E)
self.outpath = Tkinter.Entry(body, width=50) self.outpath = Tkinter.Entry(body, width=50)
self.outpath.grid(row=1, column=1, sticky=sticky) self.outpath.grid(row=1, column=1, sticky=sticky)
self.outpath.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.outpath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_outpath) button = Tkinter.Button(body, text="...", command=self.get_outpath)
button.grid(row=1, column=2) button.grid(row=1, column=2)
@@ -88,6 +92,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -106,6 +111,7 @@ class MainDialog(Tkinter.Frame):
else : else :
cmdline = 'lib\cmbtc_dump_nonK4PC.py -v -d ' + pidoption + outoption + '"' + infile + '"' cmdline = 'lib\cmbtc_dump_nonK4PC.py -v -d ' + pidoption + outoption + '"' + infile + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
@@ -122,9 +128,11 @@ class MainDialog(Tkinter.Frame):
return return
def get_outpath(self): def get_outpath(self):
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
outpath = tkFileDialog.askdirectory( outpath = tkFileDialog.askdirectory(
parent=None, title='Directory to Extract Files into', parent=None, title='Directory to Extract Files into',
initialdir=os.getcwd(), initialfile=None) initialdir=cwd, initialfile=None)
if outpath: if outpath:
outpath = os.path.normpath(outpath) outpath = os.path.normpath(outpath)
self.outpath.delete(0, Tkconstants.END) self.outpath.delete(0, Tkconstants.END)
@@ -166,6 +174,7 @@ class MainDialog(Tkinter.Frame):
log += 'First 8 chars of PID = "' + pidnum + '"\n' log += 'First 8 chars of PID = "' + pidnum + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n' log += 'Please Wait ...\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.topazrdr(tpzpath, outpath, pidnum) self.p2 = self.topazrdr(tpzpath, outpath, pidnum)

View File

@@ -31,7 +31,9 @@ class MainDialog(Tkinter.Frame):
Tkinter.Label(body, text='Directory you Extracted Topaz Files into').grid(row=0, sticky=Tkconstants.E) Tkinter.Label(body, text='Directory you Extracted Topaz Files into').grid(row=0, sticky=Tkconstants.E)
self.bookdir = Tkinter.Entry(body, width=50) self.bookdir = Tkinter.Entry(body, width=50)
self.bookdir.grid(row=0, column=1, sticky=sticky) self.bookdir.grid(row=0, column=1, sticky=sticky)
self.bookdir.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.bookdir.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_bookdir) button = Tkinter.Button(body, text="...", command=self.get_bookdir)
button.grid(row=0, column=2) button.grid(row=0, column=2)
@@ -76,6 +78,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -92,14 +95,17 @@ class MainDialog(Tkinter.Frame):
else : else :
cmdline = 'lib\genhtml.py "' + bookdir + '"' cmdline = 'lib\genhtml.py "' + bookdir + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
def get_bookdir(self): def get_bookdir(self):
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
bookdir = tkFileDialog.askdirectory( bookdir = tkFileDialog.askdirectory(
parent=None, title='Select the Directory you Extracted Topaz Files into', parent=None, title='Select the Directory you Extracted Topaz Files into',
initialdir=os.getcwd(), initialfile=None) initialdir=cwd, initialfile=None)
if bookdir: if bookdir:
bookdir = os.path.normpath(bookdir) bookdir = os.path.normpath(bookdir)
self.bookdir.delete(0, Tkconstants.END) self.bookdir.delete(0, Tkconstants.END)
@@ -127,6 +133,7 @@ class MainDialog(Tkinter.Frame):
log += 'Book Directory = "' + bookdir + '"\n' log += 'Book Directory = "' + bookdir + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n' log += 'Please Wait ...\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.topazrdr(bookdir) self.p2 = self.topazrdr(bookdir)

View File

@@ -31,7 +31,9 @@ class MainDialog(Tkinter.Frame):
Tkinter.Label(body, text='Directory you Extracted Topaz Files into').grid(row=0, sticky=Tkconstants.E) Tkinter.Label(body, text='Directory you Extracted Topaz Files into').grid(row=0, sticky=Tkconstants.E)
self.bookdir = Tkinter.Entry(body, width=50) self.bookdir = Tkinter.Entry(body, width=50)
self.bookdir.grid(row=0, column=1, sticky=sticky) self.bookdir.grid(row=0, column=1, sticky=sticky)
self.bookdir.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.bookdir.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_bookdir) button = Tkinter.Button(body, text="...", command=self.get_bookdir)
button.grid(row=0, column=2) button.grid(row=0, column=2)
@@ -76,6 +78,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -92,14 +95,17 @@ class MainDialog(Tkinter.Frame):
else : else :
cmdline = 'lib\gensvg.py "' + bookdir + '"' cmdline = 'lib\gensvg.py "' + bookdir + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
def get_bookdir(self): def get_bookdir(self):
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
bookdir = tkFileDialog.askdirectory( bookdir = tkFileDialog.askdirectory(
parent=None, title='Select the Directory you Extracted Topaz Files into', parent=None, title='Select the Directory you Extracted Topaz Files into',
initialdir=os.getcwd(), initialfile=None) initialdir=cwd, initialfile=None)
if bookdir: if bookdir:
bookdir = os.path.normpath(bookdir) bookdir = os.path.normpath(bookdir)
self.bookdir.delete(0, Tkconstants.END) self.bookdir.delete(0, Tkconstants.END)
@@ -127,6 +133,7 @@ class MainDialog(Tkinter.Frame):
log += 'Book Directory = "' + bookdir + '"\n' log += 'Book Directory = "' + bookdir + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n' log += 'Please Wait ...\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.topazrdr(bookdir) self.p2 = self.topazrdr(bookdir)

View File

@@ -31,7 +31,9 @@ class MainDialog(Tkinter.Frame):
Tkinter.Label(body, text='Directory you Extracted Topaz Files into').grid(row=0, sticky=Tkconstants.E) Tkinter.Label(body, text='Directory you Extracted Topaz Files into').grid(row=0, sticky=Tkconstants.E)
self.bookdir = Tkinter.Entry(body, width=50) self.bookdir = Tkinter.Entry(body, width=50)
self.bookdir.grid(row=0, column=1, sticky=sticky) self.bookdir.grid(row=0, column=1, sticky=sticky)
self.bookdir.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.bookdir.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_bookdir) button = Tkinter.Button(body, text="...", command=self.get_bookdir)
button.grid(row=0, column=2) button.grid(row=0, column=2)
@@ -76,6 +78,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -92,14 +95,17 @@ class MainDialog(Tkinter.Frame):
else : else :
cmdline = 'lib\genxml.py "' + bookdir + '"' cmdline = 'lib\genxml.py "' + bookdir + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
def get_bookdir(self): def get_bookdir(self):
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
bookdir = tkFileDialog.askdirectory( bookdir = tkFileDialog.askdirectory(
parent=None, title='Select the Directory you Extracted Topaz Files into', parent=None, title='Select the Directory you Extracted Topaz Files into',
initialdir=os.getcwd(), initialfile=None) initialdir=cwd, initialfile=None)
if bookdir: if bookdir:
bookdir = os.path.normpath(bookdir) bookdir = os.path.normpath(bookdir)
self.bookdir.delete(0, Tkconstants.END) self.bookdir.delete(0, Tkconstants.END)
@@ -127,6 +133,7 @@ class MainDialog(Tkinter.Frame):
log += 'Book Directory = "' + bookdir + '"\n' log += 'Book Directory = "' + bookdir + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n' log += 'Please Wait ...\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.topazrdr(bookdir) self.p2 = self.topazrdr(bookdir)

View File

@@ -1,5 +1,5 @@
#! /usr/bin/python #! /usr/bin/python
# For use in Topaz Scripts version 2.2 # For use in Topaz Scripts version 2.3
""" """

View File

@@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
# For use with Topaz Scripts Version 2.2 # For use with Topaz Scripts Version 2.3
class Unbuffered: class Unbuffered:
def __init__(self, stream): def __init__(self, stream):

View File

@@ -1,6 +1,6 @@
#! /usr/bin/python #! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.2 # For use with Topaz Scripts Version 2.4
class Unbuffered: class Unbuffered:
def __init__(self, stream): def __init__(self, stream):
@@ -243,6 +243,8 @@ class PageParser(object):
'region.h' : (1, 'scalar_number', 0, 0), 'region.h' : (1, 'scalar_number', 0, 0),
'region.w' : (1, 'scalar_number', 0, 0), 'region.w' : (1, 'scalar_number', 0, 0),
'empty_text_region' : (1, 'snippets', 1, 0),
'img' : (1, 'snippets', 1, 0), 'img' : (1, 'snippets', 1, 0),
'img.x' : (1, 'scalar_number', 0, 0), 'img.x' : (1, 'scalar_number', 0, 0),
'img.y' : (1, 'scalar_number', 0, 0), 'img.y' : (1, 'scalar_number', 0, 0),

View File

@@ -1,6 +1,6 @@
#! /usr/bin/python #! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.2 # For use with Topaz Scripts Version 2.3
import csv import csv
import sys import sys

View File

@@ -1,6 +1,6 @@
#! /usr/bin/python #! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.2 # For use with Topaz Scripts Version 2.3
import sys import sys
import csv import csv

View File

@@ -1,6 +1,6 @@
#! /usr/bin/python #! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.2 # For use with Topaz Scripts Version 2.3
class Unbuffered: class Unbuffered:
def __init__(self, stream): def __init__(self, stream):

View File

@@ -1,6 +1,6 @@
#! /usr/bin/python #! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.2 # For use with Topaz Scripts Version 2.3
class Unbuffered: class Unbuffered:
def __init__(self, stream): def __init__(self, stream):
@@ -28,15 +28,24 @@ class GParser(object):
self.gh = self.getData('info.glyph.h') self.gh = self.getData('info.glyph.h')
self.gw = self.getData('info.glyph.w') self.gw = self.getData('info.glyph.w')
self.guse = self.getData('info.glyph.use') self.guse = self.getData('info.glyph.use')
self.count = len(self.guse) if self.guse :
self.count = len(self.guse)
else :
self.count = 0
self.gvtx = self.getData('info.glyph.vtx') self.gvtx = self.getData('info.glyph.vtx')
self.glen = self.getData('info.glyph.len') self.glen = self.getData('info.glyph.len')
self.gdpi = self.getData('info.glyph.dpi') self.gdpi = self.getData('info.glyph.dpi')
self.vx = self.getData('info.vtx.x') self.vx = self.getData('info.vtx.x')
self.vy = self.getData('info.vtx.y') self.vy = self.getData('info.vtx.y')
self.vlen = self.getData('info.len.n') self.vlen = self.getData('info.len.n')
self.glen.append(len(self.vlen)) if self.vlen :
self.gvtx.append(len(self.vx)) self.glen.append(len(self.vlen))
elif self.glen:
self.glen.append(0)
if self.vx :
self.gvtx.append(len(self.vx))
elif self.gvtx :
self.gvtx.append(0)
def getData(self, path): def getData(self, path):
result = None result = None

View File

@@ -1,6 +1,6 @@
#! /usr/bin/python #! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.2 # For use with Topaz Scripts Version 2.3
class Unbuffered: class Unbuffered:
def __init__(self, stream): def __init__(self, stream):

View File

@@ -1,6 +1,6 @@
#! /usr/bin/python #! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.2 # For use with Topaz Scripts Version 2.3
import csv import csv
import sys import sys

View File

@@ -1,6 +1,6 @@
#! /usr/bin/python #! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.2 # For use with Topaz Scripts Version 2.3
import csv import csv
import sys import sys

View File

@@ -1,3 +1,7 @@
Canges in 2.3
- fix for use with non-latin1 based systems (thank you Tedd)
- fixes for out of order tokens in xml
Changes in 2.2 Changes in 2.2
- fix for minor bug in encode_Number from clark nova - fix for minor bug in encode_Number from clark nova
- more fixes to handle paths with spaces in them - more fixes to handle paths with spaces in them

View File

@@ -30,7 +30,9 @@ class MainDialog(Tkinter.Frame):
Tkinter.Label(body, text='eBook Pml input file').grid(row=0, sticky=Tkconstants.E) Tkinter.Label(body, text='eBook Pml input file').grid(row=0, sticky=Tkconstants.E)
self.pmlpath = Tkinter.Entry(body, width=50) self.pmlpath = Tkinter.Entry(body, width=50)
self.pmlpath.grid(row=0, column=1, sticky=sticky) self.pmlpath.grid(row=0, column=1, sticky=sticky)
self.pmlpath.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.pmlpath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_pmlpath) button = Tkinter.Button(body, text="...", command=self.get_pmlpath)
button.grid(row=0, column=2) button.grid(row=0, column=2)
@@ -82,6 +84,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -98,6 +101,7 @@ class MainDialog(Tkinter.Frame):
else : else :
cmdline = 'lib\\xpml2xhtml.py "' + infile + '" "' + outfile + '"' cmdline = 'lib\\xpml2xhtml.py "' + infile + '" "' + outfile + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
@@ -156,6 +160,7 @@ class MainDialog(Tkinter.Frame):
log += 'HTML Output File = "' + outpath + '"\n' log += 'HTML Output File = "' + outpath + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n\n' log += 'Please Wait ...\n\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.pmlhtml(pmlpath, outpath) self.p2 = self.pmlhtml(pmlpath, outpath)

View File

@@ -31,14 +31,18 @@ class MainDialog(Tkinter.Frame):
Tkinter.Label(body, text='eBook PDB input file').grid(row=0, sticky=Tkconstants.E) Tkinter.Label(body, text='eBook PDB input file').grid(row=0, sticky=Tkconstants.E)
self.pdbpath = Tkinter.Entry(body, width=50) self.pdbpath = Tkinter.Entry(body, width=50)
self.pdbpath.grid(row=0, column=1, sticky=sticky) self.pdbpath.grid(row=0, column=1, sticky=sticky)
self.pdbpath.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.pdbpath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_pdbpath) button = Tkinter.Button(body, text="...", command=self.get_pdbpath)
button.grid(row=0, column=2) button.grid(row=0, column=2)
Tkinter.Label(body, text='Output Directory').grid(row=1, sticky=Tkconstants.E) Tkinter.Label(body, text='Output Directory').grid(row=1, sticky=Tkconstants.E)
self.outpath = Tkinter.Entry(body, width=50) self.outpath = Tkinter.Entry(body, width=50)
self.outpath.grid(row=1, column=1, sticky=sticky) self.outpath.grid(row=1, column=1, sticky=sticky)
self.outpath.insert(0, os.getcwd()) cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.outpath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_outpath) button = Tkinter.Button(body, text="...", command=self.get_outpath)
button.grid(row=1, column=2) button.grid(row=1, column=2)
@@ -93,6 +97,7 @@ class MainDialog(Tkinter.Frame):
# post output from subprocess in scrolled text widget # post output from subprocess in scrolled text widget
def showCmdOutput(self, msg): def showCmdOutput(self, msg):
if msg and msg !='': if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg) self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END) self.stext.yview_pickplace(Tkconstants.END)
return return
@@ -109,6 +114,7 @@ class MainDialog(Tkinter.Frame):
else : else :
cmdline = 'lib\erdr2pml.py "' + infile + '" "' + outdir + '" "' + name + '" ' + ccnum cmdline = 'lib\erdr2pml.py "' + infile + '" "' + outdir + '" "' + name + '" ' + ccnum
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False) p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2 return p2
@@ -125,9 +131,11 @@ class MainDialog(Tkinter.Frame):
return return
def get_outpath(self): def get_outpath(self):
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
outpath = tkFileDialog.askdirectory( outpath = tkFileDialog.askdirectory(
parent=None, title='Directory to Store Output into', parent=None, title='Directory to Store Output into',
initialdir=os.getcwd(), initialfile=None) initialdir=cwd, initialfile=None)
if outpath: if outpath:
outpath = os.path.normpath(outpath) outpath = os.path.normpath(outpath)
self.outpath.delete(0, Tkconstants.END) self.outpath.delete(0, Tkconstants.END)
@@ -175,6 +183,7 @@ class MainDialog(Tkinter.Frame):
log += 'Last 8 of CC = "' + ccnum + '"\n' log += 'Last 8 of CC = "' + ccnum + '"\n'
log += '\n\n' log += '\n\n'
log += 'Please Wait ...\n' log += 'Please Wait ...\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log) self.stext.insert(Tkconstants.END,log)
self.p2 = self.erdr(pdbpath, outpath, name, ccnum) self.p2 = self.erdr(pdbpath, outpath, name, ccnum)

View File

@@ -0,0 +1,180 @@
#!/usr/bin/env python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
import sys
sys.path.append('lib')
import os, os.path, urllib
import subprocess
from subprocess import Popen, PIPE, STDOUT
import Tkinter
import Tkconstants
import tkFileDialog
import tkMessageBox
import subasyncio
from subasyncio import Process
from scrolltextwidget import ScrolledText
class MainDialog(Tkinter.Frame):
def __init__(self, root):
Tkinter.Frame.__init__(self, root, border=5)
self.root = root
self.interval = 2000
self.p2 = None
self.status = Tkinter.Label(self, text='eReader eBook Conversion to PMLZ')
self.status.pack(fill=Tkconstants.X, expand=1)
body = Tkinter.Frame(self)
body.pack(fill=Tkconstants.X, expand=1)
sticky = Tkconstants.E + Tkconstants.W
body.grid_columnconfigure(1, weight=2)
Tkinter.Label(body, text='eBook PDB input file').grid(row=0, sticky=Tkconstants.E)
self.pdbpath = Tkinter.Entry(body, width=50)
self.pdbpath.grid(row=0, column=1, sticky=sticky)
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.pdbpath.insert(0, cwd)
button = Tkinter.Button(body, text="...", command=self.get_pdbpath)
button.grid(row=0, column=2)
Tkinter.Label(body, text='Name on CC').grid(row=1, sticky=Tkconstants.E)
self.name = Tkinter.StringVar()
self.nameinfo = Tkinter.Entry(body, width=40, textvariable=self.name)
self.nameinfo.grid(row=1, column=1, sticky=sticky)
Tkinter.Label(body, text='Last 8 digits of CC Number').grid(row=2, sticky=Tkconstants.E)
self.ccnum = Tkinter.StringVar()
self.ccinfo = Tkinter.Entry(body, width=10, textvariable=self.ccnum)
self.ccinfo.grid(row=2, column=1, sticky=sticky)
msg1 = 'Conversion Log \n\n'
self.stext = ScrolledText(body, bd=5, relief=Tkconstants.RIDGE, height=15, width=60, wrap=Tkconstants.WORD)
self.stext.grid(row=3, column=0, columnspan=2,sticky=sticky)
self.stext.insert(Tkconstants.END,msg1)
buttons = Tkinter.Frame(self)
buttons.pack()
self.sbotton = Tkinter.Button(
buttons, text="Start", width=10, command=self.convertit)
self.sbotton.pack(side=Tkconstants.LEFT)
Tkinter.Frame(buttons, width=10).pack(side=Tkconstants.LEFT)
self.qbutton = Tkinter.Button(
buttons, text="Quit", width=10, command=self.quitting)
self.qbutton.pack(side=Tkconstants.RIGHT)
# read from subprocess pipe without blocking
# invoked every interval via the widget "after"
# option being used, so need to reset it for the next time
def processPipe(self):
poll = self.p2.wait('nowait')
if poll != None:
text = self.p2.readerr()
text += self.p2.read()
msg = text + '\n\n' + 'File successfully converted\n'
if poll != 0:
msg = text + '\n\n' + 'Error: Conversion Failed\n'
self.showCmdOutput(msg)
self.p2 = None
self.sbotton.configure(state='normal')
return
text = self.p2.readerr()
text += self.p2.read()
self.showCmdOutput(text)
# make sure we get invoked again by event loop after interval
self.stext.after(self.interval,self.processPipe)
return
# post output from subprocess in scrolled text widget
def showCmdOutput(self, msg):
if msg and msg !='':
msg = msg.encode('utf-8')
self.stext.insert(Tkconstants.END,msg)
self.stext.yview_pickplace(Tkconstants.END)
return
# run erdr2pml.py as a subprocess via pipes and collect stdout
def erdr(self, infile, name, ccnum):
# os.putenv('PYTHONUNBUFFERED', '1')
cmdline = 'python ./lib/erdr2pml.py --make-pmlz "' + infile + '" "' + name + '" ' + ccnum
if sys.platform[0:3] == 'win':
search_path = os.environ['PATH']
search_path = search_path.lower()
if search_path.find('python') >= 0:
cmdline = 'python lib\erdr2pml.py --make-pmlz "' + infile + '" "' + name + '" ' + ccnum
else :
cmdline = 'lib\erdr2pml.py --make-pmlz "' + infile + '" "' + name + '" ' + ccnum
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2
def get_pdbpath(self):
pdbpath = tkFileDialog.askopenfilename(
parent=None, title='Select eReader PDB File',
defaultextension='.pdb', filetypes=[('eReader eBooks', '.pdb'),
('All Files', '.*')])
if pdbpath:
pdbpath = os.path.normpath(pdbpath)
self.pdbpath.delete(0, Tkconstants.END)
self.pdbpath.insert(0, pdbpath)
return
def quitting(self):
# kill any still running subprocess
if self.p2 != None:
if (self.p2.wait('nowait') == None):
self.p2.terminate()
self.root.destroy()
# actually ready to run the subprocess and get its output
def convertit(self):
# now disable the button to prevent multiple launches
self.sbotton.configure(state='disabled')
pdbpath = self.pdbpath.get()
if not pdbpath or not os.path.exists(pdbpath):
self.status['text'] = 'Specified eBook file does not exist'
self.sbotton.configure(state='normal')
return
name = self.name.get()
if not name or name == '':
self.status['text'] = 'Your forgot to enter the Name on the CC'
self.sbotton.configure(state='normal')
return
ccnum = self.ccnum.get()
if not ccnum or ccnum == '':
self.status['text'] = 'Your forgot to enter the last 8 digits on the CC'
self.sbotton.configure(state='normal')
return
log = 'Command = "python erdr2pml.py --make-pmlz "\n'
log += 'PDB Path = "'+ pdbpath + '"\n'
log += 'Name = "' + name + '"\n'
log += 'Last 8 of CC = "' + ccnum + '"\n'
log += '\n\n'
log += 'Please Wait ...\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log)
self.p2 = self.erdr(pdbpath, name, ccnum)
# python does not seem to allow you to create
# your own eventloop which every other gui does - strange
# so need to use the widget "after" command to force
# event loop to run non-gui events every interval
self.stext.after(self.interval,self.processPipe)
return
def main(argv=None):
root = Tkinter.Tk()
root.title('eReader PDB to PMLZ Conversion')
root.resizable(True, False)
root.minsize(300, 0)
MainDialog(root).pack(fill=Tkconstants.X, expand=1)
root.mainloop()
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@@ -52,8 +52,9 @@
# 0.11 - fixups for using correct xml for footnotes and sidebars for use with Dropbook # 0.11 - fixups for using correct xml for footnotes and sidebars for use with Dropbook
# 0.12 - Fix added to prevent lowercasing of image names when the pml code itself uses a different case in the link name. # 0.12 - Fix added to prevent lowercasing of image names when the pml code itself uses a different case in the link name.
# 0.13 - change to unbuffered stdout for use with gui front ends # 0.13 - change to unbuffered stdout for use with gui front ends
# 0.14 - contributed enhancement to support --make-pmlz switch
__version__='0.13' __version__='0.14'
# Import Psyco if available # Import Psyco if available
try: try:
@@ -85,7 +86,7 @@ class Unbuffered:
import sys import sys
sys.stdout=Unbuffered(sys.stdout) sys.stdout=Unbuffered(sys.stdout)
import struct, binascii, zlib, os, os.path, urllib import struct, binascii, getopt, zlib, os, os.path, urllib, tempfile
try: try:
from hashlib import sha1 from hashlib import sha1
@@ -592,27 +593,54 @@ def convertEreaderToPml(infile, name, cc, outdir):
# file(os.path.join(outdir, 'bookinfo.txt'),'wb').write(bkinfo) # file(os.path.join(outdir, 'bookinfo.txt'),'wb').write(bkinfo)
def usage():
print "Converts DRMed eReader books to PML Source"
print "Usage:"
print " erdr2pml [options] infile.pdb [outdir] \"your name\" credit_card_number "
print " "
print "Options: "
print " -h prints this message"
print " --make-pmlz create PMLZ instead of using output directory"
print " "
print "Note:"
print " if ommitted, outdir defaults based on 'infile.pdb'"
print " It's enough to enter the last 8 digits of the credit card number"
return
def main(argv=None): def main(argv=None):
global bookname global bookname
if argv is None: try:
argv = sys.argv opts, args = getopt.getopt(sys.argv[1:], "h", ["make-pmlz"])
except getopt.GetoptError, err:
print str(err)
usage()
return 1
make_pmlz = False
zipname = None
for o, a in opts:
if o == "-h":
usage()
return 0
elif o == "--make-pmlz":
make_pmlz = True
zipname = ''
print "eRdr2Pml v%s. Copyright (c) 2009 The Dark Reverser" % __version__ print "eRdr2Pml v%s. Copyright (c) 2009 The Dark Reverser" % __version__
if len(argv)!=4 and len(argv)!=5: if len(args)!=3 and len(args)!=4:
print "Converts DRMed eReader books to PML Source" usage()
print "Usage:"
print " erdr2pml infile.pdb [outdir] \"your name\" credit_card_number "
print "Note:"
print " if ommitted, outdir defaults based on 'infile.pdb'"
print " It's enough to enter the last 8 digits of the credit card number"
return 1 return 1
else: else:
if len(argv)==4: if len(args)==3:
infile, name, cc = argv[1], argv[2], argv[3] infile, name, cc = args[0], args[1], args[2]
outdir = infile[:-4] + '_Source' outdir = infile[:-4] + '_Source'
elif len(argv)==5: elif len(args)==4:
infile, outdir, name, cc = argv[1], argv[2], argv[3], argv[4] infile, outdir, name, cc = args[0], args[1], args[2], args[3]
if make_pmlz :
# ignore specified outdir, use tempdir instead
outdir = tempfile.mkdtemp()
bookname = os.path.splitext(os.path.basename(infile))[0] bookname = os.path.splitext(os.path.basename(infile))[0]
try: try:
@@ -620,10 +648,38 @@ def main(argv=None):
import time import time
start_time = time.time() start_time = time.time()
convertEreaderToPml(infile, name, cc, outdir) convertEreaderToPml(infile, name, cc, outdir)
if make_pmlz :
import zipfile
import shutil
print " Creating PMLZ file"
zipname = infile[:-4] + '.pmlz'
myZipFile = zipfile.ZipFile(zipname,'w',zipfile.ZIP_STORED, False)
list = os.listdir(outdir)
for file in list:
localname = file
filePath = os.path.join(outdir,file)
if os.path.isfile(filePath):
myZipFile.write(filePath, localname)
elif os.path.isdir(filePath):
imageList = os.listdir(filePath)
localimgdir = os.path.basename(filePath)
for image in imageList:
localname = os.path.join(localimgdir,image)
imagePath = os.path.join(filePath,image)
if os.path.isfile(imagePath):
myZipFile.write(imagePath, localname)
myZipFile.close()
# remove temporary directory
shutil.rmtree(outdir)
end_time = time.time() end_time = time.time()
search_time = end_time - start_time search_time = end_time - start_time
print 'elapsed time: %.2f seconds' % (search_time, ) print 'elapsed time: %.2f seconds' % (search_time, )
print 'output in %s' % outdir if make_pmlz :
print 'output in %s' % zipname
else :
print 'output in %s' % outdir
print "done" print "done"
except ValueError, e: except ValueError, e:
print "Error: %s" % e print "Error: %s" % e