Browse Source

Merge pull request #3567 from ngosang/rssfixes

[RSS] Several changes in RSSs. Closes #3560
adaptive-webui-19844
sledgehammer999 9 years ago
parent
commit
70f2086202
  1. 12
      src/gui/rss/rss.ui
  2. 120
      src/gui/rss/rss_imp.cpp
  3. 4
      src/gui/rss/rssarticle.cpp
  4. 6
      src/gui/rss/rssfeed.cpp
  5. 56
      src/gui/rss/rssparser.cpp

12
src/gui/rss/rss.ui

@ -116,16 +116,12 @@ @@ -116,16 +116,12 @@
<widget class="QLabel" name="news_lbl">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Torrents:&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;(double-click to download)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>Torrents: (double-click to download)</string>
</property>
</widget>
</item>
@ -139,7 +135,7 @@ p, li { white-space: pre-wrap; } @@ -139,7 +135,7 @@ p, li { white-space: pre-wrap; }
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>

120
src/gui/rss/rss_imp.cpp

@ -112,20 +112,31 @@ void RSSImp::displayItemsListMenu(const QPoint&) @@ -112,20 +112,31 @@ void RSSImp::displayItemsListMenu(const QPoint&)
{
QMenu myItemListMenu(this);
QList<QListWidgetItem*> selectedItems = listArticles->selectedItems();
if (selectedItems.size() > 0) {
bool has_attachment = false;
foreach (const QListWidgetItem* item, selectedItems) {
if (m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString())
->getItem(item->data(Article::IdRole).toString())->hasAttachment()) {
has_attachment = true;
break;
}
}
if (has_attachment)
myItemListMenu.addAction(actionDownload_torrent);
myItemListMenu.addAction(actionOpen_news_URL);
if (selectedItems.size() <= 0)
return;
bool hasTorrent = false;
bool hasLink = false;
foreach (const QListWidgetItem* item, selectedItems) {
if (!item) continue;
RssFeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString());
if (!feed) continue;
RssArticlePtr article = feed->getItem(item->data(Article::IdRole).toString());
if (!article) continue;
if (!article->torrentUrl().isEmpty())
hasTorrent = true;
if (!article->link().isEmpty())
hasLink = true;
if (hasTorrent && hasLink)
break;
}
myItemListMenu.exec(QCursor::pos());
if (hasTorrent)
myItemListMenu.addAction(actionDownload_torrent);
if (hasLink)
myItemListMenu.addAction(actionOpen_news_URL);
if (hasTorrent || hasLink)
myItemListMenu.exec(QCursor::pos());
}
void RSSImp::on_actionManage_cookies_triggered()
@ -238,21 +249,13 @@ void RSSImp::deleteSelectedItems() @@ -238,21 +249,13 @@ void RSSImp::deleteSelectedItems()
QList<QTreeWidgetItem*> selectedItems = m_feedList->selectedItems();
if (selectedItems.isEmpty())
return;
if ((selectedItems.size() == 1) && (selectedItems.first() == m_feedList->stickyUnreadItem()))
return;
int ret;
if (selectedItems.size() > 1) {
ret = QMessageBox::question(this, tr("Are you sure? -- qBittorrent"), tr("Are you sure you want to delete these elements from the list?"),
tr("&Yes"), tr("&No"),
QString(), 0, 1);
}
else {
if (selectedItems.first() == m_feedList->stickyUnreadItem())
return;
ret = QMessageBox::question(this, tr("Are you sure? -- qBittorrent"), tr("Are you sure you want to delete this element from the list?"),
tr("&Yes"), tr("&No"),
QString(), 0, 1);
}
if (ret)
QMessageBox::StandardButton answer = QMessageBox::question(this, tr("Deletion confirmation"),
tr("Are you sure you want to delete the selected RSS feeds?"),
QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
if (answer == QMessageBox::No)
return;
foreach (QTreeWidgetItem* item, selectedItems) {
@ -337,31 +340,57 @@ void RSSImp::refreshAllFeeds() @@ -337,31 +340,57 @@ void RSSImp::refreshAllFeeds()
void RSSImp::downloadSelectedTorrents()
{
QList<QListWidgetItem*> selected_items = listArticles->selectedItems();
foreach (const QListWidgetItem* item, selected_items) {
if (selected_items.size() <= 0)
return;
foreach (QListWidgetItem* item, selected_items) {
if (!item) continue;
RssFeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString());
if (!feed) continue;
RssArticlePtr article = feed->getItem(item->data(Article::IdRole).toString());
if (!article) continue;
// Mark as read
article->markAsRead();
item->setData(Article::ColorRole, QVariant(QColor("grey")));
item->setData(Article::IconRole, QVariant(QIcon(":/icons/sphere.png")));
if (article->torrentUrl().isEmpty())
continue;
if (Preferences::instance()->useAdditionDialog())
AddNewTorrentDialog::show(article->torrentUrl());
else
BitTorrent::Session::instance()->addTorrent(article->torrentUrl());
}
// Decrement feed nb unread news
updateItemInfos(m_feedList->stickyUnreadItem());
updateItemInfos(m_feedList->getTreeItemFromUrl(selected_items.first()->data(Article::FeedUrlRole).toString()));
}
// open the url of the selected RSS articles in the Web browser
void RSSImp::openSelectedArticlesUrls()
{
QList<QListWidgetItem *> selected_items = listArticles->selectedItems();
foreach (const QListWidgetItem* item, selected_items) {
RssArticlePtr news = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString())
->getItem(item->data(Article::IdRole).toString());
const QString link = news->link();
if (selected_items.size() <= 0)
return;
foreach (QListWidgetItem* item, selected_items) {
if (!item) continue;
RssFeedPtr feed = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString());
if (!feed) continue;
RssArticlePtr article = feed->getItem(item->data(Article::IdRole).toString());
if (!article) continue;
// Mark as read
article->markAsRead();
item->setData(Article::ColorRole, QVariant(QColor("grey")));
item->setData(Article::IconRole, QVariant(QIcon(":/icons/sphere.png")));
const QString link = article->link();
if (!link.isEmpty())
QDesktopServices::openUrl(QUrl(link));
}
// Decrement feed nb unread news
updateItemInfos(m_feedList->stickyUnreadItem());
updateItemInfos(m_feedList->getTreeItemFromUrl(selected_items.first()->data(Article::FeedUrlRole).toString()));
}
//right-click on stream : give it an alias
@ -538,21 +567,11 @@ void RSSImp::refreshTextBrowser() @@ -538,21 +567,11 @@ void RSSImp::refreshTextBrowser()
{
QList<QListWidgetItem*> selection = listArticles->selectedItems();
if (selection.empty()) return;
Q_ASSERT(selection.size() == 1);
QListWidgetItem *item = selection.first();
Q_ASSERT(item);
if (item == m_currentArticle) return;
// Stop displaying previous news if necessary
if (m_feedList->currentFeed() == m_feedList->stickyUnreadItem()) {
if (m_currentArticle) {
disconnect(listArticles, SIGNAL(itemSelectionChanged()), this, SLOT(refreshTextBrowser()));
listArticles->removeItemWidget(m_currentArticle);
Q_ASSERT(m_currentArticle);
delete m_currentArticle;
connect(listArticles, SIGNAL(itemSelectionChanged()), this, SLOT(refreshTextBrowser()));
}
m_currentArticle = item;
}
m_currentArticle = item;
RssFeedPtr stream = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString());
RssArticlePtr article = stream->getItem(item->data(Article::IdRole).toString());
QString html;
@ -675,14 +694,11 @@ void RSSImp::onFeedContentChanged(const QString& url) @@ -675,14 +694,11 @@ void RSSImp::onFeedContentChanged(const QString& url)
qDebug() << Q_FUNC_INFO << url;
QTreeWidgetItem *item = m_feedList->getTreeItemFromUrl(url);
// If the feed is selected, update the displayed news
if (m_feedList->currentItem() == item ) {
if (m_feedList->currentItem() == item)
populateArticleList(item);
}
else {
// Update unread items
if (m_feedList->currentItem() == m_feedList->stickyUnreadItem())
populateArticleList(m_feedList->stickyUnreadItem());
}
// Update unread items
else if (m_feedList->currentItem() == m_feedList->stickyUnreadItem())
populateArticleList(m_feedList->stickyUnreadItem());
}
void RSSImp::updateRefreshInterval(uint val)
@ -715,8 +731,6 @@ RSSImp::RSSImp(QWidget *parent): @@ -715,8 +731,6 @@ RSSImp::RSSImp(QWidget *parent):
m_feedList = new FeedListWidget(splitter_h, m_rssManager);
splitter_h->insertWidget(0, m_feedList);
listArticles->setSelectionBehavior(QAbstractItemView::SelectItems);
listArticles->setSelectionMode(QAbstractItemView::SingleSelection);
editHotkey = new QShortcut(QKeySequence("F2"), m_feedList, 0, 0, Qt::WidgetShortcut);
connect(editHotkey, SIGNAL(activated()), SLOT(renameSelectedRssFile()));
connect(m_feedList, SIGNAL(doubleClicked(QModelIndex)), SLOT(renameSelectedRssFile()));

4
src/gui/rss/rssarticle.cpp

@ -82,7 +82,7 @@ const QString& RssArticle::author() const { @@ -82,7 +82,7 @@ const QString& RssArticle::author() const {
}
const QString& RssArticle::torrentUrl() const {
return m_torrentUrl.isEmpty() ? m_link : m_torrentUrl;
return m_torrentUrl;
}
const QString& RssArticle::link() const {
@ -123,6 +123,6 @@ const QString& RssArticle::title() const @@ -123,6 +123,6 @@ const QString& RssArticle::title() const
}
void RssArticle::handleTorrentDownloadSuccess(const QString &url) {
if (url == m_torrentUrl || url == m_link)
if (url == m_torrentUrl)
markAsRead();
}

6
src/gui/rss/rssfeed.cpp

@ -364,6 +364,12 @@ void RssFeed::downloadArticleTorrentIfMatching(RssDownloadRuleList* rules, const @@ -364,6 +364,12 @@ void RssFeed::downloadArticleTorrentIfMatching(RssDownloadRuleList* rules, const
rules->saveRulesToStorage();
// Download the torrent
const QString& torrent_url = article->torrentUrl();
if (torrent_url.isEmpty()) {
Logger::instance()->addMessage(tr("Automatic download %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(BitTorrent::Session::instance(), SIGNAL(downloadFromUrlFinished(QString)), article.data(), SLOT(handleTorrentDownloadSuccess(const QString&)), Qt::UniqueConnection);
connect(article.data(), SIGNAL(articleWasRead()), SLOT(handleArticleStateChanged()), Qt::UniqueConnection);

56
src/gui/rss/rssparser.cpp

@ -254,24 +254,32 @@ void RssParser::parseRssArticle(QXmlStreamReader& xml, const QString& feedUrl) @@ -254,24 +254,32 @@ void RssParser::parseRssArticle(QXmlStreamReader& xml, const QString& feedUrl)
if (xml.isStartElement()) {
if (xml.name() == "title")
article["title"] = xml.readElementText();
article["title"] = xml.readElementText().trimmed();
else if (xml.name() == "enclosure") {
if (xml.attributes().value("type") == "application/x-bittorrent")
article["torrent_url"] = xml.attributes().value("url").toString();
}
else if (xml.name() == "link")
article["news_link"] = xml.readElementText();
else if (xml.name() == "link") {
QString link = xml.readElementText().trimmed();
if (link.startsWith("magnet:", Qt::CaseInsensitive))
article["torrent_url"] = link; // magnet link instead of a news URL
else
article["news_link"] = link;
}
else if (xml.name() == "description")
article["description"] = xml.readElementText();
article["description"] = xml.readElementText().trimmed();
else if (xml.name() == "pubDate")
article["date"] = parseDate(xml.readElementText());
article["date"] = parseDate(xml.readElementText().trimmed());
else if (xml.name() == "author")
article["author"] = xml.readElementText();
article["author"] = xml.readElementText().trimmed();
else if (xml.name() == "guid")
article["id"] = xml.readElementText();
article["id"] = xml.readElementText().trimmed();
}
}
if (!article.contains("torrent_url") && article.contains("news_link"))
article["torrent_url"] = article["news_link"];
if (!article.contains("id")) {
// Item does not have a guid, fall back to some other identifier
const QString link = article.value("news_link").toString();
@ -338,20 +346,21 @@ void RssParser::parseAtomArticle(QXmlStreamReader& xml, const QString& feedUrl, @@ -338,20 +346,21 @@ void RssParser::parseAtomArticle(QXmlStreamReader& xml, const QString& feedUrl,
// Workaround for CDATA (QString cannot parse html escapes on it's own)
QTextDocument doc;
doc.setHtml(xml.readElementText());
article["title"] = doc.toPlainText();
article["title"] = doc.toPlainText().trimmed();
}
else if (xml.name() == "link") {
QString theLink = ( xml.attributes().isEmpty() ?
xml.readElementText() :
xml.attributes().value("href").toString() );
QString link = ( xml.attributes().isEmpty() ?
xml.readElementText().trimmed() :
xml.attributes().value("href").toString() );
if (link.startsWith("magnet:", Qt::CaseInsensitive))
article["torrent_url"] = link; // magnet link instead of a news URL
else
// Atom feeds can have relative links, work around this and
// take the stress of figuring article full URI from UI
// Assemble full URI
article["news_link"] = ( baseUrl.isEmpty() ? link : baseUrl + link );
// Atom feeds can have relative links, work around this and
// take the stress of figuring article full URI from UI
// Assemble full URI
article["news_link"] = ( baseUrl.isEmpty() ?
theLink :
baseUrl + theLink );
}
else if (xml.name() == "summary" || xml.name() == "content"){
if(double_content) { // Duplicate content -> ignore
@ -367,13 +376,13 @@ void RssParser::parseAtomArticle(QXmlStreamReader& xml, const QString& feedUrl, @@ -367,13 +376,13 @@ void RssParser::parseAtomArticle(QXmlStreamReader& xml, const QString& feedUrl,
// Actually works great for non-broken content too
QString feedText = xml.readElementText(QXmlStreamReader::IncludeChildElements);
if (!feedText.isEmpty())
article["description"] = feedText;
article["description"] = feedText.trimmed();
double_content = true;
}
else if (xml.name() == "updated"){
// ATOM uses standard compliant date, don't do fancy stuff
QDateTime articleDate = QDateTime::fromString(xml.readElementText(), Qt::ISODate);
QDateTime articleDate = QDateTime::fromString(xml.readElementText().trimmed(), Qt::ISODate);
article["date"] = ( articleDate.isValid() ?
articleDate :
QDateTime::currentDateTime() );
@ -382,15 +391,18 @@ void RssParser::parseAtomArticle(QXmlStreamReader& xml, const QString& feedUrl, @@ -382,15 +391,18 @@ void RssParser::parseAtomArticle(QXmlStreamReader& xml, const QString& feedUrl,
xml.readNext();
while(xml.name() != "author") {
if(xml.name() == "name")
article["author"] = xml.readElementText();
article["author"] = xml.readElementText().trimmed();
xml.readNext();
}
}
else if (xml.name() == "id")
article["id"] = xml.readElementText();
article["id"] = xml.readElementText().trimmed();
}
}
if (!article.contains("torrent_url") && article.contains("news_link"))
article["torrent_url"] = article["news_link"];
if (!article.contains("id")) {
// Item does not have a guid, fall back to some other identifier
const QString link = article.value("news_link").toString();

Loading…
Cancel
Save