From 62ef567280dc20f7707c10080b8e1b0c3eecb940 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Sun, 23 Oct 2022 19:57:47 +0200 Subject: [PATCH 1/4] YACReaderLibrary Server: Add webui status page --- CHANGELOG.md | 3 + .../webui/statuspagecontroller.cpp | 84 +++++++++++++++++++ .../controllers/webui/statuspagecontroller.h | 19 +++++ YACReaderLibrary/server/requestmapper.cpp | 13 ++- YACReaderLibrary/server/requestmapper.h | 1 + YACReaderLibrary/server/server.pri | 8 +- 6 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp create mode 100644 YACReaderLibrary/server/controllers/webui/statuspagecontroller.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 940ee0f2..ed91c358 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ Version counting is based on semantic versioning (Major.Feature.Patch) * UI gets updated when YACReaderLibrary gets updates from YACReader or YACReader for iOS. * Linux: Add fallback for dynamically loading libqrencode on distros that don't provide unversioned library symlinks +### Server +* Add webui status page (reachable by navigating to server::port/webui) + ## 9.9.2 ### General diff --git a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp new file mode 100644 index 00000000..bbec2d8e --- /dev/null +++ b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp @@ -0,0 +1,84 @@ +#include "statuspagecontroller.h" + +#include "template.h" +#include "yacreader_global.h" +#include "db_helper.h" +#include "yacreader_libraries.h" +#include "QsLog.h" + +#include + +using stefanfrings::HttpRequest; +using stefanfrings::HttpResponse; +//using stefanfrings::HttpSession; +using stefanfrings::Template; + +StatusPageController::StatusPageController() {} + +void StatusPageController::service(HttpRequest &request, HttpResponse &response) +{ + response.setHeader("Content-Type", "text/html; charset=utf-8"); + response.setHeader("Connection", "close"); + + Template StatusPage = Template(QStringLiteral( + "\n" + "\n" + "\n" + "YACReaderLibrary Server\n" + "\n" + "\n\n" + "
\n" + "\n" + "

YACReaderLibraryServer is up and running.

\n" + "

YACReader {yr.version}

\n" + "

Server {server.version}

\n" + "

OS:\t{os.name} {os.version}

\n" + "

Port:\t{os.port}

\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "{loop Library}" + "\n" + "\n" + "\n" + "\n" + "{end Library}" + "

\n" + "\n" + "\n" + "\n" + ), + + "StatusPage" + ); + + StatusPage.enableWarnings(); + + // Set template variables + StatusPage.setVariable("os.name", QSysInfo::prettyProductName()); + StatusPage.setVariable("os.version", QSysInfo::productVersion()); + // Getting the port from the request is basically a hack, but should do the trick + StatusPage.setVariable("os.port", QString(request.getHeader("host")).split(":")[1]); + + StatusPage.setVariable("server.version", SERVER_VERSION_NUMBER); + StatusPage.setVariable("yr.version", VERSION); + + // Get library info + YACReaderLibraries libraries = DBHelper::getLibraries(); + QList library_names = libraries.getNames(); + size_t num_libs = libraries.getNames().size(); + + // Fill template + StatusPage.loop("Library", num_libs); + for (size_t i = 0; i < num_libs; i++) + { + StatusPage.setVariable(QString("Library%1.Name").arg(i), library_names.at(i)); + StatusPage.setVariable(QString("Library%1.Path").arg(i), libraries.getPath(library_names.at(i))); + } + + response.write(StatusPage.toUtf8(), true); +} diff --git a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h new file mode 100644 index 00000000..09db86b1 --- /dev/null +++ b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h @@ -0,0 +1,19 @@ +#ifndef STATUSPAGE_CONTROLLER +#define STATUSPAGE_CONTROLLER + +#include "httprequest.h" +#include "httpresponse.h" +#include "httprequesthandler.h" + +class StatusPageController : public stefanfrings::HttpRequestHandler +{ + Q_OBJECT + Q_DISABLE_COPY(StatusPageController); + + public: + StatusPageController(); + + void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; +}; + +#endif // STATUSPAGE_CONTROLLER diff --git a/YACReaderLibrary/server/requestmapper.cpp b/YACReaderLibrary/server/requestmapper.cpp index e6ce2e9e..780fb590 100644 --- a/YACReaderLibrary/server/requestmapper.cpp +++ b/YACReaderLibrary/server/requestmapper.cpp @@ -41,6 +41,8 @@ #include "controllers/v2/comicfullinfocontroller_v2.h" #include "controllers/v2/comiccontrollerinreadinglist_v2.h" +#include "controllers/webui/statuspagecontroller.h" + #include "db_helper.h" #include "yacreader_libraries.h" @@ -157,13 +159,22 @@ void RequestMapper::service(HttpRequest &request, HttpResponse &response) QLOG_TRACE() << "RequestMapper: path=" << path.data(); QLOG_TRACE() << "X-Request-Id: " << request.getHeader("x-request-id"); - if (path.startsWith("/v2")) { + // Browsers ask for text/html + if (path.startsWith("/webui")) + { + serviceWebUI(request, response); + } else if (path.startsWith("/v2")) { serviceV2(request, response); } else { serviceV1(request, response); } } +void RequestMapper::serviceWebUI(HttpRequest &request, HttpResponse &response) +{ + StatusPageController().service(request, response); +} + void RequestMapper::serviceV1(HttpRequest &request, HttpResponse &response) { QByteArray path = request.getPath(); diff --git a/YACReaderLibrary/server/requestmapper.h b/YACReaderLibrary/server/requestmapper.h index 4a63f89a..4ec435fa 100644 --- a/YACReaderLibrary/server/requestmapper.h +++ b/YACReaderLibrary/server/requestmapper.h @@ -27,6 +27,7 @@ signals: private: void serviceV1(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response); void serviceV2(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response); + void serviceWebUI(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response); static QMutex mutex; }; diff --git a/YACReaderLibrary/server/server.pri b/YACReaderLibrary/server/server.pri index b7723a47..345ea1cc 100644 --- a/YACReaderLibrary/server/server.pri +++ b/YACReaderLibrary/server/server.pri @@ -47,7 +47,9 @@ HEADERS += \ $$PWD/controllers/v2/comicfullinfocontroller_v2.h \ $$PWD/controllers/v2/readinglistinfocontroller_v2.h \ $$PWD/controllers/v2/taginfocontroller_v2.h \ - $$PWD/controllers/v2/comiccontrollerinreadinglist_v2.h + $$PWD/controllers/v2/comiccontrollerinreadinglist_v2.h\ + #Browser + $$PWD/controllers/webui/statuspagecontroller.h SOURCES += \ @@ -89,7 +91,9 @@ SOURCES += \ $$PWD/controllers/v2/comicfullinfocontroller_v2.cpp \ $$PWD/controllers/v2/readinglistinfocontroller_v2.cpp \ $$PWD/controllers/v2/taginfocontroller_v2.cpp \ - $$PWD/controllers/v2/comiccontrollerinreadinglist_v2.cpp + $$PWD/controllers/v2/comiccontrollerinreadinglist_v2.cpp \ + #WebUI + $$PWD/controllers/webui/statuspagecontroller.cpp include(../../third_party/QtWebApp/httpserver/httpserver.pri) include(../../third_party/QtWebApp/templateengine/templateengine.pri) From 5ad5d52f05846880a059a5d6dcecfb5a02877360 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Sun, 23 Oct 2022 20:02:12 +0200 Subject: [PATCH 2/4] Web UI status page: Add YACReader svg --- .../docroot/images/webui/YACLibraryServer.svg | 262 ++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 release/server/docroot/images/webui/YACLibraryServer.svg diff --git a/release/server/docroot/images/webui/YACLibraryServer.svg b/release/server/docroot/images/webui/YACLibraryServer.svg new file mode 100644 index 00000000..bc7cc2f7 --- /dev/null +++ b/release/server/docroot/images/webui/YACLibraryServer.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + From f9c07707f358f9b91b2432698aad8e04414c6366 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Sun, 23 Oct 2022 20:21:16 +0200 Subject: [PATCH 3/4] Fix code formatting --- .../webui/statuspagecontroller.cpp | 74 +++++++++---------- .../controllers/webui/statuspagecontroller.h | 2 +- YACReaderLibrary/server/requestmapper.cpp | 3 +- 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp index bbec2d8e..80e65d76 100644 --- a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp +++ b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp @@ -10,51 +10,50 @@ using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; -//using stefanfrings::HttpSession; +// using stefanfrings::HttpSession; using stefanfrings::Template; -StatusPageController::StatusPageController() {} +StatusPageController::StatusPageController() { } void StatusPageController::service(HttpRequest &request, HttpResponse &response) { response.setHeader("Content-Type", "text/html; charset=utf-8"); response.setHeader("Connection", "close"); - Template StatusPage = Template(QStringLiteral( - "\n" - "\n" - "\n" - "YACReaderLibrary Server\n" - "\n" - "\n\n" - "
\n" - "\n" - "

YACReaderLibraryServer is up and running.

\n" - "

YACReader {yr.version}

\n" - "

Server {server.version}

\n" - "

OS:\t{os.name} {os.version}

\n" - "

Port:\t{os.port}

\n" - "
LibraryPath
{Library.Name}{Library.Path}
\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "{loop Library}" - "\n" - "\n" - "\n" - "\n" - "{end Library}" - "

\n" - "\n" - "\n" - "\n" - ), + Template StatusPage = Template( + QStringLiteral( + "\n" + "\n" + "\n" + "YACReaderLibrary Server\n" + "\n" + "\n\n" + "
\n" + "\n" + "

YACReaderLibraryServer is up and running.

\n" + "

YACReader {yr.version}

\n" + "

Server {server.version}

\n" + "

OS:\t{os.name} {os.version}

\n" + "

Port:\t{os.port}

\n" + "
LibraryPath
{Library.Name}{Library.Path}
\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "{loop Library}" + "\n" + "\n" + "\n" + "\n" + "{end Library}" + "

\n" + "\n" + "\n" + "\n"), - "StatusPage" - ); + "StatusPage"); StatusPage.enableWarnings(); @@ -74,8 +73,7 @@ void StatusPageController::service(HttpRequest &request, HttpResponse &response) // Fill template StatusPage.loop("Library", num_libs); - for (size_t i = 0; i < num_libs; i++) - { + for (size_t i = 0; i < num_libs; i++) { StatusPage.setVariable(QString("Library%1.Name").arg(i), library_names.at(i)); StatusPage.setVariable(QString("Library%1.Path").arg(i), libraries.getPath(library_names.at(i))); } diff --git a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h index 09db86b1..22dae09f 100644 --- a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h +++ b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h @@ -10,7 +10,7 @@ class StatusPageController : public stefanfrings::HttpRequestHandler Q_OBJECT Q_DISABLE_COPY(StatusPageController); - public: +public: StatusPageController(); void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; diff --git a/YACReaderLibrary/server/requestmapper.cpp b/YACReaderLibrary/server/requestmapper.cpp index 780fb590..1106bbd6 100644 --- a/YACReaderLibrary/server/requestmapper.cpp +++ b/YACReaderLibrary/server/requestmapper.cpp @@ -160,8 +160,7 @@ void RequestMapper::service(HttpRequest &request, HttpResponse &response) QLOG_TRACE() << "X-Request-Id: " << request.getHeader("x-request-id"); // Browsers ask for text/html - if (path.startsWith("/webui")) - { + if (path.startsWith("/webui")) { serviceWebUI(request, response); } else if (path.startsWith("/v2")) { serviceV2(request, response); From 0533d5d9a3c7425204bd743b4dd16edaf42ab675 Mon Sep 17 00:00:00 2001 From: Felix Kauselmann Date: Mon, 24 Oct 2022 19:20:45 +0200 Subject: [PATCH 4/4] Server: Check for v2 api before webui --- YACReaderLibrary/server/requestmapper.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/YACReaderLibrary/server/requestmapper.cpp b/YACReaderLibrary/server/requestmapper.cpp index 1106bbd6..4051b6f2 100644 --- a/YACReaderLibrary/server/requestmapper.cpp +++ b/YACReaderLibrary/server/requestmapper.cpp @@ -159,11 +159,10 @@ void RequestMapper::service(HttpRequest &request, HttpResponse &response) QLOG_TRACE() << "RequestMapper: path=" << path.data(); QLOG_TRACE() << "X-Request-Id: " << request.getHeader("x-request-id"); - // Browsers ask for text/html - if (path.startsWith("/webui")) { - serviceWebUI(request, response); - } else if (path.startsWith("/v2")) { + if (path.startsWith("/v2")) { serviceV2(request, response); + } else if (path.startsWith("/webui")) { + serviceWebUI(request, response); } else { serviceV1(request, response); }
LibraryPath
{Library.Name}{Library.Path}