From 6ed79f5133095be239c3b23c73125e19a58d2b12 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Sun, 18 Oct 2020 20:54:44 +0200 Subject: [PATCH] Label assignments are now correctly download for TT-RSS, storage works for all plugins. --- src/librssguard/core/message.cpp | 2 + src/librssguard/core/message.h | 5 ++ .../miscellaneous/databasequeries.cpp | 52 +++++++++++++++++++ .../miscellaneous/databasequeries.h | 1 + src/librssguard/services/abstract/feed.cpp | 6 +++ src/librssguard/services/abstract/label.cpp | 6 ++- .../tt-rss/network/ttrssnetworkfactory.cpp | 22 +++++++- .../tt-rss/network/ttrssnetworkfactory.h | 4 +- src/librssguard/services/tt-rss/ttrssfeed.cpp | 2 +- 9 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/librssguard/core/message.cpp b/src/librssguard/core/message.cpp index f58887ceb..64b322f36 100644 --- a/src/librssguard/core/message.cpp +++ b/src/librssguard/core/message.cpp @@ -3,6 +3,7 @@ #include "core/message.h" #include "miscellaneous/textfactory.h" +#include "services/abstract/label.h" #include #include @@ -61,6 +62,7 @@ Message::Message() { m_enclosures = QList(); m_accountId = m_id = 0; m_isRead = m_isImportant = false; + m_assignedLabels = QList(); } Message Message::fromSqlRecord(const QSqlRecord& record, bool* result) { diff --git a/src/librssguard/core/message.h b/src/librssguard/core/message.h index 91cc1be3f..b078bb897 100644 --- a/src/librssguard/core/message.h +++ b/src/librssguard/core/message.h @@ -28,6 +28,8 @@ class Enclosures { static QString encodeEnclosuresToString(const QList& enclosures); }; +class Label; + // Represents single message. class Message { public: @@ -52,6 +54,9 @@ class Message { bool m_isImportant; QList m_enclosures; + // List of custom IDs of labels assigned to this message. + QList m_assignedLabels; + // Is true if "created" date was obtained directly // from the feed, otherwise is false bool m_createdFromFeed = false; diff --git a/src/librssguard/miscellaneous/databasequeries.cpp b/src/librssguard/miscellaneous/databasequeries.cpp index 4059d2ed4..d7f8b572e 100755 --- a/src/librssguard/miscellaneous/databasequeries.cpp +++ b/src/librssguard/miscellaneous/databasequeries.cpp @@ -80,6 +80,35 @@ bool DatabaseQueries::assignLabelToMessage(const QSqlDatabase& db, Label* label, return succ; } +bool DatabaseQueries::setLabelsForMessage(const QSqlDatabase& db, const QList& labels, const Message& msg) { + QSqlQuery q(db); + + q.setForwardOnly(true); + q.prepare(QSL("DELETE FROM LabelsInMessages WHERE message = :message AND account_id = :account_id")); + q.bindValue(QSL(":account_id"), msg.m_accountId); + q.bindValue(QSL(":message"), msg.m_customId.isEmpty() ? QString::number(msg.m_id) : msg.m_customId); + + auto succ = q.exec(); + + if (!succ) { + return false; + } + + q.prepare(QSL("INSERT INTO LabelsInMessages (message, label, account_id) VALUES (:message, :label, :account_id);")); + + for (const Label* label : labels) { + q.bindValue(QSL(":account_id"), msg.m_accountId); + q.bindValue(QSL(":message"), msg.m_customId.isEmpty() ? QString::number(msg.m_id) : msg.m_customId); + q.bindValue(QSL(":label"), label->customId()); + + if (!q.exec()) { + return false; + } + } + + return true; +} + QList DatabaseQueries::getLabels(const QSqlDatabase& db, int account_id) { QList labels; QSqlQuery q(db); @@ -912,6 +941,10 @@ int DatabaseQueries::updateMessages(QSqlDatabase db, if (query_insert.exec() && query_insert.numRowsAffected() == 1) { updated_messages++; + if (query_insert.lastInsertId().isValid()) { + id_existing_message = query_insert.lastInsertId().toInt(); + } + qDebugNN << LOGSEC_DB << "Adding new message with title '" << message.m_title @@ -930,6 +963,25 @@ int DatabaseQueries::updateMessages(QSqlDatabase db, query_insert.finish(); } + + // Update labels assigned to message. + if (!message.m_assignedLabels.isEmpty()) { + // NOTE: This message provides list of its labels from remote + // source, which means they must replace local labels. + if (!message.m_customId.isEmpty()) { + setLabelsForMessage(db, message.m_assignedLabels, message); + } + else if (id_existing_message >= 0) { + message.m_id = id_existing_message; + setLabelsForMessage(db, message.m_assignedLabels, message); + } + else { + qWarningNN << LOGSEC_DB + << "Cannot set labels for message" + << QUOTE_W_SPACE(message.m_title) + << "because we don't have ID or custom ID."; + } + } } // Now, fixup custom IDS for messages which initially did not have them, diff --git a/src/librssguard/miscellaneous/databasequeries.h b/src/librssguard/miscellaneous/databasequeries.h index 6522a6988..da1f103b9 100644 --- a/src/librssguard/miscellaneous/databasequeries.h +++ b/src/librssguard/miscellaneous/databasequeries.h @@ -22,6 +22,7 @@ class DatabaseQueries { static bool isLabelAssignedToMessage(const QSqlDatabase& db, Label* label, const Message& msg); static bool deassignLabelFromMessage(const QSqlDatabase& db, Label* label, const Message& msg); static bool assignLabelToMessage(const QSqlDatabase& db, Label* label, const Message& msg); + static bool setLabelsForMessage(const QSqlDatabase& db, const QList& labels, const Message& msg); static QList getLabels(const QSqlDatabase& db, int account_id); static bool updateLabel(const QSqlDatabase& db, Label* label); static bool deleteLabel(const QSqlDatabase& db, Label* label); diff --git a/src/librssguard/services/abstract/feed.cpp b/src/librssguard/services/abstract/feed.cpp index 7c8cd2497..7e228154a 100755 --- a/src/librssguard/services/abstract/feed.cpp +++ b/src/librssguard/services/abstract/feed.cpp @@ -11,6 +11,7 @@ #include "miscellaneous/textfactory.h" #include "services/abstract/cacheforserviceroot.h" #include "services/abstract/importantnode.h" +#include "services/abstract/labelsnode.h" #include "services/abstract/recyclebin.h" #include "services/abstract/serviceroot.h" @@ -227,6 +228,11 @@ int Feed::updateMessages(const QList& messages, bool error_during_obtai getParentServiceRoot()->importantNode()->updateCounts(true); items_to_update.append(getParentServiceRoot()->importantNode()); } + + if (getParentServiceRoot()->labelsNode() != nullptr) { + getParentServiceRoot()->labelsNode()->updateCounts(true); + items_to_update.append(getParentServiceRoot()->labelsNode()); + } } } else { diff --git a/src/librssguard/services/abstract/label.cpp b/src/librssguard/services/abstract/label.cpp index b375a7499..fbb90da14 100755 --- a/src/librssguard/services/abstract/label.cpp +++ b/src/librssguard/services/abstract/label.cpp @@ -10,6 +10,7 @@ #include #include +#include Label::Label(const QString& name, const QColor& color, RootItem* parent_item) : Label(parent_item) { setColor(color); @@ -71,7 +72,10 @@ bool Label::deleteViaGui() { } void Label::updateCounts(bool including_total_count) { - QSqlDatabase database = qApp->database()->connection(metaObject()->className()); + bool is_main_thread = QThread::currentThread() == qApp->thread(); + QSqlDatabase database = is_main_thread ? + qApp->database()->connection(metaObject()->className()) : + qApp->database()->connection(QSL("feed_upd")); int account_id = getParentServiceRoot()->accountId(); if (including_total_count) { diff --git a/src/librssguard/services/tt-rss/network/ttrssnetworkfactory.cpp b/src/librssguard/services/tt-rss/network/ttrssnetworkfactory.cpp index 5947c5e83..9bf98162e 100644 --- a/src/librssguard/services/tt-rss/network/ttrssnetworkfactory.cpp +++ b/src/librssguard/services/tt-rss/network/ttrssnetworkfactory.cpp @@ -2,6 +2,7 @@ #include "services/tt-rss/network/ttrssnetworkfactory.h" +#include "3rd-party/boolinq/boolinq.h" #include "definitions/definitions.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" @@ -9,7 +10,9 @@ #include "network-web/networkfactory.h" #include "services/abstract/category.h" #include "services/abstract/label.h" +#include "services/abstract/labelsnode.h" #include "services/abstract/rootitem.h" +#include "services/abstract/serviceroot.h" #include "services/tt-rss/definitions.h" #include "services/tt-rss/ttrssfeed.h" @@ -626,7 +629,7 @@ TtRssGetHeadlinesResponse::TtRssGetHeadlinesResponse(const QString& raw_content) TtRssGetHeadlinesResponse::~TtRssGetHeadlinesResponse() = default; -QList TtRssGetHeadlinesResponse::messages() const { +QList TtRssGetHeadlinesResponse::messages(ServiceRoot* root) const { QList messages; for (const QJsonValue& item : m_rawContent["content"].toArray()) { @@ -638,6 +641,23 @@ QList TtRssGetHeadlinesResponse::messages() const { message.m_isImportant = mapped["marked"].toBool(); message.m_contents = mapped["content"].toString(); + auto active_labels = root->labelsNode() != nullptr ? root->labelsNode()->labels() : QList(); + + for (const QJsonValue& lbl_val : mapped["labels"].toArray()) { + QString lbl_custom_id = QString::number(lbl_val.toArray().at(0).toInt()); + Label* label = boolinq::from(active_labels.begin(), active_labels.end()).firstOrDefault([lbl_custom_id](Label* lbl) { + return lbl->customId() == lbl_custom_id; + }); + + if (label != nullptr) { + message.m_assignedLabels.append(label); + } + else { + qWarningNN << LOGSEC_TTRSS << "Label with custom ID" << QUOTE_W_SPACE(lbl_custom_id) + << "was not found. Maybe you need to perform sync-in to download it from server."; + } + } + // Multiply by 1000 because Tiny Tiny RSS API does not include miliseconds in Unix // date/time number. const qint64 t = static_cast(mapped["updated"].toDouble()) * 1000; diff --git a/src/librssguard/services/tt-rss/network/ttrssnetworkfactory.h b/src/librssguard/services/tt-rss/network/ttrssnetworkfactory.h index b7902d294..40bf63732 100644 --- a/src/librssguard/services/tt-rss/network/ttrssnetworkfactory.h +++ b/src/librssguard/services/tt-rss/network/ttrssnetworkfactory.h @@ -59,12 +59,14 @@ class TtRssGetFeedsCategoriesResponse : public TtRssResponse { RootItem* feedsCategories(bool obtain_icons, QString base_address = QString()) const; }; +class ServiceRoot; + class TtRssGetHeadlinesResponse : public TtRssResponse { public: explicit TtRssGetHeadlinesResponse(const QString& raw_content = QString()); virtual ~TtRssGetHeadlinesResponse(); - QList messages() const; + QList messages(ServiceRoot* root) const; }; class TtRssUpdateArticleResponse : public TtRssResponse { diff --git a/src/librssguard/services/tt-rss/ttrssfeed.cpp b/src/librssguard/services/tt-rss/ttrssfeed.cpp index 5d0e029ae..b3b36cb33 100644 --- a/src/librssguard/services/tt-rss/ttrssfeed.cpp +++ b/src/librssguard/services/tt-rss/ttrssfeed.cpp @@ -87,7 +87,7 @@ QList TtRssFeed::obtainNewMessages(bool* error_during_obtaining) { return QList(); } else { - QList new_messages = headlines.messages(); + QList new_messages = headlines.messages(getParentServiceRoot()); messages.append(new_messages); newly_added_messages = new_messages.size();