Compare commits

..

7 Commits

Author SHA1 Message Date
apprenticeharper
07485be2c0 Add transparency to the obok logo 2015-09-03 08:06:33 +01:00
apprenticeharper
e5e269fbae Fixes for android key extraction 2015-09-03 07:51:10 +01:00
apprenticeharper
d54dc38c2d Fix for Kobo Desktop 3.17 2015-09-03 07:49:09 +01:00
apprenticeharper
3c322f3695 Second and last step to fix capitalisation issue 2015-09-01 07:08:46 +01:00
apprenticeharper
c112c28f58 First step to fix capitalisation issue 2015-09-01 07:06:13 +01:00
apprenticeharper
b8606cd182 Merge pull request #32 from eli-schwartz/master
Linux: Allow using ~ when specifying a wineprefix.
2015-09-01 06:57:48 +01:00
Eli Schwartz
f2190a6755 Linux: Allow using ~ when specifying a wineprefix. 2015-08-12 17:39:50 -04:00
18 changed files with 168 additions and 71 deletions

View File

@@ -24,7 +24,7 @@
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>droplet</string> <string>droplet</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>DeDRM AppleScript 6.3.3 Written 20102015 by Apprentice Alf et al.</string> <string>DeDRM AppleScript 6.3.4 Written 20102015 by Apprentice Alf et al.</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>DeDRM</string> <string>DeDRM</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@@ -36,7 +36,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>6.3.3</string> <string>6.3.4</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>dplt</string> <string>dplt</string>
<key>LSRequiresCarbon</key> <key>LSRequiresCarbon</key>

View File

@@ -45,6 +45,7 @@ __docformat__ = 'restructuredtext en'
# 6.3.1 - Version number bump for clarity # 6.3.1 - Version number bump for clarity
# 6.3.2 - Fixed Kindle for Android help file # 6.3.2 - Fixed Kindle for Android help file
# 6.3.3 - Bug fix for Kindle for PC support # 6.3.3 - Bug fix for Kindle for PC support
# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17
""" """
@@ -52,7 +53,7 @@ Decrypt DRMed ebooks.
""" """
PLUGIN_NAME = u"DeDRM" PLUGIN_NAME = u"DeDRM"
PLUGIN_VERSION_TUPLE = (6, 3, 3) PLUGIN_VERSION_TUPLE = (6, 3, 4)
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE]) 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. # Include an html helpfile in the plugin's zipfile with the following name.
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
@@ -148,7 +149,7 @@ class DeDRM(FileTypePlugin):
try: try:
open(file_path,'wb').write(data) open(file_path,'wb').write(data)
except: except:
print u"{0} v{1}: Exception when copying needed library files after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime) print u"{0} v{1}: Exception when copying needed library files".format(PLUGIN_NAME, PLUGIN_VERSION)
traceback.print_exc() traceback.print_exc()
pass pass

View File

@@ -16,16 +16,18 @@ from __future__ import with_statement
# - and added in unicode command line support # - and added in unicode command line support
# 1.3 - added in TkInter interface, output to a file # 1.3 - added in TkInter interface, output to a file
# 1.4 - Fix some problems identified by Aldo Bleeker # 1.4 - Fix some problems identified by Aldo Bleeker
# 1.5 - Fix another problem identified by Aldo Bleeker
""" """
Retrieve Kindle for Android Serial Number. Retrieve Kindle for Android Serial Number.
""" """
__license__ = 'GPL v3' __license__ = 'GPL v3'
__version__ = '1.4' __version__ = '1.5'
import os import os
import sys import sys
import traceback
import getopt import getopt
import tempfile import tempfile
import zlib import zlib
@@ -220,20 +222,30 @@ def get_serials2(path=STORAGE2):
userdata_keys = cursor.fetchall() userdata_keys = cursor.fetchall()
dsns = [] dsns = []
for userdata_row in userdata_keys: for userdata_row in userdata_keys:
if userdata_row: try:
userdata_utf8 = userdata_row[0].encode('utf8') if userdata_row and userdata_row[0]:
if len(userdata_utf8) > 0: userdata_utf8 = userdata_row[0].encode('utf8')
dsns.append(userdata_utf8) if len(userdata_utf8) > 0:
dsns.append(userdata_utf8)
except:
print "Error getting one of the device serial name keys"
traceback.print_exc()
pass
dsns = list(set(dsns)) dsns = list(set(dsns))
cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''') cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''')
userdata_keys = cursor.fetchall() userdata_keys = cursor.fetchall()
tokens = [] tokens = []
for userdata_row in userdata_keys: for userdata_row in userdata_keys:
if userdata_row: try:
userdata_utf8 = userdata_row[0].encode('utf8') if userdata_row and userdata_row[0]:
if len(userdata_utf8) > 0: userdata_utf8 = userdata_row[0].encode('utf8')
tokens.append(userdata_utf8) if len(userdata_utf8) > 0:
tokens.append(userdata_utf8)
except:
print "Error getting one of the account token keys"
traceback.print_exc()
pass
tokens = list(set(tokens)) tokens = list(set(tokens))
serials = [] serials = []
@@ -377,7 +389,6 @@ def gui_main():
import Tkconstants import Tkconstants
import tkMessageBox import tkMessageBox
import tkFileDialog import tkFileDialog
import traceback
except: except:
print "Tkinter not installed" print "Tkinter not installed"
return cli_main() return cli_main()

View File

@@ -18,8 +18,9 @@
# 6.3.1 - Version bump for clarity # 6.3.1 - Version bump for clarity
# 6.3.2 - Version bump to match plugin # 6.3.2 - Version bump to match plugin
# 6.3.3 - Version bump to match plugin # 6.3.3 - Version bump to match plugin
# 6.3.4 - Version bump to match plugin
__version__ = '6.3.3' __version__ = '6.3.4'
import sys import sys
import os, os.path import os, os.path

View File

@@ -45,6 +45,7 @@ __docformat__ = 'restructuredtext en'
# 6.3.1 - Version number bump for clarity # 6.3.1 - Version number bump for clarity
# 6.3.2 - Fixed Kindle for Android help file # 6.3.2 - Fixed Kindle for Android help file
# 6.3.3 - Bug fix for Kindle for PC support # 6.3.3 - Bug fix for Kindle for PC support
# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17
""" """
@@ -52,7 +53,7 @@ Decrypt DRMed ebooks.
""" """
PLUGIN_NAME = u"DeDRM" PLUGIN_NAME = u"DeDRM"
PLUGIN_VERSION_TUPLE = (6, 3, 3) PLUGIN_VERSION_TUPLE = (6, 3, 4)
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE]) 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. # Include an html helpfile in the plugin's zipfile with the following name.
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
@@ -148,7 +149,7 @@ class DeDRM(FileTypePlugin):
try: try:
open(file_path,'wb').write(data) open(file_path,'wb').write(data)
except: except:
print u"{0} v{1}: Exception when copying needed library files after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime) print u"{0} v{1}: Exception when copying needed library files".format(PLUGIN_NAME, PLUGIN_VERSION)
traceback.print_exc() traceback.print_exc()
pass pass

View File

@@ -16,16 +16,18 @@ from __future__ import with_statement
# - and added in unicode command line support # - and added in unicode command line support
# 1.3 - added in TkInter interface, output to a file # 1.3 - added in TkInter interface, output to a file
# 1.4 - Fix some problems identified by Aldo Bleeker # 1.4 - Fix some problems identified by Aldo Bleeker
# 1.5 - Fix another problem identified by Aldo Bleeker
""" """
Retrieve Kindle for Android Serial Number. Retrieve Kindle for Android Serial Number.
""" """
__license__ = 'GPL v3' __license__ = 'GPL v3'
__version__ = '1.4' __version__ = '1.5'
import os import os
import sys import sys
import traceback
import getopt import getopt
import tempfile import tempfile
import zlib import zlib
@@ -220,20 +222,30 @@ def get_serials2(path=STORAGE2):
userdata_keys = cursor.fetchall() userdata_keys = cursor.fetchall()
dsns = [] dsns = []
for userdata_row in userdata_keys: for userdata_row in userdata_keys:
if userdata_row: try:
userdata_utf8 = userdata_row[0].encode('utf8') if userdata_row and userdata_row[0]:
if len(userdata_utf8) > 0: userdata_utf8 = userdata_row[0].encode('utf8')
dsns.append(userdata_utf8) if len(userdata_utf8) > 0:
dsns.append(userdata_utf8)
except:
print "Error getting one of the device serial name keys"
traceback.print_exc()
pass
dsns = list(set(dsns)) dsns = list(set(dsns))
cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''') cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''')
userdata_keys = cursor.fetchall() userdata_keys = cursor.fetchall()
tokens = [] tokens = []
for userdata_row in userdata_keys: for userdata_row in userdata_keys:
if userdata_row: try:
userdata_utf8 = userdata_row[0].encode('utf8') if userdata_row and userdata_row[0]:
if len(userdata_utf8) > 0: userdata_utf8 = userdata_row[0].encode('utf8')
tokens.append(userdata_utf8) if len(userdata_utf8) > 0:
tokens.append(userdata_utf8)
except:
print "Error getting one of the account token keys"
traceback.print_exc()
pass
tokens = list(set(tokens)) tokens = list(set(tokens))
serials = [] serials = []
@@ -377,7 +389,6 @@ def gui_main():
import Tkconstants import Tkconstants
import tkMessageBox import tkMessageBox
import tkFileDialog import tkFileDialog
import traceback
except: except:
print "Tkinter not installed" print "Tkinter not installed"
return cli_main() return cli_main()

View File

@@ -45,6 +45,7 @@ __docformat__ = 'restructuredtext en'
# 6.3.1 - Version number bump for clarity # 6.3.1 - Version number bump for clarity
# 6.3.2 - Fixed Kindle for Android help file # 6.3.2 - Fixed Kindle for Android help file
# 6.3.3 - Bug fix for Kindle for PC support # 6.3.3 - Bug fix for Kindle for PC support
# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17
""" """
@@ -52,7 +53,7 @@ Decrypt DRMed ebooks.
""" """
PLUGIN_NAME = u"DeDRM" PLUGIN_NAME = u"DeDRM"
PLUGIN_VERSION_TUPLE = (6, 3, 3) PLUGIN_VERSION_TUPLE = (6, 3, 4)
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE]) 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. # Include an html helpfile in the plugin's zipfile with the following name.
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
@@ -148,7 +149,7 @@ class DeDRM(FileTypePlugin):
try: try:
open(file_path,'wb').write(data) open(file_path,'wb').write(data)
except: except:
print u"{0} v{1}: Exception when copying needed library files after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime) print u"{0} v{1}: Exception when copying needed library files".format(PLUGIN_NAME, PLUGIN_VERSION)
traceback.print_exc() traceback.print_exc()
pass pass

View File

@@ -16,16 +16,18 @@ from __future__ import with_statement
# - and added in unicode command line support # - and added in unicode command line support
# 1.3 - added in TkInter interface, output to a file # 1.3 - added in TkInter interface, output to a file
# 1.4 - Fix some problems identified by Aldo Bleeker # 1.4 - Fix some problems identified by Aldo Bleeker
# 1.5 - Fix another problem identified by Aldo Bleeker
""" """
Retrieve Kindle for Android Serial Number. Retrieve Kindle for Android Serial Number.
""" """
__license__ = 'GPL v3' __license__ = 'GPL v3'
__version__ = '1.4' __version__ = '1.5'
import os import os
import sys import sys
import traceback
import getopt import getopt
import tempfile import tempfile
import zlib import zlib
@@ -220,20 +222,30 @@ def get_serials2(path=STORAGE2):
userdata_keys = cursor.fetchall() userdata_keys = cursor.fetchall()
dsns = [] dsns = []
for userdata_row in userdata_keys: for userdata_row in userdata_keys:
if userdata_row: try:
userdata_utf8 = userdata_row[0].encode('utf8') if userdata_row and userdata_row[0]:
if len(userdata_utf8) > 0: userdata_utf8 = userdata_row[0].encode('utf8')
dsns.append(userdata_utf8) if len(userdata_utf8) > 0:
dsns.append(userdata_utf8)
except:
print "Error getting one of the device serial name keys"
traceback.print_exc()
pass
dsns = list(set(dsns)) dsns = list(set(dsns))
cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''') cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''')
userdata_keys = cursor.fetchall() userdata_keys = cursor.fetchall()
tokens = [] tokens = []
for userdata_row in userdata_keys: for userdata_row in userdata_keys:
if userdata_row: try:
userdata_utf8 = userdata_row[0].encode('utf8') if userdata_row and userdata_row[0]:
if len(userdata_utf8) > 0: userdata_utf8 = userdata_row[0].encode('utf8')
tokens.append(userdata_utf8) if len(userdata_utf8) > 0:
tokens.append(userdata_utf8)
except:
print "Error getting one of the account token keys"
traceback.print_exc()
pass
tokens = list(set(tokens)) tokens = list(set(tokens))
serials = [] serials = []
@@ -377,7 +389,6 @@ def gui_main():
import Tkconstants import Tkconstants
import tkMessageBox import tkMessageBox
import tkFileDialog import tkFileDialog
import traceback
except: except:
print "Tkinter not installed" print "Tkinter not installed"
return cli_main() return cli_main()

View File

@@ -26,6 +26,7 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
if not os.path.exists(outdirpath): if not os.path.exists(outdirpath):
os.makedirs(outdirpath) os.makedirs(outdirpath)
wineprefix = os.path.abspath(os.path.expanduser(os.path.expandvars(wineprefix)))
if wineprefix != "" and os.path.exists(wineprefix): if wineprefix != "" and os.path.exists(wineprefix):
cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix) cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix)
else: else:

Binary file not shown.

View File

@@ -19,7 +19,7 @@ except NameError:
PLUGIN_NAME = 'Obok DeDRM' PLUGIN_NAME = 'Obok DeDRM'
PLUGIN_SAFE_NAME = PLUGIN_NAME.strip().lower().replace(' ', '_') PLUGIN_SAFE_NAME = PLUGIN_NAME.strip().lower().replace(' ', '_')
PLUGIN_DESCRIPTION = _('Removes DRM from Kobo kepubs and adds them to the library.') PLUGIN_DESCRIPTION = _('Removes DRM from Kobo kepubs and adds them to the library.')
PLUGIN_VERSION_TUPLE = (3, 1, 3) PLUGIN_VERSION_TUPLE = (3, 1, 4)
PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE]) PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE])
HELPFILE_NAME = PLUGIN_SAFE_NAME + '_Help.htm' HELPFILE_NAME = PLUGIN_SAFE_NAME + '_Help.htm'
PLUGIN_AUTHORS = 'Anon' PLUGIN_AUTHORS = 'Anon'

View File

@@ -6,7 +6,7 @@ __license__ = 'GPL v3'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os, zipfile import os, traceback, zipfile
try: try:
from PyQt5.Qt import QToolButton, QUrl from PyQt5.Qt import QToolButton, QUrl
@@ -98,6 +98,7 @@ class InterfacePluginAction(InterfaceAction):
candidate_keys = self.library.userkeys candidate_keys = self.library.userkeys
except: except:
print (_('Trouble retrieving keys with newer obok method.')) print (_('Trouble retrieving keys with newer obok method.'))
traceback.print_exc()
else: else:
if len(candidate_keys): if len(candidate_keys):
self.userkeys.extend(candidate_keys) self.userkeys.extend(candidate_keys)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,6 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Version 3.1.4 September 2015
# Updated for version 3.17 of the Windows Desktop app.
#
# Version 3.1.3 August 2015 # Version 3.1.3 August 2015
# Add translations for Portuguese and Arabic # Add translations for Portuguese and Arabic
# #
@@ -220,7 +223,7 @@ class KoboLibrary(object):
of books, their titles, and the user's encryption key(s).""" of books, their titles, and the user's encryption key(s)."""
def __init__ (self): def __init__ (self):
print u"Obok v{0}\nCopyright © 2012-2014 Physisticated et al.".format(__version__) print u"Obok v{0}\nCopyright © 2012-2015 Physisticated et al.".format(__version__)
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
if sys.getwindowsversion().major > 5: if sys.getwindowsversion().major > 5:
self.kobodir = os.environ['LOCALAPPDATA'] self.kobodir = os.environ['LOCALAPPDATA']
@@ -249,9 +252,8 @@ class KoboLibrary(object):
""" """
if len(self._userkeys) != 0: if len(self._userkeys) != 0:
return self._userkeys return self._userkeys
userid = self.__getuserid()
for macaddr in self.__getmacaddrs(): for macaddr in self.__getmacaddrs():
self._userkeys.append(self.__getuserkey(macaddr, userid)) self._userkeys.extend(self.__getuserkeys(macaddr))
return self._userkeys return self._userkeys
@property @property
@@ -297,13 +299,33 @@ class KoboLibrary(object):
macaddrs.append(m[0].upper()) macaddrs.append(m[0].upper())
return macaddrs return macaddrs
def __getuserid (self): def __getuserids (self):
return self.__cursor.execute('SELECT UserID FROM user WHERE HasMadePurchase = "true"').fetchone()[0] userids = []
cursor = self.__cursor.execute('SELECT UserID FROM user WHERE HasMadePurchase = "true"')
row = cursor.fetchone()
while row is not None:
try:
userid = row[0]
userids.append(userid)
except:
pass
row = cursor.fetchone()
return userids
def __getuserkey (self, macaddr, userid): def __getuserkeys (self, macaddr):
userids = self.__getuserids()
userkeys = []
# This version is used for versions before 3.17.0.
deviceid = hashlib.sha256('NoCanLook' + macaddr).hexdigest() deviceid = hashlib.sha256('NoCanLook' + macaddr).hexdigest()
userkey = hashlib.sha256(deviceid + userid).hexdigest() for userid in userids:
return binascii.a2b_hex(userkey[32:]) userkey = hashlib.sha256(deviceid + userid).hexdigest()
userkeys.append(binascii.a2b_hex(userkey[32:]))
# This version is used for 3.17.0 and later.
deviceid = hashlib.sha256('XzUhGYdFp' + macaddr).hexdigest()
for userid in userids:
userkey = hashlib.sha256(deviceid + userid).hexdigest()
userkeys.append(binascii.a2b_hex(userkey[32:]))
return userkeys
class KoboBook(object): class KoboBook(object):
"""A Kobo book. """A Kobo book.

View File

@@ -16,16 +16,18 @@ from __future__ import with_statement
# - and added in unicode command line support # - and added in unicode command line support
# 1.3 - added in TkInter interface, output to a file # 1.3 - added in TkInter interface, output to a file
# 1.4 - Fix some problems identified by Aldo Bleeker # 1.4 - Fix some problems identified by Aldo Bleeker
# 1.5 - Fix another problem identified by Aldo Bleeker
""" """
Retrieve Kindle for Android Serial Number. Retrieve Kindle for Android Serial Number.
""" """
__license__ = 'GPL v3' __license__ = 'GPL v3'
__version__ = '1.4' __version__ = '1.5'
import os import os
import sys import sys
import traceback
import getopt import getopt
import tempfile import tempfile
import zlib import zlib
@@ -220,20 +222,30 @@ def get_serials2(path=STORAGE2):
userdata_keys = cursor.fetchall() userdata_keys = cursor.fetchall()
dsns = [] dsns = []
for userdata_row in userdata_keys: for userdata_row in userdata_keys:
if userdata_row: try:
userdata_utf8 = userdata_row[0].encode('utf8') if userdata_row and userdata_row[0]:
if len(userdata_utf8) > 0: userdata_utf8 = userdata_row[0].encode('utf8')
dsns.append(userdata_utf8) if len(userdata_utf8) > 0:
dsns.append(userdata_utf8)
except:
print "Error getting one of the device serial name keys"
traceback.print_exc()
pass
dsns = list(set(dsns)) dsns = list(set(dsns))
cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''') cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''')
userdata_keys = cursor.fetchall() userdata_keys = cursor.fetchall()
tokens = [] tokens = []
for userdata_row in userdata_keys: for userdata_row in userdata_keys:
if userdata_row: try:
userdata_utf8 = userdata_row[0].encode('utf8') if userdata_row and userdata_row[0]:
if len(userdata_utf8) > 0: userdata_utf8 = userdata_row[0].encode('utf8')
tokens.append(userdata_utf8) if len(userdata_utf8) > 0:
tokens.append(userdata_utf8)
except:
print "Error getting one of the account token keys"
traceback.print_exc()
pass
tokens = list(set(tokens)) tokens = list(set(tokens))
serials = [] serials = []
@@ -377,7 +389,6 @@ def gui_main():
import Tkconstants import Tkconstants
import tkMessageBox import tkMessageBox
import tkFileDialog import tkFileDialog
import traceback
except: except:
print "Tkinter not installed" print "Tkinter not installed"
return cli_main() return cli_main()

View File

@@ -1,6 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Version 3.1.4 September 2015
# Updated for version 3.17 of the Windows Desktop app.
#
# Version 3.1.3 August 2015
# Add translations for Portuguese and Arabic
#
# Version 3.1.2 January 2015 # Version 3.1.2 January 2015
# Add coding, version number and version announcement # Add coding, version number and version announcement
# #
@@ -109,7 +115,7 @@
# #
"""Manage all Kobo books, either encrypted or DRM-free.""" """Manage all Kobo books, either encrypted or DRM-free."""
__version__ = '3.1.1' __version__ = '3.1.3'
import sys import sys
import os import os
@@ -217,7 +223,7 @@ class KoboLibrary(object):
of books, their titles, and the user's encryption key(s).""" of books, their titles, and the user's encryption key(s)."""
def __init__ (self): def __init__ (self):
print u"Obok v{0}\nCopyright © 2012-2014 Physisticated et al.".format(__version__) print u"Obok v{0}\nCopyright © 2012-2015 Physisticated et al.".format(__version__)
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
if sys.getwindowsversion().major > 5: if sys.getwindowsversion().major > 5:
self.kobodir = os.environ['LOCALAPPDATA'] self.kobodir = os.environ['LOCALAPPDATA']
@@ -246,9 +252,8 @@ class KoboLibrary(object):
""" """
if len(self._userkeys) != 0: if len(self._userkeys) != 0:
return self._userkeys return self._userkeys
userid = self.__getuserid()
for macaddr in self.__getmacaddrs(): for macaddr in self.__getmacaddrs():
self._userkeys.append(self.__getuserkey(macaddr, userid)) self._userkeys.extend(self.__getuserkeys(macaddr))
return self._userkeys return self._userkeys
@property @property
@@ -294,13 +299,33 @@ class KoboLibrary(object):
macaddrs.append(m[0].upper()) macaddrs.append(m[0].upper())
return macaddrs return macaddrs
def __getuserid (self): def __getuserids (self):
return self.__cursor.execute('SELECT UserID FROM user WHERE HasMadePurchase = "true"').fetchone()[0] userids = []
cursor = self.__cursor.execute('SELECT UserID FROM user WHERE HasMadePurchase = "true"')
row = cursor.fetchone()
while row is not None:
try:
userid = row[0]
userids.append(userid)
except:
pass
row = cursor.fetchone()
return userids
def __getuserkey (self, macaddr, userid): def __getuserkeys (self, macaddr):
userids = self.__getuserids()
userkeys = []
# This version is used for versions before 3.17.0.
deviceid = hashlib.sha256('NoCanLook' + macaddr).hexdigest() deviceid = hashlib.sha256('NoCanLook' + macaddr).hexdigest()
userkey = hashlib.sha256(deviceid + userid).hexdigest() for userid in userids:
return binascii.a2b_hex(userkey[32:]) userkey = hashlib.sha256(deviceid + userid).hexdigest()
userkeys.append(binascii.a2b_hex(userkey[32:]))
# This version is used for 3.17.0 and later.
deviceid = hashlib.sha256('XzUhGYdFp' + macaddr).hexdigest()
for userid in userids:
userkey = hashlib.sha256(deviceid + userid).hexdigest()
userkeys.append(binascii.a2b_hex(userkey[32:]))
return userkeys
class KoboBook(object): class KoboBook(object):
"""A Kobo book. """A Kobo book.

View File

@@ -1,7 +1,7 @@
Welcome to the tools! Welcome to the tools!
===================== =====================
This ReadMe_First.txt is meant to give users a quick overview of what is available and how to get started. This document is part of the Tools v6.3.1 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/ This ReadMe_First.txt is meant to give users a quick overview of what is available and how to get started. This document is part of the Tools v6.3.4 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/
The is archive includes tools to remove DRM from: The is archive includes tools to remove DRM from: