diff --git a/resources/text/CHANGELOG b/resources/text/CHANGELOG
index fcb65f7d4..314908986 100755
--- a/resources/text/CHANGELOG
+++ b/resources/text/CHANGELOG
@@ -5,7 +5,8 @@ Added:
▪ Auto-update status of feeds is now more general and complete. (issue #91)
Changed:
-▪ Better ATOM parsing, respects now XML namespaces, bit better link parsing and other stuff. (issue #104)
+▪ Updating of RSS Guard now uses GitHub API. (issue #109)
+▪ Better ATOM/RSS parsing, respects now XML namespaces, bit better link parsing and other stuff. (issue #104)
▪ Folder which holds SQL scripts got renamed to "sql".
▪ Tweaked some conditions for determining newly "updated" messages in ATOM format. (issue #103)
diff --git a/resources/text/UPDATES b/resources/text/UPDATES
deleted file mode 100644
index f9c7c4339..000000000
--- a/resources/text/UPDATES
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- https://github.com/martinrotter/rssguard/releases/download/3.4.0/rssguard-3.4.0-cb15ba92-win32.exe
-
-
diff --git a/src/definitions/definitions.h b/src/definitions/definitions.h
index 05ba72ba8..01c9e1fb5 100755
--- a/src/definitions/definitions.h
+++ b/src/definitions/definitions.h
@@ -31,8 +31,7 @@
#define URI_SCHEME_FEED_SHORT "feed:"
#define URI_SCHEME_FEED "feed://"
#define URI_SCHEME_HTTP "http://"
-#define RELEASES_LIST "https://raw.githubusercontent.com/martinrotter/rssguard/master/resources/text/UPDATES"
-#define CHANGELOG "https://raw.githubusercontent.com/martinrotter/rssguard/master/resources/text/CHANGELOG"
+#define RELEASES_LIST "https://api.github.com/repos/martinrotter/rssguard/releases"
#define DEFAULT_LOCALE "en"
#define DEFAULT_FEED_ENCODING "UTF-8"
#define DEFAULT_FEED_TYPE "RSS"
diff --git a/src/gui/dialogs/formupdate.cpp b/src/gui/dialogs/formupdate.cpp
index 02df02182..5d1dc8456 100755
--- a/src/gui/dialogs/formupdate.cpp
+++ b/src/gui/dialogs/formupdate.cpp
@@ -34,16 +34,25 @@
FormUpdate::FormUpdate(QWidget *parent)
- : QDialog(parent), m_downloader(nullptr), m_readyToInstall(false), m_ui(new Ui::FormUpdate) {
+ : QDialog(parent), m_downloader(nullptr), m_readyToInstall(false), m_ui(new Ui::FormUpdate), m_lastDownloadedBytes(0) {
m_ui->setupUi(this);
- m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Download update"), QDialogButtonBox::ActionRole);
- m_btnUpdate->setToolTip(tr("Download new installation files."));
m_ui->m_lblCurrentRelease->setText(APP_VERSION);
+ m_ui->m_tabInfo->removeTab(1);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("help-about")));
+ if (isSelfUpdateSupported()) {
+ m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Download selected update"), QDialogButtonBox::ActionRole);
+ m_btnUpdate->setToolTip(tr("Download new installation files."));
+ }
+ else {
+ m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Go to application website"), QDialogButtonBox::ActionRole);
+ m_btnUpdate->setToolTip(tr("Go to application website to get update packages manually."));
+ }
+
+ m_btnUpdate->setVisible(false);
connect(m_btnUpdate, &QPushButton::clicked, this, &FormUpdate::startUpdate);
checkForUpdates();
}
@@ -51,12 +60,8 @@ FormUpdate::FormUpdate(QWidget *parent)
FormUpdate::~FormUpdate() {
}
-bool FormUpdate::isUpdateForThisSystem() const {
- return m_updateInfo.m_urls.keys().contains(OS_ID);
-}
-
bool FormUpdate::isSelfUpdateSupported() const {
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
return true;
#else
return false;
@@ -64,51 +69,47 @@ bool FormUpdate::isSelfUpdateSupported() const {
}
void FormUpdate::checkForUpdates() {
- const QPair update = qApp->system()->checkForUpdates();
-
- m_updateInfo = update.first;
+ const QPair, QNetworkReply::NetworkError> update = qApp->system()->checkForUpdates();
if (update.second != QNetworkReply::NoError) {
+ m_updateInfo = UpdateInfo();
+ m_ui->m_tabInfo->setEnabled(false);
+
//: Unknown release.
m_ui->m_lblAvailableRelease->setText(tr("unknown"));
m_ui->m_txtChanges->clear();
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Error,
tr("Error: '%1'.").arg(NetworkFactory::networkErrorText(update.second)),
tr("List with updates was not\ndownloaded successfully."));
- m_btnUpdate->setEnabled(false);
- m_btnUpdate->setToolTip(tr("Checking for updates failed."));
}
else {
- m_ui->m_lblAvailableRelease->setText(update.first.m_availableVersion);
- m_ui->m_txtChanges->setText(update.first.m_changes);
+ const bool self_update_supported = isSelfUpdateSupported();
- const bool is_self_update_for_this_system = isUpdateForThisSystem() && isSelfUpdateSupported();
+ m_updateInfo = update.first.at(0);
+ m_ui->m_tabInfo->setEnabled(true);
+ m_ui->m_lblAvailableRelease->setText(m_updateInfo.m_availableVersion);
+ m_ui->m_txtChanges->setText(m_updateInfo.m_changes);
- if (SystemFactory::isVersionNewer(update.first.m_availableVersion, APP_VERSION)) {
+ if (SystemFactory::isVersionNewer(m_updateInfo.m_availableVersion, APP_VERSION)) {
+ m_btnUpdate->setVisible(true);
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok,
tr("New release available."),
tr("This is new version which can be\ndownloaded."));
- m_btnUpdate->setEnabled(true);
- m_btnUpdate->setToolTip(is_self_update_for_this_system ?
- tr("Download installation file for your OS.") :
- tr("Installation file is not available directly.\n"
- "Go to application website to obtain it manually."));
- m_btnUpdate->setText(is_self_update_for_this_system ? tr("Download update") : tr("Go to application website"));
+ if (self_update_supported) {
+ loadAvailableFiles();
+ }
}
else {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Warning,
tr("No new release available."),
tr("This release is not newer than\ncurrently installed one."));
- m_btnUpdate->setEnabled(false);
- m_btnUpdate->setToolTip(tr("No new update available."));
}
}
}
void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) {
- if (bytes_received % 10 == 0) {
- qApp->processEvents();
+ if (bytes_received - m_lastDownloadedBytes > 500000 || m_lastDownloadedBytes == 0) {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Information,
tr("Downloaded %1% (update size is %2 kB).").arg(QString::number(bytes_total == 0 ? 0 : (bytes_received * 100.0) / bytes_total,
'f',
@@ -117,11 +118,14 @@ void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) {
'f',
2)),
tr("Downloading update..."));
+ m_ui->m_lblStatus->repaint();
+
+ m_lastDownloadedBytes = bytes_received;
}
}
void FormUpdate::saveUpdateFile(const QByteArray &file_contents) {
- const QString url_file = m_updateInfo.m_urls.value(OS_ID).m_fileUrl;;
+ const QString url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString();
const QString temp_directory = qApp->getTempFolderPath();
if (!temp_directory.isEmpty()) {
@@ -151,13 +155,34 @@ void FormUpdate::saveUpdateFile(const QByteArray &file_contents) {
}
}
+void FormUpdate::loadAvailableFiles() {
+ m_ui->m_listFiles->clear();
+
+ foreach (const UpdateUrl &url, m_updateInfo.m_urls) {
+ QListWidgetItem *item = new QListWidgetItem(url.m_name + tr(" (size ") + url.m_size + QSL(")"));
+ item->setData(Qt::UserRole, url.m_fileUrl);
+ item->setToolTip(url.m_fileUrl);
+ m_ui->m_listFiles->addItem(item);
+ }
+
+ if (m_ui->m_listFiles->count() > 0) {
+ m_ui->m_listFiles->setCurrentRow(0);
+ }
+ else {
+ m_btnUpdate->setEnabled(false);
+ }
+
+ m_ui->m_tabInfo->addTab(m_ui->tabFiles, tr("Available update files"));
+ m_ui->m_tabInfo->setCurrentIndex(1);
+}
+
void FormUpdate::updateCompleted(QNetworkReply::NetworkError status, QByteArray contents) {
qDebug("Download of application update file was completed with code '%d'.", status);
switch (status) {
case QNetworkReply::NoError:
saveUpdateFile(contents);
- m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok, tr("Downloaded successfully"), tr("Package was downloaded successfully.\nYou must install it manually."));
+ m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok, tr("Downloaded successfully"), tr("Package was downloaded successfully.\nYou can install it now."));
m_btnUpdate->setText(tr("Install"));
m_btnUpdate->setEnabled(true);
break;
@@ -171,10 +196,11 @@ void FormUpdate::updateCompleted(QNetworkReply::NetworkError status, QByteArray
void FormUpdate::startUpdate() {
QString url_file;
- const bool update_for_this_system = isUpdateForThisSystem() && isSelfUpdateSupported();
+ const bool update_for_this_system = isSelfUpdateSupported();
- if (update_for_this_system) {
- url_file = m_updateInfo.m_urls.value(OS_ID).m_fileUrl;
+ if (update_for_this_system && m_ui->m_listFiles->currentItem() != nullptr) {
+ url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString();
+ m_ui->m_listFiles->setEnabled(false);
}
else {
url_file = APP_URL;
diff --git a/src/gui/dialogs/formupdate.h b/src/gui/dialogs/formupdate.h
index 84de91fe6..58dc21451 100755
--- a/src/gui/dialogs/formupdate.h
+++ b/src/gui/dialogs/formupdate.h
@@ -38,15 +38,11 @@ class FormUpdate : public QDialog {
explicit FormUpdate(QWidget *parent = 0);
virtual ~FormUpdate();
- // Returns true if current update provides
- // installation file for current platform.
- bool isUpdateForThisSystem() const;
-
// Returns true if application can self-update
// on current platform.
bool isSelfUpdateSupported() const;
- protected slots:
+ private slots:
// Check for updates and interprets the results.
void checkForUpdates();
void startUpdate();
@@ -56,12 +52,15 @@ class FormUpdate : public QDialog {
void saveUpdateFile(const QByteArray &file_contents);
private:
+ void loadAvailableFiles();
+
Downloader *m_downloader;
bool m_readyToInstall;
QString m_updateFilePath;
QScopedPointer m_ui;
UpdateInfo m_updateInfo;
QPushButton *m_btnUpdate;
+ qint64 m_lastDownloadedBytes;
};
#endif // FORMUPDATE_H
diff --git a/src/gui/dialogs/formupdate.ui b/src/gui/dialogs/formupdate.ui
index ba145bbf7..ddc829fd6 100755
--- a/src/gui/dialogs/formupdate.ui
+++ b/src/gui/dialogs/formupdate.ui
@@ -7,7 +7,7 @@
0
0
607
- 366
+ 326
@@ -15,10 +15,7 @@
-
-
-
- QFormLayout::AllNonFixedFieldsGrow
-
+
-
@@ -40,16 +37,6 @@
- -
-
-
- Changes
-
-
- m_txtChanges
-
-
-
-
@@ -75,37 +62,85 @@
-
-
-
-
- 0
- 1
-
+
+
+ 0
-
-
- DejaVu Sans Mono
-
-
-
- false
-
-
- QTextEdit::WidgetWidth
-
-
- true
-
-
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+
+
+ Changelog
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 1
+
+
+
+
+ DejaVu Sans Mono
+
+
+
+ false
+
+
+ QTextEdit::WidgetWidth
+
+
+ true
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:8.25pt; font-weight:400; font-style:normal;">
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p></body></html>
-
-
- Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
-
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+
+
+
+
+ Available files
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
diff --git a/src/miscellaneous/systemfactory.cpp b/src/miscellaneous/systemfactory.cpp
index 9c3b142fd..96f3f2cd4 100755
--- a/src/miscellaneous/systemfactory.cpp
+++ b/src/miscellaneous/systemfactory.cpp
@@ -28,9 +28,9 @@
#include
#include
#include
-#include
-#include
-#include
+#include
+#include
+#include
#include
#include
#include
@@ -205,18 +205,15 @@ QString SystemFactory::getUsername() const {
return name;
}
-QPair SystemFactory::checkForUpdates() const {
- QPair result;
- QByteArray releases_xml;
- QByteArray changelog;
+QPair, QNetworkReply::NetworkError> SystemFactory::checkForUpdates() const {
+ QPair, QNetworkReply::NetworkError> result;
+ QByteArray releases_json;
result.second = NetworkFactory::performNetworkOperation(RELEASES_LIST, DOWNLOAD_TIMEOUT, QByteArray(), QString(),
- releases_xml, QNetworkAccessManager::GetOperation).first;
- NetworkFactory::performNetworkOperation(CHANGELOG, DOWNLOAD_TIMEOUT, QByteArray(), QString(), changelog,
- QNetworkAccessManager::GetOperation);
+ releases_json, QNetworkAccessManager::GetOperation).first;
if (result.second == QNetworkReply::NoError) {
- result.first = parseUpdatesFile(releases_xml, changelog);
+ result.first = parseUpdatesFile(releases_json);
}
return result;
@@ -267,43 +264,47 @@ bool SystemFactory::openFolderFile(const QString &file_path) {
#endif
}
-UpdateInfo SystemFactory::parseUpdatesFile(const QByteArray &updates_file, const QByteArray &changelog) const {
- UpdateInfo update;
- QDomDocument document; document.setContent(updates_file, false);
- const QDomNodeList releases = document.elementsByTagName(QSL("release"));
+QList SystemFactory::parseUpdatesFile(const QByteArray &updates_file) const {
+ QList updates;
- if (releases.size() == 1) {
- QDomElement rel_elem = releases.at(0).toElement();
+ QJsonArray document = QJsonDocument::fromJson(updates_file).array();
- update.m_availableVersion = rel_elem.attributes().namedItem(QSL("version")).toAttr().value();
- update.m_changes = QString::fromUtf8(changelog);
+ for (int i = 0; i < document.size(); i++) {
+ QJsonObject release = document.at(i).toObject();
+ UpdateInfo update;
- QDomNodeList urls = rel_elem.elementsByTagName(QSL("url"));
+ update.m_date = QDateTime::fromString(release["published_at"].toString(), QSL("yyyy-MM-ddTHH:mm:ssZ"));
+ update.m_availableVersion = release["tag_name"].toString();
+ update.m_changes = release["body"].toString();
- for (int j = 0; j < urls.size(); j++) {
+ QJsonArray assets = release["assets"].toArray();
+
+ for (int j = 0; j < assets.size(); j++) {
+ QJsonObject asset = assets.at(j).toObject();
UpdateUrl url;
- QDomElement url_elem = urls.at(j).toElement();
- url.m_fileUrl = url_elem.text();
- url.m_os = url_elem.attributes().namedItem(QSL("os")).toAttr().value();
- url.m_platform = url_elem.attributes().namedItem(QSL("platform")).toAttr().value();
+ url.m_fileUrl = asset["browser_download_url"].toString();
+ url.m_name = asset["name"].toString();
+ url.m_size = asset["size"].toVariant().toString() + tr(" bytes");
- update.m_urls.insert(url.m_os, url);
+ update.m_urls.append(url);
}
- }
- else {
- update.m_availableVersion = QString();
+
+ updates.append(update);
}
+ qSort(updates.begin(), updates.end(), [](const UpdateInfo &a, const UpdateInfo &b) -> bool {
+ return a.m_date > b.m_date;
+ });
- return update;
+ return updates;
}
void SystemFactory::checkForUpdatesOnStartup() {
- const UpdateCheck updates = checkForUpdates();
+ const QPair, QNetworkReply::NetworkError> updates = checkForUpdates();
- if (updates.second == QNetworkReply::NoError && isVersionNewer(updates.first.m_availableVersion,
- APP_VERSION)) {
+ if (!updates.first.isEmpty() && updates.second == QNetworkReply::NoError && isVersionNewer(updates.first.at(0).m_availableVersion,
+ APP_VERSION)) {
qApp->showGuiMessage(tr("New version available"),
tr("Click the bubble for more information."),
QSystemTrayIcon::Information,
diff --git a/src/miscellaneous/systemfactory.h b/src/miscellaneous/systemfactory.h
index 3e83dc3d7..f34fb738e 100755
--- a/src/miscellaneous/systemfactory.h
+++ b/src/miscellaneous/systemfactory.h
@@ -29,18 +29,19 @@
class UpdateUrl {
public:
QString m_fileUrl;
- QString m_platform;
- QString m_os;
+ QString m_name;
+ QString m_size;
};
class UpdateInfo {
public:
- explicit UpdateInfo() : m_availableVersion(QString()), m_changes(QString()) {
+ explicit UpdateInfo() : m_availableVersion(QString()), m_changes(QString()), m_urls(QList()) {
}
QString m_availableVersion;
QString m_changes;
- QHash m_urls;
+ QList m_urls;
+ QDateTime m_date;
};
Q_DECLARE_METATYPE(UpdateInfo)
@@ -84,7 +85,7 @@ class SystemFactory : public QObject {
QString getUsername() const;
// Tries to download list with new updates.
- QPair checkForUpdates() const;
+ QPair, QNetworkReply::NetworkError> checkForUpdates() const;
// Checks if update is newer than current application version.
static bool isVersionNewer(const QString &new_version, const QString &base_version);
@@ -97,7 +98,7 @@ class SystemFactory : public QObject {
private:
// Performs parsing of downloaded file with list of updates.
- UpdateInfo parseUpdatesFile(const QByteArray &updates_file, const QByteArray &changelog) const;
+ QList parseUpdatesFile(const QByteArray &updates_file) const;
};
#endif // SYSTEMFACTORY_H
diff --git a/src/services/standard/feedparser.cpp b/src/services/standard/feedparser.cpp
index cf0d0ea8d..a2a016b33 100644
--- a/src/services/standard/feedparser.cpp
+++ b/src/services/standard/feedparser.cpp
@@ -94,3 +94,7 @@ QStringList FeedParser::textsFromPath(const QDomElement &element, const QString
return result;
}
+
+QString FeedParser::feedAuthor() const {
+ return "";
+}
diff --git a/src/services/standard/feedparser.h b/src/services/standard/feedparser.h
index 0829a3106..d18ca4469 100644
--- a/src/services/standard/feedparser.h
+++ b/src/services/standard/feedparser.h
@@ -34,7 +34,7 @@ class FeedParser {
protected:
QStringList textsFromPath(const QDomElement &element, const QString &namespace_uri, const QString &xml_path, bool only_first) const;
virtual QDomNodeList messageElements() = 0;
- virtual QString feedAuthor() const = 0;
+ virtual QString feedAuthor() const;
virtual Message extractMessage(const QDomElement &msg_element, QDateTime current_time) const = 0;
protected:
diff --git a/src/services/standard/rssparser.cpp b/src/services/standard/rssparser.cpp
index bdfcd328e..ff43127f1 100644
--- a/src/services/standard/rssparser.cpp
+++ b/src/services/standard/rssparser.cpp
@@ -19,105 +19,104 @@
#include "miscellaneous/textfactory.h"
#include "network-web/webfactory.h"
+#include "miscellaneous/iofactory.h"
+#include "exceptions/applicationexception.h"
#include
-RssParser::RssParser() {
+RssParser::RssParser(const QString &data) : FeedParser(data) {
}
RssParser::~RssParser() {
}
-QList RssParser::parseXmlData(const QString &data) {
- QList messages;
- QDomDocument xml_file;
- QDateTime current_time = QDateTime::currentDateTime();
+QDomNodeList RssParser::messageElements() {
+ QDomNode channel_elem = m_xml.namedItem(QSL("rss")).namedItem(QSL("channel"));
- xml_file.setContent(data, true);
+ if (channel_elem.isNull()) {
+ return QDomNodeList();
+ }
+ else {
+ return channel_elem.toElement().elementsByTagName(QSL("item"));
+ }
+}
- // Pull out all messages.
- QDomNodeList messages_in_xml = xml_file.elementsByTagName(QSL("item"));
+Message RssParser::extractMessage(const QDomElement &msg_element, QDateTime current_time) const {
+ Message new_message;
- for (int i = 0; i < messages_in_xml.size(); i++) {
- QDomNode message_item = messages_in_xml.item(i);
- Message new_message;
+ // Deal with titles & descriptions.
+ QString elem_title = msg_element.namedItem(QSL("title")).toElement().text().simplified();
+ QString elem_description = msg_element.namedItem(QSL("encoded")).toElement().text();
+ QString elem_enclosure = msg_element.namedItem(QSL("enclosure")).toElement().attribute(QSL("url"));
+ QString elem_enclosure_type = msg_element.namedItem(QSL("enclosure")).toElement().attribute(QSL("type"));
- // Deal with titles & descriptions.
- QString elem_title = message_item.namedItem(QSL("title")).toElement().text().simplified();
- QString elem_description = message_item.namedItem(QSL("encoded")).toElement().text();
- QString elem_enclosure = message_item.namedItem(QSL("enclosure")).toElement().attribute(QSL("url"));
- QString elem_enclosure_type = message_item.namedItem(QSL("enclosure")).toElement().attribute(QSL("type"));
-
- if (elem_description.isEmpty()) {
- elem_description = message_item.namedItem(QSL("description")).toElement().text();
- }
-
- // Now we obtained maximum of information for title & description.
- if (elem_title.isEmpty()) {
- if (elem_description.isEmpty()) {
- // BOTH title and description are empty, skip this message.
- continue;
- }
- else {
- // Title is empty but description is not.
- new_message.m_title = WebFactory::instance()->stripTags(elem_description.simplified());
- new_message.m_contents = elem_description;
- }
- }
- else {
- // Title is really not empty, description does not matter.
- new_message.m_title = WebFactory::instance()->stripTags(elem_title);
- new_message.m_contents = elem_description;
- }
-
- if (!elem_enclosure.isEmpty()) {
- new_message.m_enclosures.append(Enclosure(elem_enclosure, elem_enclosure_type));
-
- qDebug("Adding enclosure '%s' for the message.", qPrintable(elem_enclosure));
- }
-
- // Deal with link and author.
- new_message.m_url = message_item.namedItem(QSL("link")).toElement().text();
-
- if (new_message.m_url.isEmpty() && !new_message.m_enclosures.isEmpty()) {
- new_message.m_url = new_message.m_enclosures.first().m_url;
- }
-
- if (new_message.m_url.isEmpty()) {
- // Try to get "href" attribute.
- new_message.m_url = message_item.namedItem(QSL("link")).toElement().attribute(QSL("href"));
- }
-
- new_message.m_author = message_item.namedItem(QSL("author")).toElement().text();
-
- if (new_message.m_author.isEmpty()) {
- new_message.m_author = message_item.namedItem(QSL("creator")).toElement().text();
- }
-
- // Deal with creation date.
- new_message.m_created = TextFactory::parseDateTime(message_item.namedItem(QSL("pubDate")).toElement().text());
-
- if (new_message.m_created.isNull()) {
- new_message.m_created = TextFactory::parseDateTime(message_item.namedItem(QSL("date")).toElement().text());
- }
-
- if (!(new_message.m_createdFromFeed = !new_message.m_created.isNull())) {
- // Date was NOT obtained from the feed,
- // set current date as creation date for the message.
- new_message.m_created = current_time;
- }
-
- if (new_message.m_author.isNull()) {
- new_message.m_author = "";
- }
-
- if (new_message.m_url.isNull()) {
- new_message.m_url = "";
- }
-
- messages.append(new_message);
+ if (elem_description.isEmpty()) {
+ elem_description = msg_element.namedItem(QSL("description")).toElement().text();
}
- return messages;
+ // Now we obtained maximum of information for title & description.
+ if (elem_title.isEmpty()) {
+ if (elem_description.isEmpty()) {
+ // BOTH title and description are empty, skip this message.
+ throw new ApplicationException(QSL("Not enough data for the message."));
+ }
+ else {
+ // Title is empty but description is not.
+ new_message.m_title = WebFactory::instance()->stripTags(elem_description.simplified());
+ new_message.m_contents = elem_description;
+ }
+ }
+ else {
+ // Title is really not empty, description does not matter.
+ new_message.m_title = WebFactory::instance()->stripTags(elem_title);
+ new_message.m_contents = elem_description;
+ }
+
+ if (!elem_enclosure.isEmpty()) {
+ new_message.m_enclosures.append(Enclosure(elem_enclosure, elem_enclosure_type));
+
+ qDebug("Adding enclosure '%s' for the message.", qPrintable(elem_enclosure));
+ }
+
+ // Deal with link and author.
+ new_message.m_url = msg_element.namedItem(QSL("link")).toElement().text();
+
+ if (new_message.m_url.isEmpty() && !new_message.m_enclosures.isEmpty()) {
+ new_message.m_url = new_message.m_enclosures.first().m_url;
+ }
+
+ if (new_message.m_url.isEmpty()) {
+ // Try to get "href" attribute.
+ new_message.m_url = msg_element.namedItem(QSL("link")).toElement().attribute(QSL("href"));
+ }
+
+ new_message.m_author = msg_element.namedItem(QSL("author")).toElement().text();
+
+ if (new_message.m_author.isEmpty()) {
+ new_message.m_author = msg_element.namedItem(QSL("creator")).toElement().text();
+ }
+
+ // Deal with creation date.
+ new_message.m_created = TextFactory::parseDateTime(msg_element.namedItem(QSL("pubDate")).toElement().text());
+
+ if (new_message.m_created.isNull()) {
+ new_message.m_created = TextFactory::parseDateTime(msg_element.namedItem(QSL("date")).toElement().text());
+ }
+
+ if (!(new_message.m_createdFromFeed = !new_message.m_created.isNull())) {
+ // Date was NOT obtained from the feed,
+ // set current date as creation date for the message.
+ new_message.m_created = current_time;
+ }
+
+ if (new_message.m_author.isNull()) {
+ new_message.m_author = "";
+ }
+
+ if (new_message.m_url.isNull()) {
+ new_message.m_url = "";
+ }
+
+ return new_message;
}
diff --git a/src/services/standard/rssparser.h b/src/services/standard/rssparser.h
index 66f0dd3b3..db8e9822e 100644
--- a/src/services/standard/rssparser.h
+++ b/src/services/standard/rssparser.h
@@ -18,17 +18,21 @@
#ifndef RSSPARSER_H
#define RSSPARSER_H
+#include "services/standard/feedparser.h"
+
#include "core/message.h"
#include
-class RssParser {
+class RssParser : public FeedParser {
public:
- explicit RssParser();
+ explicit RssParser(const QString &data);
virtual ~RssParser();
- QList parseXmlData(const QString &data);
+ private:
+ QDomNodeList messageElements();
+ Message extractMessage(const QDomElement &msg_element, QDateTime current_time) const;
};
#endif // RSSPARSER_H
diff --git a/src/services/standard/standardfeed.cpp b/src/services/standard/standardfeed.cpp
index 4e1de2bcb..718c0bead 100755
--- a/src/services/standard/standardfeed.cpp
+++ b/src/services/standard/standardfeed.cpp
@@ -446,7 +446,7 @@ QList StandardFeed::obtainNewMessages(bool *error_during_obtaining) {
switch (type()) {
case StandardFeed::Rss0X:
case StandardFeed::Rss2X:
- messages = RssParser().parseXmlData(formatted_feed_contents);
+ messages = RssParser(formatted_feed_contents).messages();
break;
case StandardFeed::Rdf: