mirror of
https://github.com/transmission/transmission
synced 2024-12-23 08:13:27 +00:00
d7930984ef
There're places where manual intervention is still required as uncrustify is not ideal (unfortunately), but at least one may rely on it to do the right thing most of the time (e.g. when sending in a patch). The style itself is quite different from what we had before but making it uniform across all the codebase is the key. I also hope that it'll make the code more readable (YMMV) and less sensitive to further changes.
152 lines
3.3 KiB
C++
152 lines
3.3 KiB
C++
/*
|
|
* This file Copyright (C) 2012-2015 Mnemosyne LLC
|
|
*
|
|
* It may be used under the GNU GPL versions 2 or 3
|
|
* or any future license endorsed by Mnemosyne LLC.
|
|
*
|
|
*/
|
|
|
|
#include <QDir>
|
|
#include <QNetworkAccessManager>
|
|
#include <QNetworkReply>
|
|
#include <QNetworkRequest>
|
|
#include <QStandardPaths>
|
|
|
|
#include "FaviconCache.h"
|
|
|
|
/***
|
|
****
|
|
***/
|
|
|
|
FaviconCache::FaviconCache()
|
|
{
|
|
myNAM = new QNetworkAccessManager();
|
|
connect(myNAM, SIGNAL(finished(QNetworkReply*)), this, SLOT(onRequestFinished(QNetworkReply*)));
|
|
}
|
|
|
|
FaviconCache::~FaviconCache()
|
|
{
|
|
delete myNAM;
|
|
}
|
|
|
|
/***
|
|
****
|
|
***/
|
|
|
|
QString FaviconCache::getCacheDir()
|
|
{
|
|
const QString base = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
|
|
|
return QDir(base).absoluteFilePath(QLatin1String("favicons"));
|
|
}
|
|
|
|
void FaviconCache::ensureCacheDirHasBeenScanned()
|
|
{
|
|
static bool hasBeenScanned = false;
|
|
|
|
if (!hasBeenScanned)
|
|
{
|
|
hasBeenScanned = true;
|
|
|
|
QDir cacheDir(getCacheDir());
|
|
cacheDir.mkpath(cacheDir.absolutePath());
|
|
|
|
QStringList files = cacheDir.entryList(QDir::Files | QDir::Readable);
|
|
|
|
for (const QString& file : files)
|
|
{
|
|
QPixmap pixmap;
|
|
pixmap.load(cacheDir.absoluteFilePath(file));
|
|
|
|
if (!pixmap.isNull())
|
|
{
|
|
myPixmaps.insert(file, pixmap);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
QString FaviconCache::getHost(const QUrl& url)
|
|
{
|
|
QString host = url.host();
|
|
const int first_dot = host.indexOf(QLatin1Char('.'));
|
|
const int last_dot = host.lastIndexOf(QLatin1Char('.'));
|
|
|
|
if ((first_dot != -1) && (last_dot != -1) && (first_dot != last_dot))
|
|
{
|
|
host.remove(0, first_dot + 1);
|
|
}
|
|
|
|
return host;
|
|
}
|
|
|
|
QSize FaviconCache::getIconSize()
|
|
{
|
|
return QSize(16, 16);
|
|
}
|
|
|
|
QPixmap FaviconCache::find(const QUrl& url)
|
|
{
|
|
return findFromHost(getHost(url));
|
|
}
|
|
|
|
QPixmap FaviconCache::findFromHost(const QString& host)
|
|
{
|
|
ensureCacheDirHasBeenScanned();
|
|
|
|
return myPixmaps[host];
|
|
}
|
|
|
|
void FaviconCache::add(const QUrl& url)
|
|
{
|
|
ensureCacheDirHasBeenScanned();
|
|
|
|
const QString host = getHost(url);
|
|
|
|
if (!myPixmaps.contains(host))
|
|
{
|
|
// add a placholder s.t. we only ping the server once per session
|
|
myPixmaps.insert(host, QPixmap());
|
|
|
|
// try to download the favicon
|
|
const QString path = QLatin1String("http://") + host + QLatin1String("/favicon.");
|
|
QStringList suffixes;
|
|
suffixes << QLatin1String("ico") << QLatin1String("png") << QLatin1String("gif") << QLatin1String("jpg");
|
|
|
|
for (const QString& suffix : suffixes)
|
|
{
|
|
myNAM->get(QNetworkRequest(path + suffix));
|
|
}
|
|
}
|
|
}
|
|
|
|
void FaviconCache::onRequestFinished(QNetworkReply* reply)
|
|
{
|
|
const QString host = reply->url().host();
|
|
|
|
QPixmap pixmap;
|
|
|
|
const QByteArray content = reply->readAll();
|
|
|
|
if (!reply->error())
|
|
{
|
|
pixmap.loadFromData(content);
|
|
}
|
|
|
|
if (!pixmap.isNull())
|
|
{
|
|
// save it in memory...
|
|
myPixmaps.insert(host, pixmap);
|
|
|
|
// save it on disk...
|
|
QDir cacheDir(getCacheDir());
|
|
cacheDir.mkpath(cacheDir.absolutePath());
|
|
QFile file(cacheDir.absoluteFilePath(host));
|
|
file.open(QIODevice::WriteOnly);
|
|
file.write(content);
|
|
file.close();
|
|
|
|
// notify listeners
|
|
emit pixmapReady(host);
|
|
}
|
|
}
|