Browse Source

Start RSS rewrite: Use SharedPtr for RssArticle objects

adaptive-webui-19844
Christophe Dumez 13 years ago
parent
commit
a13bb06ec3
  1. 3
      src/rss/rss.pri
  2. 42
      src/rss/rss_imp.cpp
  3. 151
      src/rss/rssarticle.cpp
  4. 29
      src/rss/rssarticle.h
  5. 62
      src/rss/rssarticle_p.h
  6. 9
      src/rss/rssdownloadrule.cpp
  7. 67
      src/rss/rssfeed.cpp
  8. 12
      src/rss/rssfeed.h
  9. 6
      src/rss/rssfile.h
  10. 68
      src/rss/rssfolder.cpp
  11. 8
      src/rss/rssfolder.h
  12. 6
      src/rss/rssmanager.cpp
  13. 4
      src/rss/rssmanager.h

3
src/rss/rss.pri

@ -12,8 +12,7 @@ HEADERS += $$PWD/rss_imp.h \ @@ -12,8 +12,7 @@ HEADERS += $$PWD/rss_imp.h \
$$PWD/rsssettings.h \
$$PWD/rssdownloadrule.h \
$$PWD/rssdownloadrulelist.h \
$$PWD/cookiesdlg.h \
$$PWD/rssarticle_p.h
$$PWD/cookiesdlg.h
SOURCES += $$PWD/rss_imp.cpp \
$$PWD/rsssettingsdlg.cpp \

42
src/rss/rss_imp.cpp

@ -108,7 +108,7 @@ void RSSImp::displayItemsListMenu(const QPoint&){ @@ -108,7 +108,7 @@ void RSSImp::displayItemsListMenu(const QPoint&){
qDebug("text(3) URL: %s", qPrintable(item->data(Article::FeedUrlRole).toString()));
qDebug("text(2) TITLE: %s", qPrintable(item->data(Article::TitleRole).toString()));
if(m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString())
->getItem(item->data(Article::IdRole).toString()).hasAttachment()) {
->getItem(item->data(Article::IdRole).toString())->hasAttachment()) {
has_attachment = true;
break;
}
@ -323,12 +323,12 @@ void RSSImp::on_updateAllButton_clicked() { @@ -323,12 +323,12 @@ void RSSImp::on_updateAllButton_clicked() {
void RSSImp::downloadTorrent() {
QList<QListWidgetItem *> selected_items = listArticles->selectedItems();
foreach(const QListWidgetItem* item, selected_items) {
const RssArticle article = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString())
RssArticlePtr article = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString())
->getItem(item->data(Article::IdRole).toString());
if(article.hasAttachment()) {
QBtSession::instance()->downloadFromUrl(article.torrentUrl());
if(article->hasAttachment()) {
QBtSession::instance()->downloadFromUrl(article->torrentUrl());
} else {
QBtSession::instance()->downloadFromUrl(article.link());
QBtSession::instance()->downloadFromUrl(article->link());
}
}
}
@ -337,9 +337,9 @@ void RSSImp::downloadTorrent() { @@ -337,9 +337,9 @@ void RSSImp::downloadTorrent() {
void RSSImp::openNewsUrl() {
QList<QListWidgetItem *> selected_items = listArticles->selectedItems();
foreach(const QListWidgetItem* item, selected_items) {
const RssArticle news = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString())
RssArticlePtr news = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString())
->getItem(item->data(Article::IdRole).toString());
const QString link = news.link();
const QString link = news->link();
if(!link.isEmpty())
QDesktopServices::openUrl(QUrl(link));
}
@ -459,7 +459,7 @@ void RSSImp::refreshArticleList(QTreeWidgetItem* item) { @@ -459,7 +459,7 @@ void RSSImp::refreshArticleList(QTreeWidgetItem* item) {
if(!rss_item) return;
qDebug("Getting the list of news");
QList<RssArticle> news;
QList<RssArticlePtr> news;
if(rss_item == m_rssManager)
news = rss_item->unreadArticleList();
else if(rss_item)
@ -471,12 +471,12 @@ void RSSImp::refreshArticleList(QTreeWidgetItem* item) { @@ -471,12 +471,12 @@ void RSSImp::refreshArticleList(QTreeWidgetItem* item) {
m_currentArticle = 0;
listArticles->clear();
qDebug("Got the list of news");
foreach(const RssArticle &article, news){
foreach(const RssArticlePtr &article, news){
QListWidgetItem* it = new QListWidgetItem(listArticles);
it->setData(Article::TitleRole, article.title());
it->setData(Article::FeedUrlRole, article.parent()->url());
it->setData(Article::IdRole, article.guid());
if(article.isRead()){
it->setData(Article::TitleRole, article->title());
it->setData(Article::FeedUrlRole, article->parent()->url());
it->setData(Article::IdRole, article->guid());
if(article->isRead()){
it->setData(Article::ColorRole, QVariant(QColor("grey")));
it->setData(Article::IconRole, QVariant(QIcon(":/Icons/sphere.png")));
}else{
@ -508,20 +508,20 @@ void RSSImp::refreshTextBrowser() { @@ -508,20 +508,20 @@ void RSSImp::refreshTextBrowser() {
m_currentArticle = item;
}
RssFeed *stream = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString());
RssArticle article = stream->getItem(item->data(Article::IdRole).toString());
RssArticlePtr article = stream->getItem(item->data(Article::IdRole).toString());
QString html;
html += "<div style='border: 2px solid red; margin-left: 5px; margin-right: 5px; margin-bottom: 5px;'>";
html += "<div style='background-color: #678db2; font-weight: bold; color: #fff;'>"+article.title() + "</div>";
if(article.date().isValid()) {
html += "<div style='background-color: #efefef;'><b>"+tr("Date: ")+"</b>"+article.date().toLocalTime().toString(Qt::SystemLocaleLongDate)+"</div>";
html += "<div style='background-color: #678db2; font-weight: bold; color: #fff;'>"+article->title() + "</div>";
if(article->date().isValid()) {
html += "<div style='background-color: #efefef;'><b>"+tr("Date: ")+"</b>"+article->date().toLocalTime().toString(Qt::SystemLocaleLongDate)+"</div>";
}
if(!article.author().isEmpty()) {
html += "<div style='background-color: #efefef;'><b>"+tr("Author: ")+"</b>"+article.author()+"</div>";
if(!article->author().isEmpty()) {
html += "<div style='background-color: #efefef;'><b>"+tr("Author: ")+"</b>"+article->author()+"</div>";
}
html += "</div>";
html += "<divstyle='margin-left: 5px; margin-right: 5px;'>"+article.description()+"</div>";
html += "<divstyle='margin-left: 5px; margin-right: 5px;'>"+article->description()+"</div>";
textBrowser->setHtml(html);
article.markAsRead();
article->markAsRead();
item->setData(Article::ColorRole, QVariant(QColor("grey")));
item->setData(Article::IconRole, QVariant(QIcon(":/Icons/sphere.png")));
// Decrement feed nb unread news

151
src/rss/rssarticle.cpp

@ -35,7 +35,6 @@ @@ -35,7 +35,6 @@
#include <iostream>
#include "rssarticle.h"
#include "rssarticle_p.h"
static const char shortDay[][4] = {
"Mon", "Tue", "Wed",
@ -153,11 +152,11 @@ QDateTime RssArticle::parseDate(const QString &string) { @@ -153,11 +152,11 @@ QDateTime RssArticle::parseDate(const QString &string) {
negOffset = true; // military zone: RFC 2822 treats as '-0000'
else if (zone != "UT" && zone != "GMT") { // treated as '+0000'
offset = (zone == "EDT") ? -4*3600
: (zone == "EST" || zone == "CDT") ? -5*3600
: (zone == "CST" || zone == "MDT") ? -6*3600
: (zone == "MST" || zone == "PDT") ? -7*3600
: (zone == "PST") ? -8*3600
: 0;
: (zone == "EST" || zone == "CDT") ? -5*3600
: (zone == "CST" || zone == "MDT") ? -6*3600
: (zone == "MST" || zone == "PDT") ? -7*3600
: (zone == "PST") ? -8*3600
: 0;
if (!offset) {
// Check for any other alphabetic time zone
bool nonalpha = false;
@ -176,7 +175,7 @@ QDateTime RssArticle::parseDate(const QString &string) { @@ -176,7 +175,7 @@ QDateTime RssArticle::parseDate(const QString &string) {
return QDateTime::currentDateTime();
QDateTime result(qdate, QTime(hour, minute, second));
if (!result.isValid()
|| (dayOfWeek >= 0 && result.date().dayOfWeek() != dayOfWeek+1))
|| (dayOfWeek >= 0 && result.date().dayOfWeek() != dayOfWeek+1))
return QDateTime::currentDateTime(); // invalid date/time, or weekday doesn't correspond with date
if (!offset) {
result.setTimeSpec(Qt::UTC);
@ -190,15 +189,37 @@ QDateTime RssArticle::parseDate(const QString &string) { @@ -190,15 +189,37 @@ QDateTime RssArticle::parseDate(const QString &string) {
return result;
}
RssArticle::RssArticle():
d(new RssArticleData(0))
{
// public constructor
RssArticle::RssArticle(RssFeed* parent, const QString &guid):
m_parent(parent), m_guid(guid), m_read(false) {}
bool RssArticle::hasAttachment() const {
return !m_torrentUrl.isEmpty();
}
// public constructor
RssArticle::RssArticle(RssFeed* parent, QXmlStreamReader& xml):
d(new RssArticleData(parent))
QVariantHash RssArticle::toHash() const {
QVariantHash item;
item["title"] = m_title;
item["id"] = m_guid;
item["torrent_url"] = m_torrentUrl;
item["news_link"] = m_link;
item["description"] = m_description;
item["date"] = m_date;
item["author"] = m_author;
item["read"] = m_read;
return item;
}
RssArticlePtr xmlToRssArticle(RssFeed* parent, QXmlStreamReader& xml)
{
QString guid;
QString title;
QString torrentUrl;
QString link;
QString description;
QDateTime date;
QString author;
while(!xml.atEnd()) {
xml.readNext();
@ -207,125 +228,103 @@ RssArticle::RssArticle(RssFeed* parent, QXmlStreamReader& xml): @@ -207,125 +228,103 @@ RssArticle::RssArticle(RssFeed* parent, QXmlStreamReader& xml):
if(xml.isStartElement()) {
if(xml.name() == "title") {
d->title = xml.readElementText();
title = xml.readElementText();
}
else if(xml.name() == "enclosure") {
if(xml.attributes().value("type") == "application/x-bittorrent") {
d->torrentUrl = xml.attributes().value("url").toString();
torrentUrl = xml.attributes().value("url").toString();
}
}
else if(xml.name() == "link") {
d->link = xml.readElementText();
if(d->guid.isEmpty())
d->guid = d->link;
link = xml.readElementText();
if(guid.isEmpty())
guid = link;
}
else if(xml.name() == "description") {
d->description = xml.readElementText();
description = xml.readElementText();
}
else if(xml.name() == "pubDate") {
d->date = parseDate(xml.readElementText());
date = RssArticle::parseDate(xml.readElementText());
}
else if(xml.name() == "author") {
d->author = xml.readElementText();
author = xml.readElementText();
}
else if(xml.name() == "guid") {
d->guid = xml.readElementText();
guid = xml.readElementText();
}
}
}
}
RssArticle::RssArticle(RssFeed* parent, const QString &guid):
d(new RssArticleData(parent, guid)) {}
if (guid.isEmpty())
return RssArticlePtr();
RssArticle::~RssArticle() {}
RssArticlePtr art(new RssArticle(parent, guid));
art->m_title = title;
art->m_torrentUrl = torrentUrl;
art->m_link = link;
art->m_description = description;
art->m_date = date;
art->m_author = author;
RssArticle::RssArticle(const RssArticle& other): d(other.d) {
}
RssArticle & RssArticle::operator =(const RssArticle &other)
{
d = other.d;
return *this;
}
bool RssArticle::hasAttachment() const {
return !d->torrentUrl.isEmpty();
}
QVariantHash RssArticle::toHash() const {
QVariantHash item;
item["title"] = d->title;
item["id"] = d->guid;
item["torrent_url"] = d->torrentUrl;
item["news_link"] = d->link;
item["description"] = d->description;
item["date"] = d->date;
item["author"] = d->author;
item["read"] = d->read;
return item;
return art;
}
RssArticle hashToRssArticle(RssFeed* parent, const QVariantHash &h) {
RssArticlePtr hashToRssArticle(RssFeed* parent, const QVariantHash &h) {
const QString guid = h.value("id").toString();
if(guid.isEmpty()) return RssArticle();
RssArticle art(parent, guid);
art.d->title = h.value("title", "").toString();
art.d->torrentUrl = h.value("torrent_url", "").toString();
art.d->link = h.value("news_link", "").toString();
art.d->description = h.value("description").toString();
art.d->date = h.value("date").toDateTime();
art.d->author = h.value("author").toString();
art.d->read = h.value("read").toBool();
if(guid.isEmpty()) return RssArticlePtr();
RssArticlePtr art(new RssArticle(parent, guid));
art->m_title = h.value("title", "").toString();
art->m_torrentUrl = h.value("torrent_url", "").toString();
art->m_link = h.value("news_link", "").toString();
art->m_description = h.value("description").toString();
art->m_date = h.value("date").toDateTime();
art->m_author = h.value("author").toString();
art->m_read = h.value("read").toBool();
Q_ASSERT(art.isValid());
return art;
}
RssFeed* RssArticle::parent() const {
return d->parent;
}
bool RssArticle::isValid() const {
return !d->guid.isEmpty();
return m_parent;
}
QString RssArticle::author() const {
return d->author;
return m_author;
}
QString RssArticle::torrentUrl() const{
return d->torrentUrl;
return m_torrentUrl;
}
QString RssArticle::link() const {
return d->link;
return m_link;
}
QString RssArticle::description() const{
if(d->description.isNull())
if(m_description.isNull())
return "";
return d->description;
return m_description;
}
QDateTime RssArticle::date() const {
return d->date;
return m_date;
}
bool RssArticle::isRead() const{
return d->read;
return m_read;
}
void RssArticle::markAsRead(){
d->read = true;
m_read = true;
}
QString RssArticle::guid() const
{
return d->guid;
return m_guid;
}
QString RssArticle::title() const
{
return d->title;
return m_title;
}

29
src/rss/rssarticle.h

@ -34,23 +34,19 @@ @@ -34,23 +34,19 @@
#include <QXmlStreamReader>
#include <QDateTime>
#include <QVariantHash>
#include <QExplicitlySharedDataPointer>
#include <QSharedPointer>
class RssFeed;
class RssArticleData;
class RssArticle;
typedef QSharedPointer<RssArticle> RssArticlePtr;
// Item of a rss stream, single information
class RssArticle {
public:
RssArticle();
RssArticle(RssFeed* parent, QXmlStreamReader& xml);
RssArticle(RssFeed* parent, const QString &guid);
RssArticle(const RssArticle& other); // Copy constructor
RssArticle& operator=(const RssArticle& other);
~RssArticle();
// Accessors
bool isValid() const;
bool hasAttachment() const;
QString guid() const;
RssFeed* parent() const;
@ -65,15 +61,26 @@ public: @@ -65,15 +61,26 @@ public:
void markAsRead();
// Serialization
QVariantHash toHash() const;
friend RssArticle hashToRssArticle(RssFeed* parent, const QVariantHash &hash);
friend RssArticlePtr xmlToRssArticle(RssFeed* parent, QXmlStreamReader& xml);
friend RssArticlePtr hashToRssArticle(RssFeed* parent, const QVariantHash &hash);
private:
static QDateTime parseDate(const QString &string);
private:
QExplicitlySharedDataPointer<RssArticleData> d;
RssFeed* m_parent;
QString m_guid;
QString m_title;
QString m_torrentUrl;
QString m_link;
QString m_description;
QDateTime m_date;
QString m_author;
bool m_read;
};
RssArticle hashToRssArticle(RssFeed* parent, const QVariantHash &hash);
RssArticlePtr xmlToRssArticle(RssFeed* parent, QXmlStreamReader& xml);
RssArticlePtr hashToRssArticle(RssFeed* parent, const QVariantHash &hash);
#endif // RSSARTICLE_H

62
src/rss/rssarticle_p.h

@ -1,62 +0,0 @@ @@ -1,62 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact: chris@qbittorrent.org, arnaud@qbittorrent.org
*/
#ifndef RSSARTICLE_P_H
#define RSSARTICLE_P_H
#include <QString>
#include <QSharedData>
#include <QDateTime>
class RssFeed;
class RssArticleData: public QSharedData {
public:
RssArticleData(RssFeed* _parent, const QString& _guid = QString()):
parent(_parent), guid(_guid), read(false) {}
~RssArticleData() {}
RssArticleData(const RssArticleData& other):
QSharedData(other), parent(other.parent),
guid(other.guid), title(other.title), torrentUrl(other.torrentUrl),
link(other.link), description(other.description), date(other.date),
author(other.author), read(other.read) {}
RssFeed* parent;
QString guid;
QString title;
QString torrentUrl;
QString link;
QString description;
QDateTime date;
QString author;
bool read;
};
#endif // RSSARTICLE_P_H

9
src/rss/rssdownloadrule.cpp

@ -137,11 +137,10 @@ void RssDownloadRule::setSavePath(const QString &save_path) @@ -137,11 +137,10 @@ void RssDownloadRule::setSavePath(const QString &save_path)
QStringList RssDownloadRule::findMatchingArticles(const RssFeed *feed) const
{
QStringList ret;
const QHash<QString, RssArticle>& feed_articles = feed->articleListNoCopy();
QHash<QString, RssArticle>::const_iterator artIt;
for(artIt = feed_articles.begin(); artIt != feed_articles.end(); artIt++) {
const QString title = artIt.value().title();
if(matches(title))
const RssArticleHash& feed_articles = feed->articleHash();
for(RssArticleHash::ConstIterator artIt = feed_articles.begin(); artIt != feed_articles.end(); artIt++) {
const QString title = artIt.value()->title();
if (matches(title))
ret << title;
}
return ret;

67
src/rss/rssfeed.cpp

@ -66,8 +66,8 @@ RssFeed::~RssFeed(){ @@ -66,8 +66,8 @@ RssFeed::~RssFeed(){
void RssFeed::saveItemsToDisk() {
QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QVariantList old_items;
foreach(const RssArticle &item, m_articles.values()) {
old_items << item.toHash();
for (RssArticleHash::ConstIterator it=m_articles.begin(); it != m_articles.end(); it++) {
old_items << it.value()->toHash();
}
qDebug("Saving %d old items for feed %s", old_items.size(), displayName().toLocal8Bit().data());
QHash<QString, QVariant> all_old_items = qBTRSS.value("old_items", QHash<QString, QVariant>()).toHash();
@ -81,11 +81,11 @@ void RssFeed::loadItemsFromDisk() { @@ -81,11 +81,11 @@ void RssFeed::loadItemsFromDisk() {
const QVariantList old_items = all_old_items.value(m_url, QVariantList()).toList();
qDebug("Loading %d old items for feed %s", old_items.size(), displayName().toLocal8Bit().data());
foreach(const QVariant &var_it, old_items) {
foreach (const QVariant &var_it, old_items) {
QHash<QString, QVariant> item = var_it.toHash();
const RssArticle rss_item = hashToRssArticle(this, item);
if(rss_item.isValid()) {
m_articles.insert(rss_item.guid(), rss_item);
RssArticlePtr rss_item = hashToRssArticle(this, item);
if (rss_item) {
m_articles.insert(rss_item->guid(), rss_item);
}
}
}
@ -177,7 +177,7 @@ void RssFeed::setIconPath(const QString &path) { @@ -177,7 +177,7 @@ void RssFeed::setIconPath(const QString &path) {
m_icon = path;
}
const RssArticle RssFeed::getItem(const QString &guid) const {
RssArticlePtr RssFeed::getItem(const QString &guid) const {
return m_articles.value(guid);
}
@ -186,31 +186,30 @@ uint RssFeed::count() const{ @@ -186,31 +186,30 @@ uint RssFeed::count() const{
}
void RssFeed::markAsRead() {
QHash<QString, RssArticle>::iterator it;
for(it = m_articles.begin(); it != m_articles.end(); it++) {
it.value().markAsRead();
for (RssArticleHash::ConstIterator it=m_articles.begin(); it != m_articles.end(); it++) {
it.value()->markAsRead();
}
RssManager::instance()->forwardFeedInfosChanged(m_url, displayName(), 0);
}
uint RssFeed::unreadCount() const{
uint nbUnread=0;
foreach(const RssArticle &item, m_articles.values()) {
if(!item.isRead())
uint nbUnread = 0;
for (RssArticleHash::ConstIterator it=m_articles.begin(); it != m_articles.end(); it++) {
if(!it.value()->isRead())
++nbUnread;
}
return nbUnread;
}
const QList<RssArticle> RssFeed::articleList() const{
const QList<RssArticlePtr> RssFeed::articleList() const{
return m_articles.values();
}
const QList<RssArticle> RssFeed::unreadArticleList() const {
QList<RssArticle> unread_news;
foreach(const RssArticle &item, m_articles.values()) {
if(!item.isRead())
unread_news << item;
const QList<RssArticlePtr> RssFeed::unreadArticleList() const {
QList<RssArticlePtr> unread_news;
for (RssArticleHash::ConstIterator it = m_articles.begin(); it != m_articles.end(); it++) {
if(!it.value()->isRead())
unread_news << it.value();
}
return unread_news;
}
@ -275,10 +274,9 @@ bool RssFeed::parseRSS(QIODevice* device) { @@ -275,10 +274,9 @@ bool RssFeed::parseRSS(QIODevice* device) {
}
}
else if(xml.name() == "item") {
RssArticle item(this, xml);
if(item.isValid() && !itemAlreadyExists(item.guid())) {
m_articles.insert(item.guid(), item);
}
RssArticlePtr art = xmlToRssArticle(this, xml);
if(art && !itemAlreadyExists(art->guid()))
m_articles.insert(art->guid(), art);
}
}
}
@ -298,22 +296,21 @@ bool RssFeed::parseRSS(QIODevice* device) { @@ -298,22 +296,21 @@ bool RssFeed::parseRSS(QIODevice* device) {
void RssFeed::downloadMatchingArticleTorrents() {
Q_ASSERT(RssSettings().isRssDownloadingEnabled());
QHash<QString, RssArticle>::iterator it;
for (it = m_articles.begin(); it != m_articles.end(); it++) {
RssArticle item = it.value();
if(item.isRead()) continue;
for (RssArticleHash::ConstIterator it = m_articles.begin(); it != m_articles.end(); it++) {
RssArticlePtr item = it.value();
if(item->isRead()) continue;
QString torrent_url;
if(item.hasAttachment())
torrent_url = item.torrentUrl();
if(item->hasAttachment())
torrent_url = item->torrentUrl();
else
torrent_url = item.link();
torrent_url = item->link();
// Check if the item should be automatically downloaded
const RssDownloadRule matching_rule = RssDownloadRuleList::instance()->findMatchingRule(m_url, item.title());
const RssDownloadRule matching_rule = RssDownloadRuleList::instance()->findMatchingRule(m_url, item->title());
if(matching_rule.isValid()) {
// Item was downloaded, consider it as Read
item.markAsRead();
item->markAsRead();
// Download the torrent
QBtSession::instance()->addConsoleMessage(tr("Automatically downloading %1 torrent from %2 RSS feed...").arg(item.title()).arg(displayName()));
QBtSession::instance()->addConsoleMessage(tr("Automatically downloading %1 torrent from %2 RSS feed...").arg(item->title()).arg(displayName()));
QBtSession::instance()->downloadUrlAndSkipDialog(torrent_url, matching_rule.savePath(), matching_rule.label());
}
}
@ -323,11 +320,11 @@ void RssFeed::resizeList() { @@ -323,11 +320,11 @@ void RssFeed::resizeList() {
const uint max_articles = RssSettings().getRSSMaxArticlesPerFeed();
const uint nb_articles = m_articles.size();
if(nb_articles > max_articles) {
QList<RssArticle> listItems = m_articles.values();
QList<RssArticlePtr> listItems = m_articles.values();
RssManager::sortNewsList(listItems);
const int excess = nb_articles - max_articles;
for(uint i=nb_articles-excess; i<nb_articles; ++i){
m_articles.remove(listItems.at(i).guid());
m_articles.remove(listItems.at(i)->guid());
}
}
}

12
src/rss/rssfeed.h

@ -37,6 +37,8 @@ @@ -37,6 +37,8 @@
class RssManager;
typedef QHash<QString, RssArticlePtr> RssArticleHash;
class RssFeed: public QObject, public IRssFile {
Q_OBJECT
@ -59,13 +61,13 @@ public: @@ -59,13 +61,13 @@ public:
QString icon() const;
bool hasCustomIcon() const;
void setIconPath(const QString &pathHierarchy);
const RssArticle getItem(const QString &guid) const;
RssArticlePtr getItem(const QString &guid) const;
uint count() const;
void markAsRead();
uint unreadCount() const;
const QList<RssArticle> articleList() const;
const QHash<QString, RssArticle>& articleListNoCopy() const { return m_articles; }
const QList<RssArticle> unreadArticleList() const;
const QList<RssArticlePtr> articleList() const;
const RssArticleHash& articleHash() const { return m_articles; }
const QList<RssArticlePtr> unreadArticleList() const;
private slots:
void handleFinishedDownload(const QString& url, const QString &file_path);
@ -81,7 +83,7 @@ private: @@ -81,7 +83,7 @@ private:
void loadItemsFromDisk();
private:
QHash<QString, RssArticle> m_articles;
RssArticleHash m_articles;
RssFolder *m_parent;
QString m_title;
QString m_url;

6
src/rss/rssfile.h

@ -33,8 +33,8 @@ @@ -33,8 +33,8 @@
#include <QList>
#include <QStringList>
#include "rssarticle.h"
class RssArticle;
class RssFolder;
class IRssFile {
@ -54,8 +54,8 @@ public: @@ -54,8 +54,8 @@ public:
virtual void setParent(RssFolder* parent) = 0;
virtual void refresh() = 0;
virtual void removeAllSettings() = 0;
virtual const QList<RssArticle> articleList() const = 0;
virtual const QList<RssArticle> unreadArticleList() const = 0;
virtual const QList<RssArticlePtr> articleList() const = 0;
virtual const QList<RssArticlePtr> unreadArticleList() const = 0;
QStringList pathHierarchy() const;
};

68
src/rss/rssfolder.cpp

@ -45,9 +45,9 @@ RssFolder::~RssFolder() { @@ -45,9 +45,9 @@ RssFolder::~RssFolder() {
}
unsigned int RssFolder::unreadCount() const {
unsigned int nb_unread = 0;
foreach(const IRssFile *file, m_children.values()) {
nb_unread += file->unreadCount();
uint nb_unread = 0;
for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
nb_unread += it.value()->unreadCount();
}
return nb_unread;
}
@ -57,7 +57,7 @@ IRssFile::FileType RssFolder::type() const { @@ -57,7 +57,7 @@ IRssFile::FileType RssFolder::type() const {
}
void RssFolder::removeChild(const QString &childId) {
if(m_children.contains(childId)) {
if (m_children.contains(childId)) {
IRssFile* child = m_children.take(childId);
child->removeAllSettings();
delete child;
@ -66,7 +66,7 @@ void RssFolder::removeChild(const QString &childId) { @@ -66,7 +66,7 @@ void RssFolder::removeChild(const QString &childId) {
RssFolder* RssFolder::addFolder(const QString &name) {
RssFolder *subfolder;
if(!m_children.contains(name)) {
if (!m_children.contains(name)) {
subfolder = new RssFolder(this, name);
m_children[name] = subfolder;
} else {
@ -85,23 +85,23 @@ RssFeed* RssFolder::addStream(const QString &url) { @@ -85,23 +85,23 @@ RssFeed* RssFolder::addStream(const QString &url) {
// Refresh All Children
void RssFolder::refresh() {
foreach(IRssFile *child, m_children.values()) {
child->refresh();
for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
it.value()->refresh();
}
}
const QList<RssArticle> RssFolder::articleList() const {
QList<RssArticle> news;
foreach(const IRssFile *child, m_children.values()) {
news << child->articleList();
const QList<RssArticlePtr> RssFolder::articleList() const {
QList<RssArticlePtr> news;
for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
news << it.value()->articleList();
}
return news;
}
const QList<RssArticle> RssFolder::unreadArticleList() const {
QList<RssArticle> unread_news;
foreach(const IRssFile *child, m_children.values()) {
unread_news << child->unreadArticleList();
const QList<RssArticlePtr> RssFolder::unreadArticleList() const {
QList<RssArticlePtr> unread_news;
for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
unread_news << it.value()->unreadArticleList();
}
return unread_news;
}
@ -111,10 +111,10 @@ QList<IRssFile*> RssFolder::getContent() const { @@ -111,10 +111,10 @@ QList<IRssFile*> RssFolder::getContent() const {
}
unsigned int RssFolder::getNbFeeds() const {
unsigned int nbFeeds = 0;
foreach(IRssFile* item, m_children.values()) {
if(item->type() == IRssFile::FOLDER)
nbFeeds += ((RssFolder*)item)->getNbFeeds();
uint nbFeeds = 0;
for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
if (it.value()->type() == IRssFile::FOLDER)
nbFeeds += ((RssFolder*)*it)->getNbFeeds();
else
nbFeeds += 1;
}
@ -126,9 +126,9 @@ QString RssFolder::displayName() const { @@ -126,9 +126,9 @@ QString RssFolder::displayName() const {
}
void RssFolder::rename(const QString &new_name) {
if(m_name == new_name) return;
if (m_name == new_name) return;
Q_ASSERT(!m_parent->hasChild(new_name));
if(!m_parent->hasChild(new_name)) {
if (!m_parent->hasChild(new_name)) {
// Update parent
m_parent->renameChildFolder(m_name, new_name);
// Actually rename
@ -137,18 +137,18 @@ void RssFolder::rename(const QString &new_name) { @@ -137,18 +137,18 @@ void RssFolder::rename(const QString &new_name) {
}
void RssFolder::markAsRead() {
foreach(IRssFile *item, m_children.values()) {
item->markAsRead();
for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
it.value()->markAsRead();
}
}
QList<RssFeed*> RssFolder::getAllFeeds() const {
QList<RssFeed*> streams;
foreach(IRssFile *item, m_children.values()) {
if(item->type() == IRssFile::FEED) {
streams << static_cast<RssFeed*>(item);
for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
if (it.value()->type() == IRssFile::FEED) {
streams << static_cast<RssFeed*>(it.value());
} else {
streams << static_cast<RssFolder*>(item)->getAllFeeds();
streams << static_cast<RssFolder*>(it.value())->getAllFeeds();
}
}
return streams;
@ -156,21 +156,21 @@ QList<RssFeed*> RssFolder::getAllFeeds() const { @@ -156,21 +156,21 @@ QList<RssFeed*> RssFolder::getAllFeeds() const {
QHash<QString, RssFeed*> RssFolder::getAllFeedsAsHash() const {
QHash<QString, RssFeed*> ret;
foreach(IRssFile *item, m_children.values()) {
if(item->type() == IRssFile::FEED) {
RssFeed* feed = dynamic_cast<RssFeed*>(item);
for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
if (it.value()->type() == IRssFile::FEED) {
RssFeed* feed = dynamic_cast<RssFeed*>(it.value());
Q_ASSERT(feed);
qDebug() << Q_FUNC_INFO << feed->url();
ret[feed->url()] = feed;
} else {
ret.unite(static_cast<RssFolder*>(item)->getAllFeedsAsHash());
ret.unite(static_cast<RssFolder*>(it.value())->getAllFeedsAsHash());
}
}
return ret;
}
void RssFolder::addFile(IRssFile * item) {
if(item->type() == IRssFile::FEED) {
if (item->type() == IRssFile::FEED) {
RssFeed* feedItem = dynamic_cast<RssFeed*>(item);
Q_ASSERT(!m_children.contains(feedItem->url()));
m_children[feedItem->url()] = item;
@ -191,8 +191,8 @@ void RssFolder::removeAllItems() { @@ -191,8 +191,8 @@ void RssFolder::removeAllItems() {
}
void RssFolder::removeAllSettings() {
foreach(IRssFile* child, m_children.values()) {
child->removeAllSettings();
for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
it.value()->removeAllSettings();
}
}

8
src/rss/rssfolder.h

@ -38,6 +38,8 @@ @@ -38,6 +38,8 @@
class RssArticle;
class RssFeed;
typedef QHash<QString, IRssFile*> RssFileHash;
class RssFolder: public QObject, public IRssFile {
Q_OBJECT
@ -57,8 +59,8 @@ public: @@ -57,8 +59,8 @@ public:
QString displayName() const;
QString id() const;
bool hasChild(const QString &childId);
const QList<RssArticle> articleList() const;
const QList<RssArticle> unreadArticleList() const;
const QList<RssArticlePtr> articleList() const;
const QList<RssArticlePtr> unreadArticleList() const;
void removeAllSettings();
void removeAllItems();
void renameChildFolder(const QString &old_name, const QString &new_name);
@ -74,7 +76,7 @@ public slots: @@ -74,7 +76,7 @@ public slots:
private:
RssFolder *m_parent;
QString m_name;
QHash<QString, IRssFile*> m_children;
RssFileHash m_children;
};
#endif // RSSFOLDER_H

6
src/rss/rssmanager.cpp

@ -133,12 +133,12 @@ void RssManager::saveStreamList() const { @@ -133,12 +133,12 @@ void RssManager::saveStreamList() const {
settings.setRssFeedsAliases(aliases);
}
static bool laterItemDate(const RssArticle& a, const RssArticle& b)
static bool laterItemDate(const RssArticlePtr& a, const RssArticlePtr& b)
{
return (a.date() > b.date());
return (a->date() > b->date());
}
void RssManager::sortNewsList(QList<RssArticle>& news_list) {
void RssManager::sortNewsList(QList<RssArticlePtr>& news_list) {
qSort(news_list.begin(), news_list.end(), laterItemDate);
}

4
src/rss/rssmanager.h

@ -48,8 +48,8 @@ public: @@ -48,8 +48,8 @@ public:
static void drop();
virtual ~RssManager();
inline DownloadThread* rssDownloader() const { return m_rssDownloader; }
static void insertSortElem(QList<RssArticle> &list, const RssArticle &item);
static void sortNewsList(QList<RssArticle>& news_list);
static void insertSortElem(QList<RssArticlePtr> &list, const RssArticlePtr &item);
static void sortNewsList(QList<RssArticlePtr>& news_list);
public slots:
void loadStreamList();

Loading…
Cancel
Save