mirror of https://github.com/kiwix/libkiwix.git
170 lines
5.8 KiB
C++
170 lines
5.8 KiB
C++
/*
|
|
* Copyright 2021 Veloman Yunkan <veloman.yunkan@gmail.com>
|
|
*
|
|
* 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 "internalServer.h"
|
|
|
|
#include "library.h"
|
|
#include "opds_dumper.h"
|
|
#include "request_context.h"
|
|
#include "response.h"
|
|
#include "tools/otherTools.h"
|
|
#include "kiwixlib-resources.h"
|
|
|
|
#include <mustache.hpp>
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace kiwix {
|
|
|
|
std::unique_ptr<Response> InternalServer::handle_catalog_v2(const RequestContext& request)
|
|
{
|
|
if (m_verbose.load()) {
|
|
printf("** running handle_catalog_v2");
|
|
}
|
|
|
|
std::string url;
|
|
try {
|
|
url = request.get_url_part(2);
|
|
} catch (const std::out_of_range&) {
|
|
return HTTP404HtmlResponse(*this, request)
|
|
+ urlNotFoundMsg;
|
|
}
|
|
|
|
if (url == "root.xml") {
|
|
return handle_catalog_v2_root(request);
|
|
} else if (url == "searchdescription.xml") {
|
|
const std::string endpoint_root = m_root + "/catalog/v2";
|
|
return ContentResponse::build(*this,
|
|
RESOURCE::catalog_v2_searchdescription_xml,
|
|
kainjow::mustache::object({{"endpoint_root", endpoint_root}}),
|
|
"application/opensearchdescription+xml"
|
|
);
|
|
} else if (url == "entry") {
|
|
const std::string entryId = request.get_url_part(3);
|
|
return handle_catalog_v2_complete_entry(request, entryId);
|
|
} else if (url == "entries") {
|
|
return handle_catalog_v2_entries(request, /*partial=*/false);
|
|
} else if (url == "partial_entries") {
|
|
return handle_catalog_v2_entries(request, /*partial=*/true);
|
|
} else if (url == "categories") {
|
|
return handle_catalog_v2_categories(request);
|
|
} else if (url == "languages") {
|
|
return handle_catalog_v2_languages(request);
|
|
} else if (url == "illustration") {
|
|
return handle_catalog_v2_illustration(request);
|
|
} else {
|
|
return HTTP404HtmlResponse(*this, request)
|
|
+ urlNotFoundMsg;
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<Response> InternalServer::handle_catalog_v2_root(const RequestContext& request)
|
|
{
|
|
return ContentResponse::build(
|
|
*this,
|
|
RESOURCE::templates::catalog_v2_root_xml,
|
|
kainjow::mustache::object{
|
|
{"date", gen_date_str()},
|
|
{"endpoint_root", m_root + "/catalog/v2"},
|
|
{"feed_id", gen_uuid(m_library_id)},
|
|
{"all_entries_feed_id", gen_uuid(m_library_id + "/entries")},
|
|
{"partial_entries_feed_id", gen_uuid(m_library_id + "/partial_entries")},
|
|
{"category_list_feed_id", gen_uuid(m_library_id + "/categories")},
|
|
{"language_list_feed_id", gen_uuid(m_library_id + "/languages")}
|
|
},
|
|
"application/atom+xml;profile=opds-catalog;kind=navigation"
|
|
);
|
|
}
|
|
|
|
std::unique_ptr<Response> InternalServer::handle_catalog_v2_entries(const RequestContext& request, bool partial)
|
|
{
|
|
OPDSDumper opdsDumper(mp_library);
|
|
opdsDumper.setRootLocation(m_root);
|
|
opdsDumper.setLibraryId(m_library_id);
|
|
const auto bookIds = search_catalog(request, opdsDumper);
|
|
const auto opdsFeed = opdsDumper.dumpOPDSFeedV2(bookIds, request.get_query(), partial);
|
|
return ContentResponse::build(
|
|
*this,
|
|
opdsFeed,
|
|
"application/atom+xml;profile=opds-catalog;kind=acquisition"
|
|
);
|
|
}
|
|
|
|
std::unique_ptr<Response> InternalServer::handle_catalog_v2_complete_entry(const RequestContext& request, const std::string& entryId)
|
|
{
|
|
try {
|
|
mp_library->getBookById(entryId);
|
|
} catch (const std::out_of_range&) {
|
|
return HTTP404HtmlResponse(*this, request)
|
|
+ urlNotFoundMsg;
|
|
}
|
|
|
|
OPDSDumper opdsDumper(mp_library);
|
|
opdsDumper.setRootLocation(m_root);
|
|
opdsDumper.setLibraryId(m_library_id);
|
|
const auto opdsFeed = opdsDumper.dumpOPDSCompleteEntry(entryId);
|
|
return ContentResponse::build(
|
|
*this,
|
|
opdsFeed,
|
|
"application/atom+xml;type=entry;profile=opds-catalog"
|
|
);
|
|
}
|
|
|
|
std::unique_ptr<Response> InternalServer::handle_catalog_v2_categories(const RequestContext& request)
|
|
{
|
|
OPDSDumper opdsDumper(mp_library);
|
|
opdsDumper.setRootLocation(m_root);
|
|
opdsDumper.setLibraryId(m_library_id);
|
|
return ContentResponse::build(
|
|
*this,
|
|
opdsDumper.categoriesOPDSFeed(),
|
|
"application/atom+xml;profile=opds-catalog;kind=navigation"
|
|
);
|
|
}
|
|
|
|
std::unique_ptr<Response> InternalServer::handle_catalog_v2_languages(const RequestContext& request)
|
|
{
|
|
OPDSDumper opdsDumper(mp_library);
|
|
opdsDumper.setRootLocation(m_root);
|
|
opdsDumper.setLibraryId(m_library_id);
|
|
return ContentResponse::build(
|
|
*this,
|
|
opdsDumper.languagesOPDSFeed(),
|
|
"application/atom+xml;profile=opds-catalog;kind=navigation"
|
|
);
|
|
}
|
|
|
|
std::unique_ptr<Response> InternalServer::handle_catalog_v2_illustration(const RequestContext& request)
|
|
{
|
|
try {
|
|
const auto bookName = request.get_url_part(3);
|
|
const auto bookId = mp_nameMapper->getIdForName(bookName);
|
|
auto book = mp_library->getBookByIdThreadSafe(bookId);
|
|
auto size = request.get_argument<unsigned int>("size");
|
|
auto illustration = book.getIllustration(size);
|
|
return ContentResponse::build(*this, illustration->getData(), illustration->mimeType);
|
|
} catch(...) {
|
|
return HTTP404HtmlResponse(*this, request)
|
|
+ urlNotFoundMsg;
|
|
}
|
|
}
|
|
|
|
} // namespace kiwix
|