]> spindle.queued.net Git - midori/commitdiff
Improve XBEL format compatibility and support bookmark sharing
authorChristian Dywan <christian@twotoasts.de>
Sun, 29 Nov 2009 22:50:59 +0000 (23:50 +0100)
committerChristian Dywan <christian@twotoasts.de>
Mon, 30 Nov 2009 18:36:15 +0000 (19:36 +0100)
Loading of XBEL needs to handle title and desc children of the root
element. This is equal to using the according properties.

MicroB uses metadata without an owner and uses children rather than
properties. This is against the spec but we want to handle that.

A key value leak was plugged.

If the bookmark file is absolute, we assume it is a foreign file
and we shouldn't overwrite it.

midori/main.c
midori/midori-array.c

index c31b4754069eb53fad9e569a1da630947a55fd96..a52f521bd97e53583cfb8481aad1c7fe01456e11 100644 (file)
     #include <signal.h>
 #endif
 
+#if HAVE_HILDON
+    #define BOOKMARK_FILE "/home/user/.bookmarks/MyBookmarks.xml"
+#else
+    #define BOOKMARK_FILE "bookmarks.xbel"
+#endif
+
 #define MIDORI_HISTORY_ERROR g_quark_from_string("MIDORI_HISTORY_ERROR")
 
 typedef enum
@@ -62,7 +68,11 @@ typedef enum
 static gchar*
 build_config_filename (const gchar* filename)
 {
-    const gchar* path = sokoke_set_config_dir (NULL);
+    const gchar* path;
+
+    if (g_path_is_absolute (filename))
+        return g_strdup (filename);
+    path = sokoke_set_config_dir (NULL);
     return g_build_filename (path, filename, NULL);
 }
 
@@ -805,7 +815,7 @@ midori_bookmarks_notify_item_cb (KatzeArray* folder,
     gchar* config_file;
     GError* error;
 
-    config_file = build_config_filename ("bookmarks.xbel");
+    config_file = build_config_filename (BOOKMARK_FILE);
     error = NULL;
     if (!midori_array_to_file (bookmarks, config_file, "xbel", &error))
     {
@@ -833,7 +843,7 @@ midori_bookmarks_add_item_cb (KatzeArray* folder,
     gchar* config_file;
     GError* error;
 
-    config_file = build_config_filename ("bookmarks.xbel");
+    config_file = build_config_filename (BOOKMARK_FILE);
     error = NULL;
     if (!midori_array_to_file (bookmarks, config_file, "xbel", &error))
     {
@@ -862,7 +872,7 @@ midori_bookmarks_remove_item_cb (KatzeArray* folder,
     gchar* config_file;
     GError* error;
 
-    config_file = build_config_filename ("bookmarks.xbel");
+    config_file = build_config_filename (BOOKMARK_FILE);
     error = NULL;
     if (!midori_array_to_file (bookmarks, config_file, "xbel", &error))
     {
@@ -1864,7 +1874,7 @@ main (int    argc,
     }
     bookmarks = katze_array_new (KATZE_TYPE_ARRAY);
     #if HAVE_LIBXML
-    katze_assign (config_file, build_config_filename ("bookmarks.xbel"));
+    katze_assign (config_file, build_config_filename (BOOKMARK_FILE));
     error = NULL;
     if (!midori_array_from_file (bookmarks, config_file, "xbel", &error))
     {
@@ -2016,8 +2026,9 @@ main (int    argc,
                     G_CALLBACK (midori_search_engines_modify_cb), search_engines);
         }
     }
-    katze_assign (config_file, build_config_filename ("bookmarks.xbel"));
-    if (1)
+    katze_assign (config_file, build_config_filename (BOOKMARK_FILE));
+    /* Don't save bookmarks if they are not our own */
+    if (!g_path_is_absolute (BOOKMARK_FILE))
     {
         g_signal_connect_after (bookmarks, "add-item",
             G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
index e68a3077c6e11d0ad783f989c38f737e23f16927..18aeece033b9f95818f6a4a884a09890a61c8e44 100644 (file)
@@ -93,11 +93,13 @@ katze_array_from_xmlNodePtr (xmlNodePtr cur)
         {
             key = xmlNodeGetContent (cur);
             katze_item_set_name (KATZE_ITEM (array), g_strstrip ((gchar*)key));
+            xmlFree (key);
         }
         else if (!xmlStrcmp (cur->name, (const xmlChar*)"desc"))
         {
             key = xmlNodeGetContent (cur);
             katze_item_set_text (KATZE_ITEM (array), g_strstrip ((gchar*)key));
+            xmlFree (key);
         }
         else if (!xmlStrcmp (cur->name, (const xmlChar*)"folder"))
         {
@@ -129,19 +131,26 @@ katze_xbel_parse_info (KatzeItem* item,
         if (!xmlStrcmp (cur->name, (const xmlChar*)"metadata"))
         {
             xmlChar* owner = xmlGetProp (cur, (xmlChar*)"owner");
-            g_strstrip ((gchar*)owner);
+            if (owner)
+                g_strstrip ((gchar*)owner);
+            else
+                /* Albeit required, "owner" is not set by MicroB */
+                owner = (xmlChar*)NULL;
             /* FIXME: Save metadata from unknown owners */
-            if (!g_strcmp0 ((gchar*)owner, "http://www.twotoasts.de"))
+            if (!owner || !strcmp ((gchar*)owner, "http://www.twotoasts.de"))
             {
                 xmlAttrPtr properties = cur->properties;
+                xmlNodePtr children = cur->children;
                 while (properties)
                 {
+                    xmlChar* value;
+
                     if (!xmlStrcmp (properties->name, (xmlChar*)"owner"))
                     {
                         properties = properties->next;
                         continue;
                     }
-                    xmlChar* value = xmlGetProp (cur, properties->name);
+                    value = xmlGetProp (cur, properties->name);
                     if (properties->ns && properties->ns->prefix)
                     {
                         gchar* ns_value = g_strdup_printf ("%s:%s",
@@ -156,6 +165,26 @@ katze_xbel_parse_info (KatzeItem* item,
                     xmlFree (value);
                     properties = properties->next;
                 }
+                while (children)
+                {
+                    xmlNodePtr grand_children = children->children;
+                    while (grand_children)
+                    {
+                        xmlChar* value = grand_children->content;
+                        gchar* ns_value;
+                        if (!owner)
+                            ns_value = g_strdup_printf (":%s", children->name);
+                        else if (xmlStrEqual (owner, (xmlChar*)"http://www.twotoasts.de"))
+                            ns_value = g_strdup_printf ("midori:%s", children->name);
+                        else /* FIXME: Save metadata from unknown owners */
+                            ns_value = g_strdup_printf (":%s", children->name);
+                        katze_item_set_meta_string (item, ns_value, (gchar*)value);
+                        g_free (ns_value);
+                        grand_children = grand_children->next;
+                    }
+
+                    children = children->next;
+                }
             }
             xmlFree (owner);
         }
@@ -211,6 +240,16 @@ katze_array_from_xmlDocPtr (KatzeArray* array,
             item = katze_item_new ();
         else if (!xmlStrcmp (cur->name, (const xmlChar*)"info"))
             katze_xbel_parse_info (KATZE_ITEM (array), cur);
+        else if (!xmlStrcmp (cur->name, (xmlChar*)"title"))
+        {
+            xmlNodePtr node = cur->xmlChildrenNode;
+            katze_item_set_name (KATZE_ITEM (array), (gchar*)node->content);
+        }
+        else if (!xmlStrcmp (cur->name, (xmlChar*)"desc"))
+        {
+            xmlNodePtr node = cur->xmlChildrenNode;
+            katze_item_set_text (KATZE_ITEM (array), (gchar*)node->content);
+        }
         if (item)
             katze_array_add_item (array, item);
         cur = cur->next;
@@ -480,28 +519,47 @@ katze_item_metadata_to_xbel (KatzeItem* item)
 {
     GList* keys = katze_item_get_meta_keys (item);
     GString* markup;
-    /* FIXME: Allow specifying an alternative namespace/ URI */
-    const gchar* namespace_uri = "http://www.twotoasts.de";
-    const gchar* namespace = "midori";
+    GString* markdown;
+    /* FIXME: Allow specifying an alternative default namespace */
+    /* FIXME: Support foreign namespaces with their own URI */
+    gchar* namespace = NULL;
+    const gchar* namespace_uri;
     gsize i;
     const gchar* key;
+    const gchar* value;
 
     if (!keys)
         return g_strdup ("");
 
-    markup = g_string_new ("<info>\n<metadata owner=\"");
-    g_string_append_printf (markup, "%s\"", namespace_uri);
+    markup = g_string_new ("<info>\n<metadata");
+    markdown = g_string_new (NULL);
     i = 0;
     while ((key = g_list_nth_data (keys, i++)))
-        if (katze_item_get_meta_string (item, key))
+        if ((value = katze_item_get_meta_string (item, key)))
         {
-            gchar* escaped =
-                g_markup_escape_text (katze_item_get_meta_string (item, key), -1);
-            g_string_append_printf (markup, " %s:%s=\"%s\"", namespace, key,
-                escaped);
+            gchar* escaped = g_markup_escape_text (value, -1);
+            namespace = strchr (key, ':');
+            if (key[0] == ':') /* MicroB uses un-namespaced children */
+            {
+                key = &key[1];
+                g_string_append_printf (markdown, "<%s>%s</%s>\n", key, escaped, key);
+            }
+            else if (namespace)
+                g_string_append_printf (markup, " %s=\"%s\"", key, escaped);
+            else
+                g_string_append_printf (markup, " midori:%s=\"%s\"", key, escaped);
             g_free (escaped);
         }
-    g_string_append_printf (markup, "/>\n</info>\n");
+    if (!namespace)
+    {
+        namespace_uri = "http://www.twotoasts.de";
+        g_string_append_printf (markup, " owner=\"%s\"", namespace_uri);
+    }
+    if (markdown->len)
+        g_string_append_printf (markup, ">\n%s</metadata>\n</info>\n", markdown->str);
+    else
+        g_string_append_printf (markup, "/>\n</info>\n");
+    g_string_free (markdown, TRUE);
     return g_string_free (markup, FALSE);
 }