public static MessagesModel Get(SearchModel search) { var output = new MessagesModel(); var channelName = search.ChannelId == 0 ? ChannelHelper.GetById(1) : ChannelHelper.GetById(search.ChannelId); var networkName = "irc.afternet.org"; var prevFromDate = search.FromDate; var prevToDate = search.ToDate; search.FromDate = search.FromDate ?? DateTime.Now.AddMinutes(-15); search.ToDate = search.ToDate ?? DateTime.Now.AddMinutes(15); var lines = FastLogReader.ReadAllLines(networkName, channelName, search.FromDate.Value, search.ToDate.Value); Process(output, Filter(lines, search, output)); search.FromDate = prevFromDate; search.ToDate = prevToDate; return output; }
private static IEnumerable<FastLogReader.Line> Filter(IEnumerable<FastLogReader.Line> lines, SearchModel search, MessagesModel output) { var regexOptions = RegexOptions.Compiled | (search.IsCaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase); Func<string, Regex> buildStringMatcherFor = input => { if (String.IsNullOrEmpty(input)) return null; switch (search.MatchType) { case MatchTypes.PlainText: return new Regex(Regex.Escape(input), regexOptions); case MatchTypes.Wildcard: return new Regex("^" + Regex.Escape(input).Replace(@"\*", "(.*)").Replace(@"\?", ".") + "$", regexOptions); case MatchTypes.Regex: return new Regex(input, regexOptions); default: goto case MatchTypes.PlainText; } }; var nickMatcher = buildStringMatcherFor(search.Nickname); var userMatcher = buildStringMatcherFor(search.Username); var hostMatcher = buildStringMatcherFor(search.Hostname); var msgMatcher = buildStringMatcherFor(search.Message); Func<FastLogReader.Line, bool> isDirectLineMatch = line => { if (line.When < search.FromDate || line.When > search.ToDate) return false; if (nickMatcher != null && !nickMatcher.IsMatch(line.Nick ?? String.Empty)) return false; if (userMatcher != null && !userMatcher.IsMatch(line.User ?? String.Empty)) return false; if (hostMatcher != null && !hostMatcher.IsMatch(line.Host ?? String.Empty)) return false; if (msgMatcher != null && !msgMatcher.IsMatch(line.Message ?? String.Empty)) return false; return true; }; uint postContextCount = 0; var queue = new FixedLengthQueue<FastLogReader.Line>(search.Context == 0 ? 1 : search.Context); foreach (var line in lines) { // NOTE: The order of these if-statements matters. output.LinesSearched++; if (isDirectLineMatch(line)) { output.LinesMatching++; // We have a match, but we also have some outstanding context lines to // print prior to this one, so do that now. if (search.Context != 0) { while (queue.Count != 0) { output.LinesDisplaying++; yield return queue.Dequeue(); } postContextCount = search.Context; } } // Not a match, but we have some trailing lines to print, so do that. else if (postContextCount != 0) { postContextCount--; } // Not a match, not even a trailing line. Candidate for a pre-context line. Queue it. else if (search.Context != 0) { queue.Enqueue(line); continue; } // Not a context-dependant search, so drop it. else { continue; } // Fallthrough, print a direct match or one of the current trailing lines. output.LinesDisplaying++; yield return line; } }
public static MvcHtmlString RenderHeading(this HtmlHelper helper, SearchModel search) { return new MvcHtmlString("<h2>Scouring through " + ChannelHelper.GetById(search.ChannelId) + "...</h2>"); }