39 Commits
0.6.1 ... 1.0.0

Author SHA1 Message Date
Matthieu Gautier
e4eafd7459 Merge pull request #260 from kiwix/new_version
New version 1.0.0
2019-02-22 11:19:03 +01:00
Matthieu Gautier
16a29127a1 New version 1.0.0 2019-02-22 10:50:33 +01:00
Matthieu Gautier
7fa0579ea1 Merge pull request #258 from kiwix/redirect
[server] Correctly implement 302 redirection if the entry is a redirection
2019-02-20 17:14:52 +01:00
Matthieu Gautier
978dc47865 [server] Correctly implement 302 redirection if the entry is a redirection.
If the entry is a redirection, we should redirect the client to the
right entry instead of serving the target content.

As we are doing a redirection, urls are good and we don't have to change
link inside the html or css content.

Fix #192
2019-02-20 16:57:10 +01:00
Matthieu Gautier
b7793f6e75 Merge pull request #259 from kiwix/use_correct_dep_archive
Use new xz archive
2019-02-20 16:46:19 +01:00
Matthieu Gautier
8095ae9ea8 Use new xz archive 2019-02-20 16:06:04 +01:00
Matthieu Gautier
286f599b3e Merge pull request #256 from kiwix/new_version
New version
2019-01-29 14:00:23 +01:00
Matthieu Gautier
174b236312 New version 0.9.0 2019-01-29 11:45:55 +01:00
Matthieu Gautier
c7e9d44b38 We do not need the exact version 0.43.0 for meson. 2019-01-29 11:45:55 +01:00
Matthieu Gautier
3a80951c23 Merge pull request #255 from kiwix/update_to_api
Update to api
2019-01-23 17:42:59 +01:00
Matthieu Gautier
ffaecb5389 Update to last kiwix-lib API.
The `common` repository has been renamed to `tools`.
2019-01-23 15:48:53 +01:00
Matthieu Gautier
7b25308248 Update build system as we don't use ctpp2 anymore. 2019-01-23 15:46:14 +01:00
Matthieu Gautier
7ac14aa64f Merge pull request #254 from kiwix/new_api_no_external_index
Do not handle external index.
2019-01-09 10:18:48 +01:00
Matthieu Gautier
3c8da8c74c Do not handle external index.
Now that kiwix-lib do not handle external index, we must not try to handle
it ourselves.

See kiwix/kiwix-lib#190.
Fix #245
2019-01-08 17:40:02 +01:00
Matthieu Gautier
9ed3fc353b Merge pull request #253 from kiwix/fix_warning
Initialize geoquery variables.
2019-01-08 17:39:30 +01:00
Matthieu Gautier
51051752f1 Initialize geoquery variables.
Fix #251
2019-01-08 16:15:55 +01:00
Kelson
4e8a8533c4 Merge pull request #248 from kiwix/legoktm-patch-2
Improve kiwix-serve.1
2018-12-20 10:05:32 +01:00
Kelson
fd2a0decd3 Merge branch 'master' into legoktm-patch-2 2018-12-20 09:40:34 +01:00
Kelson
624fb32091 Merge pull request #247 from kiwix/legoktm-patch-1
Improve grammar in kiwix-manage.1
2018-12-20 09:39:15 +01:00
Kunal Mehta
067a40a156 Improve kiwix-serve.1
Minor grammar fixes and remove reference to kiwix-install(1).
2018-12-20 00:36:09 -08:00
Kunal Mehta
cfa22365fe Improve grammar in kiwix-manage.1
And change one of the URLs to HTTPS, and remove a reference
to the removed kiwix-install(1).
2018-12-20 00:28:32 -08:00
Popo le Chien
d5066ba6bf Updated README
typo
2018-12-13 14:54:23 +01:00
Kelson
f1ec1ec182 Merge pull request #239 from kiwix/updated_usage
Update usage()
2018-11-17 09:08:19 +01:00
Kelson
d1802c52a2 Update usage() 2018-11-17 09:05:37 +01:00
Matthieu Gautier
38088ee321 New version 0.8.0 2018-11-12 16:52:29 +01:00
Matthieu Gautier
0f445e9791 Merge pull request #238 from kiwix/remove_several_id
Be able to remove several books in a single command.
2018-11-12 14:38:28 +01:00
Matthieu Gautier
1032a46c57 Be able to remove several books in a single command.
Fix #236
2018-11-12 14:00:45 +01:00
Matthieu Gautier
cbe8f1df87 Merge pull request #234 from kiwix/new_version
New version 0.7.0
2018-10-31 15:30:03 +01:00
Matthieu Gautier
2fe5ec1d7c New version 0.7.0 2018-10-31 14:45:05 +01:00
Matthieu Gautier
eba80b92ef Merge pull request #229 from kiwix/new_kiwix-lib_api
WIP New kiwix lib api
2018-10-26 13:28:59 +02:00
Matthieu Gautier
c1e635bd4e [kiwix-manage] Add a download command to kiwix-manage.
With the download command, it is possible to download a zim corresponding
to a remote book in the library.
2018-10-26 13:26:04 +02:00
Matthieu Gautier
c8be8fbad8 [kiwix-manage] Update to last API of kiwix-lib.
`kiwix::Manager` cannot set the book index. We have to modify the book
itself.

We remove the `backend` option as the only supported xapian was and always
was xapian.
2018-10-24 15:24:27 +02:00
Matthieu Gautier
640f907fb2 Avoid recopy of books 2018-10-24 15:05:33 +02:00
Matthieu Gautier
eb407956b9 The index path must be absolute. 2018-10-24 15:05:14 +02:00
Matthieu Gautier
422dde9ff2 Allow the opds feed to filtered by the language and "paged". 2018-10-24 15:03:14 +02:00
Matthieu Gautier
f691f85724 Correctly get the bookIds to the opdsfeed.
We want to have LOCAL and REMOTE and VALID files.
2018-10-24 15:01:46 +02:00
Matthieu Gautier
fd4f228a41 Use the to_string function in kiwix lib instead of redefine it. 2018-10-24 14:53:25 +02:00
Matthieu Gautier
bf40d4ff91 Adapt kiwix-manage to new kiwix-lib API.
- Books are identified by Id, not by index.
- No more current option.
2018-09-06 18:59:51 +02:00
Matthieu Gautier
74fecd34e6 Adapt kiwix-serve to new API.
We also change the welcome page to link to icon url instead of
embeded them as base64 data.
2018-09-06 18:58:54 +02:00
11 changed files with 298 additions and 237 deletions

View File

@@ -1,3 +1,58 @@
kiwix-tools 1.0.0
=================
* [CI] Use the new deps archive xz
* Move version 1.0.0. There is no need to stay in pre 1.0 version.
kiwix-serve
-----------
* Correctly implement redirection.
kiwix-serve now return a 302 http status code instead of resolving the
redirection internally and return the content.
kiwix-tools 0.9.0
=================
* Update README
* Update man pages
* Remove support of external indexes (manage, search, serve)
* Update build system as we don't use ctpp2 anymore
* Update to last kiwix-lib API.
kiwix-manage
------------
* Update usage.
kiwix-tools 0.8.0
=================
kiwix-manage
------------
* Be able to remove several books from the library in one command.
kiwix-tools 0.7.0
=================
* Adapt to kiwix-lib new API
kiwix-serve
-----------
* Dumps only valid books in the opdsfeed.
* Allow the opds feed to be filtered by lang and paginated.
kiwix-manage
------------
* Add a download command to download a remote book locally
* Book are referenced by bookId not index.
* No more indexType option as it is always XAPIAN.
kiwix-tools 0.6.1
=================

View File

@@ -16,7 +16,7 @@ Preamble
Although the Kiwix tools can be compiled/cross-compiled on/for many
sytems, the following documentation explains how to do it on POSIX
ones. It is primarly though for GNU/Linux systems and has been tested
ones. It is primarly thought for GNU/Linux systems and has been tested
on recent releases of Ubuntu and Fedora.
Dependencies

View File

@@ -1,5 +1,5 @@
project('kiwix-tools', 'cpp',
version : '0.6.1',
version : '1.0.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:'>=2.0.2', static:static_linkage)
kiwixlib_dep = dependency('kiwix', version:'>=4.0.0', static:static_linkage)
microhttpd_dep = dependency('libmicrohttpd', static:static_linkage)
z_dep = dependency('zlib', static:static_linkage)

View File

@@ -15,12 +15,12 @@ kiwix\-manage LIBRARY_PATH add ZIM_PATH ...
.PP
\fBkiwix\-manage\fP tool for managing a kiwix library.
.PP
Allows one to manage the content of the kiwix library. Library file is an XML flat file
listing ZIM files with all necessary information like favicon, date, creator,
description, indexpath, filepath, title, source/metalink etc.
Allows one to manage the content of the kiwix library. The library file is a
flat XML file listing ZIM files with all necessary information like favicon,
date, creator, description, indexpath, filepath, title, source/metalink, etc.
.
.PP
Example library file can be found at http://www.kiwix.org/library\.xml
Example library file can be found at https://www.kiwix.org/library\.xml
.br
.TP
\fBadd\fR
@@ -55,7 +55,7 @@ Path to full-text index for that ZIM file.
Set the content location of the ZIM file over the network for in\-kiwix download.
.SH SEE ALSO
kiwix(1) kiwix\-install(1) kiwix\-serve(1)
kiwix(1) kiwix\-serve(1)
.SH AUTHOR
Emmanuel Engelhart <kelson@kiwix.org>
.br

View File

@@ -9,7 +9,7 @@ kiwix\-serve [\-\-index=INDEX_PATH] [\-\-port=PORT] [\-\-verbose] [\-\-daemon] [
kiwix\-serve \-\-library [\-\-port=PORT] [\-\-verbose] [\-\-daemon] [\-\-attachToProcess=PID] LIBRARY_PATH
.SH DESCRIPTION
.PP
Stand\-alone HTTP server for serving ZIM content over the network.
Stand\-alone HTTP server for serving ZIM contents over the network.
.TP
\fB\-\-index=INDEX_PATH\fR
@@ -27,7 +27,7 @@ Enable verbose output.
.TP
\fB\-\-daemon\fR
Run the server as a daemon
Run the server as a daemon.
.TP
\fB\-\-attachToProcess=PID\fR
@@ -49,12 +49,11 @@ Serves the contents of a library file instead of a single ZIM file.
\fBLIBRARY_PATH\fR
Kiwix library file path.
.br
Library is XML file created using \fBkiwix-manage\fB.
Library is an XML file created using \fBkiwix-manage\fB.
.SH SEE ALSO
kiwix(1) kiwix\-manage(1)
.br
kiwix\-install(1)
.SH AUTHOR
Emmanuel Engelhart <kelson@kiwix.org>
.br

View File

@@ -21,34 +21,39 @@
#include <unistd.h>
#endif
#include <getopt.h>
#include <kiwix/common/pathTools.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 };
enum supportedAction { NONE, ADD, SHOW, REMOVE, DOWNLOAD };
void show(kiwix::Library library)
void show(kiwix::Library* library)
{
std::vector<kiwix::Book>::iterator itr;
auto booksIds = library->getBooksIds();
unsigned int inc = 1;
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
for(auto& id: booksIds) {
auto& book = library->getBookById(id);
std::cout << "#" << inc++ << std::endl
<< "id:\t\t" << itr->id << std::endl
<< "path:\t\t" << itr->path << std::endl
<< "indexpath:\t" << itr->indexPath << std::endl
<< "url:\t\t" << itr->url << std::endl
<< "title:\t\t" << itr->title << std::endl
<< "name:\t\t" << itr->name << std::endl
<< "tags:\t\t" << itr->tags << std::endl
<< "description:\t" << itr->description << std::endl
<< "creator:\t" << itr->creator << std::endl
<< "date:\t\t" << itr->date << std::endl
<< "articleCount:\t" << itr->articleCount << std::endl
<< "mediaCount:\t" << itr->mediaCount << std::endl
<< "size:\t\t" << itr->size << " KB" << std::endl
<< "id:\t\t" << book.getId() << std::endl
<< "path:\t\t" << book.getPath() << std::endl
<< "url:\t\t" << book.getUrl() << std::endl
<< "title:\t\t" << book.getTitle() << std::endl
<< "name:\t\t" << book.getName() << std::endl
<< "tags:\t\t" << book.getTags() << std::endl
<< "description:\t" << book.getDescription() << std::endl
<< "creator:\t" << book.getCreator() << std::endl
<< "date:\t\t" << book.getDate() << std::endl
<< "articleCount:\t" << book.getArticleCount() << std::endl
<< "mediaCount:\t" << book.getMediaCount() << std::endl
<< "size:\t\t" << book.getSize() << " KB" << std::endl
<< std::endl;
}
}
@@ -58,7 +63,6 @@ void usage()
cerr << "Usage:" << endl;
cerr << "\tkiwix-manage LIBRARY_PATH add ZIM_PATH "
"[--zimPathToSave=../content/foobar.zim] [--current] "
"[--indexBackend=xapian] [--indexPath=FULLTEXT_IDX_PATH] "
"[--url=http://...metalink]"
<< endl;
cerr << "\tkiwix-manage LIBRARY_PATH show [CONTENTID1] [CONTENTID2] ... "
@@ -68,23 +72,20 @@ void usage()
}
bool handle_show(kiwix::Manager* libraryManager, const std::string& libraryPath,
bool handle_show(kiwix::Library* library, const std::string& libraryPath,
int argc, char* argv[])
{
show(libraryManager->cloneLibrary());
show(library);
return(0);
}
bool handle_add(kiwix::Manager* libraryManager, const std::string& libraryPath,
bool handle_add(kiwix::Library* library, const std::string& libraryPath,
int argc, char* argv[])
{
string zimPath;
string zimPathToSave = ".";
string indexPath;
kiwix::supportedIndexType indexBackend = kiwix::XAPIAN;
string url;
string origID = "";
bool setCurrent = false;
int option_index = 0;
int c = 0;
bool resultCode = 0;
@@ -99,13 +100,10 @@ bool handle_add(kiwix::Manager* libraryManager, const std::string& libraryPath,
static struct option long_options[]
= {{"url", required_argument, 0, 'u'},
{"origId", required_argument, 0, 'o'},
{"indexPath", required_argument, 0, 'i'},
{"indexBackend", required_argument, 0, 'b'},
{"zimPathToSave", required_argument, 0, 'z'},
{"current", no_argument, 0, 'c'},
{0, 0, 0, 0}};
c = getopt_long(argc, argv, "cz:u:i:b:", long_options, &option_index);
c = getopt_long(argc, argv, "cz:u:", long_options, &option_index);
if (c != -1) {
switch (c) {
@@ -117,22 +115,6 @@ bool handle_add(kiwix::Manager* libraryManager, const std::string& libraryPath,
origID = optarg;
break;
case 'c':
setCurrent = true;
break;
case 'i':
indexPath = optarg;
break;
case 'b':
if (!strcmp(optarg, "xapian")) {
indexBackend = kiwix::XAPIAN;
} else {
usage();
}
break;
case 'z':
zimPathToSave = optarg;
break;
@@ -143,20 +125,9 @@ bool handle_add(kiwix::Manager* libraryManager, const std::string& libraryPath,
}
if (!zimPath.empty()) {
kiwix::Manager manager(library);
zimPathToSave = zimPathToSave == "." ? zimPath : zimPathToSave;
string bookId = libraryManager->addBookFromPathAndGetId(
zimPath, zimPathToSave, url, false);
if (!bookId.empty()) {
if (setCurrent)
libraryManager->setCurrentBookId(bookId);
/* Save the index infos if necessary */
if (!indexPath.empty())
libraryManager->setBookIndex(bookId, indexPath, indexBackend);
} else {
cerr << "Unable to build or save library file '" << libraryPath << "'"
<< endl;
resultCode = 1;
}
manager.addBookFromPathAndGetId(zimPath, zimPathToSave, url, false);
} else {
std::cerr << "Invalid zim file path" << std::endl;
resultCode = 1;
@@ -165,29 +136,29 @@ bool handle_add(kiwix::Manager* libraryManager, const std::string& libraryPath,
return(resultCode);
}
bool handle_remove(kiwix::Manager* libraryManager, const std::string& libraryPath,
bool handle_remove(kiwix::Library* library, const std::string& libraryPath,
int argc, char* argv[])
{
unsigned int bookIndex = 0;
const unsigned int totalBookCount = libraryManager->getBookCount(true, true);
std::string bookId;
const unsigned int totalBookCount = library->getBookCount(true, true);
bool exitCode = 0;
if (argc > 3) {
bookIndex = atoi(argv[3]);
if (argc <= 3) {
std::cerr << "BookId to remove missing in the command line" << std::endl;
return (-1);
}
if (bookIndex > 0 && bookIndex <= totalBookCount) {
libraryManager->removeBookByIndex(bookIndex - 1);
} else {
if (totalBookCount > 0) {
std::cerr
<< "Invalid book index number. Please give a number between 1 and "
<< totalBookCount << std::endl;
exitCode = 1;
} else {
std::cerr
<< "Invalid book index number. Library is empty, no book to delete."
<< std::endl;
if (!totalBookCount) {
std::cerr << "Library is empty, no book to delete."
<< std::endl;
return 1;
}
for (int i = 3; i<argc; i++) {
bookId = argv[i];
if (!library->removeBookById(bookId)) {
std::cerr << "Invalid book id '" << bookId << "'." << std::endl;
exitCode = 1;
}
}
@@ -195,11 +166,67 @@ bool handle_remove(kiwix::Manager* libraryManager, const std::string& libraryPat
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 = "";
supportedAction action = NONE;
kiwix::Manager libraryManager;
kiwix::Library library;
/* Argument parsing */
if (argc > 2) {
@@ -212,6 +239,8 @@ 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 */
@@ -224,21 +253,31 @@ int main(int argc, char** argv)
libraryPath = isRelativePath(libraryPath)
? computeAbsolutePath(getCurrentDirectory(), libraryPath)
: libraryPath;
libraryManager.readFile(libraryPath, false);
kiwix::Manager manager(&library);
manager.readFile(libraryPath, false);
/* SHOW */
bool exitCode = 0;
if (action == SHOW) {
exitCode = handle_show(&libraryManager, libraryPath, argc, argv);
} else if (action == ADD) {
exitCode = handle_add(&libraryManager, libraryPath, argc, argv);
} else if (action == REMOVE) {
exitCode = handle_remove(&libraryManager, libraryPath, argc, argv);
switch (action) {
case SHOW:
exitCode = handle_show(&library, libraryPath, argc, argv);
break;
case ADD:
exitCode = handle_add(&library, libraryPath, argc, argv);
break;
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) {
libraryManager.writeFile(libraryPath);
if (action == REMOVE || action == ADD || action == DOWNLOAD) {
library.writeToFile(libraryPath);
}
exit(exitCode);

View File

@@ -27,8 +27,7 @@ void usage()
{
cout << "Usage: kiwix-search [OPTIONS] ZIM PATTERN" << endl << endl
<< " kiwix-search allows to find articles based on the a fulltext search pattern." << endl << endl
<< " ZIM is the full path of the ZIM file. This can also be a disctinct fulltext" << endl
<< " index directory (usually distributed with the *.idx extension)." << endl
<< " ZIM is the full path of the ZIM file." << endl
<< " PATTERN is/are word(s) - or part of - to search in the ZIM." << endl << endl
<< " -s, --suggestion\tSuggest article titles based on the few letters of the PATTERN instead of making a fulltext search. Work a bit like a completion solution." << endl
<< " -v, --verbose\t\tGive details about the search process" << endl;
@@ -102,12 +101,8 @@ int main(int argc, char** argv)
searcher = new kiwix::Searcher();
searcher->add_reader(reader, "");
} else {
try {
searcher = new kiwix::Searcher(zimPath, NULL, "");
} catch (...) {
cerr << "Unable to search through zim '" << zimPath << "'." << endl;
exit(1);
}
cerr << "Unable to search through zim '" << zimPath << "'." << endl;
exit(1);
}
/* Start the indexing */

View File

@@ -44,10 +44,10 @@ extern "C" {
#endif
#include <getopt.h>
#include <kiwix/common/otherTools.h>
#include <kiwix/common/pathTools.h>
#include <kiwix/common/regexTools.h>
#include <kiwix/common/stringTools.h>
#include <kiwix/tools/otherTools.h>
#include <kiwix/tools/pathTools.h>
#include <kiwix/tools/regexTools.h>
#include <kiwix/tools/stringTools.h>
#include <kiwix/manager.h>
#include <kiwix/reader.h>
#include <kiwix/searcher.h>
@@ -101,20 +101,11 @@ static std::map<std::string, std::string> extMimeTypes;
static std::map<std::string, kiwix::Reader*> readers;
static std::map<std::string, kiwix::Searcher*> searchers;
static kiwix::Searcher* globalSearcher = nullptr;
static kiwix::Manager libraryManager;
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;
template<typename T>
inline std::string _tostring(const T& value)
{
std::ostringstream stream;
stream << value;
return stream.str();
}
std::pair<kiwix::Reader*, kiwix::Searcher*>
get_from_humanReadableBookId(const std::string& humanReadableBookId) {
kiwix::Searcher* searcher
@@ -385,7 +376,7 @@ static struct MHD_Response* build_callback_response_from_entry(
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_RANGE, oss.str().c_str());
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_LENGTH,
_tostring(range_len).c_str());
kiwix::to_string(range_len).c_str());
/* Specify the mime type */
MHD_add_response_header(
@@ -547,9 +538,9 @@ static struct MHD_Response* handle_search(RequestContext* request)
/* Retrive geo search */
bool has_geo_query = false;
float latitude;
float longitude;
float distance;
float latitude = 0;
float longitude = 0;
float distance = 0;
try {
latitude = request->get_argument<float>("latitude");
longitude = request->get_argument<float>("longitude");
@@ -694,33 +685,51 @@ static struct MHD_Response* handle_catalog(RequestContext* request)
kiwix::OPDSDumper opdsDumper;
opdsDumper.setRootLocation(rootLocation);
opdsDumper.setSearchDescriptionUrl("catalog/searchdescription.xml");
opdsDumper.setId(kiwix::to_string(uuid));
opdsDumper.setLibrary(&library);
mimeType = "application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8";
kiwix::Library library_to_dump;
std::vector<std::string> bookIdsToDump;
if (url == "root.xml") {
opdsDumper.setTitle("All zims");
uuid = zim::Uuid::generate(host);
library_to_dump = libraryManager.cloneLibrary();
bookIdsToDump = library.listBooksIds(
kiwix::VALID|kiwix::LOCAL|kiwix::REMOTE);
} else if (url == "search") {
std::string query;
std::string language;
size_t count(10);
size_t startIndex(0);
try {
query = request->get_argument("q");
} catch (const std::out_of_range&) {
return build_404(request, "");
}
} catch (const std::out_of_range&) {}
try {
language = request->get_argument("lang");
} catch (const std::out_of_range&) {}
try {
count = stoul(request->get_argument("count"));
} catch (...) {}
try {
startIndex = stoul(request->get_argument("start"));
} catch (...) {}
opdsDumper.setTitle("Search result for " + query);
uuid = zim::Uuid::generate();
library_to_dump = libraryManager.filter(query);
bookIdsToDump = library.listBooksIds(
kiwix::VALID|kiwix::LOCAL|kiwix::REMOTE,
kiwix::UNSORTED,
query,
language);
auto totalResults = bookIdsToDump.size();
bookIdsToDump.erase(bookIdsToDump.begin(), bookIdsToDump.begin()+startIndex);
if (count>0 && bookIdsToDump.size() > count) {
bookIdsToDump.resize(count);
}
opdsDumper.setOpenSearchInfo(totalResults, startIndex, bookIdsToDump.size());
} else {
return build_404(request, "");
}
{
std::stringstream ss;
ss << uuid;
opdsDumper.setId(ss.str());
}
opdsDumper.setLibrary(library_to_dump);
content = opdsDumper.dumpOPDSFeed();
content = opdsDumper.dumpOPDSFeed(bookIdsToDump);
}
bool deflated = request->can_compress() && compress_content(content, mimeType);
@@ -757,10 +766,22 @@ static struct MHD_Response* handle_content(RequestContext* request)
}
auto urlStr = request->get_url().substr(humanReadableBookId.size()+1);
if (urlStr[0] == '/') {
urlStr = urlStr.substr(1);
}
try {
entry = reader->getEntryFromPath(urlStr);
entry = entry.getFinalEntry();
if (entry.isRedirect() || urlStr.empty()) {
// If urlStr is empty, we want to mainPage.
// We must do a redirection to the real page.
entry = entry.getFinalEntry();
std::string httpRedirection = (
rootLocation + "/" + humanReadableBookId + "/" +
kiwix::urlEncode(entry.getPath()));
request->httpResponseCode = MHD_HTTP_FOUND;
return build_response("", 0, httpRedirection, "", false, false);
}
} catch(kiwix::NoEntry& e) {
if (isVerbose.load())
printf("Failed to find %s\n", urlStr.c_str());
@@ -785,29 +806,8 @@ static struct MHD_Response* handle_content(RequestContext* request)
zim::Blob raw_content = entry.getBlob();
content = string(raw_content.data(), raw_content.size());
/* Special rewrite URL in case of ZIM file use intern *asbolute* url like
* /A/Kiwix */
if (mimeType.find("text/html") != string::npos) {
baseUrl = "/" + entry.getPath();
pthread_mutex_lock(&regexLock);
content = replaceRegex(content,
"$1$2" + rootLocation + "/" + humanReadableBookId + "/$3/",
"(href|src)(=[\"|\']{0,1})/([A-Z|\\-])/");
content = replaceRegex(content,
"$1$2" + rootLocation + "/" + humanReadableBookId + "/$3/",
"(@import[ ]+)([\"|\']{0,1})/([A-Z|\\-])/");
content = replaceRegex(
content,
"<head><base href=\"" + rootLocation + "/" + humanReadableBookId + baseUrl + "\" />",
"<head>");
pthread_mutex_unlock(&regexLock);
introduceTaskbar(content, humanReadableBookId);
} else if (mimeType.find("text/css") != string::npos) {
pthread_mutex_lock(&regexLock);
content = replaceRegex(content,
"$1$2" + rootLocation + "/" + humanReadableBookId + "/$3/",
"(url|URL)(\\([\"|\']{0,1})/([A-Z|\\-])/");
pthread_mutex_unlock(&regexLock);
}
bool deflated
@@ -905,7 +905,6 @@ int main(int argc, char** argv)
struct MHD_Daemon* daemon;
vector<string> zimPathes;
string libraryPath;
string indexPath;
string rootPath;
string interface;
int serverPort = 80;
@@ -921,7 +920,6 @@ int main(int argc, char** argv)
{"library", no_argument, 0, 'l'},
{"nolibrarybutton", no_argument, 0, 'm'},
{"nosearchbar", no_argument, 0, 'n'},
{"index", required_argument, 0, 'i'},
{"attachToProcess", required_argument, 0, 'a'},
{"port", required_argument, 0, 'p'},
{"interface", required_argument, 0, 'f'},
@@ -933,7 +931,7 @@ int main(int argc, char** argv)
while (true) {
int option_index = 0;
int c
= getopt_long(argc, argv, "mndvli:a:p:f:t:r:", long_options, &option_index);
= getopt_long(argc, argv, "mndvla:p:f:t:r:", long_options, &option_index);
if (c != -1) {
switch (c) {
@@ -952,9 +950,6 @@ int main(int argc, char** argv)
case 'm':
noLibraryButtonFlag = true;
break;
case 'i':
indexPath = optarg;
break;
case 'p':
serverPort = atoi(optarg);
break;
@@ -1015,12 +1010,8 @@ int main(int argc, char** argv)
exit(1);
}
if ((zimPathes.size() > 1) && !indexPath.empty()) {
cerr << "You cannot set a indexPath if you also set several zimPathes";
exit(1);
}
/* Setup the library manager and get the list of books */
kiwix::Manager manager(&library);
if (libraryFlag) {
vector<string> libraryPaths = kiwix::split(libraryPath, ";");
vector<string>::iterator itr;
@@ -1034,7 +1025,7 @@ int main(int argc, char** argv)
= isRelativePath(*itr)
? computeAbsolutePath(getCurrentDirectory(), *itr)
: *itr;
retVal = libraryManager.readFile(libraryPath, true);
retVal = manager.readFile(libraryPath, true);
} catch (...) {
retVal = false;
}
@@ -1048,74 +1039,51 @@ int main(int argc, char** argv)
}
/* Check if the library is not empty (or only remote books)*/
if (libraryManager.getBookCount(true, false) == 0) {
if (library.getBookCount(true, false) == 0) {
cerr << "The XML library file '" << libraryPath
<< "' is empty (or has only remote books)." << endl;
}
} else {
std::vector<std::string>::iterator it;
for (it = zimPathes.begin(); it != zimPathes.end(); it++) {
if (!libraryManager.addBookFromPath(*it, *it, "", false)) {
if (!manager.addBookFromPath(*it, *it, "", false)) {
cerr << "Unable to add the ZIM file '" << *it
<< "' to the internal library." << endl;
exit(1);
}
}
if (!indexPath.empty()) {
libraryManager.setBookIndex(libraryManager.getBooksIds()[0], indexPath);
}
}
/* Instance the readers and searcher and build the corresponding maps */
vector<string> booksIds = libraryManager.getBooksIds();
vector<string>::iterator itr;
kiwix::Book currentBook;
vector<string> booksIds = library.listBooksIds(kiwix::LOCAL);
globalSearcher = new kiwix::Searcher();
globalSearcher->setProtocolPrefix(rootLocation + "/");
globalSearcher->setSearchProtocolPrefix(rootLocation + "/" + "search?");
for (itr = booksIds.begin(); itr != booksIds.end(); ++itr) {
bool zimFileOk = false;
libraryManager.getBookById(*itr, currentBook);
std::string zimPath = currentBook.pathAbsolute;
for (auto& bookId: booksIds) {
auto& currentBook = library.getBookById(bookId);
auto zimPath = currentBook.getPath();
if (!zimPath.empty()) {
indexPath = currentBook.indexPathAbsolute;
/* Instanciate the ZIM file handler */
kiwix::Reader* reader = NULL;
try {
reader = new kiwix::Reader(zimPath);
} catch (...) {
cerr << "Unable to open the ZIM file '" << zimPath << "'." << endl;
continue;
}
/* Instanciate the ZIM file handler */
kiwix::Reader* reader = NULL;
try {
reader = new kiwix::Reader(zimPath);
zimFileOk = true;
} catch (...) {
cerr << "Unable to open the ZIM file '" << zimPath << "'." << endl;
}
auto humanReadableId = currentBook.getHumanReadableIdFromPath();
readers[humanReadableId] = reader;
if (zimFileOk) {
string humanReadableId = currentBook.getHumanReadableIdFromPath();
readers[humanReadableId] = reader;
if ( reader->hasFulltextIndex()) {
kiwix::Searcher* searcher = new kiwix::Searcher(humanReadableId);
searcher->setProtocolPrefix(rootLocation + "/");
searcher->setSearchProtocolPrefix(rootLocation + "/" + "search?");
searcher->add_reader(reader, humanReadableId);
globalSearcher->add_reader(reader, humanReadableId);
searchers[humanReadableId] = searcher;
} else if ( !indexPath.empty() ) {
try {
kiwix::Searcher* searcher = new kiwix::Searcher(indexPath, reader, humanReadableId);
searcher->setProtocolPrefix(rootLocation + "/");
searcher->setSearchProtocolPrefix(rootLocation + "/" + "search?");
searchers[humanReadableId] = searcher;
} catch (...) {
cerr << "Unable to open the search index '" << indexPath << "'."
<< endl;
searchers[humanReadableId] = nullptr;
}
} else {
searchers[humanReadableId] = nullptr;
}
}
if (reader->hasFulltextIndex()) {
kiwix::Searcher* searcher = new kiwix::Searcher(humanReadableId);
searcher->setProtocolPrefix(rootLocation + "/");
searcher->setSearchProtocolPrefix(rootLocation + "/" + "search?");
searcher->add_reader(reader, humanReadableId);
globalSearcher->add_reader(reader, humanReadableId);
searchers[humanReadableId] = searcher;
} else {
searchers[humanReadableId] = nullptr;
}
}
@@ -1123,24 +1091,25 @@ int main(int argc, char** argv)
string welcomeBooksHtml
= ""
"<div class='book__list'>";
for (itr = booksIds.begin(); itr != booksIds.end(); ++itr) {
libraryManager.getBookById(*itr, currentBook);
for (auto& bookId: booksIds) {
auto& currentBook = library.getBookById(bookId);
if (!currentBook.path.empty()
if (!currentBook.getPath().empty()
&& readers.find(currentBook.getHumanReadableIdFromPath())
!= readers.end()) {
welcomeBooksHtml += ""
"<a href='" + rootLocation + "/" + currentBook.getHumanReadableIdFromPath() + "/'>"
"<div class='book'>"
"<div class='book__background' style='background-image: url(data:" + currentBook.faviconMimeType+ ";base64," + currentBook.favicon + ");'>"
"<div class='book__title' title='" + currentBook.title + "'>" + currentBook.title + "</div>"
"<div class='book__description' title='" + currentBook.description + "'>" + currentBook.description + "</div>"
"<div class='book__background' style=\"background-image: url('/meta?content="
+ currentBook.getHumanReadableIdFromPath() + "&name=favicon');\">"
"<div class='book__title' title='" + currentBook.getTitle() + "'>" + currentBook.getTitle() + "</div>"
"<div class='book__description' title='" + currentBook.getDescription() + "'>" + currentBook.getDescription() + "</div>"
"<div class='book__info'>"
"" + kiwix::beautifyInteger(atoi(currentBook.articleCount.c_str())) + " articles, " + kiwix::beautifyInteger(atoi(currentBook.mediaCount.c_str())) + " medias"
"" + kiwix::beautifyInteger(currentBook.getArticleCount()) + " articles, " + kiwix::beautifyInteger(currentBook.getMediaCount()) + " medias"
"</div>"
"</div>"
"</div>"
"</a>";
"</a>\n";
}
}
welcomeBooksHtml += ""

View File

@@ -4,5 +4,6 @@
<Description>Search zim files in the catalog.</Description>
<Url type="application/atom+xml;profile=opds-catalog"
xmlns:atom="http://www.w3.org/2005/Atom"
template="/__ROOT_LOCATION__/catalog/search?q={searchTerms}"/>
indexOffset="0"
template="/__ROOT_LOCATION__/catalog/search?q={searchTerms}&lang={language}&count={count}&start={startIndex}"/>
</OpenSearchDescription>

View File

@@ -24,6 +24,6 @@ esac
cd ${TRAVIS_BUILD_DIR}
export PKG_CONFIG_PATH=${INSTALL_DIR}/lib/x86_64-linux-gnu/pkgconfig
export PATH=${INSTALL_DIR}/bin:$PATH
meson . build -Dctpp2-install-prefix=${INSTALL_DIR} ${MESON_OPTION}
meson . build ${MESON_OPTION}
cd build
ninja

View File

@@ -3,33 +3,36 @@
set -e
REPO_NAME=${TRAVIS_REPO_SLUG#*/}
ARCHIVE_NAME=deps_${TRAVIS_OS_NAME}_${PLATFORM}_${REPO_NAME}.tar.gz
ARCHIVE_NAME=deps_${TRAVIS_OS_NAME}_${PLATFORM}_${REPO_NAME}.tar.xz
# Packages.
case ${PLATFORM} in
"native_static")
PACKAGES="gcc cmake libbz2-dev ccache zlib1g-dev uuid-dev libctpp2-dev"
PACKAGES="gcc python3.5 cmake libbz2-dev ccache zlib1g-dev uuid-dev"
;;
"native_dyn")
PACKAGES="gcc cmake libbz2-dev ccache zlib1g-dev uuid-dev libctpp2-dev libmicrohttpd-dev"
PACKAGES="gcc python3.5 cmake libbz2-dev ccache zlib1g-dev uuid-dev libmicrohttpd-dev"
;;
"win32_static")
PACKAGES="g++-mingw-w64-i686 gcc-mingw-w64-i686 gcc-mingw-w64-base mingw-w64-tools ccache"
PACKAGES="g++-mingw-w64-i686 gcc-mingw-w64-i686 gcc-mingw-w64-base mingw-w64-tools ccache python3.5"
;;
"win32_dyn")
PACKAGES="g++-mingw-w64-i686 gcc-mingw-w64-i686 gcc-mingw-w64-base mingw-w64-tools ccache"
PACKAGES="g++-mingw-w64-i686 gcc-mingw-w64-i686 gcc-mingw-w64-base mingw-w64-tools ccache python3.5"
;;
"android_arm")
PACKAGES="gcc cmake ccache"
PACKAGES="gcc python3.5 cmake ccache"
;;
"android_arm64")
PACKAGES="gcc cmake ccache"
PACKAGES="gcc python3.5 cmake ccache"
;;
esac
sudo apt-get update -qq
sudo apt-get install -qq python3-pip ${PACKAGES}
sudo pip3 install meson==0.43.0
wget https://bootstrap.pypa.io/get-pip.py
python3.5 get-pip.py --user
python3.5 -m pip install --user --upgrade pip
python3.5 -m pip install --user meson
# Ninja
cd $HOME