48 Commits
r0.1 ... 0.2

Author SHA1 Message Date
Matthieu Gautier
856bfc675a Bump-up the version to 0.2.
Time to make a new release.
2017-06-27 15:22:33 +02:00
Kelson
7850e79eab Merge pull request #44 from kiwix/custom_welcome_css
custom welcome page css
2017-06-08 13:21:01 +02:00
Emmanuel Engelhart
62769aed57 custom welcome page css 2017-06-08 13:12:31 +02:00
Kelson
29e281209d Merge pull request #43 from Skylsmoi/335/rewrite_welcome_page
rewrite welcome page (fixed histo)
2017-06-08 12:47:55 +02:00
Skylsmoi
0f480d9fb8 fixed boxes size with ellipsis + moved style tag to template + reduced margin/padding 2017-06-08 09:55:11 +02:00
Skylsmoi
1aeeaa2c3b rewrite welcome page 2017-06-07 11:48:21 +02:00
Matthieu Gautier
2fe1a9443c Merge pull request #39 from kiwix/t38
Add --nolibrarybutton option refs #38
2017-06-06 14:40:07 +02:00
Emmanuel Engelhart
569b4d946e Add --nolibrarybutton option 2017-06-04 18:49:55 +02:00
Matthieu Gautier
e51539d161 Merge pull request #36 from kiwix/new_api
Adapt to new kiwix-lib search API.
2017-05-28 23:15:27 +02:00
Matthieu Gautier
f12a731939 Adapt to new kiwix-lib search API. 2017-05-28 23:11:02 +02:00
Matthieu Gautier
d94423964e Merge pull request #34 from kiwix/full_html_document
ZIM/libzim/libkiwix should provide full HTML DOM
2017-05-22 16:00:51 +02:00
Emmanuel Engelhart
af10b665a9 ZIM/libzim/libkiwix should provide full HTML DOM 2017-05-19 20:37:21 +02:00
Kelson
c2d29376d9 Merge pull request #32 from Skylsmoi/336/fix_display_taskbar_save
336/fix display taskbar save
2017-05-16 14:11:28 +02:00
Skylsmoi
fd9c63c76a Merge branch '336/fix_display_taskbar_save' of github.com:Skylsmoi/kiwix-tools into 336/fix_display_taskbar_save 2017-05-16 11:16:26 +02:00
Skylsmoi
4cc46685f7 fix breakpoint for cybook 2017-05-16 11:16:04 +02:00
Kelson
e30da0c0cd Merge pull request #29 from Skylsmoi/336/fix_display_taskbar_save
css rules for taskbar are now more strict
2017-05-07 10:06:27 +02:00
Kelson
70a652e020 Merge branch 'master' into 336/fix_display_taskbar_save 2017-05-06 21:08:38 +02:00
Skylsmoi
97f0c8ec5b added important rules to set the taskbar design 2017-05-02 16:20:59 +02:00
Matthieu Gautier
da83027710 Merge pull request #26 from kiwix/no_ssh_key
Get dependencies from http server, not from ssh.
2017-04-24 17:20:37 +02:00
Matthieu Gautier
ef9b48682b Get dependencies from http server, not from ssh.
`kiwix-build` now publish intermediate dependencies archives in a
http accessible location.

Let's use this location instead of `scp` the archives.
2017-04-24 17:13:42 +02:00
Kelson
e26244687d Merge pull request #24 from Skylsmoi/336/fix_display_taskbar_save
336/fix display taskbar save
2017-04-23 15:43:22 +02:00
Skylsmoi
2634167f41 fix taskbar design for iOS 2017-04-21 15:00:57 +02:00
Skylsmoi
7edc49c4eb Merge branch 'master' of github.com:kiwix/kiwix-tools into 336/fix_display_taskbar_save 2017-04-20 17:37:03 +02:00
Skylsmoi
36225207c0 force custom design to override rules from libraries 2017-04-20 17:35:12 +02:00
Emmanuel Engelhart
1d61e270fb Add CTPP2 link in README 2017-04-16 20:37:01 +02:00
Kelson
5aecb4231d Merge pull request #20 from Skylsmoi/336/fix_display_taskbar
#336 taskbar is now responsive
2017-04-16 11:06:47 +02:00
Skylsmoi
126781bbb5 removed calc() 2017-04-13 11:52:27 +02:00
Skylsmoi
f045590243 #336 taskbar is now responsive 2017-04-13 11:52:27 +02:00
Matthieu Gautier
f46e560d7f Merge pull request #22 from kiwix/search_in_libzim
Search in libzim
2017-04-11 14:02:21 +02:00
Matthieu Gautier
643293c7df Try to link with uuid only if xapian is present. 2017-04-10 14:47:19 +02:00
Matthieu Gautier
799a47142b Adapt kiwix-tools to last kiwix-lib API (Xapian in zimlib). 2017-04-10 14:47:19 +02:00
Matthieu Gautier
79fdee1df2 Merge pull request #23 from kiwix/travisci
Travisci
2017-04-10 14:46:22 +02:00
Matthieu Gautier
ab623b7176 Add TravisCI.
Now the project is build on every PR using TravisCI.

The project dependencies are get from the archive generated by kiwix-build.
2017-04-10 14:42:41 +02:00
Matthieu Gautier
208050df4b Merge pull request #21 from kiwix/no_indexer
Remove indexer and indexing functionality from installer.
2017-04-06 15:39:07 +02:00
Matthieu Gautier
9ead431b3f Remove indexer and indexing functionality from installer.
This is handled by zimwriterfs now (and zimlib itself later on).
2017-04-06 15:37:39 +02:00
Julian Harty
1e6353330d Please discount (ignore) my last commit, it was intended for the kiwix-apache repo. 2017-04-06 00:05:08 +01:00
Julian Harty
482577fd53 You're welcome... and here's the starting point to encourage you to get involved. 2017-04-06 00:02:27 +01:00
Matthieu Gautier
856b487007 Merge pull request #18 from kiwix/snippets
Update to the new API of kiwix-lib.
2017-03-28 11:37:58 +02:00
Matthieu Gautier
cb20e719ee Update to the new API of kiwix-lib. 2017-03-21 16:33:57 +01:00
Matthieu Gautier
25091c320b Merge pull request #16 from kiwix/kiwix-serve.bugfix
Kiwix serve.bugfix
2017-03-20 11:05:21 +01:00
Matthieu Gautier
35b83144c6 Do not compress only if the content is small.
We do not need the test "contentLength < COMPRESSOR_BUFFER_SIZE" to know
if we compress the content or not.

This is a non sens, we WANT to compress the content if it is big.
2017-03-20 10:08:14 +01:00
Matthieu Gautier
063e9ba80d Use compressBound function to reserve the right amount of space.
compressBound function give the upper bound of space needed to
reserve to the compression buffer. Use it instead of using a define.
2017-03-20 10:08:14 +01:00
Matthieu Gautier
e27ce444c6 Correctly check that compress gone well before using the result buffer.
We need to check the return code of compress.
Compress may fail for different reason, one being that the compr_buffer
is not large enough.
2017-03-20 10:08:14 +01:00
Matthieu Gautier
3592cd84c6 Do not modify the compr buffer pointer.
The compr pointer points to the allocated memory. We must not modify
it value.
If we advance the pointer by two bytes each time we compress an answer
we will end to write in some random memory and segfault.

Now, we use a std::vector to correctly handle allocation
(and deallocation!) of the memory.
2017-03-20 10:08:14 +01:00
Matthieu Gautier
a27010c247 Correctly change the compression buffer we send.
For ie browser, we need to remove the two first bytes.
If we make our buffer start two bytes after, we also need to reduce the
size of the buffer by two bytes. Else we will read and send two extra
junk bytes.

Fix #15
2017-03-20 10:08:14 +01:00
Matthieu Gautier
0c01ec5bb5 Cleanup a bit kiwix-serve.cpp
- Remove spaces at end of lines
- Remove unused variables.
2017-03-20 10:08:14 +01:00
Matthieu Gautier
a3a0127edb Do not try to discover ctpp2 ourselves.
Kiwixlib now exports ctpp2 link/cflags in its pkg-config file.
So we don't have to check to ctpp2 here.
2017-02-22 12:10:47 +01:00
Matthieu Gautier
ad7d30cc4f Do not link with iconv when cross-compilating to windows.
Ideally we should check if iconv is present to know if ctpp2 has been
build with iconv.
This may be a bit too complex for our present case. As we know our
cross-compilation environment. It is better to remove the use of iconv
everywhere for now.
2017-02-07 12:25:43 +01:00
16 changed files with 339 additions and 332 deletions

11
.travis.yml Normal file
View File

@@ -0,0 +1,11 @@
language: cpp
dist: trusty
sudo: required
cache: ccache
install: travis/install_deps.sh
script: travis/compile.sh
env:
- PLATFORM="native_static"
- PLATFORM="native_dyn"
- PLATFORM="win32_static"
- PLATFORM="win32_dyn"

20
Changelog Normal file
View File

@@ -0,0 +1,20 @@
kiwix-tools 0.2.0
=================
* Remove indexer tools
kiwix-serve
----------
* Correctly fix the deflate data we send over http. (#15)
* Update in the taskbar (or topbar):
* Taskbar is responsive (github.com/kiwix/kiwix/issues/336)
* Force css rules for the taskbar (and not be impacted by content's css)
* Add `--nolibrarybutton` to hide the library button from the taskbar.
* Rewrite of the welcome page.
kiwix-installer
---------------
* Remove indexing functionnality

View File

@@ -30,6 +30,7 @@ libraries need to be available:
(no package for now)
* 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)

View File

@@ -1,4 +1,6 @@
project('kiwix-tools', 'cpp')
project('kiwix-tools', 'cpp',
version : '0.2.0',
license : 'GPL')
compiler = meson.get_compiler('cpp')
@@ -12,49 +14,6 @@ kiwixlib_dep = dependency('kiwix', static:static_linkage)
microhttpd_dep = dependency('libmicrohttpd', static:static_linkage)
z_dep = dependency('zlib', static:static_linkage)
# Idealy we should not have more dependency, however :
# We should declare we use ctpp2 in kiwixlib in the pkg-config file.
# But there is no pkg-config file for ctpp2. Once one exists, no need to
# declare the dependency here
ctpp2_prefix_install = get_option('ctpp2-install-prefix')
find_library_in_compiler = meson.version().version_compare('>=0.31.0')
if ctpp2_prefix_install == ''
if not compiler.has_header('ctpp2/CTPP2Logger.hpp')
error('ctpp2/CTPP2Logger.hppnot found')
endif
if find_library_in_compiler
ctpp2_lib = compiler.find_library('ctpp2')
else
ctpp2_lib = find_library('ctpp2')
endif
link_args = ['-lctpp2']
if meson.is_cross_build()
if host_machine.system() == 'windows'
link_args += ['-liconv']
endif
endif
ctpp2_dep = declare_dependency(link_args:link_args)
else
if not find_library_in_compiler
error('For custom ctpp2_prefix_install you need a meson version >=0.31.0')
endif
ctpp2_include_path = ctpp2_prefix_install + '/include'
ctpp2_include_args = ['-I'+ctpp2_include_path]
if not compiler.has_header('ctpp2/CTPP2Logger.hpp', args:ctpp2_include_args)
error('ctpp2/CTPP2Logger.hpp not found')
endif
ctpp2_include_path = include_directories(ctpp2_include_path, is_system:true)
ctpp2_lib_path = ctpp2_prefix_install+'/lib'
ctpp2_lib = compiler.find_library('ctpp2', dirs:ctpp2_lib_path)
link_args = ['-L'+ctpp2_lib_path, '-lctpp2']
if meson.is_cross_build()
if host_machine.system() == 'windows'
link_args += ['-liconv']
endif
endif
ctpp2_dep = declare_dependency(include_directories:ctpp2_include_path, link_args:link_args)
endif
# This is a temporary workaround until xapian fix it's xapian-core.pc
# For a correct dependency checking we should test if uuid is really installed
# but for a workaround, we assume that in xapian is installed, uuid also.
@@ -62,10 +21,15 @@ if meson.is_cross_build() and host_machine.system() == 'windows'
# xapian doesn't use uuid on windows.
uuid_dep = declare_dependency()
else
uuid_dep = declare_dependency(link_args:['-luuid', '-lrt'])
xapian_dep = dependency('xapian-core', required : false)
if xapian_dep.found()
uuid_dep = declare_dependency(link_args:['-luuid', '-lrt'])
else
uuid_dep = declare_dependency()
endif
endif
all_deps = [thread_dep, kiwixlib_dep, microhttpd_dep, ctpp2_dep, z_dep, uuid_dep]
all_deps = [thread_dep, kiwixlib_dep, microhttpd_dep, z_dep, uuid_dep]
#subdir('include')
subdir('static')

View File

@@ -1,4 +1,2 @@
option('static-linkage', type : 'boolean', value : false,
description : 'Create statically linked binaries.')
option('ctpp2-install-prefix', type : 'string', value : '',
description : 'Prefix where ctpp libs has been installed')

View File

@@ -1,107 +0,0 @@
/*
* Copyright 2009-2013 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <kiwix/xapianIndexer.h>
#include <getopt.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
void usage() {
cout << "Usage: kiwix-index [--verbose] ZIM_PATH INDEX_PATH" << endl;
exit(1);
}
int main(int argc, char **argv) {
/* Init the variables */
char *zimFilePath = NULL;
char *indexPath = NULL;
bool verboseFlag = false;
int option_index = 0;
int c = 0;
kiwix::XapianIndexer *indexer = NULL;
/* Argument parsing */
while (42) {
static struct option long_options[] = {
{"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
if (c != -1) {
c = getopt_long(argc, argv, "v", long_options, &option_index);
switch (c) {
case 'v':
verboseFlag = true;
break;
}
} else {
if (optind < argc) {
if (zimFilePath == NULL) {
zimFilePath = argv[optind++];
} else if (indexPath == NULL) {
indexPath = argv[optind++];
} else {
usage();
}
} else {
break;
}
}
}
/* Check if we have enough arguments */
if (zimFilePath == NULL || indexPath == NULL) {
usage();
}
/* Try to prepare the indexing */
try {
indexer = new kiwix::XapianIndexer();
} catch (...) {
cerr << "Unable to index '" << zimFilePath << "'." << endl;
exit(1);
}
/* Start the indexing */
if (indexer != NULL) {
indexer->setVerboseFlag(verboseFlag);
indexer->start(zimFilePath, indexPath);
while (indexer->isRunning()) {
if (verboseFlag)
cout << indexer->getProgression() << "% of all the articles indexed..." << endl;
kiwix::sleep(1000);
}
if (verboseFlag)
cout << "100% of the articles were successfuly indexed..." << endl;
delete indexer;
} else {
cerr << "Unable instanciate the Kiwix indexer." << endl;
exit(1);
}
exit(0);
}

View File

@@ -1,3 +0,0 @@
executable('kiwix-index', ['kiwix-index.cpp'],
dependencies:all_deps,
install:true)

View File

@@ -19,14 +19,13 @@
#include <getopt.h>
#include <kiwix/common/pathTools.h>
#include <kiwix/xapianIndexer.h>
#include <kiwix/reader.h>
#include <kiwix/manager.h>
enum supportedAction { NONE, ADDCONTENT };
void usage() {
cout << "Usage: kiwix-install [--verbose] [--buildIndex] addcontent ZIM_PATH KIWIX_PATH" << endl;
cout << "Usage: kiwix-install [--verbose] addcontent ZIM_PATH KIWIX_PATH" << endl;
exit(1);
}
@@ -37,7 +36,6 @@ int main(int argc, char **argv) {
const char *kiwixPath = NULL;
supportedAction action = NONE;
bool verboseFlag = false;
bool buildIndexFlag = false;
int option_index = 0;
int c = 0;
@@ -46,7 +44,6 @@ int main(int argc, char **argv) {
static struct option long_options[] = {
{"verbose", no_argument, 0, 'v'},
{"buildIndex", no_argument, 0, 'i'},
{0, 0, 0, 0}
};
@@ -57,9 +54,6 @@ int main(int argc, char **argv) {
case 'v':
verboseFlag = true;
break;
case 'i':
buildIndexFlag = true;
break;
}
} else {
if (optind < argc) {
@@ -137,12 +131,6 @@ int main(int argc, char **argv) {
makeDirectory(dataLibraryPath);
}
/* Check if the directory "data/index" structure exists */
string dataIndexPath = computeAbsolutePath(kiwixPath, "data/index/");
if (!fileExists(dataIndexPath)) {
makeDirectory(dataIndexPath);
}
/* Copy the file to the data/content directory */
if (verboseFlag) { std::cout << "Copy ZIM file to the target directory..." << std::endl; }
string newContentPath = computeAbsolutePath(dataContentPath, contentFilename);
@@ -150,33 +138,6 @@ int main(int argc, char **argv) {
copyFile(contentPath, newContentPath);
}
/* Index the file if necessary */
if (verboseFlag) { std::cout << "Check if the index directory exists..." << std::endl; }
string indexFilename = contentFilename + ".idx";
string indexPath = computeAbsolutePath(dataIndexPath, indexFilename);
if (buildIndexFlag && !fileExists(indexPath)) {
if (verboseFlag) { std::cout << "Start indexing the ZIM file..." << std::endl; }
kiwix::XapianIndexer *indexer = NULL;
try {
indexer = new kiwix::XapianIndexer();
} catch (...) {
cerr << "Unable to index '" << contentPath << "'." << endl;
exit(1);
}
if (indexer != NULL) {
indexer->setVerboseFlag(verboseFlag);
indexer->start(contentPath, indexPath);
while (indexer->isRunning()) {
kiwix::sleep(1000);
}
delete indexer;
} else {
cerr << "Unable instanciate the Kiwix indexer." << endl;
exit(1);
}
}
/* Add the file to the library.xml */
if (verboseFlag) { std::cout << "Create the library XML file..." << std::endl; }
kiwix::Manager libraryManager;
@@ -184,9 +145,6 @@ int main(int argc, char **argv) {
string bookId = libraryManager.addBookFromPathAndGetId(newContentPath, "../content/" + contentFilename, "", false);
if (!bookId.empty()) {
libraryManager.setCurrentBookId(bookId);
if (buildIndexFlag) {
libraryManager.setBookIndex(bookId, "../index/" + indexFilename, kiwix::XAPIAN);
}
libraryManager.writeFile(libraryPath);
} else {
cerr << "Unable to build or save library file '" << libraryPath << "'" << endl;

View File

@@ -1,6 +1,4 @@
subdir('indexer')
subdir('installer')
subdir('manager')
subdir('reader')

View File

@@ -19,12 +19,11 @@
#include <getopt.h>
#include <unistd.h>
#include <kiwix/xapianSearcher.h>
enum supportedBackend { XAPIAN };
#include <kiwix/reader.h>
#include <kiwix/searcher.h>
void usage() {
cout << "Usage: kiwix-search [--verbose|-v] [--backend|-b=xapian] INDEX_PATH SEARCH" << endl;
cout << "Usage: kiwix-search [--verbose|-v] ZIM_PATH SEARCH" << endl;
exit(1);
}
@@ -33,21 +32,20 @@ int main(int argc, char **argv) {
/* Init the variables */
//const char *indexPath = "/home/itamar/.www.kiwix.org/kiwix/43k0i1j4.default/6d2e587b-d586-dc6a-dc6a-e4ef035a1495d15c.index";
//const char *indexPath = "/home/itamar/testindex";
const char *indexPath = NULL;
const char *zimPath = NULL;
const char *search = NULL;
bool verboseFlag = false;
int option_index = 0;
int c = 0;
supportedBackend backend = XAPIAN;
kiwix::Searcher *searcher = NULL;
kiwix::Reader *reader = NULL;
/* Argument parsing */
while (42) {
static struct option long_options[] = {
{"verbose", no_argument, 0, 'v'},
{"backend", required_argument, 0, 'b'},
{0, 0, 0, 0}
};
@@ -58,22 +56,15 @@ int main(int argc, char **argv) {
case 'v':
verboseFlag = true;
break;
case 'b':
if (!strcmp(optarg, "xapian")) {
backend = XAPIAN;
} else {
usage();
}
break;
}
} else {
if (optind < argc) {
if (indexPath == NULL) {
indexPath = argv[optind++];
if (zimPath == NULL) {
zimPath = argv[optind++];
} else if (search == NULL) {
search = argv[optind++];
} else {
cout << indexPath << endl;
cout << zimPath << endl;
usage();
}
} else {
@@ -83,30 +74,40 @@ int main(int argc, char **argv) {
}
/* Check if we have enough arguments */
if (indexPath == NULL || search == NULL) {
if (zimPath == NULL || search == NULL) {
usage();
}
/* Try to prepare the indexing */
try {
searcher = new kiwix::XapianSearcher(indexPath);
reader = new kiwix::Reader(zimPath);
} catch (...) {
cerr << "Unable to search through index '" << indexPath << "'." << endl;
exit(1);
/* Cannot open the zimPath, maybe it is a plain old xapian database directory */
}
if ( reader ) {
searcher = new kiwix::Searcher("", reader);
} else {
try {
searcher = new kiwix::Searcher(zimPath, NULL);
} catch (...) {
cerr << "Unable to search through zim '" << zimPath << "'." << endl;
exit(1);
}
}
/* Start the indexing */
if (searcher != NULL) {
string searchString(search);
searcher->search(searchString, 0, 10);
string url;
string title;
unsigned int score;
while (searcher->getNextResult(url, title, score)) {
cout << title << endl;
kiwix::Result* p_result;
while ( (p_result = searcher->getNextResult()) ) {
cout << p_result->get_title() << endl;
delete p_result;
}
delete searcher;
delete reader;
// kiwix::XapianSearcher::terminate();
} else {

View File

@@ -49,6 +49,7 @@ extern "C" {
#include <getopt.h>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <iostream>
@@ -61,7 +62,7 @@ extern "C" {
#include <zlib.h>
#include <kiwix/reader.h>
#include <kiwix/manager.h>
#include <kiwix/xapianSearcher.h>
#include <kiwix/searcher.h>
#include <kiwix/common/pathTools.h>
#include <kiwix/common/regexTools.h>
#include <kiwix/common/stringTools.h>
@@ -84,7 +85,8 @@ extern "C" {
using namespace std;
static bool nosearchbarFlag = false;
static bool noLibraryButtonFlag = false;
static bool noSearchBarFlag = false;
static string welcomeHTML;
static bool verboseFlag = false;
static std::map<std::string, std::string> extMimeTypes;
@@ -119,13 +121,17 @@ static std::string getMimeTypeForFile(const std::string& filename) {
}
void introduceTaskbar(string &content, const string &humanReadableBookId) {
if (!nosearchbarFlag) {
content = appendToFirstOccurence(content, "<head>",
if (!noSearchBarFlag) {
content = appendToFirstOccurence(content, "<head>",
replaceRegex(RESOURCE::include_html_part,
humanReadableBookId, "__CONTENT__"));
content = appendToFirstOccurence(content, "<head>", "<style>" +
RESOURCE::taskbar_css + "</style>");
content = appendToFirstOccurence(content, "<body[^>]*>",
content = appendToFirstOccurence(content,
"<head>",
"<style>" +
RESOURCE::taskbar_css +
(noLibraryButtonFlag ? " #kiwix_serve_taskbar_library_button { display: none }" : "") +
"</style>");
content = appendToFirstOccurence(content, "<body[^>]*>",
replaceRegex(RESOURCE::taskbar_html_part,
humanReadableBookId, "__CONTENT__"));
}
@@ -140,50 +146,47 @@ bool isVerbose() {
return value;
}
/* For compression */
#define COMPRESSOR_BUFFER_SIZE 10000000
static Bytef *compr = (Bytef *)malloc(COMPRESSOR_BUFFER_SIZE);
static uLongf comprLen;
static
bool compress_content(string &content,
const string &mimeType)
{
static std::vector<Bytef> compr_buffer;
/* Should be deflate */
bool deflated = mimeType.find("text/") != string::npos ||
mimeType.find("application/javascript") != string::npos ||
mimeType.find("application/json") != string::npos;
if ( ! deflated )
return false;
/* Compute the lengh */
unsigned int contentLength = content.size();
/* Should be deflate */
bool deflated =
contentLength > KIWIX_MIN_CONTENT_SIZE_TO_DEFLATE &&
contentLength < COMPRESSOR_BUFFER_SIZE &&
(mimeType.find("text/") != string::npos ||
mimeType.find("application/javascript") != string::npos ||
mimeType.find("application/json") != string::npos);
/* If the content is too short, no need to compress it */
if ( contentLength <= KIWIX_MIN_CONTENT_SIZE_TO_DEFLATE)
return false;
uLong bufferBound = compressBound(contentLength);
/* Compress the content if necessary */
if (deflated) {
pthread_mutex_lock(&compressorLock);
comprLen = COMPRESSOR_BUFFER_SIZE;
compress(compr, &comprLen, (const Bytef*)(content.data()), contentLength);
pthread_mutex_lock(&compressorLock);
compr_buffer.reserve(bufferBound);
uLongf comprLen = compr_buffer.capacity();
int err = compress(&compr_buffer[0], &comprLen, (const Bytef*)(content.data()), contentLength);
if (comprLen > 2 && comprLen < contentLength) {
/* /!\ Internet Explorer has a bug with deflate compression.
It can not handle the first two bytes (compression headers)
We need to chunk them off (move the content 2bytes)
It has no incidence on other browsers
See http://www.subbu.org/blog/2008/03/ie7-deflate-or-not and comments */
compr += 2;
content = string((char *)compr, comprLen);
contentLength = comprLen;
} else {
deflated = false;
}
pthread_mutex_unlock(&compressorLock);
if (err == Z_OK && comprLen > 2 && comprLen < (contentLength+2)) {
/* /!\ Internet Explorer has a bug with deflate compression.
It can not handle the first two bytes (compression headers)
We need to chunk them off (move the content 2bytes)
It has no incidence on other browsers
See http://www.subbu.org/blog/2008/03/ie7-deflate-or-not and comments */
content = string((char *)&compr_buffer[2], comprLen-2);
} else {
deflated = false;
}
pthread_mutex_unlock(&compressorLock);
return deflated;
}
@@ -396,12 +399,14 @@ struct MHD_Response* handle_search(struct MHD_Connection * connection,
/* Get the results */
pthread_mutex_lock(&searcherLock);
pthread_mutex_lock(&readerLock);
try {
searcher->search(patternString, startNumber, endNumber, isVerbose());
content = searcher->getHtml();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
pthread_mutex_unlock(&readerLock);
pthread_mutex_unlock(&searcherLock);
} else {
content = "<!DOCTYPE html>\n<html><head><meta content=\"text/html;charset=UTF-8\" http-equiv=\"content-type\" /><title>Fulltext search unavailable</title></head><body><h1>Not Found</h1><p>There is no article with the title <b>\"" + kiwix::encodeDiples(patternString) + "\"</b> and the fulltext search engine is not available for this content.</p></body></html>";
@@ -426,7 +431,6 @@ struct MHD_Response* handle_random(struct MHD_Connection * connection,
bool acceptEncodingDeflate)
{
std::string httpRedirection;
bool cacheEnabled = false;
httpResponseCode = MHD_HTTP_FOUND;
if (reader != NULL) {
pthread_mutex_lock(&readerLock);
@@ -449,7 +453,6 @@ struct MHD_Response* handle_content(struct MHD_Connection * connection,
std::string baseUrl;
std::string content;
std::string mimeType;
unsigned int contentLength;
bool found = false;
zim::Article article;
@@ -513,10 +516,6 @@ struct MHD_Response* handle_content(struct MHD_Connection * connection,
/* Special rewrite URL in case of ZIM file use intern *asbolute* url like /A/Kiwix */
if (mimeType.find("text/html") != string::npos) {
if (content.find("<body") == std::string::npos &&
content.find("<BODY") == std::string::npos) {
content = "<html><head><title>" + article.getTitle() + "</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body>" + content + "</body></html>";
}
baseUrl = "/" + std::string(1, article.getNamespace()) + "/" + article.getUrl();
content = replaceRegex(content, "$1$2" + humanReadableBookId + "/$3/",
"(href|src)(=[\"|\']{0,1}/)([A-Z|\\-])/");
@@ -591,7 +590,7 @@ static int accessHandlerCallback(void *cls,
const char* acceptEncodingHeaderValue = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_ACCEPT_ENCODING);
const bool acceptEncodingDeflate = acceptEncodingHeaderValue && string(acceptEncodingHeaderValue).find("deflate") != string::npos;
/* Check if range is requested */
/* Check if range is requested. [TODO] Handle this somehow */
const char* acceptRangeHeaderValue = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_RANGE);
const bool acceptRange = acceptRangeHeaderValue != NULL;
@@ -607,7 +606,7 @@ static int accessHandlerCallback(void *cls,
const char* tmpGetValue = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "content");
humanReadableBookId = (tmpGetValue != NULL ? string(tmpGetValue) : "");
} else {
humanReadableBookId = urlStr.substr(1, urlStr.find("/", 1) != string::npos ?
humanReadableBookId = urlStr.substr(1, urlStr.find("/", 1) != string::npos ?
urlStr.find("/", 1) - 1 : urlStr.size() - 2);
if (!humanReadableBookId.empty()) {
urlStr = urlStr.substr(urlStr.find("/", 1) != string::npos ?
@@ -697,7 +696,7 @@ static int accessHandlerCallback(void *cls,
httpResponseCode,
response);
MHD_destroy_response(response);
return ret;
}
@@ -719,6 +718,7 @@ int main(int argc, char **argv) {
{"daemon", no_argument, 0, 'd'},
{"verbose", no_argument, 0, 'v'},
{"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'},
@@ -730,7 +730,7 @@ int main(int argc, char **argv) {
/* Argument parsing */
while (true) {
int option_index = 0;
int c = getopt_long(argc, argv, "ndvli:a:p:f:", long_options, &option_index);
int c = getopt_long(argc, argv, "mndvli:a:p:f:", long_options, &option_index);
if (c != -1) {
@@ -745,7 +745,10 @@ int main(int argc, char **argv) {
libraryFlag = true;
break;
case 'n':
nosearchbarFlag = true;
noSearchBarFlag = true;
break;
case 'm':
noLibraryButtonFlag = true;
break;
case 'i':
indexPath = optarg;
@@ -777,8 +780,8 @@ 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] [--daemon] [--attachToProcess=PID] [--interface=IF_NAME] ZIM_PATH+" << endl;
cerr << " kiwix-serve --library [--port=PORT] [--verbose] [--daemon] [--nosearchbar] [--attachToProcess=PID] [--interface=IF_NAME] LIBRARY_PATH" << endl;
cerr << "Usage: kiwix-serve [--index=INDEX_PATH] [--port=PORT] [--verbose] [--nosearchbar] [--nolibrarybutton] [--daemon] [--attachToProcess=PID] [--interface=IF_NAME] ZIM_PATH+" << endl;
cerr << " kiwix-serve --library [--port=PORT] [--verbose] [--daemon] [--nosearchbar] [--nolibrarybutton] [--attachToProcess=PID] [--interface=IF_NAME] LIBRARY_PATH" << endl;
cerr << "\n If you set more than one ZIM_PATH, you cannot set a INDEX_PATH." << endl;
exit(1);
}
@@ -792,7 +795,7 @@ int main(int argc, char **argv) {
if (libraryFlag) {
vector<string> libraryPaths = kiwix::split(libraryPath, ";");
vector<string>::iterator itr;
for ( itr = libraryPaths.begin(); itr != libraryPaths.end(); ++itr ) {
if (!itr->empty()) {
bool retVal = false;
@@ -862,7 +865,7 @@ int main(int argc, char **argv) {
if (!indexPath.empty()) {
try {
kiwix::Searcher *searcher = new kiwix::XapianSearcher(indexPath);
kiwix::Searcher *searcher = new kiwix::Searcher(indexPath, reader);
searcher->setProtocolPrefix("/");
searcher->setSearchProtocolPrefix("/search?");
searcher->setContentHumanReadableId(humanReadableId);
@@ -876,25 +879,29 @@ int main(int argc, char **argv) {
}
/* Compute the Welcome HTML */
string welcomeBooksHtml;
string welcomeBooksHtml = ""
"<div class='book__list'>";
for (itr = booksIds.begin(); itr != booksIds.end(); ++itr) {
libraryManager.getBookById(*itr, currentBook);
if (!currentBook.path.empty() && readers.find(currentBook.getHumanReadableIdFromPath()) != readers.end()) {
welcomeBooksHtml += "<h3><a href=\"#\">" + currentBook.title + "</a></h3>\n \
<table style=\"overflow-x: hidden; overflow-y: hidden; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;\"><tr>\n \
<td style=\"background-repeat: no-repeat; background-image: url(data:" + currentBook.faviconMimeType+ ";base64," + currentBook.favicon + ")\"><div style=\"width: 50px\"></div></td>\n \
<td style=\"width: 100%;\">" + currentBook.description +
"<br/><table style=\"font-size: small; color: grey; width: 100%;\">" +
"<tr><td style=\"width: 50%\">Size: " + kiwix::beautifyFileSize(atoi(currentBook.size.c_str())) + " (" + kiwix::beautifyInteger(atoi(currentBook.articleCount.c_str())) + " articles, " + kiwix::beautifyInteger(atoi(currentBook.mediaCount.c_str())) + " medias)\n \
</td><td>Date: " + currentBook.date + "</td><td style=\"vertical-align: bottom; width: 20%\" rowspan=\"3\"><form action=\"/" + currentBook.getHumanReadableIdFromPath() + "/\" method=\"GET\"><input style=\"align: right; right: 0px; float:right; width: 100%; height: 60px; font-weight: bold;\" type=\"submit\" value=\"Load\" /></form></td></tr>\n \
<tr><td>Author: " + currentBook.creator + "</td><td>Language: " + currentBook.language + "</td></tr>\n \
<tr><td>Publisher: " + (currentBook.publisher.empty() ? "unknown" : currentBook.publisher ) + "</td><td></td></tr>\n \
</table>\n \
</td></tr>\n \
</table>\n\n";
welcomeBooksHtml += ""
"<a href='/" + 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__info'>"
"" + kiwix::beautifyInteger(atoi(currentBook.articleCount.c_str())) + " articles, " + kiwix::beautifyInteger(atoi(currentBook.mediaCount.c_str())) + " medias"
"</div>"
"</div>"
"</div>"
"</a>";
}
}
welcomeBooksHtml += ""
"</div>";
welcomeHTML = replaceRegex(RESOURCE::home_html_tmpl, welcomeBooksHtml, "__BOOKS__");
#ifndef _WIN32
@@ -924,7 +931,7 @@ int main(int argc, char **argv) {
pthread_mutex_init(&compressorLock, NULL);
pthread_mutex_init(&verboseFlagLock, NULL);
pthread_mutex_init(&mimeTypeLock, NULL);
/* Hard coded mimetypes */
extMimeTypes["html"] = "text/html";
extMimeTypes["htm"] = "text/html";
@@ -945,7 +952,7 @@ int main(int argc, char **argv) {
extMimeTypes["ttf"] = "application/font-ttf";
extMimeTypes["woff"] = "application/font-woff";
extMimeTypes["vtt"] = "text/vtt";
/* Start the HTTP daemon */
void *page = NULL;
if (interface.length() > 0) {
@@ -956,7 +963,6 @@ int main(int argc, char **argv) {
struct sockaddr_in sockAddr;
struct ifaddrs *ifaddr, *ifa;
int family, n;
char host[NI_MAXHOST];
/* Search all available interfaces */
if (getifaddrs(&ifaddr) == -1) {

View File

@@ -7,6 +7,39 @@
<script type="text/javascript" src="/skin/jquery-ui/jquery-ui.min.js"></script>
<link type="text/css" href="/skin/jquery-ui/jquery-ui.min.css" rel="Stylesheet" />
<link type="text/css" href="/skin/jquery-ui/jquery-ui.theme.min.css" rel="Stylesheet" />
<style>
body {
background:
radial-gradient(#EEEEEE 15%, transparent 16%) 0 0,
radial-gradient(#EEEEEE 15%, transparent 16%) 8px 8px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px;
background-color:#E8E8E8;
background-size:16px 16px;
margin-left: auto;
margin-right: auto;
max-width: 65.8em;
}
.book__list { text-align: center; }
.book {
display: inline-block; vertical-align: bottom; margin: 8px; padding: 12px 15px; width: 300px;
border: 1px solid #ccc; border-radius: 8px;
text-align: left; color: #000; font-family: sans-serif; font-size: 13px;
background-color:#F1F1F1;
box-shadow: 2px 2px 5px 0px #ccc;
}
.book:hover { background-color: #F9F9F9; box-shadow: none;}
.book__background { background-repeat: no-repeat; background-size: auto; background-position: top right; }
.book__title {
padding: 0 55px 0 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
font-size: 18px; color: #0645ad;
}
.book__description {
padding: 5px 55px 5px 0px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
font-size: 15px;
}
.book__info { line-height: 18px; color: #777; font-weight: bold; font-size: 13px; }
</style>
<script>
$(function() {
$( "#accordion" ).accordion();
@@ -15,7 +48,7 @@ $( "#accordion" ).accordion();
</head>
<body class="kiwix">
<div id="accordion" class="kiwix">
<div class="kiwix">
__BOOKS__
</div>
</body>

View File

@@ -5,16 +5,57 @@
right:0;
top: 0;
z-index:100;
max-height: 2.8em;
}
#kiwixtoolbar > a {
float: left;
}
.height_separator {
height: 3em;
}
#kiwixsearchbox {
width: 20em;
}
.kiwixsearch {
float: right;
}s
.kiwix .kiwix_centered {
max-width: 720px;
margin: 0 auto;
}
.kiwix .kiwix_button_wrapper {
float: left;
}
.kiwix .kiwix_searchform {
float: right;
}
.kiwix #kiwixtoolbar button,
.kiwix #kiwixtoolbar input[type="submit"] {
box-sizing: border-box !important;
height: 26px !important;
line-height: 20px !important;
margin-right: 5px !important;
padding: 2px 6px !important;
border: 1px solid #999 !important;
border-radius: 3px !important;
background-color: #ededed !important;
font-weight: normal !important;
cursor: pointer !important;
font-size: 16px !important;
}
.kiwix #kiwixtoolbar a {
margin-bottom: 5px;
}
.kiwix #kiwixtoolbar #kiwixsearchform input[type='text'] {
box-sizing: border-box !important;
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;
font-size: 16px !important;
}
/* Try to fix buggy stuff in jquery-ui autocomplete */
#ui-id-1, .ui-autocomplete {
@@ -26,25 +67,22 @@ li.ui-state-focus {
font-weight: bold;
}
/* Specific CSS for Bookeen Cybook device (800x600 B&W ereader) */
.cybook #kiwixtoolbar button, .cybook #kiwixtoolbar input {
font-size: 1.5em;
@media (max-width: 520px) {
.kiwixsearch {
margin-top: 5px;
}
}
.cybook #kiwixsearchbox {
width: 7em;
}
.cybook a {
text-decoration: underline;
}
@media only screen and (min--moz-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 1.5/1),
only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min-device-pixel-ratio: 1.5) {
#kiwixtoolbar button, #kiwixtoolbar input {
font-size: 2em;
@media (max-width: 645px) {
.kiwixsearch {
float: none;
}
#kiwixsearchbox {
width: 7em;
}
width: 65%;
}
#kiwixsearchform input[type="submit"] {
width: 28%;
}
.height_separator {
height: 6em;
}
}

View File

@@ -2,14 +2,20 @@
<link type="text/css" href="/skin/jquery-ui/jquery-ui.theme.min.css" rel="Stylesheet" />
<span class="kiwix">
<span id="kiwixtoolbar" class="ui-widget-header">
<a href="/"><button>Library</button></a>
<a href="/__CONTENT__/"><button>Home</button></a>
<a href="/random?content=__CONTENT__"><button>Random</button></a>
<form class="kiwixsearch" method="GET" action="/search" id="kiwixsearchform">
<input type="hidden" name="content" value="__CONTENT__" />
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
<input type="submit" value="Search">
</form>
<div class="kiwix_centered">
<div class="kiwix_button_wrapper">
<a id="kiwix_serve_taskbar_library_button" href="/"><button>Library</button></a>
<a id="kiwix_serve_taskbar_home_button" href="/__CONTENT__/"><button>Home</button></a>
<a id="kiwix_serve_taskbar_random_button" href="/random?content=__CONTENT__"><button>Random</button></a>
</div>
<div class="kiwix_searchform">
<form class="kiwixsearch" method="GET" action="/search" id="kiwixsearchform">
<input type="hidden" name="content" value="__CONTENT__" />
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
<input type="submit" value="Search">
</form>
</div>
</div>
</span>
</span>
<div style="display: block; height: 3em;"></div>
<div style="display: block; height: 5em;"></div>

36
travis/compile.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -e
BUILD_DIR=${HOME}/BUILD_${PLATFORM}
INSTALL_DIR=${BUILD_DIR}/INSTALL
case ${PLATFORM} in
"native_static")
MESON_OPTION="--default-library=static"
;;
"native_dyn")
MESON_OPTION="--default-library=shared"
;;
"win32_static")
MESON_OPTION="--default-library=static --cross-file ${BUILD_DIR}/meson_cross_file.txt"
;;
"win32_dyn")
MESON_OPTION="--default-library=shared --cross-file ${BUILD_DIR}/meson_cross_file.txt"
;;
"android_arm")
MESON_OPTION="-Dandroid=true --default-library=shared --cross-file ${BUILD_DIR}/meson_cross_file.txt"
;;
"android_arm64")
MESON_OPTION="-Dandroid=true --default-library=shared --cross-file ${BUILD_DIR}/meson_cross_file.txt"
;;
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}
cd build
ninja

47
travis/install_deps.sh Executable file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env bash
set -e
REPO_NAME=${TRAVIS_REPO_SLUG#*/}
ARCHIVE_NAME=deps_${PLATFORM}_${REPO_NAME}.tar.gz
# Packages.
case ${PLATFORM} in
"native_static")
PACKAGES="gcc cmake libbz2-dev ccache zlib1g-dev uuid-dev libctpp2-dev"
;;
"native_dyn")
PACKAGES="gcc cmake libbz2-dev ccache zlib1g-dev uuid-dev libctpp2-dev libmicrohttpd-dev"
;;
"win32_static")
PACKAGES="g++-mingw-w64-i686 gcc-mingw-w64-i686 gcc-mingw-w64-base mingw-w64-tools ccache"
;;
"win32_dyn")
PACKAGES="g++-mingw-w64-i686 gcc-mingw-w64-i686 gcc-mingw-w64-base mingw-w64-tools ccache"
;;
"android_arm")
PACKAGES="gcc cmake ccache"
;;
"android_arm64")
PACKAGES="gcc cmake ccache"
;;
esac
sudo apt-get update -qq
sudo apt-get install -qq python3-pip ${PACKAGES}
pip3 install meson
# Ninja
cd $HOME
git clone git://github.com/ninja-build/ninja.git
cd ninja
git checkout release
./configure.py --bootstrap
sudo cp ninja /bin
# Dependencies comming from kiwix-build.
cd ${HOME}
wget http://tmp.kiwix.org/ci/${ARCHIVE_NAME}
mkdir -p BUILD_${PLATFORM}
cd BUILD_${PLATFORM}
tar xf ${HOME}/${ARCHIVE_NAME}