diff --git a/CalDav.Client/CalDav.Client.csproj b/CalDav.Client/CalDav.Client.csproj deleted file mode 100644 index 5b3b531..0000000 --- a/CalDav.Client/CalDav.Client.csproj +++ /dev/null @@ -1,64 +0,0 @@ - - - - - Debug - AnyCPU - {1B9B42A0-A34B-4BF6-A5D5-21C46ED0D9B3} - Library - Properties - CalDav.Client - CalDav.Client - v4.5 - 512 - ..\ - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - {01a4c4cf-5ad1-4324-a391-dc922c84be1c} - CalDav - - - - - - \ No newline at end of file diff --git a/CalDav.Client/Calendar.cs b/CalDav.Client/Calendar.cs deleted file mode 100644 index 99d95db..0000000 --- a/CalDav.Client/Calendar.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Xml.Linq; - -namespace CalDav.Client { - public class Calendar { - public Uri Url { get; set; } - public NetworkCredential Credentials { get; set; } - public string Name { get; set; } - public string Description { get; set; } - - public void Initialize() { - var result = Common.Request(Url, "PROPFIND", CalDav.Common.xDav.Element("propfind", - CalDav.Common.xDav.Element("allprop")), Credentials, new Dictionary { - { "Depth", 0 } - }); - var xdoc = XDocument.Parse(result.Item2); - var desc = xdoc.Descendants(CalDav.Common.xCalDav.GetName("calendar-description")).FirstOrDefault(); - var name = xdoc.Descendants(CalDav.Common.xDav.GetName("displayname")).FirstOrDefault(); - if (name != null) Name = name.Value; - if (desc != null) Description = desc.Value; - - var resourceTypes = xdoc.Descendants(CalDav.Common.xDav.GetName("resourcetype")); - if (!resourceTypes.Any( - r => r.Elements(CalDav.Common.xDav.GetName("collection")).Any() - && r.Elements(CalDav.Common.xCalDav.GetName("calendar")).Any() - )) - throw new Exception("This server does not appear to support CALDAV"); - } - - public CalendarCollection Search(CalDav.CalendarQuery query) { - var result = Common.Request(Url, "REPORT", (XElement)query, Credentials, new Dictionary { - { "Depth", 1 } - }); - var xdoc = XDocument.Parse(result.Item2); - var data = xdoc.Descendants(CalDav.Common.xCalDav.GetName("calendar-data")); - var serializer = new Serializer(); - return new CalendarCollection(data.SelectMany(x => { - using (var rdr = new System.IO.StringReader(x.Value)) { - return serializer.Deserialize(rdr); - } - })); - } - - public void Save(Event e) { - if (string.IsNullOrEmpty(e.UID)) e.UID = Guid.NewGuid().ToString(); - e.LastModified = DateTime.UtcNow; - - var result = Common.Request(new Uri(Url, e.UID + ".ics"), "PUT", (req, str) => { - req.Headers[System.Net.HttpRequestHeader.IfNoneMatch] = "*"; - req.ContentType = "text/calendar"; - var calendar = new CalDav.Calendar(); - e.Sequence = (e.Sequence ?? 0) + 1; - calendar.Events.Add(e); - Common.Serialize(str, calendar); - - }, Credentials); - if (result.Item1 != System.Net.HttpStatusCode.Created && result.Item1 != HttpStatusCode.NoContent) - throw new Exception("Unable to save event: " + result.Item1); - e.Url = new Uri(Url, result.Item3[System.Net.HttpResponseHeader.Location]); - - GetObject(e.UID); - } - - public CalendarCollection GetAll() { - var result = Common.Request(Url, "PROPFIND", CalDav.Common.xCalDav.Element("calendar-multiget", - CalDav.Common.xDav.Element("prop", - CalDav.Common.xDav.Element("getetag"), - CalDav.Common.xCalDav.Element("calendar-data") - ) - ), Credentials, new Dictionary { { "Depth", 1 } }); - - - - - return null; - } - - public CalendarCollection GetObject(string uid) { - var result = Common.Request(Url, "REPORT", CalDav.Common.xCalDav.Element("calendar-multiget", - CalDav.Common.xDav.Element("prop", - CalDav.Common.xDav.Element("getetag"), - CalDav.Common.xCalDav.Element("calendar-data") - ), - CalDav.Common.xDav.Element("href", new Uri(Url, uid + ".ics")) - ), Credentials, new Dictionary { { "Depth", 1 } }); - - - return null; - - } - } -} diff --git a/CalDav.Client/Common.cs b/CalDav.Client/Common.cs deleted file mode 100644 index f2af237..0000000 --- a/CalDav.Client/Common.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Net; -using System.Xml.Linq; - -namespace CalDav.Client { - internal static class Common { - - public static Tuple Request(Uri url, string method, XDocument content, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { - return Request(url, method, content.Root, credentials, headers); - } - public static Tuple Request(Uri url, string method, XElement content, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { - return Request(url, method, (req, str) => { - req.ContentType = "text/xml"; - var xml = content.ToString(); - using (var wrtr = new System.IO.StreamWriter(str)) - wrtr.Write(xml); - }, credentials, headers); - } - - public static Tuple Request(Uri url, string method, string contentType, string content, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { - return Request(url, method, (req, str) => { - req.ContentType = contentType; - using (var wrtr = new System.IO.StreamWriter(str)) - wrtr.Write(content); - }, credentials, headers); - } - - public static Tuple Request(Uri url, string method = "GET", Action content = null, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { - var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url); - req.Method = method.ToUpper(); - - //Dear .NET, please don't try to do things for me. kthxbai - System.Net.ServicePointManager.Expect100Continue = false; - - if (headers != null) - foreach (var header in headers) { - var value = Convert.ToString(header.Value); - if (header.Key.Is("User-Agent")) - req.UserAgent = value; - else req.Headers[header.Key] = value; - } - - if (credentials != null) { - //req.Credentials = credentials; - var b64 = credentials.UserName + ":" + credentials.Password; - b64 = System.Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(b64)); - req.Headers[HttpRequestHeader.Authorization] = "Basic " + b64; - } - - using (var stream = req.GetRequestStream()) { - if (content != null) { - content(req, stream); - } - - using (var res = GetResponse(req)) - using (var str = res.GetResponseStream()) - using (var rdr = new System.IO.StreamReader(str)) { - return Tuple.Create(res.StatusCode, rdr.ReadToEnd(), res.Headers); - } - } - } - - private static System.Net.HttpWebResponse GetResponse(System.Net.HttpWebRequest req) { - try { - return (System.Net.HttpWebResponse)req.GetResponse(); - } catch (System.Net.WebException wex) { - return (System.Net.HttpWebResponse)wex.Response; - } - } - - public static void Serialize(System.IO.Stream stream, Event e, System.Text.Encoding encoding = null) { - var ical = new CalDav.Calendar(); - ical.Events.Add(e); - Serialize(stream, ical, encoding); - } - - public static void Serialize(System.IO.Stream stream, CalDav.Calendar ical, System.Text.Encoding encoding = null) { - var serializer = new CalDav.Serializer(); - serializer.Serialize(stream, ical, encoding); - } - } -} diff --git a/CalDav.Client/Properties/AssemblyInfo.cs b/CalDav.Client/Properties/AssemblyInfo.cs deleted file mode 100644 index 384b32d..0000000 --- a/CalDav.Client/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("CalDav.Client")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("CalDav.Client")] -[assembly: AssemblyCopyright("Copyright © 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("1c876acc-09dc-4f34-a6fd-ab014f47219a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CalDav.Client/Server.cs b/CalDav.Client/Server.cs deleted file mode 100644 index 7e89355..0000000 --- a/CalDav.Client/Server.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml.Linq; - -namespace CalDav.Client { - public class Server { - public Uri Url { get; set; } - public System.Net.NetworkCredential Credentials { get; set; } - public Server(string url, string username = null, string password = null) - : this(new Uri(url), username, password) { } - - private HashSet _Options; - - public Server(Uri url, string username = null, string password = null) { - Url = url; - if (username != null && password != null) { - Credentials = new System.Net.NetworkCredential(username, password); - } - _Options = GetOptions(); - } - - public HashSet Options { - get { - if (_Options == null) - lock (this) - if (_Options == null) - _Options = GetOptions(); - return _Options; - } - } - - private HashSet GetOptions() { - var result = Common.Request(Url, "options", credentials: Credentials); - if (result.Item3["WWW-Authenticate"] != null) - throw new Exception("Authentication is required"); - var dav = result.Item3["DAV"]; - if (dav == null || !dav.Contains("calendar-access")) - throw new Exception("This does not appear to be a valid CalDav server"); - return new HashSet((result.Item3["Allow"] ?? string.Empty).ToUpper().Split(',').Select(x => x.Trim()).Distinct(), StringComparer.OrdinalIgnoreCase); - } - - public void CreateCalendar(string name) { - if (!Options.Contains("MKCALENDAR")) - throw new Exception("This server does not support creating calendars"); - var result = Common.Request(new Uri(Url, name), "mkcalendar", credentials: Credentials); - if (result.Item1 != System.Net.HttpStatusCode.Created) - throw new Exception("Unable to create calendar"); - } - - public Calendar[] GetCalendars() { - var xcollectionset = CalDav.Common.xCalDav.GetName("calendar-collection-set"); - var result = Common.Request(Url, "propfind", new XDocument( - new XElement(CalDav.Common.xDav.GetName("options"), - new XElement(xcollectionset) - ) - ), Credentials, new System.Collections.Generic.Dictionary { { "Depth", 0 } }); - - if (string.IsNullOrEmpty(result.Item2)) - return new[]{ - new Calendar { Url = Url, Credentials = Credentials } - }; - - var xdoc = XDocument.Parse(result.Item2); - var hrefs = xdoc.Descendants(xcollectionset).SelectMany(x => x.Descendants(CalDav.Common.xDav.GetName("href"))); - return hrefs.Select(x => new Calendar { Url = new Uri(Url, x.Value), Credentials = Credentials }).ToArray(); - } - - - public bool Supports(string option) { - return Options.Contains(option); - } - } -} diff --git a/CalDav.Server/CalDav.Server.csproj b/CalDav.Server/CalDav.Server.csproj deleted file mode 100644 index 76140e4..0000000 --- a/CalDav.Server/CalDav.Server.csproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Debug - AnyCPU - {471EA68F-FB1F-4DF8-AAC1-31022C7316AB} - Library - Properties - CalDav.Server - CalDav.Server - v4.0 - 512 - ..\ - true - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - {01a4c4cf-5ad1-4324-a391-dc922c84be1c} - CalDav - - - - - Designer - - - - - - \ No newline at end of file diff --git a/CalDav.Server/CalDav.Server.nuspec b/CalDav.Server/CalDav.Server.nuspec deleted file mode 100644 index 00084a4..0000000 --- a/CalDav.Server/CalDav.Server.nuspec +++ /dev/null @@ -1,16 +0,0 @@ - - - - CalDav.Server - #version# - Tracky, Andy Edinborough - Simple CalDav server. - en-US - http://andyedinborough.mit-license.org/ - - ical, caldav, dday - - - - - \ No newline at end of file diff --git a/CalDav.Server/Controllers/CalDavController.cs b/CalDav.Server/Controllers/CalDavController.cs deleted file mode 100644 index 7481558..0000000 --- a/CalDav.Server/Controllers/CalDavController.cs +++ /dev/null @@ -1,421 +0,0 @@ -using CalDav.Server.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Web.Mvc; -using System.Web.Routing; -using System.Xml.Linq; -//http://greenbytes.de/tech/webdav/draft-dusseault-caldav-05.html -//http://wwcsd.net/principals/__uids__/wiki-ilovemysmartboard/ - - -namespace CalDav.Server.Controllers { - public class CalDavController : Controller { - public static void RegisterRoutes(System.Web.Routing.RouteCollection routes, string routePrefix = "caldav", bool disallowMakeCalendar = false, bool requireAuthentication = false, string basicAuthenticationRealm = null) { - RegisterRoutes(routes, routePrefix, disallowMakeCalendar, requireAuthentication, basicAuthenticationRealm); - } - public static void RegisterRoutes(System.Web.Routing.RouteCollection routes, string routePrefix = "caldav", bool disallowMakeCalendar = false, bool requireAuthentication = false, string basicAuthenticationRealm = null) - where T : CalDavController { - var caldavControllerType = typeof(T); - - var namespaces = new[] { caldavControllerType.Namespace }; - var controller = caldavControllerType.Name; - if (caldavControllerType.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) - controller = caldavControllerType.Name.Substring(0, caldavControllerType.Name.Length - "controller".Length); - - var defaults = new { controller, action = "index" }; - MapFirst(routes, "CalDav Root", string.Empty, new { controller, action = "PropFind" }, namespaces, new { httpMethod = new Method("PROPFIND") }); - MapFirst(routes, "CalDav", BASE = routePrefix, defaults, namespaces); - MapFirst(routes, "CalDav", BASE = routePrefix, defaults, namespaces); - MapFirst(routes, "CalDav User", USER_ROUTE = routePrefix + "/user/{id}/", defaults, namespaces); - MapFirst(routes, "CalDav Calendar", CALENDAR_ROUTE = routePrefix + "/calendar/{id}/", defaults, namespaces); - MapFirst(routes, "CalDav Object", OBJECT_ROUTE = routePrefix + "/{uid}.ics", defaults, namespaces); - MapFirst(routes, "CalDav Calendar Object", CALENDAR_OBJECT_ROUTE = routePrefix + "/calendar/{id}/{uid}.ics", defaults, namespaces); - rxObjectRoute = new Regex(routePrefix + "(/calendar/(?[^/]+))?/(?.+?).ics", RegexOptions.Compiled | RegexOptions.IgnoreCase); - - RequireAuthentication = requireAuthentication; - BasicAuthenticationRealm = basicAuthenticationRealm; - DisallowMakeCalendar = disallowMakeCalendar; - } - - private static void MapFirst(System.Web.Routing.RouteCollection routes, string name, string path, object defaults, string[] namespaces, object constraints = null) { - var route = routes.MapRoute(name, path, defaults); - if (constraints != null) - route.Constraints = new System.Web.Routing.RouteValueDictionary(constraints); - routes.Remove(route); - routes.Insert(0, route); - } - - public virtual ActionResult Index(string id, string uid) { - if (RequireAuthentication && !User.Identity.IsAuthenticated) { - return new Result { - Status = System.Net.HttpStatusCode.Unauthorized, - Headers = BasicAuthenticationRealm == null ? null : new Dictionary { - {"WWW-Authenticate", "Basic realm=\"" + Request.Url.Host + "\"" } - } - }; - } - - switch (Request.HttpMethod) { - case "OPTIONS": return Options(); - case "PROPFIND": return PropFind(id); - case "REPORT": return Report(id); - case "DELETE": return Delete(id, uid); - case "PUT": return Put(id, uid); - case "MKCALENDAR": - if (DisallowMakeCalendar) return NotImplemented(); - return MakeCalendar(id); - case "GET": return Get(id, uid); - default: return NotImplemented(); - } - } - - private static string BASE, CALENDAR_ROUTE, OBJECT_ROUTE, CALENDAR_OBJECT_ROUTE, USER_ROUTE; - private static Regex rxObjectRoute; - public static bool DisallowMakeCalendar { get; set; } - public static bool RequireAuthentication { get; set; } - public static string BasicAuthenticationRealm { get; set; } - - protected virtual string GetUserUrl(string id = null) { - if (string.IsNullOrEmpty(id)) - return GetCalendarUrl(null); - //id = User.Identity.Name; - if (string.IsNullOrEmpty(id)) id = "ANONYMOUS"; - return "/" + USER_ROUTE.Replace("{id}", Uri.EscapeDataString(id)).Replace("{*path}", string.Empty); - } - - protected virtual string GetUserEmail(string id = null) { - if (string.IsNullOrEmpty(id)) id = User.Identity.Name; - return id + "@" + Request.Url.Host; - } - protected virtual string GetCalendarUrl(string id) { - if (string.IsNullOrEmpty(id)) return "/" + BASE; - return "/" + CALENDAR_ROUTE.Replace("{id}", Uri.EscapeDataString(id)); - } - protected virtual string GetCalendarObjectUrl(string id, string uid) { - if (string.IsNullOrEmpty(id)) - return "/" + OBJECT_ROUTE.Replace("{uid}", Uri.EscapeDataString(uid)); - return "/" + CALENDAR_OBJECT_ROUTE.Replace("{id}", Uri.EscapeDataString(id)).Replace("{uid}", Uri.EscapeDataString(uid)); - } - protected virtual string GetObjectUIDFromPath(string path) { - return rxObjectRoute.Match(path).Groups["uid"].Value; - } - - public virtual ActionResult Options() { - var xdoc = GetRequestXml(); - if (xdoc != null) { - var request = xdoc.Root.Elements().FirstOrDefault(); - switch (request.Name.LocalName.ToLower()) { - case "calendar-collection-set": - var repo = GetService(); - var calendars = repo.GetCalendars().ToArray(); - - return new Result { - Content = CalDav.Common.xDav.Element("options-response", - CalDav.Common.xCalDav.Element("calendar-collection-set", - calendars.Select(calendar => - CalDav.Common.xDav.Element("href", - new Uri(Request.Url, GetCalendarUrl(calendar.Name)) - )) - ) - ) - }; - } - } - - return new Result { - Headers = new Dictionary { - {"Allow", "OPTIONS, PROPFIND, HEAD, GET, REPORT, PROPPATCH, PUT, DELETE, POST" } - } - }; - } - - public class Method : ActionMethodSelectorAttribute, IRouteConstraint { - private string _Method; - public Method(string method) { - _Method = method.ToUpper(); - } - - public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo) { - return _Method.Equals(controllerContext.HttpContext.Request.HttpMethod, StringComparison.OrdinalIgnoreCase); - } - - public bool Match(System.Web.HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { - return _Method.Equals(httpContext.Request.HttpMethod, StringComparison.OrdinalIgnoreCase); - } - } - - public virtual ActionResult PropFind(string id) { - var depth = Request.Headers["Depth"].ToInt() ?? 0; - var repo = GetService(); - var calendar = repo.GetCalendarByID(id); - - var xdoc = GetRequestXml(); - var props = xdoc.Descendants(CalDav.Common.xDav.GetName("prop")).FirstOrDefault().Elements(); - - var allprop = props.Elements(Common.xDav.GetName("allprops")).Any(); - var hrefName = Common.xDav.GetName("href"); - //var scheduleInboxURLName = Common.xCalDav.GetName("schedule-inbox-URL"); - //var scheduleOutoxURLName = Common.xCalDav.GetName("schedule-outbox-URL"); - //var addressbookHomeSetName = Common.xCalDav.GetName("addressbook-home-set"); - - var calendarUserAddressSetName = Common.xCalDav.GetName("calendar-user-address-set"); - var calendarUserAddress = !allprop && !props.Any(x => x.Name == calendarUserAddressSetName) ? null : - calendarUserAddressSetName.Element( - hrefName.Element(GetUserUrl()), - hrefName.Element("mailto:" + GetUserEmail()) - ); - - - var supportedReportSetName = Common.xDav.GetName("supported-report-set"); - var supportedReportSet = !allprop && !props.Any(x => x.Name == supportedReportSetName) ? null : - supportedReportSetName.Element( - Common.xDav.Element("supported-report", Common.xDav.Element("report", Common.xDav.Element("calendar-multiget"))) - ); - - var calendarHomeSetName = Common.xCalDav.GetName("calendar-home-set"); - var calendarHomeSet = !allprop && !props.Any(x => x.Name == calendarHomeSetName) ? null : - calendarHomeSetName.Element(hrefName.Element(GetUserUrl())); - - var getetagName = Common.xDav.GetName("getetag"); - var getetag = !allprop && !props.Any(x => x.Name == getetagName) ? null : - getetagName.Element(); - - var currentUserPrincipalName = Common.xDav.GetName("current-user-principal"); - var currentUserPrincipal = !props.Any(x => x.Name == currentUserPrincipalName) ? null : - currentUserPrincipalName.Element(hrefName.Element(GetUserUrl())); - - var resourceTypeName = Common.xDav.GetName("resourcetype"); - var resourceType = !allprop && !props.Any(x => x.Name == resourceTypeName) ? null : ( - resourceTypeName.Element(Common.xDav.Element("collection"), Common.xCalDav.Element("calendar"), Common.xDav.Element("principal")) - ); - - var ownerName = Common.xDav.GetName("owner"); - var owner = !allprop && !props.Any(x => x.Name == ownerName) ? null : - ownerName.Element(hrefName.Element(GetUserUrl())); - - var displayNameName = Common.xDav.GetName("displayname"); - var displayName = calendar == null || (!allprop && !props.Any(x => x.Name == displayNameName)) ? null : - displayNameName.Element(calendar.Name ?? calendar.ID); - - var calendarColorName = Common.xApple.GetName("calendar-color"); - var calendarColor = !allprop && !props.Any(x => x.Name == calendarColorName) ? null : - calendarColorName.Element("FF5800"); - - var calendarDescriptionName = Common.xCalDav.GetName("calendar-description"); - var calendarDescription = calendar == null || (!allprop && !props.Any(x => x.Name == calendarDescriptionName)) ? null : - calendarDescriptionName.Element(calendar.Name); - - var supportedComponentsName = Common.xCalDav.GetName("supported-calendar-component-set"); - var supportedComponents = !allprop && !props.Any(x => x.Name == supportedComponentsName) ? null : - new[]{ - Common.xCalDav.Element("comp", new XAttribute("name", "VEVENT")), - Common.xCalDav.Element("comp", new XAttribute("name", "VTODO")) - }; - - var getContentTypeName = Common.xDav.GetName("getcontenttype"); - var getContentType = !allprop && !props.Any(x => x.Name == getContentTypeName) ? null : - getContentTypeName.Element("text/calendar; component=vevent"); - - var supportedProperties = new HashSet { - resourceTypeName, ownerName, supportedComponentsName, getContentTypeName, - displayNameName, calendarDescriptionName, calendarColorName, - currentUserPrincipalName, calendarHomeSetName, calendarUserAddressSetName, - supportedComponentsName - }; - var prop404 = Common.xDav.Element("prop", props - .Where(p => !supportedProperties.Contains(p.Name)) - .Select(p => new XElement(p.Name)) - ); - var propStat404 = Common.xDav.Element("propstat", - Common.xDav.Element("status", "HTTP/1.1 404 Not Found"), prop404); - - return new Result { - Status = (System.Net.HttpStatusCode)207, - Content = Common.xDav.Element("multistatus", - Common.xDav.Element("response", - Common.xDav.Element("href", Request.RawUrl), - Common.xDav.Element("propstat", - Common.xDav.Element("status", "HTTP/1.1 200 OK"), - Common.xDav.Element("prop", - resourceType, owner, supportedComponents, displayName, - getContentType, calendarDescription, calendarHomeSet, - currentUserPrincipal, supportedReportSet, calendarColor, - calendarUserAddress - ) - ), - - (prop404.Elements().Any() ? propStat404 : null) - ), - - (depth == 0 ? null : - (repo.GetObjects(calendar) - .Where(x => x != null) - .ToArray() - .Select(item => Common.xDav.Element("response", - hrefName.Element(GetCalendarObjectUrl(calendar.ID, item.UID)), - Common.xDav.Element("propstat", - Common.xDav.Element("status", "HTTP/1.1 200 OK"), - resourceType == null ? null : resourceTypeName.Element(), - (getContentType == null ? null : getContentTypeName.Element("text/calendar; component=v" + item.GetType().Name.ToLower())), - getetag == null ? null : getetagName.Element("\"" + Common.FormatDate(item.LastModified) + "\"") - ) - )) - .ToArray())) - ) - }; - } - - public virtual ActionResult MakeCalendar(string id) { - var repo = GetService(); - var calendar = repo.CreateCalendar(id); - - return new Result { - Headers = new Dictionary { - {"Location", GetCalendarUrl(calendar.ID) }, - }, - Status = System.Net.HttpStatusCode.Created - }; - } - - public virtual ActionResult Delete(string id, string uid) { - var repo = GetService(); - var calendar = repo.GetCalendarByID(id); - repo.DeleteObject(calendar, uid); - return new Result(); - } - - public virtual ActionResult Put(string id, string uid) { - var repo = GetService(); - var calendar = repo.GetCalendarByID(id); - var input = GetRequestCalendar(); - var e = input.Items.FirstOrDefault(); - e.LastModified = DateTime.UtcNow; - repo.Save(calendar, e); - - return new Result { - Headers = new Dictionary { - {"Location", GetCalendarObjectUrl(calendar.ID, e.UID) }, - {"ETag", Common.FormatDate(e.LastModified) } - }, - Status = System.Net.HttpStatusCode.Created - }; - } - - public virtual ActionResult Get(string id, string uid) { - var repo = GetService(); - var calendar = repo.GetCalendarByID(id); - var obj = repo.GetObjectByUID(calendar, uid); - - Response.ContentType = "text/calendar"; - Response.Write(ToString(obj)); - return null; - } - - public virtual ActionResult Report(string id) { - var xdoc = GetRequestXml(); - if (xdoc == null) return new Result(); - - var repo = GetService(); - var calendar = repo.GetCalendarByID(id); - - var request = xdoc.Root.Elements().FirstOrDefault(); - var filterElm = request.Element(CalDav.Common.xCalDav.GetName("filter")); - var filter = filterElm == null ? null : new Filter(filterElm); - var hrefName = CalDav.Common.xDav.GetName("href"); - var hrefs = xdoc.Descendants(hrefName).Select(x => x.Value).ToArray(); - var getetagName = CalDav.Common.xDav.GetName("getetag"); - var getetag = xdoc.Descendants(getetagName).FirstOrDefault(); - var calendarDataName = CalDav.Common.xCalDav.GetName("calendar-data"); - var calendarData = xdoc.Descendants(calendarDataName).FirstOrDefault(); - - var ownerName = Common.xDav.GetName("owner"); - var displaynameName = Common.xDav.GetName("displayname"); - - IQueryable result = null; - if (filter != null) result = repo.GetObjectsByFilter(calendar, filter); - else if (hrefs.Any()) - result = hrefs.Select(x => repo.GetObjectByUID(calendar, GetObjectUIDFromPath(x))) - .Where(x => x != null) - .AsQueryable(); - - if (result != null) { - return new Result { - Status = (System.Net.HttpStatusCode)207, - Content = CalDav.Common.xDav.Element("multistatus", - result.Select(r => - CalDav.Common.xDav.Element("response", - CalDav.Common.xDav.Element("href", new Uri(Request.Url, r.UID + ".ics")), - CalDav.Common.xDav.Element("propstat", - CalDav.Common.xDav.Element("status", "HTTP/1.1 200 OK"), - CalDav.Common.xDav.Element("prop", - (getetag == null ? null : CalDav.Common.xDav.Element("getetag", "\"" + Common.FormatDate(r.LastModified) + "\"")), - (calendarData == null ? null : CalDav.Common.xCalDav.Element("calendar-data", - ToString(r) - )) - ) - ) - ) - )) - }; - } - - return new Result { - Headers = new Dictionary { - {"ETag" , calendar == null ? null : Common.FormatDate( calendar.LastModified ) } - } - }; - } - - public ActionResult NotImplemented() { - return new Result { Status = System.Net.HttpStatusCode.NotImplemented }; - } - - private List _Disposables = new List(); - private T GetService() { - var obj = System.Web.Mvc.DependencyResolver.Current.GetService(); - if (obj != null && obj is IDisposable) - _Disposables.Add(obj as IDisposable); - return obj; - } - - protected override void OnResultExecuted(ResultExecutedContext filterContext) { - base.OnResultExecuted(filterContext); - foreach (var disposable in _Disposables) - if (disposable != null) - try { - disposable.Dispose(); - } catch (Exception) { } - } - - internal System.IO.Stream Stream { get; set; } - - private XDocument GetRequestXml() { - if (!(Request.ContentType ?? string.Empty).ToLower().Contains("xml") || Request.ContentLength == 0) - return null; - using (var str = (Stream ?? Request.InputStream)) - return XDocument.Load(str); - } - - private Calendar GetRequestCalendar() { - if (!(Request.ContentType ?? string.Empty).ToLower().Contains("calendar") || Request.ContentLength == 0) - return null; - var serializer = new Serializer(); - using (var str = (Stream ?? Request.InputStream)) { - var ical = serializer.Deserialize(str, Request.ContentEncoding ?? System.Text.Encoding.Default); - return ical.FirstOrDefault(); - } - } - - private static string ToString(ICalendarObject obj) { - var calendar = new CalDav.Calendar(); - calendar.AddItem(obj); - var serializer = new Serializer(); - using (var str = new System.IO.StringWriter()) { - serializer.Serialize(str, calendar); - return str.ToString(); - } - } - } -} diff --git a/CalDav.Server/Controllers/Result.cs b/CalDav.Server/Controllers/Result.cs deleted file mode 100644 index f1425bd..0000000 --- a/CalDav.Server/Controllers/Result.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.Mvc; -using System.Xml.Linq; - -namespace CalDav.Server.Controllers { - public class Result : System.Web.Mvc.ActionResult { - public Result() { } - public Result(Action content) { Content = content; } - - public System.Net.HttpStatusCode? Status { get; set; } - public object Content { get; set; } - public Dictionary Headers { get; set; } - public string ContentType { get; set; } - - public override void ExecuteResult(System.Web.Mvc.ControllerContext context) { - var res = context.HttpContext.Response; - res.StatusCode = (int)(Status ?? System.Net.HttpStatusCode.OK); - - if (Headers != null && Headers.Count > 0) - foreach (var header in Headers) - res.AppendHeader(header.Key, header.Value); - res.AppendHeader("DAV", "1, 2, 3, calendar-access, calendar-schedule, calendar-proxy"); - - var content = Content; - if (content is XDocument) content = ((XDocument)content).Root; - if (content is XElement) { - ContentType = "text/xml"; - ((XElement)content).Save(res.Output); - } else if (content is string) res.Write(content as string); - else if (content is byte[]) res.BinaryWrite(content as byte[]); - else if (content is Action) ((Action)content)(context); - - if (ContentType != null) - res.ContentType = ContentType; - } - } -} \ No newline at end of file diff --git a/CalDav.Server/Models/ICalendarInfo.cs b/CalDav.Server/Models/ICalendarInfo.cs deleted file mode 100644 index 32e3b15..0000000 --- a/CalDav.Server/Models/ICalendarInfo.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CalDav.Server.Models { - public interface ICalendarInfo { - string ID { get; } - string Name { get; } - string Description { get; } - DateTime LastModified { get; } - } -} diff --git a/CalDav.Server/Models/ICalendarRepository.cs b/CalDav.Server/Models/ICalendarRepository.cs deleted file mode 100644 index 1f91073..0000000 --- a/CalDav.Server/Models/ICalendarRepository.cs +++ /dev/null @@ -1,21 +0,0 @@ -using CalDav; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CalDav.Server.Models { - public interface ICalendarRepository { - IQueryable GetCalendars(); - ICalendarInfo GetCalendarByID(string id); - ICalendarInfo CreateCalendar(string id); - void Save(ICalendarInfo calendar, ICalendarObject e); - - ICalendarObject GetObjectByUID(ICalendarInfo calendar, string uid); - IQueryable GetObjectsByFilter(ICalendarInfo calendar, Filter filter); - IQueryable GetObjects(ICalendarInfo calendar); - - void DeleteObject(ICalendarInfo calendar, string uid); - } -} diff --git a/CalDav.Server/Properties/AssemblyInfo.cs b/CalDav.Server/Properties/AssemblyInfo.cs deleted file mode 100644 index e58bb7b..0000000 --- a/CalDav.Server/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("CalDav.Server")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Tracky")] -[assembly: AssemblyProduct("CalDav.Server")] -[assembly: AssemblyCopyright("Copyright © 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b249d5d8-9013-47b4-9ba7-d81255bd24bf")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.0.1.0")] -[assembly: AssemblyFileVersion("0.0.1-beta3")] diff --git a/CalDav.sln b/CalDav.sln index 2cf0eb5..0202b92 100644 --- a/CalDav.sln +++ b/CalDav.sln @@ -1,14 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "Console\Console.csproj", "{EE946C60-392B-4A4F-B0A5-9D9A32C283DD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{FABD2E1F-315B-4DCB-8DDA-FDE9263F99E1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalDav", "CalDav\CalDav.csproj", "{01A4C4CF-5AD1-4324-A391-DC922C84BE1C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalDav.Client", "CalDav.Client\CalDav.Client.csproj", "{1B9B42A0-A34B-4BF6-A5D5-21C46ED0D9B3}" -EndProject +# Visual Studio 2013 +VisualStudioVersion = 12.0.30110.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{9A2D1E8A-0F23-4431-8FAD-113F12F2AD96}" ProjectSection(SolutionItems) = preProject .nuget\NuGet.Config = .nuget\NuGet.Config @@ -16,16 +10,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{9A2D1E .nuget\NuGet.targets = .nuget\NuGet.targets EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.WPF", "Demo.WPF\Demo.WPF.csproj", "{69BD41BC-3945-4C33-8A07-A0BD6DD9B160}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "Console\Console.csproj", "{EE946C60-392B-4A4F-B0A5-9D9A32C283DD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalDav.Server", "CalDav.Server\CalDav.Server.csproj", "{471EA68F-FB1F-4DF8-AAC1-31022C7316AB}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{FABD2E1F-315B-4DCB-8DDA-FDE9263F99E1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.MVC", "Demo.MVC\Demo.MVC.csproj", "{9164611E-4CAF-4FE1-B707-397CC1D515C0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalDav", "CalDav\CalDav.csproj", "{01A4C4CF-5AD1-4324-A391-DC922C84BE1C}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0374EF10-4265-4EEC-8608-94D0561FBF7F}" - ProjectSection(SolutionItems) = preProject - Create-Package.ps1 = Create-Package.ps1 - EndProjectSection +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.MVC", "Demo.MVC\Demo.MVC.csproj", "{9164611E-4CAF-4FE1-B707-397CC1D515C0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -45,18 +36,6 @@ Global {01A4C4CF-5AD1-4324-A391-DC922C84BE1C}.Debug|Any CPU.Build.0 = Debug|Any CPU {01A4C4CF-5AD1-4324-A391-DC922C84BE1C}.Release|Any CPU.ActiveCfg = Release|Any CPU {01A4C4CF-5AD1-4324-A391-DC922C84BE1C}.Release|Any CPU.Build.0 = Release|Any CPU - {1B9B42A0-A34B-4BF6-A5D5-21C46ED0D9B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1B9B42A0-A34B-4BF6-A5D5-21C46ED0D9B3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1B9B42A0-A34B-4BF6-A5D5-21C46ED0D9B3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1B9B42A0-A34B-4BF6-A5D5-21C46ED0D9B3}.Release|Any CPU.Build.0 = Release|Any CPU - {69BD41BC-3945-4C33-8A07-A0BD6DD9B160}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {69BD41BC-3945-4C33-8A07-A0BD6DD9B160}.Debug|Any CPU.Build.0 = Debug|Any CPU - {69BD41BC-3945-4C33-8A07-A0BD6DD9B160}.Release|Any CPU.ActiveCfg = Release|Any CPU - {69BD41BC-3945-4C33-8A07-A0BD6DD9B160}.Release|Any CPU.Build.0 = Release|Any CPU - {471EA68F-FB1F-4DF8-AAC1-31022C7316AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {471EA68F-FB1F-4DF8-AAC1-31022C7316AB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {471EA68F-FB1F-4DF8-AAC1-31022C7316AB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {471EA68F-FB1F-4DF8-AAC1-31022C7316AB}.Release|Any CPU.Build.0 = Release|Any CPU {9164611E-4CAF-4FE1-B707-397CC1D515C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9164611E-4CAF-4FE1-B707-397CC1D515C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {9164611E-4CAF-4FE1-B707-397CC1D515C0}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/CalDav/Alarm.cs b/CalDav/Alarm.cs index bc3b6cd..5f7f81a 100644 --- a/CalDav/Alarm.cs +++ b/CalDav/Alarm.cs @@ -1,28 +1,34 @@  -namespace CalDav { - public class Alarm : ISerializeToICAL { - public string Action { get; set; } - public string Description { get; set; } - public Trigger Trigger { get; set; } +namespace CalDav +{ + public class Alarm : ISerializeToICAL + { + public string Action { get; set; } + public string Description { get; set; } + public Trigger Trigger { get; set; } - public void Deserialize(System.IO.TextReader rdr, Serializer serializer) { - string name, value; - var parameters = new System.Collections.Specialized.NameValueCollection(); - while (rdr.Property(out name, out value, parameters) && !string.IsNullOrEmpty(name)) { - switch (name) { - case "ACTION": Action = value; break; - case "DESCRIPTION": Description = value; break; - case "TRIGGER": Trigger = serializer.GetService(); Trigger.Deserialize(value, parameters); break; - } - } - } + public void Deserialize(System.IO.TextReader rdr, Serializer serializer) + { + string name, value; + var parameters = new System.Collections.Specialized.NameValueCollection(); + while (rdr.Property(out name, out value, parameters) && !string.IsNullOrEmpty(name)) + { + switch (name) + { + case "ACTION": Action = value; break; + case "DESCRIPTION": Description = value; break; + case "TRIGGER": Trigger = serializer.GetService(); Trigger.Deserialize(value, parameters); break; + } + } + } - public void Serialize(System.IO.TextWriter wrtr) { - wrtr.BeginBlock("VALARM"); - wrtr.Property("ACTION", Action); - wrtr.Property("DESCRIPTION", Description); - wrtr.Property("TRIGGER", Trigger); - wrtr.EndBlock("VALARM"); - } - } + public void Serialize(System.IO.TextWriter wrtr) + { + wrtr.BeginBlock("VALARM"); + wrtr.Property("ACTION", Action); + wrtr.Property("DESCRIPTION", Description); + wrtr.Property("TRIGGER", Trigger); + wrtr.EndBlock("VALARM"); + } + } } diff --git a/CalDav/CalDav.csproj b/CalDav/CalDav.csproj index daef403..8b56890 100644 --- a/CalDav/CalDav.csproj +++ b/CalDav/CalDav.csproj @@ -9,7 +9,7 @@ Properties CalDav CalDav - v4.0 + v4.5 512 ..\ true @@ -23,6 +23,7 @@ DEBUG;TRACE prompt 4 + false pdbonly @@ -31,10 +32,40 @@ TRACE prompt 4 + false + + True + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + + False + ..\packages\Microsoft.AspNet.WebPages.3.1.1\lib\net45\System.Web.Helpers.dll + + + False + ..\packages\Microsoft.AspNet.Mvc.5.1.1\lib\net45\System.Web.Mvc.dll + + + False + ..\packages\Microsoft.AspNet.Razor.3.1.1\lib\net45\System.Web.Razor.dll + + + False + ..\packages\Microsoft.AspNet.WebPages.3.1.1\lib\net45\System.Web.WebPages.dll + + + False + ..\packages\Microsoft.AspNet.WebPages.3.1.1\lib\net45\System.Web.WebPages.Deployment.dll + + + False + ..\packages\Microsoft.AspNet.WebPages.3.1.1\lib\net45\System.Web.WebPages.Razor.dll + @@ -45,8 +76,12 @@ + + + + @@ -54,23 +89,29 @@ + + + + + + - - Designer - + + + +
-
+ + + + + - - - + + + + - - - - + + - - - - - - + + + + + + - - + + + + - - + + + + - - + + + + + + + + + + + + + + + + + + + - + + + + - - - + \ No newline at end of file diff --git a/Demo.MVC/packages.config b/Demo.MVC/packages.config index bb29542..bd9ae6a 100644 --- a/Demo.MVC/packages.config +++ b/Demo.MVC/packages.config @@ -1,14 +1,10 @@  - - - - - - - - - + + + + + + - \ No newline at end of file diff --git a/Demo.WPF/App.config b/Demo.WPF/App.config deleted file mode 100644 index 8e15646..0000000 --- a/Demo.WPF/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Demo.WPF/App.xaml b/Demo.WPF/App.xaml deleted file mode 100644 index 52a981d..0000000 --- a/Demo.WPF/App.xaml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/Demo.WPF/App.xaml.cs b/Demo.WPF/App.xaml.cs deleted file mode 100644 index e55c55f..0000000 --- a/Demo.WPF/App.xaml.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using System.Windows; - -namespace Demo.WPF { - /// - /// Interaction logic for App.xaml - /// - public partial class App : Application { - } -} diff --git a/Demo.WPF/Demo.WPF.csproj b/Demo.WPF/Demo.WPF.csproj deleted file mode 100644 index 4690144..0000000 --- a/Demo.WPF/Demo.WPF.csproj +++ /dev/null @@ -1,115 +0,0 @@ - - - - - Debug - AnyCPU - {69BD41BC-3945-4C33-8A07-A0BD6DD9B160} - WinExe - Properties - CalDav.WPF - CalDav.WPF - v4.5 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - 4.0 - - - - - - - - MSBuild:Compile - Designer - - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - MainWindow.xaml - Code - - - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - - - - {1b9b42a0-a34b-4bf6-a5d5-21c46ed0d9b3} - CalDav.Client - - - {01a4c4cf-5ad1-4324-a391-dc922c84be1c} - CalDav - - - - - \ No newline at end of file diff --git a/Demo.WPF/MainWindow.xaml b/Demo.WPF/MainWindow.xaml deleted file mode 100644 index 53a1e7c..0000000 --- a/Demo.WPF/MainWindow.xaml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - diff --git a/Demo.WPF/MainWindow.xaml.cs b/Demo.WPF/MainWindow.xaml.cs deleted file mode 100644 index 29fdea6..0000000 --- a/Demo.WPF/MainWindow.xaml.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Linq; -using System.Windows; -using System.Windows.Controls; - -namespace Demo.WPF { - /// - /// Interaction logic for MainWindow.xaml - /// - public partial class MainWindow : Window { - public MainWindow() { - InitializeComponent(); - Loaded += MainWindow_Loaded; - } - - CalDav.Client.Server _Server; - CalDav.Client.Calendar _Calendar; - - void MainWindow_Loaded(object sender, RoutedEventArgs e) { - _Server = new CalDav.Client.Server("https://www.google.com/calendar/dav/andy.edinborough@gmail.com/events/", "andy.edinborough@gmail.com", "Gboey6Emo!"); - _Calendar = _Server.GetCalendars().FirstOrDefault(); - - this.AsyncUI(_Calendar.Initialize, () => lblCalendarName.Content = _Calendar.Name); - LoadEvents(); - } - - void LoadEvents() { - this.AsyncUI(() => { - var now = DateTime.UtcNow; - var from = new DateTime(now.Year, now.Month, 1); - var to = from.AddMonths(1); - return _Calendar.Search(CalDav.CalendarQuery.SearchEvents(from, to)); - }, results => { - lbEvents.Items.Clear(); - var events = results.SelectMany(x => x.Events); - lbEvents.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; - foreach (var evnt in events) { - var grid = new Grid(); - grid.Margin = new Thickness(0); - grid.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; - grid.ColumnDefinitions.Add(new ColumnDefinition { }); - grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(90) }); - grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(90) }); - - var lbl = new Label { Content = evnt.Start.Value.ToShortDateString() + " " + evnt.Summary }; - grid.Children.Add(lbl); - Grid.SetColumn(lbl, 0); - - var btn = new Button { - Content = "Tomorrow" - }; - btn.Click += (sender, ee) => { - evnt.Start = DateTime.UtcNow.AddDays(1).Date; - btn.IsEnabled = false; - this.AsyncUI(() => _Calendar.Save(evnt), LoadEvents); - }; - btn.HorizontalAlignment = System.Windows.HorizontalAlignment.Right; - btn.Margin = new Thickness(0); - grid.Children.Add(btn); - Grid.SetColumn(btn, 1); - - var btn2 = new Button { - Content = "Next Week" - }; - btn2.Click += (sender, ee) => { - evnt.Start = DateTime.UtcNow.AddDays(7).Date; - btn2.IsEnabled = false; - this.AsyncUI(() => _Calendar.Save(evnt), LoadEvents); - }; - btn2.HorizontalAlignment = System.Windows.HorizontalAlignment.Right; - btn2.Margin = new Thickness(0); - grid.Children.Add(btn2); - Grid.SetColumn(btn2, 2); - - lbEvents.Items.Add(grid); - } - }); - } - } -} diff --git a/Demo.WPF/Properties/AssemblyInfo.cs b/Demo.WPF/Properties/AssemblyInfo.cs deleted file mode 100644 index 30e7481..0000000 --- a/Demo.WPF/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Windows; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Demo.WPF")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Demo.WPF")] -[assembly: AssemblyCopyright("Copyright © 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -//In order to begin building localizable applications, set -//CultureYouAreCodingWith in your .csproj file -//inside a . For example, if you are using US english -//in your source files, set the to en-US. Then uncomment -//the NeutralResourceLanguage attribute below. Update the "en-US" in -//the line below to match the UICulture setting in the project file. - -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) -)] - - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demo.WPF/Properties/Resources.Designer.cs b/Demo.WPF/Properties/Resources.Designer.cs deleted file mode 100644 index 7e330c6..0000000 --- a/Demo.WPF/Properties/Resources.Designer.cs +++ /dev/null @@ -1,62 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17929 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Demo.WPF.Properties { - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if ((resourceMan == null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Demo.WPF.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/Demo.WPF/Properties/Resources.resx b/Demo.WPF/Properties/Resources.resx deleted file mode 100644 index af7dbeb..0000000 --- a/Demo.WPF/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Demo.WPF/Properties/Settings.Designer.cs b/Demo.WPF/Properties/Settings.Designer.cs deleted file mode 100644 index 41e5749..0000000 --- a/Demo.WPF/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17929 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Demo.WPF.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/Demo.WPF/Properties/Settings.settings b/Demo.WPF/Properties/Settings.settings deleted file mode 100644 index 033d7a5..0000000 --- a/Demo.WPF/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Demo.WPF/Utilities.cs b/Demo.WPF/Utilities.cs deleted file mode 100644 index 3879bb6..0000000 --- a/Demo.WPF/Utilities.cs +++ /dev/null @@ -1,20 +0,0 @@ - -using System; -using System.Threading.Tasks; -using System.Windows; -namespace Demo.WPF { - public static class Utilities { - - public static void UI(this Window window, Action dothis) { - window.Dispatcher.BeginInvoke(dothis); - } - - public static Task AsyncUI(this Window window, Action dothis, Action thenThisOnUI) { - return Task.Run(dothis).ContinueWith(_ => window.Dispatcher.BeginInvoke(thenThisOnUI)); - } - - public static Task AsyncUI(this Window window, Func dothis, Action thenThisOnUi) { - return Task.Run(dothis).ContinueWith(_ => window.Dispatcher.BeginInvoke((Action)(() => thenThisOnUi(_.Result)))); - } - } -} diff --git a/README.md b/README.md new file mode 100644 index 0000000..9a5929d --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +CalDav +====== + +CalDav server and client libraries diff --git a/Tests/IRLTests.cs b/Tests/IRLTests.cs index 98539fa..075a9ba 100644 --- a/Tests/IRLTests.cs +++ b/Tests/IRLTests.cs @@ -3,35 +3,46 @@ using Shouldly; using System; -namespace Tests { - [TestClass] - public class IRLTests { - [TestMethod] - public void ParseFeed() { - var calendar = new CalDav.Calendar(); - var serializer = new Serializer(); - var req = System.Net.HttpWebRequest.Create("http://www.nasa.gov/templateimages/redesign/calendar/iCal/nasa_calendar.ics"); - using (var res = req.GetResponse()) - using (var str = res.GetResponseStream()) - using (var rdr = new System.IO.StreamReader(str)) - calendar.Deserialize(rdr, serializer); +namespace Tests +{ + [TestClass] + public class IRLTests + { + [TestMethod] + public void ParseFeed() + { + var calendar = new CalDav.Calendar(); + var serializer = new Serializer(); + var req = System.Net.WebRequest.Create("http://www.nasa.gov/templateimages/redesign/calendar/iCal/nasa_calendar.ics"); + + using (var res = req.GetResponse()) + { + using (var str = res.GetResponseStream()) + { + using (var rdr = new System.IO.StreamReader(str)) + { + calendar.Deserialize(rdr, serializer); + } + } + } - calendar.Events.Count.ShouldBeGreaterThan(0); - } + calendar.Events.Count.ShouldBeGreaterThan(0); + } - [TestMethod] - public void ParseICal() { - //http://blogs.nologin.es/rickyepoderi/index.php?/archives/14-Introducing-CalDAV-Part-I.html - //http://blogs.nologin.es/rickyepoderi/index.php?/archives/15-Introducing-CalDAV-Part-II.html + [TestMethod] + public void ParseICal() + { + //http://blogs.nologin.es/rickyepoderi/index.php?/archives/14-Introducing-CalDAV-Part-I.html + //http://blogs.nologin.es/rickyepoderi/index.php?/archives/15-Introducing-CalDAV-Part-II.html - var server = new CalDav.Client.Server("https://www.google.com/calendar/dav/andy.edinborough@gmail.com/events/", "andy.edinborough@gmail.com", "Gboey6Emo!"); - var calendars = server.GetCalendars(); - calendars.ShouldNotBeEmpty(); + var server = new CalDav.Client.Server("https://www.google.com/calendar/dav/andy.edinborough@gmail.com/events/", "andy.edinborough@gmail.com", "Gboey6Emo!"); + var calendars = server.GetCalendars(); + calendars.ShouldNotBeEmpty(); - var calendar = calendars[0]; - var events = calendar.Search(CalendarQuery.SearchEvents(new DateTime(2012, 8, 1), new DateTime(2012, 8, 31))).ToArray(); - events.Length.ShouldBeGreaterThan(0); + var calendar = calendars[0]; + var events = calendar.Search(CalendarQuery.SearchEvents(new DateTime(2012, 8, 1), new DateTime(2012, 8, 31))).ToArray(); + events.Length.ShouldBeGreaterThan(0); - } - } + } + } } diff --git a/Tests/ParsingBasic.cs b/Tests/ParsingBasic.cs index 10acca5..91723c5 100644 --- a/Tests/ParsingBasic.cs +++ b/Tests/ParsingBasic.cs @@ -5,70 +5,84 @@ using System.Collections.Specialized; using System.Net.Mail; -namespace Tests { - [TestClass] - public class ParsingBasic { - [TestMethod] - public void KeyValue() { - var values = DeserializeProperty("TEST;VALUE1=ONE;VALUE2=TWO:tested\n\t tested"); - values.Item1.ShouldBe("TEST"); - values.Item2.ShouldBe("tested tested"); - values.Item3["VALUE1"].ShouldBe("ONE"); - values.Item3["VALUE2"].ShouldBe("TWO"); - } +namespace Tests +{ + [TestClass] + public class ParsingBasic + { + [TestMethod] + public void KeyValue() + { + var values = DeserializeProperty("TEST;VALUE1=ONE;VALUE2=TWO:tested\n\t tested"); + values.Item1.ShouldBe("TEST"); + values.Item2.ShouldBe("tested tested"); + values.Item3["VALUE1"].ShouldBe("ONE"); + values.Item3["VALUE2"].ShouldBe("TWO"); + } - private static Tuple DeserializeProperty(string text) { - using (var rdr = new System.IO.StringReader(text)) { - string name, value; - var parameters = new System.Collections.Specialized.NameValueCollection(); - rdr.Property(out name, out value, parameters); - if (name == null) return null; - return Tuple.Create(name, value, parameters); - } - } + private static Tuple DeserializeProperty(string text) + { + using (var rdr = new System.IO.StringReader(text)) + { + string name, value; + var parameters = new NameValueCollection(); + rdr.Property(out name, out value, parameters); + + if (name == null) + { + return null; + } - private static T Deserialize(string property) where T : class, IHasParameters, new() { - var t = new T(); - var values = DeserializeProperty(property); - t.Deserialize(values.Item2, values.Item3); - return t; - } + return Tuple.Create(name, value, parameters); + } + } - [TestMethod] - public void Contact() { - var text = "ORGANIZER;CN=JohnSmith;DIR=\"ldap" + "://host.com:6666/o=3DDC Associates,c=3DUS??(cn=3DJohn Smith)\":MAILTO" + ":jsmith@host1.com"; - var contact = Deserialize(text); + private static T Deserialize(string property) where T : class, IHasParameters, new() + { + var t = new T(); + var values = DeserializeProperty(property); + t.Deserialize(values.Item2, values.Item3); + return t; + } - contact.Name.ShouldBe("JohnSmith"); - contact.Email.ShouldBe("jsmith@host1.com"); - var addr = (MailAddress)contact; - addr.DisplayName.ShouldBe("JohnSmith"); - addr.Address.ShouldBe("jsmith@host1.com"); + [TestMethod] + public void Contact() + { + var text = "ORGANIZER;CN=JohnSmith;DIR=\"ldap" + "://host.com:6666/o=3DDC Associates,c=3DUS??(cn=3DJohn Smith)\":MAILTO" + ":jsmith@host1.com"; + var contact = Deserialize(text); - contact.Directory.ShouldBe("ldap" + "://host.com:6666/o=DC Associates,c=US??(cn=John Smith)"); + contact.Name.ShouldBe("JohnSmith"); + contact.Email.ShouldBe("jsmith@host1.com"); + var addr = (MailAddress)contact; + addr.DisplayName.ShouldBe("JohnSmith"); + addr.Address.ShouldBe("jsmith@host1.com"); - var text2 = Serialize("ORGANIZER", contact); - text2.ShouldBe(text); - } + contact.Directory.ShouldBe("ldap" + "://host.com:6666/o=DC Associates,c=US??(cn=John Smith)"); - private static string Serialize(string name, IHasParameters obj) { - return name + Common.FormatParameters(obj.GetParameters()) + ":" + obj.ToString(); - } + var text2 = Serialize("ORGANIZER", contact); + text2.ShouldBe(text); + } - [TestMethod] - public void Trigger() { - var text = "TRIGGER;VALUE=DATE-TIME:20120328T133700Z"; - var trigger = Deserialize(text); - trigger.DateTime.ShouldBe(new DateTime(2012, 3, 28, 13, 37, 0, DateTimeKind.Utc)); - var text2 = Serialize("TRIGGER", trigger); - text2.ShouldBe(text); + private static string Serialize(string name, IHasParameters obj) + { + return name + Common.FormatParameters(obj.GetParameters()) + ":" + obj.ToString(); + } - text = "TRIGGER;RELATED=END:-P1W3DT2H3M45S"; - trigger = Deserialize(text); - trigger.Related.ShouldBe(CalDav.Trigger.Relateds.End); - trigger.Duration.ShouldBe(-(new TimeSpan(1 * 7 + 3, 2, 3, 45, 0))); - text2 = Serialize("TRIGGER", trigger); - text2.ShouldBe(text); - } - } + [TestMethod] + public void Trigger() + { + var text = "TRIGGER;VALUE=DATE-TIME:20120328T133700Z"; + var trigger = Deserialize(text); + trigger.DateTime.ShouldBe(new DateTime(2012, 3, 28, 13, 37, 0, DateTimeKind.Utc)); + var text2 = Serialize("TRIGGER", trigger); + text2.ShouldBe(text); + + text = "TRIGGER;RELATED=END:-P1W3DT2H3M45S"; + trigger = Deserialize(text); + trigger.Related.ShouldBe(CalDav.Trigger.Relateds.End); + trigger.Duration.ShouldBe(-(new TimeSpan(1 * 7 + 3, 2, 3, 45, 0))); + text2 = Serialize("TRIGGER", trigger); + text2.ShouldBe(text); + } + } } diff --git a/Tests/ParsingFilters.cs b/Tests/ParsingFilters.cs index a9ca56c..a67917a 100644 --- a/Tests/ParsingFilters.cs +++ b/Tests/ParsingFilters.cs @@ -4,13 +4,16 @@ using System.Linq; using System.Xml.Linq; -namespace Tests { - [TestClass] - public class Filters { - [TestMethod] - public void TimeZone() { +namespace Tests +{ + [TestClass] + public class Filters + { + [TestMethod] + public void TimeZone() + { - var xdoc = XDocument.Parse(@" + var xdoc = XDocument.Parse(@" @@ -21,18 +24,20 @@ public void TimeZone() { "); - var f = new CalDav.Filter(xdoc.Root.Elements().First()); - Test(f, x => { - x.Filters[0].Name.ShouldBe("VCALENDAR"); - x.Filters[0].Filters[0].Name.ShouldBe("VTIMEZONE"); - x.Filters[0].Filters[0].IsDefined.ShouldBe(true); - }); - } + var f = new CalDav.Filter(xdoc.Root.Elements().First()); + Test(f, x => + { + x.Filters[0].Name.ShouldBe("VCALENDAR"); + x.Filters[0].Filters[0].Name.ShouldBe("VTIMEZONE"); + x.Filters[0].Filters[0].IsDefined.ShouldBe(true); + }); + } - [TestMethod] - public void ParticipationStatus() { + [TestMethod] + public void ParticipationStatus() + { - var xdoc = XDocument.Parse(@" + var xdoc = XDocument.Parse(@" @@ -49,23 +54,25 @@ public void ParticipationStatus() { "); - var f = new CalDav.Filter(xdoc.Root.Elements().First()); - Test(f, x => { - x.Filters[0].Name.ShouldBe("VCALENDAR"); - x.Filters[0].Filters[0].Name.ShouldBe("VEVENT"); - var prop = x.Filters[0].Filters[0].Properties[0]; - prop.Name.ShouldBe("ATTENDEE"); - prop.IgnoreCase.ShouldBe(true); - prop.Text.ShouldBe("mailto:jsmith@foo.org"); - prop.Parameters[0].Name.ShouldBe("PARTSTAT"); - prop.Parameters[0].Text.ShouldBe("NEEDS-ACTION"); - prop.Parameters[0].IgnoreCase.ShouldBe(false); - }); - } + var f = new CalDav.Filter(xdoc.Root.Elements().First()); + Test(f, x => + { + x.Filters[0].Name.ShouldBe("VCALENDAR"); + x.Filters[0].Filters[0].Name.ShouldBe("VEVENT"); + var prop = x.Filters[0].Filters[0].Properties[0]; + prop.Name.ShouldBe("ATTENDEE"); + prop.IgnoreCase.ShouldBe(true); + prop.Text.ShouldBe("mailto:jsmith@foo.org"); + prop.Parameters[0].Name.ShouldBe("PARTSTAT"); + prop.Parameters[0].Text.ShouldBe("NEEDS-ACTION"); + prop.Parameters[0].IgnoreCase.ShouldBe(false); + }); + } - [TestMethod] - public void UID() { - var xdoc = XDocument.Parse(@" + [TestMethod] + public void UID() + { + var xdoc = XDocument.Parse(@" @@ -79,20 +86,22 @@ public void UID() { "); - var f = new CalDav.Filter(xdoc.Root.Elements().First()); - Test(f, x => { - x.Filters[0].Name.ShouldBe("VCALENDAR"); - x.Filters[0].Filters[0].Name.ShouldBe("VEVENT"); - var prop = x.Filters[0].Filters[0].Properties[0]; - prop.Name.ShouldBe("UID"); - prop.IgnoreCase.ShouldBe(false); - prop.Text.ShouldBe("20041121-FEEBDAED@foo.org"); - }); - } + var f = new CalDav.Filter(xdoc.Root.Elements().First()); + Test(f, x => + { + x.Filters[0].Name.ShouldBe("VCALENDAR"); + x.Filters[0].Filters[0].Name.ShouldBe("VEVENT"); + var prop = x.Filters[0].Filters[0].Properties[0]; + prop.Name.ShouldBe("UID"); + prop.IgnoreCase.ShouldBe(false); + prop.Text.ShouldBe("20041121-FEEBDAED@foo.org"); + }); + } - [TestMethod] - public void TimeRange() { - var xdoc = XDocument.Parse(@" + [TestMethod] + public void TimeRange() + { + var xdoc = XDocument.Parse(@" @@ -106,21 +115,23 @@ public void TimeRange() { "); - var f = new CalDav.Filter(xdoc.Root.Elements().First()); - Test(f, x => { - x.Filters[0].Name.ShouldBe("VCALENDAR"); - x.Filters[0].Filters[0].Name.ShouldBe("VTODO"); - x.Filters[0].Filters[0].Filters[0].Name.ShouldBe("VALARM"); - var timerange = x.Filters[0].Filters[0].Filters[0].TimeRange; - timerange.Start.ShouldBe(new DateTime(2004, 11, 21, 0, 0, 0, DateTimeKind.Utc)); - timerange.End.ShouldBe(new DateTime(2004, 11, 21, 23, 59, 59, DateTimeKind.Utc)); - }); - } + var f = new CalDav.Filter(xdoc.Root.Elements().First()); + Test(f, x => + { + x.Filters[0].Name.ShouldBe("VCALENDAR"); + x.Filters[0].Filters[0].Name.ShouldBe("VTODO"); + x.Filters[0].Filters[0].Filters[0].Name.ShouldBe("VALARM"); + var timerange = x.Filters[0].Filters[0].Filters[0].TimeRange; + timerange.Start.ShouldBe(new DateTime(2004, 11, 21, 0, 0, 0, DateTimeKind.Utc)); + timerange.End.ShouldBe(new DateTime(2004, 11, 21, 23, 59, 59, DateTimeKind.Utc)); + }); + } - private static void Test(CalDav.Filter filter, Action test){ - test(filter); - filter = new CalDav.Filter((XElement)filter); - test(filter); - } - } + private static void Test(CalDav.Filter filter, Action test) + { + test(filter); + filter = new CalDav.Filter((XElement)filter); + test(filter); + } + } } diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 0c1ddd8..6d8e84c 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -37,10 +37,12 @@ 4 - - ..\packages\Shouldly.1.1.1.1\lib\35\Shouldly.dll + + False + ..\packages\Shouldly.2.1.0\lib\net40\Shouldly.dll + @@ -63,10 +65,6 @@ - - {1b9b42a0-a34b-4bf6-a5d5-21c46ed0d9b3} - CalDav.Client - {01a4c4cf-5ad1-4324-a391-dc922c84be1c} CalDav diff --git a/Tests/app.config b/Tests/app.config index 56f696d..87b702a 100644 --- a/Tests/app.config +++ b/Tests/app.config @@ -1,11 +1,37 @@  + + +
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tests/packages.config b/Tests/packages.config index 17a0521..a32e920 100644 --- a/Tests/packages.config +++ b/Tests/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file