source: trunk/gtk/favicon.c @ 10382

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

(trunk gtk) small filter/favicon code cleanups

File size: 3.8 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 <glib/gstdio.h> /* g_remove() */
14#include <gtk/gtk.h>
15
16#include <libtransmission/transmission.h>
17#include <libtransmission/web.h> /* tr_webRun() */
18
19#include "favicon.h"
20#include "util.h" /* gtr_mkdir_with_parents(), gtr_idle_add() */
21
22struct favicon_data
23{
24    GFunc func;
25    gpointer data;
26    char * host;
27    char * contents;
28    size_t len;
29};
30
31static char*
32favicon_get_cache_dir( void )
33{
34    static char * dir = NULL;
35
36    if( dir == NULL )
37    {
38        dir = g_build_filename( g_get_user_cache_dir(),
39                                "transmission",
40                                "favicons",
41                                NULL );
42        gtr_mkdir_with_parents( dir, 0777 );
43    }
44
45    return dir;
46}
47
48static char*
49favicon_get_cache_filename( const char * host )
50{
51    return g_build_filename( favicon_get_cache_dir(), host, NULL );
52}
53
54static void
55favicon_save_cache_file( const char * host, const void * data, size_t len )
56{
57    char * filename = favicon_get_cache_filename( host );
58    g_file_set_contents( filename, data, len, NULL );
59    g_free( filename );
60}
61
62static GdkPixbuf*
63favicon_load_from_data( const void * data, size_t len )
64{
65    GdkPixbuf * pixbuf = NULL;
66
67    if( len > 0 )
68    {
69        GInputStream * i = g_memory_input_stream_new_from_data( data, len, NULL );
70        pixbuf = gdk_pixbuf_new_from_stream_at_scale( i, 16, 16, TRUE, NULL, NULL );
71        g_object_unref( i );
72    }
73
74    return pixbuf;
75}
76
77static gboolean
78favicon_web_done_idle_cb( gpointer vfav )
79{
80    struct favicon_data * fav = vfav;
81    GdkPixbuf * pixbuf = favicon_load_from_data( fav->contents, fav->len );
82
83    if( pixbuf != NULL )
84        favicon_save_cache_file( fav->host, fav->contents, fav->len );
85
86    fav->func( pixbuf, fav->data );
87
88    g_free( fav->host );
89    g_free( fav->contents );
90    g_free( fav );
91    return FALSE;
92}
93
94static void
95favicon_web_done_cb( tr_session    * session UNUSED,
96                     long            code UNUSED,
97                     const void    * data,
98                     size_t          len,
99                     void          * vfav )
100{
101    struct favicon_data * fav = vfav;
102    fav->contents = g_memdup( data, len );
103    fav->len = len;
104
105    gtr_idle_add( favicon_web_done_idle_cb, fav );
106}
107   
108static GdkPixbuf*
109favicon_load_from_file( const char * host )
110{
111    gsize len;
112    char * data;
113    char * path = favicon_get_cache_filename( host );
114    GdkPixbuf * pixbuf = NULL;
115
116    if( g_file_get_contents( path, &data, &len, NULL ) )
117    {
118        pixbuf = favicon_load_from_data( data, len );
119        if( pixbuf == NULL ) /* bad file... delete it from the cache */
120            g_remove( path );
121        g_free( data );
122    }
123
124    g_free( path );
125    return pixbuf;
126}
127   
128void
129gtr_get_favicon( tr_session  * session,
130                 const char  * host, 
131                 GFunc         pixbuf_ready_func, 
132                 gpointer      pixbuf_ready_func_data )
133{
134    GdkPixbuf * pixbuf = favicon_load_from_file( host );
135
136    if( pixbuf != NULL )
137    {
138        pixbuf_ready_func( pixbuf, pixbuf_ready_func_data );
139    }
140    else
141    {
142        struct favicon_data * data;
143        char * url = g_strdup_printf( "http://%s/favicon.ico", host );
144
145        g_debug( "trying favicon from \"%s\"", url );
146        data  = g_new( struct favicon_data, 1 );
147        data->func = pixbuf_ready_func;
148        data->data = pixbuf_ready_func_data;
149        data->host = g_strdup( host );
150        tr_webRun( session, url, NULL, favicon_web_done_cb, data );
151
152        g_free( url );
153    }
154}
Note: See TracBrowser for help on using the repository browser.