mirror of
https://github.com/Fishwaldo/huginn.git
synced 2025-03-15 19:31:26 +00:00
Allow escaping of JSONPath outputs; demonstrate in the formatting agent.
This commit is contained in:
parent
a00af51d68
commit
306237c306
4 changed files with 146 additions and 112 deletions
|
@ -24,7 +24,7 @@ module Agents
|
|||
subject: "$.data"
|
||||
}
|
||||
|
||||
JSONPaths must be between < and > . Make sure that you dont use these symbols anywhere else.
|
||||
JSONPaths must be between < and > . Make sure that you don't use these symbols anywhere else.
|
||||
|
||||
Events generated by this possible Event Formatting Agent will look like:
|
||||
|
||||
|
@ -35,7 +35,13 @@ module Agents
|
|||
|
||||
If you want to retain original contents of events and only add new keys, then set `mode` to `merge`, otherwise set it to `clean`.
|
||||
|
||||
By default, the output event will have `agent` and `created_at` fields as well, reflecting the original Agent type and Event creation time. You can skip these outputs by setting `skip_agent` and `skip_created_at` to `true`.
|
||||
By default, the output event will have `agent` and `created_at` fields added as well, reflecting the original Agent type and Event creation time. You can skip these outputs by setting `skip_agent` and `skip_created_at` to `true`.
|
||||
|
||||
To CGI escape output (for example when creating a link), prefix with `escape`, like so:
|
||||
|
||||
{
|
||||
:message => "A peak was on Twitter in <$.group_by>. Search: https://twitter.com/search?q=<escape $.group_by>"
|
||||
}
|
||||
MD
|
||||
|
||||
event_description <<-MD
|
||||
|
@ -62,7 +68,9 @@ module Agents
|
|||
end
|
||||
|
||||
def value_constructor(value, payload)
|
||||
value.gsub(/<[^>]+>/).each {|jsonpath| Utils.values_at(payload,jsonpath[1..-2]).first.to_s }
|
||||
value.gsub(/<[^>]+>/).each { |jsonpath|
|
||||
Utils.values_at(payload, jsonpath[1..-2]).first.to_s
|
||||
}
|
||||
end
|
||||
|
||||
def receive(incoming_events)
|
||||
|
|
15
lib/utils.rb
15
lib/utils.rb
|
@ -1,4 +1,5 @@
|
|||
require 'jsonpath'
|
||||
require 'cgi'
|
||||
|
||||
module Utils
|
||||
# Unindents if the indentation is 2 or more characters.
|
||||
|
@ -22,6 +23,18 @@ module Utils
|
|||
end
|
||||
|
||||
def self.values_at(data, path)
|
||||
JsonPath.new(path, :allow_eval => false).on(data.is_a?(String) ? data : data.to_json)
|
||||
if path =~ /\Aescape /
|
||||
path.gsub!(/\Aescape /, '')
|
||||
escape = true
|
||||
else
|
||||
escape = false
|
||||
end
|
||||
|
||||
result = JsonPath.new(path, :allow_eval => false).on(data.is_a?(String) ? data : data.to_json)
|
||||
if escape
|
||||
result.map {|r| CGI::escape r }
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
|
@ -24,5 +24,9 @@ describe Utils do
|
|||
Utils.values_at({ :foo => [ { :bar => :baz }, { :bar => :bing } ]}, "foo[*].bar").should == %w[baz bing]
|
||||
Utils.values_at({ :foo => [ { :bar => :baz }, { :bar => :bing } ]}, "foo[*].bar").should == %w[baz bing]
|
||||
end
|
||||
|
||||
it "should allow escaping" do
|
||||
Utils.values_at({ :foo => { :bar => "escape this!?" }}, "escape $.foo.bar").should == ["escape+this%21%3F"]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,119 +1,128 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Agents::EventFormattingAgent do
|
||||
before do
|
||||
@valid_params = {
|
||||
:name => "somename",
|
||||
:options => {
|
||||
:instructions => {
|
||||
:message => "Received <$.content.text.*> from <$.content.name> .",
|
||||
:subject => "Weather looks like <$.conditions>"
|
||||
},
|
||||
:mode => "clean",
|
||||
:skip_agent => "false",
|
||||
:skip_created_at => "false"
|
||||
}
|
||||
}
|
||||
@checker = Agents::EventFormattingAgent.new(@valid_params)
|
||||
@checker.user = users(:jane)
|
||||
@checker.save!
|
||||
|
||||
@event = Event.new
|
||||
@event.agent = agents(:jane_weather_agent)
|
||||
@event.created_at = Time.now
|
||||
@event.payload = {
|
||||
:content => {
|
||||
:text => "Some Lorem Ipsum",
|
||||
:name => "somevalue"
|
||||
before do
|
||||
@valid_params = {
|
||||
:name => "somename",
|
||||
:options => {
|
||||
:instructions => {
|
||||
:message => "Received <$.content.text.*> from <$.content.name> .",
|
||||
:subject => "Weather looks like <$.conditions>"
|
||||
},
|
||||
:conditions => "someothervalue"
|
||||
:mode => "clean",
|
||||
:skip_agent => "false",
|
||||
:skip_created_at => "false"
|
||||
}
|
||||
}
|
||||
@checker = Agents::EventFormattingAgent.new(@valid_params)
|
||||
@checker.user = users(:jane)
|
||||
@checker.save!
|
||||
|
||||
@event = Event.new
|
||||
@event.agent = agents(:jane_weather_agent)
|
||||
@event.created_at = Time.now
|
||||
@event.payload = {
|
||||
:content => {
|
||||
:text => "Some Lorem Ipsum",
|
||||
:name => "somevalue"
|
||||
},
|
||||
:conditions => "someothervalue"
|
||||
}
|
||||
end
|
||||
|
||||
describe "#receive" do
|
||||
it "should accept clean mode" do
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:content].should == nil
|
||||
end
|
||||
|
||||
describe "#receive" do
|
||||
it "checks if clean mode is working fine" do
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:content].should == nil
|
||||
end
|
||||
|
||||
it "checks if merge mode is working fine" do
|
||||
@checker.options[:mode] = "merge"
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:content].should_not == nil
|
||||
end
|
||||
|
||||
it "checks if skip_agent is working fine" do
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:agent].should == "WeatherAgent"
|
||||
@checker.options[:skip_agent] = "true"
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:agent].should == nil
|
||||
end
|
||||
|
||||
it "checks if skip_created_at is working fine" do
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:created_at].should_not == nil
|
||||
@checker.options[:skip_created_at] = "true"
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:created_at].should == nil
|
||||
end
|
||||
|
||||
it "checks if instructions are working fine" do
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:message].should == "Received Some Lorem Ipsum from somevalue ."
|
||||
Event.last.payload[:subject].should == "Weather looks like someothervalue"
|
||||
end
|
||||
|
||||
it "checks if it can handle multiple events" do
|
||||
event1 = Event.new
|
||||
event1.agent = agents(:bob_weather_agent)
|
||||
event1.payload = {
|
||||
:content => {
|
||||
:text => "Some Lorem Ipsum",
|
||||
:name => "somevalue"
|
||||
},
|
||||
:conditions => "someothervalue"
|
||||
}
|
||||
|
||||
event2 = Event.new
|
||||
event2.agent = agents(:bob_weather_agent)
|
||||
event2.payload = {
|
||||
:content => {
|
||||
:text => "Some Lorem Ipsum",
|
||||
:name => "somevalue"
|
||||
},
|
||||
:conditions => "someothervalue"
|
||||
}
|
||||
|
||||
lambda {
|
||||
@checker.receive([event2,event1])
|
||||
}.should change { Event.count }.by(2)
|
||||
end
|
||||
it "should accept merge mode" do
|
||||
@checker.options[:mode] = "merge"
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:content].should_not == nil
|
||||
end
|
||||
|
||||
describe "validation" do
|
||||
before do
|
||||
@checker.should be_valid
|
||||
end
|
||||
|
||||
it "should validate presence of instructions" do
|
||||
@checker.options[:instructions] = ""
|
||||
@checker.should_not be_valid
|
||||
end
|
||||
|
||||
it "should validate presence of mode" do
|
||||
@checker.options[:mode] = ""
|
||||
@checker.should_not be_valid
|
||||
end
|
||||
|
||||
it "should validate presence of skip_agent" do
|
||||
@checker.options[:skip_agent] = ""
|
||||
@checker.should_not be_valid
|
||||
end
|
||||
|
||||
it "should validate presence of skip_created_at" do
|
||||
@checker.options[:skip_created_at] = ""
|
||||
@checker.should_not be_valid
|
||||
end
|
||||
it "should accept skip_agent" do
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:agent].should == "WeatherAgent"
|
||||
@checker.options[:skip_agent] = "true"
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:agent].should == nil
|
||||
end
|
||||
|
||||
it "should accept skip_created_at" do
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:created_at].should_not == nil
|
||||
@checker.options[:skip_created_at] = "true"
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:created_at].should == nil
|
||||
end
|
||||
|
||||
it "should handle JSONPaths in instructions" do
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:message].should == "Received Some Lorem Ipsum from somevalue ."
|
||||
Event.last.payload[:subject].should == "Weather looks like someothervalue"
|
||||
end
|
||||
|
||||
it "should allow escaping" do
|
||||
@event.payload[:content][:name] = "escape this!?"
|
||||
@event.save!
|
||||
@checker.options[:instructions][:message] = "Escaped: <escape $.content.name>\nNot escaped: <$.content.name>"
|
||||
@checker.save!
|
||||
@checker.receive([@event])
|
||||
Event.last.payload[:message].should == "Escaped: escape+this%21%3F\nNot escaped: escape this!?"
|
||||
end
|
||||
|
||||
it "should handle multiple events" do
|
||||
event1 = Event.new
|
||||
event1.agent = agents(:bob_weather_agent)
|
||||
event1.payload = {
|
||||
:content => {
|
||||
:text => "Some Lorem Ipsum",
|
||||
:name => "somevalue"
|
||||
},
|
||||
:conditions => "someothervalue"
|
||||
}
|
||||
|
||||
event2 = Event.new
|
||||
event2.agent = agents(:bob_weather_agent)
|
||||
event2.payload = {
|
||||
:content => {
|
||||
:text => "Some Lorem Ipsum",
|
||||
:name => "somevalue"
|
||||
},
|
||||
:conditions => "someothervalue"
|
||||
}
|
||||
|
||||
lambda {
|
||||
@checker.receive([event2, event1])
|
||||
}.should change { Event.count }.by(2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "validation" do
|
||||
before do
|
||||
@checker.should be_valid
|
||||
end
|
||||
|
||||
it "should validate presence of instructions" do
|
||||
@checker.options[:instructions] = ""
|
||||
@checker.should_not be_valid
|
||||
end
|
||||
|
||||
it "should validate presence of mode" do
|
||||
@checker.options[:mode] = ""
|
||||
@checker.should_not be_valid
|
||||
end
|
||||
|
||||
it "should validate presence of skip_agent" do
|
||||
@checker.options[:skip_agent] = ""
|
||||
@checker.should_not be_valid
|
||||
end
|
||||
|
||||
it "should validate presence of skip_created_at" do
|
||||
@checker.options[:skip_created_at] = ""
|
||||
@checker.should_not be_valid
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue