[gnome-calendar] Introduce new source discoverer



commit 371fdbc881e5e92d85a64989eac6a824b151dc52
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Jul 10 19:04:50 2019 -0300

    Introduce new source discoverer
    
    The new source discoverer is a complete overhaul of
    the current code. It is async-only, correctly threaded,
    and easier to maintain.
    
    A major new feature of this web source discoverer is
    that it now pings the server to see if the URL feeds
    us back with an iCalendar file.
    
    Furthermore, it continues to use E-D-S WebDAV discovery
    functions as a fallback mechanism.
    
    Fixes #380

 src/meson.build                    |   1 +
 src/utils/gcal-source-discoverer.c | 405 +++++++++++++++++++++++++++++++++++++
 src/utils/gcal-source-discoverer.h |  52 +++++
 tests/gcal-simple-server.c         |   2 +-
 tests/meson.build                  |   1 +
 tests/test-discoverer.c            | 190 +++++++++++++++++
 6 files changed, 650 insertions(+), 1 deletion(-)
---
diff --git a/src/meson.build b/src/meson.build
index 90938097..91a06dd3 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -124,6 +124,7 @@ sources = files(
   'search/gcal-search-hit-event.c',
   'search/gcal-search-model.c',
   'utils/gcal-date-time-utils.c',
+  'utils/gcal-source-discoverer.c',
   'utils/gcal-thread-utils.c',
   'utils/gcal-utils.c',
   'views/gcal-month-cell.c',
diff --git a/src/utils/gcal-source-discoverer.c b/src/utils/gcal-source-discoverer.c
new file mode 100644
index 00000000..6c61cdab
--- /dev/null
+++ b/src/utils/gcal-source-discoverer.c
@@ -0,0 +1,405 @@
+/* gcal-source-discoverer.c
+ *
+ * Copyright 2019 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "GcalSourceDiscoverer"
+
+#include <libecal/libecal.h>
+#include <libsoup/soup.h>
+
+#include "gcal-debug.h"
+#include "gcal-source-discoverer.h"
+#include "gcal-utils.h"
+
+G_DEFINE_QUARK (GcalSourceDiscoverer, gcal_source_discoverer_error);
+
+typedef struct
+{
+  gchar              *uri;
+  gchar              *username;
+  gchar              *password;
+} DiscovererData;
+
+
+/*
+ * Auxiliary methods
+ */
+
+static void
+discoverer_data_free (gpointer data)
+{
+  DiscovererData *discoverer_data = data;
+
+  if (!discoverer_data)
+    return;
+
+  g_free (discoverer_data->uri);
+  g_free (discoverer_data->username);
+  g_free (discoverer_data->password);
+  g_free (discoverer_data);
+}
+
+static ESource*
+create_source_for_uri (DiscovererData  *data)
+{
+  ESourceAuthentication *auth;
+  g_autoptr (SoupURI) soup_uri = NULL;
+  g_autofree gchar *display_name = NULL;
+  g_autofree gchar *basename = NULL;
+  ESourceExtension *ext;
+  ESourceWebdav *webdav;
+  ESource *source;
+  const gchar *host;
+  const gchar *path;
+
+  soup_uri = soup_uri_new (data->uri);
+  if (!soup_uri)
+    GCAL_RETURN (NULL);
+
+  host = soup_uri_get_host (soup_uri);
+
+  /* Create the new source and add the needed extensions */
+  source = e_source_new (NULL, NULL, NULL);
+  e_source_set_parent (source, "webcal-stub");
+
+  /* Display name */
+  path = soup_uri_get_path (soup_uri);
+  basename = g_path_get_basename (path);
+  display_name = gcal_utils_format_filename_for_display (basename);
+  e_source_set_display_name (source, display_name);
+
+  ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
+  e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "webcal");
+
+  /* Authentication */
+  auth = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
+  e_source_authentication_set_host (auth, host);
+
+  /* Webdav */
+  webdav = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
+  e_source_webdav_set_soup_uri (webdav, soup_uri);
+
+  return source;
+}
+
+static ESource*
+create_discovered_source (ESource                 *source,
+                          GSList                  *user_addresses,
+                          EWebDAVDiscoveredSource *discovered_source)
+{
+  g_autoptr (SoupURI) soup_uri = NULL;
+  ESourceSelectable *selectable;
+  ESourceExtension *ext;
+  ESourceWebdav *webdav;
+  ESource *new_source;
+  const gchar *resource_path;
+
+  soup_uri = soup_uri_new (discovered_source->href);
+  resource_path = soup_uri_get_path (soup_uri);
+
+  new_source = e_source_new (NULL, NULL, NULL);
+  e_source_set_parent (new_source, "local");
+
+  ext = e_source_get_extension (new_source, E_SOURCE_EXTENSION_CALENDAR);
+  e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "local");
+
+  /* Copy Authentication data */
+  if (e_source_has_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION))
+    {
+      ESourceAuthentication *new_auth, *parent_auth;
+
+      parent_auth = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
+      new_auth = e_source_get_extension (new_source, E_SOURCE_EXTENSION_AUTHENTICATION);
+
+      e_source_authentication_set_host (new_auth, e_source_authentication_get_host (parent_auth));
+      e_source_authentication_set_method (new_auth, e_source_authentication_get_method (parent_auth));
+      e_source_authentication_set_port (new_auth, e_source_authentication_get_port (parent_auth));
+      e_source_authentication_set_user (new_auth, e_source_authentication_get_user (parent_auth));
+      e_source_authentication_set_proxy_uid (new_auth, e_source_authentication_get_proxy_uid (parent_auth));
+    }
+
+  /* Copy Webdav data */
+  if (e_source_has_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND))
+    {
+      ESourceWebdav *new_webdav, *parent_webdav;
+
+      parent_webdav = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
+      new_webdav = e_source_get_extension (new_source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
+
+      e_source_webdav_set_display_name (new_webdav, e_source_webdav_get_display_name (parent_webdav));
+      e_source_webdav_set_resource_path (new_webdav, e_source_webdav_get_resource_path (parent_webdav));
+      e_source_webdav_set_resource_query (new_webdav, e_source_webdav_get_resource_query (parent_webdav));
+      e_source_webdav_set_email_address (new_webdav, e_source_webdav_get_email_address (parent_webdav));
+      e_source_webdav_set_ssl_trust (new_webdav, e_source_webdav_get_ssl_trust (parent_webdav));
+
+      e_source_set_parent (new_source, "webcal-stub");
+      e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "webcal");
+    }
+
+  /* build up the new source */
+  e_source_set_display_name (new_source, discovered_source->display_name);
+
+  webdav = e_source_get_extension (new_source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
+  e_source_webdav_set_resource_path (webdav, resource_path);
+  e_source_webdav_set_display_name (webdav, discovered_source->display_name);
+
+  if (user_addresses)
+    e_source_webdav_set_email_address (webdav, user_addresses->data);
+
+  /* Setup the color */
+  selectable = e_source_get_extension (new_source, E_SOURCE_EXTENSION_CALENDAR);
+  e_source_selectable_set_color (selectable, discovered_source->color);
+
+  return new_source;
+}
+
+static gboolean
+is_authentication_error (gint code)
+{
+  switch (code)
+    {
+    case SOUP_STATUS_UNAUTHORIZED:
+    case SOUP_STATUS_FORBIDDEN:
+    case SOUP_STATUS_METHOD_NOT_ALLOWED:
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+/*
+ * Callbacks
+ */
+
+static void
+on_soup_session_authenticate_cb (SoupSession *session,
+                                 SoupMessage *message,
+                                 SoupAuth    *auth,
+                                 gboolean     retrying,
+                                 gpointer     user_data)
+{
+  DiscovererData *data = user_data;
+
+  if (data->username && data->password)
+    soup_auth_authenticate (auth, data->username, data->password);
+  else
+    soup_message_set_status (message, SOUP_STATUS_UNAUTHORIZED);
+}
+
+typedef GPtrArray* (*DiscoverFunc) (DiscovererData  *data,
+                                    GCancellable    *cancellable,
+                                    GError         **error);
+
+static GPtrArray*
+discover_file_in_thread (DiscovererData  *data,
+                         GCancellable    *cancellable,
+                         GError         **error)
+{
+  g_autoptr (GInputStream) input_stream = NULL;
+  g_autoptr (SoupMessage) message = NULL;
+  g_autoptr (SoupSession) session = NULL;
+  g_autoptr (GPtrArray) source = NULL;
+  const gchar *content_type;
+
+  GCAL_ENTRY;
+
+  GCAL_TRACE_MSG ("Creating request for %s", data->uri);
+
+  session = soup_session_new_with_options (SOUP_SESSION_TIMEOUT, 10, NULL);
+  g_signal_connect (session, "authenticate", G_CALLBACK (on_soup_session_authenticate_cb), data);
+
+  message = soup_message_new ("GET", data->uri);
+  input_stream = soup_session_send (session, message, cancellable, error);
+
+  if (!input_stream)
+    GCAL_RETURN (NULL);
+
+  g_input_stream_close (input_stream, cancellable, error);
+
+  content_type = soup_message_headers_get_content_type (message->response_headers, NULL);
+  GCAL_TRACE_MSG ("Message retrieved, content type: %s, status code: %u", content_type, 
message->status_code);
+
+  if (is_authentication_error (message->status_code))
+    {
+      g_set_error (error,
+                   GCAL_SOURCE_DISCOVERER_ERROR,
+                   GCAL_SOURCE_DISCOVERER_ERROR_UNAUTHORIZED,
+                   "%s",
+                   soup_status_get_phrase (message->status_code));
+
+      GCAL_RETURN (NULL);
+    }
+
+  if (content_type && g_strstr_len (content_type, -1, "text/calendar") != NULL)
+    {
+      source = g_ptr_array_new_full (1, g_object_unref);
+      g_ptr_array_add (source, create_source_for_uri (data));
+    }
+
+  GCAL_RETURN (g_steal_pointer (&source));
+}
+
+static GPtrArray*
+discover_webdav_in_thread (DiscovererData  *data,
+                           GCancellable    *cancellable,
+                           GError         **error)
+{
+  g_autoptr (ENamedParameters) credentials = NULL;
+  g_autoptr (GPtrArray) sources = NULL;
+  g_autoptr (ESource) source = NULL;
+  g_autoptr (GError) local_error = NULL;
+  g_autofree gchar *certificate_pem = NULL;
+  GTlsCertificateFlags flags;
+  GSList *discovered_sources = NULL;
+  GSList *user_addresses = NULL;
+  GSList *l;
+
+  GCAL_ENTRY;
+
+  credentials = e_named_parameters_new ();
+  e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_USERNAME, data->username);
+  e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_PASSWORD, data->password);
+
+  source = create_source_for_uri (data);
+
+  e_webdav_discover_sources_sync (source,
+                                  data->uri,
+                                  E_WEBDAV_DISCOVER_SUPPORTS_EVENTS,
+                                  credentials,
+                                  &certificate_pem,
+                                  &flags,
+                                  &discovered_sources,
+                                  &user_addresses,
+                                  cancellable,
+                                  &local_error);
+
+  if (local_error)
+    {
+      if (is_authentication_error (local_error->code))
+        {
+          g_set_error (error,
+                       GCAL_SOURCE_DISCOVERER_ERROR,
+                       GCAL_SOURCE_DISCOVERER_ERROR_UNAUTHORIZED,
+                       "%s",
+                       soup_status_get_phrase (local_error->code));
+        }
+      else
+        {
+          g_propagate_error (error, g_steal_pointer (&local_error));
+        }
+
+      GCAL_RETURN (NULL);
+    }
+
+  sources = g_ptr_array_new_full (g_slist_length (discovered_sources), g_object_unref);
+  for (l = discovered_sources; l; l = l->next)
+    {
+      EWebDAVDiscoveredSource *discovered_source;
+      ESource *new_source;
+
+      discovered_source = l->data;
+      new_source = create_discovered_source (source, user_addresses, discovered_source);
+
+      if (!new_source)
+        continue;
+
+      g_ptr_array_add (sources, new_source);
+    }
+
+  g_clear_pointer (&discovered_sources, e_webdav_discover_free_discovered_sources);
+  g_slist_free_full (user_addresses, g_free);
+
+  GCAL_RETURN (g_steal_pointer (&sources));
+}
+
+static void
+discover_sources_in_thread_cb (GTask        *task,
+                               gpointer      source_object,
+                               gpointer      task_data,
+                               GCancellable *cancellable)
+{
+  g_autoptr (GError) error = NULL;
+  DiscovererData *data = task_data;
+  guint i;
+
+  const DiscoverFunc discover_funcs[] = {
+    discover_file_in_thread,
+    discover_webdav_in_thread,
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (discover_funcs); i++)
+    {
+      g_autoptr (GPtrArray) sources = NULL;
+      g_autoptr (GError) local_error = NULL;
+
+      sources = discover_funcs[i] (data, cancellable, &local_error);
+
+      if (sources)
+        {
+          g_task_return_pointer (task, g_steal_pointer (&sources), NULL);
+          return;
+        }
+      else if (local_error)
+        {
+          g_clear_error (&error);
+          g_propagate_error (&error, g_steal_pointer (&local_error));
+        }
+    }
+
+  if (error)
+    g_task_return_error (task, g_steal_pointer (&error));
+  else
+    g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_UNKNOWN, "Unknown error");
+}
+
+void
+gcal_discover_sources_from_uri (const gchar         *uri,
+                                const gchar         *username,
+                                const gchar         *password,
+                                GCancellable        *cancellable,
+                                GAsyncReadyCallback  callback,
+                                gpointer             user_data)
+{
+  g_autoptr (GTask) task = NULL;
+  DiscovererData *data;
+
+  g_assert (uri != NULL);
+
+  data = g_new0 (DiscovererData, 1);
+  data->uri = g_strdup (uri);
+  data->username = g_strdup (username);
+  data->password = g_strdup (password);
+
+  task = g_task_new (NULL, cancellable, callback, user_data);
+  g_task_set_source_tag (task, gcal_discover_sources_from_uri);
+  g_task_set_task_data (task, data, discoverer_data_free);
+
+  g_task_run_in_thread (task, discover_sources_in_thread_cb);
+}
+
+GPtrArray*
+gcal_discover_sources_from_uri_finish (GAsyncResult  *result,
+                                       GError       **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, NULL), NULL);
+  g_return_val_if_fail (!error || !*error, NULL);
+
+  return g_task_propagate_pointer (G_TASK (result), error);
+}
diff --git a/src/utils/gcal-source-discoverer.h b/src/utils/gcal-source-discoverer.h
new file mode 100644
index 00000000..6e95bd2b
--- /dev/null
+++ b/src/utils/gcal-source-discoverer.h
@@ -0,0 +1,52 @@
+/* gcal-source-discoverer.h
+ *
+ * Copyright 2019 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GcalDiscovererError:
+ * @GCAL_SOURCE_DISCOVERER_ERROR_UNAUTHORIZED: indicated an invalid start date
+ *
+ * Errors that can generate.
+ */
+typedef enum
+{
+  GCAL_SOURCE_DISCOVERER_ERROR_UNAUTHORIZED,
+} GcalSourceDiscovererError;
+
+#define GCAL_SOURCE_DISCOVERER_ERROR (gcal_source_discoverer_error_quark ())
+
+GQuark               gcal_source_discoverer_error_quark          (void);
+
+void                 gcal_discover_sources_from_uri              (const gchar         *uri,
+                                                                  const gchar         *username,
+                                                                  const gchar         *password,
+                                                                  GCancellable        *cancellable,
+                                                                  GAsyncReadyCallback  callback,
+                                                                  gpointer             user_data);
+
+GPtrArray*           gcal_discover_sources_from_uri_finish       (GAsyncResult       *result,
+                                                                  GError            **error);
+
+G_END_DECLS
diff --git a/tests/gcal-simple-server.c b/tests/gcal-simple-server.c
index 21ad7db8..15b3f010 100644
--- a/tests/gcal-simple-server.c
+++ b/tests/gcal-simple-server.c
@@ -88,7 +88,7 @@ static void
 process_caldav (SoupMessage *message,
                 const gchar *path)
 {
-  g_message ("Processing CalDAV");
+  g_debug ("Processing CalDAV request");
 }
 
 
diff --git a/tests/meson.build b/tests/meson.build
index a45a00ef..ec704dfd 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -33,6 +33,7 @@ libgcal_test_dep = declare_dependency(
 
 tests = [
   'server',
+  'discoverer',
   'event',
   'manager',
 ]
diff --git a/tests/test-discoverer.c b/tests/test-discoverer.c
new file mode 100644
index 00000000..73ce1016
--- /dev/null
+++ b/tests/test-discoverer.c
@@ -0,0 +1,190 @@
+/* test-discoverer.c
+ *
+ * Copyright 2019 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+
+#include <glib.h>
+#include <libecal/libecal.h>
+
+#include "gcal-simple-server.h"
+#include "gcal-source-discoverer.h"
+
+static GcalSimpleServer*
+init_server (void)
+{
+  g_autoptr (GcalSimpleServer) server = NULL;
+
+  server = gcal_simple_server_new ();
+  gcal_simple_server_start (server);
+
+  return g_steal_pointer (&server);
+}
+
+/*********************************************************************************************************************/
+
+static void
+discovered_file_cb (GObject      *source_object,
+                    GAsyncResult *result,
+                    gpointer      user_data)
+{
+  g_autoptr (GPtrArray) sources = NULL;
+  g_autoptr (GError) error = NULL;
+  GMainLoop *mainloop = user_data;
+
+  sources = gcal_discover_sources_from_uri_finish (result, &error);
+  g_assert_no_error (error);
+  g_assert_cmpuint (sources->len, ==, 1);
+
+  g_main_loop_quit (mainloop);
+}
+
+static void
+discoverer_file (void)
+{
+  g_autoptr (GcalSimpleServer) server = NULL;
+  g_autoptr (GMainLoop) mainloop = NULL;
+  g_autoptr (SoupURI) uri = NULL;
+  g_autofree gchar *uri_str = NULL;
+
+  server = init_server ();
+  uri = gcal_simple_server_get_uri (server);
+  soup_uri_set_path (uri, "/public/calendar");
+
+  uri_str = soup_uri_to_string (uri, FALSE);
+
+  mainloop = g_main_loop_new (NULL, FALSE);
+
+  gcal_discover_sources_from_uri (uri_str,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  discovered_file_cb,
+                                  mainloop);
+
+  g_main_loop_run (mainloop);
+}
+
+/*********************************************************************************************************************/
+
+static void
+discovered_webdav_no_auth_cb (GObject      *source_object,
+                              GAsyncResult *result,
+                              gpointer      user_data)
+{
+  g_autoptr (GPtrArray) sources = NULL;
+  g_autoptr (GError) error = NULL;
+  GMainLoop *mainloop = user_data;
+
+  sources = gcal_discover_sources_from_uri_finish (result, &error);
+  g_assert_error (error, GCAL_SOURCE_DISCOVERER_ERROR, GCAL_SOURCE_DISCOVERER_ERROR_UNAUTHORIZED);
+
+  g_main_loop_quit (mainloop);
+}
+
+static void
+discoverer_webdav_no_auth (void)
+{
+  g_autoptr (GcalSimpleServer) server = NULL;
+  g_autoptr (GMainLoop) mainloop = NULL;
+  g_autoptr (SoupURI) uri = NULL;
+  g_autofree gchar *uri_str = NULL;
+
+  server = init_server ();
+  uri = gcal_simple_server_get_uri (server);
+  soup_uri_set_path (uri, "/secret-area/calendar");
+
+  uri_str = soup_uri_to_string (uri, FALSE);
+
+  mainloop = g_main_loop_new (NULL, FALSE);
+
+  gcal_discover_sources_from_uri (uri_str,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  discovered_webdav_no_auth_cb,
+                                  mainloop);
+
+  g_main_loop_run (mainloop);
+}
+
+/*********************************************************************************************************************/
+
+#if 0
+
+// TODO: Implement raw CalDAV server in GcalSimpleServer
+
+static void
+discoverer_webdav_auth_cb (GObject      *source_object,
+                           GAsyncResult *result,
+                           gpointer      user_data)
+{
+  g_autoptr (GPtrArray) sources = NULL;
+  g_autoptr (GError) error = NULL;
+  GMainLoop *mainloop = user_data;
+
+  sources = gcal_discover_sources_from_uri_finish (result, &error);
+  g_assert_no_error (error);
+
+  g_main_loop_quit (mainloop);
+}
+
+static void
+discoverer_webdav_auth (void)
+{
+  g_autoptr (GcalSimpleServer) server = NULL;
+  g_autoptr (GMainLoop) mainloop = NULL;
+  g_autoptr (SoupURI) uri = NULL;
+  g_autofree gchar *uri_str = NULL;
+
+  server = init_server ();
+  uri = gcal_simple_server_get_uri (server);
+  soup_uri_set_path (uri, "/secret-area/dav");
+
+  uri_str = soup_uri_to_string (uri, FALSE);
+
+  mainloop = g_main_loop_new (NULL, FALSE);
+
+  gcal_discover_sources_from_uri (uri_str,
+                                  "feaneron",
+                                  "idonotmaintainanything",
+                                  NULL,
+                                  discoverer_webdav_auth_cb,
+                                  mainloop);
+
+  g_main_loop_run (mainloop);
+}
+
+#endif
+
+/*********************************************************************************************************************/
+
+gint
+main (gint   argc,
+      gchar *argv[])
+{
+  g_setenv ("TZ", "UTC", TRUE);
+
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/discoverer/file", discoverer_file);
+  g_test_add_func ("/discoverer/webdav/no-auth", discoverer_webdav_no_auth);
+
+  return g_test_run ();
+}
+


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