@ -1,6 +1,7 @@
@@ -1,6 +1,7 @@
/*
* Bittorrent Client using Qt4 and libtorrent .
* Copyright ( C ) 2010 Christophe Dumez , Arnaud Demaiziere
* Bittorrent Client using Qt and libtorrent .
* Copyright ( C ) 2010 Christophe Dumez < chris @ qbittorrent . org >
* Copyright ( C ) 2010 Arnaud Demaiziere < arnaud @ qbittorrent . org >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
@ -30,15 +31,15 @@
@@ -30,15 +31,15 @@
# include <QDebug>
# include "base/bittorrent/session.h"
# include "base/bittorrent/magneturi.h"
# include "base/preferences.h"
# include "base/qinisettings.h"
# include "base/logger.h"
# include "base/bittorrent/session.h"
# include "base/bittorrent/magneturi.h"
# include "base/utils/misc.h"
# include "base/utils/fs.h"
# include "base/net/downloadmanager.h"
# include "base/net/downloadhandler.h"
# include "base/utils/fs.h"
# include "base/logger.h"
# include "rssdownloadrulelist.h"
# include "rssarticle.h"
# include "rssparser.h"
@ -51,15 +52,15 @@ bool rssArticleDateRecentThan(const RssArticlePtr& left, const RssArticlePtr& ri
@@ -51,15 +52,15 @@ bool rssArticleDateRecentThan(const RssArticlePtr& left, const RssArticlePtr& ri
return left - > date ( ) > right - > date ( ) ;
}
RssFeed : : RssFeed ( RssManager * manager , RssFolder * parent , const QString & url ) :
m_manager ( manager ) ,
m_parent ( parent ) ,
m_url ( QUrl : : fromEncoded ( url . toUtf8 ( ) ) . toString ( ) ) ,
m_icon ( " :/icons/oxygen/application-rss+xml.png " ) ,
m_unreadCount ( 0 ) ,
m_dirty ( false ) ,
m_inErrorState ( false ) ,
m_loading ( false )
RssFeed : : RssFeed ( RssManager * manager , RssFolder * parent , const QString & url )
: m_manager ( manager )
, m_parent ( parent )
, m_url ( QUrl : : fromEncoded ( url . toUtf8 ( ) ) . toString ( ) )
, m_icon ( " :/icons/oxygen/application-rss+xml.png " )
, m_unreadCount ( 0 )
, m_dirty ( false )
, m_inErrorState ( false )
, m_loading ( false )
{
qDebug ( ) < < Q_FUNC_INFO < < m_url ;
// Listen for new RSS downloads
@ -83,44 +84,55 @@ RssFeed::~RssFeed()
@@ -83,44 +84,55 @@ RssFeed::~RssFeed()
Utils : : Fs : : forceRemove ( m_icon ) ;
}
RssFolder * RssFeed : : parent ( ) const
{
return m_parent ;
}
void RssFeed : : setParent ( RssFolder * parent )
{
m_parent = parent ;
}
void RssFeed : : saveItemsToDisk ( )
{
qDebug ( ) < < Q_FUNC_INFO < < m_url ;
if ( ! m_dirty )
return ;
if ( ! m_dirty ) return ;
markAsDirty ( false ) ;
QIniSettings qBTRSS ( " qBittorrent " , " qBittorrent-rss " ) ;
QVariantList old_items ;
QVariantList oldI tems ;
RssArticleHash : : ConstIterator it = m_articles . begin ( ) ;
RssArticleHash : : ConstIterator itend = m_articles . end ( ) ;
for ( ; it ! = itend ; + + it ) {
old_i tems < < it . value ( ) - > toHash ( ) ;
oldI tems < < it . value ( ) - > toHash ( ) ;
}
qDebug ( " Saving %d old items for feed %s " , old_i tems . size ( ) , qPrintable ( displayName ( ) ) ) ;
QHash < QString , QVariant > all_old_i tems = qBTRSS . value ( " old_items " , QHash < QString , QVariant > ( ) ) . toHash ( ) ;
all_old_i tems[ m_url ] = old_i tems ;
qBTRSS . setValue ( " old_items " , all_old_i tems ) ;
qDebug ( " Saving %d old items for feed %s " , oldI tems . size ( ) , qPrintable ( displayName ( ) ) ) ;
QHash < QString , QVariant > allOldI tems = qBTRSS . value ( " old_items " , QHash < QString , QVariant > ( ) ) . toHash ( ) ;
allOldI tems [ m_url ] = oldI tems ;
qBTRSS . setValue ( " old_items " , allOldI tems ) ;
}
void RssFeed : : loadItemsFromDisk ( )
{
QIniSettings qBTRSS ( " qBittorrent " , " qBittorrent-rss " ) ;
QHash < QString , QVariant > all_old_i tems = qBTRSS . value ( " old_items " , QHash < QString , QVariant > ( ) ) . toHash ( ) ;
const QVariantList old_items = all_old_i tems . value ( m_url , QVariantList ( ) ) . toList ( ) ;
qDebug ( " Loading %d old items for feed %s " , old_i tems . size ( ) , qPrintable ( displayName ( ) ) ) ;
QHash < QString , QVariant > allOldI tems = qBTRSS . value ( " old_items " , QHash < QString , QVariant > ( ) ) . toHash ( ) ;
const QVariantList oldItems = allOldI tems . value ( m_url , QVariantList ( ) ) . toList ( ) ;
qDebug ( " Loading %d old items for feed %s " , oldI tems . size ( ) , qPrintable ( displayName ( ) ) ) ;
foreach ( const QVariant & var_it , old_i tems ) {
foreach ( const QVariant & var_it , oldI tems ) {
QVariantHash item = var_it . toHash ( ) ;
RssArticlePtr rss_i tem = hashTo RssArticle( this , item ) ;
if ( rss_i tem )
addArticle ( rss_i tem ) ;
RssArticlePtr rssI tem = RssArticle : : fromHash ( this , item ) ;
if ( rssI tem )
addArticle ( rssI tem ) ;
}
}
void RssFeed : : addArticle ( const RssArticlePtr & article ) {
int max_articles = Preferences : : instance ( ) - > getRSSMaxArticlesPerFeed ( ) ;
void RssFeed : : addArticle ( const RssArticlePtr & article )
{
int maxArticles = Preferences : : instance ( ) - > getRSSMaxArticlesPerFeed ( ) ;
if ( ! m_articles . contains ( article - > guid ( ) ) ) {
markAsDirty ( ) ;
@ -134,7 +146,7 @@ void RssFeed::addArticle(const RssArticlePtr& article) {
@@ -134,7 +146,7 @@ void RssFeed::addArticle(const RssArticlePtr& article) {
RssArticleList : : Iterator lowerBound = qLowerBound ( m_articlesByDate . begin ( ) , m_articlesByDate . end ( ) , article , rssArticleDateRecentThan ) ;
m_articlesByDate . insert ( lowerBound , article ) ;
int lbIndex = m_articlesByDate . indexOf ( article ) ;
if ( m_articlesByDate . size ( ) > max_a rticles ) {
if ( m_articlesByDate . size ( ) > maxA rticles ) {
RssArticlePtr oldestArticle = m_articlesByDate . takeLast ( ) ;
m_articles . remove ( oldestArticle - > guid ( ) ) ;
// Update unreadCount
@ -144,7 +156,7 @@ void RssFeed::addArticle(const RssArticlePtr& article) {
@@ -144,7 +156,7 @@ void RssFeed::addArticle(const RssArticlePtr& article) {
// Check if article was inserted at the end of the list and will break max_articles limit
if ( Preferences : : instance ( ) - > isRssDownloadingEnabled ( ) ) {
if ( lbIndex < max_articles & & ! article - > isRead ( ) )
if ( ( lbIndex < maxArticles ) & & ! article - > isRead ( ) )
downloadArticleTorrentIfMatching ( m_manager - > downloadRules ( ) , article ) ;
}
}
@ -176,24 +188,29 @@ bool RssFeed::refresh()
@@ -176,24 +188,29 @@ bool RssFeed::refresh()
return true ;
}
QString RssFeed : : id ( ) const
{
return m_url ;
}
void RssFeed : : removeAllSettings ( )
{
qDebug ( ) < < " Removing all settings / history for feed: " < < m_url ;
QIniSettings qBTRSS ( " qBittorrent " , " qBittorrent-rss " ) ;
QVariantHash feeds_w_downloader = qBTRSS . value ( " downloader_on " , QVariantHash ( ) ) . toHash ( ) ;
if ( feeds_w_d ownloader . contains ( m_url ) ) {
feeds_w_d ownloader. remove ( m_url ) ;
qBTRSS . setValue ( " downloader_on " , feeds_w_d ownloader ) ;
QVariantHash feedsWD ownloader = qBTRSS . value ( " downloader_on " , QVariantHash ( ) ) . toHash ( ) ;
if ( feedsWD ownloader . contains ( m_url ) ) {
feedsWD ownloader . remove ( m_url ) ;
qBTRSS . setValue ( " downloader_on " , feedsWD ownloader ) ;
}
QVariantHash all_feeds_f ilters = qBTRSS . value ( " feed_filters " , QVariantHash ( ) ) . toHash ( ) ;
if ( all_feeds_f ilters . contains ( m_url ) ) {
all_feeds_f ilters. remove ( m_url ) ;
qBTRSS . setValue ( " feed_filters " , all_feeds_f ilters ) ;
QVariantHash allFeedsF ilters = qBTRSS . value ( " feed_filters " , QVariantHash ( ) ) . toHash ( ) ;
if ( allFeedsF ilters . contains ( m_url ) ) {
allFeedsF ilters . remove ( m_url ) ;
qBTRSS . setValue ( " feed_filters " , allFeedsF ilters ) ;
}
QVariantHash all_old_i tems = qBTRSS . value ( " old_items " , QVariantHash ( ) ) . toHash ( ) ;
if ( all_old_i tems . contains ( m_url ) ) {
all_old_i tems. remove ( m_url ) ;
qBTRSS . setValue ( " old_items " , all_old_i tems ) ;
QVariantHash allOldI tems = qBTRSS . value ( " old_items " , QVariantHash ( ) ) . toHash ( ) ;
if ( allOldI tems . contains ( m_url ) ) {
allOldI tems . remove ( m_url ) ;
qBTRSS . setValue ( " old_items " , allOldI tems ) ;
}
}
@ -207,10 +224,10 @@ QString RssFeed::title() const
@@ -207,10 +224,10 @@ QString RssFeed::title() const
return m_title ;
}
void RssFeed : : rename ( const QString & new_n ame )
void RssFeed : : rename ( const QString & newN ame )
{
qDebug ( ) < < " Renaming stream to " < < new_n ame ;
m_alias = new_n ame ;
qDebug ( ) < < " Renaming stream to " < < newN ame ;
m_alias = newN ame ;
}
// Return the alias if the stream has one, the url if it has no alias
@ -243,9 +260,7 @@ bool RssFeed::hasCustomIcon() const
@@ -243,9 +260,7 @@ bool RssFeed::hasCustomIcon() const
void RssFeed : : setIconPath ( const QString & path )
{
if ( path . isEmpty ( ) | | ! QFile : : exists ( path ) )
return ;
if ( ! path . isEmpty ( ) & & QFile : : exists ( path ) )
m_icon = path ;
}
@ -285,17 +300,22 @@ RssArticleList RssFeed::articleListByDateDesc() const
@@ -285,17 +300,22 @@ RssArticleList RssFeed::articleListByDateDesc() const
return m_articlesByDate ;
}
const RssArticleHash & RssFeed : : articleHash ( ) const
{
return m_articles ;
}
RssArticleList RssFeed : : unreadArticleListByDateDesc ( ) const
{
RssArticleList unread_news ;
RssArticleList unreadN ews ;
RssArticleList : : ConstIterator it = m_articlesByDate . begin ( ) ;
RssArticleList : : ConstIterator itend = m_articlesByDate . end ( ) ;
for ( ; it ! = itend ; + + it ) {
if ( ! ( * it ) - > isRead ( ) )
unread_n ews < < * it ;
unreadN ews < < * it ;
}
return unread_n ews ;
return unreadN ews ;
}
// download the icon from the address
@ -312,7 +332,8 @@ void RssFeed::handleFinishedDownload(const QString &url, const QString &filePath
@@ -312,7 +332,8 @@ void RssFeed::handleFinishedDownload(const QString &url, const QString &filePath
qDebug ( ) < < Q_FUNC_INFO < < " Successfully downloaded RSS feed at " < < url ;
// Parse the download RSS
m_manager - > rssParser ( ) - > parseRssFile ( m_url , filePath ) ;
} else if ( url = = m_iconUrl ) {
}
else if ( url = = m_iconUrl ) {
m_icon = filePath ;
qDebug ( ) < < Q_FUNC_INFO < < " icon path: " < < m_icon ;
m_manager - > forwardFeedIconChanged ( m_url , m_icon ) ;
@ -332,11 +353,8 @@ void RssFeed::handleDownloadFailure(const QString &url, const QString &error)
@@ -332,11 +353,8 @@ void RssFeed::handleDownloadFailure(const QString &url, const QString &error)
void RssFeed : : handleFeedTitle ( const QString & feedUrl , const QString & title )
{
if ( feedUrl ! = m_url )
return ;
if ( m_title = = title )
return ;
if ( feedUrl ! = m_url ) return ;
if ( m_title = = title ) return ;
m_title = title ;
@ -348,45 +366,45 @@ void RssFeed::handleFeedTitle(const QString& feedUrl, const QString& title)
@@ -348,45 +366,45 @@ void RssFeed::handleFeedTitle(const QString& feedUrl, const QString& title)
void RssFeed : : downloadArticleTorrentIfMatching ( RssDownloadRuleList * rules , const RssArticlePtr & article )
{
Q_ASSERT ( Preferences : : instance ( ) - > isRssDownloadingEnabled ( ) ) ;
RssDownloadRulePtr matching_rule = rules - > findMatchingRule ( m_url , article - > title ( ) ) ;
if ( ! matching_rule )
return ;
RssDownloadRulePtr matchingRule = rules - > findMatchingRule ( m_url , article - > title ( ) ) ;
if ( ! matchingRule ) return ;
if ( matching_r ule - > ignoreDays ( ) > 0 ) {
QDateTime lastMatch = matching_r ule - > lastMatch ( ) ;
if ( matchingR ule - > ignoreDays ( ) > 0 ) {
QDateTime lastMatch = matchingR ule - > lastMatch ( ) ;
if ( lastMatch . isValid ( ) ) {
if ( QDateTime : : currentDateTime ( ) < lastMatch . addDays ( matching_r ule - > ignoreDays ( ) ) ) {
if ( QDateTime : : currentDateTime ( ) < lastMatch . addDays ( matchingR ule - > ignoreDays ( ) ) ) {
connect ( article . data ( ) , SIGNAL ( articleWasRead ( ) ) , SLOT ( handleArticleStateChanged ( ) ) , Qt : : UniqueConnection ) ;
article - > markAsRead ( ) ;
return ;
}
}
}
matching_rule - > setLastMatch ( QDateTime : : currentDateTime ( ) ) ;
matchingRule - > setLastMatch ( QDateTime : : currentDateTime ( ) ) ;
rules - > saveRulesToStorage ( ) ;
// Download the torrent
const QString & torrent_u rl = article - > torrentUrl ( ) ;
if ( torrent_u rl . isEmpty ( ) ) {
const QString & torrentU rl = article - > torrentUrl ( ) ;
if ( torrentU rl . isEmpty ( ) ) {
Logger : : instance ( ) - > addMessage ( tr ( " Automatic download of '%1' from '%2' RSS feed failed because it doesn't contain a torrent or a magnet link... " ) . arg ( article - > title ( ) ) . arg ( displayName ( ) ) , Log : : WARNING ) ;
article - > markAsRead ( ) ;
return ;
}
Logger : : instance ( ) - > addMessage ( tr ( " Automatically downloading '%1' torrent from '%2' RSS feed... " ) . arg ( article - > title ( ) ) . arg ( displayName ( ) ) ) ;
connect ( article . data ( ) , SIGNAL ( articleWasRead ( ) ) , SLOT ( handleArticleStateChanged ( ) ) , Qt : : UniqueConnection ) ;
connect ( BitTorrent : : Session : : instance ( ) , SIGNAL ( downloadFromUrlFinished ( QString ) ) , article . data ( ) , SLOT ( handleTorrentDownloadSuccess ( const QString & ) ) , Qt : : UniqueConnection ) ;
if ( BitTorrent : : MagnetUri ( torrent_url ) . isValid ( ) )
article - > markAsRead ( ) ;
else
connect ( BitTorrent : : Session : : instance ( ) , SIGNAL ( downloadFromUrlFinished ( QString ) ) , article . data ( ) , SLOT ( handleTorrentDownloadSuccess ( const QString & ) ) , Qt : : UniqueConnection ) ;
BitTorrent : : AddTorrentParams params ;
params . savePath = matching_r ule - > savePath ( ) ;
params . label = matching_r ule - > label ( ) ;
if ( matching_r ule - > addPaused ( ) = = RssDownloadRule : : ALWAYS_PAUSED )
params . savePath = matchingR ule - > savePath ( ) ;
params . label = matchingR ule - > label ( ) ;
if ( matchingR ule - > addPaused ( ) = = RssDownloadRule : : ALWAYS_PAUSED )
params . addPaused = TriStateBool : : True ;
else if ( matching_r ule - > addPaused ( ) = = RssDownloadRule : : NEVER_PAUSED )
else if ( matchingR ule - > addPaused ( ) = = RssDownloadRule : : NEVER_PAUSED )
params . addPaused = TriStateBool : : False ;
BitTorrent : : Session : : instance ( ) - > addTorrent ( torrent_u rl , params ) ;
BitTorrent : : Session : : instance ( ) - > addTorrent ( torrentU rl , params ) ;
}
void RssFeed : : recheckRssItemsForDownload ( )
@ -401,10 +419,9 @@ void RssFeed::recheckRssItemsForDownload()
@@ -401,10 +419,9 @@ void RssFeed::recheckRssItemsForDownload()
void RssFeed : : handleNewArticle ( const QString & feedUrl , const QVariantHash & articleData )
{
if ( feedUrl ! = m_url )
return ;
if ( feedUrl ! = m_url ) return ;
RssArticlePtr article = hashTo RssArticle( this , articleData ) ;
RssArticlePtr article = RssArticle : : fromHash ( this , articleData ) ;
if ( article . isNull ( ) ) {
qDebug ( ) < < " Article hash corrupted or guid is uncomputable; feed url: " < < feedUrl ;
return ;
@ -420,8 +437,7 @@ void RssFeed::handleNewArticle(const QString& feedUrl, const QVariantHash& artic
@@ -420,8 +437,7 @@ void RssFeed::handleNewArticle(const QString& feedUrl, const QVariantHash& artic
void RssFeed : : handleFeedParsingFinished ( const QString & feedUrl , const QString & error )
{
if ( feedUrl ! = m_url )
return ;
if ( feedUrl ! = m_url ) return ;
if ( ! error . isEmpty ( ) ) {
qWarning ( ) < < " Failed to parse RSS feed at " < < feedUrl ;