diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml
index c267a5089..fcee471f6 100644
--- a/resources/desktop/com.github.rssguard.appdata.xml
+++ b/resources/desktop/com.github.rssguard.appdata.xml
@@ -30,7 +30,7 @@
https://martinrotter.github.io/donate/
-
+
none
diff --git a/src/librssguard/network-web/networkfactory.cpp b/src/librssguard/network-web/networkfactory.cpp
index 906ea842e..ab49c3f65 100644
--- a/src/librssguard/network-web/networkfactory.cpp
+++ b/src/librssguard/network-web/networkfactory.cpp
@@ -137,66 +137,71 @@ QString NetworkFactory::networkErrorText(QNetworkReply::NetworkError error_code)
}
}
-QNetworkReply::NetworkError NetworkFactory::downloadIcon(const QList& urls, int timeout,
+QNetworkReply::NetworkError NetworkFactory::downloadIcon(const QList>& urls, int timeout,
QIcon& output, const QNetworkProxy& custom_proxy) {
QNetworkReply::NetworkError network_result = QNetworkReply::NetworkError::UnknownNetworkError;
- for (const QString& url : urls) {
- if (url.isEmpty()) {
+ for (const auto& url : urls) {
+ if (url.first.isEmpty()) {
continue;
}
QByteArray icon_data;
- network_result = performNetworkOperation(url,
- timeout,
- {},
- icon_data,
- QNetworkAccessManager::Operation::GetOperation,
- {},
- false,
- {},
- {},
- custom_proxy).first;
+ if (url.second) {
+ // Download directly.
+ network_result = performNetworkOperation(url.first,
+ timeout,
+ {},
+ icon_data,
+ QNetworkAccessManager::Operation::GetOperation,
+ {},
+ false,
+ {},
+ {},
+ custom_proxy).first;
- if (network_result == QNetworkReply::NetworkError::NoError) {
- QPixmap icon_pixmap;
+ if (network_result == QNetworkReply::NetworkError::NoError) {
+ QPixmap icon_pixmap;
- icon_pixmap.loadFromData(icon_data);
- output = QIcon(icon_pixmap);
+ icon_pixmap.loadFromData(icon_data);
+ output = QIcon(icon_pixmap);
- if (!output.isNull()) {
- break;
+ if (!output.isNull()) {
+ break;
+ }
}
}
+ else {
+ // Use favicon fetching service.
+ QString host = QUrl(url.first).host();
- QString host = QUrl(url).host();
+ if (host.startsWith(QSL("www."))) {
+ host = host.mid(4);
+ }
- if (host.startsWith(QSL("www."))) {
- host = host.mid(4);
- }
+ const QString ddg_icon_service = QString("https://external-content.duckduckgo.com/ip3/%1.ico").arg(host);
- const QString ddg_icon_service = QString("https://external-content.duckduckgo.com/ip3/%1.ico").arg(host);
+ network_result = performNetworkOperation(ddg_icon_service,
+ timeout,
+ QByteArray(),
+ icon_data,
+ QNetworkAccessManager::Operation::GetOperation,
+ {},
+ false,
+ {},
+ {},
+ custom_proxy).first;
- network_result = performNetworkOperation(ddg_icon_service,
- timeout,
- QByteArray(),
- icon_data,
- QNetworkAccessManager::Operation::GetOperation,
- {},
- false,
- {},
- {},
- custom_proxy).first;
+ if (network_result == QNetworkReply::NetworkError::NoError) {
+ QPixmap icon_pixmap;
- if (network_result == QNetworkReply::NetworkError::NoError) {
- QPixmap icon_pixmap;
+ icon_pixmap.loadFromData(icon_data);
+ output = QIcon(icon_pixmap);
- icon_pixmap.loadFromData(icon_data);
- output = QIcon(icon_pixmap);
-
- if (!output.isNull()) {
- break;
+ if (!output.isNull()) {
+ break;
+ }
}
}
}
diff --git a/src/librssguard/network-web/networkfactory.h b/src/librssguard/network-web/networkfactory.h
index 3de6cfd2b..c2496e7d6 100644
--- a/src/librssguard/network-web/networkfactory.h
+++ b/src/librssguard/network-web/networkfactory.h
@@ -31,7 +31,7 @@ class NetworkFactory {
// Performs SYNCHRONOUS download if favicon for the site,
// given URL belongs to.
- static QNetworkReply::NetworkError downloadIcon(const QList& urls,
+ static QNetworkReply::NetworkError downloadIcon(const QList>& urls,
int timeout,
QIcon& output,
const QNetworkProxy& custom_proxy = QNetworkProxy::ProxyType::DefaultProxy);
diff --git a/src/librssguard/services/feedly/definitions.h b/src/librssguard/services/feedly/definitions.h
index 5cc6c2c23..4d8fa03b9 100755
--- a/src/librssguard/services/feedly/definitions.h
+++ b/src/librssguard/services/feedly/definitions.h
@@ -9,7 +9,7 @@
#define FEEDLY_GENERATE_DAT "https://feedly.com/v3/auth/dev"
-#define FEEDLY_API_REDIRECT_URI_PORT 8080
+#define FEEDLY_API_REDIRECT_URI_PORT 14466
#define FEEDLY_API_SCOPE "https://cloud.feedly.com/subscriptions"
//#define FEEDLY_API_URL_BASE "https://sandbox7.feedly.com/v3/"
diff --git a/src/librssguard/services/feedly/feedlynetwork.cpp b/src/librssguard/services/feedly/feedlynetwork.cpp
index 4d632649b..4bf1dab59 100755
--- a/src/librssguard/services/feedly/feedlynetwork.cpp
+++ b/src/librssguard/services/feedly/feedlynetwork.cpp
@@ -359,9 +359,9 @@ RootItem* FeedlyNetwork::decodeCollections(const QByteArray& json, bool obtain_i
if (obtain_icons) {
QIcon icon;
- auto result = NetworkFactory::downloadIcon({ fee_obj["iconUrl"].toString(),
- fee_obj["logo"].toString(),
- fee_obj["website"].toString() },
+ auto result = NetworkFactory::downloadIcon({ { fee_obj["iconUrl"].toString(), true },
+ { fee_obj["website"].toString(), false },
+ { fee_obj["logo"].toString(), true } },
timeout,
icon,
proxy);
diff --git a/src/librssguard/services/greader/greadernetwork.cpp b/src/librssguard/services/greader/greadernetwork.cpp
index 845ca86ef..4f619108e 100755
--- a/src/librssguard/services/greader/greadernetwork.cpp
+++ b/src/librssguard/services/greader/greadernetwork.cpp
@@ -308,7 +308,7 @@ RootItem* GreaderNetwork::decodeTagsSubscriptions(const QString& categories, con
QIcon icon;
- if (NetworkFactory::downloadIcon({ icon_url },
+ if (NetworkFactory::downloadIcon({ { icon_url, true } },
timeout,
icon,
proxy) == QNetworkReply::NetworkError::NoError) {
diff --git a/src/librssguard/services/standard/standardfeed.cpp b/src/librssguard/services/standard/standardfeed.cpp
index d35280dad..91b5be69b 100644
--- a/src/librssguard/services/standard/standardfeed.cpp
+++ b/src/librssguard/services/standard/standardfeed.cpp
@@ -194,7 +194,6 @@ StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type,
auto timeout = qApp->settings()->value(GROUP(Feeds),
SETTING(Feeds::UpdateTimeout)).toInt();
QByteArray feed_contents;
- QList icon_possible_locations;
QString content_type;
if (source_type == StandardFeed::SourceType::Url) {
@@ -216,8 +215,6 @@ StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type,
*result = false;
return nullptr;
}
-
- icon_possible_locations.append(source);
}
else {
qDebugNN << LOGSEC_CORE
@@ -261,6 +258,15 @@ StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type,
StandardFeed* feed = nullptr;
+ // Now we need to obtain list of URLs of icons.
+ // Priority of links:
+ // 1. Links of "homepage" obtained from feed files which will be processed via DuckDuckGo.
+ // 2. Direct links of "favicon", "icon", "logo" obtained from feed files which will be downloaded directly.
+ // 3. Link of the feed file itself which will be processed via DuckDuckGo.
+ // The "bool" if true means that the URL is direct and download directly, if false then
+ // only use its domain and download via DuckDuckGo.
+ QList> icon_possible_locations;
+
if (content_type.contains(QSL("json"), Qt::CaseSensitivity::CaseInsensitive) ||
feed_contents.startsWith('{')) {
feed = new StandardFeed();
@@ -274,14 +280,21 @@ StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type,
feed->setTitle(json.object()["title"].toString());
feed->setDescription(json.object()["description"].toString());
- auto icon = json.object()["icon"].toString();
+ auto home_page = json.object()["home_page_url"].toString();
+
+ if (!home_page.isEmpty()) {
+ icon_possible_locations.prepend({ home_page, false });
+ }
+
+ auto icon = json.object()["favicon"].toString();
if (icon.isEmpty()) {
- icon = json.object()["favicon"].toString();
+ icon = json.object()["icon"].toString();
}
if (!icon.isEmpty()) {
- icon_possible_locations.prepend(icon);
+ // Low priority, download directly.
+ icon_possible_locations.append({ icon, true });
}
}
else {
@@ -347,10 +360,10 @@ StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type,
feed->setTitle(channel_element.namedItem(QSL("title")).toElement().text());
feed->setDescription(channel_element.namedItem(QSL("description")).toElement().text());
- QString source_link = channel_element.namedItem(QSL("link")).toElement().text();
+ QString home_page = channel_element.namedItem(QSL("link")).toElement().text();
- if (!source_link.isEmpty()) {
- icon_possible_locations.prepend(source_link);
+ if (!home_page.isEmpty()) {
+ icon_possible_locations.prepend({ home_page, false });
}
}
else if (root_tag_name == QL1S("rss")) {
@@ -370,19 +383,19 @@ StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type,
feed->setDescription(channel_element.namedItem(QSL("description")).toElement().text());
QString icon_link = channel_element.namedItem(QSL("image")).toElement().text();
- QString icon_url_link = channel_element.namedItem(QSL("image")).namedItem(QSL("url")).toElement().text();
+ QString icon_url_link = channel_element.namedItem(QSL("image")).toElement().attribute(QSL("url"));
if (!icon_url_link.isEmpty()) {
- icon_possible_locations.prepend(icon_url_link);
+ icon_possible_locations.append({ icon_url_link, true });
}
else if (!icon_link.isEmpty()) {
- icon_possible_locations.prepend(icon_link);
+ icon_possible_locations.append({ icon_link, true });
}
- QString source_link = channel_element.namedItem(QSL("link")).toElement().text();
+ QString home_page = channel_element.namedItem(QSL("link")).toElement().text();
- if (!source_link.isEmpty()) {
- icon_possible_locations.append(source_link);
+ if (!home_page.isEmpty()) {
+ icon_possible_locations.prepend({ home_page, false });
}
}
else if (root_tag_name == QL1S("feed")) {
@@ -394,19 +407,13 @@ StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type,
QString icon_link = root_element.namedItem(QSL("icon")).toElement().text();
if (!icon_link.isEmpty()) {
- icon_possible_locations.prepend(icon_link);
+ icon_possible_locations.append({ icon_link, true });
}
- QString logo_link = root_element.namedItem(QSL("logo")).toElement().text();
+ QString home_page = root_element.namedItem(QSL("link")).toElement().attribute(QSL("href"));
- if (!logo_link.isEmpty()) {
- icon_possible_locations.prepend(logo_link);
- }
-
- QString source_link = root_element.namedItem(QSL("link")).toElement().text();
-
- if (!source_link.isEmpty()) {
- icon_possible_locations.prepend(source_link);
+ if (!home_page.isEmpty()) {
+ icon_possible_locations.prepend({ home_page, false });
}
}
else {