2
0
mirror of https://github.com/apprenticeharper/DeDRM_tools synced 2024-11-18 21:25:39 +00:00

tools v3.8

This commit is contained in:
Apprentice Alf 2011-03-28 13:01:05 +01:00
parent 867ac35b45
commit 4163d5ccf4
22 changed files with 346 additions and 306 deletions

View File

@ -323,12 +323,12 @@ def generateBook(bookDir, raw, fixedimage):
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('&','&amp;')
title = title.replace('<','&lt;')
title = title.replace('>','&gt;')
meta_array['Title'] = title
authors = meta_array['Authors']
authors = meta_array.get('Authors','No Authors Provided')
authors = authors.replace('&','&amp;')
authors = authors.replace('<','&lt;')
authors = authors.replace('>','&gt;')
@ -413,7 +413,9 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'
@ -430,7 +432,9 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'
@ -485,8 +489,11 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'

View File

@ -18,9 +18,9 @@ global charMap3
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+/"
@ -67,22 +67,6 @@ def decode(data,map):
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):
@ -241,7 +225,7 @@ def getKindlePid(pidlst, rec209, token, serialnum):
# 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
@ -255,9 +239,16 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
if kindleDatabase == None :
return pidlst
try:
# 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)
@ -273,10 +264,7 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
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)
@ -300,8 +288,10 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
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:

View File

@ -29,7 +29,7 @@ from __future__ import with_statement
# and import that ZIP into Calibre using its plugin configuration GUI.
__version__ = '2.7'
__version__ = '2.8'
class Unbuffered:
def __init__(self, stream):
@ -250,7 +250,7 @@ if not __name__ == "__main__" and inCalibre:
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

View File

@ -168,9 +168,8 @@ def CryptUnprotectData(encryptedData):
return cleartext
# Locate and open the .kindle-info file
def openKindleInfo(kInfoFile=None):
if kInfoFile == None:
# 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())
@ -178,17 +177,24 @@ def openKindleInfo(kInfoFile=None):
out1, out2 = p1.communicate()
reslst = out1.split('\n')
kinfopath = 'NONE'
found = False
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')
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

View File

@ -93,18 +93,25 @@ def CryptUnprotectData():
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
#
# Locate and open the Kindle.info file.
#
def openKindleInfo(kInfoFile=None):
if kInfoFile == None:
# 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):
raise DrmException('Error: kindle.info file can not be found')
return open(kinfopath,'r')
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

View File

@ -24,7 +24,7 @@
<key>CFBundleExecutable</key>
<string>droplet</string>
<key>CFBundleGetInfoString</key>
<string>DeDRM 2.5, Written 20102011 by Apprentice Alf and others.</string>
<string>DeDRM 2.6, Written 20102011 by Apprentice Alf and others.</string>
<key>CFBundleIconFile</key>
<string>droplet</string>
<key>CFBundleInfoDictionaryVersion</key>
@ -34,7 +34,7 @@
<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>

View File

@ -323,12 +323,12 @@ def generateBook(bookDir, raw, fixedimage):
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('&','&amp;')
title = title.replace('<','&lt;')
title = title.replace('>','&gt;')
meta_array['Title'] = title
authors = meta_array['Authors']
authors = meta_array.get('Authors','No Authors Provided')
authors = authors.replace('&','&amp;')
authors = authors.replace('<','&lt;')
authors = authors.replace('>','&gt;')
@ -413,7 +413,9 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'
@ -430,7 +432,9 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'
@ -485,8 +489,11 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'

View File

@ -29,7 +29,7 @@ from __future__ import with_statement
# and import that ZIP into Calibre using its plugin configuration GUI.
__version__ = '2.7'
__version__ = '2.8'
class Unbuffered:
def __init__(self, stream):
@ -250,7 +250,7 @@ if not __name__ == "__main__" and inCalibre:
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

View File

@ -168,9 +168,8 @@ def CryptUnprotectData(encryptedData):
return cleartext
# Locate and open the .kindle-info file
def openKindleInfo(kInfoFile=None):
if kInfoFile == None:
# 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())
@ -178,17 +177,24 @@ def openKindleInfo(kInfoFile=None):
out1, out2 = p1.communicate()
reslst = out1.split('\n')
kinfopath = 'NONE'
found = False
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')
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

View File

@ -93,18 +93,25 @@ def CryptUnprotectData():
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
#
# Locate and open the Kindle.info file.
#
def openKindleInfo(kInfoFile=None):
if kInfoFile == None:
# 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):
raise DrmException('Error: kindle.info file can not be found')
return open(kinfopath,'r')
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

View File

@ -18,9 +18,9 @@ global charMap3
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+/"
@ -67,22 +67,6 @@ def decode(data,map):
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):
@ -241,7 +225,7 @@ def getKindlePid(pidlst, rec209, token, serialnum):
# 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
@ -255,9 +239,16 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
if kindleDatabase == None :
return pidlst
try:
# 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)
@ -273,10 +264,7 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
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)
@ -300,8 +288,10 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
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:

View File

@ -323,12 +323,12 @@ def generateBook(bookDir, raw, fixedimage):
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('&','&amp;')
title = title.replace('<','&lt;')
title = title.replace('>','&gt;')
meta_array['Title'] = title
authors = meta_array['Authors']
authors = meta_array.get('Authors','No Authors Provided')
authors = authors.replace('&','&amp;')
authors = authors.replace('<','&lt;')
authors = authors.replace('>','&gt;')
@ -413,7 +413,9 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'
@ -430,7 +432,9 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'
@ -485,8 +489,11 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'

View File

@ -29,7 +29,7 @@ from __future__ import with_statement
# and import that ZIP into Calibre using its plugin configuration GUI.
__version__ = '2.7'
__version__ = '2.8'
class Unbuffered:
def __init__(self, stream):
@ -250,7 +250,7 @@ if not __name__ == "__main__" and inCalibre:
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

View File

@ -168,9 +168,8 @@ def CryptUnprotectData(encryptedData):
return cleartext
# Locate and open the .kindle-info file
def openKindleInfo(kInfoFile=None):
if kInfoFile == None:
# 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())
@ -178,17 +177,24 @@ def openKindleInfo(kInfoFile=None):
out1, out2 = p1.communicate()
reslst = out1.split('\n')
kinfopath = 'NONE'
found = False
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')
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

View File

@ -93,18 +93,25 @@ def CryptUnprotectData():
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
#
# Locate and open the Kindle.info file.
#
def openKindleInfo(kInfoFile=None):
if kInfoFile == None:
# 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):
raise DrmException('Error: kindle.info file can not be found')
return open(kinfopath,'r')
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

View File

@ -18,9 +18,9 @@ global charMap3
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+/"
@ -67,22 +67,6 @@ def decode(data,map):
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):
@ -241,7 +225,7 @@ def getKindlePid(pidlst, rec209, token, serialnum):
# 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
@ -255,9 +239,16 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
if kindleDatabase == None :
return pidlst
try:
# 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)
@ -273,10 +264,7 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
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)
@ -300,8 +288,10 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
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:

View File

@ -323,12 +323,12 @@ def generateBook(bookDir, raw, fixedimage):
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('&','&amp;')
title = title.replace('<','&lt;')
title = title.replace('>','&gt;')
meta_array['Title'] = title
authors = meta_array['Authors']
authors = meta_array.get('Authors','No Authors Provided')
authors = authors.replace('&','&amp;')
authors = authors.replace('<','&lt;')
authors = authors.replace('>','&gt;')
@ -413,7 +413,9 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'
@ -430,7 +432,9 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'
@ -485,8 +489,11 @@ def generateBook(bookDir, raw, fixedimage):
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'
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'

View File

@ -29,7 +29,7 @@ from __future__ import with_statement
# and import that ZIP into Calibre using its plugin configuration GUI.
__version__ = '2.7'
__version__ = '2.8'
class Unbuffered:
def __init__(self, stream):
@ -250,7 +250,7 @@ if not __name__ == "__main__" and inCalibre:
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

View File

@ -168,9 +168,8 @@ def CryptUnprotectData(encryptedData):
return cleartext
# Locate and open the .kindle-info file
def openKindleInfo(kInfoFile=None):
if kInfoFile == None:
# 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())
@ -178,17 +177,24 @@ def openKindleInfo(kInfoFile=None):
out1, out2 = p1.communicate()
reslst = out1.split('\n')
kinfopath = 'NONE'
found = False
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')
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

View File

@ -93,18 +93,25 @@ def CryptUnprotectData():
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
#
# Locate and open the Kindle.info file.
#
def openKindleInfo(kInfoFile=None):
if kInfoFile == None:
# 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):
raise DrmException('Error: kindle.info file can not be found')
return open(kinfopath,'r')
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

View File

@ -18,9 +18,9 @@ global charMap3
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+/"
@ -67,22 +67,6 @@ def decode(data,map):
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):
@ -241,7 +225,7 @@ def getKindlePid(pidlst, rec209, token, serialnum):
# 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
@ -255,9 +239,16 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
if kindleDatabase == None :
return pidlst
try:
# 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)
@ -273,10 +264,7 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
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)
@ -300,8 +288,10 @@ def getK4Pids(pidlst, rec209, token, kInfoFile=None):
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: