mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-25 14:04:23 +00:00
Keep RSS articles sorted by date in memory do avoid sorting them all the time
Optimization to address issue #34.
This commit is contained in:
parent
aecdc57cd4
commit
d1e30cacf8
@ -490,11 +490,9 @@ void RSSImp::refreshArticleList(QTreeWidgetItem* item) {
|
|||||||
qDebug("Getting the list of news");
|
qDebug("Getting the list of news");
|
||||||
RssArticleList news;
|
RssArticleList news;
|
||||||
if (rss_item == m_rssManager)
|
if (rss_item == m_rssManager)
|
||||||
news = rss_item->unreadArticleList();
|
news = rss_item->unreadArticleListByDateDesc();
|
||||||
else if (rss_item)
|
else if (rss_item)
|
||||||
news = rss_item->articleList();
|
news = rss_item->articleListByDateDesc();
|
||||||
// Sort
|
|
||||||
RssManager::sortArticleListByDateDesc(news);
|
|
||||||
// Clear the list first
|
// Clear the list first
|
||||||
textBrowser->clear();
|
textBrowser->clear();
|
||||||
m_currentArticle = 0;
|
m_currentArticle = 0;
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
#include "downloadthread.h"
|
#include "downloadthread.h"
|
||||||
#include "fs_utils.h"
|
#include "fs_utils.h"
|
||||||
|
|
||||||
|
bool rssArticleDateRecentThan(const RssArticlePtr& left, const RssArticlePtr& right)
|
||||||
|
{
|
||||||
|
return left->date() > right->date();
|
||||||
|
}
|
||||||
|
|
||||||
RssFeed::RssFeed(RssManager* manager, RssFolder* parent, const QString &url):
|
RssFeed::RssFeed(RssManager* manager, RssFolder* parent, const QString &url):
|
||||||
m_manager(manager), m_parent(parent), m_icon(":/Icons/oxygen/application-rss+xml.png"),
|
m_manager(manager), m_parent(parent), m_icon(":/Icons/oxygen/application-rss+xml.png"),
|
||||||
m_unreadCount(0), m_dirty(false), m_inErrorState(false), m_loading(false) {
|
m_unreadCount(0), m_dirty(false), m_inErrorState(false), m_loading(false) {
|
||||||
@ -95,11 +100,30 @@ void RssFeed::loadItemsFromDisk() {
|
|||||||
foreach (const QVariant &var_it, old_items) {
|
foreach (const QVariant &var_it, old_items) {
|
||||||
QHash<QString, QVariant> item = var_it.toHash();
|
QHash<QString, QVariant> item = var_it.toHash();
|
||||||
RssArticlePtr rss_item = hashToRssArticle(this, item);
|
RssArticlePtr rss_item = hashToRssArticle(this, item);
|
||||||
if (rss_item) {
|
if (rss_item)
|
||||||
m_articles.insert(rss_item->guid(), rss_item);
|
addArticle(rss_item);
|
||||||
if (!rss_item->isRead())
|
}
|
||||||
++m_unreadCount;
|
}
|
||||||
}
|
|
||||||
|
void RssFeed::addArticle(const RssArticlePtr& article)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!m_articles.contains(article->guid()));
|
||||||
|
// Update unreadCount
|
||||||
|
if (!article->isRead())
|
||||||
|
++m_unreadCount;
|
||||||
|
// Insert in hash table
|
||||||
|
m_articles[article->guid()] = article;
|
||||||
|
// Insertion sort
|
||||||
|
RssArticleList::Iterator lowerBound = qLowerBound(m_articlesByDate.begin(), m_articlesByDate.end(), article, rssArticleDateRecentThan);
|
||||||
|
m_articlesByDate.insert(lowerBound, article);
|
||||||
|
// Restrict size
|
||||||
|
const int max_articles = RssSettings().getRSSMaxArticlesPerFeed();
|
||||||
|
if (m_articlesByDate.size() > max_articles) {
|
||||||
|
RssArticlePtr oldestArticle = m_articlesByDate.takeLast();
|
||||||
|
m_articles.remove(oldestArticle->guid());
|
||||||
|
// Update unreadCount
|
||||||
|
if (!oldestArticle->isRead())
|
||||||
|
--m_unreadCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,18 +225,18 @@ uint RssFeed::unreadCount() const
|
|||||||
return m_unreadCount;
|
return m_unreadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
RssArticleList RssFeed::articleList() const {
|
RssArticleList RssFeed::articleListByDateDesc() const {
|
||||||
return m_articles.values();
|
return m_articlesByDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
RssArticleList RssFeed::unreadArticleList() const {
|
RssArticleList RssFeed::unreadArticleListByDateDesc() const {
|
||||||
RssArticleList unread_news;
|
RssArticleList unread_news;
|
||||||
|
|
||||||
RssArticleHash::ConstIterator it = m_articles.begin();
|
RssArticleList::ConstIterator it = m_articlesByDate.begin();
|
||||||
RssArticleHash::ConstIterator itend = m_articles.end();
|
RssArticleList::ConstIterator itend = m_articlesByDate.end();
|
||||||
for ( ; it != itend; ++it) {
|
for ( ; it != itend; ++it) {
|
||||||
if (!it.value()->isRead())
|
if (!(*it)->isRead())
|
||||||
unread_news << it.value();
|
unread_news << *it;
|
||||||
}
|
}
|
||||||
return unread_news;
|
return unread_news;
|
||||||
}
|
}
|
||||||
@ -223,22 +247,6 @@ QString RssFeed::iconUrl() const {
|
|||||||
return QString("http://")+QUrl(m_url).host()+QString("/favicon.ico");
|
return QString("http://")+QUrl(m_url).host()+QString("/favicon.ico");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RssFeed::removeOldArticles() {
|
|
||||||
const uint max_articles = RssSettings().getRSSMaxArticlesPerFeed();
|
|
||||||
const uint nb_articles = m_articles.size();
|
|
||||||
if (nb_articles > max_articles) {
|
|
||||||
RssArticleList listItems = m_articles.values();
|
|
||||||
RssManager::sortArticleListByDateDesc(listItems);
|
|
||||||
const int excess = nb_articles - max_articles;
|
|
||||||
for (uint i=nb_articles-excess; i<nb_articles; ++i) {
|
|
||||||
RssArticlePtr article = m_articles.take(listItems.at(i)->guid());
|
|
||||||
// Update unreadCount
|
|
||||||
if (!article->isRead())
|
|
||||||
--m_unreadCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// read and store the downloaded rss' informations
|
// read and store the downloaded rss' informations
|
||||||
void RssFeed::handleFinishedDownload(const QString& url, const QString &file_path) {
|
void RssFeed::handleFinishedDownload(const QString& url, const QString &file_path) {
|
||||||
if (url == m_url) {
|
if (url == m_url) {
|
||||||
@ -290,7 +298,7 @@ void RssFeed::handleNewArticle(const QString& feedUrl, const QVariantHash& artic
|
|||||||
|
|
||||||
RssArticlePtr article = hashToRssArticle(this, articleData);
|
RssArticlePtr article = hashToRssArticle(this, articleData);
|
||||||
Q_ASSERT(article);
|
Q_ASSERT(article);
|
||||||
m_articles[guid] = article;
|
addArticle(article);
|
||||||
|
|
||||||
// Download torrent if necessary.
|
// Download torrent if necessary.
|
||||||
if (RssSettings().isRssDownloadingEnabled()) {
|
if (RssSettings().isRssDownloadingEnabled()) {
|
||||||
@ -307,9 +315,6 @@ void RssFeed::handleNewArticle(const QString& feedUrl, const QVariantHash& artic
|
|||||||
QBtSession::instance()->downloadUrlAndSkipDialog(torrent_url, matching_rule->savePath(), matching_rule->label());
|
QBtSession::instance()->downloadUrlAndSkipDialog(torrent_url, matching_rule->savePath(), matching_rule->label());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update unreadCount if necessary
|
|
||||||
if (!article->isRead())
|
|
||||||
++m_unreadCount;
|
|
||||||
|
|
||||||
m_manager->forwardFeedInfosChanged(m_url, displayName(), m_unreadCount);
|
m_manager->forwardFeedInfosChanged(m_url, displayName(), m_unreadCount);
|
||||||
// FIXME: We should forward the information here but this would seriously decrease
|
// FIXME: We should forward the information here but this would seriously decrease
|
||||||
@ -327,9 +332,6 @@ void RssFeed::handleFeedParsingFinished(const QString& feedUrl, const QString& e
|
|||||||
qWarning() << "Reason:" << error;
|
qWarning() << "Reason:" << error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we limit the number of articles
|
|
||||||
removeOldArticles();
|
|
||||||
|
|
||||||
m_loading = false;
|
m_loading = false;
|
||||||
m_inErrorState = !error.isEmpty();
|
m_inErrorState = !error.isEmpty();
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ typedef QHash<QString, RssArticlePtr> RssArticleHash;
|
|||||||
typedef QSharedPointer<RssFeed> RssFeedPtr;
|
typedef QSharedPointer<RssFeed> RssFeedPtr;
|
||||||
typedef QList<RssFeedPtr> RssFeedList;
|
typedef QList<RssFeedPtr> RssFeedList;
|
||||||
|
|
||||||
|
bool rssArticleDateRecentThan(const RssArticlePtr& left, const RssArticlePtr& right);
|
||||||
|
|
||||||
class RssFeed: public QObject, public RssFile {
|
class RssFeed: public QObject, public RssFile {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -70,9 +72,9 @@ public:
|
|||||||
uint count() const;
|
uint count() const;
|
||||||
virtual void markAsRead();
|
virtual void markAsRead();
|
||||||
virtual uint unreadCount() const;
|
virtual uint unreadCount() const;
|
||||||
virtual RssArticleList articleList() const;
|
virtual RssArticleList articleListByDateDesc() const;
|
||||||
const RssArticleHash& articleHash() const { return m_articles; }
|
const RssArticleHash& articleHash() const { return m_articles; }
|
||||||
virtual RssArticleList unreadArticleList() const;
|
virtual RssArticleList unreadArticleListByDateDesc() const;
|
||||||
void decrementUnreadCount();
|
void decrementUnreadCount();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@ -83,14 +85,15 @@ private slots:
|
|||||||
void handleFeedParsingFinished(const QString& feedUrl, const QString& error);
|
void handleFeedParsingFinished(const QString& feedUrl, const QString& error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void removeOldArticles();
|
|
||||||
QString iconUrl() const;
|
QString iconUrl() const;
|
||||||
void loadItemsFromDisk();
|
void loadItemsFromDisk();
|
||||||
|
void addArticle(const RssArticlePtr& article);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RssManager* m_manager;
|
RssManager* m_manager;
|
||||||
RssArticleHash m_articles;
|
RssArticleHash m_articles;
|
||||||
RssFolder *m_parent;
|
RssArticleList m_articlesByDate; // Articles sorted by date (more recent first)
|
||||||
|
RssFolder* m_parent;
|
||||||
QString m_title;
|
QString m_title;
|
||||||
QString m_url;
|
QString m_url;
|
||||||
QString m_alias;
|
QString m_alias;
|
||||||
|
@ -59,8 +59,8 @@ public:
|
|||||||
virtual RssFolder* parent() const = 0;
|
virtual RssFolder* parent() const = 0;
|
||||||
virtual void setParent(RssFolder* parent) = 0;
|
virtual void setParent(RssFolder* parent) = 0;
|
||||||
virtual void refresh() = 0;
|
virtual void refresh() = 0;
|
||||||
virtual RssArticleList articleList() const = 0;
|
virtual RssArticleList articleListByDateDesc() const = 0;
|
||||||
virtual RssArticleList unreadArticleList() const = 0;
|
virtual RssArticleList unreadArticleListByDateDesc() const = 0;
|
||||||
virtual void removeAllSettings() = 0;
|
virtual void removeAllSettings() = 0;
|
||||||
virtual void saveItemsToDisk() = 0;
|
virtual void saveItemsToDisk() = 0;
|
||||||
QStringList pathHierarchy() const;
|
QStringList pathHierarchy() const;
|
||||||
|
@ -91,24 +91,28 @@ void RssFolder::refresh() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RssArticleList RssFolder::articleList() const {
|
RssArticleList RssFolder::articleListByDateDesc() const {
|
||||||
RssArticleList news;
|
RssArticleList news;
|
||||||
|
|
||||||
RssFileHash::ConstIterator it = m_children.begin();
|
RssFileHash::ConstIterator it = m_children.begin();
|
||||||
RssFileHash::ConstIterator itend = m_children.end();
|
RssFileHash::ConstIterator itend = m_children.end();
|
||||||
for ( ; it != itend; ++it) {
|
for ( ; it != itend; ++it) {
|
||||||
news << it.value()->articleList();
|
int n = news.size();
|
||||||
|
news << it.value()->articleListByDateDesc();
|
||||||
|
std::inplace_merge(news.begin(), news.begin() + n, news.end(), rssArticleDateRecentThan);
|
||||||
}
|
}
|
||||||
return news;
|
return news;
|
||||||
}
|
}
|
||||||
|
|
||||||
RssArticleList RssFolder::unreadArticleList() const {
|
RssArticleList RssFolder::unreadArticleListByDateDesc() const {
|
||||||
RssArticleList unread_news;
|
RssArticleList unread_news;
|
||||||
|
|
||||||
RssFileHash::ConstIterator it = m_children.begin();
|
RssFileHash::ConstIterator it = m_children.begin();
|
||||||
RssFileHash::ConstIterator itend = m_children.end();
|
RssFileHash::ConstIterator itend = m_children.end();
|
||||||
for ( ; it != itend; ++it) {
|
for ( ; it != itend; ++it) {
|
||||||
unread_news << it.value()->unreadArticleList();
|
int n = unread_news.size();
|
||||||
|
unread_news << it.value()->unreadArticleListByDateDesc();
|
||||||
|
std::inplace_merge(unread_news.begin(), unread_news.begin() + n, unread_news.end(), rssArticleDateRecentThan);
|
||||||
}
|
}
|
||||||
return unread_news;
|
return unread_news;
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,8 @@ public:
|
|||||||
virtual QString displayName() const;
|
virtual QString displayName() const;
|
||||||
virtual QString id() const;
|
virtual QString id() const;
|
||||||
bool hasChild(const QString &childId);
|
bool hasChild(const QString &childId);
|
||||||
virtual RssArticleList articleList() const;
|
virtual RssArticleList articleListByDateDesc() const;
|
||||||
virtual RssArticleList unreadArticleList() const;
|
virtual RssArticleList unreadArticleListByDateDesc() const;
|
||||||
virtual void removeAllSettings();
|
virtual void removeAllSettings();
|
||||||
virtual void saveItemsToDisk();
|
virtual void saveItemsToDisk();
|
||||||
void removeAllItems();
|
void removeAllItems();
|
||||||
|
@ -151,15 +151,6 @@ void RssManager::saveStreamList() const {
|
|||||||
settings.setRssFeedsAliases(aliases);
|
settings.setRssFeedsAliases(aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool laterItemDate(const RssArticlePtr& a, const RssArticlePtr& b)
|
|
||||||
{
|
|
||||||
return (a->date() > b->date());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RssManager::sortArticleListByDateDesc(RssArticleList& news_list) {
|
|
||||||
qSort(news_list.begin(), news_list.end(), laterItemDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
RssDownloadRuleList *RssManager::downloadRules() const
|
RssDownloadRuleList *RssManager::downloadRules() const
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_downloadRules);
|
Q_ASSERT(m_downloadRules);
|
||||||
|
@ -52,7 +52,6 @@ public:
|
|||||||
|
|
||||||
DownloadThread* rssDownloader() const;
|
DownloadThread* rssDownloader() const;
|
||||||
RssParser* rssParser() const;
|
RssParser* rssParser() const;
|
||||||
static void sortArticleListByDateDesc(RssArticleList& news_list);
|
|
||||||
|
|
||||||
RssDownloadRuleList* downloadRules() const;
|
RssDownloadRuleList* downloadRules() const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user