Merge pull request #850 from cclauss/modernize-Python-2-codes

Use print() function in both Python 2 and Python 3
pull/859/head^2
Apprentice Harper 4 years ago committed by GitHub
commit c1ece2f288
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -150,6 +150,7 @@
# after all.
#
"""Manage all Kobo books, either encrypted or DRM-free."""
from __future__ import print_function
__version__ = '3.2.4'
__about__ = u"Obok v{0}\nCopyright © 2012-2016 Physisticated et al.".format(__version__)
@ -291,7 +292,7 @@ class KoboLibrary(object):
of books, their titles, and the user's encryption key(s)."""
def __init__ (self, serials = [], device_path = None):
print __about__
print(__about__)
self.kobodir = u""
kobodb = u""
@ -374,7 +375,7 @@ class KoboLibrary(object):
# make a copy of the database in a temporary file
# so we can ensure it's not using WAL logging which sqlite3 can't do.
self.newdb = tempfile.NamedTemporaryFile(mode='wb', delete=False)
print self.newdb.name
print(self.newdb.name)
olddb = open(kobodb, 'rb')
self.newdb.write(olddb.read(18))
self.newdb.write('\x01\x01')
@ -595,32 +596,32 @@ class KoboFile(object):
# assume utf-8 with no BOM
textoffset = 0
stride = 1
print u"Checking text:{0}:".format(contents[:10])
print(u"Checking text:{0}:".format(contents[:10]))
# check for byte order mark
if contents[:3]=="\xef\xbb\xbf":
# seems to be utf-8 with BOM
print u"Could be utf-8 with BOM"
print(u"Could be utf-8 with BOM")
textoffset = 3
elif contents[:2]=="\xfe\xff":
# seems to be utf-16BE
print u"Could be utf-16BE"
print(u"Could be utf-16BE")
textoffset = 3
stride = 2
elif contents[:2]=="\xff\xfe":
# seems to be utf-16LE
print u"Could be utf-16LE"
print(u"Could be utf-16LE")
textoffset = 2
stride = 2
else:
print u"Perhaps utf-8 without BOM"
print(u"Perhaps utf-8 without BOM")
# now check that the first few characters are in the ASCII range
for i in xrange(textoffset,textoffset+5*stride,stride):
if ord(contents[i])<32 or ord(contents[i])>127:
# Non-ascii, so decryption probably failed
print u"Bad character at {0}, value {1}".format(i,ord(contents[i]))
print(u"Bad character at {0}, value {1}".format(i,ord(contents[i])))
raise ValueError
print u"Seems to be good text"
print(u"Seems to be good text")
return True
if contents[:5]=="<?xml" or contents[:8]=="\xef\xbb\xbf<?xml":
# utf-8
@ -641,13 +642,13 @@ class KoboFile(object):
# utf-16LE of weird <!DOCTYPE start
return True
else:
print u"Bad XML: {0}".format(contents[:8])
print(u"Bad XML: {0}".format(contents[:8]))
raise ValueError
elif self.mimetype == 'image/jpeg':
if contents[:3] == '\xff\xd8\xff':
return True
else:
print u"Bad JPEG: {0}".format(contents[:3].encode('hex'))
print(u"Bad JPEG: {0}".format(contents[:3].encode('hex')))
raise ValueError()
return False
@ -670,18 +671,18 @@ class KoboFile(object):
return contents
def decrypt_book(book, lib):
print u"Converting {0}".format(book.title)
print(u"Converting {0}".format(book.title))
zin = zipfile.ZipFile(book.filename, "r")
# make filename out of Unicode alphanumeric and whitespace equivalents from title
outname = u"{0}.epub".format(re.sub('[^\s\w]', '_', book.title, 0, re.UNICODE))
if (book.type == 'drm-free'):
print u"DRM-free book, conversion is not needed"
print(u"DRM-free book, conversion is not needed")
shutil.copyfile(book.filename, outname)
print u"Book saved as {0}".format(os.path.join(os.getcwd(), outname))
print(u"Book saved as {0}".format(os.path.join(os.getcwd(), outname)))
return 0
result = 1
for userkey in lib.userkeys:
print u"Trying key: {0}".format(userkey.encode('hex_codec'))
print(u"Trying key: {0}".format(userkey.encode('hex_codec')))
try:
zout = zipfile.ZipFile(outname, "w", zipfile.ZIP_DEFLATED)
for filename in zin.namelist():
@ -693,12 +694,12 @@ def decrypt_book(book, lib):
file.check(contents)
zout.writestr(filename, contents)
zout.close()
print u"Decryption succeeded."
print u"Book saved as {0}".format(os.path.join(os.getcwd(), outname))
print(u"Decryption succeeded.")
print(u"Book saved as {0}".format(os.path.join(os.getcwd(), outname)))
result = 0
break
except ValueError:
print u"Decryption failed."
print(u"Decryption failed.")
zout.close()
os.remove(outname)
zin.close()
@ -723,8 +724,8 @@ def cli_main():
books = lib.books
else:
for i, book in enumerate(lib.books):
print u"{0}: {1}".format(i + 1, book.title)
print u"Or 'all'"
print(u"{0}: {1}".format(i + 1, book.title))
print(u"Or 'all'")
choice = raw_input(u"Convert book number... ")
if choice == u'all':
@ -734,14 +735,14 @@ def cli_main():
num = int(choice)
books = [lib.books[num - 1]]
except (ValueError, IndexError):
print u"Invalid choice. Exiting..."
print(u"Invalid choice. Exiting...")
exit()
results = [decrypt_book(book, lib) for book in books]
lib.close()
overall_result = all(result != 0 for result in results)
if overall_result != 0:
print u"Could not decrypt book with any of the keys found."
print(u"Could not decrypt book with any of the keys found.")
return overall_result

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from __future__ import print_function
# __init__.py for DeDRM_plugin
# Copyright © 2008-2019 Apprentice Harper et al.
@ -169,7 +170,7 @@ class DeDRM(FileTypePlugin):
else:
names = [u"libalfcrypto32.so",u"libalfcrypto64.so",u"kindlekey.py",u"adobekey.py",u"subasyncio.py"]
lib_dict = self.load_resources(names)
print u"{0} v{1}: Copying needed library files from plugin's zip".format(PLUGIN_NAME, PLUGIN_VERSION)
print(u"{0} v{1}: Copying needed library files from plugin's zip".format(PLUGIN_NAME, PLUGIN_VERSION))
for entry, data in lib_dict.items():
file_path = os.path.join(self.alfdir, entry)
@ -181,7 +182,7 @@ class DeDRM(FileTypePlugin):
try:
open(file_path,'wb').write(data)
except:
print u"{0} v{1}: Exception when copying needed library files".format(PLUGIN_NAME, PLUGIN_VERSION)
print(u"{0} v{1}: Exception when copying needed library files".format(PLUGIN_NAME, PLUGIN_VERSION))
traceback.print_exc()
pass
@ -202,11 +203,11 @@ class DeDRM(FileTypePlugin):
inf = self.temporary_file(u".epub")
try:
print u"{0} v{1}: Verifying zip archive integrity".format(PLUGIN_NAME, PLUGIN_VERSION)
print(u"{0} v{1}: Verifying zip archive integrity".format(PLUGIN_NAME, PLUGIN_VERSION))
fr = zipfix.fixZip(path_to_ebook, inf.name)
fr.fix()
except Exception, e:
print u"{0} v{1}: Error \'{2}\' when checking zip archive".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0])
print(u"{0} v{1}: Error \'{2}\' when checking zip archive".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0]))
raise Exception(e)
# import the decryption keys
@ -219,19 +220,19 @@ class DeDRM(FileTypePlugin):
#check the book
if ignobleepub.ignobleBook(inf.name):
print u"{0} v{1}: “{2}” is a secure Barnes & Noble ePub".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))
print(u"{0} v{1}: “{2}” is a secure Barnes & Noble ePub".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))
# Attempt to decrypt epub with each encryption key (generated or provided).
for keyname, userkey in dedrmprefs['bandnkeys'].items():
keyname_masked = u"".join((u'X' if (x.isdigit()) else x) for x in keyname)
print u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked)
print(u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked))
of = self.temporary_file(u".epub")
# Give the user key, ebook and TemporaryPersistent file to the decryption function.
try:
result = ignobleepub.decryptBook(userkey, inf.name, of.name)
except:
print u"{0} v{1}: Exception when trying to decrypt after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when trying to decrypt after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
result = 1
@ -242,10 +243,10 @@ class DeDRM(FileTypePlugin):
# Return the modified PersistentTemporary file to calibre.
return of.name
print u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime)
print(u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime))
# perhaps we should see if we can get a key from a log file
print u"{0} v{1}: Looking for new NOOK Study Keys after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Looking for new NOOK Study Keys after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
# get the default NOOK Study keys
defaultkeys = []
@ -262,7 +263,7 @@ class DeDRM(FileTypePlugin):
defaultkeys = WineGetKeys(scriptpath, u".b64",dedrmprefs['adobewineprefix'])
except:
print u"{0} v{1}: Exception when getting default NOOK Study Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when getting default NOOK Study Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
newkeys = []
@ -273,7 +274,7 @@ class DeDRM(FileTypePlugin):
if len(newkeys) > 0:
try:
for i,userkey in enumerate(newkeys):
print u"{0} v{1}: Trying a new default key".format(PLUGIN_NAME, PLUGIN_VERSION)
print(u"{0} v{1}: Trying a new default key".format(PLUGIN_NAME, PLUGIN_VERSION))
of = self.temporary_file(u".epub")
@ -281,7 +282,7 @@ class DeDRM(FileTypePlugin):
try:
result = ignobleepub.decryptBook(userkey, inf.name, of.name)
except:
print u"{0} v{1}: Exception when trying to decrypt after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when trying to decrypt after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
result = 1
@ -290,59 +291,59 @@ class DeDRM(FileTypePlugin):
if result == 0:
# Decryption was a success
# Store the new successful key in the defaults
print u"{0} v{1}: Saving a new default key".format(PLUGIN_NAME, PLUGIN_VERSION)
print(u"{0} v{1}: Saving a new default key".format(PLUGIN_NAME, PLUGIN_VERSION))
try:
dedrmprefs.addnamedvaluetoprefs('bandnkeys','nook_Study_key',keyvalue)
dedrmprefs.writeprefs()
print u"{0} v{1}: Saved a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Saved a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
except:
print u"{0} v{1}: Exception saving a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception saving a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
# Return the modified PersistentTemporary file to calibre.
return of.name
print u"{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
except Exception, e:
pass
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
# import the Adobe Adept ePub handler
import calibre_plugins.dedrm.ineptepub as ineptepub
if ineptepub.adeptBook(inf.name):
print u"{0} v{1}: {2} is a secure Adobe Adept ePub".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))
print(u"{0} v{1}: {2} is a secure Adobe Adept ePub".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))
# Attempt to decrypt epub with each encryption key (generated or provided).
for keyname, userkeyhex in dedrmprefs['adeptkeys'].items():
userkey = userkeyhex.decode('hex')
print u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname)
print(u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname))
of = self.temporary_file(u".epub")
# Give the user key, ebook and TemporaryPersistent file to the decryption function.
try:
result = ineptepub.decryptBook(userkey, inf.name, of.name)
except:
print u"{0} v{1}: Exception when decrypting after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when decrypting after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
result = 1
try:
of.close()
except:
print u"{0} v{1}: Exception closing temporary file after {2:.1f} seconds. Ignored.".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception closing temporary file after {2:.1f} seconds. Ignored.".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
if result == 0:
# Decryption was successful.
# Return the modified PersistentTemporary file to calibre.
print u"{0} v{1}: Decrypted with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime)
print(u"{0} v{1}: Decrypted with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime))
return of.name
print u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime)
print(u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime))
# perhaps we need to get a new default ADE key
print u"{0} v{1}: Looking for new default Adobe Digital Editions Keys after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Looking for new default Adobe Digital Editions Keys after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
# get the default Adobe keys
defaultkeys = []
@ -360,7 +361,7 @@ class DeDRM(FileTypePlugin):
self.default_key = defaultkeys[0]
except:
print u"{0} v{1}: Exception when getting default Adobe Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when getting default Adobe Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
self.default_key = u""
@ -372,14 +373,14 @@ class DeDRM(FileTypePlugin):
if len(newkeys) > 0:
try:
for i,userkey in enumerate(newkeys):
print u"{0} v{1}: Trying a new default key".format(PLUGIN_NAME, PLUGIN_VERSION)
print(u"{0} v{1}: Trying a new default key".format(PLUGIN_NAME, PLUGIN_VERSION))
of = self.temporary_file(u".epub")
# Give the user key, ebook and TemporaryPersistent file to the decryption function.
try:
result = ineptepub.decryptBook(userkey, inf.name, of.name)
except:
print u"{0} v{1}: Exception when decrypting after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when decrypting after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
result = 1
@ -388,31 +389,31 @@ class DeDRM(FileTypePlugin):
if result == 0:
# Decryption was a success
# Store the new successful key in the defaults
print u"{0} v{1}: Saving a new default key".format(PLUGIN_NAME, PLUGIN_VERSION)
print(u"{0} v{1}: Saving a new default key".format(PLUGIN_NAME, PLUGIN_VERSION))
try:
dedrmprefs.addnamedvaluetoprefs('adeptkeys','default_key',keyvalue.encode('hex'))
dedrmprefs.writeprefs()
print u"{0} v{1}: Saved a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Saved a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
except:
print u"{0} v{1}: Exception when saving a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when saving a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
print u"{0} v{1}: Decrypted with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Decrypted with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
# Return the modified PersistentTemporary file to calibre.
return of.name
print u"{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
except Exception, e:
print u"{0} v{1}: Unexpected Exception trying a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Unexpected Exception trying a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
pass
# Something went wrong with decryption.
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
# Not a Barnes & Noble nor an Adobe Adept
# Import the fixed epub.
print u"{0} v{1}: “{2}” is neither an Adobe Adept nor a Barnes & Noble encrypted ePub".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))
print(u"{0} v{1}: “{2}” is neither an Adobe Adept nor a Barnes & Noble encrypted ePub".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))
raise DeDRMError(u"{0} v{1}: Couldn't decrypt after {2:.1f} seconds. DRM free perhaps?".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
def PDFDecrypt(self,path_to_ebook):
@ -421,17 +422,17 @@ class DeDRM(FileTypePlugin):
dedrmprefs = prefs.DeDRM_Prefs()
# Attempt to decrypt epub with each encryption key (generated or provided).
print u"{0} v{1}: {2} is a PDF ebook".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))
print(u"{0} v{1}: {2} is a PDF ebook".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))
for keyname, userkeyhex in dedrmprefs['adeptkeys'].items():
userkey = userkeyhex.decode('hex')
print u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname)
print(u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname))
of = self.temporary_file(u".pdf")
# Give the user key, ebook and TemporaryPersistent file to the decryption function.
try:
result = ineptpdf.decryptBook(userkey, path_to_ebook, of.name)
except:
print u"{0} v{1}: Exception when decrypting after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when decrypting after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
result = 1
@ -442,10 +443,10 @@ class DeDRM(FileTypePlugin):
# Return the modified PersistentTemporary file to calibre.
return of.name
print u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime)
print(u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime))
# perhaps we need to get a new default ADE key
print u"{0} v{1}: Looking for new default Adobe Digital Editions Keys after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Looking for new default Adobe Digital Editions Keys after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
# get the default Adobe keys
defaultkeys = []
@ -463,7 +464,7 @@ class DeDRM(FileTypePlugin):
self.default_key = defaultkeys[0]
except:
print u"{0} v{1}: Exception when getting default Adobe Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when getting default Adobe Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
self.default_key = u""
@ -475,14 +476,14 @@ class DeDRM(FileTypePlugin):
if len(newkeys) > 0:
try:
for i,userkey in enumerate(newkeys):
print u"{0} v{1}: Trying a new default key".format(PLUGIN_NAME, PLUGIN_VERSION)
print(u"{0} v{1}: Trying a new default key".format(PLUGIN_NAME, PLUGIN_VERSION))
of = self.temporary_file(u".pdf")
# Give the user key, ebook and TemporaryPersistent file to the decryption function.
try:
result = ineptpdf.decryptBook(userkey, path_to_ebook, of.name)
except:
print u"{0} v{1}: Exception when decrypting after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when decrypting after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
result = 1
@ -491,23 +492,23 @@ class DeDRM(FileTypePlugin):
if result == 0:
# Decryption was a success
# Store the new successful key in the defaults
print u"{0} v{1}: Saving a new default key".format(PLUGIN_NAME, PLUGIN_VERSION)
print(u"{0} v{1}: Saving a new default key".format(PLUGIN_NAME, PLUGIN_VERSION))
try:
dedrmprefs.addnamedvaluetoprefs('adeptkeys','default_key',keyvalue.encode('hex'))
dedrmprefs.writeprefs()
print u"{0} v{1}: Saved a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Saved a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
except:
print u"{0} v{1}: Exception when saving a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when saving a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
# Return the modified PersistentTemporary file to calibre.
return of.name
print u"{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
except Exception, e:
pass
# Something went wrong with decryption.
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
@ -538,8 +539,8 @@ class DeDRM(FileTypePlugin):
decoded = False
# perhaps we need to get a new default Kindle for Mac/PC key
defaultkeys = []
print u"{0} v{1}: Failed to decrypt with error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION,e.args[0])
print u"{0} v{1}: Looking for new default Kindle Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Failed to decrypt with error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION,e.args[0]))
print(u"{0} v{1}: Looking for new default Kindle Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
try:
if iswindows or isosx:
@ -552,7 +553,7 @@ class DeDRM(FileTypePlugin):
scriptpath = os.path.join(self.alfdir,u"kindlekey.py")
defaultkeys = WineGetKeys(scriptpath, u".k4i",dedrmprefs['kindlewineprefix'])
except:
print u"{0} v{1}: Exception when getting default Kindle Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
print(u"{0} v{1}: Exception when getting default Kindle Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc()
pass
@ -562,12 +563,12 @@ class DeDRM(FileTypePlugin):
if keyvalue not in dedrmprefs['kindlekeys'].values():
newkeys[keyname] = keyvalue
if len(newkeys) > 0:
print u"{0} v{1}: Found {2} new {3}".format(PLUGIN_NAME, PLUGIN_VERSION, len(newkeys), u"key" if len(newkeys)==1 else u"keys")
print(u"{0} v{1}: Found {2} new {3}".format(PLUGIN_NAME, PLUGIN_VERSION, len(newkeys), u"key" if len(newkeys)==1 else u"keys"))
try:
book = k4mobidedrm.GetDecryptedBook(path_to_ebook,newkeys.items(),[],[],[],self.starttime)
decoded = True
# store the new successful keys in the defaults
print u"{0} v{1}: Saving {2} new {3}".format(PLUGIN_NAME, PLUGIN_VERSION, len(newkeys), u"key" if len(newkeys)==1 else u"keys")
print(u"{0} v{1}: Saving {2} new {3}".format(PLUGIN_NAME, PLUGIN_VERSION, len(newkeys), u"key" if len(newkeys)==1 else u"keys"))
for keyvalue in newkeys.values():
dedrmprefs.addnamedvaluetoprefs('kindlekeys','default_key',keyvalue)
dedrmprefs.writeprefs()
@ -575,7 +576,7 @@ class DeDRM(FileTypePlugin):
pass
if not decoded:
#if you reached here then no luck raise and exception
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
of = self.temporary_file(book.getBookExtension())
@ -594,7 +595,7 @@ class DeDRM(FileTypePlugin):
# Attempt to decrypt epub with each encryption key (generated or provided).
for keyname, userkey in dedrmprefs['ereaderkeys'].items():
keyname_masked = u"".join((u'X' if (x.isdigit()) else x) for x in keyname)
print u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked)
print(u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked))
of = self.temporary_file(u".pmlz")
# Give the userkey, ebook and TemporaryPersistent file to the decryption function.
@ -605,12 +606,12 @@ class DeDRM(FileTypePlugin):
# Decryption was successful return the modified PersistentTemporary
# file to Calibre's import process.
if result == 0:
print u"{0} v{1}: Successfully decrypted with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime)
print(u"{0} v{1}: Successfully decrypted with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime))
return of.name
print u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime)
print(u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime))
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
@ -620,7 +621,7 @@ class DeDRM(FileTypePlugin):
sys.stdout=SafeUnbuffered(sys.stdout)
sys.stderr=SafeUnbuffered(sys.stderr)
print u"{0} v{1}: Trying to decrypt {2}".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))
print(u"{0} v{1}: Trying to decrypt {2}".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))
self.starttime = time.time()
booktype = os.path.splitext(path_to_ebook)[1].lower()[1:]
@ -639,9 +640,9 @@ class DeDRM(FileTypePlugin):
# Adobe Adept or B&N ePub
decrypted_ebook = self.ePubDecrypt(path_to_ebook)
else:
print u"Unknown booktype {0}. Passing back to calibre unchanged".format(booktype)
print(u"Unknown booktype {0}. Passing back to calibre unchanged".format(booktype))
return path_to_ebook
print u"{0} v{1}: Finished after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print(u"{0} v{1}: Finished after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
return decrypted_ebook
def is_customizable(self):

@ -52,6 +52,7 @@ from __future__ import with_statement
"""
Retrieve Adobe ADEPT user key.
"""
from __future__ import print_function
__license__ = 'GPL v3'
__version__ = '6.0'
@ -407,7 +408,7 @@ if iswindows:
keys.append(userkey)
if len(keys) == 0:
raise ADEPTError('Could not locate privateLicenseKey')
print u"Found {0:d} keys".format(len(keys))
print(u"Found {0:d} keys".format(len(keys)))
return keys
@ -465,7 +466,7 @@ def getkey(outpath):
outfile = outpath
with file(outfile, 'wb') as keyfileout:
keyfileout.write(keys[0])
print u"Saved a key to {0}".format(outfile)
print(u"Saved a key to {0}".format(outfile))
else:
keycount = 0
for key in keys:
@ -476,28 +477,28 @@ def getkey(outpath):
break
with file(outfile, 'wb') as keyfileout:
keyfileout.write(key)
print u"Saved a key to {0}".format(outfile)
print(u"Saved a key to {0}".format(outfile))
return True
return False
def usage(progname):
print u"Finds, decrypts and saves the default Adobe Adept encryption key(s)."
print u"Keys are saved to the current directory, or a specified output directory."
print u"If a file name is passed instead of a directory, only the first key is saved, in that file."
print u"Usage:"
print u" {0:s} [-h] [<outpath>]".format(progname)
print(u"Finds, decrypts and saves the default Adobe Adept encryption key(s).")
print(u"Keys are saved to the current directory, or a specified output directory.")
print(u"If a file name is passed instead of a directory, only the first key is saved, in that file.")
print(u"Usage:")
print(u" {0:s} [-h] [<outpath>]".format(progname))
def cli_main():
sys.stdout=SafeUnbuffered(sys.stdout)
sys.stderr=SafeUnbuffered(sys.stderr)
argv=unicode_argv()
progname = os.path.basename(argv[0])
print u"{0} v{1}\nCopyright © 2009-2013 i♥cabbages and Apprentice Alf".format(progname,__version__)
print(u"{0} v{1}\nCopyright © 2009-2013 i♥cabbages and Apprentice Alf".format(progname,__version__))
try:
opts, args = getopt.getopt(argv[1:], "h")
except getopt.GetoptError, err:
print u"Error in options or arguments: {0}".format(err.args[0])
print(u"Error in options or arguments: {0}".format(err.args[0]))
usage(progname)
sys.exit(2)
@ -528,7 +529,7 @@ def cli_main():
outfile = outpath
with file(outfile, 'wb') as keyfileout:
keyfileout.write(keys[0])
print u"Saved a key to {0}".format(outfile)
print(u"Saved a key to {0}".format(outfile))
else:
keycount = 0
for key in keys:
@ -539,9 +540,9 @@ def cli_main():
break
with file(outfile, 'wb') as keyfileout:
keyfileout.write(key)
print u"Saved a key to {0}".format(outfile)
print(u"Saved a key to {0}".format(outfile))
else:
print u"Could not retrieve Adobe Adept key."
print(u"Could not retrieve Adobe Adept key.")
return 0

@ -8,6 +8,7 @@
# pbkdf2.py Copyright © 2009 Daniel Holth <dholth@fastmail.fm>
# pbkdf2.py This code may be freely used and modified for any purpose.
from __future__ import print_function
import sys, os
import hmac
from struct import pack
@ -158,7 +159,7 @@ def _load_libalfcrypto():
topazCryptoDecrypt(ctx, data, out, len(data))
return out.raw
print u"Using Library AlfCrypto DLL/DYLIB/SO"
print(u"Using Library AlfCrypto DLL/DYLIB/SO")
return (AES_CBC, Pukall_Cipher, Topaz_Cipher)
@ -244,7 +245,7 @@ def _load_python_alfcrypto():
cleartext = self.aes.decrypt(iv + data)
return cleartext
print u"Using Library AlfCrypto Python"
print(u"Using Library AlfCrypto Python")
return (AES_CBC, Pukall_Cipher, Topaz_Cipher)

@ -21,6 +21,7 @@ from __future__ import with_statement
"""
Retrieve Kindle for Android Serial Number.
"""
from __future__ import print_function
__license__ = 'GPL v3'
__version__ = '1.5'
@ -228,7 +229,7 @@ def get_serials2(path=STORAGE2):
if len(userdata_utf8) > 0:
dsns.append(userdata_utf8)
except:
print "Error getting one of the device serial name keys"
print("Error getting one of the device serial name keys")
traceback.print_exc()
pass
dsns = list(set(dsns))
@ -243,7 +244,7 @@ def get_serials2(path=STORAGE2):
if len(userdata_utf8) > 0:
tokens.append(userdata_utf8)
except:
print "Error getting one of the account token keys"
print("Error getting one of the account token keys")
traceback.print_exc()
pass
tokens = list(set(tokens))
@ -321,13 +322,13 @@ def getkey(outfile, inpath):
def usage(progname):
print u"Decrypts the serial number(s) of Kindle For Android from Android backup or file"
print u"Get backup.ab file using adb backup com.amazon.kindle for Android 4.0+."
print u"Otherwise extract AmazonSecureStorage.xml from /data/data/com.amazon.kindle/shared_prefs/AmazonSecureStorage.xml"
print u"Or map_data_storage.db from /data/data/com.amazon.kindle/databases/map_data_storage.db"
print u""
print u"Usage:"
print u" {0:s} [-h] [-b <backup.ab>] [<outfile.k4a>]".format(progname)
print(u"Decrypts the serial number(s) of Kindle For Android from Android backup or file")
print(u"Get backup.ab file using adb backup com.amazon.kindle for Android 4.0+.")
print(u"Otherwise extract AmazonSecureStorage.xml from /data/data/com.amazon.kindle/shared_prefs/AmazonSecureStorage.xml")
print(u"Or map_data_storage.db from /data/data/com.amazon.kindle/databases/map_data_storage.db")
print(u"")
print(u"Usage:")
print(u" {0:s} [-h] [-b <backup.ab>] [<outfile.k4a>]".format(progname))
def cli_main():
@ -335,13 +336,13 @@ def cli_main():
sys.stderr=SafeUnbuffered(sys.stderr)
argv=unicode_argv()
progname = os.path.basename(argv[0])
print u"{0} v{1}\nCopyright © 2010-2015 Thom, some_updates, Apprentice Alf and Apprentice Harper".format(progname,__version__)
print(u"{0} v{1}\nCopyright © 2010-2015 Thom, some_updates, Apprentice Alf and Apprentice Harper".format(progname,__version__))
try:
opts, args = getopt.getopt(argv[1:], "hb:")
except getopt.GetoptError, err:
usage(progname)
print u"\nError in options or arguments: {0}".format(err.args[0])
print(u"\nError in options or arguments: {0}".format(err.args[0]))
return 2
inpath = ""
@ -373,13 +374,13 @@ def cli_main():
if not os.path.isfile(inpath):
usage(progname)
print u"\n{0:s} file not found".format(inpath)
print(u"\n{0:s} file not found".format(inpath))
return 2
if getkey(outfile, inpath):
print u"\nSaved Kindle for Android key to {0}".format(outfile)
print(u"\nSaved Kindle for Android key to {0}".format(outfile))
else:
print u"\nCould not retrieve Kindle for Android key."
print(u"\nCould not retrieve Kindle for Android key.")
return 0
@ -390,7 +391,7 @@ def gui_main():
import tkMessageBox
import tkFileDialog
except:
print "Tkinter not installed"
print("Tkinter not installed")
return cli_main()
class DecryptionDialog(Tkinter.Frame):

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from __future__ import print_function
__license__ = 'GPL v3'
@ -457,7 +458,7 @@ class ManageKeysDialog(QDialog):
class RenameKeyDialog(QDialog):
def __init__(self, parent=None,):
print repr(self), repr(parent)
print(repr(self), repr(parent))
QDialog.__init__(self, parent)
self.parent = parent
self.setWindowTitle("{0} {1}: Rename {0}".format(PLUGIN_NAME, PLUGIN_VERSION, parent.key_type_name))

@ -2,6 +2,7 @@
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.6
from __future__ import print_function
class Unbuffered:
def __init__(self, stream):
self.stream = stream
@ -139,7 +140,7 @@ class Dictionary(object):
self.pos = val
return self.stable[self.pos]
else:
print "Error - %d outside of string table limits" % val
print("Error - %d outside of string table limits" % val)
raise TpzDRMError('outside of string table limits')
# sys.exit(-1)
@ -151,7 +152,7 @@ class Dictionary(object):
def dumpDict(self):
for i in xrange(self.size):
print "%d %s %s" % (i, convert(i), self.stable[i])
print("%d %s %s" % (i, convert(i), self.stable[i]))
return
# parses the xml snippets that are represented by each page*.dat file.
@ -457,7 +458,7 @@ class PageParser(object):
elif (argtype == 'snippets') :
result = arg
else :
print "Error Unknown argtype %s" % argtype
print("Error Unknown argtype %s" % argtype)
sys.exit(-2)
return result
@ -469,7 +470,7 @@ class PageParser(object):
known_token = False
self.tag_push(token)
if self.debug : print 'Processing: ', self.get_tagpath(0)
if self.debug : print('Processing: ', self.get_tagpath(0))
cnt = self.tagpath_len()
for j in xrange(cnt):
tkn = self.get_tagpath(j)
@ -495,7 +496,7 @@ class PageParser(object):
if (subtags == 1):
ntags = readEncodedNumber(self.fo)
if self.debug : print 'subtags: ' + token + ' has ' + str(ntags)
if self.debug : print('subtags: ' + token + ' has ' + str(ntags))
for j in xrange(ntags):
val = readEncodedNumber(self.fo)
subtagres.append(self.procToken(self.dict.lookup(val)))
@ -529,7 +530,7 @@ class PageParser(object):
else:
result = []
if (self.debug or self.first_unknown):
print 'Unknown Token:', token
print('Unknown Token:', token)
self.first_unknown = False
self.tag_pop()
return result
@ -544,9 +545,9 @@ class PageParser(object):
result = 'Set of '+ str(cnt) + ' xml snippets. The overall structure \n'
result += 'of the document is indicated by snippet number sets at the\n'
result += 'end of each snippet. \n'
print result
print(result)
for i in xrange(cnt):
if self.debug: print 'Snippet:',str(i)
if self.debug: print('Snippet:',str(i))
snippet = []
snippet.append(i)
val = readEncodedNumber(self.fo)
@ -588,10 +589,10 @@ class PageParser(object):
cnt = readEncodedNumber(self.fo)
mode = readEncodedNumber(self.fo)
if self.debug : print 'Loop for', cnt, 'with mode', mode, ': '
if self.debug : print('Loop for', cnt, 'with mode', mode, ': ')
return self.doLoop76Mode(argtype, cnt, mode)
if self.dbug: print "Unknown command", cmd
if self.dbug: print("Unknown command", cmd)
result = []
return result
@ -720,7 +721,7 @@ class PageParser(object):
else:
rlst.append(self.formatTag(j))
result = "".join(rlst)
if self.debug : print result
if self.debug : print(result)
return result
@ -775,7 +776,7 @@ class PageParser(object):
self.doc.append(tag)
else:
if self.debug:
print "Main Loop: Unknown value: %x" % v
print("Main Loop: Unknown value: %x" % v)
if (v == 0):
if (self.peek(1) == 0x5f):
skip = self.fo.read(1)
@ -783,11 +784,11 @@ class PageParser(object):
# now do snippet injection
if len(self.snippetList) > 0 :
if self.debug : print 'Injecting Snippets:'
if self.debug : print('Injecting Snippets:')
snippet = self.injectSnippets(self.snippetList[0])
snipno = snippet[0]
tag_add = snippet[1]
if self.debug : print self.formatTag(tag_add)
if self.debug : print(self.formatTag(tag_add))
if len(tag_add) > 0:
self.doc.append(tag_add)
@ -812,19 +813,19 @@ def getXML(dict, fname):
return xmlpage
def usage():
print 'Usage: '
print ' convert2xml.py dict0000.dat infile.dat '
print ' '
print ' Options:'
print ' -h print this usage help message '
print ' -d turn on debug output to check for potential errors '
print ' --flat-xml output the flattened xml page description only '
print ' '
print ' This program will attempt to convert a page*.dat file or '
print ' glyphs*.dat file, using the dict0000.dat file, to its xml description. '
print ' '
print ' Use "cmbtc_dump.py" first to unencrypt, uncompress, and dump '
print ' the *.dat files from a Topaz format e-book.'
print('Usage: ')
print(' convert2xml.py dict0000.dat infile.dat ')
print(' ')
print(' Options:')
print(' -h print this usage help message ')
print(' -d turn on debug output to check for potential errors ')
print(' --flat-xml output the flattened xml page description only ')
print(' ')
print(' This program will attempt to convert a page*.dat file or ')
print(' glyphs*.dat file, using the dict0000.dat file, to its xml description. ')
print(' ')
print(' Use "cmbtc_dump.py" first to unencrypt, uncompress, and dump ')
print(' the *.dat files from a Topaz format e-book.')
#
# Main
@ -846,7 +847,7 @@ def main(argv):
except getopt.GetoptError, err:
# print help information and exit:
print str(err) # will print something like "option -a not recognized"
print(str(err)) # will print something like "option -a not recognized"
usage()
sys.exit(2)
@ -875,7 +876,7 @@ def main(argv):
xmlpage = pp.process()
if printOutput:
print xmlpage
print(xmlpage)
return 0
return xmlpage

@ -15,6 +15,7 @@ Provide base64 encoding.
"""
from __future__ import with_statement
from __future__ import print_function
__license__ = 'GPL v3'
@ -23,9 +24,9 @@ import os
import base64
def usage(progname):
print "Applies base64 encoding to the supplied file, sending to standard output"
print "Usage:"
print " %s <infile>" % progname
print("Applies base64 encoding to the supplied file, sending to standard output")
print("Usage:")
print(" %s <infile>" % progname)
def cli_main(argv=sys.argv):
progname = os.path.basename(argv[0])
@ -37,7 +38,7 @@ def cli_main(argv=sys.argv):
keypath = argv[1]
with open(keypath, 'rb') as f:
keyder = f.read()
print keyder.encode('base64')
print(keyder.encode('base64'))
return 0

@ -45,6 +45,7 @@
#
from __future__ import with_statement
from __future__ import print_function
__version__ = '1.01'
@ -199,7 +200,7 @@ def encryption(infile):
def main():
argv=unicode_argv()
print encryption(argv[1])
print(encryption(argv[1]))
return 0
if __name__ == "__main__":

@ -2,6 +2,7 @@
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.6
from __future__ import print_function
import sys
import csv
import os
@ -750,11 +751,11 @@ class DocParser(object):
hlst.append('<div class="graphic"><img src="img/img%04d.jpg" alt="" /></div>' % int(simgsrc))
else :
print ' Making region type', regtype,
print(' Making region type', regtype, end=' ')
(pos, temp) = self.findinDoc('paragraph',start,end)
(pos2, temp) = self.findinDoc('span',start,end)
if pos != -1 or pos2 != -1:
print ' a "text" region'
print(' a "text" region')
orig_regtype = regtype
regtype = 'fixed'
ptype = 'full'
@ -779,7 +780,7 @@ class DocParser(object):
else :
hlst.append(self.buildParagraph(pclass, pdesc, ptype, regtype))
else :
print ' a "graphic" region'
print(' a "graphic" region')
(pos, simgsrc) = self.findinDoc('img.src',start,end)
if simgsrc:
hlst.append('<div class="graphic"><img src="img/img%04d.jpg" alt="" /></div>' % int(simgsrc))

@ -1,6 +1,7 @@
#! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
from __future__ import print_function
from .convert2xml import encodeNumber
class Unbuffered:
@ -119,7 +120,7 @@ class Dictionary(object):
self.pos = val
return self.stable[self.pos]
else:
print "Error: %d outside of string table limits" % val
print("Error: %d outside of string table limits" % val)
raise TpzDRMError('outside or string table limits')
# sys.exit(-1)
def getSize(self):
@ -270,32 +271,32 @@ class GlyphDict(object):
def generateBook(bookDir, raw, fixedimage):
# sanity check Topaz file extraction
if not os.path.exists(bookDir) :
print "Can not find directory with unencrypted book"
print("Can not find directory with unencrypted book")
return 1
dictFile = os.path.join(bookDir,'dict0000.dat')
if not os.path.exists(dictFile) :
print "Can not find dict0000.dat file"
print("Can not find dict0000.dat file")
return 1
pageDir = os.path.join(bookDir,'page')
if not os.path.exists(pageDir) :
print "Can not find page directory in unencrypted book"
print("Can not find page directory in unencrypted book")
return 1
imgDir = os.path.join(bookDir,'img')
if not os.path.exists(imgDir) :
print "Can not find image directory in unencrypted book"
print("Can not find image directory in unencrypted book")
return 1
glyphsDir = os.path.join(bookDir,'glyphs')
if not os.path.exists(glyphsDir) :
print "Can not find glyphs directory in unencrypted book"
print("Can not find glyphs directory in unencrypted book")
return 1
metaFile = os.path.join(bookDir,'metadata0000.dat')
if not os.path.exists(metaFile) :
print "Can not find metadata0000.dat in unencrypted book"
print("Can not find metadata0000.dat in unencrypted book")
return 1
svgDir = os.path.join(bookDir,'svg')
@ -309,10 +310,10 @@ def generateBook(bookDir, raw, fixedimage):
otherFile = os.path.join(bookDir,'other0000.dat')
if not os.path.exists(otherFile) :
print "Can not find other0000.dat in unencrypted book"
print("Can not find other0000.dat in unencrypted book")
return 1
print "Updating to color images if available"
print("Updating to color images if available")
spath = os.path.join(bookDir,'color_img')
dpath = os.path.join(bookDir,'img')
filenames = os.listdir(spath)
@ -324,7 +325,7 @@ def generateBook(bookDir, raw, fixedimage):
imgdata = file(sfile,'rb').read()
file(dfile,'wb').write(imgdata)
print "Creating cover.jpg"
print("Creating cover.jpg")
isCover = False
cpath = os.path.join(bookDir,'img')
cpath = os.path.join(cpath,'img0000.jpg')
@ -335,10 +336,10 @@ def generateBook(bookDir, raw, fixedimage):
isCover = True
print 'Processing Dictionary'
print('Processing Dictionary')
dict = Dictionary(dictFile)
print 'Processing Meta Data and creating OPF'
print('Processing Meta Data and creating OPF')
meta_array = getMetaArray(metaFile)
# replace special chars in title and authors like & < >
@ -362,7 +363,7 @@ def generateBook(bookDir, raw, fixedimage):
mlst = None
file(xname, 'wb').write(metastr)
print 'Processing StyleSheet'
print('Processing StyleSheet')
# get some scaling info from metadata to use while processing styles
# and first page info
@ -428,7 +429,7 @@ def generateBook(bookDir, raw, fixedimage):
xname = os.path.join(xmlDir, 'other0000.xml')
file(xname, 'wb').write(convert2xml.getXML(dict, otherFile))
print 'Processing Glyphs'
print('Processing Glyphs')
gd = GlyphDict()
filenames = os.listdir(glyphsDir)
filenames = sorted(filenames)
@ -442,7 +443,7 @@ def generateBook(bookDir, raw, fixedimage):
counter = 0
for filename in filenames:
# print ' ', filename
print '.',
print('.', end=' ')
fname = os.path.join(glyphsDir,filename)
flat_xml = convert2xml.fromData(dict, fname)
@ -461,7 +462,7 @@ def generateBook(bookDir, raw, fixedimage):
glyfile.write('</defs>\n')
glyfile.write('</svg>\n')
glyfile.close()
print " "
print(" ")
# start up the html
@ -483,7 +484,7 @@ def generateBook(bookDir, raw, fixedimage):
hlst.append('<link href="style.css" rel="stylesheet" type="text/css" />\n')
hlst.append('</head>\n<body>\n')
print 'Processing Pages'
print('Processing Pages')
# Books are at 1440 DPI. This is rendering at twice that size for
# readability when rendering to the screen.
scaledpi = 1440.0
@ -497,7 +498,7 @@ def generateBook(bookDir, raw, fixedimage):
for filename in filenames:
# print ' ', filename
print ".",
print(".", end=' ')
fname = os.path.join(pageDir,filename)
flat_xml = convert2xml.fromData(dict, fname)
@ -519,8 +520,8 @@ def generateBook(bookDir, raw, fixedimage):
hlst = None
file(os.path.join(bookDir, htmlFileName), 'wb').write(htmlstr)
print " "
print 'Extracting Table of Contents from Amazon OCR'
print(" ")
print('Extracting Table of Contents from Amazon OCR')
# first create a table of contents file for the svg images
tlst = []
@ -552,7 +553,7 @@ def generateBook(bookDir, raw, fixedimage):
toclst = tocentries.split('\n')
toclst.pop()
for entry in toclst:
print entry
print(entry)
title, pagenum = entry.split('|')
id = pageidnums[int(pagenum)]
if (raw):
@ -582,7 +583,7 @@ def generateBook(bookDir, raw, fixedimage):
slst.append('</head>\n')
slst.append('<body>\n')
print "Building svg images of each book page"
print("Building svg images of each book page")
slst.append('<h2>List of Pages</h2>\n')
slst.append('<div>\n')
idlst = sorted(pageIDMap.keys())
@ -595,7 +596,7 @@ def generateBook(bookDir, raw, fixedimage):
nextid = idlst[j+1]
else:
nextid = None
print '.',
print('.', end=' ')
pagelst = pageIDMap[pageid]
flst = []
for page in pagelst:
@ -620,7 +621,7 @@ def generateBook(bookDir, raw, fixedimage):
slst = None
file(os.path.join(bookDir, 'index_svg.xhtml'), 'wb').write(svgindex)
print " "
print(" ")
# build the opf file
opfname = os.path.join(bookDir, 'book.opf')
@ -669,20 +670,20 @@ def generateBook(bookDir, raw, fixedimage):
olst = None
file(opfname, 'wb').write(opfstr)
print 'Processing Complete'
print('Processing Complete')
return 0
def usage():
print "genbook.py generates a book from the extract Topaz Files"
print "Usage:"
print " genbook.py [-r] [-h [--fixed-image] <bookDir> "
print " "
print "Options:"
print " -h : help - print this usage message"
print " -r : generate raw svg files (not wrapped in xhtml)"
print " --fixed-image : genearate any Fixed Area as an svg image in the html"
print " "
print("genbook.py generates a book from the extract Topaz Files")
print("Usage:")
print(" genbook.py [-r] [-h [--fixed-image] <bookDir> ")
print(" ")
print("Options:")
print(" -h : help - print this usage message")
print(" -r : generate raw svg files (not wrapped in xhtml)")
print(" --fixed-image : genearate any Fixed Area as an svg image in the html")
print(" ")
def main(argv):
@ -694,7 +695,7 @@ def main(argv):
opts, args = getopt.getopt(argv[1:], "rh:",["fixed-image"])
except getopt.GetoptError, err:
print str(err)
print(str(err))
usage()
return 1

@ -41,6 +41,7 @@ from __future__ import with_statement
"""
Decrypt Barnes & Noble encrypted ePub books.
"""
from __future__ import print_function
__license__ = 'GPL v3'
__version__ = "4.1"
@ -262,7 +263,7 @@ def decryptBook(keyb64, inpath, outpath):
namelist = set(inf.namelist())
if 'META-INF/rights.xml' not in namelist or \
'META-INF/encryption.xml' not in namelist:
print u"{0:s} is DRM-free.".format(os.path.basename(inpath))
print(u"{0:s} is DRM-free.".format(os.path.basename(inpath)))
return 1
for name in META_NAMES:
namelist.remove(name)
@ -272,7 +273,7 @@ def decryptBook(keyb64, inpath, outpath):
expr = './/%s' % (adept('encryptedKey'),)
bookkey = ''.join(rights.findtext(expr))
if len(bookkey) != 64:
print u"{0:s} is not a secure Barnes & Noble ePub.".format(os.path.basename(inpath))
print(u"{0:s} is not a secure Barnes & Noble ePub.".format(os.path.basename(inpath)))
return 1
bookkey = aes.decrypt(bookkey.decode('base64'))
bookkey = bookkey[:-ord(bookkey[-1])]
@ -315,7 +316,7 @@ def decryptBook(keyb64, inpath, outpath):
pass
outf.writestr(zi, decryptor.decrypt(path, data))
except:
print u"Could not decrypt {0:s} because of an exception:\n{1:s}".format(os.path.basename(inpath), traceback.format_exc())
print(u"Could not decrypt {0:s} because of an exception:\n{1:s}".format(os.path.basename(inpath), traceback.format_exc()))
return 2
return 0
@ -326,13 +327,13 @@ def cli_main():
argv=unicode_argv()
progname = os.path.basename(argv[0])
if len(argv) != 4:
print u"usage: {0} <keyfile.b64> <inbook.epub> <outbook.epub>".format(progname)
print(u"usage: {0} <keyfile.b64> <inbook.epub> <outbook.epub>".format(progname))
return 1
keypath, inpath, outpath = argv[1:]
userkey = open(keypath,'rb').read()
result = decryptBook(userkey, inpath, outpath)
if result == 0:
print u"Successfully decrypted {0:s} as {1:s}".format(os.path.basename(inpath),os.path.basename(outpath))
print(u"Successfully decrypted {0:s} as {1:s}".format(os.path.basename(inpath),os.path.basename(outpath)))
return result
def gui_main():

@ -18,6 +18,7 @@ from __future__ import with_statement
"""
Get Barnes & Noble EPUB user key from nook Studio log file
"""
from __future__ import print_function
__license__ = 'GPL v3'
__version__ = "1.1"
@ -198,7 +199,7 @@ def nookkeys(files = []):
for file in files:
fileKeys = getKeysFromLog(file)
if fileKeys:
print u"Found {0} keys in the Nook Study log files".format(len(fileKeys))
print(u"Found {0} keys in the Nook Study log files".format(len(fileKeys)))
keys.extend(fileKeys)
return list(set(keys))
@ -211,7 +212,7 @@ def getkey(outpath, files=[]):
outfile = outpath
with file(outfile, 'w') as keyfileout:
keyfileout.write(keys[-1])
print u"Saved a key to {0}".format(outfile)
print(u"Saved a key to {0}".format(outfile))
else:
keycount = 0
for key in keys:
@ -222,16 +223,16 @@ def getkey(outpath, files=[]):
break
with file(outfile, 'w') as keyfileout:
keyfileout.write(key)
print u"Saved a key to {0}".format(outfile)
print(u"Saved a key to {0}".format(outfile))
return True
return False
def usage(progname):
print u"Finds the nook Study encryption keys."
print u"Keys are saved to the current directory, or a specified output directory."
print u"If a file name is passed instead of a directory, only the first key is saved, in that file."
print u"Usage:"
print u" {0:s} [-h] [-k <logFile>] [<outpath>]".format(progname)
print(u"Finds the nook Study encryption keys.")
print(u"Keys are saved to the current directory, or a specified output directory.")
print(u"If a file name is passed instead of a directory, only the first key is saved, in that file.")
print(u"Usage:")
print(u" {0:s} [-h] [-k <logFile>] [<outpath>]".format(progname))
def cli_main():
@ -239,12 +240,12 @@ def cli_main():
sys.stderr=SafeUnbuffered(sys.stderr)
argv=unicode_argv()
progname = os.path.basename(argv[0])
print u"{0} v{1}\nCopyright © 2015 Apprentice Alf".format(progname,__version__)
print(u"{0} v{1}\nCopyright © 2015 Apprentice Alf".format(progname,__version__))
try:
opts, args = getopt.getopt(argv[1:], "hk:")
except getopt.GetoptError, err:
print u"Error in options or arguments: {0}".format(err.args[0])
print(u"Error in options or arguments: {0}".format(err.args[0]))
usage(progname)
sys.exit(2)
@ -273,7 +274,7 @@ def cli_main():
outpath = os.path.realpath(os.path.normpath(outpath))
if not getkey(outpath, files):
print u"Could not retrieve nook Study key."
print(u"Could not retrieve nook Study key.")
return 0
@ -307,7 +308,7 @@ def gui_main():
keys = nookkeys()
keycount = 0
for key in keys:
print key
print(key)
while True:
keycount += 1
outfile = os.path.join(progpath,u"nookkey{0:d}.b64".format(keycount))

@ -28,6 +28,7 @@ from __future__ import with_statement
"""
Fetch Barnes & Noble EPUB user key from B&N servers using email and password
"""
from __future__ import print_function
__license__ = 'GPL v3'
__version__ = "1.1"
@ -155,14 +156,14 @@ def cli_main():
argv=unicode_argv()
progname = os.path.basename(argv[0])
if len(argv) != 4:
print u"usage: {0} <email> <password> <keyfileout.b64>".format(progname)
print(u"usage: {0} <email> <password> <keyfileout.b64>".format(progname))
return 1
email, password, keypath = argv[1:]
userkey = fetch_key(email, password)
if len(userkey) == 28:
open(keypath,'wb').write(userkey)
return 0
print u"Failed to fetch key."
print(u"Failed to fetch key.")
return 1

@ -38,6 +38,7 @@ from __future__ import with_statement
"""
Generate Barnes & Noble EPUB user key from name and credit card number.
"""
from __future__ import print_function
__license__ = 'GPL v3'
__version__ = "2.8"
@ -223,12 +224,12 @@ def cli_main():
argv=unicode_argv()
progname = os.path.basename(argv[0])
if AES is None:
print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \
print("%s: This script requires OpenSSL or PyCrypto, which must be installed " \
"separately. Read the top-of-script comment for details." % \
(progname,)
(progname,))
return 1
if len(argv) != 4:
print u"usage: {0} <Name> <CC#> <keyfileout.b64>".format(progname)
print(u"usage: {0} <Name> <CC#> <keyfileout.b64>".format(progname))
return 1
name, ccn, keypath = argv[1:]
userkey = generate_key(name, ccn)

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from __future__ import print_function
# Engine to remove drm from Kindle KFX ebooks
@ -43,7 +44,7 @@ class KFXZipBook:
data += fh.read()
if self.voucher is None:
self.decrypt_voucher(totalpids)
print u'Decrypting KFX DRMION: {0}'.format(filename)
print(u'Decrypting KFX DRMION: {0}'.format(filename))
outfile = StringIO()
ion.DrmIon(StringIO(data[8:-8]), lambda name: self.voucher).parse(outfile)
self.decrypted[filename] = outfile.getvalue()
@ -65,7 +66,7 @@ class KFXZipBook:
else:
raise Exception(u'The .kfx-zip archive contains an encrypted DRMION file without a DRM voucher')
print u'Decrypting KFX DRM voucher: {0}'.format(info.filename)
print(u'Decrypting KFX DRM voucher: {0}'.format(info.filename))
for pid in [''] + totalpids:
for dsn_len,secret_len in [(0,0), (16,0), (16,40), (32,40), (40,40)]:
@ -84,7 +85,7 @@ class KFXZipBook:
else:
raise Exception(u'Failed to decrypt KFX DRM voucher with any key')
print u'KFX DRM voucher successfully decrypted'
print(u'KFX DRM voucher successfully decrypted')
license_type = voucher.getlicensetype()
if license_type != "Purchase":

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from __future__ import print_function
# kgenpids.py
# Copyright © 2008-2017 Apprentice Harper et al.
@ -214,7 +215,7 @@ def getK4Pids(rec209, token, kindleDatabase):
try:
# Get the DSN token, if present
DSN = (kindleDatabase[1])['DSN'].decode('hex')
print u"Got DSN key from database {0}".format(kindleDatabase[0])
print(u"Got DSN key from database {0}".format(kindleDatabase[0]))
except KeyError:
# See if we have the info to generate the DSN
try:
@ -225,7 +226,7 @@ def getK4Pids(rec209, token, kindleDatabase):
try:
# Get the SerialNumber token, if present
IDString = (kindleDatabase[1])['SerialNumber'].decode('hex')
print u"Got SerialNumber from database {0}".format(kindleDatabase[0])
print(u"Got SerialNumber from database {0}".format(kindleDatabase[0]))
except KeyError:
# Get the IDString we added
IDString = (kindleDatabase[1])['IDString'].decode('hex')
@ -233,7 +234,7 @@ def getK4Pids(rec209, token, kindleDatabase):
try:
# Get the UsernameHash token, if present
encodedUsername = (kindleDatabase[1])['UsernameHash'].decode('hex')
print u"Got UsernameHash from database {0}".format(kindleDatabase[0])
print(u"Got UsernameHash from database {0}".format(kindleDatabase[0]))
except KeyError:
# Get the UserName we added
UserName = (kindleDatabase[1])['UserName'].decode('hex')
@ -241,7 +242,7 @@ def getK4Pids(rec209, token, kindleDatabase):
encodedUsername = encodeHash(UserName,charMap1)
#print u"encodedUsername",encodedUsername.encode('hex')
except KeyError:
print u"Keys not found in the database {0}.".format(kindleDatabase[0])
print(u"Keys not found in the database {0}.".format(kindleDatabase[0]))
return pids
# Get the ID string used
@ -297,14 +298,14 @@ def getPidList(md1, md2, serials=[], kDatabases=[]):
try:
pidlst.extend(getK4Pids(md1, md2, kDatabase))
except Exception, e:
print u"Error getting PIDs from database {0}: {1}".format(kDatabase[0],e.args[0])
print(u"Error getting PIDs from database {0}: {1}".format(kDatabase[0],e.args[0]))
traceback.print_exc()
for serialnum in serials:
try:
pidlst.extend(getKindlePids(md1, md2, serialnum))
except Exception, e:
print u"Error getting PIDs from serial number {0}: {1}".format(serialnum ,e.args[0])
print(u"Error getting PIDs from serial number {0}: {1}".format(serialnum ,e.args[0]))
traceback.print_exc()
return pidlst

@ -11,6 +11,7 @@
# 0.4 Added support for serial numbers starting with '9', fixed unicode bugs.
# 0.5 moved unicode_argv call inside main for Windows DeDRM compatibility
from __future__ import print_function
import sys
import binascii
@ -73,7 +74,7 @@ def unicode_argv():
return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv]
if sys.hexversion >= 0x3000000:
print 'This script is incompatible with Python 3.x. Please install Python 2.7.x.'
print('This script is incompatible with Python 3.x. Please install Python 2.7.x.')
sys.exit(2)
letters = 'ABCDEFGHIJKLMNPQRSTUVWXYZ123456789'
@ -113,28 +114,28 @@ def pidFromSerial(s, l):
return pid
def cli_main():
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")
argv=unicode_argv()
if len(argv)==2:
serial = argv[1]
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
if len(serial)==16:
if serial.startswith("B") or serial.startswith("9"):
print u"Kindle serial number detected"
print(u"Kindle serial number detected")
else:
print u"Warning: unrecognized serial number. Please recheck input."
print(u"Warning: unrecognized serial number. Please recheck input.")
return 1
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
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)
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
print u"Warning: unrecognized serial number. Please recheck input."
print(u"Warning: unrecognized serial number. Please recheck input.")
return 1

@ -5,6 +5,7 @@
# Copyright © 2008 The Dark Reverser
# Portions © 20082017 Apprentice Harper et al.
from __future__ import print_function
__license__ = 'GPL v3'
__version__ = u"0.42"
@ -80,7 +81,7 @@ import binascii
try:
from alfcrypto import Pukall_Cipher
except:
print u"AlfCrypto not found. Using python PC1 implementation."
print(u"AlfCrypto not found. Using python PC1 implementation.")
# Wrap a stream so that output gets flushed immediately
# and also make sure that any unicode strings get
@ -244,12 +245,12 @@ class MobiBook:
pass
def __init__(self, infile):
print u"MobiDeDrm v{0:s}.\nCopyright © 2008-2017 The Dark Reverser, Apprentice Harper et al.".format(__version__)
print(u"MobiDeDrm v{0:s}.\nCopyright © 2008-2017 The Dark Reverser, Apprentice Harper et al.".format(__version__))
try:
from alfcrypto import Pukall_Cipher
except:
print u"AlfCrypto not found. Using python PC1 implementation."
print(u"AlfCrypto not found. Using python PC1 implementation.")
# initial sanity check on file
self.data_file = file(infile, 'rb').read()
@ -282,7 +283,7 @@ class MobiBook:
self.mobi_version = -1
if self.magic == 'TEXtREAd':
print u"PalmDoc format book detected."
print(u"PalmDoc format book detected.")
return
self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18])
@ -424,10 +425,10 @@ class MobiBook:
def processBook(self, pidlist):
crypto_type, = struct.unpack('>H', self.sect[0xC:0xC+2])
print u"Crypto Type is: {0:d}".format(crypto_type)
print(u"Crypto Type is: {0:d}".format(crypto_type))
self.crypto_type = crypto_type
if crypto_type == 0:
print u"This book is not encrypted."
print(u"This book is not encrypted.")
# we must still check for Print Replica
self.print_replica = (self.loadSection(1)[0:4] == '%MOP')
self.mobi_data = self.data_file
@ -444,12 +445,12 @@ class MobiBook:
for pid in pidlist:
if len(pid)==10:
if checksumPid(pid[0:-2]) != pid:
print u"Warning: PID {0} has incorrect checksum, should have been {1}".format(pid,checksumPid(pid[0:-2]))
print(u"Warning: PID {0} has incorrect checksum, should have been {1}".format(pid,checksumPid(pid[0:-2])))
goodpids.append(pid[0:-2])
elif len(pid)==8:
goodpids.append(pid)
else:
print u"Warning: PID {0} has wrong number of digits".format(pid)
print(u"Warning: PID {0} has wrong number of digits".format(pid))
if self.crypto_type == 1:
t1_keyvec = 'QDCVEPMU675RUBSZ'
@ -475,22 +476,22 @@ class MobiBook:
self.patchSection(0, '\xff' * 4 + '\0' * 12, 0xA8)
if pid=='00000000':
print u"File has default encryption, no specific key needed."
print(u"File has default encryption, no specific key needed.")
else:
print u"File is encoded with PID {0}.".format(checksumPid(pid))
print(u"File is encoded with PID {0}.".format(checksumPid(pid)))
# clear the crypto type
self.patchSection(0, "\0" * 2, 0xC)
# decrypt sections
print u"Decrypting. Please wait . . .",
print(u"Decrypting. Please wait . . .", end=' ')
mobidataList = []
mobidataList.append(self.data_file[:self.sections[1][0]])
for i in xrange(1, self.records+1):
data = self.loadSection(i)
extra_size = getSizeOfTrailingDataEntries(data, len(data), self.extra_data_flags)
if i%100 == 0:
print u".",
print(u".", end=' ')
# print "record %d, extra_size %d" %(i,extra_size)
decoded_data = PC1(found_key, data[0:len(data) - extra_size])
if i==1:
@ -501,7 +502,7 @@ class MobiBook:
if self.num_sections > self.records+1:
mobidataList.append(self.data_file[self.sections[self.records+1][0]:])
self.mobi_data = "".join(mobidataList)
print u"done"
print(u"done")
return
def getUnencryptedBook(infile,pidlist):
@ -516,10 +517,10 @@ def cli_main():
argv=unicode_argv()
progname = os.path.basename(argv[0])
if len(argv)<3 or len(argv)>4:
print u"MobiDeDrm v{0:s}.\nCopyright © 2008-2017 The Dark Reverser, Apprentice Harper et al.".format(__version__)
print u"Removes protection from Kindle/Mobipocket, Kindle/KF8 and Kindle/Print Replica ebooks"
print u"Usage:"
print u" {0} <infile> <outfile> [<Comma separated list of PIDs to try>]".format(progname)
print(u"MobiDeDrm v{0:s}.\nCopyright © 2008-2017 The Dark Reverser, Apprentice Harper et al.".format(__version__))
print(u"Removes protection from Kindle/Mobipocket, Kindle/KF8 and Kindle/Print Replica ebooks")
print(u"Usage:")
print(u" {0} <infile> <outfile> [<Comma separated list of PIDs to try>]".format(progname))
return 1
else:
infile = argv[1]
@ -532,7 +533,7 @@ def cli_main():
stripped_file = getUnencryptedBook(infile, pidlist)
file(outfile, 'wb').write(stripped_file)
except DrmException, e:
print u"MobiDeDRM v{0} Error: {1:s}".format(__version__,e.args[0])
print(u"MobiDeDRM v{0} Error: {1:s}".format(__version__,e.args[0]))
return 1
return 0

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
from __future__ import print_function
import sys
import os
import re
@ -23,7 +24,7 @@ def decryptepub(infile, outdir, rscpath):
zippath = os.path.join(bpath,name + '_temp.zip')
rv = zipfix.repairBook(infile, zippath)
if rv != 0:
print "Error while trying to fix epub"
print("Error while trying to fix epub")
return rv
# determine a good name for the output file
@ -43,7 +44,7 @@ def decryptepub(infile, outdir, rscpath):
try:
rv = ineptepub.decryptBook(userkey, zippath, outfile)
if rv == 0:
print "Decrypted Adobe ePub with key file {0}".format(filename)
print("Decrypted Adobe ePub with key file {0}".format(filename))
break
except Exception, e:
errlog += traceback.format_exc()
@ -63,7 +64,7 @@ def decryptepub(infile, outdir, rscpath):
try:
rv = ignobleepub.decryptBook(userkey, zippath, outfile)
if rv == 0:
print "Decrypted B&N ePub with key file {0}".format(filename)
print("Decrypted B&N ePub with key file {0}".format(filename))
break
except Exception, e:
errlog += traceback.format_exc()
@ -72,14 +73,14 @@ def decryptepub(infile, outdir, rscpath):
else:
encryption = epubtest.encryption(zippath)
if encryption == "Unencrypted":
print "{0} is not DRMed.".format(name)
print("{0} is not DRMed.".format(name))
rv = 0
else:
print "{0} has an unknown encryption.".format(name)
print("{0} has an unknown encryption.".format(name))
os.remove(zippath)
if rv != 0:
print errlog
print(errlog)
return rv
@ -109,7 +110,7 @@ def decryptpdf(infile, outdir, rscpath):
rv = 1
if rv != 0:
print errlog
print(errlog)
return rv
@ -127,7 +128,7 @@ def decryptpdb(infile, outdir, rscpath):
try:
name, cc8 = i.split(':')
except ValueError:
print ' Error parsing user supplied social drm data.'
print(' Error parsing user supplied social drm data.')
return 1
try:
rv = erdr2pml.decryptBook(infile, outpath, True, erdr2pml.getuser_key(name, cc8))

@ -2,6 +2,7 @@
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.6
from __future__ import print_function
import csv
import sys
import os
@ -114,9 +115,9 @@ class DocParser(object):
# process each style converting what you can
if debug: print ' ', 'Processing styles.'
if debug: print(' ', 'Processing styles.')
for j in xrange(stylecnt):
if debug: print ' ', 'Processing style %d' %(j)
if debug: print(' ', 'Processing style %d' %(j))
start = styleList[j]
end = styleList[j+1]
@ -135,7 +136,7 @@ class DocParser(object):
else :
sclass = ''
if debug: print 'sclass', sclass
if debug: print('sclass', sclass)
# check for any "after class" specifiers
(pos, aftclass) = self.findinDoc('style._after_class',start,end)
@ -145,7 +146,7 @@ class DocParser(object):
else :
aftclass = ''
if debug: print 'aftclass', aftclass
if debug: print('aftclass', aftclass)
cssargs = {}
@ -154,8 +155,8 @@ class DocParser(object):
(pos1, attr) = self.findinDoc('style.rule.attr', start, end)
(pos2, val) = self.findinDoc('style.rule.value', start, end)
if debug: print 'attr', attr
if debug: print 'val', val
if debug: print('attr', attr)
if debug: print('val', val)
if attr == None : break
@ -182,7 +183,7 @@ class DocParser(object):
try:
f = float(val)
except:
print "Warning: unrecognised val, ignoring"
print("Warning: unrecognised val, ignoring")
val = 0
pv = float(val)/scale
cssargs[attr] = (self.attr_val_map[attr], pv)
@ -194,7 +195,7 @@ class DocParser(object):
if aftclass != "" : keep = False
if keep :
if debug: print 'keeping style'
if debug: print('keeping style')
# make sure line-space does not go below 100% or above 300% since
# it can be wacky in some styles
if 'line-space' in cssargs:
@ -266,15 +267,15 @@ class DocParser(object):
def convert2CSS(flatxml, fontsize, ph, pw):
print ' ', 'Using font size:',fontsize
print ' ', 'Using page height:', ph
print ' ', 'Using page width:', pw
print(' ', 'Using font size:',fontsize)
print(' ', 'Using page height:', ph)
print(' ', 'Using page width:', pw)
# create a document parser
dp = DocParser(flatxml, fontsize, ph, pw)
if debug: print ' ', 'Created DocParser.'
if debug: print(' ', 'Created DocParser.')
csspage = dp.process()
if debug: print ' ', 'Processed DocParser.'
if debug: print(' ', 'Processed DocParser.')
return csspage

@ -8,6 +8,7 @@
# 4.9 - moved unicode_argv call inside main for Windows DeDRM compatibility
# 5.0 - Fixed potential unicode problem with command line interface
from __future__ import print_function
__version__ = '5.0'
import sys
@ -213,7 +214,7 @@ class TopazBook:
# Read and return the data of one header record at the current book file position
# [[offset,decompressedLength,compressedLength],...]
nbValues = bookReadEncodedNumber(self.fo)
if debug: print "%d records in header " % nbValues,
if debug: print("%d records in header " % nbValues, end=' ')
values = []
for i in range (0,nbValues):
values.append([bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo)])
@ -227,10 +228,10 @@ class TopazBook:
record = bookReadHeaderRecordData()
return [tag,record]
nbRecords = bookReadEncodedNumber(self.fo)
if debug: print "Headers: %d" % nbRecords
if debug: print("Headers: %d" % nbRecords)
for i in range (0,nbRecords):
result = parseTopazHeaderRecord()
if debug: print result[0], ": ", result[1]
if debug: print(result[0], ": ", result[1])
self.bookHeaderRecords[result[0]] = result[1]
if ord(self.fo.read(1)) != 0x64 :
raise DrmException(u"Parse Error : Invalid Header")
@ -244,12 +245,12 @@ class TopazBook:
raise DrmException(u"Parse Error : Record Names Don't Match")
flags = ord(self.fo.read(1))
nbRecords = ord(self.fo.read(1))
if debug: print "Metadata Records: %d" % nbRecords
if debug: print("Metadata Records: %d" % nbRecords)
for i in range (0,nbRecords) :
keyval = bookReadString(self.fo)
content = bookReadString(self.fo)
if debug: print keyval
if debug: print content
if debug: print(keyval)
if debug: print(content)
self.bookMetadata[keyval] = content
return self.bookMetadata
@ -319,11 +320,11 @@ class TopazBook:
try:
keydata = self.getBookPayloadRecord('dkey', 0)
except DrmException, e:
print u"no dkey record found, book may not be encrypted"
print u"attempting to extrct files without a book key"
print(u"no dkey record found, book may not be encrypted")
print(u"attempting to extrct files without a book key")
self.createBookDirectory()
self.extractFiles()
print u"Successfully Extracted Topaz contents"
print(u"Successfully Extracted Topaz contents")
if inCalibre:
from calibre_plugins.dedrm import genbook
else:
@ -331,7 +332,7 @@ class TopazBook:
rv = genbook.generateBook(self.outdir, raw, fixedimage)
if rv == 0:
print u"Book Successfully generated."
print(u"Book Successfully generated.")
return rv
# try each pid to decode the file
@ -339,7 +340,7 @@ class TopazBook:
for pid in pidlst:
# use 8 digit pids here
pid = pid[0:8]
print u"Trying: {0}".format(pid)
print(u"Trying: {0}".format(pid))
bookKeys = []
data = keydata
try:
@ -348,7 +349,7 @@ class TopazBook:
pass
else:
bookKey = bookKeys[0]
print u"Book Key Found! ({0})".format(bookKey.encode('hex'))
print(u"Book Key Found! ({0})".format(bookKey.encode('hex')))
break
if not bookKey:
@ -357,7 +358,7 @@ class TopazBook:
self.setBookKey(bookKey)
self.createBookDirectory()
self.extractFiles()
print u"Successfully Extracted Topaz contents"
print(u"Successfully Extracted Topaz contents")
if inCalibre:
from calibre_plugins.dedrm import genbook
else:
@ -365,7 +366,7 @@ class TopazBook:
rv = genbook.generateBook(self.outdir, raw, fixedimage)
if rv == 0:
print u"Book Successfully generated"
print(u"Book Successfully generated")
return rv
def createBookDirectory(self):
@ -394,7 +395,7 @@ class TopazBook:
ext = u".dat"
if name == 'img': ext = u".jpg"
if name == 'color' : ext = u".jpg"
print u"Processing Section: {0}\n. . .".format(name),
print(u"Processing Section: {0}\n. . .".format(name), end=' ')
for index in range (0,len(self.bookHeaderRecords[name])) :
fname = u"{0}{1:04d}{2}".format(name,index,ext)
destdir = outdir
@ -407,11 +408,11 @@ class TopazBook:
if name == 'glyphs':
destdir = os.path.join(outdir,u"glyphs")
outputFile = os.path.join(destdir,fname)
print u".",
print(u".", end=' ')
record = self.getBookPayloadRecord(name,index)
if record != '':
file(outputFile, 'wb').write(record)
print u" "
print(u" ")
def getFile(self, zipname):
htmlzip = zipfile.ZipFile(zipname,'w',zipfile.ZIP_DEFLATED, False)
@ -441,20 +442,20 @@ class TopazBook:
shutil.rmtree(self.outdir, True)
def usage(progname):
print u"Removes DRM protection from Topaz ebooks and extracts the contents"
print u"Usage:"
print u" {0} [-k <kindle.k4i>] [-p <comma separated PIDs>] [-s <comma separated Kindle serial numbers>] <infile> <outdir>".format(progname)
print(u"Removes DRM protection from Topaz ebooks and extracts the contents")
print(u"Usage:")
print(u" {0} [-k <kindle.k4i>] [-p <comma separated PIDs>] [-s <comma separated Kindle serial numbers>] <infile> <outdir>".format(progname))
# Main
def cli_main():
argv=unicode_argv()
progname = os.path.basename(argv[0])
print u"TopazExtract v{0}.".format(__version__)
print(u"TopazExtract v{0}.".format(__version__))
try:
opts, args = getopt.getopt(argv[1:], "k:p:s:x")
except getopt.GetoptError, err:
print u"Error in options or arguments: {0}".format(err.args[0])
print(u"Error in options or arguments: {0}".format(err.args[0]))
usage(progname)
return 1
if len(args)<2:
@ -464,11 +465,11 @@ def cli_main():
infile = args[0]
outdir = args[1]
if not os.path.isfile(infile):
print u"Input File {0} Does Not Exist.".format(infile)
print(u"Input File {0} Does Not Exist.".format(infile))
return 1
if not os.path.exists(outdir):
print u"Output Directory {0} Does Not Exist.".format(outdir)
print(u"Output Directory {0} Does Not Exist.".format(outdir))
return 1
kDatabaseFiles = []
@ -493,19 +494,19 @@ def cli_main():
tb = TopazBook(infile)
title = tb.getBookTitle()
print u"Processing Book: {0}".format(title)
print(u"Processing Book: {0}".format(title))
md1, md2 = tb.getPIDMetaInfo()
pids.extend(kgenpids.getPidList(md1, md2, serials, kDatabaseFiles))
try:
print u"Decrypting Book"
print(u"Decrypting Book")
tb.processBook(pids)
print u" Creating HTML ZIP Archive"
print(u" Creating HTML ZIP Archive")
zipname = os.path.join(outdir, bookname + u"_nodrm.htmlz")
tb.getFile(zipname)
print u" Creating SVG ZIP Archive"
print(u" Creating SVG ZIP Archive")
zipname = os.path.join(outdir, bookname + u"_SVG.zip")
tb.getSVGZip(zipname)
@ -513,7 +514,7 @@ def cli_main():
tb.cleanup()
except DrmException, e:
print u"Decryption failed\n{0}".format(traceback.format_exc())
print(u"Decryption failed\n{0}".format(traceback.format_exc()))
try:
tb.cleanup()
@ -522,7 +523,7 @@ def cli_main():
return 1
except Exception, e:
print u"Decryption failed\m{0}".format(traceback.format_exc())
print(u"Decryption failed\m{0}".format(traceback.format_exc()))
try:
tb.cleanup()
except:

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from __future__ import print_function
__license__ = 'GPL v3'
@ -20,7 +21,7 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
import json
basepath, script = os.path.split(scriptpath)
print u"{0} v{1}: Running {2} under Wine".format(PLUGIN_NAME, PLUGIN_VERSION, script)
print(u"{0} v{1}: Running {2} under Wine".format(PLUGIN_NAME, PLUGIN_VERSION, script))
outdirpath = os.path.join(basepath, u"winekeysdir")
if not os.path.exists(outdirpath):
@ -31,26 +32,26 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix)
else:
cmdline = u"wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath)
print u"{0} v{1}: Command line: '{2}'".format(PLUGIN_NAME, PLUGIN_VERSION, cmdline)
print(u"{0} v{1}: Command line: '{2}'".format(PLUGIN_NAME, PLUGIN_VERSION, cmdline))
try:
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=sys.stdout, stderr=STDOUT, close_fds=False)
result = p2.wait("wait")
except Exception, e:
print u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0])
print(u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0]))
if wineprefix != "" and os.path.exists(wineprefix):
cmdline = u"WINEPREFIX=\"{2}\" wine C:\\Python27\\python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix)
else:
cmdline = u"wine C:\\Python27\\python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath)
print u"{0} v{1}: Command line: “{2}".format(PLUGIN_NAME, PLUGIN_VERSION, cmdline)
print(u"{0} v{1}: Command line: “{2}".format(PLUGIN_NAME, PLUGIN_VERSION, cmdline))
try:
cmdline = cmdline.encode(sys.getfilesystemencoding())
p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=sys.stdout, stderr=STDOUT, close_fds=False)
result = p2.wait("wait")
except Exception, e:
print u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0])
print(u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0]))
# try finding winekeys anyway, even if above code errored
winekeys = []
@ -66,8 +67,8 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
new_key_value = keyfile.read()
winekeys.append(new_key_value)
except:
print u"{0} v{1}: Error loading file {2}".format(PLUGIN_NAME, PLUGIN_VERSION, filename)
print(u"{0} v{1}: Error loading file {2}".format(PLUGIN_NAME, PLUGIN_VERSION, filename))
traceback.print_exc()
os.remove(fpath)
print u"{0} v{1}: Found and decrypted {2} {3}".format(PLUGIN_NAME, PLUGIN_VERSION, len(winekeys), u"key file" if len(winekeys) == 1 else u"key files")
print(u"{0} v{1}: Found and decrypted {2} {3}".format(PLUGIN_NAME, PLUGIN_VERSION, len(winekeys), u"key file" if len(winekeys) == 1 else u"key files"))
return winekeys

@ -14,6 +14,7 @@
"""
Re-write zip (or ePub) fixing problems with file names (and mimetype entry).
"""
from __future__ import print_function
__license__ = 'GPL v3'
__version__ = "1.1"
@ -156,22 +157,22 @@ class fixZip:
def usage():
print """usage: zipfix.py inputzip outputzip
print("""usage: zipfix.py inputzip outputzip
inputzip is the source zipfile to fix
outputzip is the fixed zip archive
"""
""")
def repairBook(infile, outfile):
if not os.path.exists(infile):
print "Error: Input Zip File does not exist"
print("Error: Input Zip File does not exist")
return 1
try:
fr = fixZip(infile, outfile)
fr.fix()
return 0
except Exception, e:
print "Error Occurred ", e
print("Error Occurred ", e)
return 2

@ -150,6 +150,7 @@
# after all.
#
"""Manage all Kobo books, either encrypted or DRM-free."""
from __future__ import print_function
__version__ = '3.2.4'
__about__ = u"Obok v{0}\nCopyright © 2012-2016 Physisticated et al.".format(__version__)
@ -291,7 +292,7 @@ class KoboLibrary(object):
of books, their titles, and the user's encryption key(s)."""
def __init__ (self, serials = [], device_path = None):
print __about__
print(__about__)
self.kobodir = u""
kobodb = u""
@ -374,7 +375,7 @@ class KoboLibrary(object):
# make a copy of the database in a temporary file
# so we can ensure it's not using WAL logging which sqlite3 can't do.
self.newdb = tempfile.NamedTemporaryFile(mode='wb', delete=False)
print self.newdb.name
print(self.newdb.name)
olddb = open(kobodb, 'rb')
self.newdb.write(olddb.read(18))
self.newdb.write('\x01\x01')
@ -591,32 +592,32 @@ class KoboFile(object):
# assume utf-8 with no BOM
textoffset = 0
stride = 1
print u"Checking text:{0}:".format(contents[:10])
print(u"Checking text:{0}:".format(contents[:10]))
# check for byte order mark
if contents[:3]=="\xef\xbb\xbf":
# seems to be utf-8 with BOM
print u"Could be utf-8 with BOM"
print(u"Could be utf-8 with BOM")
textoffset = 3
elif contents[:2]=="\xfe\xff":
# seems to be utf-16BE
print u"Could be utf-16BE"
print(u"Could be utf-16BE")
textoffset = 3
stride = 2
elif contents[:2]=="\xff\xfe":
# seems to be utf-16LE
print u"Could be utf-16LE"
print(u"Could be utf-16LE")
textoffset = 2
stride = 2
else:
print u"Perhaps utf-8 without BOM"
print(u"Perhaps utf-8 without BOM")
# now check that the first few characters are in the ASCII range
for i in xrange(textoffset,textoffset+5*stride,stride):
if ord(contents[i])<32 or ord(contents[i])>127:
# Non-ascii, so decryption probably failed
print u"Bad character at {0}, value {1}".format(i,ord(contents[i]))
print(u"Bad character at {0}, value {1}".format(i,ord(contents[i])))
raise ValueError
print u"Seems to be good text"
print(u"Seems to be good text")
return True
if contents[:5]=="<?xml" or contents[:8]=="\xef\xbb\xbf<?xml":
# utf-8
@ -637,13 +638,13 @@ class KoboFile(object):
# utf-16LE of weird <!DOCTYPE start
return True
else:
print u"Bad XML: {0}".format(contents[:8])
print(u"Bad XML: {0}".format(contents[:8]))
raise ValueError
elif self.mimetype == 'image/jpeg':
if contents[:3] == '\xff\xd8\xff':
return True
else:
print u"Bad JPEG: {0}".format(contents[:3].encode('hex'))
print(u"Bad JPEG: {0}".format(contents[:3].encode('hex')))
raise ValueError()
return False
@ -666,18 +667,18 @@ class KoboFile(object):
return contents
def decrypt_book(book, lib):
print u"Converting {0}".format(book.title)
print(u"Converting {0}".format(book.title))
zin = zipfile.ZipFile(book.filename, "r")
# make filename out of Unicode alphanumeric and whitespace equivalents from title
outname = u"{0}.epub".format(re.sub('[^\s\w]', '_', book.title, 0, re.UNICODE))
if (book.type == 'drm-free'):
print u"DRM-free book, conversion is not needed"
print(u"DRM-free book, conversion is not needed")
shutil.copyfile(book.filename, outname)
print u"Book saved as {0}".format(os.path.join(os.getcwd(), outname))
print(u"Book saved as {0}".format(os.path.join(os.getcwd(), outname)))
return 0
result = 1
for userkey in lib.userkeys:
print u"Trying key: {0}".format(userkey.encode('hex_codec'))
print(u"Trying key: {0}".format(userkey.encode('hex_codec')))
try:
zout = zipfile.ZipFile(outname, "w", zipfile.ZIP_DEFLATED)
for filename in zin.namelist():
@ -689,12 +690,12 @@ def decrypt_book(book, lib):
file.check(contents)
zout.writestr(filename, contents)
zout.close()
print u"Decryption succeeded."
print u"Book saved as {0}".format(os.path.join(os.getcwd(), outname))
print(u"Decryption succeeded.")
print(u"Book saved as {0}".format(os.path.join(os.getcwd(), outname)))
result = 0
break
except ValueError:
print u"Decryption failed."
print(u"Decryption failed.")
zout.close()
os.remove(outname)
zin.close()
@ -719,8 +720,8 @@ def cli_main():
books = lib.books
else:
for i, book in enumerate(lib.books):
print u"{0}: {1}".format(i + 1, book.title)
print u"Or 'all'"
print(u"{0}: {1}".format(i + 1, book.title))
print(u"Or 'all'")
choice = raw_input(u"Convert book number... ")
if choice == u'all':
@ -730,14 +731,14 @@ def cli_main():
num = int(choice)
books = [lib.books[num - 1]]
except (ValueError, IndexError):
print u"Invalid choice. Exiting..."
print(u"Invalid choice. Exiting...")
exit()
results = [decrypt_book(book, lib) for book in books]
lib.close()
overall_result = all(result != 0 for result in results)
if overall_result != 0:
print u"Could not decrypt book with any of the keys found."
print(u"Could not decrypt book with any of the keys found.")
return overall_result

Loading…
Cancel
Save