Merge pull request #1110 from kiwix/revert-1107-feature/data-directory

This commit is contained in:
Matthieu Gautier 2024-08-12 16:32:21 +02:00 committed by GitHub
commit cb0a2c234a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 96 additions and 18 deletions

View File

@ -172,12 +172,7 @@ class Downloader
typedef std::vector<std::pair<std::string, std::string>> Options; typedef std::vector<std::pair<std::string, std::string>> Options;
public: // functions public: // functions
/* Downloader();
* Create a new Downloader object.
*
* @param sessionFileDir: The directory where aria2 will store its session file.
*/
explicit Downloader(std::string sessionFileDir);
virtual ~Downloader(); virtual ~Downloader();
void close(); void close();
@ -196,11 +191,10 @@ class Downloader
* User should call `update` on the returned `Download` to have an accurate status. * User should call `update` on the returned `Download` to have an accurate status.
* *
* @param uri: The uri of the thing to download. * @param uri: The uri of the thing to download.
* @param downloadDir: The download directory where the thing should be stored (takes precedence over any "dir" in `options`).
* @param options: A series of pair <option_name, option_value> to pass to aria. * @param options: A series of pair <option_name, option_value> to pass to aria.
* @return: The newly created Download. * @return: The newly created Download.
*/ */
std::shared_ptr<Download> startDownload(const std::string& uri, const std::string& downloadDir, Options options = {}); std::shared_ptr<Download> startDownload(const std::string& uri, const Options& options = {});
/** /**
* Get a download corrsponding to a download id (did) * Get a download corrsponding to a download id (did)

View File

@ -45,6 +45,32 @@ typedef std::vector<std::string> FeedCategories;
*/ */
std::string getCurrentDirectory(); std::string getCurrentDirectory();
/**
* Return the data directory
*
* The data directory is the default directory where downloaded files
* should be saved (it can be overriden via the options parameter of
* `kiwix::Downloader::startDownload()`).
*
* Its path can vary and is determined as follows:
*
* * `$KIWIX_DATA_DIR` if `$KIWIX_DATA_DIR` environment variable set, *otherwise...*
* * On Windows:
*
* * `$APPDATA/kiwix` if environment variable `$APPDATA` set, *otherwise...*
* * `$USERPROFILE/kiwix` if environment variable `$USERPROFILE` set, *otherwise...*
*
* * On other Operating Systems:
*
* * `$XDG_DATA_HOME/kiwix` if environment variable `$XDG_DATA_HOME` set, *otherwise...*
* * `$HOME/.local/share/kiwx` if environment variable `$HOME` set, *otherwise...*
*
* * Current working directory.
*
* @return the path of the data directory (UTF-8 encoded)
*/
std::string getDataDirectory();
/** Return the path of the executable /** Return the path of the executable
* *
* Some application may be packaged in auto extractible archive (Appimage) and the * Some application may be packaged in auto extractible archive (Appimage) and the

View File

@ -55,15 +55,18 @@ void pauseAnyActiveDownloads(const std::string& ariaSessionFilePath)
} // unnamed namespace } // unnamed namespace
Aria2::Aria2(std::string sessionFileDir): Aria2::Aria2():
mp_aria(nullptr), mp_aria(nullptr),
m_port(42042), m_port(42042),
m_secret(getNewRpcSecret()) m_secret(getNewRpcSecret())
{ {
m_downloadDir = getDataDirectory();
makeDirectory(m_downloadDir);
std::vector<const char*> callCmd; std::vector<const char*> callCmd;
std::string rpc_port = "--rpc-listen-port=" + to_string(m_port); std::string rpc_port = "--rpc-listen-port=" + to_string(m_port);
std::string session_file = appendToDirectory(sessionFileDir, "kiwix.session"); std::string download_dir = "--dir=" + getDataDirectory();
std::string session_file = appendToDirectory(getDataDirectory(), "kiwix.session");
pauseAnyActiveDownloads(session_file); pauseAnyActiveDownloads(session_file);
std::string session = "--save-session=" + session_file; std::string session = "--save-session=" + session_file;
std::string inputFile = "--input-file=" + session_file; std::string inputFile = "--input-file=" + session_file;
@ -91,6 +94,7 @@ Aria2::Aria2(std::string sessionFileDir):
callCmd.push_back("--enable-rpc"); callCmd.push_back("--enable-rpc");
callCmd.push_back(rpc_secret.c_str()); callCmd.push_back(rpc_secret.c_str());
callCmd.push_back(rpc_port.c_str()); callCmd.push_back(rpc_port.c_str());
callCmd.push_back(download_dir.c_str());
if (fileReadable(session_file)) { if (fileReadable(session_file)) {
callCmd.push_back(inputFile.c_str()); callCmd.push_back(inputFile.c_str());
} }

View File

@ -22,10 +22,11 @@ class Aria2
std::unique_ptr<Subprocess> mp_aria; std::unique_ptr<Subprocess> mp_aria;
int m_port; int m_port;
std::string m_secret; std::string m_secret;
std::string m_downloadDir;
std::string doRequest(const MethodCall& methodCall); std::string doRequest(const MethodCall& methodCall);
public: public:
explicit Aria2(std::string sessionFileDir); Aria2();
virtual ~Aria2() = default; virtual ~Aria2() = default;
void close(); void close();

View File

@ -125,8 +125,8 @@ void Download::cancelDownload()
} }
/* Constructor */ /* Constructor */
Downloader::Downloader(std::string sessionFileDir) : Downloader::Downloader() :
mp_aria(new Aria2(sessionFileDir)) mp_aria(new Aria2())
{ {
try { try {
for (auto gid : mp_aria->tellWaiting()) { for (auto gid : mp_aria->tellWaiting()) {
@ -209,13 +209,9 @@ bool downloadCanBeReused(const Download& d,
} // unnamed namespace } // unnamed namespace
std::shared_ptr<Download> Downloader::startDownload(const std::string& uri, const std::string& downloadDir, Options options) std::shared_ptr<Download> Downloader::startDownload(const std::string& uri, const Options& options)
{ {
std::unique_lock<std::mutex> lock(m_lock); std::unique_lock<std::mutex> lock(m_lock);
options.erase(std::remove_if(options.begin(), options.end(), [](const auto& option) {
return option.first == "dir";
}), options.end());
options.push_back({"dir", downloadDir});
for (auto& p: m_knownDownloads) { for (auto& p: m_knownDownloads) {
auto& d = p.second; auto& d = p.second;
if ( downloadCanBeReused(*d, uri, options) ) if ( downloadCanBeReused(*d, uri, options) )

View File

@ -320,6 +320,16 @@ bool kiwix::fileReadable(const std::string& path)
#endif #endif
} }
bool makeDirectory(const std::string& path)
{
#ifdef _WIN32
int status = _wmkdir(Utf8ToWide(path).c_str());
#else
int status = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
#endif
return status == 0;
}
std::string makeTmpDirectory() std::string makeTmpDirectory()
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -428,6 +438,52 @@ std::string kiwix::getCurrentDirectory()
return ret; return ret;
} }
std::string kiwix::getDataDirectory()
{
// Try to get the dataDir from the `KIWIX_DATA_DIR` env var
#ifdef _WIN32
wchar_t* cDataDir = ::_wgetenv(L"KIWIX_DATA_DIR");
if (cDataDir != nullptr) {
return WideToUtf8(cDataDir);
}
#else
char* cDataDir = ::getenv("KIWIX_DATA_DIR");
if (cDataDir != nullptr) {
return cDataDir;
}
#endif
// Compute the dataDir from the user directory.
std::string dataDir;
#ifdef _WIN32
cDataDir = ::_wgetenv(L"APPDATA");
if (cDataDir == nullptr)
cDataDir = ::_wgetenv(L"USERPROFILE");
if (cDataDir != nullptr)
dataDir = WideToUtf8(cDataDir);
#else
cDataDir = ::getenv("XDG_DATA_HOME");
if (cDataDir != nullptr) {
dataDir = cDataDir;
} else {
cDataDir = ::getenv("HOME");
if (cDataDir != nullptr) {
dataDir = cDataDir;
dataDir = appendToDirectory(dataDir, ".local");
dataDir = appendToDirectory(dataDir, "share");
}
}
#endif
if (!dataDir.empty()) {
dataDir = appendToDirectory(dataDir, "kiwix");
makeDirectory(dataDir);
return dataDir;
}
// Let's use the currentDirectory
return getCurrentDirectory();
}
static std::map<std::string, std::string> extMimeTypes = { static std::map<std::string, std::string> extMimeTypes = {
{ "html", "text/html"}, { "html", "text/html"},
{ "htm", "text/html"}, { "htm", "text/html"},

View File

@ -29,6 +29,7 @@ std::wstring Utf8ToWide(const std::string& str);
unsigned int getFileSize(const std::string& path); unsigned int getFileSize(const std::string& path);
std::string getFileSizeAsString(const std::string& path); std::string getFileSizeAsString(const std::string& path);
bool makeDirectory(const std::string& path);
std::string makeTmpDirectory(); std::string makeTmpDirectory();
bool copyFile(const std::string& sourcePath, const std::string& destPath); bool copyFile(const std::string& sourcePath, const std::string& destPath);
bool writeTextFile(const std::string& path, const std::string& content); bool writeTextFile(const std::string& path, const std::string& content);