source: trunk/qt/favicon.cc @ 14204

Last change on this file since 14204 was 14204, checked in by jordan, 9 years ago

copyediting: indentation cleanups

  • Property svn:keywords set to Date Rev Author Id
File size: 3.5 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
9 *
10 * $Id: favicon.cc 14204 2013-09-14 22:45:04Z jordan $
11 */
12
13#include <QDir>
14#include <QNetworkAccessManager>
15#include <QNetworkReply>
16#include <QNetworkRequest>
17
18#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
19 #include <QDesktopServices>
20#else
21 #include <QStandardPaths>
22#endif
23
24#include "favicon.h"
25
26/***
27****
28***/
29
30Favicons :: Favicons ()
31{
32  myNAM = new QNetworkAccessManager ();
33  connect (myNAM, SIGNAL(finished(QNetworkReply*)), this, SLOT(onRequestFinished(QNetworkReply*)));
34}
35
36Favicons :: ~Favicons ()
37{
38  delete myNAM;
39}
40
41/***
42****
43***/
44
45QString
46Favicons :: getCacheDir ()
47{
48  const QString base =
49#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
50    QDesktopServices::storageLocation (QDesktopServices::CacheLocation);
51#else
52    QStandardPaths::writableLocation (QStandardPaths::CacheLocation);
53#endif
54
55  return QDir(base).absoluteFilePath ("favicons");
56}
57
58void
59Favicons :: ensureCacheDirHasBeenScanned ()
60{
61  static bool hasBeenScanned = false;
62
63  if (!hasBeenScanned)
64    {
65      hasBeenScanned = true;
66
67      QDir cacheDir (getCacheDir ());
68      cacheDir.mkpath (cacheDir.absolutePath ());
69
70      QStringList files = cacheDir.entryList (QDir::Files|QDir::Readable);
71      foreach (QString file, files)
72        {
73          QPixmap pixmap;
74          pixmap.load (cacheDir.absoluteFilePath (file));
75          if (!pixmap.isNull ())
76            myPixmaps.insert (file, pixmap);
77        }
78    }
79}
80
81QString
82Favicons :: getHost (const QUrl& url)
83{
84  QString host = url.host ();
85  const int first_dot = host.indexOf ('.');
86  const int last_dot = host.lastIndexOf ('.');
87
88  if ((first_dot != -1) && (last_dot != -1) &&  (first_dot != last_dot))
89    host.remove (0, first_dot + 1);
90
91  return host;
92}
93
94QPixmap
95Favicons :: find (const QUrl& url)
96{
97  return findFromHost (getHost (url));
98}
99
100namespace
101{
102  const QSize rightSize (16, 16);
103};
104
105QPixmap
106Favicons :: findFromHost (const QString& host)
107{
108  ensureCacheDirHasBeenScanned ();
109
110  const QPixmap pixmap = myPixmaps[ host ];
111  return pixmap.size()==rightSize ? pixmap : pixmap.scaled(rightSize);
112}
113
114void
115Favicons :: add (const QUrl& url)
116{
117  ensureCacheDirHasBeenScanned ();
118
119  const QString host = getHost (url);
120
121  if (!myPixmaps.contains (host))
122    {
123      // add a placholder s.t. we only ping the server once per session
124      QPixmap tmp (rightSize);
125      tmp.fill (Qt::transparent);
126      myPixmaps.insert (host, tmp);
127
128      // try to download the favicon
129      const QString path = "http://" + host + "/favicon.";
130      QStringList suffixes;
131      suffixes << "ico" << "png" << "gif" << "jpg";
132      foreach (QString suffix, suffixes)
133        myNAM->get (QNetworkRequest (path + suffix));
134    }
135}
136
137void
138Favicons :: onRequestFinished (QNetworkReply * reply)
139{
140  const QString host = reply->url().host();
141
142  QPixmap pixmap;
143
144  const QByteArray content = reply->readAll ();
145  if (!reply->error ())
146    pixmap.loadFromData (content);
147
148  if (!pixmap.isNull ())
149    {
150      // save it in memory...
151      myPixmaps.insert (host, pixmap);
152
153      // save it on disk...
154      QDir cacheDir (getCacheDir ());
155      cacheDir.mkpath (cacheDir.absolutePath ());
156      QFile file (cacheDir.absoluteFilePath (host));
157      file.open (QIODevice::WriteOnly);
158      file.write (content);
159      file.close ();
160
161      // notify listeners
162      emit pixmapReady (host);
163    }
164}
Note: See TracBrowser for help on using the repository browser.