mirror of
https://github.com/apprenticeharper/DeDRM_tools
synced 2024-12-26 09:58:55 +01:00
Merge pull request #850 from cclauss/modernize-Python-2-codes
Use print() function in both Python 2 and Python 3
This commit is contained in:
commit
c1ece2f288
25 changed files with 353 additions and 328 deletions
|
@ -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 © 2008–2017 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…
Reference in a new issue