mirror of
https://github.com/Leseratte10/acsm-calibre-plugin.git
synced 2024-12-22 17:29:56 +06:00
Add account setup stuff
This commit is contained in:
parent
4f5f22a63d
commit
1107fe4214
@ -17,14 +17,15 @@ import subprocess
|
|||||||
|
|
||||||
from calibre.utils.config import config_dir # type: ignore
|
from calibre.utils.config import config_dir # type: ignore
|
||||||
from calibre.constants import iswindows, isosx # type: ignore
|
from calibre.constants import iswindows, isosx # type: ignore
|
||||||
|
from calibre.gui2 import (question_dialog, error_dialog, info_dialog, choose_save_file) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DeACSM(FileTypePlugin):
|
class DeACSM(FileTypePlugin):
|
||||||
name = PLUGIN_NAME
|
name = PLUGIN_NAME
|
||||||
description = "Takes an Adobe ACSM file and converts that into a useable EPUB file"
|
description = "Takes an Adobe ACSM file and converts that into a useable EPUB file."
|
||||||
supported_platforms = ['linux']
|
supported_platforms = ['linux']
|
||||||
author = "Leseratte10"
|
author = "Leseratte10 (Plugin), Grégory Soutadé (libgourou)"
|
||||||
version = PLUGIN_VERSION_TUPLE
|
version = PLUGIN_VERSION_TUPLE
|
||||||
minimum_calibre_version = (5, 0, 0)
|
minimum_calibre_version = (5, 0, 0)
|
||||||
file_types = set(['acsm'])
|
file_types = set(['acsm'])
|
||||||
@ -34,14 +35,7 @@ class DeACSM(FileTypePlugin):
|
|||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
"""
|
"""
|
||||||
Dynamic modules can't be imported/loaded from a zipfile.
|
On initialization, make sure the libgourou code is present for compilation.
|
||||||
So this routine will extract the appropriate
|
|
||||||
library for the target OS and copy it to the 'alfcrypto' subdirectory of
|
|
||||||
calibre's configuration directory. That 'alfcrypto' directory is then
|
|
||||||
inserted into the syspath (as the very first entry) in the run function
|
|
||||||
so the CDLL stuff will work in the alfcrypto.py script.
|
|
||||||
The extraction only happens once per version of the plugin
|
|
||||||
Also perform upgrade of preferences once per version
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.pluginsdir = os.path.join(config_dir,"plugins")
|
self.pluginsdir = os.path.join(config_dir,"plugins")
|
||||||
@ -127,11 +121,15 @@ class DeACSM(FileTypePlugin):
|
|||||||
|
|
||||||
print(ret)
|
print(ret)
|
||||||
|
|
||||||
|
if not (os.path.exists(outputname)):
|
||||||
|
error_dialog(None, "ACSM->EPUB failed", "Could not convert ACSM to EPUB:", det_msg=str(ret), show=True, show_copy_button=True)
|
||||||
|
print("{0} v{1}: Failed, return original ...".format(PLUGIN_NAME, PLUGIN_VERSION))
|
||||||
|
return path_to_ebook
|
||||||
|
|
||||||
|
|
||||||
return outputname
|
return outputname
|
||||||
|
|
||||||
|
|
||||||
print("{0} v{1}: Failed, return original ...".format(PLUGIN_NAME, PLUGIN_VERSION))
|
|
||||||
return path_to_ebook
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
|
|
||||||
# pyright: reportUndefinedVariable=false
|
# pyright: reportUndefinedVariable=false
|
||||||
|
|
||||||
import os, glob, shutil, tarfile, subprocess, time
|
import os, glob, shutil, tarfile, subprocess, time, tempfile, datetime
|
||||||
|
|
||||||
|
from lxml import etree
|
||||||
|
|
||||||
|
|
||||||
from PyQt5.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
|
from PyQt5.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
|
||||||
QGroupBox, QPushButton, QListWidget, QListWidgetItem,
|
QGroupBox, QPushButton, QListWidget, QListWidgetItem, QInputDialog,
|
||||||
QAbstractItemView, QIcon, QDialog, QDialogButtonBox, QUrl)
|
QLineEdit, QAbstractItemView, QIcon, QDialog, QDialogButtonBox, QUrl)
|
||||||
|
|
||||||
from PyQt5 import Qt as QtGui
|
from PyQt5 import Qt as QtGui
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
@ -46,24 +49,168 @@ class ConfigWidget(QWidget):
|
|||||||
layout.addWidget(self.button_compile)
|
layout.addWidget(self.button_compile)
|
||||||
|
|
||||||
|
|
||||||
ua_group_box = QGroupBox(_('Path to account:'), self)
|
ua_group_box = QGroupBox(_('Account information:'), self)
|
||||||
layout.addWidget(ua_group_box)
|
layout.addWidget(ua_group_box)
|
||||||
ua_group_box_layout = QVBoxLayout()
|
ua_group_box_layout = QVBoxLayout()
|
||||||
ua_group_box.setLayout(ua_group_box_layout)
|
ua_group_box.setLayout(ua_group_box_layout)
|
||||||
|
|
||||||
self.txtboxUA = QtGui.QLineEdit(self)
|
#self.txtboxUA = QtGui.QLineEdit(self)
|
||||||
self.txtboxUA.setToolTip(_("Enter folder path to account data"))
|
#self.txtboxUA.setToolTip(_("Enter folder path to account data"))
|
||||||
self.txtboxUA.setText(self.tempdeacsmprefs['path_to_account_data'])
|
#self.txtboxUA.setText(self.tempdeacsmprefs['path_to_account_data'])
|
||||||
ua_group_box_layout.addWidget(self.txtboxUA)
|
#ua_group_box_layout.addWidget(self.txtboxUA)
|
||||||
|
|
||||||
|
info_string, activated = self.get_account_info()
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
self.button_export_key = QtGui.QPushButton(self)
|
self.button_export_key = QtGui.QPushButton(self)
|
||||||
self.button_export_key.setText(_("Export account key"))
|
self.button_export_key.setText(_("Export account encryption key"))
|
||||||
self.button_export_key.clicked.connect(self.export_key)
|
self.button_export_key.clicked.connect(self.export_key)
|
||||||
|
self.button_export_key.setEnabled(activated)
|
||||||
ua_group_box_layout.addWidget(self.button_export_key)
|
ua_group_box_layout.addWidget(self.button_export_key)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
self.resize(self.sizeHint())
|
self.resize(self.sizeHint())
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
return "Authorized with ADE ID ("+ade_type+") " + ade_mail + "\non device " + ade_device_name, True
|
||||||
|
except:
|
||||||
|
return "ADE authorization seems to be corrupted", False
|
||||||
|
|
||||||
|
|
||||||
|
def export_activation(self):
|
||||||
|
pluginsdir = os.path.join(config_dir,"plugins")
|
||||||
|
maindir = os.path.join(pluginsdir,"DeACSM")
|
||||||
|
|
||||||
|
filters = [("ZIP", ["zip"])]
|
||||||
|
filename = choose_save_file(self, "Export ADE activation files", _("Export ADE activation files"), filters, all_files=False)
|
||||||
|
|
||||||
|
print("would export to " + filename)
|
||||||
|
|
||||||
|
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 link_account(self):
|
||||||
|
pluginsdir = os.path.join(config_dir,"plugins")
|
||||||
|
maindir = os.path.join(pluginsdir,"DeACSM")
|
||||||
|
verdir = os.path.join(maindir,PLUGIN_VERSION)
|
||||||
|
|
||||||
|
mail, ok = QInputDialog.getText(self, "Authorizing ADE account", "Please enter mail address")
|
||||||
|
passwd, ok = QInputDialog.getText(self, "Authorizing ADE account", "Please enter password", QLineEdit.Password)
|
||||||
|
|
||||||
|
|
||||||
|
import calibre_plugins.deacsm.prefs as prefs # type: ignore
|
||||||
|
deacsmprefs = prefs.DeACSM_Prefs()
|
||||||
|
|
||||||
|
output_dir = tempfile.mkdtemp()
|
||||||
|
|
||||||
|
my_env = os.environ.copy()
|
||||||
|
my_env["LD_LIBRARY_PATH"] = ".:" + my_env["LD_LIBRARY_PATH"]
|
||||||
|
|
||||||
|
# Make backup ...
|
||||||
|
if (os.path.exists(os.path.join(deacsmprefs["path_to_account_data"], "device.xml")) or
|
||||||
|
os.path.exists(os.path.join(deacsmprefs["path_to_account_data"], "activation.xml")) or
|
||||||
|
os.path.exists(os.path.join(deacsmprefs["path_to_account_data"], "devicesalt")) ):
|
||||||
|
|
||||||
|
try:
|
||||||
|
currenttime = datetime.datetime.now()
|
||||||
|
backup_file = "backup_" + str(currenttime.year) + "-" + str(currenttime.month) + "-" + str(currenttime.day) + "_"
|
||||||
|
backup_file += str(currenttime.hour) + "-" + str(currenttime.minute) + "-" + str(currenttime.second) + ".zip"
|
||||||
|
with ZipFile(os.path.join(deacsmprefs["path_to_account_data"], backup_file), 'w') as zipfile:
|
||||||
|
try:
|
||||||
|
zipfile.write(os.path.join(self.deacsmprefs["path_to_account_data"], "device.xml"), "device.xml")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
zipfile.write(os.path.join(self.deacsmprefs["path_to_account_data"], "activation.xml"), "activation.xml")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
zipfile.write(os.path.join(self.deacsmprefs["path_to_account_data"], "devicesalt"), "devicesalt")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
|
||||||
|
ret = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
|
||||||
|
ret = subprocess.run([os.path.join(verdir, "adept_activate"),
|
||||||
|
"-u", mail,
|
||||||
|
"-p", passwd,
|
||||||
|
"-O", output_dir,
|
||||||
|
"-v"
|
||||||
|
], capture_output=True, shell=False, cwd=verdir, env=my_env)
|
||||||
|
|
||||||
|
print(ret)
|
||||||
|
|
||||||
|
except:
|
||||||
|
return error_dialog(None, "ADE activation failed", "ADE activation failed", det_msg=str(ret), show=True, show_copy_button=True)
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
shutil.copy(os.path.join(output_dir, "device.xml"), os.path.join(deacsmprefs["path_to_account_data"], "device.xml"))
|
||||||
|
shutil.copy(os.path.join(output_dir, "activation.xml"), os.path.join(deacsmprefs["path_to_account_data"], "activation.xml"))
|
||||||
|
shutil.copy(os.path.join(output_dir, "devicesalt"), os.path.join(deacsmprefs["path_to_account_data"], "devicesalt"))
|
||||||
|
shutil.rmtree(output_dir)
|
||||||
|
|
||||||
|
info_dialog(None, "Done", "Authorization successful!", show=True, show_copy_button=False)
|
||||||
|
|
||||||
|
except IndexError:
|
||||||
|
return error_dialog(None, "Authorization failed", "Authorization failed", show=True, det_msg=str(ret), show_copy_button=True)
|
||||||
|
|
||||||
|
# update display
|
||||||
|
info_string, activated = self.get_account_info()
|
||||||
|
self.lblAccInfo.setText(info_string)
|
||||||
|
|
||||||
|
self.button_link_account.setEnabled(False)
|
||||||
|
self.button_export_key.setEnabled(True)
|
||||||
|
self.button_export_activation.setEnabled(True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def export_key(self):
|
def export_key(self):
|
||||||
pluginsdir = os.path.join(config_dir,"plugins")
|
pluginsdir = os.path.join(config_dir,"plugins")
|
||||||
maindir = os.path.join(pluginsdir,"DeACSM")
|
maindir = os.path.join(pluginsdir,"DeACSM")
|
||||||
@ -104,6 +251,8 @@ class ConfigWidget(QWidget):
|
|||||||
"-e"
|
"-e"
|
||||||
], capture_output=True, shell=False, cwd=verdir, env=my_env)
|
], capture_output=True, shell=False, cwd=verdir, env=my_env)
|
||||||
|
|
||||||
|
print(ret)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
return error_dialog(None, "Export failed", "Export failed.", det_msg=str(ret), show=True, show_copy_button=True)
|
return error_dialog(None, "Export failed", "Export failed.", det_msg=str(ret), show=True, show_copy_button=True)
|
||||||
|
|
||||||
@ -112,10 +261,10 @@ class ConfigWidget(QWidget):
|
|||||||
shutil.move(new_key, filename)
|
shutil.move(new_key, filename)
|
||||||
info_dialog(None, "Done", "Key successfully exported", show=True, show_copy_button=False)
|
info_dialog(None, "Done", "Key successfully exported", show=True, show_copy_button=False)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return error_dialog(None, "Export failed", "Export failed.", det_msg=str(ret), show=True, show_copy_button=True)
|
return error_dialog(None, "Export failed", "Export failed.", show=True, show_copy_button=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print(ret)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -147,7 +296,7 @@ class ConfigWidget(QWidget):
|
|||||||
print(ret2)
|
print(ret2)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shutil.copy(os.path.join(verdir, "libgourou", "AAlibgourou.so"), verdir)
|
shutil.copy(os.path.join(verdir, "libgourou", "libgourou.so"), verdir)
|
||||||
shutil.copy(os.path.join(verdir, "libgourou", "utils", "acsmdownloader"), verdir)
|
shutil.copy(os.path.join(verdir, "libgourou", "utils", "acsmdownloader"), verdir)
|
||||||
shutil.copy(os.path.join(verdir, "libgourou", "utils", "adept_activate"), verdir)
|
shutil.copy(os.path.join(verdir, "libgourou", "utils", "adept_activate"), verdir)
|
||||||
info_dialog(None, "Done", "Compiling successful", show=True, show_copy_button=False)
|
info_dialog(None, "Done", "Compiling successful", show=True, show_copy_button=False)
|
||||||
@ -158,7 +307,7 @@ class ConfigWidget(QWidget):
|
|||||||
|
|
||||||
|
|
||||||
def save_settings(self):
|
def save_settings(self):
|
||||||
self.deacsmprefs.set('path_to_account_data', self.txtboxUA.text())
|
#self.deacsmprefs.set('path_to_account_data', self.txtboxUA.text())
|
||||||
self.deacsmprefs.writeprefs()
|
self.deacsmprefs.writeprefs()
|
||||||
|
|
||||||
def load_resource(self, name):
|
def load_resource(self, name):
|
||||||
|
@ -9,7 +9,6 @@ import traceback
|
|||||||
|
|
||||||
from calibre.utils.config import JSONConfig, config_dir # type: ignore
|
from calibre.utils.config import JSONConfig, config_dir # type: ignore
|
||||||
from calibre_plugins.deacsm.__init__ import PLUGIN_NAME # type: ignore
|
from calibre_plugins.deacsm.__init__ import PLUGIN_NAME # type: ignore
|
||||||
from calibre.constants import isosx, islinux # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
class DeACSM_Prefs():
|
class DeACSM_Prefs():
|
||||||
|
Loading…
Reference in New Issue
Block a user