summaryrefslogtreecommitdiffstats
path: root/DeDRM_Windows_Application
diff options
context:
space:
mode:
authorApprentice Harper <[email protected]>2015-03-18 20:37:54 +0000
committerApprentice Alf <[email protected]>2015-03-18 20:37:54 +0000
commit4c9aacd01ec517e4236b48a476eea03c6034de08 (patch)
treead93a699cb8ae857446627fe649db86b76c49968 /DeDRM_Windows_Application
parent6b2672ff7ce2693634009b9377dcf3c4c5e177f8 (diff)
Added help file for Kindle for Android keys to plugin. Copied updated files to Mac and Windows applications.
Diffstat (limited to 'DeDRM_Windows_Application')
-rw-r--r--DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_EInk Kindle Serial Number_Help.htm4
-rw-r--r--DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Kindle for Android_Help.htm52
-rw-r--r--DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py4
-rw-r--r--DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/androidkindlekey.py4
-rw-r--r--DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/config.py121
-rw-r--r--DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/prefs.py3
6 files changed, 157 insertions, 31 deletions
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_EInk Kindle Serial Number_Help.htm b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_EInk Kindle Serial Number_Help.htm
index e79abd7..5a4692d 100644
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_EInk Kindle Serial Number_Help.htm
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_EInk Kindle Serial Number_Help.htm
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
@@ -27,7 +27,7 @@ li {margin-top: 0.5em}
<p>On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog for entering a new Kindle serial number.</p>
<ul>
-<li><span class="bold">Eink Kindle Serial Number:</span> this is the unique serial number of your device. It usually starts with a ‘B’ or a ‘9’ and is sixteen characters long. For a reference of where to find serial numbers and their ranges, please refere to this <a href="http://wiki.mobileread.com/wiki/Kindle_serial_numbers">mobileread wiki page.</a></li>
+<li><span class="bold">Eink Kindle Serial Number:</span> this is the unique serial number of your device. It usually starts with a ‘B’ or a ‘9’ and is sixteen characters long. For a reference of where to find serial numbers and their ranges, please refer to this <a href="http://wiki.mobileread.com/wiki/Kindle_serial_numbers">mobileread wiki page.</a></li>
</ul>
<p>Click the OK button to save the serial number. Or Cancel if you didn’t want to enter a serial number.</p>
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Kindle for Android_Help.htm b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Kindle for Android_Help.htm
new file mode 100644
index 0000000..7bdba64
--- /dev/null
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Kindle for Android_Help.htm
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8">
+<title>Managing Kindle for Android serial numbers</title>
+<style type="text/css">
+span.version {font-size: 50%}
+span.bold {font-weight: bold}
+h3 {margin-bottom: 0}
+p {margin-top: 0}
+li {margin-top: 0.5em}
+</style>
+</head>
+
+<body>
+
+<h1>Managing Kindle for Android serial numbers</h1>
+
+<p>Amazon's Kindle for Android application uses an internal serial number that's 72 character long. Extracting that serial number is a little tricky, but worth it, as it then allows the DRM to be removed from any Kindle ebooks that have been downloaded to that Android device.</p>
+
+<p>Please note that it is not currently known whether the same applies to the Kindle application on the Kindle Fire and Fire HD.</p>
+
+<h3>Getting the Kindle for Android backup file</h3>
+
+<p>Obtain and install adb (Android Debug Bridge) on your computer. Details of how to do this are beyond the scope of this help file, but there are plenty of on-line guides.</p>
+<p>Enable developer mode on your Android device. Again, look for an on-line guide for your device.</p>
+<p>Once you have adb installed and your device in developer mode, connect your device to your computer with a USB cable and then open up a command line (Terminal on Mac OS X and cmd.exe on Windows) and enter "adb backup com.amazon.kindle" (without the quotation marks!) and press return. A file "backup.ab" should be created in your home directory.
+
+<h3>Adding the Kindle for Android serial number</h3>
+
+<p>At the bottom-left of the plugin’s customization dialog, you will see a button labeled "Import Existing Keyfiles". Use this button to import the ‘backup.ab’ file you obtained by using the adb command. The backup file will be processed to extract any serial numbers in it, and the numbers will be added to the list.</p>
+
+<h3>Adding the Kindle for Android serial number manually</h3>
+<p>On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog for entering a new Kindle for Android serial number.</p>
+<ul>
+<li><span class="bold">Kindle for Android Serial Number:</span> this is the unique serial number of your device. You may have obtained this through using the old android.py script.</li>
+</ul>
+
+<p>Click the OK button to save the serial number. Or Cancel if you didn’t want to enter a serial number.</p>
+
+<h3>Deleting Kindle for Android serial numbers:</h3>
+
+<p>On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted Kindle serial number from the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.</p>
+
+<p>Once done creating/deleting serial numbers, click Close to exit the customization dialogue. Your changes wil only be saved permanently when you click OK in the main configuration dialog.</p>
+
+</body>
+
+</html>
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py
index 37c454c..ef1e1b4 100644
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py
@@ -39,13 +39,14 @@ __docformat__ = 'restructuredtext en'
# 6.1.0 - Fixed multiple books import problem and PDF import with no key problem
# 6.2.0 - Support for getting B&N key from nook Study log. Fix for UTF-8 filenames in Adobe ePubs.
# Fix for not copying needed files. Fix for getting default Adobe key for PDFs
+# 6.3.0 - Added in Kindle for Android serial number solution
"""
Decrypt DRMed ebooks.
"""
PLUGIN_NAME = u"DeDRM"
-PLUGIN_VERSION_TUPLE = (6, 2, 0)
+PLUGIN_VERSION_TUPLE = (6, 3, 0)
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
# Include an html helpfile in the plugin's zipfile with the following name.
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
@@ -478,6 +479,7 @@ class DeDRM(FileTypePlugin):
dedrmprefs = prefs.DeDRM_Prefs()
pids = dedrmprefs['pids']
serials = dedrmprefs['serials']
+ serials.extend(dedrmprefs['androidserials'])
kindleDatabases = dedrmprefs['kindlekeys'].items()
try:
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/androidkindlekey.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/androidkindlekey.py
index d5cb01a..fd4c193 100644
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/androidkindlekey.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/androidkindlekey.py
@@ -256,14 +256,14 @@ def get_serials(path=STORAGE):
tar = tarfile.open(fileobj=output)
for member in tar.getmembers():
if member.name.strip().endswith(STORAGE1):
- write = tempfile.NamedTemporaryFile(mode='w', delete=False)
+ write = tempfile.NamedTemporaryFile(mode='wb', delete=False)
write.write(tar.extractfile(member).read())
write.close()
write_path = os.path.abspath(write.name)
serials.extend(get_serials1(write_path))
os.remove(write_path)
elif member.name.strip().endswith(STORAGE2):
- write = tempfile.NamedTemporaryFile(mode='w', delete=False)
+ write = tempfile.NamedTemporaryFile(mode='wb', delete=False)
write.write(tar.extractfile(member).read())
write.close()
write_path = os.path.abspath(write.name)
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/config.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/config.py
index b5c5300..1357b49 100644
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/config.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/config.py
@@ -34,6 +34,7 @@ from calibre.constants import iswindows, isosx
from calibre_plugins.dedrm.__init__ import PLUGIN_NAME, PLUGIN_VERSION
from calibre_plugins.dedrm.__init__ import RESOURCE_NAME as help_file_name
from calibre_plugins.dedrm.utilities import uStrCmp
+from calibre_plugins.dedrm.androidkindlekey import get_serials
import calibre_plugins.dedrm.prefs as prefs
@@ -55,6 +56,7 @@ class ConfigWidget(QWidget):
self.tempdedrmprefs['kindlekeys'] = self.dedrmprefs['kindlekeys'].copy()
self.tempdedrmprefs['pids'] = list(self.dedrmprefs['pids'])
self.tempdedrmprefs['serials'] = list(self.dedrmprefs['serials'])
+ self.tempdedrmprefs['androidserials'] = list(self.dedrmprefs['androidserials'])
self.tempdedrmprefs['adobewineprefix'] = self.dedrmprefs['adobewineprefix']
self.tempdedrmprefs['kindlewineprefix'] = self.dedrmprefs['kindlewineprefix']
@@ -83,6 +85,10 @@ class ConfigWidget(QWidget):
self.bandn_button.setToolTip(_(u"Click to manage keys for Barnes and Noble ebooks"))
self.bandn_button.setText(u"Barnes and Noble ebooks")
self.bandn_button.clicked.connect(self.bandn_keys)
+ self.kindle_android_button = QtGui.QPushButton(self)
+ self.kindle_android_button.setToolTip(_(u"Click to manage Kindle for Android serial numbers for Kindle ebooks"))
+ self.kindle_android_button.setText(u"Kindle for Android ebooks")
+ self.kindle_android_button.clicked.connect(self.kindle_android_serials)
self.kindle_serial_button = QtGui.QPushButton(self)
self.kindle_serial_button.setToolTip(_(u"Click to manage eInk Kindle serial numbers for Kindle ebooks"))
self.kindle_serial_button.setText(u"eInk Kindle ebooks")
@@ -104,6 +110,7 @@ class ConfigWidget(QWidget):
self.ereader_button.setText(u"eReader ebooks")
self.ereader_button.clicked.connect(self.ereader_keys)
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)
@@ -115,6 +122,10 @@ class ConfigWidget(QWidget):
def kindle_serials(self):
d = ManageKeysDialog(self,u"EInk Kindle Serial Number",self.tempdedrmprefs['serials'], AddSerialDialog)
d.exec_()
+
+ def kindle_android_serials(self):
+ d = ManageKeysDialog(self,u"Kindle for Andoid Serial Number",self.tempdedrmprefs['androidserials'], AddAndroidSerialDialog, 'ab')
+ d.exec_()
def kindle_keys(self):
if isosx or iswindows:
@@ -164,6 +175,7 @@ class ConfigWidget(QWidget):
self.dedrmprefs.set('kindlekeys', self.tempdedrmprefs['kindlekeys'])
self.dedrmprefs.set('pids', self.tempdedrmprefs['pids'])
self.dedrmprefs.set('serials', self.tempdedrmprefs['serials'])
+ self.dedrmprefs.set('androidserials', self.tempdedrmprefs['androidserials'])
self.dedrmprefs.set('adobewineprefix', self.tempdedrmprefs['adobewineprefix'])
self.dedrmprefs.set('kindlewineprefix', self.tempdedrmprefs['kindlewineprefix'])
self.dedrmprefs.set('configured', True)
@@ -188,6 +200,7 @@ class ManageKeysDialog(QDialog):
self.import_key = (keyfile_ext != u"")
self.binary_file = (keyfile_ext == u"der")
self.json_file = (keyfile_ext == u"k4i")
+ self.android_file = (keyfile_ext == u"ab")
self.wineprefix = wineprefix
self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))
@@ -370,32 +383,43 @@ class ManageKeysDialog(QDialog):
for filename in files:
fpath = os.path.join(config_dir, filename)
filename = os.path.basename(filename)
- new_key_name = os.path.splitext(os.path.basename(filename))[0]
- with open(fpath,'rb') as keyfile:
- new_key_value = keyfile.read()
- if self.binary_file:
- new_key_value = new_key_value.encode('hex')
- elif self.json_file:
- new_key_value = json.loads(new_key_value)
- match = False
- for key in self.plugin_keys.keys():
- if uStrCmp(new_key_name, key, True):
- skipped += 1
- msg = u"A key with the name <strong>{0}</strong> already exists!\nSkipping key file <strong>{1}</strong>.\nRename the existing key and import again".format(new_key_name,filename)
- inf = info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
- _(msg), show_copy_button=False, show=True)
- match = True
- break
- if not match:
- if new_key_value in self.plugin_keys.values():
- old_key_name = [name for name, value in self.plugin_keys.iteritems() if value == new_key_value][0]
- skipped += 1
- info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
- u"The key in file {0} is the same as the existing key <strong>{1}</strong> and has been skipped.".format(filename,old_key_name), show_copy_button=False, show=True)
- else:
- counter += 1
- self.plugin_keys[new_key_name] = new_key_value
-
+ if type(self.plugin_keys) != dict:
+ # must be the new Kindle for Android section
+ print u"Getting keys from "+fpath
+ new_keys = get_serials(fpath)
+ for key in new_keys:
+ if key in self.plugin_keys:
+ skipped += 1
+ else:
+ counter += 1
+ self.plugin_keys.append(key)
+ else:
+ new_key_name = os.path.splitext(os.path.basename(filename))[0]
+ with open(fpath,'rb') as keyfile:
+ new_key_value = keyfile.read()
+ if self.binary_file:
+ new_key_value = new_key_value.encode('hex')
+ elif self.json_file:
+ new_key_value = json.loads(new_key_value)
+ match = False
+ for key in self.plugin_keys.keys():
+ if uStrCmp(new_key_name, key, True):
+ skipped += 1
+ msg = u"A key with the name <strong>{0}</strong> already exists!\nSkipping key file <strong>{1}</strong>.\nRename the existing key and import again".format(new_key_name,filename)
+ inf = info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
+ _(msg), show_copy_button=False, show=True)
+ match = True
+ break
+ if not match:
+ if new_key_value in self.plugin_keys.values():
+ old_key_name = [name for name, value in self.plugin_keys.iteritems() if value == new_key_value][0]
+ skipped += 1
+ info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
+ u"The key in file {0} is the same as the existing key <strong>{1}</strong> and has been skipped.".format(filename,old_key_name), show_copy_button=False, show=True)
+ else:
+ counter += 1
+ self.plugin_keys[new_key_name] = new_key_value
+
msg = u""
if counter+skipped > 1:
if counter > 0:
@@ -863,6 +887,51 @@ class AddSerialDialog(QDialog):
QDialog.accept(self)
+class AddAndroidSerialDialog(QDialog):
+ def __init__(self, parent=None,):
+ QDialog.__init__(self, parent)
+ self.parent = parent
+ self.setWindowTitle(u"{0} {1}: Add New Kindle for Android Serial Number".format(PLUGIN_NAME, PLUGIN_VERSION))
+ layout = QVBoxLayout(self)
+ self.setLayout(layout)
+
+ data_group_box = QGroupBox(u"", self)
+ layout.addWidget(data_group_box)
+ data_group_box_layout = QVBoxLayout()
+ data_group_box.setLayout(data_group_box_layout)
+
+ key_group = QHBoxLayout()
+ 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.")
+ key_group.addWidget(self.key_ledit)
+ key_label = QLabel(_(''), self)
+ key_label.setAlignment(Qt.AlignHCenter)
+ data_group_box_layout.addWidget(key_label)
+
+ self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
+ self.button_box.accepted.connect(self.accept)
+ self.button_box.rejected.connect(self.reject)
+ layout.addWidget(self.button_box)
+
+ self.resize(self.sizeHint())
+
+ @property
+ def key_name(self):
+ return unicode(self.key_ledit.text()).strip()
+
+ @property
+ def key_value(self):
+ return unicode(self.key_ledit.text()).strip()
+
+ def accept(self):
+ if len(self.key_name) == 0 or self.key_name.isspace():
+ errmsg = u"Please enter a Kindle for Android Serial Number or click Cancel in the dialog."
+ return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
+ QDialog.accept(self)
+
+
class AddPIDDialog(QDialog):
def __init__(self, parent=None,):
QDialog.__init__(self, parent)
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/prefs.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/prefs.py
index 05065ac..f0f494c 100644
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/prefs.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/prefs.py
@@ -25,6 +25,7 @@ class DeDRM_Prefs():
self.dedrmprefs.defaults['kindlekeys'] = {}
self.dedrmprefs.defaults['pids'] = []
self.dedrmprefs.defaults['serials'] = []
+ self.dedrmprefs.defaults['androidserials'] = []
self.dedrmprefs.defaults['adobewineprefix'] = ""
self.dedrmprefs.defaults['kindlewineprefix'] = ""
@@ -44,6 +45,8 @@ class DeDRM_Prefs():
self.dedrmprefs['pids'] = []
if self.dedrmprefs['serials'] == []:
self.dedrmprefs['serials'] = []
+ if self.dedrmprefs['androidserials'] == []:
+ self.dedrmprefs['androidserials'] = []
def __getitem__(self,kind = None):
if kind is not None: