api work
This commit is contained in:
parent
aa7b18827c
commit
6b9041a110
@ -1 +1 @@
|
||||
Subproject commit 2b41d67a372b6ce42ed666e7d88e7815694f1966
|
||||
Subproject commit b874b2fad4fcb91861b62ae2a52df44efac98ddd
|
@ -275,10 +275,6 @@ QList<Feed*> FeedsModel::feedsForScheduledUpdate(bool auto_update_now) {
|
||||
return feeds_for_update;
|
||||
}
|
||||
|
||||
QList<Message> FeedsModel::messagesForItem(RootItem* item) const {
|
||||
return item->undeletedMessages();
|
||||
}
|
||||
|
||||
int FeedsModel::columnCount(const QModelIndex& parent) const {
|
||||
Q_UNUSED(parent)
|
||||
return FEEDS_VIEW_COLUMN_COUNT;
|
||||
|
@ -54,11 +54,6 @@ class RSSGUARD_DLLSPEC FeedsModel : public QAbstractItemModel {
|
||||
// This method might change some properties of some feeds.
|
||||
QList<Feed*> feedsForScheduledUpdate(bool auto_update_now);
|
||||
|
||||
// Returns (undeleted) messages for given feeds.
|
||||
// This is usually used for displaying whole feeds
|
||||
// in "newspaper" mode.
|
||||
QList<Message> messagesForItem(RootItem* item) const;
|
||||
|
||||
// Returns ALL RECURSIVE CHILD feeds contained within single index.
|
||||
QList<Feed*> feedsForIndex(const QModelIndex& index = QModelIndex()) const;
|
||||
|
||||
|
@ -164,6 +164,14 @@ void Message::sanitize(const Feed* feed, bool fix_future_datetimes) {
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject Message::toJson() const {
|
||||
QJsonObject obj;
|
||||
|
||||
obj.insert(QSL("contents"), m_contents);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
Message Message::fromSqlRecord(const QSqlRecord& record, bool* result) {
|
||||
if (record.count() != MSG_DB_LABELS_IDS + 1) {
|
||||
if (result != nullptr) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#ifndef MESSAGE_H
|
||||
#define MESSAGE_H
|
||||
|
||||
//#include "definitions/definitions.h"
|
||||
// #include "definitions/definitions.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDateTime>
|
||||
@ -56,6 +56,8 @@ class RSSGUARD_DLLSPEC Message {
|
||||
|
||||
void sanitize(const Feed* feed, bool fix_future_datetimes);
|
||||
|
||||
QJsonObject toJson() const;
|
||||
|
||||
// Creates Message from given record, which contains
|
||||
// row from query SELECT * FROM Messages WHERE ....;
|
||||
static Message fromSqlRecord(const QSqlRecord& record, bool* result = nullptr);
|
||||
|
@ -1174,6 +1174,55 @@ QList<Message> DatabaseQueries::getUndeletedUnreadMessages(const QSqlDatabase& d
|
||||
return messages;
|
||||
}
|
||||
|
||||
QList<Message> DatabaseQueries::getFeedsSlice(const QSqlDatabase& db,
|
||||
const QString& feed_custom_id,
|
||||
int account_id,
|
||||
bool newest_first,
|
||||
bool unread_only,
|
||||
int row_offset,
|
||||
int row_limit) {
|
||||
QList<Message> messages;
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare(QSL("SELECT %1 "
|
||||
"FROM Messages "
|
||||
"WHERE is_deleted = 0 AND is_pdeleted = 0 AND "
|
||||
" is_read = :is_read "
|
||||
" feed = :feed AND account_id = :account_id "
|
||||
"ORDER BY Messages.date_created %2 "
|
||||
"LIMIT :row_limit OFFSET :row_offset;")
|
||||
.arg(messageTableAttributes(true, db.driverName() == QSL(APP_DB_SQLITE_DRIVER)).values().join(QSL(", ")),
|
||||
newest_first ? QSL("DESC") : QSL("ASC")));
|
||||
q.bindValue(QSL(":feed"), feed_custom_id);
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
q.bindValue(QSL(":row_limit"), row_limit);
|
||||
q.bindValue(QSL(":row_offset"), row_offset);
|
||||
|
||||
if (unread_only) {
|
||||
q.bindValue(QSL(":is_read"), 0);
|
||||
}
|
||||
else {
|
||||
q.bindValue(QSL(":is_read"), QSL("is_read"));
|
||||
}
|
||||
|
||||
if (q.exec()) {
|
||||
while (q.next()) {
|
||||
bool decoded;
|
||||
Message message = Message::fromSqlRecord(q.record(), &decoded);
|
||||
|
||||
if (decoded) {
|
||||
messages.append(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw ApplicationException(q.lastError().driverText());
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
QList<Message> DatabaseQueries::getUndeletedMessagesForFeed(const QSqlDatabase& db,
|
||||
const QString& feed_custom_id,
|
||||
int account_id,
|
||||
|
@ -118,6 +118,14 @@ class DatabaseQueries {
|
||||
static QList<Message> getUndeletedMessagesForBin(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
|
||||
static QList<Message> getUndeletedMessagesForAccount(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
|
||||
|
||||
static QList<Message> getFeedsSlice(const QSqlDatabase& db,
|
||||
const QString& feed_custom_id,
|
||||
int account_id,
|
||||
bool newest_first,
|
||||
bool unread_only,
|
||||
int row_offset,
|
||||
int row_limit);
|
||||
|
||||
// Custom ID accumulators.
|
||||
static QStringList bagOfMessages(const QSqlDatabase& db, ServiceRoot::BagOfMessages bag, const Feed* feed);
|
||||
static QHash<QString, QStringList> bagsOfMessages(const QSqlDatabase& db, const QList<Label*>& labels);
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
ApiServer::ApiServer(QObject* parent) : HttpServer(parent) {}
|
||||
|
||||
void ApiServer::answerClient(QTcpSocket* socket, const QHttpRequest& request) {
|
||||
void ApiServer::answerClient(QTcpSocket* socket, const HttpRequest& request) {
|
||||
QByteArray incoming_data = socket->readAll();
|
||||
QByteArray output_data;
|
||||
|
||||
@ -26,9 +26,17 @@ void ApiServer::answerClient(QTcpSocket* socket, const QHttpRequest& request) {
|
||||
}
|
||||
else {
|
||||
ApiRequest req(incoming_doc);
|
||||
ApiResponse resp(processRequest(req));
|
||||
|
||||
output_data = resp.toJson().toJson();
|
||||
try {
|
||||
ApiResponse resp(processRequest(req));
|
||||
|
||||
output_data = resp.toJson().toJson();
|
||||
}
|
||||
catch (const ApplicationException& ex) {
|
||||
ApiResponse err_resp(ApiResponse::Result::Error, req.m_method, ex.message());
|
||||
|
||||
output_data = err_resp.toJson().toJson();
|
||||
}
|
||||
}
|
||||
|
||||
const QByteArray reply_message = QSL("HTTP/1.0 200 OK \r\n"
|
||||
@ -63,17 +71,23 @@ ApiResponse ApiServer::processAppVersion() const {
|
||||
|
||||
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();
|
||||
bool newest_first = data.value(QSL("newest_first")).toBool();
|
||||
bool unread_only = data.value(QSL("unread_only")).toBool();
|
||||
int row_offset = data.value(QSL("row_offset")).toInt();
|
||||
int row_limit = data.value(QSL("row_limit")).toInt();
|
||||
|
||||
QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className());
|
||||
QList<Message> msgs = DatabaseQueries::getUndeletedMessagesForFeed(database, feed_id, account_id);
|
||||
QList<Message> msgs =
|
||||
DatabaseQueries::getFeedsSlice(database, feed_id, account_id, newest_first, unread_only, row_offset, row_limit);
|
||||
QJsonArray msgs_json_array;
|
||||
|
||||
for (const Message& msg : msgs) {
|
||||
QJsonObject msg_obj;
|
||||
|
||||
msg_obj.insert(QSL("contents"), msg.m_contents);
|
||||
msg_obj.insert(QSL("contents"), msg.toJson());
|
||||
msgs_json_array.append(msg_obj);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ class ApiServer : public HttpServer {
|
||||
explicit ApiServer(QObject* parent = nullptr);
|
||||
|
||||
protected:
|
||||
virtual void answerClient(QTcpSocket* socket, const QHttpRequest& request);
|
||||
virtual void answerClient(QTcpSocket* socket, const HttpRequest& request);
|
||||
|
||||
private:
|
||||
ApiResponse processRequest(const ApiRequest& req) const;
|
||||
|
@ -79,28 +79,28 @@ void HttpServer::readReceivedData(QTcpSocket* socket) {
|
||||
m_connectedClients[socket].m_port = m_httpServer.serverPort();
|
||||
}
|
||||
|
||||
QHttpRequest* request = &m_connectedClients[socket];
|
||||
HttpRequest* request = &m_connectedClients[socket];
|
||||
bool error = false;
|
||||
|
||||
if (Q_LIKELY(request->m_state == QHttpRequest::State::ReadingMethod)) {
|
||||
if (Q_LIKELY(request->m_state == HttpRequest::State::ReadingMethod)) {
|
||||
if (Q_UNLIKELY(error = !request->readMethod(socket))) {
|
||||
qWarningNN << LOGSEC_NETWORK << "Invalid method.";
|
||||
}
|
||||
}
|
||||
|
||||
if (Q_LIKELY(!error && request->m_state == QHttpRequest::State::ReadingUrl)) {
|
||||
if (Q_LIKELY(!error && request->m_state == HttpRequest::State::ReadingUrl)) {
|
||||
if (Q_UNLIKELY(error = !request->readUrl(socket))) {
|
||||
qWarningNN << LOGSEC_NETWORK << "Invalid URL.";
|
||||
}
|
||||
}
|
||||
|
||||
if (Q_LIKELY(!error && request->m_state == QHttpRequest::State::ReadingStatus)) {
|
||||
if (Q_LIKELY(!error && request->m_state == HttpRequest::State::ReadingStatus)) {
|
||||
if (Q_UNLIKELY(error = !request->readStatus(socket))) {
|
||||
qWarningNN << LOGSEC_NETWORK << "Invalid status.";
|
||||
}
|
||||
}
|
||||
|
||||
if (Q_LIKELY(!error && request->m_state == QHttpRequest::State::ReadingHeader)) {
|
||||
if (Q_LIKELY(!error && request->m_state == HttpRequest::State::ReadingHeader)) {
|
||||
if (Q_UNLIKELY(error = !request->readHeader(socket))) {
|
||||
qWarningNN << LOGSEC_NETWORK << "Invalid header.";
|
||||
}
|
||||
@ -111,7 +111,7 @@ void HttpServer::readReceivedData(QTcpSocket* socket) {
|
||||
m_connectedClients.remove(socket);
|
||||
}
|
||||
else if (!request->m_url.isEmpty()) {
|
||||
Q_ASSERT(request->m_state != QHttpRequest::State::ReadingUrl);
|
||||
Q_ASSERT(request->m_state != HttpRequest::State::ReadingUrl);
|
||||
|
||||
answerClient(socket, *request);
|
||||
m_connectedClients.remove(socket);
|
||||
@ -130,7 +130,7 @@ quint16 HttpServer::listenPort() const {
|
||||
return m_listenPort;
|
||||
}
|
||||
|
||||
bool HttpServer::QHttpRequest::readMethod(QTcpSocket* socket) {
|
||||
bool HttpServer::HttpRequest::readMethod(QTcpSocket* socket) {
|
||||
bool finished = false;
|
||||
|
||||
while ((socket->bytesAvailable() != 0) && !finished) {
|
||||
@ -173,7 +173,7 @@ bool HttpServer::QHttpRequest::readMethod(QTcpSocket* socket) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpServer::QHttpRequest::readUrl(QTcpSocket* socket) {
|
||||
bool HttpServer::HttpRequest::readUrl(QTcpSocket* socket) {
|
||||
bool finished = false;
|
||||
|
||||
while ((socket->bytesAvailable() != 0) && !finished) {
|
||||
@ -208,7 +208,7 @@ bool HttpServer::QHttpRequest::readUrl(QTcpSocket* socket) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpServer::QHttpRequest::readStatus(QTcpSocket* socket) {
|
||||
bool HttpServer::HttpRequest::readStatus(QTcpSocket* socket) {
|
||||
bool finished = false;
|
||||
|
||||
while ((socket->bytesAvailable() != 0) && !finished) {
|
||||
@ -235,7 +235,7 @@ bool HttpServer::QHttpRequest::readStatus(QTcpSocket* socket) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpServer::QHttpRequest::readHeader(QTcpSocket* socket) {
|
||||
bool HttpServer::HttpRequest::readHeader(QTcpSocket* socket) {
|
||||
while (socket->bytesAvailable() != 0) {
|
||||
m_fragment += socket->read(1);
|
||||
|
||||
|
@ -35,7 +35,7 @@ class HttpServer : public QObject {
|
||||
void setListenAddressPort(const QString& full_uri, bool start_handler);
|
||||
|
||||
protected:
|
||||
struct QHttpRequest {
|
||||
struct HttpRequest {
|
||||
bool readMethod(QTcpSocket* socket);
|
||||
bool readUrl(QTcpSocket* socket);
|
||||
bool readStatus(QTcpSocket* socket);
|
||||
@ -67,7 +67,7 @@ class HttpServer : public QObject {
|
||||
QMap<QByteArray, QByteArray> m_headers;
|
||||
};
|
||||
|
||||
virtual void answerClient(QTcpSocket* socket, const QHttpRequest& request) = 0;
|
||||
virtual void answerClient(QTcpSocket* socket, const HttpRequest& request) = 0;
|
||||
|
||||
private slots:
|
||||
void clientConnected();
|
||||
@ -76,7 +76,7 @@ class HttpServer : public QObject {
|
||||
void readReceivedData(QTcpSocket* socket);
|
||||
|
||||
private:
|
||||
QMap<QTcpSocket*, QHttpRequest> m_connectedClients;
|
||||
QMap<QTcpSocket*, HttpRequest> m_connectedClients;
|
||||
QTcpServer m_httpServer;
|
||||
QHostAddress m_listenAddress;
|
||||
quint16 m_listenPort;
|
||||
|
@ -44,7 +44,7 @@ void OAuthHttpHandler::handleRedirection(const QVariantMap& data) {
|
||||
}
|
||||
}
|
||||
|
||||
void OAuthHttpHandler::answerClient(QTcpSocket* socket, const QHttpRequest& request) {
|
||||
void OAuthHttpHandler::answerClient(QTcpSocket* socket, const HttpRequest& request) {
|
||||
if (!request.m_url.path().remove(QL1C('/')).isEmpty()) {
|
||||
qCriticalNN << LOGSEC_OAUTH << "Invalid request:" << QUOTE_W_SPACE_DOT(request.m_url.toString());
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class OAuthHttpHandler : public HttpServer {
|
||||
void authGranted(const QString& auth_code, const QString& state);
|
||||
|
||||
protected:
|
||||
virtual void answerClient(QTcpSocket* socket, const QHttpRequest& request);
|
||||
virtual void answerClient(QTcpSocket* socket, const HttpRequest& request);
|
||||
|
||||
private:
|
||||
void handleRedirection(const QVariantMap& data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user