[evolution-data-server/gnome-42] I#386 - e-webdav-discover: Fails to find Radicale calendars within collection account
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-42] I#386 - e-webdav-discover: Fails to find Radicale calendars within collection account
- Date: Mon, 25 Apr 2022 13:52:50 +0000 (UTC)
commit 0a2e5eb786921407e8d1b61d88f9441b63e0194c
Author: Milan Crha <mcrha redhat com>
Date: Mon Apr 25 15:51:02 2022 +0200
I#386 - e-webdav-discover: Fails to find Radicale calendars within collection account
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/386
src/libedataserver/e-webdav-discover.c | 70 +++++++++++++++++++++++++------
src/libedataserver/e-webdav-session.c | 77 ++++++++++++++++++----------------
2 files changed, 98 insertions(+), 49 deletions(-)
---
diff --git a/src/libedataserver/e-webdav-discover.c b/src/libedataserver/e-webdav-discover.c
index 79980200b..a824cdf2c 100644
--- a/src/libedataserver/e-webdav-discover.c
+++ b/src/libedataserver/e-webdav-discover.c
@@ -45,15 +45,18 @@ G_DEFINE_BOXED_TYPE (EWebDAVDiscoveredSource, e_webdav_discovered_source, e_webd
static gboolean
e_webdav_discovery_already_discovered (const gchar *href,
- const GSList *discovered_sources)
+ const GSList *discovered_sources,
+ guint32 href_supports)
{
GSList *link;
for (link = (GSList *) discovered_sources; link; link = g_slist_next (link)) {
EWebDAVDiscoveredSource *discovered = link->data;
- if (discovered && g_strcmp0 (href, discovered->href) == 0)
+ if (discovered && g_strcmp0 (href, discovered->href) == 0) {
+ discovered->supports |= href_supports;
return TRUE;
+ }
}
return FALSE;
@@ -82,7 +85,8 @@ e_webdav_discover_split_resources (WebDAVDiscoverData *wdd,
continue;
if (e_webdav_discovery_already_discovered (resource->href,
- resource->kind == E_WEBDAV_RESOURCE_KIND_ADDRESSBOOK ? wdd->addressbooks :
wdd->calendars))
+ resource->kind == E_WEBDAV_RESOURCE_KIND_ADDRESSBOOK ? wdd->addressbooks :
wdd->calendars,
+ resource->supports))
continue;
discovered = g_slice_new0 (EWebDAVDiscoveredSource);
@@ -105,6 +109,45 @@ e_webdav_discover_split_resources (WebDAVDiscoverData *wdd,
}
}
+typedef enum {
+ COVERED_LOOKUP = 1 << 0,
+ COVERED_ADDRESSBOOK = 1 << 1,
+ COVERED_CALENDAR = 1 << 2
+} ECoveredMark;
+
+static void
+e_webdav_discover_mark_covered (GHashTable *covered_hrefs,
+ const gchar *href,
+ ECoveredMark mark)
+{
+ gint value;
+
+ if (!covered_hrefs || !href || !*href)
+ return;
+
+ value = GPOINTER_TO_INT (g_hash_table_lookup (covered_hrefs, href));
+
+ if ((value & mark) != mark) {
+ value |= mark;
+ g_hash_table_insert (covered_hrefs, g_strdup (href), GINT_TO_POINTER (value));
+ }
+}
+
+static gboolean
+e_webdav_discover_is_covered (GHashTable *covered_hrefs,
+ const gchar *href,
+ ECoveredMark mark)
+{
+ gint value;
+
+ if (!covered_hrefs || !href || !*href)
+ return FALSE;
+
+ value = GPOINTER_TO_INT (g_hash_table_lookup (covered_hrefs, href));
+
+ return (value & mark) == mark;
+}
+
static gboolean
e_webdav_discover_propfind_uri_sync (EWebDAVSession *webdav,
WebDAVDiscoverData *wdd,
@@ -145,7 +188,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
full_href = e_webdav_session_ensure_full_uri (webdav, request_uri, (const gchar *)
home_set_href);
- if (full_href && *full_href && GPOINTER_TO_INT (g_hash_table_contains
(wdd->covered_hrefs, full_href)) != 2 &&
+ if (full_href && *full_href && !e_webdav_discover_is_covered (wdd->covered_hrefs,
full_href, COVERED_ADDRESSBOOK) &&
e_webdav_session_list_sync (webdav, full_href, E_WEBDAV_DEPTH_THIS_AND_CHILDREN,
E_WEBDAV_LIST_ONLY_ADDRESSBOOK | E_WEBDAV_LIST_ALL,
&resources, wdd->cancellable, &local_error)) {
@@ -154,7 +197,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
}
if (full_href && *full_href)
- g_hash_table_insert (wdd->covered_hrefs, g_strdup (full_href),
GINT_TO_POINTER (2));
+ e_webdav_discover_mark_covered (wdd->covered_hrefs, full_href,
COVERED_ADDRESSBOOK);
if (local_error && wdd->error && !*wdd->error)
g_propagate_error (wdd->error, local_error);
@@ -181,7 +224,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
full_href = e_webdav_session_ensure_full_uri (webdav, request_uri, (const gchar *)
home_set_href);
- if (full_href && *full_href && GPOINTER_TO_INT (g_hash_table_contains
(wdd->covered_hrefs, full_href)) != 2 &&
+ if (full_href && *full_href && !e_webdav_discover_is_covered (wdd->covered_hrefs,
full_href, COVERED_CALENDAR) &&
e_webdav_session_list_sync (webdav, full_href, E_WEBDAV_DEPTH_THIS_AND_CHILDREN,
E_WEBDAV_LIST_ONLY_CALENDAR | E_WEBDAV_LIST_ALL,
&resources, wdd->cancellable, &local_error)) {
@@ -190,7 +233,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
}
if (full_href && *full_href)
- g_hash_table_insert (wdd->covered_hrefs, g_strdup (full_href),
GINT_TO_POINTER (2));
+ e_webdav_discover_mark_covered (wdd->covered_hrefs, full_href,
COVERED_CALENDAR);
if (local_error && wdd->error && !*wdd->error)
g_propagate_error (wdd->error, local_error);
@@ -262,10 +305,11 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
is_addressbook = e_xml_find_child (node, E_WEBDAV_NS_CARDDAV, "addressbook") != NULL;
if (is_calendar || is_addressbook) {
+ gint covered_mark = (is_addressbook ? COVERED_ADDRESSBOOK : 0) | (is_calendar ?
COVERED_CALENDAR : 0);
GSList *resources = NULL;
GError *local_error = NULL;
- if (GPOINTER_TO_INT (g_hash_table_contains (wdd->covered_hrefs, href)) != 2 &&
+ if (!e_webdav_discover_is_covered (wdd->covered_hrefs, href, covered_mark) &&
!g_cancellable_is_cancelled (wdd->cancellable) &&
e_webdav_session_list_sync (webdav, href, E_WEBDAV_DEPTH_THIS,
(is_calendar ? E_WEBDAV_LIST_ONLY_CALENDAR : 0) | (is_addressbook ?
E_WEBDAV_LIST_ONLY_ADDRESSBOOK : 0) | E_WEBDAV_LIST_ALL,
@@ -274,7 +318,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
g_slist_free_full (resources, e_webdav_resource_free);
}
- g_hash_table_insert (wdd->covered_hrefs, g_strdup (href), GINT_TO_POINTER (2));
+ e_webdav_discover_mark_covered (wdd->covered_hrefs, href, covered_mark);
if (local_error && wdd->error && !*wdd->error)
g_propagate_error (wdd->error, local_error);
@@ -285,7 +329,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
if (((wdd->only_supports & (~CUSTOM_SUPPORTS_FLAGS)) == E_WEBDAV_DISCOVER_SUPPORTS_NONE ||
(wdd->only_supports & E_WEBDAV_DISCOVER_SUPPORTS_WEBDAV_NOTES) != 0) &&
(g_str_has_suffix (href, "/Notes") || g_str_has_suffix (href, "/Notes/")) &&
- !e_webdav_discovery_already_discovered (href, wdd->calendars) &&
+ !e_webdav_discovery_already_discovered (href, wdd->calendars, 0) &&
e_xml_find_in_hierarchy (prop_node, E_WEBDAV_NS_DAV, "resourcetype", E_WEBDAV_NS_DAV,
"collection", NULL, NULL)) {
GSList *resources = NULL;
@@ -299,7 +343,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
g_slist_free_full (resources, e_webdav_resource_free);
- g_hash_table_insert (wdd->covered_hrefs, g_strdup (href), GINT_TO_POINTER (2));
+ e_webdav_discover_mark_covered (wdd->covered_hrefs, href, COVERED_CALENDAR);
}
return TRUE;
@@ -319,10 +363,10 @@ e_webdav_discover_propfind_uri_sync (EWebDAVSession *webdav,
g_return_val_if_fail (wdd != NULL, FALSE);
g_return_val_if_fail (uri && *uri, FALSE);
- if (g_hash_table_contains (wdd->covered_hrefs, uri))
+ if (e_webdav_discover_is_covered (wdd->covered_hrefs, uri, COVERED_LOOKUP))
return TRUE;
- g_hash_table_insert (wdd->covered_hrefs, g_strdup (uri), GINT_TO_POINTER (1));
+ e_webdav_discover_mark_covered (wdd->covered_hrefs, uri, COVERED_LOOKUP);
xml = e_xml_document_new (E_WEBDAV_NS_DAV, "propfind");
g_return_val_if_fail (xml != NULL, FALSE);
diff --git a/src/libedataserver/e-webdav-session.c b/src/libedataserver/e-webdav-session.c
index 57e75f3d1..e9825a24f 100644
--- a/src/libedataserver/e-webdav-session.c
+++ b/src/libedataserver/e-webdav-session.c
@@ -3459,57 +3459,62 @@ e_webdav_session_extract_kind (xmlNodePtr parent_node)
}
static guint32
-e_webdav_session_extract_supports (xmlNodePtr prop_node)
+e_webdav_session_extract_supports (xmlNodePtr prop_node,
+ EWebDAVResourceKind kind)
{
- xmlNodePtr calendar_components;
guint32 supports = E_WEBDAV_RESOURCE_SUPPORTS_NONE;
g_return_val_if_fail (prop_node != NULL, E_WEBDAV_RESOURCE_SUPPORTS_NONE);
- if (e_xml_find_in_hierarchy (prop_node, E_WEBDAV_NS_DAV, "resourcetype", E_WEBDAV_NS_CARDDAV,
"addressbook", NULL, NULL))
+ if (kind == E_WEBDAV_RESOURCE_KIND_ADDRESSBOOK &&
+ e_xml_find_in_hierarchy (prop_node, E_WEBDAV_NS_DAV, "resourcetype", E_WEBDAV_NS_CARDDAV,
"addressbook", NULL, NULL))
supports = supports | E_WEBDAV_RESOURCE_SUPPORTS_CONTACTS;
- calendar_components = e_xml_find_child (prop_node, E_WEBDAV_NS_CALDAV,
"supported-calendar-component-set");
+ if (kind == E_WEBDAV_RESOURCE_KIND_CALENDAR) {
+ xmlNodePtr calendar_components;
- if (calendar_components) {
- xmlNodePtr node;
- gint found_comps = 0;
+ calendar_components = e_xml_find_child (prop_node, E_WEBDAV_NS_CALDAV,
"supported-calendar-component-set");
+
+ if (calendar_components) {
+ xmlNodePtr node;
+ gint found_comps = 0;
- for (node = calendar_components->children; node; node = xmlNextElementSibling (node)) {
- if (e_xml_is_element_name (node, E_WEBDAV_NS_CALDAV, "comp")) {
- xmlChar *name;
+ for (node = calendar_components->children; node; node = xmlNextElementSibling (node))
{
+ if (e_xml_is_element_name (node, E_WEBDAV_NS_CALDAV, "comp")) {
+ xmlChar *name;
- found_comps++;
+ found_comps++;
- name = xmlGetProp (node, (const xmlChar *) "name");
+ name = xmlGetProp (node, (const xmlChar *) "name");
- if (!name)
- continue;
+ if (!name)
+ continue;
- if (g_ascii_strcasecmp ((const gchar *) name, "VEVENT") == 0)
- supports |= E_WEBDAV_RESOURCE_SUPPORTS_EVENTS;
- else if (g_ascii_strcasecmp ((const gchar *) name, "VJOURNAL") == 0)
- supports |= E_WEBDAV_RESOURCE_SUPPORTS_MEMOS;
- else if (g_ascii_strcasecmp ((const gchar *) name, "VTODO") == 0)
- supports |= E_WEBDAV_RESOURCE_SUPPORTS_TASKS;
- else if (g_ascii_strcasecmp ((const gchar *) name, "VFREEBUSY") == 0)
- supports |= E_WEBDAV_RESOURCE_SUPPORTS_FREEBUSY;
- else if (g_ascii_strcasecmp ((const gchar *) name, "VTIMEZONE") == 0)
- supports |= E_WEBDAV_RESOURCE_SUPPORTS_TIMEZONE;
+ if (g_ascii_strcasecmp ((const gchar *) name, "VEVENT") == 0)
+ supports |= E_WEBDAV_RESOURCE_SUPPORTS_EVENTS;
+ else if (g_ascii_strcasecmp ((const gchar *) name, "VJOURNAL") == 0)
+ supports |= E_WEBDAV_RESOURCE_SUPPORTS_MEMOS;
+ else if (g_ascii_strcasecmp ((const gchar *) name, "VTODO") == 0)
+ supports |= E_WEBDAV_RESOURCE_SUPPORTS_TASKS;
+ else if (g_ascii_strcasecmp ((const gchar *) name, "VFREEBUSY") == 0)
+ supports |= E_WEBDAV_RESOURCE_SUPPORTS_FREEBUSY;
+ else if (g_ascii_strcasecmp ((const gchar *) name, "VTIMEZONE") == 0)
+ supports |= E_WEBDAV_RESOURCE_SUPPORTS_TIMEZONE;
- xmlFree (name);
+ xmlFree (name);
+ }
}
- }
- if (!found_comps) {
- /* If the property is not present, assume all component
- * types are supported. (RFC 4791, Section 5.2.3) */
- supports = supports |
- E_WEBDAV_RESOURCE_SUPPORTS_EVENTS |
- E_WEBDAV_RESOURCE_SUPPORTS_MEMOS |
- E_WEBDAV_RESOURCE_SUPPORTS_TASKS |
- E_WEBDAV_RESOURCE_SUPPORTS_FREEBUSY |
- E_WEBDAV_RESOURCE_SUPPORTS_TIMEZONE;
+ if (!found_comps) {
+ /* If the property is not present, assume all component
+ * types are supported. (RFC 4791, Section 5.2.3) */
+ supports = supports |
+ E_WEBDAV_RESOURCE_SUPPORTS_EVENTS |
+ E_WEBDAV_RESOURCE_SUPPORTS_MEMOS |
+ E_WEBDAV_RESOURCE_SUPPORTS_TASKS |
+ E_WEBDAV_RESOURCE_SUPPORTS_FREEBUSY |
+ E_WEBDAV_RESOURCE_SUPPORTS_TIMEZONE;
+ }
}
}
@@ -3672,7 +3677,7 @@ e_webdav_session_list_cb (EWebDAVSession *webdav,
source_href = e_webdav_session_util_maybe_dequote (g_strdup ((const gchar *)
x_source_href));
}
- supports = e_webdav_session_extract_supports (prop_node);
+ supports = e_webdav_session_extract_supports (prop_node, kind);
etag = e_webdav_session_extract_nonempty (prop_node, E_WEBDAV_NS_DAV, "getetag",
E_WEBDAV_NS_CALENDARSERVER, "getctag");
display_name = e_webdav_session_extract_nonempty (prop_node, E_WEBDAV_NS_DAV, "displayname",
NULL, NULL);
content_type = e_webdav_session_extract_nonempty (prop_node, E_WEBDAV_NS_DAV,
"getcontenttype", NULL, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]