Move base RSS names to Rss namespace.

This commit is contained in:
Vladimir Golovnev (Glassez)
2015-10-15 19:33:27 +03:00
committed by Vladimir Golovnev (qlassez)
parent 67758cb092
commit 6f7ae728eb
22 changed files with 708 additions and 659 deletions

View File

@@ -36,20 +36,22 @@
#include "rssfeed.h"
#include "rssarticle.h"
using namespace Rss;
// public constructor
RssArticle::RssArticle(RssFeed *parent, const QString &guid)
Article::Article(Feed *parent, const QString &guid)
: m_parent(parent)
, m_guid(guid)
, m_read(false)
{
}
bool RssArticle::hasAttachment() const
bool Article::hasAttachment() const
{
return !m_torrentUrl.isEmpty();
}
QVariantHash RssArticle::toHash() const
QVariantHash Article::toHash() const
{
QVariantHash item;
item["title"] = m_title;
@@ -63,13 +65,13 @@ QVariantHash RssArticle::toHash() const
return item;
}
RssArticlePtr RssArticle::fromHash(RssFeed *parent, const QVariantHash &h)
ArticlePtr Article::fromHash(Feed *parent, const QVariantHash &h)
{
const QString guid = h.value("id").toString();
if (guid.isEmpty())
return RssArticlePtr();
return ArticlePtr();
RssArticlePtr art(new RssArticle(parent, guid));
ArticlePtr art(new Article(parent, guid));
art->m_title = h.value("title", "").toString();
art->m_torrentUrl = h.value("torrent_url", "").toString();
art->m_link = h.value("news_link", "").toString();
@@ -81,42 +83,42 @@ RssArticlePtr RssArticle::fromHash(RssFeed *parent, const QVariantHash &h)
return art;
}
RssFeed *RssArticle::parent() const
Feed *Article::parent() const
{
return m_parent;
}
const QString &RssArticle::author() const
const QString &Article::author() const
{
return m_author;
}
const QString &RssArticle::torrentUrl() const
const QString &Article::torrentUrl() const
{
return m_torrentUrl;
}
const QString &RssArticle::link() const
const QString &Article::link() const
{
return m_link;
}
QString RssArticle::description() const
QString Article::description() const
{
return m_description.isNull() ? "" : m_description;
}
const QDateTime &RssArticle::date() const
const QDateTime &Article::date() const
{
return m_date;
}
bool RssArticle::isRead() const
bool Article::isRead() const
{
return m_read;
}
void RssArticle::markAsRead()
void Article::markAsRead()
{
if (m_read) return;
@@ -126,17 +128,17 @@ void RssArticle::markAsRead()
emit articleWasRead();
}
const QString &RssArticle::guid() const
const QString &Article::guid() const
{
return m_guid;
}
const QString &RssArticle::title() const
const QString &Article::title() const
{
return m_title;
}
void RssArticle::handleTorrentDownloadSuccess(const QString &url)
void Article::handleTorrentDownloadSuccess(const QString &url)
{
if (url == m_torrentUrl)
markAsRead();

View File

@@ -37,53 +37,56 @@
#include <QVariantHash>
#include <QSharedPointer>
class RssFeed;
class RssArticle;
typedef QSharedPointer<RssArticle> RssArticlePtr;
// Item of a rss stream, single information
class RssArticle: public QObject
namespace Rss
{
Q_OBJECT
class Feed;
class Article;
public:
RssArticle(RssFeed *parent, const QString &guid);
typedef QSharedPointer<Article> ArticlePtr;
// Accessors
bool hasAttachment() const;
const QString &guid() const;
RssFeed *parent() const;
const QString &title() const;
const QString &author() const;
const QString &torrentUrl() const;
const QString &link() const;
QString description() const;
const QDateTime &date() const;
bool isRead() const;
// Setters
void markAsRead();
// Item of a rss stream, single information
class Article: public QObject
{
Q_OBJECT
// Serialization
QVariantHash toHash() const;
static RssArticlePtr fromHash(RssFeed *parent, const QVariantHash &hash);
public:
Article(Feed *parent, const QString &guid);
signals:
void articleWasRead();
// Accessors
bool hasAttachment() const;
const QString &guid() const;
Feed *parent() const;
const QString &title() const;
const QString &author() const;
const QString &torrentUrl() const;
const QString &link() const;
QString description() const;
const QDateTime &date() const;
bool isRead() const;
// Setters
void markAsRead();
public slots:
void handleTorrentDownloadSuccess(const QString &url);
// Serialization
QVariantHash toHash() const;
static ArticlePtr fromHash(Feed *parent, const QVariantHash &hash);
private:
RssFeed *m_parent;
QString m_guid;
QString m_title;
QString m_torrentUrl;
QString m_link;
QString m_description;
QDateTime m_date;
QString m_author;
bool m_read;
};
signals:
void articleWasRead();
public slots:
void handleTorrentDownloadSuccess(const QString &url);
private:
Feed *m_parent;
QString m_guid;
QString m_title;
QString m_torrentUrl;
QString m_link;
QString m_description;
QDateTime m_date;
QString m_author;
bool m_read;
};
}
#endif // RSSARTICLE_H

View File

@@ -38,14 +38,16 @@
#include "rssarticle.h"
#include "rssdownloadrule.h"
RssDownloadRule::RssDownloadRule()
using namespace Rss;
DownloadRule::DownloadRule()
: m_enabled(false)
, m_useRegex(false)
, m_apstate(USE_GLOBAL)
{
}
bool RssDownloadRule::matches(const QString &articleTitle) const
bool DownloadRule::matches(const QString &articleTitle) const
{
foreach (const QString &token, m_mustContain) {
if (!token.isEmpty()) {
@@ -123,7 +125,7 @@ bool RssDownloadRule::matches(const QString &articleTitle) const
return true;
}
void RssDownloadRule::setMustContain(const QString &tokens)
void DownloadRule::setMustContain(const QString &tokens)
{
if (m_useRegex)
m_mustContain = QStringList() << tokens;
@@ -131,7 +133,7 @@ void RssDownloadRule::setMustContain(const QString &tokens)
m_mustContain = tokens.split(" ");
}
void RssDownloadRule::setMustNotContain(const QString &tokens)
void DownloadRule::setMustNotContain(const QString &tokens)
{
if (m_useRegex)
m_mustNotContain = QStringList() << tokens;
@@ -139,34 +141,34 @@ void RssDownloadRule::setMustNotContain(const QString &tokens)
m_mustNotContain = tokens.split("|");
}
QStringList RssDownloadRule::rssFeeds() const
QStringList DownloadRule::rssFeeds() const
{
return m_rssFeeds;
}
void RssDownloadRule::setRssFeeds(const QStringList &rssFeeds)
void DownloadRule::setRssFeeds(const QStringList &rssFeeds)
{
m_rssFeeds = rssFeeds;
}
QString RssDownloadRule::name() const
QString DownloadRule::name() const
{
return m_name;
}
void RssDownloadRule::setName(const QString &name)
void DownloadRule::setName(const QString &name)
{
m_name = name;
}
QString RssDownloadRule::savePath() const
QString DownloadRule::savePath() const
{
return m_savePath;
}
RssDownloadRulePtr RssDownloadRule::fromVariantHash(const QVariantHash &ruleHash)
DownloadRulePtr DownloadRule::fromVariantHash(const QVariantHash &ruleHash)
{
RssDownloadRulePtr rule(new RssDownloadRule);
DownloadRulePtr rule(new DownloadRule);
rule->setName(ruleHash.value("name").toString());
rule->setUseRegex(ruleHash.value("use_regex", false).toBool());
rule->setMustContain(ruleHash.value("must_contain").toString());
@@ -182,7 +184,7 @@ RssDownloadRulePtr RssDownloadRule::fromVariantHash(const QVariantHash &ruleHash
return rule;
}
QVariantHash RssDownloadRule::toVariantHash() const
QVariantHash DownloadRule::toVariantHash() const
{
QVariantHash hash;
hash["name"] = m_name;
@@ -200,12 +202,12 @@ QVariantHash RssDownloadRule::toVariantHash() const
return hash;
}
bool RssDownloadRule::operator==(const RssDownloadRule &other) const
bool DownloadRule::operator==(const DownloadRule &other) const
{
return m_name == other.name();
}
void RssDownloadRule::setSavePath(const QString &savePath)
void DownloadRule::setSavePath(const QString &savePath)
{
if (!savePath.isEmpty() && (QDir(savePath) != QDir(Preferences::instance()->getSavePath())))
m_savePath = Utils::Fs::fromNativePath(savePath);
@@ -213,93 +215,93 @@ void RssDownloadRule::setSavePath(const QString &savePath)
m_savePath = QString();
}
RssDownloadRule::AddPausedState RssDownloadRule::addPaused() const
DownloadRule::AddPausedState DownloadRule::addPaused() const
{
return m_apstate;
}
void RssDownloadRule::setAddPaused(const RssDownloadRule::AddPausedState &aps)
void DownloadRule::setAddPaused(const DownloadRule::AddPausedState &aps)
{
m_apstate = aps;
}
QString RssDownloadRule::label() const
QString DownloadRule::label() const
{
return m_label;
}
void RssDownloadRule::setLabel(const QString &label)
void DownloadRule::setLabel(const QString &label)
{
m_label = label;
}
bool RssDownloadRule::isEnabled() const
bool DownloadRule::isEnabled() const
{
return m_enabled;
}
void RssDownloadRule::setEnabled(bool enable)
void DownloadRule::setEnabled(bool enable)
{
m_enabled = enable;
}
void RssDownloadRule::setLastMatch(const QDateTime &d)
void DownloadRule::setLastMatch(const QDateTime &d)
{
m_lastMatch = d;
}
QDateTime RssDownloadRule::lastMatch() const
QDateTime DownloadRule::lastMatch() const
{
return m_lastMatch;
}
void RssDownloadRule::setIgnoreDays(int d)
void DownloadRule::setIgnoreDays(int d)
{
m_ignoreDays = d;
}
int RssDownloadRule::ignoreDays() const
int DownloadRule::ignoreDays() const
{
return m_ignoreDays;
}
QString RssDownloadRule::mustContain() const
QString DownloadRule::mustContain() const
{
return m_mustContain.join(" ");
}
QString RssDownloadRule::mustNotContain() const
QString DownloadRule::mustNotContain() const
{
return m_mustNotContain.join("|");
}
bool RssDownloadRule::useRegex() const
bool DownloadRule::useRegex() const
{
return m_useRegex;
}
void RssDownloadRule::setUseRegex(bool enabled)
void DownloadRule::setUseRegex(bool enabled)
{
m_useRegex = enabled;
}
QString RssDownloadRule::episodeFilter() const
QString DownloadRule::episodeFilter() const
{
return m_episodeFilter;
}
void RssDownloadRule::setEpisodeFilter(const QString &e)
void DownloadRule::setEpisodeFilter(const QString &e)
{
m_episodeFilter = e;
}
QStringList RssDownloadRule::findMatchingArticles(const RssFeedPtr &feed) const
QStringList DownloadRule::findMatchingArticles(const FeedPtr &feed) const
{
QStringList ret;
const RssArticleHash &feedArticles = feed->articleHash();
const ArticleHash &feedArticles = feed->articleHash();
RssArticleHash::ConstIterator artIt = feedArticles.begin();
RssArticleHash::ConstIterator artItend = feedArticles.end();
ArticleHash::ConstIterator artIt = feedArticles.begin();
ArticleHash::ConstIterator artItend = feedArticles.end();
for ( ; artIt != artItend ; ++artIt) {
const QString title = artIt.value()->title();
if (matches(title))

View File

@@ -36,68 +36,71 @@
#include <QSharedPointer>
#include <QDateTime>
class RssFeed;
typedef QSharedPointer<RssFeed> RssFeedPtr;
class RssDownloadRule;
typedef QSharedPointer<RssDownloadRule> RssDownloadRulePtr;
class RssDownloadRule
namespace Rss
{
public:
enum AddPausedState
class Feed;
typedef QSharedPointer<Feed> FeedPtr;
class DownloadRule;
typedef QSharedPointer<DownloadRule> DownloadRulePtr;
class DownloadRule
{
USE_GLOBAL = 0,
ALWAYS_PAUSED,
NEVER_PAUSED
public:
enum AddPausedState
{
USE_GLOBAL = 0,
ALWAYS_PAUSED,
NEVER_PAUSED
};
DownloadRule();
static DownloadRulePtr fromVariantHash(const QVariantHash &ruleHash);
QVariantHash toVariantHash() const;
bool matches(const QString &articleTitle) const;
void setMustContain(const QString &tokens);
void setMustNotContain(const QString &tokens);
QStringList rssFeeds() const;
void setRssFeeds(const QStringList &rssFeeds);
QString name() const;
void setName(const QString &name);
QString savePath() const;
void setSavePath(const QString &savePath);
AddPausedState addPaused() const;
void setAddPaused(const AddPausedState &aps);
QString label() const;
void setLabel(const QString &label);
bool isEnabled() const;
void setEnabled(bool enable);
void setLastMatch(const QDateTime &d);
QDateTime lastMatch() const;
void setIgnoreDays(int d);
int ignoreDays() const;
QString mustContain() const;
QString mustNotContain() const;
bool useRegex() const;
void setUseRegex(bool enabled);
QString episodeFilter() const;
void setEpisodeFilter(const QString &e);
QStringList findMatchingArticles(const FeedPtr &feed) const;
// Operators
bool operator==(const DownloadRule &other) const;
private:
QString m_name;
QStringList m_mustContain;
QStringList m_mustNotContain;
QString m_episodeFilter;
QString m_savePath;
QString m_label;
bool m_enabled;
QStringList m_rssFeeds;
bool m_useRegex;
AddPausedState m_apstate;
QDateTime m_lastMatch;
int m_ignoreDays;
};
RssDownloadRule();
static RssDownloadRulePtr fromVariantHash(const QVariantHash &ruleHash);
QVariantHash toVariantHash() const;
bool matches(const QString &articleTitle) const;
void setMustContain(const QString &tokens);
void setMustNotContain(const QString &tokens);
QStringList rssFeeds() const;
void setRssFeeds(const QStringList &rssFeeds);
QString name() const;
void setName(const QString &name);
QString savePath() const;
void setSavePath(const QString &savePath);
AddPausedState addPaused() const;
void setAddPaused(const AddPausedState &aps);
QString label() const;
void setLabel(const QString &label);
bool isEnabled() const;
void setEnabled(bool enable);
void setLastMatch(const QDateTime &d);
QDateTime lastMatch() const;
void setIgnoreDays(int d);
int ignoreDays() const;
QString mustContain() const;
QString mustNotContain() const;
bool useRegex() const;
void setUseRegex(bool enabled);
QString episodeFilter() const;
void setEpisodeFilter(const QString &e);
QStringList findMatchingArticles(const RssFeedPtr &feed) const;
// Operators
bool operator==(const RssDownloadRule &other) const;
private:
QString m_name;
QStringList m_mustContain;
QStringList m_mustNotContain;
QString m_episodeFilter;
QString m_savePath;
QString m_label;
bool m_enabled;
QStringList m_rssFeeds;
bool m_useRegex;
AddPausedState m_apstate;
QDateTime m_lastMatch;
int m_ignoreDays;
};
}
#endif // RSSDOWNLOADRULE_H

View File

@@ -36,23 +36,25 @@
#include "base/qinisettings.h"
#include "rssdownloadrulelist.h"
RssDownloadRuleList::RssDownloadRuleList()
using namespace Rss;
DownloadRuleList::DownloadRuleList()
{
loadRulesFromStorage();
}
RssDownloadRulePtr RssDownloadRuleList::findMatchingRule(const QString &feedUrl, const QString &articleTitle) const
DownloadRulePtr DownloadRuleList::findMatchingRule(const QString &feedUrl, const QString &articleTitle) const
{
Q_ASSERT(Preferences::instance()->isRssDownloadingEnabled());
QStringList ruleNames = m_feedRules.value(feedUrl);
foreach (const QString &rule_name, ruleNames) {
RssDownloadRulePtr rule = m_rules[rule_name];
DownloadRulePtr rule = m_rules[rule_name];
if (rule->isEnabled() && rule->matches(articleTitle)) return rule;
}
return RssDownloadRulePtr();
return DownloadRulePtr();
}
void RssDownloadRuleList::replace(RssDownloadRuleList *other)
void DownloadRuleList::replace(DownloadRuleList *other)
{
m_rules.clear();
m_feedRules.clear();
@@ -61,39 +63,39 @@ void RssDownloadRuleList::replace(RssDownloadRuleList *other)
}
}
void RssDownloadRuleList::saveRulesToStorage()
void DownloadRuleList::saveRulesToStorage()
{
QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss");
qBTRSS.setValue("download_rules", toVariantHash());
}
void RssDownloadRuleList::loadRulesFromStorage()
void DownloadRuleList::loadRulesFromStorage()
{
QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss");
loadRulesFromVariantHash(qBTRSS.value("download_rules").toHash());
}
QVariantHash RssDownloadRuleList::toVariantHash() const
QVariantHash DownloadRuleList::toVariantHash() const
{
QVariantHash ret;
foreach (const RssDownloadRulePtr &rule, m_rules.values()) {
foreach (const DownloadRulePtr &rule, m_rules.values()) {
ret.insert(rule->name(), rule->toVariantHash());
}
return ret;
}
void RssDownloadRuleList::loadRulesFromVariantHash(const QVariantHash &h)
void DownloadRuleList::loadRulesFromVariantHash(const QVariantHash &h)
{
QVariantHash::ConstIterator it = h.begin();
QVariantHash::ConstIterator itend = h.end();
for ( ; it != itend; ++it) {
RssDownloadRulePtr rule = RssDownloadRule::fromVariantHash(it.value().toHash());
DownloadRulePtr rule = DownloadRule::fromVariantHash(it.value().toHash());
if (rule && !rule->name().isEmpty())
saveRule(rule);
}
}
void RssDownloadRuleList::saveRule(const RssDownloadRulePtr &rule)
void DownloadRuleList::saveRule(const DownloadRulePtr &rule)
{
qDebug() << Q_FUNC_INFO << rule->name();
Q_ASSERT(rule);
@@ -109,22 +111,22 @@ void RssDownloadRuleList::saveRule(const RssDownloadRulePtr &rule)
qDebug() << Q_FUNC_INFO << "EXIT";
}
void RssDownloadRuleList::removeRule(const QString &name)
void DownloadRuleList::removeRule(const QString &name)
{
qDebug() << Q_FUNC_INFO << name;
if (!m_rules.contains(name)) return;
RssDownloadRulePtr rule = m_rules.take(name);
DownloadRulePtr rule = m_rules.take(name);
// Update feedRules hashtable
foreach (const QString &feedUrl, rule->rssFeeds()) {
m_feedRules[feedUrl].removeOne(rule->name());
}
}
void RssDownloadRuleList::renameRule(const QString &oldName, const QString &newName)
void DownloadRuleList::renameRule(const QString &oldName, const QString &newName)
{
if (!m_rules.contains(oldName)) return;
RssDownloadRulePtr rule = m_rules.take(oldName);
DownloadRulePtr rule = m_rules.take(oldName);
rule->setName(newName);
m_rules.insert(newName, rule);
// Update feedRules hashtable
@@ -133,22 +135,22 @@ void RssDownloadRuleList::renameRule(const QString &oldName, const QString &newN
}
}
RssDownloadRulePtr RssDownloadRuleList::getRule(const QString &name) const
DownloadRulePtr DownloadRuleList::getRule(const QString &name) const
{
return m_rules.value(name);
}
QStringList RssDownloadRuleList::ruleNames() const
QStringList DownloadRuleList::ruleNames() const
{
return m_rules.keys();
}
bool RssDownloadRuleList::isEmpty() const
bool DownloadRuleList::isEmpty() const
{
return m_rules.isEmpty();
}
bool RssDownloadRuleList::serialize(const QString &path)
bool DownloadRuleList::serialize(const QString &path)
{
QFile f(path);
if (f.open(QIODevice::WriteOnly)) {
@@ -162,7 +164,7 @@ bool RssDownloadRuleList::serialize(const QString &path)
return false;
}
bool RssDownloadRuleList::unserialize(const QString &path)
bool DownloadRuleList::unserialize(const QString &path)
{
QFile f(path);
if (f.open(QIODevice::ReadOnly)) {

View File

@@ -37,34 +37,37 @@
#include "rssdownloadrule.h"
class RssDownloadRuleList
namespace Rss
{
Q_DISABLE_COPY(RssDownloadRuleList)
class DownloadRuleList
{
Q_DISABLE_COPY(DownloadRuleList)
public:
RssDownloadRuleList();
public:
DownloadRuleList();
RssDownloadRulePtr findMatchingRule(const QString &feedUrl, const QString &articleTitle) const;
// Operators
void saveRule(const RssDownloadRulePtr &rule);
void removeRule(const QString &name);
void renameRule(const QString &oldName, const QString &newName);
RssDownloadRulePtr getRule(const QString &name) const;
QStringList ruleNames() const;
bool isEmpty() const;
void saveRulesToStorage();
bool serialize(const QString &path);
bool unserialize(const QString &path);
void replace(RssDownloadRuleList *other);
DownloadRulePtr findMatchingRule(const QString &feedUrl, const QString &articleTitle) const;
// Operators
void saveRule(const DownloadRulePtr &rule);
void removeRule(const QString &name);
void renameRule(const QString &oldName, const QString &newName);
DownloadRulePtr getRule(const QString &name) const;
QStringList ruleNames() const;
bool isEmpty() const;
void saveRulesToStorage();
bool serialize(const QString &path);
bool unserialize(const QString &path);
void replace(DownloadRuleList *other);
private:
void loadRulesFromStorage();
void loadRulesFromVariantHash(const QVariantHash &l);
QVariantHash toVariantHash() const;
private:
void loadRulesFromStorage();
void loadRulesFromVariantHash(const QVariantHash &l);
QVariantHash toVariantHash() const;
private:
QHash<QString, RssDownloadRulePtr> m_rules;
QHash<QString, QStringList> m_feedRules;
};
private:
QHash<QString, DownloadRulePtr> m_rules;
QHash<QString, QStringList> m_feedRules;
};
}
#endif // RSSDOWNLOADFILTERLIST_H

View File

@@ -47,12 +47,17 @@
#include "rssmanager.h"
#include "rssfeed.h"
bool rssArticleDateRecentThan(const RssArticlePtr &left, const RssArticlePtr &right)
namespace Rss
{
return left->date() > right->date();
bool articleDateRecentThan(const ArticlePtr &left, const ArticlePtr &right)
{
return left->date() > right->date();
}
}
RssFeed::RssFeed(RssManager *manager, RssFolder *parent, const QString &url)
using namespace Rss;
Feed::Feed(Manager *manager, Folder *parent, const QString &url)
: m_manager(manager)
, m_parent(parent)
, m_url (QUrl::fromEncoded(url.toUtf8()).toString())
@@ -78,23 +83,23 @@ RssFeed::RssFeed(RssManager *manager, RssFolder *parent, const QString &url)
loadItemsFromDisk();
}
RssFeed::~RssFeed()
Feed::~Feed()
{
if (!m_icon.startsWith(":/") && QFile::exists(m_icon))
Utils::Fs::forceRemove(m_icon);
}
RssFolder *RssFeed::parent() const
Folder *Feed::parent() const
{
return m_parent;
}
void RssFeed::setParent(RssFolder *parent)
void Feed::setParent(Folder *parent)
{
m_parent = parent;
}
void RssFeed::saveItemsToDisk()
void Feed::saveItemsToDisk()
{
qDebug() << Q_FUNC_INFO << m_url;
if (!m_dirty) return;
@@ -104,8 +109,8 @@ void RssFeed::saveItemsToDisk()
QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QVariantList oldItems;
RssArticleHash::ConstIterator it = m_articles.begin();
RssArticleHash::ConstIterator itend = m_articles.end();
ArticleHash::ConstIterator it = m_articles.begin();
ArticleHash::ConstIterator itend = m_articles.end();
for ( ; it != itend; ++it) {
oldItems << it.value()->toHash();
}
@@ -115,7 +120,7 @@ void RssFeed::saveItemsToDisk()
qBTRSS.setValue("old_items", allOldItems);
}
void RssFeed::loadItemsFromDisk()
void Feed::loadItemsFromDisk()
{
QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QHash<QString, QVariant> allOldItems = qBTRSS.value("old_items", QHash<QString, QVariant>()).toHash();
@@ -124,13 +129,13 @@ void RssFeed::loadItemsFromDisk()
foreach (const QVariant &var_it, oldItems) {
QVariantHash item = var_it.toHash();
RssArticlePtr rssItem = RssArticle::fromHash(this, item);
ArticlePtr rssItem = Article::fromHash(this, item);
if (rssItem)
addArticle(rssItem);
}
}
void RssFeed::addArticle(const RssArticlePtr &article)
void Feed::addArticle(const ArticlePtr &article)
{
int maxArticles = Preferences::instance()->getRSSMaxArticlesPerFeed();
@@ -143,11 +148,11 @@ void RssFeed::addArticle(const RssArticlePtr &article)
// Insert in hash table
m_articles[article->guid()] = article;
// Insertion sort
RssArticleList::Iterator lowerBound = qLowerBound(m_articlesByDate.begin(), m_articlesByDate.end(), article, rssArticleDateRecentThan);
ArticleList::Iterator lowerBound = qLowerBound(m_articlesByDate.begin(), m_articlesByDate.end(), article, articleDateRecentThan);
m_articlesByDate.insert(lowerBound, article);
int lbIndex = m_articlesByDate.indexOf(article);
if (m_articlesByDate.size() > maxArticles) {
RssArticlePtr oldestArticle = m_articlesByDate.takeLast();
ArticlePtr oldestArticle = m_articlesByDate.takeLast();
m_articles.remove(oldestArticle->guid());
// Update unreadCount
if (!oldestArticle->isRead())
@@ -164,7 +169,7 @@ void RssFeed::addArticle(const RssArticlePtr &article)
// m_articles.contains(article->guid())
// Try to download skipped articles
if (Preferences::instance()->isRssDownloadingEnabled()) {
RssArticlePtr skipped = m_articles.value(article->guid(), RssArticlePtr());
ArticlePtr skipped = m_articles.value(article->guid(), ArticlePtr());
if (skipped) {
if (!skipped->isRead())
downloadArticleTorrentIfMatching(m_manager->downloadRules(), skipped);
@@ -173,7 +178,7 @@ void RssFeed::addArticle(const RssArticlePtr &article)
}
}
bool RssFeed::refresh()
bool Feed::refresh()
{
if (m_loading) {
qWarning() << Q_FUNC_INFO << "Feed" << displayName() << "is already being refreshed, ignoring request";
@@ -188,12 +193,12 @@ bool RssFeed::refresh()
return true;
}
QString RssFeed::id() const
QString Feed::id() const
{
return m_url;
}
void RssFeed::removeAllSettings()
void Feed::removeAllSettings()
{
qDebug() << "Removing all settings / history for feed: " << m_url;
QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss");
@@ -214,24 +219,24 @@ void RssFeed::removeAllSettings()
}
}
bool RssFeed::isLoading() const
bool Feed::isLoading() const
{
return m_loading;
}
QString RssFeed::title() const
QString Feed::title() const
{
return m_title;
}
void RssFeed::rename(const QString &newName)
void Feed::rename(const QString &newName)
{
qDebug() << "Renaming stream to" << newName;
m_alias = newName;
}
// Return the alias if the stream has one, the url if it has no alias
QString RssFeed::displayName() const
QString Feed::displayName() const
{
if (!m_alias.isEmpty())
return m_alias;
@@ -240,12 +245,12 @@ QString RssFeed::displayName() const
return m_url;
}
QString RssFeed::url() const
QString Feed::url() const
{
return m_url;
}
QString RssFeed::iconPath() const
QString Feed::iconPath() const
{
if (m_inErrorState)
return QLatin1String(":/icons/oxygen/unavailable.png");
@@ -253,31 +258,31 @@ QString RssFeed::iconPath() const
return m_icon;
}
bool RssFeed::hasCustomIcon() const
bool Feed::hasCustomIcon() const
{
return !m_icon.startsWith(":/");
}
void RssFeed::setIconPath(const QString &path)
void Feed::setIconPath(const QString &path)
{
if (!path.isEmpty() && QFile::exists(path))
m_icon = path;
}
RssArticlePtr RssFeed::getItem(const QString &guid) const
ArticlePtr Feed::getItem(const QString &guid) const
{
return m_articles.value(guid);
}
uint RssFeed::count() const
uint Feed::count() const
{
return m_articles.size();
}
void RssFeed::markAsRead()
void Feed::markAsRead()
{
RssArticleHash::ConstIterator it = m_articles.begin();
RssArticleHash::ConstIterator itend = m_articles.end();
ArticleHash::ConstIterator it = m_articles.begin();
ArticleHash::ConstIterator itend = m_articles.end();
for ( ; it != itend; ++it) {
it.value()->markAsRead();
}
@@ -285,32 +290,32 @@ void RssFeed::markAsRead()
m_manager->forwardFeedInfosChanged(m_url, displayName(), 0);
}
void RssFeed::markAsDirty(bool dirty)
void Feed::markAsDirty(bool dirty)
{
m_dirty = dirty;
}
uint RssFeed::unreadCount() const
uint Feed::unreadCount() const
{
return m_unreadCount;
}
RssArticleList RssFeed::articleListByDateDesc() const
ArticleList Feed::articleListByDateDesc() const
{
return m_articlesByDate;
}
const RssArticleHash &RssFeed::articleHash() const
const ArticleHash &Feed::articleHash() const
{
return m_articles;
}
RssArticleList RssFeed::unreadArticleListByDateDesc() const
ArticleList Feed::unreadArticleListByDateDesc() const
{
RssArticleList unreadNews;
ArticleList unreadNews;
RssArticleList::ConstIterator it = m_articlesByDate.begin();
RssArticleList::ConstIterator itend = m_articlesByDate.end();
ArticleList::ConstIterator it = m_articlesByDate.begin();
ArticleList::ConstIterator itend = m_articlesByDate.end();
for ( ; it != itend; ++it) {
if (!(*it)->isRead())
unreadNews << *it;
@@ -319,14 +324,14 @@ RssArticleList RssFeed::unreadArticleListByDateDesc() const
}
// download the icon from the address
QString RssFeed::iconUrl() const
QString Feed::iconUrl() const
{
// XXX: This works for most sites but it is not perfect
return QString("http://") + QUrl(m_url).host() + QString("/favicon.ico");
}
// read and store the downloaded rss' informations
void RssFeed::handleFinishedDownload(const QString &url, const QString &filePath)
void Feed::handleFinishedDownload(const QString &url, const QString &filePath)
{
if (url == m_url) {
qDebug() << Q_FUNC_INFO << "Successfully downloaded RSS feed at" << url;
@@ -340,7 +345,7 @@ void RssFeed::handleFinishedDownload(const QString &url, const QString &filePath
}
}
void RssFeed::handleDownloadFailure(const QString &url, const QString &error)
void Feed::handleDownloadFailure(const QString &url, const QString &error)
{
if (url != m_url) return;
@@ -351,7 +356,7 @@ void RssFeed::handleDownloadFailure(const QString &url, const QString &error)
qWarning() << "Reason:" << error;
}
void RssFeed::handleFeedTitle(const QString &feedUrl, const QString &title)
void Feed::handleFeedTitle(const QString &feedUrl, const QString &title)
{
if (feedUrl != m_url) return;
if (m_title == title) return;
@@ -363,10 +368,10 @@ void RssFeed::handleFeedTitle(const QString &feedUrl, const QString &title)
m_manager->forwardFeedInfosChanged(feedUrl, title, m_unreadCount);
}
void RssFeed::downloadArticleTorrentIfMatching(RssDownloadRuleList *rules, const RssArticlePtr &article)
void Feed::downloadArticleTorrentIfMatching(DownloadRuleList *rules, const ArticlePtr &article)
{
Q_ASSERT(Preferences::instance()->isRssDownloadingEnabled());
RssDownloadRulePtr matchingRule = rules->findMatchingRule(m_url, article->title());
DownloadRulePtr matchingRule = rules->findMatchingRule(m_url, article->title());
if (!matchingRule) return;
if (matchingRule->ignoreDays() > 0) {
@@ -400,28 +405,28 @@ void RssFeed::downloadArticleTorrentIfMatching(RssDownloadRuleList *rules, const
BitTorrent::AddTorrentParams params;
params.savePath = matchingRule->savePath();
params.label = matchingRule->label();
if (matchingRule->addPaused() == RssDownloadRule::ALWAYS_PAUSED)
if (matchingRule->addPaused() == DownloadRule::ALWAYS_PAUSED)
params.addPaused = TriStateBool::True;
else if (matchingRule->addPaused() == RssDownloadRule::NEVER_PAUSED)
else if (matchingRule->addPaused() == DownloadRule::NEVER_PAUSED)
params.addPaused = TriStateBool::False;
BitTorrent::Session::instance()->addTorrent(torrentUrl, params);
}
void RssFeed::recheckRssItemsForDownload()
void Feed::recheckRssItemsForDownload()
{
Q_ASSERT(Preferences::instance()->isRssDownloadingEnabled());
RssDownloadRuleList *rules = m_manager->downloadRules();
foreach (const RssArticlePtr &article, m_articlesByDate) {
DownloadRuleList *rules = m_manager->downloadRules();
foreach (const ArticlePtr &article, m_articlesByDate) {
if (!article->isRead())
downloadArticleTorrentIfMatching(rules, article);
}
}
void RssFeed::handleNewArticle(const QString &feedUrl, const QVariantHash &articleData)
void Feed::handleNewArticle(const QString &feedUrl, const QVariantHash &articleData)
{
if (feedUrl != m_url) return;
RssArticlePtr article = RssArticle::fromHash(this, articleData);
ArticlePtr article = Article::fromHash(this, articleData);
if (article.isNull()) {
qDebug() << "Article hash corrupted or guid is uncomputable; feed url: " << feedUrl;
return;
@@ -435,7 +440,7 @@ void RssFeed::handleNewArticle(const QString &feedUrl, const QVariantHash &artic
//m_manager->forwardFeedContentChanged(m_url);
}
void RssFeed::handleFeedParsingFinished(const QString &feedUrl, const QString &error)
void Feed::handleFeedParsingFinished(const QString &feedUrl, const QString &error)
{
if (feedUrl != m_url) return;
@@ -454,12 +459,12 @@ void RssFeed::handleFeedParsingFinished(const QString &feedUrl, const QString &e
saveItemsToDisk();
}
void RssFeed::handleArticleStateChanged()
void Feed::handleArticleStateChanged()
{
m_manager->forwardFeedInfosChanged(m_url, displayName(), m_unreadCount);
}
void RssFeed::decrementUnreadCount()
void Feed::decrementUnreadCount()
{
--m_unreadCount;
}

View File

@@ -40,78 +40,81 @@
#include "rssfile.h"
class RssFolder;
class RssFeed;
class RssManager;
class RssDownloadRuleList;
typedef QHash<QString, RssArticlePtr> RssArticleHash;
typedef QSharedPointer<RssFeed> RssFeedPtr;
typedef QList<RssFeedPtr> RssFeedList;
bool rssArticleDateRecentThan(const RssArticlePtr &left, const RssArticlePtr &right);
class RssFeed: public QObject, public RssFile
namespace Rss
{
Q_OBJECT
class Folder;
class Feed;
class Manager;
class DownloadRuleList;
public:
RssFeed(RssManager *manager, RssFolder *parent, const QString &url);
~RssFeed();
typedef QHash<QString, ArticlePtr> ArticleHash;
typedef QSharedPointer<Feed> FeedPtr;
typedef QList<FeedPtr> FeedList;
RssFolder *parent() const;
void setParent(RssFolder *parent);
bool refresh();
QString id() const;
void removeAllSettings();
void saveItemsToDisk();
bool isLoading() const;
QString title() const;
void rename(const QString &newName);
QString displayName() const;
QString url() const;
QString iconPath() const;
bool hasCustomIcon() const;
void setIconPath(const QString &pathHierarchy);
RssArticlePtr getItem(const QString &guid) const;
uint count() const;
void markAsRead();
void markAsDirty(bool dirty = true);
uint unreadCount() const;
RssArticleList articleListByDateDesc() const;
const RssArticleHash &articleHash() const;
RssArticleList unreadArticleListByDateDesc() const;
void decrementUnreadCount();
void recheckRssItemsForDownload();
bool articleDateRecentThan(const ArticlePtr &left, const ArticlePtr &right);
private slots:
void handleFinishedDownload(const QString &url, const QString &filePath);
void handleDownloadFailure(const QString &url, const QString &error);
void handleFeedTitle(const QString &feedUrl, const QString &title);
void handleNewArticle(const QString &feedUrl, const QVariantHash &article);
void handleFeedParsingFinished(const QString &feedUrl, const QString &error);
void handleArticleStateChanged();
class Feed: public QObject, public File
{
Q_OBJECT
private:
QString iconUrl() const;
void loadItemsFromDisk();
void addArticle(const RssArticlePtr &article);
void downloadArticleTorrentIfMatching(RssDownloadRuleList *rules, const RssArticlePtr &article);
public:
Feed(Manager *manager, Folder *parent, const QString &url);
~Feed();
private:
RssManager *m_manager;
RssArticleHash m_articles;
RssArticleList m_articlesByDate; // Articles sorted by date (more recent first)
RssFolder *m_parent;
QString m_title;
QString m_url;
QString m_alias;
QString m_icon;
QString m_iconUrl;
uint m_unreadCount;
bool m_dirty;
bool m_inErrorState;
bool m_loading;
};
Folder *parent() const;
void setParent(Folder *parent);
bool refresh();
QString id() const;
void removeAllSettings();
void saveItemsToDisk();
bool isLoading() const;
QString title() const;
void rename(const QString &newName);
QString displayName() const;
QString url() const;
QString iconPath() const;
bool hasCustomIcon() const;
void setIconPath(const QString &pathHierarchy);
ArticlePtr getItem(const QString &guid) const;
uint count() const;
void markAsRead();
void markAsDirty(bool dirty = true);
uint unreadCount() const;
ArticleList articleListByDateDesc() const;
const ArticleHash &articleHash() const;
ArticleList unreadArticleListByDateDesc() const;
void decrementUnreadCount();
void recheckRssItemsForDownload();
private slots:
void handleFinishedDownload(const QString &url, const QString &filePath);
void handleDownloadFailure(const QString &url, const QString &error);
void handleFeedTitle(const QString &feedUrl, const QString &title);
void handleNewArticle(const QString &feedUrl, const QVariantHash &article);
void handleFeedParsingFinished(const QString &feedUrl, const QString &error);
void handleArticleStateChanged();
private:
QString iconUrl() const;
void loadItemsFromDisk();
void addArticle(const ArticlePtr &article);
void downloadArticleTorrentIfMatching(DownloadRuleList *rules, const ArticlePtr &article);
private:
Manager *m_manager;
ArticleHash m_articles;
ArticleList m_articlesByDate; // Articles sorted by date (more recent first)
Folder *m_parent;
QString m_title;
QString m_url;
QString m_alias;
QString m_icon;
QString m_iconUrl;
uint m_unreadCount;
bool m_dirty;
bool m_inErrorState;
bool m_loading;
};
}
#endif // RSSFEED_H

View File

@@ -32,9 +32,11 @@
#include "rssfolder.h"
#include "rssfile.h"
RssFile::~RssFile() {}
using namespace Rss;
QStringList RssFile::pathHierarchy() const
File::~File() {}
QStringList File::pathHierarchy() const
{
QStringList path;
if (parent())

View File

@@ -36,42 +36,45 @@
#include <QStringList>
#include <QSharedPointer>
class RssFolder;
class RssFile;
class RssArticle;
typedef QSharedPointer<RssFile> RssFilePtr;
typedef QSharedPointer<RssArticle> RssArticlePtr;
typedef QList<RssArticlePtr> RssArticleList;
typedef QList<RssFilePtr> RssFileList;
/**
* Parent interface for RssFolder and RssFeed.
*/
class RssFile
namespace Rss
{
public:
virtual ~RssFile();
class Folder;
class File;
class Article;
virtual uint unreadCount() const = 0;
virtual QString displayName() const = 0;
virtual QString id() const = 0;
virtual QString iconPath() const = 0;
virtual void rename(const QString &newName) = 0;
virtual void markAsRead() = 0;
virtual RssFolder *parent() const = 0;
virtual void setParent(RssFolder *parent) = 0;
virtual bool refresh() = 0;
virtual RssArticleList articleListByDateDesc() const = 0;
virtual RssArticleList unreadArticleListByDateDesc() const = 0;
virtual void removeAllSettings() = 0;
virtual void saveItemsToDisk() = 0;
virtual void recheckRssItemsForDownload() = 0;
typedef QSharedPointer<File> FilePtr;
typedef QSharedPointer<Article> ArticlePtr;
typedef QList<ArticlePtr> ArticleList;
typedef QList<FilePtr> FileList;
QStringList pathHierarchy() const;
/**
* Parent interface for Rss::Folder and Rss::Feed.
*/
class File
{
public:
virtual ~File();
protected:
uint m_unreadCount;
};
virtual uint unreadCount() const = 0;
virtual QString displayName() const = 0;
virtual QString id() const = 0;
virtual QString iconPath() const = 0;
virtual void rename(const QString &newName) = 0;
virtual void markAsRead() = 0;
virtual Folder *parent() const = 0;
virtual void setParent(Folder *parent) = 0;
virtual bool refresh() = 0;
virtual ArticleList articleListByDateDesc() const = 0;
virtual ArticleList unreadArticleListByDateDesc() const = 0;
virtual void removeAllSettings() = 0;
virtual void saveItemsToDisk() = 0;
virtual void recheckRssItemsForDownload() = 0;
QStringList pathHierarchy() const;
protected:
uint m_unreadCount;
};
}
#endif // RSSFILE_H

View File

@@ -38,61 +38,63 @@
#include "rssarticle.h"
#include "rssfolder.h"
RssFolder::RssFolder(RssFolder *parent, const QString &name)
using namespace Rss;
Folder::Folder(Folder *parent, const QString &name)
: m_parent(parent)
, m_name(name)
{
}
RssFolder::~RssFolder() {}
Folder::~Folder() {}
RssFolder *RssFolder::parent() const
Folder *Folder::parent() const
{
return m_parent;
}
void RssFolder::setParent(RssFolder *parent)
void Folder::setParent(Folder *parent)
{
m_parent = parent;
}
uint RssFolder::unreadCount() const
uint Folder::unreadCount() const
{
uint nbUnread = 0;
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
for ( ; it != itend; ++it)
nbUnread += it.value()->unreadCount();
return nbUnread;
}
void RssFolder::removeChild(const QString &childId)
void Folder::removeChild(const QString &childId)
{
if (m_children.contains(childId)) {
RssFilePtr child = m_children.take(childId);
FilePtr child = m_children.take(childId);
child->removeAllSettings();
}
}
RssFolderPtr RssFolder::addFolder(const QString &name)
FolderPtr Folder::addFolder(const QString &name)
{
RssFolderPtr subfolder;
FolderPtr subfolder;
if (!m_children.contains(name)) {
subfolder = RssFolderPtr(new RssFolder(this, name));
subfolder = FolderPtr(new Folder(this, name));
m_children[name] = subfolder;
}
else {
subfolder = qSharedPointerDynamicCast<RssFolder>(m_children.value(name));
subfolder = qSharedPointerDynamicCast<Folder>(m_children.value(name));
}
return subfolder;
}
RssFeedPtr RssFolder::addStream(RssManager *manager, const QString &url)
FeedPtr Folder::addStream(Manager *manager, const QString &url)
{
qDebug() << Q_FUNC_INFO << manager << url;
RssFeedPtr stream(new RssFeed(manager, this, url));
FeedPtr stream(new Feed(manager, this, url));
Q_ASSERT(stream);
qDebug() << "Stream URL is " << stream->url();
Q_ASSERT(!m_children.contains(stream->url()));
@@ -102,10 +104,10 @@ RssFeedPtr RssFolder::addStream(RssManager *manager, const QString &url)
}
// Refresh All Children
bool RssFolder::refresh()
bool Folder::refresh()
{
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
bool refreshed = false;
for ( ; it != itend; ++it) {
if (it.value()->refresh())
@@ -114,47 +116,47 @@ bool RssFolder::refresh()
return refreshed;
}
RssArticleList RssFolder::articleListByDateDesc() const
ArticleList Folder::articleListByDateDesc() const
{
RssArticleList news;
ArticleList news;
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
for ( ; it != itend; ++it) {
int n = news.size();
news << it.value()->articleListByDateDesc();
std::inplace_merge(news.begin(), news.begin() + n, news.end(), rssArticleDateRecentThan);
std::inplace_merge(news.begin(), news.begin() + n, news.end(), articleDateRecentThan);
}
return news;
}
RssArticleList RssFolder::unreadArticleListByDateDesc() const
ArticleList Folder::unreadArticleListByDateDesc() const
{
RssArticleList unreadNews;
ArticleList unreadNews;
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
for ( ; it != itend; ++it) {
int n = unreadNews.size();
unreadNews << it.value()->unreadArticleListByDateDesc();
std::inplace_merge(unreadNews.begin(), unreadNews.begin() + n, unreadNews.end(), rssArticleDateRecentThan);
std::inplace_merge(unreadNews.begin(), unreadNews.begin() + n, unreadNews.end(), articleDateRecentThan);
}
return unreadNews;
}
RssFileList RssFolder::getContent() const
FileList Folder::getContent() const
{
return m_children.values();
}
uint RssFolder::getNbFeeds() const
uint Folder::getNbFeeds() const
{
uint nbFeeds = 0;
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
for ( ; it != itend; ++it) {
if (RssFolderPtr folder = qSharedPointerDynamicCast<RssFolder>(it.value()))
if (FolderPtr folder = qSharedPointerDynamicCast<Folder>(it.value()))
nbFeeds += folder->getNbFeeds();
else
++nbFeeds; // Feed
@@ -162,12 +164,12 @@ uint RssFolder::getNbFeeds() const
return nbFeeds;
}
QString RssFolder::displayName() const
QString Folder::displayName() const
{
return m_name;
}
void RssFolder::rename(const QString &newName)
void Folder::rename(const QString &newName)
{
if (m_name == newName) return;
@@ -180,56 +182,56 @@ void RssFolder::rename(const QString &newName)
}
}
void RssFolder::markAsRead()
void Folder::markAsRead()
{
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
for ( ; it != itend; ++it) {
it.value()->markAsRead();
}
}
RssFeedList RssFolder::getAllFeeds() const
FeedList Folder::getAllFeeds() const
{
RssFeedList streams;
FeedList streams;
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
for ( ; it != itend; ++it) {
if (RssFeedPtr feed = qSharedPointerDynamicCast<RssFeed>(it.value()))
if (FeedPtr feed = qSharedPointerDynamicCast<Feed>(it.value()))
streams << feed;
else if (RssFolderPtr folder = qSharedPointerDynamicCast<RssFolder>(it.value()))
else if (FolderPtr folder = qSharedPointerDynamicCast<Folder>(it.value()))
streams << folder->getAllFeeds();
}
return streams;
}
QHash<QString, RssFeedPtr> RssFolder::getAllFeedsAsHash() const
QHash<QString, FeedPtr> Folder::getAllFeedsAsHash() const
{
QHash<QString, RssFeedPtr> ret;
QHash<QString, FeedPtr> ret;
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
for ( ; it != itend; ++it) {
if (RssFeedPtr feed = qSharedPointerDynamicCast<RssFeed>(it.value())) {
if (FeedPtr feed = qSharedPointerDynamicCast<Feed>(it.value())) {
qDebug() << Q_FUNC_INFO << feed->url();
ret[feed->url()] = feed;
}
else if (RssFolderPtr folder = qSharedPointerDynamicCast<RssFolder>(it.value())) {
else if (FolderPtr folder = qSharedPointerDynamicCast<Folder>(it.value())) {
ret.unite(folder->getAllFeedsAsHash());
}
}
return ret;
}
void RssFolder::addFile(const RssFilePtr &item)
void Folder::addFile(const FilePtr &item)
{
if (RssFeedPtr feed = qSharedPointerDynamicCast<RssFeed>(item)) {
if (FeedPtr feed = qSharedPointerDynamicCast<Feed>(item)) {
Q_ASSERT(!m_children.contains(feed->url()));
m_children[feed->url()] = item;
qDebug("Added feed %s to folder ./%s", qPrintable(feed->url()), qPrintable(m_name));
}
else if (RssFolderPtr folder = qSharedPointerDynamicCast<RssFolder>(item)) {
else if (FolderPtr folder = qSharedPointerDynamicCast<Folder>(item)) {
Q_ASSERT(!m_children.contains(folder->displayName()));
m_children[folder->displayName()] = item;
qDebug("Added folder %s to folder ./%s", qPrintable(folder->displayName()), qPrintable(m_name));
@@ -238,56 +240,56 @@ void RssFolder::addFile(const RssFilePtr &item)
item->setParent(this);
}
void RssFolder::removeAllItems()
void Folder::removeAllItems()
{
m_children.clear();
}
void RssFolder::removeAllSettings()
void Folder::removeAllSettings()
{
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
for ( ; it != itend; ++it)
it.value()->removeAllSettings();
}
void RssFolder::saveItemsToDisk()
void Folder::saveItemsToDisk()
{
foreach (const RssFilePtr &child, m_children.values())
foreach (const FilePtr &child, m_children.values())
child->saveItemsToDisk();
}
QString RssFolder::id() const
QString Folder::id() const
{
return m_name;
}
QString RssFolder::iconPath() const
QString Folder::iconPath() const
{
return IconProvider::instance()->getIconPath("inode-directory");
}
bool RssFolder::hasChild(const QString &childId)
bool Folder::hasChild(const QString &childId)
{
return m_children.contains(childId);
}
void RssFolder::renameChildFolder(const QString &oldName, const QString &newName)
void Folder::renameChildFolder(const QString &oldName, const QString &newName)
{
Q_ASSERT(m_children.contains(oldName));
RssFilePtr folder = m_children.take(oldName);
FilePtr folder = m_children.take(oldName);
m_children[newName] = folder;
}
RssFilePtr RssFolder::takeChild(const QString &childId)
FilePtr Folder::takeChild(const QString &childId)
{
return m_children.take(childId);
}
void RssFolder::recheckRssItemsForDownload()
void Folder::recheckRssItemsForDownload()
{
RssFileHash::ConstIterator it = m_children.begin();
RssFileHash::ConstIterator itend = m_children.end();
FileHash::ConstIterator it = m_children.begin();
FileHash::ConstIterator itend = m_children.end();
for ( ; it != itend; ++it)
it.value()->recheckRssItemsForDownload();
}

View File

@@ -37,56 +37,59 @@
#include "rssfile.h"
class RssFolder;
class RssFeed;
class RssManager;
typedef QHash<QString, RssFilePtr> RssFileHash;
typedef QSharedPointer<RssFeed> RssFeedPtr;
typedef QSharedPointer<RssFolder> RssFolderPtr;
typedef QList<RssFeedPtr> RssFeedList;
class RssFolder: public QObject, public RssFile
namespace Rss
{
Q_OBJECT
class Folder;
class Feed;
class Manager;
public:
explicit RssFolder(RssFolder *parent = 0, const QString &name = QString());
~RssFolder();
typedef QHash<QString, FilePtr> FileHash;
typedef QSharedPointer<Feed> FeedPtr;
typedef QSharedPointer<Folder> FolderPtr;
typedef QList<FeedPtr> FeedList;
RssFolder *parent() const;
void setParent(RssFolder *parent);
uint unreadCount() const;
RssFeedPtr addStream(RssManager *manager, const QString &url);
RssFolderPtr addFolder(const QString &name);
uint getNbFeeds() const;
RssFileList getContent() const;
RssFeedList getAllFeeds() const;
QHash<QString, RssFeedPtr> getAllFeedsAsHash() const;
QString displayName() const;
QString id() const;
QString iconPath() const;
bool hasChild(const QString &childId);
RssArticleList articleListByDateDesc() const;
RssArticleList unreadArticleListByDateDesc() const;
void removeAllSettings();
void saveItemsToDisk();
void removeAllItems();
void renameChildFolder(const QString &oldName, const QString &newName);
RssFilePtr takeChild(const QString &childId);
void recheckRssItemsForDownload();
class Folder: public QObject, public File
{
Q_OBJECT
public slots:
bool refresh();
void addFile(const RssFilePtr &item);
void removeChild(const QString &childId);
void rename(const QString &newName);
void markAsRead();
public:
explicit Folder(Folder *parent = 0, const QString &name = QString());
~Folder();
private:
RssFolder *m_parent;
QString m_name;
RssFileHash m_children;
};
Folder *parent() const;
void setParent(Folder *parent);
uint unreadCount() const;
FeedPtr addStream(Manager *manager, const QString &url);
FolderPtr addFolder(const QString &name);
uint getNbFeeds() const;
FileList getContent() const;
FeedList getAllFeeds() const;
QHash<QString, FeedPtr> getAllFeedsAsHash() const;
QString displayName() const;
QString id() const;
QString iconPath() const;
bool hasChild(const QString &childId);
ArticleList articleListByDateDesc() const;
ArticleList unreadArticleListByDateDesc() const;
void removeAllSettings();
void saveItemsToDisk();
void removeAllItems();
void renameChildFolder(const QString &oldName, const QString &newName);
FilePtr takeChild(const QString &childId);
void recheckRssItemsForDownload();
public slots:
bool refresh();
void addFile(const FilePtr &item);
void removeChild(const QString &childId);
void rename(const QString &newName);
void markAsRead();
private:
Folder *m_parent;
QString m_name;
FileHash m_children;
};
}
#endif // RSSFOLDER_H

View File

@@ -41,16 +41,18 @@
static const int MSECS_PER_MIN = 60000;
RssManager::RssManager()
: m_downloadRules(new RssDownloadRuleList)
, m_rssParser(new RssParser(this))
using namespace Rss;
Manager::Manager()
: m_downloadRules(new DownloadRuleList)
, m_rssParser(new Parser(this))
{
connect(&m_refreshTimer, SIGNAL(timeout()), SLOT(refresh()));
m_refreshInterval = Preferences::instance()->getRSSRefreshInterval();
m_refreshTimer.start(m_refreshInterval * MSECS_PER_MIN);
}
RssManager::~RssManager()
Manager::~Manager()
{
qDebug("Deleting RSSManager...");
delete m_downloadRules;
@@ -60,12 +62,12 @@ RssManager::~RssManager()
qDebug("RSSManager deleted");
}
RssParser *RssManager::rssParser() const
Parser *Manager::rssParser() const
{
return m_rssParser;
}
void RssManager::updateRefreshInterval(uint val)
void Manager::updateRefreshInterval(uint val)
{
if (m_refreshInterval != val) {
m_refreshInterval = val;
@@ -74,7 +76,7 @@ void RssManager::updateRefreshInterval(uint val)
}
}
void RssManager::loadStreamList()
void Manager::loadStreamList()
{
const Preferences *const pref = Preferences::instance();
const QStringList streamsUrl = pref->getRssFeedsUrls();
@@ -93,14 +95,14 @@ void RssManager::loadStreamList()
const QString feedUrl = path.takeLast();
qDebug() << "Feed URL:" << feedUrl;
// Create feed path (if it does not exists)
RssFolder *feedParent = this;
Folder *feedParent = this;
foreach (const QString &folderName, path) {
qDebug() << "Adding parent folder:" << folderName;
feedParent = feedParent->addFolder(folderName).data();
}
// Create feed
qDebug() << "Adding feed to parent folder";
RssFeedPtr stream = feedParent->addStream(this, feedUrl);
FeedPtr stream = feedParent->addStream(this, feedUrl);
const QString &alias = aliases[i];
if (!alias.isEmpty())
stream->rename(alias);
@@ -109,24 +111,24 @@ void RssManager::loadStreamList()
qDebug("NB RSS streams loaded: %d", streamsUrl.size());
}
void RssManager::forwardFeedContentChanged(const QString &url)
void Manager::forwardFeedContentChanged(const QString &url)
{
emit feedContentChanged(url);
}
void RssManager::forwardFeedInfosChanged(const QString &url, const QString &displayName, uint unreadCount)
void Manager::forwardFeedInfosChanged(const QString &url, const QString &displayName, uint unreadCount)
{
emit feedInfosChanged(url, displayName, unreadCount);
}
void RssManager::forwardFeedIconChanged(const QString &url, const QString &iconPath)
void Manager::forwardFeedIconChanged(const QString &url, const QString &iconPath)
{
emit feedIconChanged(url, iconPath);
}
void RssManager::moveFile(const RssFilePtr &file, const RssFolderPtr &destinationFolder)
void Manager::moveFile(const FilePtr &file, const FolderPtr &destinationFolder)
{
RssFolder *srcFolder = file->parent();
Folder *srcFolder = file->parent();
if (destinationFolder != srcFolder) {
// Remove reference in old folder
srcFolder->takeChild(file->id());
@@ -138,12 +140,12 @@ void RssManager::moveFile(const RssFilePtr &file, const RssFolderPtr &destinatio
}
}
void RssManager::saveStreamList() const
void Manager::saveStreamList() const
{
QStringList streamsUrl;
QStringList aliases;
RssFeedList streams = getAllFeeds();
foreach (const RssFeedPtr &stream, streams) {
FeedList streams = getAllFeeds();
foreach (const FeedPtr &stream, streams) {
// This backslash has nothing to do with path handling
QString streamPath = stream->pathHierarchy().join("\\");
if (streamPath.isNull())
@@ -157,7 +159,7 @@ void RssManager::saveStreamList() const
pref->setRssFeedsAliases(aliases);
}
RssDownloadRuleList *RssManager::downloadRules() const
DownloadRuleList *Manager::downloadRules() const
{
Q_ASSERT(m_downloadRules);
return m_downloadRules;

View File

@@ -37,42 +37,45 @@
#include "rssfolder.h"
class RssDownloadRuleList;
class RssParser;
class RssManager;
typedef QSharedPointer<RssManager> RssManagerPtr;
class RssManager: public RssFolder
namespace Rss
{
Q_OBJECT
class DownloadRuleList;
class Parser;
class Manager;
public:
RssManager();
~RssManager();
typedef QSharedPointer<Manager> ManagerPtr;
RssParser *rssParser() const;
RssDownloadRuleList *downloadRules() const;
class Manager: public Folder
{
Q_OBJECT
public slots:
void loadStreamList();
void saveStreamList() const;
void forwardFeedContentChanged(const QString &url);
void forwardFeedInfosChanged(const QString &url, const QString &displayName, uint unreadCount);
void forwardFeedIconChanged(const QString &url, const QString &iconPath);
void moveFile(const RssFilePtr &file, const RssFolderPtr &destinationFolder);
void updateRefreshInterval(uint val);
public:
Manager();
~Manager();
signals:
void feedContentChanged(const QString &url);
void feedInfosChanged(const QString &url, const QString &displayName, uint unreadCount);
void feedIconChanged(const QString &url, const QString &iconPath);
Parser *rssParser() const;
DownloadRuleList *downloadRules() const;
private:
QTimer m_refreshTimer;
uint m_refreshInterval;
RssDownloadRuleList *m_downloadRules;
RssParser *m_rssParser;
};
public slots:
void loadStreamList();
void saveStreamList() const;
void forwardFeedContentChanged(const QString &url);
void forwardFeedInfosChanged(const QString &url, const QString &displayName, uint unreadCount);
void forwardFeedIconChanged(const QString &url, const QString &iconPath);
void moveFile(const FilePtr &file, const FolderPtr &destinationFolder);
void updateRefreshInterval(uint val);
signals:
void feedContentChanged(const QString &url);
void feedInfosChanged(const QString &url, const QString &displayName, uint unreadCount);
void feedIconChanged(const QString &url, const QString &iconPath);
private:
QTimer m_refreshTimer;
uint m_refreshInterval;
DownloadRuleList *m_downloadRules;
Parser *m_rssParser;
};
}
#endif // RSSMANAGER_H

View File

@@ -37,11 +37,14 @@
#include "base/utils/fs.h"
#include "rssparser.h"
struct ParsingJob
namespace Rss
{
QString feedUrl;
QString filePath;
};
struct ParsingJob
{
QString feedUrl;
QString filePath;
};
}
static const char shortDay[][4] = {
"Mon", "Tue", "Wed",
@@ -61,8 +64,24 @@ static const char shortMonth[][4] = {
"Sep", "Oct", "Nov", "Dec"
};
using namespace Rss;
Parser::Parser(QObject *parent)
: QThread(parent)
, m_running(true)
{
start();
}
Parser::~Parser()
{
m_running = false;
m_waitCondition.wakeOne();
wait();
}
// Ported to Qt from KDElibs4
QDateTime RssParser::parseDate(const QString &string)
QDateTime Parser::parseDate(const QString &string)
{
const QString str = string.trimmed();
if (str.isEmpty())
@@ -208,21 +227,7 @@ QDateTime RssParser::parseDate(const QString &string)
return result;
}
RssParser::RssParser(QObject *parent)
: QThread(parent)
, m_running(true)
{
start();
}
RssParser::~RssParser()
{
m_running = false;
m_waitCondition.wakeOne();
wait();
}
void RssParser::parseRssFile(const QString &feedUrl, const QString &filePath)
void Parser::parseRssFile(const QString &feedUrl, const QString &filePath)
{
qDebug() << Q_FUNC_INFO << feedUrl << filePath;
m_mutex.lock();
@@ -236,14 +241,14 @@ void RssParser::parseRssFile(const QString &feedUrl, const QString &filePath)
m_mutex.unlock();
}
void RssParser::clearFeedData(const QString &feedUrl)
void Parser::clearFeedData(const QString &feedUrl)
{
m_mutex.lock();
m_lastBuildDates.remove(feedUrl);
m_mutex.unlock();
}
void RssParser::run()
void Parser::run()
{
while (m_running) {
m_mutex.lock();
@@ -261,7 +266,7 @@ void RssParser::run()
}
}
void RssParser::parseRssArticle(QXmlStreamReader &xml, const QString &feedUrl)
void Parser::parseRssArticle(QXmlStreamReader &xml, const QString &feedUrl)
{
QVariantHash article;
@@ -325,7 +330,7 @@ void RssParser::parseRssArticle(QXmlStreamReader &xml, const QString &feedUrl)
emit newArticle(feedUrl, article);
}
void RssParser::parseRSSChannel(QXmlStreamReader &xml, const QString &feedUrl)
void Parser::parseRSSChannel(QXmlStreamReader &xml, const QString &feedUrl)
{
qDebug() << Q_FUNC_INFO << feedUrl;
Q_ASSERT(xml.isStartElement() && xml.name() == "channel");
@@ -356,7 +361,7 @@ void RssParser::parseRSSChannel(QXmlStreamReader &xml, const QString &feedUrl)
}
}
void RssParser::parseAtomArticle(QXmlStreamReader &xml, const QString &feedUrl, const QString &baseUrl)
void Parser::parseAtomArticle(QXmlStreamReader &xml, const QString &feedUrl, const QString &baseUrl)
{
QVariantHash article;
bool doubleContent = false;
@@ -446,7 +451,7 @@ void RssParser::parseAtomArticle(QXmlStreamReader &xml, const QString &feedUrl,
emit newArticle(feedUrl, article);
}
void RssParser::parseAtomChannel(QXmlStreamReader &xml, const QString &feedUrl)
void Parser::parseAtomChannel(QXmlStreamReader &xml, const QString &feedUrl)
{
qDebug() << Q_FUNC_INFO << feedUrl;
Q_ASSERT(xml.isStartElement() && xml.name() == "feed");
@@ -480,7 +485,7 @@ void RssParser::parseAtomChannel(QXmlStreamReader &xml, const QString &feedUrl)
}
// read and create items from a rss document
void RssParser::parseFeed(const ParsingJob &job)
void Parser::parseFeed(const ParsingJob &job)
{
qDebug() << Q_FUNC_INFO << job.feedUrl << job.filePath;
QFile fileRss(job.filePath);
@@ -534,7 +539,7 @@ void RssParser::parseFeed(const ParsingJob &job)
Utils::Fs::forceRemove(job.filePath);
}
void RssParser::reportFailure(const ParsingJob &job, const QString &error)
void Parser::reportFailure(const ParsingJob &job, const QString &error)
{
emit feedParsingFinished(job.feedUrl, error);
Utils::Fs::forceRemove(job.filePath);

View File

@@ -38,42 +38,45 @@
#include "rssarticle.h"
struct ParsingJob;
class RssParser: public QThread
namespace Rss
{
Q_OBJECT
struct ParsingJob;
public:
explicit RssParser(QObject *parent = 0);
virtual ~RssParser();
class Parser: public QThread
{
Q_OBJECT
signals:
void newArticle(const QString &feedUrl, const QVariantHash &rssArticle);
void feedTitle(const QString &feedUrl, const QString &title);
void feedParsingFinished(const QString &feedUrl, const QString &error);
public:
explicit Parser(QObject *parent = 0);
virtual ~Parser();
public slots:
void parseRssFile(const QString &feedUrl, const QString &filePath);
void clearFeedData(const QString &feedUrl);
signals:
void newArticle(const QString &feedUrl, const QVariantHash &rssArticle);
void feedTitle(const QString &feedUrl, const QString &title);
void feedParsingFinished(const QString &feedUrl, const QString &error);
protected:
virtual void run();
public slots:
void parseRssFile(const QString &feedUrl, const QString &filePath);
void clearFeedData(const QString &feedUrl);
private:
static QDateTime parseDate(const QString &string);
void parseRssArticle(QXmlStreamReader &xml, const QString &feedUrl);
void parseRSSChannel(QXmlStreamReader &xml, const QString &feedUrl);
void parseAtomArticle(QXmlStreamReader &xml, const QString &feedUrl, const QString &baseUrl);
void parseAtomChannel(QXmlStreamReader &xml, const QString &feedUrl);
void parseFeed(const ParsingJob &job);
void reportFailure(const ParsingJob &job, const QString &error);
protected:
virtual void run();
bool m_running;
QMutex m_mutex;
QQueue<ParsingJob> m_queue;
QWaitCondition m_waitCondition;
QHash<QString/*feedUrl*/, QString/*lastBuildDate*/> m_lastBuildDates; // Optimization
};
private:
static QDateTime parseDate(const QString &string);
void parseRssArticle(QXmlStreamReader &xml, const QString &feedUrl);
void parseRSSChannel(QXmlStreamReader &xml, const QString &feedUrl);
void parseAtomArticle(QXmlStreamReader &xml, const QString &feedUrl, const QString &baseUrl);
void parseAtomChannel(QXmlStreamReader &xml, const QString &feedUrl);
void parseFeed(const ParsingJob &job);
void reportFailure(const ParsingJob &job, const QString &error);
bool m_running;
QMutex m_mutex;
QQueue<ParsingJob> m_queue;
QWaitCondition m_waitCondition;
QHash<QString/*feedUrl*/, QString/*lastBuildDate*/> m_lastBuildDates; // Optimization
};
}
#endif // RSSPARSER_H