tools v1.0
(With some additions) Lots of authors, brought together by Apprentice Alf.
This commit is contained in:
parent
71d66953d3
commit
93c2ccd2c2
|
@ -21,7 +21,10 @@
|
||||||
# 0.07 - The extra data flags aren't present in MOBI header < 0xE8 in size
|
# 0.07 - The extra data flags aren't present in MOBI header < 0xE8 in size
|
||||||
# 0.08 - ...and also not in Mobi header version < 6
|
# 0.08 - ...and also not in Mobi header version < 6
|
||||||
# 0.09 - ...but they are there with Mobi header version 6, header size 0xE4!
|
# 0.09 - ...but they are there with Mobi header version 6, header size 0xE4!
|
||||||
# 0.10 - use autoflushed stdout and proper return values
|
# 0.10 - Outputs unencrypted files as-is, so that when run as a Calibre
|
||||||
|
# import filter it works when importing unencrypted files.
|
||||||
|
# Also now handles encrypted files that don't need a specific PID.
|
||||||
|
# 0.11 - use autoflushed stdout and proper return values
|
||||||
|
|
||||||
class Unbuffered:
|
class Unbuffered:
|
||||||
def __init__(self, stream):
|
def __init__(self, stream):
|
||||||
|
@ -143,6 +146,17 @@ class DrmStripper:
|
||||||
if verification == ver and cksum == temp_key_sum and (flags & 0x1F) == 1:
|
if verification == ver and cksum == temp_key_sum and (flags & 0x1F) == 1:
|
||||||
found_key = finalkey
|
found_key = finalkey
|
||||||
break
|
break
|
||||||
|
if not found_key:
|
||||||
|
# Then try the default encoding that doesn't require a PID
|
||||||
|
temp_key = keyvec1
|
||||||
|
temp_key_sum = sum(map(ord,temp_key)) & 0xff
|
||||||
|
for i in xrange(count):
|
||||||
|
verification, size, type, cksum, cookie = struct.unpack('>LLLBxxx32s', data[i*0x30:i*0x30+0x30])
|
||||||
|
cookie = PC1(temp_key, cookie)
|
||||||
|
ver,flags,finalkey,expiry,expiry2 = struct.unpack('>LL16sLL', cookie)
|
||||||
|
if verification == ver and cksum == temp_key_sum:
|
||||||
|
found_key = finalkey
|
||||||
|
break
|
||||||
return found_key
|
return found_key
|
||||||
|
|
||||||
|
|
||||||
|
@ -178,34 +192,35 @@ class DrmStripper:
|
||||||
|
|
||||||
crypto_type, = struct.unpack('>H', sect[0xC:0xC+2])
|
crypto_type, = struct.unpack('>H', sect[0xC:0xC+2])
|
||||||
if crypto_type == 0:
|
if crypto_type == 0:
|
||||||
raise DrmException("it seems that this book isn't encrypted")
|
print "This book is not encrypted."
|
||||||
if crypto_type == 1:
|
else:
|
||||||
raise DrmException("cannot decode Mobipocket encryption type 1")
|
if crypto_type == 1:
|
||||||
if crypto_type != 2:
|
raise DrmException("cannot decode Mobipocket encryption type 1")
|
||||||
raise DrmException("unknown encryption type: %d" % crypto_type)
|
if crypto_type != 2:
|
||||||
|
raise DrmException("unknown encryption type: %d" % crypto_type)
|
||||||
# calculate the keys
|
|
||||||
drm_ptr, drm_count, drm_size, drm_flags = struct.unpack('>LLLL', sect[0xA8:0xA8+16])
|
# calculate the keys
|
||||||
if drm_count == 0:
|
drm_ptr, drm_count, drm_size, drm_flags = struct.unpack('>LLLL', sect[0xA8:0xA8+16])
|
||||||
raise DrmException("no PIDs found in this file")
|
if drm_count == 0:
|
||||||
found_key = self.parseDRM(sect[drm_ptr:drm_ptr+drm_size], drm_count, pid)
|
raise DrmException("no PIDs found in this file")
|
||||||
if not found_key:
|
found_key = self.parseDRM(sect[drm_ptr:drm_ptr+drm_size], drm_count, pid)
|
||||||
raise DrmException("no key found. maybe the PID is incorrect")
|
if not found_key:
|
||||||
|
raise DrmException("no key found. maybe the PID is incorrect")
|
||||||
# kill the drm keys
|
|
||||||
self.patchSection(0, "\0" * drm_size, drm_ptr)
|
# kill the drm keys
|
||||||
# kill the drm pointers
|
self.patchSection(0, "\0" * drm_size, drm_ptr)
|
||||||
self.patchSection(0, "\xff" * 4 + "\0" * 12, 0xA8)
|
# kill the drm pointers
|
||||||
# clear the crypto type
|
self.patchSection(0, "\xff" * 4 + "\0" * 12, 0xA8)
|
||||||
self.patchSection(0, "\0" * 2, 0xC)
|
# clear the crypto type
|
||||||
|
self.patchSection(0, "\0" * 2, 0xC)
|
||||||
# decrypt sections
|
|
||||||
print "Decrypting. Please wait...",
|
# decrypt sections
|
||||||
for i in xrange(1, records+1):
|
print "Decrypting. Please wait...",
|
||||||
data = self.loadSection(i)
|
for i in xrange(1, records+1):
|
||||||
extra_size = getSizeOfTrailingDataEntries(data, len(data), extra_data_flags)
|
data = self.loadSection(i)
|
||||||
# print "record %d, extra_size %d" %(i,extra_size)
|
extra_size = getSizeOfTrailingDataEntries(data, len(data), extra_data_flags)
|
||||||
self.patchSection(i, PC1(found_key, data[0:len(data) - extra_size]))
|
# print "record %d, extra_size %d" %(i,extra_size)
|
||||||
|
self.patchSection(i, PC1(found_key, data[0:len(data) - extra_size]))
|
||||||
print "done"
|
print "done"
|
||||||
def getResult(self):
|
def getResult(self):
|
||||||
return self.data_file
|
return self.data_file
|
||||||
|
@ -219,7 +234,7 @@ 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, 0, 10) # The version number of this plugin
|
version = (0, 1, 0) # 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
|
||||||
|
|
||||||
|
@ -245,25 +260,22 @@ if not __name__ == "__main__":
|
||||||
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)'
|
||||||
|
|
||||||
def main(argv=sys.argv):
|
if __name__ == "__main__":
|
||||||
print "MobiDeDrm v0.10. Copyright (c) 2008 The Dark Reverser"
|
print "MobiDeDrm v0.11. 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)"
|
||||||
return 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]
|
||||||
data_file = file(infile, 'rb').read()
|
data_file = file(infile, 'rb').read()
|
||||||
try:
|
try:
|
||||||
file(outfile, 'wb').write(DrmStripper(data_file, pid).getResult())
|
strippedFile = DrmStripper(data_file, pid)
|
||||||
|
file(outfile, 'wb').write(strippedFile.getResult())
|
||||||
except DrmException, e:
|
except DrmException, e:
|
||||||
print "Error: %s" % e
|
print "Error: %s" % e
|
||||||
return 1
|
sys.exit(1)
|
||||||
return 0
|
sys.exit(0)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
sys.exit(main())
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
#!/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='Extract Contents of Topaz eBook to a Directory')
|
||||||
|
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='Topaz eBook input file').grid(row=0, sticky=Tkconstants.E)
|
||||||
|
self.tpzpath = Tkinter.Entry(body, width=50)
|
||||||
|
self.tpzpath.grid(row=0, column=1, sticky=sticky)
|
||||||
|
self.tpzpath.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_tpzpath)
|
||||||
|
button.grid(row=0, column=2)
|
||||||
|
|
||||||
|
Tkinter.Label(body, text='Output Directory').grid(row=1, sticky=Tkconstants.E)
|
||||||
|
self.outpath = Tkinter.Entry(body, width=50)
|
||||||
|
self.outpath.grid(row=1, column=1, sticky=sticky)
|
||||||
|
self.outpath.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_outpath)
|
||||||
|
button.grid(row=1, column=2)
|
||||||
|
|
||||||
|
Tkinter.Label(body, text='First 8 char of PID (optional)').grid(row=3, sticky=Tkconstants.E)
|
||||||
|
self.pidnum = Tkinter.StringVar()
|
||||||
|
self.ccinfo = Tkinter.Entry(body, width=10, textvariable=self.pidnum)
|
||||||
|
self.ccinfo.grid(row=3, 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=4, 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' + 'Files successfully extracted\n'
|
||||||
|
if poll != 0:
|
||||||
|
msg = text + '\n\n' + 'Error: File Extraction 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 !='':
|
||||||
|
self.stext.insert(Tkconstants.END,msg)
|
||||||
|
self.stext.yview_pickplace(Tkconstants.END)
|
||||||
|
return
|
||||||
|
|
||||||
|
# run as a subprocess via pipes and collect stdout
|
||||||
|
def topazrdr(self, infile, outdir, pidnum):
|
||||||
|
# os.putenv('PYTHONUNBUFFERED', '1')
|
||||||
|
pidoption = ''
|
||||||
|
if pidnum and pidnum != '':
|
||||||
|
pidoption = ' -p "' + pidnum + '" '
|
||||||
|
outoption = ' -o "' + outdir + '" '
|
||||||
|
cmdline = 'python ./lib/cmbtc_dump.py -v -d ' + pidoption + outoption + '"' + infile + '"'
|
||||||
|
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\cmbtc_dump.py -v -d ' + pidoption + outoption + '"' + infile + '"'
|
||||||
|
else :
|
||||||
|
cmdline = 'lib\cmbtc_dump.py -v -d ' + pidoption + outoption + '"' + infile + '"'
|
||||||
|
|
||||||
|
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
|
||||||
|
return p2
|
||||||
|
|
||||||
|
|
||||||
|
def get_tpzpath(self):
|
||||||
|
tpzpath = tkFileDialog.askopenfilename(
|
||||||
|
parent=None, title='Select Topaz File',
|
||||||
|
defaultextension='.prc', filetypes=[('Topaz azw1', '.azw1'), ('Topaz prc', '.prc'),
|
||||||
|
('All Files', '.*')])
|
||||||
|
if tpzpath:
|
||||||
|
tpzpath = os.path.normpath(tpzpath)
|
||||||
|
self.tpzpath.delete(0, Tkconstants.END)
|
||||||
|
self.tpzpath.insert(0, tpzpath)
|
||||||
|
return
|
||||||
|
|
||||||
|
def get_outpath(self):
|
||||||
|
outpath = tkFileDialog.askdirectory(
|
||||||
|
parent=None, title='Directory to Extract Files into',
|
||||||
|
initialdir=os.getcwd(), initialfile=None)
|
||||||
|
if outpath:
|
||||||
|
outpath = os.path.normpath(outpath)
|
||||||
|
self.outpath.delete(0, Tkconstants.END)
|
||||||
|
self.outpath.insert(0, outpath)
|
||||||
|
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')
|
||||||
|
tpzpath = self.tpzpath.get()
|
||||||
|
outpath = self.outpath.get()
|
||||||
|
if not tpzpath or not os.path.exists(tpzpath):
|
||||||
|
self.status['text'] = 'Specified Topaz eBook file does not exist'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
if not outpath:
|
||||||
|
self.status['text'] = 'No output directory specified'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
if not os.path.exists(outpath):
|
||||||
|
os.makedirs(outpath)
|
||||||
|
pidnum = self.pidnum.get()
|
||||||
|
# if not pidnum or pidnum == '':
|
||||||
|
# self.status['text'] = 'You have not entered a PID '
|
||||||
|
# self.sbotton.configure(state='normal')
|
||||||
|
# return
|
||||||
|
|
||||||
|
log = 'Command = "python cmbtc_dump.py"\n'
|
||||||
|
log += 'Topaz Path Path = "'+ tpzpath + '"\n'
|
||||||
|
log += 'Output Directory = "' + outpath + '"\n'
|
||||||
|
log += 'First 8 chars of PID = "' + pidnum + '"\n'
|
||||||
|
log += '\n\n'
|
||||||
|
log += 'Please Wait ...\n'
|
||||||
|
self.stext.insert(Tkconstants.END,log)
|
||||||
|
self.p2 = self.topazrdr(tpzpath, outpath, pidnum)
|
||||||
|
|
||||||
|
# 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('Topaz eBook File Extraction')
|
||||||
|
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())
|
|
@ -0,0 +1,191 @@
|
||||||
|
#!/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='Extract Contents of Topaz eBook to a Directory')
|
||||||
|
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='Topaz eBook input file').grid(row=0, sticky=Tkconstants.E)
|
||||||
|
self.tpzpath = Tkinter.Entry(body, width=50)
|
||||||
|
self.tpzpath.grid(row=0, column=1, sticky=sticky)
|
||||||
|
self.tpzpath.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_tpzpath)
|
||||||
|
button.grid(row=0, column=2)
|
||||||
|
|
||||||
|
Tkinter.Label(body, text='Output Directory').grid(row=1, sticky=Tkconstants.E)
|
||||||
|
self.outpath = Tkinter.Entry(body, width=50)
|
||||||
|
self.outpath.grid(row=1, column=1, sticky=sticky)
|
||||||
|
self.outpath.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_outpath)
|
||||||
|
button.grid(row=1, column=2)
|
||||||
|
|
||||||
|
Tkinter.Label(body, text='First 8 characters of PID').grid(row=3, sticky=Tkconstants.E)
|
||||||
|
self.pidnum = Tkinter.StringVar()
|
||||||
|
self.ccinfo = Tkinter.Entry(body, width=10, textvariable=self.pidnum)
|
||||||
|
self.ccinfo.grid(row=3, 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=4, 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' + 'Files successfully extracted\n'
|
||||||
|
if poll != 0:
|
||||||
|
msg = text + '\n\n' + 'Error: File Extraction 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 !='':
|
||||||
|
self.stext.insert(Tkconstants.END,msg)
|
||||||
|
self.stext.yview_pickplace(Tkconstants.END)
|
||||||
|
return
|
||||||
|
|
||||||
|
# run as a subprocess via pipes and collect stdout
|
||||||
|
def topazrdr(self, infile, outdir, pidnum):
|
||||||
|
# os.putenv('PYTHONUNBUFFERED', '1')
|
||||||
|
pidoption = ' -p "' + pidnum + '" '
|
||||||
|
outoption = ' -o "' + outdir + '" '
|
||||||
|
cmdline = 'python ./lib/cmbtc_dump_nonK4PC.py -v -d ' + pidoption + outoption + '"' + infile + '"'
|
||||||
|
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\cmbtc_dump_nonK4PC.py -v -d ' + pidoption + outoption + '"' + infile + '"'
|
||||||
|
else :
|
||||||
|
cmdline = 'lib\cmbtc_dump_nonK4PC.py -v -d ' + pidoption + outoption + '"' + infile + '"'
|
||||||
|
|
||||||
|
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
|
||||||
|
return p2
|
||||||
|
|
||||||
|
|
||||||
|
def get_tpzpath(self):
|
||||||
|
tpzpath = tkFileDialog.askopenfilename(
|
||||||
|
parent=None, title='Select Topaz File',
|
||||||
|
defaultextension='.prc', filetypes=[('Topaz azw1', '.azw1'), ('Topaz prc', '.prc'),
|
||||||
|
('All Files', '.*')])
|
||||||
|
if tpzpath:
|
||||||
|
tpzpath = os.path.normpath(tpzpath)
|
||||||
|
self.tpzpath.delete(0, Tkconstants.END)
|
||||||
|
self.tpzpath.insert(0, tpzpath)
|
||||||
|
return
|
||||||
|
|
||||||
|
def get_outpath(self):
|
||||||
|
outpath = tkFileDialog.askdirectory(
|
||||||
|
parent=None, title='Directory to Extract Files into',
|
||||||
|
initialdir=os.getcwd(), initialfile=None)
|
||||||
|
if outpath:
|
||||||
|
outpath = os.path.normpath(outpath)
|
||||||
|
self.outpath.delete(0, Tkconstants.END)
|
||||||
|
self.outpath.insert(0, outpath)
|
||||||
|
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')
|
||||||
|
tpzpath = self.tpzpath.get()
|
||||||
|
outpath = self.outpath.get()
|
||||||
|
if not tpzpath or not os.path.exists(tpzpath):
|
||||||
|
self.status['text'] = 'Specified Topaz eBook file does not exist'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
if not outpath:
|
||||||
|
self.status['text'] = 'No output directory specified'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
if not os.path.exists(outpath):
|
||||||
|
os.makedirs(outpath)
|
||||||
|
pidnum = self.pidnum.get()
|
||||||
|
if not pidnum or pidnum == '':
|
||||||
|
self.status['text'] = 'You have not entered a PID '
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
|
||||||
|
log = 'Command = "python cmbtc_dump_nonK4PC.py"\n'
|
||||||
|
log += 'Topaz Path Path = "'+ tpzpath + '"\n'
|
||||||
|
log += 'Output Directory = "' + outpath + '"\n'
|
||||||
|
log += 'First 8 chars of PID = "' + pidnum + '"\n'
|
||||||
|
log += '\n\n'
|
||||||
|
log += 'Please Wait ...\n'
|
||||||
|
self.stext.insert(Tkconstants.END,log)
|
||||||
|
self.p2 = self.topazrdr(tpzpath, outpath, pidnum)
|
||||||
|
|
||||||
|
# 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('Topaz eBook File Extraction')
|
||||||
|
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())
|
|
@ -0,0 +1,152 @@
|
||||||
|
#!/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='Convert Files From Topaz eBook to HTML')
|
||||||
|
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='Directory you Extracted Topaz Files into').grid(row=0, sticky=Tkconstants.E)
|
||||||
|
self.bookdir = Tkinter.Entry(body, width=50)
|
||||||
|
self.bookdir.grid(row=0, column=1, sticky=sticky)
|
||||||
|
self.bookdir.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_bookdir)
|
||||||
|
button.grid(row=0, column=2)
|
||||||
|
|
||||||
|
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=4, 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' + 'book.html successfully created in ' + self.bookdir.get() + '\n'
|
||||||
|
if poll != 0:
|
||||||
|
msg = text + '\n\n' + 'Error: HTML 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 !='':
|
||||||
|
self.stext.insert(Tkconstants.END,msg)
|
||||||
|
self.stext.yview_pickplace(Tkconstants.END)
|
||||||
|
return
|
||||||
|
|
||||||
|
# run as a subprocess via pipes and collect stdout
|
||||||
|
def topazrdr(self, bookdir):
|
||||||
|
# os.putenv('PYTHONUNBUFFERED', '1')
|
||||||
|
cmdline = 'python ./lib/genhtml.py "' + bookdir + '"'
|
||||||
|
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\genhtml.py "' + bookdir + '"'
|
||||||
|
else :
|
||||||
|
cmdline = 'lib\genhtml.py "' + bookdir + '"'
|
||||||
|
|
||||||
|
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
|
||||||
|
return p2
|
||||||
|
|
||||||
|
|
||||||
|
def get_bookdir(self):
|
||||||
|
bookdir = tkFileDialog.askdirectory(
|
||||||
|
parent=None, title='Select the Directory you Extracted Topaz Files into',
|
||||||
|
initialdir=os.getcwd(), initialfile=None)
|
||||||
|
if bookdir:
|
||||||
|
bookdir = os.path.normpath(bookdir)
|
||||||
|
self.bookdir.delete(0, Tkconstants.END)
|
||||||
|
self.bookdir.insert(0, bookdir)
|
||||||
|
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')
|
||||||
|
bookdir = self.bookdir.get()
|
||||||
|
if not bookdir:
|
||||||
|
self.status['text'] = 'No directory specified'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
|
||||||
|
log = 'Command = "python genhtml.py"\n'
|
||||||
|
log += 'Book Directory = "' + bookdir + '"\n'
|
||||||
|
log += '\n\n'
|
||||||
|
log += 'Please Wait ...\n'
|
||||||
|
self.stext.insert(Tkconstants.END,log)
|
||||||
|
self.p2 = self.topazrdr(bookdir)
|
||||||
|
|
||||||
|
# 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('Convert Topaz Files to SVG Files')
|
||||||
|
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())
|
|
@ -0,0 +1,152 @@
|
||||||
|
#!/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='Convert Files From Topaz eBook to SVG')
|
||||||
|
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='Directory you Extracted Topaz Files into').grid(row=0, sticky=Tkconstants.E)
|
||||||
|
self.bookdir = Tkinter.Entry(body, width=50)
|
||||||
|
self.bookdir.grid(row=0, column=1, sticky=sticky)
|
||||||
|
self.bookdir.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_bookdir)
|
||||||
|
button.grid(row=0, column=2)
|
||||||
|
|
||||||
|
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=4, 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' + 'SVG embedded in XHTML files successfully created in the svg directory in ' + self.bookdir.get() + '\n'
|
||||||
|
if poll != 0:
|
||||||
|
msg = text + '\n\n' + 'Error: SVG 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 !='':
|
||||||
|
self.stext.insert(Tkconstants.END,msg)
|
||||||
|
self.stext.yview_pickplace(Tkconstants.END)
|
||||||
|
return
|
||||||
|
|
||||||
|
# run as a subprocess via pipes and collect stdout
|
||||||
|
def topazrdr(self, bookdir):
|
||||||
|
# os.putenv('PYTHONUNBUFFERED', '1')
|
||||||
|
cmdline = 'python ./lib/gensvg.py "' + bookdir + '"'
|
||||||
|
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\gensvg.py "' + bookdir + '"'
|
||||||
|
else :
|
||||||
|
cmdline = 'lib\gensvg.py "' + bookdir + '"'
|
||||||
|
|
||||||
|
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
|
||||||
|
return p2
|
||||||
|
|
||||||
|
|
||||||
|
def get_bookdir(self):
|
||||||
|
bookdir = tkFileDialog.askdirectory(
|
||||||
|
parent=None, title='Select the Directory you Extracted Topaz Files into',
|
||||||
|
initialdir=os.getcwd(), initialfile=None)
|
||||||
|
if bookdir:
|
||||||
|
bookdir = os.path.normpath(bookdir)
|
||||||
|
self.bookdir.delete(0, Tkconstants.END)
|
||||||
|
self.bookdir.insert(0, bookdir)
|
||||||
|
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')
|
||||||
|
bookdir = self.bookdir.get()
|
||||||
|
if not bookdir:
|
||||||
|
self.status['text'] = 'No directory specified'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
|
||||||
|
log = 'Command = "python gensvg.py"\n'
|
||||||
|
log += 'Book Directory = "' + bookdir + '"\n'
|
||||||
|
log += '\n\n'
|
||||||
|
log += 'Please Wait ...\n'
|
||||||
|
self.stext.insert(Tkconstants.END,log)
|
||||||
|
self.p2 = self.topazrdr(bookdir)
|
||||||
|
|
||||||
|
# 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('Convert Topaz Files to SVG Files')
|
||||||
|
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())
|
|
@ -0,0 +1,152 @@
|
||||||
|
#!/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='Convert Files From Topaz eBook to XML')
|
||||||
|
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='Directory you Extracted Topaz Files into').grid(row=0, sticky=Tkconstants.E)
|
||||||
|
self.bookdir = Tkinter.Entry(body, width=50)
|
||||||
|
self.bookdir.grid(row=0, column=1, sticky=sticky)
|
||||||
|
self.bookdir.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_bookdir)
|
||||||
|
button.grid(row=0, column=2)
|
||||||
|
|
||||||
|
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=4, 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' + 'XML files successfully created in the xml directory in ' + self.bookdir.get() + '\n'
|
||||||
|
if poll != 0:
|
||||||
|
msg = text + '\n\n' + 'Error: XML 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 !='':
|
||||||
|
self.stext.insert(Tkconstants.END,msg)
|
||||||
|
self.stext.yview_pickplace(Tkconstants.END)
|
||||||
|
return
|
||||||
|
|
||||||
|
# run as a subprocess via pipes and collect stdout
|
||||||
|
def topazrdr(self, bookdir):
|
||||||
|
# os.putenv('PYTHONUNBUFFERED', '1')
|
||||||
|
cmdline = 'python ./lib/genxml.py "' + bookdir + '"'
|
||||||
|
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\genxml.py "' + bookdir + '"'
|
||||||
|
else :
|
||||||
|
cmdline = 'lib\genxml.py "' + bookdir + '"'
|
||||||
|
|
||||||
|
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
|
||||||
|
return p2
|
||||||
|
|
||||||
|
|
||||||
|
def get_bookdir(self):
|
||||||
|
bookdir = tkFileDialog.askdirectory(
|
||||||
|
parent=None, title='Select the Directory you Extracted Topaz Files into',
|
||||||
|
initialdir=os.getcwd(), initialfile=None)
|
||||||
|
if bookdir:
|
||||||
|
bookdir = os.path.normpath(bookdir)
|
||||||
|
self.bookdir.delete(0, Tkconstants.END)
|
||||||
|
self.bookdir.insert(0, bookdir)
|
||||||
|
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')
|
||||||
|
bookdir = self.bookdir.get()
|
||||||
|
if not bookdir:
|
||||||
|
self.status['text'] = 'No directory specified'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
|
||||||
|
log = 'Command = "python genxml.py"\n'
|
||||||
|
log += 'Book Directory = "' + bookdir + '"\n'
|
||||||
|
log += '\n\n'
|
||||||
|
log += 'Please Wait ...\n'
|
||||||
|
self.stext.insert(Tkconstants.END,log)
|
||||||
|
self.p2 = self.topazrdr(bookdir)
|
||||||
|
|
||||||
|
# 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('Convert Topaz Files to XML Files')
|
||||||
|
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())
|
|
@ -1,5 +1,5 @@
|
||||||
#! /usr/bin/python
|
#! /usr/bin/python
|
||||||
# For use in Topaz Scripts version 2.0
|
# For use in Topaz Scripts version 2.2
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -13,11 +13,22 @@ y2/pHuYme7U1TsgSjwIDAQAB
|
||||||
-----END PUBLIC KEY-----
|
-----END PUBLIC KEY-----
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
import csv
|
class Unbuffered:
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.stream = stream
|
||||||
|
def write(self, data):
|
||||||
|
self.stream.write(data)
|
||||||
|
self.stream.flush()
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
sys.stdout=Unbuffered(sys.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
import csv
|
||||||
import os
|
import os
|
||||||
import getopt
|
import getopt
|
||||||
import zlib
|
import zlib
|
||||||
|
@ -305,7 +316,10 @@ def encodeNumber(number):
|
||||||
byte += flag
|
byte += flag
|
||||||
result += chr(byte)
|
result += chr(byte)
|
||||||
flag = 0x80
|
flag = 0x80
|
||||||
if number == 0 : break
|
if number == 0 :
|
||||||
|
if (byte == 0xFF and negative == False) :
|
||||||
|
result += chr(0x80)
|
||||||
|
break
|
||||||
|
|
||||||
if negative:
|
if negative:
|
||||||
result += chr(0xFF)
|
result += chr(0xFF)
|
||||||
|
@ -841,13 +855,12 @@ def main(argv=sys.argv):
|
||||||
if len(bookKeys) == 0 :
|
if len(bookKeys) == 0 :
|
||||||
if verbose > 0 :
|
if verbose > 0 :
|
||||||
print ("Book key could not be found. Maybe this book is not registered with this device.")
|
print ("Book key could not be found. Maybe this book is not registered with this device.")
|
||||||
|
return 1
|
||||||
else :
|
else :
|
||||||
bookKey = bookKeys[0]
|
bookKey = bookKeys[0]
|
||||||
if verbose > 0:
|
if verbose > 0:
|
||||||
print("Book key: " + bookKey.encode('hex'))
|
print("Book key: " + bookKey.encode('hex'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if command == "printRecord" :
|
if command == "printRecord" :
|
||||||
extractBookPayloadRecord(recordName,int(recordIndex),outputFile)
|
extractBookPayloadRecord(recordName,int(recordIndex),outputFile)
|
||||||
if outputFile != "" and verbose>0 :
|
if outputFile != "" and verbose>0 :
|
||||||
|
@ -859,6 +872,7 @@ def main(argv=sys.argv):
|
||||||
print ("Decrypted book saved. Don't pirate!")
|
print ("Decrypted book saved. Don't pirate!")
|
||||||
elif verbose > 0:
|
elif verbose > 0:
|
||||||
print("Output directory name was not supplied.")
|
print("Output directory name was not supplied.")
|
||||||
|
return 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
#! /usr/bin/python
|
#!/usr/bin/python
|
||||||
# For use with Topaz Scripts Version 2.0
|
# For use with Topaz Scripts Version 2.2
|
||||||
|
|
||||||
from __future__ import with_statement
|
class Unbuffered:
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.stream = stream
|
||||||
|
def write(self, data):
|
||||||
|
self.stream.write(data)
|
||||||
|
self.stream.flush()
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.stdout=Unbuffered(sys.stdout)
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import getopt
|
import getopt
|
||||||
import zlib
|
import zlib
|
||||||
|
@ -90,7 +99,10 @@ def encodeNumber(number):
|
||||||
byte += flag
|
byte += flag
|
||||||
result += chr(byte)
|
result += chr(byte)
|
||||||
flag = 0x80
|
flag = 0x80
|
||||||
if number == 0 : break
|
if number == 0 :
|
||||||
|
if (byte == 0xFF and negative == False) :
|
||||||
|
result += chr(0x80)
|
||||||
|
break
|
||||||
|
|
||||||
if negative:
|
if negative:
|
||||||
result += chr(0xFF)
|
result += chr(0xFF)
|
||||||
|
@ -480,12 +492,11 @@ def main(argv=sys.argv):
|
||||||
if len(bookKeys) == 0 :
|
if len(bookKeys) == 0 :
|
||||||
if verbose > 0 :
|
if verbose > 0 :
|
||||||
print ("Book key could not be found. Maybe this book is not registered with this device.")
|
print ("Book key could not be found. Maybe this book is not registered with this device.")
|
||||||
|
return 1
|
||||||
else :
|
else :
|
||||||
bookKey = bookKeys[0]
|
bookKey = bookKeys[0]
|
||||||
if verbose > 0:
|
if verbose > 0:
|
||||||
print("Book key: " + bookKey.encode('hex'))
|
print("Book key: " + bookKey.encode('hex'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if command == "printRecord" :
|
if command == "printRecord" :
|
||||||
extractBookPayloadRecord(recordName,int(recordIndex),outputFile)
|
extractBookPayloadRecord(recordName,int(recordIndex),outputFile)
|
||||||
|
@ -498,6 +509,7 @@ def main(argv=sys.argv):
|
||||||
print ("Decrypted book saved. Don't pirate!")
|
print ("Decrypted book saved. Don't pirate!")
|
||||||
elif verbose > 0:
|
elif verbose > 0:
|
||||||
print("Output directory name was not supplied.")
|
print("Output directory name was not supplied.")
|
||||||
|
return 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
#! /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.0
|
# For use with Topaz Scripts Version 2.2
|
||||||
|
|
||||||
|
class Unbuffered:
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.stream = stream
|
||||||
|
def write(self, data):
|
||||||
|
self.stream.write(data)
|
||||||
|
self.stream.flush()
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
from __future__ import with_statement
|
|
||||||
import csv
|
|
||||||
import sys
|
import sys
|
||||||
|
sys.stdout=Unbuffered(sys.stdout)
|
||||||
|
|
||||||
|
import csv
|
||||||
import os
|
import os
|
||||||
import getopt
|
import getopt
|
||||||
from struct import pack
|
from struct import pack
|
||||||
|
@ -61,7 +71,10 @@ def encodeNumber(number):
|
||||||
byte += flag
|
byte += flag
|
||||||
result += chr(byte)
|
result += chr(byte)
|
||||||
flag = 0x80
|
flag = 0x80
|
||||||
if number == 0 : break
|
if number == 0 :
|
||||||
|
if (byte == 0xFF and negative == False) :
|
||||||
|
result += chr(0x80)
|
||||||
|
break
|
||||||
|
|
||||||
if negative:
|
if negative:
|
||||||
result += chr(0xFF)
|
result += chr(0xFF)
|
||||||
|
@ -729,8 +742,6 @@ def main(argv):
|
||||||
if len(argv) == 0:
|
if len(argv) == 0:
|
||||||
printOutput = True
|
printOutput = True
|
||||||
argv = sys.argv
|
argv = sys.argv
|
||||||
else :
|
|
||||||
argv = argv.split()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(argv[1:], "hd", ["flat-xml"])
|
opts, args = getopt.getopt(argv[1:], "hd", ["flat-xml"])
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#! /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.0
|
# For use with Topaz Scripts Version 2.2
|
||||||
|
|
||||||
from __future__ import with_statement
|
|
||||||
import csv
|
import csv
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
@ -61,8 +60,11 @@ def encodeNumber(number):
|
||||||
byte += flag
|
byte += flag
|
||||||
result += chr(byte)
|
result += chr(byte)
|
||||||
flag = 0x80
|
flag = 0x80
|
||||||
if number == 0 : break
|
if number == 0 :
|
||||||
|
if (byte == 0xFF and negative == False) :
|
||||||
|
result += chr(0x80)
|
||||||
|
break
|
||||||
|
|
||||||
if negative:
|
if negative:
|
||||||
result += chr(0xFF)
|
result += chr(0xFF)
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
#! /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.0
|
# For use with Topaz Scripts Version 2.2
|
||||||
|
|
||||||
from __future__ import with_statement
|
|
||||||
import csv
|
|
||||||
import sys
|
import sys
|
||||||
|
import csv
|
||||||
import os
|
import os
|
||||||
import math
|
import math
|
||||||
import getopt
|
import getopt
|
||||||
|
|
|
@ -1,8 +1,21 @@
|
||||||
#! /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.0
|
# For use with Topaz Scripts Version 2.2
|
||||||
|
|
||||||
import os, sys, getopt
|
class Unbuffered:
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.stream = stream
|
||||||
|
def write(self, data):
|
||||||
|
self.stream.write(data)
|
||||||
|
self.stream.flush()
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.stdout=Unbuffered(sys.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
import os, getopt
|
||||||
|
|
||||||
# local routines
|
# local routines
|
||||||
import convert2xml
|
import convert2xml
|
||||||
|
@ -27,8 +40,6 @@ def main(argv):
|
||||||
|
|
||||||
if len(argv) == 0:
|
if len(argv) == 0:
|
||||||
argv = sys.argv
|
argv = sys.argv
|
||||||
else :
|
|
||||||
argv = argv.split()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(argv[1:], "h:",["fixed-image"])
|
opts, args = getopt.getopt(argv[1:], "h:",["fixed-image"])
|
||||||
|
@ -36,11 +47,11 @@ def main(argv):
|
||||||
except getopt.GetoptError, err:
|
except getopt.GetoptError, err:
|
||||||
print str(err)
|
print str(err)
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(1)
|
||||||
|
|
||||||
if len(opts) == 0 and len(args) == 0 :
|
if len(opts) == 0 and len(args) == 0 :
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(1)
|
||||||
|
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
if o =="-h":
|
if o =="-h":
|
||||||
|
@ -53,39 +64,39 @@ def main(argv):
|
||||||
|
|
||||||
if not os.path.exists(bookDir) :
|
if not os.path.exists(bookDir) :
|
||||||
print "Can not find directory with unencrypted book"
|
print "Can not find directory with unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
dictFile = os.path.join(bookDir,'dict0000.dat')
|
dictFile = os.path.join(bookDir,'dict0000.dat')
|
||||||
|
|
||||||
if not os.path.exists(dictFile) :
|
if not os.path.exists(dictFile) :
|
||||||
print "Can not find dict0000.dat file"
|
print "Can not find dict0000.dat file"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
pageDir = os.path.join(bookDir,'page')
|
pageDir = os.path.join(bookDir,'page')
|
||||||
if not os.path.exists(pageDir) :
|
if not os.path.exists(pageDir) :
|
||||||
print "Can not find page directory in unencrypted book"
|
print "Can not find page directory in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
imgDir = os.path.join(bookDir,'img')
|
imgDir = os.path.join(bookDir,'img')
|
||||||
if not os.path.exists(imgDir) :
|
if not os.path.exists(imgDir) :
|
||||||
print "Can not find image directory in unencrypted book"
|
print "Can not find image directory in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
svgDir = os.path.join(bookDir,'svg')
|
svgDir = os.path.join(bookDir,'svg')
|
||||||
if not os.path.exists(svgDir) :
|
if not os.path.exists(svgDir) :
|
||||||
print "Can not find svg directory in unencrypted book"
|
print "Can not find svg directory in unencrypted book"
|
||||||
print "please run gensvg.py before running genhtml.py"
|
print "please run gensvg.py before running genhtml.py"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
otherFile = os.path.join(bookDir,'other0000.dat')
|
otherFile = os.path.join(bookDir,'other0000.dat')
|
||||||
if not os.path.exists(otherFile) :
|
if not os.path.exists(otherFile) :
|
||||||
print "Can not find other0000.dat in unencrypted book"
|
print "Can not find other0000.dat in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
metaFile = os.path.join(bookDir,'metadata0000.dat')
|
metaFile = os.path.join(bookDir,'metadata0000.dat')
|
||||||
if not os.path.exists(metaFile) :
|
if not os.path.exists(metaFile) :
|
||||||
print "Can not find metadata0000.dat in unencrypted book"
|
print "Can not find metadata0000.dat in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
htmlFileName = "book.html"
|
htmlFileName = "book.html"
|
||||||
htmlstr = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
|
htmlstr = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
|
||||||
|
@ -123,18 +134,28 @@ def main(argv):
|
||||||
pnum = int(spage)
|
pnum = int(spage)
|
||||||
|
|
||||||
# get page height and width from first text page for use in stylesheet scaling
|
# get page height and width from first text page for use in stylesheet scaling
|
||||||
pname = 'page%04d.dat' % pnum
|
pname = 'page%04d.dat' % (pnum + 1)
|
||||||
fname = os.path.join(pageDir,pname)
|
fname = os.path.join(pageDir,pname)
|
||||||
flat_xml = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
|
pargv=[]
|
||||||
|
pargv.append('convert2xml.py')
|
||||||
|
pargv.append('--flat-xml')
|
||||||
|
pargv.append(dictFile)
|
||||||
|
pargv.append(fname)
|
||||||
|
flat_xml = convert2xml.main(pargv)
|
||||||
(ph, pw) = getpagedim.getPageDim(flat_xml)
|
(ph, pw) = getpagedim.getPageDim(flat_xml)
|
||||||
if (ph == '-1') : ph = 11000
|
if (ph == '-1') or (ph == '0') : ph = '11000'
|
||||||
if (pw == '-1') : pw = 8500
|
if (pw == '-1') or (pw == '0') : pw = '8500'
|
||||||
|
|
||||||
# now build up the style sheet
|
# now build up the style sheet
|
||||||
print ' ', 'other0000.dat'
|
print ' ', 'other0000.dat'
|
||||||
fname = os.path.join(bookDir,'other0000.dat')
|
fname = os.path.join(bookDir,'other0000.dat')
|
||||||
xname = os.path.join(bookDir, 'style.css')
|
xname = os.path.join(bookDir, 'style.css')
|
||||||
xmlstr = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
|
pargv=[]
|
||||||
|
pargv.append('convert2xml.py')
|
||||||
|
pargv.append('--flat-xml')
|
||||||
|
pargv.append(dictFile)
|
||||||
|
pargv.append(fname)
|
||||||
|
xmlstr = convert2xml.main(pargv)
|
||||||
cssstr , classlst = stylexml2css.convert2CSS(xmlstr, fontsize, ph, pw)
|
cssstr , classlst = stylexml2css.convert2CSS(xmlstr, fontsize, ph, pw)
|
||||||
file(xname, 'wb').write(cssstr)
|
file(xname, 'wb').write(cssstr)
|
||||||
htmlstr += '<link href="style.css" rel="stylesheet" type="text/css" />\n'
|
htmlstr += '<link href="style.css" rel="stylesheet" type="text/css" />\n'
|
||||||
|
@ -143,7 +164,12 @@ def main(argv):
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
print ' ', filename
|
print ' ', filename
|
||||||
fname = os.path.join(pageDir,filename)
|
fname = os.path.join(pageDir,filename)
|
||||||
flat_xml = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
|
pargv=[]
|
||||||
|
pargv.append('convert2xml.py')
|
||||||
|
pargv.append('--flat-xml')
|
||||||
|
pargv.append(dictFile)
|
||||||
|
pargv.append(fname)
|
||||||
|
flat_xml = convert2xml.main(pargv)
|
||||||
htmlstr += flatxml2html.convert2HTML(flat_xml, classlst, fname, bookDir, fixedimage)
|
htmlstr += flatxml2html.convert2HTML(flat_xml, classlst, fname, bookDir, fixedimage)
|
||||||
|
|
||||||
htmlstr += '</body>\n</html>\n'
|
htmlstr += '</body>\n</html>\n'
|
||||||
|
|
|
@ -1,8 +1,20 @@
|
||||||
#! /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.0
|
# For use with Topaz Scripts Version 2.2
|
||||||
|
|
||||||
import os, sys, getopt
|
class Unbuffered:
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.stream = stream
|
||||||
|
def write(self, data):
|
||||||
|
self.stream.write(data)
|
||||||
|
self.stream.flush()
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.stdout=Unbuffered(sys.stdout)
|
||||||
|
|
||||||
|
import os, getopt
|
||||||
|
|
||||||
# local routines
|
# local routines
|
||||||
import convert2xml
|
import convert2xml
|
||||||
|
@ -190,8 +202,6 @@ def main(argv):
|
||||||
|
|
||||||
if len(argv) == 0:
|
if len(argv) == 0:
|
||||||
argv = sys.argv
|
argv = sys.argv
|
||||||
else :
|
|
||||||
argv = argv.split()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(argv[1:], "xrh")
|
opts, args = getopt.getopt(argv[1:], "xrh")
|
||||||
|
@ -199,11 +209,11 @@ def main(argv):
|
||||||
except getopt.GetoptError, err:
|
except getopt.GetoptError, err:
|
||||||
print str(err)
|
print str(err)
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(1)
|
||||||
|
|
||||||
if len(opts) == 0 and len(args) == 0 :
|
if len(opts) == 0 and len(args) == 0 :
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(1)
|
||||||
|
|
||||||
raw = 0
|
raw = 0
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
|
@ -219,33 +229,33 @@ def main(argv):
|
||||||
|
|
||||||
if not os.path.exists(bookDir) :
|
if not os.path.exists(bookDir) :
|
||||||
print "Can not find directory with unencrypted book"
|
print "Can not find directory with unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
dictFile = os.path.join(bookDir,'dict0000.dat')
|
dictFile = os.path.join(bookDir,'dict0000.dat')
|
||||||
|
|
||||||
if not os.path.exists(dictFile) :
|
if not os.path.exists(dictFile) :
|
||||||
print "Can not find dict0000.dat file"
|
print "Can not find dict0000.dat file"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
pageDir = os.path.join(bookDir,'page')
|
pageDir = os.path.join(bookDir,'page')
|
||||||
if not os.path.exists(pageDir) :
|
if not os.path.exists(pageDir) :
|
||||||
print "Can not find page directory in unencrypted book"
|
print "Can not find page directory in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
imgDir = os.path.join(bookDir,'img')
|
imgDir = os.path.join(bookDir,'img')
|
||||||
if not os.path.exists(imgDir) :
|
if not os.path.exists(imgDir) :
|
||||||
print "Can not find image directory in unencrypted book"
|
print "Can not find image directory in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
glyphsDir = os.path.join(bookDir,'glyphs')
|
glyphsDir = os.path.join(bookDir,'glyphs')
|
||||||
if not os.path.exists(glyphsDir) :
|
if not os.path.exists(glyphsDir) :
|
||||||
print "Can not find glyphs directory in unencrypted book"
|
print "Can not find glyphs directory in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
metaFile = os.path.join(bookDir,'metadata0000.dat')
|
metaFile = os.path.join(bookDir,'metadata0000.dat')
|
||||||
if not os.path.exists(metaFile) :
|
if not os.path.exists(metaFile) :
|
||||||
print "Can not find metadata0000.dat in unencrypted book"
|
print "Can not find metadata0000.dat in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
svgDir = os.path.join(bookDir,'svg')
|
svgDir = os.path.join(bookDir,'svg')
|
||||||
if not os.path.exists(svgDir) :
|
if not os.path.exists(svgDir) :
|
||||||
|
@ -274,7 +284,12 @@ def main(argv):
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
print ' ', filename
|
print ' ', filename
|
||||||
fname = os.path.join(glyphsDir,filename)
|
fname = os.path.join(glyphsDir,filename)
|
||||||
flat_xml = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
|
pargv=[]
|
||||||
|
pargv.append('convert2xml.py')
|
||||||
|
pargv.append('--flat-xml')
|
||||||
|
pargv.append(dictFile)
|
||||||
|
pargv.append(fname)
|
||||||
|
flat_xml = convert2xml.main(pargv)
|
||||||
gp = GParser(flat_xml)
|
gp = GParser(flat_xml)
|
||||||
for i in xrange(0, gp.count):
|
for i in xrange(0, gp.count):
|
||||||
path = gp.getPath(i)
|
path = gp.getPath(i)
|
||||||
|
@ -297,7 +312,12 @@ def main(argv):
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
print ' ', filename
|
print ' ', filename
|
||||||
fname = os.path.join(pageDir,filename)
|
fname = os.path.join(pageDir,filename)
|
||||||
flat_xml = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
|
pargv=[]
|
||||||
|
pargv.append('convert2xml.py')
|
||||||
|
pargv.append('--flat-xml')
|
||||||
|
pargv.append(dictFile)
|
||||||
|
pargv.append(fname)
|
||||||
|
flat_xml = convert2xml.main(pargv)
|
||||||
pp = PParser(flat_xml)
|
pp = PParser(flat_xml)
|
||||||
if (raw) :
|
if (raw) :
|
||||||
pfile = open(os.path.join(svgDir,filename.replace('.dat','.svg')), 'w')
|
pfile = open(os.path.join(svgDir,filename.replace('.dat','.svg')), 'w')
|
||||||
|
|
|
@ -1,8 +1,21 @@
|
||||||
#! /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.0
|
# For use with Topaz Scripts Version 2.2
|
||||||
|
|
||||||
import os, sys, getopt
|
class Unbuffered:
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.stream = stream
|
||||||
|
def write(self, data):
|
||||||
|
self.stream.write(data)
|
||||||
|
self.stream.flush()
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.stdout=Unbuffered(sys.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
import os, getopt
|
||||||
|
|
||||||
# local routines
|
# local routines
|
||||||
import convert2xml
|
import convert2xml
|
||||||
|
@ -23,8 +36,6 @@ def main(argv):
|
||||||
|
|
||||||
if len(argv) == 0:
|
if len(argv) == 0:
|
||||||
argv = sys.argv
|
argv = sys.argv
|
||||||
else :
|
|
||||||
argv = argv.split()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(argv[1:], "h:")
|
opts, args = getopt.getopt(argv[1:], "h:")
|
||||||
|
@ -32,11 +43,11 @@ def main(argv):
|
||||||
except getopt.GetoptError, err:
|
except getopt.GetoptError, err:
|
||||||
print str(err)
|
print str(err)
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(1)
|
||||||
|
|
||||||
if len(opts) == 0 and len(args) == 0 :
|
if len(opts) == 0 and len(args) == 0 :
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(1)
|
||||||
|
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
if o =="-h":
|
if o =="-h":
|
||||||
|
@ -47,32 +58,32 @@ def main(argv):
|
||||||
|
|
||||||
if not os.path.exists(bookDir) :
|
if not os.path.exists(bookDir) :
|
||||||
print "Can not find directory with unencrypted book"
|
print "Can not find directory with unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
dictFile = os.path.join(bookDir,'dict0000.dat')
|
dictFile = os.path.join(bookDir,'dict0000.dat')
|
||||||
if not os.path.exists(dictFile) :
|
if not os.path.exists(dictFile) :
|
||||||
print "Can not find dict0000.dat file"
|
print "Can not find dict0000.dat file"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
pageDir = os.path.join(bookDir,'page')
|
pageDir = os.path.join(bookDir,'page')
|
||||||
if not os.path.exists(pageDir) :
|
if not os.path.exists(pageDir) :
|
||||||
print "Can not find page directory in unencrypted book"
|
print "Can not find page directory in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
glyphsDir = os.path.join(bookDir,'glyphs')
|
glyphsDir = os.path.join(bookDir,'glyphs')
|
||||||
if not os.path.exists(glyphsDir) :
|
if not os.path.exists(glyphsDir) :
|
||||||
print "Can not find glyphs directory in unencrypted book"
|
print "Can not find glyphs directory in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
otherFile = os.path.join(bookDir,'other0000.dat')
|
otherFile = os.path.join(bookDir,'other0000.dat')
|
||||||
if not os.path.exists(otherFile) :
|
if not os.path.exists(otherFile) :
|
||||||
print "Can not find other0000.dat in unencrypted book"
|
print "Can not find other0000.dat in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
metaFile = os.path.join(bookDir,'metadata0000.dat')
|
metaFile = os.path.join(bookDir,'metadata0000.dat')
|
||||||
if not os.path.exists(metaFile) :
|
if not os.path.exists(metaFile) :
|
||||||
print "Can not find metadata0000.dat in unencrypted book"
|
print "Can not find metadata0000.dat in unencrypted book"
|
||||||
sys.exit(-1)
|
sys.exit(1)
|
||||||
|
|
||||||
xmlDir = os.path.join(bookDir,'xml')
|
xmlDir = os.path.join(bookDir,'xml')
|
||||||
if not os.path.exists(xmlDir):
|
if not os.path.exists(xmlDir):
|
||||||
|
@ -90,7 +101,11 @@ def main(argv):
|
||||||
print ' ', 'other0000.dat'
|
print ' ', 'other0000.dat'
|
||||||
fname = os.path.join(bookDir,'other0000.dat')
|
fname = os.path.join(bookDir,'other0000.dat')
|
||||||
xname = os.path.join(xmlDir, 'stylesheet.xml')
|
xname = os.path.join(xmlDir, 'stylesheet.xml')
|
||||||
xmlstr = convert2xml.main('convert2xml.py ' + dictFile + ' ' + fname)
|
pargv=[]
|
||||||
|
pargv.append('convert2xml.py')
|
||||||
|
pargv.append(dictFile)
|
||||||
|
pargv.append(fname)
|
||||||
|
xmlstr = convert2xml.main(pargv)
|
||||||
file(xname, 'wb').write(xmlstr)
|
file(xname, 'wb').write(xmlstr)
|
||||||
|
|
||||||
filenames = os.listdir(pageDir)
|
filenames = os.listdir(pageDir)
|
||||||
|
@ -100,7 +115,11 @@ def main(argv):
|
||||||
print ' ', filename
|
print ' ', filename
|
||||||
fname = os.path.join(pageDir,filename)
|
fname = os.path.join(pageDir,filename)
|
||||||
xname = os.path.join(xmlDir, filename.replace('.dat','.xml'))
|
xname = os.path.join(xmlDir, filename.replace('.dat','.xml'))
|
||||||
xmlstr = convert2xml.main('convert2xml.py ' + dictFile + ' ' + fname)
|
pargv=[]
|
||||||
|
pargv.append('convert2xml.py')
|
||||||
|
pargv.append(dictFile)
|
||||||
|
pargv.append(fname)
|
||||||
|
xmlstr = convert2xml.main(pargv)
|
||||||
file(xname, 'wb').write(xmlstr)
|
file(xname, 'wb').write(xmlstr)
|
||||||
|
|
||||||
filenames = os.listdir(glyphsDir)
|
filenames = os.listdir(glyphsDir)
|
||||||
|
@ -110,7 +129,11 @@ def main(argv):
|
||||||
print ' ', filename
|
print ' ', filename
|
||||||
fname = os.path.join(glyphsDir,filename)
|
fname = os.path.join(glyphsDir,filename)
|
||||||
xname = os.path.join(xmlDir, filename.replace('.dat','.xml'))
|
xname = os.path.join(xmlDir, filename.replace('.dat','.xml'))
|
||||||
xmlstr = convert2xml.main('convert2xml.py ' + dictFile + ' ' + fname)
|
pargv=[]
|
||||||
|
pargv.append('convert2xml.py')
|
||||||
|
pargv.append(dictFile)
|
||||||
|
pargv.append(fname)
|
||||||
|
xmlstr = convert2xml.main(pargv)
|
||||||
file(xname, 'wb').write(xmlstr)
|
file(xname, 'wb').write(xmlstr)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#! /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.0
|
# For use with Topaz Scripts Version 2.2
|
||||||
|
|
||||||
from __future__ import with_statement
|
|
||||||
import csv
|
import csv
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
|
||||||
|
|
||||||
|
import Tkinter
|
||||||
|
import Tkconstants
|
||||||
|
|
||||||
|
# basic scrolled text widget
|
||||||
|
class ScrolledText(Tkinter.Text):
|
||||||
|
def __init__(self, master=None, **kw):
|
||||||
|
self.frame = Tkinter.Frame(master)
|
||||||
|
self.vbar = Tkinter.Scrollbar(self.frame)
|
||||||
|
self.vbar.pack(side=Tkconstants.RIGHT, fill=Tkconstants.Y)
|
||||||
|
kw.update({'yscrollcommand': self.vbar.set})
|
||||||
|
Tkinter.Text.__init__(self, self.frame, **kw)
|
||||||
|
self.pack(side=Tkconstants.LEFT, fill=Tkconstants.BOTH, expand=True)
|
||||||
|
self.vbar['command'] = self.yview
|
||||||
|
# Copy geometry methods of self.frame without overriding Text
|
||||||
|
# methods = hack!
|
||||||
|
text_meths = vars(Tkinter.Text).keys()
|
||||||
|
methods = vars(Tkinter.Pack).keys() + vars(Tkinter.Grid).keys() + vars(Tkinter.Place).keys()
|
||||||
|
methods = set(methods).difference(text_meths)
|
||||||
|
for m in methods:
|
||||||
|
if m[0] != '_' and m != 'config' and m != 'configure':
|
||||||
|
setattr(self, m, getattr(self.frame, m))
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.frame)
|
|
@ -1,8 +1,7 @@
|
||||||
#! /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.0
|
# For use with Topaz Scripts Version 2.2
|
||||||
|
|
||||||
from __future__ import with_statement
|
|
||||||
import csv
|
import csv
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
|
||||||
|
|
||||||
|
import os, sys
|
||||||
|
import signal
|
||||||
|
import threading
|
||||||
|
import subprocess
|
||||||
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
|
# **heavily** chopped up and modfied version of asyncproc.py
|
||||||
|
# to make it actually work on Windows as well as Mac/Linux
|
||||||
|
# For the original see:
|
||||||
|
# "http://www.lysator.liu.se/~bellman/download/"
|
||||||
|
# author is "Thomas Bellman <bellman@lysator.liu.se>"
|
||||||
|
# available under GPL version 3 or Later
|
||||||
|
|
||||||
|
# create an asynchronous subprocess whose output can be collected in
|
||||||
|
# a non-blocking manner
|
||||||
|
|
||||||
|
# What a mess! Have to use threads just to get non-blocking io
|
||||||
|
# in a cross-platform manner
|
||||||
|
|
||||||
|
# luckily all thread use is hidden within this class
|
||||||
|
|
||||||
|
class Process(object):
|
||||||
|
def __init__(self, *params, **kwparams):
|
||||||
|
if len(params) <= 3:
|
||||||
|
kwparams.setdefault('stdin', subprocess.PIPE)
|
||||||
|
if len(params) <= 4:
|
||||||
|
kwparams.setdefault('stdout', subprocess.PIPE)
|
||||||
|
if len(params) <= 5:
|
||||||
|
kwparams.setdefault('stderr', subprocess.PIPE)
|
||||||
|
self.__pending_input = []
|
||||||
|
self.__collected_outdata = []
|
||||||
|
self.__collected_errdata = []
|
||||||
|
self.__exitstatus = None
|
||||||
|
self.__lock = threading.Lock()
|
||||||
|
self.__inputsem = threading.Semaphore(0)
|
||||||
|
self.__quit = False
|
||||||
|
|
||||||
|
self.__process = subprocess.Popen(*params, **kwparams)
|
||||||
|
|
||||||
|
if self.__process.stdin:
|
||||||
|
self.__stdin_thread = threading.Thread(
|
||||||
|
name="stdin-thread",
|
||||||
|
target=self.__feeder, args=(self.__pending_input,
|
||||||
|
self.__process.stdin))
|
||||||
|
self.__stdin_thread.setDaemon(True)
|
||||||
|
self.__stdin_thread.start()
|
||||||
|
|
||||||
|
if self.__process.stdout:
|
||||||
|
self.__stdout_thread = threading.Thread(
|
||||||
|
name="stdout-thread",
|
||||||
|
target=self.__reader, args=(self.__collected_outdata,
|
||||||
|
self.__process.stdout))
|
||||||
|
self.__stdout_thread.setDaemon(True)
|
||||||
|
self.__stdout_thread.start()
|
||||||
|
|
||||||
|
if self.__process.stderr:
|
||||||
|
self.__stderr_thread = threading.Thread(
|
||||||
|
name="stderr-thread",
|
||||||
|
target=self.__reader, args=(self.__collected_errdata,
|
||||||
|
self.__process.stderr))
|
||||||
|
self.__stderr_thread.setDaemon(True)
|
||||||
|
self.__stderr_thread.start()
|
||||||
|
|
||||||
|
def pid(self):
|
||||||
|
return self.__process.pid
|
||||||
|
|
||||||
|
def kill(self, signal):
|
||||||
|
self.__process.send_signal(signal)
|
||||||
|
|
||||||
|
# check on subprocess (pass in 'nowait') to act like poll
|
||||||
|
def wait(self, flag):
|
||||||
|
if flag.lower() == 'nowait':
|
||||||
|
rc = self.__process.poll()
|
||||||
|
else:
|
||||||
|
rc = self.__process.wait()
|
||||||
|
if rc != None:
|
||||||
|
if self.__process.stdin:
|
||||||
|
self.closeinput()
|
||||||
|
if self.__process.stdout:
|
||||||
|
self.__stdout_thread.join()
|
||||||
|
if self.__process.stderr:
|
||||||
|
self.__stderr_thread.join()
|
||||||
|
return self.__process.returncode
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
if self.__process.stdin:
|
||||||
|
self.closeinput()
|
||||||
|
self.__process.terminate()
|
||||||
|
|
||||||
|
# thread gets data from subprocess stdout
|
||||||
|
def __reader(self, collector, source):
|
||||||
|
while True:
|
||||||
|
data = os.read(source.fileno(), 65536)
|
||||||
|
self.__lock.acquire()
|
||||||
|
collector.append(data)
|
||||||
|
self.__lock.release()
|
||||||
|
if data == "":
|
||||||
|
source.close()
|
||||||
|
break
|
||||||
|
return
|
||||||
|
|
||||||
|
# thread feeds data to subprocess stdin
|
||||||
|
def __feeder(self, pending, drain):
|
||||||
|
while True:
|
||||||
|
self.__inputsem.acquire()
|
||||||
|
self.__lock.acquire()
|
||||||
|
if not pending and self.__quit:
|
||||||
|
drain.close()
|
||||||
|
self.__lock.release()
|
||||||
|
break
|
||||||
|
data = pending.pop(0)
|
||||||
|
self.__lock.release()
|
||||||
|
drain.write(data)
|
||||||
|
|
||||||
|
# non-blocking read of data from subprocess stdout
|
||||||
|
def read(self):
|
||||||
|
self.__lock.acquire()
|
||||||
|
outdata = "".join(self.__collected_outdata)
|
||||||
|
del self.__collected_outdata[:]
|
||||||
|
self.__lock.release()
|
||||||
|
return outdata
|
||||||
|
|
||||||
|
# non-blocking read of data from subprocess stderr
|
||||||
|
def readerr(self):
|
||||||
|
self.__lock.acquire()
|
||||||
|
errdata = "".join(self.__collected_errdata)
|
||||||
|
del self.__collected_errdata[:]
|
||||||
|
self.__lock.release()
|
||||||
|
return errdata
|
||||||
|
|
||||||
|
# non-blocking write to stdin of subprocess
|
||||||
|
def write(self, data):
|
||||||
|
if self.__process.stdin is None:
|
||||||
|
raise ValueError("Writing to process with stdin not a pipe")
|
||||||
|
self.__lock.acquire()
|
||||||
|
self.__pending_input.append(data)
|
||||||
|
self.__inputsem.release()
|
||||||
|
self.__lock.release()
|
||||||
|
|
||||||
|
# close stdinput of subprocess
|
||||||
|
def closeinput(self):
|
||||||
|
self.__lock.acquire()
|
||||||
|
self.__quit = True
|
||||||
|
self.__inputsem.release()
|
||||||
|
self.__lock.release()
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
Changes in 2.2
|
||||||
|
- fix for minor bug in encode_Number from clark nova
|
||||||
|
- more fixes to handle paths with spaces in them
|
||||||
|
- updates to work better with the gui front end
|
||||||
|
|
||||||
|
|
||||||
|
Changes in 2.1
|
||||||
|
- extremely minor changes to support a gui frontend
|
||||||
|
- no changes to functionality
|
||||||
|
|
||||||
|
|
||||||
|
Changes in version 2.0
|
||||||
|
|
||||||
|
- gensvg.py now accepts two options
|
||||||
|
-x : output browseable XHTML+SVG pages (default)
|
||||||
|
-r : output raw SVG images (useful for later conversion to pdf)
|
||||||
|
|
||||||
|
- flatxml2html.py now understands page.groups of type graphic
|
||||||
|
and handles vertical regions as svg images
|
||||||
|
|
||||||
|
- genhtml.py now accepts an option
|
||||||
|
--fixed-image : which will force the conversion
|
||||||
|
of all fixed regions to svg images
|
||||||
|
|
||||||
|
- minor bug fixes and html conversion improvements
|
||||||
|
|
||||||
|
|
||||||
|
Changes in version 1.8
|
||||||
|
- gensvg.py now builds wonderful xhtml pages with embedded svg
|
||||||
|
that can be easily paged through as if reading a book!
|
||||||
|
(tested in Safari for Mac and Win and Firefox)
|
||||||
|
(requires javascript to be enabled)
|
||||||
|
- genhtml.py now REQUIRES that gensvg.py be run FIRST
|
||||||
|
this allows create of images on the fly from glyphs
|
||||||
|
- genhtml.py now automatically makes tables of words into svg
|
||||||
|
based images and will handle glyph based ornate first
|
||||||
|
letters of words
|
||||||
|
- cmbtc_dump_mac_linux.py has been renamed to be
|
||||||
|
cmbtc_dump_nonK4PC.py to make it clearer
|
||||||
|
when it needs to be used
|
||||||
|
|
||||||
|
|
||||||
|
Changes in version 1.7
|
||||||
|
- gensvg.py has been improved so that the glyphs render exactly (ClarkNova)
|
||||||
|
- gensvg.py has fixed a render order "bug" that allowed some images to cover or hide text. (ClarkNova)
|
||||||
|
- change generated html to use external stylesheet via a link to "style.css"
|
||||||
|
- add missing <title> tag
|
||||||
|
- make xhtml compliant doctype and minor changes to write correct xhtml
|
||||||
|
- make divs that act as anchors be hidden visually and to take up 0 height and 0 width to prevent any impact on layout
|
||||||
|
|
||||||
|
Changes in version 1.6
|
||||||
|
- support for books whose paragraphs have no styles
|
||||||
|
- support to run cmbtc_dump on Linux and Mac OSX provided you know your PID of your ipod or standalone Kindle
|
||||||
|
(contributed by DiapDealer)
|
||||||
|
|
||||||
|
Changes in version 1.5
|
||||||
|
- completely reworked generation of styles to use actual page heights and widths
|
||||||
|
- added new script getpagedim.py to support the above
|
||||||
|
- style names with underscores in them are now properly paired with their base class
|
||||||
|
- fixed hanging indents that did not ever set a left margin
|
||||||
|
- added support for a number of not previously known region types
|
||||||
|
- added support for a previously unknown snippet - <empty></empty>
|
||||||
|
- corrected a bug that caused unknown regions to abort the program
|
||||||
|
- added code to make the handling of unknown regions better in general
|
||||||
|
- corrected a bug that caused the last link on a page to be missing (if it was the last thing on the page)
|
||||||
|
|
||||||
|
Changes in version 1.3
|
||||||
|
- font generation by gensvg.py is now greatly improved with support for contour points added
|
||||||
|
- support for more region types
|
||||||
|
- support for inline images in paragraphs or text fields (ie. initial graphics for the first letter of a word)
|
||||||
|
- greatly improved dtd information used for the xml to prevent parsing mistakes
|
||||||
|
|
||||||
|
Version 1.0
|
||||||
|
- initial release
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
#!/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 subasyncio
|
||||||
|
from subasyncio import Process
|
||||||
|
import Tkinter
|
||||||
|
import Tkconstants
|
||||||
|
import tkFileDialog
|
||||||
|
import tkMessageBox
|
||||||
|
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='Pml to HTML Conversion')
|
||||||
|
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 Pml input file').grid(row=0, sticky=Tkconstants.E)
|
||||||
|
self.pmlpath = Tkinter.Entry(body, width=50)
|
||||||
|
self.pmlpath.grid(row=0, column=1, sticky=sticky)
|
||||||
|
self.pmlpath.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_pmlpath)
|
||||||
|
button.grid(row=0, column=2)
|
||||||
|
|
||||||
|
Tkinter.Label(body, text='Name for HTML Output File').grid(row=1, sticky=Tkconstants.E)
|
||||||
|
self.outpath = Tkinter.Entry(body, width=50)
|
||||||
|
self.outpath.grid(row=1, column=1, sticky=sticky)
|
||||||
|
self.outpath.insert(0, '')
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_outpath)
|
||||||
|
button.grid(row=1, column=2)
|
||||||
|
|
||||||
|
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=2, 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 !='':
|
||||||
|
self.stext.insert(Tkconstants.END,msg)
|
||||||
|
self.stext.yview_pickplace(Tkconstants.END)
|
||||||
|
return
|
||||||
|
|
||||||
|
# run xpml2hxtml.py as a subprocess via pipes and collect stdout
|
||||||
|
def pmlhtml(self, infile, outfile):
|
||||||
|
# os.putenv('PYTHONUNBUFFERED', '1')
|
||||||
|
cmdline = 'python ./lib/xpml2xhtml.py "' + infile + '" "' + outfile + '"'
|
||||||
|
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\\xpml2xhtml.py "' + infile + '" "' + outfile + '"'
|
||||||
|
else :
|
||||||
|
cmdline = 'lib\\xpml2xhtml.py "' + infile + '" "' + outfile + '"'
|
||||||
|
|
||||||
|
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
|
||||||
|
return p2
|
||||||
|
|
||||||
|
|
||||||
|
def get_pmlpath(self):
|
||||||
|
pmlpath = tkFileDialog.askopenfilename(
|
||||||
|
parent=None, title='Select eBook Pml File',
|
||||||
|
defaultextension='.pml', filetypes=[('eBook Pml File', '.pml'),
|
||||||
|
('All Files', '.*')])
|
||||||
|
if pmlpath:
|
||||||
|
pmlpath = os.path.normpath(pmlpath)
|
||||||
|
self.pmlpath.delete(0, Tkconstants.END)
|
||||||
|
self.pmlpath.insert(0, pmlpath)
|
||||||
|
return
|
||||||
|
|
||||||
|
def get_outpath(self):
|
||||||
|
pmlpath = self.pmlpath.get()
|
||||||
|
initname = os.path.basename(pmlpath)
|
||||||
|
p = initname.find('.')
|
||||||
|
if p >= 0: initname = initname[0:p]
|
||||||
|
initname += '.html'
|
||||||
|
outpath = tkFileDialog.asksaveasfilename(
|
||||||
|
parent=None, title='Select HTML file to produce',
|
||||||
|
defaultextension='.html', initialfile=initname,
|
||||||
|
filetypes=[('HTML files', '.html'), ('All files', '.*')])
|
||||||
|
if outpath:
|
||||||
|
outpath = os.path.normpath(outpath)
|
||||||
|
self.outpath.delete(0, Tkconstants.END)
|
||||||
|
self.outpath.insert(0, outpath)
|
||||||
|
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')
|
||||||
|
pmlpath = self.pmlpath.get()
|
||||||
|
outpath = self.outpath.get()
|
||||||
|
if not pmlpath or not os.path.exists(pmlpath):
|
||||||
|
self.status['text'] = 'Specified eBook pml file does not exist'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
if not outpath:
|
||||||
|
self.status['text'] = 'No output file specified'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
|
||||||
|
log = 'Command = "python xpml2xhtml.py"\n'
|
||||||
|
log += 'PDB Path = "'+ pmlpath + '"\n'
|
||||||
|
log += 'HTML Output File = "' + outpath + '"\n'
|
||||||
|
log += '\n\n'
|
||||||
|
log += 'Please Wait ...\n\n'
|
||||||
|
self.stext.insert(Tkconstants.END,log)
|
||||||
|
self.p2 = self.pmlhtml(pmlpath, outpath)
|
||||||
|
|
||||||
|
# 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('eBook Pml to HTML 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())
|
|
@ -0,0 +1,200 @@
|
||||||
|
#!/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')
|
||||||
|
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)
|
||||||
|
self.pdbpath.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_pdbpath)
|
||||||
|
button.grid(row=0, column=2)
|
||||||
|
|
||||||
|
Tkinter.Label(body, text='Output Directory').grid(row=1, sticky=Tkconstants.E)
|
||||||
|
self.outpath = Tkinter.Entry(body, width=50)
|
||||||
|
self.outpath.grid(row=1, column=1, sticky=sticky)
|
||||||
|
self.outpath.insert(0, os.getcwd())
|
||||||
|
button = Tkinter.Button(body, text="...", command=self.get_outpath)
|
||||||
|
button.grid(row=1, column=2)
|
||||||
|
|
||||||
|
Tkinter.Label(body, text='Name on CC').grid(row=2, sticky=Tkconstants.E)
|
||||||
|
self.name = Tkinter.StringVar()
|
||||||
|
self.nameinfo = Tkinter.Entry(body, width=40, textvariable=self.name)
|
||||||
|
self.nameinfo.grid(row=2, column=1, sticky=sticky)
|
||||||
|
|
||||||
|
Tkinter.Label(body, text='Last 8 digits of CC Number').grid(row=3, sticky=Tkconstants.E)
|
||||||
|
self.ccnum = Tkinter.StringVar()
|
||||||
|
self.ccinfo = Tkinter.Entry(body, width=10, textvariable=self.ccnum)
|
||||||
|
self.ccinfo.grid(row=3, 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=4, 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 !='':
|
||||||
|
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, outdir, name, ccnum):
|
||||||
|
# os.putenv('PYTHONUNBUFFERED', '1')
|
||||||
|
cmdline = 'python ./lib/erdr2pml.py "' + infile + '" "' + outdir + '" "' + 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 "' + infile + '" "' + outdir + '" "' + name + '" ' + ccnum
|
||||||
|
else :
|
||||||
|
cmdline = 'lib\erdr2pml.py "' + infile + '" "' + outdir + '" "' + name + '" ' + ccnum
|
||||||
|
|
||||||
|
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 get_outpath(self):
|
||||||
|
outpath = tkFileDialog.askdirectory(
|
||||||
|
parent=None, title='Directory to Store Output into',
|
||||||
|
initialdir=os.getcwd(), initialfile=None)
|
||||||
|
if outpath:
|
||||||
|
outpath = os.path.normpath(outpath)
|
||||||
|
self.outpath.delete(0, Tkconstants.END)
|
||||||
|
self.outpath.insert(0, outpath)
|
||||||
|
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()
|
||||||
|
outpath = self.outpath.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
|
||||||
|
if not outpath:
|
||||||
|
self.status['text'] = 'No output directory specified'
|
||||||
|
self.sbotton.configure(state='normal')
|
||||||
|
return
|
||||||
|
if not os.path.exists(outpath):
|
||||||
|
os.makedirs(outpath)
|
||||||
|
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"\n'
|
||||||
|
log += 'PDB Path = "'+ pdbpath + '"\n'
|
||||||
|
log += 'Output Directory = "' + outpath + '"\n'
|
||||||
|
log += 'Name = "' + name + '"\n'
|
||||||
|
log += 'Last 8 of CC = "' + ccnum + '"\n'
|
||||||
|
log += '\n\n'
|
||||||
|
log += 'Please Wait ...\n'
|
||||||
|
self.stext.insert(Tkconstants.END,log)
|
||||||
|
self.p2 = self.erdr(pdbpath, outpath, 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 PML 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())
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
|
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
|
||||||
#
|
#
|
||||||
# eRdr2Pml.py
|
# erdr2pml.py
|
||||||
#
|
#
|
||||||
# This is a python script. You need a Python interpreter to run it.
|
# This is a python script. You need a Python interpreter to run it.
|
||||||
# For example, ActiveState Python, which exists for windows.
|
# For example, ActiveState Python, which exists for windows.
|
||||||
|
@ -50,9 +50,10 @@
|
||||||
# 0.09 - fixed typos in first_pages to first_page to again support older formats
|
# 0.09 - fixed typos in first_pages to first_page to again support older formats
|
||||||
# 0.10 - minor cleanups
|
# 0.10 - minor cleanups
|
||||||
# 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 - fixup for file name cleaning - no longer converts to lower case
|
# 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
|
||||||
|
|
||||||
__version__='0.12'
|
__version__='0.13'
|
||||||
|
|
||||||
# Import Psyco if available
|
# Import Psyco if available
|
||||||
try:
|
try:
|
||||||
|
@ -72,7 +73,20 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
import struct, binascii, zlib, os, sys, os.path, urllib
|
class Unbuffered:
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.stream = stream
|
||||||
|
def write(self, data):
|
||||||
|
self.stream.write(data)
|
||||||
|
self.stream.flush()
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.stdout=Unbuffered(sys.stdout)
|
||||||
|
|
||||||
|
import struct, binascii, zlib, os, os.path, urllib
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -85,7 +99,6 @@ import logging
|
||||||
logging.basicConfig()
|
logging.basicConfig()
|
||||||
#logging.basicConfig(level=logging.DEBUG)
|
#logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
|
|
||||||
ECB = 0
|
ECB = 0
|
||||||
CBC = 1
|
CBC = 1
|
||||||
class Des(object):
|
class Des(object):
|
||||||
|
@ -593,6 +606,7 @@ def main(argv=None):
|
||||||
print "Note:"
|
print "Note:"
|
||||||
print " if ommitted, outdir defaults based on 'infile.pdb'"
|
print " if ommitted, outdir defaults based on 'infile.pdb'"
|
||||||
print " It's enough to enter the last 8 digits of the credit card number"
|
print " It's enough to enter the last 8 digits of the credit card number"
|
||||||
|
return 1
|
||||||
else:
|
else:
|
||||||
if len(argv)==4:
|
if len(argv)==4:
|
||||||
infile, name, cc = argv[1], argv[2], argv[3]
|
infile, name, cc = argv[1], argv[2], argv[3]
|
||||||
|
@ -613,6 +627,8 @@ def main(argv=None):
|
||||||
print "done"
|
print "done"
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
print "Error: %s" % e
|
print "Error: %s" % e
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
#import cProfile
|
#import cProfile
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
|
||||||
|
|
||||||
|
import Tkinter
|
||||||
|
import Tkconstants
|
||||||
|
|
||||||
|
# basic scrolled text widget
|
||||||
|
class ScrolledText(Tkinter.Text):
|
||||||
|
def __init__(self, master=None, **kw):
|
||||||
|
self.frame = Tkinter.Frame(master)
|
||||||
|
self.vbar = Tkinter.Scrollbar(self.frame)
|
||||||
|
self.vbar.pack(side=Tkconstants.RIGHT, fill=Tkconstants.Y)
|
||||||
|
kw.update({'yscrollcommand': self.vbar.set})
|
||||||
|
Tkinter.Text.__init__(self, self.frame, **kw)
|
||||||
|
self.pack(side=Tkconstants.LEFT, fill=Tkconstants.BOTH, expand=True)
|
||||||
|
self.vbar['command'] = self.yview
|
||||||
|
# Copy geometry methods of self.frame without overriding Text
|
||||||
|
# methods = hack!
|
||||||
|
text_meths = vars(Tkinter.Text).keys()
|
||||||
|
methods = vars(Tkinter.Pack).keys() + vars(Tkinter.Grid).keys() + vars(Tkinter.Place).keys()
|
||||||
|
methods = set(methods).difference(text_meths)
|
||||||
|
for m in methods:
|
||||||
|
if m[0] != '_' and m != 'config' and m != 'configure':
|
||||||
|
setattr(self, m, getattr(self.frame, m))
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.frame)
|
|
@ -0,0 +1,149 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
|
||||||
|
|
||||||
|
import os, sys
|
||||||
|
import signal
|
||||||
|
import threading
|
||||||
|
import subprocess
|
||||||
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
|
# **heavily** chopped up and modfied version of asyncproc.py
|
||||||
|
# to make it actually work on Windows as well as Mac/Linux
|
||||||
|
# For the original see:
|
||||||
|
# "http://www.lysator.liu.se/~bellman/download/"
|
||||||
|
# author is "Thomas Bellman <bellman@lysator.liu.se>"
|
||||||
|
# available under GPL version 3 or Later
|
||||||
|
|
||||||
|
# create an asynchronous subprocess whose output can be collected in
|
||||||
|
# a non-blocking manner
|
||||||
|
|
||||||
|
# What a mess! Have to use threads just to get non-blocking io
|
||||||
|
# in a cross-platform manner
|
||||||
|
|
||||||
|
# luckily all thread use is hidden within this class
|
||||||
|
|
||||||
|
class Process(object):
|
||||||
|
def __init__(self, *params, **kwparams):
|
||||||
|
if len(params) <= 3:
|
||||||
|
kwparams.setdefault('stdin', subprocess.PIPE)
|
||||||
|
if len(params) <= 4:
|
||||||
|
kwparams.setdefault('stdout', subprocess.PIPE)
|
||||||
|
if len(params) <= 5:
|
||||||
|
kwparams.setdefault('stderr', subprocess.PIPE)
|
||||||
|
self.__pending_input = []
|
||||||
|
self.__collected_outdata = []
|
||||||
|
self.__collected_errdata = []
|
||||||
|
self.__exitstatus = None
|
||||||
|
self.__lock = threading.Lock()
|
||||||
|
self.__inputsem = threading.Semaphore(0)
|
||||||
|
self.__quit = False
|
||||||
|
|
||||||
|
self.__process = subprocess.Popen(*params, **kwparams)
|
||||||
|
|
||||||
|
if self.__process.stdin:
|
||||||
|
self.__stdin_thread = threading.Thread(
|
||||||
|
name="stdin-thread",
|
||||||
|
target=self.__feeder, args=(self.__pending_input,
|
||||||
|
self.__process.stdin))
|
||||||
|
self.__stdin_thread.setDaemon(True)
|
||||||
|
self.__stdin_thread.start()
|
||||||
|
|
||||||
|
if self.__process.stdout:
|
||||||
|
self.__stdout_thread = threading.Thread(
|
||||||
|
name="stdout-thread",
|
||||||
|
target=self.__reader, args=(self.__collected_outdata,
|
||||||
|
self.__process.stdout))
|
||||||
|
self.__stdout_thread.setDaemon(True)
|
||||||
|
self.__stdout_thread.start()
|
||||||
|
|
||||||
|
if self.__process.stderr:
|
||||||
|
self.__stderr_thread = threading.Thread(
|
||||||
|
name="stderr-thread",
|
||||||
|
target=self.__reader, args=(self.__collected_errdata,
|
||||||
|
self.__process.stderr))
|
||||||
|
self.__stderr_thread.setDaemon(True)
|
||||||
|
self.__stderr_thread.start()
|
||||||
|
|
||||||
|
def pid(self):
|
||||||
|
return self.__process.pid
|
||||||
|
|
||||||
|
def kill(self, signal):
|
||||||
|
self.__process.send_signal(signal)
|
||||||
|
|
||||||
|
# check on subprocess (pass in 'nowait') to act like poll
|
||||||
|
def wait(self, flag):
|
||||||
|
if flag.lower() == 'nowait':
|
||||||
|
rc = self.__process.poll()
|
||||||
|
else:
|
||||||
|
rc = self.__process.wait()
|
||||||
|
if rc != None:
|
||||||
|
if self.__process.stdin:
|
||||||
|
self.closeinput()
|
||||||
|
if self.__process.stdout:
|
||||||
|
self.__stdout_thread.join()
|
||||||
|
if self.__process.stderr:
|
||||||
|
self.__stderr_thread.join()
|
||||||
|
return self.__process.returncode
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
if self.__process.stdin:
|
||||||
|
self.closeinput()
|
||||||
|
self.__process.terminate()
|
||||||
|
|
||||||
|
# thread gets data from subprocess stdout
|
||||||
|
def __reader(self, collector, source):
|
||||||
|
while True:
|
||||||
|
data = os.read(source.fileno(), 65536)
|
||||||
|
self.__lock.acquire()
|
||||||
|
collector.append(data)
|
||||||
|
self.__lock.release()
|
||||||
|
if data == "":
|
||||||
|
source.close()
|
||||||
|
break
|
||||||
|
return
|
||||||
|
|
||||||
|
# thread feeds data to subprocess stdin
|
||||||
|
def __feeder(self, pending, drain):
|
||||||
|
while True:
|
||||||
|
self.__inputsem.acquire()
|
||||||
|
self.__lock.acquire()
|
||||||
|
if not pending and self.__quit:
|
||||||
|
drain.close()
|
||||||
|
self.__lock.release()
|
||||||
|
break
|
||||||
|
data = pending.pop(0)
|
||||||
|
self.__lock.release()
|
||||||
|
drain.write(data)
|
||||||
|
|
||||||
|
# non-blocking read of data from subprocess stdout
|
||||||
|
def read(self):
|
||||||
|
self.__lock.acquire()
|
||||||
|
outdata = "".join(self.__collected_outdata)
|
||||||
|
del self.__collected_outdata[:]
|
||||||
|
self.__lock.release()
|
||||||
|
return outdata
|
||||||
|
|
||||||
|
# non-blocking read of data from subprocess stderr
|
||||||
|
def readerr(self):
|
||||||
|
self.__lock.acquire()
|
||||||
|
errdata = "".join(self.__collected_errdata)
|
||||||
|
del self.__collected_errdata[:]
|
||||||
|
self.__lock.release()
|
||||||
|
return errdata
|
||||||
|
|
||||||
|
# non-blocking write to stdin of subprocess
|
||||||
|
def write(self, data):
|
||||||
|
if self.__process.stdin is None:
|
||||||
|
raise ValueError("Writing to process with stdin not a pipe")
|
||||||
|
self.__lock.acquire()
|
||||||
|
self.__pending_input.append(data)
|
||||||
|
self.__inputsem.release()
|
||||||
|
self.__lock.release()
|
||||||
|
|
||||||
|
# close stdinput of subprocess
|
||||||
|
def closeinput(self):
|
||||||
|
self.__lock.acquire()
|
||||||
|
self.__quit = True
|
||||||
|
self.__inputsem.release()
|
||||||
|
self.__lock.release()
|
||||||
|
|
|
@ -29,10 +29,23 @@
|
||||||
# 0.16 - use proper and safe temporary file when passing things to tidy
|
# 0.16 - use proper and safe temporary file when passing things to tidy
|
||||||
# 0.17 - add support for tidy.exe under windows
|
# 0.17 - add support for tidy.exe under windows
|
||||||
# 0.18 - fix corner case of lines that start with \axxx or \Uxxxx tags
|
# 0.18 - fix corner case of lines that start with \axxx or \Uxxxx tags
|
||||||
|
# 0.19 - change to use auto flushed stdout, and use proper return values
|
||||||
|
|
||||||
__version__='0.18'
|
__version__='0.19'
|
||||||
|
|
||||||
import struct, binascii, zlib, os, getopt, sys, os.path, urllib, re, tempfile
|
class Unbuffered:
|
||||||
|
def __init__(self, stream):
|
||||||
|
self.stream = stream
|
||||||
|
def write(self, data):
|
||||||
|
self.stream.write(data)
|
||||||
|
self.stream.flush()
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.stdout=Unbuffered(sys.stdout)
|
||||||
|
|
||||||
|
import struct, binascii, zlib, os, getopt, os.path, urllib, re, tempfile
|
||||||
import logging
|
import logging
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
|
@ -790,10 +803,10 @@ def main(argv=None):
|
||||||
except getopt.GetoptError, err:
|
except getopt.GetoptError, err:
|
||||||
print str(err)
|
print str(err)
|
||||||
usage()
|
usage()
|
||||||
return 2
|
return 1
|
||||||
if len(args) != 2:
|
if len(args) != 2:
|
||||||
usage()
|
usage()
|
||||||
return 2
|
return 1
|
||||||
sigil_breaks = False
|
sigil_breaks = False
|
||||||
use_tidy = False
|
use_tidy = False
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
|
@ -832,7 +845,7 @@ def main(argv=None):
|
||||||
print "Finished Processing"
|
print "Finished Processing"
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
print "Error: %s" % e
|
print "Error: %s" % e
|
||||||
return 2
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in New Issue