Improve RSS subsystem initialization

PR #17227.
This commit is contained in:
Vladimir Golovnev
2022-06-18 09:56:49 +03:00
committed by GitHub
parent 7d97905716
commit a2121f2483
8 changed files with 94 additions and 96 deletions

View File

@@ -222,7 +222,10 @@ void Feed::handleDownloadFinished(const Net::DownloadResult &result)
LogMsg(tr("RSS feed at '%1' is successfully downloaded. Starting to parse it.")
.arg(result.url));
// Parse the download RSS
m_parser->parse(result.data);
QMetaObject::invokeMethod(m_parser, [this, data = result.data]()
{
m_parser->parse(data);
});
}
else
{
@@ -306,18 +309,18 @@ void Feed::storeDeferred()
m_savingTimer.start(5 * 1000, this);
}
bool Feed::addArticle(Article *article)
bool Feed::addArticle(const QVariantHash &articleData)
{
Q_ASSERT(article);
Q_ASSERT(!m_articles.contains(article->guid()));
Q_ASSERT(!m_articles.contains(articleData.value(Article::KeyId).toString()));
// Insertion sort
const int maxArticles = m_session->maxArticlesPerFeed();
const auto lowerBound = std::lower_bound(m_articlesByDate.begin(), m_articlesByDate.end()
, article->date(), Article::articleDateRecentThan);
, articleData.value(Article::KeyDate).toDateTime(), Article::articleDateRecentThan);
if ((lowerBound - m_articlesByDate.begin()) >= maxArticles)
return false; // we reach max articles
auto *article = new Article(this, articleData);
m_articles[article->guid()] = article;
m_articlesByDate.insert(lowerBound, article);
if (!article->isRead())
@@ -434,7 +437,7 @@ int Feed::updateArticles(const QList<QVariantHash> &loadedArticles)
{
if (a.second)
{
addArticle(new Article {this, *a.second});
addArticle(*a.second);
++newArticlesCount;
}
});
@@ -462,7 +465,12 @@ QJsonValue Feed::toJsonValue(const bool withData) const
QJsonArray jsonArr;
for (Article *article : asConst(m_articles))
jsonArr << article->toJsonObject();
{
auto articleObj = QJsonObject::fromVariantHash(article->data());
// JSON object doesn't support DateTime so we need to convert it
articleObj[Article::KeyDate] = article->date().toString(Qt::RFC2822Date);
jsonArr.append(articleObj);
}
jsonObj.insert(KEY_ARTICLES, jsonArr);
}
@@ -489,19 +497,40 @@ void Feed::handleArticleRead(Article *article)
storeDeferred();
}
void Feed::handleArticleLoadFinished(const QVector<QVariantHash> &articles)
void Feed::handleArticleLoadFinished(QVector<QVariantHash> articles)
{
for (const QVariantHash &data : articles)
Q_ASSERT(m_articles.isEmpty());
Q_ASSERT(m_unreadCount == 0);
const int maxArticles = m_session->maxArticlesPerFeed();
if (articles.size() > maxArticles)
articles.resize(maxArticles);
m_articles.reserve(articles.size());
m_articlesByDate.reserve(articles.size());
for (const QVariantHash &articleData : articles)
{
try
const auto articleID = articleData.value(Article::KeyId).toString();
// TODO: use [[unlikely]] in C++20
if (Q_UNLIKELY(m_articles.contains(articleID)))
continue;
auto *article = new Article(this, articleData);
m_articles[articleID] = article;
m_articlesByDate.append(article);
if (!article->isRead())
{
auto *article = new Article(this, data);
if (!addArticle(article))
delete article;
++m_unreadCount;
connect(article, &Article::read, this, &Feed::handleArticleRead);
}
catch (const RuntimeError &) {}
emit newArticle(article);
}
if (m_unreadCount > 0)
emit unreadCountChanged(this);
m_isInitialized = true;
emit stateChanged(this);