2 * This file Copyright (C) 2012-2014 Mnemosyne LLC
4 * It may be used under the GNU Public License v2 or v3 licenses,
5 * or any future license endorsed by Mnemosyne LLC.
7 * $Id: favicon.cc 14225 2014-01-19 01:09:44Z jordan $
11 #include <QNetworkAccessManager>
12 #include <QNetworkReply>
13 #include <QNetworkRequest>
15 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
16 #include <QDesktopServices>
18 #include <QStandardPaths>
27 Favicons :: Favicons ()
29 myNAM
= new QNetworkAccessManager ();
30 connect (myNAM
, SIGNAL(finished(QNetworkReply
*)), this, SLOT(onRequestFinished(QNetworkReply
*)));
33 Favicons :: ~Favicons ()
43 Favicons :: getCacheDir ()
46 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
47 QDesktopServices::storageLocation (QDesktopServices::CacheLocation
);
49 QStandardPaths::writableLocation (QStandardPaths::CacheLocation
);
52 return QDir(base
).absoluteFilePath ("favicons");
56 Favicons :: ensureCacheDirHasBeenScanned ()
58 static bool hasBeenScanned
= false;
62 hasBeenScanned
= true;
64 QDir
cacheDir (getCacheDir ());
65 cacheDir
.mkpath (cacheDir
.absolutePath ());
67 QStringList files
= cacheDir
.entryList (QDir::Files
|QDir::Readable
);
68 foreach (QString file
, files
)
71 pixmap
.load (cacheDir
.absoluteFilePath (file
));
72 if (!pixmap
.isNull ())
73 myPixmaps
.insert (file
, pixmap
);
79 Favicons :: getHost (const QUrl
& url
)
81 QString host
= url
.host ();
82 const int first_dot
= host
.indexOf ('.');
83 const int last_dot
= host
.lastIndexOf ('.');
85 if ((first_dot
!= -1) && (last_dot
!= -1) && (first_dot
!= last_dot
))
86 host
.remove (0, first_dot
+ 1);
92 Favicons :: find (const QUrl
& url
)
94 return findFromHost (getHost (url
));
99 const QSize
rightSize (16, 16);
103 Favicons :: findFromHost (const QString
& host
)
105 ensureCacheDirHasBeenScanned ();
107 const QPixmap pixmap
= myPixmaps
[ host
];
108 return pixmap
.size()==rightSize
? pixmap
: pixmap
.scaled(rightSize
);
112 Favicons :: add (const QUrl
& url
)
114 ensureCacheDirHasBeenScanned ();
116 const QString host
= getHost (url
);
118 if (!myPixmaps
.contains (host
))
120 // add a placholder s.t. we only ping the server once per session
121 QPixmap
tmp (rightSize
);
122 tmp
.fill (Qt::transparent
);
123 myPixmaps
.insert (host
, tmp
);
125 // try to download the favicon
126 const QString path
= "http://" + host
+ "/favicon.";
127 QStringList suffixes
;
128 suffixes
<< "ico" << "png" << "gif" << "jpg";
129 foreach (QString suffix
, suffixes
)
130 myNAM
->get (QNetworkRequest (path
+ suffix
));
135 Favicons :: onRequestFinished (QNetworkReply
* reply
)
137 const QString host
= reply
->url().host();
141 const QByteArray content
= reply
->readAll ();
142 if (!reply
->error ())
143 pixmap
.loadFromData (content
);
145 if (!pixmap
.isNull ())
147 // save it in memory...
148 myPixmaps
.insert (host
, pixmap
);
150 // save it on disk...
151 QDir
cacheDir (getCacheDir ());
152 cacheDir
.mkpath (cacheDir
.absolutePath ());
153 QFile
file (cacheDir
.absoluteFilePath (host
));
154 file
.open (QIODevice::WriteOnly
);
155 file
.write (content
);
159 emit
pixmapReady (host
);