2010-07-25 17:16:03 +00:00
|
|
|
/*
|
2015-06-10 21:27:11 +00:00
|
|
|
* This file Copyright (C) 2012-2015 Mnemosyne LLC
|
2010-07-25 17:16:03 +00:00
|
|
|
*
|
2014-12-21 23:49:39 +00:00
|
|
|
* It may be used under the GNU GPL versions 2 or 3
|
2014-01-19 01:09:44 +00:00
|
|
|
* or any future license endorsed by Mnemosyne LLC.
|
2010-07-25 17:16:03 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <QDir>
|
|
|
|
#include <QNetworkAccessManager>
|
|
|
|
#include <QNetworkReply>
|
|
|
|
#include <QNetworkRequest>
|
2017-02-11 10:44:34 +00:00
|
|
|
#include <QStandardPaths>
|
2010-07-25 17:16:03 +00:00
|
|
|
|
2015-06-10 21:27:11 +00:00
|
|
|
#include "FaviconCache.h"
|
2010-07-25 17:16:03 +00:00
|
|
|
|
|
|
|
/***
|
|
|
|
****
|
|
|
|
***/
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
FaviconCache::FaviconCache()
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
myNAM = new QNetworkAccessManager();
|
|
|
|
connect(myNAM, SIGNAL(finished(QNetworkReply*)), this, SLOT(onRequestFinished(QNetworkReply*)));
|
2010-07-25 17:16:03 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
FaviconCache::~FaviconCache()
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
delete myNAM;
|
2010-07-25 17:16:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
|
|
****
|
|
|
|
***/
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
QString FaviconCache::getCacheDir()
|
2010-07-25 17:42:43 +00:00
|
|
|
{
|
2017-04-20 16:02:19 +00:00
|
|
|
QString const base = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
2013-08-17 16:22:56 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
return QDir(base).absoluteFilePath(QLatin1String("favicons"));
|
2010-07-25 17:42:43 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
void FaviconCache::ensureCacheDirHasBeenScanned()
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
static bool hasBeenScanned = false;
|
2010-07-25 17:16:03 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
if (!hasBeenScanned)
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
hasBeenScanned = true;
|
2013-09-14 22:45:04 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
QDir cacheDir(getCacheDir());
|
|
|
|
cacheDir.mkpath(cacheDir.absolutePath());
|
2013-09-14 22:45:04 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
QStringList files = cacheDir.entryList(QDir::Files | QDir::Readable);
|
|
|
|
|
2017-04-20 16:02:19 +00:00
|
|
|
for (QString const& file : files)
|
2013-09-14 22:45:04 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
QPixmap pixmap;
|
|
|
|
pixmap.load(cacheDir.absoluteFilePath(file));
|
|
|
|
|
|
|
|
if (!pixmap.isNull())
|
|
|
|
{
|
|
|
|
myPixmaps.insert(file, pixmap);
|
|
|
|
}
|
2010-07-25 17:16:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-20 16:02:19 +00:00
|
|
|
QString FaviconCache::getHost(QUrl const& url)
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
QString host = url.host();
|
2017-04-20 16:02:19 +00:00
|
|
|
int const first_dot = host.indexOf(QLatin1Char('.'));
|
|
|
|
int const last_dot = host.lastIndexOf(QLatin1Char('.'));
|
2010-07-25 17:16:03 +00:00
|
|
|
|
2017-04-30 16:25:26 +00:00
|
|
|
if (first_dot != -1 && last_dot != -1 && first_dot != last_dot)
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
|
|
|
host.remove(0, first_dot + 1);
|
|
|
|
}
|
2010-07-25 17:16:03 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
return host;
|
2010-07-25 17:16:03 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
QSize FaviconCache::getIconSize()
|
2015-01-20 23:28:38 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
return QSize(16, 16);
|
2015-01-20 23:28:38 +00:00
|
|
|
}
|
|
|
|
|
2017-04-20 16:02:19 +00:00
|
|
|
QPixmap FaviconCache::find(QUrl const& url)
|
2010-07-30 22:23:47 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
return findFromHost(getHost(url));
|
2010-07-30 22:23:47 +00:00
|
|
|
}
|
|
|
|
|
2017-04-20 16:02:19 +00:00
|
|
|
QPixmap FaviconCache::findFromHost(QString const& host)
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
ensureCacheDirHasBeenScanned();
|
2010-07-25 17:16:03 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
return myPixmaps[host];
|
2010-07-25 17:16:03 +00:00
|
|
|
}
|
|
|
|
|
2017-04-20 16:02:19 +00:00
|
|
|
void FaviconCache::add(QUrl const& url)
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
ensureCacheDirHasBeenScanned();
|
2010-07-25 17:16:03 +00:00
|
|
|
|
2017-04-20 16:02:19 +00:00
|
|
|
QString const host = getHost(url);
|
2010-07-25 20:38:44 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
if (!myPixmaps.contains(host))
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
// add a placholder s.t. we only ping the server once per session
|
|
|
|
myPixmaps.insert(host, QPixmap());
|
|
|
|
|
|
|
|
// try to download the favicon
|
2017-04-20 16:02:19 +00:00
|
|
|
QString const path = QLatin1String("http://") + host + QLatin1String("/favicon.");
|
2017-04-19 12:04:45 +00:00
|
|
|
QStringList suffixes;
|
|
|
|
suffixes << QLatin1String("ico") << QLatin1String("png") << QLatin1String("gif") << QLatin1String("jpg");
|
|
|
|
|
2017-04-20 16:02:19 +00:00
|
|
|
for (QString const& suffix : suffixes)
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
|
|
|
myNAM->get(QNetworkRequest(path + suffix));
|
|
|
|
}
|
2010-07-25 17:16:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
void FaviconCache::onRequestFinished(QNetworkReply* reply)
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-20 16:02:19 +00:00
|
|
|
QString const host = reply->url().host();
|
2017-04-19 12:04:45 +00:00
|
|
|
|
|
|
|
QPixmap pixmap;
|
2010-07-25 17:16:03 +00:00
|
|
|
|
2017-04-20 16:02:19 +00:00
|
|
|
QByteArray const content = reply->readAll();
|
2010-07-25 17:16:03 +00:00
|
|
|
|
2017-04-30 16:25:26 +00:00
|
|
|
if (reply->error() == QNetworkReply::NoError)
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
|
|
|
pixmap.loadFromData(content);
|
|
|
|
}
|
2010-07-25 17:16:03 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
if (!pixmap.isNull())
|
2010-07-25 17:16:03 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +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);
|
2010-07-25 17:16:03 +00:00
|
|
|
}
|
|
|
|
}
|