aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--configure.in4
-rw-r--r--src/bookmarks/ephy-bookmarks-import.c339
3 files changed, 274 insertions, 82 deletions
diff --git a/ChangeLog b/ChangeLog
index 025550f3e..8a63d033c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2003-09-03 Christian Persch <chpe@cvs.gnome.org>
+ * src/bookmarks/ephy-bookmarks-import.c: (xbel_parse_single_bookmark),
+ (xbel_parse_bookmark), (xbel_parse_folder), (xbel_parse_bookmarks),
+ (ephy_bookmarks_import_xbel):
+
+ Rewrote xbel bookmarks importer using xmlreader api. Should fix
+ bug 120803.
+
+ * configure.in:
+
+ Require libxml2 >= 2.5.9
+
+2003-09-03 Christian Persch <chpe@cvs.gnome.org>
+
* src/bookmarks/ephy-bookmarks-editor.c: (add_bookmarks_source_menu),
(cmd_bookmarks_import):
diff --git a/configure.in b/configure.in
index fcc09bdc4..94639a035 100644
--- a/configure.in
+++ b/configure.in
@@ -16,9 +16,11 @@ ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
GTK_REQUIRED=2.3
LIBBONOBOUI_REQUIRED=2.1.1
+LIBXML_REQUIRED=2.5.9
AC_SUBST(LIBBONOBOUI_REQUIRED)
AC_SUBST(GTK_REQUIRED)
+AC_SUBST(LIBXML_REQUIRED)
AC_ENABLE_SHARED(yes)
AC_ENABLE_STATIC(no)
@@ -66,7 +68,7 @@ fi
AC_MSG_RESULT($enable_nautilus_view)
AM_CONDITIONAL(ENABLE_NAUTILUS_VIEW, test "x$enable_nautilus_view" = "xyes")
-PKG_CHECK_MODULES(EPIPHANY_DEPENDENCY, gtk+-2.0 >= $GTK_REQUIRED libxml-2.0 libgnomeui-2.0 libglade-2.0 bonobo-activation-2.0 libbonoboui-2.0 >= $LIBBONOBOUI_REQUIRED ORBit-2.0 libglade-2.0 gnome-vfs-2.0 gnome-vfs-module-2.0 gconf-2.0 $nautilusview_pkgs)
+PKG_CHECK_MODULES(EPIPHANY_DEPENDENCY, gtk+-2.0 >= $GTK_REQUIRED libxml-2.0 >= $LIBXML_REQUIRED libgnomeui-2.0 libglade-2.0 bonobo-activation-2.0 libbonoboui-2.0 >= $LIBBONOBOUI_REQUIRED ORBit-2.0 libglade-2.0 gnome-vfs-2.0 gnome-vfs-module-2.0 gconf-2.0 $nautilusview_pkgs)
AC_SUBST(EPIPHANY_DEPENDENCY_CFLAGS)
AC_SUBST(EPIPHANY_DEPENDENCY_LIBS)
diff --git a/src/bookmarks/ephy-bookmarks-import.c b/src/bookmarks/ephy-bookmarks-import.c
index 3ebffe624..1310ef0f8 100644
--- a/src/bookmarks/ephy-bookmarks-import.c
+++ b/src/bookmarks/ephy-bookmarks-import.c
@@ -14,13 +14,22 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <glib.h>
#include <libxml/HTMLtree.h>
+#include <libxml/xmlreader.h>
#include <string.h>
#include <libgnomevfs/gnome-vfs-mime-utils.h>
+#include <bonobo/bonobo-i18n.h>
+
#include "ephy-bookmarks-import.h"
#include "ephy-debug.h"
@@ -37,12 +46,6 @@ typedef enum
NS_UNKNOWN
} NSItemType;
-typedef struct _XbelInfo
-{
- char *title;
- char *smarturl;
-} XbelInfo;
-
static EphyNode *
bookmark_add (EphyBookmarks *bookmarks,
const char *title,
@@ -103,113 +106,285 @@ ephy_bookmarks_import (EphyBookmarks *bookmarks,
return FALSE;
}
-static void
-xbel_parse_single_bookmark (EphyBookmarks *bookmarks,
- xmlNodePtr node, XbelInfo *xbel)
+/* XBEL import */
+
+typedef enum
{
- xmlNodePtr child = node;
+ STATE_FOLDER,
+ STATE_BOOKMARK,
+ STATE_TITLE,
+ STATE_DESC,
+ STATE_INFO,
+ STATE_METADATA,
+ STATE_SMARTURL
+} EphyXBELImporterState;
- while (child != NULL)
+static EphyNode *
+xbel_parse_bookmark (EphyBookmarks *eb, xmlTextReaderPtr reader)
+{
+ EphyXBELImporterState state = STATE_BOOKMARK;
+ EphyNode *node;
+ xmlChar *title = NULL;
+ xmlChar *address = NULL;
+ int ret = 1;
+
+ while (ret == 1)
{
- if (xmlStrEqual (child->name, "title"))
+ xmlChar *tag;
+ xmlReaderTypes type;
+
+ tag = xmlTextReaderName (reader);
+ g_return_val_if_fail (tag != NULL, NULL);
+
+ type = xmlTextReaderNodeType (reader);
+
+ if (xmlStrEqual (tag, "#text"))
+ {
+ if (state == STATE_TITLE && title == NULL)
+ {
+ title = xmlTextReaderValue (reader);
+ }
+ else if (state == STATE_SMARTURL)
+ {
+ xmlFree (address);
+ address = xmlTextReaderValue (reader);
+ }
+ else
+ {
+ /* eat it */
+ }
+ }
+ else if (xmlStrEqual (tag, "bookmark"))
+ {
+ if (type == XML_READER_TYPE_ELEMENT && state == STATE_BOOKMARK && address == NULL)
+ {
+ address = xmlTextReaderGetAttribute (reader, "href");
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT && state == STATE_BOOKMARK)
+ {
+ /* we're done */
+
+ break;
+ }
+ }
+ else if (xmlStrEqual (tag, "title"))
+ {
+ if (type == XML_READER_TYPE_ELEMENT && state == STATE_BOOKMARK && title == NULL)
+ {
+ state = STATE_TITLE;
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT && state == STATE_TITLE)
+ {
+ state = STATE_BOOKMARK;
+ }
+ }
+ else if (xmlStrEqual (tag, "desc"))
{
- xbel->title = xmlNodeGetContent (child);
+ if (type == XML_READER_TYPE_ELEMENT && state == STATE_BOOKMARK)
+ {
+ state = STATE_DESC;
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT && state == STATE_DESC)
+ {
+ state = STATE_BOOKMARK;
+ }
}
- else if (xmlStrEqual (child->name, "info"))
+ else if (xmlStrEqual (tag, "info"))
{
- xbel_parse_single_bookmark (bookmarks,
- child->children,
- xbel);
+ if (type == XML_READER_TYPE_ELEMENT && state == STATE_BOOKMARK)
+ {
+ state = STATE_INFO;
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT && state == STATE_INFO)
+ {
+ state = STATE_BOOKMARK;
+ }
}
- else if (xmlStrEqual (child->name, "metadata"))
+ else if (xmlStrEqual (tag, "metadata"))
{
- xbel_parse_single_bookmark (bookmarks,
- child->children,
- xbel);
+ if (type == XML_READER_TYPE_ELEMENT && state == STATE_INFO)
+ {
+ state = STATE_METADATA;
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT && state == STATE_METADATA)
+ {
+ state = STATE_INFO;
+ }
}
- else if (xmlStrEqual (child->name, "smarturl"))
+ else if (xmlStrEqual (tag, "smarturl"))
{
- xbel->smarturl = xmlNodeGetContent (child);
+ if (type == XML_READER_TYPE_ELEMENT && state == STATE_METADATA)
+ {
+ state = STATE_SMARTURL;
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT && state == STATE_SMARTURL)
+ {
+ state = STATE_METADATA;
+ }
}
- child = child->next;
+ xmlFree (tag);
+
+ /* next one, please */
+ ret = xmlTextReaderRead (reader);
+ }
+
+ g_return_val_if_fail (address != NULL, NULL);
+
+ if (title == NULL)
+ {
+ title = xmlStrdup (_("Untitled"));
}
+
+ node = bookmark_add (eb, title, address, NULL);
+ if (node == NULL)
+ {
+ /* probably a duplicate */
+ node = ephy_bookmarks_find_bookmark (eb, address);
+ }
+
+ xmlFree (title);
+ xmlFree (address);
+
+ return node;
}
-static void
-xbel_parse_folder (EphyBookmarks *bookmarks,
- xmlNodePtr node)
+static GList *
+xbel_parse_folder (EphyBookmarks *eb, xmlTextReaderPtr reader)
{
- xmlNodePtr child = node;
- xmlChar *keyword = NULL;
+ EphyXBELImporterState state = STATE_FOLDER;
+ EphyNode *keyword;
+ GList *list = NULL, *l;
+ xmlChar *title = NULL;
+ int ret;
- while (child != NULL)
+ ret = xmlTextReaderRead (reader);
+
+ while (ret == 1)
{
- if (xmlStrEqual (child->name, "title"))
+ xmlChar *tag;
+ xmlReaderTypes type;
+
+ tag = xmlTextReaderName (reader);
+ type = xmlTextReaderNodeType (reader);
+
+ if (tag == NULL)
{
- keyword = xmlNodeGetContent (child);
+ /* shouldn't happen but does anyway :) */
}
- else if (xmlStrEqual (child->name, "bookmark"))
+ else if (xmlStrEqual (tag, "#text"))
{
- XbelInfo *xbel;
- xmlChar *url;
-
- xbel = g_new0 (XbelInfo, 1);
- xbel->title = NULL;
- xbel->smarturl = NULL;
-
- url = xmlGetProp (child, "href");
-
- xbel_parse_single_bookmark (bookmarks,
- child->children,
- xbel);
+ if (state == STATE_TITLE && title == NULL)
+ {
+ title = xmlTextReaderValue (reader);
+ }
+ else
+ {
+ /* eat it */
+ }
+ }
+ else if (xmlStrEqual (tag, "bookmark") && type == 1 && state == STATE_FOLDER)
+ {
+ EphyNode *node;
- bookmark_add (bookmarks, xbel->title, url, keyword);
+ node = xbel_parse_bookmark (eb, reader);
- xmlFree (url);
+ if (EPHY_IS_NODE (node))
+ {
+ list = g_list_prepend (list, node);
+ }
+ }
+ else if ((xmlStrEqual (tag, "folder") || xmlStrEqual (tag, "xbel"))
+ && state == STATE_FOLDER)
+ {
+ if (type == XML_READER_TYPE_ELEMENT)
+ {
+ GList *sublist;
- if (xbel && xbel->title)
- xmlFree (xbel->title);
+ sublist = xbel_parse_folder (eb, reader);
- if (xbel && xbel->smarturl)
- xmlFree (xbel->smarturl);
+ list = g_list_concat (list, sublist);
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT)
+ {
+ /* we're done */
- g_free (xbel);
+ break;
+ }
}
- else if (xmlStrEqual (child->name, "folder"))
+ else if (xmlStrEqual (tag, "title"))
{
- xbel_parse_folder (bookmarks,
- child->children);
-
- g_free (keyword);
- keyword = NULL;
+ if (type == XML_READER_TYPE_ELEMENT && state == STATE_FOLDER)
+ {
+ state = STATE_TITLE;
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT && state == STATE_TITLE)
+ {
+ state = STATE_FOLDER;
+ }
+ }
+ else if (xmlStrEqual (tag, "info"))
+ {
+ if (type == XML_READER_TYPE_ELEMENT && state == STATE_FOLDER)
+ {
+ state = STATE_INFO;
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT && state == STATE_INFO)
+ {
+ state = STATE_FOLDER;
+ }
+ }
+ else if (xmlStrEqual (tag, "desc"))
+ {
+ if (type == XML_READER_TYPE_ELEMENT && state == STATE_FOLDER)
+ {
+ state = STATE_DESC;
+ }
+ else if (type == XML_READER_TYPE_END_ELEMENT && state == STATE_DESC)
+ {
+ state = STATE_FOLDER;
+ }
+ }
+ else
+ {
+ /* eat it */
}
- child = child->next;
+ xmlFree (tag);
+
+ /* next one, please */
+ ret = xmlTextReaderRead (reader);
}
- g_free (keyword);
-}
+ /* tag all bookmarks in the list with keyword %title */
+ if (title == NULL)
+ {
+ title = xmlStrdup (_("Untitled"));
+ }
+ keyword = ephy_bookmarks_find_keyword (eb, title, FALSE);
-static void
-xbel_parse_bookmarks (EphyBookmarks *bookmarks,
- xmlNodePtr node)
-{
- xmlNodePtr child = node;
+ if (keyword == NULL)
+ {
+ keyword = ephy_bookmarks_add_keyword (eb, title);
+ }
- while (child != NULL)
+ xmlFree (title);
+
+ g_return_val_if_fail (EPHY_IS_NODE (keyword), list);
+
+ for (l = list; l != NULL; l = l->next)
{
- if (xmlStrEqual (child->name, "xbel"))
- {
- xbel_parse_folder (bookmarks,
- child->children);
- }
+ EphyNode *node = (EphyNode *) l->data;
- child = child->next;
+ ephy_bookmarks_set_keyword (eb, keyword, node);
}
+
+ return list;
}
+/* Mozilla/Netscape import */
+
static gchar *
gul_general_read_line_from_file (FILE *f)
{
@@ -430,19 +605,21 @@ gboolean
ephy_bookmarks_import_xbel (EphyBookmarks *bookmarks,
const char *filename)
{
- xmlDocPtr doc;
- xmlNodePtr child;
+ xmlTextReaderPtr reader;
+ GList *list;
if (g_file_test (filename, G_FILE_TEST_EXISTS) == FALSE)
+ {
return FALSE;
+ }
+
+ reader = xmlNewTextReaderFilename (filename);
+ g_return_val_if_fail (reader != NULL, FALSE);
- doc = xmlParseFile (filename);
- g_assert (doc != NULL);
-
- child = doc->children;
- xbel_parse_bookmarks (bookmarks, child);
+ list = xbel_parse_folder (bookmarks, reader);
- xmlFreeDoc (doc);
+ g_list_free (list);
+ xmlFreeTextReader (reader);
return TRUE;
}