diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml index 53f61d800..f8b9a18fc 100644 --- a/resources/desktop/com.github.rssguard.appdata.xml +++ b/resources/desktop/com.github.rssguard.appdata.xml @@ -30,7 +30,7 @@ https://martinrotter.github.io/donate/ - + none diff --git a/src/librssguard/core/feeddownloader.cpp b/src/librssguard/core/feeddownloader.cpp index e7d0cd52f..f5480c3ce 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -127,27 +127,27 @@ void FeedDownloader::updateOneFeed(Feed* feed) { QSqlDatabase database = is_main_thread ? qApp->database()->driver()->connection(metaObject()->className()) : qApp->database()->driver()->connection(QSL("feed_upd")); - QHash> stated_messages; + QHash> stated_messages; QHash tagged_messages; if (feed->getParentServiceRoot()->wantsBaggedIdsOfExistingMessages()) { // This account has activated intelligent downloading of messages. // Prepare bags. - stated_messages.insert(feed->customId(), - { ServiceRoot::BagOfMessages::Read, - DatabaseQueries::bagOfMessages(database, - ServiceRoot::BagOfMessages::Read, - feed) }); - stated_messages.insert(feed->customId(), - { ServiceRoot::BagOfMessages::Unread, - DatabaseQueries::bagOfMessages(database, - ServiceRoot::BagOfMessages::Unread, - feed) }); - stated_messages.insert(feed->customId(), - { ServiceRoot::BagOfMessages::Starred, - DatabaseQueries::bagOfMessages(database, - ServiceRoot::BagOfMessages::Starred, - feed) }); + QHash per_feed_states; + + per_feed_states.insert(ServiceRoot::BagOfMessages::Read, + DatabaseQueries::bagOfMessages(database, + ServiceRoot::BagOfMessages::Read, + feed)); + per_feed_states.insert(ServiceRoot::BagOfMessages::Unread, + DatabaseQueries::bagOfMessages(database, + ServiceRoot::BagOfMessages::Unread, + feed)); + per_feed_states.insert(ServiceRoot::BagOfMessages::Starred, + DatabaseQueries::bagOfMessages(database, + ServiceRoot::BagOfMessages::Starred, + feed)); + stated_messages.insert(feed->customId(), per_feed_states); tagged_messages = DatabaseQueries::bagsOfMessages(database, feed->getParentServiceRoot()->labelsNode()->labels()); diff --git a/src/librssguard/core/messagesmodelsqllayer.cpp b/src/librssguard/core/messagesmodelsqllayer.cpp index dcb4c4b13..3f094b589 100644 --- a/src/librssguard/core/messagesmodelsqllayer.cpp +++ b/src/librssguard/core/messagesmodelsqllayer.cpp @@ -39,9 +39,10 @@ MessagesModelSqlLayer::MessagesModelSqlLayer() << MSG_DB_SCORE_INDEX; } -void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order) { +void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order, bool ignore_multicolumn_sorting) { int existing = m_sortColumns.indexOf(column); - bool is_ctrl_pressed = (QApplication::queryKeyboardModifiers() & Qt::ControlModifier) == Qt::ControlModifier; + bool is_ctrl_pressed = (QApplication::queryKeyboardModifiers() & + Qt::KeyboardModifier::ControlModifier) == Qt::KeyboardModifier::ControlModifier; if (existing >= 0) { m_sortColumns.removeAt(existing); @@ -55,14 +56,18 @@ void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order) { m_sortOrders.removeAt(0); } - if (is_ctrl_pressed) { + if (is_ctrl_pressed && !ignore_multicolumn_sorting) { // User is activating the multicolumn sort mode. m_sortColumns.append(column); m_sortOrders.append(order); + + qDebugNN << "CTRL is pressed while sorting articles - sorting with multicolumn mode."; } else { m_sortColumns.prepend(column); m_sortOrders.prepend(order); + + qDebugNN << "CTRL is NOT pressed while sorting articles - sorting with standard mode."; } } diff --git a/src/librssguard/core/messagesmodelsqllayer.h b/src/librssguard/core/messagesmodelsqllayer.h index 1a8729ed4..cc2a884ec 100644 --- a/src/librssguard/core/messagesmodelsqllayer.h +++ b/src/librssguard/core/messagesmodelsqllayer.h @@ -13,7 +13,7 @@ class MessagesModelSqlLayer { explicit MessagesModelSqlLayer(); // Adds this new state to queue of sort states. - void addSortState(int column, Qt::SortOrder order); + void addSortState(int column, Qt::SortOrder order, bool ignore_multicolumn_sorting); // Sets SQL WHERE clause, without "WHERE" keyword. void setFilter(const QString& filter); diff --git a/src/librssguard/database/databasequeries.cpp b/src/librssguard/database/databasequeries.cpp index c547cfb24..d16605096 100755 --- a/src/librssguard/database/databasequeries.cpp +++ b/src/librssguard/database/databasequeries.cpp @@ -982,9 +982,10 @@ QStringList DatabaseQueries::bagOfMessages(const QSqlDatabase& db, ServiceRoot:: q.prepare(QSL("SELECT custom_id " "FROM Messages " - "WHERE %1 AND account_id = :account_id;").arg(query)); + "WHERE %1 AND feed = :feed AND account_id = :account_id;").arg(query)); q.bindValue(QSL(":account_id"), feed->getParentServiceRoot()->accountId()); + q.bindValue(QSL(":feed"), feed->customId()); q.exec(); while (q.next()) { @@ -1277,22 +1278,20 @@ QPair DatabaseQueries::updateMessages(QSqlDatabase db, // // 4) FOR ALL SERVICES: Message update is forced, we want to overwrite message as some arbitrary atribute was changed, // this particularly happens when manual message filter execution happens. - if (/* 1 */ (!message.m_customId.isEmpty() && feed->getParentServiceRoot()->isSyncable() && - (message.m_created.toMSecsSinceEpoch() != date_existing_message || - message.m_isRead != is_read_existing_message || - message.m_isImportant != is_important_existing_message || - message.m_feedId != feed_id_existing_message || - message.m_title != title_existing_message || - message.m_contents != contents_existing_message)) || + bool cond_1 = !message.m_customId.isEmpty() && feed->getParentServiceRoot()->isSyncable() && + (message.m_created.toMSecsSinceEpoch() != date_existing_message || + message.m_isRead != is_read_existing_message || + message.m_isImportant != is_important_existing_message || + message.m_feedId != feed_id_existing_message || + message.m_title != title_existing_message || + message.m_contents != contents_existing_message); + bool cond_2 = !message.m_customId.isEmpty() && !feed->getParentServiceRoot()->isSyncable() && + (message.m_title != title_existing_message || + message.m_contents != contents_existing_message); + bool cond_3 = message.m_createdFromFeed && message.m_created.toMSecsSinceEpoch() != date_existing_message && + message.m_contents != contents_existing_message; - /* 2 */ (!message.m_customId.isEmpty() && !feed->getParentServiceRoot()->isSyncable() && - (message.m_title != title_existing_message || - message.m_contents != contents_existing_message)) || - - /* 3 */ (message.m_createdFromFeed && message.m_created.toMSecsSinceEpoch() != date_existing_message && - message.m_contents != contents_existing_message) || - - /* 4 */ force_update) { + if (cond_1 || cond_2 || cond_3 || force_update) { // Message exists and is changed, update it. query_update.bindValue(QSL(":title"), unnulifyString(message.m_title)); query_update.bindValue(QSL(":is_read"), int(message.m_isRead)); diff --git a/src/librssguard/gui/messagesview.cpp b/src/librssguard/gui/messagesview.cpp index 723bf3ef1..da3cf5005 100644 --- a/src/librssguard/gui/messagesview.cpp +++ b/src/librssguard/gui/messagesview.cpp @@ -52,12 +52,15 @@ void MessagesView::reloadFontSettings() { m_sourceModel->setupFonts(); } -void MessagesView::sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header) { +void MessagesView::sort(int column, Qt::SortOrder order, + bool repopulate_data, bool change_header, + bool emit_changed_from_header, + bool ignore_multicolumn_sorting) { if (change_header && !emit_changed_from_header) { header()->blockSignals(true); } - m_sourceModel->addSortState(column, order); + m_sourceModel->addSortState(column, order, ignore_multicolumn_sorting); if (repopulate_data) { m_sourceModel->repopulate(); @@ -94,7 +97,7 @@ void MessagesView::reloadSelections() { const Qt::SortOrder ord = header()->sortIndicatorOrder(); // Reload the model now. - sort(col, ord, true, false, false); + sort(col, ord, true, false, false, true); // Now, we must find the same previously focused message. if (selected_message.m_id > 0) { @@ -363,7 +366,7 @@ void MessagesView::loadItem(RootItem* item) { const Qt::SortOrder ord = header()->sortIndicatorOrder(); scrollToTop(); - sort(col, ord, false, true, false); + sort(col, ord, false, true, false, true); m_sourceModel->loadMessages(item); // Messages are loaded, make sure that previously @@ -679,7 +682,7 @@ void MessagesView::adjustColumns() { void MessagesView::onSortIndicatorChanged(int column, Qt::SortOrder order) { // Repopulate the shit. - sort(column, order, true, false, false); + sort(column, order, true, false, false, false); emit currentMessageRemoved(); } diff --git a/src/librssguard/gui/messagesview.h b/src/librssguard/gui/messagesview.h index 4939bffaa..cc6f9e810 100644 --- a/src/librssguard/gui/messagesview.h +++ b/src/librssguard/gui/messagesview.h @@ -80,7 +80,8 @@ class MessagesView : public QTreeView { void willReselectSameMessage(); private: - void sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header); + void sort(int column, Qt::SortOrder order, bool repopulate_data, + bool change_header, bool emit_changed_from_header, bool ignore_multicolumn_sorting); // Creates needed connections. void createConnections(); diff --git a/src/librssguard/services/abstract/serviceroot.h b/src/librssguard/services/abstract/serviceroot.h index d16198913..f37401e14 100644 --- a/src/librssguard/services/abstract/serviceroot.h +++ b/src/librssguard/services/abstract/serviceroot.h @@ -102,7 +102,7 @@ class ServiceRoot : public RootItem { // Throws exception subclassed from ApplicationException, preferably FeedFetchException // if any problems arise. virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages) = 0; // This method should prepare messages for given "item" (download them maybe?) diff --git a/src/librssguard/services/feedly/feedlyserviceroot.cpp b/src/librssguard/services/feedly/feedlyserviceroot.cpp index 77086ee83..072d45815 100755 --- a/src/librssguard/services/feedly/feedlyserviceroot.cpp +++ b/src/librssguard/services/feedly/feedlyserviceroot.cpp @@ -73,7 +73,7 @@ void FeedlyServiceRoot::setCustomDatabaseData(const QVariantHash& data) { } QList FeedlyServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) diff --git a/src/librssguard/services/feedly/feedlyserviceroot.h b/src/librssguard/services/feedly/feedlyserviceroot.h index d0b1a72e5..ed79024dd 100755 --- a/src/librssguard/services/feedly/feedlyserviceroot.h +++ b/src/librssguard/services/feedly/feedlyserviceroot.h @@ -24,7 +24,7 @@ class FeedlyServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages); FeedlyNetwork* network() const; diff --git a/src/librssguard/services/gmail/gmailserviceroot.cpp b/src/librssguard/services/gmail/gmailserviceroot.cpp index f8985c810..27f5586d2 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.cpp +++ b/src/librssguard/services/gmail/gmailserviceroot.cpp @@ -75,7 +75,7 @@ void GmailServiceRoot::setCustomDatabaseData(const QVariantHash& data) { } QList GmailServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) diff --git a/src/librssguard/services/gmail/gmailserviceroot.h b/src/librssguard/services/gmail/gmailserviceroot.h index 58b5ba9bc..71a7dd94c 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.h +++ b/src/librssguard/services/gmail/gmailserviceroot.h @@ -32,7 +32,7 @@ class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages); protected: diff --git a/src/librssguard/services/greader/definitions.h b/src/librssguard/services/greader/definitions.h index ea237fb85..ce6914dbe 100755 --- a/src/librssguard/services/greader/definitions.h +++ b/src/librssguard/services/greader/definitions.h @@ -27,6 +27,8 @@ #define GREADER_API_SUBSCRIPTION_LIST "reader/api/0/subscription/list?output=json" #define GREADER_API_STREAM_CONTENTS "reader/api/0/stream/contents/%1?output=json&n=%2" #define GREADER_API_EDIT_TAG "reader/api/0/edit-tag" +#define GREADER_API_ITEM_IDS "reader/api/0/stream/items/ids?output=json&s=%1" +#define GREADER_API_ITEM_CONTENTS "reader/api/0/stream/items/contents?output=json&n=%1" #define GREADER_API_TOKEN "reader/api/0/token" #define GREADER_API_USER_INFO "reader/api/0/user-info?output=json" diff --git a/src/librssguard/services/greader/greadernetwork.cpp b/src/librssguard/services/greader/greadernetwork.cpp index 9a827beeb..da0f3e063 100755 --- a/src/librssguard/services/greader/greadernetwork.cpp +++ b/src/librssguard/services/greader/greadernetwork.cpp @@ -120,6 +120,41 @@ QVariantHash GreaderNetwork::userInfo(const QNetworkProxy& proxy) { return QJsonDocument::fromJson(output).object().toVariantHash(); } +QList GreaderNetwork::getMessagesIntelligently(ServiceRoot* root, + const QString& stream_id, + const QHash& stated_messages, + const QHash& tagged_messages, + Feed::Status& error, + const QNetworkProxy& proxy) { + // 1. Get unread IDs for a feed. + // 2. Get read IDs for a feed. + // 3. Download messages/contents for missing or changed IDs. + // 4. Download all starred messages and append those belonging to this feed. + + auto remote_all_ids_list = itemIds(stream_id, false, proxy); + auto remote_unread_ids_list = itemIds(stream_id, true, proxy); + QSet remote_all_ids(remote_all_ids_list.begin(), remote_all_ids_list.end()); + + // 1. + auto local_unread_ids_list = stated_messages.value(ServiceRoot::BagOfMessages::Unread); + QSet remote_unread_ids(remote_unread_ids_list.begin(), remote_unread_ids_list.end()); + QSet local_unread_ids(local_unread_ids_list.begin(), + local_unread_ids_list.end()); + + // 2. + auto local_read_ids_list = stated_messages.value(ServiceRoot::BagOfMessages::Read); + QSet remote_read_ids = remote_all_ids - remote_unread_ids; + QSet local_read_ids(local_read_ids_list.begin(), + local_read_ids_list.end()); + auto not_downloaded = remote_all_ids - local_read_ids - local_unread_ids; + auto moved_unread = local_unread_ids.intersect(remote_read_ids); + auto moved_read = local_read_ids.intersect(remote_unread_ids); + auto to_download = not_downloaded + moved_read + moved_unread; + QList to_download_list(to_download.begin(), to_download.end()); + + return itemContents(root, to_download_list, error, proxy); +} + QNetworkReply::NetworkError GreaderNetwork::markMessagesRead(RootItem::ReadStatus status, const QStringList& msg_custom_ids, const QNetworkProxy& proxy) { @@ -132,6 +167,115 @@ QNetworkReply::NetworkError GreaderNetwork::markMessagesStarred(RootItem::Import return editLabels(GREADER_API_FULL_STATE_IMPORTANT, importance == RootItem::Importance::Important, msg_custom_ids, proxy); } +QStringList GreaderNetwork::itemIds(const QString& stream_id, bool unread_only, const QNetworkProxy& proxy) { + QString continuation; + + if (!ensureLogin(proxy)) { + throw ApplicationException(tr("login failed")); + } + + QStringList ids; + + do { + QString full_url = generateFullUrl(Operations::ItemIds).arg(m_service == GreaderServiceRoot::Service::TheOldReader + ? stream_id + : QUrl::toPercentEncoding(stream_id)); + auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt(); + + if (unread_only) { + full_url += QSL("&xt=%1").arg(GREADER_API_FULL_STATE_READ); + } + + if (!continuation.isEmpty()) { + full_url += QSL("&c=%1").arg(continuation); + } + + QByteArray output_stream; + auto result_stream = NetworkFactory::performNetworkOperation(full_url, + timeout, + {}, + output_stream, + QNetworkAccessManager::Operation::GetOperation, + { authHeader() }, + false, + {}, + {}, + proxy); + + if (result_stream.first != QNetworkReply::NetworkError::NoError) { + qCriticalNN << LOGSEC_GREADER + << "Cannot download item IDs for " + << QUOTE_NO_SPACE(stream_id) + << ", network error:" + << QUOTE_W_SPACE_DOT(result_stream.first); + throw NetworkException(result_stream.first); + } + else { + ids.append(decodeItemIds(output_stream, continuation)); + } + } + while (!continuation.isEmpty()); + + return ids; +} + +QList GreaderNetwork::itemContents(ServiceRoot* root, const QList& stream_ids, + Feed::Status& error, const QNetworkProxy& proxy) { + QString continuation; + + if (!ensureLogin(proxy)) { + error = Feed::Status::AuthError; + return {}; + } + + QList msgs; + int target_msgs_size = 999; + + do { + QString full_url = generateFullUrl(Operations::ItemContents).arg(QString::number(target_msgs_size)); + auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt(); + + if (!continuation.isEmpty()) { + full_url += QSL("&c=%1").arg(continuation); + } + + std::list inp = boolinq::from(stream_ids).select([this](const QString& id) { + return QSL("i=%1").arg(m_service == GreaderServiceRoot::Service::TheOldReader + ? id + : QUrl::toPercentEncoding(id)); + }).toStdList(); + QByteArray input = FROM_STD_LIST(QStringList, inp).join(QSL("&")).toUtf8(); + QByteArray output_stream; + auto result_stream = NetworkFactory::performNetworkOperation(full_url, + timeout, + input, + output_stream, + QNetworkAccessManager::Operation::PostOperation, + { authHeader() }, + false, + {}, + {}, + proxy); + + if (result_stream.first != QNetworkReply::NetworkError::NoError) { + qCriticalNN << LOGSEC_GREADER + << "Cannot download messages for " + << stream_ids + << ", network error:" + << QUOTE_W_SPACE_DOT(result_stream.first); + error = Feed::Status::NetworkError; + return {}; + } + else { + msgs.append(decodeStreamContents(root, output_stream, "", continuation)); + } + } + while (!continuation.isEmpty()); + + error = Feed::Status::Normal; + return msgs; +} + QList GreaderNetwork::streamContents(ServiceRoot* root, const QString& stream_id, Feed::Status& error, const QNetworkProxy& proxy) { QString continuation; @@ -548,6 +692,21 @@ QString GreaderNetwork::simplifyStreamId(const QString& stream_id) const { return QString(stream_id).replace(QRegularExpression("\\/\\d+\\/"), QSL("/-/")); } +QStringList GreaderNetwork::decodeItemIds(const QString& stream_json_data, QString& continuation) { + QStringList ids; + QJsonDocument json_doc = QJsonDocument::fromJson(stream_json_data.toUtf8()); + QJsonArray json = json_doc.object()["itemRefs"].toArray(); + + continuation = json_doc.object()["continuation"].toString(); + ids.reserve(json.count()); + + for (const QJsonValue& id : json) { + ids.append(id.toObject()["id"].toString()); + } + + return ids; +} + QList GreaderNetwork::decodeStreamContents(ServiceRoot* root, const QString& stream_json_data, const QString& stream_id, @@ -618,7 +777,9 @@ QList GreaderNetwork::decodeStreamContents(ServiceRoot* root, message.m_contents = message_obj["summary"].toObject()["content"].toString(); message.m_rawContents = QJsonDocument(message_obj).toJson(QJsonDocument::JsonFormat::Compact); - message.m_feedId = stream_id; + message.m_feedId = stream_id.isEmpty() + ? message_obj["origin"].toObject()["streamId"].toString() + : stream_id; messages.append(message); } @@ -680,6 +841,12 @@ QString GreaderNetwork::generateFullUrl(GreaderNetwork::Operations operation) co case Operations::EditTag: return sanitizedBaseUrl() + GREADER_API_EDIT_TAG; + case Operations::ItemIds: + return sanitizedBaseUrl() + GREADER_API_ITEM_IDS; + + case Operations::ItemContents: + return sanitizedBaseUrl() + GREADER_API_ITEM_CONTENTS; + default: return sanitizedBaseUrl(); } diff --git a/src/librssguard/services/greader/greadernetwork.h b/src/librssguard/services/greader/greadernetwork.h index 5ba364245..0b15690ee 100755 --- a/src/librssguard/services/greader/greadernetwork.h +++ b/src/librssguard/services/greader/greadernetwork.h @@ -20,7 +20,9 @@ class GreaderNetwork : public QObject { StreamContents, EditTag, Token, - UserInfo + UserInfo, + ItemIds, + ItemContents }; explicit GreaderNetwork(QObject* parent = nullptr); @@ -38,7 +40,19 @@ class GreaderNetwork : public QObject { QVariantHash userInfo(const QNetworkProxy& proxy); + QList getMessagesIntelligently(ServiceRoot* root, + const QString& stream_id, + const QHash& stated_messages, + const QHash& tagged_messages, + Feed::Status& error, + const QNetworkProxy& proxy); + + QStringList itemIds(const QString& stream_id, bool unread_only, const QNetworkProxy& proxy); + // Stream contents for a feed/label/etc. + QList itemContents(ServiceRoot* root, const QList& stream_ids, + Feed::Status& error, const QNetworkProxy& proxy); + QList streamContents(ServiceRoot* root, const QString& stream_id, Feed::Status& error, const QNetworkProxy& proxy); @@ -78,6 +92,7 @@ class GreaderNetwork : public QObject { bool ensureLogin(const QNetworkProxy& proxy, QNetworkReply::NetworkError* output = nullptr); QString simplifyStreamId(const QString& stream_id) const; + QStringList decodeItemIds(const QString& stream_json_data, QString& continuation); QList decodeStreamContents(ServiceRoot* root, const QString& stream_json_data, const QString& stream_id, QString& continuation); RootItem* decodeTagsSubscriptions(const QString& categories, const QString& feeds, bool obtain_icons, const QNetworkProxy& proxy); QString sanitizedBaseUrl() const; diff --git a/src/librssguard/services/greader/greaderserviceroot.cpp b/src/librssguard/services/greader/greaderserviceroot.cpp index 81297a484..9bd25455f 100755 --- a/src/librssguard/services/greader/greaderserviceroot.cpp +++ b/src/librssguard/services/greader/greaderserviceroot.cpp @@ -58,7 +58,7 @@ void GreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) { } QList GreaderServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) @@ -68,7 +68,17 @@ QList GreaderServiceRoot::obtainNewMessages(const QList& feeds, for (Feed* feed : feeds) { Feed::Status error = Feed::Status::Normal; - messages << network()->streamContents(this, feed->customId(), error, networkProxy()); + if (true /* intelligent downloading */ ) { + messages << network()->getMessagesIntelligently(this, + feed->customId(), + stated_messages.value(feed->customId()), + tagged_messages, + error, + networkProxy()); + } + else { + messages << network()->streamContents(this, feed->customId(), error, networkProxy()); + } if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError) { throw FeedFetchException(error); diff --git a/src/librssguard/services/greader/greaderserviceroot.h b/src/librssguard/services/greader/greaderserviceroot.h index d9c8df5b9..2c22c414b 100755 --- a/src/librssguard/services/greader/greaderserviceroot.h +++ b/src/librssguard/services/greader/greaderserviceroot.h @@ -32,7 +32,7 @@ class GreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages); virtual bool wantsBaggedIdsOfExistingMessages() const; diff --git a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp index 741cfd4ed..5d19c2496 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp @@ -57,7 +57,7 @@ void InoreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) { } QList InoreaderServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) diff --git a/src/librssguard/services/inoreader/inoreaderserviceroot.h b/src/librssguard/services/inoreader/inoreaderserviceroot.h index b1dfe27a9..939f7da3a 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.h +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.h @@ -30,7 +30,7 @@ class InoreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages); protected: diff --git a/src/librssguard/services/owncloud/owncloudserviceroot.cpp b/src/librssguard/services/owncloud/owncloudserviceroot.cpp index f45221792..ad4aff717 100644 --- a/src/librssguard/services/owncloud/owncloudserviceroot.cpp +++ b/src/librssguard/services/owncloud/owncloudserviceroot.cpp @@ -151,7 +151,7 @@ void OwnCloudServiceRoot::setCustomDatabaseData(const QVariantHash& data) { } QList OwnCloudServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) diff --git a/src/librssguard/services/owncloud/owncloudserviceroot.h b/src/librssguard/services/owncloud/owncloudserviceroot.h index 78600e6c3..5a15fc61d 100644 --- a/src/librssguard/services/owncloud/owncloudserviceroot.h +++ b/src/librssguard/services/owncloud/owncloudserviceroot.h @@ -29,7 +29,7 @@ class OwnCloudServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages); OwnCloudNetworkFactory* network() const; diff --git a/src/librssguard/services/standard/standardserviceroot.cpp b/src/librssguard/services/standard/standardserviceroot.cpp index 60efbd018..75bf4abbb 100644 --- a/src/librssguard/services/standard/standardserviceroot.cpp +++ b/src/librssguard/services/standard/standardserviceroot.cpp @@ -145,7 +145,7 @@ Qt::ItemFlags StandardServiceRoot::additionalFlags() const { } QList StandardServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) diff --git a/src/librssguard/services/standard/standardserviceroot.h b/src/librssguard/services/standard/standardserviceroot.h index 89553f983..b1912fdc4 100644 --- a/src/librssguard/services/standard/standardserviceroot.h +++ b/src/librssguard/services/standard/standardserviceroot.h @@ -33,7 +33,7 @@ class StandardServiceRoot : public ServiceRoot { virtual bool supportsCategoryAdding() const; virtual Qt::ItemFlags additionalFlags() const; virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages); QList serviceMenu(); diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp index a1b6d7ca5..baa5cb6e7 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp @@ -215,7 +215,7 @@ void TtRssServiceRoot::setCustomDatabaseData(const QVariantHash& data) { } QList TtRssServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.h b/src/librssguard/services/tt-rss/ttrssserviceroot.h index 042be9099..195e82f9c 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.h +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.h @@ -34,7 +34,7 @@ class TtRssServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + const QHash>& stated_messages, const QHash& tagged_messages); // Access to network.