aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2002-07-31 13:54:30 +0800
committerMichael Zucci <zucchi@src.gnome.org>2002-07-31 13:54:30 +0800
commit8ff3a3a595a1cd9ae6e9d37be83b0f231e3dc9e5 (patch)
tree613c45f004c3a21d1256357405db5b81411b2e5b
parent8137a35173541e4a5a3ed180b6493f2166d08ac1 (diff)
downloadgsoc2013-evolution-8ff3a3a595a1cd9ae6e9d37be83b0f231e3dc9e5.tar
gsoc2013-evolution-8ff3a3a595a1cd9ae6e9d37be83b0f231e3dc9e5.tar.gz
gsoc2013-evolution-8ff3a3a595a1cd9ae6e9d37be83b0f231e3dc9e5.tar.bz2
gsoc2013-evolution-8ff3a3a595a1cd9ae6e9d37be83b0f231e3dc9e5.tar.lz
gsoc2013-evolution-8ff3a3a595a1cd9ae6e9d37be83b0f231e3dc9e5.tar.xz
gsoc2013-evolution-8ff3a3a595a1cd9ae6e9d37be83b0f231e3dc9e5.tar.zst
gsoc2013-evolution-8ff3a3a595a1cd9ae6e9d37be83b0f231e3dc9e5.zip
Added global cameldatacache for managing remote image cache.
2002-07-31 Not Zed <NotZed@Ximian.com> * mail-display.c: Added global cameldatacache for managing remote image cache. (fetch_remote): Lookup data in cache first, use that if available, or setup a new cache item. (fetch_data): Write any retrieved data to cache as well as html stream. (fetch_free): Unref cache stream. (fetch_done): (fetch_cancel): If failed/cancelled, remove cache items so they dont foul the result. Probably need a header in cache items to guarantee this, but this is ok for now. (mail_display_class_init): Setup cache structure. Also ensure globals are initialised at-most once. svn path=/trunk/; revision=17652
-rw-r--r--mail/ChangeLog16
-rw-r--r--mail/mail-display.c70
2 files changed, 83 insertions, 3 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 491ece9440..70b8b6b8e7 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,19 @@
+2002-07-31 Not Zed <NotZed@Ximian.com>
+
+ * mail-display.c: Added global cameldatacache for managing remote
+ image cache.
+ (fetch_remote): Lookup data in cache first, use that if available,
+ or setup a new cache item.
+ (fetch_data): Write any retrieved data to cache as well as html
+ stream.
+ (fetch_free): Unref cache stream.
+ (fetch_done):
+ (fetch_cancel): If failed/cancelled, remove cache items so they
+ dont foul the result. Probably need a header in cache items to
+ guarantee this, but this is ok for now.
+ (mail_display_class_init): Setup cache structure. Also ensure
+ globals are initialised at-most once.
+
2002-07-30 Radek Doulik <rodo@ximian.com>
* mail-config.c (mail_config_signature_set_name): save signature
diff --git a/mail/mail-display.c b/mail/mail-display.c
index 40706e3f76..528bb07fe4 100644
--- a/mail/mail-display.c
+++ b/mail/mail-display.c
@@ -58,6 +58,8 @@
#include "mail-mt.h"
#include "mail.h"
+#include "camel/camel-data-cache.h"
+
#include "art/empty.xpm"
#define d(x)
@@ -82,6 +84,9 @@ struct _MailDisplayPrivate {
/* max number of connections to download images */
#define FETCH_MAX_CONNECTIONS (4)
+/* path to http cache in fetch_cache */
+#define FETCH_HTTP_CACHE "http"
+
/* for asynchronously downloading remote content */
struct _remote_data {
struct _remote_data *next;
@@ -93,6 +98,7 @@ struct _remote_data {
char *uri;
GtkHTML *html;
GtkHTMLStream *stream;
+ CamelStream *cstream; /* cache stream */
size_t length;
size_t total;
};
@@ -104,6 +110,9 @@ static void fetch_data(SoupMessage *req, void *data);
static void fetch_free(struct _remote_data *rd);
static void fetch_done(SoupMessage *req, void *data);
+/* global http cache, relies on external evolution_dir as well */
+static CamelDataCache *fetch_cache;
+
#define PARENT_TYPE (gtk_vbox_get_type ())
static GtkObjectClass *mail_display_parent_class;
@@ -1306,6 +1315,32 @@ static void fetch_next(MailDisplay *md)
static void fetch_remote(MailDisplay *md, const char *uri, GtkHTML *html, GtkHTMLStream *stream)
{
struct _remote_data *rd;
+ CamelStream *cstream = NULL;
+
+ if (fetch_cache) {
+ cstream = camel_data_cache_get(fetch_cache, FETCH_HTTP_CACHE, uri, NULL);
+ if (cstream) {
+ char buf[1024];
+ ssize_t len;
+
+ /* need to verify header? */
+
+ while (!camel_stream_eos(cstream)) {
+ len = camel_stream_read(cstream, buf, 1024);
+ if (len > 0) {
+ gtk_html_write(html, stream, buf, len);
+ } else if (len < 0) {
+ gtk_html_end(html, stream, GTK_HTML_STREAM_ERROR);
+ camel_object_unref(cstream);
+ return;
+ }
+ }
+ gtk_html_end(html, stream, GTK_HTML_STREAM_OK);
+ camel_object_unref(cstream);
+ return;
+ }
+ cstream = camel_data_cache_add(fetch_cache, FETCH_HTTP_CACHE, uri, NULL);
+ }
rd = g_malloc0(sizeof(*rd));
rd->md = md; /* dont ref */
@@ -1313,6 +1348,7 @@ static void fetch_remote(MailDisplay *md, const char *uri, GtkHTML *html, GtkHTM
rd->html = html;
gtk_object_ref((GtkObject *)html);
rd->stream = stream;
+ rd->cstream = cstream;
md->priv->fetch_total++;
e_dlist_addtail(&md->priv->fetch_queue, (EDListNode *)rd);
@@ -1339,6 +1375,15 @@ static void fetch_data(SoupMessage *req, void *data)
gtk_html_write(rd->html, rd->stream, req->response.body, req->response.length);
+ /* copy to cache, clear cache if we get a cache failure */
+ if (rd->cstream) {
+ if (camel_stream_write(rd->cstream, req->response.body, req->response.length) == -1) {
+ camel_data_cache_remove(fetch_cache, FETCH_HTTP_CACHE, rd->uri, NULL);
+ camel_object_unref(rd->cstream);
+ rd->cstream = NULL;
+ }
+ }
+
/* update based on total active + finished totals */
complete = 0.0;
wd = (struct _remote_data *)p->fetch_active.head;
@@ -1357,8 +1402,10 @@ static void fetch_data(SoupMessage *req, void *data)
static void fetch_free(struct _remote_data *rd)
{
gtk_object_unref((GtkObject *)rd->html);
+ if (rd->cstream)
+ camel_object_unref(rd->cstream);
g_free(rd->uri);
- g_free(rd);
+ g_free(rd);
}
static void fetch_done(SoupMessage *req, void *data)
@@ -1369,6 +1416,8 @@ static void fetch_done(SoupMessage *req, void *data)
if (SOUP_MESSAGE_IS_ERROR(req)) {
d(printf("Loading '%s' failed!\n", rd->uri));
gtk_html_end(rd->html, rd->stream, GTK_HTML_STREAM_ERROR);
+ if (fetch_cache)
+ camel_data_cache_remove(fetch_cache, FETCH_HTTP_CACHE, rd->uri, NULL);
} else {
d(printf("Loading '%s' complete!\n", rd->uri));
gtk_html_end(rd->html, rd->stream, GTK_HTML_STREAM_OK);
@@ -1388,6 +1437,8 @@ static void fetch_cancel(MailDisplay *md)
/* first, clean up all the ones we haven't finished yet */
while ((rd = (struct _remote_data *)e_dlist_remhead(&md->priv->fetch_queue))) {
gtk_html_end(rd->html, rd->stream, GTK_HTML_STREAM_ERROR);
+ if (fetch_cache)
+ camel_data_cache_remove(fetch_cache, FETCH_HTTP_CACHE, rd->uri, NULL);
fetch_free(rd);
}
@@ -1918,9 +1969,22 @@ static void
mail_display_class_init (GtkObjectClass *object_class)
{
object_class->destroy = mail_display_destroy;
- mail_display_parent_class = gtk_type_class (PARENT_TYPE);
- thumbnail_cache = g_hash_table_new (g_str_hash, g_str_equal);
+ if (mail_display_parent_class == NULL) {
+ /* blah, this is an unecessary dependency ... */
+ extern char *evolution_dir;
+ char *path = alloca(strlen(evolution_dir)+16);
+
+ sprintf(path, "%s/cache", evolution_dir);
+ /* cache expiry - 2 hour access, 1 day max */
+ fetch_cache = camel_data_cache_new(path, 0, NULL);
+ camel_data_cache_set_expire_age(fetch_cache, 24*60*60);
+ camel_data_cache_set_expire_access(fetch_cache, 2*60*60);
+
+ mail_display_parent_class = gtk_type_class (PARENT_TYPE);
+ thumbnail_cache = g_hash_table_new (g_str_hash, g_str_equal);
+
+ }
}
static void