tools v2.0

Most tools now have plugins
This commit is contained in:
Apprentice Alf
2010-10-18 21:06:58 +01:00
parent d427f758f6
commit bf03edd18c
96 changed files with 7081 additions and 82 deletions

View File

@@ -0,0 +1,38 @@
The Topaz Tools only work for "Kindle for PC" books, and original standalone Kindles that have never been updated to firmware 2.5 or later, Kindle for iPhone/iPad/iPodTouch (where the PID is known) and Kindle for Mac (with the PID provided by the Kindle_4_Mac_Tools).
For Topaz:
1. Make sure you have Python 2.X installed (32 bit) and properly set as part of your SYSTEM PATH environment variable (On Windows I recommend ActivePython. See their web pages for instructions on how to install and how to properly set your PATH). On Mac OSX 10.6 everything you need is already installed.
2. Simply download the latest tools_vX.X.zip file (see the comments after the first post on this blog) and extract the entire archive. Do not move or rename anything after extracting the entire archive.
3. move to tools\Topaz_Tools\
4. If you have an old Kindle (never updated to 2.5 or later) or an iPod, iPhone, or iPad or Kindle for Mac and you know your PID then double-click on the following:
TopazExtract_iPhone_iPad_K4M.pyw
If you have Kindle for PC (and no Kindle for Mac will NOT work here) then instead double-click on the following:
TopazExtract_Kindle4PC.pyw
Hit the first “…” button to select the Topaz book with DRM that you want to convert
Hit the second “…” to select an entirely new directory to extract the many book pieces into
And add info for your PID (or extra PIDs) if needed (should not be needed for Kindle For PC).
Hit the Start button
3. Next double-click on TopazFiles2SVG.pyw
(use the “…” button to select the new directory you created from the previous step, and hit Start)
4. Finally double-click on TopazFiles2HTML.pyw
(use the “…” button to slect the new directory you created in step 2, and hit Start)
5. After all of this you should have book.html inside the directory you created with its own image directory and css style sheet. This file is created from the ocr that is done by Amazon and stored in the Topaz file. All errors belong to Amazon.
Inside of that same directory, you should have an svg directory which has an exact image of each page of the book. To see it, simply open the .xhtml page which has the embedded svg image in a good browser (Firefox, Safari, etc)
If you run into any problems and there can be problems because the format has not been completely reversed engineered, simply copy the entire contents of the Conversion Log window and paste them in a post here or on the Dark Reversers New Blog and I will find it and try to help

View File

@@ -1,200 +0,0 @@
#!/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)
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.tpzpath.insert(0, cwd)
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)
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
self.outpath.insert(0, cwd)
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 !='':
msg = msg.encode('utf-8')
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 + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
return p2
def get_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):
cwd = os.getcwdu()
cwd = cwd.encode('utf-8')
outpath = tkFileDialog.askdirectory(
parent=None, title='Directory to Extract Files into',
initialdir=cwd, 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'
log = log.encode('utf-8')
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())

View File

@@ -654,12 +654,15 @@ def createDecryptedPayload(payload):
if name != "dkey" :
ext = '.dat'
if name == 'img' : ext = '.jpg'
if name == 'color' : ext = '.jpg'
for index in range (0,len(bookHeaderRecords[name])) :
fnum = "%04d" % index
fname = name + fnum + ext
destdir = payload
if name == 'img':
destdir = os.path.join(payload,'img')
if name == 'color':
destdir = os.path.join(payload,'color_img')
if name == 'page':
destdir = os.path.join(payload,'page')
if name == 'glyphs':
@@ -679,6 +682,10 @@ def createDecryptedBook(outdir):
if not os.path.exists(destdir):
os.makedirs(destdir)
destdir = os.path.join(outdir,'color_img')
if not os.path.exists(destdir):
os.makedirs(destdir)
destdir = os.path.join(outdir,'page')
if not os.path.exists(destdir):
os.makedirs(destdir)

View File

@@ -360,12 +360,15 @@ def createDecryptedPayload(payload):
if name != "dkey" :
ext = '.dat'
if name == 'img' : ext = '.jpg'
if name == 'color' : ext = '.jpg'
for index in range (0,len(bookHeaderRecords[name])) :
fnum = "%04d" % index
fname = name + fnum + ext
destdir = payload
if name == 'img':
destdir = os.path.join(payload,'img')
if name == 'color':
destdir = os.path.join(payload,'color_img')
if name == 'page':
destdir = os.path.join(payload,'page')
if name == 'glyphs':
@@ -385,6 +388,10 @@ def createDecryptedBook(outdir):
if not os.path.exists(destdir):
os.makedirs(destdir)
destdir = os.path.join(outdir,'color_img')
if not os.path.exists(destdir):
os.makedirs(destdir)
destdir = os.path.join(outdir,'page')
if not os.path.exists(destdir):
os.makedirs(destdir)