[asterisk-commits] twilson: branch group/calendaring_ews r263194 - /team/group/calendaring_ews/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri May 14 14:46:54 CDT 2010
Author: twilson
Date: Fri May 14 14:46:50 2010
New Revision: 263194
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=263194
Log:
Add attendee support
Modified:
team/group/calendaring_ews/res/res_calendar_ews.c
Modified: team/group/calendaring_ews/res/res_calendar_ews.c
URL: http://svnview.digium.com/svn/asterisk/team/group/calendaring_ews/res/res_calendar_ews.c?view=diff&rev=263194&r1=263193&r2=263194
==============================================================================
--- team/group/calendaring_ews/res/res_calendar_ews.c (original)
+++ team/group/calendaring_ews/res/res_calendar_ews.c Fri May 14 14:46:50 2010
@@ -53,11 +53,23 @@
.unref_calendar = unref_ewscal,
};
+enum xml_op {
+ XML_OP_FIND = 100,
+ XML_OP_GET,
+};
+
+struct calendar_id {
+ struct ast_str *id;
+ AST_LIST_ENTRY(calendar_id) next;
+};
+
struct xml_context {
ne_xml_parser *parser;
struct ast_str *cdata;
struct ast_calendar_event *event;
+ enum xml_op op;
struct ewscal_pvt *pvt;
+ AST_LIST_HEAD_NOLOCK(ids, calendar_id) ids;
};
/* Important states of XML parsing */
@@ -67,7 +79,11 @@
XML_EVENT_END,
XML_EVENT_BUSY,
XML_EVENT_ORGANIZER,
- XML_EVENT_LOCATION
+ XML_EVENT_LOCATION,
+ XML_EVENT_ATTENDEE_LIST,
+ XML_EVENT_ATTENDEE,
+ XML_EVENT_MAILBOX,
+ XML_EVENT_EMAIL_ADDRESS,
};
struct ewscal_pvt {
@@ -150,11 +166,11 @@
struct xml_context *ctx = userdata;
/* Nodes needed for traversing until CalendarItem is found */
- if ( !strcmp(name, "Envelope") ||
- !strcmp(name, "Body") ||
- !strcmp(name, "FindItemResponse") ||
- !strcmp(name, "ResponseMessages") ||
- !strcmp(name, "FindItemResponseMessage") ||
+ if (!strcmp(name, "Envelope") ||
+ !strcmp(name, "Body") ||
+ !strcmp(name, "FindItemResponse") || !strcmp(name, "GetItemResponse") ||
+ !strcmp(name, "ResponseMessages") ||
+ !strcmp(name, "FindItemResponseMessage") || !strcmp(name, "GetItemResponseMessage") ||
!strcmp(name, "Items")
) {
return 1;
@@ -201,8 +217,22 @@
/* Event UID */
else if (!strcmp(name, "ItemId")) {
- ast_debug(1, "EWS: XML: UID: %s\n", ne_xml_get_attr(ctx->parser, atts, NULL, "Id"));
- ast_string_field_set(ctx->event, uid, ne_xml_get_attr(ctx->parser, atts, NULL, "Id"));
+ if (ctx->op == XML_OP_FIND) {
+ struct calendar_id *id;
+ if (!(id = ast_calloc(1, sizeof(id)))) {
+ return NE_XML_ABORT;
+ }
+ if (!(id->id = ast_str_create(256))) {
+ ast_free(id);
+ return NE_XML_ABORT;
+ }
+ ast_str_set(&id->id, 0, "%s", ne_xml_get_attr(ctx->parser, atts, NULL, "Id"));
+ AST_LIST_INSERT_TAIL(&ctx->ids, id, next);
+ ast_debug(1, "EWS_FIND: XML: UID: %s\n", ast_str_buffer(id->id));
+ } else {
+ ast_debug(1, "EWS_GET: XML: UID: %s\n", ne_xml_get_attr(ctx->parser, atts, NULL, "Id"));
+ ast_string_field_set(ctx->event, uid, ne_xml_get_attr(ctx->parser, atts, NULL, "Id"));
+ }
return XML_EVENT_NAME;
}
@@ -246,6 +276,18 @@
}
ast_str_reset(ctx->cdata);
return XML_EVENT_LOCATION;
+ } else if (!strcmp(name, "RequiredAttendees") || !strcmp(name, "OptionalAttendees")) {
+ return XML_EVENT_ATTENDEE_LIST;
+ } else if (!strcmp(name, "Attendee") && parent == XML_EVENT_ATTENDEE_LIST) {
+ return XML_EVENT_ATTENDEE;
+ } else if (!strcmp(name, "Mailbox") && parent == XML_EVENT_ATTENDEE) {
+ return XML_EVENT_MAILBOX;
+ } else if (!strcmp(name, "EmailAddress") && parent == XML_EVENT_MAILBOX) {
+ if (!ctx->cdata) {
+ return NE_XML_ABORT;
+ }
+ ast_str_reset(ctx->cdata);
+ return XML_EVENT_EMAIL_ADDRESS;
}
return NE_XML_DECLINE;
@@ -306,6 +348,10 @@
/* ast_debug(1, "EWS: XML: End: %s\n", name); */
struct xml_context *ctx = userdata;
+ if (ctx->op == XML_OP_FIND) {
+ return 0;
+ }
+
/* Event name end*/
if (!strcmp(name, "Subject")) {
ast_string_field_set(ctx->event, summary, ast_str_buffer(ctx->cdata));
@@ -324,6 +370,20 @@
else if (!strcmp(name, "Location")) {
ast_string_field_set(ctx->event, location, ast_str_buffer(ctx->cdata));
ast_debug(1, "EWS: XML: Location: %s\n", ctx->event->location);
+ ast_str_reset(ctx->cdata);
+ } else if (state == XML_EVENT_EMAIL_ADDRESS) {
+ struct ast_calendar_attendee *attendee;
+
+ if (!(attendee = ast_calloc(1, sizeof(*attendee)))) {
+ ctx->event = ast_calendar_unref_event(ctx->event);
+ return 1;
+ }
+
+ if (ast_str_strlen(ctx->cdata)) {
+ attendee->data = ast_strdup(ast_str_buffer(ctx->cdata));
+ AST_LIST_INSERT_TAIL(&ctx->event->attendees, attendee, next);
+ }
+ ast_debug(1, "EWS: XML: attendee address '%s'\n", ast_str_buffer(ctx->cdata));
ast_str_reset(ctx->cdata);
}
@@ -341,25 +401,28 @@
}
/* Events end */
- else if (!strcmp(name, "RootFolder")) {
+ else if (!strcmp(name, "Envelope")) {
ast_debug(1, "EWS: XML: All events has been parsed, mergingâ¦\n");
ast_calendar_merge_events(ctx->pvt->owner, ctx->pvt->events);
}
return 0;
}
-static int update_ewscal(struct ewscal_pvt *pvt)
+static struct calendar_id *get_ewscal_ids_for(struct ewscal_pvt *pvt)
{
char start[21], end[21];
struct ast_tm tm;
struct timeval tv;
struct ast_str *request;
- struct xml_context ctx;
int ret;
ne_request *req;
ne_xml_parser *parser;
-
- ast_debug(1, "EWS: update_ewscal()\n");
+ struct xml_context ctx = {
+ .pvt = pvt,
+ .op = XML_OP_FIND,
+ };
+
+ ast_debug(1, "EWS: get_ewscal_ids_for()\n");
/*
* This will perform HTTP request
@@ -367,7 +430,7 @@
ast_debug(1, "EWS: HTTP request...\n");
if (!pvt) {
ast_log(LOG_ERROR, "There is no private!\n");
- return -1;
+ return NULL;
}
/* Prepare timeframe strings */
@@ -380,14 +443,14 @@
/* Prepare SOAP request */
if (!(request = ast_str_create(512))) {
- return -1;
+ return NULL;
}
ast_str_set(&request, 0,
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://schemas.microsoft.com/exchange/services/2006/types\" xmlns:ns2=\"http://schemas.microsoft.com/exchange/services/2006/messages\">"
"<SOAP-ENV:Body>"
"<ns2:FindItem Traversal=\"Shallow\">"
"<ns2:ItemShape>"
- "<ns1:BaseShape>AllProperties</ns1:BaseShape>"
+ "<ns1:BaseShape>IdOnly</ns1:BaseShape>"
"</ns2:ItemShape>"
"<ns2:CalendarView StartDate=\"%s\" EndDate=\"%s\"/>" /* Timeframe */
"<ns2:ParentFolderIds>"
@@ -398,7 +461,7 @@
"</SOAP-ENV:Envelope>",
start, end /* Timeframe */
);
- ast_debug(1, "%s", ast_str_buffer(request));
+ ast_debug(3, "%s\n", ast_str_buffer(request));
/* Prepare HTTP POST request */
req = ne_request_create(pvt->session, "POST", pvt->uri.path);
@@ -414,8 +477,7 @@
/* Prepare XML parser */
parser = ne_xml_create();
ctx.parser = parser;
- ctx.event = NULL;
- ctx.pvt = pvt;
+ AST_LIST_HEAD_INIT_NOLOCK(&ctx.ids);
ne_xml_push_handler(parser, startelm, cdata, endelm, &ctx); /* Callbacks */
/* Dispatch request and parse response as XML */
@@ -425,13 +487,97 @@
ne_request_destroy(req);
ast_free(request);
ne_xml_destroy(parser);
- return -1;
+ return NULL;
}
/* Cleanup */
ast_free(request);
ne_request_destroy(req);
ne_xml_destroy(parser);
+
+ return AST_LIST_FIRST(&ctx.ids);
+}
+
+static int parse_ewscal_id(struct ewscal_pvt *pvt, const char *id) {
+ struct ast_str *request;
+ int ret;
+ ne_request *req;
+ ne_xml_parser *parser;
+ struct xml_context ctx = {
+ .pvt = pvt,
+ .op = XML_OP_GET,
+ };
+
+ if (!(request = ast_str_create(512))) {
+ return -1;
+ }
+
+ ast_str_set(&request, 0,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" "
+ "xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">"
+ "<soap:Body>"
+ "<GetItem xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\">"
+ "<ItemShape>"
+ "<t:BaseShape>AllProperties</t:BaseShape>"
+ "</ItemShape>"
+ "<ItemIds>"
+ "<t:ItemId Id=\"%s\"/>"
+ "</ItemIds>"
+ "</GetItem>"
+ "</soap:Body>"
+ "</soap:Envelope>",
+ id);
+ ast_debug(3, "%s\n", ast_str_buffer(request));
+
+ /* Prepare HTTP POST request */
+ req = ne_request_create(pvt->session, "POST", pvt->uri.path);
+ ne_set_request_flag(req, NE_REQFLAG_IDEMPOTENT, 0);
+
+ /* Set headers */
+ ne_add_request_header(req, "Content-Type", "text/xml; charset=utf-8"); /* should be application/soap+xml, but MS⦠:/ */
+ ne_add_request_header(req, "SOAPAction", "\"http://schemas.microsoft.com/exchange/services/2006/messages/GetItem\"");
+
+ /* Set body to SOAP request */
+ ne_set_request_body_buffer(req, ast_str_buffer(request), ast_str_strlen(request));
+
+ /* Prepare XML parser */
+ parser = ne_xml_create();
+ ctx.parser = parser;
+ ne_xml_push_handler(parser, startelm, cdata, endelm, &ctx); /* Callbacks */
+
+ /* Dispatch request and parse response as XML */
+ ret = ne_xml_dispatch_request(req, parser);
+ if (ret != NE_OK) { /* Error handling */
+ ast_log(LOG_WARNING, "Unable to communicate with Exchange Web Service at '%s': %s\n", pvt->url, ne_get_error(pvt->session));
+ ne_request_destroy(req);
+ ne_xml_destroy(parser);
+ ast_free(request);
+ return -1;
+ }
+
+ /* Cleanup */
+ ne_request_destroy(req);
+ ne_xml_destroy(parser);
+ ast_free(request);
+
+ return 0;
+}
+
+static int update_ewscal(struct ewscal_pvt *pvt)
+{
+ struct calendar_id *id_head;
+ struct calendar_id *iter;
+
+ if (!(id_head = get_ewscal_ids_for(pvt))) {
+ return 0;
+ }
+
+ for (iter = id_head; iter; iter = AST_LIST_NEXT(iter, next)) {
+ parse_ewscal_id(pvt, ast_str_buffer(iter->id));
+ ast_free(iter->id);
+ ast_free(iter);
+ }
return 0;
}
More information about the asterisk-commits
mailing list