diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml index 3deebd2fd..5d4d0d4bb 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 f5480c3ce..44e4c9092 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -38,31 +38,7 @@ bool FeedDownloader::isUpdateRunning() const { return !m_feeds.isEmpty(); } -void FeedDownloader::updateAvailableFeeds() { - for (const Feed* feed : qAsConst(m_feeds)) { - auto* cache = dynamic_cast(feed->getParentServiceRoot()); - - if (cache != nullptr) { - qDebugNN << LOGSEC_FEEDDOWNLOADER - << "Saving cache for feed with DB ID '" << feed->id() - << "' and title '" << feed->title() << "'."; - cache->saveAllCachedData(false); - } - - if (m_stopCacheSynchronization) { - qWarningNN << LOGSEC_FEEDDOWNLOADER << "Aborting cache synchronization."; - - m_stopCacheSynchronization = false; - break; - } - } - - while (!m_feeds.isEmpty()) { - updateOneFeed(m_feeds.takeFirst()); - } -} - -void FeedDownloader::synchronizeAccountCaches(const QList& caches) { +void FeedDownloader::synchronizeAccountCaches(const QList& caches, bool emit_signals) { m_isCacheSynchronizationRunning = true; for (CacheForServiceRoot* cache : caches) { @@ -80,7 +56,10 @@ void FeedDownloader::synchronizeAccountCaches(const QList& m_isCacheSynchronizationRunning = false; qDebugNN << LOGSEC_FEEDDOWNLOADER << "All caches synchronized."; - emit cachesSynchronized(); + + if (emit_signals) { + emit cachesSynchronized(); + } } void FeedDownloader::updateFeeds(const QList& feeds) { @@ -100,8 +79,81 @@ void FeedDownloader::updateFeeds(const QList& feeds) { // Job starts now. emit updateStarted(); + QSet caches; + QMultiHash feeds_per_root; - updateAvailableFeeds(); + // 1. key - account. + // 2. key - feed custom ID. + // 3. key - msg state. + QHash>> stated_messages; + + // 1. key - account. + // 2. key - label custom ID. + QHash> tagged_messages; + + for (auto* fd : feeds) { + CacheForServiceRoot* fd_cache = fd->getParentServiceRoot()->toCache(); + + if (fd_cache != nullptr) { + caches.insert(fd_cache); + } + + feeds_per_root.insert(fd->getParentServiceRoot(), fd); + } + + synchronizeAccountCaches(QList(caches.begin(), caches.end()), false); + + auto roots = feeds_per_root.uniqueKeys(); + bool is_main_thread = QThread::currentThread() == qApp->thread(); + QSqlDatabase database = is_main_thread ? + qApp->database()->driver()->connection(metaObject()->className()) : + qApp->database()->driver()->connection(QSL("feed_upd")); + + for (auto* rt : roots) { + // Obtain lists of local IDs. + if (rt->wantsBaggedIdsOfExistingMessages()) { + // Tagged messages for the account. + tagged_messages.insert(rt, DatabaseQueries::bagsOfMessages(database, rt->labelsNode()->labels())); + + QHash> per_acc_states; + + // This account has activated intelligent downloading of messages. + // Prepare bags. + auto fds = feeds_per_root.values(rt); + + for (Feed* fd : fds) { + QHash per_feed_states; + + per_feed_states.insert(ServiceRoot::BagOfMessages::Read, + DatabaseQueries::bagOfMessages(database, + ServiceRoot::BagOfMessages::Read, + fd)); + per_feed_states.insert(ServiceRoot::BagOfMessages::Unread, + DatabaseQueries::bagOfMessages(database, + ServiceRoot::BagOfMessages::Unread, + fd)); + per_feed_states.insert(ServiceRoot::BagOfMessages::Starred, + DatabaseQueries::bagOfMessages(database, + ServiceRoot::BagOfMessages::Starred, + fd)); + per_acc_states.insert(fd->customId(), per_feed_states); + } + + stated_messages.insert(rt, per_acc_states); + } + + rt->aboutToBeginFeedFetching(feeds_per_root.values(rt), + stated_messages.value(rt), + tagged_messages.value(rt)); + } + + while (!m_feeds.isEmpty()) { + auto n_f = m_feeds.takeFirst(); + + updateOneFeed(n_f, + stated_messages.value(n_f->getParentServiceRoot()).value(n_f->customId()), + tagged_messages.value(n_f->getParentServiceRoot())); + } } finalizeUpdate(); @@ -113,7 +165,9 @@ void FeedDownloader::stopRunningUpdate() { m_feedsOriginalCount = m_feedsUpdated = 0; } -void FeedDownloader::updateOneFeed(Feed* feed) { +void FeedDownloader::updateOneFeed(Feed* feed, + const QHash& stated_messages, + const QHash& tagged_messages) { qDebugNN << LOGSEC_FEEDDOWNLOADER << "Downloading new messages for feed ID '" << feed->customId() << "' URL: '" << feed->source() << "' title: '" << feed->title() << "' in thread: '" @@ -127,33 +181,7 @@ 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 tagged_messages; - - if (feed->getParentServiceRoot()->wantsBaggedIdsOfExistingMessages()) { - // This account has activated intelligent downloading of messages. - // Prepare bags. - 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()); - } - - QList msgs = feed->getParentServiceRoot()->obtainNewMessages({ feed }, + QList msgs = feed->getParentServiceRoot()->obtainNewMessages(feed, stated_messages, tagged_messages); @@ -343,7 +371,6 @@ void FeedDownloader::updateOneFeed(Feed* feed) { << QUOTE_W_SPACE_DOT(feed_ex.message()); feed->setStatus(feed_ex.feedStatus(), feed_ex.message()); - feed->getParentServiceRoot()->itemChanged({ feed }); } catch (const ApplicationException& app_ex) { @@ -353,9 +380,10 @@ void FeedDownloader::updateOneFeed(Feed* feed) { << QUOTE_W_SPACE_DOT(app_ex.message()); feed->setStatus(Feed::Status::OtherError, app_ex.message()); - feed->getParentServiceRoot()->itemChanged({ feed }); } + feed->getParentServiceRoot()->itemChanged({ feed }); + m_feedsUpdated++; qDebugNN << LOGSEC_FEEDDOWNLOADER diff --git a/src/librssguard/core/feeddownloader.h b/src/librssguard/core/feeddownloader.h index bf38e6beb..291668464 100644 --- a/src/librssguard/core/feeddownloader.h +++ b/src/librssguard/core/feeddownloader.h @@ -43,7 +43,7 @@ class FeedDownloader : public QObject { bool isCacheSynchronizationRunning() const; public slots: - void synchronizeAccountCaches(const QList& caches); + void synchronizeAccountCaches(const QList& caches, bool emit_signals); void updateFeeds(const QList& feeds); void stopRunningUpdate(); @@ -54,8 +54,9 @@ class FeedDownloader : public QObject { void updateProgress(const Feed* feed, int current, int total); private: - void updateOneFeed(Feed* feed); - void updateAvailableFeeds(); + void updateOneFeed(Feed* feed, + const QHash& stated_messages, + const QHash& tagged_messages); void finalizeUpdate(); bool m_isCacheSynchronizationRunning; diff --git a/src/librssguard/miscellaneous/feedreader.cpp b/src/librssguard/miscellaneous/feedreader.cpp index 0f90ae4f3..f1bffb680 100644 --- a/src/librssguard/miscellaneous/feedreader.cpp +++ b/src/librssguard/miscellaneous/feedreader.cpp @@ -88,7 +88,8 @@ void FeedReader::updateFeeds(const QList& feeds) { void FeedReader::synchronizeMessageData(const QList& caches) { QMetaObject::invokeMethod(m_feedDownloader, "synchronizeAccountCaches", Qt::ConnectionType::QueuedConnection, - Q_ARG(QList, caches)); + Q_ARG(QList, caches), + Q_ARG(bool, true)); } void FeedReader::initializeFeedDownloader() { diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index 940641892..d03112f22 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -315,6 +315,14 @@ bool ServiceRoot::wantsBaggedIdsOfExistingMessages() const { return false; } +void ServiceRoot::aboutToBeginFeedFetching(const QList& feeds, + const QHash>& stated_msgs, + const QHash& tagged_msgs) { + Q_UNUSED(feeds) + Q_UNUSED(stated_msgs) + Q_UNUSED(tagged_msgs) +} + void ServiceRoot::itemChanged(const QList& items) { emit dataChanged(items); } diff --git a/src/librssguard/services/abstract/serviceroot.h b/src/librssguard/services/abstract/serviceroot.h index f37401e14..224042acd 100644 --- a/src/librssguard/services/abstract/serviceroot.h +++ b/src/librssguard/services/abstract/serviceroot.h @@ -65,6 +65,9 @@ class ServiceRoot : public RootItem { virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); virtual bool wantsBaggedIdsOfExistingMessages() const; + virtual void aboutToBeginFeedFetching(const QList& feeds, + const QHash>& stated_msgs, + const QHash& tagged_msgs); // Returns list of specific actions for "Add new item" main window menu. // So typical list of returned actions could look like: @@ -101,8 +104,8 @@ class ServiceRoot : public RootItem { // Obtains list of messages. // Throws exception subclassed from ApplicationException, preferably FeedFetchException // if any problems arise. - virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + virtual QList obtainNewMessages(Feed* feed, + 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 072d45815..3fe7689b3 100755 --- a/src/librssguard/services/feedly/feedlyserviceroot.cpp +++ b/src/librssguard/services/feedly/feedlyserviceroot.cpp @@ -72,24 +72,18 @@ void FeedlyServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool()); } -QList FeedlyServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, +QList FeedlyServiceRoot::obtainNewMessages(Feed* feed, + const QHash& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) - QList messages; - - for (Feed* feed : feeds) { - try { - messages << m_network->streamContents(feed->customId()); - } - catch (const ApplicationException& ex) { - throw FeedFetchException(Feed::Status::NetworkError, ex.message()); - } + try { + return m_network->streamContents(feed->customId()); + } + catch (const ApplicationException& ex) { + throw FeedFetchException(Feed::Status::NetworkError, ex.message()); } - - return messages; } void FeedlyServiceRoot::start(bool freshly_activated) { diff --git a/src/librssguard/services/feedly/feedlyserviceroot.h b/src/librssguard/services/feedly/feedlyserviceroot.h index ed79024dd..dc92146ef 100755 --- a/src/librssguard/services/feedly/feedlyserviceroot.h +++ b/src/librssguard/services/feedly/feedlyserviceroot.h @@ -23,8 +23,8 @@ class FeedlyServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual LabelOperation supportedLabelOperations() const; virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + virtual QList obtainNewMessages(Feed* feed, + 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 27f5586d2..aa9bdb222 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.cpp +++ b/src/librssguard/services/gmail/gmailserviceroot.cpp @@ -74,22 +74,17 @@ void GmailServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->oauth()->setRedirectUrl(data["redirect_uri"].toString()); } -QList GmailServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, +QList GmailServiceRoot::obtainNewMessages(Feed* feed, + const QHash& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) - QList messages; + Feed::Status error = Feed::Status::Normal; + QList messages = network()->messages(feed->customId(), error, networkProxy()); - for (Feed* feed : feeds) { - Feed::Status error = Feed::Status::Normal; - - messages << network()->messages(feed->customId(), error, networkProxy()); - - if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError || error == Feed::Status::ParsingError) { - throw FeedFetchException(error); - } + if (error != Feed::Status::NewMessages && error != Feed::Status::Normal) { + throw FeedFetchException(error); } return messages; diff --git a/src/librssguard/services/gmail/gmailserviceroot.h b/src/librssguard/services/gmail/gmailserviceroot.h index 71a7dd94c..a6eb65d5d 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.h +++ b/src/librssguard/services/gmail/gmailserviceroot.h @@ -31,8 +31,8 @@ class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void saveAllCachedData(bool ignore_errors); virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + virtual QList obtainNewMessages(Feed* feed, + const QHash& stated_messages, const QHash& tagged_messages); protected: diff --git a/src/librssguard/services/greader/greaderserviceroot.cpp b/src/librssguard/services/greader/greaderserviceroot.cpp index 0e904400a..7e6002446 100755 --- a/src/librssguard/services/greader/greaderserviceroot.cpp +++ b/src/librssguard/services/greader/greaderserviceroot.cpp @@ -57,35 +57,29 @@ void GreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool()); } -QList GreaderServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, +QList GreaderServiceRoot::obtainNewMessages(Feed* feed, + const QHash& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) - QList messages; + Feed::Status error = Feed::Status::Normal; - for (Feed* feed : feeds) { - Feed::Status error = Feed::Status::Normal; - - 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); - } + if (true /* intelligent downloading */ ) { + return network()->getMessagesIntelligently(this, + feed->customId(), + stated_messages, + tagged_messages, + error, + networkProxy()); + } + else { + return network()->streamContents(this, feed->customId(), error, networkProxy()); } - return messages; + if (error != Feed::Status::NewMessages && error != Feed::Status::Normal) { + throw FeedFetchException(error); + } } bool GreaderServiceRoot::wantsBaggedIdsOfExistingMessages() const { diff --git a/src/librssguard/services/greader/greaderserviceroot.h b/src/librssguard/services/greader/greaderserviceroot.h index 2c22c414b..f168420e1 100755 --- a/src/librssguard/services/greader/greaderserviceroot.h +++ b/src/librssguard/services/greader/greaderserviceroot.h @@ -31,8 +31,8 @@ class GreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual LabelOperation supportedLabelOperations() const; virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + virtual QList obtainNewMessages(Feed* feed, + 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 5d19c2496..c878c432c 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp @@ -56,22 +56,17 @@ void InoreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->oauth()->setRedirectUrl(data["redirect_uri"].toString()); } -QList InoreaderServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, +QList InoreaderServiceRoot::obtainNewMessages(Feed* feed, + const QHash& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) - QList messages; + Feed::Status error = Feed::Status::Normal; + QList messages = network()->messages(this, feed->customId(), error); - for (Feed* feed : feeds) { - Feed::Status error = Feed::Status::Normal; - - messages << network()->messages(this, feed->customId(), error); - - if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError) { - throw FeedFetchException(error); - } + if (error != Feed::Status::NewMessages && error != Feed::Status::Normal) { + throw FeedFetchException(error); } return messages; diff --git a/src/librssguard/services/inoreader/inoreaderserviceroot.h b/src/librssguard/services/inoreader/inoreaderserviceroot.h index 939f7da3a..dbba2b569 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.h +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.h @@ -29,8 +29,8 @@ class InoreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void saveAllCachedData(bool ignore_errors); virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + virtual QList obtainNewMessages(Feed* feed, + 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 ad4aff717..a30f1e3c5 100644 --- a/src/librssguard/services/owncloud/owncloudserviceroot.cpp +++ b/src/librssguard/services/owncloud/owncloudserviceroot.cpp @@ -150,24 +150,18 @@ void OwnCloudServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool()); } -QList OwnCloudServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, +QList OwnCloudServiceRoot::obtainNewMessages(Feed* feed, + const QHash& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) - QList msgs; + OwnCloudGetMessagesResponse messages = network()->getMessages(feed->customNumericId(), networkProxy()); - for (Feed* feed : feeds) { - OwnCloudGetMessagesResponse messages = network()->getMessages(feed->customNumericId(), networkProxy()); - - if (messages.networkError() != QNetworkReply::NetworkError::NoError) { - throw FeedFetchException(Feed::Status::NetworkError); - } - else { - msgs << messages.messages(); - } + if (messages.networkError() != QNetworkReply::NetworkError::NoError) { + throw FeedFetchException(Feed::Status::NetworkError); + } + else { + return messages.messages(); } - - return msgs; } diff --git a/src/librssguard/services/owncloud/owncloudserviceroot.h b/src/librssguard/services/owncloud/owncloudserviceroot.h index 5a15fc61d..9f3838c55 100644 --- a/src/librssguard/services/owncloud/owncloudserviceroot.h +++ b/src/librssguard/services/owncloud/owncloudserviceroot.h @@ -28,8 +28,8 @@ class OwnCloudServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void saveAllCachedData(bool ignore_errors); virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + virtual QList obtainNewMessages(Feed* feed, + 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 75bf4abbb..01cecb01b 100644 --- a/src/librssguard/services/standard/standardserviceroot.cpp +++ b/src/librssguard/services/standard/standardserviceroot.cpp @@ -144,134 +144,128 @@ Qt::ItemFlags StandardServiceRoot::additionalFlags() const { return Qt::ItemFlag::ItemIsDropEnabled; } -QList StandardServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, +QList StandardServiceRoot::obtainNewMessages(Feed* feed, + const QHash& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) - QList msgs; + StandardFeed* f = static_cast(feed); + QString formatted_feed_contents; + int download_timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt(); - for (Feed* f : feeds) { - StandardFeed* feed = static_cast(f); - QString formatted_feed_contents; - int download_timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt(); + if (f->sourceType() == StandardFeed::SourceType::Url) { + qDebugNN << LOGSEC_CORE + << "Downloading URL" + << QUOTE_W_SPACE(feed->source()) + << "to obtain feed data."; - if (feed->sourceType() == StandardFeed::SourceType::Url) { - qDebugNN << LOGSEC_CORE - << "Downloading URL" - << QUOTE_W_SPACE(feed->source()) - << "to obtain feed data."; + QByteArray feed_contents; + QList> headers; - QByteArray feed_contents; - QList> headers; + headers << NetworkFactory::generateBasicAuthHeader(f->username(), f->password()); - headers << NetworkFactory::generateBasicAuthHeader(feed->username(), feed->password()); + auto network_result = NetworkFactory::performNetworkOperation(feed->source(), + download_timeout, + {}, + feed_contents, + QNetworkAccessManager::Operation::GetOperation, + headers, + false, + {}, + {}, + networkProxy()).first; - auto network_result = NetworkFactory::performNetworkOperation(feed->source(), - download_timeout, - {}, - feed_contents, - QNetworkAccessManager::Operation::GetOperation, - headers, - false, - {}, - {}, - networkProxy()).first; + if (network_result != QNetworkReply::NetworkError::NoError) { + qWarningNN << LOGSEC_CORE + << "Error" + << QUOTE_W_SPACE(network_result) + << "during fetching of new messages for feed" + << QUOTE_W_SPACE_DOT(feed->source()); + throw FeedFetchException(Feed::Status::NetworkError, NetworkFactory::networkErrorText(network_result)); + } - if (network_result != QNetworkReply::NetworkError::NoError) { - qWarningNN << LOGSEC_CORE - << "Error" - << QUOTE_W_SPACE(network_result) - << "during fetching of new messages for feed" - << QUOTE_W_SPACE_DOT(feed->source()); - throw FeedFetchException(Feed::Status::NetworkError, NetworkFactory::networkErrorText(network_result)); - } + // Encode downloaded data for further parsing. + QTextCodec* codec = QTextCodec::codecForName(f->encoding().toLocal8Bit()); - // Encode downloaded data for further parsing. - QTextCodec* codec = QTextCodec::codecForName(feed->encoding().toLocal8Bit()); - - if (codec == nullptr) { - // No suitable codec for this encoding was found. - // Use non-converted data. - formatted_feed_contents = feed_contents; - } - else { - formatted_feed_contents = codec->toUnicode(feed_contents); - } + if (codec == nullptr) { + // No suitable codec for this encoding was found. + // Use non-converted data. + formatted_feed_contents = feed_contents; } else { - qDebugNN << LOGSEC_CORE - << "Running custom script" - << QUOTE_W_SPACE(feed->source()) - << "to obtain feed data."; - - // Use script to generate feed file. - try { - formatted_feed_contents = StandardFeed::generateFeedFileWithScript(feed->source(), download_timeout); - } - catch (const ScriptException& ex) { - qCriticalNN << LOGSEC_CORE - << "Custom script for generating feed file failed:" - << QUOTE_W_SPACE_DOT(ex.message()); - - throw FeedFetchException(Feed::Status::OtherError, ex.message()); - } + formatted_feed_contents = codec->toUnicode(feed_contents); } + } + else { + qDebugNN << LOGSEC_CORE + << "Running custom script" + << QUOTE_W_SPACE(feed->source()) + << "to obtain feed data."; - if (!feed->postProcessScript().simplified().isEmpty()) { - qDebugNN << LOGSEC_CORE - << "We will process feed data with post-process script" - << QUOTE_W_SPACE_DOT(feed->postProcessScript()); - - try { - formatted_feed_contents = StandardFeed::postProcessFeedFileWithScript(feed->postProcessScript(), - formatted_feed_contents, - download_timeout); - } - catch (const ScriptException& ex) { - qCriticalNN << LOGSEC_CORE - << "Post-processing script for feed file failed:" - << QUOTE_W_SPACE_DOT(ex.message()); - - throw FeedFetchException(Feed::Status::OtherError, ex.message()); - } + // Use script to generate feed file. + try { + formatted_feed_contents = StandardFeed::generateFeedFileWithScript(feed->source(), download_timeout); } + catch (const ScriptException& ex) { + qCriticalNN << LOGSEC_CORE + << "Custom script for generating feed file failed:" + << QUOTE_W_SPACE_DOT(ex.message()); - // Feed data are downloaded and encoded. - // Parse data and obtain messages. - QList messages; - - switch (feed->type()) { - case StandardFeed::Type::Rss0X: - case StandardFeed::Type::Rss2X: - messages = RssParser(formatted_feed_contents).messages(); - break; - - case StandardFeed::Type::Rdf: - messages = RdfParser(formatted_feed_contents).messages(); - break; - - case StandardFeed::Type::Atom10: - messages = AtomParser(formatted_feed_contents).messages(); - break; - - case StandardFeed::Type::Json: - messages = JsonParser(formatted_feed_contents).messages(); - break; - - default: - break; + throw FeedFetchException(Feed::Status::OtherError, ex.message()); } - - for (Message& mess : messages) { - mess.m_feedId = f->customId(); - } - - msgs << messages; } - return msgs; + if (!f->postProcessScript().simplified().isEmpty()) { + qDebugNN << LOGSEC_CORE + << "We will process feed data with post-process script" + << QUOTE_W_SPACE_DOT(f->postProcessScript()); + + try { + formatted_feed_contents = StandardFeed::postProcessFeedFileWithScript(f->postProcessScript(), + formatted_feed_contents, + download_timeout); + } + catch (const ScriptException& ex) { + qCriticalNN << LOGSEC_CORE + << "Post-processing script for feed file failed:" + << QUOTE_W_SPACE_DOT(ex.message()); + + throw FeedFetchException(Feed::Status::OtherError, ex.message()); + } + } + + // Feed data are downloaded and encoded. + // Parse data and obtain messages. + QList messages; + + switch (f->type()) { + case StandardFeed::Type::Rss0X: + case StandardFeed::Type::Rss2X: + messages = RssParser(formatted_feed_contents).messages(); + break; + + case StandardFeed::Type::Rdf: + messages = RdfParser(formatted_feed_contents).messages(); + break; + + case StandardFeed::Type::Atom10: + messages = AtomParser(formatted_feed_contents).messages(); + break; + + case StandardFeed::Type::Json: + messages = JsonParser(formatted_feed_contents).messages(); + break; + + default: + break; + } + + for (Message& mess : messages) { + mess.m_feedId = feed->customId(); + } + + return messages; } QList StandardServiceRoot::getContextMenuForFeed(StandardFeed* feed) { diff --git a/src/librssguard/services/standard/standardserviceroot.h b/src/librssguard/services/standard/standardserviceroot.h index b1912fdc4..35e03868b 100644 --- a/src/librssguard/services/standard/standardserviceroot.h +++ b/src/librssguard/services/standard/standardserviceroot.h @@ -32,8 +32,8 @@ class StandardServiceRoot : public ServiceRoot { virtual bool supportsFeedAdding() const; virtual bool supportsCategoryAdding() const; virtual Qt::ItemFlags additionalFlags() const; - virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + virtual QList obtainNewMessages(Feed* feed, + 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 baa5cb6e7..222218710 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp @@ -214,38 +214,35 @@ void TtRssServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool()); } -QList TtRssServiceRoot::obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, +QList TtRssServiceRoot::obtainNewMessages(Feed* feed, + const QHash& stated_messages, const QHash& tagged_messages) { Q_UNUSED(stated_messages) Q_UNUSED(tagged_messages) QList messages; + int newly_added_messages = 0; + int limit = network()->batchSize() <= 0 ? TTRSS_MAX_MESSAGES : network()->batchSize(); + int skip = 0; - for (Feed* feed : feeds) { - int newly_added_messages = 0; - int limit = network()->batchSize() <= 0 ? TTRSS_MAX_MESSAGES : network()->batchSize(); - int skip = 0; + do { + TtRssGetHeadlinesResponse headlines = network()->getHeadlines(feed->customNumericId(), limit, skip, + true, true, false, + network()->downloadOnlyUnreadMessages(), + networkProxy()); - do { - TtRssGetHeadlinesResponse headlines = network()->getHeadlines(feed->customNumericId(), limit, skip, - true, true, false, - network()->downloadOnlyUnreadMessages(), - networkProxy()); - - if (network()->lastError() != QNetworkReply::NetworkError::NoError) { - throw FeedFetchException(Feed::Status::NetworkError, headlines.error()); - } - else { - QList new_messages = headlines.messages(this); - - messages << new_messages; - newly_added_messages = new_messages.size(); - skip += newly_added_messages; - } + if (network()->lastError() != QNetworkReply::NetworkError::NoError) { + throw FeedFetchException(Feed::Status::NetworkError, headlines.error()); + } + else { + QList new_messages = headlines.messages(this); + + messages << new_messages; + newly_added_messages = new_messages.size(); + skip += newly_added_messages; } - while (newly_added_messages > 0 && (network()->batchSize() <= 0 || messages.size() < network()->batchSize())); } + while (newly_added_messages > 0 && (network()->batchSize() <= 0 || messages.size() < network()->batchSize())); return messages; } diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.h b/src/librssguard/services/tt-rss/ttrssserviceroot.h index 195e82f9c..866c0791a 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.h +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.h @@ -33,8 +33,8 @@ class TtRssServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void saveAllCachedData(bool ignore_errors); virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, - const QHash>& stated_messages, + virtual QList obtainNewMessages(Feed* feed, + const QHash& stated_messages, const QHash& tagged_messages); // Access to network.