tools v5.6.1
This commit is contained in:
parent
c23b903420
commit
490ee4e5d8
|
@ -1,4 +1,4 @@
|
||||||
Kindle and Mobipocket Plugin - K4MobiDeDRM_v04.18_plugin.zip
|
Kindle and Mobipocket Plugin - K4MobiDeDRM_v04.19_plugin.zip
|
||||||
============================================================
|
============================================================
|
||||||
|
|
||||||
Credit given to The Dark Reverser for the original standalone script. Credit also to the many people who have updated and expanded that script since then.
|
Credit given to The Dark Reverser for the original standalone script. Credit also to the many people who have updated and expanded that script since then.
|
||||||
|
@ -13,7 +13,7 @@ This plugin is meant to remove the DRM from .prc, .mobi, .azw, .azw1, .azw3, .az
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Do **NOT** select "Get plugins to enhance calibre" as this is reserved for "official" calibre plugins, instead select "Change calibre behavior" to go to Calibre's Preferences page. Under "Advanced" click on the Plugins button. Use the "Load plugin from file" button to select the plugin's zip file (K4MobiDeDRM_v04.18_plugin.zip) and click the 'Add' button. Click 'Yes' in the the "Are you sure?" dialog. Click OK in the "Success" dialog.
|
Do **NOT** select "Get plugins to enhance calibre" as this is reserved for "official" calibre plugins, instead select "Change calibre behavior" to go to Calibre's Preferences page. Under "Advanced" click on the Plugins button. Use the "Load plugin from file" button to select the plugin's zip file (K4MobiDeDRM_v04.19_plugin.zip) and click the 'Add' button. Click 'Yes' in the the "Are you sure?" dialog. Click OK in the "Success" dialog.
|
||||||
|
|
||||||
Make sure that you delete any old versions of the plugin. They might interfere with the operation of the new one.
|
Make sure that you delete any old versions of the plugin. They might interfere with the operation of the new one.
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,14 @@ __docformat__ = 'restructuredtext en'
|
||||||
# 0.4.16 - Yet another Topaz fix
|
# 0.4.16 - Yet another Topaz fix
|
||||||
# 0.4.17 - Manage to include the actual fix.
|
# 0.4.17 - Manage to include the actual fix.
|
||||||
# 0.4.18 - More Topaz fixes
|
# 0.4.18 - More Topaz fixes
|
||||||
|
# 0.4.19 - MobiDeDRM PalmDoc fix
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Decrypt Amazon Kindle and Mobipocket encrypted ebooks.
|
Decrypt Amazon Kindle and Mobipocket encrypted ebooks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PLUGIN_NAME = u"Kindle and Mobipocket DeDRM"
|
PLUGIN_NAME = u"Kindle and Mobipocket DeDRM"
|
||||||
PLUGIN_VERSION_TUPLE = (0, 4, 18)
|
PLUGIN_VERSION_TUPLE = (0, 4, 19)
|
||||||
PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE])
|
PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE])
|
||||||
|
|
||||||
import sys, os, re
|
import sys, os, re
|
||||||
|
|
|
@ -34,10 +34,14 @@ def _load_libalfcrypto():
|
||||||
else:
|
else:
|
||||||
name_of_lib = 'libalfcrypto64.so'
|
name_of_lib = 'libalfcrypto64.so'
|
||||||
|
|
||||||
|
# hard code to local location for libalfcrypto
|
||||||
libalfcrypto = os.path.join(sys.path[0],name_of_lib)
|
libalfcrypto = os.path.join(sys.path[0],name_of_lib)
|
||||||
|
|
||||||
if not os.path.isfile(libalfcrypto):
|
if not os.path.isfile(libalfcrypto):
|
||||||
raise Exception('libalfcrypto not found')
|
libalfcrypto = os.path.join(sys.path[0], 'lib', name_of_lib)
|
||||||
|
if not os.path.isfile(libalfcrypto):
|
||||||
|
libalfcrypto = os.path.join('.',name_of_lib)
|
||||||
|
if not os.path.isfile(libalfcrypto):
|
||||||
|
raise Exception('libalfcrypto not found at %s' % libalfcrypto)
|
||||||
|
|
||||||
libalfcrypto = CDLL(libalfcrypto)
|
libalfcrypto = CDLL(libalfcrypto)
|
||||||
|
|
||||||
|
|
|
@ -248,6 +248,7 @@ def decryptBook(infile, outdir, kInfoFiles, serials, pids):
|
||||||
|
|
||||||
# remove internal temporary directory of Topaz pieces
|
# remove internal temporary directory of Topaz pieces
|
||||||
book.cleanup()
|
book.cleanup()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def usage(progname):
|
def usage(progname):
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
# 0.2 Added support for generating PID for iPhone (thanks to mbp)
|
# 0.2 Added support for generating PID for iPhone (thanks to mbp)
|
||||||
# 0.3 changed to autoflush stdout, fixed return code usage
|
# 0.3 changed to autoflush stdout, fixed return code usage
|
||||||
# 0.3 updated for unicode
|
# 0.3 updated for unicode
|
||||||
|
# 0.4 Added support for serial numbers starting with '9', fixed unicode bugs.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import binascii
|
import binascii
|
||||||
|
@ -63,7 +64,7 @@ def unicode_argv():
|
||||||
xrange(start, argc.value)]
|
xrange(start, argc.value)]
|
||||||
# if we don't have any arguments at all, just pass back script name
|
# if we don't have any arguments at all, just pass back script name
|
||||||
# this should never happen
|
# this should never happen
|
||||||
return [u"mobidedrm.py"]
|
return [u"kindlepid.py"]
|
||||||
else:
|
else:
|
||||||
argvencoding = sys.stdin.encoding
|
argvencoding = sys.stdin.encoding
|
||||||
if argvencoding == None:
|
if argvencoding == None:
|
||||||
|
@ -92,7 +93,6 @@ def checksumPid(s):
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def pidFromSerial(s, l):
|
def pidFromSerial(s, l):
|
||||||
crc = crc32(s)
|
crc = crc32(s)
|
||||||
|
|
||||||
|
@ -113,27 +113,27 @@ def pidFromSerial(s, l):
|
||||||
|
|
||||||
def cli_main(argv=unicode_argv()):
|
def cli_main(argv=unicode_argv()):
|
||||||
print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky"
|
print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky"
|
||||||
if len(sys.argv)==2:
|
if len(argv)==2:
|
||||||
serial = sys.argv[1]
|
serial = argv[1]
|
||||||
else:
|
else:
|
||||||
print u"Usage: kindlepid.py <Kindle Serial Number>/<iPhone/iPod Touch UDID>"
|
print u"Usage: kindlepid.py <Kindle Serial Number>/<iPhone/iPod Touch UDID>"
|
||||||
return 1
|
return 1
|
||||||
if len(serial)==16:
|
if len(serial)==16:
|
||||||
if serial.startswith("B"):
|
if serial.startswith("B") or serial.startswith("9"):
|
||||||
print u"Kindle serial number detected"
|
print u"Kindle serial number detected"
|
||||||
else:
|
else:
|
||||||
print u"Warning: unrecognized serial number. Please recheck input."
|
print u"Warning: unrecognized serial number. Please recheck input."
|
||||||
return 1
|
return 1
|
||||||
pid = pidFromSerial(serial.encode("utf-8"),7)+'*'
|
pid = pidFromSerial(serial.encode("utf-8"),7)+'*'
|
||||||
print u"Mobipocket PID for Kindle serial#{0} is {1} ".format(serial,checksumPid(pid))
|
print u"Mobipocket PID for Kindle serial#{0} is {1}".format(serial,checksumPid(pid))
|
||||||
return 0
|
return 0
|
||||||
elif len(serial)==40:
|
elif len(serial)==40:
|
||||||
print u"iPhone serial number (UDID) detected"
|
print u"iPhone serial number (UDID) detected"
|
||||||
pid = pidFromSerial(serial.encode("utf-8"),8)
|
pid = pidFromSerial(serial.encode("utf-8"),8)
|
||||||
print u"Mobipocket PID for iPhone serial#{0} is {1} ".format(serial,checksumPid(pid))
|
print u"Mobipocket PID for iPhone serial#{0} is {1}".format(serial,checksumPid(pid))
|
||||||
return 0
|
return 0
|
||||||
print u"Warning: unrecognized serial number. Please recheck input."
|
print u"Warning: unrecognized serial number. Please recheck input."
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Binary file not shown.
|
@ -208,7 +208,7 @@ CryptUnprotectData = CryptUnprotectData()
|
||||||
def getKindleInfoFiles():
|
def getKindleInfoFiles():
|
||||||
kInfoFiles = []
|
kInfoFiles = []
|
||||||
# some 64 bit machines do not have the proper registry key for some reason
|
# some 64 bit machines do not have the proper registry key for some reason
|
||||||
# or the pythonn interface to the 32 vs 64 bit registry is broken
|
# or the python interface to the 32 vs 64 bit registry is broken
|
||||||
path = ""
|
path = ""
|
||||||
if 'LOCALAPPDATA' in os.environ.keys():
|
if 'LOCALAPPDATA' in os.environ.keys():
|
||||||
path = os.environ['LOCALAPPDATA']
|
path = os.environ['LOCALAPPDATA']
|
||||||
|
@ -217,17 +217,17 @@ def getKindleInfoFiles():
|
||||||
try:
|
try:
|
||||||
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\")
|
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\")
|
||||||
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
||||||
|
except WindowsError:
|
||||||
|
pass
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
path = ""
|
||||||
|
try:
|
||||||
|
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
|
||||||
|
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
||||||
|
except WindowsError:
|
||||||
|
pass
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
path = ""
|
path = ""
|
||||||
try:
|
|
||||||
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
|
|
||||||
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
|
||||||
if not os.path.isdir(path):
|
|
||||||
path = ""
|
|
||||||
except RegError:
|
|
||||||
pass
|
|
||||||
except RegError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
found = False
|
found = False
|
||||||
if path == "":
|
if path == "":
|
||||||
|
|
|
@ -66,9 +66,10 @@
|
||||||
# 0.36 - fixed problem with TEXtREAd and getBookTitle interface
|
# 0.36 - fixed problem with TEXtREAd and getBookTitle interface
|
||||||
# 0.37 - Fixed double announcement for stand-alone operation
|
# 0.37 - Fixed double announcement for stand-alone operation
|
||||||
# 0.38 - Unicode used wherever possible, cope with absent alfcrypto
|
# 0.38 - Unicode used wherever possible, cope with absent alfcrypto
|
||||||
|
# 0.39 - Fixed problem with TEXtREAd and getBookType interface
|
||||||
|
|
||||||
|
|
||||||
__version__ = u"0.38"
|
__version__ = u"0.39"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
@ -268,19 +269,22 @@ class MobiBook:
|
||||||
self.records, = struct.unpack('>H', self.sect[0x8:0x8+2])
|
self.records, = struct.unpack('>H', self.sect[0x8:0x8+2])
|
||||||
self.compression, = struct.unpack('>H', self.sect[0x0:0x0+2])
|
self.compression, = struct.unpack('>H', self.sect[0x0:0x0+2])
|
||||||
|
|
||||||
|
# det default values before PalmDoc test
|
||||||
|
self.print_replica = False
|
||||||
|
self.extra_data_flags = 0
|
||||||
|
self.meta_array = {}
|
||||||
|
self.mobi_length = 0
|
||||||
|
self.mobi_codepage = 1252
|
||||||
|
self.mobi_version = -1
|
||||||
|
|
||||||
if self.magic == 'TEXtREAd':
|
if self.magic == 'TEXtREAd':
|
||||||
print u"PalmDoc format book detected."
|
print u"PalmDoc format book detected."
|
||||||
self.extra_data_flags = 0
|
|
||||||
self.mobi_length = 0
|
|
||||||
self.mobi_codepage = 1252
|
|
||||||
self.mobi_version = -1
|
|
||||||
self.meta_array = {}
|
|
||||||
return
|
return
|
||||||
|
|
||||||
self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18])
|
self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18])
|
||||||
self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20])
|
self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20])
|
||||||
self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C])
|
self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C])
|
||||||
print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length)
|
print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length)
|
||||||
self.extra_data_flags = 0
|
|
||||||
if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5):
|
if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5):
|
||||||
self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4])
|
self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4])
|
||||||
print u"Extra Data Flags: {0:d}".format(self.extra_data_flags)
|
print u"Extra Data Flags: {0:d}".format(self.extra_data_flags)
|
||||||
|
@ -290,7 +294,6 @@ class MobiBook:
|
||||||
self.extra_data_flags &= 0xFFFE
|
self.extra_data_flags &= 0xFFFE
|
||||||
|
|
||||||
# if exth region exists parse it for metadata array
|
# if exth region exists parse it for metadata array
|
||||||
self.meta_array = {}
|
|
||||||
try:
|
try:
|
||||||
exth_flag, = struct.unpack('>L', self.sect[0x80:0x84])
|
exth_flag, = struct.unpack('>L', self.sect[0x80:0x84])
|
||||||
exth = ''
|
exth = ''
|
||||||
|
@ -313,9 +316,7 @@ class MobiBook:
|
||||||
# print type, size, content, content.encode('hex')
|
# print type, size, content, content.encode('hex')
|
||||||
pos += size
|
pos += size
|
||||||
except:
|
except:
|
||||||
self.meta_array = {}
|
|
||||||
pass
|
pass
|
||||||
self.print_replica = False
|
|
||||||
|
|
||||||
def getBookTitle(self):
|
def getBookTitle(self):
|
||||||
codec_map = {
|
codec_map = {
|
||||||
|
@ -406,7 +407,9 @@ class MobiBook:
|
||||||
return u"Print Replica"
|
return u"Print Replica"
|
||||||
if self.mobi_version >= 8:
|
if self.mobi_version >= 8:
|
||||||
return u"Kindle Format 8"
|
return u"Kindle Format 8"
|
||||||
return u"Mobipocket"
|
if self.mobi_version >= 0:
|
||||||
|
return u"Mobipocket {0:d}".format(self.mobi_version)
|
||||||
|
return u"PalmDoc"
|
||||||
|
|
||||||
def getBookExtension(self):
|
def getBookExtension(self):
|
||||||
if self.print_replica:
|
if self.print_replica:
|
||||||
|
|
|
@ -41,7 +41,7 @@ Mac OS X 10.5 and above: You do
|
||||||
\i not
|
\i not
|
||||||
\i0 need to install Python.\
|
\i0 need to install Python.\
|
||||||
\
|
\
|
||||||
Drag the DeDRM application from from tools_v5.6\\DeDRM_Applications\\Macintosh (the location of this ReadMe) to your Applications folder, or anywhere else you find convenient.\
|
Drag the DeDRM application from from tools_v5.6.1\\DeDRM_Applications\\Macintosh (the location of this ReadMe) to your Applications folder, or anywhere else you find convenient.\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
|
|
||||||
|
|
|
@ -24,17 +24,17 @@
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>droplet</string>
|
<string>droplet</string>
|
||||||
<key>CFBundleGetInfoString</key>
|
<key>CFBundleGetInfoString</key>
|
||||||
<string>DeDRM 5.6. AppleScript written 2010–2013 by Apprentice Alf and others.</string>
|
<string>DeDRM 5.6.1. AppleScript written 2010–2013 by Apprentice Alf and others.</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>DeDRM</string>
|
<string>DeDRM</string>
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>DeDRM 5.6</string>
|
<string>DeDRM 5.6.1</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>5.6</string>
|
<string>5.6.1</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>dplt</string>
|
<string>dplt</string>
|
||||||
<key>LSRequiresCarbon</key>
|
<key>LSRequiresCarbon</key>
|
||||||
|
|
Binary file not shown.
|
@ -208,7 +208,7 @@ CryptUnprotectData = CryptUnprotectData()
|
||||||
def getKindleInfoFiles():
|
def getKindleInfoFiles():
|
||||||
kInfoFiles = []
|
kInfoFiles = []
|
||||||
# some 64 bit machines do not have the proper registry key for some reason
|
# some 64 bit machines do not have the proper registry key for some reason
|
||||||
# or the pythonn interface to the 32 vs 64 bit registry is broken
|
# or the python interface to the 32 vs 64 bit registry is broken
|
||||||
path = ""
|
path = ""
|
||||||
if 'LOCALAPPDATA' in os.environ.keys():
|
if 'LOCALAPPDATA' in os.environ.keys():
|
||||||
path = os.environ['LOCALAPPDATA']
|
path = os.environ['LOCALAPPDATA']
|
||||||
|
@ -217,17 +217,17 @@ def getKindleInfoFiles():
|
||||||
try:
|
try:
|
||||||
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\")
|
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\")
|
||||||
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
||||||
|
except WindowsError:
|
||||||
|
pass
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
path = ""
|
||||||
|
try:
|
||||||
|
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
|
||||||
|
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
||||||
|
except WindowsError:
|
||||||
|
pass
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
path = ""
|
path = ""
|
||||||
try:
|
|
||||||
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
|
|
||||||
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
|
||||||
if not os.path.isdir(path):
|
|
||||||
path = ""
|
|
||||||
except RegError:
|
|
||||||
pass
|
|
||||||
except RegError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
found = False
|
found = False
|
||||||
if path == "":
|
if path == "":
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
# 0.2 Added support for generating PID for iPhone (thanks to mbp)
|
# 0.2 Added support for generating PID for iPhone (thanks to mbp)
|
||||||
# 0.3 changed to autoflush stdout, fixed return code usage
|
# 0.3 changed to autoflush stdout, fixed return code usage
|
||||||
# 0.3 updated for unicode
|
# 0.3 updated for unicode
|
||||||
|
# 0.4 Added support for serial numbers starting with '9', fixed unicode bugs.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import binascii
|
import binascii
|
||||||
|
@ -63,7 +64,7 @@ def unicode_argv():
|
||||||
xrange(start, argc.value)]
|
xrange(start, argc.value)]
|
||||||
# if we don't have any arguments at all, just pass back script name
|
# if we don't have any arguments at all, just pass back script name
|
||||||
# this should never happen
|
# this should never happen
|
||||||
return [u"mobidedrm.py"]
|
return [u"kindlepid.py"]
|
||||||
else:
|
else:
|
||||||
argvencoding = sys.stdin.encoding
|
argvencoding = sys.stdin.encoding
|
||||||
if argvencoding == None:
|
if argvencoding == None:
|
||||||
|
@ -92,7 +93,6 @@ def checksumPid(s):
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def pidFromSerial(s, l):
|
def pidFromSerial(s, l):
|
||||||
crc = crc32(s)
|
crc = crc32(s)
|
||||||
|
|
||||||
|
@ -113,27 +113,27 @@ def pidFromSerial(s, l):
|
||||||
|
|
||||||
def cli_main(argv=unicode_argv()):
|
def cli_main(argv=unicode_argv()):
|
||||||
print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky"
|
print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky"
|
||||||
if len(sys.argv)==2:
|
if len(argv)==2:
|
||||||
serial = sys.argv[1]
|
serial = argv[1]
|
||||||
else:
|
else:
|
||||||
print u"Usage: kindlepid.py <Kindle Serial Number>/<iPhone/iPod Touch UDID>"
|
print u"Usage: kindlepid.py <Kindle Serial Number>/<iPhone/iPod Touch UDID>"
|
||||||
return 1
|
return 1
|
||||||
if len(serial)==16:
|
if len(serial)==16:
|
||||||
if serial.startswith("B"):
|
if serial.startswith("B") or serial.startswith("9"):
|
||||||
print u"Kindle serial number detected"
|
print u"Kindle serial number detected"
|
||||||
else:
|
else:
|
||||||
print u"Warning: unrecognized serial number. Please recheck input."
|
print u"Warning: unrecognized serial number. Please recheck input."
|
||||||
return 1
|
return 1
|
||||||
pid = pidFromSerial(serial.encode("utf-8"),7)+'*'
|
pid = pidFromSerial(serial.encode("utf-8"),7)+'*'
|
||||||
print u"Mobipocket PID for Kindle serial#{0} is {1} ".format(serial,checksumPid(pid))
|
print u"Mobipocket PID for Kindle serial#{0} is {1}".format(serial,checksumPid(pid))
|
||||||
return 0
|
return 0
|
||||||
elif len(serial)==40:
|
elif len(serial)==40:
|
||||||
print u"iPhone serial number (UDID) detected"
|
print u"iPhone serial number (UDID) detected"
|
||||||
pid = pidFromSerial(serial.encode("utf-8"),8)
|
pid = pidFromSerial(serial.encode("utf-8"),8)
|
||||||
print u"Mobipocket PID for iPhone serial#{0} is {1} ".format(serial,checksumPid(pid))
|
print u"Mobipocket PID for iPhone serial#{0} is {1}".format(serial,checksumPid(pid))
|
||||||
return 0
|
return 0
|
||||||
print u"Warning: unrecognized serial number. Please recheck input."
|
print u"Warning: unrecognized serial number. Please recheck input."
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -66,9 +66,10 @@
|
||||||
# 0.36 - fixed problem with TEXtREAd and getBookTitle interface
|
# 0.36 - fixed problem with TEXtREAd and getBookTitle interface
|
||||||
# 0.37 - Fixed double announcement for stand-alone operation
|
# 0.37 - Fixed double announcement for stand-alone operation
|
||||||
# 0.38 - Unicode used wherever possible, cope with absent alfcrypto
|
# 0.38 - Unicode used wherever possible, cope with absent alfcrypto
|
||||||
|
# 0.39 - Fixed problem with TEXtREAd and getBookType interface
|
||||||
|
|
||||||
|
|
||||||
__version__ = u"0.38"
|
__version__ = u"0.39"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
@ -268,19 +269,22 @@ class MobiBook:
|
||||||
self.records, = struct.unpack('>H', self.sect[0x8:0x8+2])
|
self.records, = struct.unpack('>H', self.sect[0x8:0x8+2])
|
||||||
self.compression, = struct.unpack('>H', self.sect[0x0:0x0+2])
|
self.compression, = struct.unpack('>H', self.sect[0x0:0x0+2])
|
||||||
|
|
||||||
|
# det default values before PalmDoc test
|
||||||
|
self.print_replica = False
|
||||||
|
self.extra_data_flags = 0
|
||||||
|
self.meta_array = {}
|
||||||
|
self.mobi_length = 0
|
||||||
|
self.mobi_codepage = 1252
|
||||||
|
self.mobi_version = -1
|
||||||
|
|
||||||
if self.magic == 'TEXtREAd':
|
if self.magic == 'TEXtREAd':
|
||||||
print u"PalmDoc format book detected."
|
print u"PalmDoc format book detected."
|
||||||
self.extra_data_flags = 0
|
|
||||||
self.mobi_length = 0
|
|
||||||
self.mobi_codepage = 1252
|
|
||||||
self.mobi_version = -1
|
|
||||||
self.meta_array = {}
|
|
||||||
return
|
return
|
||||||
|
|
||||||
self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18])
|
self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18])
|
||||||
self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20])
|
self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20])
|
||||||
self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C])
|
self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C])
|
||||||
print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length)
|
print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length)
|
||||||
self.extra_data_flags = 0
|
|
||||||
if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5):
|
if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5):
|
||||||
self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4])
|
self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4])
|
||||||
print u"Extra Data Flags: {0:d}".format(self.extra_data_flags)
|
print u"Extra Data Flags: {0:d}".format(self.extra_data_flags)
|
||||||
|
@ -290,7 +294,6 @@ class MobiBook:
|
||||||
self.extra_data_flags &= 0xFFFE
|
self.extra_data_flags &= 0xFFFE
|
||||||
|
|
||||||
# if exth region exists parse it for metadata array
|
# if exth region exists parse it for metadata array
|
||||||
self.meta_array = {}
|
|
||||||
try:
|
try:
|
||||||
exth_flag, = struct.unpack('>L', self.sect[0x80:0x84])
|
exth_flag, = struct.unpack('>L', self.sect[0x80:0x84])
|
||||||
exth = ''
|
exth = ''
|
||||||
|
@ -313,9 +316,7 @@ class MobiBook:
|
||||||
# print type, size, content, content.encode('hex')
|
# print type, size, content, content.encode('hex')
|
||||||
pos += size
|
pos += size
|
||||||
except:
|
except:
|
||||||
self.meta_array = {}
|
|
||||||
pass
|
pass
|
||||||
self.print_replica = False
|
|
||||||
|
|
||||||
def getBookTitle(self):
|
def getBookTitle(self):
|
||||||
codec_map = {
|
codec_map = {
|
||||||
|
@ -406,7 +407,9 @@ class MobiBook:
|
||||||
return u"Print Replica"
|
return u"Print Replica"
|
||||||
if self.mobi_version >= 8:
|
if self.mobi_version >= 8:
|
||||||
return u"Kindle Format 8"
|
return u"Kindle Format 8"
|
||||||
return u"Mobipocket"
|
if self.mobi_version >= 0:
|
||||||
|
return u"Mobipocket {0:d}".format(self.mobi_version)
|
||||||
|
return u"PalmDoc"
|
||||||
|
|
||||||
def getBookExtension(self):
|
def getBookExtension(self):
|
||||||
if self.print_replica:
|
if self.print_replica:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
echo off
|
echo off
|
||||||
set PWD=%~dp0
|
set PWD=%~dp0
|
||||||
cd /d %PWD%\DeDRM_lib && start /min python DeDRM_app.pyw %*
|
cd /d %PWD%DeDRM_lib && start /min python DeDRM_app.pyw %*
|
||||||
exit
|
exit
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# DeDRM.pyw, version 5.6
|
# DeDRM.pyw, version 5.6.1
|
||||||
# By some_updates and Apprentice Alf
|
# By some_updates and Apprentice Alf
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
@ -34,23 +34,19 @@ from scriptinterface import decryptepub, decryptpdb, decryptpdf, decryptk4mobi
|
||||||
|
|
||||||
# Wrap a stream so that output gets flushed immediately
|
# Wrap a stream so that output gets flushed immediately
|
||||||
# and appended to shared queue
|
# and appended to shared queue
|
||||||
class QueuedStream:
|
class QueuedUTF8Stream:
|
||||||
def __init__(self, stream, q):
|
def __init__(self, stream, q):
|
||||||
self.stream = stream
|
self.stream = stream
|
||||||
self.encoding = stream.encoding
|
self.encoding = 'utf-8'
|
||||||
self.q = q
|
self.q = q
|
||||||
if self.encoding == None:
|
|
||||||
self.encoding = "utf-8"
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
if isinstance(data,unicode):
|
if isinstance(data,unicode):
|
||||||
data = data.encode(self.encoding,"replace")
|
data = data.encode('utf-8',"replace")
|
||||||
self.q.put(data)
|
self.q.put(data)
|
||||||
# self.stream.write(data)
|
|
||||||
# self.stream.flush()
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
return getattr(self.stream, attr)
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
__version__ = '5.6'
|
__version__ = '5.6.1'
|
||||||
|
|
||||||
class DrmException(Exception):
|
class DrmException(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -280,7 +276,7 @@ class PrefsDialog(Toplevel):
|
||||||
def get_altinfopath(self):
|
def get_altinfopath(self):
|
||||||
cpath = self.altinfopath.get()
|
cpath = self.altinfopath.get()
|
||||||
altinfopath = tkFileDialog.askopenfilename(parent=None, title='Select Alternative kindle.info or .kinf File',
|
altinfopath = tkFileDialog.askopenfilename(parent=None, title='Select Alternative kindle.info or .kinf File',
|
||||||
defaultextension='.info', filetypes=[('Kindle Info', '.info'),('Kindle KInf','.kinf')('All Files', '.*')],
|
defaultextension='.info', filetypes=[('Kindle Info', '.info'),('Kindle KInf','.kinf'),('All Files', '.*')],
|
||||||
initialdir=cpath)
|
initialdir=cpath)
|
||||||
if altinfopath:
|
if altinfopath:
|
||||||
altinfopath = os.path.normpath(altinfopath)
|
altinfopath = os.path.normpath(altinfopath)
|
||||||
|
@ -291,17 +287,17 @@ class PrefsDialog(Toplevel):
|
||||||
def get_bookpath(self):
|
def get_bookpath(self):
|
||||||
cpath = self.bookpath.get()
|
cpath = self.bookpath.get()
|
||||||
bookpath = tkFileDialog.askopenfilename(parent=None, title='Select eBook for DRM Removal',
|
bookpath = tkFileDialog.askopenfilename(parent=None, title='Select eBook for DRM Removal',
|
||||||
filetypes=[('ePub Files','.epub'),
|
filetypes=[('All Files', '.*'),
|
||||||
('Kindle','.azw'),
|
('ePub Files','.epub'),
|
||||||
('Kindle','.azw1'),
|
('Kindle','.azw'),
|
||||||
('Kindle','.azw3'),
|
('Kindle','.azw1'),
|
||||||
('Kindle','.azw4'),
|
('Kindle','.azw3'),
|
||||||
('Kindle','.tpz'),
|
('Kindle','.azw4'),
|
||||||
('Kindle','.mobi'),
|
('Kindle','.tpz'),
|
||||||
('Kindle','.prc'),
|
('Kindle','.mobi'),
|
||||||
('eReader','.pdb'),
|
('Kindle','.prc'),
|
||||||
('PDF','.pdf'),
|
('eReader','.pdb'),
|
||||||
('All Files', '.*')],
|
('PDF','.pdf')],
|
||||||
initialdir=cpath)
|
initialdir=cpath)
|
||||||
if bookpath:
|
if bookpath:
|
||||||
bookpath = os.path.normpath(bookpath)
|
bookpath = os.path.normpath(bookpath)
|
||||||
|
@ -412,8 +408,9 @@ class ConvDialog(Toplevel):
|
||||||
self.showCmdOutput(msg)
|
self.showCmdOutput(msg)
|
||||||
if self.numbad == 0:
|
if self.numbad == 0:
|
||||||
self.after(2000,self.conversion_done())
|
self.after(2000,self.conversion_done())
|
||||||
logfile = os.path.join(rscpath,'dedrm.log')
|
logfile = os.path.join(os.path.expanduser('~'),'DeDRM.log')
|
||||||
file(logfile,'wb').write(self.log)
|
file(logfile,'w').write(self.log)
|
||||||
|
self.log=''
|
||||||
return
|
return
|
||||||
infile = filename
|
infile = filename
|
||||||
bname = os.path.basename(infile)
|
bname = os.path.basename(infile)
|
||||||
|
@ -537,8 +534,8 @@ class ConvDialog(Toplevel):
|
||||||
def processK4MOBI(q, infile, outdir, rscpath):
|
def processK4MOBI(q, infile, outdir, rscpath):
|
||||||
add_cp65001_codec()
|
add_cp65001_codec()
|
||||||
set_utf8_default_encoding()
|
set_utf8_default_encoding()
|
||||||
sys.stdout = QueuedStream(sys.stdout, q)
|
sys.stdout = QueuedUTF8Stream(sys.stdout, q)
|
||||||
sys.stderr = QueuedStream(sys.stderr, q)
|
sys.stderr = QueuedUTF8Stream(sys.stderr, q)
|
||||||
rv = decryptk4mobi(infile, outdir, rscpath)
|
rv = decryptk4mobi(infile, outdir, rscpath)
|
||||||
sys.exit(rv)
|
sys.exit(rv)
|
||||||
|
|
||||||
|
@ -546,8 +543,8 @@ def processK4MOBI(q, infile, outdir, rscpath):
|
||||||
def processPDF(q, infile, outdir, rscpath):
|
def processPDF(q, infile, outdir, rscpath):
|
||||||
add_cp65001_codec()
|
add_cp65001_codec()
|
||||||
set_utf8_default_encoding()
|
set_utf8_default_encoding()
|
||||||
sys.stdout = QueuedStream(sys.stdout, q)
|
sys.stdout = QueuedUTF8Stream(sys.stdout, q)
|
||||||
sys.stderr = QueuedStream(sys.stderr, q)
|
sys.stderr = QueuedUTF8Stream(sys.stderr, q)
|
||||||
rv = decryptpdf(infile, outdir, rscpath)
|
rv = decryptpdf(infile, outdir, rscpath)
|
||||||
sys.exit(rv)
|
sys.exit(rv)
|
||||||
|
|
||||||
|
@ -555,8 +552,8 @@ def processPDF(q, infile, outdir, rscpath):
|
||||||
def processEPUB(q, infile, outdir, rscpath):
|
def processEPUB(q, infile, outdir, rscpath):
|
||||||
add_cp65001_codec()
|
add_cp65001_codec()
|
||||||
set_utf8_default_encoding()
|
set_utf8_default_encoding()
|
||||||
sys.stdout = QueuedStream(sys.stdout, q)
|
sys.stdout = QueuedUTF8Stream(sys.stdout, q)
|
||||||
sys.stderr = QueuedStream(sys.stderr, q)
|
sys.stderr = QueuedUTF8Stream(sys.stderr, q)
|
||||||
rv = decryptepub(infile, outdir, rscpath)
|
rv = decryptepub(infile, outdir, rscpath)
|
||||||
sys.exit(rv)
|
sys.exit(rv)
|
||||||
|
|
||||||
|
@ -564,8 +561,8 @@ def processEPUB(q, infile, outdir, rscpath):
|
||||||
def processPDB(q, infile, outdir, rscpath):
|
def processPDB(q, infile, outdir, rscpath):
|
||||||
add_cp65001_codec()
|
add_cp65001_codec()
|
||||||
set_utf8_default_encoding()
|
set_utf8_default_encoding()
|
||||||
sys.stdout = QueuedStream(sys.stdout, q)
|
sys.stdout = QueuedUTF8Stream(sys.stdout, q)
|
||||||
sys.stderr = QueuedStream(sys.stderr, q)
|
sys.stderr = QueuedUTF8Stream(sys.stderr, q)
|
||||||
rv = decryptpdb(infile, outdir, rscpath)
|
rv = decryptpdb(infile, outdir, rscpath)
|
||||||
sys.exit(rv)
|
sys.exit(rv)
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,7 @@ CryptUnprotectData = CryptUnprotectData()
|
||||||
def getKindleInfoFiles():
|
def getKindleInfoFiles():
|
||||||
kInfoFiles = []
|
kInfoFiles = []
|
||||||
# some 64 bit machines do not have the proper registry key for some reason
|
# some 64 bit machines do not have the proper registry key for some reason
|
||||||
# or the pythonn interface to the 32 vs 64 bit registry is broken
|
# or the python interface to the 32 vs 64 bit registry is broken
|
||||||
path = ""
|
path = ""
|
||||||
if 'LOCALAPPDATA' in os.environ.keys():
|
if 'LOCALAPPDATA' in os.environ.keys():
|
||||||
path = os.environ['LOCALAPPDATA']
|
path = os.environ['LOCALAPPDATA']
|
||||||
|
@ -217,17 +217,17 @@ def getKindleInfoFiles():
|
||||||
try:
|
try:
|
||||||
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\")
|
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\")
|
||||||
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
||||||
|
except WindowsError:
|
||||||
|
pass
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
path = ""
|
||||||
|
try:
|
||||||
|
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
|
||||||
|
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
||||||
|
except WindowsError:
|
||||||
|
pass
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
path = ""
|
path = ""
|
||||||
try:
|
|
||||||
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
|
|
||||||
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
|
|
||||||
if not os.path.isdir(path):
|
|
||||||
path = ""
|
|
||||||
except RegError:
|
|
||||||
pass
|
|
||||||
except RegError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
found = False
|
found = False
|
||||||
if path == "":
|
if path == "":
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
# 0.2 Added support for generating PID for iPhone (thanks to mbp)
|
# 0.2 Added support for generating PID for iPhone (thanks to mbp)
|
||||||
# 0.3 changed to autoflush stdout, fixed return code usage
|
# 0.3 changed to autoflush stdout, fixed return code usage
|
||||||
# 0.3 updated for unicode
|
# 0.3 updated for unicode
|
||||||
|
# 0.4 Added support for serial numbers starting with '9', fixed unicode bugs.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import binascii
|
import binascii
|
||||||
|
@ -63,7 +64,7 @@ def unicode_argv():
|
||||||
xrange(start, argc.value)]
|
xrange(start, argc.value)]
|
||||||
# if we don't have any arguments at all, just pass back script name
|
# if we don't have any arguments at all, just pass back script name
|
||||||
# this should never happen
|
# this should never happen
|
||||||
return [u"mobidedrm.py"]
|
return [u"kindlepid.py"]
|
||||||
else:
|
else:
|
||||||
argvencoding = sys.stdin.encoding
|
argvencoding = sys.stdin.encoding
|
||||||
if argvencoding == None:
|
if argvencoding == None:
|
||||||
|
@ -92,7 +93,6 @@ def checksumPid(s):
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def pidFromSerial(s, l):
|
def pidFromSerial(s, l):
|
||||||
crc = crc32(s)
|
crc = crc32(s)
|
||||||
|
|
||||||
|
@ -113,27 +113,27 @@ def pidFromSerial(s, l):
|
||||||
|
|
||||||
def cli_main(argv=unicode_argv()):
|
def cli_main(argv=unicode_argv()):
|
||||||
print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky"
|
print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky"
|
||||||
if len(sys.argv)==2:
|
if len(argv)==2:
|
||||||
serial = sys.argv[1]
|
serial = argv[1]
|
||||||
else:
|
else:
|
||||||
print u"Usage: kindlepid.py <Kindle Serial Number>/<iPhone/iPod Touch UDID>"
|
print u"Usage: kindlepid.py <Kindle Serial Number>/<iPhone/iPod Touch UDID>"
|
||||||
return 1
|
return 1
|
||||||
if len(serial)==16:
|
if len(serial)==16:
|
||||||
if serial.startswith("B"):
|
if serial.startswith("B") or serial.startswith("9"):
|
||||||
print u"Kindle serial number detected"
|
print u"Kindle serial number detected"
|
||||||
else:
|
else:
|
||||||
print u"Warning: unrecognized serial number. Please recheck input."
|
print u"Warning: unrecognized serial number. Please recheck input."
|
||||||
return 1
|
return 1
|
||||||
pid = pidFromSerial(serial.encode("utf-8"),7)+'*'
|
pid = pidFromSerial(serial.encode("utf-8"),7)+'*'
|
||||||
print u"Mobipocket PID for Kindle serial#{0} is {1} ".format(serial,checksumPid(pid))
|
print u"Mobipocket PID for Kindle serial#{0} is {1}".format(serial,checksumPid(pid))
|
||||||
return 0
|
return 0
|
||||||
elif len(serial)==40:
|
elif len(serial)==40:
|
||||||
print u"iPhone serial number (UDID) detected"
|
print u"iPhone serial number (UDID) detected"
|
||||||
pid = pidFromSerial(serial.encode("utf-8"),8)
|
pid = pidFromSerial(serial.encode("utf-8"),8)
|
||||||
print u"Mobipocket PID for iPhone serial#{0} is {1} ".format(serial,checksumPid(pid))
|
print u"Mobipocket PID for iPhone serial#{0} is {1}".format(serial,checksumPid(pid))
|
||||||
return 0
|
return 0
|
||||||
print u"Warning: unrecognized serial number. Please recheck input."
|
print u"Warning: unrecognized serial number. Please recheck input."
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -66,9 +66,10 @@
|
||||||
# 0.36 - fixed problem with TEXtREAd and getBookTitle interface
|
# 0.36 - fixed problem with TEXtREAd and getBookTitle interface
|
||||||
# 0.37 - Fixed double announcement for stand-alone operation
|
# 0.37 - Fixed double announcement for stand-alone operation
|
||||||
# 0.38 - Unicode used wherever possible, cope with absent alfcrypto
|
# 0.38 - Unicode used wherever possible, cope with absent alfcrypto
|
||||||
|
# 0.39 - Fixed problem with TEXtREAd and getBookType interface
|
||||||
|
|
||||||
|
|
||||||
__version__ = u"0.38"
|
__version__ = u"0.39"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
@ -268,19 +269,22 @@ class MobiBook:
|
||||||
self.records, = struct.unpack('>H', self.sect[0x8:0x8+2])
|
self.records, = struct.unpack('>H', self.sect[0x8:0x8+2])
|
||||||
self.compression, = struct.unpack('>H', self.sect[0x0:0x0+2])
|
self.compression, = struct.unpack('>H', self.sect[0x0:0x0+2])
|
||||||
|
|
||||||
|
# det default values before PalmDoc test
|
||||||
|
self.print_replica = False
|
||||||
|
self.extra_data_flags = 0
|
||||||
|
self.meta_array = {}
|
||||||
|
self.mobi_length = 0
|
||||||
|
self.mobi_codepage = 1252
|
||||||
|
self.mobi_version = -1
|
||||||
|
|
||||||
if self.magic == 'TEXtREAd':
|
if self.magic == 'TEXtREAd':
|
||||||
print u"PalmDoc format book detected."
|
print u"PalmDoc format book detected."
|
||||||
self.extra_data_flags = 0
|
|
||||||
self.mobi_length = 0
|
|
||||||
self.mobi_codepage = 1252
|
|
||||||
self.mobi_version = -1
|
|
||||||
self.meta_array = {}
|
|
||||||
return
|
return
|
||||||
|
|
||||||
self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18])
|
self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18])
|
||||||
self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20])
|
self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20])
|
||||||
self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C])
|
self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C])
|
||||||
print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length)
|
print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length)
|
||||||
self.extra_data_flags = 0
|
|
||||||
if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5):
|
if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5):
|
||||||
self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4])
|
self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4])
|
||||||
print u"Extra Data Flags: {0:d}".format(self.extra_data_flags)
|
print u"Extra Data Flags: {0:d}".format(self.extra_data_flags)
|
||||||
|
@ -290,7 +294,6 @@ class MobiBook:
|
||||||
self.extra_data_flags &= 0xFFFE
|
self.extra_data_flags &= 0xFFFE
|
||||||
|
|
||||||
# if exth region exists parse it for metadata array
|
# if exth region exists parse it for metadata array
|
||||||
self.meta_array = {}
|
|
||||||
try:
|
try:
|
||||||
exth_flag, = struct.unpack('>L', self.sect[0x80:0x84])
|
exth_flag, = struct.unpack('>L', self.sect[0x80:0x84])
|
||||||
exth = ''
|
exth = ''
|
||||||
|
@ -313,9 +316,7 @@ class MobiBook:
|
||||||
# print type, size, content, content.encode('hex')
|
# print type, size, content, content.encode('hex')
|
||||||
pos += size
|
pos += size
|
||||||
except:
|
except:
|
||||||
self.meta_array = {}
|
|
||||||
pass
|
pass
|
||||||
self.print_replica = False
|
|
||||||
|
|
||||||
def getBookTitle(self):
|
def getBookTitle(self):
|
||||||
codec_map = {
|
codec_map = {
|
||||||
|
@ -406,7 +407,9 @@ class MobiBook:
|
||||||
return u"Print Replica"
|
return u"Print Replica"
|
||||||
if self.mobi_version >= 8:
|
if self.mobi_version >= 8:
|
||||||
return u"Kindle Format 8"
|
return u"Kindle Format 8"
|
||||||
return u"Mobipocket"
|
if self.mobi_version >= 0:
|
||||||
|
return u"Mobipocket {0:d}".format(self.mobi_version)
|
||||||
|
return u"PalmDoc"
|
||||||
|
|
||||||
def getBookExtension(self):
|
def getBookExtension(self):
|
||||||
if self.print_replica:
|
if self.print_replica:
|
||||||
|
|
Loading…
Reference in New Issue