Use previous approach of deducing favicon URL

PR #19325.
Fixes regression of #19062.
Closes #19307.
This commit is contained in:
Vladimir Golovnev 2023-07-17 08:11:07 +03:00 committed by GitHub
parent 7b4b7c2b81
commit 57085ca126
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 36 deletions

View file

@ -72,6 +72,14 @@ namespace
return host; return host;
} }
QString getFaviconHost(const QString &trackerHost)
{
if (!QHostAddress(trackerHost).isNull())
return trackerHost;
return trackerHost.section(u'.', -2, -1);
}
const QString NULL_HOST = u""_s; const QString NULL_HOST = u""_s;
} }
@ -190,7 +198,7 @@ void TrackersFilterWidget::addItems(const QString &trackerURL, const QVector<Bit
trackersIt = m_trackers.insert(host, trackerData); trackersIt = m_trackers.insert(host, trackerData);
const QString scheme = getScheme(trackerURL); const QString scheme = getScheme(trackerURL);
downloadFavicon(u"%1://%2/favicon.ico"_s.arg((scheme.startsWith(u"http") ? scheme : u"http"_s), host)); downloadFavicon(host, u"%1://%2/favicon.ico"_s.arg((scheme.startsWith(u"http") ? scheme : u"http"_s), getFaviconHost(host)));
} }
Q_ASSERT(trackerItem); Q_ASSERT(trackerItem);
@ -302,8 +310,8 @@ void TrackersFilterWidget::setDownloadTrackerFavicon(bool value)
if (!tracker.isEmpty()) if (!tracker.isEmpty())
{ {
const QString scheme = getScheme(tracker); const QString scheme = getScheme(tracker);
downloadFavicon(u"%1://%2/favicon.ico"_s downloadFavicon(tracker, u"%1://%2/favicon.ico"_s
.arg((scheme.startsWith(u"http") ? scheme : u"http"_s), getHost(tracker))); .arg((scheme.startsWith(u"http") ? scheme : u"http"_s), getFaviconHost(tracker)));
} }
} }
} }
@ -364,51 +372,85 @@ void TrackersFilterWidget::handleTrackerEntriesUpdated(const BitTorrent::Torrent
applyFilter(WARNING_ROW); applyFilter(WARNING_ROW);
} }
void TrackersFilterWidget::downloadFavicon(const QString &url) void TrackersFilterWidget::downloadFavicon(const QString &trackerHost, const QString &faviconURL)
{
if (!m_downloadTrackerFavicon)
return;
QSet<QString> &downloadingFaviconNode = m_downloadingFavicons[faviconURL];
if (downloadingFaviconNode.isEmpty())
{ {
if (!m_downloadTrackerFavicon) return;
Net::DownloadManager::instance()->download( Net::DownloadManager::instance()->download(
Net::DownloadRequest(url).saveToFile(true), Preferences::instance()->useProxyForGeneralPurposes() Net::DownloadRequest(faviconURL).saveToFile(true), Preferences::instance()->useProxyForGeneralPurposes()
, this, &TrackersFilterWidget::handleFavicoDownloadFinished); , this, &TrackersFilterWidget::handleFavicoDownloadFinished);
} }
downloadingFaviconNode.insert(trackerHost);
}
void TrackersFilterWidget::handleFavicoDownloadFinished(const Net::DownloadResult &result) void TrackersFilterWidget::handleFavicoDownloadFinished(const Net::DownloadResult &result)
{ {
const QSet<QString> trackerHosts = m_downloadingFavicons.take(result.url);
Q_ASSERT(!trackerHosts.isEmpty());
if (Q_UNLIKELY(trackerHosts.isEmpty()))
return;
QIcon icon;
bool failed = false;
if (result.status != Net::DownloadStatus::Success) if (result.status != Net::DownloadStatus::Success)
{ {
if (result.url.endsWith(u".ico", Qt::CaseInsensitive)) failed = true;
downloadFavicon(result.url.left(result.url.size() - 4) + u".png");
return;
}
const QString host = getHost(result.url);
if (!m_trackers.contains(host))
{
Utils::Fs::removeFile(result.filePath);
return;
}
QListWidgetItem *trackerItem = item(rowFromTracker(host));
if (!trackerItem) return;
const QIcon icon {result.filePath.data()};
//Detect a non-decodable icon
QList<QSize> sizes = icon.availableSizes();
bool invalid = (sizes.isEmpty() || icon.pixmap(sizes.first()).isNull());
if (invalid)
{
if (result.url.endsWith(u".ico", Qt::CaseInsensitive))
downloadFavicon(result.url.left(result.url.size() - 4) + u".png");
Utils::Fs::removeFile(result.filePath);
} }
else else
{ {
trackerItem->setData(Qt::DecorationRole, QIcon(result.filePath.data())); icon = QIcon(result.filePath.data());
m_iconPaths.append(result.filePath); //Detect a non-decodable icon
QList<QSize> sizes = icon.availableSizes();
const bool invalid = (sizes.isEmpty() || icon.pixmap(sizes.first()).isNull());
if (invalid)
{
Utils::Fs::removeFile(result.filePath);
failed = true;
} }
} }
if (failed)
{
if (result.url.endsWith(u".ico", Qt::CaseInsensitive))
{
const QString faviconURL = result.url.left(result.url.size() - 4) + u".png";
for (const auto &trackerHost : trackerHosts)
{
if (m_trackers.contains(trackerHost))
downloadFavicon(trackerHost, faviconURL);
}
}
return;
}
bool matchedTrackerFound = false;
for (const auto &trackerHost : trackerHosts)
{
if (!m_trackers.contains(trackerHost))
continue;
matchedTrackerFound = true;
QListWidgetItem *trackerItem = item(rowFromTracker(trackerHost));
Q_ASSERT(trackerItem);
if (Q_UNLIKELY(!trackerItem))
continue;
trackerItem->setData(Qt::DecorationRole, icon);
}
if (matchedTrackerFound)
m_iconPaths.append(result.filePath);
else
Utils::Fs::removeFile(result.filePath);
}
void TrackersFilterWidget::showMenu() void TrackersFilterWidget::showMenu()
{ {
QMenu *menu = new QMenu(this); QMenu *menu = new QMenu(this);

View file

@ -76,7 +76,7 @@ private:
QString trackerFromRow(int row) const; QString trackerFromRow(int row) const;
int rowFromTracker(const QString &tracker) const; int rowFromTracker(const QString &tracker) const;
QSet<BitTorrent::TorrentID> getTorrentIDs(int row) const; QSet<BitTorrent::TorrentID> getTorrentIDs(int row) const;
void downloadFavicon(const QString &url); void downloadFavicon(const QString &trackerHost, const QString &faviconURL);
struct TrackerData struct TrackerData
{ {
@ -90,4 +90,5 @@ private:
PathList m_iconPaths; PathList m_iconPaths;
int m_totalTorrents = 0; int m_totalTorrents = 0;
bool m_downloadTrackerFavicon = false; bool m_downloadTrackerFavicon = false;
QHash<QString, QSet<QString>> m_downloadingFavicons; // <favicon URL, tracker hosts>
}; };