rules_engine_templates 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/rails_generators/manifests/plan_start.rb +4 -1
- data/rails_generators/manifests/plan_start.yml +0 -1
- data/rails_generators/manifests/tweet_filter.rb +4 -1
- data/rails_generators/manifests/tweet_filter.yml +0 -1
- data/rails_generators/manifests/tweet_filter_rt.rb +29 -0
- data/rails_generators/manifests/tweet_filter_rt.yml +19 -0
- data/rails_generators/manifests/tweet_reader.rb +6 -1
- data/rails_generators/manifests/tweet_reader.yml +3 -1
- data/rails_generators/manifests/tweet_word_filter.rb +29 -0
- data/rails_generators/manifests/tweet_word_filter.yml +19 -0
- data/rails_generators/manifests/tweet_word_splitter.rb +29 -0
- data/rails_generators/manifests/tweet_word_splitter.yml +19 -0
- data/rails_generators/manifests/tweet_word_writer.rb +37 -0
- data/rails_generators/manifests/tweet_word_writer.yml +30 -0
- data/rails_generators/manifests/workflow_start.rb +4 -1
- data/rails_generators/manifests/workflow_start.yml +0 -1
- data/rails_generators/manifests/workflow_stop.rb +5 -1
- data/rails_generators/manifests/workflow_stop.yml +3 -2
- data/rails_generators/rules_engine_templates_generator.rb +4 -2
- data/rails_generators/templates/app/controllers/rules/tweet_word_writer_controller.rb +21 -0
- data/rails_generators/templates/app/rules/plan_start.rb +4 -1
- data/rails_generators/templates/app/rules/tweet_filter.rb +34 -8
- data/rails_generators/templates/app/rules/tweet_filter_rt.rb +93 -0
- data/rails_generators/templates/app/rules/tweet_reader.rb +56 -7
- data/rails_generators/templates/app/rules/tweet_word_filter.rb +124 -0
- data/rails_generators/templates/app/rules/tweet_word_splitter.rb +99 -0
- data/rails_generators/templates/app/rules/tweet_word_writer.rb +115 -0
- data/rails_generators/templates/app/rules/workflow_start.rb +1 -1
- data/rails_generators/templates/app/rules/workflow_stop.rb +9 -9
- data/rails_generators/templates/app/views/re_rule_definitions/plan_start/_form.html.erb +1 -1
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_filter/_form.html.erb +11 -1
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_filter_rt/_edit.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_filter_rt/_form.html.erb +16 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_filter_rt/_help.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_filter_rt/_new.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_reader/_form.html.erb +2 -2
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_filter/_edit.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_filter/_form.html.erb +45 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_filter/_help.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_filter/_new.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_splitter/_edit.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_splitter/_form.html.erb +16 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_splitter/_help.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_splitter/_new.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_writer/_edit.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_writer/_form.html.erb +16 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_writer/_help.html.erb +2 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_writer/_new.html.erb +1 -0
- data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_writer/index.html.erb +16 -0
- data/rails_generators/templates/app/views/re_rule_definitions/workflow_start/_form.html.erb +1 -1
- data/rails_generators/templates/app/views/re_rule_definitions/workflow_stop/_form.html.erb +1 -8
- data/rails_generators/templates/db/migrate/20100725233933_create_re_tweet_reader_data.rb +12 -0
- data/rails_generators/templates/db/migrate/20100727235508_create_tweet_word_writer.rb +24 -0
- data/rails_generators/templates/spec/lib/rules/plan_start_spec.rb +40 -35
- data/rails_generators/templates/spec/lib/rules/tweet_filter_rt_spec.rb +211 -0
- data/rails_generators/templates/spec/lib/rules/tweet_filter_spec.rb +95 -46
- data/rails_generators/templates/spec/lib/rules/tweet_reader_spec.rb +160 -48
- data/rails_generators/templates/spec/lib/rules/tweet_word_filter_spec.rb +315 -0
- data/rails_generators/templates/spec/lib/rules/tweet_word_splitter_spec.rb +244 -0
- data/rails_generators/templates/spec/lib/rules/tweet_word_writer_spec.rb +244 -0
- data/rails_generators/templates/spec/lib/rules/workflow_start_spec.rb +42 -37
- data/rails_generators/templates/spec/lib/rules/workflow_stop_spec.rb +45 -70
- metadata +40 -4
|
@@ -3,12 +3,17 @@ require 'twitter'
|
|
|
3
3
|
MAX_PAGES = 5 unless defined?(MAX_PAGES)
|
|
4
4
|
TWITTER_RPP = 40 unless defined?(TWITTER_RPP)
|
|
5
5
|
|
|
6
|
+
class Re<%=rule_class%>Data < ActiveRecord::Base
|
|
7
|
+
set_table_name :re_<%=rule_name%>_data
|
|
8
|
+
end
|
|
9
|
+
|
|
6
10
|
module RulesEngine
|
|
7
11
|
module Rule
|
|
8
12
|
class <%=rule_class%> < RulesEngine::Rule::Definition
|
|
9
13
|
|
|
10
14
|
attr_reader :message
|
|
11
15
|
attr_reader :plan
|
|
16
|
+
attr_reader :re_<%=rule_name%>_data_id
|
|
12
17
|
|
|
13
18
|
##################################################################
|
|
14
19
|
# class options
|
|
@@ -28,8 +33,10 @@ module RulesEngine
|
|
|
28
33
|
@title = nil
|
|
29
34
|
@message = nil
|
|
30
35
|
@plan = nil
|
|
36
|
+
@re_<%=rule_name%>_data_id = nil
|
|
31
37
|
else
|
|
32
|
-
@title, @message, @plan = ActiveSupport::JSON.decode(data)
|
|
38
|
+
@title, @message, @plan, data_id = ActiveSupport::JSON.decode(data)
|
|
39
|
+
@re_<%=rule_name%>_data_id = data_id.to_i
|
|
33
40
|
end
|
|
34
41
|
end
|
|
35
42
|
|
|
@@ -44,11 +51,14 @@ module RulesEngine
|
|
|
44
51
|
end
|
|
45
52
|
|
|
46
53
|
def data
|
|
47
|
-
[title, message, plan].to_json
|
|
54
|
+
[title, message, plan, re_<%=rule_name%>_data_id.to_s].to_json
|
|
48
55
|
end
|
|
49
56
|
|
|
50
57
|
def expected_outcomes
|
|
51
|
-
[
|
|
58
|
+
[
|
|
59
|
+
{:outcome => RulesEngine::Rule::Outcome::NEXT},
|
|
60
|
+
{:outcome => RulesEngine::Rule::Outcome::STOP_FAILURE, :title => "Stop if plan fails"}
|
|
61
|
+
]
|
|
52
62
|
end
|
|
53
63
|
|
|
54
64
|
##################################################################
|
|
@@ -74,23 +84,62 @@ module RulesEngine
|
|
|
74
84
|
##################################################################
|
|
75
85
|
# callbacks when the rule is added and removed from a workflow
|
|
76
86
|
def before_create()
|
|
87
|
+
@re_<%=rule_name%>_data_id = Re<%=rule_class%>Data.create(:since_id => 0).id
|
|
77
88
|
end
|
|
78
89
|
|
|
79
90
|
def before_update()
|
|
80
91
|
end
|
|
81
92
|
|
|
82
93
|
def before_destroy()
|
|
94
|
+
re_<%=rule_name%>_data = Re<%=rule_class%>Data.find_by_id(re_<%=rule_name%>_data_id)
|
|
95
|
+
re_<%=rule_name%>_data.destroy if re_<%=rule_name%>_data
|
|
83
96
|
end
|
|
84
97
|
|
|
85
98
|
##################################################################
|
|
86
99
|
# execute the rule
|
|
87
100
|
def process(process_id, data)
|
|
88
101
|
|
|
89
|
-
|
|
102
|
+
re_<%=rule_name%>_data = Re<%=rule_class%>Data.find_by_id(re_<%=rule_name%>_data_id)
|
|
103
|
+
if (re_<%=rule_name%>_data == nil)
|
|
104
|
+
RulesEngine::Process.auditor.audit(process_id, "Twitter Data Mising", RulesEngine::Process::AUDIT_FAILURE)
|
|
105
|
+
return RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_FAILURE)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
page = 1
|
|
109
|
+
next_page = true
|
|
110
|
+
result_count = 0
|
|
111
|
+
since_id = re_<%=rule_name%>_data.since_id
|
|
112
|
+
success = true
|
|
113
|
+
|
|
114
|
+
while success && next_page && page <= MAX_PAGES
|
|
115
|
+
search = Twitter::Search.new(nil, :user_agent => "RulesEngine")
|
|
116
|
+
search.containing(message)
|
|
117
|
+
search.since(since_id)
|
|
118
|
+
search.page(page)
|
|
119
|
+
search.per_page(TWITTER_RPP)
|
|
120
|
+
fetch = search.fetch
|
|
121
|
+
|
|
122
|
+
since_id = fetch.max_id if fetch.max_id.to_i > since_id.to_i
|
|
123
|
+
page += 1
|
|
124
|
+
next_page = fetch.next_page
|
|
125
|
+
|
|
126
|
+
search.each do | result |
|
|
127
|
+
sub_process_id = RulesEngine::Process.runner.create
|
|
128
|
+
sub_data = RulesEngine::Publish.publisher.get(plan)
|
|
129
|
+
|
|
130
|
+
RulesEngine::Process.auditor.audit(process_id, "Found Tweet : #{result.text}")
|
|
131
|
+
|
|
132
|
+
RulesEngine::Process.auditor.audit(process_id, "Starting Sub Plan #{plan} - #{sub_process_id}", RulesEngine::Process::AUDIT_INFO)
|
|
133
|
+
|
|
134
|
+
success = RulesEngine::Process.runner.run(sub_process_id, sub_data, data.merge(:tweet => result.text, :geo => result.geo))
|
|
135
|
+
|
|
136
|
+
RulesEngine::Process.auditor.audit(process_id, "Finished Sub Plan #{plan} - #{sub_process_id}", success ? RulesEngine::Process::AUDIT_SUCCESS : RulesEngine::Process::AUDIT_FAILURE)
|
|
137
|
+
|
|
138
|
+
break unless success
|
|
139
|
+
end
|
|
140
|
+
end
|
|
90
141
|
|
|
91
|
-
|
|
92
|
-
success = RulesEngine::Process.runner.run(sub_process_id, plan, data.merge(:message => message))
|
|
93
|
-
RulesEngine::Process.auditor.audit(process_id, "Finished Sub Plan #{sub_process_id}", success ? RulesEngine::Process::AUDIT_SUCCESS : RulesEngine::Process::AUDIT_FAILURE)
|
|
142
|
+
re_<%=rule_name%>_data.update_attributes(:since_id => since_id)
|
|
94
143
|
|
|
95
144
|
return success ? RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::NEXT) : RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_FAILURE)
|
|
96
145
|
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
module RulesEngine
|
|
2
|
+
module Rule
|
|
3
|
+
class <%=rule_class%> < RulesEngine::Rule::Definition
|
|
4
|
+
|
|
5
|
+
attr_reader :words
|
|
6
|
+
attr_reader :match_type
|
|
7
|
+
|
|
8
|
+
WORD_MATCH_ANY = 0 unless defined? WORD_MATCH_ANY
|
|
9
|
+
WORD_MATCH_WORD = 1 unless defined? WORD_MATCH_WORD
|
|
10
|
+
WORD_MATCH_BEGIN_WITH = 2 unless defined? WORD_MATCH_BEGIN_WITH
|
|
11
|
+
WORD_MATCH_END_WITH = 3 unless defined? WORD_MATCH_END_WITH
|
|
12
|
+
|
|
13
|
+
##################################################################
|
|
14
|
+
# class options
|
|
15
|
+
self.options =
|
|
16
|
+
{
|
|
17
|
+
:group => 'Twitter',
|
|
18
|
+
:display_name => 'Twitter Word Filter',
|
|
19
|
+
:help_partial => '/re_rule_definitions/<%=rule_name%>/help',
|
|
20
|
+
:new_partial => '/re_rule_definitions/<%=rule_name%>/new',
|
|
21
|
+
:edit_partial => '/re_rule_definitions/<%=rule_name%>/edit'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
##################################################################
|
|
25
|
+
# set the rule data
|
|
26
|
+
def data= data
|
|
27
|
+
if data.nil?
|
|
28
|
+
@title = nil
|
|
29
|
+
@words = nil
|
|
30
|
+
@match_type = WORD_MATCH_ANY
|
|
31
|
+
else
|
|
32
|
+
@title, @words, tmp_match_type = ActiveSupport::JSON.decode(data)
|
|
33
|
+
@match_type =tmp_match_type.to_i
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
##################################################################
|
|
38
|
+
# get the rule attributes
|
|
39
|
+
def title
|
|
40
|
+
@title
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def summary
|
|
44
|
+
"Filter out tweets with the #{words.size == 1 ? 'word' : 'words'} #{words.join(', ')}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def data
|
|
48
|
+
[title, words, match_type.to_s].to_json
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def expected_outcomes
|
|
52
|
+
[{:outcome => RulesEngine::Rule::Outcome::NEXT}]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##################################################################
|
|
56
|
+
# set the rule attributes
|
|
57
|
+
def attributes=(params)
|
|
58
|
+
param_hash = params.symbolize_keys
|
|
59
|
+
|
|
60
|
+
@title = param_hash[:<%=rule_name%>_title]
|
|
61
|
+
|
|
62
|
+
@words = []
|
|
63
|
+
return if param_hash[:<%=rule_name%>_words].nil?
|
|
64
|
+
param_hash[:<%=rule_name%>_words].each do |key, values|
|
|
65
|
+
if values.is_a?(Hash)
|
|
66
|
+
word_hash = values.symbolize_keys
|
|
67
|
+
@words << word_hash[:word].downcase unless word_hash[:word].blank? || word_hash[:_delete] == '1'
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
@match_type = param_hash[:match_type].to_i
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
##################################################################
|
|
75
|
+
# validation and errors
|
|
76
|
+
def valid?
|
|
77
|
+
@errors = {}
|
|
78
|
+
@errors[:<%=rule_name%>_words] = "At least one word must be defined" if words.nil? || words.empty?
|
|
79
|
+
@errors[:<%=rule_name%>_title] = "Title required" if title.blank?
|
|
80
|
+
return @errors.empty?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##################################################################
|
|
84
|
+
# callbacks when the rule is added and removed from a workflow
|
|
85
|
+
def before_create()
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def before_update()
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def before_destroy()
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
##################################################################
|
|
95
|
+
# execute the rule
|
|
96
|
+
# if a match is found procees to the expected outcome
|
|
97
|
+
# it gets the data parameter :tweet
|
|
98
|
+
# it sets the data parameter :match
|
|
99
|
+
def process(process_id, data)
|
|
100
|
+
tweet_words = data[:tweet_words]
|
|
101
|
+
if tweet_words.nil? || tweet_words.empty?
|
|
102
|
+
return RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::NEXT)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
data[:tweet_words] = tweet_words.select do | tweet |
|
|
106
|
+
!words.any? do |word|
|
|
107
|
+
case match_type
|
|
108
|
+
when RulesEngine::Rule::<%=rule_class%>::WORD_MATCH_ANY
|
|
109
|
+
tweet =~ /#{word}/i
|
|
110
|
+
when RulesEngine::Rule::<%=rule_class%>::WORD_MATCH_WORD
|
|
111
|
+
tweet =~ /^#{word}$/i
|
|
112
|
+
when RulesEngine::Rule::<%=rule_class%>::WORD_MATCH_BEGIN_WITH
|
|
113
|
+
(tweet =~ /^#{word}/i) != nil
|
|
114
|
+
when RulesEngine::Rule::<%=rule_class%>::WORD_MATCH_END_WITH
|
|
115
|
+
tweet =~ /#{word}$/i
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::NEXT)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
module RulesEngine
|
|
2
|
+
module Rule
|
|
3
|
+
class <%=rule_class%> < RulesEngine::Rule::Definition
|
|
4
|
+
|
|
5
|
+
##################################################################
|
|
6
|
+
# class options
|
|
7
|
+
self.options =
|
|
8
|
+
{
|
|
9
|
+
:group => 'Twitter',
|
|
10
|
+
:display_name => 'Tweet Word Splitter',
|
|
11
|
+
:help_partial => '/re_rule_definitions/<%=rule_name%>/help',
|
|
12
|
+
:new_partial => '/re_rule_definitions/<%=rule_name%>/new',
|
|
13
|
+
:edit_partial => '/re_rule_definitions/<%=rule_name%>/edit'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
##################################################################
|
|
17
|
+
# set the rule data
|
|
18
|
+
def data= data
|
|
19
|
+
if data.nil?
|
|
20
|
+
@title = nil
|
|
21
|
+
else
|
|
22
|
+
@title, ignore = ActiveSupport::JSON.decode(data)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
##################################################################
|
|
27
|
+
# get the rule attributes
|
|
28
|
+
def title
|
|
29
|
+
@title
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def summary
|
|
33
|
+
"splits the tweet into seperate words and puts the array into the data as :tweet_words"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def data
|
|
37
|
+
[title].to_json
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def expected_outcomes
|
|
41
|
+
[:outcome => RulesEngine::Rule::Outcome::NEXT]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
##################################################################
|
|
45
|
+
# set the rule attributes
|
|
46
|
+
def attributes=(params)
|
|
47
|
+
param_hash = params.symbolize_keys
|
|
48
|
+
|
|
49
|
+
@title = param_hash[:<%=rule_name%>_title]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
##################################################################
|
|
53
|
+
# validation and errors
|
|
54
|
+
def valid?
|
|
55
|
+
@errors = {}
|
|
56
|
+
@errors[:<%=rule_name%>_title] = "Title required" if title.blank?
|
|
57
|
+
return @errors.empty?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
##################################################################
|
|
61
|
+
# callbacks when the rule is added and removed from a workflow
|
|
62
|
+
def before_create()
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def before_update()
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def before_destroy()
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
##################################################################
|
|
72
|
+
# execute the rule
|
|
73
|
+
# this rule does nothing
|
|
74
|
+
def process(process_id, data)
|
|
75
|
+
tweet = data[:tweet] || ""
|
|
76
|
+
|
|
77
|
+
words = tweet.strip.downcase.split(/ /).map do |word|
|
|
78
|
+
word.split(/\b/)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
tweet_words = words.map do |word|
|
|
82
|
+
if word[0] == '#'
|
|
83
|
+
"##{word[1]}"
|
|
84
|
+
elsif word[0] == '@'
|
|
85
|
+
"@#{word[1]}"
|
|
86
|
+
elsif word[0] == 'http'
|
|
87
|
+
word.join()
|
|
88
|
+
elsif word[0] && word[0].gsub(/[^a-z]+/, '').length > 0
|
|
89
|
+
word[0]
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
data[:tweet_words] = tweet_words.compact
|
|
94
|
+
|
|
95
|
+
RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::NEXT)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
class Re<%=rule_class%>List < ActiveRecord::Base
|
|
2
|
+
set_table_name :re_<%=rule_name%>_list
|
|
3
|
+
|
|
4
|
+
def self.find_or_create(word)
|
|
5
|
+
re_word = find(:first, :conditions => ["word = ?", word])
|
|
6
|
+
unless re_word
|
|
7
|
+
re_word = create(:word => word)
|
|
8
|
+
end
|
|
9
|
+
re_word.id
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class Re<%=rule_class%>Count < ActiveRecord::Base
|
|
15
|
+
set_table_name :re_<%=rule_name%>_count
|
|
16
|
+
|
|
17
|
+
belongs_to :word, :class_name => 'Re<%=rule_class%>List', :foreign_key => 'word_id'
|
|
18
|
+
|
|
19
|
+
def self.update_time_codes(word_id)
|
|
20
|
+
now = Time.now;
|
|
21
|
+
[now.strftime("%Y%m%d%H"), now.strftime("%Y%m%d"), now.strftime("%Y%m"), now.strftime("%Y")].each do |time_code|
|
|
22
|
+
re_word_count = find(:first, :conditions => ["time_code = ? AND word_id = ?", time_code, word_id])
|
|
23
|
+
if re_word_count
|
|
24
|
+
re_word_count.update_attributes(:word_count => re_word_count.word_count + 1)
|
|
25
|
+
else
|
|
26
|
+
create(:time_code => time_code, :word_id => word_id, :word_count => 1)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module RulesEngine
|
|
33
|
+
module Rule
|
|
34
|
+
class <%=rule_class%> < RulesEngine::Rule::Definition
|
|
35
|
+
|
|
36
|
+
##################################################################
|
|
37
|
+
# class options
|
|
38
|
+
self.options =
|
|
39
|
+
{
|
|
40
|
+
:group => 'Twitter',
|
|
41
|
+
:display_name => 'Tweet Word Writer',
|
|
42
|
+
:help_partial => '/re_rule_definitions/<%=rule_name%>/help',
|
|
43
|
+
:new_partial => '/re_rule_definitions/<%=rule_name%>/new',
|
|
44
|
+
:edit_partial => '/re_rule_definitions/<%=rule_name%>/edit'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
##################################################################
|
|
48
|
+
# set the rule data
|
|
49
|
+
def data= data
|
|
50
|
+
if data.nil?
|
|
51
|
+
@title = nil
|
|
52
|
+
else
|
|
53
|
+
@title, ignore = ActiveSupport::JSON.decode(data)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
##################################################################
|
|
58
|
+
# get the rule attributes
|
|
59
|
+
def title
|
|
60
|
+
@title
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def summary
|
|
64
|
+
"Write the twitter words to the database"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def data
|
|
68
|
+
[title].to_json
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def expected_outcomes
|
|
72
|
+
[:outcome => RulesEngine::Rule::Outcome::NEXT]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
##################################################################
|
|
76
|
+
# set the rule attributes
|
|
77
|
+
def attributes=(params)
|
|
78
|
+
param_hash = params.symbolize_keys
|
|
79
|
+
|
|
80
|
+
@title = param_hash[:<%=rule_name%>_title]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##################################################################
|
|
84
|
+
# validation and errors
|
|
85
|
+
def valid?
|
|
86
|
+
@errors = {}
|
|
87
|
+
@errors[:<%=rule_name%>_title] = "Title required" if title.blank?
|
|
88
|
+
return @errors.empty?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
##################################################################
|
|
92
|
+
# callbacks when the rule is added and removed from a workflow
|
|
93
|
+
def before_create()
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def before_update()
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def before_destroy()
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
##################################################################
|
|
103
|
+
# execute the rule
|
|
104
|
+
# this rule does nothing
|
|
105
|
+
def process(process_id, data)
|
|
106
|
+
(data[:tweet_words] || []).each do |word|
|
|
107
|
+
word_id = Re<%=rule_class%>List.find_or_create(word)
|
|
108
|
+
Re<%=rule_class%>Count.update_time_codes(word_id)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::NEXT)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -41,7 +41,7 @@ module RulesEngine
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def expected_outcomes
|
|
44
|
-
[:outcome => RulesEngine::Rule::Outcome::START_WORKFLOW, :
|
|
44
|
+
[:outcome => RulesEngine::Rule::Outcome::START_WORKFLOW, :title => "Start workflow : #{workflow}"]
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
##################################################################
|
|
@@ -2,7 +2,6 @@ module RulesEngine
|
|
|
2
2
|
module Rule
|
|
3
3
|
class <%=rule_class%> < RulesEngine::Rule::Definition
|
|
4
4
|
|
|
5
|
-
attr_reader :description
|
|
6
5
|
##################################################################
|
|
7
6
|
# class options
|
|
8
7
|
self.options =
|
|
@@ -19,9 +18,8 @@ module RulesEngine
|
|
|
19
18
|
def data= data
|
|
20
19
|
if data.nil?
|
|
21
20
|
@title = nil
|
|
22
|
-
@description = nil
|
|
23
21
|
else
|
|
24
|
-
@title,
|
|
22
|
+
@title, ignore = ActiveSupport::JSON.decode(data)
|
|
25
23
|
end
|
|
26
24
|
end
|
|
27
25
|
|
|
@@ -32,15 +30,15 @@ module RulesEngine
|
|
|
32
30
|
end
|
|
33
31
|
|
|
34
32
|
def summary
|
|
35
|
-
|
|
33
|
+
"Stop the workflow"
|
|
36
34
|
end
|
|
37
35
|
|
|
38
36
|
def data
|
|
39
|
-
[title
|
|
37
|
+
[title].to_json
|
|
40
38
|
end
|
|
41
39
|
|
|
42
40
|
def expected_outcomes
|
|
43
|
-
[:outcome => RulesEngine::Rule::Outcome::STOP_SUCCESS]
|
|
41
|
+
[:outcome => RulesEngine::Rule::Outcome::STOP_SUCCESS, :title => "Stop the workflow"]
|
|
44
42
|
end
|
|
45
43
|
|
|
46
44
|
##################################################################
|
|
@@ -49,7 +47,6 @@ module RulesEngine
|
|
|
49
47
|
param_hash = params.symbolize_keys
|
|
50
48
|
|
|
51
49
|
@title = param_hash[:<%=rule_name%>_title]
|
|
52
|
-
@description = param_hash[:<%=rule_name%>_description]
|
|
53
50
|
end
|
|
54
51
|
|
|
55
52
|
##################################################################
|
|
@@ -62,10 +59,13 @@ module RulesEngine
|
|
|
62
59
|
|
|
63
60
|
##################################################################
|
|
64
61
|
# callbacks when the rule is added and removed from a workflow
|
|
65
|
-
def
|
|
62
|
+
def before_create()
|
|
66
63
|
end
|
|
67
64
|
|
|
68
|
-
def
|
|
65
|
+
def before_update()
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def before_destroy()
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
##################################################################
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<%%= re_text_field "Title",
|
|
10
10
|
"<%=rule_name%>_title",
|
|
11
|
-
params[:<%=rule_name%>_title] || @re_rule.rule.title,
|
|
11
|
+
params[:<%=rule_name%>_title] || @re_rule.rule.title || @re_rule.rule.options[:display_name],
|
|
12
12
|
:size => 30,
|
|
13
13
|
:required => true,
|
|
14
14
|
:error => @re_rule.rule.errors[:<%=rule_name%>_title],
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
<%%= re_text_field "Title",
|
|
12
12
|
"<%=rule_name%>_title",
|
|
13
|
-
params[:<%=rule_name%>_title] || @re_rule.rule.title,
|
|
13
|
+
params[:<%=rule_name%>_title] || @re_rule.rule.title || @re_rule.rule.options[:display_name],
|
|
14
14
|
:size => 30,
|
|
15
15
|
:required => true,
|
|
16
16
|
:error => @re_rule.rule.errors[:<%=rule_name%>_title],
|
|
@@ -32,3 +32,13 @@
|
|
|
32
32
|
<div id="new_position_<%=rule_name%>"></div>
|
|
33
33
|
<%%= re_form_text "", re_add_link('Add another word to filter', '<%=rule_name%>') %>
|
|
34
34
|
|
|
35
|
+
q<%%= re_select "Match Type", '<%=rule_name%>_match_type',
|
|
36
|
+
options_for_select([
|
|
37
|
+
["Any Match", RulesEngine::Rule::<%=rule_class%>::TWEET_MATCH_ANY],
|
|
38
|
+
["Whole Twitter Message", RulesEngine::Rule::<%=rule_class%>::TWEET_MATCH_TWEET],
|
|
39
|
+
["Exact Word", RulesEngine::Rule::<%=rule_class%>::TWEET_MATCH_WORD],
|
|
40
|
+
["Begins With", RulesEngine::Rule::<%=rule_class%>::TWEET_MATCH_BEGIN_WITH],
|
|
41
|
+
["End With", RulesEngine::Rule::<%=rule_class%>::TWEET_MATCH_END_WITH]
|
|
42
|
+
],
|
|
43
|
+
params['<%=rule_name%>_match_type'].to_i || @re_rule.rule.match_type),
|
|
44
|
+
:required => true %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%%= render '/re_rule_definitions/<%=rule_name%>/form', :f => f %>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<%% javascript_tag do %>
|
|
2
|
+
$(document).ready(function() {
|
|
3
|
+
$('#<%=rule_name%>_title').focus();
|
|
4
|
+
});
|
|
5
|
+
|
|
6
|
+
<%% end %>
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
<%%= re_text_field "Title",
|
|
10
|
+
"<%=rule_name%>_title",
|
|
11
|
+
params[:<%=rule_name%>_title] || @re_rule.rule.title || @re_rule.rule.options[:display_name],
|
|
12
|
+
:size => 30,
|
|
13
|
+
:required => true,
|
|
14
|
+
:error => @re_rule.rule.errors[:<%=rule_name%>_title],
|
|
15
|
+
:span => '4x13' %>
|
|
16
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<p>This will filter out any retweets</p>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%%= render '/re_rule_definitions/<%=rule_name%>/form', :f => f %>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<%%= re_text_field "Title",
|
|
10
10
|
"<%=rule_name%>_title",
|
|
11
|
-
params[:<%=rule_name%>_title] || @re_rule.rule.title,
|
|
11
|
+
params[:<%=rule_name%>_title] || @re_rule.rule.title || @re_rule.rule.options[:display_name],
|
|
12
12
|
:size => 30,
|
|
13
13
|
:required => true,
|
|
14
14
|
:error => @re_rule.rule.errors[:<%=rule_name%>_title],
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<%%= re_text_field "Message",
|
|
18
18
|
"<%=rule_name%>_message",
|
|
19
19
|
params[:<%=rule_name%>_message] || @re_rule.rule.message,
|
|
20
|
-
:size =>
|
|
20
|
+
:size => 40,
|
|
21
21
|
:required => true,
|
|
22
22
|
:error => @re_rule.rule.errors[:<%=rule_name%>_message],
|
|
23
23
|
:span => '4x13' %>
|
data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_filter/_edit.html.erb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%%= render '/re_rule_definitions/<%=rule_name%>/form', :f => f %>
|
data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_filter/_form.html.erb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<%% javascript_tag do %>
|
|
2
|
+
var new_<%=rule_name%> = '<%%=escape_javascript(render("/re_rule_definitions/<%=rule_name%>/form_word"))%>'
|
|
3
|
+
|
|
4
|
+
$(document).ready(function() {
|
|
5
|
+
$('#<%=rule_name%>_title').focus();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
<%% end %>
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
<%%= re_text_field "Title",
|
|
12
|
+
"<%=rule_name%>_title",
|
|
13
|
+
params[:<%=rule_name%>_title] || @re_rule.rule.title || @re_rule.rule.options[:display_name],
|
|
14
|
+
:size => 30,
|
|
15
|
+
:required => true,
|
|
16
|
+
:error => @re_rule.rule.errors[:<%=rule_name%>_title],
|
|
17
|
+
:span => '4x13' %>
|
|
18
|
+
|
|
19
|
+
<%% position = 0 %>
|
|
20
|
+
<%% (@re_rule.rule.words || []).each do | word | %>
|
|
21
|
+
<%% f.fields_for :rule_data, {:first => false} do |frd| %>
|
|
22
|
+
<%%= render '/re_rule_definitions/<%=rule_name%>/form_word', :f => frd, :position => position, :word => word %>
|
|
23
|
+
<%% position += 1 %>
|
|
24
|
+
<%% end %>
|
|
25
|
+
<%% end %>
|
|
26
|
+
<%% if position == 0 %>
|
|
27
|
+
<%% f.fields_for :rule_data, {:first => false} do |frd| %>
|
|
28
|
+
<%%= render '/re_rule_definitions/<%=rule_name%>/form_word', :f => frd, :position => position %>
|
|
29
|
+
<%% end %>
|
|
30
|
+
<%% end %>
|
|
31
|
+
|
|
32
|
+
<div id="new_position_<%=rule_name%>"></div>
|
|
33
|
+
<%%= re_form_text "", re_add_link('Add another word to filter', '<%=rule_name%>') %>
|
|
34
|
+
|
|
35
|
+
<div class="clear top-5"></div>
|
|
36
|
+
<hr/>
|
|
37
|
+
<%%= re_select "Match Type", '<%=rule_name%>_match_type',
|
|
38
|
+
options_for_select([
|
|
39
|
+
["Any Match", RulesEngine::Rule::<%=rule_class%>::WORD_MATCH_ANY],
|
|
40
|
+
["Exact Word", RulesEngine::Rule::<%=rule_class%>::WORD_MATCH_WORD],
|
|
41
|
+
["Begins With", RulesEngine::Rule::<%=rule_class%>::WORD_MATCH_BEGIN_WITH],
|
|
42
|
+
["End With", RulesEngine::Rule::<%=rule_class%>::WORD_MATCH_END_WITH]
|
|
43
|
+
],
|
|
44
|
+
params['<%=rule_name%>_match_type'].to_i || @re_rule.rule.match_type),
|
|
45
|
+
:required => true %>
|
data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_filter/_help.html.erb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<p>This will filter out any tweets with the matching word</p>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%%= render '/re_rule_definitions/<%=rule_name%>/form', :f => f %>
|
data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_splitter/_edit.html.erb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%%= render '/re_rule_definitions/<%=rule_name%>/form' %>
|
data/rails_generators/templates/app/views/re_rule_definitions/tweet_word_splitter/_form.html.erb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<%% javascript_tag do %>
|
|
2
|
+
|
|
3
|
+
$(document).ready(function() {
|
|
4
|
+
$('#<%=rule_name%>_title').focus();
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
<%% end %>
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
<%%= re_text_field "Title",
|
|
11
|
+
"<%=rule_name%>_title",
|
|
12
|
+
params[:<%=rule_name%>_title] || @re_rule.rule.title || @re_rule.rule.options[:display_name],
|
|
13
|
+
:size => 30,
|
|
14
|
+
:required => true,
|
|
15
|
+
:error => @re_rule.rule.errors[:<%=rule_name%>_title],
|
|
16
|
+
:span => '4x13' %>
|