Fix bug in Nextcloud which repeatedly overwriterd messages in DB even if they were not changed. Also fix incorrect real intervals between auto-downloads used.

This commit is contained in:
Martin Rotter 2020-12-21 12:25:11 +01:00
parent 1a6e7cd31c
commit ff04afd46b
7 changed files with 71 additions and 71 deletions

View File

@ -1037,7 +1037,9 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
feed_id_existing_message = query_select_with_custom_id.value(5).toString(); feed_id_existing_message = query_select_with_custom_id.value(5).toString();
qDebugNN << LOGSEC_DB qDebugNN << LOGSEC_DB
<< "Message with custom ID %s is already present in DB and has DB ID '" << "Message with custom ID"
<< QUOTE_W_SPACE(message.m_customId)
<< "is already present in DB and has DB ID '"
<< id_existing_message << id_existing_message
<< "'."; << "'.";
} }

View File

@ -283,7 +283,7 @@ void FeedReader::executeNextAutoUpdate() {
// then we need to restore it. // then we need to restore it.
if (m_globalAutoUpdateEnabled && --m_globalAutoUpdateRemainingInterval < 0) { if (m_globalAutoUpdateEnabled && --m_globalAutoUpdateRemainingInterval < 0) {
// We should start next auto-update interval. // We should start next auto-update interval.
m_globalAutoUpdateRemainingInterval = m_globalAutoUpdateInitialInterval; m_globalAutoUpdateRemainingInterval = m_globalAutoUpdateInitialInterval - 1;
} }
qDebugNN << LOGSEC_CORE qDebugNN << LOGSEC_CORE

View File

@ -103,7 +103,12 @@ void FormEditOwnCloudAccount::performTest() {
OwnCloudStatusResponse result = factory.status(); OwnCloudStatusResponse result = factory.status();
if (result.isLoaded()) { if (result.networkError() != QNetworkReply::NetworkError::NoError) {
m_ui->m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error,
tr("Network error: '%1'.").arg(NetworkFactory::networkErrorText(result.networkError())),
tr("Network error, have you entered correct Nextcloud endpoint and password?"));
}
else if (result.isLoaded()) {
if (!SystemFactory::isVersionEqualOrNewer(result.version(), OWNCLOUD_MIN_VERSION)) { if (!SystemFactory::isVersionEqualOrNewer(result.version(), OWNCLOUD_MIN_VERSION)) {
m_ui->m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error, m_ui->m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error,
tr( tr(
@ -121,11 +126,6 @@ void FormEditOwnCloudAccount::performTest() {
tr("Nextcloud News server is okay.")); tr("Nextcloud News server is okay."));
} }
} }
else if (factory.lastError() != QNetworkReply::NoError) {
m_ui->m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error,
tr("Network error: '%1'.").arg(NetworkFactory::networkErrorText(factory.lastError())),
tr("Network error, have you entered correct Nextcloud endpoint and password?"));
}
else { else {
m_ui->m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error, m_ui->m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error,
tr("Unspecified error, did you enter correct URL?"), tr("Unspecified error, did you enter correct URL?"),

View File

@ -75,10 +75,6 @@ void OwnCloudNetworkFactory::setAuthPassword(const QString& auth_password) {
m_authPassword = auth_password; m_authPassword = auth_password;
} }
QNetworkReply::NetworkError OwnCloudNetworkFactory::lastError() const {
return m_lastError;
}
OwnCloudStatusResponse OwnCloudNetworkFactory::status() { OwnCloudStatusResponse OwnCloudNetworkFactory::status() {
QByteArray result_raw; QByteArray result_raw;
QList<QPair<QByteArray, QByteArray>> headers; QList<QPair<QByteArray, QByteArray>> headers;
@ -92,7 +88,7 @@ OwnCloudStatusResponse OwnCloudNetworkFactory::status() {
QByteArray(), result_raw, QByteArray(), result_raw,
QNetworkAccessManager::GetOperation, QNetworkAccessManager::GetOperation,
headers); headers);
OwnCloudStatusResponse status_response(QString::fromUtf8(result_raw)); OwnCloudStatusResponse status_response(network_reply.first, QString::fromUtf8(result_raw));
qDebugNN << LOGSEC_NEXTCLOUD qDebugNN << LOGSEC_NEXTCLOUD
<< "Raw status data is:" << QUOTE_W_SPACE_DOT(result_raw); << "Raw status data is:" << QUOTE_W_SPACE_DOT(result_raw);
@ -103,7 +99,6 @@ OwnCloudStatusResponse OwnCloudNetworkFactory::status() {
<< QUOTE_W_SPACE_DOT(network_reply.first); << QUOTE_W_SPACE_DOT(network_reply.first);
} }
m_lastError = network_reply.first;
return status_response; return status_response;
} }
@ -125,8 +120,7 @@ OwnCloudGetFeedsCategoriesResponse OwnCloudNetworkFactory::feedsCategories() {
qCriticalNN << LOGSEC_NEXTCLOUD qCriticalNN << LOGSEC_NEXTCLOUD
<< "Obtaining of categories failed with error" << "Obtaining of categories failed with error"
<< QUOTE_W_SPACE_DOT(network_reply.first); << QUOTE_W_SPACE_DOT(network_reply.first);
m_lastError = network_reply.first; return OwnCloudGetFeedsCategoriesResponse(network_reply.first);
return OwnCloudGetFeedsCategoriesResponse();
} }
QString content_categories = QString::fromUtf8(result_raw); QString content_categories = QString::fromUtf8(result_raw);
@ -143,14 +137,12 @@ OwnCloudGetFeedsCategoriesResponse OwnCloudNetworkFactory::feedsCategories() {
qCriticalNN << LOGSEC_NEXTCLOUD qCriticalNN << LOGSEC_NEXTCLOUD
<< "Obtaining of feeds failed with error" << "Obtaining of feeds failed with error"
<< QUOTE_W_SPACE_DOT(network_reply.first); << QUOTE_W_SPACE_DOT(network_reply.first);
m_lastError = network_reply.first; return OwnCloudGetFeedsCategoriesResponse(network_reply.first);
return OwnCloudGetFeedsCategoriesResponse();
} }
QString content_feeds = QString::fromUtf8(result_raw); QString content_feeds = QString::fromUtf8(result_raw);
m_lastError = network_reply.first; return OwnCloudGetFeedsCategoriesResponse(network_reply.first, content_categories, content_feeds);
return OwnCloudGetFeedsCategoriesResponse(content_categories, content_feeds);
} }
bool OwnCloudNetworkFactory::deleteFeed(const QString& feed_id) { bool OwnCloudNetworkFactory::deleteFeed(const QString& feed_id) {
@ -167,8 +159,6 @@ bool OwnCloudNetworkFactory::deleteFeed(const QString& feed_id) {
QByteArray(), raw_output, QNetworkAccessManager::DeleteOperation, QByteArray(), raw_output, QNetworkAccessManager::DeleteOperation,
headers); headers);
m_lastError = network_reply.first;
if (network_reply.first != QNetworkReply::NoError) { if (network_reply.first != QNetworkReply::NoError) {
qCriticalNN << LOGSEC_NEXTCLOUD qCriticalNN << LOGSEC_NEXTCLOUD
<< "Obtaining of categories failed with error" << "Obtaining of categories failed with error"
@ -208,8 +198,6 @@ bool OwnCloudNetworkFactory::createFeed(const QString& url, int parent_id) {
QNetworkAccessManager::PostOperation, QNetworkAccessManager::PostOperation,
headers); headers);
m_lastError = network_reply.first;
if (network_reply.first != QNetworkReply::NoError) { if (network_reply.first != QNetworkReply::NoError) {
qCriticalNN << LOGSEC_NEXTCLOUD qCriticalNN << LOGSEC_NEXTCLOUD
<< "Creating of category failed with error" << "Creating of category failed with error"
@ -241,8 +229,6 @@ bool OwnCloudNetworkFactory::renameFeed(const QString& new_name, const QString&
QNetworkAccessManager::PutOperation, QNetworkAccessManager::PutOperation,
headers); headers);
m_lastError = network_reply.first;
if (network_reply.first != QNetworkReply::NoError) { if (network_reply.first != QNetworkReply::NoError) {
qCriticalNN << LOGSEC_NEXTCLOUD qCriticalNN << LOGSEC_NEXTCLOUD
<< "Renaming of feed failed with error" << "Renaming of feed failed with error"
@ -275,7 +261,7 @@ OwnCloudGetMessagesResponse OwnCloudNetworkFactory::getMessages(int feed_id) {
QByteArray(), result_raw, QByteArray(), result_raw,
QNetworkAccessManager::GetOperation, QNetworkAccessManager::GetOperation,
headers); headers);
OwnCloudGetMessagesResponse msgs_response(QString::fromUtf8(result_raw)); OwnCloudGetMessagesResponse msgs_response(network_reply.first, QString::fromUtf8(result_raw));
if (network_reply.first != QNetworkReply::NoError) { if (network_reply.first != QNetworkReply::NoError) {
qCriticalNN << LOGSEC_NEXTCLOUD qCriticalNN << LOGSEC_NEXTCLOUD
@ -283,7 +269,6 @@ OwnCloudGetMessagesResponse OwnCloudNetworkFactory::getMessages(int feed_id) {
<< QUOTE_W_SPACE_DOT(network_reply.first); << QUOTE_W_SPACE_DOT(network_reply.first);
} }
m_lastError = network_reply.first;
return msgs_response; return msgs_response;
} }
@ -309,10 +294,10 @@ QNetworkReply::NetworkError OwnCloudNetworkFactory::triggerFeedUpdate(int feed_i
<< QUOTE_W_SPACE_DOT(network_reply.first); << QUOTE_W_SPACE_DOT(network_reply.first);
} }
return (m_lastError = network_reply.first); return network_reply.first;
} }
void OwnCloudNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids) { NetworkResult OwnCloudNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids) {
QJsonObject json; QJsonObject json;
QJsonArray ids; QJsonArray ids;
QString final_url; QString final_url;
@ -337,7 +322,7 @@ void OwnCloudNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const
QByteArray output; QByteArray output;
NetworkFactory::performNetworkOperation(final_url, return NetworkFactory::performNetworkOperation(final_url,
qApp->settings()->value(GROUP(Feeds), qApp->settings()->value(GROUP(Feeds),
SETTING(Feeds::UpdateTimeout)).toInt(), SETTING(Feeds::UpdateTimeout)).toInt(),
QJsonDocument(json).toJson(QJsonDocument::Compact), QJsonDocument(json).toJson(QJsonDocument::Compact),
@ -346,7 +331,7 @@ void OwnCloudNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const
headers); headers);
} }
void OwnCloudNetworkFactory::markMessagesStarred(RootItem::Importance importance, NetworkResult OwnCloudNetworkFactory::markMessagesStarred(RootItem::Importance importance,
const QStringList& feed_ids, const QStringList& feed_ids,
const QStringList& guid_hashes) { const QStringList& guid_hashes) {
QJsonObject json; QJsonObject json;
@ -377,7 +362,7 @@ void OwnCloudNetworkFactory::markMessagesStarred(RootItem::Importance importance
QByteArray output; QByteArray output;
NetworkFactory::performNetworkOperation(final_url, return NetworkFactory::performNetworkOperation(final_url,
qApp->settings()->value(GROUP(Feeds), qApp->settings()->value(GROUP(Feeds),
SETTING(Feeds::UpdateTimeout)).toInt(), SETTING(Feeds::UpdateTimeout)).toInt(),
QJsonDocument(json).toJson(QJsonDocument::Compact), QJsonDocument(json).toJson(QJsonDocument::Compact),
@ -402,10 +387,9 @@ void OwnCloudNetworkFactory::setDownloadOnlyUnreadMessages(bool dowload_only_unr
m_downloadOnlyUnreadMessages = dowload_only_unread_messages; m_downloadOnlyUnreadMessages = dowload_only_unread_messages;
} }
OwnCloudResponse::OwnCloudResponse(const QString& raw_content) { OwnCloudResponse::OwnCloudResponse(QNetworkReply::NetworkError response, const QString& raw_content) :
m_rawContent = QJsonDocument::fromJson(raw_content.toUtf8()).object(); m_networkError(response), m_rawContent(QJsonDocument::fromJson(raw_content.toUtf8()).object()),
m_emptyString = raw_content.isEmpty(); m_emptyString(raw_content.isEmpty()) {}
}
OwnCloudResponse::~OwnCloudResponse() = default; OwnCloudResponse::~OwnCloudResponse() = default;
@ -417,7 +401,12 @@ QString OwnCloudResponse::toString() const {
return QJsonDocument(m_rawContent).toJson(QJsonDocument::Compact); return QJsonDocument(m_rawContent).toJson(QJsonDocument::Compact);
} }
OwnCloudStatusResponse::OwnCloudStatusResponse(const QString& raw_content) : OwnCloudResponse(raw_content) {} QNetworkReply::NetworkError OwnCloudResponse::networkError() const {
return m_networkError;
}
OwnCloudStatusResponse::OwnCloudStatusResponse(QNetworkReply::NetworkError response, const QString& raw_content)
: OwnCloudResponse(response, raw_content) {}
OwnCloudStatusResponse::~OwnCloudStatusResponse() = default; OwnCloudStatusResponse::~OwnCloudStatusResponse() = default;
@ -439,9 +428,10 @@ bool OwnCloudStatusResponse::misconfiguredCron() const {
} }
} }
OwnCloudGetFeedsCategoriesResponse::OwnCloudGetFeedsCategoriesResponse(QString raw_categories, OwnCloudGetFeedsCategoriesResponse::OwnCloudGetFeedsCategoriesResponse(QNetworkReply::NetworkError response,
QString raw_categories,
QString raw_feeds) QString raw_feeds)
: m_contentCategories(std::move(raw_categories)), m_contentFeeds(std::move(raw_feeds)) {} : OwnCloudResponse(response), m_contentCategories(std::move(raw_categories)), m_contentFeeds(std::move(raw_feeds)) {}
OwnCloudGetFeedsCategoriesResponse::~OwnCloudGetFeedsCategoriesResponse() = default; OwnCloudGetFeedsCategoriesResponse::~OwnCloudGetFeedsCategoriesResponse() = default;
@ -523,7 +513,8 @@ RootItem* OwnCloudGetFeedsCategoriesResponse::feedsCategories(bool obtain_icons)
return parent; return parent;
} }
OwnCloudGetMessagesResponse::OwnCloudGetMessagesResponse(const QString& raw_content) : OwnCloudResponse(raw_content) {} OwnCloudGetMessagesResponse::OwnCloudGetMessagesResponse(QNetworkReply::NetworkError response, const QString& raw_content)
: OwnCloudResponse(response, raw_content) {}
OwnCloudGetMessagesResponse::~OwnCloudGetMessagesResponse() = default; OwnCloudGetMessagesResponse::~OwnCloudGetMessagesResponse() = default;
@ -551,7 +542,7 @@ QList<Message>OwnCloudGetMessagesResponse::messages() const {
msg.m_enclosures.append(enclosure); msg.m_enclosures.append(enclosure);
} }
msg.m_feedId = QString::number(message_map["feedId"].toInt()); msg.m_feedId = message_map["feedId"].toString();
msg.m_isImportant = message_map["starred"].toBool(); msg.m_isImportant = message_map["starred"].toBool();
msg.m_isRead = !message_map["unread"].toBool(); msg.m_isRead = !message_map["unread"].toBool();
msg.m_title = message_map["title"].toString(); msg.m_title = message_map["title"].toString();

View File

@ -4,6 +4,7 @@
#define OWNCLOUDNETWORKFACTORY_H #define OWNCLOUDNETWORKFACTORY_H
#include "core/message.h" #include "core/message.h"
#include "network-web/networkfactory.h"
#include "services/abstract/rootitem.h" #include "services/abstract/rootitem.h"
#include <QDateTime> #include <QDateTime>
@ -14,20 +15,22 @@
class OwnCloudResponse { class OwnCloudResponse {
public: public:
explicit OwnCloudResponse(const QString& raw_content = QString()); explicit OwnCloudResponse(QNetworkReply::NetworkError response, const QString& raw_content = QString());
virtual ~OwnCloudResponse(); virtual ~OwnCloudResponse();
bool isLoaded() const; bool isLoaded() const;
QString toString() const; QString toString() const;
QNetworkReply::NetworkError networkError() const;
protected: protected:
QNetworkReply::NetworkError m_networkError;
QJsonObject m_rawContent; QJsonObject m_rawContent;
bool m_emptyString; bool m_emptyString;
}; };
class OwnCloudGetMessagesResponse : public OwnCloudResponse { class OwnCloudGetMessagesResponse : public OwnCloudResponse {
public: public:
explicit OwnCloudGetMessagesResponse(const QString& raw_content = QString()); explicit OwnCloudGetMessagesResponse(QNetworkReply::NetworkError response, const QString& raw_content = QString());
virtual ~OwnCloudGetMessagesResponse(); virtual ~OwnCloudGetMessagesResponse();
QList<Message> messages() const; QList<Message> messages() const;
@ -35,7 +38,7 @@ class OwnCloudGetMessagesResponse : public OwnCloudResponse {
class OwnCloudStatusResponse : public OwnCloudResponse { class OwnCloudStatusResponse : public OwnCloudResponse {
public: public:
explicit OwnCloudStatusResponse(const QString& raw_content = QString()); explicit OwnCloudStatusResponse(QNetworkReply::NetworkError response, const QString& raw_content = QString());
virtual ~OwnCloudStatusResponse(); virtual ~OwnCloudStatusResponse();
QString version() const; QString version() const;
@ -44,9 +47,9 @@ class OwnCloudStatusResponse : public OwnCloudResponse {
class RootItem; class RootItem;
class OwnCloudGetFeedsCategoriesResponse { class OwnCloudGetFeedsCategoriesResponse : public OwnCloudResponse {
public: public:
explicit OwnCloudGetFeedsCategoriesResponse(QString raw_categories = QString(), QString raw_feeds = QString()); explicit OwnCloudGetFeedsCategoriesResponse(QNetworkReply::NetworkError response, QString raw_categories = QString(), QString raw_feeds = QString());
virtual ~OwnCloudGetFeedsCategoriesResponse(); virtual ~OwnCloudGetFeedsCategoriesResponse();
// Returns tree of feeds/categories. // Returns tree of feeds/categories.
@ -76,8 +79,6 @@ class OwnCloudNetworkFactory {
QString authPassword() const; QString authPassword() const;
void setAuthPassword(const QString& auth_password); void setAuthPassword(const QString& auth_password);
QNetworkReply::NetworkError lastError() const;
// Operations. // Operations.
// Get version info. // Get version info.
@ -96,8 +97,8 @@ class OwnCloudNetworkFactory {
// Misc methods. // Misc methods.
QNetworkReply::NetworkError triggerFeedUpdate(int feed_id); QNetworkReply::NetworkError triggerFeedUpdate(int feed_id);
void markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids); NetworkResult markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids);
void markMessagesStarred(RootItem::Importance importance, const QStringList& feed_ids, const QStringList& guid_hashes); NetworkResult markMessagesStarred(RootItem::Importance importance, const QStringList& feed_ids, const QStringList& guid_hashes);
// Gets/sets the amount of messages to obtain during single feed update. // Gets/sets the amount of messages to obtain during single feed update.
int batchSize() const; int batchSize() const;
@ -113,8 +114,6 @@ class OwnCloudNetworkFactory {
bool m_forceServerSideUpdate; bool m_forceServerSideUpdate;
QString m_authUsername; QString m_authUsername;
QString m_authPassword; QString m_authPassword;
QNetworkReply::NetworkError m_lastError;
int m_batchSize; int m_batchSize;
// Endpoints. // Endpoints.

View File

@ -42,7 +42,7 @@ OwnCloudServiceRoot* OwnCloudFeed::serviceRoot() const {
QList<Message> OwnCloudFeed::obtainNewMessages(bool* error_during_obtaining) { QList<Message> OwnCloudFeed::obtainNewMessages(bool* error_during_obtaining) {
OwnCloudGetMessagesResponse messages = serviceRoot()->network()->getMessages(customNumericId()); OwnCloudGetMessagesResponse messages = serviceRoot()->network()->getMessages(customNumericId());
if (serviceRoot()->network()->lastError() != QNetworkReply::NetworkError::NoError) { if (messages.networkError() != QNetworkReply::NetworkError::NoError) {
setStatus(Feed::Status::NetworkError); setStatus(Feed::Status::NetworkError);
*error_during_obtaining = true; *error_during_obtaining = true;
serviceRoot()->itemChanged(QList<RootItem*>() << this); serviceRoot()->itemChanged(QList<RootItem*>() << this);

View File

@ -91,7 +91,11 @@ void OwnCloudServiceRoot::saveAllCachedData() {
QStringList ids = i.value(); QStringList ids = i.value();
if (!ids.isEmpty()) { if (!ids.isEmpty()) {
network()->markMessagesRead(key, ids); auto res = network()->markMessagesRead(key, ids);
if (res.first != QNetworkReply::NetworkError::NoError) {
addMessageStatesToCache(ids, key);
}
} }
} }
@ -111,7 +115,11 @@ void OwnCloudServiceRoot::saveAllCachedData() {
guid_hashes.append(msg.m_customHash); guid_hashes.append(msg.m_customHash);
} }
network()->markMessagesStarred(key, feed_ids, guid_hashes); auto res = network()->markMessagesStarred(key, feed_ids, guid_hashes);
if (res.first != QNetworkReply::NetworkError::NoError) {
addMessageStatesToCache(messages, key);
}
} }
} }
} }
@ -153,7 +161,7 @@ void OwnCloudServiceRoot::saveAccountDataToDatabase() {
RootItem* OwnCloudServiceRoot::obtainNewTreeForSyncIn() const { RootItem* OwnCloudServiceRoot::obtainNewTreeForSyncIn() const {
OwnCloudGetFeedsCategoriesResponse feed_cats_response = m_network->feedsCategories(); OwnCloudGetFeedsCategoriesResponse feed_cats_response = m_network->feedsCategories();
if (m_network->lastError() == QNetworkReply::NoError) { if (feed_cats_response.networkError() == QNetworkReply::NetworkError::NoError) {
return feed_cats_response.feedsCategories(true); return feed_cats_response.feedsCategories(true);
} }
else { else {