mirror of https://github.com/kiwix/libkiwix.git
Make the downloader use the aria2c wrapper instead of the aria2 library.
This commit is contained in:
parent
0a93cb0872
commit
db9000f706
|
@ -21,15 +21,13 @@
|
||||||
#define KIWIX_DOWNLOADER_H
|
#define KIWIX_DOWNLOADER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#ifdef ENABLE_LIBARIA2
|
|
||||||
# include <aria2/aria2.h>
|
|
||||||
#endif
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace kiwix
|
namespace kiwix
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class Aria2;
|
||||||
struct DownloadedFile {
|
struct DownloadedFile {
|
||||||
DownloadedFile()
|
DownloadedFile()
|
||||||
: success(false) {}
|
: success(false) {}
|
||||||
|
@ -56,17 +54,8 @@ class Downloader
|
||||||
DownloadedFile download(const std::string& url);
|
DownloadedFile download(const std::string& url);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static pthread_mutex_t globalLock;
|
|
||||||
|
|
||||||
std::string tmpDir;
|
std::unique_ptr<Aria2> mp_aria;
|
||||||
#ifdef ENABLE_LIBARIA2
|
|
||||||
DownloadedFile* fileHandle;
|
|
||||||
aria2::Session* session;
|
|
||||||
static int downloadEventCallback(aria2::Session* session,
|
|
||||||
aria2::DownloadEvent event,
|
|
||||||
aria2::A2Gid gid,
|
|
||||||
void* userData);
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ libicu_dep = dependency('icu-i18n', static:static_deps)
|
||||||
libzim_dep = dependency('libzim', version : '>=4.0.0', static:static_deps)
|
libzim_dep = dependency('libzim', version : '>=4.0.0', static:static_deps)
|
||||||
pugixml_dep = dependency('pugixml', static:static_deps)
|
pugixml_dep = dependency('pugixml', static:static_deps)
|
||||||
libcurl_dep = dependency('libcurl', static:static_deps)
|
libcurl_dep = dependency('libcurl', static:static_deps)
|
||||||
libaria2_dep = dependency('libaria2', static:static_deps, required:false)
|
|
||||||
|
|
||||||
ctpp2_include_path = ''
|
ctpp2_include_path = ''
|
||||||
has_ctpp2_dep = false
|
has_ctpp2_dep = false
|
||||||
|
@ -79,7 +78,7 @@ endif
|
||||||
|
|
||||||
xapian_dep = dependency('xapian-core', required:false, static:static_deps)
|
xapian_dep = dependency('xapian-core', required:false, static:static_deps)
|
||||||
|
|
||||||
all_deps = [thread_dep, libicu_dep, libzim_dep, xapian_dep, pugixml_dep, libcurl_dep, libaria2_dep]
|
all_deps = [thread_dep, libicu_dep, libzim_dep, xapian_dep, pugixml_dep, libcurl_dep]
|
||||||
if has_ctpp2_dep
|
if has_ctpp2_dep
|
||||||
all_deps += [ctpp2_dep]
|
all_deps += [ctpp2_dep]
|
||||||
endif
|
endif
|
||||||
|
@ -89,7 +88,6 @@ inc = include_directories('include')
|
||||||
conf = configuration_data()
|
conf = configuration_data()
|
||||||
conf.set('VERSION', '"@0@"'.format(meson.project_version()))
|
conf.set('VERSION', '"@0@"'.format(meson.project_version()))
|
||||||
conf.set('ENABLE_CTPP2', has_ctpp2_dep)
|
conf.set('ENABLE_CTPP2', has_ctpp2_dep)
|
||||||
conf.set('ENABLE_LIBARIA2', libaria2_dep.found())
|
|
||||||
|
|
||||||
if build_machine.system() == 'windows'
|
if build_machine.system() == 'windows'
|
||||||
extra_link_args = ['-lshlwapi', '-lwinmm']
|
extra_link_args = ['-lshlwapi', '-lwinmm']
|
||||||
|
@ -104,9 +102,6 @@ subdir('src')
|
||||||
subdir('test')
|
subdir('test')
|
||||||
|
|
||||||
pkg_requires = ['libzim', 'icu-i18n', 'pugixml', 'libcurl']
|
pkg_requires = ['libzim', 'icu-i18n', 'pugixml', 'libcurl']
|
||||||
if libaria2_dep.found()
|
|
||||||
pkg_requires += ['libaria2']
|
|
||||||
endif
|
|
||||||
if xapian_dep.found()
|
if xapian_dep.found()
|
||||||
pkg_requires += ['xapian-core']
|
pkg_requires += ['xapian-core']
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -2,5 +2,3 @@
|
||||||
#mesondefine VERSION
|
#mesondefine VERSION
|
||||||
|
|
||||||
#mesondefine ENABLE_CTPP2
|
#mesondefine ENABLE_CTPP2
|
||||||
|
|
||||||
#mesondefine ENABLE_LIBARIA2
|
|
||||||
|
|
|
@ -20,101 +20,73 @@
|
||||||
#include "downloader.h"
|
#include "downloader.h"
|
||||||
#include "common/pathTools.h"
|
#include "common/pathTools.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#include <thread>
|
||||||
# include <unistd.h>
|
#include <chrono>
|
||||||
#endif
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "aria2.h"
|
||||||
|
#include "xmlrpc.h"
|
||||||
|
#include "common/otherTools.h"
|
||||||
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
namespace kiwix
|
namespace kiwix
|
||||||
{
|
{
|
||||||
|
|
||||||
pthread_mutex_t Downloader::globalLock = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
|
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
Downloader::Downloader()
|
Downloader::Downloader() :
|
||||||
|
mp_aria(new Aria2())
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_LIBARIA2
|
|
||||||
aria2::SessionConfig config;
|
|
||||||
config.downloadEventCallback = Downloader::downloadEventCallback;
|
|
||||||
config.userData = this;
|
|
||||||
tmpDir = makeTmpDirectory();
|
|
||||||
aria2::KeyVals options;
|
|
||||||
options.push_back(std::pair<std::string, std::string>("dir", tmpDir));
|
|
||||||
session = aria2::sessionNew(options, config);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Destructor */
|
/* Destructor */
|
||||||
Downloader::~Downloader()
|
Downloader::~Downloader()
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_LIBARIA2
|
|
||||||
aria2::sessionFinal(session);
|
|
||||||
#endif
|
|
||||||
rmdir(tmpDir.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_LIBARIA2
|
pugi::xml_node find_member_in_struct(pugi::xml_node struct_node, std::string member_name) {
|
||||||
int Downloader::downloadEventCallback(aria2::Session* session,
|
for(auto member=struct_node.first_child(); member; member=member.next_sibling()) {
|
||||||
aria2::DownloadEvent event,
|
std::string _member_name = member.child("name").text().get();
|
||||||
aria2::A2Gid gid,
|
if (_member_name == member_name) {
|
||||||
void* userData)
|
return member.child("value");
|
||||||
{
|
}
|
||||||
Downloader* downloader = static_cast<Downloader*>(userData);
|
|
||||||
|
|
||||||
auto fileHandle = downloader->fileHandle;
|
|
||||||
auto dh = aria2::getDownloadHandle(session, gid);
|
|
||||||
|
|
||||||
if (!dh) {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return pugi::xml_node();
|
||||||
switch (event) {
|
|
||||||
case aria2::EVENT_ON_DOWNLOAD_COMPLETE:
|
|
||||||
{
|
|
||||||
if (dh->getNumFiles() > 0) {
|
|
||||||
auto f = dh->getFile(1);
|
|
||||||
fileHandle->path = f.path;
|
|
||||||
fileHandle->success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case aria2::EVENT_ON_DOWNLOAD_ERROR:
|
|
||||||
{
|
|
||||||
fileHandle->success = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
aria2::deleteDownloadHandle(dh);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
DownloadedFile Downloader::download(const std::string& url) {
|
DownloadedFile Downloader::download(const std::string& url) {
|
||||||
pthread_mutex_lock(&globalLock);
|
|
||||||
DownloadedFile fileHandle;
|
DownloadedFile fileHandle;
|
||||||
#ifdef ENABLE_LIBARIA2
|
|
||||||
try {
|
try {
|
||||||
std::vector<std::string> uris = {url};
|
std::vector<std::string> uris = {url};
|
||||||
aria2::KeyVals options;
|
std::vector<std::string> status_key = {"status", "files"};
|
||||||
aria2::A2Gid gid;
|
std::string gid;
|
||||||
int ret;
|
|
||||||
DownloadedFile fileHandle;
|
|
||||||
|
|
||||||
ret = aria2::addUri(session, &gid, uris, options);
|
gid = mp_aria->addUri(uris);
|
||||||
if (ret < 0) {
|
std::cerr << "gid is : " << gid << std::endl;
|
||||||
std::cerr << "Failed to download" << std::endl;
|
pugi::xml_document ret;
|
||||||
} else {
|
while(true) {
|
||||||
this->fileHandle = &fileHandle;
|
auto strStatus = mp_aria->tellStatus(gid, status_key);
|
||||||
aria2::run(session, aria2::RUN_DEFAULT);
|
MethodResponse response(strStatus);
|
||||||
|
auto structNode = response.getParams().getParam(0).getValue().getStruct();
|
||||||
|
auto status = structNode.getMember("status").getValue().getAsS();
|
||||||
|
std::cerr << "Status is " << status << std::endl;
|
||||||
|
if (status == "complete") {
|
||||||
|
fileHandle.success = true;
|
||||||
|
auto filesMember = structNode.getMember("files");
|
||||||
|
auto fileStruct = filesMember.getValue().getArray().getValue(0).getStruct();
|
||||||
|
fileHandle.path = fileStruct.getMember("path").getValue().getAsS();
|
||||||
|
std::cerr << "FilePath is " << fileHandle.path << std::endl;
|
||||||
|
} else if (status == "error") {
|
||||||
|
fileHandle.success = false;
|
||||||
|
} else {
|
||||||
|
// [TODO] Be wise here.
|
||||||
|
std::this_thread::sleep_for(std::chrono::microseconds(100000));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} catch (...) {};
|
} catch (...) { std::cerr << "waautena " << std::endl; };
|
||||||
this->fileHandle = nullptr;
|
|
||||||
pthread_mutex_unlock(&globalLock);
|
|
||||||
#endif
|
|
||||||
return fileHandle;
|
return fileHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ bool Manager::parseOpdsDom(const pugi::xml_document& doc, const std::string& url
|
||||||
|
|
||||||
if (rel == "http://opds-spec.org/image/thumbnail") {
|
if (rel == "http://opds-spec.org/image/thumbnail") {
|
||||||
auto faviconUrl = urlHost + linkNode.attribute("href").value();
|
auto faviconUrl = urlHost + linkNode.attribute("href").value();
|
||||||
auto downloader = Downloader();
|
Downloader downloader;
|
||||||
auto fileHandle = downloader.download(faviconUrl);
|
auto fileHandle = downloader.download(faviconUrl);
|
||||||
if (fileHandle.success) {
|
if (fileHandle.success) {
|
||||||
auto content = getFileContent(fileHandle.path);
|
auto content = getFileContent(fileHandle.path);
|
||||||
|
|
Loading…
Reference in New Issue