Begin work on standalone version
Now the plugin ZIP file (DeDRM_plugin.zip) can be run with a normal Python interpreter as if it were a Python file (try `python3 DeDRM_plugin.zip --help`). This way I can begin building a standalone version (that can run without Calibre) without having to duplicate a ton of code.
This commit is contained in:
parent
9c40b3ce5a
commit
dbf4b54026
|
@ -97,11 +97,19 @@ import sys, os
|
|||
import time
|
||||
import traceback
|
||||
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
class DeDRMError(Exception):
|
||||
pass
|
||||
|
||||
from calibre.customize import FileTypePlugin
|
||||
try:
|
||||
from calibre.customize import FileTypePlugin
|
||||
except:
|
||||
# Allow import without Calibre.
|
||||
class FileTypePlugin:
|
||||
pass
|
||||
|
||||
try:
|
||||
from calibre.constants import iswindows, isosx
|
||||
|
@ -109,7 +117,10 @@ except:
|
|||
iswindows = sys.platform.startswith('win')
|
||||
isosx = sys.platform.startswith('darwin')
|
||||
|
||||
from calibre.utils.config import config_dir
|
||||
try:
|
||||
from calibre.utils.config import config_dir
|
||||
except:
|
||||
config_dir = ""
|
||||
|
||||
|
||||
# Wrap a stream so that output gets flushed immediately
|
||||
|
@ -150,6 +161,10 @@ class DeDRM(FileTypePlugin):
|
|||
priority = 600
|
||||
|
||||
|
||||
def cli_main(self, data):
|
||||
from standalone import main
|
||||
main(data)
|
||||
|
||||
def initialize(self):
|
||||
"""
|
||||
Dynamic modules can't be imported/loaded from a zipfile.
|
||||
|
@ -216,7 +231,7 @@ class DeDRM(FileTypePlugin):
|
|||
postProcessStart = time.time()
|
||||
|
||||
try:
|
||||
import calibre_plugins.dedrm.prefs as prefs
|
||||
import prefs
|
||||
dedrmprefs = prefs.DeDRM_Prefs()
|
||||
|
||||
if dedrmprefs["deobfuscate_fonts"] is True:
|
||||
|
@ -224,7 +239,7 @@ class DeDRM(FileTypePlugin):
|
|||
path_to_ebook = self.checkFonts(path_to_ebook) or path_to_ebook
|
||||
|
||||
if dedrmprefs["remove_watermarks"] is True:
|
||||
import calibre_plugins.dedrm.epubwatermark as watermark
|
||||
import epubwatermark as watermark
|
||||
|
||||
# Remove Tolino's CDP watermark file
|
||||
path_to_ebook = watermark.removeCDPwatermark(self, path_to_ebook) or path_to_ebook
|
||||
|
@ -251,7 +266,7 @@ class DeDRM(FileTypePlugin):
|
|||
# It checks if there's fonts that need to be deobfuscated
|
||||
|
||||
try:
|
||||
import calibre_plugins.dedrm.epubfontdecrypt as epubfontdecrypt
|
||||
import epubfontdecrypt
|
||||
|
||||
output = self.temporary_file(".epub").name
|
||||
ret = epubfontdecrypt.decryptFontsBook(path_to_ebook, output)
|
||||
|
@ -272,7 +287,7 @@ class DeDRM(FileTypePlugin):
|
|||
def ePubDecrypt(self,path_to_ebook):
|
||||
# Create a TemporaryPersistent file to work with.
|
||||
# Check original epub archive for zip errors.
|
||||
import calibre_plugins.dedrm.zipfix as zipfix
|
||||
import zipfix
|
||||
|
||||
inf = self.temporary_file(".epub")
|
||||
try:
|
||||
|
@ -284,12 +299,12 @@ class DeDRM(FileTypePlugin):
|
|||
raise
|
||||
|
||||
# import the decryption keys
|
||||
import calibre_plugins.dedrm.prefs as prefs
|
||||
import prefs
|
||||
dedrmprefs = prefs.DeDRM_Prefs()
|
||||
|
||||
|
||||
# import the LCP handler
|
||||
import calibre_plugins.dedrm.lcpdedrm as lcpdedrm
|
||||
import lcpdedrm
|
||||
|
||||
if (lcpdedrm.isLCPbook(path_to_ebook)):
|
||||
try:
|
||||
|
@ -304,7 +319,7 @@ class DeDRM(FileTypePlugin):
|
|||
# Not an LCP book, do the normal EPUB (Adobe) handling.
|
||||
|
||||
# import the Adobe ePub handler
|
||||
import calibre_plugins.dedrm.ineptepub as ineptepub
|
||||
import ineptepub
|
||||
|
||||
if ineptepub.adeptBook(inf.name):
|
||||
|
||||
|
@ -345,11 +360,11 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
try:
|
||||
if iswindows or isosx:
|
||||
from calibre_plugins.dedrm.ignoblekeyNookStudy import nookkeys
|
||||
from ignoblekeyNookStudy import nookkeys
|
||||
|
||||
defaultkeys_study = nookkeys()
|
||||
else: # linux
|
||||
from .wineutils import WineGetKeys
|
||||
from wineutils import WineGetKeys
|
||||
|
||||
scriptpath = os.path.join(self.alfdir,"ignoblekeyNookStudy.py")
|
||||
defaultkeys_study = WineGetKeys(scriptpath, ".b64",dedrmprefs['adobewineprefix'])
|
||||
|
@ -365,7 +380,7 @@ class DeDRM(FileTypePlugin):
|
|||
if iswindows:
|
||||
# That's a Windows store app, it won't run on Linux or MacOS anyways.
|
||||
# No need to waste time running Wine.
|
||||
from calibre_plugins.dedrm.ignoblekeyWindowsStore import dump_keys as dump_nook_keys
|
||||
from ignoblekeyWindowsStore import dump_keys as dump_nook_keys
|
||||
defaultkeys_store = dump_nook_keys(False)
|
||||
|
||||
except:
|
||||
|
@ -377,7 +392,7 @@ class DeDRM(FileTypePlugin):
|
|||
try:
|
||||
if iswindows:
|
||||
# Right now this is only implemented for Windows. MacOS support still needs to be added.
|
||||
from calibre_plugins.dedrm.adobekey_get_passhash import passhash_keys
|
||||
from adobekey_get_passhash import passhash_keys
|
||||
defaultkeys_ade, names = passhash_keys()
|
||||
if isosx:
|
||||
print("{0} v{1}: Dumping ADE PassHash data is not yet supported on MacOS.".format(PLUGIN_NAME, PLUGIN_VERSION))
|
||||
|
@ -522,11 +537,11 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
try:
|
||||
if iswindows or isosx:
|
||||
from calibre_plugins.dedrm.adobekey import adeptkeys
|
||||
from adobekey import adeptkeys
|
||||
|
||||
defaultkeys, defaultnames = adeptkeys()
|
||||
else: # linux
|
||||
from .wineutils import WineGetKeys
|
||||
from wineutils import WineGetKeys
|
||||
|
||||
scriptpath = os.path.join(self.alfdir,"adobekey.py")
|
||||
defaultkeys, defaultnames = WineGetKeys(scriptpath, ".der",dedrmprefs['adobewineprefix'])
|
||||
|
@ -546,7 +561,7 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
# Check for DeACSM keys:
|
||||
try:
|
||||
from calibre_plugins.dedrm.config import checkForDeACSMkeys
|
||||
from config import checkForDeACSMkeys
|
||||
|
||||
newkey, newname = checkForDeACSMkeys()
|
||||
|
||||
|
@ -613,8 +628,8 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
def PDFIneptDecrypt(self, path_to_ebook):
|
||||
# Sub function to prevent PDFDecrypt from becoming too large ...
|
||||
import calibre_plugins.dedrm.prefs as prefs
|
||||
import calibre_plugins.dedrm.ineptpdf as ineptpdf
|
||||
import prefs
|
||||
import ineptpdf
|
||||
dedrmprefs = prefs.DeDRM_Prefs()
|
||||
|
||||
book_uuid = None
|
||||
|
@ -688,11 +703,11 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
try:
|
||||
if iswindows or isosx:
|
||||
from calibre_plugins.dedrm.adobekey import adeptkeys
|
||||
from adobekey import adeptkeys
|
||||
|
||||
defaultkeys, defaultnames = adeptkeys()
|
||||
else: # linux
|
||||
from .wineutils import WineGetKeys
|
||||
from wineutils import WineGetKeys
|
||||
|
||||
scriptpath = os.path.join(self.alfdir,"adobekey.py")
|
||||
defaultkeys, defaultnames = WineGetKeys(scriptpath, ".der",dedrmprefs['adobewineprefix'])
|
||||
|
@ -712,7 +727,7 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
# Check for DeACSM keys:
|
||||
try:
|
||||
from calibre_plugins.dedrm.config import checkForDeACSMkeys
|
||||
from config import checkForDeACSMkeys
|
||||
|
||||
newkey, newname = checkForDeACSMkeys()
|
||||
|
||||
|
@ -789,8 +804,8 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
def PDFStandardDecrypt(self, path_to_ebook):
|
||||
# Sub function to prevent PDFDecrypt from becoming too large ...
|
||||
import calibre_plugins.dedrm.prefs as prefs
|
||||
import calibre_plugins.dedrm.ineptpdf as ineptpdf
|
||||
import prefs
|
||||
import ineptpdf
|
||||
dedrmprefs = prefs.DeDRM_Prefs()
|
||||
|
||||
# Attempt to decrypt PDF with each encryption key (generated or provided).
|
||||
|
@ -836,9 +851,9 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
|
||||
def PDFDecrypt(self,path_to_ebook):
|
||||
import calibre_plugins.dedrm.prefs as prefs
|
||||
import calibre_plugins.dedrm.ineptpdf as ineptpdf
|
||||
import calibre_plugins.dedrm.lcpdedrm as lcpdedrm
|
||||
import prefs
|
||||
import ineptpdf
|
||||
import lcpdedrm
|
||||
dedrmprefs = prefs.DeDRM_Prefs()
|
||||
|
||||
if (lcpdedrm.isLCPbook(path_to_ebook)):
|
||||
|
@ -881,8 +896,8 @@ class DeDRM(FileTypePlugin):
|
|||
# Had to move this import here so the custom libs can be
|
||||
# extracted to the appropriate places beforehand these routines
|
||||
# look for them.
|
||||
import calibre_plugins.dedrm.prefs as prefs
|
||||
import calibre_plugins.dedrm.k4mobidedrm as k4mobidedrm
|
||||
import prefs
|
||||
import k4mobidedrm
|
||||
|
||||
dedrmprefs = prefs.DeDRM_Prefs()
|
||||
pids = dedrmprefs['pids']
|
||||
|
@ -905,11 +920,11 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
try:
|
||||
if iswindows or isosx:
|
||||
from calibre_plugins.dedrm.kindlekey import kindlekeys
|
||||
from kindlekey import kindlekeys
|
||||
|
||||
defaultkeys = kindlekeys()
|
||||
else: # linux
|
||||
from .wineutils import WineGetKeys
|
||||
from wineutils import WineGetKeys
|
||||
|
||||
scriptpath = os.path.join(self.alfdir,"kindlekey.py")
|
||||
defaultkeys = WineGetKeys(scriptpath, ".k4i",dedrmprefs['kindlewineprefix'])
|
||||
|
@ -949,8 +964,8 @@ class DeDRM(FileTypePlugin):
|
|||
|
||||
def eReaderDecrypt(self,path_to_ebook):
|
||||
|
||||
import calibre_plugins.dedrm.prefs as prefs
|
||||
import calibre_plugins.dedrm.erdr2pml as erdr2pml
|
||||
import prefs
|
||||
import erdr2pml
|
||||
|
||||
dedrmprefs = prefs.DeDRM_Prefs()
|
||||
# Attempt to decrypt epub with each encryption key (generated or provided).
|
||||
|
@ -1011,7 +1026,7 @@ class DeDRM(FileTypePlugin):
|
|||
return True
|
||||
|
||||
def config_widget(self):
|
||||
import calibre_plugins.dedrm.config as config
|
||||
import config
|
||||
return config.ConfigWidget(self.plugin_path, self.alfdir)
|
||||
|
||||
def save_settings(self, config_widget):
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# __main__.py for DeDRM_plugin
|
||||
# (CLI interface without Calibre)
|
||||
# Copyright © 2021 NoDRM
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
# For revision history see __init__.py
|
||||
|
||||
"""
|
||||
Run DeDRM plugin without Calibre.
|
||||
"""
|
||||
|
||||
# Import __init__.py from the standalone folder so we can have all the
|
||||
# standalone / non-Calibre code in that subfolder.
|
||||
|
||||
import standalone.__init__ as mdata
|
||||
import sys
|
||||
|
||||
mdata.main(sys.argv)
|
|
@ -16,19 +16,23 @@ from PyQt5.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
|
|||
from PyQt5 import Qt as QtGui
|
||||
from zipfile import ZipFile
|
||||
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
# calibre modules and constants.
|
||||
from calibre.gui2 import (error_dialog, question_dialog, info_dialog, open_url,
|
||||
choose_dir, choose_files, choose_save_file)
|
||||
from calibre.utils.config import dynamic, config_dir, JSONConfig
|
||||
from calibre.constants import iswindows, isosx
|
||||
|
||||
# modules from this plugin's zipfile.
|
||||
from calibre_plugins.dedrm.__init__ import PLUGIN_NAME, PLUGIN_VERSION
|
||||
from calibre_plugins.dedrm.__init__ import RESOURCE_NAME as help_file_name
|
||||
from calibre_plugins.dedrm.utilities import uStrCmp
|
||||
|
||||
import calibre_plugins.dedrm.prefs as prefs
|
||||
import calibre_plugins.dedrm.androidkindlekey as androidkindlekey
|
||||
from __init__ import PLUGIN_NAME, PLUGIN_VERSION
|
||||
from __init__ import RESOURCE_NAME as help_file_name
|
||||
from utilities import uStrCmp
|
||||
|
||||
import prefs
|
||||
import androidkindlekey
|
||||
|
||||
def checkForDeACSMkeys():
|
||||
try:
|
||||
|
@ -868,7 +872,7 @@ class AddBandNKeyDialog(QDialog):
|
|||
errmsg = "This isn't the correct path, or the data is invalid."
|
||||
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
||||
|
||||
from calibre_plugins.dedrm.ignoblekeyAndroid import dump_keys
|
||||
from ignoblekeyAndroid import dump_keys
|
||||
store_result = dump_keys(path_to_ade_data)
|
||||
|
||||
if len(store_result) == 0:
|
||||
|
@ -899,7 +903,7 @@ class AddBandNKeyDialog(QDialog):
|
|||
def accept_ade_dump_passhash(self):
|
||||
|
||||
try:
|
||||
from calibre_plugins.dedrm.adobekey_get_passhash import passhash_keys
|
||||
from adobekey_get_passhash import passhash_keys
|
||||
keys, names = passhash_keys()
|
||||
except:
|
||||
errmsg = "Failed to grab PassHash keys from ADE."
|
||||
|
@ -940,7 +944,7 @@ class AddBandNKeyDialog(QDialog):
|
|||
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
||||
|
||||
try:
|
||||
from calibre_plugins.dedrm.ignoblekeyWindowsStore import dump_keys
|
||||
from ignoblekeyWindowsStore import dump_keys
|
||||
store_result = dump_keys(False)
|
||||
except:
|
||||
errmsg = "Failed to import from Nook Microsoft Store app."
|
||||
|
@ -948,7 +952,7 @@ class AddBandNKeyDialog(QDialog):
|
|||
|
||||
try:
|
||||
# Try the Nook Study app
|
||||
from calibre_plugins.dedrm.ignoblekeyNookStudy import nookkeys
|
||||
from ignoblekeyNookStudy import nookkeys
|
||||
study_result = nookkeys()
|
||||
except:
|
||||
errmsg = "Failed to import from Nook Study app."
|
||||
|
@ -1009,7 +1013,7 @@ class AddBandNKeyDialog(QDialog):
|
|||
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
||||
|
||||
try:
|
||||
from calibre_plugins.dedrm.ignoblekeyGenPassHash import generate_key
|
||||
from ignoblekeyGenPassHash import generate_key
|
||||
self.result_data = generate_key(self.user_name, self.cc_number)
|
||||
except:
|
||||
errmsg = "Key generation failed."
|
||||
|
@ -1077,7 +1081,7 @@ class AddEReaderDialog(QDialog):
|
|||
|
||||
@property
|
||||
def key_value(self):
|
||||
from calibre_plugins.dedrm.erdr2pml import getuser_key as generate_ereader_key
|
||||
from erdr2pml import getuser_key as generate_ereader_key
|
||||
return codecs.encode(generate_ereader_key(self.user_name, self.cc_number),'hex')
|
||||
|
||||
@property
|
||||
|
@ -1124,7 +1128,7 @@ class AddAdeptDialog():
|
|||
|
||||
try:
|
||||
if iswindows or isosx:
|
||||
from calibre_plugins.dedrm.adobekey import adeptkeys
|
||||
from adobekey import adeptkeys
|
||||
|
||||
defaultkeys, defaultnames = adeptkeys()
|
||||
else: # linux
|
||||
|
@ -1220,7 +1224,7 @@ class AddKindleDialog(QDialog):
|
|||
|
||||
try:
|
||||
if iswindows or isosx:
|
||||
from calibre_plugins.dedrm.kindlekey import kindlekeys
|
||||
from kindlekey import kindlekeys
|
||||
|
||||
defaultkeys = kindlekeys()
|
||||
else: # linux
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# erdr2pml.py
|
||||
# Copyright © 2008-2020 The Dark Reverser, Apprentice Harper et al.
|
||||
# Copyright © 2008-2021 The Dark Reverser, Apprentice Harper, noDRM et al.
|
||||
#
|
||||
# Changelog
|
||||
#
|
||||
|
@ -64,16 +64,16 @@
|
|||
# 0.22 - Unicode and plugin support, different image folders for PMLZ and source
|
||||
# 0.23 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
||||
# 1.00 - Added Python 3 compatibility for calibre 5.0
|
||||
# 1.01 - Bugfixes for standalone version.
|
||||
|
||||
__version__='1.00'
|
||||
|
||||
import sys, re
|
||||
import struct, binascii, getopt, zlib, os, os.path, urllib, tempfile, traceback
|
||||
|
||||
if 'calibre' in sys.modules:
|
||||
inCalibre = True
|
||||
else:
|
||||
inCalibre = False
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
# Wrap a stream so that output gets flushed immediately
|
||||
# and also make sure that any unicode strings get
|
||||
|
@ -141,40 +141,25 @@ def unicode_argv():
|
|||
Des = None
|
||||
if iswindows:
|
||||
# first try with pycrypto
|
||||
if inCalibre:
|
||||
from calibre_plugins.dedrm import pycrypto_des
|
||||
else:
|
||||
import pycrypto_des
|
||||
import pycrypto_des
|
||||
Des = pycrypto_des.load_pycrypto()
|
||||
if Des == None:
|
||||
# they try with openssl
|
||||
if inCalibre:
|
||||
from calibre_plugins.dedrm import openssl_des
|
||||
else:
|
||||
import openssl_des
|
||||
import openssl_des
|
||||
Des = openssl_des.load_libcrypto()
|
||||
else:
|
||||
# first try with openssl
|
||||
if inCalibre:
|
||||
from calibre_plugins.dedrm import openssl_des
|
||||
else:
|
||||
import openssl_des
|
||||
import openssl_des
|
||||
Des = openssl_des.load_libcrypto()
|
||||
if Des == None:
|
||||
# then try with pycrypto
|
||||
if inCalibre:
|
||||
from calibre_plugins.dedrm import pycrypto_des
|
||||
else:
|
||||
import pycrypto_des
|
||||
import pycrypto_des
|
||||
Des = pycrypto_des.load_pycrypto()
|
||||
|
||||
# if that did not work then use pure python implementation
|
||||
# of DES and try to speed it up with Psycho
|
||||
if Des == None:
|
||||
if inCalibre:
|
||||
from calibre_plugins.dedrm import python_des
|
||||
else:
|
||||
import python_des
|
||||
import python_des
|
||||
Des = python_des.Des
|
||||
# Import Psyco if available
|
||||
try:
|
||||
|
|
|
@ -35,25 +35,18 @@ import getopt
|
|||
from struct import pack
|
||||
from struct import unpack
|
||||
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
class TpzDRMError(Exception):
|
||||
pass
|
||||
|
||||
# local support routines
|
||||
if 'calibre' in sys.modules:
|
||||
inCalibre = True
|
||||
else:
|
||||
inCalibre = False
|
||||
|
||||
if inCalibre :
|
||||
from calibre_plugins.dedrm import convert2xml
|
||||
from calibre_plugins.dedrm import flatxml2html
|
||||
from calibre_plugins.dedrm import flatxml2svg
|
||||
from calibre_plugins.dedrm import stylexml2css
|
||||
else :
|
||||
import convert2xml
|
||||
import flatxml2html
|
||||
import flatxml2svg
|
||||
import stylexml2css
|
||||
import convert2xml
|
||||
import flatxml2html
|
||||
import flatxml2svg
|
||||
import stylexml2css
|
||||
|
||||
# global switch
|
||||
buildXML = False
|
||||
|
|
|
@ -72,26 +72,18 @@ import time
|
|||
import html.entities
|
||||
import json
|
||||
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
class DrmException(Exception):
|
||||
pass
|
||||
|
||||
if 'calibre' in sys.modules:
|
||||
inCalibre = True
|
||||
else:
|
||||
inCalibre = False
|
||||
|
||||
if inCalibre:
|
||||
from calibre_plugins.dedrm import mobidedrm
|
||||
from calibre_plugins.dedrm import topazextract
|
||||
from calibre_plugins.dedrm import kgenpids
|
||||
from calibre_plugins.dedrm import androidkindlekey
|
||||
from calibre_plugins.dedrm import kfxdedrm
|
||||
else:
|
||||
import mobidedrm
|
||||
import topazextract
|
||||
import kgenpids
|
||||
import androidkindlekey
|
||||
import kfxdedrm
|
||||
import mobidedrm
|
||||
import topazextract
|
||||
import kgenpids
|
||||
import androidkindlekey
|
||||
import kfxdedrm
|
||||
|
||||
# Wrap a stream so that output gets flushed immediately
|
||||
# and also make sure that any unicode strings get
|
||||
|
@ -243,7 +235,7 @@ def GetDecryptedBook(infile, kDatabases, androidFiles, serials, pids, starttime
|
|||
try:
|
||||
mb.processBook(totalpids)
|
||||
except:
|
||||
mb.cleanup
|
||||
mb.cleanup()
|
||||
raise
|
||||
|
||||
print("Decryption succeeded after {0:.1f} seconds".format(time.time()-starttime))
|
||||
|
|
|
@ -8,16 +8,18 @@
|
|||
# 2.1.1 - Whitespace!
|
||||
|
||||
|
||||
import os
|
||||
import os, sys
|
||||
import shutil
|
||||
import traceback
|
||||
import zipfile
|
||||
|
||||
from io import BytesIO
|
||||
try:
|
||||
from ion import DrmIon, DrmIonVoucher
|
||||
except:
|
||||
from calibre_plugins.dedrm.ion import DrmIon, DrmIonVoucher
|
||||
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from ion import DrmIon, DrmIonVoucher
|
||||
|
||||
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
__license__ = 'GPL v3'
|
||||
|
||||
# Standard Python modules.
|
||||
import os
|
||||
import os, sys
|
||||
import traceback
|
||||
|
||||
from calibre.utils.config import JSONConfig
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
try:
|
||||
from calibre_plugins.dedrm.__init__ import PLUGIN_NAME
|
||||
except:
|
||||
PLUGIN_NAME = "DeDRM"
|
||||
|
||||
from calibre.utils.config import JSONConfig
|
||||
from __init__ import PLUGIN_NAME
|
||||
|
||||
class DeDRM_Prefs():
|
||||
def __init__(self):
|
||||
|
|
|
@ -5,15 +5,19 @@
|
|||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
import re
|
||||
import traceback
|
||||
import calibre_plugins.dedrm.ineptepub
|
||||
import calibre_plugins.dedrm.ignobleepub
|
||||
import calibre_plugins.dedrm.epubtest
|
||||
import calibre_plugins.dedrm.zipfix
|
||||
import calibre_plugins.dedrm.ineptpdf
|
||||
import calibre_plugins.dedrm.erdr2pml
|
||||
import calibre_plugins.dedrm.k4mobidedrm
|
||||
import ineptepub
|
||||
import epubtest
|
||||
import zipfix
|
||||
import ineptpdf
|
||||
import erdr2pml
|
||||
import k4mobidedrm
|
||||
|
||||
def decryptepub(infile, outdir, rscpath):
|
||||
errlog = ''
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# CLI interface for the DeDRM plugin (useable without Calibre, too)
|
||||
|
||||
# Copyright © 2021 NoDRM
|
||||
|
||||
OPT_SHORT_TO_LONG = [
|
||||
["h", "help"],
|
||||
["t", "test"],
|
||||
["v", "verbose"],
|
||||
["q", "quiet"],
|
||||
["u", "username"],
|
||||
["p", "password"],
|
||||
["d", "dest"],
|
||||
["f", "force"]
|
||||
]
|
||||
|
||||
import sys, os
|
||||
IS_CALIBRE = False
|
||||
if "calibre" in sys.modules:
|
||||
IS_CALIBRE = True
|
||||
|
||||
# Explicitly allow importing the parent folder
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
# Explicitly set the package identifier so we are allowed to import stuff ...
|
||||
__package__ = "DeDRM_plugin"
|
||||
|
||||
|
||||
global _additional_data
|
||||
global _additional_params
|
||||
global _function
|
||||
_additional_data = []
|
||||
_additional_params = []
|
||||
_function = None
|
||||
|
||||
def print_err_header():
|
||||
from __init__ import PLUGIN_NAME, PLUGIN_VERSION # type: ignore
|
||||
|
||||
print(PLUGIN_NAME + " v" + PLUGIN_VERSION + " - DRM removal plugin by noDRM")
|
||||
print()
|
||||
|
||||
def print_help():
|
||||
from __init__ import PLUGIN_NAME, PLUGIN_VERSION
|
||||
print(PLUGIN_NAME + " v" + PLUGIN_VERSION + " - DRM removal plugin by noDRM")
|
||||
print("Based on DeDRM Calibre plugin by Apprentice Harper, Apprentice Alf and others.")
|
||||
print("See https://github.com/noDRM/DeDRM_tools for more information.")
|
||||
print()
|
||||
if IS_CALIBRE:
|
||||
print("This plugin can be run through Calibre - like you are doing right now - ")
|
||||
print("but it can also be executed with a standalone Python interpreter.")
|
||||
else:
|
||||
print("This plugin can either be imported into Calibre, or be executed directly")
|
||||
print("through Python like you are doing right now.")
|
||||
print()
|
||||
print("TODO: Parameters here ...")
|
||||
|
||||
def print_credits():
|
||||
from __init__ import PLUGIN_NAME, PLUGIN_VERSION
|
||||
print(PLUGIN_NAME + " v" + PLUGIN_VERSION + " - Calibre DRM removal plugin by noDRM")
|
||||
print("Based on DeDRM Calibre plugin by Apprentice Harper, Apprentice Alf and others.")
|
||||
print("See https://github.com/noDRM/DeDRM_tools for more information.")
|
||||
print()
|
||||
print("Credits:")
|
||||
print(" - noDRM for the current release of the DeDRM plugin")
|
||||
print(" - Apprentice Alf and Apprentice Harper for the previous versions of the DeDRM plugin")
|
||||
print(" - The Dark Reverser for the Mobipocket and eReader script")
|
||||
print(" - i ♥ cabbages for the Adobe Digital Editions scripts")
|
||||
print(" - Skindle aka Bart Simpson for the Amazon Kindle for PC script")
|
||||
print(" - CMBDTC for Amazon Topaz DRM removal script")
|
||||
print(" - some_updates, clarknova and Bart Simpson for Amazon Topaz conversion scripts")
|
||||
print(" - DiapDealer for the first calibre plugin versions of the tools")
|
||||
print(" - some_updates, DiapDealer, Apprentice Alf and mdlnx for Amazon Kindle/Mobipocket tools")
|
||||
print(" - some_updates for the DeDRM all-in-one Python tool")
|
||||
print(" - Apprentice Alf for the DeDRM all-in-one AppleScript tool")
|
||||
|
||||
|
||||
def handle_single_argument(arg, next):
|
||||
used_up = 0
|
||||
global _additional_params
|
||||
|
||||
if arg == "--help":
|
||||
print_help()
|
||||
exit(0)
|
||||
|
||||
elif arg == "--credits":
|
||||
print_credits()
|
||||
exit(0)
|
||||
|
||||
elif arg in ["--username", "--password"]:
|
||||
used_up = 1
|
||||
_additional_params.append(arg)
|
||||
if next is None:
|
||||
print_err_header()
|
||||
print("Missing parameter for argument " + arg)
|
||||
exit(1)
|
||||
else:
|
||||
_additional_params.append(next[0])
|
||||
|
||||
elif arg in ["--verbose", "--quiet"]:
|
||||
_additional_params.append(arg)
|
||||
|
||||
|
||||
else:
|
||||
print_err_header()
|
||||
print("Unknown argument: " + arg)
|
||||
exit(1)
|
||||
|
||||
|
||||
# Used up 0 additional arguments
|
||||
return used_up
|
||||
|
||||
|
||||
|
||||
def handle_data(data):
|
||||
global _function
|
||||
global _additional_data
|
||||
|
||||
if _function is None:
|
||||
_function = str(data)
|
||||
else:
|
||||
_additional_data.append(str(data))
|
||||
|
||||
def execute_action(action, filenames, params):
|
||||
print("Executing '{0}' on file(s) {1} with parameters {2}".format(action, str(filenames), str(params)))
|
||||
|
||||
print("ERROR: This feature is still in development. Right now it can't be used yet.")
|
||||
|
||||
|
||||
def main(argv):
|
||||
arguments = argv
|
||||
skip_opts = False
|
||||
|
||||
# First element is always the ZIP name, remove that.
|
||||
if not arguments[0].lower().endswith(".zip") and not IS_CALIBRE:
|
||||
print("Warning: File name does not end in .zip ...")
|
||||
print(arguments)
|
||||
arguments.pop(0)
|
||||
|
||||
while len(arguments) > 0:
|
||||
arg = arguments.pop(0)
|
||||
|
||||
if arg == "--":
|
||||
skip_opts = True
|
||||
continue
|
||||
|
||||
if not skip_opts:
|
||||
if arg.startswith("--"):
|
||||
# Give the current arg, plus all remaining ones.
|
||||
# Return the number of additional args we used.
|
||||
used = handle_single_argument(arg, arguments)
|
||||
for _ in range(used):
|
||||
# Function returns number of additional arguments that were
|
||||
# "used up" by that argument.
|
||||
# Remove that amount of arguments from the list.
|
||||
try:
|
||||
arguments.pop(0)
|
||||
except:
|
||||
pass
|
||||
continue
|
||||
elif arg.startswith("-"):
|
||||
single_args = list(arg[1:])
|
||||
# single_args is now a list of single chars, for when you call the program like "ls -alR"
|
||||
# with multiple single-letter options combined.
|
||||
while len(single_args) > 0:
|
||||
c = single_args.pop(0)
|
||||
|
||||
# See if we have a long name for that option.
|
||||
for wrapper in OPT_SHORT_TO_LONG:
|
||||
if wrapper[0] == c:
|
||||
c = "--" + wrapper[1]
|
||||
break
|
||||
else:
|
||||
c = "-" + c
|
||||
# c is now the long term (unless there is no long version, then it's the short version).
|
||||
|
||||
if len(single_args) > 0:
|
||||
# If we have more short arguments, the argument for this one must be None.
|
||||
handle_single_argument(c, None)
|
||||
used = 0
|
||||
else:
|
||||
# If not, then there might be parameters for this short argument.
|
||||
used = handle_single_argument(c, arguments)
|
||||
|
||||
for _ in range(used):
|
||||
# Function returns number of additional arguments that were
|
||||
# "used up" by that argument.
|
||||
# Remove that amount of arguments from the list.
|
||||
try:
|
||||
arguments.pop(0)
|
||||
except:
|
||||
pass
|
||||
|
||||
continue
|
||||
|
||||
handle_data(arg)
|
||||
|
||||
|
||||
if _function is None:
|
||||
print_help()
|
||||
return(1)
|
||||
|
||||
# Okay, now actually begin doing stuff.
|
||||
# This function gets told what to do and gets additional data (filenames).
|
||||
# It also receives additional parameters.
|
||||
# The rest of the code will be in different Python files.
|
||||
execute_action(_function, _additional_data, _additional_params)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# NOTE: This MUST not do anything else other than calling main()
|
||||
# All the code must be in main(), not in here.
|
||||
import sys
|
||||
main(sys.argv)
|
|
@ -13,14 +13,16 @@ __version__ = '6.0'
|
|||
|
||||
import sys
|
||||
import os, csv, getopt
|
||||
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
import zlib, zipfile, tempfile, shutil
|
||||
import traceback
|
||||
from struct import pack
|
||||
from struct import unpack
|
||||
try:
|
||||
from calibre_plugins.dedrm.alfcrypto import Topaz_Cipher
|
||||
except:
|
||||
from alfcrypto import Topaz_Cipher
|
||||
|
||||
from alfcrypto import Topaz_Cipher
|
||||
|
||||
# Wrap a stream so that output gets flushed immediately
|
||||
# and also make sure that any unicode strings get
|
||||
|
@ -88,12 +90,7 @@ def unicode_argv():
|
|||
#global switch
|
||||
debug = False
|
||||
|
||||
if 'calibre' in sys.modules:
|
||||
inCalibre = True
|
||||
from calibre_plugins.dedrm import kgenpids
|
||||
else:
|
||||
inCalibre = False
|
||||
import kgenpids
|
||||
import kgenpids
|
||||
|
||||
|
||||
class DrmException(Exception):
|
||||
|
@ -336,10 +333,7 @@ class TopazBook:
|
|||
self.createBookDirectory()
|
||||
self.extractFiles()
|
||||
print("Successfully Extracted Topaz contents")
|
||||
if inCalibre:
|
||||
from calibre_plugins.dedrm import genbook
|
||||
else:
|
||||
import genbook
|
||||
import genbook
|
||||
|
||||
rv = genbook.generateBook(self.outdir, raw, fixedimage)
|
||||
if rv == 0:
|
||||
|
@ -370,10 +364,7 @@ class TopazBook:
|
|||
self.createBookDirectory()
|
||||
self.extractFiles()
|
||||
print("Successfully Extracted Topaz contents")
|
||||
if inCalibre:
|
||||
from calibre_plugins.dedrm import genbook
|
||||
else:
|
||||
import genbook
|
||||
import genbook
|
||||
|
||||
rv = genbook.generateBook(self.outdir, raw, fixedimage)
|
||||
if rv == 0:
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from calibre_plugins.dedrm.ignoblekeyGenPassHash import generate_key
|
||||
import sys, os
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
from ignoblekeyGenPassHash import generate_key
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
|
||||
|
|
|
@ -20,14 +20,13 @@ Re-write zip (or ePub) fixing problems with file names (and mimetype entry).
|
|||
__license__ = 'GPL v3'
|
||||
__version__ = "1.1"
|
||||
|
||||
import sys
|
||||
import sys, os
|
||||
|
||||
# Calibre stuff - so we can import from our ZIP without absolute module name
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
import zlib
|
||||
try:
|
||||
import zipfilerugged
|
||||
except:
|
||||
import calibre_plugins.dedrm.zipfilerugged as zipfilerugged
|
||||
import os
|
||||
import os.path
|
||||
import zipfilerugged
|
||||
import getopt
|
||||
from struct import unpack
|
||||
|
||||
|
|
Loading…
Reference in New Issue