[evolution-rss] part of Bug 586205 - Add folder support to OPML import/export
- From: Lucian Langa <lucilanga src gnome org>
- To: svn-commits-list gnome org
- Subject: [evolution-rss] part of Bug 586205 - Add folder support to OPML import/export
- Date: Wed, 15 Jul 2009 04:54:18 +0000 (UTC)
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]