From 89b205b431568d58b4f7b1be1a377e5caf9497c8 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 12 Dec 2017 13:41:40 +0100 Subject: [PATCH 1/7] New donate link. --- README.md | 2 +- resources/binaries | 2 +- rssguard.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9c95e48ca..36c078190 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Welcome to RSS Guard website. You can find here basic information. RSS Guard is simple, light and easy-to-use RSS/ATOM feed aggregator developed using Qt framework which supports online feed synchronization. #### You can support this project via donations: -* [PATREON](https://www.patreon.com/martinrotter), +* [LIBERAPAY](https://liberapay.com/martinrotter), * [PAYPAL](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=XMWPLPK893VH4). #### See [Wiki](https://github.com/martinrotter/rssguard/wiki) for more information about features, download links and other stuff. diff --git a/resources/binaries b/resources/binaries index ae7084718..4a01edaec 160000 --- a/resources/binaries +++ b/resources/binaries @@ -1 +1 @@ -Subproject commit ae7084718c41afc01919779e58cd449e0eebd401 +Subproject commit 4a01edaec7d67d3b2ae81aeea2a3c876216fbab8 diff --git a/rssguard.pro b/rssguard.pro index a9d3524c8..e4795e949 100755 --- a/rssguard.pro +++ b/rssguard.pro @@ -65,7 +65,7 @@ APP_URL_ISSUES = "https://github.com/martinrotter/rssguard/issues APP_URL_ISSUES_NEW = "https://github.com/martinrotter/rssguard/issues/new" APP_URL_WIKI = "https://github.com/martinrotter/rssguard/wiki" APP_USERAGENT = "RSS Guard/$$APP_VERSION (github.com/martinrotter/rssguard)" -APP_DONATE_URL = "https://goo.gl/YFVJ0j" +APP_DONATE_URL = "https://liberapay.com/martinrotter" APP_WIN_ARCH = "win64" isEmpty(PREFIX) { From 3aa3ae1d46b49a8ee2c6123743cacf57a037910b Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 12 Dec 2017 13:42:15 +0100 Subject: [PATCH 2/7] New donate link. --- src/gui/dialogs/formmain.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/dialogs/formmain.ui b/src/gui/dialogs/formmain.ui index 9f4148054..4328b08bc 100755 --- a/src/gui/dialogs/formmain.ui +++ b/src/gui/dialogs/formmain.ui @@ -525,7 +525,7 @@ - &Donate via PayPal + &Donate... From 296a11e05f62fa904297876e69308e607cb4a2fe Mon Sep 17 00:00:00 2001 From: fanteik Date: Wed, 13 Dec 2017 22:12:02 +0100 Subject: [PATCH 3/7] Fix date bug in tt-rss service The value "Created on" of messages received from tiny tiny rss server are always 1969 or 1970. A 32-bit int can not record the timestamp in milliseconds. Changing to qint64 solve the problem. --- src/services/tt-rss/network/ttrssnetworkfactory.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/services/tt-rss/network/ttrssnetworkfactory.cpp b/src/services/tt-rss/network/ttrssnetworkfactory.cpp index 16828876c..b6808ca7e 100755 --- a/src/services/tt-rss/network/ttrssnetworkfactory.cpp +++ b/src/services/tt-rss/network/ttrssnetworkfactory.cpp @@ -580,8 +580,9 @@ QList TtRssGetHeadlinesResponse::messages() const { message.m_contents = mapped["content"].toString(); // Multiply by 1000 because Tiny Tiny RSS API does not include miliseconds in Unix - // date/time number. - message.m_created = TextFactory::parseDateTime(int(mapped["updated"].toDouble()) * 1000); + // date/time number. + const qint64 t = static_cast(mapped["updated"].toDouble()) * 1000; + message.m_created = TextFactory::parseDateTime(t); message.m_createdFromFeed = true; message.m_customId = QString::number(mapped["id"].toInt()); message.m_feedId = mapped["feed_id"].toString(); From 238c84b54ea32f4cbfdc977320ccd573380b6710 Mon Sep 17 00:00:00 2001 From: fanteik Date: Wed, 13 Dec 2017 22:38:35 +0100 Subject: [PATCH 4/7] Skip creating info file "aaa" rssguard writes a file "aaa" with some result values when using the tt-rss service. Not necessary for productive system. --- src/services/tt-rss/network/ttrssnetworkfactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/tt-rss/network/ttrssnetworkfactory.cpp b/src/services/tt-rss/network/ttrssnetworkfactory.cpp index b6808ca7e..c221b58b1 100755 --- a/src/services/tt-rss/network/ttrssnetworkfactory.cpp +++ b/src/services/tt-rss/network/ttrssnetworkfactory.cpp @@ -225,7 +225,7 @@ TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id, int lim result = TtRssGetHeadlinesResponse(QString::fromUtf8(result_raw)); } - IOFactory::writeFile("aaa", result_raw); + //IOFactory::writeFile("aaa", result_raw); if (network_reply.first != QNetworkReply::NoError) { qWarning("TT-RSS: getHeadlines failed with error %d.", network_reply.first); From a5340cce99f11a8d109cf65175cac9c007e0d98e Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 15 Dec 2017 07:49:24 +0100 Subject: [PATCH 5/7] Fix margins and rename import/export buttons. --- .../standard/gui/formstandardimportexport.cpp | 2 + .../standard/gui/formstandardimportexport.ui | 51 ++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/services/standard/gui/formstandardimportexport.cpp b/src/services/standard/gui/formstandardimportexport.cpp index e4d6eab87..1ced0865d 100755 --- a/src/services/standard/gui/formstandardimportexport.cpp +++ b/src/services/standard/gui/formstandardimportexport.cpp @@ -49,6 +49,7 @@ void FormStandardImportExport::setMode(const FeedsImportExportModel::Mode& mode) m_ui->m_lblRootNode->setVisible(false); m_ui->m_groupFile->setTitle(tr("Destination file")); m_ui->m_groupFeeds->setTitle(tr("Source feeds && categories")); + m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setText(tr("&Export to file")); setWindowTitle(tr("Export feeds")); setWindowIcon(qApp->icons()->fromTheme(QSL("document-export"))); break; @@ -58,6 +59,7 @@ void FormStandardImportExport::setMode(const FeedsImportExportModel::Mode& mode) m_ui->m_groupFile->setTitle(tr("Source file")); m_ui->m_groupFeeds->setTitle(tr("Target feeds && categories")); m_ui->m_groupFeeds->setDisabled(true); + m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setText(tr("&Import from file")); // Load categories. loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot); diff --git a/src/services/standard/gui/formstandardimportexport.ui b/src/services/standard/gui/formstandardimportexport.ui index b438067af..dd5314696 100755 --- a/src/services/standard/gui/formstandardimportexport.ui +++ b/src/services/standard/gui/formstandardimportexport.ui @@ -20,6 +20,18 @@ + + 3 + + + 3 + + + 3 + + + 3 + @@ -73,6 +85,18 @@ + + 3 + + + 3 + + + 3 + + + 3 + @@ -137,6 +161,18 @@ Operation results + + 3 + + + 3 + + + 3 + + + 3 + @@ -154,6 +190,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -176,10 +225,10 @@ m_btnSelectFile + m_cmbRootNode m_btnCheckAllItems m_btnUncheckAllItems m_treeFeeds - m_buttonBox From 4175dc226506cf02ec937ab02358408c98b66d90 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 15 Dec 2017 08:41:56 +0100 Subject: [PATCH 6/7] Automatically replace NULL strings with EMPTY strings. Fixes #169. --- resources/text/CHANGELOG | 2 ++ src/core/message.cpp | 2 +- src/miscellaneous/databasequeries.cpp | 36 ++++++++++++++------------- src/services/standard/atomparser.cpp | 1 + 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/resources/text/CHANGELOG b/resources/text/CHANGELOG index 821a3b04b..fa6b1551d 100644 --- a/resources/text/CHANGELOG +++ b/resources/text/CHANGELOG @@ -2,6 +2,8 @@ ————— Fixed: +▪ Bad handling of null/empty strings when inserting messages into DB. (bug #169) +▪ Bad conversion of "created on" date/time in TT-RSS plugin. (bug #172) ▪ Missing obligatory attribute in OPML 2.0 files. (bug #166) 3.5.5 diff --git a/src/core/message.cpp b/src/core/message.cpp index 46d1709fc..eb94f41ac 100755 --- a/src/core/message.cpp +++ b/src/core/message.cpp @@ -48,7 +48,7 @@ QString Enclosures::encodeEnclosuresToString(const QList& enclosures) } Message::Message() { - m_title = m_url = m_author = m_contents = m_feedId = m_customId = m_customHash = QSL(""); + m_title = m_url = m_author = m_contents = m_feedId = m_customId = m_customHash = ""; m_enclosures = QList(); m_accountId = m_id = 0; m_isRead = m_isImportant = false; diff --git a/src/miscellaneous/databasequeries.cpp b/src/miscellaneous/databasequeries.cpp index a038878e5..dc7188d6c 100755 --- a/src/miscellaneous/databasequeries.cpp +++ b/src/miscellaneous/databasequeries.cpp @@ -30,6 +30,8 @@ #include #include +#define EMPT_STR_NULL(x) ( ## x ## .isNull() ? "" : x) + bool DatabaseQueries::markMessagesReadUnread(QSqlDatabase db, const QStringList& ids, RootItem::ReadStatus read) { QSqlQuery q(db); @@ -516,10 +518,10 @@ int DatabaseQueries::updateMessages(QSqlDatabase db, if (message.m_customId.isEmpty()) { // We need to recognize existing messages according URL & AUTHOR & TITLE. // NOTE: This particularly concerns messages from standard account. - query_select_with_url.bindValue(QSL(":feed"), feed_custom_id); - query_select_with_url.bindValue(QSL(":title"), message.m_title); - query_select_with_url.bindValue(QSL(":url"), message.m_url); - query_select_with_url.bindValue(QSL(":author"), message.m_author); + query_select_with_url.bindValue(QSL(":feed"), EMPT_STR_NULL(feed_custom_id)); + query_select_with_url.bindValue(QSL(":title"), EMPT_STR_NULL(message.m_title)); + query_select_with_url.bindValue(QSL(":url"), EMPT_STR_NULL(message.m_url)); + query_select_with_url.bindValue(QSL(":author"), EMPT_STR_NULL(message.m_author)); query_select_with_url.bindValue(QSL(":account_id"), account_id); qDebug("Checking if message with title '%s', url '%s' and author '%s' is present in DB.", @@ -545,7 +547,7 @@ int DatabaseQueries::updateMessages(QSqlDatabase db, // We can recognize existing messages via their custom ID. // NOTE: This concerns messages from custom accounts, like TT-RSS or ownCloud News. query_select_with_id.bindValue(QSL(":account_id"), account_id); - query_select_with_id.bindValue(QSL(":custom_id"), message.m_customId); + query_select_with_id.bindValue(QSL(":custom_id"), EMPT_STR_NULL(message.m_customId)); qDebug("Checking if message with custom ID %s is present in DB.", qPrintable(message.m_customId)); @@ -582,15 +584,15 @@ int DatabaseQueries::updateMessages(QSqlDatabase db, /* 2 */ (message.m_createdFromFeed && message.m_created.toMSecsSinceEpoch() != date_existing_message && message.m_contents != contents_existing_message)) { // Message exists, it is changed, update it. - query_update.bindValue(QSL(":title"), message.m_title); + query_update.bindValue(QSL(":title"), EMPT_STR_NULL(message.m_title)); query_update.bindValue(QSL(":is_read"), (int) message.m_isRead); query_update.bindValue(QSL(":is_important"), (int) message.m_isImportant); - query_update.bindValue(QSL(":url"), message.m_url); - query_update.bindValue(QSL(":author"), message.m_author); + query_update.bindValue(QSL(":url"), EMPT_STR_NULL(message.m_url)); + query_update.bindValue(QSL(":author"), EMPT_STR_NULL(message.m_author)); query_update.bindValue(QSL(":date_created"), message.m_created.toMSecsSinceEpoch()); - query_update.bindValue(QSL(":contents"), message.m_contents); + query_update.bindValue(QSL(":contents"), EMPT_STR_NULL(message.m_contents)); query_update.bindValue(QSL(":enclosures"), Enclosures::encodeEnclosuresToString(message.m_enclosures)); - query_update.bindValue(QSL(":feed"), message.m_feedId); + query_update.bindValue(QSL(":feed"), EMPT_STR_NULL(feed_id_existing_message)); query_update.bindValue(QSL(":id"), id_existing_message); *any_message_changed = true; @@ -610,17 +612,17 @@ int DatabaseQueries::updateMessages(QSqlDatabase db, } else { // Message with this URL is not fetched in this feed yet. - query_insert.bindValue(QSL(":feed"), feed_custom_id); - query_insert.bindValue(QSL(":title"), message.m_title); + query_insert.bindValue(QSL(":feed"), EMPT_STR_NULL(feed_custom_id)); + query_insert.bindValue(QSL(":title"), EMPT_STR_NULL(message.m_title)); query_insert.bindValue(QSL(":is_read"), (int) message.m_isRead); query_insert.bindValue(QSL(":is_important"), (int) message.m_isImportant); - query_insert.bindValue(QSL(":url"), message.m_url); - query_insert.bindValue(QSL(":author"), message.m_author); + query_insert.bindValue(QSL(":url"), EMPT_STR_NULL( message.m_url)); + query_insert.bindValue(QSL(":author"), EMPT_STR_NULL(message.m_author)); query_insert.bindValue(QSL(":date_created"), message.m_created.toMSecsSinceEpoch()); - query_insert.bindValue(QSL(":contents"), message.m_contents); + query_insert.bindValue(QSL(":contents"), EMPT_STR_NULL(message.m_contents)); query_insert.bindValue(QSL(":enclosures"), Enclosures::encodeEnclosuresToString(message.m_enclosures)); - query_insert.bindValue(QSL(":custom_id"), message.m_customId); - query_insert.bindValue(QSL(":custom_hash"), message.m_customHash); + query_insert.bindValue(QSL(":custom_id"), EMPT_STR_NULL(message.m_customId)); + query_insert.bindValue(QSL(":custom_hash"), EMPT_STR_NULL(message.m_customHash)); query_insert.bindValue(QSL(":account_id"), account_id); if (query_insert.exec() && query_insert.numRowsAffected() == 1) { diff --git a/src/services/standard/atomparser.cpp b/src/services/standard/atomparser.cpp index d973d86ab..7740df34b 100755 --- a/src/services/standard/atomparser.cpp +++ b/src/services/standard/atomparser.cpp @@ -59,6 +59,7 @@ Message AtomParser::extractMessage(const QDomElement& msg_element, QDateTime cur new_message.m_title = qApp->web()->stripTags(title); new_message.m_contents = summary; new_message.m_author = qApp->web()->escapeHtml(messageAuthor(msg_element)); + QString updated = textsFromPath(msg_element, m_atomNamespace, QSL("updated"), true).join(QSL(", ")); if (updated.isEmpty()) { From f23e1aec73dbd9abbd53cee30de6a126123cea56 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 15 Dec 2017 09:11:07 +0100 Subject: [PATCH 7/7] Some optimalizations on OAuth process. --- src/network-web/oauth2service.cpp | 6 +++++- src/services/gmail/gmailserviceroot.cpp | 4 ++-- src/services/gmail/network/gmailnetworkfactory.cpp | 2 ++ src/services/inoreader/inoreaderserviceroot.cpp | 5 +++-- src/services/inoreader/network/inoreadernetworkfactory.cpp | 2 ++ 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/network-web/oauth2service.cpp b/src/network-web/oauth2service.cpp index 696c8da03..200c27be1 100755 --- a/src/network-web/oauth2service.cpp +++ b/src/network-web/oauth2service.cpp @@ -26,6 +26,7 @@ #include "definitions/definitions.h" #include "miscellaneous/application.h" +#include "network-web/networkfactory.h" #include "network-web/webfactory.h" #include "services/inoreader/definitions.h" @@ -186,7 +187,10 @@ void OAuth2Service::tokenRequestFinished(QNetworkReply* network_reply) { qDebug() << "Token response:" << json_document.toJson(); - if (root_obj.keys().contains("error")) { + if (network_reply->error() != QNetworkReply::NetworkError::NoError) { + emit tokensRetrieveError(QString(), NetworkFactory::networkErrorText(network_reply->error())); + } + else if (root_obj.keys().contains("error")) { QString error = root_obj.value("error").toString(); QString error_description = root_obj.value("error_description").toString(); diff --git a/src/services/gmail/gmailserviceroot.cpp b/src/services/gmail/gmailserviceroot.cpp index 2c732e07d..9c99050ab 100755 --- a/src/services/gmail/gmailserviceroot.cpp +++ b/src/services/gmail/gmailserviceroot.cpp @@ -164,11 +164,11 @@ void GmailServiceRoot::start(bool freshly_activated) { loadFromDatabase(); loadCacheFromFile(accountId()); - m_network->oauth()->login(); - if (childCount() <= 1) { syncIn(); } + + m_network->oauth()->login(); } void GmailServiceRoot::stop() { diff --git a/src/services/gmail/network/gmailnetworkfactory.cpp b/src/services/gmail/network/gmailnetworkfactory.cpp index 2d2276541..4b2655f33 100755 --- a/src/services/gmail/network/gmailnetworkfactory.cpp +++ b/src/services/gmail/network/gmailnetworkfactory.cpp @@ -269,6 +269,8 @@ void GmailNetworkFactory::onTokensError(const QString& error, const QString& err QSystemTrayIcon::Critical, nullptr, false, [this]() { + m_oauth2->setAccessToken(QString()); + m_oauth2->setRefreshToken(QString()); m_oauth2->login(); }); } diff --git a/src/services/inoreader/inoreaderserviceroot.cpp b/src/services/inoreader/inoreaderserviceroot.cpp index 35f34cc5c..764b572d4 100755 --- a/src/services/inoreader/inoreaderserviceroot.cpp +++ b/src/services/inoreader/inoreaderserviceroot.cpp @@ -122,11 +122,12 @@ void InoreaderServiceRoot::start(bool freshly_activated) { loadFromDatabase(); loadCacheFromFile(accountId()); - m_network->oauth()->login(); - if (childCount() <= 1) { syncIn(); } + else { + m_network->oauth()->login(); + } } void InoreaderServiceRoot::stop() { diff --git a/src/services/inoreader/network/inoreadernetworkfactory.cpp b/src/services/inoreader/network/inoreadernetworkfactory.cpp index ab8172e11..f2740200a 100755 --- a/src/services/inoreader/network/inoreadernetworkfactory.cpp +++ b/src/services/inoreader/network/inoreadernetworkfactory.cpp @@ -283,6 +283,8 @@ void InoreaderNetworkFactory::onTokensError(const QString& error, const QString& QSystemTrayIcon::Critical, nullptr, false, [this]() { + m_oauth2->setAccessToken(QString()); + m_oauth2->setRefreshToken(QString()); m_oauth2->login(); }); }