[evolution-rss] part of Bug 586205 - Add folder support to OPML import/export



commit 8452a42cd1f663fefb0930846b3c376c78f304a1
Author: Lucian Langa <lucilanga gnome org>
Date:   Wed Jul 15 07:50:46 2009 +0300

    part of Bug 586205 - Add folder support to OPML import/export

 TODO                     |    2 +
 src/parser.c             |   23 ++-----
 src/rss-config-factory.c |  167 ++++++++++++++++++++++++++++++++++++++++++----
 src/rss.c                |   35 +++++++---
 src/rss.h                |    2 +
 5 files changed, 189 insertions(+), 40 deletions(-)
---
diff --git a/TODO b/TODO
index ee421de..f8e9143 100644
--- a/TODO
+++ b/TODO
@@ -43,3 +43,5 @@
 	* detect duplicate items by content not by feedid
 	* make gtkhtml rendering non-bloking
  	* check webkit user agent
+	* use ellipsize in web auth dialog
+	* check feed_folders for errors
diff --git a/src/parser.c b/src/parser.c
index f63911f..9badd48 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -309,9 +309,6 @@ xmlNode *
 html_find (xmlNode *node,
             char *match)
 {
-#ifdef RDF_DEBUG
-g_print("parser entry 3_1!!!\n");
-#endif
 	while (node) {
 #ifdef RDF_DEBUG
                 xmlDebugDumpNode (stdout, node, 32);
@@ -322,30 +319,16 @@ g_print("parser entry 3_1!!!\n");
                 else {
                         while (node && !node->next)
                                 node = node->parent;
-                        //if (!node || node == top)
                         if (!node)
-{
-#ifdef RDF_DEBUG
-g_print("parser error 3_2 -> return NULL!!!\n");
-#endif
                                 return NULL;
-}
                         node = node->next;
                 }
 
                 if (node->name) {
                         if (!strcmp ((char *)node->name, match))
-{
-#ifdef RDF_DEBUG
-g_print("parser error 3_3 -> return NULL!!!\n");
-#endif
                                 return node;
-}
                 }
         }
-#ifdef RDF_DEBUG
-g_print("parser error 3_4 -> return NULL!!!\n");
-#endif
         return NULL;
 }
 
@@ -1078,7 +1061,11 @@ update_channel(RDF *r)
 		g_array_append_val(r->uids, uid);
 		CF->feedid 	= g_strdup(buf);
 		CF->sender 	= g_strdup(sender);
-		CF->full_path 	= g_strdup(chn_name);
+		if (r->prefix)
+			CF->full_path	= g_strconcat(r->prefix, "/", chn_name, NULL);
+		else
+			CF->full_path 	= g_strdup(chn_name);
+
 		subj = CF->subj;
 
 		while (gtk_events_pending())
diff --git a/src/rss-config-factory.c b/src/rss-config-factory.c
index ef353a8..177a5ee 100644
--- a/src/rss-config-factory.c
+++ b/src/rss-config-factory.c
@@ -309,14 +309,18 @@ construct_list(gpointer key, gpointer value, gpointer user_data)
         GtkTreeIter    iter;
 
         gtk_list_store_append (store, &iter);
-	gchar *name = g_path_get_basename(lookup_feed_folder(key));
+	gchar *full_name = lookup_feed_folder(key);
+	gchar *name = g_path_get_basename(full_name);
+	gchar *full_path = g_strconcat(lookup_main_folder(), "/", full_name, NULL);
         gtk_list_store_set (store, &iter,
                 0, g_hash_table_lookup(rf->hre, lookup_key(key)),
                 1, name,
                 2, g_hash_table_lookup(rf->hrt, lookup_key(key)),
 		3, key,
+		4, full_path,
                 -1);
 	g_free(name);
+	g_free(full_path);
 }
 
 static void
@@ -890,7 +894,7 @@ delete_response(GtkWidget *selector, guint response, gpointer user_data)
         if (response == GTK_RESPONSE_OK) {
                 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(user_data));
                 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
-                        gtk_tree_model_get (model, &iter, 3, &name, -1);
+                        gtk_tree_model_get (model, &iter, 4, &name, -1);
 			rss_delete_feed(name,
 				gconf_client_get_bool(rss_gconf, GCONF_KEY_REMOVE_FOLDER, NULL));
                         g_free(name);
@@ -1129,7 +1133,7 @@ import_dialog_response(GtkWidget *selector, guint response, gpointer user_data)
 }
 
 gboolean
-import_one_feed(gchar *url, gchar *title)
+import_one_feed(gchar *url, gchar *title, gchar *prefix)
 {
         add_feed *feed = g_new0(add_feed, 1);
         feed->changed=0;
@@ -1139,6 +1143,7 @@ import_one_feed(gchar *url, gchar *title)
 	feed->enabled = feed_enabled;
 	feed->feed_url = g_strdup(url);
 	feed->feed_name = decode_html_entities(title);
+	feed->prefix = prefix;
 	/* we'll get rid of this as soon as we fetch unblocking */
         if (g_hash_table_find(rf->hr,
                                      check_if_match,
@@ -1221,7 +1226,6 @@ import_opml(gchar *file)
         gtk_widget_show_all(import_dialog);
         g_free(msg);
 	if ((src=src->children)) {
-		d(g_print("found %s\n", src->name));
 		if (!g_ascii_strcasecmp((char *)src->name, "rdf")) {
 			while (src) {
 				src=src->children;
@@ -1236,7 +1240,7 @@ import_opml(gchar *file)
                 			}
 					if (name) xmlFree(name);
 				}
-			g_print("total:%d\n", total);
+			d(g_print("total:%d\n", total));
 			type = 1;
 			}
 		}
@@ -1250,7 +1254,7 @@ import_opml(gchar *file)
 				if (name) xmlFree(name);
         		}
 			type = 0;
-			g_print("total:%d\n", total);
+			d(g_print("total:%d\n", total));
 		}
 	}	
         src = doc;
@@ -1271,6 +1275,85 @@ import_opml(gchar *file)
 		d(g_print("group name:%s\n", layer_find(src, "name", NULL)));
 		src = src->next;
 	}
+
+	gint size = 0;
+	gchar *base = NULL, *root = NULL, *last = NULL;
+	gchar *rssprefix = NULL, *rssurl = NULL, *rsstitle = NULL;
+	while (src) {
+		if (rf->cancel) {
+			if (src) xmlFree(src);
+			rf->cancel = 0;
+			goto out;
+		}
+                if (src->children)
+                        src = src->children;
+                else {
+                        while (src && !src->next) {
+                                src = src->parent;
+				g_print("<-");
+				last =  g_path_get_basename(root);
+				if (last && strcmp(last, ".")) {
+					g_print("retract:%s\n", last);
+					size = strstr(root, last)-root-1;
+					gchar *tmp = root;
+					if (size > 0)
+						root = g_strndup(root, size);
+					else
+						root = NULL;
+					g_free(last);
+					if (tmp) g_free(tmp);
+				}
+			}
+                        if (!src) break;
+                        src = src->next;
+                }
+                if (src->name) {
+			gchar *prop = (gchar *)xmlGetProp(src, (xmlChar *)"type");
+			if (prop) {
+				if (!strcmp(prop, "folder")) {
+					base = (gchar *)xmlGetProp(src, (xmlChar *)"text");
+					if (NULL != src->last) {
+						gchar *tmp = root;
+						if (!root)
+							root = g_build_path("/", base, NULL);
+						else
+							root = g_build_path("/", root, base, NULL);
+						if (base) xmlFree(base);
+						if (tmp) g_free(tmp);
+					}
+				// we're insterested in rss/pie only
+				// we might just handle all variations of type= property
+				} else if (strcmp(prop, "link")) {
+					rssprefix = root;
+					rssurl = (gchar *)xmlGetProp(src, (xmlChar *)"xmlUrl");
+					rsstitle = (gchar *)xmlGetProp(src, (xmlChar *)"title");
+					gtk_label_set_text(GTK_LABEL(import_label), (gchar *)rsstitle);
+#if GTK_VERSION >= 2006000
+					gtk_label_set_ellipsize (GTK_LABEL (import_label), PANGO_ELLIPSIZE_START);
+#endif
+					gtk_label_set_justify(GTK_LABEL(import_label), GTK_JUSTIFY_CENTER);
+					import_one_feed(rssurl, rsstitle, rssprefix);
+					if (rssurl) xmlFree(rssurl);
+					if (rsstitle) xmlFree(rsstitle);
+                        		while (gtk_events_pending ())
+                                		gtk_main_iteration ();
+					current++;
+					float fr = ((current*100)/total);
+					gtk_progress_bar_set_fraction((GtkProgressBar *)import_progress, fr/100);
+					what = g_strdup_printf(_("%2.0f%% done"), fr);
+					gtk_progress_bar_set_text((GtkProgressBar *)import_progress, what);
+					g_free(what);
+					while (gtk_events_pending ())
+						gtk_main_iteration ();
+					store_redraw(GTK_TREE_VIEW(rf->treeview));
+					save_gconf_feed();
+				}
+			xmlFree(prop);
+			}
+                }
+        }
+
+	goto out;
 	while ((src = iterate_import_file(src, &url, &name, type))) {
                 if (url && strlen(url)) {
 			d(g_print("url:%s\n", url));
@@ -1284,7 +1367,7 @@ import_opml(gchar *file)
                         gtk_label_set_ellipsize (GTK_LABEL (import_label), PANGO_ELLIPSIZE_START);
 #endif
                         gtk_label_set_justify(GTK_LABEL(import_label), GTK_JUSTIFY_CENTER);
-			import_one_feed(url, (gchar *)name);
+			import_one_feed(url, (gchar *)name, NULL);
 			if (name) xmlFree(name);
 			if (url) xmlFree(url);
 
@@ -1558,14 +1641,72 @@ import_cb (GtkWidget *widget, gpointer data)
 }
 
 static void
+get_folder_info (CamelStore *store, CamelFolderInfo *info, CamelException *ex)
+{
+while (info) {
+                CamelFolder *fold;
+		gchar **path, *fpath;
+		gint i=0;
+
+                if (info->child) {
+			get_folder_info(store, info->child, ex);
+                        if (camel_exception_is_set (ex))
+                                return;
+                }
+
+                if (!(fold = camel_store_get_folder (store, info->full_name, 0, ex)))
+                        return;
+
+//		g_print("fold:%s\n", fold->full_name);
+		fpath = extract_main_folder(fold->full_name);
+		g_print("fpath:%s\n", fpath);
+	
+		path = g_strsplit(fpath, "/", 0);
+		if (path) {
+			do {
+				g_print("path:%s\n", path[i]);
+			} while (NULL != path[i++]);
+		}
+
+                info = info->next;
+        }
+
+
+}
+
+static void
 construct_opml_line(gpointer key, gpointer value, gpointer user_data)
 {
         gchar *url = g_hash_table_lookup(rf->hr, value);
         gchar *type = g_hash_table_lookup(rf->hrt, value);
         gchar *url_esc = g_markup_escape_text(url, strlen(url));
         gchar *key_esc = g_markup_escape_text(key, strlen(key));
-        gchar *tmp = g_strdup_printf("<outline text=\"%s\" title=\"%s\" type=\"%s\" xmlUrl=\"%s\" htmlUrl=\"%s\"/>\n",
-                key_esc, key_esc, type, url_esc, url_esc);
+	g_print("value:%s\n", g_hash_table_lookup(rf->hrname_r, value));
+	g_print("name:%s\n", g_path_get_dirname(g_hash_table_lookup(rf->hrname_r, value)));
+
+
+CamelFolderInfo *info;
+	CamelStore *store = mail_component_peek_local_store(NULL);
+        CamelException ex;
+        gint response;
+        guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_FAST;
+
+
+        camel_exception_init (&ex);
+
+        info = camel_store_get_folder_info (store, "News and Blogs", flags, &ex);
+
+        if (camel_exception_is_set (&ex))
+                goto out;
+	get_folder_info(store, info, &ex);
+
+out:
+        camel_store_free_folder_info(store, info);
+
+
+        //gchar *tmp = g_strdup_printf("<outline text=\"%s\" title=\"%s\" type=\"%s\" xmlUrl=\"%s\" htmlUrl=\"%s\"/>\n",
+        gchar *tmp = g_strdup_printf("<outline text=\"%s\" title=\"%s\" type=\"rss\" xmlUrl=\"%s\" htmlUrl=\"%s\"/>\n",
+                key_esc, key_esc, url_esc, url_esc);
         if (buffer != NULL)
                 buffer = g_strconcat(buffer, tmp, NULL);
         else
@@ -1615,6 +1756,7 @@ export_opml(gchar *file)
                 buffer);
         g_free(buffer);
 
+#if 0
         if (g_file_test (file, G_FILE_TEST_IS_REGULAR)) {
                 GtkWidget *dlg;
 
@@ -1634,6 +1776,7 @@ export_opml(gchar *file)
                 goto over;
         else
                 goto out;
+#endif
 
 over:   f = fopen(file, "w+");
         if (f) {
@@ -2144,8 +2287,6 @@ rss_folder_factory (EPlugin *epl, EConfigHookItemFactoryData *data)
 	gchar *folder = target->folder->full_name;
 	add_feed *feed = NULL;
 
-	g_print("folder:%s\n", folder);
-	g_print("main_folder:%s\n", main_folder);
 	//filter only rss folders
 	if (folder == NULL
           || g_ascii_strncasecmp(folder, main_folder, strlen(main_folder))
@@ -2210,8 +2351,8 @@ rss_config_control_new (void)
 
 	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
 
-	store = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING,
-                                G_TYPE_STRING, G_TYPE_STRING);
+	store = gtk_list_store_new (5, G_TYPE_BOOLEAN, G_TYPE_STRING,
+                                G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 
 	gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), (GtkTreeModel *)store);
 
diff --git a/src/rss.c b/src/rss.c
index 69df342..76fd76d 100644
--- a/src/rss.c
+++ b/src/rss.c
@@ -2502,7 +2502,9 @@ top:	d(g_print("adding feed->feed_url:%s\n", feed->feed_url));
         content = fetch_blocking(feed->feed_url, NULL, post, textcb, rf, &err);
         if (err) {
 		g_print("setup_feed() -> err:%s\n", err->message);
-		rss_error(NULL, feed->feed_name ? feed->feed_name: _("Unamed feed"), _("Error while fetching feed."), err->message);
+		gchar *tmpkey = gen_md5(feed->feed_url);
+		rss_error(tmpkey, feed->feed_name ? feed->feed_name: _("Unamed feed"), _("Error while fetching feed."), err->message);
+		g_free(tmpkey);
 		goto out;
         }
         xmlDocPtr doc = NULL;
@@ -2538,6 +2540,9 @@ add:
 		chn_name = sanitize_folder(chn_name);
 		tmp = chn_name;
                	chn_name = generate_safe_chn_name(chn_name);
+		if (feed->prefix)
+			chn_name = g_build_path("/", feed->prefix, chn_name, NULL);
+		r->prefix = feed->prefix;
 		
 		gpointer crc_feed = gen_md5(feed->feed_url);
 		g_hash_table_insert(rf->hrname, 
@@ -3475,6 +3480,10 @@ check_feed_folder(gchar *folder_name)
 {
 	CamelStore *store = mail_component_peek_local_store(NULL);
 	CamelFolder *mail_folder;
+	char **path = NULL;
+	gint i=0;
+	gchar *base_folder;
+
 	gchar *main_folder = lookup_main_folder();
 	gchar *real_folder = lookup_feed_folder(folder_name);
 	gchar *real_name = g_strdup_printf("%s/%s", main_folder, real_folder);
@@ -3482,8 +3491,16 @@ check_feed_folder(gchar *folder_name)
 	d(g_print("real_folder:%s\n", real_folder));
 	d(g_print("real_name:%s\n", real_name));
         mail_folder = camel_store_get_folder (store, real_name, 0, NULL);
+	base_folder = main_folder;
 	if (mail_folder == NULL) {
-                camel_store_create_folder (store, main_folder, real_folder, NULL);
+        	path = g_strsplit(real_folder, "/", 0);
+		if (path) {
+			do {
+               			camel_store_create_folder (store, base_folder, path[i], NULL);
+				base_folder = g_strconcat(base_folder, "/", path[i], NULL);
+			} while (NULL != path[++i]);
+			g_strfreev(path);
+		}
                 mail_folder = camel_store_get_folder (store, real_name, 0, NULL);
         }
 	g_free(real_name);
@@ -3492,14 +3509,14 @@ check_feed_folder(gchar *folder_name)
 }
 
 void
-rss_delete_feed(gchar *name, gboolean folder)
+rss_delete_feed(gchar *full_path, gboolean folder)
 {
         CamelException ex;
 	gchar *tmp;
         CamelStore *store = mail_component_peek_local_store(NULL);
-        gchar *full_path = g_strdup_printf("%s/%s",
-                lookup_main_folder(),
-                lookup_feed_folder(name));
+	gchar *name = extract_main_folder(full_path);
+	if (!name)
+		return;
         delete_feed_folder_alloc(lookup_feed_folder(name));
         camel_exception_init (&ex);
         rss_delete_folders (store, full_path, &ex);
@@ -3508,7 +3525,6 @@ rss_delete_feed(gchar *name, gboolean folder)
                 "mail:no-delete-folder", full_path, ex.desc, NULL);
                 camel_exception_clear (&ex);
         }
-        g_free(full_path);
         //also remove status file
         gchar *tkey = g_hash_table_lookup(rf->hrname, name);
 	if (!tkey)
@@ -3530,6 +3546,7 @@ rss_delete_feed(gchar *name, gboolean folder)
 	g_free(tmp);
 out:	if (folder)
 		remove_feed_hash(name);
+	g_free(name);
         save_gconf_feed();
 }
 
@@ -3537,8 +3554,8 @@ static void
 store_folder_deleted(CamelObject *o, void *event_data, void *data)
 {
 	CamelFolderInfo *info = event_data;
-	printf("Folder deleted '%s'\n", info->name);
-	rss_delete_feed(info->name, 1);
+	d(printf("Folder deleted '%s' full '%s'\n", info->name, info->full_name));
+	rss_delete_feed(info->full_name, 1);
 }
 
 static void
diff --git a/src/rss.h b/src/rss.h
index 5f68f0c..9a0a36a 100644
--- a/src/rss.h
+++ b/src/rss.h
@@ -59,6 +59,7 @@ typedef struct _RDF {
 	gchar		*version;	//feed version
         gchar		*feedid;  	//md5 string id of feed
 	gchar		*title;		//title of the feed
+	gchar		*prefix;	//directory path
 	gchar		*maindate;	//channel date
 	GArray		*item;		//feed content
 	gchar		*image;		//feed image
@@ -189,6 +190,7 @@ typedef struct ADD_FEED {
 	GladeXML	*gui;
         gchar           *feed_url;
 	gchar		*feed_name;
+	gchar 		*prefix;
         gboolean        fetch_html;	//show webpage instead of summary
         gboolean        add;		//ok button
 	gboolean	changed;



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