Compare commits

..

2 Commits

Author SHA1 Message Date
renaud gaudin
795bfecb9e trigger here 2023-04-17 13:44:55 +00:00
renaud gaudin
4efa093af8 Revert "Unlink and remove some linked python3 files"
This reverts commit 95bde675ef.
2023-04-17 13:43:34 +00:00
11 changed files with 74 additions and 224 deletions

View File

@@ -3,7 +3,7 @@ name: CI
on:
push:
branches:
- main
- can-revert
pull_request:
jobs:
@@ -39,103 +39,3 @@ jobs:
SKIP_BIG_MEMORY_TEST: 1
LD_LIBRARY_PATH: ${{env.HOME}}/BUILD_native_dyn/INSTALL/lib:${{env.HOME}}/BUILD_native_dyn/INSTALL/lib64
run: meson test -C build --verbose
Linux:
strategy:
fail-fast: false
matrix:
name:
- native_static
- native_dyn
- android_arm
- android_arm64
- win32_static
- win32_dyn
include:
- name: native_static
target: native_static
image_variant: bionic
lib_postfix: '/x86_64-linux-gnu'
- name: native_dyn
target: native_dyn
image_variant: bionic
lib_postfix: '/x86_64-linux-gnu'
- name: android_arm
target: android_arm
image_variant: bionic
lib_postfix: '/arm-linux-androideabi'
- name: android_arm64
target: android_arm64
image_variant: bionic
lib_postfix: '/aarch64-linux-android'
- name: win32_static
target: win32_static
image_variant: f35
lib_postfix: '64'
- name: win32_dyn
target: win32_dyn
image_variant: f35
lib_postfix: '64'
env:
HOME: /home/runner
runs-on: ubuntu-latest
container:
image: "ghcr.io/kiwix/kiwix-build_ci_${{matrix.image_variant}}:36"
steps:
- name: Checkout code
shell: python
run: |
from subprocess import check_call
from os import environ
command = [
'git', 'clone',
'https://github.com/${{github.repository}}',
'--depth=1',
'--branch', '${{ github.head_ref || github.ref_name }}'
]
check_call(command, cwd=environ['HOME'])
- name: Install deps
shell: bash
run: |
ARCHIVE_NAME=deps2_${OS_NAME}_${{matrix.target}}_libkiwix.tar.xz
wget -O- http://tmp.kiwix.org/ci/${ARCHIVE_NAME} | tar -xJ -C /home/runner
- name: Compile
shell: bash
run: |
meson --version
if [[ "${{matrix.target}}" =~ .*_dyn ]]; then
MESON_OPTION="--default-library=shared"
else
MESON_OPTION="--default-library=static"
fi
if [[ "${{matrix.target}}" =~ native_.* ]]; then
MESON_OPTION="$MESON_OPTION -Db_coverage=true"
else
MESON_OPTION="$MESON_OPTION --cross-file $HOME/BUILD_${{matrix.target}}/meson_cross_file.txt"
fi
if [[ "${{matrix.target}}" =~ android_.* ]]; then
MESON_OPTION="$MESON_OPTION -Dstatic-linkage=true"
fi
cd $HOME/libkiwix
meson . build ${MESON_OPTION}
cd build
ninja
env:
PKG_CONFIG_PATH: "/home/runner/BUILD_${{matrix.target}}/INSTALL/lib/pkgconfig:/home/runner/BUILD_${{matrix.target}}/INSTALL/lib${{matrix.lib_postfix}}/pkgconfig"
CPPFLAGS: "-I/home/runner/BUILD_${{matrix.target}}/INSTALL/include"
- name: Test
if: startsWith(matrix.target, 'native_')
shell: bash
run: |
cd $HOME/libkiwix/build
meson test --verbose
ninja coverage
env:
LD_LIBRARY_PATH: "/home/runner/BUILD_${{matrix.target}}/INSTALL/lib:/home/runner/BUILD_${{matrix.target}}/INSTALL/lib${{matrix.lib_postfix}}"
SKIP_BIG_MEMORY_TEST: 1
- name: Publish coverage
if: startsWith(matrix.target, 'native_')
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -26,7 +26,7 @@ kiwix_sources = [
'server/request_context.cpp',
'server/response.cpp',
'server/internalServer.cpp',
'server/internalServer_catalog.cpp',
'server/internalServer_catalog_v2.cpp',
'server/i18n.cpp',
'opds_catalog.cpp',
'version.cpp'

View File

@@ -150,17 +150,17 @@ string OPDSDumper::dumpOPDSFeedV2(const std::vector<std::string>& bookIds, const
const auto booksData = getBooksData(library, nameMapper, bookIds, rootLocation, partial);
const char* const endpoint = partial ? "/partial_entries" : "/entries";
const std::string url = endpoint + (query.empty() ? "" : "?" + query);
const kainjow::mustache::object template_data{
{"date", gen_date_str()},
{"endpoint_root", endpointRoot},
{"feed_id", gen_uuid(libraryId + endpoint + "?" + query)},
{"filter", onlyAsNonEmptyMustacheValue(query)},
{"self_url", url},
{"query", query.empty() ? "" : "?" + query},
{"totalResults", to_string(m_totalResults)},
{"startIndex", to_string(m_startIndex)},
{"itemsPerPage", to_string(m_count)},
{"books", booksData }
{"books", booksData },
{"dump_partial_entries", MustacheData(partial)}
};
return render_template(RESOURCE::templates::catalog_v2_entries_xml, template_data);

View File

@@ -1046,6 +1046,56 @@ std::unique_ptr<Response> InternalServer::handle_catch(const RequestContext& req
+ urlNotFoundMsg;
}
std::unique_ptr<Response> InternalServer::handle_catalog(const RequestContext& request)
{
if (m_verbose.load()) {
printf("** running handle_catalog");
}
std::string host;
std::string url;
try {
host = request.get_header("Host");
url = request.get_url_part(1);
} catch (const std::out_of_range&) {
return HTTP404Response(*this, request)
+ urlNotFoundMsg;
}
if (url == "v2") {
return handle_catalog_v2(request);
}
if (url != "searchdescription.xml" && url != "root.xml" && url != "search") {
return HTTP404Response(*this, request)
+ urlNotFoundMsg;
}
if (url == "searchdescription.xml") {
auto response = ContentResponse::build(*this, RESOURCE::opensearchdescription_xml, get_default_data(), "application/opensearchdescription+xml");
return std::move(response);
}
zim::Uuid uuid;
kiwix::OPDSDumper opdsDumper(mp_library, mp_nameMapper);
opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(getLibraryId());
std::vector<std::string> bookIdsToDump;
if (url == "root.xml") {
uuid = zim::Uuid::generate(host);
bookIdsToDump = mp_library->filter(kiwix::Filter().valid(true).local(true).remote(true));
} else if (url == "search") {
bookIdsToDump = search_catalog(request, opdsDumper);
uuid = zim::Uuid::generate();
}
auto response = ContentResponse::build(
*this,
opdsDumper.dumpOPDSFeed(bookIdsToDump, request.get_query()),
"application/atom+xml; profile=opds-catalog; kind=acquisition; charset=utf-8");
return std::move(response);
}
std::vector<std::string>
InternalServer::search_catalog(const RequestContext& request,
kiwix::OPDSDumper& opdsDumper)
@@ -1088,7 +1138,6 @@ const std::string CONTENT_CSP_HEADER =
"sandbox allow-scripts "
"allow-same-origin "
"allow-top-navigation-by-user-activation "
"allow-modals "
"allow-popups "
"allow-forms "

View File

@@ -33,74 +33,6 @@
namespace kiwix {
namespace
{
enum OPDSResponseKind
{
OPDS_ENTRY,
OPDS_NAVIGATION_FEED,
OPDS_ACQUISITION_FEED
};
const std::string opdsMimeType[] = {
"application/atom+xml;type=entry;profile=opds-catalog;charset=utf-8",
"application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8",
"application/atom+xml;profile=opds-catalog;kind=acquisition;charset=utf-8"
};
} // unnamed namespace
std::unique_ptr<Response> InternalServer::handle_catalog(const RequestContext& request)
{
if (m_verbose.load()) {
printf("** running handle_catalog");
}
std::string host;
std::string url;
try {
host = request.get_header("Host");
url = request.get_url_part(1);
} catch (const std::out_of_range&) {
return HTTP404Response(*this, request)
+ urlNotFoundMsg;
}
if (url == "v2") {
return handle_catalog_v2(request);
}
if (url != "searchdescription.xml" && url != "root.xml" && url != "search") {
return HTTP404Response(*this, request)
+ urlNotFoundMsg;
}
if (url == "searchdescription.xml") {
auto response = ContentResponse::build(*this, RESOURCE::opensearchdescription_xml, get_default_data(), "application/opensearchdescription+xml");
return std::move(response);
}
zim::Uuid uuid;
kiwix::OPDSDumper opdsDumper(mp_library, mp_nameMapper);
opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(getLibraryId());
std::vector<std::string> bookIdsToDump;
if (url == "root.xml") {
uuid = zim::Uuid::generate(host);
bookIdsToDump = mp_library->filter(kiwix::Filter().valid(true).local(true).remote(true));
} else if (url == "search") {
bookIdsToDump = search_catalog(request, opdsDumper);
uuid = zim::Uuid::generate();
}
auto response = ContentResponse::build(
*this,
opdsDumper.dumpOPDSFeed(bookIdsToDump, request.get_query()),
opdsMimeType[OPDS_ACQUISITION_FEED]);
return std::move(response);
}
std::unique_ptr<Response> InternalServer::handle_catalog_v2(const RequestContext& request)
{
if (m_verbose.load()) {
@@ -158,7 +90,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_root(const RequestCo
{"category_list_feed_id", gen_uuid(libraryId + "/categories")},
{"language_list_feed_id", gen_uuid(libraryId + "/languages")}
},
opdsMimeType[OPDS_NAVIGATION_FEED]
"application/atom+xml;profile=opds-catalog;kind=navigation"
);
}
@@ -172,7 +104,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_entries(const Reques
return ContentResponse::build(
*this,
opdsFeed,
opdsMimeType[OPDS_ACQUISITION_FEED]
"application/atom+xml;profile=opds-catalog;kind=acquisition"
);
}
@@ -192,7 +124,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_complete_entry(const
return ContentResponse::build(
*this,
opdsFeed,
opdsMimeType[OPDS_ENTRY]
"application/atom+xml;type=entry;profile=opds-catalog"
);
}
@@ -204,7 +136,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_categories(const Req
return ContentResponse::build(
*this,
opdsDumper.categoriesOPDSFeed(),
opdsMimeType[OPDS_NAVIGATION_FEED]
"application/atom+xml;profile=opds-catalog;kind=navigation"
);
}
@@ -216,7 +148,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_languages(const Requ
return ContentResponse::build(
*this,
opdsDumper.languagesOPDSFeed(),
opdsMimeType[OPDS_NAVIGATION_FEED]
"application/atom+xml;profile=opds-catalog;kind=navigation"
);
}

View File

@@ -51,7 +51,7 @@
}
function queryUrlBuilder() {
let url = `${root}/catalog/v2/entries?`;
let url = `${root}/catalog/search?`;
url += Object.keys(incrementalLoadingParams).map(key => `${key}=${incrementalLoadingParams[key]}`).join("&");
params.forEach((value, key) => {url+= value ? `&${key}=${value}` : ''});
return (url);
@@ -131,13 +131,8 @@
const title = getInnerHtml(book, 'title');
const description = getInnerHtml(book, 'summary');
const id = getInnerHtml(book, 'id');
const langCodesList = getInnerHtml(book, 'language').split(',');
const langCode = langCodesList.length == 1 ? langCodesList[0] : 'mul';
let language = languages[langCode];
if (langCode == 'mul') {
const mulLangList = langCodesList.filter(x => languages.hasOwnProperty(x)).map(x => languages[x]);
language = mulLangList.join(', ');
}
const langCode = getInnerHtml(book, 'language');
const language = languages[langCode];
const tags = getInnerHtml(book, 'tags');
const tagList = tags.split(';').filter(tag => {return !(tag.startsWith('_'))});
const tagFilterLinks = tagList.map((tagValue) => generateTagLink(tagValue));
@@ -267,7 +262,7 @@
}
async function getBookCount(query) {
const url = `${root}/catalog/v2/entries?${query}&count=0`;
const url = `${root}/catalog/search?${query}`;
return await fetch(url).then(async (resp) => {
const data = new window.DOMParser().parseFromString(await resp.text(), 'application/xml');
return parseInt(data.querySelector('totalResults').innerHTML);

View File

@@ -257,7 +257,7 @@ function isExternalUrl(url) {
|| url.startsWith("https:");
}
function handleLinkClick(e) {
function onClickEvent(e) {
const iframeDocument = contentIframe.contentDocument;
const target = matchingAncestorElement(e.target, iframeDocument, "a");
if (target !== null && "href" in target) {
@@ -266,8 +266,6 @@ function handleLinkClick(e) {
if ( viewerSettings.linkBlockingEnabled ) {
return blockLink(target);
}
} else {
target.setAttribute("target", "content_iframe");
}
}
}
@@ -303,7 +301,7 @@ this.Element && function(ElementPrototype) {
}(Element.prototype);
function setup_external_link_blocker() {
setupEventHandler(contentIframe.contentDocument, 'a', 'click', handleLinkClick);
setupEventHandler(contentIframe.contentDocument, 'a', 'click', onClickEvent);
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -6,7 +6,7 @@
<id>{{feed_id}}</id>
<link rel="self"
href="{{endpoint_root}}{{self_url}}"
href="{{endpoint_root}}/{{#dump_partial_entries}}partial_{{/dump_partial_entries}}entries{{{query}}}"
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
<link rel="start"
href="{{endpoint_root}}/root.xml"

View File

@@ -69,7 +69,6 @@
</div>
<iframe id="content_iframe"
name="content_iframe"
referrerpolicy="no-referrer"
onload="on_content_load()"
src="./skin/blank.html?KIWIXCACHEID" title="ZIM content" width="100%"

View File

@@ -728,7 +728,7 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_range)
const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?start=1&count=1");
EXPECT_EQ(r->status, 200);
EXPECT_EQ(maskVariableOPDSFeedData(r->body),
CATALOG_V2_ENTRIES_PREAMBLE("?start=1&amp;count=1")
CATALOG_V2_ENTRIES_PREAMBLE("?start=1&count=1")
" <title>Filtered Entries (start=1&amp;count=1)</title>\n"
" <updated>YYYY-MM-DDThh:mm:ssZ</updated>\n"
" <totalResults>3</totalResults>\n"
@@ -793,24 +793,6 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_language)
}
}
TEST_F(LibraryServerTest, catalog_v2_entries_multiple_filters)
{
{
const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?lang=fra&category=jazz");
EXPECT_EQ(r->status, 200);
EXPECT_EQ(maskVariableOPDSFeedData(r->body),
CATALOG_V2_ENTRIES_PREAMBLE("?lang=fra&amp;category=jazz")
" <title>Filtered Entries (lang=fra&amp;category=jazz)</title>\n"
" <updated>YYYY-MM-DDThh:mm:ssZ</updated>\n"
" <totalResults>1</totalResults>\n"
" <startIndex>0</startIndex>\n"
" <itemsPerPage>1</itemsPerPage>\n"
CHARLES_RAY_CATALOG_ENTRY
"</feed>\n"
);
}
}
TEST_F(LibraryServerTest, catalog_v2_individual_entry_access)
{
const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entry/raycharles");
@@ -1211,7 +1193,7 @@ TEST_F(LibraryServerTest, noJS) {
FILTERS_HTML("")
HOME_BODY_0_RESULTS
FINAL_HTML_TEXT);
// no_js_download
r = zfs1_->GET("/ROOT%23%3F/nojs/download/zimfile");
EXPECT_EQ(r->status, 200);

View File

@@ -63,7 +63,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.css" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.css?cacheid=e4d76d16" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.js" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.js?cacheid=07b06fca" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.js?cacheid=d38d9ef1" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js" },
@@ -73,7 +73,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=bbdaf425" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=b548ad94" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=b9a574d4" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" },
@@ -288,7 +288,7 @@ R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/index.css?cacheid=e4d76d16"
<script type="text/javascript" src="/ROOT%23%3F/skin/languages.js?cacheid=b00b12db" defer></script>
<script src="/ROOT%23%3F/skin/isotope.pkgd.min.js?cacheid=2e48d392" defer></script>
<script src="/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3"></script>
<script type="text/javascript" src="/ROOT%23%3F/skin/index.js?cacheid=07b06fca" defer></script>
<script type="text/javascript" src="/ROOT%23%3F/skin/index.js?cacheid=d38d9ef1" defer></script>
<img src="/ROOT%23%3F/skin/feed.svg?cacheid=055b333f"
<img src="/ROOT%23%3F/skin/langSelector.svg?cacheid=00b59961"
)EXPECTEDRESULT"
@@ -312,7 +312,7 @@ R"EXPECTEDRESULT( <link type="text/css" href="./skin/taskbar.css?cacheid=bbda
<link type="text/css" href="./skin/css/autoComplete.css?cacheid=08951e06" rel="Stylesheet" />
<script type="module" src="./skin/i18n.js?cacheid=2cf0f8c5" defer></script>
<script type="text/javascript" src="./skin/languages.js?cacheid=b00b12db" defer></script>
<script type="text/javascript" src="./skin/viewer.js?cacheid=b548ad94" defer></script>
<script type="text/javascript" src="./skin/viewer.js?cacheid=b9a574d4" defer></script>
<script type="text/javascript" src="./skin/autoComplete.min.js?cacheid=1191aaaf"></script>
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";
<img src="./skin/langSelector.svg?cacheid=00b59961">
@@ -497,13 +497,8 @@ TEST_F(ServerTest, MimeTypes)
{ "/skin/blank.html", "text/html" },
{ "/skin/index.css", "text/css" },
{ "/skin/index.js", "application/javascript" },
{ "/catalog/root.xml", "application/atom+xml;profile=opds-catalog;kind=acquisition;charset=utf-8" },
{ "/catalog/v2/searchdescription.xml", "application/opensearchdescription+xml" },
{ "/catalog/v2/root.xml", "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8" },
{ "/catalog/v2/languages", "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8" },
{ "/catalog/v2/categories", "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8" },
{ "/catalog/v2/entries", "application/atom+xml;profile=opds-catalog;kind=acquisition;charset=utf-8" },
{ "/catalog/v2/entry/6f1d19d0-633f-087b-fb55-7ac324ff9baf", "application/atom+xml;type=entry;profile=opds-catalog;charset=utf-8" },
{ "/catalog/v2/root.xml", "application/atom+xml;profile=opds-catalog;kind=navigation" },
{ "/skin/search-icon.svg", "image/svg+xml" },
{ "/skin/bittorrent.png", "image/png" },
{ "/skin/favicon/favicon.ico", "image/x-icon" },