diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml
index 5df20f7dd..58814dd32 100644
--- a/resources/desktop/com.github.rssguard.appdata.xml
+++ b/resources/desktop/com.github.rssguard.appdata.xml
@@ -22,11 +22,10 @@
https://github.com/martinrotter/rssguard
https://github.com/martinrotter/rssguard/issues
- https://www.transifex.com/martinrotter/rssguard
https://github.com/sponsors/martinrotter
-
+
none
diff --git a/src/librssguard/services/tt-rss/gui/formeditttrssaccount.cpp b/src/librssguard/services/tt-rss/gui/formeditttrssaccount.cpp
index 04d644fcf..6ed3d2b1d 100644
--- a/src/librssguard/services/tt-rss/gui/formeditttrssaccount.cpp
+++ b/src/librssguard/services/tt-rss/gui/formeditttrssaccount.cpp
@@ -32,8 +32,12 @@ void FormEditTtRssAccount::apply() {
account()->network()->setAuthUsername(m_details->m_ui.m_txtHttpUsername->lineEdit()->text());
account()->network()->setAuthPassword(m_details->m_ui.m_txtHttpPassword->lineEdit()->text());
account()->network()->setBatchSize(m_details->m_ui.m_spinLimitMessages->value());
- account()->network()->setForceServerSideUpdate(m_details->m_ui.m_checkServerSideUpdate->isChecked());
- account()->network()->setDownloadOnlyUnreadMessages(m_details->m_ui.m_checkDownloadOnlyUnreadMessages->isChecked());
+ account()->network()->setIntelligentSynchronization(m_details->m_ui.m_cbNewAlgorithm->isChecked());
+ account()->network()->setForceServerSideUpdate(m_details->m_ui.m_checkServerSideUpdate
+ ->isChecked());
+ account()
+ ->network()
+ ->setDownloadOnlyUnreadMessages(m_details->m_ui.m_checkDownloadOnlyUnreadMessages->isChecked());
account()->saveAccountDataToDatabase();
accept();
@@ -58,6 +62,7 @@ void FormEditTtRssAccount::loadAccountData() {
m_details->m_ui.m_spinLimitMessages->setValue(existing_root->network()->batchSize());
m_details->m_ui.m_checkServerSideUpdate->setChecked(existing_root->network()->forceServerSideUpdate());
m_details->m_ui.m_checkDownloadOnlyUnreadMessages->setChecked(existing_root->network()->downloadOnlyUnreadMessages());
+ m_details->m_ui.m_cbNewAlgorithm->setChecked(existing_root->network()->intelligentSynchronization());
}
void FormEditTtRssAccount::performTest() {
diff --git a/src/librssguard/services/tt-rss/gui/ttrssaccountdetails.cpp b/src/librssguard/services/tt-rss/gui/ttrssaccountdetails.cpp
index a65d656da..aac7073af 100644
--- a/src/librssguard/services/tt-rss/gui/ttrssaccountdetails.cpp
+++ b/src/librssguard/services/tt-rss/gui/ttrssaccountdetails.cpp
@@ -11,9 +11,16 @@ TtRssAccountDetails::TtRssAccountDetails(QWidget* parent) : QWidget(parent) {
m_ui.setupUi(this);
m_ui.m_lblTestResult->label()->setWordWrap(true);
- m_ui.m_lblServerSideUpdateInformation->setHelpText(tr("Leaving this option on causes that updates "
- "of feeds will be probably much slower and may time-out often."),
- true);
+ m_ui.m_lblNewAlgorithm->setHelpText(tr("If you select intelligent synchronization, then only not-yet-fetched "
+ "or updated articles are downloaded. Network usage is greatly reduced and "
+ "overall synchronization speed is greatly improved, but "
+ "first feed fetching could be slow anyway if your feed contains "
+ "huge number of articles."),
+ false);
+ m_ui.m_lblServerSideUpdateInformation
+ ->setHelpText(tr("Leaving this option on causes that updates "
+ "of feeds will be probably much slower and may time-out often."),
+ true);
m_ui.m_txtHttpUsername->lineEdit()->setPlaceholderText(tr("HTTP authentication username"));
m_ui.m_txtHttpPassword->lineEdit()->setPlaceholderText(tr("HTTP authentication password"));
m_ui.m_txtPassword->lineEdit()->setPlaceholderText(tr("Password for your TT-RSS account"));
@@ -25,7 +32,8 @@ TtRssAccountDetails::TtRssAccountDetails(QWidget* parent) : QWidget(parent) {
setTabOrder(m_ui.m_txtUrl->lineEdit(), m_ui.m_checkDownloadOnlyUnreadMessages);
setTabOrder(m_ui.m_checkDownloadOnlyUnreadMessages, m_ui.m_spinLimitMessages);
- setTabOrder(m_ui.m_spinLimitMessages, m_ui.m_checkServerSideUpdate);
+ setTabOrder(m_ui.m_spinLimitMessages, m_ui.m_cbNewAlgorithm);
+ setTabOrder(m_ui.m_cbNewAlgorithm, m_ui.m_checkServerSideUpdate);
setTabOrder(m_ui.m_checkServerSideUpdate, m_ui.m_txtUsername->lineEdit());
setTabOrder(m_ui.m_txtUsername->lineEdit(), m_ui.m_txtPassword->lineEdit());
setTabOrder(m_ui.m_txtPassword->lineEdit(), m_ui.m_gbHttpAuthentication);
@@ -38,8 +46,14 @@ TtRssAccountDetails::TtRssAccountDetails(QWidget* parent) : QWidget(parent) {
connect(m_ui.m_txtPassword->lineEdit(), &BaseLineEdit::textChanged, this, &TtRssAccountDetails::onPasswordChanged);
connect(m_ui.m_txtUsername->lineEdit(), &BaseLineEdit::textChanged, this, &TtRssAccountDetails::onUsernameChanged);
- connect(m_ui.m_txtHttpPassword->lineEdit(), &BaseLineEdit::textChanged, this, &TtRssAccountDetails::onHttpPasswordChanged);
- connect(m_ui.m_txtHttpUsername->lineEdit(), &BaseLineEdit::textChanged, this, &TtRssAccountDetails::onHttpUsernameChanged);
+ connect(m_ui.m_txtHttpPassword->lineEdit(),
+ &BaseLineEdit::textChanged,
+ this,
+ &TtRssAccountDetails::onHttpPasswordChanged);
+ connect(m_ui.m_txtHttpUsername->lineEdit(),
+ &BaseLineEdit::textChanged,
+ this,
+ &TtRssAccountDetails::onHttpUsernameChanged);
connect(m_ui.m_txtUrl->lineEdit(), &BaseLineEdit::textChanged, this, &TtRssAccountDetails::onUrlChanged);
connect(m_ui.m_gbHttpAuthentication, &QGroupBox::toggled, this, &TtRssAccountDetails::onHttpPasswordChanged);
connect(m_ui.m_gbHttpAuthentication, &QGroupBox::toggled, this, &TtRssAccountDetails::onHttpUsernameChanged);
@@ -87,21 +101,24 @@ void TtRssAccountDetails::performTest(const QNetworkProxy& proxy) {
}
else if (result.apiLevel() < TTRSS_MINIMAL_API_LEVEL) {
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error,
- tr("Installed version: %1, required at least: %2.").arg(QString::number(result.apiLevel()),
- QString::number(TTRSS_MINIMAL_API_LEVEL)),
+ tr("Installed version: %1, required at least: %2.")
+ .arg(QString::number(result.apiLevel()),
+ QString::number(TTRSS_MINIMAL_API_LEVEL)),
tr("Selected Tiny Tiny RSS server is running unsupported version of API."));
}
else {
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok,
- tr("Installed version: %1, required at least: %2.").arg(QString::number(result.apiLevel()),
- QString::number(TTRSS_MINIMAL_API_LEVEL)),
+ tr("Installed version: %1, required at least: %2.")
+ .arg(QString::number(result.apiLevel()),
+ QString::number(TTRSS_MINIMAL_API_LEVEL)),
tr("Tiny Tiny RSS 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 Tiny Tiny RSS API endpoint and password?"));
+ 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 Tiny Tiny RSS API endpoint and password?"));
}
else {
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error,
@@ -133,25 +150,23 @@ void TtRssAccountDetails::onPasswordChanged() {
}
void TtRssAccountDetails::onHttpUsernameChanged() {
- const bool is_username_ok = !m_ui.m_gbHttpAuthentication->isChecked() || !m_ui.m_txtHttpUsername->lineEdit()->text().isEmpty();
+ const bool is_username_ok =
+ !m_ui.m_gbHttpAuthentication->isChecked() || !m_ui.m_txtHttpUsername->lineEdit()->text().isEmpty();
- m_ui.m_txtHttpUsername->setStatus(is_username_ok ?
- LineEditWithStatus::StatusType::Ok :
- LineEditWithStatus::StatusType::Warning,
- is_username_ok ?
- tr("Username is ok or it is not needed.") :
- tr("Username is empty."));
+ m_ui.m_txtHttpUsername->setStatus(is_username_ok ? LineEditWithStatus::StatusType::Ok
+ : LineEditWithStatus::StatusType::Warning,
+ is_username_ok ? tr("Username is ok or it is not needed.")
+ : tr("Username is empty."));
}
void TtRssAccountDetails::onHttpPasswordChanged() {
- const bool is_username_ok = !m_ui.m_gbHttpAuthentication->isChecked() || !m_ui.m_txtHttpPassword->lineEdit()->text().isEmpty();
+ const bool is_username_ok =
+ !m_ui.m_gbHttpAuthentication->isChecked() || !m_ui.m_txtHttpPassword->lineEdit()->text().isEmpty();
- m_ui.m_txtHttpPassword->setStatus(is_username_ok ?
- LineEditWithStatus::StatusType::Ok :
- LineEditWithStatus::StatusType::Warning,
- is_username_ok ?
- tr("Password is ok or it is not needed.") :
- tr("Password is empty."));
+ m_ui.m_txtHttpPassword->setStatus(is_username_ok ? LineEditWithStatus::StatusType::Ok
+ : LineEditWithStatus::StatusType::Warning,
+ is_username_ok ? tr("Password is ok or it is not needed.")
+ : tr("Password is empty."));
}
void TtRssAccountDetails::onUrlChanged() {
diff --git a/src/librssguard/services/tt-rss/gui/ttrssaccountdetails.ui b/src/librssguard/services/tt-rss/gui/ttrssaccountdetails.ui
index a25d0bb76..2692e93f5 100644
--- a/src/librssguard/services/tt-rss/gui/ttrssaccountdetails.ui
+++ b/src/librssguard/services/tt-rss/gui/ttrssaccountdetails.ui
@@ -11,7 +11,7 @@
- -
+
-
Qt::Vertical
@@ -41,13 +41,6 @@
- -
-
-
- Download unread articles only
-
-
-
-
-
@@ -85,17 +78,28 @@
+ -
+
+
+ Download unread articles only
+
+
+
-
+
+
+ Intelligent synchronization algorithm
+
+
+
+ -
Force execution of server-side feeds update
- -
-
-
- -
+
-
Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported.
@@ -139,7 +143,7 @@
- -
+
-
Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported.
@@ -186,7 +190,7 @@
- -
+
-
-
@@ -210,21 +214,27 @@
+ -
+
+
+ -
+
+
-
- LineEditWithStatus
- QWidget
-
- 1
-
LabelWithStatus
QWidget
1
+
+ LineEditWithStatus
+ QWidget
+
+ 1
+
MessageCountSpinBox
QSpinBox
diff --git a/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp b/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp
index d5a1a8cc4..5206fe207 100644
--- a/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp
+++ b/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp
@@ -22,9 +22,10 @@
#include
TtRssNetworkFactory::TtRssNetworkFactory()
- : m_bareUrl(QString()), m_fullUrl(QString()), m_username(QString()), m_password(QString()), m_batchSize(TTRSS_DEFAULT_MESSAGES),
- m_forceServerSideUpdate(false), m_authIsUsed(false), m_authUsername(QString()), m_authPassword(QString()), m_sessionId(QString()),
- m_lastError(QNetworkReply::NoError) {}
+ : m_bareUrl(QString()), m_fullUrl(QString()), m_username(QString()), m_password(QString()),
+ m_batchSize(TTRSS_DEFAULT_MESSAGES), m_forceServerSideUpdate(false), m_intelligentSynchronization(true),
+ m_authIsUsed(false), m_authUsername(QString()), m_authPassword(QString()), m_sessionId(QString()),
+ m_lastError(QNetworkReply::NoError) {}
QString TtRssNetworkFactory::url() const {
return m_bareUrl;
@@ -71,8 +72,7 @@ QNetworkReply::NetworkError TtRssNetworkFactory::lastError() const {
TtRssLoginResponse TtRssNetworkFactory::login(const QNetworkProxy& proxy) {
if (!m_sessionId.isEmpty()) {
- qWarningNN << LOGSEC_TTRSS
- << "Session ID is not empty before login, logging out first.";
+ qWarningNN << LOGSEC_TTRSS << "Session ID is not empty before login, logging out first.";
logout(proxy);
}
@@ -88,18 +88,19 @@ TtRssLoginResponse TtRssNetworkFactory::login(const QNetworkProxy& proxy) {
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- qApp->settings()->value(GROUP(Feeds),
- SETTING(
- Feeds::UpdateTimeout)).toInt(),
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ qApp->settings()
+ ->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout))
+ .toInt(),
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
TtRssLoginResponse login_response(QString::fromUtf8(result_raw));
if (network_reply.m_networkError == QNetworkReply::NoError) {
@@ -107,9 +108,7 @@ TtRssLoginResponse TtRssNetworkFactory::login(const QNetworkProxy& proxy) {
m_lastLoginTime = QDateTime::currentDateTime();
}
else {
- qWarningNN << LOGSEC_TTRSS
- << "Login failed with error:"
- << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ qWarningNN << LOGSEC_TTRSS << "Login failed with error:" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
m_lastError = network_reply.m_networkError;
@@ -128,18 +127,19 @@ TtRssResponse TtRssNetworkFactory::logout(const QNetworkProxy& proxy) {
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- qApp->settings()->value(GROUP(Feeds),
- SETTING(
- Feeds::UpdateTimeout)).toInt(),
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ qApp->settings()
+ ->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout))
+ .toInt(),
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
m_lastError = network_reply.m_networkError;
@@ -147,16 +147,13 @@ TtRssResponse TtRssNetworkFactory::logout(const QNetworkProxy& proxy) {
m_sessionId.clear();
}
else {
- qWarningNN << LOGSEC_TTRSS
- << "Logout failed with error:"
- << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ qWarningNN << LOGSEC_TTRSS << "Logout failed with error:" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
return TtRssResponse(QString::fromUtf8(result_raw));
}
else {
- qWarningNN << LOGSEC_TTRSS
- << "Cannot logout because session ID is empty.";
+ qWarningNN << LOGSEC_TTRSS << "Cannot logout because session ID is empty.";
m_lastError = QNetworkReply::NetworkError::NoError;
return TtRssResponse();
}
@@ -175,34 +172,35 @@ TtRssGetLabelsResponse TtRssNetworkFactory::getLabels(const QNetworkProxy& proxy
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers);
TtRssGetLabelsResponse result(QString::fromUtf8(result_raw));
if (result.isNotLoggedIn()) {
// We are not logged in.
login(proxy);
json[QSL("sid")] = m_sessionId;
- network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
result = TtRssGetLabelsResponse(QString::fromUtf8(result_raw));
}
if (network_reply.m_networkError != QNetworkReply::NoError) {
- qWarningNN << LOGSEC_TTRSS
- << "getLabels failed with error:"
- << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ qWarningNN << LOGSEC_TTRSS << "getLabels failed with error:" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
m_lastError = network_reply.m_networkError;
@@ -225,39 +223,40 @@ TtRssResponse TtRssNetworkFactory::shareToPublished(const TtRssNoteToPublish& no
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
TtRssResponse result(QString::fromUtf8(result_raw));
if (result.isNotLoggedIn()) {
// We are not logged in.
login(proxy);
json[QSL("sid")] = m_sessionId;
- network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
result = TtRssResponse(QString::fromUtf8(result_raw));
}
if (network_reply.m_networkError != QNetworkReply::NoError) {
qWarningNN << LOGSEC_TTRSS
- << "shareToPublished failed with error:"
- << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ << "shareToPublished failed with error:" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
m_lastError = network_reply.m_networkError;
@@ -277,47 +276,166 @@ TtRssGetFeedsCategoriesResponse TtRssNetworkFactory::getFeedsCategories(const QN
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
TtRssGetFeedsCategoriesResponse result(QString::fromUtf8(result_raw));
if (result.isNotLoggedIn()) {
// We are not logged in.
login(proxy);
json[QSL("sid")] = m_sessionId;
- network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
result = TtRssGetFeedsCategoriesResponse(QString::fromUtf8(result_raw));
}
if (network_reply.m_networkError != QNetworkReply::NoError) {
- qWarningNN << LOGSEC_TTRSS
- << "getFeedTree failed with error:"
- << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ qWarningNN << LOGSEC_TTRSS << "getFeedTree failed with error:" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
m_lastError = network_reply.m_networkError;
return result;
}
-TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id, int limit, int skip,
- bool show_content, bool include_attachments,
- bool sanitize, bool unread_only,
+TtRssGetCompactHeadlinesResponse TtRssNetworkFactory::getCompactHeadlines(int feed_id,
+ int limit,
+ int skip,
+ const QString& view_mode,
+ const QNetworkProxy& proxy) {
+ QJsonObject json;
+
+ json[QSL("op")] = QSL("getCompactHeadlines");
+ json[QSL("sid")] = m_sessionId;
+ json[QSL("feed_id")] = feed_id;
+ json[QSL("limit")] = limit;
+ // json[QSL("skip")] = skip;
+ json[QSL("view_mode")] = view_mode;
+
+ const int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
+ QByteArray result_raw;
+ QList> headers;
+
+ headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
+ headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
+
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
+ TtRssGetCompactHeadlinesResponse result(QString::fromUtf8(result_raw));
+
+ if (result.isNotLoggedIn()) {
+ // We are not logged in.
+ login(proxy);
+ json[QSL("sid")] = m_sessionId;
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
+ result = TtRssGetCompactHeadlinesResponse(QString::fromUtf8(result_raw));
+ }
+
+ if (network_reply.m_networkError != QNetworkReply::NetworkError::NoError) {
+ qWarningNN << LOGSEC_TTRSS
+ << "getCompactHeadlines failed with error:" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ }
+
+ m_lastError = network_reply.m_networkError;
+ return result;
+}
+
+TtRssGetHeadlinesResponse TtRssNetworkFactory::getArticle(const QStringList& article_ids, const QNetworkProxy& proxy) {
+ QJsonObject json;
+
+ json[QSL("op")] = QSL("getArticle");
+ json[QSL("sid")] = m_sessionId;
+ json[QSL("article_id")] = article_ids.join(QL1C(','));
+
+ const int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
+ QByteArray result_raw;
+ QList> headers;
+
+ headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
+ headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
+
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
+ TtRssGetHeadlinesResponse result(QString::fromUtf8(result_raw));
+
+ if (result.isNotLoggedIn()) {
+ // We are not logged in.
+ login(proxy);
+ json[QSL("sid")] = m_sessionId;
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
+ result = TtRssGetHeadlinesResponse(QString::fromUtf8(result_raw));
+ }
+
+ if (network_reply.m_networkError != QNetworkReply::NetworkError::NoError) {
+ qWarningNN << LOGSEC_TTRSS << "getArticle failed with error:" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ }
+
+ m_lastError = network_reply.m_networkError;
+ return result;
+}
+
+TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id,
+ int limit,
+ int skip,
+ bool show_content,
+ bool include_attachments,
+ bool sanitize,
+ bool unread_only,
const QNetworkProxy& proxy) {
QJsonObject json;
@@ -339,47 +457,49 @@ TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id, int lim
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
TtRssGetHeadlinesResponse result(QString::fromUtf8(result_raw));
if (result.isNotLoggedIn()) {
// We are not logged in.
login(proxy);
json[QSL("sid")] = m_sessionId;
- network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
result = TtRssGetHeadlinesResponse(QString::fromUtf8(result_raw));
}
if (network_reply.m_networkError != QNetworkReply::NoError) {
- qWarningNN << LOGSEC_TTRSS
- << "getHeadlines failed with error:"
- << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ qWarningNN << LOGSEC_TTRSS << "getHeadlines failed with error:" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
m_lastError = network_reply.m_networkError;
return result;
}
-TtRssResponse TtRssNetworkFactory::setArticleLabel(const QStringList& article_ids, const QString& label_custom_id,
- bool assign, const QNetworkProxy& proxy) {
+TtRssResponse TtRssNetworkFactory::setArticleLabel(const QStringList& article_ids,
+ const QString& label_custom_id,
+ bool assign,
+ const QNetworkProxy& proxy) {
QJsonObject json;
json[QSL("op")] = QSL("setArticleLabel");
@@ -395,38 +515,39 @@ TtRssResponse TtRssNetworkFactory::setArticleLabel(const QStringList& article_id
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
TtRssResponse result(QString::fromUtf8(result_raw));
if (result.isNotLoggedIn()) {
// We are not logged in.
login(proxy);
json[QSL("sid")] = m_sessionId;
- network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
result = TtRssResponse(QString::fromUtf8(result_raw));
}
if (network_reply.m_networkError != QNetworkReply::NoError) {
- qWarningNN << LOGSEC_TTRSS
- << "setArticleLabel failed with error"
+ qWarningNN << LOGSEC_TTRSS << "setArticleLabel failed with error"
<< QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
@@ -453,48 +574,50 @@ TtRssUpdateArticleResponse TtRssNetworkFactory::updateArticles(const QStringList
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
TtRssUpdateArticleResponse result(QString::fromUtf8(result_raw));
if (result.isNotLoggedIn()) {
// We are not logged in.
login(proxy);
json[QSL("sid")] = m_sessionId;
- network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
result = TtRssUpdateArticleResponse(QString::fromUtf8(result_raw));
}
if (network_reply.m_networkError != QNetworkReply::NoError) {
- qWarningNN << LOGSEC_TTRSS
- << "updateArticle failed with error"
- << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ qWarningNN << LOGSEC_TTRSS << "updateArticle failed with error" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
m_lastError = network_reply.m_networkError;
return result;
}
-TtRssSubscribeToFeedResponse TtRssNetworkFactory::subscribeToFeed(const QString& url, int category_id,
+TtRssSubscribeToFeedResponse TtRssNetworkFactory::subscribeToFeed(const QString& url,
+ int category_id,
const QNetworkProxy& proxy,
- bool protectd, const QString& username,
+ bool protectd,
+ const QString& username,
const QString& password) {
QJsonObject json;
@@ -515,39 +638,39 @@ TtRssSubscribeToFeedResponse TtRssNetworkFactory::subscribeToFeed(const QString&
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
TtRssSubscribeToFeedResponse result(QString::fromUtf8(result_raw));
if (result.isNotLoggedIn()) {
// We are not logged in.
login(proxy);
json[QSL("sid")] = m_sessionId;
- network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
result = TtRssSubscribeToFeedResponse(QString::fromUtf8(result_raw));
}
if (network_reply.m_networkError != QNetworkReply::NoError) {
- qWarningNN << LOGSEC_TTRSS
- << "updateArticle failed with error"
- << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ qWarningNN << LOGSEC_TTRSS << "updateArticle failed with error" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
m_lastError = network_reply.m_networkError;
@@ -567,39 +690,39 @@ TtRssUnsubscribeFeedResponse TtRssNetworkFactory::unsubscribeFeed(int feed_id, c
headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
- NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ NetworkResult network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
TtRssUnsubscribeFeedResponse result(QString::fromUtf8(result_raw));
if (result.isNotLoggedIn()) {
// We are not logged in.
login(proxy);
json[QSL("sid")] = m_sessionId;
- network_reply = NetworkFactory::performNetworkOperation(m_fullUrl,
- timeout,
- QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
- result_raw,
- QNetworkAccessManager::Operation::PostOperation,
- headers,
- false,
- {},
- {},
- proxy);
+ network_reply =
+ NetworkFactory::performNetworkOperation(m_fullUrl,
+ timeout,
+ QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact),
+ result_raw,
+ QNetworkAccessManager::Operation::PostOperation,
+ headers,
+ false,
+ {},
+ {},
+ proxy);
result = TtRssUnsubscribeFeedResponse(QString::fromUtf8(result_raw));
}
if (network_reply.m_networkError != QNetworkReply::NoError) {
- qWarningNN << LOGSEC_TTRSS
- << "getFeeds failed with error"
- << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
+ qWarningNN << LOGSEC_TTRSS << "getFeeds failed with error" << QUOTE_W_SPACE_DOT(network_reply.m_networkError);
}
m_lastError = network_reply.m_networkError;
@@ -614,6 +737,14 @@ void TtRssNetworkFactory::setBatchSize(int batch_size) {
m_batchSize = batch_size;
}
+bool TtRssNetworkFactory::intelligentSynchronization() const {
+ return m_intelligentSynchronization;
+}
+
+void TtRssNetworkFactory::setIntelligentSynchronization(bool intelligent_synchronization) {
+ m_intelligentSynchronization = intelligent_synchronization;
+}
+
bool TtRssNetworkFactory::downloadOnlyUnreadMessages() const {
return m_downloadOnlyUnreadMessages;
}
@@ -729,7 +860,8 @@ bool TtRssResponse::hasError() const {
}
}
-TtRssGetFeedsCategoriesResponse::TtRssGetFeedsCategoriesResponse(const QString& raw_content) : TtRssResponse(raw_content) {}
+TtRssGetFeedsCategoriesResponse::TtRssGetFeedsCategoriesResponse(const QString& raw_content)
+ : TtRssResponse(raw_content) {}
TtRssGetFeedsCategoriesResponse::~TtRssGetFeedsCategoriesResponse() = default;
@@ -740,14 +872,14 @@ RootItem* TtRssGetFeedsCategoriesResponse::feedsCategories(TtRssNetworkFactory*
auto* parent = new RootItem();
// Chop the "api/" from the end of the address.
- qDebugNN << LOGSEC_TTRSS
- << "Base address to get feed icons is"
- << QUOTE_W_SPACE_DOT(base_address);
+ qDebugNN << LOGSEC_TTRSS << "Base address to get feed icons is" << QUOTE_W_SPACE_DOT(base_address);
if (status() == TTRSS_API_STATUS_OK) {
// We have data, construct object tree according to data.
- QJsonArray items_to_process = m_rawContent[QSL("content")].toObject()[QSL("categories")].toObject()[QSL("items")].toArray();
- QVector> pairs; pairs.reserve(items_to_process.size());
+ QJsonArray items_to_process =
+ m_rawContent[QSL("content")].toObject()[QSL("categories")].toObject()[QSL("items")].toArray();
+ QVector> pairs;
+ pairs.reserve(items_to_process.size());
for (const QJsonValue& item : items_to_process) {
pairs.append(QPair(parent, item));
@@ -793,7 +925,8 @@ RootItem* TtRssGetFeedsCategoriesResponse::feedsCategories(TtRssNetworkFactory*
auto* feed = new TtRssFeed();
if (obtain_icons) {
- QString icon_path = item[QSL("icon")].type() == QJsonValue::String ? item[QSL("icon")].toString() : QString();
+ QString icon_path =
+ item[QSL("icon")].type() == QJsonValue::String ? item[QSL("icon")].toString() : QString();
if (!icon_path.isEmpty()) {
// Chop the "api/" suffix out and append
@@ -802,23 +935,17 @@ RootItem* TtRssGetFeedsCategoriesResponse::feedsCategories(TtRssNetworkFactory*
QList> headers;
if (network->authIsUsed()) {
- headers << NetworkFactory::generateBasicAuthHeader(network->authUsername(),
- network->authPassword());
+ headers << NetworkFactory::generateBasicAuthHeader(network->authUsername(), network->authPassword());
}
- auto res = NetworkFactory::downloadIcon({ { full_icon_address, true } },
- DOWNLOAD_TIMEOUT,
- icon,
- headers,
- proxy);
+ auto res =
+ NetworkFactory::downloadIcon({{full_icon_address, true}}, DOWNLOAD_TIMEOUT, icon, headers, proxy);
if (res == QNetworkReply::NoError) {
feed->setIcon(icon);
}
else {
- qWarningNN << LOGSEC_TTRSS
- << "Failed to download icon with error"
- << QUOTE_W_SPACE_DOT(res);
+ qWarningNN << LOGSEC_TTRSS << "Failed to download icon with error" << QUOTE_W_SPACE_DOT(res);
}
}
}
@@ -851,6 +978,14 @@ TtRssGetHeadlinesResponse::TtRssGetHeadlinesResponse(const QString& raw_content)
TtRssGetHeadlinesResponse::~TtRssGetHeadlinesResponse() = default;
+TtRssGetArticleResponse::TtRssGetArticleResponse(const QString& raw_content) : TtRssResponse(raw_content) {}
+
+QList TtRssGetArticleResponse::messages(ServiceRoot* root) const {
+ return {};
+}
+
+TtRssGetArticleResponse::~TtRssGetArticleResponse() = default;
+
QList TtRssGetHeadlinesResponse::messages(ServiceRoot* root) const {
QList messages;
auto active_labels = root->labelsNode() != nullptr ? root->labelsNode()->labels() : QList