Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfc13db6c5 | ||
|
|
8aa2157d55 | ||
|
|
81b08dcf05 | ||
|
|
ca42e028a7 | ||
|
|
10963f6011 | ||
|
|
72968d2124 | ||
|
|
3e95168972 | ||
|
|
ecf1d76d90 | ||
|
|
e59f0f346d | ||
|
|
b6046d3f4b | ||
|
|
a863a4856a | ||
|
|
a13d08c3bc | ||
|
|
9434751a72 | ||
|
|
fc156852a4 | ||
|
|
0c67fd43a2 |
Binary file not shown.
@@ -24,7 +24,7 @@
|
|||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>droplet</string>
|
<string>droplet</string>
|
||||||
<key>CFBundleGetInfoString</key>
|
<key>CFBundleGetInfoString</key>
|
||||||
<string>DeDRM AppleScript 6.3.4 Written 2010–2015 by Apprentice Alf et al.</string>
|
<string>DeDRM AppleScript 6.3.6 Written 2010–2016 by Apprentice Alf et al.</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>DeDRM</string>
|
<string>DeDRM</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>6.3.4</string>
|
<string>6.3.6</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>dplt</string>
|
<string>dplt</string>
|
||||||
<key>LSRequiresCarbon</key>
|
<key>LSRequiresCarbon</key>
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ __docformat__ = 'restructuredtext en'
|
|||||||
# 6.3.2 - Fixed Kindle for Android help file
|
# 6.3.2 - Fixed Kindle for Android help file
|
||||||
# 6.3.3 - Bug fix for Kindle for PC support
|
# 6.3.3 - Bug fix for Kindle for PC support
|
||||||
# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17
|
# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17
|
||||||
|
# 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging
|
||||||
|
# 6.3.6 - Fixes for ADE ePub and PDF introduced in 6.3.5
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -53,7 +55,7 @@ Decrypt DRMed ebooks.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
PLUGIN_NAME = u"DeDRM"
|
PLUGIN_NAME = u"DeDRM"
|
||||||
PLUGIN_VERSION_TUPLE = (6, 3, 4)
|
PLUGIN_VERSION_TUPLE = (6, 3, 6)
|
||||||
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
|
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
|
||||||
# Include an html helpfile in the plugin's zipfile with the following name.
|
# Include an html helpfile in the plugin's zipfile with the following name.
|
||||||
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
||||||
@@ -96,7 +98,7 @@ class DeDRM(FileTypePlugin):
|
|||||||
supported_platforms = ['linux', 'osx', 'windows']
|
supported_platforms = ['linux', 'osx', 'windows']
|
||||||
author = u"Apprentice Alf, Aprentice Harper, The Dark Reverser and i♥cabbages"
|
author = u"Apprentice Alf, Aprentice Harper, The Dark Reverser and i♥cabbages"
|
||||||
version = PLUGIN_VERSION_TUPLE
|
version = PLUGIN_VERSION_TUPLE
|
||||||
minimum_calibre_version = (0, 7, 55) # Compiled python libraries cannot be imported in earlier versions.
|
minimum_calibre_version = (1, 0, 0) # Compiled python libraries cannot be imported in earlier versions.
|
||||||
file_types = set(['epub','pdf','pdb','prc','mobi','pobi','azw','azw1','azw3','azw4','tpz'])
|
file_types = set(['epub','pdf','pdb','prc','mobi','pobi','azw','azw1','azw3','azw4','tpz'])
|
||||||
on_import = True
|
on_import = True
|
||||||
priority = 600
|
priority = 600
|
||||||
@@ -296,11 +298,15 @@ class DeDRM(FileTypePlugin):
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
result = 1
|
result = 1
|
||||||
|
|
||||||
|
try:
|
||||||
of.close()
|
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)
|
||||||
|
|
||||||
if result == 0:
|
if result == 0:
|
||||||
# Decryption was successful.
|
# Decryption was successful.
|
||||||
# Return the modified PersistentTemporary file to calibre.
|
# 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)
|
||||||
return of.name
|
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)
|
||||||
@@ -360,6 +366,7 @@ class DeDRM(FileTypePlugin):
|
|||||||
except:
|
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()
|
traceback.print_exc()
|
||||||
|
print u"{0} v{1}: Decrypted with new default key after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
|
||||||
# Return the modified PersistentTemporary file to calibre.
|
# Return the modified PersistentTemporary file to calibre.
|
||||||
return of.name
|
return of.name
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,19 @@
|
|||||||
|
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
# ineptepub.pyw, version 6.1
|
# ineptepub.pyw, version 6.5
|
||||||
# Copyright © 2009-2010 by i♥cabbages
|
# Copyright © 2009-2010 by i♥cabbages
|
||||||
|
|
||||||
# Released under the terms of the GNU General Public Licence, version 3
|
# Released under the terms of the GNU General Public Licence, version 3
|
||||||
# <http://www.gnu.org/licenses/>
|
# <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
# Modified 2010–2013 by some_updates, DiapDealer and Apprentice Alf
|
# Modified 2010–2013 by some_updates, DiapDealer and Apprentice Alf
|
||||||
|
# Modified 2015–2016 by Apprentice Harper
|
||||||
|
|
||||||
# Windows users: Before running this program, you must first install Python 2.6
|
# Windows users: Before running this program, you must first install Python 2.7
|
||||||
# from <http://www.python.org/download/> and PyCrypto from
|
# from <http://www.python.org/download/> and PyCrypto from
|
||||||
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
||||||
# install the version for Python 2.6). Save this script file as
|
# install the version for Python 2.7). Save this script file as
|
||||||
# ineptepub.pyw and double-click on it to run it.
|
# ineptepub.pyw and double-click on it to run it.
|
||||||
#
|
#
|
||||||
# Mac OS X users: Save this script file as ineptepub.pyw. You can run this
|
# Mac OS X users: Save this script file as ineptepub.pyw. You can run this
|
||||||
@@ -38,13 +39,16 @@ from __future__ import with_statement
|
|||||||
# 6.0 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
# 6.0 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
||||||
# 6.1 - Work if TkInter is missing
|
# 6.1 - Work if TkInter is missing
|
||||||
# 6.2 - Handle UTF-8 file names inside an ePub, fix by Jose Luis
|
# 6.2 - Handle UTF-8 file names inside an ePub, fix by Jose Luis
|
||||||
|
# 6.3 - Add additional check on DER file sanity
|
||||||
|
# 6.4 - Remove erroneous check on DER file sanity
|
||||||
|
# 6.5 - Completely remove erroneous check on DER file sanity
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Decrypt Adobe Digital Editions encrypted ePub books.
|
Decrypt Adobe Digital Editions encrypted ePub books.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__version__ = "6.2"
|
__version__ = "6.5"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -3,18 +3,19 @@
|
|||||||
|
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
# ineptpdf.pyw, version 7.11
|
# ineptpdf.pyw, version 8.0.4
|
||||||
# Copyright © 2009-2010 by i♥cabbages
|
# Copyright © 2009-2010 by i♥cabbages
|
||||||
|
|
||||||
# Released under the terms of the GNU General Public Licence, version 3
|
# Released under the terms of the GNU General Public Licence, version 3
|
||||||
# <http://www.gnu.org/licenses/>
|
# <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
# Modified 2010–2012 by some_updates, DiapDealer and Apprentice Alf
|
# Modified 2010–2012 by some_updates, DiapDealer and Apprentice Alf
|
||||||
|
# Modified 2015-2016 by Apprentice Harper
|
||||||
|
|
||||||
# Windows users: Before running this program, you must first install Python 2.6
|
# Windows users: Before running this program, you must first install Python 2.7
|
||||||
# from <http://www.python.org/download/> and PyCrypto from
|
# from <http://www.python.org/download/> and PyCrypto from
|
||||||
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
||||||
# install the version for Python 2.6). Save this script file as
|
# install the version for Python 2.7). Save this script file as
|
||||||
# ineptpdf.pyw and double-click on it to run it.
|
# ineptpdf.pyw and double-click on it to run it.
|
||||||
#
|
#
|
||||||
# Mac OS X users: Save this script file as ineptpdf.pyw. You can run this
|
# Mac OS X users: Save this script file as ineptpdf.pyw. You can run this
|
||||||
@@ -53,13 +54,17 @@ from __future__ import with_statement
|
|||||||
# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
||||||
# 8.0 - Work if TkInter is missing
|
# 8.0 - Work if TkInter is missing
|
||||||
# 8.0.1 - Broken Metadata fix.
|
# 8.0.1 - Broken Metadata fix.
|
||||||
|
# 8.0.2 - Add additional check on DER file sanity
|
||||||
|
# 8.0.3 - Remove erroneous check on DER file sanity
|
||||||
|
# 8.0.4 - Completely remove erroneous check on DER file sanity
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Decrypts Adobe ADEPT-encrypted PDF files.
|
Decrypts Adobe ADEPT-encrypted PDF files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__version__ = "8.0.1"
|
__version__ = "8.0.4"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
|
|||||||
if not os.path.exists(outdirpath):
|
if not os.path.exists(outdirpath):
|
||||||
os.makedirs(outdirpath)
|
os.makedirs(outdirpath)
|
||||||
|
|
||||||
|
wineprefix = os.path.abspath(os.path.expanduser(os.path.expandvars(wineprefix)))
|
||||||
if wineprefix != "" and os.path.exists(wineprefix):
|
if wineprefix != "" and os.path.exists(wineprefix):
|
||||||
cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix)
|
cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix)
|
||||||
else:
|
else:
|
||||||
@@ -38,8 +39,20 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
|
|||||||
result = p2.wait("wait")
|
result = p2.wait("wait")
|
||||||
except Exception, e:
|
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])
|
||||||
return []
|
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)
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
|
# try finding winekeys anyway, even if above code errored
|
||||||
winekeys = []
|
winekeys = []
|
||||||
# get any files with extension in the output dir
|
# get any files with extension in the output dir
|
||||||
files = [f for f in os.listdir(outdirpath) if f.endswith(extension)]
|
files = [f for f in os.listdir(outdirpath) if f.endswith(extension)]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# DeDRM.pyw
|
# DeDRM.pyw
|
||||||
# Copyright 2010-2015 some_updates, Apprentice Alf and Apprentice Harper
|
# Copyright 2010-2016 some_updates, Apprentice Alf and Apprentice Harper
|
||||||
|
|
||||||
# Revision history:
|
# Revision history:
|
||||||
# 6.0.0 - Release along with unified plugin
|
# 6.0.0 - Release along with unified plugin
|
||||||
@@ -19,8 +19,10 @@
|
|||||||
# 6.3.2 - Version bump to match plugin
|
# 6.3.2 - Version bump to match plugin
|
||||||
# 6.3.3 - Version bump to match plugin
|
# 6.3.3 - Version bump to match plugin
|
||||||
# 6.3.4 - Version bump to match plugin
|
# 6.3.4 - Version bump to match plugin
|
||||||
|
# 6.3.5 - Version bump to match plugin
|
||||||
|
# 6.3.6 - Version bump to match plugin
|
||||||
|
|
||||||
__version__ = '6.3.4'
|
__version__ = '6.3.6'
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os, os.path
|
import os, os.path
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ __docformat__ = 'restructuredtext en'
|
|||||||
# 6.3.2 - Fixed Kindle for Android help file
|
# 6.3.2 - Fixed Kindle for Android help file
|
||||||
# 6.3.3 - Bug fix for Kindle for PC support
|
# 6.3.3 - Bug fix for Kindle for PC support
|
||||||
# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17
|
# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17
|
||||||
|
# 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging
|
||||||
|
# 6.3.6 - Fixes for ADE ePub and PDF introduced in 6.3.5
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -53,7 +55,7 @@ Decrypt DRMed ebooks.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
PLUGIN_NAME = u"DeDRM"
|
PLUGIN_NAME = u"DeDRM"
|
||||||
PLUGIN_VERSION_TUPLE = (6, 3, 4)
|
PLUGIN_VERSION_TUPLE = (6, 3, 6)
|
||||||
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
|
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
|
||||||
# Include an html helpfile in the plugin's zipfile with the following name.
|
# Include an html helpfile in the plugin's zipfile with the following name.
|
||||||
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
||||||
@@ -96,7 +98,7 @@ class DeDRM(FileTypePlugin):
|
|||||||
supported_platforms = ['linux', 'osx', 'windows']
|
supported_platforms = ['linux', 'osx', 'windows']
|
||||||
author = u"Apprentice Alf, Aprentice Harper, The Dark Reverser and i♥cabbages"
|
author = u"Apprentice Alf, Aprentice Harper, The Dark Reverser and i♥cabbages"
|
||||||
version = PLUGIN_VERSION_TUPLE
|
version = PLUGIN_VERSION_TUPLE
|
||||||
minimum_calibre_version = (0, 7, 55) # Compiled python libraries cannot be imported in earlier versions.
|
minimum_calibre_version = (1, 0, 0) # Compiled python libraries cannot be imported in earlier versions.
|
||||||
file_types = set(['epub','pdf','pdb','prc','mobi','pobi','azw','azw1','azw3','azw4','tpz'])
|
file_types = set(['epub','pdf','pdb','prc','mobi','pobi','azw','azw1','azw3','azw4','tpz'])
|
||||||
on_import = True
|
on_import = True
|
||||||
priority = 600
|
priority = 600
|
||||||
@@ -296,11 +298,15 @@ class DeDRM(FileTypePlugin):
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
result = 1
|
result = 1
|
||||||
|
|
||||||
|
try:
|
||||||
of.close()
|
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)
|
||||||
|
|
||||||
if result == 0:
|
if result == 0:
|
||||||
# Decryption was successful.
|
# Decryption was successful.
|
||||||
# Return the modified PersistentTemporary file to calibre.
|
# 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)
|
||||||
return of.name
|
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)
|
||||||
@@ -360,6 +366,7 @@ class DeDRM(FileTypePlugin):
|
|||||||
except:
|
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()
|
traceback.print_exc()
|
||||||
|
print u"{0} v{1}: Decrypted with new default key after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
|
||||||
# Return the modified PersistentTemporary file to calibre.
|
# Return the modified PersistentTemporary file to calibre.
|
||||||
return of.name
|
return of.name
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,19 @@
|
|||||||
|
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
# ineptepub.pyw, version 6.1
|
# ineptepub.pyw, version 6.5
|
||||||
# Copyright © 2009-2010 by i♥cabbages
|
# Copyright © 2009-2010 by i♥cabbages
|
||||||
|
|
||||||
# Released under the terms of the GNU General Public Licence, version 3
|
# Released under the terms of the GNU General Public Licence, version 3
|
||||||
# <http://www.gnu.org/licenses/>
|
# <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
# Modified 2010–2013 by some_updates, DiapDealer and Apprentice Alf
|
# Modified 2010–2013 by some_updates, DiapDealer and Apprentice Alf
|
||||||
|
# Modified 2015–2016 by Apprentice Harper
|
||||||
|
|
||||||
# Windows users: Before running this program, you must first install Python 2.6
|
# Windows users: Before running this program, you must first install Python 2.7
|
||||||
# from <http://www.python.org/download/> and PyCrypto from
|
# from <http://www.python.org/download/> and PyCrypto from
|
||||||
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
||||||
# install the version for Python 2.6). Save this script file as
|
# install the version for Python 2.7). Save this script file as
|
||||||
# ineptepub.pyw and double-click on it to run it.
|
# ineptepub.pyw and double-click on it to run it.
|
||||||
#
|
#
|
||||||
# Mac OS X users: Save this script file as ineptepub.pyw. You can run this
|
# Mac OS X users: Save this script file as ineptepub.pyw. You can run this
|
||||||
@@ -38,13 +39,16 @@ from __future__ import with_statement
|
|||||||
# 6.0 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
# 6.0 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
||||||
# 6.1 - Work if TkInter is missing
|
# 6.1 - Work if TkInter is missing
|
||||||
# 6.2 - Handle UTF-8 file names inside an ePub, fix by Jose Luis
|
# 6.2 - Handle UTF-8 file names inside an ePub, fix by Jose Luis
|
||||||
|
# 6.3 - Add additional check on DER file sanity
|
||||||
|
# 6.4 - Remove erroneous check on DER file sanity
|
||||||
|
# 6.5 - Completely remove erroneous check on DER file sanity
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Decrypt Adobe Digital Editions encrypted ePub books.
|
Decrypt Adobe Digital Editions encrypted ePub books.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__version__ = "6.2"
|
__version__ = "6.5"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -3,18 +3,19 @@
|
|||||||
|
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
# ineptpdf.pyw, version 7.11
|
# ineptpdf.pyw, version 8.0.4
|
||||||
# Copyright © 2009-2010 by i♥cabbages
|
# Copyright © 2009-2010 by i♥cabbages
|
||||||
|
|
||||||
# Released under the terms of the GNU General Public Licence, version 3
|
# Released under the terms of the GNU General Public Licence, version 3
|
||||||
# <http://www.gnu.org/licenses/>
|
# <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
# Modified 2010–2012 by some_updates, DiapDealer and Apprentice Alf
|
# Modified 2010–2012 by some_updates, DiapDealer and Apprentice Alf
|
||||||
|
# Modified 2015-2016 by Apprentice Harper
|
||||||
|
|
||||||
# Windows users: Before running this program, you must first install Python 2.6
|
# Windows users: Before running this program, you must first install Python 2.7
|
||||||
# from <http://www.python.org/download/> and PyCrypto from
|
# from <http://www.python.org/download/> and PyCrypto from
|
||||||
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
||||||
# install the version for Python 2.6). Save this script file as
|
# install the version for Python 2.7). Save this script file as
|
||||||
# ineptpdf.pyw and double-click on it to run it.
|
# ineptpdf.pyw and double-click on it to run it.
|
||||||
#
|
#
|
||||||
# Mac OS X users: Save this script file as ineptpdf.pyw. You can run this
|
# Mac OS X users: Save this script file as ineptpdf.pyw. You can run this
|
||||||
@@ -53,13 +54,17 @@ from __future__ import with_statement
|
|||||||
# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
||||||
# 8.0 - Work if TkInter is missing
|
# 8.0 - Work if TkInter is missing
|
||||||
# 8.0.1 - Broken Metadata fix.
|
# 8.0.1 - Broken Metadata fix.
|
||||||
|
# 8.0.2 - Add additional check on DER file sanity
|
||||||
|
# 8.0.3 - Remove erroneous check on DER file sanity
|
||||||
|
# 8.0.4 - Completely remove erroneous check on DER file sanity
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Decrypts Adobe ADEPT-encrypted PDF files.
|
Decrypts Adobe ADEPT-encrypted PDF files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__version__ = "8.0.1"
|
__version__ = "8.0.4"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
|
|||||||
if not os.path.exists(outdirpath):
|
if not os.path.exists(outdirpath):
|
||||||
os.makedirs(outdirpath)
|
os.makedirs(outdirpath)
|
||||||
|
|
||||||
|
wineprefix = os.path.abspath(os.path.expanduser(os.path.expandvars(wineprefix)))
|
||||||
if wineprefix != "" and os.path.exists(wineprefix):
|
if wineprefix != "" and os.path.exists(wineprefix):
|
||||||
cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix)
|
cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix)
|
||||||
else:
|
else:
|
||||||
@@ -38,8 +39,20 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
|
|||||||
result = p2.wait("wait")
|
result = p2.wait("wait")
|
||||||
except Exception, e:
|
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])
|
||||||
return []
|
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)
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
|
# try finding winekeys anyway, even if above code errored
|
||||||
winekeys = []
|
winekeys = []
|
||||||
# get any files with extension in the output dir
|
# get any files with extension in the output dir
|
||||||
files = [f for f in os.listdir(outdirpath) if f.endswith(extension)]
|
files = [f for f in os.listdir(outdirpath) if f.endswith(extension)]
|
||||||
|
|||||||
Binary file not shown.
@@ -46,6 +46,8 @@ __docformat__ = 'restructuredtext en'
|
|||||||
# 6.3.2 - Fixed Kindle for Android help file
|
# 6.3.2 - Fixed Kindle for Android help file
|
||||||
# 6.3.3 - Bug fix for Kindle for PC support
|
# 6.3.3 - Bug fix for Kindle for PC support
|
||||||
# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17
|
# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17
|
||||||
|
# 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging
|
||||||
|
# 6.3.6 - Fixes for ADE ePub and PDF introduced in 6.3.5
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -53,7 +55,7 @@ Decrypt DRMed ebooks.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
PLUGIN_NAME = u"DeDRM"
|
PLUGIN_NAME = u"DeDRM"
|
||||||
PLUGIN_VERSION_TUPLE = (6, 3, 4)
|
PLUGIN_VERSION_TUPLE = (6, 3, 6)
|
||||||
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
|
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
|
||||||
# Include an html helpfile in the plugin's zipfile with the following name.
|
# Include an html helpfile in the plugin's zipfile with the following name.
|
||||||
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
||||||
@@ -96,7 +98,7 @@ class DeDRM(FileTypePlugin):
|
|||||||
supported_platforms = ['linux', 'osx', 'windows']
|
supported_platforms = ['linux', 'osx', 'windows']
|
||||||
author = u"Apprentice Alf, Aprentice Harper, The Dark Reverser and i♥cabbages"
|
author = u"Apprentice Alf, Aprentice Harper, The Dark Reverser and i♥cabbages"
|
||||||
version = PLUGIN_VERSION_TUPLE
|
version = PLUGIN_VERSION_TUPLE
|
||||||
minimum_calibre_version = (0, 7, 55) # Compiled python libraries cannot be imported in earlier versions.
|
minimum_calibre_version = (1, 0, 0) # Compiled python libraries cannot be imported in earlier versions.
|
||||||
file_types = set(['epub','pdf','pdb','prc','mobi','pobi','azw','azw1','azw3','azw4','tpz'])
|
file_types = set(['epub','pdf','pdb','prc','mobi','pobi','azw','azw1','azw3','azw4','tpz'])
|
||||||
on_import = True
|
on_import = True
|
||||||
priority = 600
|
priority = 600
|
||||||
@@ -296,11 +298,15 @@ class DeDRM(FileTypePlugin):
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
result = 1
|
result = 1
|
||||||
|
|
||||||
|
try:
|
||||||
of.close()
|
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)
|
||||||
|
|
||||||
if result == 0:
|
if result == 0:
|
||||||
# Decryption was successful.
|
# Decryption was successful.
|
||||||
# Return the modified PersistentTemporary file to calibre.
|
# 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)
|
||||||
return of.name
|
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)
|
||||||
@@ -360,6 +366,7 @@ class DeDRM(FileTypePlugin):
|
|||||||
except:
|
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()
|
traceback.print_exc()
|
||||||
|
print u"{0} v{1}: Decrypted with new default key after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
|
||||||
# Return the modified PersistentTemporary file to calibre.
|
# Return the modified PersistentTemporary file to calibre.
|
||||||
return of.name
|
return of.name
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,19 @@
|
|||||||
|
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
# ineptepub.pyw, version 6.1
|
# ineptepub.pyw, version 6.5
|
||||||
# Copyright © 2009-2010 by i♥cabbages
|
# Copyright © 2009-2010 by i♥cabbages
|
||||||
|
|
||||||
# Released under the terms of the GNU General Public Licence, version 3
|
# Released under the terms of the GNU General Public Licence, version 3
|
||||||
# <http://www.gnu.org/licenses/>
|
# <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
# Modified 2010–2013 by some_updates, DiapDealer and Apprentice Alf
|
# Modified 2010–2013 by some_updates, DiapDealer and Apprentice Alf
|
||||||
|
# Modified 2015–2016 by Apprentice Harper
|
||||||
|
|
||||||
# Windows users: Before running this program, you must first install Python 2.6
|
# Windows users: Before running this program, you must first install Python 2.7
|
||||||
# from <http://www.python.org/download/> and PyCrypto from
|
# from <http://www.python.org/download/> and PyCrypto from
|
||||||
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
||||||
# install the version for Python 2.6). Save this script file as
|
# install the version for Python 2.7). Save this script file as
|
||||||
# ineptepub.pyw and double-click on it to run it.
|
# ineptepub.pyw and double-click on it to run it.
|
||||||
#
|
#
|
||||||
# Mac OS X users: Save this script file as ineptepub.pyw. You can run this
|
# Mac OS X users: Save this script file as ineptepub.pyw. You can run this
|
||||||
@@ -38,13 +39,16 @@ from __future__ import with_statement
|
|||||||
# 6.0 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
# 6.0 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
||||||
# 6.1 - Work if TkInter is missing
|
# 6.1 - Work if TkInter is missing
|
||||||
# 6.2 - Handle UTF-8 file names inside an ePub, fix by Jose Luis
|
# 6.2 - Handle UTF-8 file names inside an ePub, fix by Jose Luis
|
||||||
|
# 6.3 - Add additional check on DER file sanity
|
||||||
|
# 6.4 - Remove erroneous check on DER file sanity
|
||||||
|
# 6.5 - Completely remove erroneous check on DER file sanity
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Decrypt Adobe Digital Editions encrypted ePub books.
|
Decrypt Adobe Digital Editions encrypted ePub books.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__version__ = "6.2"
|
__version__ = "6.5"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -3,18 +3,19 @@
|
|||||||
|
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
# ineptpdf.pyw, version 7.11
|
# ineptpdf.pyw, version 8.0.4
|
||||||
# Copyright © 2009-2010 by i♥cabbages
|
# Copyright © 2009-2010 by i♥cabbages
|
||||||
|
|
||||||
# Released under the terms of the GNU General Public Licence, version 3
|
# Released under the terms of the GNU General Public Licence, version 3
|
||||||
# <http://www.gnu.org/licenses/>
|
# <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
# Modified 2010–2012 by some_updates, DiapDealer and Apprentice Alf
|
# Modified 2010–2012 by some_updates, DiapDealer and Apprentice Alf
|
||||||
|
# Modified 2015-2016 by Apprentice Harper
|
||||||
|
|
||||||
# Windows users: Before running this program, you must first install Python 2.6
|
# Windows users: Before running this program, you must first install Python 2.7
|
||||||
# from <http://www.python.org/download/> and PyCrypto from
|
# from <http://www.python.org/download/> and PyCrypto from
|
||||||
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
# <http://www.voidspace.org.uk/python/modules.shtml#pycrypto> (make sure to
|
||||||
# install the version for Python 2.6). Save this script file as
|
# install the version for Python 2.7). Save this script file as
|
||||||
# ineptpdf.pyw and double-click on it to run it.
|
# ineptpdf.pyw and double-click on it to run it.
|
||||||
#
|
#
|
||||||
# Mac OS X users: Save this script file as ineptpdf.pyw. You can run this
|
# Mac OS X users: Save this script file as ineptpdf.pyw. You can run this
|
||||||
@@ -53,13 +54,17 @@ from __future__ import with_statement
|
|||||||
# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility
|
||||||
# 8.0 - Work if TkInter is missing
|
# 8.0 - Work if TkInter is missing
|
||||||
# 8.0.1 - Broken Metadata fix.
|
# 8.0.1 - Broken Metadata fix.
|
||||||
|
# 8.0.2 - Add additional check on DER file sanity
|
||||||
|
# 8.0.3 - Remove erroneous check on DER file sanity
|
||||||
|
# 8.0.4 - Completely remove erroneous check on DER file sanity
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Decrypts Adobe ADEPT-encrypted PDF files.
|
Decrypts Adobe ADEPT-encrypted PDF files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__version__ = "8.0.1"
|
__version__ = "8.0.4"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -39,8 +39,20 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
|
|||||||
result = p2.wait("wait")
|
result = p2.wait("wait")
|
||||||
except Exception, e:
|
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])
|
||||||
return []
|
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)
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
|
# try finding winekeys anyway, even if above code errored
|
||||||
winekeys = []
|
winekeys = []
|
||||||
# get any files with extension in the output dir
|
# get any files with extension in the output dir
|
||||||
files = [f for f in os.listdir(outdirpath) if f.endswith(extension)]
|
files = [f for f in os.listdir(outdirpath) if f.endswith(extension)]
|
||||||
|
|||||||
Binary file not shown.
@@ -19,7 +19,7 @@ except NameError:
|
|||||||
PLUGIN_NAME = 'Obok DeDRM'
|
PLUGIN_NAME = 'Obok DeDRM'
|
||||||
PLUGIN_SAFE_NAME = PLUGIN_NAME.strip().lower().replace(' ', '_')
|
PLUGIN_SAFE_NAME = PLUGIN_NAME.strip().lower().replace(' ', '_')
|
||||||
PLUGIN_DESCRIPTION = _('Removes DRM from Kobo kepubs and adds them to the library.')
|
PLUGIN_DESCRIPTION = _('Removes DRM from Kobo kepubs and adds them to the library.')
|
||||||
PLUGIN_VERSION_TUPLE = (3, 1, 6)
|
PLUGIN_VERSION_TUPLE = (6, 3, 6)
|
||||||
PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE])
|
PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE])
|
||||||
HELPFILE_NAME = PLUGIN_SAFE_NAME + '_Help.htm'
|
HELPFILE_NAME = PLUGIN_SAFE_NAME + '_Help.htm'
|
||||||
PLUGIN_AUTHORS = 'Anon'
|
PLUGIN_AUTHORS = 'Anon'
|
||||||
|
|||||||
@@ -34,15 +34,6 @@ from calibre_plugins.obok_dedrm.utilities import (
|
|||||||
from calibre_plugins.obok_dedrm.obok.obok import KoboLibrary
|
from calibre_plugins.obok_dedrm.obok.obok import KoboLibrary
|
||||||
from calibre_plugins.obok_dedrm.obok.legacy_obok import legacy_obok
|
from calibre_plugins.obok_dedrm.obok.legacy_obok import legacy_obok
|
||||||
|
|
||||||
can_parse_xml = True
|
|
||||||
try:
|
|
||||||
from xml.etree import ElementTree as ET
|
|
||||||
debug_print("using xml.etree for xml parsing")
|
|
||||||
except ImportError:
|
|
||||||
can_parse_xml = False
|
|
||||||
debug_print("Cannot find xml.etree, disabling extraction of serial numbers")
|
|
||||||
|
|
||||||
|
|
||||||
PLUGIN_ICONS = ['images/obok.png']
|
PLUGIN_ICONS = ['images/obok.png']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -90,28 +81,16 @@ class InterfacePluginAction(InterfaceAction):
|
|||||||
#
|
#
|
||||||
# search for connected device in case serials are saved
|
# search for connected device in case serials are saved
|
||||||
tmpserials = cfg['kobo_serials']
|
tmpserials = cfg['kobo_serials']
|
||||||
device = self.parent().device_manager.connected_device
|
|
||||||
device_path = None
|
device_path = None
|
||||||
|
try:
|
||||||
|
device = self.parent().device_manager.connected_device
|
||||||
if (device):
|
if (device):
|
||||||
device_path = device._main_prefix
|
device_path = device._main_prefix
|
||||||
debug_print("get_device_settings - device_path=", device_path)
|
debug_print("get_device_settings - device_path=", device_path)
|
||||||
# get serial from device_path/.adobe-digital-editions/device.xml
|
|
||||||
if can_parse_xml:
|
|
||||||
devicexml = os.path.join(device_path, '.adobe-digital-editions', 'device.xml')
|
|
||||||
debug_print("trying to load %s" % devicexml)
|
|
||||||
if (os.path.exists(devicexml)):
|
|
||||||
debug_print("trying to parse %s" % devicexml)
|
|
||||||
xmltree = ET.parse(devicexml)
|
|
||||||
for node in xmltree.iter():
|
|
||||||
if "deviceSerial" in node.tag:
|
|
||||||
serial = node.text
|
|
||||||
debug_print ("found serial %s" % serial)
|
|
||||||
tmpserials.append(serial)
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
debug_print("didn't find device")
|
debug_print("didn't find device")
|
||||||
|
except:
|
||||||
|
debug_print("Exception getting device path. Probably not an E-Ink Kobo device")
|
||||||
|
|
||||||
# Get the Kobo Library object (obok v3.01)
|
# Get the Kobo Library object (obok v3.01)
|
||||||
self.library = KoboLibrary(tmpserials, device_path)
|
self.library = KoboLibrary(tmpserials, device_path)
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Version 3.2.0 January 2016
|
||||||
|
# Update for latest version of Windows Desktop app.
|
||||||
|
# Support Kobo devices in the command line version.
|
||||||
|
#
|
||||||
|
# Version 3.1.9 November 2015
|
||||||
|
# Handle Kobo Desktop under wine on Linux
|
||||||
|
#
|
||||||
|
# Version 3.1.8 November 2015
|
||||||
|
# Handle the case of Kobo Arc or Vox device (i.e. don't crash).
|
||||||
|
#
|
||||||
|
# Version 3.1.7 October 2015
|
||||||
|
# Handle the case of no device or database more gracefully.
|
||||||
|
#
|
||||||
# Version 3.1.6 September 2015
|
# Version 3.1.6 September 2015
|
||||||
# Enable support for Kobo devices
|
# Enable support for Kobo devices
|
||||||
# More character encoding fixes (unicode strings)
|
# More character encoding fixes (unicode strings)
|
||||||
@@ -123,7 +136,8 @@
|
|||||||
#
|
#
|
||||||
"""Manage all Kobo books, either encrypted or DRM-free."""
|
"""Manage all Kobo books, either encrypted or DRM-free."""
|
||||||
|
|
||||||
__version__ = '3.1.6'
|
__version__ = '3.1.9'
|
||||||
|
__about__ = u"Obok v{0}\nCopyright © 2012-2015 Physisticated et al.".format(__version__)
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
@@ -137,6 +151,18 @@ import hashlib
|
|||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
import string
|
import string
|
||||||
import shutil
|
import shutil
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
can_parse_xml = True
|
||||||
|
try:
|
||||||
|
from xml.etree import ElementTree as ET
|
||||||
|
# print u"using xml.etree for xml parsing"
|
||||||
|
except ImportError:
|
||||||
|
can_parse_xml = False
|
||||||
|
# print u"Cannot find xml.etree, disabling extraction of serial numbers"
|
||||||
|
|
||||||
|
# List of all known hash keys
|
||||||
|
KOBO_HASH_KEYS = ['88b3a2e13', 'XzUhGYdFp', 'NoCanLook']
|
||||||
|
|
||||||
class ENCRYPTIONError(Exception):
|
class ENCRYPTIONError(Exception):
|
||||||
pass
|
pass
|
||||||
@@ -249,24 +275,59 @@ class KoboLibrary(object):
|
|||||||
of books, their titles, and the user's encryption key(s)."""
|
of books, their titles, and the user's encryption key(s)."""
|
||||||
|
|
||||||
def __init__ (self, serials = [], device_path = None):
|
def __init__ (self, serials = [], device_path = None):
|
||||||
print u"Obok v{0}\nCopyright © 2012-2015 Physisticated et al.".format(__version__)
|
print __about__
|
||||||
self.kobodir = u""
|
self.kobodir = u""
|
||||||
kobodb = u""
|
kobodb = u""
|
||||||
|
|
||||||
# - first check whether serials have been found or are provided
|
# Order of checks
|
||||||
# and a device is connected. In this case, use the device
|
# 1. first check if a device_path has been passed in, and whether
|
||||||
# - otherwise fall back to Kobo Desktop Application for Windows and Mac
|
# we can find the sqlite db in the respective place
|
||||||
if (device_path and (len(serials) > 0)):
|
# 2. if 1., and we got some serials passed in (from saved
|
||||||
|
# settings in calibre), just use it
|
||||||
|
# 3. if 1. worked, but we didn't get serials, try to parse them
|
||||||
|
# from the device, if this didn't work, unset everything
|
||||||
|
# 4. if by now we don't have kobodir set, give up on device and
|
||||||
|
# try to use the Desktop app.
|
||||||
|
|
||||||
|
# step 1. check whether this looks like a real device
|
||||||
|
if (device_path):
|
||||||
|
# we got a device path
|
||||||
self.kobodir = os.path.join(device_path, u".kobo")
|
self.kobodir = os.path.join(device_path, u".kobo")
|
||||||
# devices use KoboReader.sqlite
|
# devices use KoboReader.sqlite
|
||||||
kobodb = os.path.join(self.kobodir, u"KoboReader.sqlite")
|
kobodb = os.path.join(self.kobodir, u"KoboReader.sqlite")
|
||||||
if (not(os.path.exists(kobodb))):
|
if (not(os.path.isfile(kobodb))):
|
||||||
# give up here, we haven't found anything useful
|
# device path seems to be wrong, unset it
|
||||||
|
device_path = u""
|
||||||
|
self.kobodir = u""
|
||||||
|
kobodb = u""
|
||||||
|
|
||||||
|
if (self.kobodir):
|
||||||
|
# step 3. we found a device but didn't get serials, try to get them
|
||||||
|
if (len(serials) == 0):
|
||||||
|
# we got a device path but no saved serial
|
||||||
|
# try to get the serial from the device
|
||||||
|
# print u"get_device_settings - device_path = {0}".format(device_path)
|
||||||
|
# get serial from device_path/.adobe-digital-editions/device.xml
|
||||||
|
if can_parse_xml:
|
||||||
|
devicexml = os.path.join(device_path, '.adobe-digital-editions', 'device.xml')
|
||||||
|
# print u"trying to load {0}".format(devicexml)
|
||||||
|
if (os.path.exists(devicexml)):
|
||||||
|
# print u"trying to parse {0}".format(devicexml)
|
||||||
|
xmltree = ET.parse(devicexml)
|
||||||
|
for node in xmltree.iter():
|
||||||
|
if "deviceSerial" in node.tag:
|
||||||
|
serial = node.text
|
||||||
|
# print u"found serial {0}".format(serial)
|
||||||
|
serials.append(serial)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# print u"cannot get serials from device."
|
||||||
|
device_path = u""
|
||||||
self.kobodir = u""
|
self.kobodir = u""
|
||||||
kobodb = u""
|
kobodb = u""
|
||||||
|
|
||||||
if (self.kobodir == u""):
|
if (self.kobodir == u""):
|
||||||
# we haven't found a device with serials, so try desktop apps
|
# step 4. we haven't found a device with serials, so try desktop apps
|
||||||
if sys.platform.startswith('win'):
|
if sys.platform.startswith('win'):
|
||||||
import _winreg as winreg
|
import _winreg as winreg
|
||||||
if sys.getwindowsversion().major > 5:
|
if sys.getwindowsversion().major > 5:
|
||||||
@@ -280,8 +341,17 @@ class KoboLibrary(object):
|
|||||||
self.kobodir = os.path.join(self.kobodir, u"Kobo", u"Kobo Desktop Edition")
|
self.kobodir = os.path.join(self.kobodir, u"Kobo", u"Kobo Desktop Edition")
|
||||||
elif sys.platform.startswith('darwin'):
|
elif sys.platform.startswith('darwin'):
|
||||||
self.kobodir = os.path.join(os.environ['HOME'], u"Library", u"Application Support", u"Kobo", u"Kobo Desktop Edition")
|
self.kobodir = os.path.join(os.environ['HOME'], u"Library", u"Application Support", u"Kobo", u"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, u"Local Settings", u"Application Data", u"Kobo", u"Kobo Desktop Edition")
|
||||||
# desktop versions use Kobo.sqlite
|
# desktop versions use Kobo.sqlite
|
||||||
kobodb = os.path.join(self.kobodir, u"Kobo.sqlite")
|
kobodb = os.path.join(self.kobodir, u"Kobo.sqlite")
|
||||||
|
# check for existence of file
|
||||||
|
if (not(os.path.isfile(kobodb))):
|
||||||
|
# give up here, we haven't found anything useful
|
||||||
|
self.kobodir = u""
|
||||||
|
kobodb = u""
|
||||||
|
|
||||||
|
|
||||||
if (self.kobodir != u""):
|
if (self.kobodir != u""):
|
||||||
self.bookdir = os.path.join(self.kobodir, u"kepub")
|
self.bookdir = os.path.join(self.kobodir, u"kepub")
|
||||||
@@ -349,6 +419,13 @@ class KoboLibrary(object):
|
|||||||
for m in matches:
|
for m in matches:
|
||||||
# print u"m:{0}".format(m[0])
|
# print u"m:{0}".format(m[0])
|
||||||
macaddrs.append(m[0].upper())
|
macaddrs.append(m[0].upper())
|
||||||
|
else:
|
||||||
|
# probably linux, let's try ipconfig under wine
|
||||||
|
c = re.compile('\s(' + '[0-9a-f]{2}-' * 5 + '[0-9a-f]{2})(\s|$)', re.IGNORECASE)
|
||||||
|
for line in os.popen('ipconfig /all'):
|
||||||
|
m = c.search(line)
|
||||||
|
if m:
|
||||||
|
macaddrs.append(re.sub("-", ":", m.group(1)).upper())
|
||||||
|
|
||||||
# extend the list of macaddrs in any case with the serials
|
# extend the list of macaddrs in any case with the serials
|
||||||
# cannot hurt ;-)
|
# cannot hurt ;-)
|
||||||
@@ -372,13 +449,8 @@ class KoboLibrary(object):
|
|||||||
def __getuserkeys (self, macaddr):
|
def __getuserkeys (self, macaddr):
|
||||||
userids = self.__getuserids()
|
userids = self.__getuserids()
|
||||||
userkeys = []
|
userkeys = []
|
||||||
# This version is used for versions before 3.17.0.
|
for hash in KOBO_HASH_KEYS:
|
||||||
deviceid = hashlib.sha256('NoCanLook' + macaddr).hexdigest()
|
deviceid = hashlib.sha256(hash + macaddr).hexdigest()
|
||||||
for userid in userids:
|
|
||||||
userkey = hashlib.sha256(deviceid + userid).hexdigest()
|
|
||||||
userkeys.append(binascii.a2b_hex(userkey[32:]))
|
|
||||||
# This version is used for 3.17.0 and later.
|
|
||||||
deviceid = hashlib.sha256('XzUhGYdFp' + macaddr).hexdigest()
|
|
||||||
for userid in userids:
|
for userid in userids:
|
||||||
userkey = hashlib.sha256(deviceid + userid).hexdigest()
|
userkey = hashlib.sha256(deviceid + userid).hexdigest()
|
||||||
userkeys.append(binascii.a2b_hex(userkey[32:]))
|
userkeys.append(binascii.a2b_hex(userkey[32:]))
|
||||||
@@ -518,7 +590,17 @@ class KoboFile(object):
|
|||||||
return contents
|
return contents
|
||||||
|
|
||||||
def cli_main():
|
def cli_main():
|
||||||
lib = KoboLibrary()
|
description = __about__
|
||||||
|
epilog = u"Parsing of arguments failed."
|
||||||
|
parser = argparse.ArgumentParser(prog=sys.argv[0], description=description, epilog=epilog)
|
||||||
|
parser.add_argument('--devicedir', default='/media/KOBOeReader', help="directory of connected Kobo device")
|
||||||
|
args = vars(parser.parse_args())
|
||||||
|
serials = []
|
||||||
|
devicedir = u""
|
||||||
|
if args['devicedir']:
|
||||||
|
devicedir = args['devicedir']
|
||||||
|
|
||||||
|
lib = KoboLibrary(serials, devicedir)
|
||||||
|
|
||||||
for i, book in enumerate(lib.books):
|
for i, book in enumerate(lib.books):
|
||||||
print u"{0}: {1}".format(i + 1, book.title)
|
print u"{0}: {1}".format(i + 1, book.title)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
obok_plugin.zip
|
obok_plugin.zip
|
||||||
================
|
================
|
||||||
|
|
||||||
This plugin will remove the DRM from Kobo ebooks download on Mac or Windows using the Kobo desktop application, or from Kobo ebooks on an attached Kobo reader. If both are available, ebooks will be read from the attached Kobo reader. To import from the desktop application, unplug the Kobo reader.
|
This plugin will remove the DRM from Kobo ebooks download on Mac or Windows using the Kobo desktop application, or from Kobo ebooks on an attached E-Ink Kobo reader (but not a Kobo Arc or Kobo Vox). If both are available, ebooks will be read from the attached E-Ink Kobo reader. To import from the desktop application, unplug the Kobo reader.
|
||||||
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Version 3.2.0 January 2016
|
||||||
|
# Update for latest version of Windows Desktop app.
|
||||||
|
# Support Kobo devices in the command line version.
|
||||||
|
#
|
||||||
|
# Version 3.1.9 November 2015
|
||||||
|
# Handle Kobo Desktop under wine on Linux
|
||||||
|
#
|
||||||
|
# Version 3.1.8 November 2015
|
||||||
|
# Handle the case of Kobo Arc or Vox device (i.e. don't crash).
|
||||||
|
#
|
||||||
|
# Version 3.1.7 October 2015
|
||||||
|
# Handle the case of no device or database more gracefully.
|
||||||
|
#
|
||||||
# Version 3.1.6 September 2015
|
# Version 3.1.6 September 2015
|
||||||
# Enable support for Kobo devices
|
# Enable support for Kobo devices
|
||||||
# More character encoding fixes (unicode strings)
|
# More character encoding fixes (unicode strings)
|
||||||
@@ -123,7 +136,8 @@
|
|||||||
#
|
#
|
||||||
"""Manage all Kobo books, either encrypted or DRM-free."""
|
"""Manage all Kobo books, either encrypted or DRM-free."""
|
||||||
|
|
||||||
__version__ = '3.1.6'
|
__version__ = '3.1.9'
|
||||||
|
__about__ = u"Obok v{0}\nCopyright © 2012-2015 Physisticated et al.".format(__version__)
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
@@ -137,6 +151,18 @@ import hashlib
|
|||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
import string
|
import string
|
||||||
import shutil
|
import shutil
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
can_parse_xml = True
|
||||||
|
try:
|
||||||
|
from xml.etree import ElementTree as ET
|
||||||
|
# print u"using xml.etree for xml parsing"
|
||||||
|
except ImportError:
|
||||||
|
can_parse_xml = False
|
||||||
|
# print u"Cannot find xml.etree, disabling extraction of serial numbers"
|
||||||
|
|
||||||
|
# List of all known hash keys
|
||||||
|
KOBO_HASH_KEYS = ['88b3a2e13', 'XzUhGYdFp', 'NoCanLook']
|
||||||
|
|
||||||
class ENCRYPTIONError(Exception):
|
class ENCRYPTIONError(Exception):
|
||||||
pass
|
pass
|
||||||
@@ -249,24 +275,59 @@ class KoboLibrary(object):
|
|||||||
of books, their titles, and the user's encryption key(s)."""
|
of books, their titles, and the user's encryption key(s)."""
|
||||||
|
|
||||||
def __init__ (self, serials = [], device_path = None):
|
def __init__ (self, serials = [], device_path = None):
|
||||||
print u"Obok v{0}\nCopyright © 2012-2015 Physisticated et al.".format(__version__)
|
print __about__
|
||||||
self.kobodir = u""
|
self.kobodir = u""
|
||||||
kobodb = u""
|
kobodb = u""
|
||||||
|
|
||||||
# - first check whether serials have been found or are provided
|
# Order of checks
|
||||||
# and a device is connected. In this case, use the device
|
# 1. first check if a device_path has been passed in, and whether
|
||||||
# - otherwise fall back to Kobo Desktop Application for Windows and Mac
|
# we can find the sqlite db in the respective place
|
||||||
if (device_path and (len(serials) > 0)):
|
# 2. if 1., and we got some serials passed in (from saved
|
||||||
|
# settings in calibre), just use it
|
||||||
|
# 3. if 1. worked, but we didn't get serials, try to parse them
|
||||||
|
# from the device, if this didn't work, unset everything
|
||||||
|
# 4. if by now we don't have kobodir set, give up on device and
|
||||||
|
# try to use the Desktop app.
|
||||||
|
|
||||||
|
# step 1. check whether this looks like a real device
|
||||||
|
if (device_path):
|
||||||
|
# we got a device path
|
||||||
self.kobodir = os.path.join(device_path, u".kobo")
|
self.kobodir = os.path.join(device_path, u".kobo")
|
||||||
# devices use KoboReader.sqlite
|
# devices use KoboReader.sqlite
|
||||||
kobodb = os.path.join(self.kobodir, u"KoboReader.sqlite")
|
kobodb = os.path.join(self.kobodir, u"KoboReader.sqlite")
|
||||||
if (not(os.path.exists(kobodb))):
|
if (not(os.path.isfile(kobodb))):
|
||||||
# give up here, we haven't found anything useful
|
# device path seems to be wrong, unset it
|
||||||
|
device_path = u""
|
||||||
|
self.kobodir = u""
|
||||||
|
kobodb = u""
|
||||||
|
|
||||||
|
if (self.kobodir):
|
||||||
|
# step 3. we found a device but didn't get serials, try to get them
|
||||||
|
if (len(serials) == 0):
|
||||||
|
# we got a device path but no saved serial
|
||||||
|
# try to get the serial from the device
|
||||||
|
# print u"get_device_settings - device_path = {0}".format(device_path)
|
||||||
|
# get serial from device_path/.adobe-digital-editions/device.xml
|
||||||
|
if can_parse_xml:
|
||||||
|
devicexml = os.path.join(device_path, '.adobe-digital-editions', 'device.xml')
|
||||||
|
# print u"trying to load {0}".format(devicexml)
|
||||||
|
if (os.path.exists(devicexml)):
|
||||||
|
# print u"trying to parse {0}".format(devicexml)
|
||||||
|
xmltree = ET.parse(devicexml)
|
||||||
|
for node in xmltree.iter():
|
||||||
|
if "deviceSerial" in node.tag:
|
||||||
|
serial = node.text
|
||||||
|
# print u"found serial {0}".format(serial)
|
||||||
|
serials.append(serial)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# print u"cannot get serials from device."
|
||||||
|
device_path = u""
|
||||||
self.kobodir = u""
|
self.kobodir = u""
|
||||||
kobodb = u""
|
kobodb = u""
|
||||||
|
|
||||||
if (self.kobodir == u""):
|
if (self.kobodir == u""):
|
||||||
# we haven't found a device with serials, so try desktop apps
|
# step 4. we haven't found a device with serials, so try desktop apps
|
||||||
if sys.platform.startswith('win'):
|
if sys.platform.startswith('win'):
|
||||||
import _winreg as winreg
|
import _winreg as winreg
|
||||||
if sys.getwindowsversion().major > 5:
|
if sys.getwindowsversion().major > 5:
|
||||||
@@ -280,8 +341,17 @@ class KoboLibrary(object):
|
|||||||
self.kobodir = os.path.join(self.kobodir, u"Kobo", u"Kobo Desktop Edition")
|
self.kobodir = os.path.join(self.kobodir, u"Kobo", u"Kobo Desktop Edition")
|
||||||
elif sys.platform.startswith('darwin'):
|
elif sys.platform.startswith('darwin'):
|
||||||
self.kobodir = os.path.join(os.environ['HOME'], u"Library", u"Application Support", u"Kobo", u"Kobo Desktop Edition")
|
self.kobodir = os.path.join(os.environ['HOME'], u"Library", u"Application Support", u"Kobo", u"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, u"Local Settings", u"Application Data", u"Kobo", u"Kobo Desktop Edition")
|
||||||
# desktop versions use Kobo.sqlite
|
# desktop versions use Kobo.sqlite
|
||||||
kobodb = os.path.join(self.kobodir, u"Kobo.sqlite")
|
kobodb = os.path.join(self.kobodir, u"Kobo.sqlite")
|
||||||
|
# check for existence of file
|
||||||
|
if (not(os.path.isfile(kobodb))):
|
||||||
|
# give up here, we haven't found anything useful
|
||||||
|
self.kobodir = u""
|
||||||
|
kobodb = u""
|
||||||
|
|
||||||
|
|
||||||
if (self.kobodir != u""):
|
if (self.kobodir != u""):
|
||||||
self.bookdir = os.path.join(self.kobodir, u"kepub")
|
self.bookdir = os.path.join(self.kobodir, u"kepub")
|
||||||
@@ -349,6 +419,13 @@ class KoboLibrary(object):
|
|||||||
for m in matches:
|
for m in matches:
|
||||||
# print u"m:{0}".format(m[0])
|
# print u"m:{0}".format(m[0])
|
||||||
macaddrs.append(m[0].upper())
|
macaddrs.append(m[0].upper())
|
||||||
|
else:
|
||||||
|
# probably linux, let's try ipconfig under wine
|
||||||
|
c = re.compile('\s(' + '[0-9a-f]{2}-' * 5 + '[0-9a-f]{2})(\s|$)', re.IGNORECASE)
|
||||||
|
for line in os.popen('ipconfig /all'):
|
||||||
|
m = c.search(line)
|
||||||
|
if m:
|
||||||
|
macaddrs.append(re.sub("-", ":", m.group(1)).upper())
|
||||||
|
|
||||||
# extend the list of macaddrs in any case with the serials
|
# extend the list of macaddrs in any case with the serials
|
||||||
# cannot hurt ;-)
|
# cannot hurt ;-)
|
||||||
@@ -372,13 +449,8 @@ class KoboLibrary(object):
|
|||||||
def __getuserkeys (self, macaddr):
|
def __getuserkeys (self, macaddr):
|
||||||
userids = self.__getuserids()
|
userids = self.__getuserids()
|
||||||
userkeys = []
|
userkeys = []
|
||||||
# This version is used for versions before 3.17.0.
|
for hash in KOBO_HASH_KEYS:
|
||||||
deviceid = hashlib.sha256('NoCanLook' + macaddr).hexdigest()
|
deviceid = hashlib.sha256(hash + macaddr).hexdigest()
|
||||||
for userid in userids:
|
|
||||||
userkey = hashlib.sha256(deviceid + userid).hexdigest()
|
|
||||||
userkeys.append(binascii.a2b_hex(userkey[32:]))
|
|
||||||
# This version is used for 3.17.0 and later.
|
|
||||||
deviceid = hashlib.sha256('XzUhGYdFp' + macaddr).hexdigest()
|
|
||||||
for userid in userids:
|
for userid in userids:
|
||||||
userkey = hashlib.sha256(deviceid + userid).hexdigest()
|
userkey = hashlib.sha256(deviceid + userid).hexdigest()
|
||||||
userkeys.append(binascii.a2b_hex(userkey[32:]))
|
userkeys.append(binascii.a2b_hex(userkey[32:]))
|
||||||
@@ -518,7 +590,17 @@ class KoboFile(object):
|
|||||||
return contents
|
return contents
|
||||||
|
|
||||||
def cli_main():
|
def cli_main():
|
||||||
lib = KoboLibrary()
|
description = __about__
|
||||||
|
epilog = u"Parsing of arguments failed."
|
||||||
|
parser = argparse.ArgumentParser(prog=sys.argv[0], description=description, epilog=epilog)
|
||||||
|
parser.add_argument('--devicedir', default='/media/KOBOeReader', help="directory of connected Kobo device")
|
||||||
|
args = vars(parser.parse_args())
|
||||||
|
serials = []
|
||||||
|
devicedir = u""
|
||||||
|
if args['devicedir']:
|
||||||
|
devicedir = args['devicedir']
|
||||||
|
|
||||||
|
lib = KoboLibrary(serials, devicedir)
|
||||||
|
|
||||||
for i, book in enumerate(lib.books):
|
for i, book in enumerate(lib.books):
|
||||||
print u"{0}: {1}".format(i + 1, book.title)
|
print u"{0}: {1}".format(i + 1, book.title)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1,10 +1,4 @@
|
|||||||
How-to:
|
The latest Scuolabook tool can be found at Hex's own blog:
|
||||||
1) Make sure you can read all PDF files on Scuolabook Reader.
|
https://thisishex.wordpress.com/scuolabook-drm-remover/
|
||||||
2) Run Scuolabook DRM Remover.
|
|
||||||
3) Get your free books from the directory where you started the program.
|
|
||||||
|
|
||||||
Note:
|
Harper.
|
||||||
It is recommended to use Scuolabook version 2.0.1 and refuse all updates
|
|
||||||
because the encryption algorithm may change making this tool useless.
|
|
||||||
|
|
||||||
Hex
|
|
||||||
@@ -12,7 +12,7 @@ The is archive includes tools to remove DRM from:
|
|||||||
- Adobe Digital Editions PDFs
|
- Adobe Digital Editions PDFs
|
||||||
- Mobipocket ebooks
|
- Mobipocket ebooks
|
||||||
- eReader PDB books
|
- eReader PDB books
|
||||||
- Scuolabooks (Windows only solution by Hex)
|
- Scuolabooks (Link to solution by Hex)
|
||||||
|
|
||||||
These tools do NOT work with Apple's iBooks FairPlay DRM (see end of this file.)
|
These tools do NOT work with Apple's iBooks FairPlay DRM (see end of this file.)
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ Rocket_ebooks
|
|||||||
Information about the now-obsolete Rocket ebook format and DRM, along with source for a tool to remove the DRM.
|
Information about the now-obsolete Rocket ebook format and DRM, along with source for a tool to remove the DRM.
|
||||||
|
|
||||||
Scuolabook_DRM
|
Scuolabook_DRM
|
||||||
A windows-only application (including source code) for removing DRM from ScuolaBooks PDFs, created by "Hex" and included with permission.
|
A link to the tool for removing DRM from ScuolaBooks PDFs, created by "Hex".
|
||||||
|
|
||||||
|
|
||||||
Windows and Python
|
Windows and Python
|
||||||
|
|||||||
Reference in New Issue
Block a user