Browse Source

Move base RSS names to Rss namespace.

adaptive-webui-19844
Vladimir Golovnev (Glassez) 9 years ago committed by Vladimir Golovnev (qlassez)
parent
commit
6f7ae728eb
  1. 36
      src/base/rss/rssarticle.cpp
  2. 83
      src/base/rss/rssarticle.h
  3. 70
      src/base/rss/rssdownloadrule.cpp
  4. 117
      src/base/rss/rssdownloadrule.h
  5. 44
      src/base/rss/rssdownloadrulelist.cpp
  6. 51
      src/base/rss/rssdownloadrulelist.h
  7. 115
      src/base/rss/rssfeed.cpp
  8. 133
      src/base/rss/rssfeed.h
  9. 6
      src/base/rss/rssfile.cpp
  10. 67
      src/base/rss/rssfile.h
  11. 138
      src/base/rss/rssfolder.cpp
  12. 93
      src/base/rss/rssfolder.h
  13. 38
      src/base/rss/rssmanager.cpp
  14. 63
      src/base/rss/rssmanager.h
  15. 61
      src/base/rss/rssparser.cpp
  16. 63
      src/base/rss/rssparser.h
  17. 30
      src/gui/rss/automatedrssdownloader.cpp
  18. 19
      src/gui/rss/automatedrssdownloader.h
  19. 36
      src/gui/rss/feedlistwidget.cpp
  20. 12
      src/gui/rss/feedlistwidget.h
  21. 66
      src/gui/rss/rss_imp.cpp
  22. 8
      src/gui/rss/rss_imp.h

36
src/base/rss/rssarticle.cpp

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

83
src/base/rss/rssarticle.h

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

70
src/base/rss/rssdownloadrule.cpp

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

117
src/base/rss/rssdownloadrule.h

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

44
src/base/rss/rssdownloadrulelist.cpp

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

51
src/base/rss/rssdownloadrulelist.h

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

115
src/base/rss/rssfeed.cpp

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

133
src/base/rss/rssfeed.h

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

6
src/base/rss/rssfile.cpp

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

67
src/base/rss/rssfile.h

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

138
src/base/rss/rssfolder.cpp

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

93
src/base/rss/rssfolder.h

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

38
src/base/rss/rssmanager.cpp

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

63
src/base/rss/rssmanager.h

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

61
src/base/rss/rssparser.cpp

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

63
src/base/rss/rssparser.h

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

30
src/gui/rss/automatedrssdownloader.cpp

@ -45,7 +45,7 @@
#include "base/utils/fs.h" #include "base/utils/fs.h"
#include "base/utils/string.h" #include "base/utils/string.h"
AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<RssManager>& manager, QWidget *parent) : AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager>& manager, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::AutomatedRssDownloader), ui(new Ui::AutomatedRssDownloader),
m_manager(manager), m_editedRule(0) m_manager(manager), m_editedRule(0)
@ -68,7 +68,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<RssManager>& m
ok = connect(ui->listRules, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayRulesListMenu(const QPoint&))); ok = connect(ui->listRules, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayRulesListMenu(const QPoint&)));
Q_ASSERT(ok); Q_ASSERT(ok);
m_ruleList = manager.toStrongRef()->downloadRules(); m_ruleList = manager.toStrongRef()->downloadRules();
m_editableRuleList = new RssDownloadRuleList; // Read rule list from disk m_editableRuleList = new Rss::DownloadRuleList; // Read rule list from disk
m_episodeValidator = new QRegExpValidator( m_episodeValidator = new QRegExpValidator(
QRegExp("^(^[1-9]{1,1}\\d{0,3}x([1-9]{1,1}\\d{0,3}(-([1-9]{1,1}\\d{0,3})?)?;){1,}){1,1}", QRegExp("^(^[1-9]{1,1}\\d{0,3}x([1-9]{1,1}\\d{0,3}(-([1-9]{1,1}\\d{0,3})?)?;){1,}){1,1}",
Qt::CaseInsensitive), Qt::CaseInsensitive),
@ -199,7 +199,7 @@ void AutomatedRssDownloader::updateFeedList()
const QString feed_url = item->data(Qt::UserRole).toString(); const QString feed_url = item->data(Qt::UserRole).toString();
bool all_enabled = false; bool all_enabled = false;
foreach (const QListWidgetItem *ruleItem, ui->listRules->selectedItems()) { foreach (const QListWidgetItem *ruleItem, ui->listRules->selectedItems()) {
RssDownloadRulePtr rule = m_editableRuleList->getRule(ruleItem->text()); Rss::DownloadRulePtr rule = m_editableRuleList->getRule(ruleItem->text());
if (!rule) continue; if (!rule) continue;
qDebug() << "Rule" << rule->name() << "affects" << rule->rssFeeds().size() << "feeds."; qDebug() << "Rule" << rule->name() << "affects" << rule->rssFeeds().size() << "feeds.";
foreach (QString test, rule->rssFeeds()) { foreach (QString test, rule->rssFeeds()) {
@ -238,7 +238,7 @@ void AutomatedRssDownloader::updateRuleDefinitionBox()
const QList<QListWidgetItem*> selection = ui->listRules->selectedItems(); const QList<QListWidgetItem*> selection = ui->listRules->selectedItems();
if (selection.count() == 1) { if (selection.count() == 1) {
m_editedRule = selection.first(); m_editedRule = selection.first();
RssDownloadRulePtr rule = getCurrentRule(); Rss::DownloadRulePtr rule = getCurrentRule();
if (rule) { if (rule) {
ui->lineContains->setText(rule->mustContain()); ui->lineContains->setText(rule->mustContain());
ui->lineNotContains->setText(rule->mustNotContain()); ui->lineNotContains->setText(rule->mustNotContain());
@ -300,12 +300,12 @@ void AutomatedRssDownloader::clearRuleDefinitionBox()
updateMustNotLineValidity(); updateMustNotLineValidity();
} }
RssDownloadRulePtr AutomatedRssDownloader::getCurrentRule() const Rss::DownloadRulePtr AutomatedRssDownloader::getCurrentRule() const
{ {
QListWidgetItem * current_item = ui->listRules->currentItem(); QListWidgetItem * current_item = ui->listRules->currentItem();
if (current_item) if (current_item)
return m_editableRuleList->getRule(current_item->text()); return m_editableRuleList->getRule(current_item->text());
return RssDownloadRulePtr(); return Rss::DownloadRulePtr();
} }
void AutomatedRssDownloader::initLabelCombobox() void AutomatedRssDownloader::initLabelCombobox()
@ -326,9 +326,9 @@ void AutomatedRssDownloader::saveEditedRule()
qDebug() << "Probably removed the item, no need to save it"; qDebug() << "Probably removed the item, no need to save it";
return; return;
} }
RssDownloadRulePtr rule = m_editableRuleList->getRule(m_editedRule->text()); Rss::DownloadRulePtr rule = m_editableRuleList->getRule(m_editedRule->text());
if (!rule) { if (!rule) {
rule = RssDownloadRulePtr(new RssDownloadRule); rule = Rss::DownloadRulePtr(new Rss::DownloadRule);
rule->setName(m_editedRule->text()); rule->setName(m_editedRule->text());
} }
if (m_editedRule->checkState() == Qt::Unchecked) if (m_editedRule->checkState() == Qt::Unchecked)
@ -344,7 +344,7 @@ void AutomatedRssDownloader::saveEditedRule()
else else
rule->setSavePath(""); rule->setSavePath("");
rule->setLabel(ui->comboLabel->currentText()); rule->setLabel(ui->comboLabel->currentText());
rule->setAddPaused(RssDownloadRule::AddPausedState(ui->comboAddPaused->currentIndex())); rule->setAddPaused(Rss::DownloadRule::AddPausedState(ui->comboAddPaused->currentIndex()));
// Save new label // Save new label
if (!rule->label().isEmpty()) if (!rule->label().isEmpty())
Preferences::instance()->addTorrentLabelExternal(rule->label()); Preferences::instance()->addTorrentLabelExternal(rule->label());
@ -498,7 +498,7 @@ void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feed_it
} }
const QString feed_url = feed_item->data(Qt::UserRole).toString(); const QString feed_url = feed_item->data(Qt::UserRole).toString();
foreach (QListWidgetItem* rule_item, ui->listRules->selectedItems()) { foreach (QListWidgetItem* rule_item, ui->listRules->selectedItems()) {
RssDownloadRulePtr rule = m_editableRuleList->getRule(rule_item->text()); Rss::DownloadRulePtr rule = m_editableRuleList->getRule(rule_item->text());
Q_ASSERT(rule); Q_ASSERT(rule);
QStringList affected_feeds = rule->rssFeeds(); QStringList affected_feeds = rule->rssFeeds();
if (feed_item->checkState() == Qt::Checked) { if (feed_item->checkState() == Qt::Checked) {
@ -521,19 +521,19 @@ void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feed_it
void AutomatedRssDownloader::updateMatchingArticles() void AutomatedRssDownloader::updateMatchingArticles()
{ {
ui->treeMatchingArticles->clear(); ui->treeMatchingArticles->clear();
RssManagerPtr manager = m_manager.toStrongRef(); Rss::ManagerPtr manager = m_manager.toStrongRef();
if (!manager) if (!manager)
return; return;
const QHash<QString, RssFeedPtr> all_feeds = manager->getAllFeedsAsHash(); const QHash<QString, Rss::FeedPtr> all_feeds = manager->getAllFeedsAsHash();
saveEditedRule(); saveEditedRule();
foreach (const QListWidgetItem *rule_item, ui->listRules->selectedItems()) { foreach (const QListWidgetItem *rule_item, ui->listRules->selectedItems()) {
RssDownloadRulePtr rule = m_editableRuleList->getRule(rule_item->text()); Rss::DownloadRulePtr rule = m_editableRuleList->getRule(rule_item->text());
if (!rule) continue; if (!rule) continue;
foreach (const QString &feed_url, rule->rssFeeds()) { foreach (const QString &feed_url, rule->rssFeeds()) {
qDebug() << Q_FUNC_INFO << feed_url; qDebug() << Q_FUNC_INFO << feed_url;
if (!all_feeds.contains(feed_url)) continue; // Feed was removed if (!all_feeds.contains(feed_url)) continue; // Feed was removed
RssFeedPtr feed = all_feeds.value(feed_url); Rss::FeedPtr feed = all_feeds.value(feed_url);
Q_ASSERT(feed); Q_ASSERT(feed);
if (!feed) continue; if (!feed) continue;
const QStringList matching_articles = rule->findMatchingArticles(feed); const QStringList matching_articles = rule->findMatchingArticles(feed);
@ -543,7 +543,7 @@ void AutomatedRssDownloader::updateMatchingArticles()
} }
} }
void AutomatedRssDownloader::addFeedArticlesToTree(const RssFeedPtr& feed, const QStringList &articles) void AutomatedRssDownloader::addFeedArticlesToTree(const Rss::FeedPtr& feed, const QStringList &articles)
{ {
// Check if this feed is already in the tree // Check if this feed is already in the tree
QTreeWidgetItem *treeFeedItem = 0; QTreeWidgetItem *treeFeedItem = 0;

19
src/gui/rss/automatedrssdownloader.h

@ -44,8 +44,11 @@ class AutomatedRssDownloader;
} }
QT_END_NAMESPACE QT_END_NAMESPACE
class RssDownloadRuleList; namespace Rss
class RssManager; {
class DownloadRuleList;
class Manager;
}
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QListWidgetItem; class QListWidgetItem;
@ -56,7 +59,7 @@ class AutomatedRssDownloader : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit AutomatedRssDownloader(const QWeakPointer<RssManager>& manager, QWidget *parent = 0); explicit AutomatedRssDownloader(const QWeakPointer<Rss::Manager>& manager, QWidget *parent = 0);
~AutomatedRssDownloader(); ~AutomatedRssDownloader();
bool isRssDownloaderEnabled() const; bool isRssDownloaderEnabled() const;
@ -86,16 +89,16 @@ private slots:
void onFinished(int result); void onFinished(int result);
private: private:
RssDownloadRulePtr getCurrentRule() const; Rss::DownloadRulePtr getCurrentRule() const;
void initLabelCombobox(); void initLabelCombobox();
void addFeedArticlesToTree(const RssFeedPtr& feed, const QStringList& articles); void addFeedArticlesToTree(const Rss::FeedPtr& feed, const QStringList& articles);
private: private:
Ui::AutomatedRssDownloader *ui; Ui::AutomatedRssDownloader *ui;
QWeakPointer<RssManager> m_manager; QWeakPointer<Rss::Manager> m_manager;
QListWidgetItem* m_editedRule; QListWidgetItem* m_editedRule;
RssDownloadRuleList *m_ruleList; Rss::DownloadRuleList *m_ruleList;
RssDownloadRuleList *m_editableRuleList; Rss::DownloadRuleList *m_editableRuleList;
QRegExpValidator *m_episodeValidator; QRegExpValidator *m_episodeValidator;
QShortcut *editHotkey; QShortcut *editHotkey;
QShortcut *deleteHotkey; QShortcut *deleteHotkey;

36
src/gui/rss/feedlistwidget.cpp

@ -33,7 +33,7 @@
#include "guiiconprovider.h" #include "guiiconprovider.h"
#include "feedlistwidget.h" #include "feedlistwidget.h"
FeedListWidget::FeedListWidget(QWidget *parent, const RssManagerPtr& rssmanager): QTreeWidget(parent), m_rssManager(rssmanager) { FeedListWidget::FeedListWidget(QWidget *parent, const Rss::ManagerPtr& rssmanager): QTreeWidget(parent), m_rssManager(rssmanager) {
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);
setDragDropMode(QAbstractItemView::InternalMove); setDragDropMode(QAbstractItemView::InternalMove);
setSelectionMode(QAbstractItemView::ExtendedSelection); setSelectionMode(QAbstractItemView::ExtendedSelection);
@ -51,20 +51,20 @@ FeedListWidget::~FeedListWidget() {
delete m_unreadStickyItem; delete m_unreadStickyItem;
} }
void FeedListWidget::itemAdded(QTreeWidgetItem *item, const RssFilePtr& file) { void FeedListWidget::itemAdded(QTreeWidgetItem *item, const Rss::FilePtr& file) {
m_rssMapping[item] = file; m_rssMapping[item] = file;
if (RssFeedPtr feed = qSharedPointerDynamicCast<RssFeed>(file)) { if (Rss::FeedPtr feed = qSharedPointerDynamicCast<Rss::Feed>(file)) {
m_feedsItems[feed->id()] = item; m_feedsItems[feed->id()] = item;
} }
} }
void FeedListWidget::itemAboutToBeRemoved(QTreeWidgetItem *item) { void FeedListWidget::itemAboutToBeRemoved(QTreeWidgetItem *item) {
RssFilePtr file = m_rssMapping.take(item); Rss::FilePtr file = m_rssMapping.take(item);
if (RssFeedPtr feed = qSharedPointerDynamicCast<RssFeed>(file)) { if (Rss::FeedPtr feed = qSharedPointerDynamicCast<Rss::Feed>(file)) {
m_feedsItems.remove(feed->id()); m_feedsItems.remove(feed->id());
} if (RssFolderPtr folder = qSharedPointerDynamicCast<RssFolder>(file)) { } if (Rss::FolderPtr folder = qSharedPointerDynamicCast<Rss::Folder>(file)) {
RssFeedList feeds = folder->getAllFeeds(); Rss::FeedList feeds = folder->getAllFeeds();
foreach (const RssFeedPtr& feed, feeds) { foreach (const Rss::FeedPtr& feed, feeds) {
m_feedsItems.remove(feed->id()); m_feedsItems.remove(feed->id());
} }
} }
@ -131,18 +131,18 @@ QList<QTreeWidgetItem*> FeedListWidget::getAllFeedItems(QTreeWidgetItem* folder)
return feeds; return feeds;
} }
RssFilePtr FeedListWidget::getRSSItem(QTreeWidgetItem *item) const { Rss::FilePtr FeedListWidget::getRSSItem(QTreeWidgetItem *item) const {
return m_rssMapping.value(item, RssFilePtr()); return m_rssMapping.value(item, Rss::FilePtr());
} }
bool FeedListWidget::isFeed(QTreeWidgetItem *item) const bool FeedListWidget::isFeed(QTreeWidgetItem *item) const
{ {
return (qSharedPointerDynamicCast<RssFeed>(m_rssMapping.value(item)) != NULL); return (qSharedPointerDynamicCast<Rss::Feed>(m_rssMapping.value(item)) != NULL);
} }
bool FeedListWidget::isFolder(QTreeWidgetItem *item) const bool FeedListWidget::isFolder(QTreeWidgetItem *item) const
{ {
return (qSharedPointerDynamicCast<RssFolder>(m_rssMapping.value(item)) != NULL); return (qSharedPointerDynamicCast<Rss::Folder>(m_rssMapping.value(item)) != NULL);
} }
QString FeedListWidget::getItemID(QTreeWidgetItem *item) const { QString FeedListWidget::getItemID(QTreeWidgetItem *item) const {
@ -153,8 +153,8 @@ QTreeWidgetItem* FeedListWidget::getTreeItemFromUrl(const QString &url) const {
return m_feedsItems.value(url, 0); return m_feedsItems.value(url, 0);
} }
RssFeedPtr FeedListWidget::getRSSItemFromUrl(const QString &url) const { Rss::FeedPtr FeedListWidget::getRSSItemFromUrl(const QString &url) const {
return qSharedPointerDynamicCast<RssFeed>(getRSSItem(getTreeItemFromUrl(url))); return qSharedPointerDynamicCast<Rss::Feed>(getRSSItem(getTreeItemFromUrl(url)));
} }
QTreeWidgetItem* FeedListWidget::currentItem() const { QTreeWidgetItem* FeedListWidget::currentItem() const {
@ -197,9 +197,9 @@ void FeedListWidget::dropEvent(QDropEvent *event) {
qDebug("dropEvent"); qDebug("dropEvent");
QList<QTreeWidgetItem*> folders_altered; QList<QTreeWidgetItem*> folders_altered;
QTreeWidgetItem *dest_folder_item = itemAt(event->pos()); QTreeWidgetItem *dest_folder_item = itemAt(event->pos());
RssFolderPtr dest_folder; Rss::FolderPtr dest_folder;
if (dest_folder_item) { if (dest_folder_item) {
dest_folder = qSharedPointerCast<RssFolder>(getRSSItem(dest_folder_item)); dest_folder = qSharedPointerCast<Rss::Folder>(getRSSItem(dest_folder_item));
folders_altered << dest_folder_item; folders_altered << dest_folder_item;
} else { } else {
dest_folder = m_rssManager; dest_folder = m_rssManager;
@ -207,7 +207,7 @@ void FeedListWidget::dropEvent(QDropEvent *event) {
QList<QTreeWidgetItem *> src_items = selectedItems(); QList<QTreeWidgetItem *> src_items = selectedItems();
// Check if there is not going to overwrite another file // Check if there is not going to overwrite another file
foreach (QTreeWidgetItem *src_item, src_items) { foreach (QTreeWidgetItem *src_item, src_items) {
RssFilePtr file = getRSSItem(src_item); Rss::FilePtr file = getRSSItem(src_item);
if (dest_folder->hasChild(file->id())) { if (dest_folder->hasChild(file->id())) {
QTreeWidget::dropEvent(event); QTreeWidget::dropEvent(event);
return; return;
@ -219,7 +219,7 @@ void FeedListWidget::dropEvent(QDropEvent *event) {
if (parent_folder && !folders_altered.contains(parent_folder)) if (parent_folder && !folders_altered.contains(parent_folder))
folders_altered << parent_folder; folders_altered << parent_folder;
// Actually move the file // Actually move the file
RssFilePtr file = getRSSItem(src_item); Rss::FilePtr file = getRSSItem(src_item);
m_rssManager->moveFile(file, dest_folder); m_rssManager->moveFile(file, dest_folder);
} }
QTreeWidget::dropEvent(event); QTreeWidget::dropEvent(event);

12
src/gui/rss/feedlistwidget.h

@ -47,7 +47,7 @@ class FeedListWidget: public QTreeWidget {
Q_OBJECT Q_OBJECT
public: public:
FeedListWidget(QWidget *parent, const RssManagerPtr& rssManager); FeedListWidget(QWidget *parent, const Rss::ManagerPtr& rssManager);
~FeedListWidget(); ~FeedListWidget();
bool hasFeed(const QString &url) const; bool hasFeed(const QString &url) const;
@ -56,17 +56,17 @@ public:
QStringList getItemPath(QTreeWidgetItem* item) const; QStringList getItemPath(QTreeWidgetItem* item) const;
QList<QTreeWidgetItem*> getAllOpenFolders(QTreeWidgetItem *parent=0) const; QList<QTreeWidgetItem*> getAllOpenFolders(QTreeWidgetItem *parent=0) const;
QList<QTreeWidgetItem*> getAllFeedItems(QTreeWidgetItem* folder); QList<QTreeWidgetItem*> getAllFeedItems(QTreeWidgetItem* folder);
RssFilePtr getRSSItem(QTreeWidgetItem *item) const; Rss::FilePtr getRSSItem(QTreeWidgetItem *item) const;
bool isFeed(QTreeWidgetItem *item) const; bool isFeed(QTreeWidgetItem *item) const;
bool isFolder(QTreeWidgetItem *item) const; bool isFolder(QTreeWidgetItem *item) const;
QString getItemID(QTreeWidgetItem *item) const; QString getItemID(QTreeWidgetItem *item) const;
QTreeWidgetItem* getTreeItemFromUrl(const QString &url) const; QTreeWidgetItem* getTreeItemFromUrl(const QString &url) const;
RssFeedPtr getRSSItemFromUrl(const QString &url) const; Rss::FeedPtr getRSSItemFromUrl(const QString &url) const;
QTreeWidgetItem* currentItem() const; QTreeWidgetItem* currentItem() const;
QTreeWidgetItem* currentFeed() const; QTreeWidgetItem* currentFeed() const;
public slots: public slots:
void itemAdded(QTreeWidgetItem *item, const RssFilePtr& file); void itemAdded(QTreeWidgetItem *item, const Rss::FilePtr& file);
void itemAboutToBeRemoved(QTreeWidgetItem *item); void itemAboutToBeRemoved(QTreeWidgetItem *item);
signals: signals:
@ -80,8 +80,8 @@ protected:
void dropEvent(QDropEvent *event); void dropEvent(QDropEvent *event);
private: private:
RssManagerPtr m_rssManager; Rss::ManagerPtr m_rssManager;
QHash<QTreeWidgetItem*, RssFilePtr> m_rssMapping; QHash<QTreeWidgetItem*, Rss::FilePtr> m_rssMapping;
QHash<QString, QTreeWidgetItem*> m_feedsItems; QHash<QString, QTreeWidgetItem*> m_feedsItems;
QTreeWidgetItem* m_currentFeed; QTreeWidgetItem* m_currentFeed;
QTreeWidgetItem *m_unreadStickyItem; QTreeWidgetItem *m_unreadStickyItem;

66
src/gui/rss/rss_imp.cpp

@ -119,9 +119,9 @@ void RSSImp::displayItemsListMenu(const QPoint&)
bool hasLink = false; bool hasLink = false;
foreach (const QListWidgetItem* item, selectedItems) { foreach (const QListWidgetItem* item, selectedItems) {
if (!item) continue; if (!item) continue;
RssFeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString()); Rss::FeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString());
if (!feed) continue; if (!feed) continue;
RssArticlePtr article = feed->getItem(item->data(Article::IdRole).toString()); Rss::ArticlePtr article = feed->getItem(item->data(Article::IdRole).toString());
if (!article) continue; if (!article) continue;
if (!article->torrentUrl().isEmpty()) if (!article->torrentUrl().isEmpty())
@ -160,10 +160,10 @@ void RSSImp::on_actionManage_cookies_triggered()
void RSSImp::askNewFolder() void RSSImp::askNewFolder()
{ {
QTreeWidgetItem* parent_item = 0; QTreeWidgetItem* parent_item = 0;
RssFolderPtr rss_parent; Rss::FolderPtr rss_parent;
if (m_feedList->selectedItems().size() > 0) { if (m_feedList->selectedItems().size() > 0) {
parent_item = m_feedList->selectedItems().at(0); parent_item = m_feedList->selectedItems().at(0);
rss_parent = qSharedPointerDynamicCast<RssFolder>(m_feedList->getRSSItem(parent_item)); rss_parent = qSharedPointerDynamicCast<Rss::Folder>(m_feedList->getRSSItem(parent_item));
Q_ASSERT(rss_parent); Q_ASSERT(rss_parent);
} }
else { else {
@ -174,7 +174,7 @@ void RSSImp::askNewFolder()
if (!ok) if (!ok)
return; return;
RssFolderPtr newFolder = rss_parent->addFolder(new_name); Rss::FolderPtr newFolder = rss_parent->addFolder(new_name);
QTreeWidgetItem* folderItem = createFolderListItem(newFolder); QTreeWidgetItem* folderItem = createFolderListItem(newFolder);
if (parent_item) if (parent_item)
parent_item->addChild(folderItem); parent_item->addChild(folderItem);
@ -203,9 +203,9 @@ void RSSImp::on_newFeedButton_clicked()
if (!m_feedList->isFolder(parent_item)) if (!m_feedList->isFolder(parent_item))
parent_item = parent_item->parent(); parent_item = parent_item->parent();
} }
RssFolderPtr rss_parent; Rss::FolderPtr rss_parent;
if (parent_item) if (parent_item)
rss_parent = qSharedPointerCast<RssFolder>(m_feedList->getRSSItem(parent_item)); rss_parent = qSharedPointerCast<Rss::Folder>(m_feedList->getRSSItem(parent_item));
else else
rss_parent = m_rssManager; rss_parent = m_rssManager;
// Ask for feed URL // Ask for feed URL
@ -229,7 +229,7 @@ void RSSImp::on_newFeedButton_clicked()
QMessageBox::Ok); QMessageBox::Ok);
return; return;
} }
RssFeedPtr stream = rss_parent->addStream(m_rssManager.data(), newUrl); Rss::FeedPtr stream = rss_parent->addStream(m_rssManager.data(), newUrl);
// Create TreeWidget item // Create TreeWidget item
QTreeWidgetItem* item = createFolderListItem(stream); QTreeWidgetItem* item = createFolderListItem(stream);
if (parent_item) if (parent_item)
@ -260,7 +260,7 @@ void RSSImp::deleteSelectedItems()
foreach (QTreeWidgetItem* item, selectedItems) { foreach (QTreeWidgetItem* item, selectedItems) {
if (item == m_feedList->stickyUnreadItem()) if (item == m_feedList->stickyUnreadItem())
continue; continue;
RssFilePtr rss_item = m_feedList->getRSSItem(item); Rss::FilePtr rss_item = m_feedList->getRSSItem(item);
QTreeWidgetItem* parent = item->parent(); QTreeWidgetItem* parent = item->parent();
// Notify TreeWidget // Notify TreeWidget
m_feedList->itemAboutToBeRemoved(item); m_feedList->itemAboutToBeRemoved(item);
@ -273,7 +273,7 @@ void RSSImp::deleteSelectedItems()
parent = parent->parent(); parent = parent->parent();
} }
// Clear feed data from RSS parser (possible caching). // Clear feed data from RSS parser (possible caching).
RssFeed* rssFeed = dynamic_cast<RssFeed*>(rss_item.data()); Rss::Feed* rssFeed = dynamic_cast<Rss::Feed*>(rss_item.data());
if (rssFeed) if (rssFeed)
m_rssManager->rssParser()->clearFeedData(rssFeed->url()); m_rssManager->rssParser()->clearFeedData(rssFeed->url());
} }
@ -341,9 +341,9 @@ void RSSImp::downloadSelectedTorrents()
return; return;
foreach (QListWidgetItem* item, selected_items) { foreach (QListWidgetItem* item, selected_items) {
if (!item) continue; if (!item) continue;
RssFeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString()); Rss::FeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString());
if (!feed) continue; if (!feed) continue;
RssArticlePtr article = feed->getItem(item->data(Article::IdRole).toString()); Rss::ArticlePtr article = feed->getItem(item->data(Article::IdRole).toString());
if (!article) continue; if (!article) continue;
// Mark as read // Mark as read
@ -371,9 +371,9 @@ void RSSImp::openSelectedArticlesUrls()
return; return;
foreach (QListWidgetItem* item, selected_items) { foreach (QListWidgetItem* item, selected_items) {
if (!item) continue; if (!item) continue;
RssFeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString()); Rss::FeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString());
if (!feed) continue; if (!feed) continue;
RssArticlePtr article = feed->getItem(item->data(Article::IdRole).toString()); Rss::ArticlePtr article = feed->getItem(item->data(Article::IdRole).toString());
if (!article) continue; if (!article) continue;
// Mark as read // Mark as read
@ -399,7 +399,7 @@ void RSSImp::renameSelectedRssFile()
QTreeWidgetItem* item = selectedItems.first(); QTreeWidgetItem* item = selectedItems.first();
if (item == m_feedList->stickyUnreadItem()) if (item == m_feedList->stickyUnreadItem())
return; return;
RssFilePtr rss_item = m_feedList->getRSSItem(item); Rss::FilePtr rss_item = m_feedList->getRSSItem(item);
bool ok; bool ok;
QString newName; QString newName;
do { do {
@ -426,7 +426,7 @@ void RSSImp::refreshSelectedItems()
{ {
QList<QTreeWidgetItem*> selectedItems = m_feedList->selectedItems(); QList<QTreeWidgetItem*> selectedItems = m_feedList->selectedItems();
foreach (QTreeWidgetItem* item, selectedItems) { foreach (QTreeWidgetItem* item, selectedItems) {
RssFilePtr file = m_feedList->getRSSItem(item); Rss::FilePtr file = m_feedList->getRSSItem(item);
// Update icons // Update icons
if (item == m_feedList->stickyUnreadItem()) { if (item == m_feedList->stickyUnreadItem()) {
refreshAllFeeds(); refreshAllFeeds();
@ -436,10 +436,10 @@ void RSSImp::refreshSelectedItems()
if (!file->refresh()) if (!file->refresh())
continue; continue;
// Update UI // Update UI
if (qSharedPointerDynamicCast<RssFeed>(file)) { if (qSharedPointerDynamicCast<Rss::Feed>(file)) {
item->setData(0, Qt::DecorationRole, QVariant(QIcon(":/icons/loading.png"))); item->setData(0, Qt::DecorationRole, QVariant(QIcon(":/icons/loading.png")));
} }
else if (qSharedPointerDynamicCast<RssFolder>(file)) { else if (qSharedPointerDynamicCast<Rss::Folder>(file)) {
// Update feeds in the folder // Update feeds in the folder
foreach (QTreeWidgetItem *feed, m_feedList->getAllFeedItems(item)) foreach (QTreeWidgetItem *feed, m_feedList->getAllFeedItems(item))
feed->setData(0, Qt::DecorationRole, QVariant(QIcon(":/icons/loading.png"))); feed->setData(0, Qt::DecorationRole, QVariant(QIcon(":/icons/loading.png")));
@ -463,7 +463,7 @@ void RSSImp::on_markReadButton_clicked()
{ {
QList<QTreeWidgetItem*> selectedItems = m_feedList->selectedItems(); QList<QTreeWidgetItem*> selectedItems = m_feedList->selectedItems();
foreach (QTreeWidgetItem* item, selectedItems) { foreach (QTreeWidgetItem* item, selectedItems) {
RssFilePtr rss_item = m_feedList->getRSSItem(item); Rss::FilePtr rss_item = m_feedList->getRSSItem(item);
Q_ASSERT(rss_item); Q_ASSERT(rss_item);
rss_item->markAsRead(); rss_item->markAsRead();
updateItemInfos(item); updateItemInfos(item);
@ -473,7 +473,7 @@ void RSSImp::on_markReadButton_clicked()
populateArticleList(m_feedList->currentItem()); populateArticleList(m_feedList->currentItem());
} }
QTreeWidgetItem* RSSImp::createFolderListItem(const RssFilePtr& rssFile) QTreeWidgetItem* RSSImp::createFolderListItem(const Rss::FilePtr& rssFile)
{ {
Q_ASSERT(rssFile); Q_ASSERT(rssFile);
QTreeWidgetItem* item = new QTreeWidgetItem; QTreeWidgetItem* item = new QTreeWidgetItem;
@ -483,14 +483,14 @@ QTreeWidgetItem* RSSImp::createFolderListItem(const RssFilePtr& rssFile)
return item; return item;
} }
void RSSImp::fillFeedsList(QTreeWidgetItem* parent, const RssFolderPtr& rss_parent) void RSSImp::fillFeedsList(QTreeWidgetItem* parent, const Rss::FolderPtr& rss_parent)
{ {
QList<RssFilePtr> children; QList<Rss::FilePtr> children;
if (parent) if (parent)
children = rss_parent->getContent(); children = rss_parent->getContent();
else else
children = m_rssManager->getContent(); children = m_rssManager->getContent();
foreach (const RssFilePtr& rssFile, children) { foreach (const Rss::FilePtr& rssFile, children) {
QTreeWidgetItem* item = createFolderListItem(rssFile); QTreeWidgetItem* item = createFolderListItem(rssFile);
Q_ASSERT(item); Q_ASSERT(item);
if (parent) if (parent)
@ -502,12 +502,12 @@ void RSSImp::fillFeedsList(QTreeWidgetItem* parent, const RssFolderPtr& rss_pare
m_feedList->itemAdded(item, rssFile); m_feedList->itemAdded(item, rssFile);
// Recursive call if this is a folder. // Recursive call if this is a folder.
if (RssFolderPtr folder = qSharedPointerDynamicCast<RssFolder>(rssFile)) if (Rss::FolderPtr folder = qSharedPointerDynamicCast<Rss::Folder>(rssFile))
fillFeedsList(item, folder); fillFeedsList(item, folder);
} }
} }
QListWidgetItem* RSSImp::createArticleListItem(const RssArticlePtr& article) QListWidgetItem* RSSImp::createArticleListItem(const Rss::ArticlePtr& article)
{ {
Q_ASSERT(article); Q_ASSERT(article);
QListWidgetItem* item = new QListWidgetItem; QListWidgetItem* item = new QListWidgetItem;
@ -535,7 +535,7 @@ void RSSImp::populateArticleList(QTreeWidgetItem* item)
return; return;
} }
RssFilePtr rss_item = m_feedList->getRSSItem(item); Rss::FilePtr rss_item = m_feedList->getRSSItem(item);
if (!rss_item) if (!rss_item)
return; return;
@ -545,14 +545,14 @@ void RSSImp::populateArticleList(QTreeWidgetItem* item)
listArticles->clear(); listArticles->clear();
qDebug("Getting the list of news"); qDebug("Getting the list of news");
RssArticleList articles; Rss::ArticleList articles;
if (rss_item == m_rssManager) if (rss_item == m_rssManager)
articles = rss_item->unreadArticleListByDateDesc(); articles = rss_item->unreadArticleListByDateDesc();
else else
articles = rss_item->articleListByDateDesc(); articles = rss_item->articleListByDateDesc();
qDebug("Got the list of news"); qDebug("Got the list of news");
foreach (const RssArticlePtr& article, articles) { foreach (const Rss::ArticlePtr& article, articles) {
QListWidgetItem* articleItem = createArticleListItem(article); QListWidgetItem* articleItem = createArticleListItem(article);
listArticles->addItem(articleItem); listArticles->addItem(articleItem);
} }
@ -569,9 +569,9 @@ void RSSImp::refreshTextBrowser()
if (item == m_currentArticle) return; if (item == m_currentArticle) return;
m_currentArticle = item; m_currentArticle = item;
RssFeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString()); Rss::FeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString());
if (!feed) return; if (!feed) return;
RssArticlePtr article = feed->getItem(item->data(Article::IdRole).toString()); Rss::ArticlePtr article = feed->getItem(item->data(Article::IdRole).toString());
if (!article) return; if (!article) return;
QString html; QString html;
html += "<div style='border: 2px solid red; margin-left: 5px; margin-right: 5px; margin-bottom: 5px;'>"; html += "<div style='border: 2px solid red; margin-left: 5px; margin-right: 5px; margin-bottom: 5px;'>";
@ -650,7 +650,7 @@ void RSSImp::updateItemsInfos(const QList<QTreeWidgetItem*>& items)
void RSSImp::updateItemInfos(QTreeWidgetItem *item) void RSSImp::updateItemInfos(QTreeWidgetItem *item)
{ {
RssFilePtr rss_item = m_feedList->getRSSItem(item); Rss::FilePtr rss_item = m_feedList->getRSSItem(item);
if (!rss_item) if (!rss_item)
return; return;
@ -677,7 +677,7 @@ void RSSImp::updateFeedInfos(const QString& url, const QString& display_name, ui
{ {
qDebug() << Q_FUNC_INFO << display_name; qDebug() << Q_FUNC_INFO << display_name;
QTreeWidgetItem *item = m_feedList->getTreeItemFromUrl(url); QTreeWidgetItem *item = m_feedList->getTreeItemFromUrl(url);
RssFeedPtr stream = qSharedPointerCast<RssFeed>(m_feedList->getRSSItem(item)); Rss::FeedPtr stream = qSharedPointerCast<Rss::Feed>(m_feedList->getRSSItem(item));
item->setText(0, display_name + QString::fromUtf8(" (") + QString::number(nbUnread) + QString(")")); item->setText(0, display_name + QString::fromUtf8(" (") + QString::number(nbUnread) + QString(")"));
if (!stream->isLoading()) if (!stream->isLoading())
item->setData(0, Qt::DecorationRole, QIcon(stream->iconPath())); item->setData(0, Qt::DecorationRole, QIcon(stream->iconPath()));
@ -707,7 +707,7 @@ void RSSImp::updateRefreshInterval(uint val)
RSSImp::RSSImp(QWidget *parent): RSSImp::RSSImp(QWidget *parent):
QWidget(parent), QWidget(parent),
m_rssManager(new RssManager) m_rssManager(new Rss::Manager)
{ {
setupUi(this); setupUi(this);
// Icons // Icons

8
src/gui/rss/rss_imp.h

@ -78,7 +78,7 @@ private slots:
void updateItemInfos(QTreeWidgetItem *item); void updateItemInfos(QTreeWidgetItem *item);
void openSelectedArticlesUrls(); void openSelectedArticlesUrls();
void downloadSelectedTorrents(); void downloadSelectedTorrents();
void fillFeedsList(QTreeWidgetItem *parent = 0, const RssFolderPtr& rss_parent = RssFolderPtr()); void fillFeedsList(QTreeWidgetItem *parent = 0, const Rss::FolderPtr& rss_parent = Rss::FolderPtr());
void saveSlidersPosition(); void saveSlidersPosition();
void restoreSlidersPosition(); void restoreSlidersPosition();
void askNewFolder(); void askNewFolder();
@ -89,11 +89,11 @@ private slots:
void on_rssDownloaderBtn_clicked(); void on_rssDownloaderBtn_clicked();
private: private:
static QListWidgetItem* createArticleListItem(const RssArticlePtr& article); static QListWidgetItem* createArticleListItem(const Rss::ArticlePtr& article);
static QTreeWidgetItem* createFolderListItem(const RssFilePtr& rssFile); static QTreeWidgetItem* createFolderListItem(const Rss::FilePtr& rssFile);
private: private:
RssManagerPtr m_rssManager; Rss::ManagerPtr m_rssManager;
FeedListWidget *m_feedList; FeedListWidget *m_feedList;
QListWidgetItem* m_currentArticle; QListWidgetItem* m_currentArticle;
QShortcut *editHotkey; QShortcut *editHotkey;

Loading…
Cancel
Save