From 2ee2a3be99a1699549c25752ab47ede7bcb928b3 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Tue, 29 Nov 2016 23:20:56 +0000 Subject: [PATCH] Add Exchange Web Services calendar --- cals/ews.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ doc/exchange.txt | 74 ++++++++++++++++++++++++++++++ makefile | 2 +- src/cal.c | 21 +++++---- src/test.c | 24 ++++++++-- 5 files changed, 224 insertions(+), 14 deletions(-) create mode 100644 cals/ews.c create mode 100644 doc/exchange.txt diff --git a/cals/ews.c b/cals/ews.c new file mode 100644 index 0000000..b8ecaa3 --- /dev/null +++ b/cals/ews.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2016 Andy Spencer + * + * 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 . + */ + +#include + +#include "util.h" +#include "conf.h" +#include "date.h" +#include "cal.h" + +/* Local Types */ +typedef struct ews_t { + cal_t cal; + struct ews_t *next; + + // Config + char *username; + char *password; + char *location; + char *domain; +} ews_t; + +/* Static data */ +static ews_t *calendars; + +/* Local functions */ +static void sync_ews(ews_t *cal) +{ + debug("Loading EWS:"); + debug(" type = %s", cal->cal.type); + debug(" name = %s", cal->cal.name); + debug(" desc = %s", cal->cal.desc); + debug(" username = %s", cal->username); + debug(" password = %s", cal->password); + debug(" location = %s", cal->location); + debug(" domain = %s", cal->domain); +} + +/* Config parser */ +void ews_config(const char *group, const char *name, const char *key, const char *value) +{ + ews_t *cal = NULL, *last = NULL; + + /* Make sure it's valid */ + if (!match(group, "ews") || !name) + return; + + /* Find existing calendar */ + for (cal = calendars; cal; last = cal, cal = cal->next) + if (match(cal->cal.name, name)) + break; + + /* Create new calendar */ + if (!cal) { + cal = new0(ews_t); + cal->cal.type = "ews"; + cal->cal.name = get_name(name); + if (last) + last->next = cal; + else + calendars = cal; + } + + /* Set calendar values */ + if (match(key, "location")) + cal->location = get_string(value); + else if (match(key, "username")) + cal->username = get_string(value); + else if (match(key, "password")) + cal->password = get_string(value); + else if (match(key, "domain")) + cal->domain = get_string(value); +} + +/* Cal functions */ +cal_t *ews_cals(void) +{ + for (ews_t *cal = calendars; cal; cal = cal->next) { + sync_ews(cal); + cal->cal.next = &cal->next->cal; + } + + return &calendars->cal; +} + +/* Event functions */ +event_t *ews_events(date_t start, date_t end) +{ + return NULL; +} + +/* Todo functions */ +todo_t *ews_todos(date_t start, date_t end) +{ + return NULL; +} + +/* Test functions */ +void ews_test(char *url, char *user, char *pass) +{ + printf("EWS -- test start\n"); + printf("EWS -- test end\n"); +} diff --git a/doc/exchange.txt b/doc/exchange.txt new file mode 100644 index 0000000..123f907 --- /dev/null +++ b/doc/exchange.txt @@ -0,0 +1,74 @@ +Microsoft Exhange Calendars + +Overview +-------- +- Use Exchange Web Services +- Use HTTP basic authentication + +For calendars: + 1. Use FindItem and CalendarView + - supply date range and fields + - returns a list of item IDs + 2. Use GetItem to get details + - supply all IDs return by FindItem + - need to request field for details + +Alternately: + 1. Request everything with FindItem + + +SOAP Requests +------------- +# For email (mostly) +SyncFolderItems: + ItemShape + BaseShape + +# Common +GetItem: + ItemIds :: list + ItemId + Id + ChangeKey + ItemShape :: struct + BaseShape="IdOnly" + BodyType="Best" + +# For Calendars +FindItem: + ParentFolderIds + DistinguishedFolderId + Id + + ItemShape: + BaseShape = IdOnly + AdditionalProperties :: list + calendar:UID + calendar:CalendarItemType + calendar:Start + calendar:End + item:ItemClass + item:Subject + + CalendarView: + StartDate + EndDate + MaxEntriesReturned + + returns: + /t:Items/t:CalendarItem :: CalendarItem + +CalendarItem: + t:UID + t:Start + t:End + t:ItemId :: tag + Id + ChangeKey + t:CalendarItemType :: enum + Occurrence + Exception + RecurringMaster + Single + +# vim: ft=txt diff --git a/makefile b/makefile index ce82c84..a479829 100644 --- a/makefile +++ b/makefile @@ -19,7 +19,7 @@ PROG_SRC ?= main util args conf date cal view print daemon TEST ?= test TEST_SRC ?= test util conf date cal daemon VIEWS ?= day week month year events todo settings help edit -CALS ?= dummy ical +CALS ?= dummy ical ews # Objects views/%.o cals/%.o: CFLAGS += -Isrc diff --git a/src/cal.c b/src/cal.c index afc18f0..8fe7e70 100644 --- a/src/cal.c +++ b/src/cal.c @@ -31,6 +31,7 @@ /* Prototypes */ CAL(dummy); CAL(ical); +CAL(ews); /* Global data */ cal_t *CAL, *CALS; @@ -106,9 +107,9 @@ static todo_t *merge_todos(todo_t *a, todo_t *b) void cal_init(void) { /* Load calendars */ - CALS = merge_cals( - dummy_cals(), - ical_cals()); + CALS = merge_cals(CALS, dummy_cals()); + CALS = merge_cals(CALS, ical_cals()); + CALS = merge_cals(CALS, ews_cals()); /* Load data */ cal_load(SEL.year, SEL.month, SEL.day, 1); @@ -164,14 +165,14 @@ void cal_load(year_t year, month_t month, day_t day, int days) end = (date_t){eyear, emonth, eday}; /* Load events */ - EVENTS = merge_events( - dummy_events(start, end), - ical_events(start, end)); + EVENTS = merge_events(NULL, dummy_events(start, end)); + EVENTS = merge_events(EVENTS, ical_events(start, end)); + EVENTS = merge_events(EVENTS, ews_events(start, end)); /* Load todos */ - TODOS = merge_todos( - dummy_todos(start, end), - ical_todos(start, end)); + TODOS = merge_todos(NULL, dummy_todos(start, end)); + TODOS = merge_todos(TODOS, ical_todos(start, end)); + TODOS = merge_todos(TODOS, ews_todos(start, end)); /* Verify events and todos*/ #ifdef CAL_ERROR @@ -199,6 +200,8 @@ void cal_config(const char *group, const char *name, const char *key, const char dummy_config(group, name, key, value); else if (match(group, "ical")) ical_config(group, name, key, value); + else if (match(group, "ews")) + ews_config(group, name, key, value); } /* Find event for matching target date */ diff --git a/src/test.c b/src/test.c index 9152b70..3ac33fb 100644 --- a/src/test.c +++ b/src/test.c @@ -23,15 +23,31 @@ void date_test(void); void conf_test(void); void ical_test(void *path); +void ews_test(char *url, char *user, char *pass); void daemon_test(); int main(int argc, char **argv) { for (int i = 1; i < argc; i++) { - if (match(argv[i], "date")) date_test(); - if (match(argv[i], "conf")) conf_test(); - if (match(argv[i], "ical")) ical_test(argv[++i]); - if (match(argv[i], "daemon")) daemon_test(); + if (match(argv[i], "date")) { + date_test(); + } + if (match(argv[i], "conf")) { + conf_test(); + } + if (match(argv[i], "ical")) { + char *path = argv[++i]; + ical_test(path); + } + if (match(argv[i], "ews")) { + char *url = argv[++i]; + char *user = argv[++i]; + char *pass = argv[++i]; + ews_test(url, user, pass); + } + if (match(argv[i], "daemon")) { + daemon_test(); + } } return 0; } -- 2.43.2