acsm-calibre-plugin/calibre-plugin/config.py

299 lines
12 KiB
Python
Raw Normal View History

2021-09-19 16:20:56 +02:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# pyright: reportUndefinedVariable=false
import os, base64, traceback
2021-09-20 15:05:07 +02:00
from lxml import etree
2021-09-19 16:20:56 +02:00
from PyQt5.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
2021-09-20 15:05:07 +02:00
QGroupBox, QPushButton, QListWidget, QListWidgetItem, QInputDialog,
QLineEdit, QAbstractItemView, QIcon, QDialog, QDialogButtonBox, QUrl)
2021-09-19 16:20:56 +02:00
from PyQt5 import Qt as QtGui
from zipfile import ZipFile
# calibre modules and constants.
from calibre.gui2 import (question_dialog, error_dialog, info_dialog, choose_save_file, choose_files) # type: ignore
2021-09-19 16:20:56 +02:00
# modules from this plugin's zipfile.
from calibre_plugins.deacsm.__init__ import PLUGIN_NAME, PLUGIN_VERSION # type: ignore
import calibre_plugins.deacsm.prefs as prefs # type: ignore
2021-09-20 11:24:11 +02:00
from calibre.utils.config import config_dir # type: ignore
2021-09-19 16:20:56 +02:00
class ConfigWidget(QWidget):
def __init__(self, plugin_path):
QWidget.__init__(self)
self.plugin_path = plugin_path
# get the prefs
self.deacsmprefs = prefs.DeACSM_Prefs()
# make a local copy
self.tempdeacsmprefs = {}
self.tempdeacsmprefs['path_to_account_data'] = self.deacsmprefs['path_to_account_data']
# Start Qt Gui dialog layout
layout = QVBoxLayout(self)
self.setLayout(layout)
2021-09-20 15:05:07 +02:00
ua_group_box = QGroupBox(_('Account information:'), self)
2021-09-19 16:20:56 +02:00
layout.addWidget(ua_group_box)
ua_group_box_layout = QVBoxLayout()
ua_group_box.setLayout(ua_group_box_layout)
info_string, activated, mail = self.get_account_info()
2021-09-20 15:05:07 +02:00
self.lblAccInfo = QtGui.QLabel(self)
self.lblAccInfo.setText(info_string)
ua_group_box_layout.addWidget(self.lblAccInfo)
if not activated:
self.button_link_account = QtGui.QPushButton(self)
self.button_link_account.setText(_("Link to ADE account"))
self.button_link_account.clicked.connect(self.link_account)
ua_group_box_layout.addWidget(self.button_link_account)
2021-09-19 16:20:56 +02:00
self.button_import_activation = QtGui.QPushButton(self)
self.button_import_activation.setText(_("Import existing activation data (ZIP)"))
self.button_import_activation.clicked.connect(self.import_activation)
ua_group_box_layout.addWidget(self.button_import_activation)
2021-09-20 11:24:11 +02:00
self.button_export_key = QtGui.QPushButton(self)
2021-09-20 15:05:07 +02:00
self.button_export_key.setText(_("Export account encryption key"))
2021-09-20 11:24:11 +02:00
self.button_export_key.clicked.connect(self.export_key)
2021-09-20 15:05:07 +02:00
self.button_export_key.setEnabled(activated)
2021-09-20 11:24:11 +02:00
ua_group_box_layout.addWidget(self.button_export_key)
2021-09-20 15:05:07 +02:00
self.button_export_activation = QtGui.QPushButton(self)
self.button_export_activation.setText(_("Export account activation data"))
self.button_export_activation.clicked.connect(self.export_activation)
self.button_export_activation.setEnabled(activated)
ua_group_box_layout.addWidget(self.button_export_activation)
2021-09-25 16:24:03 +02:00
try:
from calibre_plugins.deacsm.libadobe import VAR_HOBBES_VERSION, createDeviceKeyFile, update_account_path
from calibre_plugins.deacsm.libadobeAccount import createDeviceFile, createUser, signIn, activateDevice
except:
try:
from libadobe import VAR_HOBBES_VERSION, createDeviceKeyFile, update_account_path
from libadobeAccount import createDeviceFile, createUser, signIn, activateDevice
except:
print("{0} v{1}: Error while importing Account stuff".format(PLUGIN_NAME, PLUGIN_VERSION))
traceback.print_exc()
2021-09-25 16:24:03 +02:00
update_account_path(self.deacsmprefs["path_to_account_data"])
2021-09-19 16:20:56 +02:00
self.resize(self.sizeHint())
2021-09-20 15:05:07 +02:00
def get_account_info(self):
activation_xml_path = os.path.join(self.deacsmprefs["path_to_account_data"], "activation.xml")
device_xml_path = os.path.join(self.deacsmprefs["path_to_account_data"], "device.xml")
container = None
try:
container = etree.parse(activation_xml_path)
containerdev = etree.parse(device_xml_path)
except (FileNotFoundError, OSError) as e:
return "Not authorized for any ADE ID", False, None
2021-09-20 15:05:07 +02:00
try:
adeptNS = lambda tag: '{%s}%s' % ('http://ns.adobe.com/adept', tag)
usernameXML = container.find(adeptNS("credentials")).find(adeptNS("username"))
devicenameXML = containerdev.find(adeptNS("deviceName"))
ade_type = usernameXML.get('method', "unknown")
ade_mail = usernameXML.text
ade_device_name = devicenameXML.text
2021-09-25 16:24:03 +02:00
if container.find(adeptNS("activationToken")) == None:
return "ADE authorization seems to be corrupted (activationToken missing)", False, None
2021-09-25 16:24:03 +02:00
if container.find(adeptNS("credentials")).find(adeptNS("pkcs12")) == None:
return "ADE authorization seems to be corrupted (pkcs12 missing)", False, None
2021-09-25 16:24:03 +02:00
return "Authorized with ADE ID ("+ade_type+") " + ade_mail + "\non device " + ade_device_name, True, ade_mail
2021-09-20 15:05:07 +02:00
except:
return "ADE authorization seems to be corrupted", False, None
2021-09-20 15:05:07 +02:00
def export_activation(self):
filters = [("ZIP", ["zip"])]
filename = choose_save_file(self, "Export ADE activation files", _("Export ADE activation files"),
filters, all_files=False, initial_filename="adobe_account_backup.zip")
2021-09-20 15:05:07 +02:00
2021-09-20 15:18:12 +02:00
if (filename is None):
return
print("{0} v{1}: Exporting activation data to {2}".format(PLUGIN_NAME, PLUGIN_VERSION, filename))
2021-09-20 15:05:07 +02:00
try:
with ZipFile(filename, 'w') as zipfile:
zipfile.write(os.path.join(self.deacsmprefs["path_to_account_data"], "device.xml"), "device.xml")
zipfile.write(os.path.join(self.deacsmprefs["path_to_account_data"], "activation.xml"), "activation.xml")
zipfile.write(os.path.join(self.deacsmprefs["path_to_account_data"], "devicesalt"), "devicesalt")
except:
return error_dialog(None, "Export failed", "Export failed.", show=True, show_copy_button=False)
def import_activation(self):
filters = [("ZIP", ["zip"])]
filenames = choose_files(self, "Import ADE activation file (ZIP)", _("Import ADE activation file (ZIP)"),
filters, all_files=False, select_only_single_file=True)
try:
filename = filenames[0]
if (filename is None):
return
except:
return
print("{0} v{1}: Importing activation data from {2}".format(PLUGIN_NAME, PLUGIN_VERSION, filename))
with ZipFile(filename, 'r') as zipfile:
try:
device = zipfile.read("device.xml")
activation = zipfile.read("activation.xml")
salt = zipfile.read("devicesalt")
except:
return error_dialog(None, "Import failed", "Can't find required files in this ZIP")
try:
output_device = open(os.path.join(self.deacsmprefs["path_to_account_data"], "device.xml"), "w")
output_device.write(device.decode("utf-8"))
output_device.close()
output_activation = open(os.path.join(self.deacsmprefs["path_to_account_data"], "activation.xml"), "w")
output_activation.write(activation.decode("utf-8"))
output_activation.close()
output_salt = open(os.path.join(self.deacsmprefs["path_to_account_data"], "devicesalt"), "wb")
output_salt.write(salt)
output_salt.close()
except:
err = traceback.format_exc()
return error_dialog(None, "Import failed", "Can't write file", show=True, det_msg=err, show_copy_button=False)
# update display
info_string, activated, ade_mail = self.get_account_info()
self.lblAccInfo.setText(info_string)
self.button_link_account.setEnabled(not activated)
self.button_import_activation.setEnabled(not activated)
self.button_export_key.setEnabled(activated)
self.button_export_activation.setEnabled(activated)
info_dialog(None, "Done", "Successfully imported authorization for " + ade_mail, show=True, show_copy_button=False)
2021-09-20 15:05:07 +02:00
def link_account(self):
2021-09-25 16:24:03 +02:00
try:
from calibre_plugins.deacsm.libadobe import VAR_HOBBES_VERSION, createDeviceKeyFile, update_account_path
from calibre_plugins.deacsm.libadobeAccount import createDeviceFile, createUser, signIn, activateDevice
except:
2021-09-20 15:05:07 +02:00
try:
2021-09-25 16:24:03 +02:00
from libadobe import VAR_HOBBES_VERSION, createDeviceKeyFile, update_account_path
from libadobeAccount import createDeviceFile, createUser, signIn, activateDevice
2021-09-20 15:05:07 +02:00
except:
print("{0} v{1}: Error while importing Account stuff".format(PLUGIN_NAME, PLUGIN_VERSION))
traceback.print_exc()
2021-09-20 15:05:07 +02:00
2021-09-25 16:24:03 +02:00
update_account_path(self.deacsmprefs["path_to_account_data"])
mail, ok = QInputDialog.getText(self, "Authorizing ADE account", "Please enter mail address")
2021-09-20 15:05:07 +02:00
2021-09-25 16:24:03 +02:00
if (not ok or mail is None or len(mail) == 0):
return
2021-09-20 15:05:07 +02:00
2021-09-25 16:24:03 +02:00
passwd, ok = QInputDialog.getText(self, "Authorizing ADE account", "Please enter password", QLineEdit.Password)
2021-09-20 15:05:07 +02:00
2021-09-25 16:24:03 +02:00
if (not ok or passwd is None or len(passwd) == 0):
return
createDeviceKeyFile()
createDeviceFile(VAR_HOBBES_VERSION, False)
success, resp = createUser()
if (success is False):
return error_dialog(None, "ADE activation failed", "Couldn't create user", det_msg=str(resp), show=True, show_copy_button=True)
2021-09-20 15:05:07 +02:00
2021-09-25 16:24:03 +02:00
success, resp = signIn(mail, passwd)
if (success is False):
return error_dialog(None, "ADE activation failed", "Login unsuccessful", det_msg=str(resp), show=True, show_copy_button=True)
2021-09-20 15:05:07 +02:00
2021-09-25 16:24:03 +02:00
success, resp = activateDevice()
if (success is False):
return error_dialog(None, "ADE activation failed", "Couldn't activate device", det_msg=str(resp), show=True, show_copy_button=True)
2021-09-20 15:05:07 +02:00
2021-09-25 16:24:03 +02:00
print("Authorized to account " + mail)
2021-09-20 15:05:07 +02:00
# update display
info_string, activated, mail = self.get_account_info()
2021-09-20 15:05:07 +02:00
self.lblAccInfo.setText(info_string)
self.button_link_account.setEnabled(False)
self.button_import_activation.setEnabled(False)
2021-09-20 15:05:07 +02:00
self.button_export_key.setEnabled(True)
self.button_export_activation.setEnabled(True)
2021-09-25 16:24:03 +02:00
info_dialog(None, "Done", "Authorized to account " + mail, show=True, show_copy_button=False)
2021-09-20 15:05:07 +02:00
2021-09-20 11:24:11 +02:00
def export_key(self):
try:
from calibre_plugins.deacsm.libadobe import update_account_path
from calibre_plugins.deacsm.libadobeAccount import exportAccountEncryptionKeyDER
except:
try:
from libadobe import update_account_path
from libadobeAccount import exportAccountEncryptionKeyDER
except:
print("{0} v{1}: Error while importing Account stuff".format(PLUGIN_NAME, PLUGIN_VERSION))
traceback.print_exc()
update_account_path(self.deacsmprefs["path_to_account_data"])
2021-09-20 11:24:11 +02:00
filters = [("DER Files", ["der"])]
filename = choose_save_file(self, "Export ADE keys", _("Export ADE keys"), filters, all_files=False)
2021-09-20 15:18:12 +02:00
if (filename is None):
return
print("{0} v{1}: Exporting encryption key to {2}".format(PLUGIN_NAME, PLUGIN_VERSION, filename))
2021-09-20 11:24:11 +02:00
ret = exportAccountEncryptionKeyDER(filename)
2021-09-20 11:24:11 +02:00
if ret:
return info_dialog(None, "Done", "Key successfully exported", show=True, show_copy_button=False)
else:
return error_dialog(None, "Export failed", "Export failed", show=True, show_copy_button=False)
2021-09-20 11:24:11 +02:00
2021-09-19 16:20:56 +02:00
def save_settings(self):
2021-09-20 15:05:07 +02:00
#self.deacsmprefs.set('path_to_account_data', self.txtboxUA.text())
2021-09-19 16:20:56 +02:00
self.deacsmprefs.writeprefs()
def load_resource(self, name):
with ZipFile(self.plugin_path, 'r') as zf:
if name in zf.namelist():
return zf.read(name).decode('utf-8')
return ""