mirror of
https://github.com/Leseratte10/acsm-calibre-plugin
synced 2025-01-18 10:26:34 +01:00
Make plugin compile itself
This commit is contained in:
parent
f0d9c07af3
commit
4f5f22a63d
7 changed files with 213 additions and 87 deletions
7
.github/workflows/main.yml
vendored
7
.github/workflows/main.yml
vendored
|
@ -9,15 +9,16 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Compile
|
- name: Compile
|
||||||
run: |
|
run: |
|
||||||
DOCKER_BUILDKIT=1 docker build -o final .
|
./bundle_calibre_plugin.sh
|
||||||
cp calibre-plugin/* final/stretch/
|
|
||||||
|
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: linux
|
name: linux
|
||||||
path: |
|
path: |
|
||||||
final/stretch/
|
calibre-plugin.zip
|
||||||
|
libgourou_bundle_raw.tar.xz
|
||||||
|
|
67
Dockerfile
67
Dockerfile
|
@ -1,67 +0,0 @@
|
||||||
# Clear cache:
|
|
||||||
# docker builder prune
|
|
||||||
|
|
||||||
# Build:
|
|
||||||
# DOCKER_BUILDKIT=1 docker build -o output .
|
|
||||||
# for Windows, use
|
|
||||||
# { "features": { "buildkit": true } }
|
|
||||||
# instead of the environment variable
|
|
||||||
|
|
||||||
# Build a container
|
|
||||||
#FROM debian:bullseye as main_bullseye
|
|
||||||
#ENV DEBIAN_FRONTEND="noninteractive" TZ="Europe/London"
|
|
||||||
#RUN apt-get update -y && apt-get install -y \
|
|
||||||
# git && apt-get install -y --no-install-recommends make g++ pkg-config qtbase5-dev libssl-dev libzip-dev
|
|
||||||
#
|
|
||||||
#FROM debian:buster as main_buster
|
|
||||||
#ENV DEBIAN_FRONTEND="noninteractive" TZ="Europe/London"
|
|
||||||
#RUN apt-get update -y && apt-get install -y \
|
|
||||||
# git && apt-get install -y --no-install-recommends make g++ pkg-config qtbase5-dev libssl-dev libzip-dev
|
|
||||||
|
|
||||||
FROM debian:stretch as main_stretch
|
|
||||||
ENV DEBIAN_FRONTEND="noninteractive" TZ="Europe/London"
|
|
||||||
RUN apt-get update -y && apt-get install -y \
|
|
||||||
git && apt-get install -y --no-install-recommends make g++ pkg-config qtbase5-dev libssl-dev libzip-dev
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#FROM main_bullseye as compile_bullseye
|
|
||||||
#RUN git clone git://soutade.fr/libgourou.git && \
|
|
||||||
# cd libgourou && \
|
|
||||||
# make BUILD_SHARED=1 BUILD_UTILS=1
|
|
||||||
# mkdir final && \
|
|
||||||
# cp utils/acsmdownloader final/ && \
|
|
||||||
# cp utils/adept_activate final/ && \
|
|
||||||
# cp libgourou.so final/ && \
|
|
||||||
# cp /usr/lib/x86_64-linux-gnu/libzip.so.4 final/ && \
|
|
||||||
# true
|
|
||||||
#
|
|
||||||
#FROM main_buster as compile_buster
|
|
||||||
#RUN git clone git://soutade.fr/libgourou.git && \
|
|
||||||
# cd libgourou && \
|
|
||||||
# make BUILD_SHARED=1 BUILD_UTILS=1
|
|
||||||
# mkdir final && \
|
|
||||||
# cp utils/acsmdownloader final/ && \
|
|
||||||
# cp utils/adept_activate final/ && \
|
|
||||||
# cp libgourou.so final/ && \
|
|
||||||
# cp /usr/lib/x86_64-linux-gnu/libzip.so.4 final/ && \
|
|
||||||
# true
|
|
||||||
|
|
||||||
FROM main_stretch as compile_stretch
|
|
||||||
RUN git clone git://soutade.fr/libgourou.git && \
|
|
||||||
cd libgourou && \
|
|
||||||
make BUILD_SHARED=1 BUILD_UTILS=1 && \
|
|
||||||
mkdir final && \
|
|
||||||
cp utils/acsmdownloader final/ && \
|
|
||||||
cp utils/adept_activate final/ && \
|
|
||||||
cp libgourou.so final/ && \
|
|
||||||
cp /usr/lib/x86_64-linux-gnu/libzip.so.4 final/ && \
|
|
||||||
true
|
|
||||||
|
|
||||||
|
|
||||||
FROM scratch AS export-stage
|
|
||||||
#COPY --from=compile_bullseye /libgourou/final/ /bullseye/
|
|
||||||
#COPY --from=compile_buster /libgourou/final/ /buster/
|
|
||||||
COPY --from=compile_stretch /libgourou/final/ /stretch/
|
|
||||||
|
|
14
README
14
README
|
@ -1,8 +1,10 @@
|
||||||
- Linux x86_64 only
|
- Needed packages to compile (Debian Bullseye or Ubuntu 20.04): make, g++, libssl-dev, pkg-config, qtbase5-dev, libzip-dev
|
||||||
|
- Needed packages to run: Either just keep the above installed, or if you want to cleanup the dev stuff, you'll need:
|
||||||
- Debian Stretch or newer (or comparable)
|
- libqt5core5a, libqt5network5, libzip5 (Ubuntu) / libzip4 (Debian)
|
||||||
|
|
||||||
- You need these packages:
|
|
||||||
- qtbase5-dev
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- Run "package_sources.sh" to checkout source code bundle. That bundle (tar.xz) should be included in the plugin.
|
||||||
|
- Run "bundle_calibre_plugin.sh" to create the Calibre Plugin using the source code.
|
||||||
|
|
||||||
|
- In folder "libgourou", run "scripts/setup.sh" then run "make BUILD_SHARED=1 BUILD_UTILS=1"
|
13
bundle_calibre_plugin.sh
Executable file
13
bundle_calibre_plugin.sh
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
[ ! -f libgourou_bundle_release.tar.xz ] && ./package_sources.sh
|
||||||
|
|
||||||
|
cp libgourou_bundle_release.tar.xz calibre-plugin/
|
||||||
|
|
||||||
|
pushd calibre-plugin
|
||||||
|
|
||||||
|
zip -r ../calibre-plugin.zip *
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
rm calibre-plugin/libgourou_bundle_release.tar.xz
|
|
@ -13,6 +13,7 @@ PLUGIN_VERSION = ".".join([str(x)for x in PLUGIN_VERSION_TUPLE])
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
|
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
|
||||||
|
@ -53,20 +54,20 @@ class DeACSM(FileTypePlugin):
|
||||||
# only continue if we've never run this version of the plugin before
|
# only continue if we've never run this version of the plugin before
|
||||||
self.verdir = os.path.join(self.maindir,PLUGIN_VERSION)
|
self.verdir = os.path.join(self.maindir,PLUGIN_VERSION)
|
||||||
if not os.path.exists(self.verdir):
|
if not os.path.exists(self.verdir):
|
||||||
if iswindows:
|
if iswindows or isosx:
|
||||||
print("Windows not supported yet")
|
print("Windows and MacOS not supported!")
|
||||||
return
|
|
||||||
elif isosx:
|
|
||||||
print("Mac not supported yet")
|
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
names = ["acsmdownloader", "adept_activate", "libgourou.so", "libzip.so.4"]
|
names = ["libgourou_bundle_release.tar.xz"]
|
||||||
|
|
||||||
|
# mark that this version has been initialized
|
||||||
|
os.mkdir(self.verdir)
|
||||||
|
|
||||||
lib_dict = self.load_resources(names)
|
lib_dict = self.load_resources(names)
|
||||||
print("{0} v{1}: Copying needed library files from plugin's zip".format(PLUGIN_NAME, PLUGIN_VERSION))
|
print("{0} v{1}: Copying needed library files from plugin zip".format(PLUGIN_NAME, PLUGIN_VERSION))
|
||||||
|
|
||||||
for entry, data in lib_dict.items():
|
for entry, data in lib_dict.items():
|
||||||
file_path = os.path.join(self.alfdir, entry)
|
file_path = os.path.join(self.verdir, entry)
|
||||||
try:
|
try:
|
||||||
os.remove(file_path)
|
os.remove(file_path)
|
||||||
except:
|
except:
|
||||||
|
@ -79,8 +80,6 @@ class DeACSM(FileTypePlugin):
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# mark that this version has been initialized
|
|
||||||
os.mkdir(self.verdir)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
raise
|
raise
|
||||||
|
@ -101,6 +100,36 @@ class DeACSM(FileTypePlugin):
|
||||||
|
|
||||||
print("{0} v{1}: Trying to parse file {2}".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))
|
print("{0} v{1}: Trying to parse file {2}".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))
|
||||||
|
|
||||||
|
ext = os.path.splitext(path_to_ebook)[1].lower()
|
||||||
|
|
||||||
|
if (ext != ".acsm"):
|
||||||
|
print("{0} v{1}: That's not an ACSM, returning (is {2} instead)... ".format(PLUGIN_NAME, PLUGIN_VERSION, ext))
|
||||||
|
return path_to_ebook
|
||||||
|
|
||||||
|
import calibre_plugins.deacsm.prefs as prefs # type: ignore
|
||||||
|
deacsmprefs = prefs.DeACSM_Prefs()
|
||||||
|
|
||||||
|
print("{0} v{1}: Try to execute {2} ".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.join(self.verdir, "acsmdownloader")))
|
||||||
|
|
||||||
|
outputname = self.temporary_file(".epub").name
|
||||||
|
|
||||||
|
my_env = os.environ.copy()
|
||||||
|
my_env["LD_LIBRARY_PATH"] = ".:" + my_env["LD_LIBRARY_PATH"]
|
||||||
|
|
||||||
|
os.chmod(os.path.join(self.verdir, "acsmdownloader"), 0o775)
|
||||||
|
|
||||||
|
ret = subprocess.run([os.path.join(self.verdir, "acsmdownloader"), "-d", os.path.join(deacsmprefs["path_to_account_data"], "device.xml"),
|
||||||
|
"-a", os.path.join(deacsmprefs["path_to_account_data"], "activation.xml"),
|
||||||
|
"-k", os.path.join(deacsmprefs["path_to_account_data"], "devicesalt"),
|
||||||
|
"-o", outputname,
|
||||||
|
"-v", "-v",
|
||||||
|
"-f", path_to_ebook ], capture_output=True, shell=False, cwd=self.verdir, env=my_env)
|
||||||
|
|
||||||
|
print(ret)
|
||||||
|
|
||||||
|
return outputname
|
||||||
|
|
||||||
|
|
||||||
print("{0} v{1}: Failed, return original ...".format(PLUGIN_NAME, PLUGIN_VERSION))
|
print("{0} v{1}: Failed, return original ...".format(PLUGIN_NAME, PLUGIN_VERSION))
|
||||||
return path_to_ebook
|
return path_to_ebook
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
# pyright: reportUndefinedVariable=false
|
# pyright: reportUndefinedVariable=false
|
||||||
|
|
||||||
|
import os, glob, shutil, tarfile, subprocess, time
|
||||||
|
|
||||||
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,
|
||||||
|
@ -12,10 +13,12 @@ from PyQt5 import Qt as QtGui
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
# calibre modules and constants.
|
# calibre modules and constants.
|
||||||
from calibre.gui2 import (question_dialog, info_dialog) # type: ignore
|
from calibre.gui2 import (question_dialog, error_dialog, info_dialog, choose_save_file) # type: ignore
|
||||||
# modules from this plugin's zipfile.
|
# modules from this plugin's zipfile.
|
||||||
from calibre_plugins.deacsm.__init__ import PLUGIN_NAME, PLUGIN_VERSION # type: ignore
|
from calibre_plugins.deacsm.__init__ import PLUGIN_NAME, PLUGIN_VERSION # type: ignore
|
||||||
import calibre_plugins.deacsm.prefs as prefs # type: ignore
|
import calibre_plugins.deacsm.prefs as prefs # type: ignore
|
||||||
|
from calibre.utils.config import config_dir # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigWidget(QWidget):
|
class ConfigWidget(QWidget):
|
||||||
|
@ -36,6 +39,12 @@ class ConfigWidget(QWidget):
|
||||||
layout = QVBoxLayout(self)
|
layout = QVBoxLayout(self)
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
self.button_compile = QtGui.QPushButton(self)
|
||||||
|
self.button_compile.setToolTip(_("Click to compile"))
|
||||||
|
self.button_compile.setText(_("Compile"))
|
||||||
|
self.button_compile.clicked.connect(self.compile)
|
||||||
|
layout.addWidget(self.button_compile)
|
||||||
|
|
||||||
|
|
||||||
ua_group_box = QGroupBox(_('Path to account:'), self)
|
ua_group_box = QGroupBox(_('Path to account:'), self)
|
||||||
layout.addWidget(ua_group_box)
|
layout.addWidget(ua_group_box)
|
||||||
|
@ -47,9 +56,106 @@ class ConfigWidget(QWidget):
|
||||||
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)
|
||||||
|
|
||||||
|
self.button_export_key = QtGui.QPushButton(self)
|
||||||
|
self.button_export_key.setText(_("Export account key"))
|
||||||
|
self.button_export_key.clicked.connect(self.export_key)
|
||||||
|
ua_group_box_layout.addWidget(self.button_export_key)
|
||||||
|
|
||||||
|
|
||||||
self.resize(self.sizeHint())
|
self.resize(self.sizeHint())
|
||||||
|
|
||||||
|
def export_key(self):
|
||||||
|
pluginsdir = os.path.join(config_dir,"plugins")
|
||||||
|
maindir = os.path.join(pluginsdir,"DeACSM")
|
||||||
|
verdir = os.path.join(maindir,PLUGIN_VERSION)
|
||||||
|
|
||||||
|
filters = [("DER Files", ["der"])]
|
||||||
|
|
||||||
|
|
||||||
|
filename = choose_save_file(self, "Export ADE keys", _("Export ADE keys"), filters, all_files=False)
|
||||||
|
|
||||||
|
print("would export to " + filename)
|
||||||
|
|
||||||
|
my_env = os.environ.copy()
|
||||||
|
my_env["LD_LIBRARY_PATH"] = ".:" + my_env["LD_LIBRARY_PATH"]
|
||||||
|
|
||||||
|
|
||||||
|
old_files = glob.glob(os.path.join(verdir, "*.der"))
|
||||||
|
for file in old_files:
|
||||||
|
try:
|
||||||
|
os.remove(file)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.chmod(os.path.join(verdir, "acsmdownloader"), 0o775)
|
||||||
|
except FileNotFoundError:
|
||||||
|
return error_dialog(None, "Tool not found", "Helper tool not found. Press \"Compile\" then try again.", show=True, show_copy_button=False)
|
||||||
|
|
||||||
|
ret = None
|
||||||
|
|
||||||
|
import calibre_plugins.deacsm.prefs as prefs # type: ignore
|
||||||
|
deacsmprefs = prefs.DeACSM_Prefs()
|
||||||
|
|
||||||
|
try:
|
||||||
|
ret = subprocess.run([os.path.join(verdir, "acsmdownloader"), "-d", os.path.join(deacsmprefs["path_to_account_data"], "device.xml"),
|
||||||
|
"-a", os.path.join(deacsmprefs["path_to_account_data"], "activation.xml"),
|
||||||
|
"-k", os.path.join(deacsmprefs["path_to_account_data"], "devicesalt"),
|
||||||
|
"-e"
|
||||||
|
], capture_output=True, shell=False, cwd=verdir, env=my_env)
|
||||||
|
|
||||||
|
except:
|
||||||
|
return error_dialog(None, "Export failed", "Export failed.", det_msg=str(ret), show=True, show_copy_button=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
new_key = glob.glob(os.path.join(verdir, "*.der"))[0]
|
||||||
|
shutil.move(new_key, filename)
|
||||||
|
info_dialog(None, "Done", "Key successfully exported", show=True, show_copy_button=False)
|
||||||
|
except IndexError:
|
||||||
|
return error_dialog(None, "Export failed", "Export failed.", det_msg=str(ret), show=True, show_copy_button=True)
|
||||||
|
|
||||||
|
|
||||||
|
print(ret)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def compile(self):
|
||||||
|
|
||||||
|
# Get path to source code:
|
||||||
|
pluginsdir = os.path.join(config_dir,"plugins")
|
||||||
|
maindir = os.path.join(pluginsdir,"DeACSM")
|
||||||
|
verdir = os.path.join(maindir,PLUGIN_VERSION)
|
||||||
|
|
||||||
|
# Delete old version
|
||||||
|
try:
|
||||||
|
shutil.rmtree(os.path.join(verdir, "libgourou"))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# extract source
|
||||||
|
with tarfile.open(os.path.join(verdir, "libgourou_bundle_release.tar.xz")) as f:
|
||||||
|
f.extractall(verdir)
|
||||||
|
|
||||||
|
# Run script, compile 1st:
|
||||||
|
os.chmod(os.path.join(verdir, "libgourou", "scripts", "setup.sh"), 0o775)
|
||||||
|
|
||||||
|
|
||||||
|
ret1 = subprocess.run([ os.path.join(verdir, "libgourou", "scripts", "setup.sh") ], capture_output=True, shell=True, cwd=os.path.join(verdir, "libgourou"))
|
||||||
|
print(ret1)
|
||||||
|
|
||||||
|
ret2 = subprocess.run([ "make", "BUILD_SHARED=1", "BUILD_UTILS=1" ], capture_output=True, shell=True, cwd=os.path.join(verdir, "libgourou"))
|
||||||
|
print(ret2)
|
||||||
|
|
||||||
|
try:
|
||||||
|
shutil.copy(os.path.join(verdir, "libgourou", "AAlibgourou.so"), verdir)
|
||||||
|
shutil.copy(os.path.join(verdir, "libgourou", "utils", "acsmdownloader"), verdir)
|
||||||
|
shutil.copy(os.path.join(verdir, "libgourou", "utils", "adept_activate"), verdir)
|
||||||
|
info_dialog(None, "Done", "Compiling successful", show=True, show_copy_button=False)
|
||||||
|
except:
|
||||||
|
print("Can't copy ...")
|
||||||
|
error_dialog(None, "Compiling failed", "Compiling failed. Did you install all dependencies?", det_msg=str(ret1) + "\n" + str(ret2), show=True, show_copy_button=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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())
|
||||||
|
|
42
package_sources.sh
Executable file
42
package_sources.sh
Executable file
|
@ -0,0 +1,42 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
rm -rf libgourou
|
||||||
|
|
||||||
|
git clone git://soutade.fr/libgourou.git
|
||||||
|
pushd libgourou
|
||||||
|
|
||||||
|
# Pugixml
|
||||||
|
git clone https://github.com/zeux/pugixml.git lib/pugixml
|
||||||
|
pushd lib/pugixml
|
||||||
|
git checkout latest
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Base64
|
||||||
|
git clone https://gist.github.com/f0fd86b6c73063283afe550bc5d77594.git lib/base64
|
||||||
|
|
||||||
|
# uPDFParser
|
||||||
|
git clone git://soutade.fr/updfparser.git lib/updfparser
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
popd
|
||||||
|
rm -f libgourou_bundle_raw.tar.xz 2>/dev/null
|
||||||
|
XZ_OPT=-9 tar -Jcvf libgourou_bundle_raw.tar.xz libgourou
|
||||||
|
pushd libgourou
|
||||||
|
|
||||||
|
# Delete unnecessary stuff from release archive so the file stays small.
|
||||||
|
rm -rf ./.git/
|
||||||
|
rm -rf ./lib/*/.git/
|
||||||
|
rm -rf ./lib/pugixml/docs/
|
||||||
|
|
||||||
|
# Now patch the setup file:
|
||||||
|
|
||||||
|
echo "#!/bin/bash" > scripts/setup.sh
|
||||||
|
echo "pushd lib/updfparser" >> scripts/setup.sh
|
||||||
|
echo "make BUILD_STATIC=1 BUILD_SHARED=0" >> scripts/setup.sh
|
||||||
|
echo "popd" >> scripts/setup.sh
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
rm -f libgourou_bundle_release.tar.xz 2>/dev/null
|
||||||
|
XZ_OPT=-9 tar -Jcvf libgourou_bundle_release.tar.xz libgourou
|
Loading…
Reference in a new issue