summaryrefslogtreecommitdiffstats
path: root/DeDRM_calibre_plugin
diff options
context:
space:
mode:
authorApprentice Harper <[email protected]>2015-03-24 07:04:06 +0000
committerApprentice Alf <[email protected]>2015-03-24 07:04:06 +0000
commit08374826868dc30147a653fe414d866400dd5910 (patch)
tree2eaedb5af9d6c120949d7a24d623acc08489fde4 /DeDRM_calibre_plugin
parent4c9aacd01ec517e4236b48a476eea03c6034de08 (diff)
changed for android support - in progress
Diffstat (limited to 'DeDRM_calibre_plugin')
-rw-r--r--DeDRM_calibre_plugin/DeDRM_plugin/androidkindlekey.py147
-rw-r--r--DeDRM_calibre_plugin/DeDRM_plugin/config.py11
2 files changed, 134 insertions, 24 deletions
diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/androidkindlekey.py b/DeDRM_calibre_plugin/DeDRM_plugin/androidkindlekey.py
index fd4c193..6e6aef7 100644
--- a/DeDRM_calibre_plugin/DeDRM_plugin/androidkindlekey.py
+++ b/DeDRM_calibre_plugin/DeDRM_plugin/androidkindlekey.py
@@ -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())
diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/config.py b/DeDRM_calibre_plugin/DeDRM_plugin/config.py
index 1357b49..d474257 100644
--- a/DeDRM_calibre_plugin/DeDRM_plugin/config.py
+++ b/DeDRM_calibre_plugin/DeDRM_plugin/config.py
@@ -109,14 +109,15 @@ class ConfigWidget(QWidget):
self.ereader_button.setToolTip(_(u"Click to manage keys for eReader ebooks"))
self.ereader_button.setText(u"eReader ebooks")
self.ereader_button.clicked.connect(self.ereader_keys)
+
+ button_layout.addWidget(self.adept_button)
+ button_layout.addWidget(self.kindle_key_button)
button_layout.addWidget(self.kindle_serial_button)
button_layout.addWidget(self.kindle_android_button)
button_layout.addWidget(self.bandn_button)
button_layout.addWidget(self.mobi_button)
button_layout.addWidget(self.ereader_button)
- button_layout.addWidget(self.adept_button)
- button_layout.addWidget(self.kindle_key_button)
-
+
self.resize(self.sizeHint())
def kindle_serials(self):
@@ -124,7 +125,7 @@ class ConfigWidget(QWidget):
d.exec_()
def kindle_android_serials(self):
- d = ManageKeysDialog(self,u"Kindle for Andoid Serial Number",self.tempdedrmprefs['androidserials'], AddAndroidSerialDialog, 'ab')
+ d = ManageKeysDialog(self,u"Kindle for Andoid",self.tempdedrmprefs['androidserials'], AddAndroidSerialDialog, 'ab')
d.exec_()
def kindle_keys(self):
@@ -904,7 +905,7 @@ class AddAndroidSerialDialog(QDialog):
data_group_box_layout.addLayout(key_group)
key_group.addWidget(QLabel(u"Kindle for Android Serial Number:", self))
self.key_ledit = QLineEdit("", self)
- self.key_ledit.setToolTip(u"Enter a Kindle for ANdroid serial number. These can be found using the androidkindlekey.py script.")
+ self.key_ledit.setToolTip(u"Enter a Kindle for Android serial number. These can be found using the androidkindlekey.py script.")
key_group.addWidget(self.key_ledit)
key_label = QLabel(_(''), self)
key_label.setAlignment(Qt.AlignHCenter)