]> xmof Git - DeDRM.git/commitdiff
Cleanup
authorNoDRM <no_drm123@protonmail.com>
Wed, 29 Dec 2021 08:14:35 +0000 (09:14 +0100)
committerNoDRM <no_drm123@protonmail.com>
Wed, 29 Dec 2021 08:14:35 +0000 (09:14 +0100)
.gitignore
CALIBRE_CLI_INSTRUCTIONS.md
DeDRM_plugin/DeDRM_Help.htm
DeDRM_plugin/__init__.py
DeDRM_plugin/_unused_activitybar.py [moved from DeDRM_plugin/activitybar.py with 98% similarity]
DeDRM_plugin/_unused_scrolltextwidget.py [moved from DeDRM_plugin/scrolltextwidget.py with 97% similarity]
DeDRM_plugin/ignobleepub.py [deleted file]
DeDRM_plugin/scriptinterface.py
DeDRM_plugin/topazextract.py

index 4564a1268c93aead5b380187bd8ca8330378e39d..f3f3d471c9fae25926a9c54ed42c33f471ad8179 100644 (file)
@@ -2,4 +2,8 @@
 .DS_Store
 
 # local test data
-/user_data/
\ No newline at end of file
+/user_data/
+
+# Cache
+/DeDRM_plugin/__pycache__
+/DeDRM_plugin/standalone/__pycache__
\ No newline at end of file
index 9c1359f8d0151b6e8e80bb594d09e2f12ecb0cfb..0d7dbd4cfc1c7365e61cf4f2d2192fc9c0b67dcd 100644 (file)
@@ -13,16 +13,16 @@ platforms.
 
 #### Install plugins
   - Download the DeDRM `.zip` archive from DeDRM_tools'
-     [latest release](https://github.com/apprenticeharper/DeDRM_tools/releases/latest).
+     [latest release](https://github.com/noDRM/DeDRM_tools/releases/latest).
      Then unzip it.
   - Add the DeDRM plugin to Calibre:
      ```
      cd *the unzipped DeDRM_tools folder*
-     calibre-customize --add DeDRM_calibre_plugin/DeDRM_plugin.zip
+     calibre-customize --add DeDRM_plugin.zip
      ```
   - Add the Obok plugin:
     ```
-    calibre-customize --add Obok_calibre_plugin/obok_plugin.zip
+    calibre-customize --add Obok_plugin.zip
     ```
 
 #### Enter your keys
index 6ec385cab415e04f3ea0e23b0a52e65d39abcde6..c5a92ac6eb7ae74d0673cfdf1c60525e0a5bf01f 100644 (file)
@@ -46,7 +46,7 @@ p {margin-top: 0}
 
 <h3>Credits:</h3>
 <ul>
-<li>NoDRM for a bunch of updates and the Readium LCP support</li>
+<li>NoDRM for a bunch of updates and maintenance since November 2021, and the Readium LCP support</li>
 <li>The Dark Reverser for the Mobipocket and eReader scripts</li>
 <li>i♥cabbages for the Adobe Digital Editions scripts</li>
 <li>Skindle aka Bart Simpson for the Amazon Kindle for PC script</li>
index b0a5e4b48a867077ab89ec65d35b87c8383a3d07..ab9bcf744732c22e037e4b8cbb4a2b460d4ae0ac 100644 (file)
@@ -994,11 +994,11 @@ class DeDRM(FileTypePlugin):
             decrypted_ebook = self.eReaderDecrypt(path_to_ebook)
             pass
         elif booktype == 'pdf':
-            # Adobe PDF (hopefully)
+            # Adobe PDF (hopefully) or LCP PDF
             decrypted_ebook = self.PDFDecrypt(path_to_ebook)
             pass
         elif booktype == 'epub':
-            # Adobe Adept or B&N ePub
+            # Adobe Adept, PassHash (B&N) or LCP ePub
             decrypted_ebook = self.ePubDecrypt(path_to_ebook)
         else:
             print("Unknown booktype {0}. Passing back to calibre unchanged".format(booktype))
similarity index 98%
rename from DeDRM_plugin/activitybar.py
rename to DeDRM_plugin/_unused_activitybar.py
index bec991aac219f32c927d540272d15f414cc72177..8ebc10c88778fa79a2b32e6cc7f4c3f4b60eef68 100644 (file)
@@ -1,3 +1,5 @@
+# I think this file is unused?
+
 import sys
 import tkinter
 import tkinter.constants
similarity index 97%
rename from DeDRM_plugin/scrolltextwidget.py
rename to DeDRM_plugin/_unused_scrolltextwidget.py
index c95a26414f4be4b085639ae52faeb8225f40d97c..5969ea1bac4895639d6a7cf77484e77ccf25fd88 100644 (file)
@@ -1,6 +1,9 @@
 #!/usr/bin/env python
 # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
 
+# I think this file is unused?
+
+
 import tkinter
 import tkinter.constants
 
diff --git a/DeDRM_plugin/ignobleepub.py b/DeDRM_plugin/ignobleepub.py
deleted file mode 100644 (file)
index e1cd88f..0000000
+++ /dev/null
@@ -1,448 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-# ignobleepub.py
-# Copyright © 2009-2020 by i♥cabbages, Apprentice Harper et al.
-
-# Released under the terms of the GNU General Public Licence, version 3
-# <http://www.gnu.org/licenses/>
-
-#
-# Revision history:
-#   1 - Initial release
-#   2 - Added OS X support by using OpenSSL when available
-#   3 - screen out improper key lengths to prevent segfaults on Linux
-#   3.1 - Allow Windows versions of libcrypto to be found
-#   3.2 - add support for encoding to 'utf-8' when building up list of files to decrypt from encryption.xml
-#   3.3 - On Windows try PyCrypto first, OpenSSL next
-#   3.4 - Modify interface to allow use with import
-#   3.5 - Fix for potential problem with PyCrypto
-#   3.6 - Revised to allow use in calibre plugins to eliminate need for duplicate code
-#   3.7 - Tweaked to match ineptepub more closely
-#   3.8 - Fixed to retain zip file metadata (e.g. file modification date)
-#   3.9 - moved unicode_argv call inside main for Windows DeDRM compatibility
-#   4.0 - Work if TkInter is missing
-#   4.1 - Import tkFileDialog, don't assume something else will import it.
-#   5.0 - Python 3 for calibre 5.0
-
-"""
-Decrypt Barnes & Noble encrypted ePub books.
-"""
-
-__license__ = 'GPL v3'
-__version__ = "5.0"
-
-import sys
-import os
-import traceback
-import base64
-import zlib
-import zipfile
-from zipfile import ZipInfo, ZipFile, ZIP_STORED, ZIP_DEFLATED
-from contextlib import closing
-import xml.etree.ElementTree as etree
-
-# Wrap a stream so that output gets flushed immediately
-# and also make sure that any unicode strings get
-# encoded using "replace" before writing them.
-class SafeUnbuffered:
-    def __init__(self, stream):
-        self.stream = stream
-        self.encoding = stream.encoding
-        if self.encoding == None:
-            self.encoding = "utf-8"
-    def write(self, data):
-        if isinstance(data,str) or isinstance(data,unicode):
-            # str for Python3, unicode for Python2
-            data = data.encode(self.encoding,"replace")
-        try:
-            buffer = getattr(self.stream, 'buffer', self.stream)
-            # self.stream.buffer for Python3, self.stream for Python2
-            buffer.write(data)
-            buffer.flush()
-        except:
-            # We can do nothing if a write fails
-            raise
-    def __getattr__(self, attr):
-        return getattr(self.stream, attr)
-
-try:
-    from calibre.constants import iswindows, isosx
-except:
-    iswindows = sys.platform.startswith('win')
-    isosx = sys.platform.startswith('darwin')
-
-def unicode_argv():
-    if iswindows:
-        # Uses shell32.GetCommandLineArgvW to get sys.argv as a list of Unicode
-        # strings.
-
-        # Versions 2.x of Python don't support Unicode in sys.argv on
-        # Windows, with the underlying Windows API instead replacing multi-byte
-        # characters with '?'.
-
-
-        from ctypes import POINTER, byref, cdll, c_int, windll
-        from ctypes.wintypes import LPCWSTR, LPWSTR
-
-        GetCommandLineW = cdll.kernel32.GetCommandLineW
-        GetCommandLineW.argtypes = []
-        GetCommandLineW.restype = LPCWSTR
-
-        CommandLineToArgvW = windll.shell32.CommandLineToArgvW
-        CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)]
-        CommandLineToArgvW.restype = POINTER(LPWSTR)
-
-        cmd = GetCommandLineW()
-        argc = c_int(0)
-        argv = CommandLineToArgvW(cmd, byref(argc))
-        if argc.value > 0:
-            # Remove Python executable and commands if present
-            start = argc.value - len(sys.argv)
-            return [argv[i] for i in
-                    range(start, argc.value)]
-        return ["ineptepub.py"]
-    else:
-        argvencoding = sys.stdin.encoding or "utf-8"
-        return [arg if (isinstance(arg, str) or isinstance(arg,unicode)) else str(arg, argvencoding) for arg in sys.argv]
-
-
-class IGNOBLEError(Exception):
-    pass
-
-def _load_crypto_libcrypto():
-    from ctypes import CDLL, POINTER, c_void_p, c_char_p, c_int, c_long, \
-        Structure, c_ulong, create_string_buffer, cast
-    from ctypes.util import find_library
-
-    if iswindows:
-        libcrypto = find_library('libeay32')
-    else:
-        libcrypto = find_library('crypto')
-
-    if libcrypto is None:
-        raise IGNOBLEError('libcrypto not found')
-    libcrypto = CDLL(libcrypto)
-
-    AES_MAXNR = 14
-
-    c_char_pp = POINTER(c_char_p)
-    c_int_p = POINTER(c_int)
-
-    class AES_KEY(Structure):
-        _fields_ = [('rd_key', c_long * (4 * (AES_MAXNR + 1))),
-                    ('rounds', c_int)]
-    AES_KEY_p = POINTER(AES_KEY)
-
-    def F(restype, name, argtypes):
-        func = getattr(libcrypto, name)
-        func.restype = restype
-        func.argtypes = argtypes
-        return func
-
-    AES_set_decrypt_key = F(c_int, 'AES_set_decrypt_key',
-                            [c_char_p, c_int, AES_KEY_p])
-    AES_cbc_encrypt = F(None, 'AES_cbc_encrypt',
-                        [c_char_p, c_char_p, c_ulong, AES_KEY_p, c_char_p,
-                         c_int])
-
-    class AES(object):
-        def __init__(self, userkey):
-            self._blocksize = len(userkey)
-            if (self._blocksize != 16) and (self._blocksize != 24) and (self._blocksize != 32) :
-                raise IGNOBLEError('AES improper key used')
-                return
-            key = self._key = AES_KEY()
-            rv = AES_set_decrypt_key(userkey, len(userkey) * 8, key)
-            if rv < 0:
-                raise IGNOBLEError('Failed to initialize AES key')
-
-        def decrypt(self, data):
-            out = create_string_buffer(len(data))
-            iv = (b'\x00' * self._blocksize)
-            rv = AES_cbc_encrypt(data, out, len(data), self._key, iv, 0)
-            if rv == 0:
-                raise IGNOBLEError('AES decryption failed')
-            return out.raw
-
-    return AES
-
-def _load_crypto_pycrypto():
-    from Crypto.Cipher import AES as _AES
-
-    class AES(object):
-        def __init__(self, key):
-            self._aes = _AES.new(key, _AES.MODE_CBC, b'\x00'*16)
-
-        def decrypt(self, data):
-            return self._aes.decrypt(data)
-
-    return AES
-
-def _load_crypto():
-    AES = None
-    cryptolist = (_load_crypto_libcrypto, _load_crypto_pycrypto)
-    if sys.platform.startswith('win'):
-        cryptolist = (_load_crypto_pycrypto, _load_crypto_libcrypto)
-    for loader in cryptolist:
-        try:
-            AES = loader()
-            break
-        except (ImportError, IGNOBLEError):
-            pass
-    return AES
-
-AES = _load_crypto()
-
-META_NAMES = ('mimetype', 'META-INF/rights.xml', 'META-INF/encryption.xml')
-NSMAP = {'adept': 'http://ns.adobe.com/adept',
-         'enc': 'http://www.w3.org/2001/04/xmlenc#'}
-
-class Decryptor(object):
-    def __init__(self, bookkey, encryption):
-        enc = lambda tag: '{%s}%s' % (NSMAP['enc'], tag)
-        self._aes = AES(bookkey)
-        encryption = etree.fromstring(encryption)
-        self._encrypted = encrypted = set()
-        expr = './%s/%s/%s' % (enc('EncryptedData'), enc('CipherData'),
-                               enc('CipherReference'))
-        for elem in encryption.findall(expr):
-            path = elem.get('URI', None)
-            if path is not None:
-                path = path.encode('utf-8')
-                encrypted.add(path)
-
-    def decompress(self, bytes):
-        dc = zlib.decompressobj(-15)
-        bytes = dc.decompress(bytes)
-        ex = dc.decompress(b'Z') + dc.flush()
-        if ex:
-            bytes = bytes + ex
-        return bytes
-
-    def decrypt(self, path, data):
-        if bytes(path,'utf-8') in self._encrypted:
-            data = self._aes.decrypt(data)[16:]
-            data = data[:-data[-1]]
-            data = self.decompress(data)
-        return data
-
-# check file to make check whether it's probably an Adobe Adept encrypted ePub
-def ignobleBook(inpath):
-    with closing(ZipFile(open(inpath, 'rb'))) as inf:
-        namelist = set(inf.namelist())
-        if 'META-INF/rights.xml' not in namelist or \
-           'META-INF/encryption.xml' not in namelist:
-            return False
-        try:
-            rights = etree.fromstring(inf.read('META-INF/rights.xml'))
-            adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag)
-            expr = './/%s' % (adept('encryptedKey'),)
-            bookkey = ''.join(rights.findtext(expr))
-            if len(bookkey) == 64:
-                return True
-        except:
-            # if we couldn't check, assume it is
-            return True
-    return False
-
-def decryptBook(keyb64, inpath, outpath):
-    if AES is None:
-        raise IGNOBLEError("PyCrypto or OpenSSL must be installed.")
-    key = base64.b64decode(keyb64)[:16]
-    aes = AES(key)
-    with closing(ZipFile(open(inpath, 'rb'))) as inf:
-        namelist = set(inf.namelist())
-        if 'META-INF/rights.xml' not in namelist or \
-           'META-INF/encryption.xml' not in namelist:
-            print("{0:s} is DRM-free.".format(os.path.basename(inpath)))
-            return 1
-        for name in META_NAMES:
-            namelist.remove(name)
-        try:
-            rights = etree.fromstring(inf.read('META-INF/rights.xml'))
-            adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag)
-            expr = './/%s' % (adept('encryptedKey'),)
-            bookkey = ''.join(rights.findtext(expr))
-            if len(bookkey) != 64:
-                print("{0:s} is not a secure Barnes & Noble ePub.".format(os.path.basename(inpath)))
-                return 1
-            bookkey = aes.decrypt(base64.b64decode(bookkey))
-            bookkey = bookkey[:-bookkey[-1]]
-            encryption = inf.read('META-INF/encryption.xml')
-            decryptor = Decryptor(bookkey[-16:], encryption)
-            kwds = dict(compression=ZIP_DEFLATED, allowZip64=False)
-            with closing(ZipFile(open(outpath, 'wb'), 'w', **kwds)) as outf:
-                zi = ZipInfo('mimetype')
-                zi.compress_type=ZIP_STORED
-                try:
-                    # if the mimetype is present, get its info, including time-stamp
-                    oldzi = inf.getinfo('mimetype')
-                    # copy across fields to be preserved
-                    zi.date_time = oldzi.date_time
-                    zi.comment = oldzi.comment
-                    zi.extra = oldzi.extra
-                    zi.internal_attr = oldzi.internal_attr
-                    # external attributes are dependent on the create system, so copy both.
-                    zi.external_attr = oldzi.external_attr
-                    zi.create_system = oldzi.create_system
-                except:
-                    pass
-                outf.writestr(zi, inf.read('mimetype'))
-                for path in namelist:
-                    data = inf.read(path)
-                    zi = ZipInfo(path)
-                    zi.compress_type=ZIP_DEFLATED
-                    try:
-                        # get the file info, including time-stamp
-                        oldzi = inf.getinfo(path)
-                        # copy across useful fields
-                        zi.date_time = oldzi.date_time
-                        zi.comment = oldzi.comment
-                        zi.extra = oldzi.extra
-                        zi.internal_attr = oldzi.internal_attr
-                        # external attributes are dependent on the create system, so copy both.
-                        zi.external_attr = oldzi.external_attr
-                        zi.create_system = oldzi.create_system
-                    except:
-                        pass
-                    outf.writestr(zi, decryptor.decrypt(path, data))
-        except:
-            print("Could not decrypt {0:s} because of an exception:\n{1:s}".format(os.path.basename(inpath), traceback.format_exc()))
-            return 2
-    return 0
-
-
-def cli_main():
-    sys.stdout=SafeUnbuffered(sys.stdout)
-    sys.stderr=SafeUnbuffered(sys.stderr)
-    argv=unicode_argv()
-    progname = os.path.basename(argv[0])
-    if len(argv) != 4:
-        print("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("Successfully decrypted {0:s} as {1:s}".format(os.path.basename(inpath),os.path.basename(outpath)))
-    return result
-
-def gui_main():
-    try:
-        import tkinter
-        import tkinter.constants
-        import tkinter.filedialog
-        import tkinter.messagebox
-        import traceback
-    except:
-        return cli_main()
-
-    class DecryptionDialog(tkinter.Frame):
-        def __init__(self, root):
-            tkinter.Frame.__init__(self, root, border=5)
-            self.status = tkinter.Label(self, text="Select files for decryption")
-            self.status.pack(fill=tkinter.constants.X, expand=1)
-            body = tkinter.Frame(self)
-            body.pack(fill=tkinter.constants.X, expand=1)
-            sticky = tkinter.constants.E + tkinter.constants.W
-            body.grid_columnconfigure(1, weight=2)
-            tkinter.Label(body, text="Key file").grid(row=0)
-            self.keypath = tkinter.Entry(body, width=30)
-            self.keypath.grid(row=0, column=1, sticky=sticky)
-            if os.path.exists("bnepubkey.b64"):
-                self.keypath.insert(0, "bnepubkey.b64")
-            button = tkinter.Button(body, text="...", command=self.get_keypath)
-            button.grid(row=0, column=2)
-            tkinter.Label(body, text="Input file").grid(row=1)
-            self.inpath = tkinter.Entry(body, width=30)
-            self.inpath.grid(row=1, column=1, sticky=sticky)
-            button = tkinter.Button(body, text="...", command=self.get_inpath)
-            button.grid(row=1, column=2)
-            tkinter.Label(body, text="Output file").grid(row=2)
-            self.outpath = tkinter.Entry(body, width=30)
-            self.outpath.grid(row=2, column=1, sticky=sticky)
-            button = tkinter.Button(body, text="...", command=self.get_outpath)
-            button.grid(row=2, column=2)
-            buttons = tkinter.Frame(self)
-            buttons.pack()
-            botton = tkinter.Button(
-                buttons, text="Decrypt", width=10, command=self.decrypt)
-            botton.pack(side=tkinter.constants.LEFT)
-            tkinter.Frame(buttons, width=10).pack(side=tkinter.constants.LEFT)
-            button = tkinter.Button(
-                buttons, text="Quit", width=10, command=self.quit)
-            button.pack(side=tkinter.constants.RIGHT)
-
-        def get_keypath(self):
-            keypath = tkinter.filedialog.askopenfilename(
-                parent=None, title="Select Barnes & Noble \'.b64\' key file",
-                defaultextension=".b64",
-                filetypes=[('base64-encoded files', '.b64'),
-                           ('All Files', '.*')])
-            if keypath:
-                keypath = os.path.normpath(keypath)
-                self.keypath.delete(0, tkinter.constants.END)
-                self.keypath.insert(0, keypath)
-            return
-
-        def get_inpath(self):
-            inpath = tkinter.filedialog.askopenfilename(
-                parent=None, title="Select B&N-encrypted ePub file to decrypt",
-                defaultextension=".epub", filetypes=[('ePub files', '.epub')])
-            if inpath:
-                inpath = os.path.normpath(inpath)
-                self.inpath.delete(0, tkinter.constants.END)
-                self.inpath.insert(0, inpath)
-            return
-
-        def get_outpath(self):
-            outpath = tkinter.filedialog.asksaveasfilename(
-                parent=None, title="Select unencrypted ePub file to produce",
-                defaultextension=".epub", filetypes=[('ePub files', '.epub')])
-            if outpath:
-                outpath = os.path.normpath(outpath)
-                self.outpath.delete(0, tkinter.constants.END)
-                self.outpath.insert(0, outpath)
-            return
-
-        def decrypt(self):
-            keypath = self.keypath.get()
-            inpath = self.inpath.get()
-            outpath = self.outpath.get()
-            if not keypath or not os.path.exists(keypath):
-                self.status['text'] = "Specified key file does not exist"
-                return
-            if not inpath or not os.path.exists(inpath):
-                self.status['text'] = "Specified input file does not exist"
-                return
-            if not outpath:
-                self.status['text'] = "Output file not specified"
-                return
-            if inpath == outpath:
-                self.status['text'] = "Must have different input and output files"
-                return
-            userkey = open(keypath,'rb').read()
-            self.status['text'] = "Decrypting..."
-            try:
-                decrypt_status = decryptBook(userkey, inpath, outpath)
-            except Exception as e:
-                self.status['text'] = "Error: {0}".format(e.args[0])
-                return
-            if decrypt_status == 0:
-                self.status['text'] = "File successfully decrypted"
-            else:
-                self.status['text'] = "The was an error decrypting the file."
-
-    root = tkinter.Tk()
-    root.title("Barnes & Noble ePub Decrypter v.{0}".format(__version__))
-    root.resizable(True, False)
-    root.minsize(300, 0)
-    DecryptionDialog(root).pack(fill=tkinter.constants.X, expand=1)
-    root.mainloop()
-    return 0
-
-if __name__ == '__main__':
-    if len(sys.argv) > 1:
-        sys.exit(cli_main())
-    sys.exit(gui_main())
index 25a6c09456fe6a0534ffd679978c82afc49c6111..1810237e7f4b65c70f86c97992eea190d0bf3519 100644 (file)
@@ -50,8 +50,8 @@ def decryptepub(infile, outdir, rscpath):
                     errlog += traceback.format_exc()
                     errlog += str(e)
                     rv = 1
-    # now try with ignoble epub
-    elif  ignobleepub.ignobleBook(zippath):
+        
+        # now try with ignoble epub
         # try with any keyfiles (*.b64) in the rscpath
         files = os.listdir(rscpath)
         filefilter = re.compile("\.b64$", re.IGNORECASE)
@@ -62,7 +62,7 @@ def decryptepub(infile, outdir, rscpath):
                 userkey = open(keypath,'r').read()
                 #print userkey
                 try:
-                    rv = ignobleepub.decryptBook(userkey, zippath, outfile)
+                    rv = ineptepub.decryptBook(userkey, zippath, outfile)
                     if rv == 0:
                         print("Decrypted B&N ePub with key file {0}".format(filename))
                         break
@@ -121,7 +121,7 @@ def decryptpdb(infile, outdir, rscpath):
     rv = 1
     socialpath = os.path.join(rscpath,'sdrmlist.txt')
     if os.path.exists(socialpath):
-        keydata = file(socialpath,'r').read()
+        keydata = open(socialpath,'r').read()
         keydata = keydata.rstrip(os.linesep)
         ar = keydata.split(',')
         for i in ar:
@@ -148,7 +148,7 @@ def decryptk4mobi(infile, outdir, rscpath):
     pidnums = []
     pidspath = os.path.join(rscpath,'pidlist.txt')
     if os.path.exists(pidspath):
-        pidstr = file(pidspath,'r').read()
+        pidstr = open(pidspath,'r').read()
         pidstr = pidstr.rstrip(os.linesep)
         pidstr = pidstr.strip()
         if pidstr != '':
@@ -156,7 +156,7 @@ def decryptk4mobi(infile, outdir, rscpath):
     serialnums = []
     serialnumspath = os.path.join(rscpath,'seriallist.txt')
     if os.path.exists(serialnumspath):
-        serialstr = file(serialnumspath,'r').read()
+        serialstr = open(serialnumspath,'r').read()
         serialstr = serialstr.rstrip(os.linesep)
         serialstr = serialstr.strip()
         if serialstr != '':
index 98db615cc80304cb10b40bf562047907e33cf94e..55fa2ffc1dabecb96107115f7ebb55644061387d 100644 (file)
@@ -332,7 +332,7 @@ class TopazBook:
             keydata = self.getBookPayloadRecord(b'dkey', 0)
         except DrmException as e:
             print("no dkey record found, book may not be encrypted")
-            print("attempting to extrct files without a book key")
+            print("attempting to extract files without a book key")
             self.createBookDirectory()
             self.extractFiles()
             print("Successfully Extracted Topaz contents")
@@ -364,7 +364,7 @@ class TopazBook:
                 break
 
         if not bookKey:
-            raise DrmException("No key found in {0:d} keys tried. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(len(pidlst)))
+            raise DrmException("No key found in {0:d} keys tried. Read the FAQs at noDRM's repository: https://github.com/noDRM/DeDRM_tools/blob/master/FAQs.md".format(len(pidlst)))
 
         self.setBookKey(bookKey)
         self.createBookDirectory()