[asterisk-commits] twilson: branch twilson/calendaring r190185 - in /team/twilson/calendaring: i...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Apr 22 21:31:36 CDT 2009
Author: twilson
Date: Wed Apr 22 21:31:26 2009
New Revision: 190185
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=190185
Log:
Add attendee (read) support for iCalendar and CalDAV
Of course, MS in their infinite wisdom, don't make the attendee list
available over WebDAV like all of the other calendar data--youe have
to use some other hacked up way to get it. Oh, and they deprecated
the WebDAV interface in favor of a SOAP interface. So eventually
we will have to support multiple protocols to be able to access the
wonder that is Microsoft Exchange Server calendaring.
I am negotiating access to a friend's MS Exchange account so that I
can try to get attendees working, but it may be a bit. I would just
re-write everything to use the SOAP interface, but it is only
available in Exchange Server 2007. Gah. But, it looks like
"Mainstream support" for ES 2003 ended 8 days ago...so maybe I should
rewrite it. To heck with those users of ES 2003. Although, apparently
"Extended support" lasts until 4/8/2014--whatever that means.
I really hope the new SOAP interface doesn't suck.
Modified:
team/twilson/calendaring/include/asterisk/calendar.h
team/twilson/calendaring/res/res_caldav.c
team/twilson/calendaring/res/res_calendar.c
team/twilson/calendaring/res/res_exchangecal.c
team/twilson/calendaring/res/res_icalendar.c
Modified: team/twilson/calendaring/include/asterisk/calendar.h
URL: http://svn.digium.com/svn-view/asterisk/team/twilson/calendaring/include/asterisk/calendar.h?view=diff&rev=190185&r1=190184&r2=190185
==============================================================================
--- team/twilson/calendaring/include/asterisk/calendar.h (original)
+++ team/twilson/calendaring/include/asterisk/calendar.h Wed Apr 22 21:31:26 2009
@@ -83,6 +83,11 @@
AST_CALENDAR_BS_BUSY,
};
+struct ast_calendar_attendee {
+ char *data;
+ AST_LIST_ENTRY(ast_calendar_attendee) next;
+};
+
/* \brief Calendar events */
struct ast_calendar_event {
AST_DECLARE_STRING_FIELDS(
@@ -100,6 +105,7 @@
int notify_sched; /*!< The sched for event notification */
int bs_start_sched; /*!< The sched for changing the device state at the start of an event */
int bs_end_sched; /*!< The sched for changing the device state at the end of an event */
+ AST_LIST_HEAD_NOLOCK(attendees, ast_calendar_attendee) attendees;
};
/*! \brief Asterisk calendar structure */
Modified: team/twilson/calendaring/res/res_caldav.c
URL: http://svn.digium.com/svn-view/asterisk/team/twilson/calendaring/res/res_caldav.c?view=diff&rev=190185&r1=190184&r2=190185
==============================================================================
--- team/twilson/calendaring/res/res_caldav.c (original)
+++ team/twilson/calendaring/res/res_caldav.c Wed Apr 22 21:31:26 2009
@@ -364,8 +364,27 @@
}
}
- /* Only set values for alarm based on VALARM. Can be overriden in main/calendar.c by autoreminder */
- /* Currently we are only getting the first VALARM and are handling repitition in main/calendar.c from calendar.conf */
+ /* Get the attendees */
+ for (prop = icalcomponent_get_first_property(comp, ICAL_ATTENDEE_PROPERTY);
+ prop; prop = icalcomponent_get_next_property(comp, ICAL_ATTENDEE_PROPERTY)) {
+ struct ast_calendar_attendee *attendee;
+ const char *data;
+
+ if (!(attendee = ast_calloc(1, sizeof(*attendee)))) {
+ event = ast_calendar_unref_event(event);
+ return;
+ }
+ data = icalproperty_get_attendee(prop);
+ if (!ast_strlen_zero(data)) {
+ attendee->data = ast_strdup(data);;
+ AST_LIST_INSERT_TAIL(&event->attendees, attendee, next);
+ }
+ }
+
+
+ /* Only set values for alarm based on VALARM. Can be overriden in main/calendar.c by autoreminder
+ * therefore, go ahead and add events even if their is no VALARM or it is malformed
+ * Currently we are only getting the first VALARM and are handling repitition in main/calendar.c from calendar.conf */
if (!(valarm = icalcomponent_get_first_component(comp, ICAL_VALARM_COMPONENT))) {
ao2_link(pvt->events, event);
event = ast_calendar_unref_event(event);
Modified: team/twilson/calendaring/res/res_calendar.c
URL: http://svn.digium.com/svn-view/asterisk/team/twilson/calendaring/res/res_calendar.c?view=diff&rev=190185&r1=190184&r2=190185
==============================================================================
--- team/twilson/calendaring/res/res_calendar.c (original)
+++ team/twilson/calendaring/res/res_calendar.c Wed Apr 22 21:31:26 2009
@@ -461,9 +461,16 @@
static void calendar_event_destructor(void *obj)
{
struct ast_calendar_event *event = obj;
+ struct ast_calendar_attendee *attendee;
ast_debug(3, "Destroying event for calendar '%s'\n", event->owner->name);
ast_string_field_free_memory(event);
+ while ((attendee = AST_LIST_REMOVE_HEAD(&event->attendees, next))) {
+ if (attendee->data) {
+ ast_free(attendee->data);
+ }
+ ast_free(attendee);
+ }
return;
}
@@ -529,6 +536,8 @@
event->notify_sched = -1;
event->bs_start_sched = -1;
event->bs_end_sched = -1;
+
+ AST_LIST_HEAD_INIT_NOLOCK(&event->attendees);
return event;
}
@@ -703,6 +712,8 @@
static void copy_event_data(struct ast_calendar_event *dst, struct ast_calendar_event *src)
{
+ struct ast_calendar_attendee *attendee;
+
ast_string_field_set(dst, summary, src->summary);
ast_string_field_set(dst, description, src->description);
ast_string_field_set(dst, organizer, src->organizer);
@@ -713,6 +724,10 @@
dst->end = src->end;
dst->alarm = src->alarm;
dst->busy_state = src->busy_state;
+
+ while ((attendee = AST_LIST_REMOVE_HEAD(&src->attendees, next))) {
+ AST_LIST_INSERT_TAIL(&dst->attendees, attendee, next);
+ }
}
static int schedule_calendar_event(struct ast_calendar *cal, struct ast_calendar_event *old_event, struct ast_calendar_event *cmp_event)
@@ -1001,14 +1016,14 @@
);
if (!chan) {
- ast_log(LOG_WARNING, "CALENDAR_QUERY requires a channel to store the data on\n");
+ ast_log(LOG_WARNING, "%s requires a channel to store the data on\n", cmd);
return -1;
}
AST_STANDARD_APP_ARGS(args, data);
if (ast_strlen_zero(args.calendar)) {
- ast_log(LOG_WARNING, "CALENDAR_QUERY requires a calendar argument\n");
+ ast_log(LOG_WARNING, "%s requires a calendar argument\n", cmd);
return -1;
}
@@ -1017,7 +1032,7 @@
return -1;
}
- if (!(events = ao2_alloc(sizeof(struct eventlist), eventlist_destructor))) {
+ if (!(events = ao2_alloc(sizeof(*events), eventlist_destructor))) {
ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
cal = unref_calendar(cal);
return -1;
@@ -1069,6 +1084,24 @@
.name = "CALENDAR_QUERY",
.read = calendar_query_exec,
};
+
+static void calendar_join_attendees(struct ast_calendar_event *event, char *buf, size_t len)
+{
+ struct ast_str *tmp;
+ struct ast_calendar_attendee *attendee;
+
+ if (!(tmp = ast_str_create(32))) {
+ ast_log(LOG_ERROR, "Could not allocate memory for attendees!\n");
+ return;
+ }
+
+ AST_LIST_TRAVERSE(&event->attendees, attendee, next) {
+ ast_str_append(&tmp, 0, "%s%s", attendee == AST_LIST_FIRST(&event->attendees) ? "" : ",", attendee->data);
+ }
+
+ ast_copy_string(buf, ast_str_buffer(tmp), len);
+ ast_free(tmp);
+}
static int calendar_query_result_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
@@ -1083,14 +1116,14 @@
);
if (!chan) {
- ast_log(LOG_WARNING, "CALENDAR_QUERY_RESULT requires a channel\n");
+ ast_log(LOG_WARNING, "%s requires a channel\n", cmd);
return -1;
}
AST_STANDARD_APP_ARGS(args, data);
if (ast_strlen_zero(args.id) || ast_strlen_zero(args.field)) {
- ast_log(LOG_WARNING, "CALENDAR_QUERY_RESULT requires an id and a field");
+ ast_log(LOG_WARNING, "%s requires an id and a field", cmd);
return -1;
}
@@ -1133,6 +1166,8 @@
snprintf(buf, len, "%ld", entry->event->end);
} else if (!strcasecmp(args.field, "busystate")) {
snprintf(buf, len, "%d", entry->event->busy_state);
+ } else if (!strcasecmp(args.field, "attendees")) {
+ calendar_join_attendees(entry->event, buf, len);
} else {
ast_log(LOG_WARNING, "Unknown field '%s'\n", args.field);
}
@@ -1395,7 +1430,7 @@
struct ast_calendar_event *event;
if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "CALENDAR_EVENT requires an argument\n");
+ ast_log(LOG_WARNING, "%s requires an argument\n", cmd);
return -1;
}
@@ -1430,7 +1465,10 @@
snprintf(buf, len, "%ld", (long)event->end);
} else if (!strcasecmp(data, "busystate")) {
snprintf(buf, len, "%d", event->busy_state);
- }
+ } else if (!strcasecmp(data, "attendees")) {
+ calendar_join_attendees(event, buf, len);
+ }
+
return 0;
}
Modified: team/twilson/calendaring/res/res_exchangecal.c
URL: http://svn.digium.com/svn-view/asterisk/team/twilson/calendaring/res/res_exchangecal.c?view=diff&rev=190185&r1=190184&r2=190185
==============================================================================
--- team/twilson/calendaring/res/res_exchangecal.c (original)
+++ team/twilson/calendaring/res/res_exchangecal.c Wed Apr 22 21:31:26 2009
@@ -181,6 +181,7 @@
}
memcpy(str, value, len);
if (!(state->in_response && state->in_propstat && state->in_prop)) {
+ ast_free(str);
return IKS_OK;
}
/* We use ast_string_field_build here because libiksemel is parsing CDATA with < as
@@ -207,6 +208,7 @@
event->alarm = event->start - atoi(str);
}
+ ast_free(str);
return IKS_OK;
}
@@ -219,7 +221,7 @@
{
struct exchangecal_pvt *pvt = obj;
- ast_debug(1, "Destroying pvt for iCalendar %s\n", pvt->owner->name);
+ ast_debug(1, "Destroying pvt for Exchange calendar %s\n", pvt->owner->name);
if (pvt->session) {
ne_session_destroy(pvt->session);
}
@@ -370,7 +372,7 @@
struct exchangecal_pvt *pvt = userdata;
if (attempts > 1) {
- ast_log(LOG_WARNING, "Invalid username or password for iCalendar '%s'\n", pvt->owner->name);
+ ast_log(LOG_WARNING, "Invalid username or password for Exchange calendar '%s'\n", pvt->owner->name);
return -1;
}
@@ -660,14 +662,14 @@
}
if (ast_strlen_zero(pvt->url)) {
- ast_log(LOG_WARNING, "No URL was specified for iCalendar '%s' - skipping.\n", cal->name);
+ ast_log(LOG_WARNING, "No URL was specified for Exchange calendar '%s' - skipping.\n", cal->name);
pvt = unref_exchangecal(pvt);
ao2_unlock(cal);
return NULL;
}
if (ne_uri_parse(pvt->url, &pvt->uri) || pvt->uri.host == NULL || pvt->uri.path == NULL) {
- ast_log(LOG_WARNING, "Could not parse url '%s' for iCalendar '%s' - skipping.\n", pvt->url, cal->name);
+ ast_log(LOG_WARNING, "Could not parse url '%s' for Exchange calendar '%s' - skipping.\n", pvt->url, cal->name);
pvt = unref_exchangecal(pvt);
ao2_unlock(cal);
return NULL;
Modified: team/twilson/calendaring/res/res_icalendar.c
URL: http://svn.digium.com/svn-view/asterisk/team/twilson/calendaring/res/res_icalendar.c?view=diff&rev=190185&r1=190184&r2=190185
==============================================================================
--- team/twilson/calendaring/res/res_icalendar.c (original)
+++ team/twilson/calendaring/res/res_icalendar.c Wed Apr 22 21:31:26 2009
@@ -227,8 +227,27 @@
}
}
- /* Only set values for alarm based on VALARM. Can be overriden in main/calendar.c by autoreminder */
- /* Currently we are only getting the first VALARM and are handling repitition in main/calendar.c from calendar.conf */
+ /* Get the attendees */
+ for (prop = icalcomponent_get_first_property(comp, ICAL_ATTENDEE_PROPERTY);
+ prop; prop = icalcomponent_get_next_property(comp, ICAL_ATTENDEE_PROPERTY)) {
+ struct ast_calendar_attendee *attendee;
+ const char *data;
+
+ if (!(attendee = ast_calloc(1, sizeof(*attendee)))) {
+ event = ast_calendar_unref_event(event);
+ return;
+ }
+ data = icalproperty_get_attendee(prop);
+ if (!ast_strlen_zero(data)) {
+ attendee->data = ast_strdup(data);;
+ AST_LIST_INSERT_TAIL(&event->attendees, attendee, next);
+ }
+ }
+
+
+ /* Only set values for alarm based on VALARM. Can be overriden in main/calendar.c by autoreminder
+ * therefore, go ahead and add events even if their is no VALARM or it is malformed
+ * Currently we are only getting the first VALARM and are handling repitition in main/calendar.c from calendar.conf */
if (!(valarm = icalcomponent_get_first_component(comp, ICAL_VALARM_COMPONENT))) {
ao2_link(pvt->events, event);
event = ast_calendar_unref_event(event);
More information about the asterisk-commits
mailing list