internal static void ReportDiagnostics(ILogger logger) { using (var one = new OneNote(out var page, out var ns)) { logger.WriteLine(); logger.WriteLine($"Reminders on current page ({page.Title})"); var reminders = new ReminderSerializer().LoadReminders(page); foreach (var reminder in reminders) { var subject = reminder.Subject; if (subject.Length > 40) { subject = subject.Substring(0, 38); } var start = reminder.Start.ToLocalTime().ToString(); var due = reminder.Due.ToLocalTime().ToString(); var anyOid = page.Root.Descendants(ns + "OE") .Any(e => e.Attribute("objectID").Value == reminder.ObjectId); var orphan = anyOid ? String.Empty : "(orphaned) "; logger.WriteLine($"- start:{start,22} due:{due,22} {orphan}\"{subject}\""); } } }
private async Task Scan() { using (var one = new OneNote()) { var hierarchy = await one.SearchMeta(string.Empty, MetaNames.Reminder); if (hierarchy == null) { // may need to restart OneNote return; } var ns = hierarchy.GetNamespaceOfPrefix(OneNote.Prefix); var metas = hierarchy.Descendants(ns + "Meta").Where(e => e.Attribute("name").Value == MetaNames.Reminder && e.Attribute("content").Value.Length > 0); if (!metas.Any()) { return; } var serializer = new ReminderSerializer(); foreach (var meta in metas) { var reminders = serializer.DecodeContent(meta.Attribute("content").Value); var pageID = meta.Parent.Attribute("ID").Value; foreach (var reminder in reminders) { if (reminder.Silent) { continue; } if (reminder.Snooze != SnoozeRange.None && DateTime.UtcNow.CompareTo(reminder.SnoozeTime) < 0) { continue; } if (RemindScheduler.WaitingOn(reminder)) { continue; } await Test(reminder, pageID, one); } } } }
// if the user deletes the paragraph containing a reminder, the Meta will be orphaned // so this verifies that the paragraph still exists and clears the Meta if it does not private async Task <bool> ReminderIsValid(Reminder reminder, string pageID, OneNote one) { var page = one.GetPage(pageID, OneNote.PageDetail.Basic); if (page == null) { // must be an error? logger.WriteLine($"reminder page not found {pageID}"); return(false); } if (page.Root.Descendants(page.Namespace + "OE") .Any(e => e.Attribute("objectID").Value == reminder.ObjectId)) { // reminder is valid, keep it! return(true); } // clear the orphaned reminder... var serializer = new ReminderSerializer(); var reminders = serializer.LoadReminders(page); if (!reminders.Any()) { // must be an error? logger.WriteLine($"reminder not found on page {pageID}"); return(false); } var orphan = reminders.FirstOrDefault(r => r.ObjectId == reminder.ObjectId); if (orphan == null) { // must be an error? logger.WriteLine($"reminder not found in page meta {pageID}"); return(false); } reminders.Remove(orphan); page.SetMeta(MetaNames.Reminder, serializer.EncodeContent(reminders)); await one.Update(page); return(false); }
public override async Task Execute(params object[] args) { using (var one = new OneNote(out var page, out var ns)) { var tags = page.Root.Elements(ns + "Outline").Descendants(ns + "Tag").ToList(); if (!tags.Any()) { return; } var updated = false; var reminders = new ReminderSerializer().LoadReminders(page); var tagdefs = page.GetTagDefMap().Select(m => m.TagDef); foreach (var tag in tags) { // lookup the tagdef to cross-reference symbol var tagdef = tagdefs .FirstOrDefault(m => m.Index == tag.Attribute("index").Value); if (tagdef != null) { var objectId = tag.Parent.Attribute("objectID").Value; // ensure tag is not a reminder for its paragraph if (!reminders.Any(r => r.Symbol == tagdef.Symbol && r.ObjectId == objectId)) { tag.Remove(); updated = true; } } } if (updated) { await one.Update(page); } } }
public override async Task Execute(params object[] args) { using (var one = new OneNote(out var page, out var ns)) { var paragraph = page.Root.Descendants(ns + "T") .Where(e => e.Attribute("selected")?.Value == "all") .Select(e => e.Parent) .FirstOrDefault(); if (paragraph == null) { UIHelper.ShowInfo(one.Window, Resx.RemindCommand_noContext); return; } var serializer = new ReminderSerializer(); var reminders = serializer.LoadReminders(page); if (!reminders.Any()) { UIHelper.ShowError(one.Window, Resx.RemindCommand_noReminder); return; } var objectID = paragraph.Attribute("objectID").Value; var reminder = reminders.FirstOrDefault(r => r.ObjectId == objectID); if (reminder == null) { UIHelper.ShowError(one.Window, Resx.RemindCommand_noReminder); return; } XElement tag = null; if (!string.IsNullOrEmpty(reminder.Symbol) && reminder.Symbol != "0") { reminder.TagIndex = page.GetTagDefIndex(reminder.Symbol); if (reminder.TagIndex != null) { // confirm tag still exists tag = paragraph.Elements(ns + "Tag") .FirstOrDefault(e => e.Attribute("index").Value == reminder.TagIndex); } } if (tag == null) { reminders.Remove(reminder); page.SetMeta(MetaNames.Reminder, serializer.EncodeContent(reminders)); await one.Update(page); UIHelper.ShowError(one.Window, Resx.RemindCommand_noReminder); return; } // complete the reminder... reminder.Status = ReminderStatus.Completed; reminder.Percent = 100; reminder.Completed = DateTime.UtcNow; serializer.StoreReminder(page, reminder); tag.Attribute("completed").Value = "true"; tag.SetAttributeValue("completionDate", reminder.Completed.ToString(dateFormat)); await one.Update(page); } }
private Reminder GetReminder(XElement paragraph) { Reminder reminder; XElement tag; var objectID = paragraph.Attribute("objectID").Value; var reminders = new ReminderSerializer().LoadReminders(page); if (reminders.Any()) { reminder = reminders.FirstOrDefault(r => r.ObjectId == objectID); if (reminder != null && !string.IsNullOrEmpty(reminder.Symbol) && reminder.Symbol != "0") { // check tag still exists var index = page.GetTagDefIndex(reminder.Symbol); if (index != null) { tag = paragraph.Elements(ns + "Tag") .FirstOrDefault(e => e.Attribute("index").Value == index); if (tag != null) { // synchronize reminder with tag if (tag.Attribute("completed").Value == "true" && reminder.Status != ReminderStatus.Completed) { reminder.Status = ReminderStatus.Completed; reminder.Percent = 100; reminder.Completed = DateTime.Parse(tag.Attribute("completionDate").Value); } return(reminder); } } } } // either no meta or meta is orphaned from its tag so create a new one... var text = paragraph.Value; // get only raw text without <span> et al. This direct pattern match feels risky but // it seems to work for Unicode strings like Chinese whereas XElement.Parse will fail text = Regex.Replace(text, "<[^>]+>", string.Empty); if (text.Length > 40) { text = text.Substring(0, 40) + "..."; } reminder = new Reminder(objectID) { Subject = text }; tag = paragraph.Elements(ns + "Tag").FirstOrDefault(); if (tag != null) { // use existing tag on paragraph, synchronize reminder with this tag reminder.TagIndex = tag.Attribute("index").Value; reminder.Symbol = page.GetTagDefSymbol(reminder.TagIndex); reminder.Created = DateTime.Parse(tag.Attribute("creationDate").Value); var completionDate = tag.Attribute("creationDate"); if (completionDate != null) { reminder.Completed = DateTime.Parse(completionDate.Value); } } else { // use default symbol // if dialog is cancelled, OneNote will clean up the unused TagDef reminder.TagIndex = page.AddTagDef(reminder.Symbol, string.Format(Resx.RemindCommand_nameFormat, reminder.Due.ToFriendlyString())); } return(reminder); }
public override async Task Execute(params object[] args) { using (var one = new OneNote(out var page, out var ns)) { var paragraph = page.Root.Descendants(ns + "T") .Where(e => e.Attribute("selected")?.Value == "all") .Select(e => e.Parent) .FirstOrDefault(); if (paragraph == null) { UIHelper.ShowInfo(one.Window, Resx.RemindCommand_noContext); return; } var serializer = new ReminderSerializer(); var reminders = serializer.LoadReminders(page); if (!reminders.Any()) { UIHelper.ShowError(one.Window, Resx.RemindCommand_noReminder); return; } var objectID = paragraph.Attribute("objectID").Value; var reminder = reminders.FirstOrDefault(r => r.ObjectId == objectID); if (reminder == null) { UIHelper.ShowError(one.Window, Resx.RemindCommand_noReminder); return; } XElement tag = null; if (!string.IsNullOrEmpty(reminder.Symbol) && reminder.Symbol != "0") { reminder.TagIndex = page.GetTagDefIndex(reminder.Symbol); if (reminder.TagIndex != null) { // confirm tag still exists tag = paragraph.Elements(ns + "Tag") .FirstOrDefault(e => e.Attribute("index").Value == reminder.TagIndex); } } if (tag == null) { reminders.Remove(reminder); page.SetMeta(MetaNames.Reminder, serializer.EncodeContent(reminders)); await one.Update(page); UIHelper.ShowError(one.Window, Resx.RemindCommand_noReminder); return; } var result = UIHelper.ShowQuestion( Resx.DeleteReminderCommand_deleteTag, canCancel: true); if (result == DialogResult.Cancel) { return; } if (result == DialogResult.Yes) { tag.Remove(); } reminders.Remove(reminder); page.SetMeta(MetaNames.Reminder, serializer.EncodeContent(reminders)); await one.Update(page); } }