2010-10-26 23:18:46 +06:00
|
|
|
#!/usr/bin/env python
|
2012-12-19 19:48:11 +06:00
|
|
|
# -*- coding: utf-8 -*-
|
2010-10-26 23:18:46 +06:00
|
|
|
|
2010-11-12 04:11:36 +06:00
|
|
|
# eReaderPDB2PML_plugin.py
|
2012-12-19 19:48:11 +06:00
|
|
|
# Released under the terms of the GNU General Public Licence, version 3
|
|
|
|
# <http://www.gnu.org/licenses/>
|
2010-10-26 23:18:46 +06:00
|
|
|
#
|
|
|
|
# All credit given to The Dark Reverser for the original standalone script.
|
|
|
|
# I had the much easier job of converting it to Calibre a plugin.
|
|
|
|
#
|
|
|
|
# This plugin is meant to convert secure Ereader files (PDB) to unsecured PMLZ files.
|
|
|
|
# Calibre can then convert it to whatever format you desire.
|
|
|
|
# It is meant to function without having to install any dependencies...
|
2012-12-19 19:48:11 +06:00
|
|
|
# other than having Calibre installed, of course.
|
2010-10-26 23:18:46 +06:00
|
|
|
#
|
|
|
|
# Installation:
|
|
|
|
# Go to Calibre's Preferences page... click on the Plugins button. Use the file
|
|
|
|
# dialog button to select the plugin's zip file (eReaderPDB2PML_vXX_plugin.zip) and
|
|
|
|
# click the 'Add' button. You're done.
|
|
|
|
#
|
|
|
|
# Configuration:
|
|
|
|
# Highlight the plugin (eReader PDB 2 PML) and click the
|
|
|
|
# "Customize Plugin" button on Calibre's Preferences->Plugins page.
|
|
|
|
# Enter your name and the last 8 digits of the credit card number separated by
|
|
|
|
# a comma: Your Name,12341234
|
|
|
|
#
|
|
|
|
# If you've purchased books with more than one credit card, separate the info with
|
|
|
|
# a colon: Your Name,12341234:Other Name,23452345
|
|
|
|
# NOTE: Do NOT put quotes around your name like you do with the original script!!
|
|
|
|
#
|
|
|
|
# Revision history:
|
2010-11-12 04:11:36 +06:00
|
|
|
# 0.0.1 - Initial release
|
|
|
|
# 0.0.2 - updated to distinguish it from earlier non-openssl version
|
2010-12-31 04:41:07 +06:00
|
|
|
# 0.0.3 - removed added psyco code as it is not supported under Calibre's Python 2.7
|
2011-06-16 11:59:20 +06:00
|
|
|
# 0.0.4 - minor typos fixed
|
|
|
|
# 0.0.5 - updated to the new calibre plugin interface
|
2012-11-07 19:14:25 +06:00
|
|
|
# 0.0.6 - unknown changes
|
|
|
|
# 0.0.7 - improved config dialog processing and fix possible output/unicode problem
|
2012-12-19 19:48:11 +06:00
|
|
|
# 0.0.8 - Proper fix for unicode problems, separate out erdr2pml from plugin
|
|
|
|
|
|
|
|
PLUGIN_NAME = u"eReader PDB 2 PML"
|
|
|
|
PLUGIN_VERSION_TUPLE = (0, 0, 8)
|
|
|
|
PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE])
|
2010-10-26 23:18:46 +06:00
|
|
|
|
|
|
|
import sys, os
|
|
|
|
|
|
|
|
from calibre.customize import FileTypePlugin
|
2011-06-16 11:59:20 +06:00
|
|
|
from calibre.ptempfile import PersistentTemporaryDirectory
|
|
|
|
from calibre.constants import iswindows, isosx
|
2010-10-26 23:18:46 +06:00
|
|
|
|
2012-12-19 19:48:11 +06:00
|
|
|
# Wrap a stream so that output gets flushed immediately
|
|
|
|
# and also make sure that any unicode strings get
|
|
|
|
# encoded using "replace" before writing them.
|
|
|
|
class SafeUnbuffered:
|
|
|
|
def __init__(self, stream):
|
|
|
|
self.stream = stream
|
|
|
|
self.encoding = stream.encoding
|
|
|
|
if self.encoding == None:
|
|
|
|
self.encoding = "utf-8"
|
|
|
|
def write(self, data):
|
|
|
|
if isinstance(data,unicode):
|
|
|
|
data = data.encode(self.encoding,"replace")
|
|
|
|
self.stream.write(data)
|
|
|
|
self.stream.flush()
|
|
|
|
def __getattr__(self, attr):
|
|
|
|
return getattr(self.stream, attr)
|
|
|
|
|
|
|
|
|
2010-10-26 23:18:46 +06:00
|
|
|
class eRdrDeDRM(FileTypePlugin):
|
2012-12-19 19:48:11 +06:00
|
|
|
name = PLUGIN_NAME
|
|
|
|
description = u"Removes DRM from secure pdb files. Credit given to The Dark Reverser for the original standalone script."
|
2010-10-26 23:18:46 +06:00
|
|
|
supported_platforms = ['linux', 'osx', 'windows'] # Platforms this plugin will run on
|
2012-12-19 19:48:11 +06:00
|
|
|
author = u"DiapDealer, Apprentice Alf and The Dark Reverser"
|
|
|
|
version = PLUGIN_VERSION_TUPLE
|
2010-10-26 23:18:46 +06:00
|
|
|
file_types = set(['pdb']) # The file types that this plugin will be applied to
|
|
|
|
on_import = True # Run this plugin during the import
|
2011-06-16 11:59:20 +06:00
|
|
|
minimum_calibre_version = (0, 7, 55)
|
2012-12-19 19:48:11 +06:00
|
|
|
priority = 100
|
2010-10-26 23:18:46 +06:00
|
|
|
|
|
|
|
def run(self, path_to_ebook):
|
2012-12-19 19:48:11 +06:00
|
|
|
|
|
|
|
# make sure any unicode output gets converted safely with 'replace'
|
|
|
|
sys.stdout=SafeUnbuffered(sys.stdout)
|
|
|
|
sys.stderr=SafeUnbuffered(sys.stderr)
|
|
|
|
|
|
|
|
print u"{0} v{1}: Trying to decrypt {2}.".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))
|
|
|
|
|
2010-10-26 23:18:46 +06:00
|
|
|
infile = path_to_ebook
|
|
|
|
bookname = os.path.splitext(os.path.basename(infile))[0]
|
|
|
|
outdir = PersistentTemporaryDirectory()
|
|
|
|
pmlzfile = self.temporary_file(bookname + '.pmlz')
|
2012-12-19 19:48:11 +06:00
|
|
|
|
2010-10-26 23:18:46 +06:00
|
|
|
if self.site_customization:
|
2012-12-19 19:48:11 +06:00
|
|
|
from calibre_plugins.erdrpdb2pml import erdr2pml
|
|
|
|
|
2010-10-26 23:18:46 +06:00
|
|
|
keydata = self.site_customization
|
|
|
|
ar = keydata.split(':')
|
|
|
|
for i in ar:
|
|
|
|
try:
|
|
|
|
name, cc = i.split(',')
|
2012-12-19 19:48:11 +06:00
|
|
|
user_key = erdr2pml.getuser_key(name,cc)
|
2010-10-26 23:18:46 +06:00
|
|
|
except ValueError:
|
2012-12-19 19:48:11 +06:00
|
|
|
print u"{0} v{1}: Error parsing user supplied data.".format(PLUGIN_NAME, PLUGIN_VERSION)
|
2010-10-26 23:18:46 +06:00
|
|
|
return path_to_ebook
|
2012-12-19 19:48:11 +06:00
|
|
|
|
2010-10-26 23:18:46 +06:00
|
|
|
try:
|
2012-12-19 19:48:11 +06:00
|
|
|
print u"{0} v{1}: Processing...".format(PLUGIN_NAME, PLUGIN_VERSION)
|
2010-10-26 23:18:46 +06:00
|
|
|
import time
|
|
|
|
start_time = time.time()
|
2012-12-19 19:48:11 +06:00
|
|
|
if erdr2pml.decryptBook(infile,pmlzfile.name,True,user_key) == 0:
|
|
|
|
print u"{0} v{1}: Elapsed time: {2:.2f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-start_time)
|
2010-10-26 23:18:46 +06:00
|
|
|
return pmlzfile.name
|
|
|
|
else:
|
2012-12-19 19:48:11 +06:00
|
|
|
raise ValueError(u"{0} v{1}: Error Creating PML file.".format(PLUGIN_NAME, PLUGIN_VERSION))
|
2010-10-26 23:18:46 +06:00
|
|
|
except ValueError, e:
|
2012-12-19 19:48:11 +06:00
|
|
|
print u"{0} v{1}: Error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION,e.args[0])
|
2010-10-26 23:18:46 +06:00
|
|
|
pass
|
2012-12-19 19:48:11 +06:00
|
|
|
raise Exception(u"{0} v{1}: Couldn\'t decrypt pdb file. See Apprentice Alf's blog for help.".format(PLUGIN_NAME, PLUGIN_VERSION))
|
2010-10-26 23:18:46 +06:00
|
|
|
else:
|
2012-12-19 19:48:11 +06:00
|
|
|
raise Exception(u"{0} v{1}: No name and CC# provided.".format(PLUGIN_NAME, PLUGIN_VERSION))
|
|
|
|
|
|
|
|
|
2010-10-26 23:18:46 +06:00
|
|
|
def customization_help(self, gui=False):
|
2012-12-19 19:48:11 +06:00
|
|
|
return u"Enter Account Name & Last 8 digits of Credit Card number (separate with a comma, multiple pairs with a colon)"
|