diff --git a/Other_Tools/Kobo/obok.py b/Other_Tools/Kobo/obok.py index 08f484a..26d1e38 100644 --- a/Other_Tools/Kobo/obok.py +++ b/Other_Tools/Kobo/obok.py @@ -1,6 +1,16 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +# Version 6.3.5 January 2016 +# Update for latest version of Windows Desktop app. +# Support Kobo devices in the command line version. +# +# Version 3.1.9 November 2015 +# Handle Kobo Desktop under wine on Linux +# +# Version 3.1.8 November 2015 +# Handle the case of Kobo Arc or Vox device (i.e. don't crash). +# # Version 3.1.7 October 2015 # Handle the case of no device or database more gracefully. # @@ -126,7 +136,8 @@ # """Manage all Kobo books, either encrypted or DRM-free.""" -__version__ = '3.1.7' +__version__ = '3.1.9' +__about__ = u"Obok v{0}\nCopyright © 2012-2015 Physisticated et al.".format(__version__) import sys import os @@ -140,6 +151,18 @@ import hashlib import xml.etree.ElementTree as ET import string import shutil +import argparse + +can_parse_xml = True +try: + from xml.etree import ElementTree as ET + # print u"using xml.etree for xml parsing" +except ImportError: + can_parse_xml = False + # print u"Cannot find xml.etree, disabling extraction of serial numbers" + +# List of all known hash keys +KOBO_HASH_KEYS = ['88b3a2e13', 'XzUhGYdFp', 'NoCanLook'] class ENCRYPTIONError(Exception): pass @@ -252,24 +275,59 @@ class KoboLibrary(object): of books, their titles, and the user's encryption key(s).""" def __init__ (self, serials = [], device_path = None): - print u"Obok v{0}\nCopyright © 2012-2015 Physisticated et al.".format(__version__) + print __about__ self.kobodir = u"" kobodb = u"" - # - first check whether serials have been found or are provided - # and a device is connected. In this case, use the device - # - otherwise fall back to Kobo Desktop Application for Windows and Mac - if (device_path and (len(serials) > 0)): + # Order of checks + # 1. first check if a device_path has been passed in, and whether + # we can find the sqlite db in the respective place + # 2. if 1., and we got some serials passed in (from saved + # settings in calibre), just use it + # 3. if 1. worked, but we didn't get serials, try to parse them + # from the device, if this didn't work, unset everything + # 4. if by now we don't have kobodir set, give up on device and + # try to use the Desktop app. + + # step 1. check whether this looks like a real device + if (device_path): + # we got a device path self.kobodir = os.path.join(device_path, u".kobo") # devices use KoboReader.sqlite kobodb = os.path.join(self.kobodir, u"KoboReader.sqlite") if (not(os.path.isfile(kobodb))): - # give up here, we haven't found anything useful + # device path seems to be wrong, unset it + device_path = u"" self.kobodir = u"" kobodb = u"" + if (self.kobodir): + # step 3. we found a device but didn't get serials, try to get them + if (len(serials) == 0): + # we got a device path but no saved serial + # try to get the serial from the device + # print u"get_device_settings - device_path = {0}".format(device_path) + # get serial from device_path/.adobe-digital-editions/device.xml + if can_parse_xml: + devicexml = os.path.join(device_path, '.adobe-digital-editions', 'device.xml') + # print u"trying to load {0}".format(devicexml) + if (os.path.exists(devicexml)): + # print u"trying to parse {0}".format(devicexml) + xmltree = ET.parse(devicexml) + for node in xmltree.iter(): + if "deviceSerial" in node.tag: + serial = node.text + # print u"found serial {0}".format(serial) + serials.append(serial) + break + else: + # print u"cannot get serials from device." + device_path = u"" + self.kobodir = u"" + kobodb = u"" + if (self.kobodir == u""): - # we haven't found a device with serials, so try desktop apps + # step 4. we haven't found a device with serials, so try desktop apps if sys.platform.startswith('win'): import _winreg as winreg if sys.getwindowsversion().major > 5: @@ -283,6 +341,9 @@ class KoboLibrary(object): self.kobodir = os.path.join(self.kobodir, u"Kobo", u"Kobo Desktop Edition") elif sys.platform.startswith('darwin'): self.kobodir = os.path.join(os.environ['HOME'], u"Library", u"Application Support", u"Kobo", u"Kobo Desktop Edition") + elif linux_path != None: + # Probably Linux, let's get the wine prefix and path to Kobo. + self.kobodir = os.path.join(linux_path, u"Local Settings", u"Application Data", u"Kobo", u"Kobo Desktop Edition") # desktop versions use Kobo.sqlite kobodb = os.path.join(self.kobodir, u"Kobo.sqlite") # check for existence of file @@ -358,6 +419,13 @@ class KoboLibrary(object): for m in matches: # print u"m:{0}".format(m[0]) macaddrs.append(m[0].upper()) + else: + # probably linux, let's try ipconfig under wine + c = re.compile('\s(' + '[0-9a-f]{2}-' * 5 + '[0-9a-f]{2})(\s|$)', re.IGNORECASE) + for line in os.popen('ipconfig /all'): + m = c.search(line) + if m: + macaddrs.append(re.sub("-", ":", m.group(1)).upper()) # extend the list of macaddrs in any case with the serials # cannot hurt ;-) @@ -381,16 +449,11 @@ class KoboLibrary(object): def __getuserkeys (self, macaddr): userids = self.__getuserids() userkeys = [] - # This version is used for versions before 3.17.0. - deviceid = hashlib.sha256('NoCanLook' + macaddr).hexdigest() - for userid in userids: - 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:])) + for hash in KOBO_HASH_KEYS: + deviceid = hashlib.sha256(hash + macaddr).hexdigest() + for userid in userids: + userkey = hashlib.sha256(deviceid + userid).hexdigest() + userkeys.append(binascii.a2b_hex(userkey[32:])) return userkeys class KoboBook(object): @@ -527,7 +590,17 @@ class KoboFile(object): return contents def cli_main(): - lib = KoboLibrary() + description = __about__ + epilog = u"Parsing of arguments failed." + parser = argparse.ArgumentParser(prog=sys.argv[0], description=description, epilog=epilog) + parser.add_argument('--devicedir', default='/media/KOBOeReader', help="directory of connected Kobo device") + args = vars(parser.parse_args()) + serials = [] + devicedir = u"" + if args['devicedir']: + devicedir = args['devicedir'] + + lib = KoboLibrary(serials, devicedir) for i, book in enumerate(lib.books): print u"{0}: {1}".format(i + 1, book.title) diff --git a/Other_Tools/Scuolabook_DRM/Scuolabook DRM Remover 1.3 Linux.tar.gz b/Other_Tools/Scuolabook_DRM/Scuolabook DRM Remover 1.3 Linux.tar.gz deleted file mode 100644 index f8d50b0..0000000 Binary files a/Other_Tools/Scuolabook_DRM/Scuolabook DRM Remover 1.3 Linux.tar.gz and /dev/null differ diff --git a/Other_Tools/Scuolabook_DRM/Scuolabook DRM Remover 1.3 Mac OSX.zip b/Other_Tools/Scuolabook_DRM/Scuolabook DRM Remover 1.3 Mac OSX.zip deleted file mode 100644 index f1ff88c..0000000 Binary files a/Other_Tools/Scuolabook_DRM/Scuolabook DRM Remover 1.3 Mac OSX.zip and /dev/null differ diff --git a/Other_Tools/Scuolabook_DRM/Scuolabook DRM Remover 1.3 Windows.zip b/Other_Tools/Scuolabook_DRM/Scuolabook DRM Remover 1.3 Windows.zip deleted file mode 100644 index bbf86c0..0000000 Binary files a/Other_Tools/Scuolabook_DRM/Scuolabook DRM Remover 1.3 Windows.zip and /dev/null differ diff --git a/Other_Tools/Scuolabook_DRM/Scuolabook_DRM_Remover_source_2013_12_31.zip b/Other_Tools/Scuolabook_DRM/Scuolabook_DRM_Remover_source_2013_12_31.zip deleted file mode 100644 index 2fb4f06..0000000 Binary files a/Other_Tools/Scuolabook_DRM/Scuolabook_DRM_Remover_source_2013_12_31.zip and /dev/null differ diff --git a/Other_Tools/Scuolabook_DRM/Scuolabook_ReadMe.txt b/Other_Tools/Scuolabook_DRM/Scuolabook_ReadMe.txt index a360f1e..cd15dbf 100644 --- a/Other_Tools/Scuolabook_DRM/Scuolabook_ReadMe.txt +++ b/Other_Tools/Scuolabook_DRM/Scuolabook_ReadMe.txt @@ -1,18 +1,4 @@ -How-to: -1) Make sure you can read all PDF files on Scuolabook Reader. -2) Run Scuolabook DRM Remover. -3) Decrypt your books. - -Note: -It is recommended to use Scuolabook version 3.0.3 and refuse all updates -because the encryption algorithm may change making this tool useless. - -Hex - - - - -For any further help or information, see Hex's own blog at +The latest Scuolabook tool can be found at Hex's own blog: https://thisishex.wordpress.com/scuolabook-drm-remover/ Harper. \ No newline at end of file