/** <summary> * Given a URI/URL, we call iCalendar's LoadFromURI, select the first element in the return, then return true. * </summary> */ public bool Load(Uri path) { iCalc = iCalendar.LoadFromUri(path); iCal = iCalc.FirstOrDefault(); this.Uri = path; return true; }
/// <summary> /// Executed before the message is saved /// </summary> /// <param name="message"></param> /// <param name="postSaveAction">if not null an action run after the save. This happens even if the save is cancelled.</param> /// <returns> /// True if the save is to be cancelled /// </returns> public bool BeforeSave(ReceivedEmailMessage message, out Action postSaveAction) { postSaveAction = null; ///// // Check the message. ///// if (message == null) { return(false); } var iCalMessage = message.As <ReceivedICalEmailMessage>( ); ///// // Ensure the message is a received iCal email message. ///// if (iCalMessage == null) { return(false); } ///// // The iCalUpdate field was set by the iCalMailMesssageFormatter that was called as part // of the ProcessInboxes action. ///// if (string.IsNullOrEmpty(iCalMessage.ICalUpdate)) { return(false); } ///// // Read the iCal update. ///// using (var sr = new StringReader(iCalMessage.ICalUpdate)) { ///// // Deserialize the string into the iCal object model. ///// IICalendarCollection iCalendarCollection = iCalendar.LoadFromStream(sr); if (iCalendarCollection == null) { return(false); } ///// // Get the first calendar. ///// IICalendar calendar = iCalendarCollection.FirstOrDefault( ); if (calendar == null || calendar.Events == null) { return(false); } ///// // Get the first calendar event. ///// IEvent calendarEvent = calendar.Events.FirstOrDefault( ); if (calendarEvent == null) { return(false); } ///// // Make sure the calendar events UID is set. ///// if (string.IsNullOrEmpty(calendarEvent.Uid)) { return(false); } EventEmail eventEntity = null; Appointment appointment = null; ///// // Find all sent iCal UID containers that correlate to the received calendar events UID. ///// IEnumerable <ICalUidContainer> iCalUidContainers = Entity.GetByField <ICalUidContainer>(calendarEvent.Uid, ICalUidContainer.ICalUid_Field); if (iCalUidContainers != null) { ///// // Get the first sent message. ///// ICalUidContainer iCalUidContainer = iCalUidContainers.FirstOrDefault( ); if (iCalUidContainer != null && iCalUidContainer.CalendarEventEmail != null) { ///// // Get the original event email object that was used to create the sent iCal Email Message. ///// eventEntity = iCalUidContainer.CalendarEventEmail.AsWritable <EventEmail>( ); } } bool modificationsMade = false; if (eventEntity == null) { ///// // No existing event email so this is a new request. ///// EntityRef type = GetEventCreationType(message); eventEntity = type != null?Entity.Create(type).As <EventEmail>( ) : new EventEmail( ); appointment = Entity.Create <Appointment>(); eventEntity.EventEmailAppt = appointment; modificationsMade = true; eventEntity.Name = calendarEvent.Summary; var calUidContainer = new ICalUidContainer { ICalUid = calendarEvent.Uid }; eventEntity.CalendarId = calUidContainer; string creatorEmailAddress = GetEmailAddress(message.EmFrom); if (creatorEmailAddress != null) { EmailContact creatorEmailContact = FindEmailContact(creatorEmailAddress); if (creatorEmailContact == null) { var mailAddress = new MailAddress(message.EmFrom); creatorEmailContact = CreateEmailContact(creatorEmailAddress, mailAddress.DisplayName ?? creatorEmailAddress); } eventEntity.EventEmailCreator = creatorEmailContact; } foreach (IAttendee attendee in calendarEvent.Attendees) { string emailAddress = GetEmailAddress(attendee.Value.ToString( )); if (emailAddress != null) { EmailContact emailContact = FindEmailContact(emailAddress); if (emailContact == null) { CreateEmailContact(emailAddress, attendee.CommonName); } appointment.EventEmailAttendees.Add(emailContact.EmailContactOwner); } } CreateAndSendAcceptance(calendar, iCalMessage, eventEntity); } else { appointment = eventEntity.EventEmailAppt; if (calendar.Method == Methods.Publish || calendar.Method == Methods.Request) { ///// // A REQUEST or PUBLISH means a new event arriving in the system. ///// CreateAndSendAcceptance(calendar, iCalMessage, eventEntity); } } eventEntity.ReceivedEmailMessages.Add(iCalMessage); ///// // Start time. ///// if (calendarEvent.Start != null) { DateTime utcTime = calendarEvent.Start.Utc; if (!Equals(utcTime, appointment.EventStart)) { appointment.EventStart = utcTime; modificationsMade = true; } } ///// // End time. ///// if (calendarEvent.End != null) { DateTime utcTime = calendarEvent.End.Utc; if (!Equals(utcTime, appointment.EventEnd)) { appointment.EventEnd = utcTime; modificationsMade = true; } } ///// // All Day Event. ///// if (appointment.EventIsAllDay == null || !Equals(calendarEvent.IsAllDay, appointment.EventIsAllDay.Value)) { appointment.EventIsAllDay = calendarEvent.IsAllDay; modificationsMade = true; } ///// // Location. ///// if (calendarEvent.Location != null) { if (!Equals(calendarEvent.Location, appointment.EventLocation)) { appointment.EventLocation = calendarEvent.Location; modificationsMade = true; } } ///// // Location. ///// if (eventEntity.EventEmailAppt.EventEmailPriority == null || !Equals(calendarEvent.Priority, eventEntity.EventEmailAppt.EventEmailPriority)) { string priorityAlias; if (calendarEvent.Priority <= 0) { ///// // Undefined. ///// priorityAlias = null; } else if (calendarEvent.Priority <= 4) { ///// // High priority. ///// priorityAlias = "core:highPriority"; } else if (calendarEvent.Priority == 5) { ///// // Normal priority. ///// priorityAlias = "core:normalPriority"; } else if (calendarEvent.Priority <= 9) { ///// // Low priority. ///// priorityAlias = "core:lowPriority"; } else { ///// // Invalid priority. ///// priorityAlias = null; } eventEntity.EventEmailAppt.EventEmailPriority = priorityAlias != null?Entity.Get <EventEmailPriorityEnum>(priorityAlias) : null; modificationsMade = true; } ///// // Status. ///// string statusAlias = null; switch (calendarEvent.Status) { case EventStatus.Cancelled: statusAlias = "core:eventStatusCancelled"; break; case EventStatus.Confirmed: statusAlias = "core:eventStatusConfirmed"; break; case EventStatus.Tentative: statusAlias = "core:eventStatusTentative"; break; } if (!string.IsNullOrEmpty(statusAlias)) { if (appointment.EventStatus == null || appointment.EventStatus.Alias != statusAlias) { appointment.EventStatus = Entity.Get <EventStatusEnum>(statusAlias); modificationsMade = true; } } if (modificationsMade) { CustomContext cc = null; try { string timeZone = null; if (eventEntity != null) { ///// // Find all sent iCal Email Messages that correlate to the received calendar events UID. ///// IEnumerable <SentICalEmailMessage> sentICalEmailMessages = eventEntity.SentEmailMessages; if (sentICalEmailMessages != null) { SentICalEmailMessage sentICalEmailMessage = sentICalEmailMessages.FirstOrDefault(sent => sent.ICalTimeZone != null); if (sentICalEmailMessage != null) { timeZone = sentICalEmailMessage.ICalTimeZone; } } } if (string.IsNullOrEmpty(timeZone)) { if (calendar.TimeZones != null) { ITimeZone calendarTimeZone = calendar.TimeZones.FirstOrDefault( ); if (calendarTimeZone != null) { timeZone = calendarTimeZone.TzId; } } } if (!string.IsNullOrEmpty(timeZone)) { ///// // Set up a custom context just for the duration of this call. ///// RequestContext currentRequestContext = RequestContext.GetContext( ); var data = new RequestContextData(currentRequestContext) { TimeZone = timeZone }; cc = new CustomContext(data); } eventEntity.Save( ); } finally { ///// // Ensure the custom context is disposed. ///// if (cc != null) { cc.Dispose( ); } } } } return(false); }
/// <summary> /// Gets the Ical update. /// </summary> /// <param name="message">The message.</param> /// <param name="receivedICalEmailMessage">The received I cal email message.</param> /// <param name="iCal">The i cal.</param> /// <returns></returns> private static MailMessageFormatterResult GetICalUpdate(MailMessage message, ReceivedICalEmailMessage receivedICalEmailMessage, out string iCal) { iCal = null; if (message == null) { return(MailMessageFormatterResult.Skip); } try { var attachableItems = new List <AttachmentBase>( ); attachableItems.AddRange(message.AlternateViews); attachableItems.AddRange(message.Attachments); ///// // Locate a view that contains a calendar attachment. ///// foreach (AttachmentBase attachment in attachableItems) { if (attachment.ContentType.MediaType == "text/calendar") { ///// // Deserialize the iCalendar attachment. ///// IICalendarCollection iCalendarCollection = iCalendar.LoadFromStream(attachment.ContentStream); if (iCalendarCollection != null) { IICalendar calendar = iCalendarCollection.FirstOrDefault( ); if (calendar != null) { if (calendar.Method == Methods.Reply) { IEvent calendarEvent = calendar.Events.FirstOrDefault( ); if (calendarEvent != null && !string.IsNullOrEmpty(calendarEvent.Uid)) { ///// // Find all iCal UID containers that correlate to the received calendar events UID. ///// IEnumerable <ICalUidContainer> iCalUidContainers = Entity.GetByField <ICalUidContainer>(calendarEvent.Uid, ICalUidContainer.ICalUid_Field); if (iCalUidContainers != null) { ///// // Get the first iCal UID container. ///// ICalUidContainer iCalUidContainer = iCalUidContainers.FirstOrDefault( ); if (iCalUidContainer != null && iCalUidContainer.CalendarEventEmail != null) { ///// // Get the original event email object that was used to calendar UID container. ///// EventEmail eventEntity = iCalUidContainer.CalendarEventEmail; if (eventEntity != null) { // *************** // This needs to be fixed as part of dealing with replies from ical requests. The rel on a rel needs to be turned into something else. // *************** //IEntityRelationship<EventEmailAttendees, EmailContact> attendeeRelationshipInstance = FindAttendeeRelationshipInstance( eventEntity, message.From.Address.ToLowerInvariant( ) ); //if ( attendeeRelationshipInstance != null ) //{ // Attendee attendee = FindICalAttendee( calendarEvent, message.From.Address.ToLowerInvariant( ) ); // if ( attendee != null ) // { // var eventEmailAttendees = attendeeRelationshipInstance.Instance.AsWritable<EventEmailAttendees>( ); // switch ( attendee.ParticipationStatus ) // { // case ParticipationStatus.Accepted: // eventEmailAttendees.AttendeeStatus_Enum = AttendeeStatusEnum_Enumeration.AttendeeStatusAccepted; // break; // case ParticipationStatus.Declined: // eventEmailAttendees.AttendeeStatus_Enum = AttendeeStatusEnum_Enumeration.AttendeeStatusDeclined; // break; // case ParticipationStatus.Delegated: // eventEmailAttendees.AttendeeStatus_Enum = AttendeeStatusEnum_Enumeration.AttendeeStatusDelegated; // break; // case ParticipationStatus.NeedsAction: // eventEmailAttendees.AttendeeStatus_Enum = AttendeeStatusEnum_Enumeration.AttendeeStatusNeedsAction; // break; // case ParticipationStatus.Tentative: // eventEmailAttendees.AttendeeStatus_Enum = AttendeeStatusEnum_Enumeration.AttendeeStatusTentative; // break; // } // eventEmailAttendees.Save( ); // } //} //************* receivedICalEmailMessage.CreatedEventEmail = eventEntity; ///// // Save the message since the process inbox action will discard it. ///// receivedICalEmailMessage.Save( ); } } } } return(MailMessageFormatterResult.Reject); } ///// // Serialize the iCalendar to a string for storage. ///// var serializer = new iCalendarSerializer( ); iCal = serializer.SerializeToString(calendar); return(MailMessageFormatterResult.Ok); } } break; } } } catch (Exception exc) { EventLog.Application.WriteError("Failed to process email iCal attachment. " + exc); return(MailMessageFormatterResult.Error); } return(MailMessageFormatterResult.Skip); }