preload all local IDs, fix feedslist item reloading upon feed fetching, add handler to allow plugins to perform plugin-wide feed fetching befor individual feeds are fetched
This commit is contained in:
parent
dfc28bcd4e
commit
79827ad6af
@ -30,7 +30,7 @@
|
|||||||
<url type="donation">https://martinrotter.github.io/donate/</url>
|
<url type="donation">https://martinrotter.github.io/donate/</url>
|
||||||
<content_rating type="oars-1.1" />
|
<content_rating type="oars-1.1" />
|
||||||
<releases>
|
<releases>
|
||||||
<release version="3.9.2" date="2021-07-28"/>
|
<release version="3.9.2" date="2021-07-30"/>
|
||||||
</releases>
|
</releases>
|
||||||
<content_rating type="oars-1.0">
|
<content_rating type="oars-1.0">
|
||||||
<content_attribute id="violence-cartoon">none</content_attribute>
|
<content_attribute id="violence-cartoon">none</content_attribute>
|
||||||
|
@ -38,31 +38,7 @@ bool FeedDownloader::isUpdateRunning() const {
|
|||||||
return !m_feeds.isEmpty();
|
return !m_feeds.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedDownloader::updateAvailableFeeds() {
|
void FeedDownloader::synchronizeAccountCaches(const QList<CacheForServiceRoot*>& caches, bool emit_signals) {
|
||||||
for (const Feed* feed : qAsConst(m_feeds)) {
|
|
||||||
auto* cache = dynamic_cast<CacheForServiceRoot*>(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<CacheForServiceRoot*>& caches) {
|
|
||||||
m_isCacheSynchronizationRunning = true;
|
m_isCacheSynchronizationRunning = true;
|
||||||
|
|
||||||
for (CacheForServiceRoot* cache : caches) {
|
for (CacheForServiceRoot* cache : caches) {
|
||||||
@ -80,7 +56,10 @@ void FeedDownloader::synchronizeAccountCaches(const QList<CacheForServiceRoot*>&
|
|||||||
|
|
||||||
m_isCacheSynchronizationRunning = false;
|
m_isCacheSynchronizationRunning = false;
|
||||||
qDebugNN << LOGSEC_FEEDDOWNLOADER << "All caches synchronized.";
|
qDebugNN << LOGSEC_FEEDDOWNLOADER << "All caches synchronized.";
|
||||||
|
|
||||||
|
if (emit_signals) {
|
||||||
emit cachesSynchronized();
|
emit cachesSynchronized();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
|
void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
|
||||||
@ -100,8 +79,81 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
|
|||||||
|
|
||||||
// Job starts now.
|
// Job starts now.
|
||||||
emit updateStarted();
|
emit updateStarted();
|
||||||
|
QSet<CacheForServiceRoot*> caches;
|
||||||
|
QMultiHash<ServiceRoot*, Feed*> feeds_per_root;
|
||||||
|
|
||||||
updateAvailableFeeds();
|
// 1. key - account.
|
||||||
|
// 2. key - feed custom ID.
|
||||||
|
// 3. key - msg state.
|
||||||
|
QHash<ServiceRoot*, QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>> stated_messages;
|
||||||
|
|
||||||
|
// 1. key - account.
|
||||||
|
// 2. key - label custom ID.
|
||||||
|
QHash<ServiceRoot*, QHash<QString, QStringList>> 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<CacheForServiceRoot*>(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<QString, QHash<ServiceRoot::BagOfMessages, QStringList>> 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<ServiceRoot::BagOfMessages, QStringList> 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();
|
finalizeUpdate();
|
||||||
@ -113,7 +165,9 @@ void FeedDownloader::stopRunningUpdate() {
|
|||||||
m_feedsOriginalCount = m_feedsUpdated = 0;
|
m_feedsOriginalCount = m_feedsUpdated = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedDownloader::updateOneFeed(Feed* feed) {
|
void FeedDownloader::updateOneFeed(Feed* feed,
|
||||||
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
|
const QHash<QString, QStringList>& tagged_messages) {
|
||||||
qDebugNN << LOGSEC_FEEDDOWNLOADER
|
qDebugNN << LOGSEC_FEEDDOWNLOADER
|
||||||
<< "Downloading new messages for feed ID '"
|
<< "Downloading new messages for feed ID '"
|
||||||
<< feed->customId() << "' URL: '" << feed->source() << "' title: '" << feed->title() << "' in thread: '"
|
<< feed->customId() << "' URL: '" << feed->source() << "' title: '" << feed->title() << "' in thread: '"
|
||||||
@ -127,33 +181,7 @@ void FeedDownloader::updateOneFeed(Feed* feed) {
|
|||||||
QSqlDatabase database = is_main_thread ?
|
QSqlDatabase database = is_main_thread ?
|
||||||
qApp->database()->driver()->connection(metaObject()->className()) :
|
qApp->database()->driver()->connection(metaObject()->className()) :
|
||||||
qApp->database()->driver()->connection(QSL("feed_upd"));
|
qApp->database()->driver()->connection(QSL("feed_upd"));
|
||||||
QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>> stated_messages;
|
QList<Message> msgs = feed->getParentServiceRoot()->obtainNewMessages(feed,
|
||||||
QHash<QString, QStringList> tagged_messages;
|
|
||||||
|
|
||||||
if (feed->getParentServiceRoot()->wantsBaggedIdsOfExistingMessages()) {
|
|
||||||
// This account has activated intelligent downloading of messages.
|
|
||||||
// Prepare bags.
|
|
||||||
QHash<ServiceRoot::BagOfMessages, QStringList> 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<Message> msgs = feed->getParentServiceRoot()->obtainNewMessages({ feed },
|
|
||||||
stated_messages,
|
stated_messages,
|
||||||
tagged_messages);
|
tagged_messages);
|
||||||
|
|
||||||
@ -343,7 +371,6 @@ void FeedDownloader::updateOneFeed(Feed* feed) {
|
|||||||
<< QUOTE_W_SPACE_DOT(feed_ex.message());
|
<< QUOTE_W_SPACE_DOT(feed_ex.message());
|
||||||
|
|
||||||
feed->setStatus(feed_ex.feedStatus(), feed_ex.message());
|
feed->setStatus(feed_ex.feedStatus(), feed_ex.message());
|
||||||
feed->getParentServiceRoot()->itemChanged({ feed });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (const ApplicationException& app_ex) {
|
catch (const ApplicationException& app_ex) {
|
||||||
@ -353,9 +380,10 @@ void FeedDownloader::updateOneFeed(Feed* feed) {
|
|||||||
<< QUOTE_W_SPACE_DOT(app_ex.message());
|
<< QUOTE_W_SPACE_DOT(app_ex.message());
|
||||||
|
|
||||||
feed->setStatus(Feed::Status::OtherError, app_ex.message());
|
feed->setStatus(Feed::Status::OtherError, app_ex.message());
|
||||||
feed->getParentServiceRoot()->itemChanged({ feed });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
feed->getParentServiceRoot()->itemChanged({ feed });
|
||||||
|
|
||||||
m_feedsUpdated++;
|
m_feedsUpdated++;
|
||||||
|
|
||||||
qDebugNN << LOGSEC_FEEDDOWNLOADER
|
qDebugNN << LOGSEC_FEEDDOWNLOADER
|
||||||
|
@ -43,7 +43,7 @@ class FeedDownloader : public QObject {
|
|||||||
bool isCacheSynchronizationRunning() const;
|
bool isCacheSynchronizationRunning() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void synchronizeAccountCaches(const QList<CacheForServiceRoot*>& caches);
|
void synchronizeAccountCaches(const QList<CacheForServiceRoot*>& caches, bool emit_signals);
|
||||||
void updateFeeds(const QList<Feed*>& feeds);
|
void updateFeeds(const QList<Feed*>& feeds);
|
||||||
void stopRunningUpdate();
|
void stopRunningUpdate();
|
||||||
|
|
||||||
@ -54,8 +54,9 @@ class FeedDownloader : public QObject {
|
|||||||
void updateProgress(const Feed* feed, int current, int total);
|
void updateProgress(const Feed* feed, int current, int total);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateOneFeed(Feed* feed);
|
void updateOneFeed(Feed* feed,
|
||||||
void updateAvailableFeeds();
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
|
const QHash<QString, QStringList>& tagged_messages);
|
||||||
void finalizeUpdate();
|
void finalizeUpdate();
|
||||||
|
|
||||||
bool m_isCacheSynchronizationRunning;
|
bool m_isCacheSynchronizationRunning;
|
||||||
|
@ -88,7 +88,8 @@ void FeedReader::updateFeeds(const QList<Feed*>& feeds) {
|
|||||||
void FeedReader::synchronizeMessageData(const QList<CacheForServiceRoot*>& caches) {
|
void FeedReader::synchronizeMessageData(const QList<CacheForServiceRoot*>& caches) {
|
||||||
QMetaObject::invokeMethod(m_feedDownloader, "synchronizeAccountCaches",
|
QMetaObject::invokeMethod(m_feedDownloader, "synchronizeAccountCaches",
|
||||||
Qt::ConnectionType::QueuedConnection,
|
Qt::ConnectionType::QueuedConnection,
|
||||||
Q_ARG(QList<CacheForServiceRoot*>, caches));
|
Q_ARG(QList<CacheForServiceRoot*>, caches),
|
||||||
|
Q_ARG(bool, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedReader::initializeFeedDownloader() {
|
void FeedReader::initializeFeedDownloader() {
|
||||||
|
@ -315,6 +315,14 @@ bool ServiceRoot::wantsBaggedIdsOfExistingMessages() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServiceRoot::aboutToBeginFeedFetching(const QList<Feed*>& feeds,
|
||||||
|
const QHash<QString, QHash<BagOfMessages, QStringList>>& stated_msgs,
|
||||||
|
const QHash<QString, QStringList>& tagged_msgs) {
|
||||||
|
Q_UNUSED(feeds)
|
||||||
|
Q_UNUSED(stated_msgs)
|
||||||
|
Q_UNUSED(tagged_msgs)
|
||||||
|
}
|
||||||
|
|
||||||
void ServiceRoot::itemChanged(const QList<RootItem*>& items) {
|
void ServiceRoot::itemChanged(const QList<RootItem*>& items) {
|
||||||
emit dataChanged(items);
|
emit dataChanged(items);
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,9 @@ class ServiceRoot : public RootItem {
|
|||||||
virtual QVariantHash customDatabaseData() const;
|
virtual QVariantHash customDatabaseData() const;
|
||||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||||
virtual bool wantsBaggedIdsOfExistingMessages() const;
|
virtual bool wantsBaggedIdsOfExistingMessages() const;
|
||||||
|
virtual void aboutToBeginFeedFetching(const QList<Feed*>& feeds,
|
||||||
|
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_msgs,
|
||||||
|
const QHash<QString, QStringList>& tagged_msgs);
|
||||||
|
|
||||||
// Returns list of specific actions for "Add new item" main window menu.
|
// Returns list of specific actions for "Add new item" main window menu.
|
||||||
// So typical list of returned actions could look like:
|
// So typical list of returned actions could look like:
|
||||||
@ -101,8 +104,8 @@ class ServiceRoot : public RootItem {
|
|||||||
// Obtains list of messages.
|
// Obtains list of messages.
|
||||||
// Throws exception subclassed from ApplicationException, preferably FeedFetchException
|
// Throws exception subclassed from ApplicationException, preferably FeedFetchException
|
||||||
// if any problems arise.
|
// if any problems arise.
|
||||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
virtual QList<Message> obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages) = 0;
|
const QHash<QString, QStringList>& tagged_messages) = 0;
|
||||||
|
|
||||||
// This method should prepare messages for given "item" (download them maybe?)
|
// This method should prepare messages for given "item" (download them maybe?)
|
||||||
|
@ -72,24 +72,18 @@ void FeedlyServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
|||||||
m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool());
|
m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Message> FeedlyServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
QList<Message> FeedlyServiceRoot::obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages) {
|
const QHash<QString, QStringList>& tagged_messages) {
|
||||||
Q_UNUSED(stated_messages)
|
Q_UNUSED(stated_messages)
|
||||||
Q_UNUSED(tagged_messages)
|
Q_UNUSED(tagged_messages)
|
||||||
|
|
||||||
QList<Message> messages;
|
|
||||||
|
|
||||||
for (Feed* feed : feeds) {
|
|
||||||
try {
|
try {
|
||||||
messages << m_network->streamContents(feed->customId());
|
return m_network->streamContents(feed->customId());
|
||||||
}
|
}
|
||||||
catch (const ApplicationException& ex) {
|
catch (const ApplicationException& ex) {
|
||||||
throw FeedFetchException(Feed::Status::NetworkError, ex.message());
|
throw FeedFetchException(Feed::Status::NetworkError, ex.message());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return messages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedlyServiceRoot::start(bool freshly_activated) {
|
void FeedlyServiceRoot::start(bool freshly_activated) {
|
||||||
|
@ -23,8 +23,8 @@ class FeedlyServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
|||||||
virtual LabelOperation supportedLabelOperations() const;
|
virtual LabelOperation supportedLabelOperations() const;
|
||||||
virtual QVariantHash customDatabaseData() const;
|
virtual QVariantHash customDatabaseData() const;
|
||||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
virtual QList<Message> obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages);
|
const QHash<QString, QStringList>& tagged_messages);
|
||||||
|
|
||||||
FeedlyNetwork* network() const;
|
FeedlyNetwork* network() const;
|
||||||
|
@ -74,23 +74,18 @@ void GmailServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
|||||||
m_network->oauth()->setRedirectUrl(data["redirect_uri"].toString());
|
m_network->oauth()->setRedirectUrl(data["redirect_uri"].toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Message> GmailServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
QList<Message> GmailServiceRoot::obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages) {
|
const QHash<QString, QStringList>& tagged_messages) {
|
||||||
Q_UNUSED(stated_messages)
|
Q_UNUSED(stated_messages)
|
||||||
Q_UNUSED(tagged_messages)
|
Q_UNUSED(tagged_messages)
|
||||||
|
|
||||||
QList<Message> messages;
|
|
||||||
|
|
||||||
for (Feed* feed : feeds) {
|
|
||||||
Feed::Status error = Feed::Status::Normal;
|
Feed::Status error = Feed::Status::Normal;
|
||||||
|
QList<Message> messages = network()->messages(feed->customId(), error, networkProxy());
|
||||||
|
|
||||||
messages << network()->messages(feed->customId(), error, networkProxy());
|
if (error != Feed::Status::NewMessages && error != Feed::Status::Normal) {
|
||||||
|
|
||||||
if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError || error == Feed::Status::ParsingError) {
|
|
||||||
throw FeedFetchException(error);
|
throw FeedFetchException(error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@ class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
|||||||
virtual void saveAllCachedData(bool ignore_errors);
|
virtual void saveAllCachedData(bool ignore_errors);
|
||||||
virtual QVariantHash customDatabaseData() const;
|
virtual QVariantHash customDatabaseData() const;
|
||||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
virtual QList<Message> obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages);
|
const QHash<QString, QStringList>& tagged_messages);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -57,35 +57,29 @@ void GreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
|||||||
m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool());
|
m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Message> GreaderServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
QList<Message> GreaderServiceRoot::obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages) {
|
const QHash<QString, QStringList>& tagged_messages) {
|
||||||
Q_UNUSED(stated_messages)
|
Q_UNUSED(stated_messages)
|
||||||
Q_UNUSED(tagged_messages)
|
Q_UNUSED(tagged_messages)
|
||||||
|
|
||||||
QList<Message> messages;
|
|
||||||
|
|
||||||
for (Feed* feed : feeds) {
|
|
||||||
Feed::Status error = Feed::Status::Normal;
|
Feed::Status error = Feed::Status::Normal;
|
||||||
|
|
||||||
if (true /* intelligent downloading */ ) {
|
if (true /* intelligent downloading */ ) {
|
||||||
messages << network()->getMessagesIntelligently(this,
|
return network()->getMessagesIntelligently(this,
|
||||||
feed->customId(),
|
feed->customId(),
|
||||||
stated_messages.value(feed->customId()),
|
stated_messages,
|
||||||
tagged_messages,
|
tagged_messages,
|
||||||
error,
|
error,
|
||||||
networkProxy());
|
networkProxy());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
messages << network()->streamContents(this, feed->customId(), error, networkProxy());
|
return network()->streamContents(this, feed->customId(), error, networkProxy());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError) {
|
if (error != Feed::Status::NewMessages && error != Feed::Status::Normal) {
|
||||||
throw FeedFetchException(error);
|
throw FeedFetchException(error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return messages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GreaderServiceRoot::wantsBaggedIdsOfExistingMessages() const {
|
bool GreaderServiceRoot::wantsBaggedIdsOfExistingMessages() const {
|
||||||
|
@ -31,8 +31,8 @@ class GreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
|||||||
virtual LabelOperation supportedLabelOperations() const;
|
virtual LabelOperation supportedLabelOperations() const;
|
||||||
virtual QVariantHash customDatabaseData() const;
|
virtual QVariantHash customDatabaseData() const;
|
||||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
virtual QList<Message> obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages);
|
const QHash<QString, QStringList>& tagged_messages);
|
||||||
virtual bool wantsBaggedIdsOfExistingMessages() const;
|
virtual bool wantsBaggedIdsOfExistingMessages() const;
|
||||||
|
|
||||||
|
@ -56,23 +56,18 @@ void InoreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
|||||||
m_network->oauth()->setRedirectUrl(data["redirect_uri"].toString());
|
m_network->oauth()->setRedirectUrl(data["redirect_uri"].toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Message> InoreaderServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
QList<Message> InoreaderServiceRoot::obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages) {
|
const QHash<QString, QStringList>& tagged_messages) {
|
||||||
Q_UNUSED(stated_messages)
|
Q_UNUSED(stated_messages)
|
||||||
Q_UNUSED(tagged_messages)
|
Q_UNUSED(tagged_messages)
|
||||||
|
|
||||||
QList<Message> messages;
|
|
||||||
|
|
||||||
for (Feed* feed : feeds) {
|
|
||||||
Feed::Status error = Feed::Status::Normal;
|
Feed::Status error = Feed::Status::Normal;
|
||||||
|
QList<Message> messages = network()->messages(this, feed->customId(), error);
|
||||||
|
|
||||||
messages << network()->messages(this, feed->customId(), error);
|
if (error != Feed::Status::NewMessages && error != Feed::Status::Normal) {
|
||||||
|
|
||||||
if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError) {
|
|
||||||
throw FeedFetchException(error);
|
throw FeedFetchException(error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ class InoreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
|||||||
virtual void saveAllCachedData(bool ignore_errors);
|
virtual void saveAllCachedData(bool ignore_errors);
|
||||||
virtual QVariantHash customDatabaseData() const;
|
virtual QVariantHash customDatabaseData() const;
|
||||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
virtual QList<Message> obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages);
|
const QHash<QString, QStringList>& tagged_messages);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -150,24 +150,18 @@ void OwnCloudServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
|||||||
m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool());
|
m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Message> OwnCloudServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
QList<Message> OwnCloudServiceRoot::obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages) {
|
const QHash<QString, QStringList>& tagged_messages) {
|
||||||
Q_UNUSED(stated_messages)
|
Q_UNUSED(stated_messages)
|
||||||
Q_UNUSED(tagged_messages)
|
Q_UNUSED(tagged_messages)
|
||||||
|
|
||||||
QList<Message> msgs;
|
|
||||||
|
|
||||||
for (Feed* feed : feeds) {
|
|
||||||
OwnCloudGetMessagesResponse messages = network()->getMessages(feed->customNumericId(), networkProxy());
|
OwnCloudGetMessagesResponse messages = network()->getMessages(feed->customNumericId(), networkProxy());
|
||||||
|
|
||||||
if (messages.networkError() != QNetworkReply::NetworkError::NoError) {
|
if (messages.networkError() != QNetworkReply::NetworkError::NoError) {
|
||||||
throw FeedFetchException(Feed::Status::NetworkError);
|
throw FeedFetchException(Feed::Status::NetworkError);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msgs << messages.messages();
|
return messages.messages();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return msgs;
|
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ class OwnCloudServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
|||||||
virtual void saveAllCachedData(bool ignore_errors);
|
virtual void saveAllCachedData(bool ignore_errors);
|
||||||
virtual QVariantHash customDatabaseData() const;
|
virtual QVariantHash customDatabaseData() const;
|
||||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
virtual QList<Message> obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages);
|
const QHash<QString, QStringList>& tagged_messages);
|
||||||
|
|
||||||
OwnCloudNetworkFactory* network() const;
|
OwnCloudNetworkFactory* network() const;
|
||||||
|
@ -144,20 +144,17 @@ Qt::ItemFlags StandardServiceRoot::additionalFlags() const {
|
|||||||
return Qt::ItemFlag::ItemIsDropEnabled;
|
return Qt::ItemFlag::ItemIsDropEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Message> StandardServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
QList<Message> StandardServiceRoot::obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages) {
|
const QHash<QString, QStringList>& tagged_messages) {
|
||||||
Q_UNUSED(stated_messages)
|
Q_UNUSED(stated_messages)
|
||||||
Q_UNUSED(tagged_messages)
|
Q_UNUSED(tagged_messages)
|
||||||
|
|
||||||
QList<Message> msgs;
|
StandardFeed* f = static_cast<StandardFeed*>(feed);
|
||||||
|
|
||||||
for (Feed* f : feeds) {
|
|
||||||
StandardFeed* feed = static_cast<StandardFeed*>(f);
|
|
||||||
QString formatted_feed_contents;
|
QString formatted_feed_contents;
|
||||||
int download_timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
int download_timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||||
|
|
||||||
if (feed->sourceType() == StandardFeed::SourceType::Url) {
|
if (f->sourceType() == StandardFeed::SourceType::Url) {
|
||||||
qDebugNN << LOGSEC_CORE
|
qDebugNN << LOGSEC_CORE
|
||||||
<< "Downloading URL"
|
<< "Downloading URL"
|
||||||
<< QUOTE_W_SPACE(feed->source())
|
<< QUOTE_W_SPACE(feed->source())
|
||||||
@ -166,7 +163,7 @@ QList<Message> StandardServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
|||||||
QByteArray feed_contents;
|
QByteArray feed_contents;
|
||||||
QList<QPair<QByteArray, QByteArray>> headers;
|
QList<QPair<QByteArray, QByteArray>> headers;
|
||||||
|
|
||||||
headers << NetworkFactory::generateBasicAuthHeader(feed->username(), feed->password());
|
headers << NetworkFactory::generateBasicAuthHeader(f->username(), f->password());
|
||||||
|
|
||||||
auto network_result = NetworkFactory::performNetworkOperation(feed->source(),
|
auto network_result = NetworkFactory::performNetworkOperation(feed->source(),
|
||||||
download_timeout,
|
download_timeout,
|
||||||
@ -189,7 +186,7 @@ QList<Message> StandardServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Encode downloaded data for further parsing.
|
// Encode downloaded data for further parsing.
|
||||||
QTextCodec* codec = QTextCodec::codecForName(feed->encoding().toLocal8Bit());
|
QTextCodec* codec = QTextCodec::codecForName(f->encoding().toLocal8Bit());
|
||||||
|
|
||||||
if (codec == nullptr) {
|
if (codec == nullptr) {
|
||||||
// No suitable codec for this encoding was found.
|
// No suitable codec for this encoding was found.
|
||||||
@ -219,13 +216,13 @@ QList<Message> StandardServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!feed->postProcessScript().simplified().isEmpty()) {
|
if (!f->postProcessScript().simplified().isEmpty()) {
|
||||||
qDebugNN << LOGSEC_CORE
|
qDebugNN << LOGSEC_CORE
|
||||||
<< "We will process feed data with post-process script"
|
<< "We will process feed data with post-process script"
|
||||||
<< QUOTE_W_SPACE_DOT(feed->postProcessScript());
|
<< QUOTE_W_SPACE_DOT(f->postProcessScript());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
formatted_feed_contents = StandardFeed::postProcessFeedFileWithScript(feed->postProcessScript(),
|
formatted_feed_contents = StandardFeed::postProcessFeedFileWithScript(f->postProcessScript(),
|
||||||
formatted_feed_contents,
|
formatted_feed_contents,
|
||||||
download_timeout);
|
download_timeout);
|
||||||
}
|
}
|
||||||
@ -242,7 +239,7 @@ QList<Message> StandardServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
|||||||
// Parse data and obtain messages.
|
// Parse data and obtain messages.
|
||||||
QList<Message> messages;
|
QList<Message> messages;
|
||||||
|
|
||||||
switch (feed->type()) {
|
switch (f->type()) {
|
||||||
case StandardFeed::Type::Rss0X:
|
case StandardFeed::Type::Rss0X:
|
||||||
case StandardFeed::Type::Rss2X:
|
case StandardFeed::Type::Rss2X:
|
||||||
messages = RssParser(formatted_feed_contents).messages();
|
messages = RssParser(formatted_feed_contents).messages();
|
||||||
@ -265,13 +262,10 @@ QList<Message> StandardServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Message& mess : messages) {
|
for (Message& mess : messages) {
|
||||||
mess.m_feedId = f->customId();
|
mess.m_feedId = feed->customId();
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs << messages;
|
return messages;
|
||||||
}
|
|
||||||
|
|
||||||
return msgs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QAction*> StandardServiceRoot::getContextMenuForFeed(StandardFeed* feed) {
|
QList<QAction*> StandardServiceRoot::getContextMenuForFeed(StandardFeed* feed) {
|
||||||
|
@ -32,8 +32,8 @@ class StandardServiceRoot : public ServiceRoot {
|
|||||||
virtual bool supportsFeedAdding() const;
|
virtual bool supportsFeedAdding() const;
|
||||||
virtual bool supportsCategoryAdding() const;
|
virtual bool supportsCategoryAdding() const;
|
||||||
virtual Qt::ItemFlags additionalFlags() const;
|
virtual Qt::ItemFlags additionalFlags() const;
|
||||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
virtual QList<Message> obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages);
|
const QHash<QString, QStringList>& tagged_messages);
|
||||||
|
|
||||||
QList<QAction*> serviceMenu();
|
QList<QAction*> serviceMenu();
|
||||||
|
@ -214,15 +214,13 @@ void TtRssServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
|||||||
m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool());
|
m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Message> TtRssServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
QList<Message> TtRssServiceRoot::obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages) {
|
const QHash<QString, QStringList>& tagged_messages) {
|
||||||
Q_UNUSED(stated_messages)
|
Q_UNUSED(stated_messages)
|
||||||
Q_UNUSED(tagged_messages)
|
Q_UNUSED(tagged_messages)
|
||||||
|
|
||||||
QList<Message> messages;
|
QList<Message> messages;
|
||||||
|
|
||||||
for (Feed* feed : feeds) {
|
|
||||||
int newly_added_messages = 0;
|
int newly_added_messages = 0;
|
||||||
int limit = network()->batchSize() <= 0 ? TTRSS_MAX_MESSAGES : network()->batchSize();
|
int limit = network()->batchSize() <= 0 ? TTRSS_MAX_MESSAGES : network()->batchSize();
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
@ -245,7 +243,6 @@ QList<Message> TtRssServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
return messages;
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,8 @@ class TtRssServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
|||||||
virtual void saveAllCachedData(bool ignore_errors);
|
virtual void saveAllCachedData(bool ignore_errors);
|
||||||
virtual QVariantHash customDatabaseData() const;
|
virtual QVariantHash customDatabaseData() const;
|
||||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
virtual QList<Message> obtainNewMessages(Feed* feed,
|
||||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||||
const QHash<QString, QStringList>& tagged_messages);
|
const QHash<QString, QStringList>& tagged_messages);
|
||||||
|
|
||||||
// Access to network.
|
// Access to network.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user