Transmission: update to 2.82
[tomato.git] / release / src / router / transmission / gtk / favicon.c
blob71522107df4fa94b85409f22b6d5e793a1da796c
1 /*
2 * This file Copyright (C) Mnemosyne LLC
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.
10 * $Id: favicon.c 14133 2013-07-20 16:37:59Z jordan $
13 #include <glib/gstdio.h> /* g_remove () */
14 #include <gtk/gtk.h>
16 #include <libtransmission/transmission.h>
17 #include <libtransmission/web.h> /* tr_webRun () */
19 #include "favicon.h"
20 #include "util.h" /* gtr_get_host_from_url () */
22 #define IMAGE_TYPES 4
23 static const char * image_types[IMAGE_TYPES] = { "ico", "png", "gif", "jpg" };
25 struct favicon_data
27 tr_session * session;
28 GFunc func;
29 gpointer data;
30 char * host;
31 char * contents;
32 size_t len;
33 int type;
36 static char*
37 get_url (const char * host, int image_type)
39 return g_strdup_printf ("http://%s/favicon.%s", host, image_types[image_type]);
42 static char*
43 favicon_get_cache_dir (void)
45 static char * dir = NULL;
47 if (dir == NULL)
49 dir = g_build_filename (g_get_user_cache_dir (),
50 "transmission",
51 "favicons",
52 NULL);
53 g_mkdir_with_parents (dir, 0777);
56 return dir;
59 static char*
60 favicon_get_cache_filename (const char * host)
62 return g_build_filename (favicon_get_cache_dir (), host, NULL);
65 static void
66 favicon_save_to_cache (const char * host, const void * data, size_t len)
68 char * filename = favicon_get_cache_filename (host);
69 g_file_set_contents (filename, data, len, NULL);
70 g_free (filename);
73 static GdkPixbuf*
74 favicon_load_from_cache (const char * host)
76 char * filename = favicon_get_cache_filename (host);
77 GdkPixbuf * pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 16, 16, NULL);
78 if (pixbuf == NULL) /* bad file */
79 g_remove (filename);
80 g_free (filename);
81 return pixbuf;
84 static void favicon_web_done_cb (tr_session*, bool, bool, long, const void*, size_t, void*);
86 static gboolean
87 favicon_web_done_idle_cb (gpointer vfav)
89 GdkPixbuf * pixbuf = NULL;
90 gboolean finished = FALSE;
91 struct favicon_data * fav = vfav;
93 if (fav->len > 0) /* we got something... try to make a pixbuf from it */
95 favicon_save_to_cache (fav->host, fav->contents, fav->len);
96 pixbuf = favicon_load_from_cache (fav->host);
97 finished = pixbuf != NULL;
100 if (!finished) /* no pixbuf yet... */
102 if (++fav->type == IMAGE_TYPES) /* failure */
104 finished = TRUE;
106 else /* keep trying */
108 char * url = get_url (fav->host, fav->type);
110 g_free (fav->contents);
111 fav->contents = NULL;
112 fav->len = 0;
114 tr_webRun (fav->session, url, favicon_web_done_cb, fav);
115 g_free (url);
119 if (finished)
121 fav->func (pixbuf, fav->data);
122 g_free (fav->host);
123 g_free (fav->contents);
124 g_free (fav);
127 return G_SOURCE_REMOVE;
130 static void
131 favicon_web_done_cb (tr_session * session UNUSED,
132 bool did_connect UNUSED,
133 bool did_timeout UNUSED,
134 long code UNUSED,
135 const void * data,
136 size_t len,
137 void * vfav)
139 struct favicon_data * fav = vfav;
140 fav->contents = g_memdup (data, len);
141 fav->len = len;
143 gdk_threads_add_idle (favicon_web_done_idle_cb, fav);
146 void
147 gtr_get_favicon (tr_session * session,
148 const char * host,
149 GFunc pixbuf_ready_func,
150 gpointer pixbuf_ready_func_data)
152 GdkPixbuf * pixbuf = favicon_load_from_cache (host);
154 if (pixbuf != NULL)
156 pixbuf_ready_func (pixbuf, pixbuf_ready_func_data);
158 else
160 struct favicon_data * data;
161 char * url = get_url (host, 0);
163 data = g_new (struct favicon_data, 1);
164 data->session = session;
165 data->func = pixbuf_ready_func;
166 data->data = pixbuf_ready_func_data;
167 data->host = g_strdup (host);
168 data->type = 0;
170 tr_webRun (session, url, favicon_web_done_cb, data);
171 g_free (url);
175 void
176 gtr_get_favicon_from_url (tr_session * session,
177 const char * url,
178 GFunc pixbuf_ready_func,
179 gpointer pixbuf_ready_func_data)
181 char host[1024];
182 gtr_get_host_from_url (host, sizeof (host), url);
183 gtr_get_favicon (session, host, pixbuf_ready_func, pixbuf_ready_func_data);