2 * This file Copyright (C) Mnemosyne LLC
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.
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10 * $Id: favicon.cc 14150 2013-07-27 21:58:14Z jordan $
14 #include <QNetworkAccessManager>
15 #include <QNetworkReply>
16 #include <QNetworkRequest>
17 #include <QStandardPaths>
25 Favicons :: Favicons( )
27 myNAM
= new QNetworkAccessManager( );
28 connect( myNAM
, SIGNAL(finished(QNetworkReply
*)), this, SLOT(onRequestFinished(QNetworkReply
*)) );
31 Favicons :: ~Favicons( )
41 Favicons :: getCacheDir( )
43 const QString base
= QStandardPaths::writableLocation (QStandardPaths::CacheLocation
);
44 return QDir( base
).absoluteFilePath( "favicons" );
48 Favicons :: ensureCacheDirHasBeenScanned( )
50 static bool hasBeenScanned
= false;
54 hasBeenScanned
= true;
56 QDir
cacheDir( getCacheDir( ) );
57 cacheDir
.mkpath( cacheDir
.absolutePath( ) );
59 QStringList files
= cacheDir
.entryList( QDir::Files
|QDir::Readable
);
60 foreach( QString file
, files
) {
62 pixmap
.load( cacheDir
.absoluteFilePath( file
) );
63 if( !pixmap
.isNull( ) )
64 myPixmaps
.insert( file
, pixmap
);
70 Favicons :: getHost( const QUrl
& url
)
72 QString host
= url
.host( );
73 const int first_dot
= host
.indexOf( '.' );
74 const int last_dot
= host
.lastIndexOf( '.' );
76 if( ( first_dot
!= -1 ) && ( last_dot
!= -1 ) && ( first_dot
!= last_dot
) )
77 host
.remove( 0, first_dot
+ 1 );
83 Favicons :: find( const QUrl
& url
)
85 return findFromHost( getHost( url
) );
90 const QSize
rightSize( 16, 16 );
94 Favicons :: findFromHost( const QString
& host
)
96 ensureCacheDirHasBeenScanned( );
98 const QPixmap pixmap
= myPixmaps
[ host
];
99 return pixmap
.size()==rightSize
? pixmap
: pixmap
.scaled(rightSize
);
103 Favicons :: add( const QUrl
& url
)
105 ensureCacheDirHasBeenScanned( );
107 const QString host
= getHost( url
);
109 if( !myPixmaps
.contains( host
) )
111 // add a placholder s.t. we only ping the server once per session
112 QPixmap
tmp( rightSize
);
113 tmp
.fill( Qt::transparent
);
114 myPixmaps
.insert( host
, tmp
);
116 // try to download the favicon
117 const QString path
= "http://" + host
+ "/favicon.";
118 QStringList suffixes
;
119 suffixes
<< "ico" << "png" << "gif" << "jpg";
120 foreach( QString suffix
, suffixes
)
121 myNAM
->get( QNetworkRequest( path
+ suffix
) );
126 Favicons :: onRequestFinished( QNetworkReply
* reply
)
128 const QString host
= reply
->url().host();
132 const QByteArray content
= reply
->readAll( );
133 if( !reply
->error( ) )
134 pixmap
.loadFromData( content
);
136 if( !pixmap
.isNull( ) )
138 // save it in memory...
139 myPixmaps
.insert( host
, pixmap
);
141 // save it on disk...
142 QDir
cacheDir( getCacheDir( ) );
143 cacheDir
.mkpath( cacheDir
.absolutePath( ) );
144 QFile
file( cacheDir
.absoluteFilePath( host
) );
145 file
.open( QIODevice::WriteOnly
);
146 file
.write( content
);
150 emit
pixmapReady( host
);