[evince] [metadata] Add evince-convert-metadata tool



commit f2952fb9e45b33d166bd256c80199d1236fc99bc
Author: Carlos Garcia Campos <carlosgc gnome org>
Date:   Sun Oct 11 11:35:12 2009 +0200

    [metadata] Add evince-convert-metadata tool
    
    It converts the old xml based metadata file into gvfs metadata.

 po/POTFILES.in              |    1 +
 shell/Makefile.am           |   10 ++
 shell/ev-convert-metadata.c |  300 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 311 insertions(+), 0 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a09f935..d942bed 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -38,6 +38,7 @@ shell/eggfindbar.c
 shell/ev-application.c
 shell/ev-history.c
 shell/ev-keyring.c
+shell/ev-convert-metadata.c
 shell/ev-navigation-action.c
 shell/ev-navigation-action-widget.c
 shell/ev-open-recent-action.c
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 4553348..a8acf73 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -24,6 +24,8 @@ INCLUDES=							\
 
 bin_PROGRAMS=evince
 
+libexec_PROGRAMS=evince-convert-metadata
+
 EV_MEDIA_PLAYER_KEYS_SOURCES = ev-media-player-keys.c ev-media-player-keys.h
 if ENABLE_DBUS
 DBUS_SOURCES = $(EV_MEDIA_PLAYER_KEYS_SOURCES)
@@ -110,6 +112,14 @@ if ENABLE_DBUS
 BUILT_SOURCES += ev-application-service.h
 endif
 
+evince_convert_metadata_SOURCES=	\
+	ev-convert-metadata.c
+
+evince_convert_metadata_LDADD=		\
+	$(SHELL_LIBS)
+
+
+
 EXTRA_DIST = ev-marshal.list		\
 	ev-application-service.xml	\
 	$(EV_MEDIA_PLAYER_KEYS_SOURCES)
diff --git a/shell/ev-convert-metadata.c b/shell/ev-convert-metadata.c
new file mode 100644
index 0000000..9f24ed0
--- /dev/null
+++ b/shell/ev-convert-metadata.c
@@ -0,0 +1,300 @@
+/* ev-convert-metadata.c
+ *  this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos  <carlosgc gnome org>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * 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.
+ */
+
+//#include <config.h>
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+#include <string.h>
+#include <libxml/tree.h>
+
+#define EV_METADATA_NAMESPACE "metadata::evince"
+
+typedef struct {
+	xmlNodePtr cur;
+	xmlChar *uri;
+} DocItem;
+
+typedef struct {
+	GtkWidget *progress;
+	GtkWidget *label;
+
+	xmlDocPtr doc;
+	GList *items;
+	GList *current;
+	guint n_item;
+} ConvertData;
+
+static void
+free_doc_item (DocItem *item)
+{
+	xmlFree (item->uri);
+	g_free (item);
+}
+
+static void
+convert_finish (ConvertData *data)
+{
+	g_list_foreach (data->items, (GFunc)free_doc_item, NULL);
+	g_list_free (data->items);
+	xmlFreeDoc (data->doc);
+	g_free (data);
+
+	gtk_main_quit ();
+}
+
+static gboolean
+convert_file (ConvertData *data)
+{
+	GFile *file;
+	DocItem *item;
+	const gchar *uri;
+	xmlNodePtr node;
+	xmlNodePtr cur;
+	gint total, current;
+	gchar *text;
+
+	if (!data->current)
+		return FALSE;
+
+	item = (DocItem *) data->current->data;
+	uri = (const gchar *)item->uri;
+	node = item->cur;
+	data->current = g_list_next (data->current);
+
+	/* Update progress information */
+	total = g_list_length (data->items);
+	current = ++(data->n_item);
+
+	text = g_strdup_printf (_("Converting %s"), uri);
+	gtk_label_set_text (GTK_LABEL (data->label), text);
+	g_free (text);
+
+	text = g_strdup_printf (_("%d of %d documents converted"), current, total);
+	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (data->progress), text);
+	g_free (text);
+	gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (data->progress),
+				       (gdouble)(current - 1) / total);
+
+	file = g_file_new_for_uri (uri);
+	if (!g_file_query_exists (file, NULL)) {
+		g_printerr ("Uri %s does not exist\n", uri);
+		g_object_unref (file);
+
+		return data->current != NULL;
+	}
+
+	for (cur = node->xmlChildrenNode; cur != NULL; cur = cur->next) {
+		xmlChar *key;
+		xmlChar *value;
+
+		if (xmlStrcmp (cur->name, (const xmlChar *)"entry") != 0)
+			continue;
+
+		key = xmlGetProp (cur, (const xmlChar *)"key");
+		value = xmlGetProp (cur, (const xmlChar *)"value");
+		if (key && value) {
+			GFileInfo *info;
+			gchar *gio_key;
+			GError *error = NULL;
+
+			info = g_file_info_new ();
+
+			gio_key = g_strconcat (EV_METADATA_NAMESPACE"::", key, NULL);
+			g_file_info_set_attribute_string (info, gio_key, (const gchar *)value);
+			g_free (gio_key);
+
+			if (!g_file_set_attributes_from_info (file, info, 0, NULL, &error)) {
+				g_printerr ("Error setting metadata for %s: %s\n",
+					    uri, error->message);
+				g_error_free (error);
+			}
+
+			g_object_unref (info);
+		}
+
+		if (key)
+			xmlFree (key);
+		if (value)
+			xmlFree (value);
+	}
+
+	g_object_unref (file);
+
+	return data->current != NULL;
+}
+
+static void
+convert_metadata_cancel (GtkDialog   *dialog,
+			 gint         response_id,
+			 ConvertData *data)
+{
+	convert_finish (data);
+	exit (1);
+}
+
+static void
+show_progress_dialog (ConvertData *data)
+{
+	GtkWidget *dialog;
+	GtkWidget *vbox, *pbox;
+	GtkWidget *label;
+	GtkWidget *progress;
+	gchar     *text;
+
+	dialog = gtk_dialog_new_with_buttons (_("Converting metadata"),
+					      NULL,
+					      GTK_DIALOG_NO_SEPARATOR,
+					      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+					      NULL);
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6);
+
+	vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+	gtk_box_set_spacing (GTK_BOX (vbox), 12);
+
+	label = gtk_label_new (NULL);
+	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+	text = g_strdup_printf ("<b>%s</b>", _("Converting metadata"));
+	gtk_label_set_markup (GTK_LABEL (label), text);
+	g_free (text);
+	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+	gtk_widget_show (label);
+
+	label = gtk_label_new (_("The metadata format used by Evince "
+				 "has changed, and hence it needs to be migrated. "
+				 "If the migration is cancelled the metadata "
+				 "storage will not work."));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+	gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+	gtk_widget_show (label);
+
+	pbox = gtk_vbox_new (FALSE, 6);
+	progress = gtk_progress_bar_new ();
+	data->progress = progress;
+	gtk_box_pack_start (GTK_BOX (pbox), progress, TRUE, TRUE, 0);
+	gtk_widget_show (progress);
+
+	label = gtk_label_new (NULL);
+	data->label = label;
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+	gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
+	gtk_box_pack_start (GTK_BOX (pbox), label, FALSE, FALSE, 0);
+	gtk_widget_show (label);
+
+	gtk_box_pack_start (GTK_BOX (vbox), pbox, TRUE, TRUE, 0);
+	gtk_widget_show (pbox);
+
+	g_signal_connect (dialog, "response",
+			  G_CALLBACK (convert_metadata_cancel),
+			  data);
+
+	gtk_widget_show (dialog);
+}
+
+static gboolean
+convert_metadata_file (const gchar *filename)
+{
+	ConvertData *data;
+	xmlDocPtr doc;
+	xmlNodePtr cur;
+
+	if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+		return FALSE;
+
+	doc = xmlParseFile (filename);
+	if (!doc) {
+		g_printerr ("Error loading metadata file %s\n", filename);
+		return FALSE;
+	}
+
+	cur = xmlDocGetRootElement (doc);
+	if (!cur) {
+		g_printerr ("Metadata file %s is empty\n", filename);
+		xmlFreeDoc (doc);
+		return TRUE;
+	}
+
+	if (xmlStrcmp (cur->name, (const xmlChar *) "metadata")) {
+		g_printerr ("File %s is not a valid evince metadata file\n", filename);
+		xmlFreeDoc (doc);
+		return FALSE;
+	}
+
+	data = g_new0 (ConvertData, 1);
+	data->doc = doc;
+
+	for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+		xmlChar *uri;
+		DocItem *item;
+
+		if (xmlStrcmp (cur->name, (const xmlChar *)"document") != 0)
+			continue;
+
+		uri = xmlGetProp (cur, (const xmlChar *)"uri");
+		if (!uri)
+			continue;
+
+		item = g_new (DocItem, 1);
+		item->uri = uri;
+		item->cur = cur;
+		data->items = g_list_prepend (data->items, item);
+	}
+
+	if (!data->items) {
+		xmlFreeDoc (data->doc);
+		g_free (data);
+
+		return TRUE;
+	}
+
+	show_progress_dialog (data);
+
+	data->current = data->items;
+	g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+			 (GSourceFunc)convert_file,
+			 data,
+			 (GDestroyNotify)convert_finish);
+
+	return TRUE;
+}
+
+gint
+main (gint argc, gchar **argv)
+{
+	if (argc != 2) {
+		g_printerr ("%s\n", "Usage: evince-convert-metadata FILE");
+		return 1;
+	}
+
+	gtk_init (&argc, &argv);
+
+	if (!convert_metadata_file (argv[1]))
+		return 1;
+
+	gtk_main ();
+
+	return 0;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]