From 0d09ff822b90559103d109d88da5e1bacbe83927 Mon Sep 17 00:00:00 2001 From: Nikhil Tanwar <2002nikhiltanwar@gmail.com> Date: Tue, 12 Apr 2022 12:11:55 +0530 Subject: [PATCH] Replace deprecated functions This replaces the deprecated Reader and Favicon functions from libkiwix kiwix::Reader functions are converted to use zim::Archive Favicon functions are converted to use Illustration Fix #805 --- resources/i18n/en.json | 1 + src/contentmanager.cpp | 26 ++++++++++++-- src/kiwixapp.cpp | 9 +++-- src/library.cpp | 21 +++++------ src/library.h | 6 ++-- src/readinglistbar.cpp | 13 ++++--- src/suggestionlistworker.cpp | 45 ++++++++++++++++++------ src/urlschemehandler.cpp | 68 ++++++++++++++++++++++++++---------- src/webview.cpp | 10 ++++-- 9 files changed, 142 insertions(+), 57 deletions(-) diff --git a/resources/i18n/en.json b/resources/i18n/en.json index a41af4d63..1c00c7b90 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -8,6 +8,7 @@ "error-downloader-window-title":"Cannot create downloader", "error-downloader-launch-message":"Impossible to launch downloader, Kiwix-desktop will start but all download functions will not working!", "error-launch-server-message":"An error has occured!", + "error-archive":"Cannot get the archive", "open-zim":"Open Zim", "local-kiwix-server":"Local Kiwix Server", "random-article":"Random Article", diff --git a/src/contentmanager.cpp b/src/contentmanager.cpp index 42d431cea..99405eac1 100644 --- a/src/contentmanager.cpp +++ b/src/contentmanager.cpp @@ -80,13 +80,33 @@ QStringList ContentManager::getBookInfos(QString id, const QStringList &keys) ADD_V("url", getUrl); ADD_V("name", getName); ADD_V("origId", getOrigId); - ADD_V("faviconMimeType", getFaviconMimeType); ADD_V("downloadId", getDownloadId); - ADD_V("faviconUrl", getFaviconUrl); if (key == "favicon") { - auto s = b->getFavicon(); + auto s = b->getIllustration(48)->getData(); values.append(QByteArray::fromStdString(s).toBase64()); } + if (key == "faviconMimeType") { + std::string mimeType; + try { + auto item = b->getIllustration(48); + mimeType = item->mimeType; + } catch (...) { + const kiwix::Book::Illustration tempIllustration; + mimeType = tempIllustration.mimeType; + } + values.append(QString::fromStdString(mimeType)); + } + if (key == "faviconUrl") { + std::string url; + try { + auto item = b->getIllustration(48); + url = item->url; + } catch (...) { + const kiwix::Book::Illustration tempIllustration; + url = tempIllustration.url; + } + values.append(QString::fromStdString(url)); + } if (key == "size") { values.append(QString::number(b->getSize())); } diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp index 01de5997f..845ddc5e1 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -236,17 +236,20 @@ void KiwixApp::openRandomUrl(bool newTab) if (zimId.isEmpty()) { return; } - auto reader = m_library.getReader(zimId); + try { - auto entry = reader->getRandomPage(); + auto archive = m_library.getArchive(zimId); + auto entry = archive->getRandomEntry(); QUrl url; url.setScheme("zim"); url.setHost(zimId + ".zim"); url.setPath("/" + QString::fromStdString(entry.getPath())); openUrl(url, newTab); - } catch ( const kiwix::NoEntry& ) { + } catch (const zim::EntryNotFound& e) { showMessage(gt("random-article-error"), gt("error-title"), QMessageBox::Information); + } catch (std::out_of_range& e) { + showMessage(gt("error-archive"), gt("error-title"), QMessageBox::Information); } } diff --git a/src/library.cpp b/src/library.cpp index 2f8478edf..ed762ac42 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -58,22 +58,19 @@ QString Library::openBookFromPath(const QString &zimPath) return QString::fromStdString(id); } -std::shared_ptr Library::getReader(const QString &zimId) +std::shared_ptr Library::getArchive(const QString &zimId) { - try { - return m_library.getReaderById(zimId.toStdString()); - } catch (std::out_of_range& e) { - return nullptr; - } + return m_library.getArchiveById(zimId.toStdString()); } -std::shared_ptr Library::getSearcher(const QString &zimId) +std::shared_ptr Library::getSearcher(const QString &zimId) { - auto searcher = std::make_shared(); - try { - searcher->add_reader(m_library.getReaderById(zimId.toStdString()).get()); - } catch(std::out_of_range& e) { - return nullptr; + std::shared_ptr searcher; + auto archive = getArchive(zimId); + if (!searcher) { + searcher = std::make_shared(*archive); + } else { + searcher->addArchive(*archive); } return searcher; } diff --git a/src/library.h b/src/library.h index 8446dee92..81740d9c9 100644 --- a/src/library.h +++ b/src/library.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include @@ -28,8 +30,8 @@ class Library : public QObject Library(const QString& libraryDirectory); virtual ~Library(); QString openBookFromPath(const QString& zimPath); - std::shared_ptr getReader(const QString& zimId); - std::shared_ptr getSearcher(const QString& zimId); + std::shared_ptr getArchive(const QString& zimId); + std::shared_ptr getSearcher(const QString& zimId); QStringList getBookIds() const; QStringList listBookIds(const kiwix::Filter& filter, kiwix::supportedListSortBy sortBy, bool ascending) const; const std::vector getBookmarks(bool onlyValidBookmarks = false) const { return m_library.getBookmarks(onlyValidBookmarks); } diff --git a/src/readinglistbar.cpp b/src/readinglistbar.cpp index 686e5bd37..1e50f1cba 100644 --- a/src/readinglistbar.cpp +++ b/src/readinglistbar.cpp @@ -31,12 +31,15 @@ void ReadingListBar::setupList() auto listWidget = ui->listWidget; listWidget->clear(); for(auto& bookmark:bookmarks) { - auto reader = library->getReader(QString::fromStdString(bookmark.getBookId())); - if (reader == nullptr) + std::shared_ptr archive; + try { + archive = library->getArchive(QString::fromStdString(bookmark.getBookId())); + } catch (std::out_of_range& e) { continue; - std::string content; - std::string mimeType; - reader->getFavicon(content, mimeType); + } + auto illustration = archive->getIllustrationItem(48); + std::string content = illustration.getData(); + std::string mimeType = illustration.getMimetype(); QPixmap pixmap; pixmap.loadFromData(reinterpret_cast(content.data()), content.size()); auto icon = QIcon(pixmap); diff --git a/src/suggestionlistworker.cpp b/src/suggestionlistworker.cpp index d2bdb1a65..0aa079f6d 100644 --- a/src/suggestionlistworker.cpp +++ b/src/suggestionlistworker.cpp @@ -1,5 +1,6 @@ #include "suggestionlistworker.h" #include "kiwixapp.h" +#include SuggestionListWorker::SuggestionListWorker(const QString& text, int token, QObject *parent) : QThread(parent), @@ -8,6 +9,30 @@ SuggestionListWorker::SuggestionListWorker(const QString& text, int token, QObje { } +std::string lcAll(std::string title) +{ + QString word = QString::fromStdString(title); + return word.toLower().toStdString(); +} + +bool searchSuggestionsSmart(std::shared_ptr archive, + std::string prefix, + unsigned int suggestionsCount, + kiwix::SuggestionsList_t& results) +{ + auto suggestionSearcher = zim::SuggestionSearcher(*archive); + if (archive->hasTitleIndex()) { + auto suggestionSearch = suggestionSearcher.suggest(prefix); + const auto suggestions = suggestionSearch.getResults(0, suggestionsCount); + for (auto current : suggestions) { + kiwix::SuggestionItem suggestion(current.getTitle(), lcAll(current.getTitle()), + current.getPath(), current.getSnippet()); + results.push_back(suggestion); + } + } + return results.size() > 0; +} + void SuggestionListWorker::run() { QStringList suggestionList; @@ -18,25 +43,23 @@ void SuggestionListWorker::run() return; auto qurl = current->url(); auto currentZimId = qurl.host().split(".")[0]; - auto reader = KiwixApp::instance()->getLibrary()->getReader(currentZimId); - QUrl url; - url.setScheme("zim"); - if (reader) { + try { + auto archive = KiwixApp::instance()->getLibrary()->getArchive(currentZimId); + QUrl url; + url.setScheme("zim"); url.setHost(currentZimId + ".zim"); kiwix::SuggestionsList_t suggestions; - reader->searchSuggestionsSmart(m_text.toStdString(), 15, suggestions); + searchSuggestionsSmart(archive, m_text.toStdString(), 15, suggestions); for (auto& suggestion: suggestions) { QString path = QString("/") + QString::fromStdString(suggestion.getPath()); url.setPath(path); suggestionList.append(QString::fromStdString(suggestion.getTitle())); urlList.append(url); } - } - // Propose fulltext search - url.setPath(""); - if (reader) { - if (reader->hasFulltextIndex()) { + // Propose fulltext search + url.setPath(""); + if (archive->hasFulltextIndex()) { // The host is used to determine the currentZimId // The content query item is used to know in which zim search (as for kiwix-serve) url.setHost(currentZimId + ".search"); @@ -47,7 +70,7 @@ void SuggestionListWorker::run() suggestionList.append(m_text + " (" + gt("fulltext-search") + ")"); urlList.append(url); } - } else { + } catch (std::out_of_range& e) { // We do not allow multi zim search for now. // We don't have a correct UI to select on which zim search, // how to display results, ... diff --git a/src/urlschemehandler.cpp b/src/urlschemehandler.cpp index 8a2b826ee..b146c7e32 100644 --- a/src/urlschemehandler.cpp +++ b/src/urlschemehandler.cpp @@ -8,11 +8,41 @@ #include #include +#include +#include +#include + UrlSchemeHandler::UrlSchemeHandler() { } +zim::Entry getEntryFromPath(const zim::Archive& archive, const std::string& path) +{ + try { + return archive.getEntryByPath(path); + } catch (zim::EntryNotFound& e) { + if (path.empty() || path == "/") { + return archive.getMainEntry(); + } + } + throw zim::EntryNotFound("Cannot find entry for non empty path"); +} + +zim::Entry getFinalEntry(zim::Entry entry) +{ + int loopCounter = 42; + auto final_entry = entry; + while (final_entry.isRedirect() && loopCounter--) { + final_entry = final_entry.getRedirectEntry(); + } + // Prevent infinite loops. + if (final_entry.isRedirect()) { + throw zim::EntryNotFound("bad entry"); + } + return final_entry; +} + void UrlSchemeHandler::handleContentRequest(QWebEngineUrlRequestJob *request) { @@ -23,27 +53,29 @@ UrlSchemeHandler::handleContentRequest(QWebEngineUrlRequestJob *request) auto library = KiwixApp::instance()->getLibrary(); auto zim_id = qurl.host(); zim_id.resize(zim_id.length()-4); - auto reader = library->getReader(zim_id); - if ( reader == nullptr) { - request->fail(QWebEngineUrlRequestJob::UrlNotFound); - return; + std::shared_ptr archive; + try { + archive = library->getArchive(zim_id); + } catch (std::out_of_range& e) { + request->fail(QWebEngineUrlRequestJob::UrlNotFound); + return; } try { - kiwix::Entry entry = reader->getEntryFromPath(url); + auto entry = getEntryFromPath(*archive, url); if (entry.isRedirect()) { - entry = entry.getFinalEntry(); + entry = getFinalEntry(entry); auto path = QString("/") + QString::fromStdString(entry.getPath()); qurl.setPath(path); request->redirect(qurl); return; } - BlobBuffer* buffer = new BlobBuffer(entry.getBlob()); - auto mimeType = QByteArray::fromStdString(entry.getMimetype()); + BlobBuffer* buffer = new BlobBuffer(entry.getItem().getData(0)); + auto mimeType = QByteArray::fromStdString(entry.getItem(true).getMimetype()); mimeType = mimeType.split(';')[0]; connect(request, &QObject::destroyed, buffer, &QObject::deleteLater); request->reply(mimeType, buffer); - } catch (kiwix::NoEntry&) { + } catch (zim::EntryNotFound&) { request->fail(QWebEngineUrlRequestJob::UrlNotFound); } } @@ -61,8 +93,9 @@ UrlSchemeHandler::handleMetaRequest(QWebEngineUrlRequestJob* request) try { auto library = KiwixApp::instance()->getLibrary(); auto book = library->getBookById(zimId); - std::string content= book.getFavicon(); - std::string mimeType = book.getFaviconMimeType(); + auto illustration = book.getIllustration(48); + std::string content = illustration->getData(); + std::string mimeType = illustration->mimeType; QBuffer* buffer = new QBuffer; buffer->setData(content.data(), content.size()); connect(request, &QObject::destroyed, buffer, &QObject::deleteLater); @@ -103,18 +136,17 @@ UrlSchemeHandler::handleSearchRequest(QWebEngineUrlRequestJob* request) if (ok) pageLength = temp; - auto end = start + pageLength; - - auto searcher = app->getLibrary()->getSearcher(bookId); + std::shared_ptr search; try { - searcher->search(searchQuery, start, end); - } catch(std::runtime_error&) { + auto searcher = app->getLibrary()->getSearcher(bookId); + search = make_shared(searcher->search(searchQuery)); + } catch(...) { request->fail(QWebEngineUrlRequestJob::UrlInvalid); return; } - IdNameMapper nameMapper; - kiwix::SearchRenderer renderer(searcher.get(), &nameMapper); + kiwix::SearchRenderer renderer(search->getResults(start, pageLength), &nameMapper, search->getEstimatedMatches(), + start); renderer.setSearchPattern(searchQuery); renderer.setSearchContent(bookId.toStdString()); renderer.setProtocolPrefix("zim://"); diff --git a/src/webview.cpp b/src/webview.cpp index 290d4f26d..b5c29601e 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -167,12 +167,16 @@ void WebView::onUrlChanged(const QUrl& url) { m_currentZimId = zimId; emit zimIdChanged(m_currentZimId); auto app = KiwixApp::instance(); - auto reader = app->getLibrary()->getReader(m_currentZimId); - if (!reader) { + std::shared_ptr archive; + try { + archive = app->getLibrary()->getArchive(m_currentZimId); + } catch (std::out_of_range& e) { return; } std::string favicon, _mimetype; - reader->getFavicon(favicon, _mimetype); + auto item = archive->getIllustrationItem(48); + favicon = item.getData(); + _mimetype = item.getMimetype(); QPixmap pixmap; pixmap.loadFromData((const uchar*)favicon.data(), favicon.size()); m_icon = QIcon(pixmap);