diff --git a/resources/skins/nudus-base/html_style_base.scss b/resources/skins/nudus-base/html_style_base.scss index 9821a17c4..761de1b07 100644 --- a/resources/skins/nudus-base/html_style_base.scss +++ b/resources/skins/nudus-base/html_style_base.scss @@ -391,7 +391,7 @@ summary { } } - img { + img, video { // Needs to be `!important` when max-width is defined by image style // alt //max-width: 450px !important; diff --git a/resources/skins/nudus-dark/html_style.css b/resources/skins/nudus-dark/html_style.css index 784437a75..744437b55 100644 --- a/resources/skins/nudus-dark/html_style.css +++ b/resources/skins/nudus-dark/html_style.css @@ -253,7 +253,7 @@ summary:focus { .rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl a[href=""], .rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl a[href=""] + span { display: none; } @media only screen and (max-width: 800px) { - .rssguard-mwrapper img { + .rssguard-mwrapper img, .rssguard-mwrapper video { max-width: 100% !important; } } .rssguard-mbody { diff --git a/resources/skins/nudus-light/html_style.css b/resources/skins/nudus-light/html_style.css index c63af23a7..7c0fe44ff 100644 --- a/resources/skins/nudus-light/html_style.css +++ b/resources/skins/nudus-light/html_style.css @@ -253,7 +253,7 @@ summary:focus { .rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl a[href=""], .rssguard-mwrapper .rssguard-mhead .mlinks .mwrapurl a[href=""] + span { display: none; } @media only screen and (max-width: 800px) { - .rssguard-mwrapper img { + .rssguard-mwrapper img, .rssguard-mwrapper video { max-width: 100% !important; } } .rssguard-mbody { diff --git a/src/librssguard/network-web/apiserver.cpp b/src/librssguard/network-web/apiserver.cpp index 27e408317..d12ef018f 100644 --- a/src/librssguard/network-web/apiserver.cpp +++ b/src/librssguard/network-web/apiserver.cpp @@ -2,14 +2,35 @@ #include "network-web/apiserver.h" +#include "database/databasefactory.h" +#include "database/databasequeries.h" #include "definitions/definitions.h" +#include "miscellaneous/application.h" + +#include ApiServer::ApiServer(QObject* parent) : HttpServer(parent) {} void ApiServer::answerClient(QTcpSocket* socket, const QHttpRequest& request) { QByteArray incoming_data = socket->readAll(); + QByteArray output_data; + + QJsonParseError json_err; + QJsonDocument incoming_doc = QJsonDocument::fromJson(incoming_data, &json_err); + + if (json_err.error != QJsonParseError::ParseError::NoError) { + output_data = + ApiResponse(ApiResponse::Result::Error, ApiRequest::Method::Unknown, QJsonValue(json_err.errorString())) + .toJson() + .toJson(); + } + else { + ApiRequest req(incoming_doc); + ApiResponse resp(processRequest(req)); + + output_data = resp.toJson().toJson(); + } - const QByteArray output_data = incoming_data; const QByteArray reply_message = QSL("HTTP/1.0 200 OK \r\n" "Content-Type: application/json; charset=\"utf-8\"\r\n" "Content-Length: %1" @@ -21,3 +42,56 @@ void ApiServer::answerClient(QTcpSocket* socket, const QHttpRequest& request) { socket->write(reply_message); socket->disconnectFromHost(); } + +ApiResponse ApiServer::processRequest(const ApiRequest& req) const { + switch (req.m_method) { + case ApiRequest::Method::AppVersion: + return processAppVersion(); + + case ApiRequest::Method::ArticlesFromFeed: + return processArticlesFromFeed(req.m_parameters); + + case ApiRequest::Method::Unknown: + default: + return processUnknown(); + } +} + +ApiResponse ApiServer::processAppVersion() const { + return ApiResponse(ApiResponse::Result::Success, ApiRequest::Method::AppVersion, QSL(APP_VERSION)); +} + +ApiResponse ApiServer::processArticlesFromFeed(const QJsonValue& req) const { + QJsonObject data = req.toObject(); + QString feed_id = data.value(QSL("feed")).toString(); + int account_id = data.value(QSL("account")).toInt(); + + QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className()); + QList msgs = DatabaseQueries::getUndeletedMessagesForFeed(database, feed_id, account_id); + QJsonArray msgs_json_array; + + for (const Message& msg : msgs) { + QJsonObject msg_obj; + + msg_obj.insert(QSL("contents"), msg.m_contents); + msgs_json_array.append(msg_obj); + } + + ApiResponse resp(ApiResponse::Result::Success, ApiRequest::Method::ArticlesFromFeed, msgs_json_array); + + return resp; +} + +ApiResponse ApiServer::processUnknown() const { + return ApiResponse(ApiResponse::Result::Error, ApiRequest::Method::Unknown, QSL("unknown method")); +} + +QJsonDocument ApiResponse::toJson() const { + QJsonObject obj; + + obj.insert("method", int(m_method)); + obj.insert("result", int(m_result)); + obj.insert("data", m_response); + + return QJsonDocument(obj); +} diff --git a/src/librssguard/network-web/apiserver.h b/src/librssguard/network-web/apiserver.h index e9bff3716..37fafc044 100644 --- a/src/librssguard/network-web/apiserver.h +++ b/src/librssguard/network-web/apiserver.h @@ -5,12 +5,53 @@ #include "network-web/httpserver.h" +#include +#include + +struct ApiRequest { + public: + enum class Method { + Unknown = 0, + AppVersion = 1, + ArticlesFromFeed = 2 + }; + + explicit ApiRequest(const QJsonDocument& data) + : m_method(Method(data.object().value("method").toInt())), m_parameters(data.object().value("data")) {} + + Method m_method; + QJsonValue m_parameters; +}; + +struct ApiResponse { + public: + enum class Result { + Success = 1, + Error = 2 + }; + + explicit ApiResponse(Result result, ApiRequest::Method method, const QJsonValue& response) + : m_result(result), m_method(method), m_response(response) {} + + Result m_result; + ApiRequest::Method m_method; + QJsonValue m_response; + + QJsonDocument toJson() const; +}; + class ApiServer : public HttpServer { public: explicit ApiServer(QObject* parent = nullptr); protected: virtual void answerClient(QTcpSocket* socket, const QHttpRequest& request); + + private: + ApiResponse processRequest(const ApiRequest& req) const; + ApiResponse processAppVersion() const; + ApiResponse processArticlesFromFeed(const QJsonValue& req) const; + ApiResponse processUnknown() const; }; #endif // APISERVER_H