From ca6d30b2d91cff47f67f9b6acc3927a51374a450 Mon Sep 17 00:00:00 2001 From: NoDRM Date: Sat, 6 Aug 2022 20:25:07 +0200 Subject: [PATCH] More stuff I missed --- CHANGELOG.md | 5 ++- DeDRM_plugin/__init__.py | 12 +++----- DeDRM_plugin/adobekey.py | 66 ++++------------------------------------ 3 files changed, 14 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a3197e..808ce31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,4 +73,7 @@ List of changes since the fork of Apprentice Harper's repository: - Fix some more Calibre-6 bugs in the Obok plugin (should fix #114). - Fix a bug where invalid Adobe keys could cause the plugin to stop trying subsequent keys (partially fixes #109). - Fix DRM removal sometimes resetting the ZIP's internal "external_attr" value on Calibre 5 and newer. -- Fix PDF decryption issues on Calibre 4 (hopefully fixes #104). \ No newline at end of file +- Fix PDF decryption issues on Calibre 4 (hopefully fixes #104). +- Small Python 2 / Calibre 4 bugfix for Obok. +- Removing ancient AlfCrypto machine code libraries, moving all encryption / decryption to Python code. +- General cleanup and removal of dead code. diff --git a/DeDRM_plugin/__init__.py b/DeDRM_plugin/__init__.py index 913d05e..8ac3c9a 100644 --- a/DeDRM_plugin/__init__.py +++ b/DeDRM_plugin/__init__.py @@ -161,12 +161,8 @@ class DeDRM(FileTypePlugin): def initialize(self): """ - Dynamic modules can't be imported/loaded from a zipfile. - So this routine will extract the appropriate - library for the target OS and copy it to the 'alfcrypto' subdirectory of - calibre's configuration directory. That 'alfcrypto' directory is then - inserted into the syspath (as the very first entry) in the run function - so the CDLL stuff will work in the alfcrypto.py script. + Extracting a couple Python scripts if running on Linux, + just in case we need to run them in Wine. The extraction only happens once per version of the plugin Also perform upgrade of preferences once per version @@ -189,7 +185,7 @@ class DeDRM(FileTypePlugin): self.verdir = os.path.join(self.maindir,PLUGIN_VERSION) if not os.path.exists(self.verdir) and not iswindows and not isosx: - names = ["kindlekey.py","adobekey.py","ignoblekeyNookStudy.py"] + names = ["kindlekey.py","adobekey.py","ignoblekeyNookStudy.py","utilities.py","argv_utils.py"] lib_dict = self.load_resources(names) print("{0} v{1}: Copying needed Python scripts from plugin's zip".format(PLUGIN_NAME, PLUGIN_VERSION)) @@ -204,7 +200,7 @@ class DeDRM(FileTypePlugin): try: open(file_path,'wb').write(data) except: - print("{0} v{1}: Exception when copying needed library files".format(PLUGIN_NAME, PLUGIN_VERSION)) + print("{0} v{1}: Exception when copying needed python scripts".format(PLUGIN_NAME, PLUGIN_VERSION)) traceback.print_exc() pass diff --git a/DeDRM_plugin/adobekey.py b/DeDRM_plugin/adobekey.py index 50e2c71..4994dd0 100644 --- a/DeDRM_plugin/adobekey.py +++ b/DeDRM_plugin/adobekey.py @@ -45,29 +45,10 @@ import sys, os, struct, getopt from base64 import b64decode -# 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) + +from utilities import SafeUnbuffered +from argv_utils import unicode_argv + try: from calibre.constants import iswindows, isosx @@ -75,41 +56,6 @@ 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 '?'. So use shell32.GetCommandLineArgvW to get sys.argv - # as a list of Unicode strings and encode them as utf-8 - - 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)] - # if we don't have any arguments at all, just pass back script name - # this should never happen - return ["adobekey.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 ADEPTError(Exception): pass @@ -507,7 +453,7 @@ def usage(progname): def cli_main(): sys.stdout=SafeUnbuffered(sys.stdout) sys.stderr=SafeUnbuffered(sys.stderr) - argv=unicode_argv() + argv=unicode_argv("adobekey.py") progname = os.path.basename(argv[0]) print("{0} v{1}\nCopyright © 2009-2020 i♥cabbages, Apprentice Harper et al.".format(progname,__version__)) @@ -585,7 +531,7 @@ def gui_main(): self.text.insert(tkinter.constants.END, text) - argv=unicode_argv() + argv=unicode_argv("adobekey.py") root = tkinter.Tk() root.withdraw() progpath, progname = os.path.split(argv[0])