From eccb449dfd5c58e58927268f64bbd2a5ba597621 Mon Sep 17 00:00:00 2001 From: Aleksey Ivanov Date: Mon, 22 May 2017 22:34:20 +0300 Subject: [PATCH 1/4] Add configurable search_url #1552 --- app/models/agents/peak_detector_agent.rb | 5 ++++- .../agents/agent_views/peak_detector_agent/_show.html.erb | 3 +-- spec/models/agents/peak_detector_agent_spec.rb | 6 ++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/models/agents/peak_detector_agent.rb b/app/models/agents/peak_detector_agent.rb index 2aed2378..045d4843 100644 --- a/app/models/agents/peak_detector_agent.rb +++ b/app/models/agents/peak_detector_agent.rb @@ -14,6 +14,8 @@ module Agents You may set `window_duration_in_days` to change the default memory window length of `14` days, `min_peak_spacing_in_days` to change the default minimum peak spacing of `2` days (peaks closer together will be ignored), and `std_multiple` to change the default standard deviation threshold multiple of `3`. You may set `min_events` for the minimal number of accumulated events before the agent starts detecting. + + You may set `search_url` to point to something else than Twitter search. MD event_description <<-MD @@ -28,7 +30,7 @@ module Agents MD def validate_options - unless options['expected_receive_period_in_days'].present? && options['message'].present? && options['value_path'].present? && options['min_events'].present? + unless options['expected_receive_period_in_days'].present? && options['message'].present? && options['value_path'].present? && options['min_events'].present? && options['search_url'].present? errors.add(:base, "expected_receive_period_in_days, value_path, min_events and message are required") end end @@ -40,6 +42,7 @@ module Agents 'value_path' => "count", 'message' => "A peak of {{count}} was found in {{filter}}", 'min_events' => '4', + 'search_url' => 'https://twitter.com/search?q=%{q}' } end diff --git a/app/views/agents/agent_views/peak_detector_agent/_show.html.erb b/app/views/agents/agent_views/peak_detector_agent/_show.html.erb index b5556a18..8736001b 100644 --- a/app/views/agents/agent_views/peak_detector_agent/_show.html.erb +++ b/app/views/agents/agent_views/peak_detector_agent/_show.html.erb @@ -1,12 +1,11 @@ <% content_for :head do %> <%= javascript_include_tag "graphing" %> <% end %> - <% if @agent.memory[:data] && @agent.memory[:data].length > 0 %>

Recent Trends

<% @agent.memory[:data].each.with_index do |(group_name, data), index| %>
-
<%= link_to group_name.to_s, "https://twitter.com/search?q=#{CGI::escape group_name.to_s}", :target => "blank" %>
+
<%= link_to group_name.to_s, format(@agent.options[:search_url], q: CGI::escape(group_name.to_s)), :target => "blank" %>
diff --git a/spec/models/agents/peak_detector_agent_spec.rb b/spec/models/agents/peak_detector_agent_spec.rb index abefd29a..7acfaf6c 100644 --- a/spec/models/agents/peak_detector_agent_spec.rb +++ b/spec/models/agents/peak_detector_agent_spec.rb @@ -10,6 +10,7 @@ describe Agents::PeakDetectorAgent do 'value_path' => "count", 'message' => "A peak was found", 'min_events' => "4", + 'search_url' => "https://twitter.com/search?q=%{q}" } } @@ -90,6 +91,11 @@ describe Agents::PeakDetectorAgent do expect(@agent).not_to be_valid end + it "should validate presence of search_url" do + @agent.options['search_url'] = nil + expect(@agent).not_to be_valid + end + it "should validate presence of expected_receive_period_in_days" do @agent.options['expected_receive_period_in_days'] = "" expect(@agent).not_to be_valid From a4b7f1b1f5c80e9a0b2b9c4e3cf58325a86bc8cf Mon Sep 17 00:00:00 2001 From: Aleksey Ivanov Date: Tue, 23 May 2017 03:47:51 +0300 Subject: [PATCH 2/4] Fallback to default value for existing agents --- app/views/agents/agent_views/peak_detector_agent/_show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/agents/agent_views/peak_detector_agent/_show.html.erb b/app/views/agents/agent_views/peak_detector_agent/_show.html.erb index 8736001b..2f5f4a81 100644 --- a/app/views/agents/agent_views/peak_detector_agent/_show.html.erb +++ b/app/views/agents/agent_views/peak_detector_agent/_show.html.erb @@ -5,7 +5,7 @@

Recent Trends

<% @agent.memory[:data].each.with_index do |(group_name, data), index| %>
-
<%= link_to group_name.to_s, format(@agent.options[:search_url], q: CGI::escape(group_name.to_s)), :target => "blank" %>
+
<%= link_to group_name.to_s, format(@agent.options[:search_url].presence || @agent.default_options['search_url'], q: CGI::escape(group_name.to_s)), :target => "blank" %>
From 0e9c24ab54157c973f1e85426d7273619a33a0e2 Mon Sep 17 00:00:00 2001 From: Aleksey Ivanov Date: Tue, 23 May 2017 12:21:31 +0300 Subject: [PATCH 3/4] Falling back to default 'search_url' and docs --- app/models/agents/peak_detector_agent.rb | 4 ++-- spec/models/agents/peak_detector_agent_spec.rb | 8 +------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/models/agents/peak_detector_agent.rb b/app/models/agents/peak_detector_agent.rb index 045d4843..327b6e40 100644 --- a/app/models/agents/peak_detector_agent.rb +++ b/app/models/agents/peak_detector_agent.rb @@ -15,7 +15,7 @@ module Agents You may set `min_events` for the minimal number of accumulated events before the agent starts detecting. - You may set `search_url` to point to something else than Twitter search. + You may set `search_url` to point to something else than Twitter search. Default value is `https://twitter.com/search?q=%{q}` where `%{q}` will be replaced with group name. MD event_description <<-MD @@ -30,7 +30,7 @@ module Agents MD def validate_options - unless options['expected_receive_period_in_days'].present? && options['message'].present? && options['value_path'].present? && options['min_events'].present? && options['search_url'].present? + unless options['expected_receive_period_in_days'].present? && options['message'].present? && options['value_path'].present? && options['min_events'].present? errors.add(:base, "expected_receive_period_in_days, value_path, min_events and message are required") end end diff --git a/spec/models/agents/peak_detector_agent_spec.rb b/spec/models/agents/peak_detector_agent_spec.rb index 7acfaf6c..ec000dd1 100644 --- a/spec/models/agents/peak_detector_agent_spec.rb +++ b/spec/models/agents/peak_detector_agent_spec.rb @@ -9,8 +9,7 @@ describe Agents::PeakDetectorAgent do 'group_by_path' => "filter", 'value_path' => "count", 'message' => "A peak was found", - 'min_events' => "4", - 'search_url' => "https://twitter.com/search?q=%{q}" + 'min_events' => "4" } } @@ -91,11 +90,6 @@ describe Agents::PeakDetectorAgent do expect(@agent).not_to be_valid end - it "should validate presence of search_url" do - @agent.options['search_url'] = nil - expect(@agent).not_to be_valid - end - it "should validate presence of expected_receive_period_in_days" do @agent.options['expected_receive_period_in_days'] = "" expect(@agent).not_to be_valid From 6a7221a9da5907305f1e335e6718e9b9e5f97aba Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Thu, 25 May 2017 06:34:15 +0900 Subject: [PATCH 4/4] Use URI Template (RFC 6570) for interpolating `search_url` --- app/models/agents/peak_detector_agent.rb | 18 ++++++++++++++++-- .../peak_detector_agent/_show.html.erb | 3 ++- spec/models/agents/peak_detector_agent_spec.rb | 8 ++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/models/agents/peak_detector_agent.rb b/app/models/agents/peak_detector_agent.rb index 327b6e40..126f08d2 100644 --- a/app/models/agents/peak_detector_agent.rb +++ b/app/models/agents/peak_detector_agent.rb @@ -4,6 +4,8 @@ module Agents class PeakDetectorAgent < Agent cannot_be_scheduled! + DEFAULT_SEARCH_URL = 'https://twitter.com/search?q={q}' + description <<-MD The Peak Detector Agent will watch for peaks in an event stream. When a peak is detected, the resulting Event will have a payload message of `message`. You can include extractions in the message, for example: `I saw a bar of: {{foo.bar}}`, have a look at the [Wiki](https://github.com/cantino/huginn/wiki/Formatting-Events-using-Liquid) for details. @@ -15,7 +17,7 @@ module Agents You may set `min_events` for the minimal number of accumulated events before the agent starts detecting. - You may set `search_url` to point to something else than Twitter search. Default value is `https://twitter.com/search?q=%{q}` where `%{q}` will be replaced with group name. + You may set `search_url` to point to something else than Twitter search, using the URI Template syntax defined in [RFC 6570](https://tools.ietf.org/html/rfc6570). Default value is `#{DEFAULT_SEARCH_URL}` where `{q}` will be replaced with group name. MD event_description <<-MD @@ -33,6 +35,15 @@ module Agents unless options['expected_receive_period_in_days'].present? && options['message'].present? && options['value_path'].present? && options['min_events'].present? errors.add(:base, "expected_receive_period_in_days, value_path, min_events and message are required") end + begin + tmpl = search_url + rescue => e + errors.add(:base, "search_url must be a valid URI template: #{e.message}") + else + unless tmpl.keys.include?('q') + errors.add(:base, "search_url must include a variable named 'q'") + end + end end def default_options @@ -42,7 +53,6 @@ module Agents 'value_path' => "count", 'message' => "A peak of {{count}} was found in {{filter}}", 'min_events' => '4', - 'search_url' => 'https://twitter.com/search?q=%{q}' } end @@ -58,6 +68,10 @@ module Agents end end + def search_url + Addressable::Template.new(options[:search_url].presence || DEFAULT_SEARCH_URL) + end + private def check_for_peak(group, event) diff --git a/app/views/agents/agent_views/peak_detector_agent/_show.html.erb b/app/views/agents/agent_views/peak_detector_agent/_show.html.erb index 2f5f4a81..8c6bf641 100644 --- a/app/views/agents/agent_views/peak_detector_agent/_show.html.erb +++ b/app/views/agents/agent_views/peak_detector_agent/_show.html.erb @@ -3,9 +3,10 @@ <% end %> <% if @agent.memory[:data] && @agent.memory[:data].length > 0 %>

Recent Trends

+ <% search_url = @agent.search_url %> <% @agent.memory[:data].each.with_index do |(group_name, data), index| %>
-
<%= link_to group_name.to_s, format(@agent.options[:search_url].presence || @agent.default_options['search_url'], q: CGI::escape(group_name.to_s)), :target => "blank" %>
+
<%= link_to group_name.to_s, search_url.expand(q: group_name.to_s).to_s, target: '_blank' %>
diff --git a/spec/models/agents/peak_detector_agent_spec.rb b/spec/models/agents/peak_detector_agent_spec.rb index ec000dd1..75f4aecf 100644 --- a/spec/models/agents/peak_detector_agent_spec.rb +++ b/spec/models/agents/peak_detector_agent_spec.rb @@ -99,5 +99,13 @@ describe Agents::PeakDetectorAgent do @agent.options['value_path'] = "" expect(@agent).not_to be_valid end + + it "should validate search_url" do + @agent.options['search_url'] = 'https://twitter.com/' + expect(@agent).not_to be_valid + + @agent.options['search_url'] = 'https://twitter.com/{q}' + expect(@agent).to be_valid + end end end