Support importing bookmarks from Opera 6 bookmark files
This commit is contained in:
parent
fd7d778e0c
commit
308b9dd07d
2 changed files with 157 additions and 24 deletions
|
@ -15,6 +15,7 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <glib/gstdio.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#if HAVE_LIBXML
|
#if HAVE_LIBXML
|
||||||
|
@ -217,15 +218,96 @@ katze_array_from_xmlDocPtr (KatzeArray* array,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
katze_array_from_opera_file (KatzeArray* array,
|
||||||
|
FILE* file)
|
||||||
|
{
|
||||||
|
gchar line[200];
|
||||||
|
KatzeArray* folder = array;
|
||||||
|
KatzeItem* item = NULL;
|
||||||
|
|
||||||
|
while (fgets (line, 200, file))
|
||||||
|
{
|
||||||
|
g_strstrip (line);
|
||||||
|
if (line[0] == '\0')
|
||||||
|
{
|
||||||
|
item = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (line[0] == '-')
|
||||||
|
{
|
||||||
|
item = NULL;
|
||||||
|
if (folder != array)
|
||||||
|
folder = katze_item_get_parent ((KatzeItem*)folder);
|
||||||
|
else
|
||||||
|
g_warning ("A level-up although we are at the top level");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line[0] == '#')
|
||||||
|
{
|
||||||
|
const gchar* element = &line[1];
|
||||||
|
if (!g_ascii_strncasecmp (element, "FOLDER", 6))
|
||||||
|
{
|
||||||
|
item = (KatzeItem*)katze_array_new (KATZE_TYPE_ARRAY);
|
||||||
|
katze_array_add_item (folder, item);
|
||||||
|
folder = (KatzeArray*)item;
|
||||||
|
}
|
||||||
|
else if (!g_ascii_strncasecmp (element, "URL", 3))
|
||||||
|
{
|
||||||
|
item = katze_item_new ();
|
||||||
|
katze_array_add_item (folder, item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning ("Unexpected element: %s", element);
|
||||||
|
}
|
||||||
|
else if (item)
|
||||||
|
{
|
||||||
|
gchar** parts = g_strsplit (line, "=", 2);
|
||||||
|
if (parts && parts[0] && parts[1])
|
||||||
|
{
|
||||||
|
if (g_str_equal (parts[0], "NAME"))
|
||||||
|
katze_item_set_name (item, parts[1]);
|
||||||
|
else if (g_str_equal (parts[0], "URL"))
|
||||||
|
katze_item_set_uri (item, parts[1]);
|
||||||
|
else if (g_str_equal (parts[0], "DESCRIPTION"))
|
||||||
|
katze_item_set_text (item, parts[1]);
|
||||||
|
else if (g_str_equal (parts[0], "CREATED"))
|
||||||
|
katze_item_set_added (item,
|
||||||
|
g_ascii_strtoull (parts[1], NULL, 10));
|
||||||
|
/* FIXME: Implement visited time
|
||||||
|
else if (g_str_equal (parts[0], "VISITED"))
|
||||||
|
katze_item_set_visited (item,
|
||||||
|
g_ascii_strtoull (parts[1], NULL, 10)); */
|
||||||
|
/* FIXME: Implement bookmarkbar flag
|
||||||
|
else if (g_str_equal (parts[0], "ON PERSONALBAR"))
|
||||||
|
; */
|
||||||
|
/* FIXME: Implement websites as panels
|
||||||
|
else if (g_str_equal (parts[0], "IN PANEL"))
|
||||||
|
; */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning ("Broken property: %s", line);
|
||||||
|
g_strfreev (parts);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning ("Unexpected property outside of element: %s", line);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* midori_array_from_file:
|
* midori_array_from_file:
|
||||||
* @array: a #KatzeArray
|
* @array: a #KatzeArray
|
||||||
* @filename: a filename to load from
|
* @filename: a filename to load from
|
||||||
* @format: the desired format
|
* @format: "xbel", "opera", or %NULL
|
||||||
* @error: a #GError or %NULL
|
* @error: a #GError or %NULL
|
||||||
*
|
*
|
||||||
* Loads the contents of a file in the specified format.
|
* Loads the contents of a file in the specified format.
|
||||||
*
|
*
|
||||||
|
* Since 0.2.2 @format can be %NULL to indicate that the
|
||||||
|
* file should be loaded if it's any supported format.
|
||||||
|
*
|
||||||
* Return value: %TRUE on success, %FALSE otherwise
|
* Return value: %TRUE on success, %FALSE otherwise
|
||||||
*
|
*
|
||||||
* Since: 0.1.6
|
* Since: 0.1.6
|
||||||
|
@ -236,11 +318,8 @@ midori_array_from_file (KatzeArray* array,
|
||||||
const gchar* format,
|
const gchar* format,
|
||||||
GError** error)
|
GError** error)
|
||||||
{
|
{
|
||||||
xmlDocPtr doc;
|
|
||||||
|
|
||||||
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), FALSE);
|
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), FALSE);
|
||||||
g_return_val_if_fail (filename != NULL, FALSE);
|
g_return_val_if_fail (filename != NULL, FALSE);
|
||||||
g_return_val_if_fail (!g_strcmp0 (format, "xbel"), FALSE);
|
|
||||||
g_return_val_if_fail (!error || !*error, FALSE);
|
g_return_val_if_fail (!error || !*error, FALSE);
|
||||||
|
|
||||||
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||||
|
@ -252,6 +331,51 @@ midori_array_from_file (KatzeArray* array,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Opera6 */
|
||||||
|
if (!g_strcmp0 (format, "opera")
|
||||||
|
|| (!format && g_str_has_suffix (filename, ".adr")))
|
||||||
|
{
|
||||||
|
FILE* file;
|
||||||
|
if ((file = g_fopen (filename, "r")))
|
||||||
|
{
|
||||||
|
guint verify;
|
||||||
|
gchar line[50];
|
||||||
|
|
||||||
|
verify = 0;
|
||||||
|
while (fgets (line, 50, file))
|
||||||
|
{
|
||||||
|
g_strstrip (line);
|
||||||
|
if (verify == 0 && !strcmp (line, "Opera Hotlist version 2.0"))
|
||||||
|
verify++;
|
||||||
|
else if (verify == 1
|
||||||
|
&& !strcmp (line, "Options: encoding = utf8, version=3"))
|
||||||
|
verify++;
|
||||||
|
else if (verify == 2)
|
||||||
|
{
|
||||||
|
if (!katze_array_from_opera_file (array, file))
|
||||||
|
{
|
||||||
|
/* Parsing failed */
|
||||||
|
fclose (file);
|
||||||
|
if (error)
|
||||||
|
*error = g_error_new_literal (G_FILE_ERROR,
|
||||||
|
G_FILE_ERROR_FAILED, _("Malformed document."));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose (file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XBEL */
|
||||||
|
if (!g_strcmp0 (format, "xbel")
|
||||||
|
|| !format)
|
||||||
|
{
|
||||||
|
xmlDocPtr doc;
|
||||||
|
|
||||||
if ((doc = xmlParseFile (filename)) == NULL)
|
if ((doc = xmlParseFile (filename)) == NULL)
|
||||||
{
|
{
|
||||||
/* No valid xml or broken encoding */
|
/* No valid xml or broken encoding */
|
||||||
|
@ -272,6 +396,12 @@ midori_array_from_file (KatzeArray* array,
|
||||||
}
|
}
|
||||||
xmlFreeDoc (doc);
|
xmlFreeDoc (doc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
*error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||||
|
_("Unrecognized bookmark format."));
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -4031,6 +4031,7 @@ _action_bookmarks_import_activate (GtkAction* action,
|
||||||
} BookmarkClient;
|
} BookmarkClient;
|
||||||
static const BookmarkClient bookmark_clients[] = {
|
static const BookmarkClient bookmark_clients[] = {
|
||||||
{ ".local/share/data/Arora/bookmarks.xbel", N_("Arora") },
|
{ ".local/share/data/Arora/bookmarks.xbel", N_("Arora") },
|
||||||
|
{ ".opera/bookmarks.adr", N_("Opera") },
|
||||||
};
|
};
|
||||||
|
|
||||||
GtkWidget* dialog;
|
GtkWidget* dialog;
|
||||||
|
@ -4039,6 +4040,7 @@ _action_bookmarks_import_activate (GtkAction* action,
|
||||||
GtkWidget* label;
|
GtkWidget* label;
|
||||||
GtkWidget* combo;
|
GtkWidget* combo;
|
||||||
GtkComboBox* combobox;
|
GtkComboBox* combobox;
|
||||||
|
GtkComboBox* combobox_folder;
|
||||||
guint i;
|
guint i;
|
||||||
KatzeItem* item;
|
KatzeItem* item;
|
||||||
|
|
||||||
|
@ -4082,16 +4084,17 @@ _action_bookmarks_import_activate (GtkAction* action,
|
||||||
gtk_size_group_add_widget (sizegroup, label);
|
gtk_size_group_add_widget (sizegroup, label);
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||||
combo = gtk_combo_box_new_text ();
|
combo = gtk_combo_box_new_text ();
|
||||||
combobox = GTK_COMBO_BOX (combo);
|
combobox_folder = GTK_COMBO_BOX (combo);
|
||||||
gtk_combo_box_append_text (combobox, _("Toplevel folder"));
|
gtk_combo_box_append_text (combobox_folder, _("Toplevel folder"));
|
||||||
gtk_combo_box_set_active (combobox, 0);
|
gtk_combo_box_set_active (combobox_folder, 0);
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((item = katze_array_get_nth_item (browser->bookmarks, i++)))
|
while ((item = katze_array_get_nth_item (browser->bookmarks, i++)))
|
||||||
{
|
{
|
||||||
if (KATZE_IS_ARRAY (item))
|
if (KATZE_IS_ARRAY (item))
|
||||||
{
|
{
|
||||||
const gchar* name = katze_item_get_name (item);
|
const gchar* name = katze_item_get_name (item);
|
||||||
gtk_combo_box_append_text (combobox, name);
|
if (name)
|
||||||
|
gtk_combo_box_append_text (combobox_folder, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
|
||||||
|
@ -4111,7 +4114,7 @@ _action_bookmarks_import_activate (GtkAction* action,
|
||||||
i = gtk_combo_box_get_active (combobox);
|
i = gtk_combo_box_get_active (combobox);
|
||||||
path = g_build_filename (g_get_home_dir (), bookmark_clients[i].path, NULL);
|
path = g_build_filename (g_get_home_dir (), bookmark_clients[i].path, NULL);
|
||||||
|
|
||||||
selected = gtk_combo_box_get_active_text (combobox);
|
selected = gtk_combo_box_get_active_text (combobox_folder);
|
||||||
folder = browser->bookmarks;
|
folder = browser->bookmarks;
|
||||||
if (g_strcmp0 (selected, _("Toplevel folder")))
|
if (g_strcmp0 (selected, _("Toplevel folder")))
|
||||||
{
|
{
|
||||||
|
@ -4127,7 +4130,7 @@ _action_bookmarks_import_activate (GtkAction* action,
|
||||||
g_free (selected);
|
g_free (selected);
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
if (!midori_array_from_file (folder, path, "xbel", &error))
|
if (!midori_array_from_file (folder, path, NULL, &error))
|
||||||
{
|
{
|
||||||
GtkWidget* error_dialog = gtk_message_dialog_new (
|
GtkWidget* error_dialog = gtk_message_dialog_new (
|
||||||
GTK_WINDOW (browser), GTK_DIALOG_DESTROY_WITH_PARENT,
|
GTK_WINDOW (browser), GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
|
Loading…
Reference in a new issue