mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-11 07:18:08 +00:00
Start RSS rewrite: Use SharedPtr for RssArticle objects
This commit is contained in:
parent
32a6c89c8c
commit
a13bb06ec3
@ -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 \
|
||||
|
@ -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() {
|
||||
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() {
|
||||
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) {
|
||||
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) {
|
||||
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() {
|
||||
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
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "rssarticle.h"
|
||||
#include "rssarticle_p.h"
|
||||
|
||||
static const char shortDay[][4] = {
|
||||
"Mon", "Tue", "Wed",
|
||||
@ -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):
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (guid.isEmpty())
|
||||
return RssArticlePtr();
|
||||
|
||||
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;
|
||||
|
||||
return art;
|
||||
}
|
||||
|
||||
RssArticle::RssArticle(RssFeed* parent, const QString &guid):
|
||||
d(new RssArticleData(parent, guid)) {}
|
||||
|
||||
RssArticle::~RssArticle() {}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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:
|
||||
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
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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() {
|
||||
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) {
|
||||
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{
|
||||
}
|
||||
|
||||
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) {
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
||||
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() {
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@
|
||||
|
||||
class RssManager;
|
||||
|
||||
typedef QHash<QString, RssArticlePtr> RssArticleHash;
|
||||
|
||||
class RssFeed: public QObject, public IRssFile {
|
||||
Q_OBJECT
|
||||
|
||||
@ -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:
|
||||
void loadItemsFromDisk();
|
||||
|
||||
private:
|
||||
QHash<QString, RssArticle> m_articles;
|
||||
RssArticleHash m_articles;
|
||||
RssFolder *m_parent;
|
||||
QString m_title;
|
||||
QString m_url;
|
||||
|
@ -33,8 +33,8 @@
|
||||
|
||||
#include <QList>
|
||||
#include <QStringList>
|
||||
#include "rssarticle.h"
|
||||
|
||||
class RssArticle;
|
||||
class RssFolder;
|
||||
|
||||
class IRssFile {
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
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) {
|
||||
|
||||
// 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 {
|
||||
}
|
||||
|
||||
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 {
|
||||
}
|
||||
|
||||
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) {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
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() {
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
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:
|
||||
private:
|
||||
RssFolder *m_parent;
|
||||
QString m_name;
|
||||
QHash<QString, IRssFile*> m_children;
|
||||
RssFileHash m_children;
|
||||
};
|
||||
|
||||
#endif // RSSFOLDER_H
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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…
Reference in New Issue
Block a user