From: Carlos Garcia Campos Date: Sun, 11 Oct 2009 09:35:12 +0000 (+0200) Subject: [metadata] Add evince-convert-metadata tool X-Git-Tag: EVINCE_2_29_1~52 X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=commitdiff_plain;h=f2952fb9e45b33d166bd256c80199d1236fc99bc;p=evince.git [metadata] Add evince-convert-metadata tool It converts the old xml based metadata file into gvfs metadata. --- diff --git a/po/POTFILES.in b/po/POTFILES.in index a09f9356..d942bed7 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 4553348a..a8acf735 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 00000000..9f24ed01 --- /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 + * + * 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 + +#include +#include +#include +#include +#include +#include + +#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 ("%s", _("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; +}