[evolution-rss] split config and image functions to separate files



commit b8173b733f4847bc61eb71b21f7a5fc43f58e90f
Author: Lucian Langa <lucilanga gnome org>
Date:   Tue May 18 00:18:36 2010 +0300

    split config and image functions to separate files

 po/POTFILES.in           |    7 +-
 src/Makefile.am          |    7 +
 src/misc.c               |   39 ++-
 src/misc.h               |    7 +
 src/parser.c             |   17 +-
 src/parser.h             |    2 +-
 src/rss-config-factory.c |    2 +-
 src/rss-config.c         |  672 ++++++++++++++++++++++++
 src/rss-config.h         |   26 +
 src/rss-icon-factory.c   |    2 +-
 src/rss-image.c          |  609 ++++++++++++++++++++++
 src/rss-image.h          |   60 +++
 src/rss.c                | 1296 +---------------------------------------------
 src/rss.h                |    9 -
 14 files changed, 1444 insertions(+), 1311 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b1f5c86..6303c66 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -9,8 +9,9 @@ src/org-gnome-evolution-rss.error.xml
 src/org-gnome-evolution-rss.xml
 src/rss.c
 src/rss.h
+src/rss-config.c
 src/rss-config-factory.c
-src/rss-html-rendering.glade
-src/rss-ui.glade
+src/rss-html-rendering.ui
+src/rss-image.c
+src/rss-main.ui
 src/parser.c
-src/GNOME_Evolution_RSS.server.in.in
diff --git a/src/Makefile.am b/src/Makefile.am
index c04d6b5..695d51c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -82,7 +82,9 @@ SOURCES =	fetch.c			\
 		parser.c		\
 		rss.c			\
 		rss-cache.c		\
+		rss-config.c		\
 		rss-config-factory.c	\
+		rss-image.c		\
 		rss-icon-factory.c
 if HAVE_GECKO
 SOURCES+=	gecko-utils.cpp
@@ -110,6 +112,7 @@ schema_DATA	= $(schema_in_files:.schemas.in.in=.schemas)
 if HAVE_BONOBO
 server_in_files = GNOME_Evolution_RSS.server.in.in
 server_DATA = $(server_in_files:.server.in.in=_$(EVOLUTION_EXEC_VERSION).server)
+echo "src/GNOME_Evolution_RSS.server.in.in" > po/POTFILES.in
 endif
 
 @EVO_SERVER_RULE@
@@ -180,10 +183,14 @@ EXTRA_DIST =					\
 	parser.c				\
 	parser.h				\
 	rss-cache.h				\
+	rss-config.c				\
+	rss-config.h				\
 	rss-config-factory.c			\
 	rss-config-factory.h			\
 	rss-icon-factory.c			\
 	rss-icon-factory.h			\
+	rss-image.c				\
+	rss-image.h				\
 	strptime.c				\
 	evolution-import-rss.c			\
 	evolution-rss.schemas.in.in		\
diff --git a/src/misc.c b/src/misc.c
index 797fdae..1e734ec 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -31,12 +31,14 @@
 #endif
 #include <e-util/e-mktemp.h>
 
-extern int rss_verbose_debug;
 
 #include "rss.h"
 #include "parser.h"
 #include "misc.h"
 
+extern int rss_verbose_debug;
+extern rssfeed *rf;
+
 int getNumericConfValue(gpointer a);
 
 int
@@ -128,6 +130,17 @@ check_if_match (gpointer key, gpointer value, gpointer user_data)
 	return FALSE; /* Continue calling the callback till end of table */
 }
 
+void
+dup_auth_data(gchar *origurl, gchar *url)
+{
+	gchar *user = g_hash_table_lookup(rf->hruser, origurl);
+	gchar *pass = g_hash_table_lookup(rf->hrpass, origurl);
+	if (user && pass) {
+		g_hash_table_insert(rf->hruser, url, g_strdup(user));
+		g_hash_table_insert(rf->hrpass, url, g_strdup(pass));
+	}
+}
+
 gchar *
 strextr(gchar *text, const gchar *substr)
 {
@@ -620,5 +633,29 @@ write_feed_status_line(gchar *file, gchar *needle)
 	}
 }
 
+#ifdef _WIN32
+char *strcasestr(const char *a, const char *b)
+{
+	char *a2=g_ascii_strdown(a,-1), *b2=g_ascii_strdown(b,-1), *r=strstr(a2,b2);
+	if(r)
+		r=(char *)a+(r-a2);
+	g_free(a2);
+	g_free(b2);
+	return r;
+}
+#endif
+
+void
+sanitize_path_separator(gchar *str)
+{
+#ifdef _WIN32
+	while (*str != '\0') {
+		if (G_IS_DIR_SEPARATOR(*str))
+			*str = G_DIR_SEPARATOR;
+		str++;
+	}
+#endif
+}
+
 #endif
 
diff --git a/src/misc.h b/src/misc.h
index 721dfa3..dc6bf8d 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -19,6 +19,8 @@
 #ifndef MISC_H
 #define MISC_H 1
 
+#include <rss.h>
+
 void print_cf(create_feed *CF);
 gchar *gen_crc(const char *msg);
 gchar *gen_md5(gchar *buffer);
@@ -47,5 +49,10 @@ void print_hash_int(gpointer key, gpointer value, gpointer user_data);
 gboolean feed_is_new(gchar *file_name, gchar *needle);
 void feed_remove_status_line(gchar *file_name, gchar *needle);
 void write_feed_status_line(gchar *file, gchar *needle);
+void dup_auth_data(gchar *origurl, gchar *url);
+void sanitize_path_separator(gchar *);
+#ifdef _WIN32
+char *strcasestr(const char *a, const char *b);
+#endif
 
 #endif
diff --git a/src/parser.c b/src/parser.c
index b8f5885..3b5d2be 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -36,6 +36,7 @@ extern int rss_verbose_debug;
 
 #include "fetch.h"
 #include "rss.h"
+#include "rss-config.h"
 #include "parser.h"
 #include "misc.h"
 #include "network-soup.h"
@@ -857,7 +858,7 @@ tree_walk (xmlNodePtr root, RDF *r)
 	return r->title;
 }
 
-xmlChar *
+gchar *
 process_images(gchar *text, gchar *link, EMFormatHTML *format)
 {
 	xmlChar *buff = NULL;
@@ -869,7 +870,7 @@ process_images(gchar *text, gchar *link, EMFormatHTML *format)
 			gchar *name = NULL;
 			xmlChar *url = xmlGetProp(doc, (xmlChar *)"src");
 			if (url) {
-				if (name = fetch_image_redraw((gchar *)url, link, format)) {
+				if ((name = fetch_image_redraw((gchar *)url, link, format))) {
 					gchar *tmp = g_strconcat(
 							"file://",
 							name, NULL);
@@ -884,7 +885,7 @@ process_images(gchar *text, gchar *link, EMFormatHTML *format)
 		}
 		xmlDocDumpMemory(src, &buff, (int*)&size);
 		xmlFree(src);
-		return buff;
+		return (gchar *)buff;
 	}
 	return g_strdup(text);
 }
@@ -902,8 +903,6 @@ parse_channel_line(xmlNode *top, gchar *feed_name, char *main_date, gchar **arti
 	gchar *feed = NULL;
 	gchar *encl, *tmp, *id;
 	gchar *qsafe, *tcat;
-	xmlChar *buff = NULL;
-	guint size = 0;
 	GList *category = NULL;
 	create_feed *CF;
 	GList *attachments = NULL;
@@ -1054,9 +1053,9 @@ parse_channel_line(xmlNode *top, gchar *feed_name, char *main_date, gchar **arti
 		g_free(b);
 
 		if (feed_name) {
-			buff = process_images(tmp, link, NULL);
+			gchar *buff = process_images(tmp, link, NULL);
 			g_free(tmp);
-			b = (gchar *)buff;
+			b = buff;
 		} else
 			b = tmp;
 
@@ -1201,7 +1200,7 @@ update_channel(RDF *r)
 	if (mail_folder) {
 		if ((rf->import || feed_new)
 		&& (!rf->cancel && !rf->cancel_all && !rf->display_cancel)) {
-			rss_select_folder(camel_folder_get_full_name(mail_folder));
+			rss_select_folder((gchar *)camel_folder_get_full_name(mail_folder));
 			if (feed_new) feed_new = FALSE;
 		}
 #if (DATASERVER_VERSION >= 2031001)
@@ -1210,7 +1209,7 @@ update_channel(RDF *r)
 		camel_object_unref(mail_folder);
 #endif
 	}
-out:	g_free(sender);
+	g_free(sender);
 
 	if (fr) fclose(fr);
 	if (fw) fclose(fw);
diff --git a/src/parser.h b/src/parser.h
index 12e2a46..7048912 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -57,7 +57,7 @@ gchar *media_rss(xmlNode *node, gchar *search, gchar *fail);
 gchar *dublin_core_rss(xmlNode *node, gchar *fail);
 void syndication_rss(void);
 gchar *wfw_rss(xmlNode *node, gchar *fail);
-xmlChar *process_images(gchar *text, gchar *link, EMFormatHTML *format);
+gchar *process_images(gchar *text, gchar *link, EMFormatHTML *format);
 
 #endif /*__RSS_H__*/
 
diff --git a/src/rss-config-factory.c b/src/rss-config-factory.c
index e7cf1a2..cfb36bc 100644
--- a/src/rss-config-factory.c
+++ b/src/rss-config-factory.c
@@ -17,7 +17,6 @@
  */
 
 #ifdef HAVE_CONFIG_H
-
 #include "config.h"
 #endif
 
@@ -61,6 +60,7 @@ extern int rss_verbose_debug;
 #include "rss.h"
 #include "misc.h"
 #include "parser.h"
+#include "rss-config.h"
 #include "rss-config-factory.h"
 #include "network-soup.h"
 #include "notification.h"
diff --git a/src/rss-config.c b/src/rss-config.c
new file mode 100644
index 0000000..1080f63
--- /dev/null
+++ b/src/rss-config.c
@@ -0,0 +1,672 @@
+/*  Evoution RSS Reader Plugin
+ *  Copyright (C) 2007-2010 Lucian Langa <cooly gnome eu org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <gconf/gconf.h>
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "misc.h"
+#include "rss-config.h"
+
+extern rssfeed *rf;
+extern GConfClient *rss_gconf;
+
+GSList *rss_list = NULL;
+
+static gboolean
+xml_set_content (xmlNodePtr node, char **val)
+{
+	char *buf;
+	int res;
+
+	buf = (char *)xmlNodeGetContent(node);
+	if (buf == NULL) {
+		res = (*val != NULL);
+		if (res) {
+			g_free(*val);
+			*val = NULL;
+		}
+	} else {
+		res = *val == NULL || strcmp(*val, buf) != 0;
+		if (res) {
+			g_free(*val);
+			*val = g_strdup(buf);
+		}
+		xmlFree(buf);
+	}
+
+	return res;
+}
+
+static gboolean
+xml_set_prop (xmlNodePtr node, const char *name, char **val)
+{
+	char *buf;
+	int res;
+
+	buf = (char *)xmlGetProp (node, (xmlChar *)name);
+	if (buf == NULL) {
+		res = (*val != NULL);
+		if (res) {
+			g_free(*val);
+			*val = NULL;
+		}
+	} else {
+		res = *val == NULL || strcmp(*val, buf) != 0;
+		if (res) {
+			g_free(*val);
+			*val = g_strdup(buf);
+		}
+		xmlFree(buf);
+	}
+
+	return res;
+}
+
+static gboolean
+xml_set_bool (xmlNodePtr node, const char *name, gboolean *val)
+{
+	gboolean gbool;
+	char *buf;
+
+	if ((buf = (char *)xmlGetProp (node, (xmlChar *)name))) {
+		gbool = (!strcmp (buf, "true") || !strcmp (buf, "yes"));
+		xmlFree (buf);
+
+		if (gbool != *val) {
+			*val = gbool;
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+gboolean
+feed_new_from_xml(char *xml)
+{
+	xmlNodePtr node;
+	xmlDocPtr doc = NULL;
+	char *uid = NULL;
+	char *name = NULL;
+	char *url = NULL;
+	char *type = NULL;
+	gboolean enabled = FALSE;
+	gboolean html = FALSE;
+	guint del_feed=0;
+	guint del_days=0;
+	guint del_messages=0;
+	guint del_unread=0, del_notpresent=0;
+	guint ttl=0;
+	guint ttl_multiply=0;
+	guint update=0;
+	gchar *ctmp = NULL;
+
+	if (!(doc = xmlParseDoc ((xmlChar *)xml)))
+		return FALSE;
+
+	node = doc->children;
+	if (strcmp ((char *)node->name, "feed") != 0) {
+		xmlFreeDoc (doc);
+		return FALSE;
+	}
+
+	xml_set_prop (node, "uid", &uid);
+	xml_set_bool (node, "enabled", &enabled);
+	xml_set_bool (node, "html", &html);
+
+	for (node = node->children; node; node = node->next) {
+		if (!strcmp ((char *)node->name, "name")) {
+			xml_set_content (node, &name);
+		}
+		if (!strcmp ((char *)node->name, "url")) {
+			xml_set_content (node, &url);
+		}
+		if (!strcmp ((char *)node->name, "type")) {
+			xml_set_content (node, &type);
+		}
+		if (!strcmp ((char *)node->name, "delete")) {
+			xml_set_prop (node, "option", &ctmp);
+			del_feed = atoi(ctmp);
+			xml_set_prop (node, "days", &ctmp);
+			del_days = atoi(ctmp);
+			xml_set_prop (node, "messages", &ctmp);
+			del_messages = atoi(ctmp);
+			xml_set_bool (
+				node,
+				"unread",
+				(gboolean *)&del_unread);
+			xml_set_bool (
+				node,
+				"notpresent",
+				(gboolean *)&del_notpresent);
+		}
+		if (!strcmp ((char *)node->name, "ttl")) {
+			xml_set_prop (node, "option", &ctmp);
+			update = atoi(ctmp);
+			xml_set_prop (node, "value", &ctmp);
+			ttl = atoi(ctmp);
+			xml_set_prop (node, "factor", &ctmp);
+			if (ctmp)
+				ttl_multiply = atoi(ctmp);
+			if (ctmp) g_free(ctmp);
+		}
+	}
+
+	g_hash_table_insert(rf->hrname, name, uid);
+	g_hash_table_insert(
+		rf->hrname_r,
+		g_strdup(uid),
+		g_strdup(name));
+	g_hash_table_insert(
+		rf->hr,
+		g_strdup(uid),
+		url);
+	g_hash_table_insert(
+		rf->hrh,
+		g_strdup(uid),
+		GINT_TO_POINTER(html));
+	g_hash_table_insert(
+		rf->hrt,
+		g_strdup(uid),
+		type);
+	g_hash_table_insert(
+		rf->hre,
+		g_strdup(uid),
+		GINT_TO_POINTER(enabled));
+	g_hash_table_insert(
+		rf->hrdel_feed,
+		g_strdup(uid),
+		GINT_TO_POINTER(del_feed));
+	g_hash_table_insert(
+		rf->hrdel_days,
+		g_strdup(uid),
+		GINT_TO_POINTER(del_days));
+	g_hash_table_insert(
+		rf->hrdel_messages,
+		g_strdup(uid),
+		GINT_TO_POINTER(del_messages));
+	g_hash_table_insert(
+		rf->hrdel_unread,
+		g_strdup(uid),
+		GINT_TO_POINTER(del_unread));
+	g_hash_table_insert(
+		rf->hrdel_notpresent,
+		g_strdup(uid),
+		GINT_TO_POINTER(del_notpresent));
+	g_hash_table_insert(
+		rf->hrupdate,
+		g_strdup(uid),
+		GINT_TO_POINTER(update));
+	g_hash_table_insert(
+		rf->hrttl,
+		g_strdup(uid),
+		GINT_TO_POINTER(ttl));
+	g_hash_table_insert(
+		rf->hrttl_multiply,
+		g_strdup(uid),
+		GINT_TO_POINTER(ttl_multiply));
+	xmlFreeDoc (doc);
+	return TRUE;
+}
+
+char *
+feeds_uid_from_xml (const char *xml)
+{
+	xmlNodePtr node;
+	xmlDocPtr doc;
+	char *uid = NULL;
+
+	if (!(doc = xmlParseDoc ((xmlChar *)xml)))
+		return NULL;
+
+	node = doc->children;
+	if (strcmp ((char *)node->name, "feed") != 0) {
+		xmlFreeDoc (doc);
+		return NULL;
+	}
+
+	xml_set_prop (node, "uid", &uid);
+	xmlFreeDoc (doc);
+
+	return uid;
+}
+
+gchar *
+feed_to_xml(gchar *key)
+{
+	xmlNodePtr root, src;
+	char *tmp;
+	xmlChar *xmlbuf;
+	xmlDocPtr doc;
+	int n;
+	gchar *ctmp;
+
+	doc = xmlNewDoc ((xmlChar *)"1.0");
+
+	root = xmlNewDocNode (doc, NULL, (xmlChar *)"feed", NULL);
+	xmlDocSetRootElement (doc, root);
+
+	xmlSetProp (
+		root,
+		(xmlChar *)"uid",
+		(xmlChar *)(g_hash_table_lookup(rf->hrname, key)));
+	xmlSetProp (
+		root,
+		(xmlChar *)"enabled",
+		(xmlChar *)(g_hash_table_lookup(
+				rf->hre,
+				lookup_key(key)) ? "true" : "false"));
+	xmlSetProp (
+		root,
+		(xmlChar *)"html",
+		(xmlChar *)(g_hash_table_lookup(
+				rf->hrh,
+				lookup_key(key)) ? "true" : "false"));
+
+	xmlNewTextChild (root, NULL, (xmlChar *)"name", (xmlChar *)key);
+	xmlNewTextChild (
+		root, NULL, (xmlChar *)"url",
+		(xmlChar *)g_hash_table_lookup(rf->hr, lookup_key(key)));
+	xmlNewTextChild (
+		root, NULL, (xmlChar *)"type",
+		(xmlChar *)g_hash_table_lookup(rf->hrt, lookup_key(key)));
+
+	src = xmlNewTextChild (root, NULL, (xmlChar *)"delete", NULL);
+	ctmp = g_strdup_printf(
+		"%d",
+		GPOINTER_TO_INT(
+			g_hash_table_lookup(
+				rf->hrdel_feed,
+				lookup_key(key))));
+	xmlSetProp (src, (xmlChar *)"option", (xmlChar *)ctmp);
+	g_free(ctmp);
+	ctmp = g_strdup_printf(
+		"%d",
+		GPOINTER_TO_INT(
+			g_hash_table_lookup(
+				rf->hrdel_days,
+				lookup_key(key))));
+	xmlSetProp (src, (xmlChar *)"days", (xmlChar *)ctmp);
+	g_free(ctmp);
+	ctmp = g_strdup_printf(
+		"%d",
+		GPOINTER_TO_INT(
+			g_hash_table_lookup(
+				rf->hrdel_messages,
+				lookup_key(key))));
+	xmlSetProp (src, (xmlChar *)"messages", (xmlChar *)ctmp);
+	g_free(ctmp);
+	xmlSetProp (
+		src,
+		(xmlChar *)"unread",
+		(xmlChar *)(g_hash_table_lookup(
+				rf->hrdel_unread,
+				lookup_key(key)) ? "true" : "false"));
+	xmlSetProp (
+		src,
+		(xmlChar *)"notpresent",
+		(xmlChar *)(g_hash_table_lookup(
+				rf->hrdel_notpresent,
+				lookup_key(key)) ? "true" : "false"));
+
+	src = xmlNewTextChild (root, NULL, (xmlChar *)"ttl", NULL);
+	ctmp = g_strdup_printf(
+		"%d",
+		GPOINTER_TO_INT(g_hash_table_lookup(
+				rf->hrupdate,
+				lookup_key(key))));
+	xmlSetProp (src, (xmlChar *)"option", (xmlChar *)ctmp);
+	g_free(ctmp);
+	ctmp = g_strdup_printf(
+		"%d",
+		GPOINTER_TO_INT(
+			g_hash_table_lookup(
+				rf->hrttl,
+				lookup_key(key))));
+	xmlSetProp (src, (xmlChar *)"value", (xmlChar *)ctmp);
+	g_free(ctmp);
+	ctmp = g_strdup_printf(
+		"%d",
+		GPOINTER_TO_INT(
+			g_hash_table_lookup(
+				rf->hrttl_multiply,
+				lookup_key(key))));
+	xmlSetProp (src, (xmlChar *)"factor", (xmlChar *)ctmp);
+	g_free(ctmp);
+
+	xmlDocDumpMemory (doc, &xmlbuf, &n);
+	xmlFreeDoc (doc);
+
+	/* remap to glib memory */
+	tmp = g_malloc (n + 1);
+	memcpy (tmp, xmlbuf, n);
+	tmp[n] = '\0';
+	xmlFree (xmlbuf);
+
+	return tmp;
+
+}
+
+void
+prepare_feed(gpointer key, gpointer value, gpointer user_data)
+{
+	char *xmlbuf;
+
+	xmlbuf = feed_to_xml (key);
+	if (xmlbuf)
+		rss_list = g_slist_append (rss_list, xmlbuf);
+}
+
+void
+load_gconf_feed(void)
+{
+	GSList *list, *l = NULL;
+	char *uid;
+
+	list = gconf_client_get_list (rss_gconf,
+		"/apps/evolution/evolution-rss/feeds",
+		GCONF_VALUE_STRING, NULL);
+	for (l = list; l; l = l->next) {
+		uid = feeds_uid_from_xml (l->data);
+		if (!uid)
+			continue;
+
+		feed_new_from_xml (l->data);
+
+		g_free (uid);
+	}
+	g_slist_foreach(list, (GFunc) g_free, NULL);
+	g_slist_free(list);
+}
+
+void
+save_gconf_feed(void)
+{
+
+	g_hash_table_foreach(rf->hrname, prepare_feed, NULL);
+
+	gconf_client_set_list (
+		rss_gconf,
+		"/apps/evolution/evolution-rss/feeds",
+		GCONF_VALUE_STRING,
+		rss_list,
+		NULL);
+
+	while (rss_list) {
+		g_free (rss_list->data);
+		rss_list = g_slist_remove (rss_list, rss_list->data);
+	}
+
+	gconf_client_suggest_sync (rss_gconf, NULL);
+}
+
+
+void
+migrate_old_config(gchar *feed_file)
+{
+	FILE *ffile;
+	gchar rfeed[512];
+	char **str;
+	gpointer key;
+
+	memset(rfeed, 0, 512);
+
+	if ((ffile = fopen(feed_file, "r"))) {
+		while (fgets(rfeed, 511, ffile) != NULL) {
+			str = g_strsplit(rfeed, "--", 0);
+			key = gen_md5(str[1]);
+			g_hash_table_insert(rf->hrname,
+				g_strdup(str[0]),
+				g_strdup(key));
+			g_hash_table_insert(rf->hrname_r,
+				g_strdup(key),
+				g_strdup(str[0]));
+			g_hash_table_insert(rf->hr,
+				g_strdup(key),
+				g_strstrip(str[1]));
+			if (NULL != str[4]) {
+				g_hash_table_insert(rf->hrh,
+					g_strdup(key),
+					GINT_TO_POINTER(atoi(g_strstrip(str[4]))));
+				g_hash_table_insert(rf->hrt,
+					g_strdup(key),
+					g_strdup(str[3]));
+				g_hash_table_insert(rf->hre,
+					g_strdup(key),
+					GINT_TO_POINTER(atoi(str[2])));
+			} else {
+				if (NULL != str[2]) {    // 0.0.1 -> 0.0.2
+					g_hash_table_insert(rf->hrh,
+						g_strdup(key),
+						(gpointer)0);
+					g_hash_table_insert(rf->hrt,
+						g_strdup(key),
+						g_strstrip(str[3]));
+					g_hash_table_insert(rf->hre,
+						g_strdup(key),
+						GINT_TO_POINTER(atoi(str[2])));
+				} else {
+					g_hash_table_insert(rf->hrh,
+						g_strdup(key),
+						(gpointer)0);
+					g_hash_table_insert(rf->hrt,
+						g_strdup(key),
+						g_strdup("RSS"));
+					g_hash_table_insert(rf->hre,
+						g_strdup(key),
+						(gpointer)1);
+				}
+			}
+			g_free(key);
+		}
+		fclose(ffile);
+		save_gconf_feed();
+		unlink(feed_file);
+	}
+}
+
+void
+read_feeds(rssfeed *rf)
+{
+	gchar *feed_dir = rss_component_peek_base_directory();
+	gchar *feed_file;
+
+	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
+		g_mkdir_with_parents (feed_dir, 0755);
+	feed_file = g_strdup_printf("%s/evolution-feeds", feed_dir);
+	g_free(feed_dir);
+	rf->hrname =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, g_free);
+	rf->hrname_r =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, g_free);
+	rf->hr = g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, g_free);
+	rf->hre = g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+	rf->hrt =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, g_free);
+	rf->hrh =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+	rf->hruser =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, NULL, g_free);
+	rf->hrpass =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, NULL, g_free);
+	rf->hrdel_feed =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+	rf->hrdel_days =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+	rf->hrdel_messages =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+	rf->hrdel_unread =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+	rf->hrdel_notpresent =
+		g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+	rf->hrupdate = g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+	rf->hrttl = g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+	rf->hrttl_multiply = g_hash_table_new_full(
+			g_str_hash, g_str_equal, g_free, NULL);
+
+	if (g_file_test(feed_file, G_FILE_TEST_EXISTS))
+		migrate_old_config(feed_file);
+	else
+		load_gconf_feed();
+
+	g_free(feed_file);
+}
+
+gchar *
+get_main_folder(void)
+{
+	gchar mf[512];
+	gchar *feed_file;
+	gchar *feed_dir = rss_component_peek_base_directory();
+
+	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
+		g_mkdir_with_parents (feed_dir, 0755);
+	feed_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "main_folder", feed_dir);
+	g_free(feed_dir);
+	if (g_file_test(feed_file, G_FILE_TEST_EXISTS)) {
+		FILE *f = fopen(feed_file, "r");
+		if (f) {
+			if (fgets(mf, 511, f) != NULL) {
+				fclose(f);
+				g_free(feed_file);
+				return g_strdup(mf);
+			}
+		}
+	}
+	g_free(feed_file);
+	return g_strdup(DEFAULT_FEEDS_FOLDER);
+}
+
+void
+get_feed_folders(void)
+{
+	gchar tmp1[512], tmp2[512];
+	gchar *feed_dir, *feed_file;
+
+	rf->feed_folders = g_hash_table_new_full(
+		g_str_hash,
+		g_str_equal,
+		g_free, g_free);
+	rf->reversed_feed_folders = g_hash_table_new_full(
+		g_str_hash,
+		g_str_equal,
+		g_free, g_free);
+	feed_dir = rss_component_peek_base_directory();
+	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
+		g_mkdir_with_parents (feed_dir, 0755);
+	feed_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "feed_folders", feed_dir);
+	g_free(feed_dir);
+	if (g_file_test(feed_file, G_FILE_TEST_EXISTS)) {
+		FILE *f = fopen(feed_file, "r");
+		while (!feof(f)) {
+			fgets(tmp1, 512, f);
+			fgets(tmp2, 512, f);
+			g_hash_table_insert(
+				rf->feed_folders,
+				g_strdup(g_strstrip(tmp1)),
+				g_strdup(g_strstrip(tmp2)));
+		}
+		fclose(f);
+	}
+	g_free(feed_file);
+	g_hash_table_foreach(
+		rf->feed_folders,
+		(GHFunc)populate_reversed,
+		rf->reversed_feed_folders);
+}
+
+//migrates old feed data files from crc naming
+//to md5 naming while preserving content
+//
+//this will be obsoleted over a release or two
+
+void
+migrate_crc_md5(const char *name, gchar *url)
+{
+	gchar *crc = gen_crc(name);
+	gchar *crc2 = gen_crc(url);
+	gchar *md5, *md5_name, *feed_dir, *feed_name;
+
+	md5 = gen_md5(url);
+	feed_dir = rss_component_peek_base_directory();
+	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
+		g_mkdir_with_parents (feed_dir, 0755);
+
+	md5_name = g_build_path(G_DIR_SEPARATOR_S, feed_dir, md5, NULL);
+	feed_name = g_build_path(G_DIR_SEPARATOR_S, feed_dir, crc, NULL);
+	g_free(crc);
+	g_free(md5);
+
+	if (g_file_test(feed_name, G_FILE_TEST_EXISTS)) {
+		FILE *fr = fopen(feed_name, "r");
+		FILE *fw = fopen(md5_name, "a+");
+		gchar rfeed[513];
+		memset(rfeed, 0, 512);
+		if (fr && fw) {
+			while (fgets(rfeed, 511, fr) != NULL) {
+				(void)fseek(fw, 0L, SEEK_SET);
+				fwrite(rfeed, strlen(rfeed), 1, fw);
+			}
+			fclose(fw);
+			unlink(feed_name);
+		}
+		fclose(fr);
+	}
+	g_free(feed_name);
+	feed_name = g_build_path(G_DIR_SEPARATOR_S, feed_dir, crc2, NULL);
+	g_free(crc2);
+	if (g_file_test(feed_name, G_FILE_TEST_EXISTS)) {
+		FILE *fr = fopen(feed_name, "r");
+		FILE *fw = fopen(md5_name, "a+");
+		gchar rfeed[513];
+		memset(rfeed, 0, 512);
+		if (fr && fw) {
+			while (fgets(rfeed, 511, fr) != NULL) {
+				(void)fseek(fw, 0L, SEEK_SET);
+				fwrite(rfeed, strlen(rfeed), 1, fw);
+			}
+			fclose(fw);
+			unlink(feed_name);
+		}
+		fclose(fr);
+
+	}
+
+	g_free(feed_name);
+	g_free(feed_dir);
+	g_free(md5_name);
+}
+
diff --git a/src/rss-config.h b/src/rss-config.h
new file mode 100644
index 0000000..069245f
--- /dev/null
+++ b/src/rss-config.h
@@ -0,0 +1,26 @@
+/*  Evoution RSS Reader Plugin
+ *  Copyright (C) 2007-2010 Lucian Langa <cooly gnome eu org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+gchar *feed_to_xml(gchar *key);
+gboolean feed_new_from_xml(char *xml);
+char *feeds_uid_from_xml (const char *xml);
+void load_gconf_feed(void);
+void migrate_old_config(gchar *feed_file);
+void read_feeds(rssfeed *rf);
+void get_feed_folders(void);
+gchar *get_main_folder(void);
+void migrate_crc_md5(const char *name, gchar *url);
diff --git a/src/rss-icon-factory.c b/src/rss-icon-factory.c
index e8636f7..d88305b 100644
--- a/src/rss-icon-factory.c
+++ b/src/rss-icon-factory.c
@@ -1,5 +1,5 @@
 /*  Evoution RSS Reader Plugin
- *  Copyright (C) 2007-2009 Lucian Langa <cooly gnome eu org>
+ *  Copyright (C) 2007-2010 Lucian Langa <cooly gnome eu org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/src/rss-image.c b/src/rss-image.c
new file mode 100644
index 0000000..4e9a183
--- /dev/null
+++ b/src/rss-image.c
@@ -0,0 +1,609 @@
+/*  Evoution RSS Reader Plugin
+ *  Copyright (C) 2007-2010 Lucian Langa <cooly gnome eu org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <camel/camel.h>
+#include <mail/em-folder-tree.h>
+#include <mail/em-format-html.h>
+#include <sys/time.h>
+#include <string.h>
+
+extern int rss_verbose_debug;
+
+#include "fetch.h"
+#include "misc.h"
+#include "parser.h"
+#include "rss.h"
+#include "rss-cache.h"
+#include "rss-config.h"
+#include "rss-image.h"
+#include "rss-icon-factory.h"
+
+extern gpointer current_pobject;
+extern GtkTreeStore *evolution_store;
+extern rssfeed *rf;
+gchar *pixfile;
+char *pixfilebuf;
+gsize pixfilelen;
+extern GHashTable *icons;
+void
+#if LIBSOUP_VERSION < 2003000
+finish_image_feedback (SoupMessage *msg, FEED_IMAGE *user_data);
+#else
+finish_image_feedback (SoupSession *soup_sess, SoupMessage *msg, FEED_IMAGE *user_data);
+#endif
+
+void
+rss_load_images(void)
+{
+	/* load transparency */
+	pixfile = g_build_filename (EVOLUTION_ICONDIR,
+			"pix.png",
+			NULL);
+	g_file_load_contents (g_file_parse_name(pixfile),
+			NULL,
+			&pixfilebuf,
+			&pixfilelen,
+			NULL,
+			NULL);
+}
+
+void
+update_feed_image(RDF *r)
+{
+	GError *err = NULL;
+	gchar *feed_file = NULL;
+	gchar *key = gen_md5(r->uri);
+	FEED_IMAGE *fi = g_new0(FEED_IMAGE, 1);
+	gchar *image = r->image;
+	gchar *feed_dir;
+
+	if (!check_update_feed_image(key))
+		goto out;
+	feed_dir = rss_component_peek_base_directory();
+	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
+		g_mkdir_with_parents (feed_dir, 0755);
+	feed_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.img", feed_dir, key);
+	d("feed_image() tmpurl:%s\n", feed_file);
+	g_free(feed_dir);
+	if (!g_file_test(feed_file, G_FILE_TEST_EXISTS)) {
+	if (image) {		//we need to validate image here with load_pixbuf
+		CamelStream *feed_fs = camel_stream_fs_new_with_name(feed_file,
+			O_RDWR|O_CREAT, 0666);
+		dup_auth_data(r->uri, image);
+		fi->feed_fs = feed_fs;
+		fi->key = g_strdup(key);
+		fetch_unblocking(image,
+			textcb,
+			NULL,
+			(gpointer)finish_create_icon_stream,
+			fi,
+			0,
+			&err);
+		if (err) {
+			g_print("ERR:%s\n", err->message);
+			goto out;
+		}
+	} else {
+		gchar *server = get_server_from_uri(r->uri);
+		//authentication data might be different
+		dup_auth_data(r->uri, server);
+		fetch_unblocking(
+			server,
+			textcb,
+			NULL,
+			(gpointer)finish_update_feed_image,
+			g_strdup(r->uri),// we need to dupe key here
+			0,
+			&err);		// because we might loose it if
+		g_free(server);
+					// feeds get deleted
+	}
+	}
+out:	g_free(feed_file);
+	g_free(key);
+}
+
+void
+#if LIBSOUP_VERSION < 2003000
+finish_update_feed_image (SoupMessage *msg, gpointer user_data)
+#else
+finish_update_feed_image (
+	SoupSession *soup_sess, SoupMessage *msg, gpointer user_data)
+#endif
+{
+	xmlChar *icon = NULL;
+	gchar *icon_url = NULL;
+	FEED_IMAGE *fi = NULL;
+	gchar *feed_dir = rss_component_peek_base_directory();
+	gchar *url = (gchar *)user_data;
+	gchar *key = gen_md5(url);
+	gchar *img_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.img", feed_dir, key);
+	gchar *urldir, *server;
+	rfMessage *rfmsg;
+	xmlChar *app;
+	xmlNode *doc;
+
+	g_free(feed_dir);
+	sanitize_path_separator(img_file);
+	urldir = g_path_get_dirname(url);
+	server = get_server_from_uri(url);
+	rfmsg = g_new0(rfMessage, 1);
+	rfmsg->status_code = msg->status_code;
+#if LIBSOUP_VERSION < 2003000
+	rfmsg->body = msg->response.body;
+	rfmsg->length = msg->response.length;
+#else
+	rfmsg->body = (gchar *)(msg->response_body->data);
+	rfmsg->length = msg->response_body->length;
+#endif
+	doc = (xmlNode *)parse_html_sux (rfmsg->body, rfmsg->length);
+	while (doc) {
+		doc = html_find(doc, (gchar *)"link");
+		if ((app = xmlGetProp(doc, (xmlChar *)"rel"))) {
+			if (!g_ascii_strcasecmp((char *)app, "shorcut icon")
+			|| !g_ascii_strcasecmp((char *)app, "icon")) {
+				icon = xmlGetProp(doc, (xmlChar *)"href");
+				break;
+			}
+		}
+		xmlFree(app);
+	}
+	g_free(rfmsg);
+	if (icon) {
+		if (strstr((char *)icon, "://") == NULL)
+			icon_url = g_strconcat(server, "/", icon, NULL);
+		else
+			icon_url = (char *)icon;
+
+		dup_auth_data(url, g_strdup(icon_url));
+		fi = g_new0(FEED_IMAGE, 1);
+		fi->img_file = g_strdup(img_file);
+		fi->key = g_strdup(key);
+		fetch_unblocking(
+			g_strdup(icon_url),
+			textcb,
+			NULL,
+			(gpointer)finish_create_icon,
+			fi,
+			0,
+//			&err);		// because we might lose it if
+			NULL);
+	} else {
+		//              r->image = NULL;
+		icon_url = g_strconcat(urldir, "/favicon.ico", NULL);
+		dup_auth_data(url, g_strdup(icon_url));
+		fi = g_new0(FEED_IMAGE, 1);
+		fi->img_file = g_strdup(img_file);
+		fi->key = g_strdup(key);
+		fetch_unblocking(
+				g_strdup(icon_url),
+				textcb,
+				NULL,
+				(gpointer)finish_create_icon,
+				fi,
+				0,
+//				&err);	// because we might lose it if
+				NULL);
+		g_free(icon_url);
+		icon_url = g_strconcat(server, "/favicon.ico", NULL);
+		dup_auth_data(url, g_strdup(icon_url));
+		fi = g_new0(FEED_IMAGE, 1);
+		fi->img_file = g_strdup(img_file);
+		fi->key = g_strdup(key);
+		fetch_unblocking(
+				g_strdup(icon_url),
+				textcb,
+				NULL,
+				(gpointer)finish_create_icon,
+				fi,
+				0,
+//				&err);	// because we might lose it if
+				NULL);
+	}
+	g_free(key);
+	g_free(img_file);
+	g_free(icon_url);
+	g_free(server);
+	g_free(urldir);
+	g_free(user_data);
+}
+
+gboolean
+check_update_feed_image(gchar *key)
+{
+	gchar *feed_dir = rss_component_peek_base_directory();
+	gchar *fav_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.fav", feed_dir, key);
+	struct timeval start;
+	FILE *f = NULL;
+	gboolean ret = TRUE;
+	unsigned long int remain;
+	gchar rfeed[80];
+	memset(rfeed, 0, 79);
+	gettimeofday(&start, NULL);
+	g_free(feed_dir);
+	if (!g_file_test(fav_file, G_FILE_TEST_EXISTS)) {
+		if ((f = fopen(fav_file, "w"))) {
+			fprintf(f, "%lu", start.tv_sec);
+			fclose(f);
+		}
+		ret = TRUE;
+		goto out;
+	}
+	if ((f = fopen(fav_file, "r+"))) {
+		fgets(rfeed, 50, f);
+		remain = start.tv_sec - strtoul(
+					(const char *)&rfeed, NULL, 10);
+		if (FEED_IMAGE_TTL <= remain) {
+			(void)fseek(f, 0L, SEEK_SET);
+			fprintf(f, "%lu", start.tv_sec);
+			fclose(f);
+			ret =  TRUE;
+			goto out;
+		} else {
+			d("next favicon will be fetched in %lu seconds\n",
+				FEED_IMAGE_TTL - remain);
+			fclose(f);
+			ret = FALSE;
+		}
+	}
+out:	g_free(fav_file);
+	return ret;
+}
+
+void
+#if LIBSOUP_VERSION < 2003000
+finish_image_feedback (SoupMessage *msg, FEED_IMAGE *user_data)
+#else
+finish_image_feedback (SoupSession *soup_sess, SoupMessage *msg, FEED_IMAGE *user_data)
+#endif
+{
+	CamelStream *stream = NULL;
+	stream = rss_cache_add(user_data->url);
+	finish_image(soup_sess, msg, stream);
+	if (user_data->data == current_pobject)
+		em_format_redraw((EMFormat *)user_data->data);
+	g_free(user_data->url);
+	g_free(user_data);
+}
+
+void
+#if LIBSOUP_VERSION < 2003000
+finish_image (SoupMessage *msg, CamelStream *user_data)
+#else
+finish_image (SoupSession *soup_sess, SoupMessage *msg, CamelStream *user_data)
+#endif
+{
+	d("CODE:%d\n", msg->status_code);
+	// we might need to handle more error codes here
+	if (503 != msg->status_code && //handle this timedly fasion
+	    404 != msg->status_code && //NOT FOUND
+	    400 != msg->status_code && //bad request
+	      2 != msg->status_code && //STATUS_CANT_RESOLVE
+	      1 != msg->status_code && //TIMEOUT (CANCELLED) ?
+	      7 != msg->status_code && // STATUS_IO_ERROR
+#if LIBSOUP_VERSION < 2003000
+		msg->response.length) {	//ZERO SIZE
+#else
+		msg->response_body->length) { //ZERO SIZE
+#endif
+#if LIBSOUP_VERSION < 2003000
+		if (msg->response.body) {
+			camel_stream_write(user_data,
+				msg->response.body,
+				msg->response.length);
+#else
+		if (msg->response_body->data) {
+			camel_stream_write(user_data,
+				msg->response_body->data,
+				msg->response_body->length);
+#endif
+			camel_stream_close(user_data);
+#if (DATASERVER_VERSION >= 2031001)
+			g_object_unref(user_data);
+#else
+			camel_object_unref(user_data);
+#endif
+		}
+	} else {
+		camel_stream_write(user_data, pixfilebuf, pixfilelen);
+		camel_stream_close(user_data);
+#if (DATASERVER_VERSION >= 2031001)
+		g_object_unref(user_data);
+#else
+		camel_object_unref(user_data);
+#endif
+	}
+}
+
+void
+#if LIBSOUP_VERSION < 2003000
+finish_create_icon (SoupMessage *msg, FEED_IMAGE *user_data)
+#else
+finish_create_icon (SoupSession *soup_sess, SoupMessage *msg, FEED_IMAGE *user_data)
+#endif
+{
+	d("finish_image(): status:%d, user_data:%s\n", msg->status_code, user_data->img_file);
+	if (404 != msg->status_code) {
+		CamelStream *feed_fs = camel_stream_fs_new_with_name(user_data->img_file,
+			O_RDWR|O_CREAT, 0666);
+		finish_image(soup_sess, msg, feed_fs);
+#if (EVOLUTION_VERSION >= 22703)
+		display_folder_icon(evolution_store, user_data->key);
+#endif
+	}
+	g_free(user_data->key);
+	g_free(user_data);
+}
+
+void
+#if LIBSOUP_VERSION < 2003000
+finish_create_icon_stream (
+	SoupMessage *msg, FEED_IMAGE *user_data)
+#else
+finish_create_icon_stream (
+	SoupSession *soup_sess, SoupMessage *msg, FEED_IMAGE *user_data)
+#endif
+{
+	finish_image(soup_sess, msg, user_data->feed_fs);
+#if (EVOLUTION_VERSION >= 22703)
+	display_folder_icon(evolution_store, user_data->key);
+#endif
+	g_free(user_data->key);
+	g_free(user_data);
+}
+
+#if (EVOLUTION_VERSION >= 22703)
+gboolean
+display_folder_icon(GtkTreeStore *tree_store, gchar *key)
+{
+	gchar *feed_dir = rss_component_peek_base_directory();
+	gchar *img_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.img", feed_dir, key);
+	GdkPixbuf *icon, *pixbuf;
+	gboolean result = FALSE;
+	GtkTreeIter iter;
+	GtkTreePath *path;
+	GtkTreeRowReference *row;
+	EMFolderTreeModel *mod = (EMFolderTreeModel *)tree_store;
+	struct _EMFolderTreeModelStoreInfo *si;
+	CamelStore *store = rss_component_peek_local_store();
+	CamelFolder *rss_folder;
+	gint i=0, size;
+	gint *sizes;
+
+	g_return_val_if_fail(mod != NULL, FALSE);
+
+	pixbuf = gdk_pixbuf_new_from_file(img_file, NULL);
+
+	if (pixbuf) {
+		gchar *name = g_hash_table_lookup(rf->hrname_r, key);
+		gchar *full_name = g_strdup_printf(
+					"%s" G_DIR_SEPARATOR_S "%s",
+					get_main_folder(),
+					lookup_feed_folder(name));
+		rss_folder = camel_store_get_folder (
+					store,
+					full_name, 0, NULL);
+		if (!rss_folder) {
+			g_free(full_name);
+			result = FALSE;
+			goto out;
+		}
+		icon = rss_build_icon (img_file, GTK_ICON_SIZE_MENU);
+		d("icon:%p\n", icon);
+		g_hash_table_insert(icons,
+			g_strdup(key), GINT_TO_POINTER(1));
+		sizes = gtk_icon_theme_get_icon_sizes(
+				gtk_icon_theme_get_default(),
+				"mail-read"); //will mail-read always be there?
+		for (i=0; 0 != (size = sizes[i]); i++)
+			d("icon set size:%d\n", size);
+			gtk_icon_theme_add_builtin_icon(key,
+				size,
+				icon);
+		g_free(sizes);
+
+#if EVOLUTION_VERSION < 22900 //kb//
+		si = g_hash_table_lookup (mod->store_hash, store);
+#else
+		si = em_folder_tree_model_lookup_store_info (
+			EM_FOLDER_TREE_MODEL (mod), store);
+#endif
+		row = g_hash_table_lookup (si->full_hash, full_name);
+		if (!row) goto out;
+		path = gtk_tree_row_reference_get_path (row);
+		gtk_tree_model_get_iter (
+			(GtkTreeModel *)tree_store, &iter, path);
+		gtk_tree_path_free (path);
+
+		gtk_tree_store_set(
+				tree_store, &iter,
+				COL_STRING_ICON_NAME, key,
+				-1);
+		g_free(full_name);
+#if (DATASERVER_VERSION >= 2031001)
+		g_object_unref (rss_folder);
+#else
+		camel_object_unref (rss_folder);
+#endif
+		g_object_unref(pixbuf);
+		result = TRUE;
+	}
+out:	g_free(img_file);
+	g_free(feed_dir);
+	return result;
+}
+#endif
+
+/* validates if image is indeed an image file
+ * if image file is not found it tries to fetch it
+ * we need to check mime time against content
+ * because we could end up with wrong file as image
+ */
+gchar *
+verify_image(gchar *uri, EMFormatHTML *format)
+{
+	gchar *mime_type, *contents;
+	gsize length;
+	gchar *nurl, *turl;
+	gchar *base_dir, *feed_dir, *name;
+	gchar *scheme, *result;
+
+	g_return_val_if_fail(uri != NULL, NULL);
+
+	if (!g_file_test((gchar *)uri, G_FILE_TEST_EXISTS)) {
+			camel_url_decode((gchar *)uri);
+			//FIXME lame method of extracting data cache path
+			//there must be a function in camel for getting data cache path
+			base_dir = rss_component_peek_base_directory();
+			feed_dir = g_build_path(G_DIR_SEPARATOR_S,
+				base_dir,
+				"static",
+				"http",
+				NULL);
+			scheme = g_uri_parse_scheme(uri);
+			/* calling fetch_image_redraw with link NULL
+			 * as we do not have base link here
+			 * and not able to get it either
+			 */
+			if (!scheme) {
+				nurl = strextr((gchar *)uri, feed_dir);
+				g_free(feed_dir);
+				turl = nurl + 4;
+				name = fetch_image_redraw(turl, NULL, format);
+				g_free(nurl);
+			} else {
+				turl = uri;
+				name = fetch_image_redraw(uri, NULL, format);
+				g_free(scheme);
+			}
+			g_free(base_dir);
+			result = g_filename_to_uri (name, NULL, NULL);
+			g_free(name);
+			return result;
+	} else {
+		/*need to get mime type via file contents or else mime type is
+		 * bound to be wrong, especially on files fetched from the web
+		 * this is very important as we might get quite a few images
+		 * missing otherwise */
+		g_file_get_contents (uri,
+			&contents,
+			&length,
+			NULL);
+		mime_type = g_content_type_guess(NULL, (guchar *)contents, length, NULL);
+		/*FIXME mime type here could be wrong */
+		if (g_ascii_strncasecmp (mime_type, "image/", 6)) {
+			result = g_filename_to_uri (pixfile, NULL, NULL);
+			return result;
+		}
+		g_free(mime_type);
+		g_free(contents);
+/*
+ * appears the default has changed in efh_url_requested
+ * the new default is file://
+ * http://git.gnome.org/browse/evolution/commit/?id=d9deaf9bbc7fd9d0c72d5cf9b1981e3a56ed1162
+ */
+#if (EVOLUTION_VERSION >= 23000)
+		return g_filename_to_uri(uri, NULL, NULL);
+#else
+		return NULL;
+#endif
+	}
+}
+
+// constructs url from @base in case url is relative
+gchar *
+fetch_image_redraw(gchar *url, gchar *link, gpointer data)
+{
+	GError *err = NULL;
+	gchar *tmpurl = NULL;
+	FEED_IMAGE *fi = NULL;
+	gchar *result, *safe, *cache_file;
+
+	g_return_val_if_fail(url != NULL, NULL);
+
+	if (strstr(url, "://") == NULL) {
+		if (*url == '.') //test case when url begins with ".."
+			tmpurl = g_strconcat(
+					g_path_get_dirname(link),
+					"/", url, NULL);
+		else {
+			if (*url == '/')
+				tmpurl = g_strconcat(
+						get_server_from_uri(link),
+						"/", url, NULL);
+			else	//url is relative (does not begin with / or .)
+				tmpurl = g_strconcat(
+						g_path_get_dirname(link),
+						"/", url, NULL);
+		}
+	} else {
+		tmpurl = g_strdup(url);
+	}
+
+	if (!tmpurl)
+		return NULL;
+
+	safe = g_compute_checksum_for_string (
+			G_CHECKSUM_SHA1, tmpurl, -1);
+	if (g_hash_table_find(rf->key_session,
+			check_key_match,
+			tmpurl)) {
+		goto working;
+	}
+	d("fetch_image_redraw() tmpurl:%s, safe url:%s\n", tmpurl, safe);
+	cache_file = rss_cache_get_filename(safe);
+	if (!g_file_test (cache_file, G_FILE_TEST_EXISTS)) {
+		d("image cache MISS\n");
+		if (data) {
+			fi = g_new0(FEED_IMAGE, 1);
+			fi->url = g_strdup(safe);
+			fi->data = data;
+			fetch_unblocking(tmpurl,
+				textcb,
+				g_strdup(tmpurl),
+				(gpointer)finish_image_feedback,
+				fi,
+				1,
+				&err);
+		} else {
+			CamelStream *stream = rss_cache_add(safe);
+			fetch_unblocking(tmpurl,
+				textcb,
+				NULL,
+				(gpointer)finish_image,
+				stream,
+				0,
+				&err);
+		}
+		if (err) {
+			result = NULL;
+			g_free(cache_file);
+			goto error;
+		}
+	} else {
+		d("image cache HIT\n");
+	}
+	g_free(cache_file);
+
+working:result = rss_cache_get_path(FALSE, safe);
+error:	g_free(tmpurl);
+	g_free(safe);
+	return result;
+}
+
diff --git a/src/rss-image.h b/src/rss-image.h
new file mode 100644
index 0000000..dbc8e4f
--- /dev/null
+++ b/src/rss-image.h
@@ -0,0 +1,60 @@
+/*  Evoution RSS Reader Plugin
+ *  Copyright (C) 2007-2010 Lucian Langa <cooly gnome eu org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+typedef struct _FEED_IMAGE {
+	gchar *img_file;
+	CamelStream *feed_fs;
+	gchar *url;
+	gchar *key;
+	gpointer data;
+} FEED_IMAGE;
+
+void rss_load_images(void);
+gboolean display_folder_icon(GtkTreeStore *store, gchar *key);
+void
+#if LIBSOUP_VERSION < 2003000
+finish_create_icon (SoupMessage *msg, FEED_IMAGE *user_data);
+#else
+finish_create_icon (SoupSession *soup_sess,
+	SoupMessage *msg, FEED_IMAGE *user_data);
+#endif
+void
+#if LIBSOUP_VERSION < 2003000
+finish_create_icon_stream (SoupMessage *msg, FEED_IMAGE *user_data);
+#else
+finish_create_icon_stream (SoupSession *soup_sess,
+	SoupMessage *msg, FEED_IMAGE *user_data);
+#endif
+
+gchar *verify_image(gchar *uri, EMFormatHTML *format);
+
+void
+#if LIBSOUP_VERSION < 2003000
+finish_image (SoupMessage *msg, CamelStream *user_data);
+#else
+finish_image (SoupSession *soup_sess,
+	SoupMessage *msg, CamelStream *user_data);
+#endif
+void
+#if LIBSOUP_VERSION < 2003000
+finish_create_image (SoupMessage *msg, gchar *user_data);
+#else
+finish_create_image (SoupSession *soup_sess,
+	SoupMessage *msg, gchar *user_data);
+#endif
+
diff --git a/src/rss.c b/src/rss.c
index f1f55c4..0dfe82a 100644
--- a/src/rss.c
+++ b/src/rss.c
@@ -142,7 +142,9 @@ int rss_verbose_debug = 0;
 #endif
 
 #include "rss.h"
+#include "rss-config.h"
 #include "rss-cache.h"
+#include "rss-image.h"
 #include "parser.h"
 #include "network-soup.h"
 #include "notification.h"
@@ -157,31 +159,6 @@ int rss_verbose_debug = 0;
 #include "parser.h"
 
 
-#ifdef _WIN32
-char *strcasestr(const char *a, const char *b)
-{
-	char *a2=g_ascii_strdown(a,-1), *b2=g_ascii_strdown(b,-1), *r=strstr(a2,b2);
-	if(r)
-		r=(char *)a+(r-a2);
-	g_free(a2);
-	g_free(b2);
-	return r;
-}
-#endif
-
-static void sanitize_path_separator(gchar *);
-
-static void
-sanitize_path_separator(gchar *str)
-{
-#ifdef _WIN32
-	while (*str != '\0') {
-		if (G_IS_DIR_SEPARATOR(*str))
-			*str = G_DIR_SEPARATOR;
-		str++;
-	}
-#endif
-}
 
 int pop = 0;
 GtkWidget *flabel;
@@ -233,9 +210,6 @@ static GdkPixbuf *folder_icon;
 static gboolean initialised = FALSE;
 #endif
 GHashTable *icons = NULL;
-gchar *pixfile;
-char *pixfilebuf;
-gsize pixfilelen;
 #if (DATASERVER_VERSION >= 2023001)
 extern EProxy *proxy;
 #endif
@@ -253,7 +227,6 @@ rssfeed *rf = NULL;
 guint upgrade = 0;	// set to 2 when initailization successfull
 guint count = 0;
 gchar *buffer = NULL;
-GSList *rss_list = NULL;
 GConfClient *rss_gconf;
 
 gboolean inhibit_read = FALSE;	//prevent mail selection when deleting folder
@@ -279,20 +252,6 @@ void check_folders(void);
 CamelMimePart *file_to_message(const char *name);
 void check_feed_age(void);
 void get_feed_age(RDF *r, gpointer name);
-static void
-#if LIBSOUP_VERSION < 2003000
-finish_image (SoupMessage *msg, CamelStream *user_data);
-#else
-finish_image (SoupSession *soup_sess,
-	SoupMessage *msg, CamelStream *user_data);
-#endif
-void
-#if LIBSOUP_VERSION < 2003000
-finish_create_image (SoupMessage *msg, gchar *user_data);
-#else
-finish_create_image (SoupSession *soup_sess,
-	SoupMessage *msg, gchar *user_data);
-#endif
 gboolean display_feed_async(gpointer key);
 gboolean fetch_one_feed(gpointer key, gpointer value, gpointer user_data);
 gboolean fetch_feed(gpointer key, gpointer value, gpointer user_data);
@@ -303,35 +262,10 @@ guint fallback_engine(void);
 
 gchar *print_comments(gchar *url, gchar *stream, EMFormatHTML *format);
 static void refresh_cb (GtkWidget *button, EMFormatHTMLPObject *pobject);
-void dup_auth_data(gchar *origurl, gchar *url);
-gboolean display_folder_icon(GtkTreeStore *store, gchar *key);
 
-typedef struct _FEED_IMAGE {
-	gchar *img_file;
-	CamelStream *feed_fs;
-	gchar *url;
-	gchar *key;
-	gpointer data;
-} FEED_IMAGE;
-
-static void
-#if LIBSOUP_VERSION < 2003000
-finish_create_icon (SoupMessage *msg, FEED_IMAGE *user_data);
-#else
-finish_create_icon (SoupSession *soup_sess,
-	SoupMessage *msg, FEED_IMAGE *user_data);
-#endif
-static void
-#if LIBSOUP_VERSION < 2003000
-finish_create_icon_stream (SoupMessage *msg, FEED_IMAGE *user_data);
-#else
-finish_create_icon_stream (SoupSession *soup_sess,
-	SoupMessage *msg, FEED_IMAGE *user_data);
-#endif
 void webkit_set_history(gchar *base);
 gboolean show_webkit(GtkWidget *webkit);
 void sync_folders(void);
-gchar *verify_image(gchar *uri, EMFormatHTML *format);
 
 GtkTreeStore *evolution_store = NULL;
 #if EVOLUTION_VERSION >= 22900
@@ -944,153 +878,6 @@ receive_cancel(GtkButton *button, struct _send_info *info)
 //	abort_all_soup();
 }
 
-gchar *
-feed_to_xml(gchar *key)
-{
-	xmlNodePtr root, src;
-	char *tmp;
-	xmlChar *xmlbuf;
-	xmlDocPtr doc;
-	int n;
-	gchar *ctmp;
-
-	doc = xmlNewDoc ((xmlChar *)"1.0");
-
-	root = xmlNewDocNode (doc, NULL, (xmlChar *)"feed", NULL);
-	xmlDocSetRootElement (doc, root);
-
-	xmlSetProp (
-		root,
-		(xmlChar *)"uid",
-		(xmlChar *)(g_hash_table_lookup(rf->hrname, key)));
-	xmlSetProp (
-		root,
-		(xmlChar *)"enabled",
-		(xmlChar *)(g_hash_table_lookup(
-				rf->hre,
-				lookup_key(key)) ? "true" : "false"));
-	xmlSetProp (
-		root,
-		(xmlChar *)"html",
-		(xmlChar *)(g_hash_table_lookup(
-				rf->hrh,
-				lookup_key(key)) ? "true" : "false"));
-
-	xmlNewTextChild (root, NULL, (xmlChar *)"name", (xmlChar *)key);
-	xmlNewTextChild (
-		root, NULL, (xmlChar *)"url",
-		(xmlChar *)g_hash_table_lookup(rf->hr, lookup_key(key)));
-	xmlNewTextChild (
-		root, NULL, (xmlChar *)"type",
-		(xmlChar *)g_hash_table_lookup(rf->hrt, lookup_key(key)));
-
-	src = xmlNewTextChild (root, NULL, (xmlChar *)"delete", NULL);
-	ctmp = g_strdup_printf(
-		"%d", 
-		GPOINTER_TO_INT(
-			g_hash_table_lookup(
-				rf->hrdel_feed,
-				lookup_key(key))));
-	xmlSetProp (src, (xmlChar *)"option", (xmlChar *)ctmp);
-	g_free(ctmp);
-	ctmp = g_strdup_printf(
-		"%d",
-		GPOINTER_TO_INT(
-			g_hash_table_lookup(
-				rf->hrdel_days,
-				lookup_key(key))));
-	xmlSetProp (src, (xmlChar *)"days", (xmlChar *)ctmp);
-	g_free(ctmp);
-	ctmp = g_strdup_printf(
-		"%d",
-		GPOINTER_TO_INT(
-			g_hash_table_lookup(
-				rf->hrdel_messages,
-				lookup_key(key))));
-	xmlSetProp (src, (xmlChar *)"messages", (xmlChar *)ctmp);
-	g_free(ctmp);
-	xmlSetProp (
-		src,
-		(xmlChar *)"unread",
-		(xmlChar *)(g_hash_table_lookup(
-				rf->hrdel_unread,
-				lookup_key(key)) ? "true" : "false"));
-	xmlSetProp (
-		src,
-		(xmlChar *)"notpresent",
-		(xmlChar *)(g_hash_table_lookup(
-				rf->hrdel_notpresent,
-				lookup_key(key)) ? "true" : "false"));
-
-	src = xmlNewTextChild (root, NULL, (xmlChar *)"ttl", NULL);
-	ctmp = g_strdup_printf(
-		"%d",
-		GPOINTER_TO_INT(g_hash_table_lookup(
-				rf->hrupdate,
-				lookup_key(key))));
-	xmlSetProp (src, (xmlChar *)"option", (xmlChar *)ctmp);
-	g_free(ctmp);
-	ctmp = g_strdup_printf(
-		"%d",
-		GPOINTER_TO_INT(
-			g_hash_table_lookup(
-				rf->hrttl,
-				lookup_key(key))));
-	xmlSetProp (src, (xmlChar *)"value", (xmlChar *)ctmp);
-	g_free(ctmp);
-	ctmp = g_strdup_printf(
-		"%d",
-		GPOINTER_TO_INT(
-			g_hash_table_lookup(
-				rf->hrttl_multiply,
-				lookup_key(key))));
-	xmlSetProp (src, (xmlChar *)"factor", (xmlChar *)ctmp);
-	g_free(ctmp);
-
-	xmlDocDumpMemory (doc, &xmlbuf, &n);
-	xmlFreeDoc (doc);
-
-	/* remap to glib memory */
-	tmp = g_malloc (n + 1);
-	memcpy (tmp, xmlbuf, n);
-	tmp[n] = '\0';
-	xmlFree (xmlbuf);
-
-	return tmp;
-
-}
-
-void
-prepare_feed(gpointer key, gpointer value, gpointer user_data)
-{
-	char *xmlbuf;
-
-	xmlbuf = feed_to_xml (key);
-	if (xmlbuf)
-		rss_list = g_slist_append (rss_list, xmlbuf);
-}
-
-void
-save_gconf_feed(void)
-{
-
-	g_hash_table_foreach(rf->hrname, prepare_feed, NULL);
-
-	gconf_client_set_list (
-		rss_gconf,
-		"/apps/evolution/evolution-rss/feeds",
-		GCONF_VALUE_STRING,
-		rss_list,
-		NULL);
-
-	while (rss_list) {
-		g_free (rss_list->data);
-		rss_list = g_slist_remove (rss_list, rss_list->data);
-	}
-
-	gconf_client_suggest_sync (rss_gconf, NULL);
-}
-
 void
 rss_select_folder(gchar *folder_name)
 {
@@ -1144,373 +931,6 @@ rss_select_folder(gchar *folder_name)
 #endif
 }
 
-static gboolean
-xml_set_content (xmlNodePtr node, char **val)
-{
-	char *buf;
-	int res;
-
-	buf = (char *)xmlNodeGetContent(node);
-	if (buf == NULL) {
-		res = (*val != NULL);
-		if (res) {
-			g_free(*val);
-			*val = NULL;
-		}
-	} else {
-		res = *val == NULL || strcmp(*val, buf) != 0;
-		if (res) {
-			g_free(*val);
-			*val = g_strdup(buf);
-		}
-		xmlFree(buf);
-	}
-
-	return res;
-}
-
-static gboolean
-xml_set_prop (xmlNodePtr node, const char *name, char **val)
-{
-	char *buf;
-	int res;
-
-	buf = (char *)xmlGetProp (node, (xmlChar *)name);
-	if (buf == NULL) {
-		res = (*val != NULL);
-		if (res) {
-			g_free(*val);
-			*val = NULL;
-		}
-	} else {
-		res = *val == NULL || strcmp(*val, buf) != 0;
-		if (res) {
-			g_free(*val);
-			*val = g_strdup(buf);
-		}
-		xmlFree(buf);
-	}
-
-	return res;
-}
-
-static gboolean
-xml_set_bool (xmlNodePtr node, const char *name, gboolean *val)
-{
-	gboolean gbool;
-	char *buf;
-
-	if ((buf = (char *)xmlGetProp (node, (xmlChar *)name))) {
-		gbool = (!strcmp (buf, "true") || !strcmp (buf, "yes"));
-		xmlFree (buf);
-
-		if (gbool != *val) {
-			*val = gbool;
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-gboolean
-feed_new_from_xml(char *xml)
-{
-	xmlNodePtr node;
-	xmlDocPtr doc = NULL;
-	char *uid = NULL;
-	char *name = NULL;
-	char *url = NULL;
-	char *type = NULL;
-	gboolean enabled = FALSE;
-	gboolean html = FALSE;
-	guint del_feed=0;
-	guint del_days=0;
-	guint del_messages=0;
-	guint del_unread=0, del_notpresent=0;
-	guint ttl=0;
-	guint ttl_multiply=0;
-	guint update=0;
-	gchar *ctmp = NULL;
-
-	if (!(doc = xmlParseDoc ((xmlChar *)xml)))
-		return FALSE;
-
-	node = doc->children;
-	if (strcmp ((char *)node->name, "feed") != 0) {
-		xmlFreeDoc (doc);
-		return FALSE;
-	}
-
-	xml_set_prop (node, "uid", &uid);
-	xml_set_bool (node, "enabled", &enabled);
-	xml_set_bool (node, "html", &html);
-
-	for (node = node->children; node; node = node->next) {
-		if (!strcmp ((char *)node->name, "name")) {
-			xml_set_content (node, &name);
-		}
-		if (!strcmp ((char *)node->name, "url")) {
-			xml_set_content (node, &url);
-		}
-		if (!strcmp ((char *)node->name, "type")) {
-			xml_set_content (node, &type);
-		}
-		if (!strcmp ((char *)node->name, "delete")) {
-			xml_set_prop (node, "option", &ctmp);
-			del_feed = atoi(ctmp);
-			xml_set_prop (node, "days", &ctmp);
-			del_days = atoi(ctmp);
-			xml_set_prop (node, "messages", &ctmp);
-			del_messages = atoi(ctmp);
-			xml_set_bool (
-				node,
-				"unread",
-				(gboolean *)&del_unread);
-			xml_set_bool (
-				node,
-				"notpresent",
-				(gboolean *)&del_notpresent);
-		}
-		if (!strcmp ((char *)node->name, "ttl")) {
-			xml_set_prop (node, "option", &ctmp);
-			update = atoi(ctmp);
-			xml_set_prop (node, "value", &ctmp);
-			ttl = atoi(ctmp);
-			xml_set_prop (node, "factor", &ctmp);
-			if (ctmp)
-				ttl_multiply = atoi(ctmp);
-			if (ctmp) g_free(ctmp);
-		}
-	}
-
-	g_hash_table_insert(rf->hrname, name, uid);
-	g_hash_table_insert(
-		rf->hrname_r,
-		g_strdup(uid),
-		g_strdup(name));
-	g_hash_table_insert(
-		rf->hr,
-		g_strdup(uid),
-		url);
-	g_hash_table_insert(
-		rf->hrh,
-		g_strdup(uid),
-		GINT_TO_POINTER(html));
-	g_hash_table_insert(
-		rf->hrt,
-		g_strdup(uid),
-		type);
-	g_hash_table_insert(
-		rf->hre,
-		g_strdup(uid),
-		GINT_TO_POINTER(enabled));
-	g_hash_table_insert(
-		rf->hrdel_feed,
-		g_strdup(uid),
-		GINT_TO_POINTER(del_feed));
-	g_hash_table_insert(
-		rf->hrdel_days,
-		g_strdup(uid),
-		GINT_TO_POINTER(del_days));
-	g_hash_table_insert(
-		rf->hrdel_messages,
-		g_strdup(uid),
-		GINT_TO_POINTER(del_messages));
-	g_hash_table_insert(
-		rf->hrdel_unread,
-		g_strdup(uid),
-		GINT_TO_POINTER(del_unread));
-	g_hash_table_insert(
-		rf->hrdel_notpresent,
-		g_strdup(uid),
-		GINT_TO_POINTER(del_notpresent));
-	g_hash_table_insert(
-		rf->hrupdate,
-		g_strdup(uid),
-		GINT_TO_POINTER(update));
-	g_hash_table_insert(
-		rf->hrttl,
-		g_strdup(uid),
-		GINT_TO_POINTER(ttl));
-	g_hash_table_insert(
-		rf->hrttl_multiply,
-		g_strdup(uid),
-		GINT_TO_POINTER(ttl_multiply));
-	xmlFreeDoc (doc);
-	return TRUE;
-}
-
-char *
-feeds_uid_from_xml (const char *xml)
-{
-	xmlNodePtr node;
-	xmlDocPtr doc;
-	char *uid = NULL;
-
-	if (!(doc = xmlParseDoc ((xmlChar *)xml)))
-		return NULL;
-
-	node = doc->children;
-	if (strcmp ((char *)node->name, "feed") != 0) {
-		xmlFreeDoc (doc);
-		return NULL;
-	}
-
-	xml_set_prop (node, "uid", &uid);
-	xmlFreeDoc (doc);
-
-	return uid;
-}
-
-void
-load_gconf_feed(void)
-{
-	GSList *list, *l = NULL;
-	char *uid;
-
-	list = gconf_client_get_list (rss_gconf,
-		"/apps/evolution/evolution-rss/feeds",
-		GCONF_VALUE_STRING, NULL);
-	for (l = list; l; l = l->next) {
-		uid = feeds_uid_from_xml (l->data);
-		if (!uid)
-			continue;
-
-		feed_new_from_xml (l->data);
-
-		g_free (uid);
-	}
-	g_slist_foreach(list, (GFunc) g_free, NULL);
-	g_slist_free(list);
-}
-
-void
-migrate_old_config(gchar *feed_file)
-{
-	FILE *ffile;
-	gchar rfeed[512];
-	char **str;
-	gpointer key;
-
-	memset(rfeed, 0, 512);
-
-	if ((ffile = fopen(feed_file, "r"))) {
-		while (fgets(rfeed, 511, ffile) != NULL) {
-			str = g_strsplit(rfeed, "--", 0);
-			key = gen_md5(str[1]);
-			g_hash_table_insert(rf->hrname,
-				g_strdup(str[0]),
-				g_strdup(key));
-			g_hash_table_insert(rf->hrname_r,
-				g_strdup(key),
-				g_strdup(str[0]));
-			g_hash_table_insert(rf->hr,
-				g_strdup(key),
-				g_strstrip(str[1]));
-			if (NULL != str[4]) {
-				g_hash_table_insert(rf->hrh,
-					g_strdup(key),
-					GINT_TO_POINTER(atoi(g_strstrip(str[4]))));
-				g_hash_table_insert(rf->hrt,
-					g_strdup(key),
-					g_strdup(str[3]));
-				g_hash_table_insert(rf->hre,
-					g_strdup(key),
-					GINT_TO_POINTER(atoi(str[2])));
-			} else {
-				if (NULL != str[2]) {    // 0.0.1 -> 0.0.2
-					g_hash_table_insert(rf->hrh,
-						g_strdup(key),
-						(gpointer)0);
-					g_hash_table_insert(rf->hrt,
-						g_strdup(key),
-						g_strstrip(str[3]));
-					g_hash_table_insert(rf->hre,
-						g_strdup(key),
-						GINT_TO_POINTER(atoi(str[2])));
-				} else {
-					g_hash_table_insert(rf->hrh,
-						g_strdup(key),
-						(gpointer)0);
-					g_hash_table_insert(rf->hrt,
-						g_strdup(key),
-						g_strdup("RSS"));
-					g_hash_table_insert(rf->hre,
-						g_strdup(key),
-						(gpointer)1);
-				}
-			}
-			g_free(key);
-		}
-		fclose(ffile);
-		save_gconf_feed();
-		unlink(feed_file);
-	}
-}
-
-void
-read_feeds(rssfeed *rf)
-{
-	gchar *feed_dir = rss_component_peek_base_directory();
-	gchar *feed_file;
-
-	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
-		g_mkdir_with_parents (feed_dir, 0755);
-	feed_file = g_strdup_printf("%s/evolution-feeds", feed_dir);
-	g_free(feed_dir);
-	rf->hrname =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, g_free);
-	rf->hrname_r =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, g_free);
-	rf->hr = g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, g_free);
-	rf->hre = g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-	rf->hrt =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, g_free);
-	rf->hrh =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-	rf->hruser =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, NULL, g_free);
-	rf->hrpass =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, NULL, g_free);
-	rf->hrdel_feed =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-	rf->hrdel_days =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-	rf->hrdel_messages =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-	rf->hrdel_unread =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-	rf->hrdel_notpresent =
-		g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-	rf->hrupdate = g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-	rf->hrttl = g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-	rf->hrttl_multiply = g_hash_table_new_full(
-			g_str_hash, g_str_equal, g_free, NULL);
-
-	if (g_file_test(feed_file, G_FILE_TEST_EXISTS))
-		migrate_old_config(feed_file);
-	else
-		load_gconf_feed();
-
-	g_free(feed_file);
-}
-
 static void
 summary_cb (GtkWidget *button, EMFormatHTMLPObject *pobject)
 {
@@ -3365,7 +2785,7 @@ finish_setup_feed(
 	RDF *r = NULL;
 	GString *content = NULL;
 	gchar *chn_name = NULL, *tmp_chn_name = NULL, *tmp = NULL;
-	gchar *real_name, *rssurl, *ver;
+	gchar *rssurl, *ver;
 	xmlDocPtr doc = NULL;
 	xmlNodePtr root = NULL;
 	gchar *tmsgkey;
@@ -3549,16 +2969,6 @@ add:
 			(GSourceFunc)display_feed_async,
 			g_strdup(chn_name));
 
-//		if (!rf->import) {
-		/* folder might not be created yet */
-/*		real_name = g_strdup_printf(
-			"%s" G_DIR_SEPARATOR_S "%s",
-			lookup_main_folder(),
-			lookup_feed_folder(chn_name));
-		rss_select_folder(real_name);
-		g_free(real_name);*/
-//		}
-
 		if (rf->cancel_all || rf->import_cancel)
 			goto out;
 
@@ -4312,68 +3722,6 @@ rss_component_peek_local_store(void)
 #endif
 }
 
-gchar *
-get_main_folder(void)
-{
-	gchar mf[512];
-	gchar *feed_file;
-	gchar *feed_dir = rss_component_peek_base_directory();
-
-	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
-		g_mkdir_with_parents (feed_dir, 0755);
-	feed_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "main_folder", feed_dir);
-	g_free(feed_dir);
-	if (g_file_test(feed_file, G_FILE_TEST_EXISTS)) {
-		FILE *f = fopen(feed_file, "r");
-		if (f) {
-			if (fgets(mf, 511, f) != NULL) {
-				fclose(f);
-				g_free(feed_file);
-				return g_strdup(mf);
-			}
-		}
-	}
-	g_free(feed_file);
-	return g_strdup(DEFAULT_FEEDS_FOLDER);
-}
-
-void
-get_feed_folders(void)
-{
-	gchar tmp1[512], tmp2[512];
-	gchar *feed_dir, *feed_file;
-
-	rf->feed_folders = g_hash_table_new_full(
-				g_str_hash,
-				g_str_equal,
-				g_free, g_free);
-	rf->reversed_feed_folders = g_hash_table_new_full(
-				g_str_hash,
-				g_str_equal,
-				g_free, g_free);
-	feed_dir = rss_component_peek_base_directory();
-	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
-		g_mkdir_with_parents (feed_dir, 0755);
-	feed_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "feed_folders", feed_dir);
-	g_free(feed_dir);
-	if (g_file_test(feed_file, G_FILE_TEST_EXISTS)) {
-		FILE *f = fopen(feed_file, "r");
-		while (!feof(f)) {
-			fgets(tmp1, 512, f);
-			fgets(tmp2, 512, f);
-			g_hash_table_insert(
-				rf->feed_folders,
-				g_strdup(g_strstrip(tmp1)),
-				g_strdup(g_strstrip(tmp2)));
-		}
-		fclose(f);
-	}
-	g_free(feed_file);
-	g_hash_table_foreach(
-		rf->feed_folders,
-		(GHFunc)populate_reversed,
-		rf->reversed_feed_folders);
-}
 
 //
 //lookups main feed folder name
@@ -4432,221 +3780,6 @@ lookup_chn_name_by_url(gchar *url)
 	return chn_name;
 }
 
-
-void
-#if LIBSOUP_VERSION < 2003000
-finish_update_feed_image (SoupMessage *msg, gpointer user_data)
-#else
-finish_update_feed_image (
-	SoupSession *soup_sess, SoupMessage *msg, gpointer user_data)
-#endif
-{
-	xmlChar *icon = NULL;
-	gchar *icon_url = NULL;
-	FEED_IMAGE *fi = NULL;
-	gchar *feed_dir = rss_component_peek_base_directory();
-	gchar *url = (gchar *)user_data;
-	gchar *key = gen_md5(url);
-	gchar *img_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.img", feed_dir, key);
-	gchar *urldir, *server;
-	rfMessage *rfmsg;
-	xmlChar *app;
-	xmlNode *doc;
-
-	g_free(feed_dir);
-	sanitize_path_separator(img_file);
-	urldir = g_path_get_dirname(url);
-	server = get_server_from_uri(url);
-	rfmsg = g_new0(rfMessage, 1);
-	rfmsg->status_code = msg->status_code;
-#if LIBSOUP_VERSION < 2003000
-	rfmsg->body = msg->response.body;
-	rfmsg->length = msg->response.length;
-#else
-	rfmsg->body = (gchar *)(msg->response_body->data);
-	rfmsg->length = msg->response_body->length;
-#endif
-	doc = (xmlNode *)parse_html_sux (rfmsg->body, rfmsg->length);
-	while (doc) {
-		doc = html_find(doc, (gchar *)"link");
-		if ((app = xmlGetProp(doc, (xmlChar *)"rel"))) {
-			if (!g_ascii_strcasecmp((char *)app, "shorcut icon")
-			|| !g_ascii_strcasecmp((char *)app, "icon")) {
-				icon = xmlGetProp(doc, (xmlChar *)"href");
-				break;
-			}
-		}
-		xmlFree(app);
-	}
-	g_free(rfmsg);
-	if (icon) {
-		if (strstr((char *)icon, "://") == NULL)
-			icon_url = g_strconcat(server, "/", icon, NULL);
-		else
-			icon_url = (char *)icon;
-
-		dup_auth_data(url, g_strdup(icon_url));
-		fi = g_new0(FEED_IMAGE, 1);
-		fi->img_file = g_strdup(img_file);
-		fi->key = g_strdup(key);
-		fetch_unblocking(
-			g_strdup(icon_url),
-			textcb,
-			NULL,
-			(gpointer)finish_create_icon,
-			fi,
-			0,
-//			&err);		// because we might lose it if
-			NULL);
-	} else {
-		//              r->image = NULL;
-		icon_url = g_strconcat(urldir, "/favicon.ico", NULL);
-		dup_auth_data(url, g_strdup(icon_url));
-		fi = g_new0(FEED_IMAGE, 1);
-		fi->img_file = g_strdup(img_file);
-		fi->key = g_strdup(key);
-		fetch_unblocking(
-				g_strdup(icon_url),
-				textcb,
-				NULL,
-				(gpointer)finish_create_icon,
-				fi,
-				0,
-//				&err);	// because we might lose it if
-				NULL);
-		g_free(icon_url);
-		icon_url = g_strconcat(server, "/favicon.ico", NULL);
-		dup_auth_data(url, g_strdup(icon_url));
-		fi = g_new0(FEED_IMAGE, 1);
-		fi->img_file = g_strdup(img_file);
-		fi->key = g_strdup(key);
-		fetch_unblocking(
-				g_strdup(icon_url),
-				textcb,
-				NULL,
-				(gpointer)finish_create_icon,
-				fi,
-				0,
-//				&err);	// because we might lose it if
-				NULL);
-	}
-	g_free(key);
-	g_free(img_file);
-	g_free(icon_url);
-	g_free(server);
-	g_free(urldir);
-	g_free(user_data);
-}
-
-gboolean
-check_update_feed_image(gchar *key)
-{
-	gchar *feed_dir = rss_component_peek_base_directory();
-	gchar *fav_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.fav", feed_dir, key);
-	struct timeval start;
-	FILE *f = NULL;
-	gboolean ret = TRUE;
-	unsigned long int remain;
-	gchar rfeed[80];
-	memset(rfeed, 0, 79);
-	gettimeofday(&start, NULL);
-	g_free(feed_dir);
-	if (!g_file_test(fav_file, G_FILE_TEST_EXISTS)) {
-		if ((f = fopen(fav_file, "w"))) {
-			fprintf(f, "%lu", start.tv_sec);
-			fclose(f);
-		}
-		ret = TRUE;
-		goto out;
-	}
-	if ((f = fopen(fav_file, "r+"))) {
-		fgets(rfeed, 50, f);
-		remain = start.tv_sec - strtoul(
-					(const char *)&rfeed, NULL, 10);
-		if (FEED_IMAGE_TTL <= remain) {
-			(void)fseek(f, 0L, SEEK_SET);
-			fprintf(f, "%lu", start.tv_sec);
-			fclose(f);
-			ret =  TRUE;
-			goto out;
-		} else {
-			d("next favicon will be fetched in %lu seconds\n",
-				FEED_IMAGE_TTL - remain);
-			fclose(f);
-			ret = FALSE;
-		}
-	}
-out:	g_free(fav_file);
-	return ret;
-}
-
-void
-dup_auth_data(gchar *origurl, gchar *url)
-{
-	gchar *user = g_hash_table_lookup(rf->hruser, origurl);
-	gchar *pass = g_hash_table_lookup(rf->hrpass, origurl);
-	if (user && pass) {
-		g_hash_table_insert(rf->hruser, url, g_strdup(user));
-		g_hash_table_insert(rf->hrpass, url, g_strdup(pass));
-	}
-}
-
-void
-update_feed_image(RDF *r)
-{
-	GError *err = NULL;
-	gchar *feed_file = NULL;
-	gchar *key = gen_md5(r->uri);
-	FEED_IMAGE *fi = g_new0(FEED_IMAGE, 1);
-	gchar *image = r->image;
-	gchar *feed_dir;
-
-	if (!check_update_feed_image(key))
-		goto out;
-	feed_dir = rss_component_peek_base_directory();
-	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
-		g_mkdir_with_parents (feed_dir, 0755);
-	feed_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.img", feed_dir, key);
-	d("feed_image() tmpurl:%s\n", feed_file);
-	g_free(feed_dir);
-	if (!g_file_test(feed_file, G_FILE_TEST_EXISTS)) {
-	if (image) {		//we need to validate image here with load_pixbuf
-		CamelStream *feed_fs = camel_stream_fs_new_with_name(feed_file,
-			O_RDWR|O_CREAT, 0666);
-		dup_auth_data(r->uri, image);
-		fi->feed_fs = feed_fs;
-		fi->key = g_strdup(key);
-		fetch_unblocking(image,
-			textcb,
-			NULL,
-			(gpointer)finish_create_icon_stream,
-			fi,
-			0,
-			&err);
-		if (err) {
-			g_print("ERR:%s\n", err->message);
-			goto out;
-		}
-	} else {
-		gchar *server = get_server_from_uri(r->uri);
-		//authentication data might be different
-		dup_auth_data(r->uri, server);
-		fetch_unblocking(
-			server,
-			textcb,
-			NULL,
-			(gpointer)finish_update_feed_image,
-			g_strdup(r->uri),// we need to dupe key here
-			0,
-			&err);		// because we might loose it if
-		g_free(server);
-					// feeds get deleted
-	}
-	}
-out:	g_free(feed_file);
-	g_free(key);
-}
-
 void
 update_main_folder(gchar *new_name)
 {
@@ -5297,16 +4430,8 @@ void org_gnome_cooly_rss_startup(void *ep, ESEventTargetUpgrade *t)
 	}
 	custom_feed_timeout();
 
-	/* load transparency */
-	pixfile = g_build_filename (EVOLUTION_ICONDIR,
-			"pix.png",
-			NULL);
-	g_file_load_contents (g_file_parse_name(pixfile),
-			NULL,
-			&pixfilebuf,
-			&pixfilelen,
-			NULL,
-			NULL);
+	rss_load_images();
+
 
 	/* hook in rename event to catch feeds folder rename */
 	store = rss_component_peek_local_store();
@@ -6413,410 +5538,7 @@ finish_enclosure (SoupSession *soup_sess,
 				NULL);
 }
 
-void
-#if LIBSOUP_VERSION < 2003000
-finish_image_feedback (SoupMessage *msg, FEED_IMAGE *user_data)
-#else
-finish_image_feedback (SoupSession *soup_sess, SoupMessage *msg, FEED_IMAGE *user_data)
-#endif
-{
-	CamelStream *stream = NULL;
-	stream = rss_cache_add(user_data->url);
-	finish_image(soup_sess, msg, stream);
-	if (user_data->data == current_pobject)
-		em_format_redraw((EMFormat *)user_data->data);
-	g_free(user_data->url);
-	g_free(user_data);
-}
-
-void
-#if LIBSOUP_VERSION < 2003000
-finish_image (SoupMessage *msg, CamelStream *user_data)
-#else
-finish_image (SoupSession *soup_sess, SoupMessage *msg, CamelStream *user_data)
-#endif
-{
-	d("CODE:%d\n", msg->status_code);
-	// we might need to handle more error codes here
-	if (503 != msg->status_code && //handle this timedly fasion
-	    404 != msg->status_code && //NOT FOUND
-	    400 != msg->status_code && //bad request
-	      2 != msg->status_code && //STATUS_CANT_RESOLVE
-	      1 != msg->status_code && //TIMEOUT (CANCELLED) ?
-	      7 != msg->status_code && // STATUS_IO_ERROR
-#if LIBSOUP_VERSION < 2003000
-		msg->response.length) {	//ZERO SIZE
-#else
-		msg->response_body->length) { //ZERO SIZE
-#endif
-#if LIBSOUP_VERSION < 2003000
-		if (msg->response.body) {
-			camel_stream_write(user_data,
-				msg->response.body,
-				msg->response.length);
-#else
-		if (msg->response_body->data) {
-			camel_stream_write(user_data,
-				msg->response_body->data,
-				msg->response_body->length);
-#endif
-			camel_stream_close(user_data);
-#if (DATASERVER_VERSION >= 2031001)
-			g_object_unref(user_data);
-#else
-			camel_object_unref(user_data);
-#endif
-		}
-	} else {
-		camel_stream_write(user_data, pixfilebuf, pixfilelen);
-		camel_stream_close(user_data);
-#if (DATASERVER_VERSION >= 2031001)
-		g_object_unref(user_data);
-#else
-		camel_object_unref(user_data);
-#endif
-	}
-}
-
-void
-#if LIBSOUP_VERSION < 2003000
-finish_create_icon (SoupMessage *msg, FEED_IMAGE *user_data)
-#else
-finish_create_icon (SoupSession *soup_sess, SoupMessage *msg, FEED_IMAGE *user_data)
-#endif
-{
-	d("finish_image(): status:%d, user_data:%s\n", msg->status_code, user_data->img_file);
-	if (404 != msg->status_code) {
-		CamelStream *feed_fs = camel_stream_fs_new_with_name(user_data->img_file,
-			O_RDWR|O_CREAT, 0666);
-		finish_image(soup_sess, msg, feed_fs);
-#if (EVOLUTION_VERSION >= 22703)
-		display_folder_icon(evolution_store, user_data->key);
-#endif
-	}
-	g_free(user_data->key);
-	g_free(user_data);
-}
-
-void
-#if LIBSOUP_VERSION < 2003000
-finish_create_icon_stream (
-	SoupMessage *msg, FEED_IMAGE *user_data)
-#else
-finish_create_icon_stream (
-	SoupSession *soup_sess, SoupMessage *msg, FEED_IMAGE *user_data)
-#endif
-{
-	finish_image(soup_sess, msg, user_data->feed_fs);
-#if (EVOLUTION_VERSION >= 22703)
-	display_folder_icon(evolution_store, user_data->key);
-#endif
-	g_free(user_data->key);
-	g_free(user_data);
-}
-
-#if (EVOLUTION_VERSION >= 22703)
-gboolean
-display_folder_icon(GtkTreeStore *tree_store, gchar *key)
-{
-	gchar *feed_dir = rss_component_peek_base_directory();
-	gchar *img_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.img", feed_dir, key);
-	GdkPixbuf *icon, *pixbuf;
-	gboolean result = FALSE;
-	GtkTreeIter iter;
-	GtkTreePath *path;
-	GtkTreeRowReference *row;
-	EMFolderTreeModel *mod = (EMFolderTreeModel *)tree_store;
-	struct _EMFolderTreeModelStoreInfo *si;
-	CamelStore *store = rss_component_peek_local_store();
-	CamelFolder *rss_folder;
-	gint i=0, size;
-	gint *sizes;
-
-	g_return_val_if_fail(mod != NULL, FALSE);
-
-	pixbuf = gdk_pixbuf_new_from_file(img_file, NULL);
-
-	if (pixbuf) {
-		gchar *name = g_hash_table_lookup(rf->hrname_r, key);
-		gchar *full_name = g_strdup_printf(
-					"%s" G_DIR_SEPARATOR_S "%s",
-					get_main_folder(),
-					lookup_feed_folder(name));
-		rss_folder = camel_store_get_folder (
-					store,
-					full_name, 0, NULL);
-		if (!rss_folder) {
-			g_free(full_name);
-			result = FALSE;
-			goto out;
-		}
-		icon = rss_build_icon (img_file, GTK_ICON_SIZE_MENU);
-		d("icon:%p\n", icon);
-		g_hash_table_insert(icons,
-			g_strdup(key), GINT_TO_POINTER(1));
-		sizes = gtk_icon_theme_get_icon_sizes(
-				gtk_icon_theme_get_default(),
-				"mail-read"); //will mail-read always be there?
-		for (i=0; 0 != (size = sizes[i]); i++)
-			d("icon set size:%d\n", size);
-			gtk_icon_theme_add_builtin_icon(key,
-				size,
-				icon);
-		g_free(sizes);
-
-#if EVOLUTION_VERSION < 22900 //kb//
-		si = g_hash_table_lookup (mod->store_hash, store);
-#else
-		si = em_folder_tree_model_lookup_store_info (
-			EM_FOLDER_TREE_MODEL (mod), store);
-#endif
-		row = g_hash_table_lookup (si->full_hash, full_name);
-		if (!row) goto out;
-		path = gtk_tree_row_reference_get_path (row);
-		gtk_tree_model_get_iter (
-			(GtkTreeModel *)tree_store, &iter, path);
-		gtk_tree_path_free (path);
-
-		gtk_tree_store_set(
-				tree_store, &iter,
-				COL_STRING_ICON_NAME, key,
-				-1);
-		g_free(full_name);
-#if (DATASERVER_VERSION >= 2031001)
-		g_object_unref (rss_folder);
-#else
-		camel_object_unref (rss_folder);
-#endif
-		g_object_unref(pixbuf);
-		result = TRUE;
-	}
-out:	g_free(img_file);
-	g_free(feed_dir);
-	return result;
-}
-#endif
-
-/* validates if image is indeed an image file
- * if image file is not found it tries to fetch it
- * we need to check mime time against content
- * because we could end up with wrong file as image
- */
-gchar *
-verify_image(gchar *uri, EMFormatHTML *format)
-{
-	gchar *mime_type, *contents;
-	gsize length;
-	gchar *nurl, *turl;
-	gchar *base_dir, *feed_dir, *name;
-	gchar *scheme, *result;
-
-	g_return_val_if_fail(uri != NULL, NULL);
-
-	if (!g_file_test((gchar *)uri, G_FILE_TEST_EXISTS)) {
-			camel_url_decode((gchar *)uri);
-			//FIXME lame method of extracting data cache path
-			//there must be a function in camel for getting data cache path
-			base_dir = rss_component_peek_base_directory();
-			feed_dir = g_build_path(G_DIR_SEPARATOR_S,
-				base_dir,
-				"static",
-				"http",
-				NULL);
-			scheme = g_uri_parse_scheme(uri);
-			/* calling fetch_image_redraw with link NULL
-			 * as we do not have base link here
-			 * and not able to get it either
-			 */
-			if (!scheme) {
-				nurl = strextr((gchar *)uri, feed_dir);
-				g_free(feed_dir);
-				turl = nurl + 4;
-				name = fetch_image_redraw(turl, NULL, format);
-				g_free(nurl);
-			} else {
-				turl = uri;
-				name = fetch_image_redraw(uri, NULL, format);
-				g_free(scheme);
-			}
-			g_free(base_dir);
-			result = g_filename_to_uri (name, NULL, NULL);
-			g_free(name);
-			return result;
-	} else {
-		/*need to get mime type via file contents or else mime type is
-		 * bound to be wrong, especially on files fetched from the web
-		 * this is very important as we might get quite a few images
-		 * missing otherwise */
-		g_file_get_contents (uri,
-			&contents,
-			&length,
-			NULL);
-		mime_type = g_content_type_guess(NULL, (guchar *)contents, length, NULL);
-		/*FIXME mime type here could be wrong */
-		if (g_ascii_strncasecmp (mime_type, "image/", 6)) {
-			result = g_filename_to_uri (pixfile, NULL, NULL);
-			return result;
-		}
-		g_free(mime_type);
-		g_free(contents);
-/*
- * appears the default has changed in efh_url_requested
- * the new default is file://
- * http://git.gnome.org/browse/evolution/commit/?id=d9deaf9bbc7fd9d0c72d5cf9b1981e3a56ed1162
- */
-#if (EVOLUTION_VERSION >= 23000)
-		return g_filename_to_uri(uri, NULL, NULL);
-#else
-		return NULL;
-#endif
-	}
-}
-
-// constructs url from @base in case url is relative
-gchar *
-fetch_image_redraw(gchar *url, gchar *link, gpointer data)
-{
-	GError *err = NULL;
-	gchar *tmpurl = NULL;
-	FEED_IMAGE *fi = NULL;
-	gchar *result, *safe, *cache_file;
-
-	g_return_val_if_fail(url != NULL, NULL);
-
-	if (strstr(url, "://") == NULL) {
-		if (*url == '.') //test case when url begins with ".."
-			tmpurl = g_strconcat(
-					g_path_get_dirname(link),
-					"/", url, NULL);
-		else {
-			if (*url == '/')
-				tmpurl = g_strconcat(
-						get_server_from_uri(link),
-						"/", url, NULL);
-			else	//url is relative (does not begin with / or .)
-				tmpurl = g_strconcat(
-						g_path_get_dirname(link),
-						"/", url, NULL);
-		}
-	} else {
-		tmpurl = g_strdup(url);
-	}
-
-	if (!tmpurl)
-		return NULL;
-
-	safe = g_compute_checksum_for_string (
-			G_CHECKSUM_SHA1, tmpurl, -1);
-	if (g_hash_table_find(rf->key_session,
-			check_key_match,
-			tmpurl)) {
-		goto working;
-	}
-	d("fetch_image_redraw() tmpurl:%s, safe url:%s\n", tmpurl, safe);
-	cache_file = rss_cache_get_filename(safe);
-	if (!g_file_test (cache_file, G_FILE_TEST_EXISTS)) {
-		d("image cache MISS\n");
-		if (data) {
-			fi = g_new0(FEED_IMAGE, 1);
-			fi->url = g_strdup(safe);
-			fi->data = data;
-			fetch_unblocking(tmpurl,
-				textcb,
-				g_strdup(tmpurl),
-				(gpointer)finish_image_feedback,
-				fi,
-				1,
-				&err);
-		} else {
-			CamelStream *stream = rss_cache_add(safe);
-			fetch_unblocking(tmpurl,
-				textcb,
-				NULL,
-				(gpointer)finish_image,
-				stream,
-				0,
-				&err);
-		}
-		if (err) {
-			result = NULL;
-			g_free(cache_file);
-			goto error;
-		}
-	} else {
-		d("image cache HIT\n");
-	}
-	g_free(cache_file);
-
-working:result = rss_cache_get_path(FALSE, safe);
-error:	g_free(tmpurl);
-	g_free(safe);
-	return result;
-}
-
-
-//migrates old feed data files from crc naming
-//to md5 naming while preserving content
-//
-//this will be obsoleted over a release or two
-
-void
-migrate_crc_md5(const char *name, gchar *url)
-{
-	gchar *crc = gen_crc(name);
-	gchar *crc2 = gen_crc(url);
-	gchar *md5, *md5_name, *feed_dir, *feed_name;
-
-	md5 = gen_md5(url);
-	feed_dir = rss_component_peek_base_directory();
-	if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
-		g_mkdir_with_parents (feed_dir, 0755);
-
-	md5_name = g_build_path(G_DIR_SEPARATOR_S, feed_dir, md5, NULL);
-	feed_name = g_build_path(G_DIR_SEPARATOR_S, feed_dir, crc, NULL);
-	g_free(crc);
-	g_free(md5);
-
-	if (g_file_test(feed_name, G_FILE_TEST_EXISTS)) {
-		FILE *fr = fopen(feed_name, "r");
-		FILE *fw = fopen(md5_name, "a+");
-		gchar rfeed[513];
-		memset(rfeed, 0, 512);
-		if (fr && fw) {
-			while (fgets(rfeed, 511, fr) != NULL) {
-				(void)fseek(fw, 0L, SEEK_SET);
-				fwrite(rfeed, strlen(rfeed), 1, fw);
-			}
-			fclose(fw);
-			unlink(feed_name);
-		}
-		fclose(fr);
-
-	}
-	g_free(feed_name);
-	feed_name = g_build_path(G_DIR_SEPARATOR_S, feed_dir, crc2, NULL);
-	g_free(crc2);
-	if (g_file_test(feed_name, G_FILE_TEST_EXISTS)) {
-		FILE *fr = fopen(feed_name, "r");
-		FILE *fw = fopen(md5_name, "a+");
-		gchar rfeed[513];
-		memset(rfeed, 0, 512);
-		if (fr && fw) {
-			while (fgets(rfeed, 511, fr) != NULL) {
-				(void)fseek(fw, 0L, SEEK_SET);
-				fwrite(rfeed, strlen(rfeed), 1, fw);
-			}
-			fclose(fw);
-			unlink(feed_name);
-		}
-		fclose(fr);
-
-	}
-
-	g_free(feed_name);
-	g_free(feed_dir);
-	g_free(md5_name);
-}
+gchar *update_comments(RDF *r);
 
 gchar *
 update_comments(RDF *r)
@@ -6908,6 +5630,8 @@ display_doc (RDF *r)
 	return title;
 }
 
+void delete_oldest_article(CamelFolder *folder, guint unread);
+
 void
 delete_oldest_article(CamelFolder *folder, guint unread)
 {
@@ -7057,8 +5781,8 @@ get_feed_age(RDF *r, gpointer name)
 		g_print("notpresent done\n");
 	}
 	if (del_feed == 2) {
-		g_print("feed ==2\n");
 		guint del_days = GPOINTER_TO_INT(g_hash_table_lookup(rf->hrdel_days, key));
+		g_print("feed ==2\n");
 		uids = camel_folder_get_uids (folder);
 		camel_folder_freeze(folder);
 		for (i = 0; i < uids->len; i++) {
@@ -7090,9 +5814,9 @@ get_feed_age(RDF *r, gpointer name)
 		g_print("feed ==2 done\n");
 	}
 	if (del_feed == 1) {
-	g_print("del?\n");
 		guint del_messages = GPOINTER_TO_INT(g_hash_table_lookup(rf->hrdel_messages, key));
 		guint total = camel_folder_get_message_count(folder);
+	g_print("del?\n");
 		i=1;
 		while (del_messages < camel_folder_get_message_count(folder)
 			- camel_folder_get_deleted_message_count(folder) && i <= total) {
diff --git a/src/rss.h b/src/rss.h
index 3b8fc2d..7ea5d20 100644
--- a/src/rss.h
+++ b/src/rss.h
@@ -367,16 +367,10 @@ gboolean proxy_auth_dialog(
 
 gboolean timeout_soup(void);
 void network_timeout(void);
-gchar *feed_to_xml(gchar *key);
 void prepare_feed(
 	gpointer key,
 	gpointer value,
 	gpointer user_data);
-gboolean feed_new_from_xml(char *xml);
-char *feeds_uid_from_xml (const char *xml);
-void load_gconf_feed(void);
-void migrate_old_config(gchar *feed_file);
-void read_feeds(rssfeed *rf);
 void reload_cb (GtkWidget *button, gpointer data);
 void gecko_set_preferences(void);
 void browser_copy_selection(
@@ -422,7 +416,6 @@ gchar *get_real_channel_name(gchar *uri, gchar *failed);
 gchar *fetch_image(gchar *url, gchar *link);
 gchar *fetch_image_redraw(gchar *url, gchar *link, gpointer data);
 void create_mail(create_feed *CF);
-void migrate_crc_md5(const char *name, gchar *url);
 void free_cf(create_feed *CF);
 gchar *generate_safe_chn_name(gchar *chn_name);
 void update_sr_message(void);
@@ -496,7 +489,6 @@ void custom_feed_timeout(void);
 CamelFolder *check_feed_folder(gchar *folder_name);
 gboolean setup_feed(add_feed *feed);
 void web_auth_dialog(RSS_AUTH *auth_info);
-gchar *get_main_folder(void);
 gpointer lookup_key(gpointer key);
 void rss_delete_feed(gchar *name, gboolean folder);
 gint update_feed_folder(
@@ -517,7 +509,6 @@ void get_shell(void *ep, ESEventTargetShell *t);
 //#endif
 void rss_finalize(void);
 gboolean check_update_feed_image(gchar *key);
-void get_feed_folders(void);
 void update_main_folder(gchar *new_name);
 void search_rebase(gpointer key, gpointer value, gchar *oname);
 void evo_window_popup(GtkWidget *window);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]