From 032fcfa42295dc97e149b78548bb344618abf51c Mon Sep 17 00:00:00 2001 From: Apprentice Alf Date: Tue, 17 Mar 2015 17:49:30 +0000 Subject: [PATCH] Partial update of plugin to use androidkindlekey.py. Still needs more testing/tweaking in the preferences. --- DeDRM_calibre_plugin/DeDRM_plugin.zip | Bin 341636 -> 337869 bytes DeDRM_calibre_plugin/DeDRM_plugin/__init__.py | 4 +- DeDRM_calibre_plugin/DeDRM_plugin/config.py | 56 ++ DeDRM_calibre_plugin/DeDRM_plugin/dialogs.py | 719 ------------------ DeDRM_calibre_plugin/DeDRM_plugin/prefs.py | 3 + 5 files changed, 62 insertions(+), 720 deletions(-) delete mode 100644 DeDRM_calibre_plugin/DeDRM_plugin/dialogs.py diff --git a/DeDRM_calibre_plugin/DeDRM_plugin.zip b/DeDRM_calibre_plugin/DeDRM_plugin.zip index 54af1ae2db87e408b7bad6b288762503a76c90c1..01a60f50a69d97850b7b16c32e171c0aab13cc55 100644 GIT binary patch delta 22921 zcmV(pK=8kW?G(+=6o9k=^M8MdsBlIG`<&-v4FCYLDF6Ty0001CZe((AX=H0@Ze(m_ zYh`&ZaCzk#ZFAc+`1|hmA4GOL+mO0R+QA59TxmDh0c&sF*oV@~DYnv>I<}FVv|+a& z#NXhT@jQ)gD zagtq)*{YoHJ;jlS4<0_4%Y4bE)A_1gNim(WWLf00WH(8MSUTkD?wJ6!2f3VSDc(6Bo!e$%xW|1#({ybj_hD4J*Qyu7`fj%k< z37nEhu%mR2yxgJhxh#K#1ZrB6*J7P0AjcMoDs#CR;~*P`1IE}MJJND8C1k==maUdE zA(^->C67uGGg|V|lK-A(=OTh-p92kkCBoZfY6uO9(2L|&C=x|v3!X)!3&rv|Q@AEn zgn=Is{4oGs0fRDUGr=OBrhJwP;)jb##d#!?qQvD&0s79s94vp&(oIuTq-p;4h^5N|q7!8Vyfx0x{SyR#qJ`oP2SwUB5YJr3IO5ZriHuBxAEQ~$ma zWnPrkBlul0Pf~wT4g8)avwD_GJxQuvaJ7J0>$=PMiJ6GbVNKc9%TqgLpUpgk30F~) z*l9kRO&8*}&t@ZzKa8{Gs}gjkNP~HX2Kb3bq~x<>4f0O%f^nuwDfkkcgOv+jGQcZV zv@*r!=}IloAj_qQ69}smO{OiC0>YACqgA9JR2bh>hEsnev_d+FA~F~SN-Krl)03h| zc_ez^aq}F|Z)8%!1dtI+FjbUtrPw*2i?`WqHJ=M9Vu%*>lUU3l@RKYlr&C{vblx`$ z2oS*h;dp4)H8Jz8SrQ0XR`bKf;Z&Vnx*x(#c$1lx|NYIrzO4VU*LdOJzMdQ8y6A`Hkws&s>2gi`z&PrADr&(PkSJ z!eUGCo@EGBWT`Ou`yPOJdIg%sU9d5i2u?EMa*coDr(9mG{lIda*NmNoKVokcL>Gid znjVb8??id5Q`L_Ubw@zp9fTa}h1erS#uY?c3b`M1@mtNyA!tJe{NEk@S!X51M&T_Y zo>6sVah`dl&4`v7WX_shp1EY+S=FA5$r?MyhkT%~2Q zH`{-duC$omu`+>lnxyxQ7cwZD5aQxv)Z)C0Ddp1Gfpm1@y8%zp?U;qU|wS|9iAm8L#p~Dl*@CzLBMsN-uwK z>LR(MUIvOhMRE7bp;_;V9lNJ z=$a{N_^5GniIs~46JEYbp{WzlEdj}*5S4)S5>`F8%j+4DM5@HNX*8#5qE=K14_gZ{ zLEl}6El9TvcNL5jee_85iU8@^qDy~LnkSm=yJQ2h3XHg!7M5pQmJ_*rP9+O6wqN}+ zrGzw$u;*`1UmtzR-^!hc}h`^S-m|{(zDgzS(B`c6^hEHen zm5MltmCt?^QE6rJJg*C*r(Wce3I$jZ3UcWwYGg{0;o^VgYu=|okSiRp?LB|=C+Rx5 zUN0;1Cd82po7isE_Xfi+J{N<-=*z>w)7kKg!6^Q6FcSv{2lM#J!IRMemgTw=0RzZQ zQJO9UDifpt*c-X6NR$){@X3j8X|Qvd>LHs#v&Vw#LYH?=pK>1Bm&Q+ z%;h$2T&QRkIc)kY%g?mEc5$q@^{r(m6^6`=+( z+`#&1m@rPRpxXQGJ%)yY&x`TX%hp`7Hd9Z>!_Pm)uh_jE>tu&xowOXQPa{8_o;;r( ze|y}w@_n?w=|ik(T=##ECjz=}pt(&9oODERIaj-rf=f8GfK~&y!?;;2c)4&~N(0zD z>|v?q61Lnm27~f}kQ&9*3()-g4|)W)ZRlD#)O1Z8hP5N;^Oqzekb1d#ctT$x_UVOd z_DAe%-MdpKG3mk5de5jy`FdYZJabFDrBd(Dn&@8J?-JO++**I`b9nN-p4Vr?!=U4z z2I^vXI3}#iCIks(VF=)}(RlAm7phj+1<<<$U_z=D7e;BW1g^g}t3|OUL}%8AW@<

goW5te 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 JLdbI@{y!6WppF0l delta 26748 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', self) - help_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard) - help_label.setAlignment(Qt.AlignRight) - help_label.linkActivated.connect(self.help_link_activated) - help_layout.addWidget(help_label) - - keys_group_box = QGroupBox(_(u"{0}s".format(self.key_type_name)), self) - layout.addWidget(keys_group_box) - keys_group_box_layout = QHBoxLayout() - keys_group_box.setLayout(keys_group_box_layout) - - self.listy = QListWidget(self) - self.listy.setToolTip(u"{0}s that will be used to decrypt ebooks".format(self.key_type_name)) - self.listy.setSelectionMode(QAbstractItemView.SingleSelection) - self.populate_list() - keys_group_box_layout.addWidget(self.listy) - - button_layout = QVBoxLayout() - keys_group_box_layout.addLayout(button_layout) - self._add_key_button = QtGui.QToolButton(self) - self._add_key_button.setToolTip(u"Create new {0}".format(self.key_type_name)) - self._add_key_button.setIcon(QIcon(I('plus.png'))) - self._add_key_button.clicked.connect(self.add_key) - button_layout.addWidget(self._add_key_button) - - self._delete_key_button = QtGui.QToolButton(self) - self._delete_key_button.setToolTip(_(u"Delete highlighted key")) - self._delete_key_button.setIcon(QIcon(I('list_remove.png'))) - self._delete_key_button.clicked.connect(self.delete_key) - button_layout.addWidget(self._delete_key_button) - - if type(self.plugin_keys) == dict: - self._rename_key_button = QtGui.QToolButton(self) - self._rename_key_button.setToolTip(_(u"Rename highlighted key")) - self._rename_key_button.setIcon(QIcon(I('edit-select-all.png'))) - self._rename_key_button.clicked.connect(self.rename_key) - button_layout.addWidget(self._rename_key_button) - - self.export_key_button = QtGui.QToolButton(self) - self.export_key_button.setToolTip(u"Save highlighted key to a .{0} file".format(self.keyfile_ext)) - self.export_key_button.setIcon(QIcon(I('save.png'))) - self.export_key_button.clicked.connect(self.export_key) - button_layout.addWidget(self.export_key_button) - spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - button_layout.addItem(spacerItem) - - layout.addSpacing(5) - migrate_layout = QHBoxLayout() - layout.addLayout(migrate_layout) - if self.import_key: - migrate_layout.setAlignment(Qt.AlignJustify) - self.migrate_btn = QPushButton(u"Import Existing Keyfiles", self) - self.migrate_btn.setToolTip(u"Import *.{0} files (created using other tools).".format(self.keyfile_ext)) - self.migrate_btn.clicked.connect(self.migrate_wrapper) - migrate_layout.addWidget(self.migrate_btn) - migrate_layout.addStretch() - self.button_box = QDialogButtonBox(QDialogButtonBox.Close) - self.button_box.rejected.connect(self.close) - migrate_layout.addWidget(self.button_box) - - self.resize(self.sizeHint()) - - def populate_list(self): - if type(self.plugin_keys) == dict: - for key in self.plugin_keys.keys(): - self.listy.addItem(QListWidgetItem(key)) - else: - for key in self.plugin_keys: - self.listy.addItem(QListWidgetItem(key)) - - def add_key(self): - d = self.create_key(self) - d.exec_() - - if d.result() != d.Accepted: - # New key generation cancelled. - return - new_key_value = d.key_value - if type(self.plugin_keys) == dict: - if new_key_value in self.plugin_keys.values(): - old_key_name = [name for name, value in self.plugin_keys.iteritems() if value == new_key_value][0] - info_dialog(None, "{0} {1}: Duplicate {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name), - u"The new {1} is the same as the existing {1} named {0} and has not been added.".format(old_key_name,self.key_type_name), show=True) - return - self.plugin_keys[d.key_name] = new_key_value - else: - if new_key_value in self.plugin_keys: - info_dialog(None, "{0} {1}: Duplicate {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name), - u"This {0} is already in the list of {0}s has not been added.".format(self.key_type_name), show=True) - return - - self.plugin_keys.append(d.key_value) - self.listy.clear() - self.populate_list() - - def rename_key(self): - if not self.listy.currentItem(): - errmsg = u"No {0} selected to rename. Highlight a keyfile first.".format(self.key_type_name) - r = error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), - _(errmsg), show=True, show_copy_button=False) - return - - d = RenameKeyDialog(self) - d.exec_() - - if d.result() != d.Accepted: - # rename cancelled or moot. - return - keyname = unicode(self.listy.currentItem().text().toUtf8(),'utf8') - if not question_dialog(self, "{0} {1}: Confirm Rename".format(PLUGIN_NAME, PLUGIN_VERSION), u"Do you really want to rename the {2} named {0} to {1}?".format(keyname,d.key_name,self.key_type_name), show_copy_button=False, default_yes=False): - return - self.plugin_keys[d.key_name] = self.plugin_keys[keyname] - del self.plugin_keys[keyname] - - self.listy.clear() - self.populate_list() - - def delete_key(self): - if not self.listy.currentItem(): - return - keyname = unicode(self.listy.currentItem().text().toUtf8(), 'utf8') - if not question_dialog(self, "{0} {1}: Confirm Delete".format(PLUGIN_NAME, PLUGIN_VERSION), u"Do you really want to delete the {1} {0}?".format(keyname, self.key_type_name), show_copy_button=False, default_yes=False): - return - if type(self.plugin_keys) == dict: - del self.plugin_keys[keyname] - else: - self.plugin_keys.remove(keyname) - - self.listy.clear() - self.populate_list() - - def help_link_activated(self, url): - def get_help_file_resource(): - # Copy the HTML helpfile to the plugin directory each time the - # link is clicked in case the helpfile is updated in newer plugins. - help_file_name = u"{0}_{1}_Help.htm".format(PLUGIN_NAME, self.key_type_name) - file_path = os.path.join(config_dir, u"plugins", u"DeDRM", u"help", help_file_name) - with open(file_path,'w') as f: - f.write(self.parent.load_resource(help_file_name)) - return file_path - url = 'file:///' + get_help_file_resource() - open_url(QUrl(url)) - - def migrate_files(self): - dynamic[PLUGIN_NAME + u"config_dir"] = config_dir - files = choose_files(self, PLUGIN_NAME + u"config_dir", - u"Select {0} files to import".format(self.key_type_name), [(u"{0} files".format(self.key_type_name), [self.keyfile_ext])], False) - counter = 0 - skipped = 0 - if files: - for filename in files: - fpath = os.path.join(config_dir, filename) - filename = os.path.basename(filename) - new_key_name = os.path.splitext(os.path.basename(filename))[0] - with open(fpath,'rb') as keyfile: - new_key_value = keyfile.read() - if self.binary_file: - new_key_value = new_key_value.encode('hex') - elif self.json_file: - new_key_value = json.loads(new_key_value) - match = False - for key in self.plugin_keys.keys(): - if uStrCmp(new_key_name, key, True): - skipped += 1 - msg = u"A key with the name {0} already exists!\nSkipping key file {1}.\nRename the existing key and import again".format(new_key_name,filename) - inf = info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), - _(msg), show_copy_button=False, show=True) - match = True - break - if not match: - if new_key_value in self.plugin_keys.values(): - old_key_name = [name for name, value in self.plugin_keys.iteritems() if value == new_key_value][0] - skipped += 1 - info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), - u"The key in file {0} is the same as the existing key {1} and has been skipped.".format(filename,old_key_name), show_copy_button=False, show=True) - else: - counter += 1 - self.plugin_keys[new_key_name] = new_key_value - - msg = u"" - if counter+skipped > 1: - if counter > 0: - msg += u"Imported {0:d} key {1}. ".format(counter, u"file" if counter == 1 else u"files") - if skipped > 0: - msg += u"Skipped {0:d} key {1}.".format(skipped, u"file" if counter == 1 else u"files") - inf = info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), - _(msg), show_copy_button=False, show=True) - return counter > 0 - - def migrate_wrapper(self): - if self.migrate_files(): - self.listy.clear() - self.populate_list() - - def export_key(self): - if not self.listy.currentItem(): - errmsg = u"No keyfile selected to export. Highlight a keyfile first." - r = error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), - _(errmsg), show=True, show_copy_button=False) - return - filter = QString(u"{0} Files (*.{1})".format(self.key_type_name, self.keyfile_ext)) - keyname = unicode(self.listy.currentItem().text().toUtf8(), 'utf8') - if dynamic.get(PLUGIN_NAME + 'save_dir'): - defaultname = os.path.join(dynamic.get(PLUGIN_NAME + 'save_dir'), u"{0}.{1}".format(keyname , self.keyfile_ext)) - else: - defaultname = os.path.join(os.path.expanduser('~'), u"{0}.{1}".format(keyname , self.keyfile_ext)) - filename = unicode(QtGui.QFileDialog.getSaveFileName(self, u"Save {0} File as...".format(self.key_type_name), defaultname, - u"{0} Files (*.{1})".format(self.key_type_name,self.keyfile_ext), filter)) - if filename: - dynamic[PLUGIN_NAME + 'save_dir'] = os.path.split(filename)[0] - with file(filename, 'w') as fname: - if self.binary_file: - fname.write(self.plugin_keys[keyname].decode('hex')) - elif self.json_file: - fname.write(json.dumps(self.plugin_keys[keyname])) - else: - fname.write(self.plugin_keys[keyname]) - - - - -class RenameKeyDialog(QDialog): - def __init__(self, parent=None,): - print repr(self), repr(parent) - QDialog.__init__(self, parent) - self.parent = parent - self.setWindowTitle("{0} {1}: Rename {0}".format(PLUGIN_NAME, PLUGIN_VERSION, parent.key_type_name)) - layout = QVBoxLayout(self) - self.setLayout(layout) - - data_group_box = QGroupBox('', self) - layout.addWidget(data_group_box) - data_group_box_layout = QVBoxLayout() - data_group_box.setLayout(data_group_box_layout) - - data_group_box_layout.addWidget(QLabel('New Key Name:', self)) - self.key_ledit = QLineEdit(self.parent.listy.currentItem().text(), self) - self.key_ledit.setToolTip(u"Enter a new name for this existing {0}.".format(parent.key_type_name)) - data_group_box_layout.addWidget(self.key_ledit) - - layout.addSpacing(20) - - self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - self.button_box.accepted.connect(self.accept) - self.button_box.rejected.connect(self.reject) - layout.addWidget(self.button_box) - - self.resize(self.sizeHint()) - - def accept(self): - if self.key_ledit.text().isEmpty() or unicode(self.key_ledit.text()).isspace(): - errmsg = u"Key name field cannot be empty!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), - _(errmsg), show=True, show_copy_button=False) - if len(self.key_ledit.text()) < 4: - errmsg = u"Key name must be at least 4 characters long!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), - _(errmsg), show=True, show_copy_button=False) - if uStrCmp(self.key_ledit.text(), self.parent.listy.currentItem().text()): - # Same exact name ... do nothing. - return QDialog.reject(self) - for k in self.parent.plugin_keys.keys(): - if (uStrCmp(self.key_ledit.text(), k, True) and - not uStrCmp(k, self.parent.listy.currentItem().text(), True)): - errmsg = u"The key name {0} is already being used.".format(self.key_ledit.text()) - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), - _(errmsg), show=True, show_copy_button=False) - QDialog.accept(self) - - @property - def key_name(self): - return unicode(self.key_ledit.text().toUtf8(), 'utf8').strip() - - - - - - - - -class AddBandNKeyDialog(QDialog): - def __init__(self, parent=None,): - QDialog.__init__(self, parent) - self.parent = parent - self.setWindowTitle(u"{0} {1}: Create New Barnes & Noble Key".format(PLUGIN_NAME, PLUGIN_VERSION)) - layout = QVBoxLayout(self) - self.setLayout(layout) - - data_group_box = QGroupBox(u"", self) - layout.addWidget(data_group_box) - data_group_box_layout = QVBoxLayout() - data_group_box.setLayout(data_group_box_layout) - - key_group = QHBoxLayout() - data_group_box_layout.addLayout(key_group) - key_group.addWidget(QLabel(u"Unique Key Name:", self)) - self.key_ledit = QLineEdit("", self) - self.key_ledit.setToolTip(_(u"

Enter an identifying name for this new key.

" + - u"

It should be something that will help you remember " + - u"what personal information was used to create it.")) - key_group.addWidget(self.key_ledit) - key_label = QLabel(_(''), self) - key_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(key_label) - - name_group = QHBoxLayout() - data_group_box_layout.addLayout(name_group) - name_group.addWidget(QLabel(u"Your Name:", self)) - self.name_ledit = QLineEdit(u"", self) - self.name_ledit.setToolTip(_(u"

Enter your name as it appears in your B&N " + - u"account or on your credit card.

" + - u"

It will only be used to generate this " + - u"one-time key and won\'t be stored anywhere " + - u"in calibre or on your computer.

" + - u"

(ex: Jonathan Smith)")) - name_group.addWidget(self.name_ledit) - name_disclaimer_label = QLabel(_(u"(Will not be saved in configuration data)"), self) - name_disclaimer_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(name_disclaimer_label) - - ccn_group = QHBoxLayout() - data_group_box_layout.addLayout(ccn_group) - ccn_group.addWidget(QLabel(u"Credit Card#:", self)) - self.cc_ledit = QLineEdit(u"", self) - self.cc_ledit.setToolTip(_(u"

Enter the full credit card number on record " + - u"in your B&N account.

" + - u"

No spaces or dashes... just the numbers. " + - u"This number will only be used to generate this " + - u"one-time key and won\'t be stored anywhere in " + - u"calibre or on your computer.")) - ccn_group.addWidget(self.cc_ledit) - ccn_disclaimer_label = QLabel(_('(Will not be saved in configuration data)'), self) - ccn_disclaimer_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(ccn_disclaimer_label) - layout.addSpacing(10) - - self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - self.button_box.accepted.connect(self.accept) - self.button_box.rejected.connect(self.reject) - layout.addWidget(self.button_box) - - self.resize(self.sizeHint()) - - @property - def key_name(self): - return unicode(self.key_ledit.text().toUtf8(), 'utf8').strip() - - @property - def key_value(self): - return generate_bandn_key(self.user_name,self.cc_number) - - @property - def user_name(self): - return unicode(self.name_ledit.text().toUtf8(), 'utf8').strip().lower().replace(' ','') - - @property - def cc_number(self): - return unicode(self.cc_ledit.text().toUtf8(), 'utf8').strip().replace(' ', '').replace('-','') - - - def accept(self): - if len(self.key_name) == 0 or len(self.user_name) == 0 or len(self.cc_number) == 0 or self.key_name.isspace() or self.user_name.isspace() or self.cc_number.isspace(): - errmsg = u"All fields are required!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - if not self.cc_number.isdigit(): - errmsg = u"Numbers only in the credit card number field!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - if len(self.key_name) < 4: - errmsg = u"Key name must be at least 4 characters long!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - QDialog.accept(self) - -class AddEReaderDialog(QDialog): - def __init__(self, parent=None,): - QDialog.__init__(self, parent) - self.parent = parent - self.setWindowTitle(u"{0} {1}: Create New eReader Key".format(PLUGIN_NAME, PLUGIN_VERSION)) - layout = QVBoxLayout(self) - self.setLayout(layout) - - data_group_box = QGroupBox(u"", self) - layout.addWidget(data_group_box) - data_group_box_layout = QVBoxLayout() - data_group_box.setLayout(data_group_box_layout) - - key_group = QHBoxLayout() - data_group_box_layout.addLayout(key_group) - key_group.addWidget(QLabel(u"Unique Key Name:", self)) - self.key_ledit = QLineEdit("", self) - self.key_ledit.setToolTip(u"

Enter an identifying name for this new key.\nIt should be something that will help you remember what personal information was used to create it.") - key_group.addWidget(self.key_ledit) - key_label = QLabel(_(''), self) - key_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(key_label) - - name_group = QHBoxLayout() - data_group_box_layout.addLayout(name_group) - name_group.addWidget(QLabel(u"Your Name:", self)) - self.name_ledit = QLineEdit(u"", self) - self.name_ledit.setToolTip(u"Enter the name for this eReader key, usually the name on your credit card.\nIt will only be used to generate this one-time key and won\'t be stored anywhere in calibre or on your computer.\n(ex: Mr Jonathan Q Smith)") - name_group.addWidget(self.name_ledit) - name_disclaimer_label = QLabel(_(u"(Will not be saved in configuration data)"), self) - name_disclaimer_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(name_disclaimer_label) - - ccn_group = QHBoxLayout() - data_group_box_layout.addLayout(ccn_group) - ccn_group.addWidget(QLabel(u"Credit Card#:", self)) - self.cc_ledit = QLineEdit(u"", self) - self.cc_ledit.setToolTip(u"

Enter the last 8 digits of credit card number for this eReader key.\nThey will only be used to generate this one-time key and won\'t be stored anywhere in calibre or on your computer.") - ccn_group.addWidget(self.cc_ledit) - ccn_disclaimer_label = QLabel(_('(Will not be saved in configuration data)'), self) - ccn_disclaimer_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(ccn_disclaimer_label) - layout.addSpacing(10) - - self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - self.button_box.accepted.connect(self.accept) - self.button_box.rejected.connect(self.reject) - layout.addWidget(self.button_box) - - self.resize(self.sizeHint()) - - @property - def key_name(self): - return unicode(self.key_ledit.text().toUtf8(), 'utf8').strip() - - @property - def key_value(self): - return generate_ereader_key(self.user_name,self.cc_number).encode('hex') - - @property - def user_name(self): - return unicode(self.name_ledit.text().toUtf8(), 'utf8').strip().lower().replace(' ','') - - @property - def cc_number(self): - return unicode(self.cc_ledit.text().toUtf8(), 'utf8').strip().replace(' ', '').replace('-','') - - - def accept(self): - if len(self.key_name) == 0 or len(self.user_name) == 0 or len(self.cc_number) == 0 or self.key_name.isspace() or self.user_name.isspace() or self.cc_number.isspace(): - errmsg = u"All fields are required!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - if not self.cc_number.isdigit(): - errmsg = u"Numbers only in the credit card number field!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - if len(self.key_name) < 4: - errmsg = u"Key name must be at least 4 characters long!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - QDialog.accept(self) - - -class AddAdeptDialog(QDialog): - def __init__(self, parent=None,): - QDialog.__init__(self, parent) - self.parent = parent - self.setWindowTitle(u"{0} {1}: Getting Default Adobe Digital Editions Key".format(PLUGIN_NAME, PLUGIN_VERSION)) - layout = QVBoxLayout(self) - self.setLayout(layout) - - try: - self.default_key = retrieve_adept_keys()[0] - except: - self.default_key = u"" - - self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - - if len(self.default_key)>0: - data_group_box = QGroupBox(u"", self) - layout.addWidget(data_group_box) - data_group_box_layout = QVBoxLayout() - data_group_box.setLayout(data_group_box_layout) - - key_group = QHBoxLayout() - data_group_box_layout.addLayout(key_group) - key_group.addWidget(QLabel(u"Unique Key Name:", self)) - self.key_ledit = QLineEdit("", self) - self.key_ledit.setToolTip(u"

Enter an identifying name for the current default Adobe Digital Editions key.") - key_group.addWidget(self.key_ledit) - key_label = QLabel(_(''), self) - key_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(key_label) - self.button_box.accepted.connect(self.accept) - else: - default_key_error = QLabel(u"The default encryption key for Adobe Digital Editions could not be found.", self) - default_key_error.setAlignment(Qt.AlignHCenter) - layout.addWidget(default_key_error) - # if no default, bot buttons do the same - self.button_box.accepted.connect(self.reject) - - self.button_box.rejected.connect(self.reject) - layout.addWidget(self.button_box) - - self.resize(self.sizeHint()) - - @property - def key_name(self): - return unicode(self.key_ledit.text().toUtf8(), 'utf8').strip() - - @property - def key_value(self): - return self.default_key.encode('hex') - - - def accept(self): - if len(self.key_name) == 0 or self.key_name.isspace(): - errmsg = u"All fields are required!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - if len(self.key_name) < 4: - errmsg = u"Key name must be at least 4 characters long!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - QDialog.accept(self) - - -class AddKindleDialog(QDialog): - def __init__(self, parent=None,): - QDialog.__init__(self, parent) - self.parent = parent - self.setWindowTitle(u"{0} {1}: Getting Default Kindle for Mac/PC Key".format(PLUGIN_NAME, PLUGIN_VERSION)) - layout = QVBoxLayout(self) - self.setLayout(layout) - - try: - self.default_key = retrieve_kindle_keys()[0] - except: - self.default_key = u"" - - self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - - if len(self.default_key)>0: - data_group_box = QGroupBox(u"", self) - layout.addWidget(data_group_box) - data_group_box_layout = QVBoxLayout() - data_group_box.setLayout(data_group_box_layout) - - key_group = QHBoxLayout() - data_group_box_layout.addLayout(key_group) - key_group.addWidget(QLabel(u"Unique Key Name:", self)) - self.key_ledit = QLineEdit("", self) - self.key_ledit.setToolTip(u"

Enter an identifying name for the current default Kindle for Mac/PC key.") - key_group.addWidget(self.key_ledit) - key_label = QLabel(_(''), self) - key_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(key_label) - self.button_box.accepted.connect(self.accept) - else: - default_key_error = QLabel(u"The default encryption key for Kindle for Mac/PC could not be found.", self) - default_key_error.setAlignment(Qt.AlignHCenter) - layout.addWidget(default_key_error) - # if no default, bot buttons do the same - self.button_box.accepted.connect(self.reject) - - self.button_box.rejected.connect(self.reject) - layout.addWidget(self.button_box) - - self.resize(self.sizeHint()) - - @property - def key_name(self): - return unicode(self.key_ledit.text().toUtf8(), 'utf8').strip() - - @property - def key_value(self): - return self.default_key - - - def accept(self): - if len(self.key_name) == 0 or self.key_name.isspace(): - errmsg = u"All fields are required!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - if len(self.key_name) < 4: - errmsg = u"Key name must be at least 4 characters long!" - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - QDialog.accept(self) - - -class AddSerialDialog(QDialog): - def __init__(self, parent=None,): - QDialog.__init__(self, parent) - self.parent = parent - self.setWindowTitle(u"{0} {1}: Add New EInk Kindle Serial Number".format(PLUGIN_NAME, PLUGIN_VERSION)) - layout = QVBoxLayout(self) - self.setLayout(layout) - - data_group_box = QGroupBox(u"", self) - layout.addWidget(data_group_box) - data_group_box_layout = QVBoxLayout() - data_group_box.setLayout(data_group_box_layout) - - key_group = QHBoxLayout() - data_group_box_layout.addLayout(key_group) - key_group.addWidget(QLabel(u"EInk Kindle Serial Number:", self)) - self.key_ledit = QLineEdit("", self) - self.key_ledit.setToolTip(u"Enter an eInk Kindle serial number. EInk Kindle serial numbers are 16 characters long and usually start with a 'B' or a '9'. Kindle Serial Numbers are case-sensitive, so be sure to enter the upper and lower case letters unchanged.") - key_group.addWidget(self.key_ledit) - key_label = QLabel(_(''), self) - key_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(key_label) - - self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - self.button_box.accepted.connect(self.accept) - self.button_box.rejected.connect(self.reject) - layout.addWidget(self.button_box) - - self.resize(self.sizeHint()) - - @property - def key_name(self): - return unicode(self.key_ledit.text().toUtf8(), 'utf8').strip() - - @property - def key_value(self): - return unicode(self.key_ledit.text().toUtf8(), 'utf8').strip() - - def accept(self): - if len(self.key_name) == 0 or self.key_name.isspace(): - errmsg = u"Please enter an eInk Kindle Serial Number or click Cancel in the dialog." - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - if len(self.key_name) != 16: - errmsg = u"EInk Kindle Serial Numbers must be 16 characters long. This is {0:d} characters long.".format(len(self.key_name)) - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - QDialog.accept(self) - - -class AddPIDDialog(QDialog): - def __init__(self, parent=None,): - QDialog.__init__(self, parent) - self.parent = parent - self.setWindowTitle(u"{0} {1}: Add New Mobipocket PID".format(PLUGIN_NAME, PLUGIN_VERSION)) - layout = QVBoxLayout(self) - self.setLayout(layout) - - data_group_box = QGroupBox(u"", self) - layout.addWidget(data_group_box) - data_group_box_layout = QVBoxLayout() - data_group_box.setLayout(data_group_box_layout) - - key_group = QHBoxLayout() - data_group_box_layout.addLayout(key_group) - key_group.addWidget(QLabel(u"PID:", self)) - self.key_ledit = QLineEdit("", self) - self.key_ledit.setToolTip(u"Enter a Mobipocket PID. Mobipocket PIDs are 8 or 10 characters long. Mobipocket PIDs are case-sensitive, so be sure to enter the upper and lower case letters unchanged.") - key_group.addWidget(self.key_ledit) - key_label = QLabel(_(''), self) - key_label.setAlignment(Qt.AlignHCenter) - data_group_box_layout.addWidget(key_label) - - self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - self.button_box.accepted.connect(self.accept) - self.button_box.rejected.connect(self.reject) - layout.addWidget(self.button_box) - - self.resize(self.sizeHint()) - - @property - def key_name(self): - return unicode(self.key_ledit.text().toUtf8(), 'utf8').strip() - - @property - def key_value(self): - return unicode(self.key_ledit.text().toUtf8(), 'utf8').strip() - - def accept(self): - if len(self.key_name) == 0 or self.key_name.isspace(): - errmsg = u"Please enter a Mobipocket PID or click Cancel in the dialog." - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - if len(self.key_name) != 8 and len(self.key_name) != 10: - errmsg = u"Mobipocket PIDs must be 8 or 10 characters long. This is {0:d} characters long.".format(len(self.key_name)) - return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False) - QDialog.accept(self) - - diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/prefs.py b/DeDRM_calibre_plugin/DeDRM_plugin/prefs.py index 05065ac..f0f494c 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/prefs.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/prefs.py @@ -25,6 +25,7 @@ class DeDRM_Prefs(): self.dedrmprefs.defaults['kindlekeys'] = {} self.dedrmprefs.defaults['pids'] = [] self.dedrmprefs.defaults['serials'] = [] + self.dedrmprefs.defaults['androidserials'] = [] self.dedrmprefs.defaults['adobewineprefix'] = "" self.dedrmprefs.defaults['kindlewineprefix'] = "" @@ -44,6 +45,8 @@ class DeDRM_Prefs(): self.dedrmprefs['pids'] = [] if self.dedrmprefs['serials'] == []: self.dedrmprefs['serials'] = [] + if self.dedrmprefs['androidserials'] == []: + self.dedrmprefs['androidserials'] = [] def __getitem__(self,kind = None): if kind is not None: