mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-23 17:59:44 +00:00
Use QXmlStreamReader instead of QDomDocument to save memory when parsing the RSS documents
This commit is contained in:
parent
a9be841d2d
commit
3c396257de
@ -14,6 +14,7 @@
|
|||||||
- FEATURE: Allow to change the priority of several files at once
|
- FEATURE: Allow to change the priority of several files at once
|
||||||
- FEATURE: Support for multiple scan folders (Patch by Christian Kandeler)
|
- FEATURE: Support for multiple scan folders (Patch by Christian Kandeler)
|
||||||
- BUGFIX: Only one log window can be opened at a time
|
- BUGFIX: Only one log window can be opened at a time
|
||||||
|
- BUGFIX: Optimized RSS module memory usage
|
||||||
- COSMETIC: Improved style management
|
- COSMETIC: Improved style management
|
||||||
|
|
||||||
* Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0
|
* Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0
|
||||||
|
125
src/rss.cpp
125
src/rss.cpp
@ -560,56 +560,80 @@ QString RssStream::getIconUrl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read and create items from a rss document
|
// read and create items from a rss document
|
||||||
short RssStream::readDoc(const QDomDocument& doc) {
|
short RssStream::readDoc(QIODevice* device) {
|
||||||
|
qDebug("Parsing RSS file...");
|
||||||
|
QXmlStreamReader xml(device);
|
||||||
// is it a rss file ?
|
// is it a rss file ?
|
||||||
QDomElement root = doc.documentElement();
|
if (xml.atEnd()) {
|
||||||
if(root.tagName() == QString::fromUtf8("html")){
|
qDebug("ERROR: Could not parse RSS file");
|
||||||
qDebug("the file is empty, maybe the url is invalid or the server is too busy");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if(root.tagName() != QString::fromUtf8("rss")){
|
while (!xml.atEnd()) {
|
||||||
qDebug("the file is not a rss stream, <rss> omitted: %s", root.tagName().toLocal8Bit().data());
|
xml.readNext();
|
||||||
return -1;
|
if(xml.isStartElement()) {
|
||||||
}
|
if(xml.name() != "rss") {
|
||||||
QDomNode rss = root.firstChild();
|
qDebug("ERROR: this is not a rss file, root tag is <%s>", qPrintable(xml.name().toString()));
|
||||||
QDomElement channel = root.firstChild().toElement();
|
return -1;
|
||||||
|
} else {
|
||||||
while(!channel.isNull()) {
|
break;
|
||||||
// we are reading the rss'main info
|
|
||||||
if (channel.tagName() == "channel") {
|
|
||||||
QDomElement property = channel.firstChild().toElement();
|
|
||||||
while(!property.isNull()) {
|
|
||||||
if (property.tagName() == "title") {
|
|
||||||
title = property.text();
|
|
||||||
if(alias==getUrl())
|
|
||||||
rename(title);
|
|
||||||
}
|
|
||||||
else if (property.tagName() == "link")
|
|
||||||
link = property.text();
|
|
||||||
else if (property.tagName() == "description")
|
|
||||||
description = property.text();
|
|
||||||
else if (property.tagName() == "image")
|
|
||||||
image = property.text();
|
|
||||||
else if(property.tagName() == "item") {
|
|
||||||
RssItem * item = new RssItem(this, property);
|
|
||||||
if(item->isValid()) {
|
|
||||||
QString title = item->getTitle();
|
|
||||||
bool already_exists = itemAlreadyExists(title);
|
|
||||||
if(!already_exists) {
|
|
||||||
(*this)[title] = item;
|
|
||||||
} else {
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
property = property.nextSibling().toElement();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
channel = channel.nextSibling().toElement();
|
|
||||||
}
|
}
|
||||||
|
// Read channels
|
||||||
|
while(!xml.atEnd()) {
|
||||||
|
xml.readNext();
|
||||||
|
|
||||||
|
if(xml.isEndElement())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(xml.isStartElement()) {
|
||||||
|
//qDebug("xml.name() == %s", qPrintable(xml.name().toString()));
|
||||||
|
if(xml.name() == "channel") {
|
||||||
|
qDebug("in channel");
|
||||||
|
|
||||||
|
// Parse channel content
|
||||||
|
while(!xml.atEnd()) {
|
||||||
|
xml.readNext();
|
||||||
|
|
||||||
|
if(xml.isEndElement() && xml.name() == "channel") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(xml.isStartElement()) {
|
||||||
|
//qDebug("xml.name() == %s", qPrintable(xml.name().toString()));
|
||||||
|
if(xml.name() == "title") {
|
||||||
|
title = xml.readElementText();
|
||||||
|
if(alias == getUrl())
|
||||||
|
rename(title);
|
||||||
|
}
|
||||||
|
else if(xml.name() == "link") {
|
||||||
|
link = xml.readElementText();
|
||||||
|
}
|
||||||
|
else if(xml.name() == "description") {
|
||||||
|
description = xml.readElementText();
|
||||||
|
}
|
||||||
|
else if(xml.name() == "image") {
|
||||||
|
image = xml.attributes().value("url").toString();
|
||||||
|
}
|
||||||
|
else if(xml.name() == "item") {
|
||||||
|
RssItem * item = new RssItem(this, xml);
|
||||||
|
if(item->isValid() && !itemAlreadyExists(item->getTitle())) {
|
||||||
|
this->insert(item->getTitle(), item);
|
||||||
|
} else {
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qDebug("XML Error: This is not a valid RSS document");
|
||||||
|
return -1;
|
||||||
|
|
||||||
resizeList();
|
resizeList();
|
||||||
|
|
||||||
// RSS Feed Downloader
|
// RSS Feed Downloader
|
||||||
foreach(RssItem* item, values()) {
|
foreach(RssItem* item, values()) {
|
||||||
if(item->isRead()) continue;
|
if(item->isRead()) continue;
|
||||||
@ -658,7 +682,6 @@ void RssStream::resizeList() {
|
|||||||
// existing and opening test after download
|
// existing and opening test after download
|
||||||
short RssStream::openRss(){
|
short RssStream::openRss(){
|
||||||
qDebug("openRss() called");
|
qDebug("openRss() called");
|
||||||
QDomDocument doc("Rss Seed");
|
|
||||||
QFile fileRss(filePath);
|
QFile fileRss(filePath);
|
||||||
if(!fileRss.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if(!fileRss.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
qDebug("openRss error: open failed, no file or locked, %s", (const char*)filePath.toLocal8Bit());
|
qDebug("openRss error: open failed, no file or locked, %s", (const char*)filePath.toLocal8Bit());
|
||||||
@ -667,19 +690,9 @@ short RssStream::openRss(){
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
QString error_msg = "";
|
|
||||||
int line=-1;
|
|
||||||
int col = -1;
|
|
||||||
if(!doc.setContent(&fileRss, &error_msg, &line, &col)) {
|
|
||||||
qDebug("Error when parsing XML at line %d (col: %d): %s", line, col, error_msg.toLocal8Bit().data());
|
|
||||||
fileRss.close();
|
|
||||||
if(QFile::exists(filePath)) {
|
|
||||||
fileRss.remove();
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// start reading the xml
|
// start reading the xml
|
||||||
short return_lecture = readDoc(doc);
|
short return_lecture = readDoc(&fileRss);
|
||||||
fileRss.close();
|
fileRss.close();
|
||||||
if(QFile::exists(filePath)) {
|
if(QFile::exists(filePath)) {
|
||||||
fileRss.remove();
|
fileRss.remove();
|
||||||
|
61
src/rss.h
61
src/rss.h
@ -35,7 +35,7 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QDomDocument>
|
#include <QXmlStreamReader>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@ -267,36 +267,47 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// public constructor
|
// public constructor
|
||||||
RssItem(RssStream* parent, const QDomElement& properties): parent(parent), read(false) {
|
RssItem(RssStream* parent, QXmlStreamReader& xml): parent(parent), read(false) {
|
||||||
is_valid = false;
|
is_valid = false;
|
||||||
torrent_url = QString::null;
|
torrent_url = QString::null;
|
||||||
news_link = QString::null;
|
news_link = QString::null;
|
||||||
title = QString::null;
|
title = QString::null;
|
||||||
QDomElement property = properties.firstChild().toElement();
|
while(!xml.atEnd()) {
|
||||||
while(!property.isNull()) {
|
xml.readNext();
|
||||||
if (property.tagName() == "title") {
|
|
||||||
title = property.text();
|
if(xml.isEndElement() && xml.name() == "item")
|
||||||
if(title.isEmpty()) {
|
break;
|
||||||
is_valid = false;
|
qDebug("in item: <%s>", qPrintable(xml.name().toString()));
|
||||||
return;
|
|
||||||
|
if(xml.isStartElement()) {
|
||||||
|
if(xml.name() == "title") {
|
||||||
|
title = xml.readElementText();
|
||||||
|
if(title.isEmpty()) {
|
||||||
|
is_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(xml.name() == "enclosure") {
|
||||||
|
if(xml.attributes().value("type") == "application/x-bittorrent") {
|
||||||
|
torrent_url = xml.attributes().value("url").toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(xml.name() == "link") {
|
||||||
|
news_link = xml.readElementText();
|
||||||
|
}
|
||||||
|
else if(xml.name() == "description") {
|
||||||
|
description = xml.readElementText();
|
||||||
|
}
|
||||||
|
else if(xml.name() == "pubDate") {
|
||||||
|
date = parseDate(xml.readElementText());
|
||||||
|
}
|
||||||
|
else if(xml.name() == "author") {
|
||||||
|
author = xml.readElementText();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (property.tagName() == "enclosure") {
|
|
||||||
if(property.attribute("type", "") == "application/x-bittorrent") {
|
|
||||||
torrent_url = property.attribute("url", QString::null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (property.tagName() == "link")
|
|
||||||
news_link = property.text();
|
|
||||||
else if (property.tagName() == "description")
|
|
||||||
description = property.text();
|
|
||||||
else if (property.tagName() == "pubDate")
|
|
||||||
date = parseDate(property.text());
|
|
||||||
else if (property.tagName() == "author")
|
|
||||||
author = property.text();
|
|
||||||
property = property.nextSibling().toElement();
|
|
||||||
}
|
}
|
||||||
is_valid = true;
|
if(!title.isEmpty())
|
||||||
|
is_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RssItem(RssStream* parent, QString _title, QString _torrent_url, QString _news_link, QString _description, QDateTime _date, QString _author, bool _read):
|
RssItem(RssStream* parent, QString _title, QString _torrent_url, QString _news_link, QString _description, QDateTime _date, QString _author, bool _read):
|
||||||
@ -435,7 +446,7 @@ public:
|
|||||||
QString getIconUrl();
|
QString getIconUrl();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
short readDoc(const QDomDocument& doc);
|
short readDoc(QIODevice* device);
|
||||||
void resizeList();
|
void resizeList();
|
||||||
short openRss();
|
short openRss();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user