transmission/qt/FaviconCache.cc

159 lines
3.4 KiB
C++
Raw Normal View History

/*
* 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>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QDesktopServices>
#else
#include <QStandardPaths>
#endif
#include "FaviconCache.h"
/***
****
***/
FaviconCache::FaviconCache ()
{
2013-09-14 22:45:04 +00:00
myNAM = new QNetworkAccessManager ();
connect (myNAM, SIGNAL(finished(QNetworkReply*)), this, SLOT(onRequestFinished(QNetworkReply*)));
}
FaviconCache::~FaviconCache ()
{
2013-09-14 22:45:04 +00:00
delete myNAM;
}
/***
****
***/
QString
FaviconCache::getCacheDir ()
{
2013-09-14 22:45:04 +00:00
const QString base =
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2013-09-14 22:45:04 +00:00
QDesktopServices::storageLocation (QDesktopServices::CacheLocation);
#else
2013-09-14 22:45:04 +00:00
QStandardPaths::writableLocation (QStandardPaths::CacheLocation);
#endif
return QDir(base).absoluteFilePath (QLatin1String ("favicons"));
}
void
FaviconCache::ensureCacheDirHasBeenScanned ()
{
2013-09-14 22:45:04 +00:00
static bool hasBeenScanned = false;
2013-09-14 22:45:04 +00:00
if (!hasBeenScanned)
{
2013-09-14 22:45:04 +00:00
hasBeenScanned = true;
QDir cacheDir (getCacheDir ());
cacheDir.mkpath (cacheDir.absolutePath ());
QStringList files = cacheDir.entryList (QDir::Files|QDir::Readable);
for (const QString& file: files)
2013-09-14 22:45:04 +00:00
{
QPixmap pixmap;
pixmap.load (cacheDir.absoluteFilePath (file));
if (!pixmap.isNull ())
myPixmaps.insert (file, pixmap);
}
}
}
QString
FaviconCache::getHost (const QUrl& url)
{
2013-09-14 22:45:04 +00:00
QString host = url.host ();
const int first_dot = host.indexOf (QLatin1Char ('.'));
const int last_dot = host.lastIndexOf (QLatin1Char ('.'));
2013-09-14 22:45:04 +00:00
if ((first_dot != -1) && (last_dot != -1) && (first_dot != last_dot))
host.remove (0, first_dot + 1);
2013-09-14 22:45:04 +00:00
return host;
}
QSize
FaviconCache::getIconSize ()
{
return QSize (16, 16);
}
QPixmap
FaviconCache::find (const QUrl& url)
{
2013-09-14 22:45:04 +00:00
return findFromHost (getHost (url));
}
QPixmap
FaviconCache::findFromHost (const QString& host)
{
2013-09-14 22:45:04 +00:00
ensureCacheDirHasBeenScanned ();
return myPixmaps[host];
}
void
FaviconCache::add (const QUrl& url)
{
2013-09-14 22:45:04 +00:00
ensureCacheDirHasBeenScanned ();
2013-09-14 22:45:04 +00:00
const QString host = getHost (url);
2013-09-14 22:45:04 +00:00
if (!myPixmaps.contains (host))
{
2013-09-14 22:45:04 +00:00
// add a placholder s.t. we only ping the server once per session
myPixmaps.insert (host, QPixmap ());
2013-09-14 22:45:04 +00:00
// try to download the favicon
const QString path = QLatin1String ("http://") + host + QLatin1String ("/favicon.");
2013-09-14 22:45:04 +00:00
QStringList suffixes;
suffixes << QLatin1String ("ico") << QLatin1String ("png") << QLatin1String ("gif") << QLatin1String ("jpg");
for (const QString& suffix: suffixes)
2013-09-14 22:45:04 +00:00
myNAM->get (QNetworkRequest (path + suffix));
}
}
void
FaviconCache::onRequestFinished (QNetworkReply * reply)
{
2013-09-14 22:45:04 +00:00
const QString host = reply->url().host();
2013-09-14 22:45:04 +00:00
QPixmap pixmap;
2013-09-14 22:45:04 +00:00
const QByteArray content = reply->readAll ();
if (!reply->error ())
pixmap.loadFromData (content);
2013-09-14 22:45:04 +00:00
if (!pixmap.isNull ())
{
2013-09-14 22:45:04 +00:00
// 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);
}
}