Compare commits

...

20 Commits

Author SHA1 Message Date
Nikhil Tanwar
42a2ce2534 fixup! fixup! fixup! fixup! Introduce Manager::addBooksFromDirectory() 2025-11-30 20:05:44 +01:00
Nikhil Tanwar
3945dda5d0 fixup! fixup! fixup! Introduce Manager::addBooksFromDirectory() 2025-11-30 20:05:44 +01:00
Nikhil Tanwar
d65dd859da fixup! fixup! Introduce Manager::addBooksFromDirectory() 2025-11-30 20:05:44 +01:00
Nikhil Tanwar
d94d2c1e8a Remove skipInvalid flag
skipInvalid=false makes little sense, if an invalid book is found, we can simply choose to ignore it rather stopping the whole operation midway.
2025-11-30 20:05:44 +01:00
Nikhil Tanwar
a20b135f80 fixup! Introduce Manager::addBooksFromDirectory() 2025-11-30 20:05:44 +01:00
Nikhil Tanwar
6d520a8aa7 Introduce Manager::addBooksFromDirectory()
Added a function to load books from a directory. Requires rootPath to iterate over.
2025-11-30 20:05:44 +01:00
Kelson
f82bfc068f Merge pull request #1252 from kiwix/release-14.1.1
Release 14.1.1
2025-11-30 16:37:21 +01:00
Emmanuel Engelhart
e6335be897 14.1.1 changelog 2025-11-30 16:34:37 +01:00
Emmanuel Engelhart
1074e833b7 Bump-up version to 14.1.1 2025-11-30 16:30:36 +01:00
Kelson
9da5fbad1e Merge pull request #1248 from kiwix/translatewiki
Localisation updates from https://translatewiki.net.
2025-11-30 16:29:27 +01:00
translatewiki.net
1869fb4e8e Localisation updates from https://translatewiki.net. 2025-11-30 16:29:19 +01:00
Kelson
536198fa38 Merge pull request #1250 from kiwix/kiwix-serve_nosearchbar_fix
Fix for kiwix-serve --nosearchbar
2025-11-30 15:51:19 +01:00
Veloman Yunkan
ca808718f7 Fix for kiwix-serve --nosearchbar
In kiwix-serve --nosearchbar mode the viewer is still engaged and
its setup must completed appropriately, otherwise the content requested
via the URL is not loaded.
2025-11-28 17:16:24 +04:00
Veloman Yunkan
b65074f961 Got rid of an unused variable
This should have been done in commit "Viewer iframe location is checked
every 0.1s"
2025-11-28 17:10:13 +04:00
Kelson
8b7d1ef9ec Merge pull request #1249 from kiwix/fix_for_intermittent_content_blank.html_errors
Fix for intermittent /content/blank.html errors
2025-11-27 16:38:54 +01:00
Veloman Yunkan
8b0f01fa9b Fix for intermittent /content/blank.html errors
Monitoring of the iframe content URL could result in the check being
performed while the iframe placeholder page /skin/blank.html was still
loaded (a slow connection increased the odds of it happening). This was
contrary to the assumptions behind the logic of that procedure and the
outcome was an attempt to load the /content/blank.html page with a
subsequent 404 error.

Now that situation is taken into account.
2025-11-27 17:55:14 +04:00
Kelson
33f22eb966 Merge pull request #1241 from vighnesh-sawant/mustache-tag-escaping
Avoid interpretation of content coming from zim by mustache
2025-11-10 20:10:16 +01:00
Vighnesh
55c13c3d24 Avoid interpretation of content coming from zim by mustache 2025-11-10 20:10:06 +01:00
Veloman Yunkan
2b1f556c20 Merge pull request #1239 from kiwix/translatewiki
Localisation updates from https://translatewiki.net.
2025-11-10 18:41:03 +04:00
translatewiki.net
e0cd5a1642 Localisation updates from https://translatewiki.net. 2025-11-10 13:13:07 +01:00
11 changed files with 138 additions and 33 deletions

View File

@@ -1,3 +1,11 @@
libkiwix 14.1.1
===============
* Server:
- Fix regression for kiwix-serve --nosearchbar (@veloman-yunkan #1250)
- Avoid results content interpretation... crash in fulltext search (@vighnesh-sawant #1241)
- Fix for intermittent /content/blank.html errors (@veloman-yunkan #1249)
libkiwix 14.1.0
===============

View File

@@ -155,6 +155,15 @@ class Manager
const std::string& url = "",
const bool checkMetaData = false);
/**
* Add all books from the directory tree into the library.
*
* @param path The path of the directory to scan.
* @param verboseFlag Verbose logs flag.
*/
void addBooksFromDirectory(const std::string& path,
const bool verboseFlag = false);
std::string writableLibraryPath;
bool m_hasSearchResult = false;

View File

@@ -1,5 +1,5 @@
project('libkiwix', 'cpp',
version : '14.1.0',
version : '14.1.1',
license : 'GPLv3+',
default_options : ['c_std=c11', 'cpp_std=c++17', 'werror=true'])

View File

@@ -23,6 +23,14 @@
#include "tools/pathTools.h"
#include <pugixml.hpp>
#include <filesystem>
#include <iostream>
#include <set>
#include <queue>
#include <cctype>
#include <algorithm>
namespace fs = std::filesystem;
namespace kiwix
{
@@ -251,6 +259,58 @@ bool Manager::addBookFromPath(const std::string& pathToOpen,
.empty());
}
void Manager::addBooksFromDirectory(const std::string& path,
const bool verboseFlag)
{
std::set<std::string> iteratedDirs;
std::queue<std::string> dirQueue;
dirQueue.push(fs::absolute(path).u8string());
int totalBooksAdded = 0;
if (verboseFlag)
std::cout << "Adding books from the directory tree: " << dirQueue.front() << std::endl;
while (!dirQueue.empty()) {
const auto currentPath = dirQueue.front();
dirQueue.pop();
if (verboseFlag)
std::cout << "Visiting directory: " << currentPath << std::endl;
for (const auto& dirEntry : fs::directory_iterator(currentPath)) {
auto resolvedPath = dirEntry.path();
if (fs::is_symlink(dirEntry)) {
try {
resolvedPath = fs::canonical(dirEntry.path());
} catch (const std::exception& e) {
std::cerr << "Could not resolve symlink " << resolvedPath.u8string() << " to a valid path. Skipping..." << std::endl;
continue;
}
}
const std::string pathString = resolvedPath.u8string();
std::string resolvedPathExtension = resolvedPath.extension();
std::transform(resolvedPathExtension.begin(), resolvedPathExtension.end(), resolvedPathExtension.begin(),
[](unsigned char c){ return std::tolower(c); });
if (fs::is_directory(resolvedPath)) {
if (iteratedDirs.find(pathString) == iteratedDirs.end())
dirQueue.push(pathString);
else if (verboseFlag)
std::cout << "Already iterated over " << pathString << ". Skipping..." << std::endl;
} else if (resolvedPathExtension == ".zim" || resolvedPathExtension == ".zimaa") {
if (!this->addBookFromPath(pathString, pathString, "", false)) {
std::cerr << "Could not add " << pathString << " into the library." << std::endl;
} else if (verboseFlag) {
std::cout << "Added " << pathString << " into the library." << std::endl;
totalBooksAdded++;
}
} else if (verboseFlag) {
std::cout << "Skipped " << pathString << " - unsupported file type or permission denied." << std::endl;
}
}
iteratedDirs.insert(currentPath);
}
if (verboseFlag)
std::cout << "Traversal completed. Total books added: " << totalBooksAdded << std::endl;
}
bool Manager::readBookFromPath(const std::string& path, kiwix::Book* book)
{
std::string tmp_path = path;

View File

@@ -1,13 +1,18 @@
{
"@metadata": {
"authors": [
"Jimkats",
"Kelson",
"Norhorn",
"Ανώνυμος Βικιπαιδιστής"
]
},
"name": "Αγγλικά",
"suggest-full-text-search": "περιέχει '{{{SEARCH_TERMS}}}'...",
"no-such-book": "Δεν υπάρχει τέτοιο βιβλίο: {{BOOK_NAME}}",
"caution-warning": "Προσοχή!",
"search-result-book-info": "από {{BOOK_TITLE}}",
"word-count": "{{COUNT}} λέξεις",
"welcome-page-overzealous-filter": "Κανένα αποτέλεσμα. Θέλετε να <a href=\"{{URL}}\">επαναφέρετε το φίλτρο</a>;",
"powered-by-kiwix-html": "Με την υποστήριξη by&nbsp;<a href=\"https://kiwix.org\">Kiwix</a>",
"search": "Αναζήτηση",
@@ -19,10 +24,10 @@
"direct-download-alt-text": "άμεση λήψη",
"hash-download-alt-text": "λήψη αναγνωριστικού",
"magnet-alt-text": "λήψη μαγνήτη",
"torrent-download-link-text": "Αρχείο torrent",
"torrent-download-alt-text": "λήψη torrent",
"filter-by-tag": ίλτρο ανά ετικέτα \"{{TAG}}\"",
"stop-filtering-by-tag": "Διακοπή φίλτρου ανά ετικέτα \"{{TAG}}\"",
"torrent-download-link-text": "BitTorrent",
"torrent-download-alt-text": "Λήψη μέσω BitTorrent",
"filter-by-tag": ιλτράρισμα κατά ετικέτα \"{{{TAG}}}\"",
"stop-filtering-by-tag": "Διακοπή φιλτραρίσματος κατά ετικέτα \"{{{TAG}}}\"",
"welcome-to-kiwix-server": "Καλώς ορίσατε στον διακομιστή Kiwix",
"download-links-heading": "Λήψη συνδέσμων για <b><i>{{BOOK_TITLE}}</i></b>",
"download-links-title": "Κατεβάστε το βιβλίο",

View File

@@ -1,6 +1,7 @@
{
"@metadata": {
"authors": [
"Apq",
"Jopparn",
"Larsa",
"Rofiatmustapha12",
@@ -25,9 +26,25 @@
"400-page-heading": "Ogiltig begäran",
"404-page-title": "Innehållet hittades inte",
"404-page-heading": "Hittades inte",
"new-404-page-title": "Sidan kunde inte hittas",
"new-404-page-heading": "Hoppsan. Sidan hittades inte.",
"404-img-text": "Hittades ej!",
"path-was-not-found": "Den begärda sökvägen hittades ej:",
"404-advice.p1": "Innehållet du letar efter kan fortfarande vara tillgängligt, men det kan finnas på en annan plats i ZIM-filen.",
"404-advice.p2": "Vänligen:",
"404-advice.p3": "Försök att använda sökfunktionen för att hitta det innehåll du vill ha",
"404-advice.p4": "Leta efter nyckelord eller titlar relaterade till den information du söker",
"404-advice.p5": "Den här metoden bör hjälpa dig att hitta önskat innehåll, även om den ursprungliga länken inte fungerar korrekt.",
"500-page-title": "Internt serverfel",
"500-page-heading": "Internt serverfel",
"500-page-text": "Ett internt serverfel uppstod. Vi ber om ursäkt för det :/",
"500-page-heading": "Hoppsan. Sidan fungerar inte.",
"500-page-text": "Den begärda sökvägen kan inte levereras korrekt:",
"500-img-text": "Sidan fungerar ej",
"external-link-detected": "Extern länk upptäckt",
"caution-warning": "Varning!",
"external-link-intro": "Du är på väg att lämna Kiwix ZIM-läsare för att gå online till",
"external-link-advice.p1": "Länken du försöker komma åt är inte en del av ditt offlinepaket och kräver en internetanslutning.",
"external-link-advice.p2": "Om du kan gå online kan du försöka öppna länken.",
"external-link-advice.p3": "Du kan annars återgå till ditt ZIM-innehåll offline genom att använda webbläsarens bakåtknapp.",
"fulltext-search-unavailable": "Fulltextsökning är inte tillgänglig",
"no-search-results": "Sökmaskinen för fulltext är inte tillgänglig för detta innehåll.",
"search-results-page-title": "Sök: {{SEARCH_PATTERN}}",
@@ -36,9 +53,9 @@
"search-result-book-info": "från {{BOOK_TITLE}}",
"word-count": "{{COUNT}} ord",
"library-button-text": "Gå till hemsidan",
"home-button-text": "Gå till huvudsidan för \"{{BOOK_TITLE}}\"",
"home-button-text": "Gå till huvudsidan för '{{{BOOK_TITLE}}}'",
"random-page-button-text": "Gå till en slumpmässigt utvald sida",
"searchbox-tooltip": "Sök efter \"{{BOOK_TITLE}}\"",
"searchbox-tooltip": "Sök '{{{BOOK_TITLE}}}'",
"confusion-of-tongues": "Två eller fler böcker på olika språk skulle delta i sökningen, vilket kan ge förvirrande resultat.",
"welcome-page-overzealous-filter": "Inga resultat. Vill du <a href=\"{{URL}}\">återställa filtret</a>?",
"powered-by-kiwix-html": "Drivs av&nbsp;<a href=\"https://kiwix.org\">Kiwix</a>",
@@ -73,5 +90,6 @@
"book-category.wikiversity": "Wikiversity",
"book-category.wikivoyage": "Wikivoyage",
"book-category.wiktionary": "Wiktionary",
"book-category.other": "Övriga"
"book-category.other": "Övriga",
"text-loading-content": "Laddar innehåll"
}

View File

@@ -2,7 +2,8 @@
"@metadata": {
"authors": [
"Hedda",
"Rofiatmustapha12"
"Rofiatmustapha12",
"SaldırganSincap"
]
},
"name": "Türkçe",
@@ -23,8 +24,8 @@
"404-page-title": "içerik bulunamadı",
"404-page-heading": "Bulunamadı",
"500-page-title": "İç Sunucu Hatası",
"500-page-heading": "İç Sunucu Hatası",
"500-page-text": "Dahili bir sunucu hatası oluştu. Bunun için üzgünüz :/",
"500-page-heading": "Üzgünüz. Sayfa çalışmıyor.",
"500-page-text": "İstenen yol düzgün bir şekilde teslim edilemiyor:",
"fulltext-search-unavailable": "Tam metin araması kullanılamıyor",
"no-search-results": "Tam metin arama motoru bu içerik için kullanılamaz.",
"search-results-page-title": "Arama: {{SEARCH_PATTERN}}",
@@ -33,9 +34,9 @@
"search-result-book-info": "{{BOOK_TITLE}} adlı kitaptan",
"word-count": "{{COUNT}} kelime",
"library-button-text": "Karşılama sayfasına git",
"home-button-text": "'{{BOOK_TITLE}}' anasayfasına gidin",
"home-button-text": "'{{{BOOK_TITLE}}}' ana sayfasına git",
"random-page-button-text": "Rastgele seçilen bir sayfaya git",
"searchbox-tooltip": "'{{BOOK_TITLE}}' ara",
"searchbox-tooltip": "'{{{BOOK_TITLE}}}' ara",
"confusion-of-tongues": "Aramaya farklı dillerde iki veya daha fazla kitap katılacak ve bu da kafa karıştırıcı sonuçlara yol açabilecektir.",
"welcome-page-overzealous-filter": "Sonuç yok. <a href=\"{{URL}}\">Filtreyi sıfırlamak</a> ister misiniz?",
"powered-by-kiwix-html": "<a href=\"https://kiwix.org\">Kiwix</a> tarafından desteklenmektedir",
@@ -45,16 +46,16 @@
"count-of-matching-books": "{{COUNT}} kitap",
"download": "İndir",
"direct-download-link-text": "Doğrudan",
"direct-download-alt-text": "direkt indirme",
"hash-download-link-text": "Sha256 haşesi",
"hash-download-alt-text": "csv indir",
"direct-download-alt-text": "Doğrudan HTTP(S) üzerinden indir",
"hash-download-link-text": "SHA-256 sağlama toplamı",
"hash-download-alt-text": "SHA-256 dosya toplam kontrolünü görüntüle",
"magnet-link-text": "Mıknatıs bağlantısı",
"magnet-alt-text": "mıknatısı indir",
"torrent-download-link-text": "Hedef dosya",
"torrent-download-alt-text": "torrenti indir",
"magnet-alt-text": "Mıknatıs bağlantısıyla indir",
"torrent-download-link-text": "BitTorrent",
"torrent-download-alt-text": "BitTorrent üzerinden indir",
"library-opds-feed-all-entries": "Kütüphane OPDS Akışı - Tüm girişler",
"filter-by-tag": "\"{{TAG}}\" etiketine göre filtrele",
"stop-filtering-by-tag": "\"{{TAG}}\" etiketine göre filtrelemeyi durdur",
"filter-by-tag": "\"{{{TAG}}}\" etiketine göre filtrele",
"stop-filtering-by-tag": "\"{{{TAG}}}\" etiketine göre filtrelemeyi durdur",
"library-opds-feed-parameterised": "Kütüphane OPDS Özet Akışı - {{#LANG}}\nLanguage: {{LANG}} {{/LANG}}{{#CATEGORY}}\nCategory: {{CATEGORY}} {{/CATEGORY}} ile eşleşen girişler {{#TAG}}\nTag: {{TAG}} {{/TAG}}{{#Q}}\nQuery: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "Kiwix Sunucusuna Hoş Geldiniz",
"download-links-heading": "<b><i>{{BOOK_TITLE}}</i></b> için indirme bağlantıları",

View File

@@ -271,10 +271,12 @@ function translateErrorPageIfNeeded() {
let iframeLocationHref = null;
function handle_content_url_change() {
if ( iframeLocationHref == contentIframe.contentWindow.location.href )
const iframeLocation = contentIframe.contentWindow.location;
if ( iframeLocationHref == iframeLocation.href ||
!iframeLocation.pathname.startsWith(root + '/content/') )
return;
const iframeLocation = contentIframe.contentWindow.location;
iframeLocationHref = iframeLocation.href;
console.log('handle_content_url_change: ' + iframeLocation.href);
document.title = contentIframe.contentDocument.title;
@@ -431,8 +433,6 @@ function setup_chaperon_mode() {
}
}
let viewerSetupComplete = false;
function on_content_load() {
const loader = document.getElementById("kiwix__loader");
@@ -588,6 +588,7 @@ function setupViewer() {
const kiwixToolBarWrapper = document.getElementById('kiwixtoolbarwrapper');
if ( ! viewerSettings.toolbarEnabled ) {
finishViewerSetup();
return;
}
@@ -636,10 +637,13 @@ function updateUIText() {
function finishViewerSetupOnceTranslationsAreLoaded()
{
updateUIText();
finishViewerSetup();
}
function finishViewerSetup()
{
handle_location_hash_change();
window.onhashchange = handle_location_hash_change;
window.onpopstate = handle_history_state_change;
viewerSetupComplete = true;
}

View File

@@ -117,7 +117,7 @@
{{title}}
</a>
{{#snippet}}
<cite>{{>snippet}}...</cite>
<cite>{{{snippet}}}...</cite>
{{/snippet}}
{{#bookInfo}}
<div class="book-title">{{{bookInfo}}}</div>

View File

@@ -21,7 +21,7 @@
<title>{{title}}</title>
<link>{{absolutePath}}</link>
{{#snippet}}
<description>{{>snippet}}...</description>
<description>{{{snippet}}}...</description>
{{/snippet}}
{{#bookTitle}}
<book>

View File

@@ -77,7 +77,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=42e90cb9" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=3208c3ed" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=00e0fdf3" },
{ 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" },
@@ -338,7 +338,7 @@ R"EXPECTEDRESULT( <link type="text/css" href="./skin/kiwix.css?cacheid=b4e29e
<script type="text/javascript" src="./skin/polyfills.js?cacheid=a0e0343d"></script>
<script type="module" src="./skin/i18n.js?cacheid=e9a10ac1" defer></script>
<script type="text/javascript" src="./skin/languages.js?cacheid=08955948" defer></script>
<script type="text/javascript" src="./skin/viewer.js?cacheid=3208c3ed" defer></script>
<script type="text/javascript" src="./skin/viewer.js?cacheid=00e0fdf3" defer></script>
<script type="text/javascript" src="./skin/autoComplete/autoComplete.min.js?cacheid=1191aaaf"></script>
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";
<label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label>