Label assignments are now correctly download for TT-RSS, storage works for all plugins.

This commit is contained in:
Martin Rotter 2020-10-18 20:54:44 +02:00
parent ed56e7581b
commit 6ed79f5133
9 changed files with 96 additions and 4 deletions

View File

@ -3,6 +3,7 @@
#include "core/message.h"
#include "miscellaneous/textfactory.h"
#include "services/abstract/label.h"
#include <QDebug>
#include <QSqlDatabase>
@ -61,6 +62,7 @@ Message::Message() {
m_enclosures = QList<Enclosure>();
m_accountId = m_id = 0;
m_isRead = m_isImportant = false;
m_assignedLabels = QList<Label*>();
}
Message Message::fromSqlRecord(const QSqlRecord& record, bool* result) {

View File

@ -28,6 +28,8 @@ class Enclosures {
static QString encodeEnclosuresToString(const QList<Enclosure>& enclosures);
};
class Label;
// Represents single message.
class Message {
public:
@ -52,6 +54,9 @@ class Message {
bool m_isImportant;
QList<Enclosure> m_enclosures;
// List of custom IDs of labels assigned to this message.
QList<Label*> m_assignedLabels;
// Is true if "created" date was obtained directly
// from the feed, otherwise is false
bool m_createdFromFeed = false;

View File

@ -80,6 +80,35 @@ bool DatabaseQueries::assignLabelToMessage(const QSqlDatabase& db, Label* label,
return succ;
}
bool DatabaseQueries::setLabelsForMessage(const QSqlDatabase& db, const QList<Label*>& 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<Label*> DatabaseQueries::getLabels(const QSqlDatabase& db, int account_id) {
QList<Label*> 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,

View File

@ -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<Label*>& labels, const Message& msg);
static QList<Label*> getLabels(const QSqlDatabase& db, int account_id);
static bool updateLabel(const QSqlDatabase& db, Label* label);
static bool deleteLabel(const QSqlDatabase& db, Label* label);

View File

@ -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<Message>& 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 {

View File

@ -10,6 +10,7 @@
#include <QPainter>
#include <QPainterPath>
#include <QThread>
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) {

View File

@ -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<Message> TtRssGetHeadlinesResponse::messages() const {
QList<Message> TtRssGetHeadlinesResponse::messages(ServiceRoot* root) const {
QList<Message> messages;
for (const QJsonValue& item : m_rawContent["content"].toArray()) {
@ -638,6 +641,23 @@ QList<Message> 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<Label*>();
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<qint64>(mapped["updated"].toDouble()) * 1000;

View File

@ -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<Message> messages() const;
QList<Message> messages(ServiceRoot* root) const;
};
class TtRssUpdateArticleResponse : public TtRssResponse {

View File

@ -87,7 +87,7 @@ QList<Message> TtRssFeed::obtainNewMessages(bool* error_during_obtaining) {
return QList<Message>();
}
else {
QList<Message> new_messages = headlines.messages();
QList<Message> new_messages = headlines.messages(getParentServiceRoot());
messages.append(new_messages);
newly_added_messages = new_messages.size();