From 9a9e5815f93d7c11cbbf012848e6fe922491e1d4 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Tue, 18 Oct 2022 17:56:07 +0200 Subject: [PATCH 1/2] Move the server management in kiwixapp. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `LocalKiwixServer` is "just" a UI to start/configure or stop the server. One important change is that instead of having one server we configure and start/stop when needed, we are now creating a new server each time we want to start the server. It doesn't change the behavior, as libkiwix is destroying/recreating for us, but it will help us to use the new API which use a `Server::Configuration`. --- src/kiwixapp.cpp | 24 ++++++++++++++++++++++-- src/kiwixapp.h | 6 ++++-- src/localkiwixserver.cpp | 27 +++++++++++++-------------- src/localkiwixserver.h | 1 - 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp index 37ebe0af1..94e677d55 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -33,7 +33,7 @@ KiwixApp::KiwixApp(int& argc, char *argv[]) mp_manager(nullptr), mp_mainWindow(nullptr), m_nameMapper(m_library.getKiwixLibrary(), false), - m_server(&m_library.getKiwixLibrary(), &m_nameMapper) + mp_server(nullptr) { try { m_translation.setTranslation(QLocale()); @@ -114,7 +114,9 @@ void KiwixApp::init() KiwixApp::~KiwixApp() { - m_server.stop(); + if (mp_server) { + mp_server->stop(); + } if (mp_downloader) { mp_downloader->close(); delete mp_downloader; @@ -456,6 +458,24 @@ void KiwixApp::updateNameMapper() m_nameMapper.update(); } +bool KiwixApp::runServer(const QString& ipAddress, int port) { + auto settings = getSettingsManager(); + if (mp_server) { + mp_server->stop(); + } + mp_server.reset(new kiwix::Server(&m_library.getKiwixLibrary(), &m_nameMapper)); + mp_server->setPort(port); + mp_server->setAddress(ipAddress.toStdString()); + settings->setKiwixServerPort(port); + settings->setKiwixServerIpAddress(ipAddress); + return mp_server->start(); +} + +void KiwixApp::stopServer() { + mp_server->stop(); + mp_server.reset(); +} + void KiwixApp::printVersions(std::ostream& out) { out << version.toStdString() << std::endl; out << "+ libqt (compile time) " << QT_VERSION_STR << std::endl; diff --git a/src/kiwixapp.h b/src/kiwixapp.h index 604200638..e84e531ba 100644 --- a/src/kiwixapp.h +++ b/src/kiwixapp.h @@ -79,12 +79,14 @@ class KiwixApp : public QtSingleApplication TabBar* getTabWidget() { return getMainWindow()->getTabBar(); } QAction* getAction(Actions action); QString getLibraryDirectory() { return m_libraryDirectory; }; - kiwix::Server* getLocalServer() { return &m_server; } SettingsManager* getSettingsManager() { return &m_settingsManager; }; QString getText(const QString &key) { return m_translation.getText(key); }; void setMonitorDir(const QString &dir); bool isCurrentArticleBookmarked(); + bool runServer(const QString& ipAddress, int port); + void stopServer(); + public slots: void openZimFile(const QString& zimfile=""); void openUrl(const QString& url, bool newTab=true); @@ -109,7 +111,7 @@ public slots: MainWindow* mp_mainWindow; QErrorMessage* mp_errorDialog; kiwix::UpdatableNameMapper m_nameMapper; - kiwix::Server m_server; + std::unique_ptr mp_server; Translation m_translation; QFileSystemWatcher m_watcher; diff --git a/src/localkiwixserver.cpp b/src/localkiwixserver.cpp index c471250c4..2bd4a1d40 100644 --- a/src/localkiwixserver.cpp +++ b/src/localkiwixserver.cpp @@ -20,7 +20,6 @@ LocalKiwixServer::LocalKiwixServer(QWidget *parent) : QString style(byteContent); setStyleSheet(style); - mp_server = KiwixApp::instance()->getLocalServer(); m_port = KiwixApp::instance()->getSettingsManager()->getKiwixServerPort(); connect(ui->KiwixServerButton, SIGNAL(clicked()), this, SLOT(runOrStopServer())); @@ -81,28 +80,28 @@ void LocalKiwixServer::openInBrowser() void LocalKiwixServer::runOrStopServer() { if (!m_active) { - auto settingsManager = KiwixApp::instance()->getSettingsManager(); m_port = ui->PortChooser->text().toInt(); - mp_server->setPort(m_port); - m_ipAddress = (ui->IpChooser->currentText() != gt("all")) ? ui->IpChooser->currentText() : "0.0.0.0"; - settingsManager->setKiwixServerPort(m_port); - settingsManager->setKiwixServerIpAddress(m_ipAddress); - mp_server->setAddress(m_ipAddress.toStdString()); - m_ipAddress = (m_ipAddress != "0.0.0.0") ? m_ipAddress : QString::fromStdString(kiwix::getBestPublicIp()); - ui->IpAddress->setText("http://" + m_ipAddress + ":" + QString::number(m_port)); - ui->IpAddress->setReadOnly(true); - if (!mp_server->start()) { + m_ipAddress = ui->IpChooser->currentText(); + + m_active = KiwixApp::instance()->runServer( + (m_ipAddress != gt("all") ? m_ipAddress : "0.0.0.0"), + m_port + ); + + if (!m_active) { QMessageBox messageBox; messageBox.critical(0,gt("error-title"),gt("error-launch-server-message")); - return; } - m_active = true; } else { - mp_server->stop(); + KiwixApp::instance()->stopServer(); m_active = false; } if (m_active) { + // Update UI to display how to acces the server + m_ipAddress = m_ipAddress != gt("all") ? m_ipAddress : QString::fromStdString(kiwix::getBestPublicIp()); + ui->IpAddress->setText("http://" + m_ipAddress + ":" + QString::number(m_port)); + ui->IpAddress->setReadOnly(true); ui->KiwixServerButton->setText(gt("stop-kiwix-server")); ui->KiwixServerText->setText(gt("kiwix-server-running-message")); ui->stackedWidget->setCurrentIndex(1); diff --git a/src/localkiwixserver.h b/src/localkiwixserver.h index 6f479fcae..9f8ebba6d 100644 --- a/src/localkiwixserver.h +++ b/src/localkiwixserver.h @@ -22,7 +22,6 @@ public slots: private: Ui::LocalKiwixServer *ui; - kiwix::Server* mp_server; bool m_active = false; QString m_ipAddress; int m_port; From 650b803936f91dfd7652b72f0c18a6eba50d49c6 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Tue, 18 Oct 2022 18:51:36 +0200 Subject: [PATCH 2/2] Addapt kiwix desktop to last libkiwix API. Now libkiwix `Manipulator`, `Server`, `NameMapper`, ... take shared_ptr. We have to store all those object using shared_ptr instead of as plain object. --- src/contentmanager.cpp | 17 +++++++++-------- src/contentmanager.h | 2 +- src/kiwixapp.cpp | 11 ++++++----- src/kiwixapp.h | 2 +- src/library.cpp | 39 ++++++++++++++++++++------------------- src/library.h | 6 +++--- src/urlschemehandler.cpp | 9 ++++++--- 7 files changed, 46 insertions(+), 40 deletions(-) diff --git a/src/contentmanager.cpp b/src/contentmanager.cpp index c2f4ff98b..a360f40a4 100644 --- a/src/contentmanager.cpp +++ b/src/contentmanager.cpp @@ -15,6 +15,7 @@ ContentManager::ContentManager(Library* library, kiwix::Downloader* downloader, QObject *parent) : QObject(parent), mp_library(library), + mp_remoteLibrary(std::make_shared()), mp_downloader(downloader), m_remoteLibraryManager() { @@ -56,7 +57,7 @@ QStringList ContentManager::getBookInfos(QString id, const QStringList &keys) return &mp_library->getBookById(id); } catch (...) { try { - return &m_remoteLibrary.getBookById(id.toStdString()); + return &mp_remoteLibrary->getBookById(id.toStdString()); } catch(...) { return nullptr; } } }(); @@ -179,7 +180,7 @@ QStringList ContentManager::updateDownloadInfos(QString id, const QStringList &k } catch(...) { kiwix::Book bCopy(b); bCopy.setDownloadId(""); - mp_library->getKiwixLibrary().addOrUpdateBook(bCopy); + mp_library->getKiwixLibrary()->addOrUpdateBook(bCopy); mp_library->save(); emit(mp_library->booksChanged()); return values; @@ -194,7 +195,7 @@ QStringList ContentManager::updateDownloadInfos(QString id, const QStringList &k bCopy.setPathValid(true); // removing book url so that download link in kiwix-serve is not displayed. bCopy.setUrl(""); - mp_library->getKiwixLibrary().addOrUpdateBook(bCopy); + mp_library->getKiwixLibrary()->addOrUpdateBook(bCopy); mp_library->save(); mp_library->bookmarksChanged(); if (!m_local) { @@ -255,7 +256,7 @@ QString ContentManager::downloadBook(const QString &id) return ""; const auto& book = [&]()->const kiwix::Book& { try { - return m_remoteLibrary.getBookById(id.toStdString()); + return mp_remoteLibrary->getBookById(id.toStdString()); } catch (...) { return mp_library->getBookById(id); } @@ -407,8 +408,8 @@ void ContentManager::updateLibrary() { #define CATALOG_URL "library.kiwix.org" void ContentManager::updateRemoteLibrary(const QString& content) { - m_remoteLibrary = kiwix::Library(); - kiwix::Manager manager(&m_remoteLibrary); + mp_remoteLibrary = std::make_shared(); + kiwix::Manager manager(mp_remoteLibrary); manager.readOpds(content.toStdString(), CATALOG_URL); emit(this->booksChanged()); emit(this->pendingRequest(false)); @@ -457,8 +458,8 @@ QStringList ContentManager::getBookIds() return mp_library->listBookIds(filter, m_sortBy, m_sortOrderAsc); } else { filter.remote(true); - auto bookIds = m_remoteLibrary.filter(filter); - m_remoteLibrary.sort(bookIds, m_sortBy, m_sortOrderAsc); + auto bookIds = mp_remoteLibrary->filter(filter); + mp_remoteLibrary->sort(bookIds, m_sortBy, m_sortOrderAsc); QStringList list; for(auto& bookId:bookIds) { list.append(QString::fromStdString(bookId)); diff --git a/src/contentmanager.h b/src/contentmanager.h index d6abb0983..3e096f28b 100644 --- a/src/contentmanager.h +++ b/src/contentmanager.h @@ -29,7 +29,7 @@ class ContentManager : public QObject private: Library* mp_library; - kiwix::Library m_remoteLibrary; + std::shared_ptr mp_remoteLibrary; kiwix::Downloader* mp_downloader; OpdsRequestManager m_remoteLibraryManager; ContentManagerView* mp_view; diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp index 94e677d55..486671288 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -32,7 +32,7 @@ KiwixApp::KiwixApp(int& argc, char *argv[]) mp_downloader(nullptr), mp_manager(nullptr), mp_mainWindow(nullptr), - m_nameMapper(m_library.getKiwixLibrary(), false), + mp_nameMapper(std::make_shared(m_library.getKiwixLibrary(), false)), mp_server(nullptr) { try { @@ -455,7 +455,7 @@ void KiwixApp::disableItemsOnLibraryPage(bool libraryDisplayed) void KiwixApp::updateNameMapper() { - m_nameMapper.update(); + mp_nameMapper->update(); } bool KiwixApp::runServer(const QString& ipAddress, int port) { @@ -463,11 +463,12 @@ bool KiwixApp::runServer(const QString& ipAddress, int port) { if (mp_server) { mp_server->stop(); } - mp_server.reset(new kiwix::Server(&m_library.getKiwixLibrary(), &m_nameMapper)); - mp_server->setPort(port); - mp_server->setAddress(ipAddress.toStdString()); + kiwix::Server::Configuration configuration(m_library.getKiwixLibrary(), mp_nameMapper); + configuration.setPort(port); + configuration.setAddress(ipAddress.toStdString()); settings->setKiwixServerPort(port); settings->setKiwixServerIpAddress(ipAddress); + mp_server.reset(new kiwix::Server(configuration)); return mp_server->start(); } diff --git a/src/kiwixapp.h b/src/kiwixapp.h index e84e531ba..0ab741c4b 100644 --- a/src/kiwixapp.h +++ b/src/kiwixapp.h @@ -110,7 +110,7 @@ public slots: ContentManager* mp_manager; MainWindow* mp_mainWindow; QErrorMessage* mp_errorDialog; - kiwix::UpdatableNameMapper m_nameMapper; + std::shared_ptr mp_nameMapper; std::unique_ptr mp_server; Translation m_translation; QFileSystemWatcher m_watcher; diff --git a/src/library.cpp b/src/library.cpp index 7d8d371c2..cb293fb8a 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -11,23 +11,24 @@ class LibraryManipulator: public kiwix::LibraryManipulator { public: LibraryManipulator(Library* p_library) - : kiwix::LibraryManipulator(&p_library->getKiwixLibrary()) + : kiwix::LibraryManipulator(p_library->getKiwixLibrary()) , mp_library(p_library) {} virtual ~LibraryManipulator() {} bool addBookToLibrary(kiwix::Book book) { - auto ret = mp_library->m_library.addBook(book); + auto ret = mp_library->mp_library->addBook(book); emit(mp_library->booksChanged()); return ret; } void addBookmarkToLibrary(kiwix::Bookmark bookmark) { - mp_library->m_library.addBookmark(bookmark); + mp_library->mp_library->addBookmark(bookmark); } Library* mp_library; }; Library::Library(const QString& libraryDirectory) - : m_libraryDirectory(libraryDirectory) + : mp_library(std::make_shared()), + m_libraryDirectory(libraryDirectory) { auto manipulator = LibraryManipulator(this); auto manager = kiwix::Manager(&manipulator); @@ -44,11 +45,11 @@ Library::~Library() QString Library::openBookFromPath(const QString &zimPath) { try { - auto& book = m_library.getBookByPath(zimPath.toStdString()); + auto& book = mp_library->getBookByPath(zimPath.toStdString()); return QString::fromStdString(book.getId()); } catch(std::out_of_range& e) { } - kiwix::Manager manager(&m_library); + kiwix::Manager manager(mp_library); auto id = manager.addBookFromPathAndGetId(zimPath.toStdString()); if (id == "") { throw std::invalid_argument("invalid zim file"); @@ -60,18 +61,18 @@ QString Library::openBookFromPath(const QString &zimPath) std::shared_ptr Library::getArchive(const QString &zimId) { - return m_library.getArchiveById(zimId.toStdString()); + return mp_library->getArchiveById(zimId.toStdString()); } std::shared_ptr Library::getSearcher(const QString &zimId) { - return m_library.getSearcherById(zimId.toStdString()); + return mp_library->getSearcherById(zimId.toStdString()); } QStringList Library::getBookIds() const { QStringList list; - for(auto& id: m_library.getBooksIds()) { + for(auto& id: mp_library->getBooksIds()) { list.append(QString::fromStdString(id)); } return list; @@ -80,8 +81,8 @@ QStringList Library::getBookIds() const QStringList Library::listBookIds(const kiwix::Filter& filter, kiwix::supportedListSortBy sortBy, bool ascending) const { QStringList list; - auto bookIds = m_library.filter(filter); - m_library.sort(bookIds, sortBy, ascending); + auto bookIds = mp_library->filter(filter); + mp_library->sort(bookIds, sortBy, ascending); for(auto& id: bookIds) { list.append(QString::fromStdString(id)); } @@ -90,29 +91,29 @@ QStringList Library::listBookIds(const kiwix::Filter& filter, kiwix::supportedLi void Library::addBookToLibrary(kiwix::Book &book) { - m_library.addBook(book); + mp_library->addBook(book); } void Library::removeBookFromLibraryById(const QString& id) { - m_library.removeBookById(id.toStdString()); + mp_library->removeBookById(id.toStdString()); } void Library::addBookmark(kiwix::Bookmark &bookmark) { - m_library.addBookmark(bookmark); + mp_library->addBookmark(bookmark); emit bookmarksChanged(); } void Library::removeBookmark(const QString &zimId, const QString &url) { - m_library.removeBookmark(zimId.toStdString(), url.toStdString()); + mp_library->removeBookmark(zimId.toStdString(), url.toStdString()); emit bookmarksChanged(); } void Library::save() { - m_library.writeToFile(kiwix::appendToDirectory(m_libraryDirectory.toStdString(),"library.xml")); - m_library.writeBookmarksToFile(kiwix::appendToDirectory(m_libraryDirectory.toStdString(), "library.bookmarks.xml")); + mp_library->writeToFile(kiwix::appendToDirectory(m_libraryDirectory.toStdString(),"library.xml")); + mp_library->writeBookmarksToFile(kiwix::appendToDirectory(m_libraryDirectory.toStdString(), "library.bookmarks.xml")); } void Library::setMonitorDirZims(QStringList zimList) @@ -160,7 +161,7 @@ void Library::loadMonitorDir(QString monitorDir) needsRefresh |= manager.addBookFromPath(book.toStdString()); } for (auto bookPath : removedZims) { - removeBookFromLibraryById(QString::fromStdString(m_library.getBookByPath(bookPath.toStdString()).getId())); + removeBookFromLibraryById(QString::fromStdString(mp_library->getBookByPath(bookPath.toStdString()).getId())); } if (needsRefresh) { setMonitorDirZims(newDir.values()); @@ -177,5 +178,5 @@ void Library::asyncLoadMonitorDir(QString dir) const kiwix::Book &Library::getBookById(QString id) const { - return m_library.getBookById(id.toStdString()); + return mp_library->getBookById(id.toStdString()); } diff --git a/src/library.h b/src/library.h index 45d113af7..9d4b84bf8 100644 --- a/src/library.h +++ b/src/library.h @@ -32,7 +32,7 @@ class Library : public QObject 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); } + const std::vector getBookmarks(bool onlyValidBookmarks = false) const { return mp_library->getBookmarks(onlyValidBookmarks); } QStringList getLibraryZimsFromDir(QString dir) const; void setMonitorDirZims(QStringList zimList); void addBookToLibrary(kiwix::Book& book); @@ -42,7 +42,7 @@ class Library : public QObject void save(); void loadMonitorDir(QString dir); void asyncLoadMonitorDir(QString dir); - kiwix::Library& getKiwixLibrary() { return m_library; } + std::shared_ptr getKiwixLibrary() { return mp_library; } public slots: const kiwix::Book& getBookById(QString id) const; @@ -51,7 +51,7 @@ public slots: void bookmarksChanged(); private: - kiwix::Library m_library; + std::shared_ptr mp_library; QString m_libraryDirectory; QStringList m_monitorDirZims; friend class LibraryManipulator; diff --git a/src/urlschemehandler.cpp b/src/urlschemehandler.cpp index f18bd724d..fb687cda3 100644 --- a/src/urlschemehandler.cpp +++ b/src/urlschemehandler.cpp @@ -131,9 +131,12 @@ UrlSchemeHandler::handleSearchRequest(QWebEngineUrlRequestJob* request) request->fail(QWebEngineUrlRequestJob::UrlInvalid); return; } - IdNameMapper nameMapper; - kiwix::SearchRenderer renderer(search->getResults(start, pageLength), &nameMapper, search->getEstimatedMatches(), - start); + auto nameMapper = std::make_shared(); + kiwix::SearchRenderer renderer( + search->getResults(start, pageLength), + nameMapper, + search->getEstimatedMatches(), + start); renderer.setSearchPattern(searchQuery); renderer.setSearchBookQuery("content="+bookId.toStdString()); renderer.setProtocolPrefix("zim://");