Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76a47e0dd0 | ||
|
|
70a754fb46 | ||
|
|
21a7b13524 | ||
|
|
52bdbe95c9 | ||
|
|
495dda3809 | ||
|
|
52e83922c0 | ||
|
|
6cbc5285cb | ||
|
|
33b9630ca5 | ||
|
|
9346f86f73 | ||
|
|
8d2d6627cf | ||
|
|
6f198b247c | ||
|
|
9fb95eff41 | ||
|
|
7aab8a3711 | ||
|
|
2789cee331 | ||
|
|
823704cf36 | ||
|
|
a7974f0f14 |
@@ -5,7 +5,7 @@
|
||||
# Copyright © 2008-2020 Apprentice Harper et al.
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__version__ = '7.0.2'
|
||||
__version__ = '7.1.0'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ __docformat__ = 'restructuredtext en'
|
||||
# 7.0.0 - Switched to Python 3 for calibre 5.0. Thanks to all who contributed
|
||||
# 7.0.1 - More Python 3 changes. Adobe PDF decryption should now work in some cases
|
||||
# 7.0.2 - More Python 3 changes. Adobe PDF decryption should now work on PC too.
|
||||
# 7.0.3 - More Python 3 changes. Integer division in ineptpdf.py
|
||||
# 7.1.0 - Full release for calibre 5.x
|
||||
|
||||
"""
|
||||
Decrypt DRMed ebooks.
|
||||
|
||||
@@ -415,12 +415,12 @@ def decryptBook(userkey, inpath, outpath):
|
||||
return 1
|
||||
bookkey = rsa.decrypt(codecs.decode(bookkey.encode('ascii'), 'base64'))
|
||||
# Padded as per RSAES-PKCS1-v1_5
|
||||
if len(bookkey) != 16:
|
||||
if bookkey[-17] != '\x00' and bookkey[-17] != 0:
|
||||
if len(bookkey) > 16:
|
||||
if bookkey[-17] == '\x00' or bookkey[-17] == 0:
|
||||
bookkey = bookkey[-16:]
|
||||
else:
|
||||
print("Could not decrypt {0:s}. Wrong key".format(os.path.basename(inpath)))
|
||||
return 2
|
||||
else:
|
||||
bookkey = bookkey[-16:]
|
||||
encryption = inf.read('META-INF/encryption.xml')
|
||||
decryptor = Decryptor(bookkey, encryption)
|
||||
kwds = dict(compression=ZIP_DEFLATED, allowZip64=False)
|
||||
|
||||
@@ -442,7 +442,7 @@ def nunpack(s, default=0):
|
||||
elif l == 2:
|
||||
return struct.unpack('>H', s)[0]
|
||||
elif l == 3:
|
||||
return struct.unpack('>L', '\x00'+s)[0]
|
||||
return struct.unpack('>L', b'\x00'+s)[0]
|
||||
elif l == 4:
|
||||
return struct.unpack('>L', s)[0]
|
||||
else:
|
||||
@@ -1482,7 +1482,7 @@ class PDFDocument(object):
|
||||
# global static principal key for German Onleihe / Bibliothek Digital
|
||||
principalkeys = { b'bibliothek-digital.de': codecs.decode(b'rRwGv2tbpKov1krvv7PO0ws9S436/lArPlfipz5Pqhw=','base64')}
|
||||
self.is_printable = self.is_modifiable = self.is_extractable = True
|
||||
length = int_value(param.get('Length', 0)) / 8
|
||||
length = int_value(param.get('Length', 0)) // 8
|
||||
edcdata = str_value(param.get('EDCData')).decode('base64')
|
||||
pdrllic = str_value(param.get('PDRLLic')).decode('base64')
|
||||
pdrlpol = str_value(param.get('PDRLPol')).decode('base64')
|
||||
@@ -1547,8 +1547,8 @@ class PDFDocument(object):
|
||||
if 5 <= R:
|
||||
# 8
|
||||
for _ in range(50):
|
||||
hash = hashlib.md5(hash.digest()[:length/8])
|
||||
key = hash.digest()[:length/8]
|
||||
hash = hashlib.md5(hash.digest()[:length//8])
|
||||
key = hash.digest()[:length//8]
|
||||
if R == 2:
|
||||
# Algorithm 3.4
|
||||
u1 = ARC4.new(key).decrypt(password)
|
||||
@@ -1590,7 +1590,7 @@ class PDFDocument(object):
|
||||
def initialize_ebx(self, password, docid, param):
|
||||
self.is_printable = self.is_modifiable = self.is_extractable = True
|
||||
rsa = RSA(password)
|
||||
length = int_value(param.get('Length', 0)) / 8
|
||||
length = int_value(param.get('Length', 0)) // 8
|
||||
rights = codecs.decode(param.get('ADEPT_LICENSE'), 'base64')
|
||||
rights = zlib.decompress(rights, -15)
|
||||
rights = etree.fromstring(rights)
|
||||
@@ -1599,11 +1599,10 @@ class PDFDocument(object):
|
||||
bookkey = rsa.decrypt(bookkey)
|
||||
#if bookkey[0] != 2:
|
||||
# raise ADEPTError('error decrypting book session key')
|
||||
try:
|
||||
index = bookkey.index(b'\0') + 1
|
||||
bookkey = bookkey[index:]
|
||||
except ValueError:
|
||||
pass
|
||||
if len(bookkey) > 16:
|
||||
if bookkey[-17] == '\x00' or bookkey[-17] == 0:
|
||||
bookkey = bookkey[-16:]
|
||||
length = 16
|
||||
ebx_V = int_value(param.get('V', 4))
|
||||
ebx_type = int_value(param.get('EBX_ENCRYPTIONTYPE', 6))
|
||||
# added because of improper booktype / decryption book session key errors
|
||||
|
||||
@@ -815,18 +815,18 @@ class DrmIonVoucher(object):
|
||||
addprottable(self.envelope)
|
||||
|
||||
def decryptvoucher(self):
|
||||
shared = "PIDv3" + self.encalgorithm + self.enctransformation + self.hashalgorithm
|
||||
shared = ("PIDv3" + self.encalgorithm + self.enctransformation + self.hashalgorithm).encode('ASCII')
|
||||
|
||||
self.lockparams.sort()
|
||||
for param in self.lockparams:
|
||||
if param == "ACCOUNT_SECRET":
|
||||
shared += param + self.secret
|
||||
shared += param.encode('ASCII') + self.secret
|
||||
elif param == "CLIENT_ID":
|
||||
shared += param + self.dsn
|
||||
shared += param.encode('ASCII') + self.dsn
|
||||
else:
|
||||
_assert(False, "Unknown lock parameter: %s" % param)
|
||||
|
||||
sharedsecret = obfuscate(shared.encode('ASCII'), self.version)
|
||||
sharedsecret = obfuscate(shared, self.version)
|
||||
|
||||
key = hmac.new(sharedsecret, b"PIDv3", digestmod=hashlib.sha256).digest()
|
||||
aes = AES.new(key[:32], AES.MODE_CBC, self.cipheriv[:16])
|
||||
|
||||
@@ -174,14 +174,14 @@ def pidFromSerial(s, l):
|
||||
|
||||
# Parse the EXTH header records and use the Kindle serial number to calculate the book pid.
|
||||
def getKindlePids(rec209, token, serialnum):
|
||||
if isinstance(serialnum,str):
|
||||
serialnum = serialnum.encode('utf-8')
|
||||
|
||||
if rec209 is None:
|
||||
return [serialnum]
|
||||
|
||||
pids=[]
|
||||
|
||||
if isinstance(serialnum,str):
|
||||
serialnum = serialnum.encode('utf-8')
|
||||
|
||||
# Compute book PID
|
||||
pidHash = SHA1(serialnum+rec209+token)
|
||||
bookPID = encodePID(pidHash)
|
||||
|
||||
@@ -3,7 +3,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__version__ = '6.7.0'
|
||||
__version__ = '7.1.0'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
#####################################################################
|
||||
@@ -20,7 +20,7 @@ except NameError:
|
||||
PLUGIN_NAME = 'Obok DeDRM'
|
||||
PLUGIN_SAFE_NAME = PLUGIN_NAME.strip().lower().replace(' ', '_')
|
||||
PLUGIN_DESCRIPTION = _('Removes DRM from Kobo kepubs and adds them to the library.')
|
||||
PLUGIN_VERSION_TUPLE = (6, 7, 0)
|
||||
PLUGIN_VERSION_TUPLE = (7, 1, 0)
|
||||
PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE])
|
||||
HELPFILE_NAME = PLUGIN_SAFE_NAME + '_Help.htm'
|
||||
PLUGIN_AUTHORS = 'Anon'
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Version 4.1.0 February 2021
|
||||
# Add detection for Kobo directory location on Linux
|
||||
|
||||
# Version 4.0.0 September 2020
|
||||
# Python 3.0
|
||||
#
|
||||
@@ -365,9 +368,33 @@ class KoboLibrary(object):
|
||||
self.kobodir = os.path.join(self.kobodir, "Kobo", "Kobo Desktop Edition")
|
||||
elif sys.platform.startswith('darwin'):
|
||||
self.kobodir = os.path.join(os.environ['HOME'], "Library", "Application Support", "Kobo", "Kobo Desktop Edition")
|
||||
#elif linux_path != None:
|
||||
# Probably Linux, let's get the wine prefix and path to Kobo.
|
||||
# self.kobodir = os.path.join(linux_path, "Local Settings", "Application Data", "Kobo", "Kobo Desktop Edition")
|
||||
elif sys.platform.startswith('linux'):
|
||||
|
||||
#sets ~/.config/calibre as the location to store the kobodir location info file and creates this directory if necessary
|
||||
kobodir_cache_dir = os.path.join(os.environ['HOME'], ".config", "calibre")
|
||||
if not os.path.isdir(kobodir_cache_dir):
|
||||
os.mkdir(kobodir_cache_dir)
|
||||
|
||||
#appends the name of the file we're storing the kobodir location info to the above path
|
||||
kobodir_cache_file = str(kobodir_cache_dir) + "/" + "kobo location"
|
||||
|
||||
"""if the above file does not exist, recursively searches from the root
|
||||
of the filesystem until kobodir is found and stores the location of kobodir
|
||||
in that file so this loop can be skipped in the future"""
|
||||
original_stdout = sys.stdout
|
||||
if not os.path.isfile(kobodir_cache_file):
|
||||
for root, dirs, files in os.walk('/'):
|
||||
for file in files:
|
||||
if file == 'Kobo.sqlite':
|
||||
kobo_linux_path = str(root)
|
||||
with open(kobodir_cache_file, 'w') as f:
|
||||
sys.stdout = f
|
||||
print(kobo_linux_path, end='')
|
||||
sys.stdout = original_stdout
|
||||
|
||||
f = open(kobodir_cache_file, 'r' )
|
||||
self.kobodir = f.read()
|
||||
|
||||
# desktop versions use Kobo.sqlite
|
||||
kobodb = os.path.join(self.kobodir, "Kobo.sqlite")
|
||||
# check for existence of file
|
||||
|
||||
Binary file not shown.
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-11-17 12:51+0100\n"
|
||||
"PO-Revision-Date: 2020-12-25 13:38+0100\n"
|
||||
"PO-Revision-Date: 2021-01-19 12:20+0100\n"
|
||||
"Language: sv\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -41,8 +41,8 @@ msgstr "Hittade {0} möjliga nycklar att försöka med."
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:99
|
||||
msgid "<p>No userkeys found to decrypt books with. No point in proceeding."
|
||||
msgstr ""
|
||||
"<p>Inga användarnycklar hittades för att dekryptera böcker med. Ingen idé "
|
||||
"att fortsätta."
|
||||
"<p>Inga användarnycklar hittades för att dekryptera böcker med. Det är ingen "
|
||||
"idé att fortsätta."
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:115
|
||||
msgid "{} - Decryption canceled by user."
|
||||
@@ -87,13 +87,13 @@ msgstr "dubblett upptäcktes"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:233
|
||||
msgid "{0} - Successfully added EPUB format to existing {1}"
|
||||
msgstr "{0} - EPUB-format har lagts till i befintliga {1}"
|
||||
msgstr "{0} - EPUB-formatet har lagts till i befintliga {1}"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:236
|
||||
msgid ""
|
||||
"{0} - Error adding EPUB format to existing {1}. This really shouldn't happen."
|
||||
msgstr ""
|
||||
"{0} - Fel vid tilläggning av EPUB-format till befintligt {1}. Detta borde "
|
||||
"{0} - Fel vid tilläggning av EPUB-formatet till befintliga {1}. Detta borde "
|
||||
"verkligen inte hända."
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:259
|
||||
@@ -118,8 +118,8 @@ msgid ""
|
||||
" to those existing entries?<br /><br />NOTE: no pre-existing EPUBs will be "
|
||||
"overwritten."
|
||||
msgstr ""
|
||||
" till dessa befintliga poster?<br /><br />OBS: inga befintliga EPUB:er "
|
||||
"kommer att skrivas över."
|
||||
" till dessa befintliga poster?<br /><br />OBS: inga befintliga EPUB:er kommer "
|
||||
"att skrivas över."
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:295
|
||||
msgid ""
|
||||
@@ -132,20 +132,19 @@ msgstr ""
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:297
|
||||
msgid "<p><b>{0}</b> -- not added because of {1} in your library.<br /><br />"
|
||||
msgstr ""
|
||||
"<p><b>{0}</b> -- lades inte till på grund av {1} i ditt bibliotek.<br /><br /"
|
||||
">"
|
||||
"<p><b>{0}</b> -- lades inte till på grund av {1} i ditt bibliotek.<br /><br />"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:298
|
||||
msgid ""
|
||||
"Would you like to try and add the EPUB format to an available calibre "
|
||||
"duplicate?<br /><br />"
|
||||
msgstr ""
|
||||
"Vill du försöka lägga till EPUB-format till en tillgänglig calibre-dubblett?"
|
||||
"Vill du försöka lägga till EPUB-formatet till en tillgänglig calibre-dubblett?"
|
||||
"<br /><br />"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:299
|
||||
msgid "NOTE: no pre-existing EPUB will be overwritten."
|
||||
msgstr "OBS: inga befintliga EPUB:er kommer att skrivas över."
|
||||
msgstr "OBS: ingen befintlig EPUB kommer att skrivas över."
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:346
|
||||
msgid "Trying key: "
|
||||
@@ -153,7 +152,7 @@ msgstr "Försöker med nyckel: "
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:378
|
||||
msgid "Decryption failed, trying next key."
|
||||
msgstr "Det gick inte att dekryptera, försöker med nästa nyckel."
|
||||
msgstr "Dekryptering misslyckades, försöker med nästa nyckel."
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:382
|
||||
msgid "Unknown Error decrypting, trying next key.."
|
||||
@@ -164,8 +163,8 @@ msgid ""
|
||||
"<p>All selected Kobo books added as new calibre books or inserted into "
|
||||
"existing calibre ebooks.<br /><br />No issues."
|
||||
msgstr ""
|
||||
"<p>Alla valda Kobo-böcker har lagts till som nya calibre-böcker eller "
|
||||
"infogats i befintliga calibre-e-böcker.<br /><br />Inga problem."
|
||||
"<p>Alla valda Kobo-böcker har lagts till som nya calibre-böcker eller infogats "
|
||||
"i befintliga calibre-e-böcker.<br /><br />Inga problem."
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:399
|
||||
msgid "<p>{0} successfully added."
|
||||
@@ -200,8 +199,7 @@ msgid "<p><b>Book imports cancelled by user:</b> {}</p>\n"
|
||||
msgstr "<p><b>Bokimport avbröts av användaren:</b> {}</p>\n"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:428
|
||||
msgid ""
|
||||
"<p><b>New EPUB formats inserted in existing calibre books:</b> {0}</p>\n"
|
||||
msgid "<p><b>New EPUB formats inserted in existing calibre books:</b> {0}</p>\n"
|
||||
msgstr ""
|
||||
"<p><b>Nya EPUB-format infogade i befintliga calibre-böcker:</b> {0}</p>\n"
|
||||
|
||||
@@ -209,8 +207,7 @@ msgstr ""
|
||||
msgid ""
|
||||
"<p><b>EPUB formats NOT inserted into existing calibre books:</b> {}<br />\n"
|
||||
msgstr ""
|
||||
"<p><b>EPUB-format som INTE infogats i befintliga calibre-böcker:</b> {}<br /"
|
||||
">\n"
|
||||
"<p><b>EPUB-format som INTE infogats i befintliga calibre-böcker:</b> {}<br />\n"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:435
|
||||
msgid ""
|
||||
@@ -222,7 +219,7 @@ msgstr ""
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:444
|
||||
msgid "<p><b>Format imports cancelled by user:</b> {}</p>\n"
|
||||
msgstr "<p><b>Formatimporten avbröts av användaren:</b> {}</p>\n"
|
||||
msgstr "<p><b>Format-importen avbröts av användaren:</b> {}</p>\n"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:458
|
||||
msgid "Unknown Book Title"
|
||||
@@ -234,14 +231,11 @@ msgstr "den kunde inte dekrypteras."
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:462
|
||||
msgid ""
|
||||
"user CHOSE not to insert the new EPUB format, or all existing calibre "
|
||||
"entries HAD an EPUB format already."
|
||||
"user CHOSE not to insert the new EPUB format, or all existing calibre entries "
|
||||
"HAD an EPUB format already."
|
||||
msgstr ""
|
||||
"användaren VALDE att inte infoga det nya EPUB-formatet, eller alla "
|
||||
"befintliga calibre-poster hade redan ett EPUB-format.\n"
|
||||
"\n"
|
||||
"användaren valde att inte infoga det nya EPUB-formatet, eller alla "
|
||||
"befintliga kaliberposter hade redan ett EPUB-format."
|
||||
"användaren VALDE att inte infoga det nya EPUB-formatet, eller alla befintliga "
|
||||
"calibre-poster hade redan ett EPUB-format."
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\action.py:464
|
||||
msgid "of unknown reasons. Gosh I'm embarrassed!"
|
||||
@@ -282,7 +276,7 @@ msgid ""
|
||||
"cause calibre ebooks to be overwritten"
|
||||
msgstr ""
|
||||
"<p>Standardbeteende när dubbletter upptäcks. Inget av alternativen kommer att "
|
||||
"göra att calibre-e-böcker skrivs över"
|
||||
"orsaka att calibre-e-böcker skrivs över"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\config.py:35
|
||||
msgid "Ask"
|
||||
@@ -363,7 +357,7 @@ msgstr "Felaktig AES-nyckel används"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\obok\obok.py:167
|
||||
msgid "Failed to initialize AES key"
|
||||
msgstr "Misslyckades att initiera AES-nyckel"
|
||||
msgstr "Misslyckades med att initiera AES-nyckel"
|
||||
|
||||
#: I:\Herramientas\PoeditPortable\App\Poedit\bin\obok_plugin-3.1.0_trad\obok\obok.py:175
|
||||
msgid "AES decryption failed"
|
||||
|
||||
@@ -2290,10 +2290,13 @@ class PDFDocument(object):
|
||||
import win32api
|
||||
import win32security
|
||||
import win32file
|
||||
import winreg
|
||||
except:
|
||||
raise ADEPTError('PyWin Extension (Win32API module) needed.\n'+\
|
||||
'Download from http://sourceforge.net/projects/pywin32/files/ ')
|
||||
try:
|
||||
import winreg
|
||||
except ImportError:
|
||||
import _winreg as winreg
|
||||
try:
|
||||
v0 = win32api.GetVolumeInformation('C:\\')
|
||||
v1 = win32api.GetSystemInfo()[6]
|
||||
|
||||
Reference in New Issue
Block a user