require 'twitter' MAX_PAGES = 5 unless defined?(MAX_PAGES) TWITTER_RPP = 40 unless defined?(TWITTER_RPP) class Re<%=rule_class%>Data < ActiveRecord::Base set_table_name :re_<%=rule_name%>_data end module RulesEngine module Rule class <%=rule_class%> < RulesEngine::Rule::Definition attr_reader :twitter_message attr_reader :workflow_code attr_reader :re_<%=rule_name%>_data_id ################################################################## # class options self.options = { :group => 'Twitter', :display_name => 'Twitter Reader', :help_partial => '/re_rules/<%=rule_name%>/help', :new_partial => '/re_rules/<%=rule_name%>/new', :edit_partial => '/re_rules/<%=rule_name%>/edit' } ################################################################## # set the rule data def data= data if data.nil? @title = nil @twitter_message = nil @workflow_code = nil @re_<%=rule_name%>_data_id = nil else @title, @twitter_message, @workflow_code, data_id = ActiveSupport::JSON.decode(data) @re_<%=rule_name%>_data_id = data_id.to_i end end ################################################################## # get the rule attributes def title @title end def summary "Look for \"#{twitter_message}\" and send matches to the workflow : #{workflow_code}" end def data [title, twitter_message, workflow_code, re_<%=rule_name%>_data_id.to_s].to_json end def expected_outcomes [ {:outcome => RulesEngine::Rule::Outcome::NEXT}, {:outcome => RulesEngine::Rule::Outcome::STOP_FAILURE, :title => "Stop if workflow fails"} ] end ################################################################## # set the rule attributes def attributes=(params) param_hash = params.symbolize_keys @title = param_hash[:<%=rule_name%>_title] @twitter_message = param_hash[:<%=rule_name%>_twitter_message] @workflow_code = param_hash[:<%=rule_name%>_workflow_code] end ################################################################## # validation and errors def valid? @errors = {} @errors[:<%=rule_name%>_title] = "Title required" if title.blank? @errors[:<%=rule_name%>_twitter_message] = "Message required" if twitter_message.blank? @errors[:<%=rule_name%>_workflow_code] = "Workflow required" if workflow_code.blank? return @errors.empty? end ################################################################## # callbacks when the rule is added and removed from a workflow def before_create() @re_<%=rule_name%>_data_id = Re<%=rule_class%>Data.create(:since_id => 0).id end def before_update() @re_<%=rule_name%>_data_id = Re<%=rule_class%>Data.create(:since_id => 0).id unless re_<%=rule_name%>_data_id && Re<%=rule_class%>Data.find_by_id(re_<%=rule_name%>_data_id) end def before_destroy() re_<%=rule_name%>_data = Re<%=rule_class%>Data.find_by_id(re_<%=rule_name%>_data_id) re_<%=rule_name%>_data.destroy if re_<%=rule_name%>_data end ################################################################## # execute the rule def process(process_id, plan, data) re_<%=rule_name%>_data = Re<%=rule_class%>Data.find_by_id(re_<%=rule_name%>_data_id) if (re_<%=rule_name%>_data == nil) RulesEngine::Process.auditor.audit(process_id, "Twitter Data Mising", RulesEngine::Process::AUDIT_FAILURE) return RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_FAILURE) end page = 1 next_page = true result_count = 0 since_id = re_<%=rule_name%>_data.since_id success = true while success && next_page && page <= MAX_PAGES search = Twitter::Search.new(nil, :user_agent => "RulesEngine") search.containing(twitter_message) search.since(since_id) search.page(page) search.per_page(TWITTER_RPP) fetch = search.fetch since_id = fetch.max_id if fetch.max_id.to_i > since_id.to_i page += 1 next_page = fetch.next_page search.each do | result | RulesEngine::Process.auditor.audit(process_id, "Found Tweet : #{result.text}") RulesEngine::Process.auditor.audit(process_id, "Starting Workflow #{workflow_code}", RulesEngine::Process::AUDIT_INFO) success = RulesEngine::Process.runner.run_workflow(process_id, plan, workflow_code, data.merge(:tweet => result.text, :geo => result.geo)) RulesEngine::Process.auditor.audit(process_id, "Finished Workflow #{workflow_code}", success ? RulesEngine::Process::AUDIT_SUCCESS : RulesEngine::Process::AUDIT_FAILURE) break unless success end end re_<%=rule_name%>_data.update_attributes(:since_id => since_id) return success ? RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::NEXT) : RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_FAILURE) end end end end