meta_array = getMetaArray(metaFile)
# replace special chars in title and authors like & < >
- title = meta_array['Title']
+ title = meta_array.get('Title','No Title Provided')
title = title.replace('&','&')
title = title.replace('<','<')
title = title.replace('>','>')
meta_array['Title'] = title
- authors = meta_array['Authors']
+ authors = meta_array.get('Authors','No Authors Provided')
authors = authors.replace('&','&')
authors = authors.replace('<','<')
authors = authors.replace('>','>')
htmlstr += '<title>' + meta_array['Title'] + ' by ' + meta_array['Authors'] + '</title>\n'
htmlstr += '<meta name="Author" content="' + meta_array['Authors'] + '" />\n'
htmlstr += '<meta name="Title" content="' + meta_array['Title'] + '" />\n'
- htmlstr += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
- htmlstr += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
+ if 'ASIN' in meta_array:
+ htmlstr += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
+ if 'GUID' in meta_array:
+ htmlstr += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
htmlstr += '<link href="style.css" rel="stylesheet" type="text/css" />\n'
htmlstr += '</head>\n<body>\n'
svgindex += '<title>' + meta_array['Title'] + '</title>\n'
svgindex += '<meta name="Author" content="' + meta_array['Authors'] + '" />\n'
svgindex += '<meta name="Title" content="' + meta_array['Title'] + '" />\n'
- svgindex += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
- svgindex += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
+ if 'ASIN' in meta_array:
+ svgindex += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
+ if 'GUID' in meta_array:
+ svgindex += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
svgindex += '</head>\n'
svgindex += '<body>\n'
opfstr += '<package xmlns="http://www.idpf.org/2007/opf" unique-identifier="guid_id">\n'
# adding metadata
opfstr += ' <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">\n'
- opfstr += ' <dc:identifier opf:scheme="GUID" id="guid_id">' + meta_array['GUID'] + '</dc:identifier>\n'
- opfstr += ' <dc:identifier opf:scheme="ASIN">' + meta_array['ASIN'] + '</dc:identifier>\n'
- opfstr += ' <dc:identifier opf:scheme="oASIN">' + meta_array['oASIN'] + '</dc:identifier>\n'
+ if 'GUID' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="GUID" id="guid_id">' + meta_array['GUID'] + '</dc:identifier>\n'
+ if 'ASIN' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="ASIN">' + meta_array['ASIN'] + '</dc:identifier>\n'
+ if 'oASIN' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="oASIN">' + meta_array['oASIN'] + '</dc:identifier>\n'
opfstr += ' <dc:title>' + meta_array['Title'] + '</dc:title>\n'
opfstr += ' <dc:creator opf:role="aut">' + meta_array['Authors'] + '</dc:creator>\n'
opfstr += ' <dc:language>en</dc:language>\n'
global charMap4
if sys.platform.startswith('win'):
- from k4pcutils import openKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
+ from k4pcutils import getKindleInfoFiles, parseKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
if sys.platform.startswith('darwin'):
- from k4mutils import openKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
+ from k4mutils import getKindleInfoFiles, parseKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
charMap1 = "n5Pr6St7Uv8Wx9YzAb0Cd1Ef2Gh3Jk4M"
charMap3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
result += pack("B",value)
return result
-
-# Parse the Kindle.info file and return the records as a list of key-values
-def parseKindleInfo(kInfoFile):
- DB = {}
- infoReader = openKindleInfo(kInfoFile)
- infoReader.read(1)
- data = infoReader.read()
- if sys.platform.startswith('win'):
- items = data.split('{')
- else :
- items = data.split('[')
- for item in items:
- splito = item.split(':')
- DB[splito[0]] =splito[1]
- return DB
-
# Get a record from the Kindle.info file for the key "hashedKey" (already hashed and encoded).
# Return the decoded and decrypted record
def getKindleInfoValueForHash(hashedKey):
# Parse the EXTH header records and parse the Kindleinfo
# file to calculate the book pid.
-def getK4Pids(pidlst, rec209, token, kInfoFile=None):
+def getK4Pids(pidlst, rec209, token, kInfoFile):
global kindleDatabase
global charMap1
kindleDatabase = None
if kindleDatabase == None :
return pidlst
+
+ try:
+ # Get the Mazama Random number
+ MazamaRandomNumber = getKindleInfoValueForKey("MazamaRandomNumber")
- # Get the Mazama Random number
- MazamaRandomNumber = getKindleInfoValueForKey("MazamaRandomNumber")
-
+ # Get the kindle account token
+ kindleAccountToken = getKindleInfoValueForKey("kindle.account.tokens")
+ except KeyError:
+ print "Keys not found in " + kInfoFile
+ return pidlst
+
# Get the HDD serial
encodedSystemVolumeSerialNumber = encodeHash(GetVolumeSerialNumber(),charMap1)
devicePID = checksumPid(devicePID)
pidlst.append(devicePID)
- # Compute book PID
-
- # Get the kindle account token
- kindleAccountToken = getKindleInfoValueForKey("kindle.account.tokens")
+ # Compute book PIDs
# book pid
pidHash = SHA1(DSN+kindleAccountToken+rec209+token)
def getPidList(md1, md2, k4, pids, serials, kInfoFiles):
pidlst = []
+ if kInfoFiles is None:
+ kInfoFiles = []
if k4:
- pidlst = getK4Pids(pidlst, md1, md2)
+ kInfoFiles = getKindleInfoFiles(kInfoFiles)
for infoFile in kInfoFiles:
pidlst = getK4Pids(pidlst, md1, md2, infoFile)
for serialnum in serials:
# and import that ZIP into Calibre using its plugin configuration GUI.
-__version__ = '2.7'
+__version__ = '2.8'
class Unbuffered:
def __init__(self, stream):
Provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc.'
supported_platforms = ['osx', 'windows', 'linux'] # Platforms this plugin will run on
author = 'DiapDealer, SomeUpdates' # The author of this plugin
- version = (0, 2, 7) # The version number of this plugin
+ version = (0, 2, 8) # The version number of this plugin
file_types = set(['prc','mobi','azw','azw1','tpz']) # The file types that this plugin will be applied to
on_import = True # Run this plugin during the import
priority = 210 # run this plugin before mobidedrm, k4pcdedrm, k4dedrm
return cleartext
-# Locate and open the .kindle-info file
-def openKindleInfo(kInfoFile=None):
- if kInfoFile == None:
- home = os.getenv('HOME')
- cmdline = 'find "' + home + '/Library/Application Support" -name ".kindle-info"'
- cmdline = cmdline.encode(sys.getfilesystemencoding())
- p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
- out1, out2 = p1.communicate()
- reslst = out1.split('\n')
- kinfopath = 'NONE'
- cnt = len(reslst)
- for j in xrange(cnt):
- resline = reslst[j]
- pp = resline.find('.kindle-info')
- if pp >= 0:
- kinfopath = resline
- break
- if not os.path.isfile(kinfopath):
- raise DrmException('Error: .kindle-info file can not be found')
- return open(kinfopath,'r')
- else:
- if not os.path.isfile(kInfoFile):
- raise DrmException('Error: kindle-info file can not be found')
- return open(kInfoFile, 'r')
+# Locate the .kindle-info files
+def getKindleInfoFiles(kInfoFiles):
+ home = os.getenv('HOME')
+ cmdline = 'find "' + home + '/Library/Application Support" -name ".kindle-info"'
+ cmdline = cmdline.encode(sys.getfilesystemencoding())
+ p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
+ out1, out2 = p1.communicate()
+ reslst = out1.split('\n')
+ kinfopath = 'NONE'
+ found = False
+ cnt = len(reslst)
+ for resline in reslst:
+ if os.path.isfile(resline):
+ kInfoFiles.append(resline)
+ found = True
+ if not found:
+ print('No .kindle-info files have been found.')
+ return kInfoFiles
+
+# Parse the Kindle.info file and return the records as a list of key-values
+def parseKindleInfo(kInfoFile):
+ DB = {}
+ infoReader = open(kInfoFile, 'r')
+ infoReader.read(1)
+ data = infoReader.read()
+ items = data.split('[')
+ for item in items:
+ splito = item.split(':')
+ DB[splito[0]] =splito[1]
+ return DB
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
-#
-# Locate and open the Kindle.info file.
-#
-def openKindleInfo(kInfoFile=None):
- if kInfoFile == None:
- regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
- path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
- kinfopath = path +'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info'
- if not os.path.isfile(kinfopath):
- raise DrmException('Error: kindle.info file can not be found')
- return open(kinfopath,'r')
+# Locate the .kindle-info files
+def getKindleInfoFiles(kInfoFiles):
+ regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
+ path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
+ kinfopath = path +'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info'
+ if not os.path.isfile(kinfopath):
+ print('The kindle.info files has not been found.')
else:
- if not os.path.isfile(kInfoFile):
- raise DrmException('Error: kindle.info file can not be found')
- return open(kInfoFile, 'r')
+ kInfoFiles.append(kinfopath)
+ return kInfoFiles
+
+# Parse the Kindle.info file and return the records as a list of key-values
+def parseKindleInfo(kInfoFile):
+ DB = {}
+ infoReader = open(kInfoFile, 'r')
+ infoReader.read(1)
+ data = infoReader.read()
+ items = data.split('{')
+ for item in items:
+ splito = item.split(':')
+ DB[splito[0]] =splito[1]
+ return DB
<key>CFBundleExecutable</key>
<string>droplet</string>
<key>CFBundleGetInfoString</key>
- <string>DeDRM 2.5, Written 2010–2011 by Apprentice Alf and others.</string>
+ <string>DeDRM 2.6, Written 2010–2011 by Apprentice Alf and others.</string>
<key>CFBundleIconFile</key>
<string>droplet</string>
<key>CFBundleInfoDictionaryVersion</key>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>2.5</string>
+ <string>2.6</string>
<key>CFBundleSignature</key>
<string>dplt</string>
<key>LSMinimumSystemVersion</key>
meta_array = getMetaArray(metaFile)
# replace special chars in title and authors like & < >
- title = meta_array['Title']
+ title = meta_array.get('Title','No Title Provided')
title = title.replace('&','&')
title = title.replace('<','<')
title = title.replace('>','>')
meta_array['Title'] = title
- authors = meta_array['Authors']
+ authors = meta_array.get('Authors','No Authors Provided')
authors = authors.replace('&','&')
authors = authors.replace('<','<')
authors = authors.replace('>','>')
htmlstr += '<title>' + meta_array['Title'] + ' by ' + meta_array['Authors'] + '</title>\n'
htmlstr += '<meta name="Author" content="' + meta_array['Authors'] + '" />\n'
htmlstr += '<meta name="Title" content="' + meta_array['Title'] + '" />\n'
- htmlstr += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
- htmlstr += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
+ if 'ASIN' in meta_array:
+ htmlstr += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
+ if 'GUID' in meta_array:
+ htmlstr += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
htmlstr += '<link href="style.css" rel="stylesheet" type="text/css" />\n'
htmlstr += '</head>\n<body>\n'
svgindex += '<title>' + meta_array['Title'] + '</title>\n'
svgindex += '<meta name="Author" content="' + meta_array['Authors'] + '" />\n'
svgindex += '<meta name="Title" content="' + meta_array['Title'] + '" />\n'
- svgindex += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
- svgindex += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
+ if 'ASIN' in meta_array:
+ svgindex += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
+ if 'GUID' in meta_array:
+ svgindex += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
svgindex += '</head>\n'
svgindex += '<body>\n'
opfstr += '<package xmlns="http://www.idpf.org/2007/opf" unique-identifier="guid_id">\n'
# adding metadata
opfstr += ' <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">\n'
- opfstr += ' <dc:identifier opf:scheme="GUID" id="guid_id">' + meta_array['GUID'] + '</dc:identifier>\n'
- opfstr += ' <dc:identifier opf:scheme="ASIN">' + meta_array['ASIN'] + '</dc:identifier>\n'
- opfstr += ' <dc:identifier opf:scheme="oASIN">' + meta_array['oASIN'] + '</dc:identifier>\n'
+ if 'GUID' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="GUID" id="guid_id">' + meta_array['GUID'] + '</dc:identifier>\n'
+ if 'ASIN' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="ASIN">' + meta_array['ASIN'] + '</dc:identifier>\n'
+ if 'oASIN' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="oASIN">' + meta_array['oASIN'] + '</dc:identifier>\n'
opfstr += ' <dc:title>' + meta_array['Title'] + '</dc:title>\n'
opfstr += ' <dc:creator opf:role="aut">' + meta_array['Authors'] + '</dc:creator>\n'
opfstr += ' <dc:language>en</dc:language>\n'
# and import that ZIP into Calibre using its plugin configuration GUI.
-__version__ = '2.7'
+__version__ = '2.8'
class Unbuffered:
def __init__(self, stream):
Provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc.'
supported_platforms = ['osx', 'windows', 'linux'] # Platforms this plugin will run on
author = 'DiapDealer, SomeUpdates' # The author of this plugin
- version = (0, 2, 7) # The version number of this plugin
+ version = (0, 2, 8) # The version number of this plugin
file_types = set(['prc','mobi','azw','azw1','tpz']) # The file types that this plugin will be applied to
on_import = True # Run this plugin during the import
priority = 210 # run this plugin before mobidedrm, k4pcdedrm, k4dedrm
return cleartext
-# Locate and open the .kindle-info file
-def openKindleInfo(kInfoFile=None):
- if kInfoFile == None:
- home = os.getenv('HOME')
- cmdline = 'find "' + home + '/Library/Application Support" -name ".kindle-info"'
- cmdline = cmdline.encode(sys.getfilesystemencoding())
- p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
- out1, out2 = p1.communicate()
- reslst = out1.split('\n')
- kinfopath = 'NONE'
- cnt = len(reslst)
- for j in xrange(cnt):
- resline = reslst[j]
- pp = resline.find('.kindle-info')
- if pp >= 0:
- kinfopath = resline
- break
- if not os.path.isfile(kinfopath):
- raise DrmException('Error: .kindle-info file can not be found')
- return open(kinfopath,'r')
- else:
- if not os.path.isfile(kInfoFile):
- raise DrmException('Error: kindle-info file can not be found')
- return open(kInfoFile, 'r')
+# Locate the .kindle-info files
+def getKindleInfoFiles(kInfoFiles):
+ home = os.getenv('HOME')
+ cmdline = 'find "' + home + '/Library/Application Support" -name ".kindle-info"'
+ cmdline = cmdline.encode(sys.getfilesystemencoding())
+ p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
+ out1, out2 = p1.communicate()
+ reslst = out1.split('\n')
+ kinfopath = 'NONE'
+ found = False
+ cnt = len(reslst)
+ for resline in reslst:
+ if os.path.isfile(resline):
+ kInfoFiles.append(resline)
+ found = True
+ if not found:
+ print('No .kindle-info files have been found.')
+ return kInfoFiles
+
+# Parse the Kindle.info file and return the records as a list of key-values
+def parseKindleInfo(kInfoFile):
+ DB = {}
+ infoReader = open(kInfoFile, 'r')
+ infoReader.read(1)
+ data = infoReader.read()
+ items = data.split('[')
+ for item in items:
+ splito = item.split(':')
+ DB[splito[0]] =splito[1]
+ return DB
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
-#
-# Locate and open the Kindle.info file.
-#
-def openKindleInfo(kInfoFile=None):
- if kInfoFile == None:
- regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
- path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
- kinfopath = path +'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info'
- if not os.path.isfile(kinfopath):
- raise DrmException('Error: kindle.info file can not be found')
- return open(kinfopath,'r')
+# Locate the .kindle-info files
+def getKindleInfoFiles(kInfoFiles):
+ regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
+ path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
+ kinfopath = path +'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info'
+ if not os.path.isfile(kinfopath):
+ print('The kindle.info files has not been found.')
else:
- if not os.path.isfile(kInfoFile):
- raise DrmException('Error: kindle.info file can not be found')
- return open(kInfoFile, 'r')
+ kInfoFiles.append(kinfopath)
+ return kInfoFiles
+
+# Parse the Kindle.info file and return the records as a list of key-values
+def parseKindleInfo(kInfoFile):
+ DB = {}
+ infoReader = open(kInfoFile, 'r')
+ infoReader.read(1)
+ data = infoReader.read()
+ items = data.split('{')
+ for item in items:
+ splito = item.split(':')
+ DB[splito[0]] =splito[1]
+ return DB
global charMap4
if sys.platform.startswith('win'):
- from k4pcutils import openKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
+ from k4pcutils import getKindleInfoFiles, parseKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
if sys.platform.startswith('darwin'):
- from k4mutils import openKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
+ from k4mutils import getKindleInfoFiles, parseKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
charMap1 = "n5Pr6St7Uv8Wx9YzAb0Cd1Ef2Gh3Jk4M"
charMap3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
result += pack("B",value)
return result
-
-# Parse the Kindle.info file and return the records as a list of key-values
-def parseKindleInfo(kInfoFile):
- DB = {}
- infoReader = openKindleInfo(kInfoFile)
- infoReader.read(1)
- data = infoReader.read()
- if sys.platform.startswith('win'):
- items = data.split('{')
- else :
- items = data.split('[')
- for item in items:
- splito = item.split(':')
- DB[splito[0]] =splito[1]
- return DB
-
# Get a record from the Kindle.info file for the key "hashedKey" (already hashed and encoded).
# Return the decoded and decrypted record
def getKindleInfoValueForHash(hashedKey):
# Parse the EXTH header records and parse the Kindleinfo
# file to calculate the book pid.
-def getK4Pids(pidlst, rec209, token, kInfoFile=None):
+def getK4Pids(pidlst, rec209, token, kInfoFile):
global kindleDatabase
global charMap1
kindleDatabase = None
if kindleDatabase == None :
return pidlst
+
+ try:
+ # Get the Mazama Random number
+ MazamaRandomNumber = getKindleInfoValueForKey("MazamaRandomNumber")
- # Get the Mazama Random number
- MazamaRandomNumber = getKindleInfoValueForKey("MazamaRandomNumber")
-
+ # Get the kindle account token
+ kindleAccountToken = getKindleInfoValueForKey("kindle.account.tokens")
+ except KeyError:
+ print "Keys not found in " + kInfoFile
+ return pidlst
+
# Get the HDD serial
encodedSystemVolumeSerialNumber = encodeHash(GetVolumeSerialNumber(),charMap1)
devicePID = checksumPid(devicePID)
pidlst.append(devicePID)
- # Compute book PID
-
- # Get the kindle account token
- kindleAccountToken = getKindleInfoValueForKey("kindle.account.tokens")
+ # Compute book PIDs
# book pid
pidHash = SHA1(DSN+kindleAccountToken+rec209+token)
def getPidList(md1, md2, k4, pids, serials, kInfoFiles):
pidlst = []
+ if kInfoFiles is None:
+ kInfoFiles = []
if k4:
- pidlst = getK4Pids(pidlst, md1, md2)
+ kInfoFiles = getKindleInfoFiles(kInfoFiles)
for infoFile in kInfoFiles:
pidlst = getK4Pids(pidlst, md1, md2, infoFile)
for serialnum in serials:
meta_array = getMetaArray(metaFile)
# replace special chars in title and authors like & < >
- title = meta_array['Title']
+ title = meta_array.get('Title','No Title Provided')
title = title.replace('&','&')
title = title.replace('<','<')
title = title.replace('>','>')
meta_array['Title'] = title
- authors = meta_array['Authors']
+ authors = meta_array.get('Authors','No Authors Provided')
authors = authors.replace('&','&')
authors = authors.replace('<','<')
authors = authors.replace('>','>')
htmlstr += '<title>' + meta_array['Title'] + ' by ' + meta_array['Authors'] + '</title>\n'
htmlstr += '<meta name="Author" content="' + meta_array['Authors'] + '" />\n'
htmlstr += '<meta name="Title" content="' + meta_array['Title'] + '" />\n'
- htmlstr += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
- htmlstr += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
+ if 'ASIN' in meta_array:
+ htmlstr += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
+ if 'GUID' in meta_array:
+ htmlstr += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
htmlstr += '<link href="style.css" rel="stylesheet" type="text/css" />\n'
htmlstr += '</head>\n<body>\n'
svgindex += '<title>' + meta_array['Title'] + '</title>\n'
svgindex += '<meta name="Author" content="' + meta_array['Authors'] + '" />\n'
svgindex += '<meta name="Title" content="' + meta_array['Title'] + '" />\n'
- svgindex += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
- svgindex += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
+ if 'ASIN' in meta_array:
+ svgindex += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
+ if 'GUID' in meta_array:
+ svgindex += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
svgindex += '</head>\n'
svgindex += '<body>\n'
opfstr += '<package xmlns="http://www.idpf.org/2007/opf" unique-identifier="guid_id">\n'
# adding metadata
opfstr += ' <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">\n'
- opfstr += ' <dc:identifier opf:scheme="GUID" id="guid_id">' + meta_array['GUID'] + '</dc:identifier>\n'
- opfstr += ' <dc:identifier opf:scheme="ASIN">' + meta_array['ASIN'] + '</dc:identifier>\n'
- opfstr += ' <dc:identifier opf:scheme="oASIN">' + meta_array['oASIN'] + '</dc:identifier>\n'
+ if 'GUID' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="GUID" id="guid_id">' + meta_array['GUID'] + '</dc:identifier>\n'
+ if 'ASIN' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="ASIN">' + meta_array['ASIN'] + '</dc:identifier>\n'
+ if 'oASIN' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="oASIN">' + meta_array['oASIN'] + '</dc:identifier>\n'
opfstr += ' <dc:title>' + meta_array['Title'] + '</dc:title>\n'
opfstr += ' <dc:creator opf:role="aut">' + meta_array['Authors'] + '</dc:creator>\n'
opfstr += ' <dc:language>en</dc:language>\n'
# and import that ZIP into Calibre using its plugin configuration GUI.
-__version__ = '2.7'
+__version__ = '2.8'
class Unbuffered:
def __init__(self, stream):
Provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc.'
supported_platforms = ['osx', 'windows', 'linux'] # Platforms this plugin will run on
author = 'DiapDealer, SomeUpdates' # The author of this plugin
- version = (0, 2, 7) # The version number of this plugin
+ version = (0, 2, 8) # The version number of this plugin
file_types = set(['prc','mobi','azw','azw1','tpz']) # The file types that this plugin will be applied to
on_import = True # Run this plugin during the import
priority = 210 # run this plugin before mobidedrm, k4pcdedrm, k4dedrm
return cleartext
-# Locate and open the .kindle-info file
-def openKindleInfo(kInfoFile=None):
- if kInfoFile == None:
- home = os.getenv('HOME')
- cmdline = 'find "' + home + '/Library/Application Support" -name ".kindle-info"'
- cmdline = cmdline.encode(sys.getfilesystemencoding())
- p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
- out1, out2 = p1.communicate()
- reslst = out1.split('\n')
- kinfopath = 'NONE'
- cnt = len(reslst)
- for j in xrange(cnt):
- resline = reslst[j]
- pp = resline.find('.kindle-info')
- if pp >= 0:
- kinfopath = resline
- break
- if not os.path.isfile(kinfopath):
- raise DrmException('Error: .kindle-info file can not be found')
- return open(kinfopath,'r')
- else:
- if not os.path.isfile(kInfoFile):
- raise DrmException('Error: kindle-info file can not be found')
- return open(kInfoFile, 'r')
+# Locate the .kindle-info files
+def getKindleInfoFiles(kInfoFiles):
+ home = os.getenv('HOME')
+ cmdline = 'find "' + home + '/Library/Application Support" -name ".kindle-info"'
+ cmdline = cmdline.encode(sys.getfilesystemencoding())
+ p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
+ out1, out2 = p1.communicate()
+ reslst = out1.split('\n')
+ kinfopath = 'NONE'
+ found = False
+ cnt = len(reslst)
+ for resline in reslst:
+ if os.path.isfile(resline):
+ kInfoFiles.append(resline)
+ found = True
+ if not found:
+ print('No .kindle-info files have been found.')
+ return kInfoFiles
+
+# Parse the Kindle.info file and return the records as a list of key-values
+def parseKindleInfo(kInfoFile):
+ DB = {}
+ infoReader = open(kInfoFile, 'r')
+ infoReader.read(1)
+ data = infoReader.read()
+ items = data.split('[')
+ for item in items:
+ splito = item.split(':')
+ DB[splito[0]] =splito[1]
+ return DB
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
-#
-# Locate and open the Kindle.info file.
-#
-def openKindleInfo(kInfoFile=None):
- if kInfoFile == None:
- regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
- path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
- kinfopath = path +'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info'
- if not os.path.isfile(kinfopath):
- raise DrmException('Error: kindle.info file can not be found')
- return open(kinfopath,'r')
+# Locate the .kindle-info files
+def getKindleInfoFiles(kInfoFiles):
+ regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
+ path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
+ kinfopath = path +'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info'
+ if not os.path.isfile(kinfopath):
+ print('The kindle.info files has not been found.')
else:
- if not os.path.isfile(kInfoFile):
- raise DrmException('Error: kindle.info file can not be found')
- return open(kInfoFile, 'r')
+ kInfoFiles.append(kinfopath)
+ return kInfoFiles
+
+# Parse the Kindle.info file and return the records as a list of key-values
+def parseKindleInfo(kInfoFile):
+ DB = {}
+ infoReader = open(kInfoFile, 'r')
+ infoReader.read(1)
+ data = infoReader.read()
+ items = data.split('{')
+ for item in items:
+ splito = item.split(':')
+ DB[splito[0]] =splito[1]
+ return DB
global charMap4
if sys.platform.startswith('win'):
- from k4pcutils import openKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
+ from k4pcutils import getKindleInfoFiles, parseKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
if sys.platform.startswith('darwin'):
- from k4mutils import openKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
+ from k4mutils import getKindleInfoFiles, parseKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
charMap1 = "n5Pr6St7Uv8Wx9YzAb0Cd1Ef2Gh3Jk4M"
charMap3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
result += pack("B",value)
return result
-
-# Parse the Kindle.info file and return the records as a list of key-values
-def parseKindleInfo(kInfoFile):
- DB = {}
- infoReader = openKindleInfo(kInfoFile)
- infoReader.read(1)
- data = infoReader.read()
- if sys.platform.startswith('win'):
- items = data.split('{')
- else :
- items = data.split('[')
- for item in items:
- splito = item.split(':')
- DB[splito[0]] =splito[1]
- return DB
-
# Get a record from the Kindle.info file for the key "hashedKey" (already hashed and encoded).
# Return the decoded and decrypted record
def getKindleInfoValueForHash(hashedKey):
# Parse the EXTH header records and parse the Kindleinfo
# file to calculate the book pid.
-def getK4Pids(pidlst, rec209, token, kInfoFile=None):
+def getK4Pids(pidlst, rec209, token, kInfoFile):
global kindleDatabase
global charMap1
kindleDatabase = None
if kindleDatabase == None :
return pidlst
+
+ try:
+ # Get the Mazama Random number
+ MazamaRandomNumber = getKindleInfoValueForKey("MazamaRandomNumber")
- # Get the Mazama Random number
- MazamaRandomNumber = getKindleInfoValueForKey("MazamaRandomNumber")
-
+ # Get the kindle account token
+ kindleAccountToken = getKindleInfoValueForKey("kindle.account.tokens")
+ except KeyError:
+ print "Keys not found in " + kInfoFile
+ return pidlst
+
# Get the HDD serial
encodedSystemVolumeSerialNumber = encodeHash(GetVolumeSerialNumber(),charMap1)
devicePID = checksumPid(devicePID)
pidlst.append(devicePID)
- # Compute book PID
-
- # Get the kindle account token
- kindleAccountToken = getKindleInfoValueForKey("kindle.account.tokens")
+ # Compute book PIDs
# book pid
pidHash = SHA1(DSN+kindleAccountToken+rec209+token)
def getPidList(md1, md2, k4, pids, serials, kInfoFiles):
pidlst = []
+ if kInfoFiles is None:
+ kInfoFiles = []
if k4:
- pidlst = getK4Pids(pidlst, md1, md2)
+ kInfoFiles = getKindleInfoFiles(kInfoFiles)
for infoFile in kInfoFiles:
pidlst = getK4Pids(pidlst, md1, md2, infoFile)
for serialnum in serials:
meta_array = getMetaArray(metaFile)
# replace special chars in title and authors like & < >
- title = meta_array['Title']
+ title = meta_array.get('Title','No Title Provided')
title = title.replace('&','&')
title = title.replace('<','<')
title = title.replace('>','>')
meta_array['Title'] = title
- authors = meta_array['Authors']
+ authors = meta_array.get('Authors','No Authors Provided')
authors = authors.replace('&','&')
authors = authors.replace('<','<')
authors = authors.replace('>','>')
htmlstr += '<title>' + meta_array['Title'] + ' by ' + meta_array['Authors'] + '</title>\n'
htmlstr += '<meta name="Author" content="' + meta_array['Authors'] + '" />\n'
htmlstr += '<meta name="Title" content="' + meta_array['Title'] + '" />\n'
- htmlstr += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
- htmlstr += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
+ if 'ASIN' in meta_array:
+ htmlstr += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
+ if 'GUID' in meta_array:
+ htmlstr += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
htmlstr += '<link href="style.css" rel="stylesheet" type="text/css" />\n'
htmlstr += '</head>\n<body>\n'
svgindex += '<title>' + meta_array['Title'] + '</title>\n'
svgindex += '<meta name="Author" content="' + meta_array['Authors'] + '" />\n'
svgindex += '<meta name="Title" content="' + meta_array['Title'] + '" />\n'
- svgindex += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
- svgindex += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
+ if 'ASIN' in meta_array:
+ svgindex += '<meta name="ASIN" content="' + meta_array['ASIN'] + '" />\n'
+ if 'GUID' in meta_array:
+ svgindex += '<meta name="GUID" content="' + meta_array['GUID'] + '" />\n'
svgindex += '</head>\n'
svgindex += '<body>\n'
opfstr += '<package xmlns="http://www.idpf.org/2007/opf" unique-identifier="guid_id">\n'
# adding metadata
opfstr += ' <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">\n'
- opfstr += ' <dc:identifier opf:scheme="GUID" id="guid_id">' + meta_array['GUID'] + '</dc:identifier>\n'
- opfstr += ' <dc:identifier opf:scheme="ASIN">' + meta_array['ASIN'] + '</dc:identifier>\n'
- opfstr += ' <dc:identifier opf:scheme="oASIN">' + meta_array['oASIN'] + '</dc:identifier>\n'
+ if 'GUID' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="GUID" id="guid_id">' + meta_array['GUID'] + '</dc:identifier>\n'
+ if 'ASIN' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="ASIN">' + meta_array['ASIN'] + '</dc:identifier>\n'
+ if 'oASIN' in meta_array:
+ opfstr += ' <dc:identifier opf:scheme="oASIN">' + meta_array['oASIN'] + '</dc:identifier>\n'
opfstr += ' <dc:title>' + meta_array['Title'] + '</dc:title>\n'
opfstr += ' <dc:creator opf:role="aut">' + meta_array['Authors'] + '</dc:creator>\n'
opfstr += ' <dc:language>en</dc:language>\n'
# and import that ZIP into Calibre using its plugin configuration GUI.
-__version__ = '2.7'
+__version__ = '2.8'
class Unbuffered:
def __init__(self, stream):
Provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc.'
supported_platforms = ['osx', 'windows', 'linux'] # Platforms this plugin will run on
author = 'DiapDealer, SomeUpdates' # The author of this plugin
- version = (0, 2, 7) # The version number of this plugin
+ version = (0, 2, 8) # The version number of this plugin
file_types = set(['prc','mobi','azw','azw1','tpz']) # The file types that this plugin will be applied to
on_import = True # Run this plugin during the import
priority = 210 # run this plugin before mobidedrm, k4pcdedrm, k4dedrm
return cleartext
-# Locate and open the .kindle-info file
-def openKindleInfo(kInfoFile=None):
- if kInfoFile == None:
- home = os.getenv('HOME')
- cmdline = 'find "' + home + '/Library/Application Support" -name ".kindle-info"'
- cmdline = cmdline.encode(sys.getfilesystemencoding())
- p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
- out1, out2 = p1.communicate()
- reslst = out1.split('\n')
- kinfopath = 'NONE'
- cnt = len(reslst)
- for j in xrange(cnt):
- resline = reslst[j]
- pp = resline.find('.kindle-info')
- if pp >= 0:
- kinfopath = resline
- break
- if not os.path.isfile(kinfopath):
- raise DrmException('Error: .kindle-info file can not be found')
- return open(kinfopath,'r')
- else:
- if not os.path.isfile(kInfoFile):
- raise DrmException('Error: kindle-info file can not be found')
- return open(kInfoFile, 'r')
+# Locate the .kindle-info files
+def getKindleInfoFiles(kInfoFiles):
+ home = os.getenv('HOME')
+ cmdline = 'find "' + home + '/Library/Application Support" -name ".kindle-info"'
+ cmdline = cmdline.encode(sys.getfilesystemencoding())
+ p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
+ out1, out2 = p1.communicate()
+ reslst = out1.split('\n')
+ kinfopath = 'NONE'
+ found = False
+ cnt = len(reslst)
+ for resline in reslst:
+ if os.path.isfile(resline):
+ kInfoFiles.append(resline)
+ found = True
+ if not found:
+ print('No .kindle-info files have been found.')
+ return kInfoFiles
+
+# Parse the Kindle.info file and return the records as a list of key-values
+def parseKindleInfo(kInfoFile):
+ DB = {}
+ infoReader = open(kInfoFile, 'r')
+ infoReader.read(1)
+ data = infoReader.read()
+ items = data.split('[')
+ for item in items:
+ splito = item.split(':')
+ DB[splito[0]] =splito[1]
+ return DB
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
-#
-# Locate and open the Kindle.info file.
-#
-def openKindleInfo(kInfoFile=None):
- if kInfoFile == None:
- regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
- path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
- kinfopath = path +'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info'
- if not os.path.isfile(kinfopath):
- raise DrmException('Error: kindle.info file can not be found')
- return open(kinfopath,'r')
+# Locate the .kindle-info files
+def getKindleInfoFiles(kInfoFiles):
+ regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
+ path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
+ kinfopath = path +'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info'
+ if not os.path.isfile(kinfopath):
+ print('The kindle.info files has not been found.')
else:
- if not os.path.isfile(kInfoFile):
- raise DrmException('Error: kindle.info file can not be found')
- return open(kInfoFile, 'r')
+ kInfoFiles.append(kinfopath)
+ return kInfoFiles
+
+# Parse the Kindle.info file and return the records as a list of key-values
+def parseKindleInfo(kInfoFile):
+ DB = {}
+ infoReader = open(kInfoFile, 'r')
+ infoReader.read(1)
+ data = infoReader.read()
+ items = data.split('{')
+ for item in items:
+ splito = item.split(':')
+ DB[splito[0]] =splito[1]
+ return DB
global charMap4
if sys.platform.startswith('win'):
- from k4pcutils import openKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
+ from k4pcutils import getKindleInfoFiles, parseKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
if sys.platform.startswith('darwin'):
- from k4mutils import openKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
+ from k4mutils import getKindleInfoFiles, parseKindleInfo, CryptUnprotectData, GetUserName, GetVolumeSerialNumber, charMap2
charMap1 = "n5Pr6St7Uv8Wx9YzAb0Cd1Ef2Gh3Jk4M"
charMap3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
result += pack("B",value)
return result
-
-# Parse the Kindle.info file and return the records as a list of key-values
-def parseKindleInfo(kInfoFile):
- DB = {}
- infoReader = openKindleInfo(kInfoFile)
- infoReader.read(1)
- data = infoReader.read()
- if sys.platform.startswith('win'):
- items = data.split('{')
- else :
- items = data.split('[')
- for item in items:
- splito = item.split(':')
- DB[splito[0]] =splito[1]
- return DB
-
# Get a record from the Kindle.info file for the key "hashedKey" (already hashed and encoded).
# Return the decoded and decrypted record
def getKindleInfoValueForHash(hashedKey):
# Parse the EXTH header records and parse the Kindleinfo
# file to calculate the book pid.
-def getK4Pids(pidlst, rec209, token, kInfoFile=None):
+def getK4Pids(pidlst, rec209, token, kInfoFile):
global kindleDatabase
global charMap1
kindleDatabase = None
if kindleDatabase == None :
return pidlst
+
+ try:
+ # Get the Mazama Random number
+ MazamaRandomNumber = getKindleInfoValueForKey("MazamaRandomNumber")
- # Get the Mazama Random number
- MazamaRandomNumber = getKindleInfoValueForKey("MazamaRandomNumber")
-
+ # Get the kindle account token
+ kindleAccountToken = getKindleInfoValueForKey("kindle.account.tokens")
+ except KeyError:
+ print "Keys not found in " + kInfoFile
+ return pidlst
+
# Get the HDD serial
encodedSystemVolumeSerialNumber = encodeHash(GetVolumeSerialNumber(),charMap1)
devicePID = checksumPid(devicePID)
pidlst.append(devicePID)
- # Compute book PID
-
- # Get the kindle account token
- kindleAccountToken = getKindleInfoValueForKey("kindle.account.tokens")
+ # Compute book PIDs
# book pid
pidHash = SHA1(DSN+kindleAccountToken+rec209+token)
def getPidList(md1, md2, k4, pids, serials, kInfoFiles):
pidlst = []
+ if kInfoFiles is None:
+ kInfoFiles = []
if k4:
- pidlst = getK4Pids(pidlst, md1, md2)
+ kInfoFiles = getKindleInfoFiles(kInfoFiles)
for infoFile in kInfoFiles:
pidlst = getK4Pids(pidlst, md1, md2, infoFile)
for serialnum in serials: