fix for #732 + some related changes

This commit is contained in:
Martin Rotter 2022-05-11 11:11:15 +02:00
parent a70fcb663c
commit 3b064d8e34
17 changed files with 261 additions and 207 deletions

View File

@ -26,7 +26,7 @@
<url type="donation">https://github.com/sponsors/martinrotter</url> <url type="donation">https://github.com/sponsors/martinrotter</url>
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1" />
<releases> <releases>
<release version="4.2.2" date="2022-05-10"/> <release version="4.2.2" date="2022-05-11"/>
</releases> </releases>
<content_rating type="oars-1.0"> <content_rating type="oars-1.0">
<content_attribute id="violence-cartoon">none</content_attribute> <content_attribute id="violence-cartoon">none</content_attribute>

View File

@ -170,8 +170,12 @@ void FormUpdate::loadAvailableFiles() {
m_ui.m_tabInfo->setCurrentIndex(1); m_ui.m_tabInfo->setCurrentIndex(1);
} }
void FormUpdate::updateCompleted(const QUrl& url, QNetworkReply::NetworkError status, const QByteArray& contents) { void FormUpdate::updateCompleted(const QUrl& url,
QNetworkReply::NetworkError status,
int http_code,
const QByteArray& contents) {
Q_UNUSED(url) Q_UNUSED(url)
Q_UNUSED(http_code)
qDebugNN << LOGSEC_GUI << "Download of application update file was completed with code" << QUOTE_W_SPACE_DOT(status); qDebugNN << LOGSEC_GUI << "Download of application update file was completed with code" << QUOTE_W_SPACE_DOT(status);

View File

@ -17,7 +17,6 @@ class RSSGUARD_DLLSPEC FormUpdate : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
// Constructors and destructors. // Constructors and destructors.
explicit FormUpdate(QWidget* parent); explicit FormUpdate(QWidget* parent);
@ -32,7 +31,10 @@ class RSSGUARD_DLLSPEC FormUpdate : public QDialog {
void startUpdate(); void startUpdate();
void updateProgress(qint64 bytes_received, qint64 bytes_total); void updateProgress(qint64 bytes_received, qint64 bytes_total);
void updateCompleted(const QUrl &url, QNetworkReply::NetworkError status, const QByteArray& contents); void updateCompleted(const QUrl& url,
QNetworkReply::NetworkError status,
int http_code,
const QByteArray& contents);
void saveUpdateFile(const QByteArray& file_contents); void saveUpdateFile(const QByteArray& file_contents);
private: private:

View File

@ -548,7 +548,12 @@ void TextBrowserViewer::downloadNextNeededResource() {
} }
} }
void TextBrowserViewer::resourceDownloaded(const QUrl& url, QNetworkReply::NetworkError status, QByteArray contents) { void TextBrowserViewer::resourceDownloaded(const QUrl& url,
QNetworkReply::NetworkError status,
int http_code,
QByteArray contents) {
Q_UNUSED(http_code)
if (status == QNetworkReply::NetworkError::NoError) { if (status == QNetworkReply::NetworkError::NoError) {
m_loadedResources.insert(url, contents); m_loadedResources.insert(url, contents);
} }

View File

@ -86,7 +86,10 @@ class TextBrowserViewer : public QTextBrowser, public WebViewer {
private slots: private slots:
void reloadHtmlDelayed(); void reloadHtmlDelayed();
void downloadNextNeededResource(); void downloadNextNeededResource();
void resourceDownloaded(const QUrl& url, QNetworkReply::NetworkError status, QByteArray contents = QByteArray()); void resourceDownloaded(const QUrl& url,
QNetworkReply::NetworkError status,
int http_code,
QByteArray contents = QByteArray());
private: private:
bool m_resourcesEnabled; bool m_resourcesEnabled;

View File

@ -17,8 +17,8 @@
Downloader::Downloader(QObject* parent) Downloader::Downloader(QObject* parent)
: QObject(parent), m_activeReply(nullptr), m_downloadManager(new SilentNetworkAccessManager(this)), : QObject(parent), m_activeReply(nullptr), m_downloadManager(new SilentNetworkAccessManager(this)),
m_timer(new QTimer(this)), m_inputData(QByteArray()), m_inputMultipartData(nullptr), m_targetProtected(false), m_timer(new QTimer(this)), m_inputData(QByteArray()), m_inputMultipartData(nullptr), m_targetProtected(false),
m_targetUsername(QString()), m_targetPassword(QString()), m_lastOutputData(QByteArray()), m_targetUsername(QString()), m_targetPassword(QString()), m_lastOutputData({}),
m_lastOutputError(QNetworkReply::NoError) { m_lastOutputError(QNetworkReply::NetworkError::NoError), m_lastHttpStatusCode(0) {
m_timer->setInterval(DOWNLOAD_TIMEOUT); m_timer->setInterval(DOWNLOAD_TIMEOUT);
m_timer->setSingleShot(true); m_timer->setSingleShot(true);
@ -212,8 +212,9 @@ void Downloader::finished() {
m_lastCookies = {}; m_lastCookies = {};
} }
m_lastContentType = reply->header(QNetworkRequest::ContentTypeHeader); m_lastContentType = reply->header(QNetworkRequest::KnownHeaders::ContentTypeHeader);
m_lastOutputError = reply->error(); m_lastOutputError = reply->error();
m_lastHttpStatusCode = reply->attribute(QNetworkRequest::Attribute::HttpStatusCodeAttribute).toInt();
// original_url = m_activeReply->property("original_url").toUrl(); // original_url = m_activeReply->property("original_url").toUrl();
@ -224,7 +225,7 @@ void Downloader::finished() {
m_inputMultipartData->deleteLater(); m_inputMultipartData->deleteLater();
} }
emit completed(original_url, m_lastOutputError, m_lastOutputData); emit completed(original_url, m_lastOutputError, m_lastHttpStatusCode, m_lastOutputData);
} }
} }
@ -335,6 +336,10 @@ void Downloader::runGetRequest(const QNetworkRequest& request) {
connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished); connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished);
} }
int Downloader::lastHttpStatusCode() const {
return m_lastHttpStatusCode;
}
QList<QNetworkCookie> Downloader::lastCookies() const { QList<QNetworkCookie> Downloader::lastCookies() const {
return m_lastCookies; return m_lastCookies;
} }

View File

@ -29,6 +29,7 @@ class Downloader : public QObject {
QList<HttpResponse> lastOutputMultipartData() const; QList<HttpResponse> lastOutputMultipartData() const;
QVariant lastContentType() const; QVariant lastContentType() const;
QList<QNetworkCookie> lastCookies() const; QList<QNetworkCookie> lastCookies() const;
int lastHttpStatusCode() const;
void setProxy(const QNetworkProxy& proxy); void setProxy(const QNetworkProxy& proxy);
@ -68,9 +69,8 @@ class Downloader : public QObject {
const QString& password = QString()); const QString& password = QString());
signals: signals:
// Emitted when new progress is known.
void progress(qint64 bytes_received, qint64 bytes_total); void progress(qint64 bytes_received, qint64 bytes_total);
void completed(const QUrl& url, QNetworkReply::NetworkError status, QByteArray contents = QByteArray()); void completed(const QUrl& url, QNetworkReply::NetworkError status, int http_code, QByteArray contents = {});
private slots: private slots:
@ -111,8 +111,8 @@ class Downloader : public QObject {
// Response data. // Response data.
QByteArray m_lastOutputData; QByteArray m_lastOutputData;
QList<HttpResponse> m_lastOutputMultipartData; QList<HttpResponse> m_lastOutputMultipartData;
QNetworkReply::NetworkError m_lastOutputError; QNetworkReply::NetworkError m_lastOutputError;
int m_lastHttpStatusCode;
QVariant m_lastContentType; QVariant m_lastContentType;
QList<QNetworkCookie> m_lastCookies; QList<QNetworkCookie> m_lastCookies;
}; };

View File

@ -156,8 +156,12 @@ void GoogleSuggest::autoSuggest() {
m_downloader->downloadFile(url); m_downloader->downloadFile(url);
} }
void GoogleSuggest::handleNetworkData(const QUrl& url, QNetworkReply::NetworkError status, const QByteArray& contents) { void GoogleSuggest::handleNetworkData(const QUrl& url,
QNetworkReply::NetworkError status,
int http_code,
const QByteArray& contents) {
Q_UNUSED(url) Q_UNUSED(url)
Q_UNUSED(http_code)
if (status == QNetworkReply::NetworkError::NoError) { if (status == QNetworkReply::NetworkError::NoError) {
QStringList choices; QStringList choices;

View File

@ -54,7 +54,10 @@ class GoogleSuggest : public QObject {
void doneCompletion(); void doneCompletion();
void preventSuggest(); void preventSuggest();
void autoSuggest(); void autoSuggest();
void handleNetworkData(const QUrl& url, QNetworkReply::NetworkError status, const QByteArray& contents); void handleNetworkData(const QUrl& url,
QNetworkReply::NetworkError status,
int http_code,
const QByteArray& contents);
private: private:
LocationLineEdit* editor; LocationLineEdit* editor;

View File

@ -270,6 +270,7 @@ NetworkResult NetworkFactory::performNetworkOperation(const QString& url,
result.m_networkError = downloader.lastOutputError(); result.m_networkError = downloader.lastOutputError();
result.m_contentType = downloader.lastContentType().toString(); result.m_contentType = downloader.lastContentType().toString();
result.m_cookies = downloader.lastCookies(); result.m_cookies = downloader.lastCookies();
result.m_httpCode = downloader.lastHttpStatusCode();
return result; return result;
} }
@ -309,12 +310,16 @@ NetworkResult NetworkFactory::performNetworkOperation(const QString& url,
result.m_networkError = downloader.lastOutputError(); result.m_networkError = downloader.lastOutputError();
result.m_contentType = downloader.lastContentType().toString(); result.m_contentType = downloader.lastContentType().toString();
result.m_cookies = downloader.lastCookies(); result.m_cookies = downloader.lastCookies();
result.m_httpCode = downloader.lastHttpStatusCode();
return result; return result;
} }
NetworkResult::NetworkResult() NetworkResult::NetworkResult()
: m_networkError(QNetworkReply::NetworkError::NoError), m_contentType(QString()), m_cookies({}) {} : m_networkError(QNetworkReply::NetworkError::NoError), m_httpCode(0), m_contentType(QString()), m_cookies({}) {}
NetworkResult::NetworkResult(QNetworkReply::NetworkError err, const QString& ct, const QList<QNetworkCookie>& cook) NetworkResult::NetworkResult(QNetworkReply::NetworkError err,
: m_networkError(err), m_contentType(ct), m_cookies(cook) {} int http_code,
const QString& ct,
const QList<QNetworkCookie>& cook)
: m_networkError(err), m_httpCode(http_code), m_contentType(ct), m_cookies(cook) {}

View File

@ -15,11 +15,15 @@
struct NetworkResult { struct NetworkResult {
QNetworkReply::NetworkError m_networkError; QNetworkReply::NetworkError m_networkError;
int m_httpCode;
QString m_contentType; QString m_contentType;
QList<QNetworkCookie> m_cookies; QList<QNetworkCookie> m_cookies;
explicit NetworkResult(); explicit NetworkResult();
explicit NetworkResult(QNetworkReply::NetworkError err, const QString& ct, const QList<QNetworkCookie>& cook); explicit NetworkResult(QNetworkReply::NetworkError err,
int http_code,
const QString& ct,
const QList<QNetworkCookie>& cook);
}; };
class Downloader; class Downloader;
@ -44,25 +48,32 @@ class NetworkFactory {
int timeout, int timeout,
QIcon& output, QIcon& output,
const QList<QPair<QByteArray, QByteArray>>& additional_headers, const QList<QPair<QByteArray, QByteArray>>& additional_headers,
const QNetworkProxy& custom_proxy = QNetworkProxy::ProxyType::DefaultProxy); const QNetworkProxy& custom_proxy =
static NetworkResult performNetworkOperation(const QString& url, int timeout, QNetworkProxy::ProxyType::DefaultProxy);
static NetworkResult performNetworkOperation(const QString& url,
int timeout,
const QByteArray& input_data, const QByteArray& input_data,
QByteArray& output, QByteArray& output,
QNetworkAccessManager::Operation operation, QNetworkAccessManager::Operation operation,
const QList<QPair<QByteArray, QByteArray>>& additional_headers = QList<QPair<QByteArray, QByteArray>>(), const QList<QPair<QByteArray, QByteArray>>& additional_headers =
QList<QPair<QByteArray, QByteArray>>(),
bool protected_contents = false, bool protected_contents = false,
const QString& username = QString(), const QString& username = QString(),
const QString& password = QString(), const QString& password = QString(),
const QNetworkProxy& custom_proxy = QNetworkProxy::ProxyType::DefaultProxy); const QNetworkProxy& custom_proxy =
static NetworkResult performNetworkOperation(const QString& url, int timeout, QNetworkProxy::ProxyType::DefaultProxy);
static NetworkResult performNetworkOperation(const QString& url,
int timeout,
QHttpMultiPart* input_data, QHttpMultiPart* input_data,
QList<HttpResponse>& output, QList<HttpResponse>& output,
QNetworkAccessManager::Operation operation, QNetworkAccessManager::Operation operation,
const QList<QPair<QByteArray, QByteArray>>& additional_headers = QList<QPair<QByteArray, QByteArray>>(), const QList<QPair<QByteArray, QByteArray>>& additional_headers =
QList<QPair<QByteArray, QByteArray>>(),
bool protected_contents = false, bool protected_contents = false,
const QString& username = QString(), const QString& username = QString(),
const QString& password = QString(), const QString& password = QString(),
const QNetworkProxy& custom_proxy = QNetworkProxy::ProxyType::DefaultProxy); const QNetworkProxy& custom_proxy =
QNetworkProxy::ProxyType::DefaultProxy);
}; };
#endif // NETWORKFACTORY_H #endif // NETWORKFACTORY_H

View File

@ -442,11 +442,11 @@ void ServiceRoot::syncIn() {
setIcon(qApp->icons()->fromTheme(QSL("view-refresh"))); setIcon(qApp->icons()->fromTheme(QSL("view-refresh")));
itemChanged({this}); itemChanged({this});
try {
qDebugNN << LOGSEC_CORE << "Starting sync-in process."; qDebugNN << LOGSEC_CORE << "Starting sync-in process.";
RootItem* new_tree = obtainNewTreeForSyncIn(); RootItem* new_tree = obtainNewTreeForSyncIn();
if (new_tree != nullptr) {
qDebugNN << LOGSEC_CORE << "New feed tree for sync-in obtained."; qDebugNN << LOGSEC_CORE << "New feed tree for sync-in obtained.";
auto feed_custom_data = storeCustomFeedsData(); auto feed_custom_data = storeCustomFeedsData();
@ -498,8 +498,15 @@ void ServiceRoot::syncIn() {
updateCounts(true); updateCounts(true);
requestReloadMessageList(true); requestReloadMessageList(true);
} }
else { catch (const ApplicationException& ex) {
qCriticalNN << LOGSEC_CORE << "New feed tree for sync-in NOT obtained."; qCriticalNN << LOGSEC_CORE << "New feed tree for sync-in NOT obtained:" << QUOTE_W_SPACE_DOT(ex.message());
qApp->showGuiMessage(Notification::Event::GeneralEvent,
GuiMessage(tr("Error when fetching list of feeds"),
tr("Feeds & categories for account '%1' were not fetched, error: %2")
.arg(title(), ex.message()),
QSystemTrayIcon::MessageIcon::Critical),
GuiMessageDestination(true, true));
} }
setIcon(original_icon); setIcon(original_icon);

View File

@ -2,7 +2,6 @@
#include "services/feedly/feedlynetwork.h" #include "services/feedly/feedlynetwork.h"
#include "3rd-party/boolinq/boolinq.h"
#include "3rd-party/boolinq/boolinq.h" #include "3rd-party/boolinq/boolinq.h"
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "exceptions/networkexception.h" #include "exceptions/networkexception.h"
@ -30,15 +29,14 @@ FeedlyNetwork::FeedlyNetwork(QObject* parent)
QSL(FEEDLY_API_URL_BASE) + QSL(FEEDLY_API_URL_TOKEN), QSL(FEEDLY_API_URL_BASE) + QSL(FEEDLY_API_URL_TOKEN),
TextFactory::decrypt(QSL(FEEDLY_CLIENT_ID), OAUTH_DECRYPTION_KEY), TextFactory::decrypt(QSL(FEEDLY_CLIENT_ID), OAUTH_DECRYPTION_KEY),
TextFactory::decrypt(QSL(FEEDLY_CLIENT_SECRET), OAUTH_DECRYPTION_KEY), TextFactory::decrypt(QSL(FEEDLY_CLIENT_SECRET), OAUTH_DECRYPTION_KEY),
QSL(FEEDLY_API_SCOPE), this)), QSL(FEEDLY_API_SCOPE),
this)),
#endif #endif
m_username(QString()), m_username(QString()), m_developerAccessToken(QString()), m_batchSize(FEEDLY_DEFAULT_BATCH_SIZE),
m_developerAccessToken(QString()), m_batchSize(FEEDLY_DEFAULT_BATCH_SIZE), m_downloadOnlyUnreadMessages(false), m_downloadOnlyUnreadMessages(false), m_intelligentSynchronization(true) {
m_intelligentSynchronization(true) {
#if defined(FEEDLY_OFFICIAL_SUPPORT) #if defined(FEEDLY_OFFICIAL_SUPPORT)
m_oauth->setRedirectUrl(QSL(OAUTH_REDIRECT_URI) + QL1C(':') + QString::number(FEEDLY_API_REDIRECT_URI_PORT), m_oauth->setRedirectUrl(QSL(OAUTH_REDIRECT_URI) + QL1C(':') + QString::number(FEEDLY_API_REDIRECT_URI_PORT), true);
true);
connect(m_oauth, &OAuth2Service::tokensRetrieveError, this, &FeedlyNetwork::onTokensError); connect(m_oauth, &OAuth2Service::tokensRetrieveError, this, &FeedlyNetwork::onTokensError);
connect(m_oauth, &OAuth2Service::authFailed, this, &FeedlyNetwork::onAuthFailed); connect(m_oauth, &OAuth2Service::authFailed, this, &FeedlyNetwork::onAuthFailed);
@ -118,8 +116,7 @@ void FeedlyNetwork::untagEntries(const QString& tag_id, const QStringList& msg_c
throw NetworkException(QNetworkReply::NetworkError::AuthenticationRequiredError); throw NetworkException(QNetworkReply::NetworkError::AuthenticationRequiredError);
} }
QString target_url = fullUrl(Service::TagEntries) + QString target_url = fullUrl(Service::TagEntries) + QSL("/%1/").arg(QString(QUrl::toPercentEncoding(tag_id)));
QSL("/%1/").arg(QString(QUrl::toPercentEncoding(tag_id)));
int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt(); int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
QByteArray output; QByteArray output;
int i = 0; int i = 0;
@ -129,16 +126,18 @@ void FeedlyNetwork::untagEntries(const QString& tag_id, const QStringList& msg_c
i += FEEDLY_UNTAG_BATCH_SIZE; i += FEEDLY_UNTAG_BATCH_SIZE;
auto ids = boolinq::from(msg_batch).select([](const QString& msg_id) { auto ids = boolinq::from(msg_batch)
.select([](const QString& msg_id) {
return QString(QUrl::toPercentEncoding(msg_id)); return QString(QUrl::toPercentEncoding(msg_id));
}).toStdList(); })
.toStdList();
QString final_url = target_url + FROM_STD_LIST(QStringList, ids).join(','); QString final_url = target_url + FROM_STD_LIST(QStringList, ids).join(',');
auto result = NetworkFactory::performNetworkOperation(final_url, auto result = NetworkFactory::performNetworkOperation(final_url,
timeout, timeout,
{}, {},
output, output,
QNetworkAccessManager::Operation::DeleteOperation, QNetworkAccessManager::Operation::DeleteOperation,
{ bearerHeader(bear) }, {bearerHeader(bear)},
false, false,
{}, {},
{}, {},
@ -172,13 +171,13 @@ void FeedlyNetwork::tagEntries(const QString& tag_id, const QStringList& msg_cus
input[QSL("entryIds")] = QJsonArray::fromStringList(msg_custom_ids); input[QSL("entryIds")] = QJsonArray::fromStringList(msg_custom_ids);
input_data = QJsonDocument(input).toJson(QJsonDocument::JsonFormat::Compact); input_data = QJsonDocument(input).toJson(QJsonDocument::JsonFormat::Compact);
auto result = NetworkFactory::performNetworkOperation(target_url, auto result =
NetworkFactory::performNetworkOperation(target_url,
timeout, timeout,
input_data, input_data,
output, output,
QNetworkAccessManager::Operation::PutOperation, QNetworkAccessManager::Operation::PutOperation,
{ bearerHeader(bear), {bearerHeader(bear), {HTTP_HEADERS_CONTENT_TYPE, "application/json"}},
{ HTTP_HEADERS_CONTENT_TYPE, "application/json" } },
false, false,
{}, {},
{}, {},
@ -211,13 +210,13 @@ void FeedlyNetwork::markers(const QString& action, const QStringList& msg_custom
input[QSL("entryIds")] = QJsonArray::fromStringList(msg_custom_ids); input[QSL("entryIds")] = QJsonArray::fromStringList(msg_custom_ids);
QByteArray input_data = QJsonDocument(input).toJson(QJsonDocument::JsonFormat::Compact); QByteArray input_data = QJsonDocument(input).toJson(QJsonDocument::JsonFormat::Compact);
auto result = NetworkFactory::performNetworkOperation(target_url, auto result =
NetworkFactory::performNetworkOperation(target_url,
timeout, timeout,
input_data, input_data,
output, output,
QNetworkAccessManager::Operation::PostOperation, QNetworkAccessManager::Operation::PostOperation,
{ bearerHeader(bear), {bearerHeader(bear), {HTTP_HEADERS_CONTENT_TYPE, "application/json"}},
{ HTTP_HEADERS_CONTENT_TYPE, "application/json" } },
false, false,
{}, {},
{}, {},
@ -245,17 +244,18 @@ QList<Message> FeedlyNetwork::entries(const QStringList& ids) {
do { do {
QJsonArray json; QJsonArray json;
for (int window = next_message + 1000; next_message < window && next_message < ids.size(); next_message++ ) { for (int window = next_message + 1000; next_message < window && next_message < ids.size(); next_message++) {
json.append(QJsonValue(ids.at(next_message))); json.append(QJsonValue(ids.at(next_message)));
} }
QByteArray output; QByteArray output;
auto result = NetworkFactory::performNetworkOperation(target_url, auto result =
NetworkFactory::performNetworkOperation(target_url,
timeout, timeout,
QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact), QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
output, output,
QNetworkAccessManager::Operation::PostOperation, QNetworkAccessManager::Operation::PostOperation,
{ bearerHeader(bear) }, {bearerHeader(bear)},
false, false,
{}, {},
{}, {},
@ -311,7 +311,7 @@ QList<Message> FeedlyNetwork::streamContents(const QString& stream_id) {
{}, {},
output, output,
QNetworkAccessManager::Operation::GetOperation, QNetworkAccessManager::Operation::GetOperation,
{ bearerHeader(bear) }, {bearerHeader(bear)},
false, false,
{}, {},
{}, {},
@ -323,8 +323,7 @@ QList<Message> FeedlyNetwork::streamContents(const QString& stream_id) {
messages += decodeStreamContents(output, true, continuation); messages += decodeStreamContents(output, true, continuation);
} }
while (!continuation.isEmpty() && while (!continuation.isEmpty() && (m_batchSize <= 0 || messages.size() < m_batchSize) &&
(m_batchSize <= 0 || messages.size() < m_batchSize) &&
messages.size() <= FEEDLY_MAX_TOTAL_SIZE); messages.size() <= FEEDLY_MAX_TOTAL_SIZE);
return messages; return messages;
@ -369,7 +368,7 @@ QStringList FeedlyNetwork::streamIds(const QString& stream_id, bool unread_only,
{}, {},
output, output,
QNetworkAccessManager::Operation::GetOperation, QNetworkAccessManager::Operation::GetOperation,
{ bearerHeader(bear) }, {bearerHeader(bear)},
false, false,
{}, {},
{}, {},
@ -399,7 +398,9 @@ QStringList FeedlyNetwork::decodeStreamIds(const QByteArray& stream_ids, QString
return messages; return messages;
} }
QList<Message> FeedlyNetwork::decodeStreamContents(const QByteArray& stream_contents, bool nested_items, QString& continuation) const { QList<Message> FeedlyNetwork::decodeStreamContents(const QByteArray& stream_contents,
bool nested_items,
QString& continuation) const {
QList<Message> messages; QList<Message> messages;
QJsonDocument json = QJsonDocument::fromJson(stream_contents); QJsonDocument json = QJsonDocument::fromJson(stream_contents);
auto active_labels = m_service->labelsNode() != nullptr ? m_service->labelsNode()->labels() : QList<Label*>(); auto active_labels = m_service->labelsNode() != nullptr ? m_service->labelsNode()->labels() : QList<Label*>();
@ -423,14 +424,25 @@ QList<Message> FeedlyNetwork::decodeStreamContents(const QByteArray& stream_cont
} }
message.m_createdFromFeed = true; message.m_createdFromFeed = true;
message.m_created = QDateTime::fromMSecsSinceEpoch(entry_obj[QSL("published")].toVariant().toLongLong(), message.m_created =
Qt::TimeSpec::UTC); QDateTime::fromMSecsSinceEpoch(entry_obj[QSL("published")].toVariant().toLongLong(), Qt::TimeSpec::UTC);
message.m_customId = entry_obj[QSL("id")].toString(); message.m_customId = entry_obj[QSL("id")].toString();
message.m_isRead = !entry_obj[QSL("unread")].toBool(); message.m_isRead = !entry_obj[QSL("unread")].toBool();
message.m_url = entry_obj[QSL("canonicalUrl")].toString(); message.m_url = entry_obj[QSL("canonicalUrl")].toString();
if (message.m_url.isEmpty()) { if (message.m_url.isEmpty()) {
message.m_url = entry_obj[QSL("canonical")].toObject()[QSL("href")].toString(); auto canonical_arr = entry_obj[QSL("canonical")].toArray();
if (!canonical_arr.isEmpty()) {
message.m_url = canonical_arr.first().toObject()[QSL("href")].toString();
}
else {
auto alternate_arr = entry_obj[QSL("alternate")].toArray();
if (!alternate_arr.isEmpty()) {
message.m_url = alternate_arr.first().toObject()[QSL("href")].toString();
}
}
} }
auto enclosures = entry_obj[QSL("enclosure")].toArray(); auto enclosures = entry_obj[QSL("enclosure")].toArray();
@ -467,9 +479,7 @@ QList<Message> FeedlyNetwork::decodeStreamContents(const QByteArray& stream_cont
message.m_assignedLabels.append(label); message.m_assignedLabels.append(label);
} }
else { else {
qCriticalNN << LOGSEC_FEEDLY qCriticalNN << LOGSEC_FEEDLY << "Failed to find live Label object for tag" << QUOTE_W_SPACE_DOT(tag_id);
<< "Failed to find live Label object for tag"
<< QUOTE_W_SPACE_DOT(tag_id);
} }
} }
} }
@ -496,7 +506,7 @@ RootItem* FeedlyNetwork::collections(bool obtain_icons) {
{}, {},
output, output,
QNetworkAccessManager::Operation::GetOperation, QNetworkAccessManager::Operation::GetOperation,
{ bearerHeader(bear) }, {bearerHeader(bear)},
false, false,
{}, {},
{}, {},
@ -509,8 +519,10 @@ RootItem* FeedlyNetwork::collections(bool obtain_icons) {
return decodeCollections(output, obtain_icons, m_service->networkProxy(), timeout); return decodeCollections(output, obtain_icons, m_service->networkProxy(), timeout);
} }
RootItem* FeedlyNetwork::decodeCollections(const QByteArray& json, bool obtain_icons, RootItem* FeedlyNetwork::decodeCollections(const QByteArray& json,
const QNetworkProxy& proxy, int timeout) const { bool obtain_icons,
const QNetworkProxy& proxy,
int timeout) const {
QJsonDocument doc = QJsonDocument::fromJson(json); QJsonDocument doc = QJsonDocument::fromJson(json);
auto* parent = new RootItem(); auto* parent = new RootItem();
QList<QString> used_feeds; QList<QString> used_feeds;
@ -529,9 +541,7 @@ RootItem* FeedlyNetwork::decodeCollections(const QByteArray& json, bool obtain_i
QJsonObject fee_obj = fee.toObject(); QJsonObject fee_obj = fee.toObject();
if (used_feeds.contains(fee_obj[QSL("id")].toString())) { if (used_feeds.contains(fee_obj[QSL("id")].toString())) {
qWarningNN << LOGSEC_FEEDLY qWarningNN << LOGSEC_FEEDLY << "Feed" << QUOTE_W_SPACE(fee_obj[QSL("id")].toString())
<< "Feed"
<< QUOTE_W_SPACE(fee_obj[QSL("id")].toString())
<< "is already decoded and cannot be placed under several categories."; << "is already decoded and cannot be placed under several categories.";
continue; continue;
} }
@ -545,9 +555,9 @@ RootItem* FeedlyNetwork::decodeCollections(const QByteArray& json, bool obtain_i
if (obtain_icons) { if (obtain_icons) {
QIcon icon; QIcon icon;
auto result = NetworkFactory::downloadIcon({ { fee_obj[QSL("iconUrl")].toString(), true }, auto result = NetworkFactory::downloadIcon({{fee_obj[QSL("iconUrl")].toString(), true},
{ fee_obj[QSL("website")].toString(), false }, {fee_obj[QSL("website")].toString(), false},
{ fee_obj[QSL("logo")].toString(), true } }, {fee_obj[QSL("logo")].toString(), true}},
timeout, timeout,
icon, icon,
{}, {},
@ -592,7 +602,7 @@ QVariantHash FeedlyNetwork::profile(const QNetworkProxy& network_proxy) {
{}, {},
output, output,
QNetworkAccessManager::Operation::GetOperation, QNetworkAccessManager::Operation::GetOperation,
{ bearerHeader(bear) }, {bearerHeader(bear)},
false, false,
{}, {},
{}, {},
@ -621,7 +631,7 @@ QList<RootItem*> FeedlyNetwork::tags() {
{}, {},
output, output,
QNetworkAccessManager::Operation::GetOperation, QNetworkAccessManager::Operation::GetOperation,
{ bearerHeader(bear) }, {bearerHeader(bear)},
false, false,
{}, {},
{}, {},
@ -639,8 +649,7 @@ QList<RootItem*> FeedlyNetwork::tags() {
const QJsonObject& tag_obj = tag.toObject(); const QJsonObject& tag_obj = tag.toObject();
QString name_id = tag_obj[QSL("id")].toString(); QString name_id = tag_obj[QSL("id")].toString();
if (name_id.endsWith(FEEDLY_API_SYSTEM_TAG_READ) || if (name_id.endsWith(FEEDLY_API_SYSTEM_TAG_READ) || name_id.endsWith(FEEDLY_API_SYSTEM_TAG_SAVED)) {
name_id.endsWith(FEEDLY_API_SYSTEM_TAG_SAVED)) {
continue; continue;
} }
@ -683,32 +692,30 @@ void FeedlyNetwork::setBatchSize(int batch_size) {
void FeedlyNetwork::onTokensError(const QString& error, const QString& error_description) { void FeedlyNetwork::onTokensError(const QString& error, const QString& error_description) {
Q_UNUSED(error) Q_UNUSED(error)
qApp->showGuiMessage(Notification::Event::LoginFailure, { qApp->showGuiMessage(Notification::Event::LoginFailure,
tr("Feedly: authentication error"), {tr("Feedly: authentication error"),
tr("Click this to login again. Error is: '%1'").arg(error_description), tr("Click this to login again. Error is: '%1'").arg(error_description),
QSystemTrayIcon::MessageIcon::Critical }, QSystemTrayIcon::MessageIcon::Critical},
{}, { {},
tr("Login"), {tr("Login"), [this]() {
[this]() {
m_oauth->setAccessToken(QString()); m_oauth->setAccessToken(QString());
m_oauth->setRefreshToken(QString()); m_oauth->setRefreshToken(QString());
//m_oauth->logout(false); // m_oauth->logout(false);
m_oauth->login(); m_oauth->login();
} }); }});
} }
void FeedlyNetwork::onAuthFailed() { void FeedlyNetwork::onAuthFailed() {
qApp->showGuiMessage(Notification::Event::LoginFailure, { qApp->showGuiMessage(Notification::Event::LoginFailure,
tr("Feedly: authorization denied"), {tr("Feedly: authorization denied"),
tr("Click this to login again."), tr("Click this to login again."),
QSystemTrayIcon::MessageIcon::Critical }, QSystemTrayIcon::MessageIcon::Critical},
{}, { {},
tr("Login"), {tr("Login"), [this]() {
[this]() { // m_oauth->logout(false);
//m_oauth->logout(false);
m_oauth->login(); m_oauth->login();
} }); }});
} }
void FeedlyNetwork::onTokensRetrieved(const QString& access_token, const QString& refresh_token, int expires_in) { void FeedlyNetwork::onTokensRetrieved(const QString& access_token, const QString& refresh_token, int expires_in) {
@ -772,7 +779,7 @@ QString FeedlyNetwork::bearer() const {
} }
QPair<QByteArray, QByteArray> FeedlyNetwork::bearerHeader(const QString& bearer) const { QPair<QByteArray, QByteArray> FeedlyNetwork::bearerHeader(const QString& bearer) const {
return { QSL(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(), bearer.toLocal8Bit() }; return {QSL(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(), bearer.toLocal8Bit()};
} }
void FeedlyNetwork::setIntelligentSynchronization(bool intelligent_sync) { void FeedlyNetwork::setIntelligentSynchronization(bool intelligent_sync) {

View File

@ -23,8 +23,7 @@
#include "network-web/oauth2service.h" #include "network-web/oauth2service.h"
#endif #endif
FeedlyServiceRoot::FeedlyServiceRoot(RootItem* parent) FeedlyServiceRoot::FeedlyServiceRoot(RootItem* parent) : ServiceRoot(parent), m_network(new FeedlyNetwork(this)) {
: ServiceRoot(parent), m_network(new FeedlyNetwork(this)) {
setIcon(FeedlyEntryPoint().icon()); setIcon(FeedlyEntryPoint().icon());
m_network->setService(this); m_network->setService(this);
} }
@ -75,7 +74,8 @@ void FeedlyServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
} }
QList<Message> FeedlyServiceRoot::obtainNewMessages(Feed* feed, QList<Message> FeedlyServiceRoot::obtainNewMessages(Feed* feed,
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages, const QHash<ServiceRoot::BagOfMessages, QStringList>&
stated_messages,
const QHash<QString, QStringList>& tagged_messages) { const QHash<QString, QStringList>& tagged_messages) {
Q_UNUSED(tagged_messages) Q_UNUSED(tagged_messages)
@ -128,16 +128,13 @@ void FeedlyServiceRoot::saveAllCachedData(bool ignore_errors) {
if (!ids.isEmpty()) { if (!ids.isEmpty()) {
try { try {
network()->markers(key == RootItem::ReadStatus::Read network()->markers(key == RootItem::ReadStatus::Read ? QSL(FEEDLY_MARKERS_READ) : QSL(FEEDLY_MARKERS_UNREAD),
? QSL(FEEDLY_MARKERS_READ) ids);
: QSL(FEEDLY_MARKERS_UNREAD), ids);
} }
catch (const NetworkException& net_ex) { catch (const NetworkException& net_ex) {
qCriticalNN << LOGSEC_FEEDLY qCriticalNN << LOGSEC_FEEDLY
<< "Failed to synchronize read/unread state with error:" << "Failed to synchronize read/unread state with error:" << QUOTE_W_SPACE(net_ex.message())
<< QUOTE_W_SPACE(net_ex.message()) << "and HTTP code" << QUOTE_W_SPACE_DOT(net_ex.networkError());
<< "and HTTP code"
<< QUOTE_W_SPACE_DOT(net_ex.networkError());
if (!ignore_errors) { if (!ignore_errors) {
addMessageStatesToCache(ids, key); addMessageStatesToCache(ids, key);
@ -162,16 +159,13 @@ void FeedlyServiceRoot::saveAllCachedData(bool ignore_errors) {
} }
try { try {
network()->markers(key == RootItem::Importance::Important network()->markers(key == RootItem::Importance::Important ? FEEDLY_MARKERS_IMPORTANT
? FEEDLY_MARKERS_IMPORTANT : FEEDLY_MARKERS_UNIMPORTANT,
: FEEDLY_MARKERS_UNIMPORTANT, ids); ids);
} }
catch (const NetworkException& net_ex) { catch (const NetworkException& net_ex) {
qCriticalNN << LOGSEC_FEEDLY qCriticalNN << LOGSEC_FEEDLY << "Failed to synchronize important/unimportant state with error:"
<< "Failed to synchronize important/unimportant state with error:" << QUOTE_W_SPACE(net_ex.message()) << "and HTTP code" << QUOTE_W_SPACE_DOT(net_ex.networkError());
<< QUOTE_W_SPACE(net_ex.message())
<< "and HTTP code"
<< QUOTE_W_SPACE_DOT(net_ex.networkError());
if (!ignore_errors) { if (!ignore_errors) {
addMessageStatesToCache(messages, key); addMessageStatesToCache(messages, key);
@ -194,10 +188,8 @@ void FeedlyServiceRoot::saveAllCachedData(bool ignore_errors) {
} }
catch (const NetworkException& net_ex) { catch (const NetworkException& net_ex) {
qCriticalNN << LOGSEC_FEEDLY qCriticalNN << LOGSEC_FEEDLY
<< "Failed to synchronize tag assignments with error:" << "Failed to synchronize tag assignments with error:" << QUOTE_W_SPACE(net_ex.message())
<< QUOTE_W_SPACE(net_ex.message()) << "and HTTP code" << QUOTE_W_SPACE_DOT(net_ex.networkError());
<< "and HTTP code"
<< QUOTE_W_SPACE_DOT(net_ex.networkError());
if (!ignore_errors) { if (!ignore_errors) {
addLabelsAssignmentsToCache(messages, label_custom_id, true); addLabelsAssignmentsToCache(messages, label_custom_id, true);
@ -220,10 +212,8 @@ void FeedlyServiceRoot::saveAllCachedData(bool ignore_errors) {
} }
catch (const NetworkException& net_ex) { catch (const NetworkException& net_ex) {
qCriticalNN << LOGSEC_FEEDLY qCriticalNN << LOGSEC_FEEDLY
<< "Failed to synchronize tag DEassignments with error:" << "Failed to synchronize tag DEassignments with error:" << QUOTE_W_SPACE(net_ex.message())
<< QUOTE_W_SPACE(net_ex.message()) << "and HTTP code" << QUOTE_W_SPACE_DOT(net_ex.networkError());
<< "and HTTP code"
<< QUOTE_W_SPACE_DOT(net_ex.networkError());
if (!ignore_errors) { if (!ignore_errors) {
addLabelsAssignmentsToCache(messages, label_custom_id, false); addLabelsAssignmentsToCache(messages, label_custom_id, false);
@ -242,7 +232,6 @@ void FeedlyServiceRoot::updateTitle() {
} }
RootItem* FeedlyServiceRoot::obtainNewTreeForSyncIn() const { RootItem* FeedlyServiceRoot::obtainNewTreeForSyncIn() const {
try {
auto tree = m_network->collections(true); auto tree = m_network->collections(true);
auto* lblroot = new LabelsNode(tree); auto* lblroot = new LabelsNode(tree);
auto labels = m_network->tags(); auto labels = m_network->tags();
@ -251,13 +240,6 @@ RootItem* FeedlyServiceRoot::obtainNewTreeForSyncIn() const {
tree->appendChild(lblroot); tree->appendChild(lblroot);
return tree; return tree;
}
catch (const ApplicationException& ex) {
qCriticalNN << LOGSEC_FEEDLY
<< "Failed to obtain new sync-in tree:"
<< QUOTE_W_SPACE_DOT(ex.message());
return nullptr;
}
} }
bool FeedlyServiceRoot::wantsBaggedIdsOfExistingMessages() const { bool FeedlyServiceRoot::wantsBaggedIdsOfExistingMessages() const {

View File

@ -602,7 +602,7 @@ RootItem* GreaderNetwork::categoriesFeedsLabelsTree(bool obtain_icons, const QNe
if (!ensureLogin(proxy)) { if (!ensureLogin(proxy)) {
qCriticalNN << LOGSEC_GREADER << "Cannot get feed tree, not logged-in."; qCriticalNN << LOGSEC_GREADER << "Cannot get feed tree, not logged-in.";
return nullptr; throw ApplicationException(tr("you are not logged-in, maybe wrong credentials"));
} }
QByteArray output_labels; QByteArray output_labels;
@ -618,7 +618,11 @@ RootItem* GreaderNetwork::categoriesFeedsLabelsTree(bool obtain_icons, const QNe
proxy); proxy);
if (result_labels.m_networkError != QNetworkReply::NetworkError::NoError) { if (result_labels.m_networkError != QNetworkReply::NetworkError::NoError) {
return nullptr; qCriticalNN << LOGSEC_GREADER
<< "Cannot get labels tree, network error:" << QUOTE_W_SPACE_DOT(result_labels.m_networkError);
throw NetworkException(result_labels.m_networkError,
tr("cannot get list of labels, HTTP code '%1'").arg(result_labels.m_httpCode));
} }
full_url = generateFullUrl(Operations::SubscriptionList); full_url = generateFullUrl(Operations::SubscriptionList);
@ -637,7 +641,9 @@ RootItem* GreaderNetwork::categoriesFeedsLabelsTree(bool obtain_icons, const QNe
if (result_feeds.m_networkError != QNetworkReply::NetworkError::NoError) { if (result_feeds.m_networkError != QNetworkReply::NetworkError::NoError) {
qCriticalNN << LOGSEC_GREADER qCriticalNN << LOGSEC_GREADER
<< "Cannot get feed tree, network error:" << QUOTE_W_SPACE_DOT(result_feeds.m_networkError); << "Cannot get feed tree, network error:" << QUOTE_W_SPACE_DOT(result_feeds.m_networkError);
return nullptr;
throw NetworkException(result_labels.m_networkError,
tr("cannot get list of feeds, HTTP code '%1'").arg(result_feeds.m_httpCode));
} }
return decodeTagsSubscriptions(output_labels, output_feeds, obtain_icons, proxy); return decodeTagsSubscriptions(output_labels, output_feeds, obtain_icons, proxy);

View File

@ -5,6 +5,7 @@
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "exceptions/feedfetchexception.h" #include "exceptions/feedfetchexception.h"
#include "exceptions/networkexception.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
#include "miscellaneous/mutex.h" #include "miscellaneous/mutex.h"
@ -124,7 +125,8 @@ RootItem* OwnCloudServiceRoot::obtainNewTreeForSyncIn() const {
return feed_cats_response.feedsCategories(true); return feed_cats_response.feedsCategories(true);
} }
else { else {
return nullptr; throw NetworkException(feed_cats_response.networkError(),
tr("cannot get list of feeds, network error '%1'").arg(feed_cats_response.networkError()));
} }
} }
@ -151,7 +153,8 @@ void OwnCloudServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
} }
QList<Message> OwnCloudServiceRoot::obtainNewMessages(Feed* feed, QList<Message> OwnCloudServiceRoot::obtainNewMessages(Feed* feed,
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages, const QHash<ServiceRoot::BagOfMessages, QStringList>&
stated_messages,
const QHash<QString, QStringList>& tagged_messages) { const QHash<QString, QStringList>& tagged_messages) {
Q_UNUSED(stated_messages) Q_UNUSED(stated_messages)
Q_UNUSED(tagged_messages) Q_UNUSED(tagged_messages)

View File

@ -5,6 +5,7 @@
#include "3rd-party/boolinq/boolinq.h" #include "3rd-party/boolinq/boolinq.h"
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "exceptions/feedfetchexception.h" #include "exceptions/feedfetchexception.h"
#include "exceptions/networkexception.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
#include "miscellaneous/mutex.h" #include "miscellaneous/mutex.h"
@ -26,8 +27,7 @@
#include <QPair> #include <QPair>
#include <QSqlTableModel> #include <QSqlTableModel>
TtRssServiceRoot::TtRssServiceRoot(RootItem* parent) TtRssServiceRoot::TtRssServiceRoot(RootItem* parent) : ServiceRoot(parent), m_network(new TtRssNetworkFactory()) {
: ServiceRoot(parent), m_network(new TtRssNetworkFactory()) {
setIcon(TtRssServiceEntryPoint().icon()); setIcon(TtRssServiceEntryPoint().icon());
} }
@ -68,8 +68,7 @@ void TtRssServiceRoot::start(bool freshly_activated) {
void TtRssServiceRoot::stop() { void TtRssServiceRoot::stop() {
m_network->logout(networkProxy()); m_network->logout(networkProxy());
qDebugNN << LOGSEC_TTRSS qDebugNN << LOGSEC_TTRSS << "Stopping Tiny Tiny RSS account, logging out with result"
<< "Stopping Tiny Tiny RSS account, logging out with result"
<< QUOTE_W_SPACE_DOT(m_network->lastError()); << QUOTE_W_SPACE_DOT(m_network->lastError());
} }
@ -101,15 +100,18 @@ void TtRssServiceRoot::addNewFeed(RootItem* selected_item, const QString& url) {
// Lock was not obtained because // Lock was not obtained because
// it is used probably by feed updater or application // it is used probably by feed updater or application
// is quitting. // is quitting.
qApp->showGuiMessage(Notification::Event::GeneralEvent, { qApp->showGuiMessage(Notification::Event::GeneralEvent,
tr("Cannot add item"), {tr("Cannot add item"),
tr("Cannot add feed because another critical operation is ongoing."), tr("Cannot add feed because another critical operation is ongoing."),
QSystemTrayIcon::MessageIcon::Warning }); QSystemTrayIcon::MessageIcon::Warning});
return; return;
} }
QScopedPointer<FormTtRssFeedDetails> form_pointer(new FormTtRssFeedDetails(this, selected_item, url, qApp->mainFormWidget())); QScopedPointer<FormTtRssFeedDetails> form_pointer(new FormTtRssFeedDetails(this,
selected_item,
url,
qApp->mainFormWidget()));
form_pointer->addEditFeed<TtRssFeed>(); form_pointer->addEditFeed<TtRssFeed>();
qApp->feedUpdateLock()->unlock(); qApp->feedUpdateLock()->unlock();
@ -132,8 +134,7 @@ void TtRssServiceRoot::saveAllCachedData(bool ignore_errors) {
if (!ids.isEmpty()) { if (!ids.isEmpty()) {
auto res = network()->updateArticles(ids, auto res = network()->updateArticles(ids,
UpdateArticle::OperatingField::Unread, UpdateArticle::OperatingField::Unread,
key == RootItem::ReadStatus::Unread key == RootItem::ReadStatus::Unread ? UpdateArticle::Mode::SetToTrue
? UpdateArticle::Mode::SetToTrue
: UpdateArticle::Mode::SetToFalse, : UpdateArticle::Mode::SetToFalse,
networkProxy()); networkProxy());
@ -155,8 +156,7 @@ void TtRssServiceRoot::saveAllCachedData(bool ignore_errors) {
QStringList ids = customIDsOfMessages(messages); QStringList ids = customIDsOfMessages(messages);
auto res = network()->updateArticles(ids, auto res = network()->updateArticles(ids,
UpdateArticle::OperatingField::Starred, UpdateArticle::OperatingField::Starred,
key == RootItem::Importance::Important key == RootItem::Importance::Important ? UpdateArticle::Mode::SetToTrue
? UpdateArticle::Mode::SetToTrue
: UpdateArticle::Mode::SetToFalse, : UpdateArticle::Mode::SetToFalse,
networkProxy()); networkProxy());
@ -252,7 +252,8 @@ void TtRssServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
} }
QList<Message> TtRssServiceRoot::obtainNewMessages(Feed* feed, QList<Message> TtRssServiceRoot::obtainNewMessages(Feed* feed,
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages, const QHash<ServiceRoot::BagOfMessages, QStringList>&
stated_messages,
const QHash<QString, QStringList>& tagged_messages) { const QHash<QString, QStringList>& tagged_messages) {
Q_UNUSED(stated_messages) Q_UNUSED(stated_messages)
Q_UNUSED(tagged_messages) Q_UNUSED(tagged_messages)
@ -263,8 +264,12 @@ QList<Message> TtRssServiceRoot::obtainNewMessages(Feed* feed,
int skip = 0; int skip = 0;
do { do {
TtRssGetHeadlinesResponse headlines = network()->getHeadlines(feed->customNumericId(), limit, skip, TtRssGetHeadlinesResponse headlines = network()->getHeadlines(feed->customNumericId(),
true, true, false, limit,
skip,
true,
true,
false,
network()->downloadOnlyUnreadMessages(), network()->downloadOnlyUnreadMessages(),
networkProxy()); networkProxy());
@ -286,7 +291,8 @@ QList<Message> TtRssServiceRoot::obtainNewMessages(Feed* feed,
QString TtRssServiceRoot::additionalTooltip() const { QString TtRssServiceRoot::additionalTooltip() const {
return tr("Username: %1\nServer: %2\n" return tr("Username: %1\nServer: %2\n"
"Last error: %3\nLast login on: %4").arg(m_network->username(), "Last error: %3\nLast login on: %4")
.arg(m_network->username(),
m_network->url(), m_network->url(),
NetworkFactory::networkErrorText(m_network->lastError()), NetworkFactory::networkErrorText(m_network->lastError()),
m_network->lastLoginTime().isValid() m_network->lastLoginTime().isValid()
@ -315,8 +321,9 @@ void TtRssServiceRoot::updateTitle() {
RootItem* TtRssServiceRoot::obtainNewTreeForSyncIn() const { RootItem* TtRssServiceRoot::obtainNewTreeForSyncIn() const {
TtRssGetFeedsCategoriesResponse feed_cats = m_network->getFeedsCategories(networkProxy()); TtRssGetFeedsCategoriesResponse feed_cats = m_network->getFeedsCategories(networkProxy());
TtRssGetLabelsResponse labels = m_network->getLabels(networkProxy()); TtRssGetLabelsResponse labels = m_network->getLabels(networkProxy());
auto lst_error = m_network->lastError();
if (m_network->lastError() == QNetworkReply::NoError) { if (lst_error == QNetworkReply::NoError) {
auto* tree = feed_cats.feedsCategories(m_network, true, networkProxy(), m_network->url()); auto* tree = feed_cats.feedsCategories(m_network, true, networkProxy(), m_network->url());
auto* lblroot = new LabelsNode(tree); auto* lblroot = new LabelsNode(tree);
@ -326,6 +333,6 @@ RootItem* TtRssServiceRoot::obtainNewTreeForSyncIn() const {
return tree; return tree;
} }
else { else {
return nullptr; throw NetworkException(lst_error, tr("cannot get list of feeds, network error '%1'").arg(lst_error));
} }
} }