diff --git a/README.md b/README.md
index 677deb85e..9b206c068 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,9 @@ RSS Guard is simple, light and easy-to-use RSS/ATOM feed aggregator developed us
* [Tiny Tiny RSS](https://tt-rss.org),
* [Inoreader](https://www.inoreader.com),
* [Nextcloud News](https://apps.nextcloud.com/apps/news),
-* [Gmail API](https://developers.google.com/gmail/api).
+* [Gmail API](https://developers.google.com/gmail/api),
+* [FreshRSS](https://freshrss.org),
+* [The Old Reader](https://theoldreader.com),
+* [Bazqux](https://bazqux.com).
Application icon was kindly contributed by Siddharth Yadav - @Siddharth_yd (Instagram), illustrationdesignsid@gmail.com (e-mail). Flag icons were provided by [IconDrawer](http://www.icondrawer.com).
\ No newline at end of file
diff --git a/pri/vars.pri b/pri/vars.pri
index bf89b9685..2855f7c46 100644
--- a/pri/vars.pri
+++ b/pri/vars.pri
@@ -4,7 +4,7 @@ APP_REVERSE_NAME = "com.github.rssguard"
APP_LOW_H_NAME = ".rssguard"
APP_AUTHOR = "Martin Rotter"
APP_COPYRIGHT = "(C) 2011-2021 $$APP_AUTHOR"
-APP_VERSION = "3.8.5"
+APP_VERSION = "3.9.0"
APP_LONG_NAME = "$$APP_NAME $$APP_VERSION"
APP_EMAIL = "rotter.martinos@gmail.com"
APP_URL = "https://github.com/martinrotter/rssguard"
diff --git a/resources/docs/Documentation.md b/resources/docs/Documentation.md
index 99d6803b2..f438a5ab0 100644
--- a/resources/docs/Documentation.md
+++ b/resources/docs/Documentation.md
@@ -11,6 +11,7 @@
* [Supported feed formats and online feed services](Feed-formats.md)
* [Message filtering](Message-filters.md)
* [Database backends](#database-backends)
+ * [Google Reader API](#google-reader-api)
* [Gmail](#gmail)
* [Labels](Labels.md)
* [Downloading files](#downloading-files)
@@ -83,10 +84,14 @@ RSS Guard is simple (yet powerful) feed reader. It is able to fetch the most kno
* Nextcloud News (RSS Guard 3.1.0+),
* Inoreader (RSS Guard 3.5.0+),
* Gmail with e-mail sending (RSS Guard 3.7.1+).
+ * FreshRSS (RSS Guard 3.9.0+),
+ * The Old Reader (RSS Guard 3.9.0+),
+ * Bazqux (RSS Guard 3.9.0+).
* core:
* support for all feed formats (RSS/RDF/ATOM/JSON),
* full support of podcasts (RSS/ATOM/JSON),
* import/export of feeds to/from OPML 2.0,
+ * universal plugin for online services with [Google Reader API](#google-reader-api),
* possibility of using custom 3rd-party feed synchronization services,
* feed metadata fetching including icons,
* simple internal Chromium-based web viewer (or alternative version with simpler and much more lightweight internal viewer),
@@ -137,6 +142,19 @@ MariaDB (MySQL) backend is there for users, who want to store their data in a ce
For database-related configuration see `Settings -> Data storage` dialog.
+## Google Reader API
+Starting with RSS Guard 3.9.0, there is a new plugin which offers synchronization with services using Google Reader API. Plugin was so far tested with FreshRSS, The Old Reader and Bazqux. All Google Reader API enabled services should work.
+
+Note that Inoreader has its own separate plugin, because it uses OAuth as authentication method, therefore it is cleaner to have separate plugin.
+
+Google Reader API integration in RSS Guard offers a way to set custom service endpoint even if you select service which is not self-hosted such as Bazqux, providing all users with greater flexibility and freedom.
+
+
+
+Note that even when all Google Reader API enabled services should follow the API, there are still some minor differences, primarily because Google Reader API has no strict documentation to follow and some services do not offer some features.
+
+For example The Old Reader does not seem to offer tags/labels functionality, therefore tags/labels in RSS Guard are not synchronized, but you can still use offline labels.
+
## Gmail
RSS Guard includes Gmail plugin, which allows users to receive and send (!!!) e-mail messages. Plugin uses [Gmail API](https://developers.google.com/gmail/api) and offers some e-mail client-like features:
* Sending e-mail messages.
diff --git a/resources/docs/images/greader-api-settings.png b/resources/docs/images/greader-api-settings.png
new file mode 100644
index 000000000..e1a59a351
Binary files /dev/null and b/resources/docs/images/greader-api-settings.png differ
diff --git a/resources/graphics/misc/bazqux.png b/resources/graphics/misc/bazqux.png
new file mode 100644
index 000000000..7ca0c5de2
Binary files /dev/null and b/resources/graphics/misc/bazqux.png differ
diff --git a/resources/rssguard.qrc b/resources/rssguard.qrc
index 60a4f36fd..d2fe9c3a0 100755
--- a/resources/rssguard.qrc
+++ b/resources/rssguard.qrc
@@ -16,6 +16,7 @@
graphics/misc/adblock.png
graphics/misc/adblock-disabled.png
+ graphics/misc/bazqux.png
graphics/misc/freshrss.png
graphics/misc/gmail.png
graphics/misc/google.png
diff --git a/src/librssguard/miscellaneous/databasequeries.cpp b/src/librssguard/miscellaneous/databasequeries.cpp
index 717d60110..3c7ba7f43 100755
--- a/src/librssguard/miscellaneous/databasequeries.cpp
+++ b/src/librssguard/miscellaneous/databasequeries.cpp
@@ -1694,7 +1694,7 @@ QList DatabaseQueries::getGreaderAccounts(const QSqlDatabase& db,
root->network()->setPassword(TextFactory::decrypt(query.value(3).toString()));
root->network()->setBaseUrl(query.value(4).toString());
root->network()->setBatchSize(query.value(5).toInt());
- root->updateTitle();
+ root->updateTitleIcon();
fillBaseAccountData(db, root);
diff --git a/src/librssguard/services/greader/greaderserviceroot.cpp b/src/librssguard/services/greader/greaderserviceroot.cpp
index dc2022e0f..fae7abda1 100755
--- a/src/librssguard/services/greader/greaderserviceroot.cpp
+++ b/src/librssguard/services/greader/greaderserviceroot.cpp
@@ -139,7 +139,7 @@ void GreaderServiceRoot::saveAllCachedData(bool ignore_errors) {
}
}
-void GreaderServiceRoot::updateTitle() {
+void GreaderServiceRoot::updateTitleIcon() {
setTitle(QString("%1 (%2)").arg(m_network->username(),
m_network->serviceToString(m_network->service())));
@@ -152,6 +152,10 @@ void GreaderServiceRoot::updateTitle() {
setIcon(qApp->icons()->miscIcon(QSL("freshrss")));
break;
+ case Service::Bazqux:
+ setIcon(qApp->icons()->miscIcon(QSL("bazqux")));
+ break;
+
default:
setIcon(GreaderEntryPoint().icon());
break;
@@ -165,7 +169,7 @@ void GreaderServiceRoot::saveAccountDataToDatabase(bool creating_new) {
if (DatabaseQueries::overwriteGreaderAccount(database, m_network->username(),
m_network->password(), m_network->baseUrl(),
m_network->batchSize(), accountId())) {
- updateTitle();
+ updateTitleIcon();
itemChanged(QList() << this);
}
}
@@ -173,7 +177,7 @@ void GreaderServiceRoot::saveAccountDataToDatabase(bool creating_new) {
if (DatabaseQueries::createGreaderAccount(database, accountId(), m_network->username(),
m_network->password(), m_network->service(),
m_network->baseUrl(), m_network->batchSize())) {
- updateTitle();
+ updateTitleIcon();
}
}
}
diff --git a/src/librssguard/services/greader/greaderserviceroot.h b/src/librssguard/services/greader/greaderserviceroot.h
index 8dff72123..57c091797 100755
--- a/src/librssguard/services/greader/greaderserviceroot.h
+++ b/src/librssguard/services/greader/greaderserviceroot.h
@@ -35,7 +35,7 @@ class GreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot {
void setNetwork(GreaderNetwork* network);
GreaderNetwork* network() const;
- void updateTitle();
+ void updateTitleIcon();
void saveAccountDataToDatabase(bool creating_new);
protected:
diff --git a/src/librssguard/services/greader/gui/greaderaccountdetails.cpp b/src/librssguard/services/greader/gui/greaderaccountdetails.cpp
index f606c827a..9432d23ea 100755
--- a/src/librssguard/services/greader/gui/greaderaccountdetails.cpp
+++ b/src/librssguard/services/greader/gui/greaderaccountdetails.cpp
@@ -11,8 +11,8 @@
GreaderAccountDetails::GreaderAccountDetails(QWidget* parent) : QWidget(parent) {
m_ui.setupUi(this);
- for (auto serv : { GreaderServiceRoot::Service::FreshRss,
- GreaderServiceRoot::Service::Bazqux,
+ for (auto serv : { GreaderServiceRoot::Service::Bazqux,
+ GreaderServiceRoot::Service::FreshRss,
GreaderServiceRoot::Service::TheOldReader }) {
m_ui.m_cmbService->addItem(GreaderNetwork::serviceToString(serv), QVariant::fromValue(serv));
}
@@ -24,9 +24,10 @@ GreaderAccountDetails::GreaderAccountDetails(QWidget* parent) : QWidget(parent)
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Information,
tr("No test done yet."),
tr("Here, results of connection test are shown."));
- m_ui.m_lblLimitMessages->setText(
- tr("Limiting number of downloaded messages per feed makes updating of feeds faster but if your feed contains "
- "bigger number of messages than specified limit, then some messages might not be downloaded during feed update."));
+ m_ui.m_lblLimitMessages->setText(tr("Limiting number of downloaded messages per feed makes updating of "
+ "feeds faster, but if your feed contains bigger number of messages "
+ "than specified limit, then some older messages might not be "
+ "downloaded during feed update."));
connect(m_ui.m_spinLimitMessages, static_cast(&QSpinBox::valueChanged), this, [=](int value) {
if (value <= 0) {