mirror of
https://github.com/kiwix/kiwix-tools.git
synced 2026-10-02 19:55:41 +00:00
Recursively scan directories for ZIM files in kiwix-serve
- Support directory paths as positional PATH arguments in kiwix-serve - Recursively add all ZIM files found within specified directories - Unify USAGE, man page, and RST documentation to use PATH ... - Handle filesystem errors gracefully when directories are inaccessible Co-authored-by: Lakshya <162354839+lakshyajn@users.noreply.github.com>
This commit is contained in:
parent
af8d5def58
commit
b59f42d67f
3 changed files with 53 additions and 17 deletions
|
|
@ -25,7 +25,8 @@ Usage
|
|||
.. code-block:: sh
|
||||
|
||||
kiwix-serve --library [OPTIONS] LIBRARY_FILE_PATH
|
||||
kiwix-serve [OPTIONS] ZIM_FILE_PATH ...
|
||||
kiwix-serve [OPTIONS] PATH ...
|
||||
|
||||
|
||||
|
||||
Arguments
|
||||
|
|
@ -37,7 +38,9 @@ Arguments
|
|||
to serve. To be used only with the :option:`--library` option. Multiple
|
||||
library files can be provided as a semicolon (``;``) separated list.
|
||||
|
||||
``ZIM_FILE_PATH``: ZIM file path (multiple arguments are allowed).
|
||||
``PATH``: a ZIM file path or a directory path. When a directory is given, all
|
||||
ZIM files under that directory are used. Multiple arguments are allowed.
|
||||
|
||||
|
||||
Options
|
||||
-------
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ kiwix-serve \- Kiwix HTTP Server
|
|||
|
||||
.B kiwix-serve --library [OPTIONS] LIBRARY_FILE_PATH
|
||||
.br
|
||||
.B kiwix-serve [OPTIONS] ZIM_FILE_PATH ...
|
||||
.B kiwix-serve [OPTIONS] PATH ...
|
||||
|
||||
|
||||
.SH DESCRIPTION
|
||||
The \fBkiwix-serve\fR command is used to run a stand-alone HTTP server for serving ZIM contents over the network.
|
||||
|
|
@ -18,8 +19,10 @@ The \fBkiwix-serve\fR command is used to run a stand-alone HTTP server for servi
|
|||
Path of a library file (XML or OPDS) listing ZIM files to serve. To be used only with the --library option. Multiple library files can be provided as a semicolon (;) separated list.
|
||||
|
||||
.TP
|
||||
\fBZIM_FILE_PATH ...\fR
|
||||
ZIM file path(s). Multiple arguments are allowed.
|
||||
\fBPATH ...\fR
|
||||
A ZIM file path or a directory path. When a directory path is provided, all ZIM
|
||||
files under that directory are used. Multiple arguments are allowed.
|
||||
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
|
|
@ -123,6 +126,12 @@ Serve multiple ZIM files:
|
|||
.B kiwix-serve zim1.zim zim2.zim zim3.zim
|
||||
.fi
|
||||
|
||||
Serve ZIM files within a directory or directories:
|
||||
.sp
|
||||
.nf
|
||||
.B kiwix-serve zimDir1 zimDir2
|
||||
.fi
|
||||
|
||||
Serve ZIM files from a library:
|
||||
.sp
|
||||
.nf
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <kiwix/server.h>
|
||||
#include <kiwix/name_mapper.h>
|
||||
#include <kiwix/tools.h>
|
||||
#include <filesystem>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
|
|
@ -44,19 +45,20 @@
|
|||
#define LITERAL_AS_STR(A) #A
|
||||
#define AS_STR(A) LITERAL_AS_STR(A)
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
static const char USAGE[] =
|
||||
R"(Deliver ZIM file(s) articles via HTTP
|
||||
|
||||
Usage:
|
||||
kiwix-serve [options] ZIMPATH ...
|
||||
kiwix-serve [options] PATH ...
|
||||
kiwix-serve [options] (-l | --library) LIBRARYPATH
|
||||
kiwix-serve -h | --help
|
||||
kiwix-serve -V | --version
|
||||
|
||||
Mandatory arguments:
|
||||
LIBRARYPATH Library file path (XML or OPDS) listing ZIM file to serve. To be used only with the --library argument."
|
||||
ZIMPATH ZIM file path(s)
|
||||
PATH A ZIM file path or a directory path (in which case all ZIM files under that directory are used).
|
||||
|
||||
Options:
|
||||
-h --help Print this help
|
||||
|
|
@ -184,16 +186,38 @@ bool reloadLibrary(kiwix::Manager& mgr, const std::vector<std::string>& paths)
|
|||
}
|
||||
|
||||
void addPathsInManager(kiwix::Manager& manager, const std::vector<std::string>& paths,
|
||||
bool skipInvalid)
|
||||
bool skipInvalid, bool isVerboseFlag)
|
||||
{
|
||||
for (const auto& path : paths) {
|
||||
if (!manager.addBookFromPath(path, path, "", false)) {
|
||||
if (skipInvalid) {
|
||||
std::cerr << "Skipping invalid '" << path << "' ...continuing" << std::endl;
|
||||
} else {
|
||||
std::cerr << "Unable to add the ZIM file '" << path
|
||||
<< "' to the internal library." << std::endl;
|
||||
exit(1);
|
||||
std::error_code ec;
|
||||
const bool isDir = fs::is_directory(path, ec);
|
||||
|
||||
if (isDir) {
|
||||
// It's a directory - try to add all ZIM files inside it
|
||||
try {
|
||||
manager.addBooksFromDirectory(path, isVerboseFlag);
|
||||
} catch (const fs::filesystem_error& e) {
|
||||
if (skipInvalid) {
|
||||
std::cerr << "Skipping directory '" << path << "': "
|
||||
<< e.what() << "." << std::endl;
|
||||
} else {
|
||||
std::cerr << "Unable to scan directory '" << path << "': "
|
||||
<< e.what() << "." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not a directory: either a regular ZIM file, a nonexistent path, or
|
||||
// a path that could not be stat'd (e.g. permission denied on parent dir).
|
||||
// Delegate to addBookFromPath which will report a suitable error itself.
|
||||
if (!manager.addBookFromPath(path, path, "", false)) {
|
||||
if (skipInvalid) {
|
||||
std::cerr << "Skipping invalid path '" << path << "'." << std::endl;
|
||||
} else {
|
||||
std::cerr << "Unable to add '" << path
|
||||
<< "' to the internal library." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -286,7 +310,7 @@ int main(int argc, char** argv)
|
|||
STRING("--customIndex", customIndexPath)
|
||||
INT("--ipConnectionLimit", ipConnectionLimit, "IP connection limit must be an integer")
|
||||
INT("--searchLimit", searchLimit, "Search limit must be an integer")
|
||||
STRING_LIST("ZIMPATH", paths, "ZIMPATH must be a string list")
|
||||
STRING_LIST("PATH", paths, "PATH must be a string list")
|
||||
}
|
||||
|
||||
if (!errorString.empty()) {
|
||||
|
|
@ -320,7 +344,7 @@ int main(int argc, char** argv)
|
|||
<< "' is empty (or has only remote books)." << std::endl;
|
||||
}
|
||||
} else {
|
||||
addPathsInManager(manager, paths, skipInvalid);
|
||||
addPathsInManager(manager, paths, skipInvalid, isVerboseFlag);
|
||||
}
|
||||
auto libraryFileTimestamp = newestFileTimestamp(libraryPaths);
|
||||
auto curLibraryFileTimestamp = libraryFileTimestamp;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue