source: trunk/qt/favicon.cc @ 11052

Last change on this file since 11052 was 11052, checked in by charles, 12 years ago

(trunk qt) add code for a favicon cache -- it even shares the GTK+ client's favicon cache directory. :) This isn't plugged in anywhere yet, but will be useful when the filterbar and trackers tab are synced with the GTK+ client.

File size: 3.2 KB
Line 
1/*
2 * This file Copyright (C) 2010 Mnemosyne LLC
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id$
11 */
12
13#include <iostream>
14
15#include <QDesktopServices>
16#include <QDir>
17#include <QNetworkAccessManager>
18#include <QNetworkReply>
19#include <QNetworkRequest>
20
21#include "favicon.h"
22
23/***
24****
25***/
26
27QString
28Favicons :: getCacheDir( )
29{
30    const QString base = QDesktopServices::storageLocation( QDesktopServices::CacheLocation );
31    return QDir( base ).absoluteFilePath( "favicons" );
32};
33
34
35Favicons :: Favicons( )
36{
37    myNAM = new QNetworkAccessManager( );
38    connect( myNAM, SIGNAL(finished(QNetworkReply*)), this, SLOT(onRequestFinished(QNetworkReply*)) );
39}
40
41Favicons :: ~Favicons( )
42{
43    delete myNAM;
44}
45
46/***
47****
48***/
49
50void
51Favicons :: ensureCacheDirHasBeenScanned( )
52{
53    static bool hasBeenScanned = false;
54
55    if( !hasBeenScanned )
56    {
57        hasBeenScanned = true;
58   
59        QDir cacheDir( getCacheDir( ) );
60        cacheDir.mkpath( cacheDir.absolutePath( ) );
61        QStringList files = cacheDir.entryList( QDir::Files|QDir::Readable );
62        foreach( QString file, files ) {
63            QPixmap pixmap;
64            pixmap.load( cacheDir.absoluteFilePath( file ) );
65            if( !pixmap.isNull( ) )
66                myPixmaps.insert( file, pixmap );
67        }
68    }
69}
70
71QString
72Favicons :: getHost( const QUrl& url )
73{
74    QString host = url.host( );
75    const int first_dot = host.indexOf( '.' );
76    const int last_dot = host.lastIndexOf( '.' );
77
78    if( ( first_dot != -1 ) && ( last_dot != -1 ) && ( first_dot != last_dot ) )
79        host.remove( 0, first_dot + 1 );
80
81    return host;
82}
83
84QPixmap
85Favicons :: find( const QUrl& url )
86{
87    ensureCacheDirHasBeenScanned( );
88
89    return myPixmaps[ getHost(url) ];
90}
91
92void
93Favicons :: add( const QUrl& url_in )
94{
95    ensureCacheDirHasBeenScanned( );
96
97    const QString host = getHost(url_in);
98    if( !myPixmaps.contains(host) && !myPending.contains(host) )
99    {
100        const int IMAGE_TYPES = 4;
101        const QString image_types[IMAGE_TYPES] = { "ico", "png", "gif", "jpg" };
102
103        myPending.append( host ); 
104        for( int i=0; i<IMAGE_TYPES; ++i )
105        {
106            QString url( "http://" + host + "/favicon." + image_types[i]);
107            myNAM->get( QNetworkRequest( url ) );
108        }
109    }
110}
111
112void
113Favicons :: onRequestFinished( QNetworkReply * reply )
114{
115    const QString host = reply->url().host();
116
117    myPending.removeAll( host );
118
119    const QByteArray content = reply->readAll( );
120
121    QPixmap pixmap;
122
123    if( !reply->error( ) )
124        pixmap.loadFromData( content );
125
126    if( !pixmap.isNull( ) )
127    {
128        // save it in memory...
129        myPixmaps.insert( host, pixmap );
130
131        // save it on disk...
132        QDir cacheDir( getCacheDir( ) );
133        cacheDir.mkpath( cacheDir.absolutePath( ) );
134        QFile file( cacheDir.absoluteFilePath( host ) );
135        file.open( QIODevice::WriteOnly );
136        file.write( content );
137        file.close( );
138
139        // notify listeners
140        emit pixmapReady( host );
141    }
142}
Note: See TracBrowser for help on using the repository browser.