added formatters to flake and formatted
This commit is contained in:
parent
9114ef63c1
commit
398ef79341
4 changed files with 288 additions and 240 deletions
327
flake.nix
327
flake.nix
|
@ -15,151 +15,190 @@
|
|||
};
|
||||
pugixml-src = {
|
||||
url = "github:zeux/pugixml/latest";
|
||||
flake = false;
|
||||
flake = false;
|
||||
};
|
||||
};
|
||||
|
||||
outputs = flakes: let
|
||||
version = "1.3.0";
|
||||
self = flakes.self.packages.x86_64-linux;
|
||||
nixpkgs = flakes.nixpkgs.legacyPackages.x86_64-linux.pkgsStatic;
|
||||
nixpkgs-dyn = flakes.nixpkgs.legacyPackages.x86_64-linux;
|
||||
gourou-src = flakes.gourou-src;
|
||||
updfparser-src = flakes.updfparser-src;
|
||||
base64-src = flakes.base64-src;
|
||||
pugixml-src = flakes.pugixml-src;
|
||||
cxx = "${nixpkgs.stdenv.cc}/bin/x86_64-unknown-linux-musl-g++";
|
||||
ar = "${nixpkgs.stdenv.cc.bintools.bintools_bin}/bin/x86_64-unknown-linux-musl-ar";
|
||||
obj-flags = "-O2 -static";
|
||||
in rec {
|
||||
packages.x86_64-linux.libzip-static = nixpkgs.libzip.overrideAttrs (prev: {
|
||||
cmakeFlags = (prev.cmakeFlags or []) ++ [
|
||||
"-DBUILD_SHARED_LIBS=OFF"
|
||||
"-DBUILD_EXAMPLES=OFF"
|
||||
"-DBUILD_DOC=OFF"
|
||||
"-DBUILD_TOOLS=OFF"
|
||||
"-DBUILD_REGRESS=OFF"
|
||||
];
|
||||
outputs = ["out"];
|
||||
});
|
||||
packages.x86_64-linux.base64 = derivation {
|
||||
name = "updfparser";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = ["-c" ''
|
||||
mkdir -p $out/include/base64
|
||||
cp ${base64-src}/Base64.h $out/include/base64/Base64.h
|
||||
''];
|
||||
outputs = flakes:
|
||||
let
|
||||
version = "1.3.0";
|
||||
self = flakes.self.packages.x86_64-linux;
|
||||
nixpkgs = flakes.nixpkgs.legacyPackages.x86_64-linux.pkgsStatic;
|
||||
nixpkgs-dyn = flakes.nixpkgs.legacyPackages.x86_64-linux;
|
||||
nixpkgs-fmt = flakes.nixpkgs-fmt.defaultPackage.x86_64-linux;
|
||||
gourou-src = flakes.gourou-src;
|
||||
updfparser-src = flakes.updfparser-src;
|
||||
base64-src = flakes.base64-src;
|
||||
pugixml-src = flakes.pugixml-src;
|
||||
cxx = "${nixpkgs.stdenv.cc}/bin/x86_64-unknown-linux-musl-g++";
|
||||
ar = "${nixpkgs.stdenv.cc.bintools.bintools_bin}/bin/x86_64-unknown-linux-musl-ar";
|
||||
obj-flags = "-O2 -static";
|
||||
in
|
||||
rec {
|
||||
packages.x86_64-linux.libzip-static = nixpkgs.libzip.overrideAttrs (prev: {
|
||||
cmakeFlags = (prev.cmakeFlags or [ ]) ++ [
|
||||
"-DBUILD_SHARED_LIBS=OFF"
|
||||
"-DBUILD_EXAMPLES=OFF"
|
||||
"-DBUILD_DOC=OFF"
|
||||
"-DBUILD_TOOLS=OFF"
|
||||
"-DBUILD_REGRESS=OFF"
|
||||
];
|
||||
outputs = [ "out" ];
|
||||
});
|
||||
packages.x86_64-linux.base64 = derivation {
|
||||
name = "updfparser";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = [
|
||||
"-c"
|
||||
''
|
||||
mkdir -p $out/include/base64
|
||||
cp ${base64-src}/Base64.h $out/include/base64/Base64.h
|
||||
''
|
||||
];
|
||||
};
|
||||
packages.x86_64-linux.updfparser = derivation {
|
||||
name = "updfparser";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = [
|
||||
"-c"
|
||||
''
|
||||
${cxx} \
|
||||
-c ${updfparser-src}/src/*.cpp \
|
||||
-I ${updfparser-src}/include \
|
||||
${obj-flags}
|
||||
mkdir -p $out/lib
|
||||
${ar} crs $out/lib/libupdfparser.a *.o
|
||||
''
|
||||
];
|
||||
};
|
||||
packages.x86_64-linux.gourou = derivation {
|
||||
name = "gourou";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = [
|
||||
"-c"
|
||||
''
|
||||
${cxx} \
|
||||
-c \
|
||||
${gourou-src}/src/*.cpp \
|
||||
${pugixml-src}/src/pugixml.cpp \
|
||||
-I ${self.base64}/include \
|
||||
-I ${gourou-src}/include \
|
||||
-I ${pugixml-src}/src \
|
||||
-I ${updfparser-src}/include \
|
||||
${obj-flags}
|
||||
mkdir -p $out/lib $out/debug
|
||||
${ar} crs $out/lib/libgourou.a *.o
|
||||
cp *.o $out/debug
|
||||
''
|
||||
];
|
||||
};
|
||||
packages.x86_64-linux.utils-common = derivation {
|
||||
name = "utils-common";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = [
|
||||
"-c"
|
||||
''
|
||||
${cxx} \
|
||||
-c ${gourou-src}/utils/drmprocessorclientimpl.cpp \
|
||||
${gourou-src}/utils/utils_common.cpp \
|
||||
-I ${gourou-src}/utils \
|
||||
-I ${gourou-src}/include \
|
||||
-I ${pugixml-src}/src \
|
||||
-I ${nixpkgs.openssl.dev}/include \
|
||||
-I ${nixpkgs.curl.dev}/include \
|
||||
-I ${nixpkgs.zlib.dev}/include \
|
||||
-I ${self.libzip-static}/include \
|
||||
${obj-flags}
|
||||
mkdir -p $out/lib
|
||||
${ar} crs $out/lib/libutils-common.a *.o
|
||||
''
|
||||
];
|
||||
};
|
||||
packages.x86_64-linux.knock = derivation {
|
||||
name = "knock";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = [
|
||||
"-c"
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
${cxx} \
|
||||
-o $out/bin/knock \
|
||||
${./src/knock.cpp} \
|
||||
-D KNOCK_VERSION='"${version}"' \
|
||||
-Wl,--as-needed -static \
|
||||
${self.utils-common}/lib/libutils-common.a \
|
||||
${self.gourou}/lib/libgourou.a \
|
||||
${self.updfparser}/lib/libupdfparser.a \
|
||||
-Wl,--start-group \
|
||||
${self.libzip-static}/lib/libzip.a \
|
||||
${nixpkgs.libnghttp2}/lib/libnghttp2.a \
|
||||
${nixpkgs.libidn2.out}/lib/libidn2.a \
|
||||
${nixpkgs.libunistring}/lib/libunistring.a \
|
||||
${nixpkgs.libssh2}/lib/libssh2.a \
|
||||
${nixpkgs.zstd.out}/lib/libzstd.a \
|
||||
${nixpkgs.zlib}/lib/libz.a \
|
||||
${nixpkgs.openssl.out}/lib/libcrypto.a \
|
||||
${nixpkgs.curl.out}/lib/libcurl.a \
|
||||
${nixpkgs.openssl.out}/lib/libssl.a \
|
||||
-static-libgcc -static-libstdc++ \
|
||||
-Wl,--end-group \
|
||||
-I ${gourou-src}/utils \
|
||||
-I ${gourou-src}/include \
|
||||
-I ${pugixml-src}/src \
|
||||
-I ${nixpkgs.openssl.dev}/include \
|
||||
-I ${nixpkgs.curl.dev}/include \
|
||||
-I ${nixpkgs.zlib.dev}/include \
|
||||
-I ${self.libzip-static}/include
|
||||
''
|
||||
];
|
||||
};
|
||||
packages.x86_64-linux.default = self.knock;
|
||||
packages.x86_64-linux.tests = nixpkgs-dyn.stdenv.mkDerivation {
|
||||
name = "tests";
|
||||
src = ./tests;
|
||||
buildInputs = [
|
||||
(nixpkgs-dyn.python3.withPackages (p: [
|
||||
p.beautifulsoup4
|
||||
p.requests
|
||||
]))
|
||||
];
|
||||
patchPhase = ''
|
||||
substituteInPlace tests.py --replace "./result/bin/knock" "${self.knock}/bin/knock"
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp tests.py $out/bin/tests
|
||||
chmod +x $out/bin/tests
|
||||
'';
|
||||
};
|
||||
devShell.x86_64-linux = nixpkgs.mkShell {
|
||||
packages = [
|
||||
# nix formatter
|
||||
nixpkgs-dyn.nixpkgs-fmt
|
||||
# python formatter
|
||||
nixpkgs-dyn.black
|
||||
# cpp formatter
|
||||
nixpkgs-dyn.clang-tools
|
||||
];
|
||||
shellHook = ''
|
||||
fmt () {
|
||||
set -ex
|
||||
nixpkgs-fmt .
|
||||
black ./tests
|
||||
clang-format -i --verbose src/*.cpp
|
||||
set +ex
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
packages.x86_64-linux.updfparser = derivation {
|
||||
name = "updfparser";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = [ "-c" ''
|
||||
${cxx} \
|
||||
-c ${updfparser-src}/src/*.cpp \
|
||||
-I ${updfparser-src}/include \
|
||||
${obj-flags}
|
||||
mkdir -p $out/lib
|
||||
${ar} crs $out/lib/libupdfparser.a *.o
|
||||
'' ];
|
||||
};
|
||||
packages.x86_64-linux.gourou = derivation {
|
||||
name = "gourou";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = [ "-c" ''
|
||||
${cxx} \
|
||||
-c \
|
||||
${gourou-src}/src/*.cpp \
|
||||
${pugixml-src}/src/pugixml.cpp \
|
||||
-I ${self.base64}/include \
|
||||
-I ${gourou-src}/include \
|
||||
-I ${pugixml-src}/src \
|
||||
-I ${updfparser-src}/include \
|
||||
${obj-flags}
|
||||
mkdir -p $out/lib $out/debug
|
||||
${ar} crs $out/lib/libgourou.a *.o
|
||||
cp *.o $out/debug
|
||||
'' ];
|
||||
};
|
||||
packages.x86_64-linux.utils-common = derivation {
|
||||
name = "utils-common";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = [ "-c" ''
|
||||
${cxx} \
|
||||
-c ${gourou-src}/utils/drmprocessorclientimpl.cpp \
|
||||
${gourou-src}/utils/utils_common.cpp \
|
||||
-I ${gourou-src}/utils \
|
||||
-I ${gourou-src}/include \
|
||||
-I ${pugixml-src}/src \
|
||||
-I ${nixpkgs.openssl.dev}/include \
|
||||
-I ${nixpkgs.curl.dev}/include \
|
||||
-I ${nixpkgs.zlib.dev}/include \
|
||||
-I ${self.libzip-static}/include \
|
||||
${obj-flags}
|
||||
mkdir -p $out/lib
|
||||
${ar} crs $out/lib/libutils-common.a *.o
|
||||
'' ];
|
||||
};
|
||||
packages.x86_64-linux.knock = derivation {
|
||||
name = "knock";
|
||||
system = "x86_64-linux";
|
||||
builder = "${nixpkgs.bash}/bin/bash";
|
||||
PATH = "${nixpkgs.coreutils}/bin";
|
||||
args = [ "-c" ''
|
||||
mkdir -p $out/bin
|
||||
${cxx} \
|
||||
-o $out/bin/knock \
|
||||
${./src/knock.cpp} \
|
||||
-D KNOCK_VERSION='"${version}"' \
|
||||
-Wl,--as-needed -static \
|
||||
${self.utils-common}/lib/libutils-common.a \
|
||||
${self.gourou}/lib/libgourou.a \
|
||||
${self.updfparser}/lib/libupdfparser.a \
|
||||
-Wl,--start-group \
|
||||
${self.libzip-static}/lib/libzip.a \
|
||||
${nixpkgs.libnghttp2}/lib/libnghttp2.a \
|
||||
${nixpkgs.libidn2.out}/lib/libidn2.a \
|
||||
${nixpkgs.libunistring}/lib/libunistring.a \
|
||||
${nixpkgs.libssh2}/lib/libssh2.a \
|
||||
${nixpkgs.zstd.out}/lib/libzstd.a \
|
||||
${nixpkgs.zlib}/lib/libz.a \
|
||||
${nixpkgs.openssl.out}/lib/libcrypto.a \
|
||||
${nixpkgs.curl.out}/lib/libcurl.a \
|
||||
${nixpkgs.openssl.out}/lib/libssl.a \
|
||||
-static-libgcc -static-libstdc++ \
|
||||
-Wl,--end-group \
|
||||
-I ${gourou-src}/utils \
|
||||
-I ${gourou-src}/include \
|
||||
-I ${pugixml-src}/src \
|
||||
-I ${nixpkgs.openssl.dev}/include \
|
||||
-I ${nixpkgs.curl.dev}/include \
|
||||
-I ${nixpkgs.zlib.dev}/include \
|
||||
-I ${self.libzip-static}/include
|
||||
'' ];
|
||||
};
|
||||
packages.x86_64-linux.default = self.knock;
|
||||
packages.x86_64-linux.tests = nixpkgs-dyn.stdenv.mkDerivation {
|
||||
name = "tests";
|
||||
src = ./tests;
|
||||
buildInputs = [ (nixpkgs-dyn.python3.withPackages(p: [
|
||||
p.beautifulsoup4
|
||||
p.requests
|
||||
])) ];
|
||||
patchPhase = ''
|
||||
substituteInPlace tests.py --replace "./result/bin/knock" "${self.knock}/bin/knock"
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp tests.py $out/bin/tests
|
||||
chmod +x $out/bin/tests
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,14 @@ nix run .#tests -- ./tests/workspace
|
|||
|
||||
Test books can be found [here](https://www.adobe.com/solutions/ebook/digital-editions/sample-ebook-library.html).
|
||||
|
||||
### Formatting
|
||||
|
||||
```
|
||||
nix develop
|
||||
fmt
|
||||
exit
|
||||
```
|
||||
|
||||
## The Name
|
||||
|
||||
The name comes from the [D&D 5e spell](https://roll20.net/compendium/dnd5e/Knock#content) for freeing locked items:
|
||||
|
|
179
src/knock.cpp
179
src/knock.cpp
|
@ -1,119 +1,120 @@
|
|||
#include <filesystem>
|
||||
#include "drmprocessorclientimpl.h"
|
||||
#include "libgourou_common.h"
|
||||
#include "libgourou.h"
|
||||
#include "libgourou_common.h"
|
||||
#include <filesystem>
|
||||
|
||||
#ifndef KNOCK_VERSION
|
||||
#error KNOCK_VERSION must be defined
|
||||
#error KNOCK_VERSION must be defined
|
||||
#endif
|
||||
|
||||
std::string get_data_dir();
|
||||
void verify_absence(std::string file);
|
||||
void verify_presence(std::string file);
|
||||
|
||||
int main(int argc, char** argv) try {
|
||||
int main(int argc, char **argv) try {
|
||||
|
||||
if (argc == 1) {
|
||||
std::cout
|
||||
<< "info: knock version " << KNOCK_VERSION << ", libgourou version "
|
||||
<< LIBGOUROU_VERSION << "\n"
|
||||
<< "usage: " << argv[0] << " [ACSM]" << "\n"
|
||||
<< "result: converts file ACSM to a plain EPUB/PDF if present, otherwise prints this"
|
||||
<< std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (argc == 1) {
|
||||
std::cout << "info: knock version " << KNOCK_VERSION
|
||||
<< ", libgourou version " << LIBGOUROU_VERSION << "\n"
|
||||
<< "usage: " << argv[0] << " [ACSM]\n"
|
||||
<< "result: converts file ACSM to a plain EPUB/PDF if present, "
|
||||
"otherwise prints this"
|
||||
<< std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (argc != 2) {
|
||||
throw std::invalid_argument("the ACSM file must be passed as an argument");
|
||||
}
|
||||
if (argc != 2) {
|
||||
throw std::invalid_argument("the ACSM file must be passed as an argument");
|
||||
}
|
||||
|
||||
const std::string acsm_file = argv[1];
|
||||
verify_presence(acsm_file);
|
||||
const std::string acsm_stem = acsm_file.substr(0, acsm_file.find_last_of("."));
|
||||
const std::string drm_file = acsm_stem + ".drm";
|
||||
const std::string out_file = acsm_stem + ".out";
|
||||
verify_absence(drm_file);
|
||||
verify_absence(out_file);
|
||||
const std::string knock_data = get_data_dir();
|
||||
const std::string acsm_file = argv[1];
|
||||
verify_presence(acsm_file);
|
||||
const std::string acsm_stem =
|
||||
acsm_file.substr(0, acsm_file.find_last_of("."));
|
||||
const std::string drm_file = acsm_stem + ".drm";
|
||||
const std::string out_file = acsm_stem + ".out";
|
||||
verify_absence(drm_file);
|
||||
verify_absence(out_file);
|
||||
const std::string knock_data = get_data_dir();
|
||||
|
||||
DRMProcessorClientImpl client;
|
||||
gourou::DRMProcessor* processor = gourou::DRMProcessor::createDRMProcessor(
|
||||
&client,
|
||||
false, // don't "always generate a new device" (default)
|
||||
knock_data
|
||||
);
|
||||
DRMProcessorClientImpl client;
|
||||
gourou::DRMProcessor *processor = gourou::DRMProcessor::createDRMProcessor(
|
||||
&client,
|
||||
false, // don't "always generate a new device" (default)
|
||||
knock_data);
|
||||
|
||||
std::cout << "anonymously signing in..." << std::endl;
|
||||
processor->signIn("anonymous", "");
|
||||
processor->activateDevice();
|
||||
std::cout << "anonymously signing in..." << std::endl;
|
||||
processor->signIn("anonymous", "");
|
||||
processor->activateDevice();
|
||||
|
||||
std::cout << "downloading the file from Adobe..." << std::endl;
|
||||
gourou::FulfillmentItem* item = processor->fulfill(acsm_file);
|
||||
gourou::DRMProcessor::ITEM_TYPE type = processor->download(item, drm_file);
|
||||
|
||||
std::cout << "removing DRM from the file..." << std::endl;
|
||||
std::string ext_file;
|
||||
std::string file_type;
|
||||
switch (type) {
|
||||
case gourou::DRMProcessor::ITEM_TYPE::PDF: {
|
||||
// for pdfs the function moves the pdf while removing drm
|
||||
processor->removeDRM(drm_file, out_file, type, nullptr, 0);
|
||||
std::filesystem::remove(drm_file);
|
||||
ext_file = acsm_stem + ".pdf";
|
||||
file_type = "PDF";
|
||||
break;
|
||||
}
|
||||
case gourou::DRMProcessor::ITEM_TYPE::EPUB: {
|
||||
// for epubs the drm is removed in-place so in == out
|
||||
processor->removeDRM(drm_file, drm_file, type, nullptr, 0);
|
||||
std::filesystem::rename(drm_file, out_file);
|
||||
ext_file = acsm_stem + ".epub";
|
||||
file_type = "EPUB";
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::cout << "downloading the file from Adobe..." << std::endl;
|
||||
gourou::FulfillmentItem *item = processor->fulfill(acsm_file);
|
||||
gourou::DRMProcessor::ITEM_TYPE type = processor->download(item, drm_file);
|
||||
|
||||
if (std::filesystem::exists(ext_file)) {
|
||||
std::cerr
|
||||
<< "warning: failed to update file extension; " + ext_file + " already exists"
|
||||
<< std::endl;
|
||||
ext_file = out_file;
|
||||
} else {
|
||||
std::filesystem::rename(out_file, ext_file);
|
||||
}
|
||||
std::cout << "removing DRM from the file..." << std::endl;
|
||||
std::string ext_file;
|
||||
std::string file_type;
|
||||
switch (type) {
|
||||
case gourou::DRMProcessor::ITEM_TYPE::PDF: {
|
||||
// for pdfs the function moves the pdf while removing drm
|
||||
processor->removeDRM(drm_file, out_file, type, nullptr, 0);
|
||||
std::filesystem::remove(drm_file);
|
||||
ext_file = acsm_stem + ".pdf";
|
||||
file_type = "PDF";
|
||||
break;
|
||||
}
|
||||
case gourou::DRMProcessor::ITEM_TYPE::EPUB: {
|
||||
// for epubs the drm is removed in-place so in == out
|
||||
processor->removeDRM(drm_file, drm_file, type, nullptr, 0);
|
||||
std::filesystem::rename(drm_file, out_file);
|
||||
ext_file = acsm_stem + ".epub";
|
||||
file_type = "EPUB";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << file_type + " file generated at " + ext_file << std::endl;
|
||||
if (std::filesystem::exists(ext_file)) {
|
||||
std::cerr << "warning: failed to update file extension; " + ext_file +
|
||||
" already exists"
|
||||
<< std::endl;
|
||||
ext_file = out_file;
|
||||
} else {
|
||||
std::filesystem::rename(out_file, ext_file);
|
||||
}
|
||||
|
||||
return 0;
|
||||
std::cout << file_type + " file generated at " + ext_file << std::endl;
|
||||
|
||||
} catch (const gourou::Exception& e) {
|
||||
std::cerr << "error:\n" << e.what();
|
||||
return EXIT_FAILURE;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "error: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
return 0;
|
||||
|
||||
} catch (const gourou::Exception &e) {
|
||||
std::cerr << "error:\n" << e.what();
|
||||
return EXIT_FAILURE;
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "error: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::string get_data_dir() {
|
||||
char* xdg_data_home = std::getenv("XDG_DATA_HOME");
|
||||
std::string knock_data;
|
||||
if (xdg_data_home != nullptr) {
|
||||
knock_data = xdg_data_home;
|
||||
} else {
|
||||
knock_data = std::string(std::getenv("HOME")) + "/.local/share";
|
||||
}
|
||||
knock_data += "/knock/acsm";
|
||||
return knock_data;
|
||||
char *xdg_data_home = std::getenv("XDG_DATA_HOME");
|
||||
std::string knock_data;
|
||||
if (xdg_data_home != nullptr) {
|
||||
knock_data = xdg_data_home;
|
||||
} else {
|
||||
knock_data = std::string(std::getenv("HOME")) + "/.local/share";
|
||||
}
|
||||
knock_data += "/knock/acsm";
|
||||
return knock_data;
|
||||
}
|
||||
|
||||
void verify_absence(std::string file) {
|
||||
if (std::filesystem::exists(file)) {
|
||||
throw std::runtime_error("file " + file + " must be moved out of the way or deleted");
|
||||
}
|
||||
if (std::filesystem::exists(file)) {
|
||||
throw std::runtime_error("file " + file +
|
||||
" must be moved out of the way or deleted");
|
||||
}
|
||||
}
|
||||
|
||||
void verify_presence(std::string file) {
|
||||
if (!std::filesystem::exists(file)) {
|
||||
throw std::runtime_error("file " + file + " does not exist");
|
||||
}
|
||||
if (!std::filesystem::exists(file)) {
|
||||
throw std::runtime_error("file " + file + " does not exist");
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ if not knock.exists():
|
|||
if len(sys.argv) != 2:
|
||||
print(
|
||||
"error: missing required argument: directory in which to perform the tests",
|
||||
file=sys.stderr
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit()
|
||||
|
||||
|
@ -31,18 +31,18 @@ if workspace.exists():
|
|||
shutil.rmtree(workspace)
|
||||
workspace.mkdir()
|
||||
|
||||
html = requests \
|
||||
.get("https://www.adobe.com/solutions/ebook/digital-editions/sample-ebook-library.html") \
|
||||
.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
html = requests.get(
|
||||
"https://www.adobe.com/solutions/ebook/digital-editions/sample-ebook-library.html"
|
||||
).text
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
|
||||
links = []
|
||||
for a_tag in soup.find_all('a'):
|
||||
for a_tag in soup.find_all("a"):
|
||||
if a_tag.string != "Download eBook":
|
||||
continue
|
||||
if not urlparse(a_tag.get("href")).path.endswith(".acsm"):
|
||||
continue
|
||||
|
||||
|
||||
links.append(a_tag.get("href"))
|
||||
|
||||
if len(links) >= 10:
|
||||
|
|
Loading…
Reference in a new issue