Final fix for #363.

This commit is contained in:
Martin Rotter 2021-03-02 08:33:49 +01:00
parent 56e723572e
commit 26027d15e4
7 changed files with 85 additions and 73 deletions

View File

@ -30,7 +30,7 @@
<url type="donation">https://martinrotter.github.io/donate/</url>
<content_rating type="oars-1.1" />
<releases>
<release version="3.9.0" date="2021-02-24"/>
<release version="3.9.0" date="2021-03-02"/>
</releases>
<content_rating type="oars-1.0">
<content_attribute id="violence-cartoon">none</content_attribute>

View File

@ -137,66 +137,71 @@ QString NetworkFactory::networkErrorText(QNetworkReply::NetworkError error_code)
}
}
QNetworkReply::NetworkError NetworkFactory::downloadIcon(const QList<QString>& urls, int timeout,
QNetworkReply::NetworkError NetworkFactory::downloadIcon(const QList<QPair<QString, bool>>& 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;
}
}
}
}

View File

@ -31,7 +31,7 @@ class NetworkFactory {
// Performs SYNCHRONOUS download if favicon for the site,
// given URL belongs to.
static QNetworkReply::NetworkError downloadIcon(const QList<QString>& urls,
static QNetworkReply::NetworkError downloadIcon(const QList<QPair<QString, bool>>& urls,
int timeout,
QIcon& output,
const QNetworkProxy& custom_proxy = QNetworkProxy::ProxyType::DefaultProxy);

View File

@ -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/"

View File

@ -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);

View File

@ -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) {

View File

@ -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<QString> 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<QPair<QString, bool>> 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 {