mirror of https://github.com/kiwix/libkiwix.git
Merge pull request #607 from kiwix/issue/571
This commit is contained in:
commit
08e3d52957
47
README.md
47
README.md
|
@ -146,6 +146,53 @@ cp ninja ../bin
|
|||
cd ..
|
||||
```
|
||||
|
||||
Custom Index Page
|
||||
-----------------
|
||||
|
||||
to use custom welcome page mention `customIndexPage` argument in `kiwix::internalServer()` or use `kiwix::server->setCustomIndexTemplate()`.
|
||||
(note - while using custom html file please mention all external links as absolute path.)
|
||||
|
||||
to create a HTML template with custom JS you need to have a look at various OPDS based endpoints as mentioned [here](https://wiki.kiwix.org/wiki/OPDS) to load books.
|
||||
|
||||
To use JS provided by kiwix-serve you can use the following template to start with ->
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title><-- Custom Tittle --></title>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="{{root}}/skin/jquery-ui/external/jquery/jquery.js"
|
||||
></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="{{root}}/skin/jquery-ui/jquery-ui.min.js"
|
||||
></script>
|
||||
<script src="{{root}}/skin/isotope.pkgd.min.js" defer></script>
|
||||
<script src="{{root}}/skin/iso6391To3.js"></script>
|
||||
<script type="text/javascript" src="{{root}}/skin/index.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
- To get books listed using `index.js` add - `<div class="book__list"></div>` under body tag.
|
||||
- To get number of books listed add - `<h3 class="kiwixHomeBody__results"></h3>` under body tag.
|
||||
- To add language select box add - `<select id="languageFilter"></select>` under body tag.
|
||||
- To add language select box add - `<select id="categoryFilter"></select>` under body tag.
|
||||
- To add search box for books use following form -
|
||||
```
|
||||
<form id='kiwixSearchForm'>
|
||||
<input type="text" name="q" placeholder="Search" id="searchFilter" class='kiwixSearch filter'>
|
||||
<input type="submit" class="searchButton" value="Search"/>
|
||||
</form>
|
||||
```
|
||||
|
||||
|
||||
If you compile manually Libmicrohttpd, you might need to compile it
|
||||
without GNU TLS, a bug here will empeach further compilation
|
||||
otherwise.
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace kiwix
|
|||
void setPort(int port) { m_port = port; }
|
||||
void setNbThreads(int threads) { m_nbThreads = threads; }
|
||||
void setVerbose(bool verbose) { m_verbose = verbose; }
|
||||
void setIndexTemplateString(const std::string& indexTemplateString) { m_indexTemplateString = indexTemplateString; }
|
||||
void setTaskbar(bool withTaskbar, bool withLibraryButton)
|
||||
{ m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; }
|
||||
void setBlockExternalLinks(bool blockExternalLinks)
|
||||
|
@ -65,6 +66,7 @@ namespace kiwix
|
|||
NameMapper* mp_nameMapper;
|
||||
std::string m_root = "";
|
||||
std::string m_addr = "";
|
||||
std::string m_indexTemplateString = "";
|
||||
int m_port = 80;
|
||||
int m_nbThreads = 1;
|
||||
bool m_verbose = false;
|
||||
|
|
|
@ -167,5 +167,32 @@ std::vector<std::string> split(const std::string& str, const std::string& delims
|
|||
* @throw std::out_of_range if iso2 code is not known.
|
||||
*/
|
||||
std::string converta2toa3(const std::string& a2code);
|
||||
|
||||
/** Extracts content from given file.
|
||||
*
|
||||
* This function provides content of a file provided it's path.
|
||||
*
|
||||
* @param path The absolute path provided in string format.
|
||||
* @return Content of corresponding file in string format.
|
||||
*/
|
||||
std::string getFileContent(const std::string& path);
|
||||
|
||||
/** checks if file exists.
|
||||
*
|
||||
* This function returns boolean stating if file exists or not.
|
||||
*
|
||||
* @param path The absolute path provided in string format.
|
||||
* @return Boolean representing if file exists or not.
|
||||
*/
|
||||
bool fileExists(const std::string& path);
|
||||
|
||||
/** provides mimetype from filename.
|
||||
*
|
||||
* This function provides mimetype from file-name.
|
||||
*
|
||||
* @param filename string containing filename.
|
||||
* @return mimetype from filename in string format.
|
||||
*/
|
||||
std::string getMimeTypeForFile(const std::string& filename);
|
||||
}
|
||||
#endif // KIWIX_TOOLS_H
|
||||
|
|
|
@ -48,7 +48,8 @@ bool Server::start() {
|
|||
m_verbose,
|
||||
m_withTaskbar,
|
||||
m_withLibraryButton,
|
||||
m_blockExternalLinks));
|
||||
m_blockExternalLinks,
|
||||
m_indexTemplateString));
|
||||
return mp_server->start();
|
||||
}
|
||||
|
||||
|
|
|
@ -128,7 +128,8 @@ InternalServer::InternalServer(Library* library,
|
|||
bool verbose,
|
||||
bool withTaskbar,
|
||||
bool withLibraryButton,
|
||||
bool blockExternalLinks) :
|
||||
bool blockExternalLinks,
|
||||
std::string indexTemplateString) :
|
||||
m_addr(addr),
|
||||
m_port(port),
|
||||
m_root(normalizeRootUrl(root)),
|
||||
|
@ -137,6 +138,7 @@ InternalServer::InternalServer(Library* library,
|
|||
m_withTaskbar(withTaskbar),
|
||||
m_withLibraryButton(withLibraryButton),
|
||||
m_blockExternalLinks(blockExternalLinks),
|
||||
m_indexTemplateString(indexTemplateString.empty() ? RESOURCE::templates::index_html : indexTemplateString),
|
||||
mp_daemon(nullptr),
|
||||
mp_library(library),
|
||||
mp_nameMapper(nameMapper ? nameMapper : &defaultNameMapper)
|
||||
|
@ -336,7 +338,7 @@ InternalServer::get_matching_if_none_match_etag(const RequestContext& r) const
|
|||
|
||||
std::unique_ptr<Response> InternalServer::build_homepage(const RequestContext& request)
|
||||
{
|
||||
return ContentResponse::build(*this, RESOURCE::templates::index_html, get_default_data(), "text/html; charset=utf-8", true);
|
||||
return ContentResponse::build(*this, m_indexTemplateString, get_default_data(), "text/html; charset=utf-8", true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -54,7 +54,8 @@ class InternalServer {
|
|||
bool verbose,
|
||||
bool withTaskbar,
|
||||
bool withLibraryButton,
|
||||
bool blockExternalLinks);
|
||||
bool blockExternalLinks,
|
||||
std::string indexTemplateString);
|
||||
virtual ~InternalServer() = default;
|
||||
|
||||
MHD_Result handlerCallback(struct MHD_Connection* connection,
|
||||
|
@ -103,6 +104,7 @@ class InternalServer {
|
|||
bool m_withTaskbar;
|
||||
bool m_withLibraryButton;
|
||||
bool m_blockExternalLinks;
|
||||
std::string m_indexTemplateString;
|
||||
struct MHD_Daemon* mp_daemon;
|
||||
|
||||
Library* mp_library;
|
||||
|
|
|
@ -269,7 +269,7 @@ std::string getFileSizeAsString(const std::string& path)
|
|||
return convert.str();
|
||||
}
|
||||
|
||||
std::string getFileContent(const std::string& path)
|
||||
std::string kiwix::getFileContent(const std::string& path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
auto wpath = Utf8ToWide(path);
|
||||
|
@ -302,7 +302,7 @@ std::string getFileContent(const std::string& path)
|
|||
return content;
|
||||
}
|
||||
|
||||
bool fileExists(const std::string& path)
|
||||
bool kiwix::fileExists(const std::string& path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return PathFileExistsW(Utf8ToWide(path).c_str());
|
||||
|
@ -505,7 +505,7 @@ static std::map<std::string, std::string> extMimeTypes = {
|
|||
};
|
||||
|
||||
/* Try to get the mimeType from the file extension */
|
||||
std::string getMimeTypeForFile(const std::string& filename)
|
||||
std::string kiwix::getMimeTypeForFile(const std::string& filename)
|
||||
{
|
||||
std::string mimeType = "text/plain";
|
||||
auto pos = filename.find_last_of(".");
|
||||
|
|
|
@ -29,13 +29,10 @@ std::wstring Utf8ToWide(const std::string& str);
|
|||
|
||||
unsigned int getFileSize(const std::string& path);
|
||||
std::string getFileSizeAsString(const std::string& path);
|
||||
std::string getFileContent(const std::string& path);
|
||||
bool fileExists(const std::string& path);
|
||||
bool makeDirectory(const std::string& path);
|
||||
std::string makeTmpDirectory();
|
||||
bool copyFile(const std::string& sourcePath, const std::string& destPath);
|
||||
bool writeTextFile(const std::string& path, const std::string& content);
|
||||
std::string getMimeTypeForFile(const std::string& filename);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public: // types
|
|||
|
||||
public: // functions
|
||||
ZimFileServer(int serverPort, std::string libraryFilePath);
|
||||
ZimFileServer(int serverPort, const FilePathCollection& zimpaths);
|
||||
ZimFileServer(int serverPort, const FilePathCollection& zimpaths, std::string indexTemplateString = "");
|
||||
~ZimFileServer();
|
||||
|
||||
Response GET(const char* path, const Headers& headers = Headers())
|
||||
|
@ -68,7 +68,7 @@ public: // functions
|
|||
}
|
||||
|
||||
private:
|
||||
void run(int serverPort);
|
||||
void run(int serverPort, std::string indexTemplateString = "");
|
||||
|
||||
private: // data
|
||||
kiwix::Library library;
|
||||
|
@ -88,7 +88,7 @@ ZimFileServer::ZimFileServer(int serverPort, std::string libraryFilePath)
|
|||
run(serverPort);
|
||||
}
|
||||
|
||||
ZimFileServer::ZimFileServer(int serverPort, const FilePathCollection& zimpaths)
|
||||
ZimFileServer::ZimFileServer(int serverPort, const FilePathCollection& zimpaths, std::string indexTemplateString)
|
||||
: manager(&this->library)
|
||||
{
|
||||
for ( const auto& zimpath : zimpaths ) {
|
||||
|
@ -96,10 +96,10 @@ ZimFileServer::ZimFileServer(int serverPort, const FilePathCollection& zimpaths)
|
|||
throw std::runtime_error("Unable to add the ZIM file '" + zimpath + "'");
|
||||
}
|
||||
|
||||
run(serverPort);
|
||||
run(serverPort, indexTemplateString);
|
||||
}
|
||||
|
||||
void ZimFileServer::run(int serverPort)
|
||||
void ZimFileServer::run(int serverPort, std::string indexTemplateString)
|
||||
{
|
||||
const std::string address = "127.0.0.1";
|
||||
nameMapper.reset(new kiwix::HumanReadableNameMapper(library, false));
|
||||
|
@ -108,6 +108,9 @@ void ZimFileServer::run(int serverPort)
|
|||
server->setPort(serverPort);
|
||||
server->setNbThreads(2);
|
||||
server->setVerbose(false);
|
||||
if (!indexTemplateString.empty()) {
|
||||
server->setIndexTemplateString(indexTemplateString);
|
||||
}
|
||||
|
||||
if ( !server->start() )
|
||||
throw std::runtime_error("ZimFileServer failed to start");
|
||||
|
@ -211,6 +214,35 @@ ResourceCollection all200Resources()
|
|||
return concat(resources200Compressible, resources200Uncompressible);
|
||||
}
|
||||
|
||||
TEST(indexTemplateStringTest, emptyIndexTemplate) {
|
||||
const int PORT = 8001;
|
||||
const ZimFileServer::FilePathCollection ZIMFILES {
|
||||
"./test/zimfile.zim",
|
||||
"./test/corner_cases.zim"
|
||||
};
|
||||
|
||||
ZimFileServer zfs(PORT, ZIMFILES, "");
|
||||
EXPECT_EQ(200, zfs.GET("/")->status);
|
||||
}
|
||||
|
||||
TEST(indexTemplateStringTest, indexTemplateCheck) {
|
||||
const int PORT = 8001;
|
||||
const ZimFileServer::FilePathCollection ZIMFILES {
|
||||
"./test/zimfile.zim",
|
||||
"./test/corner_cases.zim"
|
||||
};
|
||||
|
||||
ZimFileServer zfs(PORT, ZIMFILES, "<!DOCTYPE html><head>"
|
||||
"<title>Welcome to kiwix library</title>"
|
||||
"</head>"
|
||||
"</html>");
|
||||
EXPECT_EQ("<!DOCTYPE html><head>"
|
||||
"<title>Welcome to kiwix library</title>"
|
||||
"<link type=\"root\" href=\"\">"
|
||||
"</head>"
|
||||
"</html>", zfs.GET("/")->body);
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, 200)
|
||||
{
|
||||
for ( const Resource& res : all200Resources() )
|
||||
|
|
Loading…
Reference in New Issue