private void SetUIforPrimary() { OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod()); //since we are in the process of flipping from secondary to primary //we know that the UI is currently in Secondary mode (or first run) //so HTML controls have the Secondary messages //disable PermaOOF by setting date to time in the past OOFData.Instance.PermaOOFDate = DateTime.Now.AddMinutes(-1); primaryToolStripMenuItem.Checked = true; secondaryToolStripMenuItem.Checked = !primaryToolStripMenuItem.Checked; lblExternalMesage.Text = "Primary External Message"; lblInternalMessage.Text = "Primary Internal Message"; htmlEditorControl1.BodyHtml = OOFData.Instance.PrimaryOOFExternalMessage; htmlEditorControl2.BodyHtml = OOFData.Instance.PrimaryOOFInternalMessage; //lastly, disable the permaOOF controls to help with some UI flow issues btnPermaOOF.Enabled = false; dtPermaOOF.Enabled = false; dtPermaOOF.Value = DateTime.Now; OOFSponderInsights.Track("Configured for primary"); }
private void SetUIforSecondary() { OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod()); primaryToolStripMenuItem.Checked = false; secondaryToolStripMenuItem.Checked = !primaryToolStripMenuItem.Checked; lblExternalMesage.Text = "Extended OOF External Message"; lblInternalMessage.Text = "Extended OOF Internal Message"; htmlEditorControl1.BodyHtml = OOFData.Instance.SecondaryOOFExternalMessage; htmlEditorControl2.BodyHtml = OOFData.Instance.SecondaryOOFInternalMessage; //update the UI if (OOFData.Instance.IsPermaOOFOn) { btnPermaOOF.Text = "Disable Extended OOF"; btnPermaOOF.Tag = "Disable"; dtPermaOOF.Enabled = false; } else { btnPermaOOF.Text = "Enable Extended OOF"; btnPermaOOF.Tag = "Enable"; dtPermaOOF.Value = DateTime.Now.AddDays(1); dtPermaOOF.Enabled = true; } //lastly, enable the permaOOF controls to help with some UI flow issues btnPermaOOF.Enabled = true; OOFSponderInsights.Track("Configured for secondary"); }
private async void btnPermaOOF_Click(object sender, EventArgs e) { OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod()); //bail if permaOOF not in the future if (DateTime.Now >= dtPermaOOF.Value) { MessageBox.Show("You must pick a date in future", "OOFSponder", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //only set up for permaOOF if we have OOF messages if (OOFData.Instance.SecondaryOOFExternalMessage == String.Empty | OOFData.Instance.SecondaryOOFInternalMessage == String.Empty) { MessageBox.Show("Unable to turn on extended OOF - Secondary OOF messages not set", "OOFSponder", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } bool result = false; if (((Button)sender).Tag.ToString() == "Enable") { OOFData.Instance.PermaOOFDate = dtPermaOOF.Value; } else { OOFData.Instance.PermaOOFDate = DateTime.Now; } //actually go OOF now result = await RunSetOofO365(); if (result) { if (((Button)sender).Tag.ToString() == "Enable") { OOFSponderInsights.Track("Enabled PermaOOF"); } else { OOFSponderInsights.Track("Disabled PermaOOF"); } } else { //if we fail to set OOF, disable PermaOOF to reset the UI OOFData.Instance.PermaOOFDate = DateTime.Now; } SetUIforSecondary(); }
//common call for both controls, regardless of primary or secondary private void htmlEditorValidated(object sender, EventArgs e) { if (radPrimary.Checked) { OOFSponderInsights.Track("PermaOOF off - persisting primary messages"); OOFData.Instance.PrimaryOOFExternalMessage = htmlEditorControl1.BodyHtml; OOFData.Instance.PrimaryOOFInternalMessage = htmlEditorControl2.BodyHtml; } else { OOFSponderInsights.Track("PermaOOF on - persisting secondary messages"); OOFData.Instance.SecondaryOOFExternalMessage = htmlEditorControl1.BodyHtml; OOFData.Instance.SecondaryOOFInternalMessage = htmlEditorControl2.BodyHtml; } }
public async System.Threading.Tasks.Task <bool> TrySetOOF365(string oofMessageExternal, string oofMessageInternal, DateTime StartTime, DateTime EndTime) { OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod()); toolStripStatusLabel1.Text = DateTime.Now.ToString() + " - Sending to O365"; //need to convert the times from local datetime to DateTimeTimeZone and UTC DateTimeTimeZone oofStart = new DateTimeTimeZone { DateTime = StartTime.ToUniversalTime().ToString("u").Replace("Z", ""), TimeZone = "UTC" }; DateTimeTimeZone oofEnd = new DateTimeTimeZone { DateTime = EndTime.ToUniversalTime().ToString("u").Replace("Z", ""), TimeZone = "UTC" }; //create local OOF object AutomaticRepliesSetting localOOF = new AutomaticRepliesSetting(); localOOF.ExternalReplyMessage = oofMessageExternal; localOOF.InternalReplyMessage = oofMessageInternal; localOOF.ScheduledStartDateTime = oofStart; localOOF.ScheduledEndDateTime = oofEnd; localOOF.Status = AutomaticRepliesStatus.Scheduled; try { OOFSponderInsights.Track("Getting OOF settings from O365"); string getOOFraw = await O365.GetHttpContentWithToken(O365.AutomatedReplySettingsURL); AutomaticRepliesSetting remoteOOF = JsonConvert.DeserializeObject <AutomaticRepliesSetting>(getOOFraw); OOFSponderInsights.Track("Successfully got OOF settings"); bool externalReplyMessageEqual = remoteOOF.ExternalReplyMessage.CleanReplyMessage() == localOOF.ExternalReplyMessage.CleanReplyMessage(); bool internalReplyMessageEqual = remoteOOF.InternalReplyMessage.CleanReplyMessage() == localOOF.InternalReplyMessage.CleanReplyMessage(); //local and remote are both UTC, so just compare times //Not sure it can ever happen to have the DateTime empty, but wrap this in a TryCatch just in case //set both to false - that way, we don't care if either one blows up //because if one is false, the overall evaluation is false anyway bool scheduledStartDateTimeEqual = false; bool scheduledEndDateTimeEqual = false; try { scheduledStartDateTimeEqual = DateTime.Parse(remoteOOF.ScheduledStartDateTime.DateTime) == DateTime.Parse(localOOF.ScheduledStartDateTime.DateTime); scheduledEndDateTimeEqual = DateTime.Parse(remoteOOF.ScheduledEndDateTime.DateTime) == DateTime.Parse(localOOF.ScheduledEndDateTime.DateTime); } catch (Exception) { //do nothing because we will just take the initialized false values; } if (!externalReplyMessageEqual || !internalReplyMessageEqual || !scheduledStartDateTimeEqual || !scheduledEndDateTimeEqual ) { OOFSponderInsights.Track("Local OOF doesn't match remote OOF"); System.Net.Http.HttpResponseMessage result = await O365.PatchHttpContentWithToken(O365.MailboxSettingsURL, localOOF); if (result.StatusCode == System.Net.HttpStatusCode.OK) { UpdateStatusLabel(toolStripStatusLabel1, DateTime.Now.ToString() + " - OOF message set - Start: " + StartTime + " - End: " + EndTime); //report back to AppInsights OOFSponderInsights.Track("Successfully set OOF"); return(true); } else { OOFSponderInsights.Track("Unable to set OOF"); UpdateStatusLabel(toolStripStatusLabel1, DateTime.Now.ToString() + " - Unable to set OOF message"); return(false); } } else { OOFSponderInsights.Track("Remote OOF matches - no changes"); UpdateStatusLabel(toolStripStatusLabel1, DateTime.Now.ToString() + " - No changes needed, OOF Message not changed - Start: " + StartTime + " - End: " + EndTime); return(true); } } catch (Exception ex) { notifyIcon1.ShowBalloonTip(100, "OOF Exception", "Unable to set OOF: " + ex.Message, ToolTipIcon.Error); UpdateStatusLabel(toolStripStatusLabel1, DateTime.Now.ToString() + " - Unable to set OOF"); OOFSponderInsights.TrackException("Unable to set OOF: " + ex.Message, ex); return(false); } }
private async System.Threading.Tasks.Task <bool> RunSetOofO365() { OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod()); bool haveNecessaryData = false; //if CredMan is turned on, then we don't need the email or password //but we still need the OOF messages and working hours //also, don't need to check SecondaryOOF messages for two reasons: //1) they won't always be set //2) the UI flow won't let you get here with permaOOF if they aren't set if (OOFData.Instance.PrimaryOOFExternalMessage != "" && OOFData.Instance.PrimaryOOFInternalMessage != "" && OOFData.Instance.WorkingHours != "") { haveNecessaryData = true; OOFSponderInsights.Track("HaveNecessaryData"); } bool result = false; if (haveNecessaryData) { DateTime[] oofTimes = getOofTime(OOFData.Instance.WorkingHours); ////if PermaOOF is turned on, need to adjust the end time //if (OOFData.Instance.PermaOOFDate < oofTimes[0]) //{ // //set all the UI stuff back to primary // //to set up for normal OOF schedule // SetUIforPrimary(); //} //persist settings just in case string oofMessageExternal = htmlEditorControl1.BodyHtml; string oofMessageInternal = htmlEditorControl2.BodyHtml; //if (!OOFData.Instance.IsPermaOOFOn) //{ // OOFData.Instance.PrimaryOOFExternalMessage = htmlEditorControl1.BodyHtml; // OOFData.Instance.PrimaryOOFInternalMessage = htmlEditorControl2.BodyHtml; //} //else //{ // OOFData.Instance.SecondaryOOFExternalMessage = htmlEditorControl1.BodyHtml; // OOFData.Instance.SecondaryOOFInternalMessage = htmlEditorControl2.BodyHtml; //} //if PermaOOF isn't turned on, use the standard logic based on the stored schedule if ((oofTimes[0] != oofTimes[1]) && !OOFData.Instance.IsPermaOOFOn) { OOFSponderInsights.Track("TrySetNormalOOF"); #if !NOOOF result = await System.Threading.Tasks.Task.Run(() => TrySetOOF365(oofMessageExternal, oofMessageInternal, oofTimes[0], oofTimes[1])); #else result = true; #endif } else //since permaOOF is on, need to adjust the end date such that is permaOOFDate //if permaOOF>oofTimes[0] and permaOOF<oofTimes[1], then AddDays((permaOOFDate - oofTimes[1]).Days //due to the way the math works out, need to add extra day if permaOOF>oofTimes[1] { int adjustmentDays = 0; if (OOFData.Instance.PermaOOFDate > oofTimes[0] && OOFData.Instance.PermaOOFDate < oofTimes[1]) { adjustmentDays = 1; } //in order to accomodate someone going OOF mid-schedule //check if now is before the next scheduled "OFF" slot //if it is, then adjust start time to NOW if (oofTimes[0] > DateTime.Now) { oofTimes[0] = DateTime.Now; } OOFSponderInsights.Track("TrySetPermaOOF"); #if !NOOOF result = await System.Threading.Tasks.Task.Run(() => TrySetOOF365(oofMessageExternal, oofMessageInternal, oofTimes[0], oofTimes[1].AddDays((OOFData.Instance.PermaOOFDate - oofTimes[1]).Days + adjustmentDays))); #else result = true; #endif } } return(result); }
public Form1() { OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod()); InitializeComponent(); #region SetBuildInfo foreach (Assembly a in Thread.GetDomain().GetAssemblies()) { if (a.GetName().Name == "OOFScheduling") { OOFData.version = lblBuild.Text = a.GetName().Version.ToString(); break; } } #endregion OOFSponderInsights.ConfigureApplicationInsights(); OOFSponderInsights.Track("OOFSponderStart"); //Set icon in code this.Icon = Properties.Resources.OOFSponderIcon; #region Add to Startup // The path to the key where Windows looks for startup applications RegistryKey rkApp = Registry.CurrentUser.OpenSubKey( @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); //Path to launch shortcut string startPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs) + @"\Microsoft\OOFSponder.appref-ms"; rkApp.SetValue("OOFSponder", startPath); #endregion #region Tray Menu Initialize // Create a simple tray menu with only one item. trayMenu = new ContextMenu(); trayMenu.MenuItems.Add("Exit", OnExit); // Add menu to tray icon and show it. notifyIcon1.ContextMenu = trayMenu; notifyIcon1.Icon = Properties.Resources.OOFSponderIcon; #endregion #region Read the list of teams to populate with templates //Read in the list of teams and build the dictionary list of team name //and template location //for each team, add an entry to the the Team Settings menu item (teamSettingsToolStripMenuItem) //If Use Team Settings is checked and a team is selected //then pull the remote files in as the text and then set the //controls to ReadOnly //Use a naming convention of "ExternalOOF.html" and "InternalOOF.html"? //Will also need to add some #Start/#End/#TimeZone logic //could even get fancy and have that be some sort of pop-up //so that each team could have its own //this is definitely future work :) #endregion //prep for async work System.Threading.Tasks.Task AuthTask = null; AuthTask = System.Threading.Tasks.Task.Run((Action)(() => { O365.MSALWork(O365.AADAction.SignIn); })); #if DEBUGFLOW MessageBox.Show("Attach now", "OOFSponder", MessageBoxButtons.OK); #endif if (OOFData.Instance.IsPermaOOFOn) { SetUIforSecondary(); } else { SetUIforPrimary(); } if (OOFData.Instance.WorkingHours != "") { string[] workingHours = OOFData.Instance.WorkingHours.Split('|'); //Zero means you are off that day (not working) therefore the box is checked string[] dayHours = workingHours[0].Split('~'); if (dayHours[2] == "0") { sundayOffWorkCB.Checked = true; } else { sundayOffWorkCB.Checked = false; } sundayStartTimepicker.Value = DateTime.Parse(dayHours[0]); sundayEndTimepicker.Value = DateTime.Parse(dayHours[1]); dayHours = workingHours[1].Split('~'); if (dayHours[2] == "0") { mondayOffWorkCB.Checked = true; } else { mondayOffWorkCB.Checked = false; } mondayStartTimepicker.Value = DateTime.Parse(dayHours[0]); mondayEndTimepicker.Value = DateTime.Parse(dayHours[1]); dayHours = workingHours[2].Split('~'); if (dayHours[2] == "0") { tuesdayOffWorkCB.Checked = true; } else { tuesdayOffWorkCB.Checked = false; } tuesdayStartTimepicker.Value = DateTime.Parse(dayHours[0]); tuesdayEndTimepicker.Value = DateTime.Parse(dayHours[1]); dayHours = workingHours[3].Split('~'); if (dayHours[2] == "0") { wednesdayOffWorkCB.Checked = true; } else { wednesdayOffWorkCB.Checked = false; } wednesdayStartTimepicker.Value = DateTime.Parse(dayHours[0]); wednesdayEndTimepicker.Value = DateTime.Parse(dayHours[1]); dayHours = workingHours[4].Split('~'); if (dayHours[2] == "0") { thursdayOffWorkCB.Checked = true; } else { thursdayOffWorkCB.Checked = false; } thursdayStartTimepicker.Value = DateTime.Parse(dayHours[0]); thursdayEndTimepicker.Value = DateTime.Parse(dayHours[1]); dayHours = workingHours[5].Split('~'); if (dayHours[2] == "0") { fridayOffWorkCB.Checked = true; } else { fridayOffWorkCB.Checked = false; } fridayStartTimepicker.Value = DateTime.Parse(dayHours[0]); fridayEndTimepicker.Value = DateTime.Parse(dayHours[1]); dayHours = workingHours[6].Split('~'); if (dayHours[2] == "0") { saturdayOffWorkCB.Checked = true; } else { saturdayOffWorkCB.Checked = false; } saturdayStartTimepicker.Value = DateTime.Parse(dayHours[0]); saturdayEndTimepicker.Value = DateTime.Parse(dayHours[1]); } bool haveNecessaryData = false; //we need the OOF messages and working hours if (OOFData.Instance.PrimaryOOFExternalMessage != "" && OOFData.Instance.PrimaryOOFInternalMessage != "" && OOFData.Instance.WorkingHours != "") { haveNecessaryData = true; } if (haveNecessaryData) { toolStripStatusLabel1.Text = "Ready"; OOFSponderInsights.TrackInfo("HaveNecessaryData"); } else { toolStripStatusLabel1.Text = "Please setup OOFsponder"; OOFSponderInsights.TrackInfo("MissingData"); } toolStripStatusLabel2.Text = ""; Loopy(); //set up handlers to persist OOF messages htmlEditorControl1.Validated += htmlEditorValidated; htmlEditorControl2.Validated += htmlEditorValidated; //wait on async auth stuff if not null if (AuthTask != null) { AuthTask.Wait(); } //trigger a check on current status System.Threading.Tasks.Task.Run(() => RunSetOofO365()); radPrimary.CheckedChanged += new System.EventHandler(radPrimary_CheckedChanged); fileToolStripMenuItem.DropDownOpening += fileToolStripMenuItem_DropDownOpening; }