mirror of
https://github.com/kiwix/kiwix-tools.git
synced 2026-01-17 18:37:44 -05:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d82f9e7d5e | ||
|
|
720a319d53 | ||
|
|
2426c35547 | ||
|
|
794f63e22b | ||
|
|
79a64d5af3 | ||
|
|
2ef160bcad | ||
|
|
817a5d4847 | ||
|
|
2c3882671b | ||
|
|
7e2c5bda03 | ||
|
|
59281bf496 | ||
|
|
ee9ae0e81f | ||
|
|
2dbe0a0016 | ||
|
|
64717c2124 | ||
|
|
fc1eb3c282 | ||
|
|
e31c1cd9a3 | ||
|
|
e897dd4e59 | ||
|
|
7db7d2a2ab | ||
|
|
5b612e67bd | ||
|
|
df047588a9 | ||
|
|
9dede26717 | ||
|
|
a22ae3d467 | ||
|
|
ea93a8a195 | ||
|
|
0a7f375f3a | ||
|
|
66c35b7b3e | ||
|
|
bad7f2ddf1 | ||
|
|
758014a5ba | ||
|
|
4fd961a761 | ||
|
|
c063587a69 | ||
|
|
9b24676b02 | ||
|
|
fc5572f495 | ||
|
|
a1b3f46e4e | ||
|
|
e0177c4923 | ||
|
|
a365c1e720 | ||
|
|
3e97352128 | ||
|
|
78d2530878 | ||
|
|
d09f481b47 | ||
|
|
e0f07086d5 | ||
|
|
bbff57e6aa | ||
|
|
3c24d0a026 | ||
|
|
6107bad17e | ||
|
|
5931ac45c4 | ||
|
|
4de8623a52 | ||
|
|
6eace310a2 | ||
|
|
c6499ad5c6 | ||
|
|
34ceaf37f2 | ||
|
|
f05096e2ce | ||
|
|
3864b2404c | ||
|
|
4cd74dca4b | ||
|
|
88cea54520 | ||
|
|
3061c8bba3 | ||
|
|
2774eb9529 | ||
|
|
77dc2ef2ed | ||
|
|
17d11f9772 | ||
|
|
68ac06c397 | ||
|
|
99f6941614 | ||
|
|
848d058610 |
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: https://kiwix.org/support-us/
|
||||
@@ -1,6 +1,6 @@
|
||||
language: cpp
|
||||
dist: trusty
|
||||
sudo: required
|
||||
dist: xenial
|
||||
sudo: true
|
||||
cache: ccache
|
||||
install: travis/install_deps.sh
|
||||
script: travis/compile.sh
|
||||
|
||||
38
Changelog
38
Changelog
@@ -1,3 +1,41 @@
|
||||
kiwix-tools 2.1.0
|
||||
=================
|
||||
|
||||
* Fix few compilation errors.
|
||||
|
||||
kiwix-serve
|
||||
-----------
|
||||
|
||||
* Use new api to filter the library.
|
||||
* Mobile friendly top bar.
|
||||
* Add notag parameter to be able to exclude tags from the zim search.
|
||||
|
||||
|
||||
kiwix-tools 2.0.0
|
||||
=================
|
||||
|
||||
kiwix-manage
|
||||
-----------
|
||||
|
||||
* Better usage()
|
||||
* Adding multiple files bug fix
|
||||
* Remove download command.
|
||||
|
||||
kiwix-serve
|
||||
-----------
|
||||
|
||||
* Better usage()
|
||||
* Display properly welcome page on 3 columns
|
||||
* New welcome page footer "Powered by Kiwix"
|
||||
|
||||
kiwix-tools 1.2.1
|
||||
=================
|
||||
|
||||
kiwix-serve
|
||||
-----------
|
||||
|
||||
* Always use POLL when avaible.
|
||||
|
||||
kiwix-tools 1.2.0
|
||||
=================
|
||||
|
||||
|
||||
21
README.md
21
README.md
@@ -1,7 +1,11 @@
|
||||
Kiwix tools
|
||||
===========
|
||||
|
||||
The Kiwix tools is a collection of Kiwix related command line tools.
|
||||
The Kiwix tools is a collection of Kiwix related command line tools:
|
||||
* kiwix-manage: Manage XML based library of ZIM files
|
||||
* kiwix-read: Read ZIM file content
|
||||
* kiwix-search: Fulltext search in ZIM files
|
||||
* kiwix-serve: HTTP daemon serving ZIM files
|
||||
|
||||
Disclaimer
|
||||
----------
|
||||
@@ -26,14 +30,9 @@ The Kiwix tools rely on a few third party software libraries. They are
|
||||
prerequisites to the Kiwix tools compilation. Therefore, following
|
||||
libraries need to be available:
|
||||
|
||||
* Kiwix lib ....................... https://github.com/kiwix/kiwix-lib
|
||||
(no package so far)
|
||||
* Libmicrohttpd .......... https://www.gnu.org/software/libmicrohttpd/
|
||||
(package libmicrohttpd-dev on Ubuntu)
|
||||
* CTPP2 ..................................... http://ctpp.havoc.ru/en/
|
||||
(package libctpp2-dev on Ubuntu)
|
||||
* Zlib .......................................... http://www.zlib.net/
|
||||
(package zlib1g-dev on Ubuntu)
|
||||
* [Kiwix lib](https://github.com/kiwix/kiwix-lib) (no package so far)
|
||||
* [Libmicrohttpd](https://www.gnu.org/software/libmicrohttpd/) (package libmicrohttpd-dev on Ubuntu)
|
||||
* [Zlib](https://www.zlib.net/) (package zlib1g-dev on Ubuntu)
|
||||
|
||||
These dependencies may or may not be packaged by your operating
|
||||
system. They may also be packaged but only in an older version. They
|
||||
@@ -46,7 +45,7 @@ If you want to install these dependencies locally, then use the
|
||||
kiwix-tools directory as install prefix.
|
||||
|
||||
If you want to compile Kiwix tools statically, the dependencies should
|
||||
be compile statically (provide a lib...a library), for example by
|
||||
be compiled statically (provide a lib...a library), for example by
|
||||
using "--enable-static" with "./configure".
|
||||
|
||||
If you compile manually Libmicrohttpd, you might need to compile it
|
||||
@@ -57,7 +56,7 @@ Environment
|
||||
-------------
|
||||
|
||||
The Kiwix tools build using [Meson](http://mesonbuild.com/) version
|
||||
0.39 or higher. Meson relies itself on Ninja, pkg-config and few other
|
||||
0.43 or higher. Meson relies itself on Ninja, pkg-config and few other
|
||||
compilation tools. Install them first:
|
||||
* Meson
|
||||
* Ninja
|
||||
|
||||
@@ -4,7 +4,7 @@ LABEL maintainer Emmanuel Engelhart <kelson@kiwix.org>
|
||||
# Install kiwix-serve
|
||||
WORKDIR /
|
||||
RUN apk add --no-cache curl bzip2
|
||||
RUN curl -kL https://download.kiwix.org/release/kiwix-tools/kiwix-tools_linux-x86_64-1.1.0.tar.gz | tar -xz && \
|
||||
RUN curl -kL https://download.kiwix.org/release/kiwix-tools/kiwix-tools_linux-x86_64-1.2.1.tar.gz | tar -xz && \
|
||||
mv kiwix-tools*/kiwix-serve /usr/local/bin && \
|
||||
rm -r kiwix-tools*
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
project('kiwix-tools', 'cpp',
|
||||
version : '1.2.0',
|
||||
version : '2.1.0',
|
||||
license : 'GPL',
|
||||
default_options: ['c_std=c11', 'cpp_std=c++11', 'werror=true'])
|
||||
|
||||
@@ -11,7 +11,7 @@ if static_linkage
|
||||
endif
|
||||
|
||||
thread_dep = dependency('threads')
|
||||
kiwixlib_dep = dependency('kiwix', version:'>=4.1.0', static:static_linkage)
|
||||
kiwixlib_dep = dependency('kiwix', version:'>=5.2.0', static:static_linkage)
|
||||
microhttpd_dep = dependency('libmicrohttpd', static:static_linkage)
|
||||
z_dep = dependency('zlib', static:static_linkage)
|
||||
|
||||
|
||||
@@ -17,23 +17,15 @@
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <getopt.h>
|
||||
#include <kiwix/tools/pathTools.h>
|
||||
#include <kiwix/tools/stringTools.h>
|
||||
#include <kiwix/manager.h>
|
||||
#include <kiwix/downloader.h>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum supportedAction { NONE, ADD, SHOW, REMOVE, DOWNLOAD };
|
||||
enum supportedAction { NONE, ADD, SHOW, REMOVE };
|
||||
|
||||
void show(kiwix::Library* library, const std::string& bookId)
|
||||
{
|
||||
@@ -57,21 +49,49 @@ void show(kiwix::Library* library, const std::string& bookId)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
/* Print correct console usage options */
|
||||
void usage()
|
||||
{
|
||||
cerr << "Usage:" << endl;
|
||||
cerr << "\tkiwix-manage LIBRARY_PATH add ZIM_PATH "
|
||||
"[--zimPathToSave=../content/foobar.zim] [--current] "
|
||||
"[--url=http://...metalink]"
|
||||
<< endl;
|
||||
cerr << "\tkiwix-manage LIBRARY_PATH show [CONTENTID1] [CONTENTID2] ... "
|
||||
"(show everything if no param.)"
|
||||
<< endl;
|
||||
cerr << "\tkiwix-manage LIBRARY_PATH remove CONTENTID1 [CONTENTID2]" << endl;
|
||||
std::cout << "Usage:" << std::endl
|
||||
<< "\tkiwix-manage LIBRARY_PATH add ZIM_PATH [OPTIONS]" << std::endl
|
||||
<< "\tkiwix-manage LIBRARY_PATH remove ZIM_ID [ZIM_ID]..." << std::endl
|
||||
<< "\tkiwix-manage LIBRARY_PATH show [ZIM_ID]..." << std::endl
|
||||
<< std::endl
|
||||
|
||||
<< "Purpose:" << std::endl
|
||||
<< "\tManipulates the Kiwix library XML file"
|
||||
<< std::endl << std::endl
|
||||
|
||||
<< "Arguments:" << std::endl
|
||||
<< "\tLIBRARY_PATH\tis the XML library file path."
|
||||
<< std::endl << std::endl
|
||||
<< "\tACTION\t\tis the pre-defined string to specify the action to run on the XML library file."
|
||||
<< std::endl << std::endl
|
||||
<< "\t\t\tMust be one of the following values:" << std::endl
|
||||
<< "\t\t\t* add: add a ZIM file to the library" << std::endl
|
||||
<< "\t\t\t* remove: remove a ZIM file from the library" << std::endl
|
||||
<< "\t\t\t* show: show the content of the library"
|
||||
<< std::endl << std::endl
|
||||
<< "\tZIM_ID\t\tZIM file unique ID"
|
||||
<< std::endl << std::endl
|
||||
<< "\tOPTIONS\t\tCustom options for \"add\" action:" << std::endl
|
||||
<< "\t\t\t--zimPathToSave=CUSTOM_ZIM_PATH to replace the current ZIM file path" << std::endl
|
||||
<< "\t\t\t--url=HTTP_ZIM_URL to create an \"url\" attribute for the online version of the ZIM file" << std::endl
|
||||
<< std::endl
|
||||
|
||||
<< "Examples:" << std::endl
|
||||
<< "\tAdd ZIM files to library: kiwix-manage my_library.xml add first.zim second.zim" << std::endl
|
||||
<< "\tRemove ZIM files from library: kiwix-manage my_library.xml remove e5c2c003-b49e-2756-5176-5d9c86393dd9" << std::endl
|
||||
<< "\tShow all library ZIM files: kiwix-manage my_library.xml show" << std::endl
|
||||
<< std::endl
|
||||
|
||||
<< "Documentation:" << std::endl
|
||||
<< "\tSource code\thttps://github.com/kiwix/kiwix-tools" << std::endl
|
||||
<< "\tMore info\thttps://wiki.kiwix.org/wiki/Kiwix-manage" << std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
||||
bool handle_show(kiwix::Library* library, const std::string& libraryPath,
|
||||
int handle_show(kiwix::Library* library, const std::string& libraryPath,
|
||||
int argc, char* argv[])
|
||||
{
|
||||
if (argc > 3 ) {
|
||||
@@ -88,7 +108,7 @@ bool handle_show(kiwix::Library* library, const std::string& libraryPath,
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool handle_add(kiwix::Library* library, const std::string& libraryPath,
|
||||
int handle_add(kiwix::Library* library, const std::string& libraryPath,
|
||||
int argc, char* argv[])
|
||||
{
|
||||
string zimPath;
|
||||
@@ -97,7 +117,7 @@ bool handle_add(kiwix::Library* library, const std::string& libraryPath,
|
||||
string origID = "";
|
||||
int option_index = 0;
|
||||
int c = 0;
|
||||
bool resultCode = 0;
|
||||
int resultCode = 0;
|
||||
|
||||
if (argc <= 3) {
|
||||
std::cerr << "Path to zim file to add is missing in the command line" << std::endl;
|
||||
@@ -150,8 +170,8 @@ bool handle_add(kiwix::Library* library, const std::string& libraryPath,
|
||||
for(auto i=optind; i<argc; i++) {
|
||||
std::string zimPath = argv[i];
|
||||
if (!zimPath.empty()) {
|
||||
zimPathToSave = zimPathToSave == "." ? zimPath : zimPathToSave;
|
||||
manager.addBookFromPathAndGetId(zimPath, zimPathToSave, url, false);
|
||||
auto _zimPathToSave = zimPathToSave == "." ? zimPath : zimPathToSave;
|
||||
manager.addBookFromPathAndGetId(zimPath, _zimPathToSave, url, false);
|
||||
} else {
|
||||
std::cerr << "Invalid zim file path" << std::endl;
|
||||
resultCode = 1;
|
||||
@@ -161,12 +181,12 @@ bool handle_add(kiwix::Library* library, const std::string& libraryPath,
|
||||
return(resultCode);
|
||||
}
|
||||
|
||||
bool handle_remove(kiwix::Library* library, const std::string& libraryPath,
|
||||
int handle_remove(kiwix::Library* library, const std::string& libraryPath,
|
||||
int argc, char* argv[])
|
||||
{
|
||||
std::string bookId;
|
||||
const unsigned int totalBookCount = library->getBookCount(true, true);
|
||||
bool exitCode = 0;
|
||||
int exitCode = 0;
|
||||
|
||||
if (argc <= 3) {
|
||||
std::cerr << "BookId to remove missing in the command line" << std::endl;
|
||||
@@ -191,62 +211,6 @@ bool handle_remove(kiwix::Library* library, const std::string& libraryPath,
|
||||
return(exitCode);
|
||||
}
|
||||
|
||||
bool handle_download(kiwix::Library* library, const std::string& libraryPath,
|
||||
int argc, char* argv[])
|
||||
{
|
||||
std::string bookId;
|
||||
bool exitCode = false;
|
||||
|
||||
if (argc > 3) {
|
||||
bookId = argv[3];
|
||||
}
|
||||
|
||||
auto& book = library->getBookById(bookId);
|
||||
auto did = book.getDownloadId();
|
||||
kiwix::Downloader downloader;
|
||||
kiwix::Download* download = nullptr;
|
||||
if (!did.empty()) {
|
||||
std::cout << "try resume " << did << std::endl;
|
||||
try {
|
||||
download = downloader.getDownload(did);
|
||||
} catch(...) {}
|
||||
}
|
||||
if (nullptr == download || download->getStatus() == kiwix::Download::K_UNKNOWN) {
|
||||
download = downloader.startDownload(book.getUrl());
|
||||
book.setDownloadId(download->getDid());
|
||||
}
|
||||
int step = 60*5;
|
||||
while (step--) {
|
||||
download->updateStatus();
|
||||
if (download->getStatus() == kiwix::Download::K_COMPLETE) {
|
||||
auto followingId = download->getFollowedBy();
|
||||
if (followingId.empty()) {
|
||||
book.setPath(download->getPath());
|
||||
book.setDownloadId("");
|
||||
std::cout << "File downloaded to " << book.getPath() << std::endl;
|
||||
break;
|
||||
} else {
|
||||
download = downloader.getDownload(followingId);
|
||||
}
|
||||
} else if (download->getStatus() == kiwix::Download::K_ACTIVE) {
|
||||
std::cout << download->getDid() << " : "
|
||||
<< kiwix::beautifyFileSize(download->getCompletedLength()) << "/"
|
||||
<< kiwix::beautifyFileSize(download->getTotalLength())
|
||||
<< " (" << kiwix::beautifyFileSize(download->getDownloadSpeed()) << "/s) "
|
||||
<< " [" << kiwix::beautifyFileSize(download->getVerifiedLength()) << "]"
|
||||
<< "[" << step << "] \n" << std::flush;
|
||||
} else if (download->getStatus() == kiwix::Download::K_ERROR) {
|
||||
std::cout << "File Error" << std::endl;
|
||||
exitCode = true;
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
|
||||
downloader.close();
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
string libraryPath = "";
|
||||
@@ -264,8 +228,6 @@ int main(int argc, char** argv)
|
||||
action = SHOW;
|
||||
else if (actionString == "remove" || actionString == "delete")
|
||||
action = REMOVE;
|
||||
else if (actionString == "download")
|
||||
action = DOWNLOAD;
|
||||
}
|
||||
|
||||
/* Print usage)) if necessary */
|
||||
@@ -282,7 +244,7 @@ int main(int argc, char** argv)
|
||||
manager.readFile(libraryPath, false);
|
||||
|
||||
/* SHOW */
|
||||
bool exitCode = 0;
|
||||
int exitCode = 0;
|
||||
switch (action) {
|
||||
case SHOW:
|
||||
exitCode = handle_show(&library, libraryPath, argc, argv);
|
||||
@@ -293,15 +255,12 @@ int main(int argc, char** argv)
|
||||
case REMOVE:
|
||||
exitCode = handle_remove(&library, libraryPath, argc, argv);
|
||||
break;
|
||||
case DOWNLOAD:
|
||||
exitCode = handle_download(&library, libraryPath, argc, argv);
|
||||
break;
|
||||
case NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Rewrite the library file */
|
||||
if (action == REMOVE || action == ADD || action == DOWNLOAD) {
|
||||
if (action == REMOVE || action == ADD) {
|
||||
library.writeToFile(libraryPath);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <getopt.h>
|
||||
#include <kiwix/reader.h>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <getopt.h>
|
||||
#include <kiwix/reader.h>
|
||||
#include <kiwix/searcher.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
void usage()
|
||||
|
||||
@@ -67,7 +67,6 @@ extern "C" {
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "server-resources.h"
|
||||
@@ -80,7 +79,6 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "request_context.h"
|
||||
@@ -106,6 +104,7 @@ static kiwix::Library library;
|
||||
static pthread_mutex_t searchLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t compressorLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t regexLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static unsigned int nb_threads = 4;
|
||||
|
||||
std::pair<kiwix::Reader*, kiwix::Searcher*>
|
||||
get_from_humanReadableBookId(const std::string& humanReadableBookId) {
|
||||
@@ -694,12 +693,12 @@ static struct MHD_Response* handle_catalog(RequestContext* request)
|
||||
opdsDumper.setTitle("All zims");
|
||||
uuid = zim::Uuid::generate(host);
|
||||
|
||||
bookIdsToDump = library.listBooksIds(
|
||||
kiwix::VALID|kiwix::LOCAL|kiwix::REMOTE);
|
||||
bookIdsToDump = library.filter(kiwix::Filter().valid(true).local(true).remote(true));
|
||||
} else if (url == "search") {
|
||||
std::string query;
|
||||
std::string language;
|
||||
std::vector<std::string> tags;
|
||||
std::vector<std::string> noTags;
|
||||
size_t count(10);
|
||||
size_t startIndex(0);
|
||||
try {
|
||||
@@ -715,18 +714,20 @@ static struct MHD_Response* handle_catalog(RequestContext* request)
|
||||
startIndex = stoul(request->get_argument("start"));
|
||||
} catch (...) {}
|
||||
try {
|
||||
tags.push_back(request->get_argument("tag"));
|
||||
tags = kiwix::split(request->get_argument("notag"), ";");
|
||||
} catch (...) {}
|
||||
try {
|
||||
noTags = kiwix::split(request->get_argument("notag"), ";");
|
||||
} catch (...) {}
|
||||
opdsDumper.setTitle("Search result for " + query);
|
||||
uuid = zim::Uuid::generate();
|
||||
bookIdsToDump = library.listBooksIds(
|
||||
kiwix::VALID|kiwix::LOCAL|kiwix::REMOTE,
|
||||
kiwix::UNSORTED,
|
||||
query,
|
||||
language,
|
||||
"", // creator
|
||||
"", // publisher
|
||||
tags);
|
||||
bookIdsToDump = library.filter(
|
||||
kiwix::Filter().valid(true).local(true).remote(true)
|
||||
.query(query)
|
||||
.lang(language)
|
||||
.acceptTags(tags)
|
||||
.rejectTags(noTags)
|
||||
);
|
||||
auto totalResults = bookIdsToDump.size();
|
||||
bookIdsToDump.erase(bookIdsToDump.begin(), bookIdsToDump.begin()+startIndex);
|
||||
if (count>0 && bookIdsToDump.size() > count) {
|
||||
@@ -937,6 +938,42 @@ bool hasHumanReadableIdCollision(const string &humanReadableId,
|
||||
return false;
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
std::cout << "Usage:" << std::endl
|
||||
<< "\tkiwix-serve [OPTIONS] ZIM_PATH+" << std::endl
|
||||
<< "\tkiwix-serve --library [OPTIONS] LIBRARY_PATH" << std::endl
|
||||
<< std::endl
|
||||
|
||||
<< "Purpose:" << std::endl
|
||||
<< "\tDeliver ZIM file articles via HTTP"
|
||||
<< std::endl << std::endl
|
||||
|
||||
<< "Mandatory arguments:" << std::endl
|
||||
<< "\tLIBRARY_PATH\t\tis the XML library file path listing ZIM file to serve. To be used only with the --library argument."
|
||||
<< std::endl
|
||||
<< "\tZIM_PATH\t\tis the path of a ZIM file."
|
||||
<< std::endl << std::endl
|
||||
|
||||
<< "Optional arguments:" << std::endl
|
||||
<< "\t-a, --attachToProcess\texit if given process id is not running anymore" << std::endl
|
||||
<< "\t-d, --daemon\t\tdetach the HTTP server daemon from the main process" << std::endl
|
||||
<< "\t-f, --interface\t\tlisten only on this interface, all available ones otherwise (POSIX only)" << std::endl
|
||||
<< "\t-m, --nolibrarybutton\tdo not print the builtin home button in the builtin top bar overlay" << std::endl
|
||||
<< "\t-n, --nosearchbar\tdo not print the builtin bar overlay on the top of each served page" << std::endl
|
||||
<< "\t-p, --port\t\tTCP port on which to listen to HTTP requests (default: 80)" << std::endl
|
||||
<< "\t-r, --urlRootLocation\tURL prefix on which the content should be made available (default: /)" << std::endl
|
||||
<< "\t-t, --threads\t\tnumber of threads to run in parallel (default: " << nb_threads << ")" << std::endl
|
||||
<< "\t-v, --verbose\t\tprint debug log to STDOUT" << std::endl
|
||||
<< "\t-z, --nodatealiases\tcreate URL aliases for each content by removing the date" << std::endl
|
||||
<< std::endl
|
||||
|
||||
<< "Documentation:" << std::endl
|
||||
<< "\tSource code\t\thttps://github.com/kiwix/kiwix-tools" << std::endl
|
||||
<< "\tMore info\t\thttps://wiki.kiwix.org/wiki/Kiwix-serve" << std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
struct MHD_Daemon* daemon;
|
||||
@@ -949,7 +986,6 @@ int main(int argc, char** argv)
|
||||
int libraryFlag = false;
|
||||
string PPIDString;
|
||||
unsigned int PPID = 0;
|
||||
unsigned int nb_threads = std::thread::hardware_concurrency();
|
||||
|
||||
static struct option long_options[]
|
||||
= {{"daemon", no_argument, 0, 'd'},
|
||||
@@ -1034,20 +1070,7 @@ int main(int argc, char** argv)
|
||||
|
||||
/* Print usage)) if necessary */
|
||||
if (zimPathes.empty() && libraryPath.empty()) {
|
||||
cerr << "Usage: kiwix-serve [--index=INDEX_PATH] [--port=PORT] [--verbose] "
|
||||
"[--nosearchbar] [--nolibrarybutton] [--nodatealiases] [--daemon] "
|
||||
"[--attachToProcess=PID] [--interface=IF_NAME] "
|
||||
"[--urlRootLocation=/URL_ROOT] "
|
||||
"[--threads=NB_THREAD(" << nb_threads << ")] ZIM_PATH+"
|
||||
<< endl;
|
||||
cerr << " kiwix-serve --library [--port=PORT] [--verbose] [--daemon] "
|
||||
"[--nosearchbar] [--nolibrarybutton] [--nodatealiases] [--attachToProcess=PID] "
|
||||
"[--interface=IF_NAME] [--urlRootLocation=/URL_ROOT] "
|
||||
"[--threads=NB_THREAD(" << nb_threads << ")] LIBRARY_PATH "
|
||||
<< endl;
|
||||
cerr << "\n If you set more than one ZIM_PATH, you cannot set a "
|
||||
"INDEX_PATH."
|
||||
<< endl;
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -1096,7 +1119,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
/* Instance the readers and searcher and build the corresponding maps */
|
||||
vector<string> booksIds = library.listBooksIds(kiwix::LOCAL);
|
||||
vector<string> booksIds = library.filter(kiwix::Filter().local(true));
|
||||
globalSearcher = new kiwix::Searcher();
|
||||
globalSearcher->setProtocolPrefix(rootLocation + "/");
|
||||
globalSearcher->setSearchProtocolPrefix(rootLocation + "/" + "search?");
|
||||
@@ -1270,7 +1293,10 @@ int main(int argc, char** argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
daemon = MHD_start_daemon(MHD_USE_POLL_INTERNALLY,
|
||||
int flags = MHD_USE_POLL_INTERNALLY;
|
||||
if (isVerbose.load())
|
||||
flags |= MHD_USE_DEBUG;
|
||||
daemon = MHD_start_daemon(flags,
|
||||
serverPort,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -1285,7 +1311,15 @@ int main(int argc, char** argv)
|
||||
#endif
|
||||
|
||||
} else {
|
||||
daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY,
|
||||
#ifdef _WIN32
|
||||
int flags = MHD_USE_SELECT_INTERNALLY;
|
||||
#else
|
||||
int flags = MHD_USE_POLL_INTERNALLY;
|
||||
#endif
|
||||
if (isVerbose.load())
|
||||
flags |= MHD_USE_DEBUG;
|
||||
|
||||
daemon = MHD_start_daemon(flags,
|
||||
serverPort,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
BIN
static/server/caret.png
Normal file
BIN
static/server/caret.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -1,13 +1,13 @@
|
||||
<span class="kiwix">
|
||||
<span id="kiwixtoolbar" class="ui-widget-header">
|
||||
<div class="kiwix_centered">
|
||||
<div class="kiwix_searchform">
|
||||
<div class="kiwix_searchform" style="margin: auto auto;float: none;">
|
||||
<form class="kiwixsearch" method="GET" action="__ROOT_LOCATION__/search" id="kiwixsearchform">
|
||||
<label for="kiwixsearchbox" style="line-height: 30px;">🔍</label>
|
||||
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
|
||||
<input type="submit" value="🔍">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
<div style="display: block; height: 5em;"></div>
|
||||
<div style="display: block; height: 5em;"></div>
|
||||
@@ -18,7 +18,7 @@
|
||||
background-size:16px 16px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 65.8em;
|
||||
max-width: 1100px;
|
||||
}
|
||||
.book__list { text-align: center; }
|
||||
.book {
|
||||
@@ -40,16 +40,17 @@
|
||||
}
|
||||
.book__info { line-height: 18px; color: #777; font-weight: bold; font-size: 13px; }
|
||||
</style>
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#accordion" ).accordion();
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="__ROOT_LOCATION__/skin/taskbar.js" async></script>
|
||||
</head>
|
||||
<body class="kiwix">
|
||||
|
||||
<div class="kiwix">
|
||||
__BOOKS__
|
||||
</div>
|
||||
|
||||
<div id="kiwixfooter">
|
||||
Powered by <a href="https://kiwix.org">Kiwix</a>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -25,3 +25,4 @@
|
||||
jk("html").addClass("cybook");
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="__ROOT_LOCATION__/skin/taskbar.js" async></script>
|
||||
@@ -19,6 +19,8 @@ jquery-ui/jquery-ui.theme.min.css
|
||||
jquery-ui/jquery-ui.min.css
|
||||
home.html.tmpl
|
||||
include.html.part
|
||||
caret.png
|
||||
taskbar.js
|
||||
taskbar.css
|
||||
taskbar.html.part
|
||||
global_taskbar.html.part
|
||||
|
||||
@@ -1,34 +1,89 @@
|
||||
#kiwixtoolbar {
|
||||
position: fixed;
|
||||
padding: .5em;
|
||||
left:0;
|
||||
right:0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index:100;
|
||||
z-index: 100;
|
||||
background-position-y: 0px;
|
||||
transition: 0.3s;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#kiwixtoolbar > a {
|
||||
#kiwixtoolbar>a {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#kiwixfooter {
|
||||
text-align: center;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.height_separator {
|
||||
height: 3em;
|
||||
}
|
||||
|
||||
#kiwixsearchbox {
|
||||
.kiwixsearch {
|
||||
position: relative;
|
||||
height: 26px;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.kiwix_searchform {
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
#kiwix_serve_taskbar_home_button button {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 160px;
|
||||
}
|
||||
|
||||
.kiwix .kiwix_centered {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.kiwix .kiwix_button_wrapper {
|
||||
float: left;
|
||||
|
||||
#kiwix_button_show_toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#kiwix_button_show_toggle:checked~label~.kiwix_button_cont,
|
||||
#kiwix_button_show_toggle:checked~label~.kiwix_button_cont>a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#kiwix_button_show_toggle:not(:checked)~label~.kiwix_button_cont {
|
||||
display: none;
|
||||
}
|
||||
|
||||
label[for="kiwix_button_show_toggle"] {
|
||||
display: inline-block;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
label[for="kiwix_button_show_toggle"] img {
|
||||
transition: 0.1s;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
#kiwix_button_show_toggle:checked~label img {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
|
||||
label[for="kiwix_button_show_toggle"],
|
||||
.kiwix_button_cont {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.kiwix .kiwix_searchform {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.kiwix #kiwixtoolbar button,
|
||||
.kiwix #kiwixtoolbar input[type="submit"] {
|
||||
box-sizing: border-box !important;
|
||||
@@ -43,22 +98,38 @@
|
||||
cursor: pointer !important;
|
||||
font-size: 16px !important;
|
||||
}
|
||||
.kiwix #kiwixtoolbar a {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.kiwix #kiwixtoolbar #kiwixsearchform input[type='text'] {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
box-sizing: border-box !important;
|
||||
width: 100%;
|
||||
height: 26px !important;
|
||||
line-height: 20px !important;
|
||||
border: 1px solid #999 !important;
|
||||
border-radius: 3px !important;
|
||||
background-color: #fff !important;
|
||||
padding: 2px 2px 2px 3px !important;
|
||||
padding: 2px 2px 2px 27px !important;
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
label[for=kiwixsearchbox] {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
left: 5px;
|
||||
font-size: 90%;
|
||||
line-height: 26px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
body {
|
||||
padding-top: 40px !important;
|
||||
}
|
||||
|
||||
/* Try to fix buggy stuff in jquery-ui autocomplete */
|
||||
#ui-id-1, .ui-autocomplete {
|
||||
#ui-id-1,
|
||||
.ui-autocomplete {
|
||||
background: white !important;
|
||||
border: solid 1px grey !important;
|
||||
}
|
||||
@@ -67,22 +138,49 @@ li.ui-state-focus {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
.kiwixsearch {
|
||||
margin-top: 5px;
|
||||
@media(min-width:420px) {
|
||||
.kiwix_button_cont {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.kiwix_button_cont>a {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
label[for="kiwix_button_show_toggle"] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 645px) {
|
||||
|
||||
#kiwix_button_show_toggle~label~.kiwix_button_cont.searching {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
label[for="kiwix_button_show_toggle"].searching {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.kiwix_searchform.full_width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.kiwixsearch {
|
||||
float: none;
|
||||
}
|
||||
#kiwixsearchbox {
|
||||
width: 65%;
|
||||
}
|
||||
#kiwixsearchform input[type="submit"] {
|
||||
width: 28%;
|
||||
|
||||
.kiwix_searchform {
|
||||
width: 36%;
|
||||
}
|
||||
|
||||
.height_separator {
|
||||
height: 6em;
|
||||
}
|
||||
}
|
||||
|
||||
@media(max-width:415px) {
|
||||
.kiwix_searchform {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
<span class="kiwix">
|
||||
<span id="kiwixtoolbar" class="ui-widget-header">
|
||||
<div class="kiwix_centered">
|
||||
<div class="kiwix_button_wrapper">
|
||||
<a id="kiwix_serve_taskbar_library_button" href="__ROOT_LOCATION__/"><button>🏠</button></a>
|
||||
<a id="kiwix_serve_taskbar_home_button" href="__ROOT_LOCATION__/__CONTENT__/"><button>__ZIM_TITLE__</button></a>
|
||||
<a id="kiwix_serve_taskbar_random_button" href="__ROOT_LOCATION__/random?content=__CONTENT_ESCAPED__"><button>🎲</button></a>
|
||||
</div>
|
||||
<div class="kiwix_searchform">
|
||||
<form class="kiwixsearch" method="GET" action="__ROOT_LOCATION__/search" id="kiwixsearchform">
|
||||
<input type="hidden" name="content" value="__CONTENT__" />
|
||||
<label for="kiwixsearchbox">🔍</label>
|
||||
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
|
||||
<input type="submit" value="🔍">
|
||||
</form>
|
||||
</div>
|
||||
<input type="checkbox" id="kiwix_button_show_toggle">
|
||||
<label for="kiwix_button_show_toggle"><img src="__ROOT_LOCATION__/skin/caret.png" alt=""></label>
|
||||
<div class="kiwix_button_cont">
|
||||
<a id="kiwix_serve_taskbar_library_button" href="__ROOT_LOCATION__/"><button>🏠</button></a>
|
||||
<a id="kiwix_serve_taskbar_home_button" href="__ROOT_LOCATION__/__CONTENT__/"><button>__ZIM_TITLE__</button></a>
|
||||
<a id="kiwix_serve_taskbar_random_button"
|
||||
href="__ROOT_LOCATION__/random?content=__CONTENT_ESCAPED__"><button>🎲</button></a>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
<div style="display: block; height: 5em;"></div>
|
||||
|
||||
49
static/server/taskbar.js
Normal file
49
static/server/taskbar.js
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
(function ($) {
|
||||
if ($(window).width() < 520) {
|
||||
var didScroll;
|
||||
var lastScrollTop = 0;
|
||||
var delta = 5;
|
||||
// on scroll, let the interval function know the user has scrolled
|
||||
$(window).scroll(function (event) {
|
||||
didScroll = true;
|
||||
});
|
||||
// run hasScrolled() and reset didScroll status
|
||||
setInterval(function () {
|
||||
if (didScroll) {
|
||||
hasScrolled();
|
||||
didScroll = false;
|
||||
}
|
||||
}, 250);
|
||||
function hasScrolled() {
|
||||
var st = $(this).scrollTop();
|
||||
|
||||
// Make sure they scroll more than delta
|
||||
if (Math.abs(lastScrollTop - st) <= delta)
|
||||
return;
|
||||
|
||||
// If they scrolled down and are past the navbar, add class .nav-up.
|
||||
// This is necessary so you never see what is "behind" the navbar.
|
||||
if (st > lastScrollTop) {
|
||||
// Scroll Down
|
||||
$('#kiwixtoolbar').css({ top: '-100%' });
|
||||
} else {
|
||||
// Scroll Up
|
||||
$('#kiwixtoolbar').css({ top: '0' });
|
||||
}
|
||||
|
||||
lastScrollTop = st;
|
||||
}
|
||||
}
|
||||
|
||||
$('#kiwixsearchbox').on({
|
||||
focus: function () {
|
||||
$('.kiwix_searchform').addClass('full_width');
|
||||
$('label[for="kiwix_button_show_toggle"], .kiwix_button_cont').addClass('searching');
|
||||
},
|
||||
blur: function () {
|
||||
$('.kiwix_searchform').removeClass('full_width');
|
||||
$('label[for="kiwix_button_show_toggle"], .kiwix_button_cont').removeClass('searching');
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -3,7 +3,7 @@
|
||||
set -e
|
||||
|
||||
REPO_NAME=${TRAVIS_REPO_SLUG#*/}
|
||||
ARCHIVE_NAME=deps_${TRAVIS_OS_NAME}_${PLATFORM}_${REPO_NAME}.tar.xz
|
||||
ARCHIVE_NAME=deps_linux_xenial_${PLATFORM}_${REPO_NAME}.tar.xz
|
||||
|
||||
# Packages.
|
||||
case ${PLATFORM} in
|
||||
@@ -46,3 +46,4 @@ sudo cp ninja /bin
|
||||
cd ${HOME}
|
||||
wget http://tmp.kiwix.org/ci/${ARCHIVE_NAME}
|
||||
tar xf ${HOME}/${ARCHIVE_NAME}
|
||||
sudo ln -s travis ../ci_builder
|
||||
|
||||
Reference in New Issue
Block a user