public void Dispose () { _appointment.AfterWrite -= Appointment_AfterWrite; _appointment.BeforeDelete -= Appointment_BeforeDelete; ((InspectorEvents_10_Event) _inspector).Close -= AppointmentItemWrapper_Close; _appointment = null; _inspector = null; }
public static void CreateGoogleExceptions(AppointmentItem ai, String recurringEventId) { if (!ai.IsRecurring) return; log.Debug("Creating Google recurrence exceptions."); List<Event> gRecurrences = GoogleCalendar.Instance.GetCalendarEntriesInRecurrence(recurringEventId); if (gRecurrences != null) { Microsoft.Office.Interop.Outlook.Exceptions exps = ai.GetRecurrencePattern().Exceptions; foreach (Microsoft.Office.Interop.Outlook.Exception oExcp in exps) { for (int g = 0; g < gRecurrences.Count; g++) { Event ev = gRecurrences[g]; String gDate = ev.OriginalStartTime.DateTime ?? ev.OriginalStartTime.Date; Boolean isDeleted = exceptionIsDeleted(oExcp); if (isDeleted && !ai.AllDayEvent) { //Deleted items get truncated?! gDate = GoogleCalendar.GoogleTimeFrom(DateTime.Parse(gDate).Date); } if (oExcp.OriginalDate == DateTime.Parse(gDate)) { if (isDeleted) { MainForm.Instance.Logboxout(GoogleCalendar.GetEventSummary(ev)); MainForm.Instance.Logboxout("Recurrence deleted."); ev.Status = "cancelled"; GoogleCalendar.Instance.UpdateCalendarEntry_save(ref ev); } else { int exceptionItemsModified = 0; Event modifiedEv = GoogleCalendar.Instance.UpdateCalendarEntry(oExcp.AppointmentItem, ev, ref exceptionItemsModified, forceCompare: true); if (exceptionItemsModified > 0) { GoogleCalendar.Instance.UpdateCalendarEntry_save(ref modifiedEv); } } break; } } } } }
public static void AddOutlookID(ref Event ev, AppointmentItem ai) { //Add the Outlook appointment ID into Google event. //This will make comparison more efficient and set the scene for 2-way sync. addOGCSproperty(ref ev, oEntryID, OutlookCalendar.Instance.IOutlook.GetGlobalApptID(ai)); }
public void Replace(AppointmentItem inner) { if (inner != Inner) { DisposeInner(); Inner = inner; } }
public void SaveAndReload() { Inner.Save(); var entryId = Inner.EntryID; DisposeInner(); Thread.MemoryBarrier(); Inner = _load (entryId); }
public OutlookCalendarItem(AppointmentItem appointmentItem) { _appointmentItem = appointmentItem; Start = _appointmentItem.Start; End = _appointmentItem.End; Location = _appointmentItem.Location; IsPrivateItem = _appointmentItem.Sensitivity != OlSensitivity.olNormal; Title = _appointmentItem.Subject; }
public AppointmentItemAdapter (Inspector inspector, AppointmentItem appointment) { _appointment = appointment; _inspector = inspector; _appointment.AfterWrite += Appointment_AfterWrite; _appointment.BeforeDelete += Appointment_BeforeDelete; ((InspectorEvents_10_Event) _inspector).Close += AppointmentItemWrapper_Close; }
public List<String> BuildGooglePattern(AppointmentItem ai, Event ev) { if (!ai.IsRecurring || ai.RecurrenceState != OlRecurrenceState.olApptMaster) return null; log.Debug("Creating Google iCalendar definition for recurring event."); List<String> gPattern = new List<String>(); gPattern.Add("RRULE:" + buildRrule(ai.GetRecurrencePattern())); log.Debug(string.Join("\r\n", gPattern.ToArray())); return gPattern; }
public ReminderInfo(AppointmentItem appointmentItem = null) { if(appointmentItem == null) return; Appointment = appointmentItem; StartTime = appointmentItem.StartInStartTimeZone; Subject = appointmentItem.Subject; Location = appointmentItem.Location; Body = appointmentItem.Body; Duration = TimeSpan.FromMinutes(appointmentItem.Duration); }
public byte[] Build(DateTime startTime, int duration, string roomName, string roomEmail, out string ext) { appt = olApp.CreateItem(OlItemType.olAppointmentItem); appt.MeetingStatus = OlMeetingStatus.olMeeting; appt.Subject = "<subject goes here>"; appt.Start = startTime; appt.Duration = duration; //appt.Location = "CN BJS (ARCA-1F, SE) Meeting Room Mencius [14] WB,TC,P"; //appt.Recipients.Add(room_email); appt.ReminderSet = true; appt.Display(true); appt.Resources = roomEmail; var tempFile = Path.GetTempFileName(); appt.SaveAs(tempFile); ext = "msg"; return File.ReadAllBytes(tempFile); }
public void CompareOutlookPattern(Event ev, AppointmentItem ai, System.Text.StringBuilder sb, ref int itemModified) { if (ev.Recurrence == null) { return; } log.Fine("Building a temporary recurrent Appointment generated from Event"); AppointmentItem evAI = OutlookCalendar.Instance.IOutlook.UseOutlookCalendar().Items.Add() as AppointmentItem; RecurrencePattern evOpattern; RecurrencePattern aiOpattern = ai.GetRecurrencePattern(); BuildOutlookPattern(ev, evAI, out evOpattern); log.Fine("Comparing Google recurrence to Outlook equivalent"); if (MainForm.CompareAttribute("Recurrence Type", Settings.Instance.SyncDirection, evOpattern.RecurrenceType.ToString(), aiOpattern.RecurrenceType.ToString(), sb, ref itemModified)) { aiOpattern.RecurrenceType = evOpattern.RecurrenceType; } if (MainForm.CompareAttribute("Recurrence Interval", Settings.Instance.SyncDirection, evOpattern.Interval.ToString(), aiOpattern.Interval.ToString(), sb, ref itemModified)) { aiOpattern.Interval = evOpattern.Interval; } if (MainForm.CompareAttribute("Recurrence Instance", Settings.Instance.SyncDirection, evOpattern.Instance.ToString(), aiOpattern.Instance.ToString(), sb, ref itemModified)) { aiOpattern.Instance = evOpattern.Instance; } if (MainForm.CompareAttribute("Recurrence DoW", Settings.Instance.SyncDirection, evOpattern.DayOfWeekMask.ToString(), aiOpattern.DayOfWeekMask.ToString(), sb, ref itemModified)) { aiOpattern.DayOfWeekMask = evOpattern.DayOfWeekMask; } if (MainForm.CompareAttribute("Recurrence MoY", Settings.Instance.SyncDirection, evOpattern.MonthOfYear.ToString(), aiOpattern.MonthOfYear.ToString(), sb, ref itemModified)) { aiOpattern.MonthOfYear = evOpattern.MonthOfYear; } aiOpattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(aiOpattern); evOpattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(evOpattern); evAI = (AppointmentItem)OutlookCalendar.ReleaseObject(evAI); }
public Event GetGoogleMasterEvent(AppointmentItem ai) { log.Fine("Found a master Outlook recurring item outside sync date range: " + OutlookCalendar.GetEventSummary(ai)); List <Event> events = new List <Event>(); if (ai.UserProperties[OutlookCalendar.gEventID] == null) { events = GoogleCalendar.Instance.GetCalendarEntriesInRange(ai.Start.Date, ai.Start.Date.AddDays(1)); List <AppointmentItem> ais = new List <AppointmentItem>(); ais.Add(ai); GoogleCalendar.Instance.ReclaimOrphanCalendarEntries(ref events, ref ais, neverDelete: true); } else { Event ev = GoogleCalendar.Instance.GetCalendarEntry(ai.UserProperties[OutlookCalendar.gEventID].Value.ToString()); if (ev != null) { events.Add(ev); } } for (int g = 0; g < events.Count(); g++) { String gEntryID; Event ev = events[g]; if (GoogleCalendar.GetOGCSproperty(ev, GoogleCalendar.oEntryID, out gEntryID)) { if (gEntryID == ai.EntryID) { log.Info("Migrating Master Event from EntryID to GlobalAppointmentID..."); GoogleCalendar.AddOutlookID(ref ev, ai); GoogleCalendar.Instance.UpdateCalendarEntry_save(ref ev); return(ev); } else if (gEntryID == OutlookCalendar.Instance.IOutlook.GetGlobalApptID(ai)) { log.Fine("Found master event."); return(ev); } } } log.Warn("Failed to find master Google event for: " + OutlookCalendar.GetEventSummary(ai)); return(null); }
private void skipCorruptedItem(ref List <AppointmentItem> outlookEntries, AppointmentItem cai, String errMsg) { try { String itemSummary = OutlookOgcs.Calendar.GetEventSummary(cai); if (string.IsNullOrEmpty(itemSummary)) { try { itemSummary = cai.Start.Date.ToShortDateString() + " => " + cai.Subject; } catch { itemSummary = cai.Subject; } } Forms.Main.Instance.Console.Update("<p>" + itemSummary + "</p><p>There is probem with this item - it will not be synced.</p><p>" + errMsg + "</p>", Console.Markup.warning, logit: true); } finally { log.Debug("Outlook object removed."); outlookEntries.Remove(cai); } }
private bool DoesMatchCategoryCriterion(AppointmentItem item) { if (!_configuration.UseEventCategoryAsFilter) { return(true); } var categoryCsv = item.Categories; if (string.IsNullOrEmpty(categoryCsv)) { return(false); } return(item.Categories .Split(new[] { CultureInfo.CurrentCulture.TextInfo.ListSeparator }, StringSplitOptions.RemoveEmptyEntries) .Select(c => c.Trim()) .Any(c => c == _configuration.EventCategory)); }
void CompareIcalEventAndAppointment(IEvent icalEvent, AppointmentItem appointment) { Assert.IsTrue(icalEvent.Start.UTC == appointment.StartUTC); Assert.IsTrue(icalEvent.End.UTC == appointment.EndUTC); Assert.IsTrue(icalEvent.IsAllDay == appointment.AllDayEvent); Assert.IsTrue(icalEvent.Location == appointment.Location); var ar = icalEvent.Categories.ToArray(); var expected = String.Join(",", ar); var actural = String.Join(",", appointment.Categories.Split(new string[] { ", ", ", ", "," }, StringSplitOptions.RemoveEmptyEntries)); Assert.AreEqual(expected, actural); var alarm = icalEvent.Alarms.FirstOrDefault(); if (alarm != null) { Assert.IsTrue(-(alarm.Trigger.Duration.Value.Minutes + alarm.Trigger.Duration.Value.Hours * 60) == appointment.ReminderMinutesBeforeStart); } }
public static void Remove(ref AppointmentItem ai, MetadataId key) { String searchKey; if (Exists(ai, key, out searchKey)) { UserProperties ups = null; UserProperty prop = null; try { ups = ai.UserProperties; prop = ups.Find(searchKey); prop.Delete(); log.Debug("Removed " + searchKey + " property."); } finally { prop = (UserProperty)Calendar.ReleaseObject(prop); ups = (UserProperties)Calendar.ReleaseObject(ups); } } }
public AppointmentItem addEntry(Event e, bool add_description, bool add_reminders, bool add_attendees) { AppointmentItem result = null; try { result = (AppointmentItem)OutlookApplication.CreateItem(OlItemType.olAppointmentItem); ModifyEvent(result, e, add_description, add_reminders, add_attendees); result.Save(); } catch (System.Exception ex) { throw ex; } return(result); }
public static Boolean GoogleIdMissing(AppointmentItem ai) { //Make sure Outlook appointment has all Google IDs stored String missingIds = ""; if (!Exists(ai, MetadataId.gEventID)) { missingIds += metadataIdKeyName(MetadataId.gEventID) + "|"; } if (!Exists(ai, MetadataId.gCalendarId)) { missingIds += metadataIdKeyName(MetadataId.gCalendarId) + "|"; } if (!string.IsNullOrEmpty(missingIds)) { log.Warn("Found Outlook item missing Google IDs (" + missingIds.TrimEnd('|') + "). " + Calendar.GetEventSummary(ai)); } return(!string.IsNullOrEmpty(missingIds)); }
public static void SetUserProperty <T>(AppointmentItem currentAppItem, string propName, T propValue) { if (currentAppItem == null) { return; } var markdownModeProperty = currentAppItem.UserProperties.Find(propName); if (markdownModeProperty != null) { markdownModeProperty.Value = propValue.ToString(); } else { var prop = currentAppItem.UserProperties.Add(Constants.EnableMarkdownModeFlag, OlUserPropertyType.olText); prop.Value = propValue.ToString(); } }
private static string exportToCSV(AppointmentItem ai) { System.Text.StringBuilder csv = new System.Text.StringBuilder(); csv.Append(GoogleCalendar.GoogleTimeFrom(ai.Start) + ","); csv.Append(GoogleCalendar.GoogleTimeFrom(ai.End) + ","); csv.Append("\"" + ai.Subject + "\","); if (ai.Location == null) { csv.Append(","); } else { csv.Append("\"" + ai.Location + "\","); } if (ai.Body == null) { csv.Append(","); } else { String csvBody = ai.Body.Replace("\"", ""); csvBody = csvBody.Replace("\r\n", " "); csv.Append("\"" + csvBody.Substring(0, System.Math.Min(csvBody.Length, 100)) + "\","); } csv.Append("\"" + ai.Sensitivity.ToString() + "\","); csv.Append("\"" + ai.BusyStatus.ToString() + "\","); csv.Append("\"" + (ai.RequiredAttendees == null?"":ai.RequiredAttendees) + "\","); csv.Append("\"" + (ai.OptionalAttendees == null?"":ai.OptionalAttendees) + "\","); csv.Append(ai.ReminderSet + ","); csv.Append(ai.ReminderMinutesBeforeStart.ToString() + ","); csv.Append(OutlookCalendar.Instance.IOutlook.GetGlobalApptID(ai) + ","); if (ai.UserProperties[gEventID] != null) { csv.Append(ai.UserProperties[gEventID].Value.ToString()); } return(csv.ToString()); }
/// <summary> /// Returns a syncronization id for a given appointment. If there is no syncronization id, a new one will be /// created and saved to outlook. If saving the appointment does fail because of authorization, NO exception /// will be thrown. /// </summary> /// <param name="outlookAppointment"> /// the outlook appointment to handle /// </param> /// <param name="appointmentList"> /// The appointment List to lookup duplicates. /// </param> /// <returns> /// the corresponding Guid /// </returns> private static Guid GetStandardAppointmentId( AppointmentItem outlookAppointment, IEnumerable <StdCalendarItem> appointmentList) { if (outlookAppointment == null) { throw new ArgumentNullException("outlookAppointment"); } var newId = Guid.NewGuid(); try { // try to read the contact id property - generate one if it's not there var contactIdObject = outlookAppointment.UserProperties[AppointmentIdOutlookPropertyName] ?? outlookAppointment.UserProperties.Add( ContactIdOutlookPropertyName, OlUserPropertyType.olText, true, 1); // test if the value is a valid id if (contactIdObject.Value.ToString().Length != 36) { // use the formerly generated id if the one from outlook is not valid contactIdObject.Value = newId.ToString(); outlookAppointment.Save(); } // finally read the id from the property newId = new Guid(contactIdObject.Value.ToString()); } catch (UnauthorizedAccessException) { // if we are not authorized to write back the id, we will assume a new id } var guid = newId; if (appointmentList != null && appointmentList.Where(x => x.Id == guid).Count() > 0) { newId = Guid.NewGuid(); } return(newId); }
private static AppointmentItem getOutlookInstance(RecurrencePattern oPattern, DateTime instanceDate) { //First check if this is not yet an exception AppointmentItem ai = null; try { ai = oPattern.GetOccurrence(instanceDate); } catch { } if (ai == null) { //The Outlook API is rubbish as the date argument is how it exists NOW (not OriginalDate). //If this has changed >1 in Google then there's no way of knowing what it might be! foreach (Microsoft.Office.Interop.Outlook.Exception oExp in oPattern.Exceptions) { if (oExp.OriginalDate.Date == instanceDate.Date) { try { log.Debug("Found Outlook exception for " + instanceDate); if (exceptionIsDeleted(oExp)) { log.Debug("This exception is deleted."); return(null); } else { return(oExp.AppointmentItem); } } catch (System.Exception ex) { MainForm.Instance.Logboxout(ex.Message); MainForm.Instance.Logboxout("If this keeps happening, please restart OGCS."); break; } } } if (ai == null) { log.Warn("Unable to find Outlook exception for " + instanceDate); } } return(ai); }
private void repopulateIDs(String entryID, Dictionary <OutlookOgcs.Calendar.MetadataId, object> propertyValues) { //Allow time for pasted item to complete System.Threading.Thread.Sleep(2000); log.Debug("Repopulating IDs to original copied Outlook item"); AppointmentItem copiedAi = null; try { OutlookOgcs.Calendar.Instance.IOutlook.GetAppointmentByID(entryID, out copiedAi); if (copiedAi == null) { throw new System.Exception("Could not find Outlook item with entryID " + entryID + " for post-processing."); } log.Debug(OutlookOgcs.Calendar.GetEventSummary(copiedAi)); foreach (KeyValuePair <OutlookOgcs.Calendar.MetadataId, object> property in propertyValues) { if (property.Value == null) { OutlookOgcs.Calendar.RemoveOGCSproperty(ref copiedAi, property.Key); } else { if (property.Value is DateTime) { OutlookOgcs.Calendar.AddOGCSproperty(ref copiedAi, property.Key, (DateTime)property.Value); } else { OutlookOgcs.Calendar.AddOGCSproperty(ref copiedAi, property.Key, property.Value.ToString()); } } } copiedAi.Save(); } catch (System.Exception ex) { log.Warn("Failed to repopulate OGCS properties back to copied item."); OGCSexception.Analyse(ex); } finally { copiedAi = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(copiedAi); } }
public List <String> BuildGooglePattern(AppointmentItem ai, Event ev) { if (!ai.IsRecurring || ai.RecurrenceState != OlRecurrenceState.olApptMaster) { return(null); } log.Debug("Creating Google iCalendar definition for recurring event."); List <String> gPattern = new List <String>(); RecurrencePattern rp = null; try { rp = ai.GetRecurrencePattern(); gPattern.Add("RRULE:" + buildRrule(rp)); } finally { rp = (RecurrencePattern)OutlookOgcs.Calendar.ReleaseObject(rp); } log.Debug(string.Join("\r\n", gPattern.ToArray())); return(gPattern); }
public void Add(AppointmentItem ai, EphemeralProperty property) { if (!ExistAny(ai)) { ephemeralProperties.Add(ai, new Dictionary <EphemeralProperty.PropertyName, object> { { property.Name, property.Value } }); } else { if (PropertyExists(ai, property.Name)) { ephemeralProperties[ai][property.Name] = property.Value; } else { ephemeralProperties[ai].Add(property.Name, property.Value); } } }
// sets the correct event status for the google event based on the outlook event public static void SetEventStatus(Event ev, AppointmentItem ai) { string outlook_status = EventStatus(ai); if (outlook_status == EVENT_STATUS_FREE) { ev.Status = "confirmed"; ev.Transparency = "transparent"; } else if (outlook_status == EVENT_STATUS_TENTATIVE) { ev.Status = "tentative"; ev.Transparency = "transparent"; } else { ev.Status = "confirmed"; ev.Transparency = "opaque"; } }
public async Task Initialize(AppointmentDbContext context) { string[] customers = { "John Oliver", "Trevor Noah", "Stephen Colbert" }; string[] carModels = { "Audi A3", "Audi Q4", "Audi Q5" }; for (int i = 0; i < customers.Length; i++) { var appointment = new AppointmentItem() { Price = 100, CustomerName = customers[i], CarModel = carModels[i], Created = DateTime.Now, Status = AppointmentStatus.Active, AppointmentDate = appointmentsHelper.GetRandomAppointmentDate(appSettings.MaximumDaysForRandomAppointmentDate) }; context.AppointmentItems.Add(appointment); } await context.SaveChangesAsync(); }
private void CalendarItems_ItemAdd(object anItem) { AppointmentItem appointment = (anItem as AppointmentItem); if (appointment != null) { try { if (this.AppointmentAdded != null) { this.AppointmentAdded(this, new EventArgs <AppointmentItem>(appointment)); } } finally { Marshal.ReleaseComObject(appointment); appointment = null; } } }
public void Should_update_existing_item_status() { var appointmentItem = new AppointmentItem() { Id = 1, Status = AppointmentStatus.Completed }; var patchObject = new JsonPatchDocument <AppointmentUpdateStatusDto>(); patchObject.Replace <AppointmentStatus>(s => s.Status, AppointmentStatus.Completed); _repository.Setup(x => x.GetSingle(1)).Returns(appointmentItem); _repository.Setup(x => x.Update(1, It.IsAny <AppointmentItem>())).Returns(appointmentItem); var result = _controller.UpdateAppointmentStatus(1, patchObject).Result as OkObjectResult; _repository.Verify(x => x.GetSingle(1), Times.Once); _repository.Verify(x => x.Update(1, appointmentItem), Times.Once); Assert.NotNull(result); Assert.IsType <AppointmentItemDto>(result.Value); Assert.Equal(AppointmentStatus.Completed, (result.Value as AppointmentItemDto).Status); }
private void Inspectors_NewInspector(Inspector Inspector) { if (Inspector.CurrentItem is AppointmentItem) { appointmentItem = Inspector.CurrentItem; CurrentLocation = appointmentItem.Location; appointmentItem.PropertyChange -= AppointmentItem_PropertyChange; appointmentItem.PropertyChange += AppointmentItem_PropertyChange; } //if (Inspector.CurrentItem is MeetingItem) //{ // meetingItem = Inspector.CurrentItem; // meetingItem.PropertyChange += MeetingItem_PropertyChange; //} //else if (Inspector.CurrentItem is AppointmentItem) //{ // appointmentItem = Inspector.CurrentItem; // appointmentItem.PropertyChange += AppointmentItem_PropertyChange; //} }
private void Appt_Write(ref bool Cancel) { Inspector inspector = Globals.ThisAddIn.Application.ActiveInspector(); AppointmentItem appt = inspector.CurrentItem as AppointmentItem; var creator = appt.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0C1A001E"); if ((appt.Organizer != Globals.ThisAddIn.Application.Session.CurrentUser.Name) && (creator != Globals.ThisAddIn.Application.Session.CurrentUser.Name)) { return; } if (!_processWrite) { return; } if (appt.UserProperties.Find("MJ-MRBS-ID") != null) { OutlookManager.SaveChangesToReservation(appt); } }
//http://stackoverflow.com/questions/17348807/how-to-translate-between-windows-and-iana-time-zones //https://en.wikipedia.org/wiki/List_of_tz_database_time_zones public Event IANAtimezone_set(Event ev, AppointmentItem ai) { try { try { ev.Start.TimeZone = IANAtimezone(ai.StartTimeZone.ID, ai.StartTimeZone.Name); } catch (System.Exception ex) { log.Debug(ex.Message); throw new ApplicationException("Failed to set start timezone. [" + ai.StartTimeZone.ID + ", " + ai.StartTimeZone.Name + "]"); } try { ev.End.TimeZone = IANAtimezone(ai.EndTimeZone.ID, ai.EndTimeZone.Name); } catch (System.Exception ex) { log.Debug(ex.Message); throw new ApplicationException("Failed to set end timezone. [" + ai.EndTimeZone.ID + ", " + ai.EndTimeZone.Name + "]"); } } catch (ApplicationException ex) { log.Warn(ex.Message); } return(ev); }
protected Cita(Entidades.Cita poCita) { this._oAplicacion = new Application(); this._oCita = (AppointmentItem)this._oAplicacion.CreateItem(OlItemType.olAppointmentItem); this._bMostrar = poCita.Mostrar; if (_oCita != null) { this._oCita.AllDayEvent = poCita.EventoTodoDia; this._oCita.Body = poCita.Contenido; this._oCita.Importance = poCita.Prioridad; this._oCita.ReminderSet = poCita.Recordatorio; this._oCita.Subject = poCita.Asunto; if (poCita.Inicio != null) { this._oCita.Start = (DateTime)poCita.Inicio; } if (poCita.Fin != null) { this._oCita.End = (DateTime)poCita.Fin; } if (poCita.Mensaje && !string.IsNullOrEmpty(poCita.Destinatario)) { this._oMensaje = this._oCita.ForwardAsVcal(); this._oMensaje.To = poCita.Destinatario; } if (poCita.Recordatorio) { this._oCita.ReminderMinutesBeforeStart = poCita.RecordatorioMinutosAntesComienzo; } if (poCita.Ubicacion != null) { this._oCita.Location = poCita.Ubicacion; } } }
/// <summary> /// Updates an appointment to the values of a redmine time entry /// </summary> /// <param name="item">The appointment item</param> /// <param name="timeEntry">The redmine time entry</param> /// <param name="issue">The issue that belongs to the timeentry. Can be <code>null</code> if the issue is not known.</param> public static void UpdateAppointmentFromTimeEntry(this AppointmentItem item, TimeEntryInfo timeEntry, IssueInfo issue) { // create new calendar item item.CreateAppointmentLocation(timeEntry.IssueInfo.Id.Value, issue); item.Subject = timeEntry.Name; item.Start = timeEntry.StartDateTime; var endTime = timeEntry.EndDateTime; if (timeEntry.IssueInfo.Id != Settings.Default.RedmineUseOvertimeIssue) { item.End = timeEntry.EndDateTime; } else { // In case of the overtime issue, we cannot take the actual hours property for determining the end time, because hours is 0. item.End = endTime; } if (timeEntry.IssueInfo.Id != Settings.Default.RedmineUseOvertimeIssue && Math.Abs((endTime - item.End).TotalMinutes) > 5) { item.AppendToBody("Die Von/Bis-Zeit dieses Elements wurde geändert, da sie nicht mit dem 'Stunden'-Feld aus Redmine übereinstimmte."); Log.WarnFormat("The end time of the time entry was changed, because it was not consistent with the provided duration. "); } // create user properties item.UpdateAppointmentFields( timeEntry.Id, timeEntry.ProjectInfo.Id.Value, timeEntry.IssueInfo.Id.Value, timeEntry.ActivityInfo.Id.Value, timeEntry.UpdateTime); if (timeEntry.IssueInfo.Id != Settings.Default.RedmineUseOvertimeIssue) { item.SetAppointmentState(AppointmentState.Synchronized); } else { item.SetAppointmentState(AppointmentState.SynchronizedOvertime); } }
public static MeetingStatusEnum GetMeetingStatus(this AppointmentItem appointment) { switch (appointment.MeetingStatus) { case OlMeetingStatus.olMeeting: return(MeetingStatusEnum.Meeting); case OlMeetingStatus.olMeetingCanceled: return(MeetingStatusEnum.MeetingCancelled); case OlMeetingStatus.olMeetingReceived: return(MeetingStatusEnum.MeetingReceived); case OlMeetingStatus.olMeetingReceivedAndCanceled: return(MeetingStatusEnum.MeetingReceivedAndCanceled); case OlMeetingStatus.olNonMeeting: return(MeetingStatusEnum.NonMeeting); } return(MeetingStatusEnum.Meeting); }
private void CalendarItems_ItemChange(object anItem) { AppointmentItem appointment = (anItem as AppointmentItem); if ((appointment != null) && _itemSaved) { try { if (this.AppointmentModified != null) { this.AppointmentModified(this, new EventArgs <AppointmentItem>(appointment)); } } finally { Marshal.ReleaseComObject(appointment); appointment = null; _itemSaved = false; } } }
public static void CreateEventOutlook(BookMeetingRoomForm data) { try { Application app = null; app = new Application(); AppointmentItem appt = app.CreateItem(OlItemType.olAppointmentItem) as AppointmentItem; appt.Subject = "Notice: book a meeting room"; appt.AllDayEvent = false; appt.Start = DateTime.Parse(data.StartDate.ToShortDateString() + " " + data.StartTime); //appt.End = DateTime.Parse(data.FinalDate.ToShortDateString() + " " + data.FinalTime); appt.Importance = OlImportance.olImportanceHigh; appt.Location = "Sala Pozuelo"; appt.Body = "Room type: " + data.TypeRoom.Value.ToString() + "Number of people: + " + data.Attendant.ToString(); appt.Display(false); } catch (System.Exception ex) { } }
private String deleteOutlookCustomProperty(ref AppointmentItem copiedAi, String propertyName) { UserProperties ups = null; UserProperty prop = null; String propertyValue = null; try { ups = copiedAi.UserProperties; prop = ups.Find(propertyName); if (prop != null) { propertyValue = prop.Value.ToString(); prop.Delete(); log.Debug("Removed " + propertyName + " property."); } } finally { prop = (UserProperty)Calendar.ReleaseObject(prop); ups = (UserProperties)Calendar.ReleaseObject(ups); } return(propertyValue); }
public ActionResult <AppointmentItemDto> CreateAppointment([FromBody] AppointmentCreateDto appointmentCreateDto) { if (appointmentCreateDto == null) { return(BadRequest()); } var appointmentItem = _mapper.Map <AppointmentItem>(appointmentCreateDto); _appointmentRepository.Add(appointmentItem); if (!_appointmentRepository.Save()) { throw new Exception("Creating an appointment failed on save!"); } AppointmentItem newAppointmentItem = _appointmentRepository.GetSingle(appointmentItem.Id); return(CreatedAtRoute(nameof(GetSingleAppointment), new { id = newAppointmentItem.Id }, _mapper.Map <AppointmentItemDto>(newAppointmentItem))); }
public static (AppointmentItem predecessor, AppointmentItem successor) GetSurroundingAppointmentsTheSameDay(AppointmentItem appointment) { AppointmentItem predecessor = null; AppointmentItem successor = null; foreach (AppointmentItem currentItem in GetItemsBetween(appointment.Start.Date, appointment.Start.Date.AddDays(1))) { if (currentItem.End <= appointment.Start) { predecessor = currentItem; continue; } if (successor == null && currentItem.Start >= appointment.End) { successor = currentItem; } } return(predecessor, successor); }
/// <summary> /// </summary> /// <param name="id"></param> /// <param name="appointmentItem"></param> /// <returns> /// </returns> private Appointment GetAppointmentFromItem(string id, AppointmentItem appointmentItem) { var app = new Appointment(appointmentItem.Body, appointmentItem.Location, appointmentItem.Subject, appointmentItem.End, appointmentItem.Start) { AllDayEvent = appointmentItem.AllDayEvent, ReminderMinutesBeforeStart = appointmentItem.ReminderMinutesBeforeStart, ReminderSet = appointmentItem.ReminderSet, IsRecurring = appointmentItem.IsRecurring, AppointmentId = appointmentItem.IsRecurring ? $"{appointmentItem.EntryID}_{appointmentItem.Start.ToString("yy-MM-dd")}" : appointmentItem.EntryID, Privacy = appointmentItem.GetAppointmentSensitivity(), MeetingStatus = appointmentItem.GetMeetingStatus() }; GetRecipients(appointmentItem, app); app.Created = appointmentItem.CreationTime; app.LastModified = appointmentItem.LastModificationTime; app.SetBusyStatus(appointmentItem.BusyStatus); GetExtendedProperties(appointmentItem, app); app.CalendarId = id; return app; }
private bool UpdateAppointment(bool addDescription, bool addReminder, bool addAttendees, bool attendeesToDescription, AppointmentItem appItem, Appointment calendarAppointment) { Recipients recipients = null; UserProperties userProperties = null; try { appItem.Subject = calendarAppointment.Subject; appItem.Location = calendarAppointment.Location; appItem.BusyStatus = calendarAppointment.GetOutlookBusyStatus(); if (EventCategory != null) { appItem.Categories = EventCategory.CategoryName; } if (calendarAppointment.AllDayEvent != appItem.AllDayEvent) { appItem.AllDayEvent = calendarAppointment.AllDayEvent; } appItem.Sensitivity = calendarAppointment.GetAppointmentSensitivity(); appItem.Start = calendarAppointment.StartTime.GetValueOrDefault(); appItem.End = calendarAppointment.EndTime.GetValueOrDefault(); if (addDescription) { appItem.Body = calendarAppointment.Description; } if (addAttendees && !attendeesToDescription) { recipients = appItem.Recipients; if (calendarAppointment.RequiredAttendees != null) { calendarAppointment.RequiredAttendees.ForEach(rcptName => { if (!CheckIfRecipientExists(recipients, rcptName)) { var recipient = appItem.Recipients.Add($"{rcptName.Name}<{rcptName.Email}>"); recipient.Type = (int) OlMeetingRecipientType.olRequired; recipient.Resolve(); } }); } if (calendarAppointment.OptionalAttendees != null) { calendarAppointment.OptionalAttendees.ForEach(rcptName => { if (!CheckIfRecipientExists(recipients, rcptName)) { var recipient = appItem.Recipients.Add($"{rcptName.Name}<{rcptName.Email}>"); recipient.Type = (int) OlMeetingRecipientType.olOptional; recipient.Resolve(); } }); } } if (addReminder) { if (appItem.ReminderSet != calendarAppointment.ReminderSet) { appItem.ReminderMinutesBeforeStart = calendarAppointment.ReminderMinutesBeforeStart; if (calendarAppointment.ReminderSet && appItem.ReminderMinutesBeforeStart != calendarAppointment.ReminderMinutesBeforeStart) { appItem.ReminderMinutesBeforeStart = calendarAppointment.ReminderMinutesBeforeStart; } } } userProperties = appItem.UserProperties; if (userProperties != null) { for (var i = 0; i < userProperties.Count; i++) { userProperties.Remove(i + 1); } foreach (var extendedProperty in calendarAppointment.ExtendedProperties) { var sourceProperty = userProperties.Add(extendedProperty.Key, OlUserPropertyType.olText); sourceProperty.Value = extendedProperty.Value; } } appItem.Save(); } catch (Exception exception) { Logger.Error(exception); return false; } finally { if (recipients != null) { Marshal.FinalReleaseComObject(recipients); } if (userProperties != null) { Marshal.FinalReleaseComObject(userProperties); } if (appItem != null) { Marshal.FinalReleaseComObject(appItem); } } return true; }
private void SetAppointmentOrganizer(AppointmentItem appItem, Recipient organizer) { try { if (appItem == null || organizer == null || !SetOrganizer) return; const string PR_SENT_REPRESENTING_NAME = "http://schemas.microsoft.com/mapi/proptag/0x0042001F"; const string PR_SENT_REPRESENTING_ENTRY_ID = "http://schemas.microsoft.com/mapi/proptag/0x00410102"; const string PR_SENDER_ENTRYID = "http://schemas.microsoft.com/mapi/proptag/0x0C190102"; PropertyAccessor pa = appItem.PropertyAccessor; pa.SetProperty(PR_SENDER_ENTRYID, pa.StringToBinary(organizer.EntryID)); pa.SetProperty(PR_SENT_REPRESENTING_NAME, organizer.Name); pa.SetProperty(PR_SENT_REPRESENTING_ENTRY_ID, pa.StringToBinary(organizer.EntryID)); } catch (Exception ex) { Logger.Error(ex); } }
/// <summary> /// </summary> /// <param name="addDescription"></param> /// <param name="addReminder"></param> /// <param name="addAttendees"></param> /// <param name="attendeesToDescription"></param> /// <param name="appItem"></param> /// <param name="calendarAppointment"></param> private Appointment AddAppointment(bool addDescription, bool addReminder, bool addAttendees, bool attendeesToDescription, AppointmentItem appItem, Appointment calendarAppointment, string id) { Recipients recipients = null; UserProperties userProperties = null; Appointment createdAppointment = null; try { appItem.Subject = calendarAppointment.Subject; if (!calendarAppointment.RequiredAttendees.Any() && !calendarAppointment.OptionalAttendees.Any() && AddAsAppointments) { appItem.MeetingStatus = OlMeetingStatus.olNonMeeting; } else { appItem.MeetingStatus = OlMeetingStatus.olMeeting; } appItem.Sensitivity = calendarAppointment.GetAppointmentSensitivity(); appItem.Location = calendarAppointment.Location; appItem.BusyStatus = calendarAppointment.GetOutlookBusyStatus(); recipients = appItem.Recipients; if (EventCategory != null) { appItem.Categories = EventCategory.CategoryName; } if (calendarAppointment.AllDayEvent) { appItem.AllDayEvent = true; } appItem.Start = calendarAppointment.StartTime.GetValueOrDefault(); appItem.End = calendarAppointment.EndTime.GetValueOrDefault(); appItem.Body = calendarAppointment.GetDescriptionData(addDescription, attendeesToDescription); Recipient organizer = null; if (addAttendees && !attendeesToDescription) { calendarAppointment.RequiredAttendees?.ForEach(rcptName => { var recipient = appItem.Recipients.Add($"{rcptName.Name}<{rcptName.Email}>"); if (SetOrganizer && calendarAppointment.Organizer != null && rcptName.Name.Equals(calendarAppointment.Organizer.Name)) { recipient.Type = (int) OlMeetingRecipientType.olOrganizer; recipient.Resolve(); organizer = recipient; } else { recipient.Type = (int) OlMeetingRecipientType.olRequired; recipient.Resolve(); } }); calendarAppointment.OptionalAttendees?.ForEach(rcptName => { var recipient = appItem.Recipients.Add($"{rcptName.Name}<{rcptName.Email}>"); if (SetOrganizer && calendarAppointment.Organizer != null && rcptName.Name.Equals(calendarAppointment.Organizer.Name)) { recipient.Type = (int) OlMeetingRecipientType.olOrganizer; recipient.Resolve(); organizer = recipient; } else { recipient.Type = (int)OlMeetingRecipientType.olOptional; recipient.Resolve(); } }); } else if (SetOrganizer && calendarAppointment.Organizer != null) { var recipient = appItem.Recipients.Add( $"{calendarAppointment.Organizer.Name}<{calendarAppointment.Organizer.Email}>"); recipient.Type = (int)OlMeetingRecipientType.olOrganizer; recipient.Resolve(); organizer = recipient; } SetAppointmentOrganizer(appItem, organizer); if (addReminder) { appItem.ReminderMinutesBeforeStart = calendarAppointment.ReminderMinutesBeforeStart; appItem.ReminderSet = calendarAppointment.ReminderSet; } userProperties = appItem.UserProperties; if (userProperties != null) { var sourceProperty = userProperties.Add(calendarAppointment.GetSourceEntryKey(), OlUserPropertyType.olText); sourceProperty.Value = calendarAppointment.AppointmentId; } appItem.Save(); createdAppointment = GetAppointmentFromItem(id, appItem); } catch (Exception exception) { Logger.Error(exception); } finally { if (userProperties != null) { Marshal.FinalReleaseComObject(userProperties); } if (recipients != null) { Marshal.FinalReleaseComObject(recipients); } if (appItem != null) { Marshal.FinalReleaseComObject(appItem); } } return createdAppointment; }
public AppointmentItem WindowsTimeZone_set(AppointmentItem ai, Event ev) { ai.Start = DateTime.Parse(ev.Start.DateTime ?? ev.Start.Date); if (!String.IsNullOrEmpty(ev.Start.TimeZone)) ai.StartTimeZone = WindowsTimeZone(ev.Start.TimeZone); ai.End = DateTime.Parse(ev.End.DateTime ?? ev.End.Date); if (!String.IsNullOrEmpty(ev.Start.TimeZone)) ai.EndTimeZone = WindowsTimeZone(ev.End.TimeZone); return ai; }
private Event createCalendarEntry_save(Event ev, AppointmentItem ai) { if (Settings.Instance.SyncDirection == SyncDirection.Bidirectional) { log.Debug("Saving timestamp when OGCS updated event."); setOGCSlastModified(ref ev); } if (Settings.Instance.APIlimit_inEffect) { addOGCSproperty(ref ev, Program.APIlimitHit, "True"); } Event createdEvent = new Event(); int backoff = 0; while (backoff < backoffLimit) { try { createdEvent = service.Events.Insert(ev, Settings.Instance.UseGoogleCalendar.Id).Fetch(); if (Settings.Instance.AddAttendees && Settings.Instance.APIlimit_inEffect) { log.Info("API limit for attendee sync lifted :-)"); Settings.Instance.APIlimit_inEffect = false; } break; } catch (Google.GoogleApiException ex) { switch (handleAPIlimits(ex, ev)) { case apiException.throwException: throw; case apiException.freeAPIexhausted: throw; case apiException.justContinue: break; case apiException.backoffThenRetry: { backoff++; if (backoff == backoffLimit) { log.Error("API limit backoff was not successful. Save failed."); throw; } else { log.Warn("API rate limit reached. Backing off " + backoff + "sec before retry."); System.Threading.Thread.Sleep(backoff * 1000); } break; } } } } Boolean gKeyExists = false; try { UserProperty up = ai.UserProperties.Find(OutlookCalendar.gEventID); gKeyExists = (up != null); } catch { } if (Settings.Instance.SyncDirection == SyncDirection.Bidirectional || gKeyExists) { log.Debug("Storing the Google event ID in Outlook appointment."); OutlookCalendar.AddOGCSproperty(ref ai, OutlookCalendar.gEventID, createdEvent.Id); ai.Save(); } //DOS ourself by triggering API limit //for (int i = 1; i <= 30; i++) { // MainForm.Instance.Logboxout("Add #" + i, verbose:true); // Event result = service.Events.Insert(e, Settings.Instance.UseGoogleCalendar.Id).Fetch(); // System.Threading.Thread.Sleep(300); // GoogleCalendar.Instance.deleteCalendarEntry(result); // System.Threading.Thread.Sleep(300); //} return createdEvent; }
public void UpdateOutlookExceptions(AppointmentItem ai, Event ev) { processOutlookExceptions(ai, ev, forceCompare: false); }
public Event UpdateCalendarEntry(AppointmentItem ai, Event ev, ref int itemModified, Boolean forceCompare = false) { if (!Settings.Instance.APIlimit_inEffect && GetOGCSproperty(ev, Program.APIlimitHit)) { log.Fine("Back processing Event affected by attendee API limit."); } else { if (!(MainForm.Instance.ManualForceCompare || forceCompare)) { //Needed if the exception has just been created, but now needs updating if (Settings.Instance.SyncDirection != SyncDirection.Bidirectional) { if (DateTime.Parse(ev.Updated) > ai.LastModificationTime) return null; } else { if (OutlookCalendar.GetOGCSlastModified(ai).AddSeconds(5) >= ai.LastModificationTime) //Outlook last modified by OGCS return null; if (DateTime.Parse(ev.Updated) > DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime))) return null; } } } String aiSummary = OutlookCalendar.GetEventSummary(ai); log.Debug("Processing >> " + aiSummary); System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.AppendLine(aiSummary); //Handle an event's all-day attribute being toggled String evStart = ev.Start.Date ?? ev.Start.DateTime; String evEnd = ev.End.Date ?? ev.End.DateTime; if (ai.AllDayEvent) { ev.Start.DateTime = null; ev.End.DateTime = null; if (MainForm.CompareAttribute("Start time", SyncDirection.OutlookToGoogle, evStart, ai.Start.ToString("yyyy-MM-dd"), sb, ref itemModified)) { ev.Start.Date = ai.Start.ToString("yyyy-MM-dd"); } if (MainForm.CompareAttribute("End time", SyncDirection.OutlookToGoogle, evEnd, ai.End.ToString("yyyy-MM-dd"), sb, ref itemModified)) { ev.End.Date = ai.End.ToString("yyyy-MM-dd"); } } else { //Handle: Google = all-day; Outlook = not all day, but midnight values (so effectively all day!) if (ev.Start.Date != null && GoogleCalendar.GoogleTimeFrom(DateTime.Parse(evStart)) == GoogleCalendar.GoogleTimeFrom(ai.Start) && GoogleCalendar.GoogleTimeFrom(DateTime.Parse(evEnd)) == GoogleCalendar.GoogleTimeFrom(ai.End)) { sb.AppendLine("All-Day: true => false"); ev.Start.DateTime = GoogleCalendar.GoogleTimeFrom(ai.Start); ev.End.DateTime = GoogleCalendar.GoogleTimeFrom(ai.End); itemModified++; } ev.Start.Date = null; ev.End.Date = null; if (MainForm.CompareAttribute("Start time", SyncDirection.OutlookToGoogle, GoogleCalendar.GoogleTimeFrom(DateTime.Parse(evStart)), GoogleCalendar.GoogleTimeFrom(ai.Start), sb, ref itemModified)) { ev.Start.DateTime = GoogleCalendar.GoogleTimeFrom(ai.Start); } if (MainForm.CompareAttribute("End time", SyncDirection.OutlookToGoogle, GoogleCalendar.GoogleTimeFrom(DateTime.Parse(evEnd)), GoogleCalendar.GoogleTimeFrom(ai.End), sb, ref itemModified)) { ev.End.DateTime = GoogleCalendar.GoogleTimeFrom(ai.End); } } List<String> oRrules = Recurrence.Instance.BuildGooglePattern(ai, ev); if (ev.Recurrence != null) { for (int r = 0; r < ev.Recurrence.Count; r++) { String rrule = ev.Recurrence[r]; if (rrule.StartsWith("RRULE:")) { if (oRrules != null) { String[] oRrule_bits = oRrules.First().TrimStart("RRULE:".ToCharArray()).Split(';'); foreach (String oRrule_bit in oRrule_bits) { if (!rrule.Contains(oRrule_bit)) { if (MainForm.CompareAttribute("Recurrence", SyncDirection.OutlookToGoogle, rrule, oRrules.First(), sb, ref itemModified)) { ev.Recurrence[r] = oRrules.First(); } } } } else { log.Debug("Converting to non-recurring event."); MainForm.CompareAttribute("Recurrence", SyncDirection.OutlookToGoogle, rrule, null, sb, ref itemModified); ev.Recurrence[r] = null; } break; } } } else { if (oRrules != null && ev.RecurringEventId == null) { log.Debug("Converting to recurring event."); MainForm.CompareAttribute("Recurrence", SyncDirection.OutlookToGoogle, null, oRrules.First(), sb, ref itemModified); ev.Recurrence = oRrules; } } if (ev.Recurrence != null && ev.RecurringEventId == null) { ev = OutlookCalendar.Instance.IOutlook.IANAtimezone_set(ev, ai); } String subjectObfuscated = Obfuscate.ApplyRegex(ai.Subject, SyncDirection.OutlookToGoogle); if (MainForm.CompareAttribute("Subject", SyncDirection.OutlookToGoogle, ev.Summary, subjectObfuscated, sb, ref itemModified)) { ev.Summary = subjectObfuscated; } if (!Settings.Instance.AddDescription) ai.Body = ""; String outlookBody = ai.Body; //Check for Google description truncated @ 8Kb if (!string.IsNullOrEmpty(ai.Body) && !string.IsNullOrEmpty(ev.Description) && ev.Description.Length == 8 * 1024 && ai.Body.Length > 8 * 1024) { outlookBody = ai.Body.Substring(0, 8 * 1024); } if (MainForm.CompareAttribute("Description", SyncDirection.OutlookToGoogle, ev.Description, outlookBody, sb, ref itemModified)) ev.Description = outlookBody; if (MainForm.CompareAttribute("Location", SyncDirection.OutlookToGoogle, ev.Location, ai.Location, sb, ref itemModified)) ev.Location = ai.Location; String oPrivacy = (ai.Sensitivity == OlSensitivity.olNormal) ? "default" : "private"; String gPrivacy = ev.Visibility ?? "default"; if (MainForm.CompareAttribute("Private", SyncDirection.OutlookToGoogle, gPrivacy, oPrivacy, sb, ref itemModified)) { ev.Visibility = oPrivacy; } String oFreeBusy = (ai.BusyStatus == OlBusyStatus.olFree) ? "transparent" : "opaque"; String gFreeBusy = ev.Transparency ?? "opaque"; if (MainForm.CompareAttribute("Free/Busy", SyncDirection.OutlookToGoogle, gFreeBusy, oFreeBusy, sb, ref itemModified)) { ev.Transparency = oFreeBusy; } if (Settings.Instance.AddAttendees && ai.Recipients.Count > 1 && !APIlimitReached_attendee) { if (ai.Recipients.Count >= 200) { MainForm.Instance.Logboxout("ALERT: Attendees will not be synced for this meeting as it has " + "more than 200, which Google does not allow."); ev.Attendees = new List<EventAttendee>(); } else { try { CompareRecipientsToAttendees(ai, ev, sb, ref itemModified); } catch (System.Exception ex) { if (OutlookCalendar.Instance.IOutlook.ExchangeConnectionMode().ToString().Contains("Disconnected")) { MainForm.Instance.Logboxout("Outlook is currently disconnected from Exchange, so it's not possible to sync attendees."); MainForm.Instance.Logboxout("Please reconnect or do not sync attendees."); throw new System.Exception("Outlook has disconnected from Exchange."); } else { MainForm.Instance.Logboxout("WARNING: Unable to sync attendees.\r\n" + ex.Message); } } } } //Reminders if (Settings.Instance.AddReminders) { Boolean OKtoSyncReminder = OutlookCalendar.Instance.IsOKtoSyncReminder(ai); if (ev.Reminders.Overrides != null) { //Find the popup reminder in Google for (int r = ev.Reminders.Overrides.Count - 1; r >= 0; r--) { EventReminder reminder = ev.Reminders.Overrides[r]; if (reminder.Method == "popup") { if (OKtoSyncReminder) { if (ai.ReminderSet) { if (MainForm.CompareAttribute("Reminder", SyncDirection.OutlookToGoogle, reminder.Minutes.ToString(), ai.ReminderMinutesBeforeStart.ToString(), sb, ref itemModified)) { reminder.Minutes = ai.ReminderMinutesBeforeStart; } } else { sb.AppendLine("Reminder: " + reminder.Minutes + " => removed"); ev.Reminders.Overrides.Remove(reminder); if (ev.Reminders.Overrides == null || ev.Reminders.Overrides.Count == 0) { ev.Reminders.UseDefault = Settings.Instance.UseGoogleDefaultReminder; } itemModified++; } //if Outlook reminders set } else { sb.AppendLine("Reminder: " + reminder.Minutes + " => removed"); ev.Reminders.Overrides.Remove(reminder); ev.Reminders.UseDefault = false; itemModified++; } } //if google reminder found } //foreach reminder } else { //no google reminders set if (ai.ReminderSet && OKtoSyncReminder) { sb.AppendLine("Reminder: nothing => " + ai.ReminderMinutesBeforeStart); ev.Reminders.UseDefault = false; EventReminder newReminder = new EventReminder(); newReminder.Method = "popup"; newReminder.Minutes = ai.ReminderMinutesBeforeStart; ev.Reminders.Overrides = new List<EventReminder>(); ev.Reminders.Overrides.Add(newReminder); itemModified++; } else { if (MainForm.CompareAttribute("Reminder Default", SyncDirection.OutlookToGoogle, ev.Reminders.UseDefault.ToString(), OKtoSyncReminder ? Settings.Instance.UseGoogleDefaultReminder.ToString() : "False", sb, ref itemModified)) { ev.Reminders.UseDefault = OKtoSyncReminder ? Settings.Instance.UseGoogleDefaultReminder : false; } } } } if (itemModified > 0) { MainForm.Instance.Logboxout(sb.ToString(), false, verbose: true); MainForm.Instance.Logboxout(itemModified + " attributes updated.", verbose: true); System.Windows.Forms.Application.DoEvents(); } return ev; }
public void CreateOutlookExceptions(AppointmentItem ai, Event ev) { processOutlookExceptions(ai, ev, forceCompare: true); }
public Boolean CompareRecipientsToAttendees(AppointmentItem ai, Event ev, StringBuilder sb, ref int itemModified) { log.Fine("Comparing Recipients"); //Build a list of Google attendees. Any remaining at the end of the diff must be deleted. List<EventAttendee> removeAttendee = new List<EventAttendee>(); foreach (EventAttendee ea in ev.Attendees ?? Enumerable.Empty<EventAttendee>()) { removeAttendee.Add(ea); } if (ai.Recipients.Count > 1) { for (int o = ai.Recipients.Count; o > 0; o--) { bool foundAttendee = false; Recipient recipient = ai.Recipients[o]; log.Fine("Comparing Outlook recipient: " + recipient.Name); String recipientSMTP = OutlookCalendar.Instance.IOutlook.GetRecipientEmail(recipient); foreach (EventAttendee attendee in ev.Attendees ?? Enumerable.Empty<EventAttendee>()) { if (attendee.Email != null && (recipientSMTP.ToLower() == attendee.Email.ToLower())) { foundAttendee = true; removeAttendee.Remove(attendee); //Optional attendee bool oOptional = (recipient.Type == (int)OlMeetingRecipientType.olOptional); bool gOptional = (attendee.Optional == null) ? false : (bool)attendee.Optional; String attendeeIdentifier = (attendee.DisplayName == null) ? attendee.Email : attendee.DisplayName; if (MainForm.CompareAttribute("Attendee " + attendeeIdentifier + " - Optional Check", SyncDirection.OutlookToGoogle, gOptional, oOptional, sb, ref itemModified)) { attendee.Optional = oOptional; } //Response switch (recipient.MeetingResponseStatus) { case OlResponseStatus.olResponseNone: if (MainForm.CompareAttribute("Attendee " + attendeeIdentifier + " - Response Status", SyncDirection.OutlookToGoogle, attendee.ResponseStatus, "needsAction", sb, ref itemModified)) { attendee.ResponseStatus = "needsAction"; } break; case OlResponseStatus.olResponseAccepted: if (MainForm.CompareAttribute("Attendee " + attendeeIdentifier + " - Response Status", SyncDirection.OutlookToGoogle, attendee.ResponseStatus, "accepted", sb, ref itemModified)) { attendee.ResponseStatus = "accepted"; } break; case OlResponseStatus.olResponseDeclined: if (MainForm.CompareAttribute("Attendee " + attendeeIdentifier + " - Response Status", SyncDirection.OutlookToGoogle, attendee.ResponseStatus, "declined", sb, ref itemModified)) { attendee.ResponseStatus = "declined"; } break; case OlResponseStatus.olResponseTentative: if (MainForm.CompareAttribute("Attendee " + attendeeIdentifier + " - Response Status", SyncDirection.OutlookToGoogle, attendee.ResponseStatus, "tentative", sb, ref itemModified)) { attendee.ResponseStatus = "tentative"; } break; } } } //each attendee if (!foundAttendee) { log.Fine("Attendee added: " + recipient.Name); sb.AppendLine("Attendee added: " + recipient.Name); if (ev.Attendees == null) ev.Attendees = new List<EventAttendee>(); ev.Attendees.Add(GoogleCalendar.CreateAttendee(recipient)); itemModified++; } } } //more than just 1 (me) recipients foreach (EventAttendee ea in removeAttendee) { log.Fine("Attendee removed: " + (ea.DisplayName ?? ea.Email), ea.Email); sb.AppendLine("Attendee removed: " + (ea.DisplayName ?? ea.Email)); ev.Attendees.Remove(ea); itemModified++; } return (itemModified > 0); }
private void GetExtendedProperties(AppointmentItem appointmentItem, Appointment app) { app.ExtendedProperties = new Dictionary<string, string>(); var userProperties = appointmentItem.UserProperties; try { if (userProperties != null) { foreach (UserProperty userProperty in userProperties) { if (userProperty != null && !app.ExtendedProperties.ContainsKey(userProperty.Name) && userProperty.Value != null) { app.ExtendedProperties.Add(userProperty.Name, userProperty.Value.ToString()); } } } } catch (Exception exception) { Logger.Error(exception); } finally { if (userProperties != null) { Marshal.FinalReleaseComObject(userProperties); } } }
private void processOutlookExceptions(AppointmentItem ai, Event ev, Boolean forceCompare) { if (!HasExceptions(ev, checkLocalCacheOnly: true)) return; if (!ai.Saved) ai.Save(); RecurrencePattern oPattern = ai.GetRecurrencePattern(); foreach (Event gExcp in Recurrence.Instance.googleExceptions.Where(exp => exp.RecurringEventId == ev.Id)) { log.Fine("Found Google exception for " + (gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date)); DateTime oExcpDate = DateTime.Parse(gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date); AppointmentItem newAiExcp = getOutlookInstance(oPattern, oExcpDate); if (newAiExcp == null) continue; if (gExcp.Status != "cancelled") { int itemModified = 0; newAiExcp = OutlookCalendar.Instance.UpdateCalendarEntry(newAiExcp, gExcp, ref itemModified, forceCompare); if (itemModified > 0) newAiExcp.Save(); } else { MainForm.Instance.Logboxout(OutlookCalendar.GetEventSummary(ai) +"\r\nDeleted."); newAiExcp.Delete(); } newAiExcp = (AppointmentItem)OutlookCalendar.ReleaseObject(newAiExcp); } if (!ai.Saved) ai.Save(); oPattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(oPattern); }
/// <summary> /// </summary> /// <param name="appointmentItem"></param> /// <param name="app"></param> private void GetRecipients(AppointmentItem appointmentItem, Appointment app) { foreach (Recipient attendee in appointmentItem.Recipients) { var recipient = new Attendee(); string name, email; if (attendee.GetEmailFromName(out name, out email)) { recipient.Name = name; recipient.Email = email; } else { recipient.Name = attendee.Name; recipient.Email = GetSMTPAddressForRecipients(attendee); } recipient.MeetingResponseStatus = attendee.GetMeetingResponseStatus(); if (appointmentItem.RequiredAttendees != null && appointmentItem.RequiredAttendees.Contains(recipient.Name)) { if (!app.RequiredAttendees.Any(reci => reci.Email.Equals(recipient.Email))) { app.RequiredAttendees.Add(recipient); } } if (appointmentItem.OptionalAttendees != null && appointmentItem.OptionalAttendees.Contains(recipient.Name)) { if (!app.OptionalAttendees.Any(reci => reci.Email.Equals(recipient.Email))) { app.OptionalAttendees.Add(recipient); } } if (appointmentItem.Organizer != null && appointmentItem.Organizer.Contains(recipient.Name)) { app.Organizer = recipient; } } }
public Event IANAtimezone_set(Event ev, AppointmentItem ai) { ev.Start.TimeZone = IANAtimezone(ai.StartTimeZone.ID, ai.StartTimeZone.Name); ev.End.TimeZone = IANAtimezone(ai.EndTimeZone.ID, ai.EndTimeZone.Name); return ev; }
public static Boolean HasExceptions(AppointmentItem ai) { return ai.GetRecurrencePattern().Exceptions.Count != 0; }
private Event createCalendarEntry(AppointmentItem ai) { string itemSummary = OutlookCalendar.GetEventSummary(ai); log.Debug("Processing >> " + itemSummary); MainForm.Instance.Logboxout(itemSummary, verbose: true); Event ev = new Event(); //Add the Outlook appointment ID into Google event AddOutlookID(ref ev, ai); ev.Start = new EventDateTime(); ev.End = new EventDateTime(); ev.Recurrence = Recurrence.Instance.BuildGooglePattern(ai, ev); if (ev.Recurrence != null) { ev = OutlookCalendar.Instance.IOutlook.IANAtimezone_set(ev, ai); } if (ai.AllDayEvent) { ev.Start.Date = ai.Start.ToString("yyyy-MM-dd"); ev.End.Date = ai.End.ToString("yyyy-MM-dd"); } else { ev.Start.DateTime = GoogleCalendar.GoogleTimeFrom(ai.Start); ev.End.DateTime = GoogleCalendar.GoogleTimeFrom(ai.End); } ev.Summary = Obfuscate.ApplyRegex(ai.Subject, SyncDirection.OutlookToGoogle); if (Settings.Instance.AddDescription) ev.Description = ai.Body; ev.Location = ai.Location; ev.Visibility = (ai.Sensitivity == OlSensitivity.olNormal) ? "default" : "private"; ev.Transparency = (ai.BusyStatus == OlBusyStatus.olFree) ? "transparent" : "opaque"; ev.Attendees = new List<EventAttendee>(); if (Settings.Instance.AddAttendees && ai.Recipients.Count > 1 && !APIlimitReached_attendee) { //Don't add attendees if there's only 1 (me) if (ai.Recipients.Count >= 200) { MainForm.Instance.Logboxout("ALERT: Attendees will not be synced for this meeting as it has " + "more than 200, which Google does not allow."); } else { foreach (Microsoft.Office.Interop.Outlook.Recipient recipient in ai.Recipients) { EventAttendee ea = GoogleCalendar.CreateAttendee(recipient); ev.Attendees.Add(ea); } } } //Reminder alert if (Settings.Instance.AddReminders) { ev.Reminders = new Event.RemindersData(); if (OutlookCalendar.Instance.IsOKtoSyncReminder(ai)) { if (ai.ReminderSet) { ev.Reminders.UseDefault = false; EventReminder reminder = new EventReminder(); reminder.Method = "popup"; reminder.Minutes = ai.ReminderMinutesBeforeStart; ev.Reminders.Overrides = new List<EventReminder>(); ev.Reminders.Overrides.Add(reminder); } else { ev.Reminders.UseDefault = Settings.Instance.UseGoogleDefaultReminder; } } else { ev.Reminders.UseDefault = false; } } return ev; }
public void BuildOutlookPattern(Event ev, AppointmentItem ai, out RecurrencePattern oPattern) { if (ev.Recurrence == null) { oPattern = null; return; } Dictionary<String, String> ruleBook = explodeRrule(ev.Recurrence); log.Fine("Building Outlook recurrence pattern"); oPattern = ai.GetRecurrencePattern(); #region RECURRENCE PATTERN //RRULE:FREQ=WEEKLY;UNTIL=20150906T000000Z;BYDAY=SA switch (ruleBook["FREQ"]) { case "DAILY": { oPattern.RecurrenceType = OlRecurrenceType.olRecursDaily; break; } case "WEEKLY": { oPattern.RecurrenceType = OlRecurrenceType.olRecursWeekly; // Need to work out dayMask from "BY" pattern // Eg "BYDAY=MO,TU,WE,TH,FR" OlDaysOfWeek dowMask = getDOWmask(ruleBook); if (dowMask != 0) { oPattern.DayOfWeekMask = dowMask; } break; } case "MONTHLY": { oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly; if (ruleBook.ContainsKey("BYSETPOS")) { oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth; int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]); oPattern.Instance = (gInstance == -1) ? 5 : gInstance; oPattern.DayOfWeekMask = getDOWmask(ruleBook); if (oPattern.DayOfWeekMask == (OlDaysOfWeek)127 && gInstance == -1 && DateTime.Parse(ev.Start.DateTime ?? ev.Start.Date).Day > 28) { //In Outlook this is simply a monthly recurring oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly; oPattern.DayOfWeekMask = 0; } } if (ruleBook.ContainsKey("BYDAY")) { if (ruleBook["BYDAY"].StartsWith("-1")) { oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth; oPattern.Instance = 5; oPattern.DayOfWeekMask = getDOWmask(ruleBook["BYDAY"].TrimStart("-1".ToCharArray())); } else if ("1,2,3,4".Contains(ruleBook["BYDAY"].Substring(0, 1))) { oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth; oPattern.Instance = Convert.ToInt16(ruleBook["BYDAY"].Substring(0, 1)); oPattern.DayOfWeekMask = getDOWmask(ruleBook["BYDAY"].TrimStart(oPattern.Instance.ToString().ToCharArray())); } } break; } case "YEARLY": { oPattern.RecurrenceType = OlRecurrenceType.olRecursYearly; //Google interval is years, Outlook is months if (ruleBook.ContainsKey("INTERVAL")) oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]) * 12; if (ruleBook.ContainsKey("BYSETPOS")) { oPattern.RecurrenceType = OlRecurrenceType.olRecursYearNth; int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]); oPattern.Instance = (gInstance == -1) ? 5 : gInstance; oPattern.DayOfWeekMask = getDOWmask(ruleBook); if (ruleBook.ContainsKey("BYMONTH")) { oPattern.MonthOfYear = Convert.ToInt16(ruleBook["BYMONTH"]); } } break; } } #endregion #region RANGE if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1 && ruleBook["FREQ"] != "YEARLY") oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]); if (ruleBook.ContainsKey("COUNT")) oPattern.Occurrences = Convert.ToInt16(ruleBook["COUNT"]); if (ruleBook.ContainsKey("UNTIL")) oPattern.PatternEndDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMddTHHmmssZ", System.Globalization.CultureInfo.InvariantCulture); #endregion ai = OutlookCalendar.Instance.IOutlook.WindowsTimeZone_set(ai, ev); }
public String GetGlobalApptID(AppointmentItem ai) { if (ai.GlobalAppointmentID == null) { log.Warn("GlobalAppointmentID is null - this shouldn't happen! Falling back to EntryID."); return ai.EntryID; } return ai.GlobalAppointmentID; }
public static string GetSenderEmailAddressOrNull (AppointmentItem source, IEntityMappingLogger logger, ILog generalLogger) { try { return source.GetPropertySafe (PR_SENDER_EMAIL_ADDRESS); } catch (COMException ex) { generalLogger.Warn ("Can't access property PR_SENDER_EMAIL_ADDRESS of appointment", ex); logger.LogMappingWarning ("Can't access property PR_SENDER_EMAIL_ADDRESS of appointment", ex); return null; } }
public static AddressEntry GetEventOrganizerOrNull (AppointmentItem source, IEntityMappingLogger logger, ILog generalLogger, int outlookMajorVersion) { try { if (outlookMajorVersion < 14) { // Microsoft recommends this way for Outlook 2007. May still work with Outlook 2010+ using (var propertyAccessor = GenericComObjectWrapper.Create (source.PropertyAccessor)) { string organizerEntryID = propertyAccessor.Inner.BinaryToString (propertyAccessor.Inner.GetProperty(PR_SENT_REPRESENTING_ENTRYID)); return Globals.ThisAddIn.Application.Session.GetAddressEntryFromID (organizerEntryID); } } else { // NB this works with Outlook 2010 but crashes with Outlook 2007 return source.GetOrganizer(); } } catch (COMException ex) { generalLogger.Warn ("Can't get organizer of appointment", ex); logger.LogMappingWarning ("Can't get organizer of appointment", ex); return null; } }