From 2880a8c0f1efdd8b567d23a57f5c20d5e7751c94 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 23 Oct 2020 16:12:27 +0200 Subject: [PATCH] Inoreader now supports syncing of label assignments. --- .../services/inoreader/definitions.h | 4 + .../inoreader/inoreaderserviceroot.cpp | 26 ++++++ .../network/inoreadernetworkfactory.cpp | 81 +++---------------- .../network/inoreadernetworkfactory.h | 7 +- 4 files changed, 45 insertions(+), 73 deletions(-) diff --git a/src/librssguard/services/inoreader/definitions.h b/src/librssguard/services/inoreader/definitions.h index 051521c02..2195a9fdc 100644 --- a/src/librssguard/services/inoreader/definitions.h +++ b/src/librssguard/services/inoreader/definitions.h @@ -22,6 +22,10 @@ #define INOREADER_STATE_READ "state/com.google/read" #define INOREADER_STATE_IMPORTANT "state/com.google/starred" +#define INOREADER_FULL_STATE_READING_LIST "user/-/state/com.google/reading-list" +#define INOREADER_FULL_STATE_READ "user/-/state/com.google/read" +#define INOREADER_FULL_STATE_IMPORTANT "user/-/state/com.google/starred" + #define INOREADER_API_FEED_CONTENTS "https://www.inoreader.com/reader/api/0/stream/contents" #define INOREADER_API_LIST_LABELS "https://www.inoreader.com/reader/api/0/tag/list?types=1" #define INOREADER_API_LIST_FEEDS "https://www.inoreader.com/reader/api/0/subscription/list" diff --git a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp index 7c2c8511c..ea29145f9 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp @@ -181,6 +181,32 @@ void InoreaderServiceRoot::saveAllCachedData(bool async) { network()->markMessagesStarred(key, custom_ids, async); } } + + QMapIterator k(msg_cache.m_cachedLabelAssignments); + + // Assign label for these messages. + while (k.hasNext()) { + k.next(); + auto label_custom_id = k.key(); + QStringList messages = k.value(); + + if (!messages.isEmpty()) { + network()->editLabels(label_custom_id, true, messages, async); + } + } + + QMapIterator l(msg_cache.m_cachedLabelDeassignments); + + // Remove label from these messages. + while (l.hasNext()) { + l.next(); + auto label_custom_id = l.key(); + QStringList messages = l.value(); + + if (!messages.isEmpty()) { + network()->editLabels(label_custom_id, false, messages, async); + } + } } bool InoreaderServiceRoot::canBeDeleted() const { diff --git a/src/librssguard/services/inoreader/network/inoreadernetworkfactory.cpp b/src/librssguard/services/inoreader/network/inoreadernetworkfactory.cpp index 62a737741..0492b1261 100644 --- a/src/librssguard/services/inoreader/network/inoreadernetworkfactory.cpp +++ b/src/librssguard/services/inoreader/network/inoreadernetworkfactory.cpp @@ -194,14 +194,14 @@ QList InoreaderNetworkFactory::messages(ServiceRoot* root, const QStrin } } -void InoreaderNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids, bool async) { +void InoreaderNetworkFactory::editLabels(const QString& state, bool assign, const QStringList& msg_custom_ids, bool async) { QString target_url = INOREADER_API_EDIT_TAG; - if (status == RootItem::ReadStatus::Read) { - target_url += QString("?a=user/-/") + INOREADER_STATE_READ + "&"; + if (assign) { + target_url += QString("?a=") + state + "&"; } else { - target_url += QString("?r=user/-/") + INOREADER_STATE_READ + "&"; + target_url += QString("?r=") + state + "&"; } QString bearer = m_oauth2->bearer().toLocal8Bit(); @@ -218,7 +218,7 @@ void InoreaderNetworkFactory::markMessagesRead(RootItem::ReadStatus status, cons QStringList trimmed_ids; QRegularExpression regex_short_id(QSL("[0-9a-zA-Z]+$")); - for (const QString& id : custom_ids) { + for (const QString& id : msg_custom_ids) { QString simplified_id = regex_short_id.match(id).captured(); trimmed_ids.append(QString("i=") + simplified_id); @@ -240,7 +240,6 @@ void InoreaderNetworkFactory::markMessagesRead(RootItem::ReadStatus status, cons // We send this batch. if (async) { - NetworkFactory::performAsyncNetworkOperation(batch_final_url, timeout, QByteArray(), @@ -263,72 +262,12 @@ void InoreaderNetworkFactory::markMessagesRead(RootItem::ReadStatus status, cons } } -void InoreaderNetworkFactory::markMessagesStarred(RootItem::Importance importance, const QStringList& custom_ids, bool async) { - QString target_url = INOREADER_API_EDIT_TAG; +void InoreaderNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const QStringList& msg_custom_ids, bool async) { + editLabels(INOREADER_FULL_STATE_READ, status == RootItem::ReadStatus::Read, msg_custom_ids, async); +} - if (importance == RootItem::Importance::Important) { - target_url += QString("?a=user/-/") + INOREADER_STATE_IMPORTANT + "&"; - } - else { - target_url += QString("?r=user/-/") + INOREADER_STATE_IMPORTANT + "&"; - } - - QString bearer = m_oauth2->bearer().toLocal8Bit(); - - if (bearer.isEmpty()) { - return; - } - - QList> headers; - - headers.append(QPair(QString(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(), - m_oauth2->bearer().toLocal8Bit())); - - QStringList trimmed_ids; - QRegularExpression regex_short_id(QSL("[0-9a-zA-Z]+$")); - - for (const QString& id : custom_ids) { - QString simplified_id = regex_short_id.match(id).captured(); - - trimmed_ids.append(QString("i=") + simplified_id); - } - - QStringList working_subset; - int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt(); - - working_subset.reserve(trimmed_ids.size() > 200 ? 200 : trimmed_ids.size()); - - // Now, we perform messages update in batches (max 200 messages per batch). - while (!trimmed_ids.isEmpty()) { - // We take 200 IDs. - for (int i = 0; i < 200 && !trimmed_ids.isEmpty(); i++) { - working_subset.append(trimmed_ids.takeFirst()); - } - - QString batch_final_url = target_url + working_subset.join(QL1C('&')); - - // We send this batch. - if (async) { - NetworkFactory::performAsyncNetworkOperation(batch_final_url, - timeout, - QByteArray(), - QNetworkAccessManager::Operation::GetOperation, - headers); - } - else { - QByteArray output; - - NetworkFactory::performNetworkOperation(batch_final_url, - timeout, - QByteArray(), - output, - QNetworkAccessManager::Operation::GetOperation, - headers); - } - - // Cleanup for next batch. - working_subset.clear(); - } +void InoreaderNetworkFactory::markMessagesStarred(RootItem::Importance importance, const QStringList& msg_custom_ids, bool async) { + editLabels(INOREADER_FULL_STATE_IMPORTANT, importance == RootItem::Importance::Important, msg_custom_ids, async); } void InoreaderNetworkFactory::onTokensError(const QString& error, const QString& error_description) { diff --git a/src/librssguard/services/inoreader/network/inoreadernetworkfactory.h b/src/librssguard/services/inoreader/network/inoreadernetworkfactory.h index 1c345d109..ed21a689c 100644 --- a/src/librssguard/services/inoreader/network/inoreadernetworkfactory.h +++ b/src/librssguard/services/inoreader/network/inoreadernetworkfactory.h @@ -41,8 +41,11 @@ class InoreaderNetworkFactory : public QObject { QList getLabels(); QList messages(ServiceRoot* root, const QString& stream_id, Feed::Status& error); - void markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids, bool async = true); - void markMessagesStarred(RootItem::Importance importance, const QStringList& custom_ids, bool async = true); + + void editLabels(const QString& state, bool assign, const QStringList& msg_custom_ids, bool async = true); + + void markMessagesRead(RootItem::ReadStatus status, const QStringList& msg_custom_ids, bool async = true); + void markMessagesStarred(RootItem::Importance importance, const QStringList& msg_custom_ids, bool async = true); private slots: void onTokensError(const QString& error, const QString& error_description);