protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { if (this.LeftChildNode.GetValue(rc, forceMatch) == null || this.RightChildNode.GetValue(rc, forceMatch) == null) { return(null); } switch (this.Operator) { case "==": return(this.LeftChildNode.GetValue(rc, forceMatch) == this.RightChildNode.GetValue(rc, forceMatch)); case "<>": case "!=": return(this.LeftChildNode.GetValue(rc, forceMatch) != this.RightChildNode.GetValue(rc, forceMatch)); case ">": return(this.LeftChildNode.GetValue(rc, forceMatch) > this.RightChildNode.GetValue(rc, forceMatch)); case "<": return(this.LeftChildNode.GetValue(rc, forceMatch) < this.RightChildNode.GetValue(rc, forceMatch)); case ">=": return(this.LeftChildNode.GetValue(rc, forceMatch) >= this.RightChildNode.GetValue(rc, forceMatch)); case "<=": return(this.LeftChildNode.GetValue(rc, forceMatch) <= this.RightChildNode.GetValue(rc, forceMatch)); } return(null); }
private void SendToIrc(IEnumerable <IStalk> stalks, IRecentChange rc) { var splitStalks = new Dictionary <string, List <IStalk> >(); foreach (var stalk in stalks) { if (!splitStalks.ContainsKey(stalk.Channel)) { splitStalks.Add(stalk.Channel, new List <IStalk>()); } splitStalks[stalk.Channel].Add(stalk); } try { foreach (var stalkList in splitStalks) { this.freenodeClient.SendMessage(stalkList.Key, this.FormatMessageForIrc(stalkList.Value, rc)); } } catch (Exception ex) { this.logger.ErrorFormat(ex, "Failed to send notification IRC message for RC {0}", rc); } }
private void SendIndividualEmail(IList <IStalk> stalks, IRecentChange rc, IBotUser botUser) { if (!botUser.EmailAddressConfirmed) { return; } var stalkList = string.Join(", ", stalks.Select(x => x.Identifier)); try { var extraHeaders = new Dictionary <string, string> { { "StalkList", stalkList } }; this.emailHelper.SendEmail( this.emailTemplateFormatter.FormatRecentChangeStalksForEmail(stalks, rc, botUser), string.Format(this.templates.EmailRcSubject, stalkList, rc.Page), null, botUser, extraHeaders); } catch (Exception ex) { this.logger.ErrorFormat(ex, "Failed to send notification email for RC {0}", rc); } }
protected virtual void SanityCheck(IRecentChange rc) { if (rc == null) { throw new ArgumentNullException("rc"); } }
public void HandleRcEvent(MessageReceivedEventArgs e, IRecentChange rc) { var stalks = this.channelConfig.MatchStalks(rc, e.Target).ToList(); if (stalks.Count == 0) { return; } this.logger.InfoFormat( "Seen stalked change for stalks: {0}", string.Join(" ", stalks.Select(x => x.Identifier))); // Touch expiry date (*before* email is sent) foreach (var stalk in stalks) { stalk.TriggerDynamicExpiry(); } // send notifications this.SendToIrc(stalks, rc); this.SendEmail(stalks, rc); // touch update/count foreach (var stalk in stalks) { stalk.LastTriggerTime = DateTime.UtcNow; stalk.TriggerCount++; } this.channelConfig.Save(); }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { var leftResult = this.LeftChildNode.Match(rc, false); var rightResult = this.RightChildNode.Match(rc, false); if (leftResult.HasValue && rightResult.HasValue && leftResult.Value == rightResult.Value) { return(false); } if (leftResult.HasValue && rightResult.HasValue) { // leftResult!=rightResult is always true because above condition, hence excluded return(true); } if (!forceMatch) { return(null); } leftResult = leftResult ?? this.LeftChildNode.Match(rc, true); rightResult = rightResult ?? this.RightChildNode.Match(rc, true); if (!leftResult.HasValue || !rightResult.HasValue) { return(null); } return(leftResult.Value != rightResult.Value); }
public override long?GetValue(IRecentChange rc, bool forceMatch) { if (!forceMatch) { return(null); } return(rc.GetPageSize()); }
public bool Match(IRecentChange rc) { if (!this.IsActive()) { return(false); } return(this.baseNode.Match(rc)); }
protected override void SanityCheck(IRecentChange rc) { base.SanityCheck(rc); if (!this.Minimum.HasValue && !this.Maximum.HasValue) { throw new InvalidOperationException("Must define at least one of min or max"); } }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { if (DateTime.UtcNow > this.Expiry) { return(false); } return(this.ChildNode.Match(rc, forceMatch)); }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { if (!forceMatch) { return(null); } return(rc.PageIsInCategory(this.Expression)); }
protected override void SanityCheck(IRecentChange rc) { base.SanityCheck(rc); if (this.ChildNode == null) { throw new InvalidOperationException("No child node defined!"); } }
protected override void SanityCheck(IRecentChange rc) { base.SanityCheck(rc); if (this.Expression == null) { throw new InvalidOperationException("No match expression has been set!"); } }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { if (!forceMatch) { return(null); } return(rc.GetUserGroups().Contains(this.Expression)); }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { this.Compile(); if (rc.EditFlags != null) { return(this.RegexExpression.Match(rc.EditFlags).Success); } return(false); }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { this.Compile(); var result = false; if (rc.User != null) { result |= this.RegexExpression.Match(rc.User).Success; } return(result); }
protected override void SanityCheck(IRecentChange rc) { base.SanityCheck(rc); if (this.ChildNodes == null) { throw new InvalidOperationException("Child node list is null"); } if (!this.ChildNodes.Any()) { throw new InvalidOperationException("No child nodes present"); } }
public bool Match(IRecentChange rc) { var initialResult = this.Match(rc, false); if (initialResult.HasValue) { return(initialResult.Value); } var match = this.Match(rc, true); if (match.HasValue) { return(match.Value); } throw new InvalidOperationException("Result of forced match is null!"); }
public IEnumerable <IStalk> MatchStalks(IRecentChange rc, string channel) { if (!this.Initialised) { throw new ApplicationException("Cannot match when not initialised!"); } using (GlobalMatchDuration.NewTimer()) { SortedList <string, IStalk> stalkListClone; lock (this.ItemList) { stalkListClone = new SortedList <string, IStalk>( this.ItemList.SelectMany(x => x.Value.Stalks.Values) .Where(x => x.WatchChannel == channel) .Where(x => x.IsActive()) .ToDictionary(x => x.Identifier + "@" + x.Channel)); } foreach (var s in stalkListClone) { bool isMatch; try { using (IndividualMatchDuration.WithLabels(s.Value.Channel, s.Value.Identifier).NewTimer()) { isMatch = s.Value.Match(rc); } } catch (InvalidOperationException ex) { this.Logger.ErrorFormat(ex, "Error during evaluation of stalk {0}", s.Key); // skip this stalk, resume with the others continue; } if (isMatch) { yield return(s.Value); } } } }
protected override void SanityCheck(IRecentChange rc) { base.SanityCheck(rc); if (this.LeftChildNode == null) { throw new InvalidOperationException("No left child node defined!"); } if (this.RightChildNode == null) { throw new InvalidOperationException("No right child node defined!"); } if (this.Operator == null) { throw new InvalidOperationException("No operator defined!"); } }
private void SendEmail(IEnumerable <IStalk> stalks, IRecentChange rc) { if (this.appConfig.EmailConfiguration == null) { this.logger.Debug("Not sending email; email configuration is disabled"); return; } var stalkSplit = this.botUserConfiguration.Items.ToDictionary(x => x, y => new HashSet <IStalk>()); foreach (var stalk in stalks) { var channel = this.channelConfig[stalk.Channel]; var userSubscriptionsToStalk = this.subscriptionHelper.GetUserSubscriptionsToStalk(channel, stalk); foreach (var subscription in userSubscriptionsToStalk.Where(x => x.IsSubscribed)) { stalkSplit[subscription.BotUser].Add(subscription.Stalk); } } foreach (var kvp in stalkSplit) { var stalkList = kvp.Value; var botUser = kvp.Key; if (!stalkList.Any()) { continue; } if (!botUser.EmailAddressConfirmed) { continue; } this.SendIndividualEmail(stalkList.ToList(), rc, botUser); } }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { int maxLimit = 0; int minLimit = 0; foreach (var node in this.ChildNodes) { var localResult = node.Match(rc, forceMatch); if (!localResult.HasValue) { maxLimit++; continue; } if (localResult.Value) { maxLimit++; minLimit++; } } if (this.Maximum.HasValue && minLimit > this.Maximum) { return(false); } if (this.Minimum.HasValue && maxLimit < this.Minimum) { return(false); } if (minLimit < this.Minimum || maxLimit > this.Maximum) { return(null); } return(true); }
public string FormatMessageForIrc(IEnumerable <IStalk> stalks, IRecentChange rc) { var stalkTags = new StringBuilder(); bool first = true; foreach (var s in stalks) { if (!first) { stalkTags.Append(this.templates.IrcStalkTagSeparator); } first = false; stalkTags.Append(s.Identifier); } var sizeDiff = "N/A"; if (rc.SizeDiff.HasValue) { sizeDiff = (rc.SizeDiff.Value > 0 ? "+" : string.Empty) + rc.SizeDiff.Value.ToString(CultureInfo.InvariantCulture); } return(string.Format( this.templates.IrcAlertFormat, stalkTags, rc.Url, rc.Page, rc.User, rc.EditSummary, sizeDiff, rc.EditFlags, DateTime.UtcNow.ToString(this.appConfig.DateFormat) )); }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { // Optimism! bool?result = true; foreach (var childNode in this.ChildNodes) { var localResult = childNode.Match(rc, forceMatch); if (localResult.GetValueOrDefault(true) == false) { return(false); } if (localResult != null) { continue; } result = null; } return(result); }
public string FormatRecentChangeStalksForEmail(IEnumerable <IStalk> stalks, IRecentChange rc, IBotUser botUser) { var stalksFormatted = this.FormatStalkListForEmail(stalks, botUser); var sizeDiff = "N/A"; if (rc.SizeDiff.HasValue) { sizeDiff = (rc.SizeDiff.Value > 0 ? "+" : string.Empty) + rc.SizeDiff.Value.ToString(CultureInfo.InvariantCulture); } return(string.Format( this.templates.EmailRcTemplate, stalksFormatted, rc.Url, rc.Page, rc.User, rc.EditSummary, sizeDiff, rc.EditFlags, DateTime.UtcNow.ToString(this.appConfig.DateFormat) )); }
public abstract long?GetValue(IRecentChange rc, bool forceMatch);
public void LocalSetup() { this.rc = this.RecentChangeBuilder().Object; }
public override long?GetValue(IRecentChange rc, bool forceMatch) { return(this.Value); }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { return(this.ChildNode.Match(rc, forceMatch)); }
protected override bool?DoMatch(IRecentChange rc, bool forceMatch) { return(false); }