aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bookmarks/ephy-bookmarks-import.c339
1 files changed, 258 insertions, 81 deletions
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;
}