public override bool ShouldInclude(SearchContext context) { Func<SearchContext, string, bool> operatorDelegate; if (!sOperatorDelegates.TryGetValue(Name, out operatorDelegate)) throw new NotSupportedException(); return operatorDelegate(context, Argument); }
private static bool OperatorTag(SearchContext context, string argument) { return context.Task.Tags.Contains(argument, StringComparer.CurrentCultureIgnoreCase); }
private static bool OperatorStatus(SearchContext context, string argument) { if (string.Compare(argument, "completed", StringComparison.OrdinalIgnoreCase) == 0) return context.Task.IsCompleted; if (string.Compare(argument, "incomplete", StringComparison.OrdinalIgnoreCase) == 0) return context.Task.IsIncomplete; throw new ArgumentException(string.Format("The given status '{0}' is not valid. Should be 'completed' or 'incomplete'.", argument)); }
private static bool OperatorPriority(SearchContext context, string argument) { if (string.Compare(argument, "none", StringComparison.Ordinal) == 0) return context.Task.Priority == TaskPriority.None; if (argument == "1") return context.Task.Priority == TaskPriority.One; if (argument == "2") return context.Task.Priority == TaskPriority.Two; if (argument == "3") return context.Task.Priority == TaskPriority.Three; throw new ArgumentException(string.Format("The given priority '{0}' is not valid. Should be 'none', '1', '2' or '3'.", argument)); }
private static bool OperatorCompletedBefore(SearchContext context, string argument) { if (!context.Task.Completed.HasValue) return false; FuzzyDateTime dateTime = DateConverter.ParseDateTime(argument, context.DateFormat); FuzzyDateTime completed = new FuzzyDateTime(context.Task.Completed.Value, true); return completed <= dateTime; }
public void GetTasks(string listId, string filter, TaskArrayCallback callback) { if (SearchMode == SearchMode.LocalOnly || SearchMode == SearchMode.LocalAndRemote) { // Local search mode... use our client side parser for the query. if (!string.IsNullOrEmpty(filter)) { try { var lexicalAnalyzer = new Search.LexicalAnalyzer(); var tokens = lexicalAnalyzer.Tokenize(filter); var astRoot = lexicalAnalyzer.BuildAst(tokens); bool includeArchivedLists = astRoot.NeedsArchivedLists(); var resultTasks = new List<Task>(); var searchableTaskLists = GetSearchableTaskLists(includeArchivedLists); if (listId != RtmElement.UnsyncedId) searchableTaskLists = searchableTaskLists.Where(tl => tl.Id == listId); foreach (var list in searchableTaskLists) { foreach (var task in list.Tasks) { var context = new Search.SearchContext(task, UserSettings.DateFormat); if (astRoot.ShouldInclude(context)) resultTasks.Add(task); } } callback(resultTasks.ToArray()); return; } catch (Exception) { if (SearchMode == SearchMode.LocalAndRemote && Syncing) { // Log the error and move on to the remote search. //IronCowTraceSource.TraceSource.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, e.Message); //IronCowTraceSource.TraceSource.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0, "Due to previous error message, falling back to remote server query."); } else { throw; } } } } if (!Syncing) { callback(new Task[0]); return; } // If we get here, we need to perform a remote search. Dictionary<string, string> parameters = new Dictionary<string, string>(); if (listId != RtmElement.UnsyncedId) parameters["list_id"] = listId.ToString(); if (filter != null) parameters["filter"] = "(" + filter + ") AND status:Incomplete"; else parameters["filter"] = "status:Incomplete"; GetResponse("rtm.tasks.getList", parameters, (response) => { List<Task> tasks = new List<Task>(); foreach (var list in response.Tasks) { foreach (var series in list.TaskSeries) { foreach (var task in series.Tasks) { //Task newTask = taskList.Tasks.GetById(series.Id, task.Id, true); Task newTask = GetTask(task.Id); tasks.Add(newTask); } } } callback(tasks.ToArray()); }); }
private static bool OperatorAddedBefore(SearchContext context, string argument) { FuzzyDateTime dateTime = DateConverter.ParseDateTime(argument, context.DateFormat); FuzzyDateTime added = new FuzzyDateTime(context.Task.Added, true); return added <= dateTime; }
private static bool OperatorTo(SearchContext context, string argument) { throw new NotSupportedException("Operator 'to' is not supported on the client."); }
private static bool OperatorLocatedWithin(SearchContext context, string argument) { // TODO: implement location-based searches return false; }
private static bool OperatorList(SearchContext context, string argument) { if (context.Task.Parent == null) throw new InvalidOperationException(string.Format("The given task '{0}' doesn't belong to any task list.", context.Task.Name)); return (string.Compare(context.Task.Parent.Name, argument, StringComparison.OrdinalIgnoreCase) == 0); }
private static bool OperatorIsTagged(SearchContext context, string argument) { if (string.Compare(argument, "true", StringComparison.OrdinalIgnoreCase) == 0) return context.Task.Tags.Count > 0; if (string.Compare(argument, "false", StringComparison.OrdinalIgnoreCase) == 0) return context.Task.Tags.Count == 0; throw new ArgumentException(string.Format("The given tagged status '{0}' is invalid. Should be 'true' or 'false'.", argument)); }
private static bool OperatorIsRepeating(SearchContext context, string argument) { if (string.Compare(argument, "true", StringComparison.OrdinalIgnoreCase) == 0) return !string.IsNullOrEmpty(context.Task.Recurrence); if (string.Compare(argument, "false", StringComparison.OrdinalIgnoreCase) == 0) return string.IsNullOrEmpty(context.Task.Recurrence); throw new ArgumentException(string.Format("The given repeating status '{0}' is invalid. Should be 'true' or 'false'.", argument)); }
private static bool OperatorIncludeArchived(SearchContext context, string argument) { // Do nothing... return true; }
private static bool OperatorDueWithin(SearchContext context, string argument) { if (!context.Task.DueDateTime.HasValue) return false; FuzzyDateTime dateTime = DateConverter.ParseDateTime(argument, context.DateFormat); return (context.Task.FuzzyDueDateTime >= FuzzyDateTime.Today && context.Task.FuzzyDueDateTime <= dateTime); }
private static bool OperatorDue(SearchContext context, string argument) { if (Regex.IsMatch(argument, @"\s*never\s*$", RegexOptions.IgnoreCase)) return !context.Task.DueDateTime.HasValue; if (!context.Task.DueDateTime.HasValue) return false; FuzzyDateTime dateTime = DateConverter.ParseDateTime(argument, context.DateFormat); return (context.Task.FuzzyDueDateTime == dateTime); }
private static bool OperatorTagContains(SearchContext context, string argument) { argument = argument.ToLower(); foreach (var tag in context.Task.Tags) { if (tag.ToLower().Contains(argument)) return true; } return false; }
private static bool OperatorTimeEstimate(SearchContext context, string argument) { if (string.IsNullOrEmpty(context.Task.Estimate)) return false; Match match = Regex.Match(argument, @"^\s*(?<comparison>\<|\>)(?<time>.*)$"); if (!match.Success) throw new ArgumentException(); TimeSpan timeSpan = DateConverter.GetTimeSpan(match.Groups["time"].Value); TimeSpan estimate = DateConverter.GetTimeSpan(context.Task.Estimate); if (match.Groups["comparison"].Success) { if (match.Groups["comparison"].Value == "<") return estimate <= timeSpan; else return estimate >= timeSpan; } else { return timeSpan == estimate; } }
private static bool OperatorLocation(SearchContext context, string argument) { return (context.Task.Location != null) && (string.Compare(context.Task.Location.Name, argument, StringComparison.OrdinalIgnoreCase) == 0); }
private static bool OperatorName(SearchContext context, string argument) { return context.Task.Name.ToLower().Contains(argument.ToLower()); }
private static bool OperatorNoteContains(SearchContext context, string argument) { argument = argument.ToLower(); foreach (var note in context.Task.Notes) { if (note.Title.ToLower().Contains(argument)) return true; if (note.Body.ToLower().Contains(argument)) return true; } return false; }
private static bool OperatorAddedWithin(SearchContext context, string argument) { FuzzyDateTime dateTime = DateConverter.ParseDateTime(argument, context.DateFormat); DateTime added = context.Task.Added; if (dateTime.HasTime) { // Make the date be backwards ("1 week of today" is not "within 1 week" but // "within the past week" in this context). TimeSpan timeSpan = dateTime.DateTime - DateTime.Now; DateTime after = DateTime.Now.Subtract(timeSpan); return added >= after && added <= DateTime.Now; } else { // Make the date be backwards ("1 week of today" is not "within 1 week" but // "within the past week" in this context). TimeSpan timeSpan = dateTime.DateTime - DateTime.Today; DateTime after = DateTime.Today.Subtract(timeSpan); return added >= after && added <= DateTime.Today; } }
private static bool OperatorPostponed(SearchContext context, string argument) { Match match = Regex.Match(argument, @"^\s*(?<comparison>\<|\>)(?<num>\d+)$"); if (!match.Success) throw new ArgumentException(string.Format("The given number of times postponed '{0}' is invalid, or has an invalid comparison operator ('>' or '<').", argument)); int num = int.Parse(match.Groups["num"].Value); int timesPostponed = context.Task.Postponed; if (match.Groups["comparison"].Success) { if (match.Groups["comparison"].Value == "<") return timesPostponed <= num; else return timesPostponed >= num; } else { return timesPostponed == num; } }
public List<Task> SearchTasksLocally(string filter) { try { var lexicalAnalyzer = new Search.LexicalAnalyzer(); var tokens = lexicalAnalyzer.Tokenize(filter); var astRoot = lexicalAnalyzer.BuildAst(tokens); bool includeArchivedLists = astRoot.NeedsArchivedLists(); var resultTasks = new List<Task>(); var searchableTaskLists = GetSearchableTaskLists(includeArchivedLists); foreach (var list in searchableTaskLists) { if (list.Tasks != null) { foreach (var task in list.Tasks) { var context = new Search.SearchContext(task, DateFormat.Default); if (astRoot.ShouldInclude(context)) resultTasks.Add(task); } } } return resultTasks; } catch (Exception e) { // if there was an exception parsing the filter, // just return an empty list and silently fail the search return new List<Task>(); } }
public override bool ShouldInclude(SearchContext context) { return context.Task.Name.ToLower().Contains(Term.ToLower()); }