From e2170b42602ec333a37bf6974aa8a2fb4296bc67 Mon Sep 17 00:00:00 2001 From: Apprentice Harper Date: Wed, 13 Apr 2016 18:39:13 +0100 Subject: [PATCH] Fox for new tags in Topaz format ebooks. --- .../DeDRM.app/Contents/Info.plist | 4 ++-- .../DeDRM.app/Contents/Resources/__init__.py | 5 ++--- .../Contents/Resources/convert2xml.py | 7 ++++++- .../DeDRM.app/Contents/Resources/kindlekey.py | 11 +++++------ .../DeDRM_App/DeDRM_lib/DeDRM_App.pyw | 3 ++- .../DeDRM_App/DeDRM_lib/lib/__init__.py | 5 ++--- .../DeDRM_App/DeDRM_lib/lib/convert2xml.py | 7 ++++++- DeDRM_calibre_plugin/DeDRM_plugin.zip | Bin 353838 -> 353872 bytes DeDRM_calibre_plugin/DeDRM_plugin/__init__.py | 5 ++--- .../DeDRM_plugin/convert2xml.py | 7 ++++++- 10 files changed, 33 insertions(+), 21 deletions(-) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist index 94ad26c..0edfc81 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist @@ -24,7 +24,7 @@ CFBundleExecutable droplet CFBundleGetInfoString - DeDRM AppleScript 6.4.0 Written 2010–2016 by Apprentice Alf et al. + DeDRM AppleScript 6.4.1 Written 2010–2016 by Apprentice Alf et al. CFBundleIconFile DeDRM CFBundleIdentifier @@ -36,7 +36,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 6.4.0 + 6.4.1 CFBundleSignature dplt LSRequiresCarbon diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py index 880d9fe..ddba7a4 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py @@ -9,8 +9,6 @@ __docformat__ = 'restructuredtext en' # Released under the terms of the GNU General Public Licence, version 3 # # -# Requires Calibre version 0.7.55 or higher. -# # All credit given to i♥cabbages and The Dark Reverser for the original standalone scripts. # We had the much easier job of converting them to a calibre plugin. # @@ -49,6 +47,7 @@ __docformat__ = 'restructuredtext en' # 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging # 6.3.6 - Fixes for ADE ePub and PDF introduced in 6.3.5 # 6.4.0 - Updated for new Kindle for PC encryption +# 6.4.1 - Fix for some new tags in Topaz ebooks. """ @@ -56,7 +55,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 4, 0) +PLUGIN_VERSION_TUPLE = (6, 4, 1) 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' diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/convert2xml.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/convert2xml.py index 101c45a..bbb7b04 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/convert2xml.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/convert2xml.py @@ -164,6 +164,7 @@ class PageParser(object): self.id = os.path.basename(filename).replace('.dat','') self.dict = dict self.debug = debug + self.first_unknown = True self.flat_xml = flat_xml self.tagpath = [] self.doc = [] @@ -262,6 +263,9 @@ class PageParser(object): 'img.w' : (1, 'scalar_number', 0, 0), 'img.src' : (1, 'scalar_number', 0, 0), 'img.color_src' : (1, 'scalar_number', 0, 0), + 'img.gridSize' : (1, 'scalar_number', 0, 0), + 'img.gridBottomCenter' : (1, 'scalar_number', 0, 0), + 'img.gridTopCenter' : (1, 'scalar_number', 0, 0), 'img.gridBeginCenter' : (1, 'scalar_number', 0, 0), 'img.gridEndCenter' : (1, 'scalar_number', 0, 0), 'img.image_type' : (1, 'scalar_number', 0, 0), @@ -506,8 +510,9 @@ class PageParser(object): # or an out of sync condition else: result = [] - if (self.debug): + if (self.debug or self.first_unknown): print 'Unknown Token:', token + self.first_unknown = False self.tag_pop() return result diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py index 0b14988..c5159cc 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py @@ -4,7 +4,7 @@ from __future__ import with_statement # kindlekey.py -# Copyright © 2010-2016 by some_updates, Apprentice Alf and Apprentice Harper +# Copyright © 2010-2015 by some_updates, Apprentice Alf and Apprentice Harper # Revision history: # 1.0 - Kindle info file decryption, extracted from k4mobidedrm, etc. @@ -19,7 +19,6 @@ from __future__ import with_statement # 1.8 - Fixes for Kindle for Mac, and non-ascii in Windows user names # 1.9 - Fixes for Unicode in Windows user names # 2.0 - Added comments and extra fix for non-ascii Windows user names -# 2.1 - Fixed Kindle for PC encryption changes March 2016 """ @@ -27,7 +26,7 @@ Retrieve Kindle for PC/Mac user key. """ __license__ = 'GPL v3' -__version__ = '2.1' +__version__ = '1.9' import sys, os, re from struct import pack, unpack, unpack_from @@ -1813,7 +1812,7 @@ elif isosx: pass if len(DB)>4: # store values used in decryption - print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(IDString, GetUserName().encode('hex')) + print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(IDString, GetUserName()) DB['IDString'] = IDString DB['UserName'] = GetUserName() else: @@ -1875,7 +1874,7 @@ def cli_main(): sys.stderr=SafeUnbuffered(sys.stderr) argv=unicode_argv() progname = os.path.basename(argv[0]) - print u"{0} v{1}\nCopyright © 2010-2016 by some_updates, Apprentice Alf and Apprentice Harper".format(progname,__version__) + print u"{0} v{1}\nCopyright © 2010-2013 some_updates and Apprentice Alf".format(progname,__version__) try: opts, args = getopt.getopt(argv[1:], "hk:") @@ -1905,7 +1904,7 @@ def cli_main(): # save to the same directory as the script outpath = os.path.dirname(argv[0]) - # make sure the outpath is canonical + # make sure the outpath is the outpath = os.path.realpath(os.path.normpath(outpath)) if not getkey(outpath, files): diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw index 4eda87f..6a2e6c8 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw @@ -22,8 +22,9 @@ # 6.3.5 - Version bump to match plugin # 6.3.6 - Version bump to match plugin # 6.4.0 - Fix for Kindle for PC encryption change +# 6.4.1 - Fix for new tags in Topaz ebooks -__version__ = '6.4.0' +__version__ = '6.4.1' import sys import os, os.path 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 880d9fe..ddba7a4 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py @@ -9,8 +9,6 @@ __docformat__ = 'restructuredtext en' # Released under the terms of the GNU General Public Licence, version 3 # # -# Requires Calibre version 0.7.55 or higher. -# # All credit given to i♥cabbages and The Dark Reverser for the original standalone scripts. # We had the much easier job of converting them to a calibre plugin. # @@ -49,6 +47,7 @@ __docformat__ = 'restructuredtext en' # 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging # 6.3.6 - Fixes for ADE ePub and PDF introduced in 6.3.5 # 6.4.0 - Updated for new Kindle for PC encryption +# 6.4.1 - Fix for some new tags in Topaz ebooks. """ @@ -56,7 +55,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 4, 0) +PLUGIN_VERSION_TUPLE = (6, 4, 1) 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' diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/convert2xml.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/convert2xml.py index 101c45a..bbb7b04 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/convert2xml.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/convert2xml.py @@ -164,6 +164,7 @@ class PageParser(object): self.id = os.path.basename(filename).replace('.dat','') self.dict = dict self.debug = debug + self.first_unknown = True self.flat_xml = flat_xml self.tagpath = [] self.doc = [] @@ -262,6 +263,9 @@ class PageParser(object): 'img.w' : (1, 'scalar_number', 0, 0), 'img.src' : (1, 'scalar_number', 0, 0), 'img.color_src' : (1, 'scalar_number', 0, 0), + 'img.gridSize' : (1, 'scalar_number', 0, 0), + 'img.gridBottomCenter' : (1, 'scalar_number', 0, 0), + 'img.gridTopCenter' : (1, 'scalar_number', 0, 0), 'img.gridBeginCenter' : (1, 'scalar_number', 0, 0), 'img.gridEndCenter' : (1, 'scalar_number', 0, 0), 'img.image_type' : (1, 'scalar_number', 0, 0), @@ -506,8 +510,9 @@ class PageParser(object): # or an out of sync condition else: result = [] - if (self.debug): + if (self.debug or self.first_unknown): print 'Unknown Token:', token + self.first_unknown = False self.tag_pop() return result diff --git a/DeDRM_calibre_plugin/DeDRM_plugin.zip b/DeDRM_calibre_plugin/DeDRM_plugin.zip index 5ad702b751320a68e0da2cf0659922b92afc744e..de165c15ff8f3067226172a9a725f02de028edfc 100644 GIT binary patch delta 14695 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 # -# Requires Calibre version 0.7.55 or higher. -# # All credit given to i♥cabbages and The Dark Reverser for the original standalone scripts. # We had the much easier job of converting them to a calibre plugin. # @@ -49,6 +47,7 @@ __docformat__ = 'restructuredtext en' # 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging # 6.3.6 - Fixes for ADE ePub and PDF introduced in 6.3.5 # 6.4.0 - Updated for new Kindle for PC encryption +# 6.4.1 - Fix for some new tags in Topaz ebooks. """ @@ -56,7 +55,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 4, 0) +PLUGIN_VERSION_TUPLE = (6, 4, 1) 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' diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/convert2xml.py b/DeDRM_calibre_plugin/DeDRM_plugin/convert2xml.py index 101c45a..bbb7b04 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/convert2xml.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/convert2xml.py @@ -164,6 +164,7 @@ class PageParser(object): self.id = os.path.basename(filename).replace('.dat','') self.dict = dict self.debug = debug + self.first_unknown = True self.flat_xml = flat_xml self.tagpath = [] self.doc = [] @@ -262,6 +263,9 @@ class PageParser(object): 'img.w' : (1, 'scalar_number', 0, 0), 'img.src' : (1, 'scalar_number', 0, 0), 'img.color_src' : (1, 'scalar_number', 0, 0), + 'img.gridSize' : (1, 'scalar_number', 0, 0), + 'img.gridBottomCenter' : (1, 'scalar_number', 0, 0), + 'img.gridTopCenter' : (1, 'scalar_number', 0, 0), 'img.gridBeginCenter' : (1, 'scalar_number', 0, 0), 'img.gridEndCenter' : (1, 'scalar_number', 0, 0), 'img.image_type' : (1, 'scalar_number', 0, 0), @@ -506,8 +510,9 @@ class PageParser(object): # or an out of sync condition else: result = [] - if (self.debug): + if (self.debug or self.first_unknown): print 'Unknown Token:', token + self.first_unknown = False self.tag_pop() return result