/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2013 Intel Corporation * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation. * * This program 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 Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Tristan Van Berkom */ #include #include #if EDS_CHECK_VERSION(3,6,0) # include /* In 3.10, we support the --use-test-sandbox option */ # if EDS_CHECK_VERSION(3,10,0) # include "client-test-utils.h" # include "e-test-server-utils.h" # endif #else # include # include #endif #if EDS_CHECK_VERSION(3,6,0) typedef EBookClient Book; #else typedef EBook Book; #endif static Book *create_book (const gchar *book_id); static void add_contacts (Book *book, GSList *contacts); static gchar *book_id = NULL; static gchar *contacts_directory = NULL; static gboolean test_sandbox = FALSE; static GOptionEntry option_entries[] = { {"book-id", 'b', 0, G_OPTION_ARG_STRING, &book_id, "The book identifier string", NULL }, {"contacts-directory", 'd', 0, G_OPTION_ARG_FILENAME, &contacts_directory, "The directory from where to read the contact files", NULL }, {"use-test-sandbox", 't', 0, G_OPTION_ARG_NONE, &test_sandbox, "Whether to use the test case sandbox to create the test book " "(Only available after EDS 3.10)", NULL }, { NULL } }; /******************************************************** * Loading contacts from directory * ********************************************************/ static EContact * contact_from_file (const gchar *vcard_file) { EContact *contact; GError *error; gchar *vcard = NULL; if (!g_file_get_contents (vcard_file, &vcard, NULL, &error)) g_error ("Failed to load vcard: %s", error->message); contact = e_contact_new_from_vcard (vcard); g_free (vcard); return contact; } static GSList * load_contacts (const gchar *vcard_directory) { GDir *dir; GError *error = NULL; const gchar *filename; GSList *contacts = NULL; dir = g_dir_open (vcard_directory, 0, &error); if (!dir) g_error ("Failed to open vcard directory '%s': %s", vcard_directory, error->message); while ((filename = g_dir_read_name (dir)) != NULL) { if (g_str_has_suffix (filename, ".vcf")) { gchar *fullpath = g_build_filename (vcard_directory, filename, NULL); EContact *contact; contact = contact_from_file (fullpath); contacts = g_slist_prepend (contacts, contact); g_free (fullpath); } } g_dir_close (dir); return g_slist_reverse (contacts); } /******************************************************** * Creating the Book * ********************************************************/ #if EDS_CHECK_VERSION(3,6,0) typedef struct { GMainLoop *loop; const gchar *book_id; EBookClient *book; } SourceAddedData; static void source_added (ESourceRegistry *registry, ESource *source, gpointer data) { SourceAddedData *added_data = (SourceAddedData *) data; GError *error = NULL; if (g_strcmp0 (e_source_get_uid (source), added_data->book_id) != 0) return; /* Open the address book */ #if EDS_CHECK_VERSION(3,8,0) added_data->book = (EBookClient *) e_book_client_connect_sync (source, (guint32) -1, NULL, &error); #else /* With 3.6 it's a bit more tricky */ added_data->book = e_book_client_new (source, &error); if (added_data->book && !e_client_open_sync (E_CLIENT (added_data->book), FALSE, NULL, &error)) g_error ("Failed to open addressbook: %s", error->message); #endif if (!added_data->book) g_error ("Failed to create addressbook: %s", error->message); if (added_data->loop) g_main_loop_quit (added_data->loop); } static gboolean create_source_timeout (gpointer user_data) { g_error ("Timed out while waiting for ESource creation from the registry"); return FALSE; } static EBookClient * create_book (const gchar *book_id) { ESourceRegistry *registry; ESource *scratch; ESourceBackend *backend = NULL; GError *error = NULL; SourceAddedData data = { NULL, NULL, NULL }; g_return_val_if_fail (book_id != NULL, NULL); data.loop = g_main_loop_new (NULL, FALSE); registry = e_source_registry_new_sync (NULL, &error); if (!registry) g_error ("Unable to create the registry: %s", error->message); /* Listen to the registry for our added source */ data.book_id = book_id; g_signal_connect ( registry, "source-added", G_CALLBACK (source_added), &data); /* Now create a scratch source for our addressbook */ scratch = e_source_new_with_uid (book_id, NULL, &error); if (!scratch) g_error ("Failed to create scratch source: %s", error->message); /* Ensure the new ESource will be a local addressbook source */ backend = e_source_get_extension (scratch, E_SOURCE_EXTENSION_ADDRESS_BOOK); e_source_backend_set_backend_name (backend, "local"); /* Commit the source to the registry */ if (!e_source_registry_commit_source_sync (registry, scratch, NULL, &error)) g_error ("Unable to add new addressbook source to the registry: %s", error->message); g_object_unref (scratch); if (data.book == NULL) { g_timeout_add_seconds (20, create_source_timeout, NULL); g_main_loop_run (data.loop); /* By now we aborted or we have an addressbook created */ g_warn_if_fail (data.book != NULL); } g_main_loop_unref (data.loop); g_object_unref (registry); return data.book; } #else static EBook * create_book (const gchar *book_id) { EBook *book; GError *error = NULL; book = e_book_new_from_uri (book_id, &error); if (!book) g_error ("Error creating book: %s", error->message); if (!e_book_open (book, FALSE, &error)) g_error ("Error opening book: %s", error->message); return book; } #endif /******************************************************** * Adding the Contacts * ********************************************************/ #if EDS_CHECK_VERSION(3,6,0) static void add_contacts (Book *book, GSList *contacts) { GError *error = NULL; if (!e_book_client_add_contacts_sync (book, contacts, E_BOOK_OPERATION_FLAG_NONE, NULL, NULL, &error)) g_error ("Failed to add contacts: %s", error->message); } #else static void add_contacts (Book *book, GSList *contacts) { GError *error = NULL; GSList *l; for (l = contacts; l; l = l->next) { EContact *contact = l->data; if (!e_book_add_contact (book, contact, &error)) g_error ("Failed to add a contact: %s", error->message); } } #endif /* Support running this in a test case in 3.10 and later */ #if EDS_CHECK_VERSION(3,10,0) static ETestServerClosure book_closure = { E_TEST_SERVER_ADDRESS_BOOK, NULL, /* Source customization function */ 0, /* Calendar Type */ TRUE, /* Keep the working sandbox after the test, don't remove it */ NULL, /* Destroy Notify function */ }; static void setup_migration_setup (ETestServerFixture *fixture, gconstpointer user_data) { fixture->source_name = g_strdup_printf ("%d.%d", EDS_MAJOR_VERSION, EDS_MINOR_VERSION); e_test_server_utils_setup (fixture, user_data); } static void setup_migration_run (ETestServerFixture *fixture, gconstpointer user_data) { EBookClient *book_client; GSList *contacts; contacts = load_contacts (contacts_directory); book_client = E_TEST_SERVER_UTILS_SERVICE (fixture, EBookClient); add_contacts (book_client, contacts); g_slist_free_full (contacts, g_object_unref); } #endif /******************************************************** * main() * ********************************************************/ gint main (gint argc, gchar *argv[]) { GOptionContext *option_context; GOptionGroup *option_group; GError *error = NULL; GSList *contacts; Book *book; option_context = g_option_context_new (NULL); g_option_context_set_summary ( option_context, "Populate a database for migration tests."); option_group = g_option_group_new ( "setup migration test", "Setup Migration options", "Setup Migration options", NULL, NULL); g_option_group_add_entries (option_group, option_entries); g_option_context_set_main_group (option_context, option_group); if (!g_option_context_parse (option_context, &argc, &argv, &error)) g_error ("Failed to parse program arguments: %s", error->message); if (!book_id || !contacts_directory) g_error ( "Must provide the book identifier and contacts directory\n%s", g_option_context_get_help (option_context, TRUE, NULL)); if (test_sandbox) { #if EDS_CHECK_VERSION(3,10,0) g_test_init (&argc, &argv, NULL); g_test_add ( "/SettingUpMigrationTest", ETestServerFixture, &book_closure, setup_migration_setup, setup_migration_run, e_test_server_utils_teardown); return e_test_server_utils_run (argc, argv); #else g_error ( "Requested sandboxed setup but that is not available until EDS 3.10, current version is %d.%d", EDS_MAJOR_VERSION, EDS_MINOR_VERSION); #endif } else { contacts = load_contacts (contacts_directory); book = create_book (book_id); add_contacts (book, contacts); g_object_unref (book); g_slist_free_full (contacts, g_object_unref); } return 0; }