diff --git a/src/librssguard/core/feeddownloader.cpp b/src/librssguard/core/feeddownloader.cpp index e35bc52c0..c3e8b2ab3 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -331,16 +331,28 @@ void FeedDownloader::updateOneFeed(ServiceRoot* acc, } // Process changed labels. + // + // NOTE: We do not need to to this for + // feeds which do not use online synchronised + // labels, because those synchronized feeds + // replace all labels later in the method. + // const bool uses_online_labels = + // (feed->getParentServiceRoot()->supportedLabelOperations() & ServiceRoot::LabelOperation::Synchronised) == + // ServiceRoot::LabelOperation::Synchronised; + + // if (!uses_online_labels) { + + // NOTE: We only remember what labels were added/removed in filters + // and store the fact to server (of synchronized) and local DB later. + // This is mainly because articles might not even be in DB yet. + // So first insert articles, then update their label assignments etc. for (Label* lbl : qAsConst(msg_original.m_assignedLabels)) { if (!msg_tweaked_by_filter->m_assignedLabels.contains(lbl)) { QMutexLocker lck(&m_mutexDb); // Label is not there anymore, it was deassigned. - lbl->deassignFromMessage(*msg_tweaked_by_filter); - - qDebugNN << LOGSEC_FEEDDOWNLOADER << "It was detected that label" << QUOTE_W_SPACE(lbl->customId()) - << "was DEASSIGNED from message" << QUOTE_W_SPACE(msg_tweaked_by_filter->m_customId) - << "by message filter(s)."; + msg_tweaked_by_filter->m_deassignedLabelsByFilter << lbl; + msg_tweaked_by_filter->m_assignedLabels << lbl; } } @@ -350,13 +362,11 @@ void FeedDownloader::updateOneFeed(ServiceRoot* acc, // Label is in new message, but is not in old message, it // was newly assigned. - lbl->assignToMessage(*msg_tweaked_by_filter); - - qDebugNN << LOGSEC_FEEDDOWNLOADER << "It was detected that label" << QUOTE_W_SPACE(lbl->customId()) - << "was ASSIGNED to message" << QUOTE_W_SPACE(msg_tweaked_by_filter->m_customId) - << "by message filter(s)."; + msg_tweaked_by_filter->m_assignedLabelsByFilter << lbl; + msg_tweaked_by_filter->m_assignedLabels << lbl; } } + //} if (remove_msg) { msgs.removeAt(i--); diff --git a/src/librssguard/core/message.cpp b/src/librssguard/core/message.cpp index b132b4116..707225d4b 100644 --- a/src/librssguard/core/message.cpp +++ b/src/librssguard/core/message.cpp @@ -67,6 +67,8 @@ Message::Message() { m_score = 0.0; m_isRead = m_isImportant = m_isDeleted = false; m_assignedLabels = QList(); + m_assignedLabelsByFilter = QList(); + m_deassignedLabelsByFilter = QList(); } void Message::sanitize(const Feed* feed, bool fix_future_datetimes) { diff --git a/src/librssguard/core/message.h b/src/librssguard/core/message.h index 48406644c..b6774c79f 100644 --- a/src/librssguard/core/message.h +++ b/src/librssguard/core/message.h @@ -67,6 +67,9 @@ class RSSGUARD_DLLSPEC Message { // List of custom IDs of labels assigned to this message. QList m_assignedLabels; + QList m_assignedLabelsByFilter; + QList m_deassignedLabelsByFilter; + // Is true if "created" date was obtained directly // from the feed, otherwise is false bool m_createdFromFeed = false; diff --git a/src/librssguard/database/databasequeries.cpp b/src/librssguard/database/databasequeries.cpp index 727348604..11c7a80f4 100644 --- a/src/librssguard/database/databasequeries.cpp +++ b/src/librssguard/database/databasequeries.cpp @@ -38,7 +38,7 @@ QMap DatabaseQueries::messageTableAttributes(bool only_msg_table) "ELSE 'false' " "END AS has_enclosures"); field_names[MSG_DB_LABELS] = - QSL("(SELECT GROUP_CONCAT(Labels.name) FROM Labels WHERE Labels.id IN (SELECT " + QSL("(SELECT GROUP_CONCAT(Labels.name) FROM Labels WHERE Labels.custom_id IN (SELECT " "LabelsInMessages.label FROM LabelsInMessages WHERE LabelsInMessages.account_id = " "Messages.account_id AND LabelsInMessages.message = Messages.custom_id)) as msg_labels"); @@ -1439,17 +1439,31 @@ QPair DatabaseQueries::updateMessages(QSqlDatabase db, } } - // Update labels assigned to message. + const bool uses_online_labels = + (feed->getParentServiceRoot()->supportedLabelOperations() & ServiceRoot::LabelOperation::Synchronised) == + ServiceRoot::LabelOperation::Synchronised; + for (Message& message : messages) { - if (!message.m_assignedLabels.isEmpty()) { - if (!message.m_customId.isEmpty() || message.m_id > 0) { - QMutexLocker lck(db_mutex); + if (!message.m_customId.isEmpty() || message.m_id > 0) { + QMutexLocker lck(db_mutex); + + if (uses_online_labels) { + // Store all labels obtained from server. setLabelsForMessage(db, message.m_assignedLabels, message); } - else { - qCriticalNN << LOGSEC_DB << "Cannot set labels for message" << QUOTE_W_SPACE(message.m_title) - << "because we don't have ID or custom ID."; + + // Adjust labels tweaked by filters. + for (Label* assigned_by_filter : message.m_assignedLabelsByFilter) { + assigned_by_filter->assignToMessage(message); } + + for (Label* removed_by_filter : message.m_deassignedLabelsByFilter) { + removed_by_filter->deassignFromMessage(message); + } + } + else { + qCriticalNN << LOGSEC_DB << "Cannot set labels for message" << QUOTE_W_SPACE(message.m_title) + << "because we don't have ID or custom ID."; } }