#!/usr/bin/env python # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai from __future__ import with_statement __license__ = 'GPL v3' # Standard Python modules. import os, sys, re, hashlib import json import traceback from calibre.utils.config import dynamic, config_dir, JSONConfig from calibre_plugins.dedrm.__init__ import PLUGIN_NAME, PLUGIN_VERSION from calibre.constants import iswindows, isosx class DeDRM_Prefs(): def __init__(self): JSON_PATH = os.path.join(u"plugins", PLUGIN_NAME.strip().lower().replace(' ', '_') + '.json') self.dedrmprefs = JSONConfig(JSON_PATH) self.dedrmprefs.defaults['configured'] = False self.dedrmprefs.defaults['bandnkeys'] = {} self.dedrmprefs.defaults['adeptkeys'] = {} self.dedrmprefs.defaults['ereaderkeys'] = {} self.dedrmprefs.defaults['kindlekeys'] = {} self.dedrmprefs.defaults['androidkeys'] = {} self.dedrmprefs.defaults['pids'] = [] self.dedrmprefs.defaults['serials'] = [] self.dedrmprefs.defaults['adobewineprefix'] = "" self.dedrmprefs.defaults['kindlewineprefix'] = "" # initialise # we must actually set the prefs that are dictionaries and lists # to empty dictionaries and lists, otherwise we are unable to add to them # as then it just adds to the (memory only) dedrmprefs.defaults versions! if self.dedrmprefs['bandnkeys'] == {}: self.dedrmprefs['bandnkeys'] = {} if self.dedrmprefs['adeptkeys'] == {}: self.dedrmprefs['adeptkeys'] = {} if self.dedrmprefs['ereaderkeys'] == {}: self.dedrmprefs['ereaderkeys'] = {} if self.dedrmprefs['kindlekeys'] == {}: self.dedrmprefs['kindlekeys'] = {} if self.dedrmprefs['androidkeys'] == {}: self.dedrmprefs['androidkeys'] = {} if self.dedrmprefs['pids'] == []: self.dedrmprefs['pids'] = [] if self.dedrmprefs['serials'] == []: self.dedrmprefs['serials'] = [] def __getitem__(self,kind = None): if kind is not None: return self.dedrmprefs[kind] return self.dedrmprefs def set(self, kind, value): self.dedrmprefs[kind] = value def writeprefs(self,value = True): self.dedrmprefs['configured'] = value def addnamedvaluetoprefs(self, prefkind, keyname, keyvalue): try: if keyvalue not in self.dedrmprefs[prefkind].values(): # ensure that the keyname is unique # by adding a number (starting with 2) to the name if it is not namecount = 1 newname = keyname while newname in self.dedrmprefs[prefkind]: namecount += 1 newname = "{0:s}_{1:d}".format(keyname,namecount) # add to the preferences self.dedrmprefs[prefkind][newname] = keyvalue return (True, newname) except: traceback.print_exc() pass return (False, keyname) def addvaluetoprefs(self, prefkind, prefsvalue): # ensure the keyvalue isn't already in the preferences try: if prefsvalue not in self.dedrmprefs[prefkind]: self.dedrmprefs[prefkind].append(prefsvalue) return True except: traceback.print_exc() return False def convertprefs(always = False): def parseIgnobleString(keystuff): from calibre_plugins.dedrm.ignoblekeygen import generate_key userkeys = [] ar = keystuff.split(':') for keystring in ar: try: name, ccn = keystring.split(',') # Generate Barnes & Noble EPUB user key from name and credit card number. keyname = u"{0}_{1}".format(name.strip(),ccn.strip()[-4:]) keyvalue = generate_key(name, ccn) userkeys.append([keyname,keyvalue]) except Exception, e: traceback.print_exc() print e.args[0] pass return userkeys def parseeReaderString(keystuff): from calibre_plugins.dedrm.erdr2pml import getuser_key userkeys = [] ar = keystuff.split(':') for keystring in ar: try: name, cc = keystring.split(',') # Generate eReader user key from name and credit card number. keyname = u"{0}_{1}".format(name.strip(),cc.strip()[-4:]) keyvalue = getuser_key(name,cc).encode('hex') userkeys.append([keyname,keyvalue]) except Exception, e: traceback.print_exc() print e.args[0] pass return userkeys def parseKindleString(keystuff): pids = [] serials = [] ar = keystuff.split(',') for keystring in ar: keystring = str(keystring).strip().replace(" ","") if len(keystring) == 10 or len(keystring) == 8 and keystring not in pids: pids.append(keystring) elif len(keystring) == 16 and keystring[0] == 'B' and keystring not in serials: serials.append(keystring) return (pids,serials) def getConfigFiles(extension, encoding = None): # get any files with extension 'extension' in the config dir userkeys = [] files = [f for f in os.listdir(config_dir) if f.endswith(extension)] for filename in files: try: fpath = os.path.join(config_dir, filename) key = os.path.splitext(filename)[0] value = open(fpath, 'rb').read() if encoding is not None: value = value.encode(encoding) userkeys.append([key,value]) except: traceback.print_exc() pass return userkeys dedrmprefs = DeDRM_Prefs() if (not always) and dedrmprefs['configured']: # We've already converted old preferences, # and we're not being forced to do it again, so just return return print u"{0} v{1}: Importing configuration data from old DeDRM plugins".format(PLUGIN_NAME, PLUGIN_VERSION) IGNOBLEPLUGINNAME = "Ignoble Epub DeDRM" EREADERPLUGINNAME = "eReader PDB 2 PML" OLDKINDLEPLUGINNAME = "K4PC, K4Mac, Kindle Mobi and Topaz DeDRM" # get prefs from older tools kindleprefs = JSONConfig(os.path.join(u"plugins", u"K4MobiDeDRM")) ignobleprefs = JSONConfig(os.path.join(u"plugins", u"ignoble_epub_dedrm")) # Handle the old ignoble plugin's customization string by converting the # old string to stored keys... get that personal data out of plain sight. from calibre.customize.ui import config sc = config['plugin_customization'] val = sc.pop(IGNOBLEPLUGINNAME, None) if val is not None: print u"{0} v{1}: Converting old Ignoble plugin configuration string.".format(PLUGIN_NAME, PLUGIN_VERSION) priorkeycount = len(dedrmprefs['bandnkeys']) userkeys = parseIgnobleString(str(val)) for keypair in userkeys: name = keypair[0] value = keypair[1] dedrmprefs.addnamedvaluetoprefs('bandnkeys', name, value) addedkeycount = len(dedrmprefs['bandnkeys'])-priorkeycount print u"{0} v{1}: {2:d} Barnes and Noble {3} imported from old Ignoble plugin configuration string".format(PLUGIN_NAME, PLUGIN_VERSION, addedkeycount, u"key" if addedkeycount==1 else u"keys") # Make the json write all the prefs to disk dedrmprefs.writeprefs(False) # Handle the old eReader plugin's customization string by converting the # old string to stored keys... get that personal data out of plain sight. val = sc.pop(EREADERPLUGINNAME, None) if val is not None: print u"{0} v{1}: Converting old eReader plugin configuration string.".format(PLUGIN_NAME, PLUGIN_VERSION) priorkeycount = len(dedrmprefs['ereaderkeys']) userkeys = parseeReaderString(str(val)) for keypair in userkeys: name = keypair[0] value = keypair[1] dedrmprefs.addnamedvaluetoprefs('ereaderkeys', name, value) addedkeycount = len(dedrmprefs['ereaderkeys'])-priorkeycount print u"{0} v{1}: {2:d} eReader {3} imported from old eReader plugin configuration string".format(PLUGIN_NAME, PLUGIN_VERSION, addedkeycount, u"key" if addedkeycount==1 else u"keys") # Make the json write all the prefs to disk dedrmprefs.writeprefs(False) # get old Kindle plugin configuration string val = sc.pop(OLDKINDLEPLUGINNAME, None) if val is not None: print u"{0} v{1}: Converting old Kindle plugin configuration string.".format(PLUGIN_NAME, PLUGIN_VERSION) priorpidcount = len(dedrmprefs['pids']) priorserialcount = len(dedrmprefs['serials']) pids, serials = parseKindleString(val) for pid in pids: dedrmprefs.addvaluetoprefs('pids',pid) for serial in serials: dedrmprefs.addvaluetoprefs('serials',serial) addedpidcount = len(dedrmprefs['pids']) - priorpidcount addedserialcount = len(dedrmprefs['serials']) - priorserialcount print u"{0} v{1}: {2:d} {3} and {4:d} {5} imported from old Kindle plugin configuration string.".format(PLUGIN_NAME, PLUGIN_VERSION, addedpidcount, u"PID" if addedpidcount==1 else u"PIDs", addedserialcount, u"serial number" if addedserialcount==1 else u"serial numbers") # Make the json write all the prefs to disk dedrmprefs.writeprefs(False) # copy the customisations back into calibre preferences, as we've now removed the nasty plaintext config['plugin_customization'] = sc # get any .b64 files in the config dir priorkeycount = len(dedrmprefs['bandnkeys']) bandnfilekeys = getConfigFiles('.b64') for keypair in bandnfilekeys: name = keypair[0] value = keypair[1] dedrmprefs.addnamedvaluetoprefs('bandnkeys', name, value) addedkeycount = len(dedrmprefs['bandnkeys'])-priorkeycount if addedkeycount > 0: print u"{0} v{1}: {2:d} Barnes and Noble {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, addedkeycount, u"key file" if addedkeycount==1 else u"key files") # Make the json write all the prefs to disk dedrmprefs.writeprefs(False) # get any .der files in the config dir priorkeycount = len(dedrmprefs['adeptkeys']) adeptfilekeys = getConfigFiles('.der','hex') for keypair in adeptfilekeys: name = keypair[0] value = keypair[1] dedrmprefs.addnamedvaluetoprefs('adeptkeys', name, value) addedkeycount = len(dedrmprefs['adeptkeys'])-priorkeycount if addedkeycount > 0: print u"{0} v{1}: {2:d} Adobe Adept {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, addedkeycount, u"keyfile" if addedkeycount==1 else u"keyfiles") # Make the json write all the prefs to disk dedrmprefs.writeprefs(False) # get ignoble json prefs if 'keys' in ignobleprefs: priorkeycount = len(dedrmprefs['bandnkeys']) for name in ignobleprefs['keys']: value = ignobleprefs['keys'][name] dedrmprefs.addnamedvaluetoprefs('bandnkeys', name, value) addedkeycount = len(dedrmprefs['bandnkeys']) - priorkeycount # no need to delete old prefs, since they contain no recoverable private data if addedkeycount > 0: print u"{0} v{1}: {2:d} Barnes and Noble {3} imported from Ignoble plugin preferences.".format(PLUGIN_NAME, PLUGIN_VERSION, addedkeycount, u"key" if addedkeycount==1 else u"keys") # Make the json write all the prefs to disk dedrmprefs.writeprefs(False) # get kindle json prefs priorpidcount = len(dedrmprefs['pids']) priorserialcount = len(dedrmprefs['serials']) if 'pids' in kindleprefs: pids, serials = parseKindleString(kindleprefs['pids']) for pid in pids: dedrmprefs.addvaluetoprefs('pids',pid) if 'serials' in kindleprefs: pids, serials = parseKindleString(kindleprefs['serials']) for serial in serials: dedrmprefs.addvaluetoprefs('serials',serial) addedpidcount = len(dedrmprefs['pids']) - priorpidcount if addedpidcount > 0: print u"{0} v{1}: {2:d} {3} imported from Kindle plugin preferences".format(PLUGIN_NAME, PLUGIN_VERSION, addedpidcount, u"PID" if addedpidcount==1 else u"PIDs") addedserialcount = len(dedrmprefs['serials']) - priorserialcount if addedserialcount > 0: print u"{0} v{1}: {2:d} {3} imported from Kindle plugin preferences".format(PLUGIN_NAME, PLUGIN_VERSION, addedserialcount, u"serial number" if addedserialcount==1 else u"serial numbers") try: if 'wineprefix' in kindleprefs and kindleprefs['wineprefix'] != "": dedrmprefs.set('adobewineprefix',kindleprefs['wineprefix']) dedrmprefs.set('kindlewineprefix',kindleprefs['wineprefix']) print u"{0} v{1}: WINEPREFIX ‘(2)’ imported from Kindle plugin preferences".format(PLUGIN_NAME, PLUGIN_VERSION, kindleprefs['wineprefix']) except: traceback.print_exc() # Make the json write all the prefs to disk dedrmprefs.writeprefs() print u"{0} v{1}: Finished setting up configuration data.".format(PLUGIN_NAME, PLUGIN_VERSION)