changed for android support - in progress

This commit is contained in:
Apprentice Harper
2015-03-24 07:04:06 +00:00
committed by Apprentice Alf
parent 4c9aacd01e
commit 0837482686
9 changed files with 918 additions and 92 deletions

View File

@@ -12,8 +12,9 @@
# 6.0.4 - Fix for other potential unicode problems
# 6.0.5 - Fix typo
# 6.2.0 - Update to match plugin and AppleScript
# 6.3.0 - Add in Android support
__version__ = '6.2.0'
__version__ = '6.3.0'
import sys
import os, os.path
@@ -158,83 +159,107 @@ class PrefsDialog(Toplevel):
body.pack(fill=Tkconstants.X, expand=1)
sticky = Tkconstants.E + Tkconstants.W
body.grid_columnconfigure(1, weight=2)
Tkinter.Label(body, text='Adobe Key file (adeptkey.der)').grid(row=0, sticky=Tkconstants.E)
cur_row = 0
Tkinter.Label(body, text='Adobe Key file (adeptkey.der)').grid(row=cur_row, sticky=Tkconstants.E)
self.adkpath = Tkinter.Entry(body, width=50)
self.adkpath.grid(row=0, column=1, sticky=sticky)
self.adkpath.grid(row=cur_row, column=1, sticky=sticky)
prefdir = self.prefs_array['dir']
keyfile = os.path.join(prefdir,'adeptkey.der')
if os.path.isfile(keyfile):
path = keyfile
self.adkpath.insert(0, path)
self.adkpath.insert(cur_row, path)
button = Tkinter.Button(body, text="...", command=self.get_adkpath)
button.grid(row=0, column=2)
button.grid(row=cur_row, column=2)
Tkinter.Label(body, text='Kindle Key file (kindlekey.k4i)').grid(row=1, sticky=Tkconstants.E)
cur_row = cur_row + 1
Tkinter.Label(body, text='Kindle Key file (kindlekey.k4i)').grid(row=cur_row, sticky=Tkconstants.E)
self.kkpath = Tkinter.Entry(body, width=50)
self.kkpath.grid(row=1, column=1, sticky=sticky)
self.kkpath.grid(row=cur_row, column=1, sticky=sticky)
prefdir = self.prefs_array['dir']
keyfile = os.path.join(prefdir,'kindlekey.k4i')
if os.path.isfile(keyfile):
path = keyfile
self.kkpath.insert(1, path)
self.kkpath.insert(0, path)
button = Tkinter.Button(body, text="...", command=self.get_kkpath)
button.grid(row=1, column=2)
button.grid(row=cur_row, column=2)
Tkinter.Label(body, text='Barnes and Noble Key file (bnepubkey.b64)').grid(row=2, sticky=Tkconstants.E)
cur_row = cur_row + 1
Tkinter.Label(body, text='Android Kindle Key file (kindlekey.k4a)').grid(row=cur_row, sticky=Tkconstants.E)
self.akkpath = Tkinter.Entry(body, width=50)
self.akkpath.grid(row=cur_row, column=1, sticky=sticky)
prefdir = self.prefs_array['dir']
keyfile = os.path.join(prefdir,'kindlekey.k4a')
if os.path.isfile(keyfile):
path = keyfile
self.akkpath.insert(0, path)
button = Tkinter.Button(body, text="...", command=self.get_akkpath)
button.grid(row=cur_row, column=2)
cur_row = cur_row + 1
Tkinter.Label(body, text='Barnes and Noble Key file (bnepubkey.b64)').grid(row=cur_row, sticky=Tkconstants.E)
self.bnkpath = Tkinter.Entry(body, width=50)
self.bnkpath.grid(row=2, column=1, sticky=sticky)
self.bnkpath.grid(row=cur_row, column=1, sticky=sticky)
prefdir = self.prefs_array['dir']
keyfile = os.path.join(prefdir,'bnepubkey.b64')
if os.path.isfile(keyfile):
path = keyfile
self.bnkpath.insert(2, path)
self.bnkpath.insert(0, path)
button = Tkinter.Button(body, text="...", command=self.get_bnkpath)
button.grid(row=2, column=2)
button.grid(row=cur_row, column=2)
Tkinter.Label(body, text='Mobipocket PID list\n(8 or 10 characters, comma separated)').grid(row=3, sticky=Tkconstants.E)
cur_row = cur_row + 1
Tkinter.Label(body, text='Mobipocket PID list\n(8 or 10 characters, comma separated)').grid(row=cur_row, sticky=Tkconstants.E)
self.pidnums = Tkinter.StringVar()
self.pidinfo = Tkinter.Entry(body, width=50, textvariable=self.pidnums)
if 'pids' in self.prefs_array:
self.pidnums.set(self.prefs_array['pids'])
self.pidinfo.grid(row=3, column=1, sticky=sticky)
self.pidinfo.grid(row=cur_row, column=1, sticky=sticky)
Tkinter.Label(body, text='eInk Kindle Serial Number list\n(16 characters, comma separated)').grid(row=4, sticky=Tkconstants.E)
cur_row = cur_row + 1
Tkinter.Label(body, text='eInk Kindle Serial Number list\n(16 characters, comma separated)').grid(row=cur_row, sticky=Tkconstants.E)
self.sernums = Tkinter.StringVar()
self.serinfo = Tkinter.Entry(body, width=50, textvariable=self.sernums)
if 'serials' in self.prefs_array:
self.sernums.set(self.prefs_array['serials'])
self.serinfo.grid(row=4, column=1, sticky=sticky)
self.serinfo.grid(row=cur_row, column=1, sticky=sticky)
Tkinter.Label(body, text='eReader data list\n(name:last 8 digits on credit card, comma separated)').grid(row=5, sticky=Tkconstants.E)
cur_row = cur_row + 1
Tkinter.Label(body, text='eReader data list\n(name:last 8 digits on credit card, comma separated)').grid(row=cur_row, sticky=Tkconstants.E)
self.sdrmnums = Tkinter.StringVar()
self.sdrminfo = Tkinter.Entry(body, width=50, textvariable=self.sdrmnums)
if 'sdrms' in self.prefs_array:
self.sdrmnums.set(self.prefs_array['sdrms'])
self.sdrminfo.grid(row=5, column=1, sticky=sticky)
self.sdrminfo.grid(row=cur_row, column=1, sticky=sticky)
Tkinter.Label(body, text="Output Folder (if blank, use input ebook's folder)").grid(row=6, sticky=Tkconstants.E)
cur_row = cur_row + 1
Tkinter.Label(body, text="Output Folder (if blank, use input ebook's folder)").grid(row=cur_row, sticky=Tkconstants.E)
self.outpath = Tkinter.Entry(body, width=50)
self.outpath.grid(row=6, column=1, sticky=sticky)
self.outpath.grid(row=cur_row, column=1, sticky=sticky)
if 'outdir' in self.prefs_array:
dpath = self.prefs_array['outdir']
self.outpath.insert(0, dpath)
button = Tkinter.Button(body, text="...", command=self.get_outpath)
button.grid(row=6, column=2)
button.grid(row=cur_row, column=2)
Tkinter.Label(body, text='').grid(row=7, column=0, columnspan=2, sticky=Tkconstants.N)
cur_row = cur_row + 1
Tkinter.Label(body, text='').grid(row=cur_row, column=0, columnspan=2, sticky=Tkconstants.N)
Tkinter.Label(body, text='Alternatively Process an eBook').grid(row=8, column=0, columnspan=2, sticky=Tkconstants.N)
cur_row = cur_row + 1
Tkinter.Label(body, text='Alternatively Process an eBook').grid(row=cur_row, column=0, columnspan=2, sticky=Tkconstants.N)
Tkinter.Label(body, text='Select an eBook to Process*').grid(row=9, sticky=Tkconstants.E)
cur_row = cur_row + 1
Tkinter.Label(body, text='Select an eBook to Process*').grid(row=cur_row, sticky=Tkconstants.E)
self.bookpath = Tkinter.Entry(body, width=50)
self.bookpath.grid(row=9, column=1, sticky=sticky)
self.bookpath.grid(row=cur_row, column=1, sticky=sticky)
button = Tkinter.Button(body, text="...", command=self.get_bookpath)
button.grid(row=9, column=2)
button.grid(row=cur_row, column=2)
Tkinter.Label(body, font=("Helvetica", "10", "italic"), text='*To DeDRM multiple ebooks simultaneously, set your preferences and quit.\nThen drag and drop ebooks or folders onto the DeDRM_Drop_Target').grid(row=10, column=1, sticky=Tkconstants.E)
cur_row = cur_row + 1
Tkinter.Label(body, font=("Helvetica", "10", "italic"), text='*To DeDRM multiple ebooks simultaneously, set your preferences and quit.\nThen drag and drop ebooks or folders onto the DeDRM_Drop_Target').grid(row=cur_row, column=1, sticky=Tkconstants.E)
Tkinter.Label(body, text='').grid(row=11, column=0, columnspan=2, sticky=Tkconstants.E)
cur_row = cur_row + 1
Tkinter.Label(body, text='').grid(row=cur_row, column=0, columnspan=2, sticky=Tkconstants.E)
buttons = Tkinter.Frame(self)
buttons.pack()
@@ -304,6 +329,24 @@ class PrefsDialog(Toplevel):
self.kkpath.insert(0, kkpath)
return
def get_akkpath(self):
akkbpath = tkFileDialog.askopenfilename(parent=None, title='Select Android for Kindle backup file',
defaultextension='.ab', filetypes=[('Kindle for Android backup file', '.ab'), ('All Files', '.*')])
if akkbpath:
# call androidkindlekey here
prefdir = self.prefs_array['dir']
androidkindlekeyfile = os.path.join(prefdir,'kindlekey.k4a')
import androidkindlekey
try:
androidkindlekey.getkey(androidkindlekeyfile, akkbpath)
except:
traceback.print_exc()
pass
if os.path.isfile(androidkindlekeyfile):
self.akkpath.delete(0, Tkconstants.END)
self.akkpath.insert(0, androidkindlekeyfile)
return
def get_bnkpath(self):
cpath = self.bnkpath.get()
bnkpath = tkFileDialog.askopenfilename(initialdir = cpath, parent=None, title='Select Barnes and Noble Key file',

View File

@@ -5,7 +5,7 @@ from __future__ import with_statement
# androidkindlekey.py
# Copyright © 2013-15 by Thom
# Some portions Copyright © 2011-15 by Apprentice Alf and Apprentice Harper
# Some portions Copyright © 2010-15 by some_updates, Apprentice Alf and Apprentice Harper
#
# Revision history:
@@ -14,14 +14,14 @@ from __future__ import with_statement
# 1.2 - Changed to be callable from AppleScript by returning only serial number
# - and changed name to androidkindlekey.py
# - and added in unicode command line support
# 1.3 - added in TkInter interface, output to a file and attempt to get backup from a connected android device.
"""
Retrieve Kindle for Android Serial Number.
"""
__license__ = 'GPL v3'
__version__ = '1.2'
__version__ = '1.3'
import os
import sys
@@ -272,7 +272,32 @@ def get_serials(path=STORAGE):
return serials
__all__ = [ 'get_serials' ]
__all__ = [ 'get_serials', 'getkey']
# interface for Python DeDRM
# returns single key or multiple keys, depending on path or file passed in
def getkey(outpath, inpath):
keys = get_serials(inpath)
if len(keys) > 0:
if not os.path.isdir(outpath):
outfile = outpath
with file(outfile, 'w') as keyfileout:
keyfileout.write(keys[0])
print u"Saved a key to {0}".format(outfile)
else:
keycount = 0
for key in keys:
while True:
keycount += 1
outfile = os.path.join(outpath,u"kindlekey{0:d}.k4a".format(keycount))
if not os.path.exists(outfile):
break
with file(outfile, 'w') as keyfileout:
keyfileout.write(key)
print u"Saved a key to {0}".format(outfile)
return True
return False
def usage(progname):
print u"{0} v{1}\nCopyright © 2013-2015 Thom and Apprentice Harper".format(progname,__version__)
@@ -283,7 +308,7 @@ def usage(progname):
print u""
print u"Serial number is written to standard output."
print u"Usage:"
print u" {0:s} [-h] <inputfile>".format(progname)
print u" {0:s} [-h] [-b <backup.ab>] [<outpath>]".format(progname)
def cli_main():
@@ -291,47 +316,131 @@ def cli_main():
sys.stderr=SafeUnbuffered(sys.stderr)
argv=unicode_argv()
progname = os.path.basename(argv[0])
print u"{0} v{1}\nCopyright © 2010-2015 Thom, some_updates, Apprentice Alf and Apprentice Harper".format(progname,__version__)
try:
opts, args = getopt.getopt(argv[1:], "h")
opts, args = getopt.getopt(argv[1:], "hb:")
except getopt.GetoptError, err:
usage(progname)
print u"\nError in options or arguments: {0}".format(err.args[0])
return 2
files = []
inpath = ""
for o, a in opts:
if o == "-h":
usage(progname)
return 0
if o == "-b":
inpath = a
if len(args) > 1:
usage(progname)
return 2
inpath = args[0]
if not os.path.isabs(inpath):
inpath = os.path.abspath(inpath)
if len(args) == 1:
# save to the specified file or directory
outpath = args[0]
if not os.path.isabs(outpath):
outpath = os.path.join(os.path.dirname(argv[0]),outpath)
outpath = os.path.abspath(outpath)
else:
# save to the same directory as the script
outpath = os.path.dirname(argv[0])
inpath = os.path.realpath(os.path.normpath(inpath))
# make sure the outpath is OK
outpath = os.path.realpath(os.path.normpath(outpath))
if not os.path.isfile(inpath):
usage(progname)
print u"\n{0:s} file not found".format(inpath)
return 2
serials = get_serials(inpath)
if not getkey(outpath, inpath):
print u"Could not retrieve Kindle for Android key."
return 0
if len(serials) == 0:
print u"No keys found in {0:s}".format(inpath)
return 2
for serial in serials:
print serial
def gui_main():
try:
import Tkinter
import Tkconstants
import tkMessageBox
import tkFileDialog
import traceback
except:
print "Tkinter not installed"
return cli_main()
class DecryptionDialog(Tkinter.Frame):
def __init__(self, root):
Tkinter.Frame.__init__(self, root, border=5)
self.status = Tkinter.Label(self, text=u"Select backup.ab file")
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=u"Backup file").grid(row=0, column=0)
self.keypath = Tkinter.Entry(body, width=40)
self.keypath.grid(row=0, column=1, sticky=sticky)
self.keypath.insert(2, u"backup.ab")
button = Tkinter.Button(body, text=u"...", command=self.get_keypath)
button.grid(row=0, column=2)
buttons = Tkinter.Frame(self)
buttons.pack()
button2 = Tkinter.Button(
buttons, text=u"Extract", width=10, command=self.generate)
button2.pack(side=Tkconstants.LEFT)
Tkinter.Frame(buttons, width=10).pack(side=Tkconstants.LEFT)
button3 = Tkinter.Button(
buttons, text=u"Quit", width=10, command=self.quit)
button3.pack(side=Tkconstants.RIGHT)
def get_keypath(self):
keypath = tkFileDialog.askopenfilename(
parent=None, title=u"Select backup.ab file",
defaultextension=u".ab",
filetypes=[('adb backup com.amazon.kindle', '.ab'),
('All Files', '.*')])
if keypath:
keypath = os.path.normpath(keypath)
self.keypath.delete(0, Tkconstants.END)
self.keypath.insert(0, keypath)
return
def generate(self):
inpath = self.keypath.get()
self.status['text'] = u"Getting key..."
try:
keys = get_serials(inpath)
keycount = 0
for key in keys:
while True:
keycount += 1
outfile = os.path.join(progpath,u"kindlekey{0:d}.k4a".format(keycount))
if not os.path.exists(outfile):
break
with file(outfile, 'w') as keyfileout:
keyfileout.write(key)
success = True
tkMessageBox.showinfo(progname, u"Key successfully retrieved to {0}".format(outfile))
except Exception, e:
self.status['text'] = u"Error: {0}".format(e.args[0])
return
self.status['text'] = u"Select backup.ab file"
argv=unicode_argv()
progpath, progname = os.path.split(argv[0])
root = Tkinter.Tk()
root.title(u"Kindle for Android Key Extraction v.{0}".format(__version__))
root.resizable(True, False)
root.minsize(300, 0)
DecryptionDialog(root).pack(fill=Tkconstants.X, expand=1)
root.mainloop()
return 0
if __name__ == '__main__':
if len(sys.argv) > 1:
sys.exit(cli_main())
usage(os.path.basename(unicode_argv()[0]))
sys.exit(0);
sys.exit(gui_main())

View File

@@ -158,6 +158,14 @@ def decryptk4mobi(infile, outdir, rscpath):
serialstr = serialstr.strip()
if serialstr != '':
serialnums = serialstr.split(',')
files = os.listdir(rscpath)
filefilter = re.compile("\.k4a$", re.IGNORECASE)
files = filter(filefilter.search, files)
if files:
for filename in files:
dpath = os.path.join(rscpath,filename)
androidserial = open(keypath,'r').read()
serialnums.append(androidserial)
kDatabaseFiles = []
files = os.listdir(rscpath)
filefilter = re.compile("\.k4i$", re.IGNORECASE)