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. 139
      src/rss/rssarticle.cpp
  4. 29
      src/rss/rssarticle.h
  5. 62
      src/rss/rssarticle_p.h
  6. 7
      src/rss/rssdownloadrule.cpp
  7. 63
      src/rss/rssfeed.cpp
  8. 12
      src/rss/rssfeed.h
  9. 6
      src/rss/rssfile.h
  10. 58
      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 \
$$PWD/rsssettings.h \ $$PWD/rsssettings.h \
$$PWD/rssdownloadrule.h \ $$PWD/rssdownloadrule.h \
$$PWD/rssdownloadrulelist.h \ $$PWD/rssdownloadrulelist.h \
$$PWD/cookiesdlg.h \ $$PWD/cookiesdlg.h
$$PWD/rssarticle_p.h
SOURCES += $$PWD/rss_imp.cpp \ SOURCES += $$PWD/rss_imp.cpp \
$$PWD/rsssettingsdlg.cpp \ $$PWD/rsssettingsdlg.cpp \

42
src/rss/rss_imp.cpp

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

139
src/rss/rssarticle.cpp

@ -35,7 +35,6 @@
#include <iostream> #include <iostream>
#include "rssarticle.h" #include "rssarticle.h"
#include "rssarticle_p.h"
static const char shortDay[][4] = { static const char shortDay[][4] = {
"Mon", "Tue", "Wed", "Mon", "Tue", "Wed",
@ -190,15 +189,37 @@ QDateTime RssArticle::parseDate(const QString &string) {
return result; return result;
} }
RssArticle::RssArticle(): // public constructor
d(new RssArticleData(0)) 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 QVariantHash RssArticle::toHash() const {
RssArticle::RssArticle(RssFeed* parent, QXmlStreamReader& xml): QVariantHash item;
d(new RssArticleData(parent)) 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()) { while(!xml.atEnd()) {
xml.readNext(); xml.readNext();
@ -207,125 +228,103 @@ RssArticle::RssArticle(RssFeed* parent, QXmlStreamReader& xml):
if(xml.isStartElement()) { if(xml.isStartElement()) {
if(xml.name() == "title") { if(xml.name() == "title") {
d->title = xml.readElementText(); title = xml.readElementText();
} }
else if(xml.name() == "enclosure") { else if(xml.name() == "enclosure") {
if(xml.attributes().value("type") == "application/x-bittorrent") { 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") { else if(xml.name() == "link") {
d->link = xml.readElementText(); link = xml.readElementText();
if(d->guid.isEmpty()) if(guid.isEmpty())
d->guid = d->link; guid = link;
} }
else if(xml.name() == "description") { else if(xml.name() == "description") {
d->description = xml.readElementText(); description = xml.readElementText();
} }
else if(xml.name() == "pubDate") { else if(xml.name() == "pubDate") {
d->date = parseDate(xml.readElementText()); date = RssArticle::parseDate(xml.readElementText());
} }
else if(xml.name() == "author") { else if(xml.name() == "author") {
d->author = xml.readElementText(); author = xml.readElementText();
} }
else if(xml.name() == "guid") { else if(xml.name() == "guid") {
d->guid = xml.readElementText(); guid = xml.readElementText();
}
} }
} }
} }
RssArticle::RssArticle(RssFeed* parent, const QString &guid): if (guid.isEmpty())
d(new RssArticleData(parent, guid)) {} 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) { return art;
}
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;
} }
RssArticle hashToRssArticle(RssFeed* parent, const QVariantHash &h) { RssArticlePtr hashToRssArticle(RssFeed* parent, const QVariantHash &h) {
const QString guid = h.value("id").toString(); const QString guid = h.value("id").toString();
if(guid.isEmpty()) return RssArticle(); if(guid.isEmpty()) return RssArticlePtr();
RssArticle art(parent, guid);
art.d->title = h.value("title", "").toString(); RssArticlePtr art(new RssArticle(parent, guid));
art.d->torrentUrl = h.value("torrent_url", "").toString(); art->m_title = h.value("title", "").toString();
art.d->link = h.value("news_link", "").toString(); art->m_torrentUrl = h.value("torrent_url", "").toString();
art.d->description = h.value("description").toString(); art->m_link = h.value("news_link", "").toString();
art.d->date = h.value("date").toDateTime(); art->m_description = h.value("description").toString();
art.d->author = h.value("author").toString(); art->m_date = h.value("date").toDateTime();
art.d->read = h.value("read").toBool(); art->m_author = h.value("author").toString();
art->m_read = h.value("read").toBool();
Q_ASSERT(art.isValid());
return art; return art;
} }
RssFeed* RssArticle::parent() const { RssFeed* RssArticle::parent() const {
return d->parent; return m_parent;
}
bool RssArticle::isValid() const {
return !d->guid.isEmpty();
} }
QString RssArticle::author() const { QString RssArticle::author() const {
return d->author; return m_author;
} }
QString RssArticle::torrentUrl() const{ QString RssArticle::torrentUrl() const{
return d->torrentUrl; return m_torrentUrl;
} }
QString RssArticle::link() const { QString RssArticle::link() const {
return d->link; return m_link;
} }
QString RssArticle::description() const{ QString RssArticle::description() const{
if(d->description.isNull()) if(m_description.isNull())
return ""; return "";
return d->description; return m_description;
} }
QDateTime RssArticle::date() const { QDateTime RssArticle::date() const {
return d->date; return m_date;
} }
bool RssArticle::isRead() const{ bool RssArticle::isRead() const{
return d->read; return m_read;
} }
void RssArticle::markAsRead(){ void RssArticle::markAsRead(){
d->read = true; m_read = true;
} }
QString RssArticle::guid() const QString RssArticle::guid() const
{ {
return d->guid; return m_guid;
} }
QString RssArticle::title() const QString RssArticle::title() const
{ {
return d->title; return m_title;
} }

29
src/rss/rssarticle.h

@ -34,23 +34,19 @@
#include <QXmlStreamReader> #include <QXmlStreamReader>
#include <QDateTime> #include <QDateTime>
#include <QVariantHash> #include <QVariantHash>
#include <QExplicitlySharedDataPointer> #include <QSharedPointer>
class RssFeed; class RssFeed;
class RssArticleData; class RssArticle;
typedef QSharedPointer<RssArticle> RssArticlePtr;
// Item of a rss stream, single information // Item of a rss stream, single information
class RssArticle { class RssArticle {
public: public:
RssArticle();
RssArticle(RssFeed* parent, QXmlStreamReader& xml);
RssArticle(RssFeed* parent, const QString &guid); RssArticle(RssFeed* parent, const QString &guid);
RssArticle(const RssArticle& other); // Copy constructor
RssArticle& operator=(const RssArticle& other);
~RssArticle();
// Accessors // Accessors
bool isValid() const;
bool hasAttachment() const; bool hasAttachment() const;
QString guid() const; QString guid() const;
RssFeed* parent() const; RssFeed* parent() const;
@ -65,15 +61,26 @@ public:
void markAsRead(); void markAsRead();
// Serialization // Serialization
QVariantHash toHash() const; 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: private:
static QDateTime parseDate(const QString &string); static QDateTime parseDate(const QString &string);
private: 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 #endif // RSSARTICLE_H

62
src/rss/rssarticle_p.h

@ -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

7
src/rss/rssdownloadrule.cpp

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

63
src/rss/rssfeed.cpp

@ -66,8 +66,8 @@ RssFeed::~RssFeed(){
void RssFeed::saveItemsToDisk() { void RssFeed::saveItemsToDisk() {
QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss"); QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QVariantList old_items; QVariantList old_items;
foreach(const RssArticle &item, m_articles.values()) { for (RssArticleHash::ConstIterator it=m_articles.begin(); it != m_articles.end(); it++) {
old_items << item.toHash(); old_items << it.value()->toHash();
} }
qDebug("Saving %d old items for feed %s", old_items.size(), displayName().toLocal8Bit().data()); 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(); QHash<QString, QVariant> all_old_items = qBTRSS.value("old_items", QHash<QString, QVariant>()).toHash();
@ -83,9 +83,9 @@ void RssFeed::loadItemsFromDisk() {
foreach (const QVariant &var_it, old_items) { foreach (const QVariant &var_it, old_items) {
QHash<QString, QVariant> item = var_it.toHash(); QHash<QString, QVariant> item = var_it.toHash();
const RssArticle rss_item = hashToRssArticle(this, item); RssArticlePtr rss_item = hashToRssArticle(this, item);
if(rss_item.isValid()) { if (rss_item) {
m_articles.insert(rss_item.guid(), rss_item); m_articles.insert(rss_item->guid(), rss_item);
} }
} }
} }
@ -177,7 +177,7 @@ void RssFeed::setIconPath(const QString &path) {
m_icon = path; m_icon = path;
} }
const RssArticle RssFeed::getItem(const QString &guid) const { RssArticlePtr RssFeed::getItem(const QString &guid) const {
return m_articles.value(guid); return m_articles.value(guid);
} }
@ -186,31 +186,30 @@ uint RssFeed::count() const{
} }
void RssFeed::markAsRead() { void RssFeed::markAsRead() {
QHash<QString, RssArticle>::iterator it; for (RssArticleHash::ConstIterator it=m_articles.begin(); it != m_articles.end(); it++) {
for(it = m_articles.begin(); it != m_articles.end(); it++) { it.value()->markAsRead();
it.value().markAsRead();
} }
RssManager::instance()->forwardFeedInfosChanged(m_url, displayName(), 0); RssManager::instance()->forwardFeedInfosChanged(m_url, displayName(), 0);
} }
uint RssFeed::unreadCount() const{ uint RssFeed::unreadCount() const{
uint nbUnread = 0; uint nbUnread = 0;
foreach(const RssArticle &item, m_articles.values()) { for (RssArticleHash::ConstIterator it=m_articles.begin(); it != m_articles.end(); it++) {
if(!item.isRead()) if(!it.value()->isRead())
++nbUnread; ++nbUnread;
} }
return nbUnread; return nbUnread;
} }
const QList<RssArticle> RssFeed::articleList() const{ const QList<RssArticlePtr> RssFeed::articleList() const{
return m_articles.values(); return m_articles.values();
} }
const QList<RssArticle> RssFeed::unreadArticleList() const { const QList<RssArticlePtr> RssFeed::unreadArticleList() const {
QList<RssArticle> unread_news; QList<RssArticlePtr> unread_news;
foreach(const RssArticle &item, m_articles.values()) { for (RssArticleHash::ConstIterator it = m_articles.begin(); it != m_articles.end(); it++) {
if(!item.isRead()) if(!it.value()->isRead())
unread_news << item; unread_news << it.value();
} }
return unread_news; return unread_news;
} }
@ -275,10 +274,9 @@ bool RssFeed::parseRSS(QIODevice* device) {
} }
} }
else if(xml.name() == "item") { else if(xml.name() == "item") {
RssArticle item(this, xml); RssArticlePtr art = xmlToRssArticle(this, xml);
if(item.isValid() && !itemAlreadyExists(item.guid())) { if(art && !itemAlreadyExists(art->guid()))
m_articles.insert(item.guid(), item); m_articles.insert(art->guid(), art);
}
} }
} }
} }
@ -298,22 +296,21 @@ bool RssFeed::parseRSS(QIODevice* device) {
void RssFeed::downloadMatchingArticleTorrents() { void RssFeed::downloadMatchingArticleTorrents() {
Q_ASSERT(RssSettings().isRssDownloadingEnabled()); Q_ASSERT(RssSettings().isRssDownloadingEnabled());
QHash<QString, RssArticle>::iterator it; for (RssArticleHash::ConstIterator it = m_articles.begin(); it != m_articles.end(); it++) {
for (it = m_articles.begin(); it != m_articles.end(); it++) { RssArticlePtr item = it.value();
RssArticle item = it.value(); if(item->isRead()) continue;
if(item.isRead()) continue;
QString torrent_url; QString torrent_url;
if(item.hasAttachment()) if(item->hasAttachment())
torrent_url = item.torrentUrl(); torrent_url = item->torrentUrl();
else else
torrent_url = item.link(); torrent_url = item->link();
// Check if the item should be automatically downloaded // 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()) { if(matching_rule.isValid()) {
// Item was downloaded, consider it as Read // Item was downloaded, consider it as Read
item.markAsRead(); item->markAsRead();
// Download the torrent // 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()); QBtSession::instance()->downloadUrlAndSkipDialog(torrent_url, matching_rule.savePath(), matching_rule.label());
} }
} }
@ -323,11 +320,11 @@ void RssFeed::resizeList() {
const uint max_articles = RssSettings().getRSSMaxArticlesPerFeed(); const uint max_articles = RssSettings().getRSSMaxArticlesPerFeed();
const uint nb_articles = m_articles.size(); const uint nb_articles = m_articles.size();
if(nb_articles > max_articles) { if(nb_articles > max_articles) {
QList<RssArticle> listItems = m_articles.values(); QList<RssArticlePtr> listItems = m_articles.values();
RssManager::sortNewsList(listItems); RssManager::sortNewsList(listItems);
const int excess = nb_articles - max_articles; const int excess = nb_articles - max_articles;
for(uint i=nb_articles-excess; i<nb_articles; ++i){ 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 @@
class RssManager; class RssManager;
typedef QHash<QString, RssArticlePtr> RssArticleHash;
class RssFeed: public QObject, public IRssFile { class RssFeed: public QObject, public IRssFile {
Q_OBJECT Q_OBJECT
@ -59,13 +61,13 @@ public:
QString icon() const; QString icon() const;
bool hasCustomIcon() const; bool hasCustomIcon() const;
void setIconPath(const QString &pathHierarchy); void setIconPath(const QString &pathHierarchy);
const RssArticle getItem(const QString &guid) const; RssArticlePtr getItem(const QString &guid) const;
uint count() const; uint count() const;
void markAsRead(); void markAsRead();
uint unreadCount() const; uint unreadCount() const;
const QList<RssArticle> articleList() const; const QList<RssArticlePtr> articleList() const;
const QHash<QString, RssArticle>& articleListNoCopy() const { return m_articles; } const RssArticleHash& articleHash() const { return m_articles; }
const QList<RssArticle> unreadArticleList() const; const QList<RssArticlePtr> unreadArticleList() const;
private slots: private slots:
void handleFinishedDownload(const QString& url, const QString &file_path); void handleFinishedDownload(const QString& url, const QString &file_path);
@ -81,7 +83,7 @@ private:
void loadItemsFromDisk(); void loadItemsFromDisk();
private: private:
QHash<QString, RssArticle> m_articles; RssArticleHash m_articles;
RssFolder *m_parent; RssFolder *m_parent;
QString m_title; QString m_title;
QString m_url; QString m_url;

6
src/rss/rssfile.h

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

58
src/rss/rssfolder.cpp

@ -45,9 +45,9 @@ RssFolder::~RssFolder() {
} }
unsigned int RssFolder::unreadCount() const { unsigned int RssFolder::unreadCount() const {
unsigned int nb_unread = 0; uint nb_unread = 0;
foreach(const IRssFile *file, m_children.values()) { for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
nb_unread += file->unreadCount(); nb_unread += it.value()->unreadCount();
} }
return nb_unread; return nb_unread;
} }
@ -85,23 +85,23 @@ RssFeed* RssFolder::addStream(const QString &url) {
// Refresh All Children // Refresh All Children
void RssFolder::refresh() { void RssFolder::refresh() {
foreach(IRssFile *child, m_children.values()) { for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
child->refresh(); it.value()->refresh();
} }
} }
const QList<RssArticle> RssFolder::articleList() const { const QList<RssArticlePtr> RssFolder::articleList() const {
QList<RssArticle> news; QList<RssArticlePtr> news;
foreach(const IRssFile *child, m_children.values()) { for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
news << child->articleList(); news << it.value()->articleList();
} }
return news; return news;
} }
const QList<RssArticle> RssFolder::unreadArticleList() const { const QList<RssArticlePtr> RssFolder::unreadArticleList() const {
QList<RssArticle> unread_news; QList<RssArticlePtr> unread_news;
foreach(const IRssFile *child, m_children.values()) { for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
unread_news << child->unreadArticleList(); unread_news << it.value()->unreadArticleList();
} }
return unread_news; return unread_news;
} }
@ -111,10 +111,10 @@ QList<IRssFile*> RssFolder::getContent() const {
} }
unsigned int RssFolder::getNbFeeds() const { unsigned int RssFolder::getNbFeeds() const {
unsigned int nbFeeds = 0; uint nbFeeds = 0;
foreach(IRssFile* item, m_children.values()) { for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
if(item->type() == IRssFile::FOLDER) if (it.value()->type() == IRssFile::FOLDER)
nbFeeds += ((RssFolder*)item)->getNbFeeds(); nbFeeds += ((RssFolder*)*it)->getNbFeeds();
else else
nbFeeds += 1; nbFeeds += 1;
} }
@ -137,18 +137,18 @@ void RssFolder::rename(const QString &new_name) {
} }
void RssFolder::markAsRead() { void RssFolder::markAsRead() {
foreach(IRssFile *item, m_children.values()) { for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
item->markAsRead(); it.value()->markAsRead();
} }
} }
QList<RssFeed*> RssFolder::getAllFeeds() const { QList<RssFeed*> RssFolder::getAllFeeds() const {
QList<RssFeed*> streams; QList<RssFeed*> streams;
foreach(IRssFile *item, m_children.values()) { for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
if(item->type() == IRssFile::FEED) { if (it.value()->type() == IRssFile::FEED) {
streams << static_cast<RssFeed*>(item); streams << static_cast<RssFeed*>(it.value());
} else { } else {
streams << static_cast<RssFolder*>(item)->getAllFeeds(); streams << static_cast<RssFolder*>(it.value())->getAllFeeds();
} }
} }
return streams; return streams;
@ -156,14 +156,14 @@ QList<RssFeed*> RssFolder::getAllFeeds() const {
QHash<QString, RssFeed*> RssFolder::getAllFeedsAsHash() const { QHash<QString, RssFeed*> RssFolder::getAllFeedsAsHash() const {
QHash<QString, RssFeed*> ret; QHash<QString, RssFeed*> ret;
foreach(IRssFile *item, m_children.values()) { for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
if(item->type() == IRssFile::FEED) { if (it.value()->type() == IRssFile::FEED) {
RssFeed* feed = dynamic_cast<RssFeed*>(item); RssFeed* feed = dynamic_cast<RssFeed*>(it.value());
Q_ASSERT(feed); Q_ASSERT(feed);
qDebug() << Q_FUNC_INFO << feed->url(); qDebug() << Q_FUNC_INFO << feed->url();
ret[feed->url()] = feed; ret[feed->url()] = feed;
} else { } else {
ret.unite(static_cast<RssFolder*>(item)->getAllFeedsAsHash()); ret.unite(static_cast<RssFolder*>(it.value())->getAllFeedsAsHash());
} }
} }
return ret; return ret;
@ -191,8 +191,8 @@ void RssFolder::removeAllItems() {
} }
void RssFolder::removeAllSettings() { void RssFolder::removeAllSettings() {
foreach(IRssFile* child, m_children.values()) { for (RssFileHash::ConstIterator it = m_children.begin(); it != m_children.end(); it++) {
child->removeAllSettings(); it.value()->removeAllSettings();
} }
} }

8
src/rss/rssfolder.h

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

6
src/rss/rssmanager.cpp

@ -133,12 +133,12 @@ void RssManager::saveStreamList() const {
settings.setRssFeedsAliases(aliases); 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); qSort(news_list.begin(), news_list.end(), laterItemDate);
} }

4
src/rss/rssmanager.h

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

Loading…
Cancel
Save