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 :message attr_reader :plan attr_reader :re_<%=rule_name%>_data_id ################################################################## # class options self.options = { :group => 'Twitter', :display_name => 'Twitter Reader', :help_partial => '/re_rule_definitions/<%=rule_name%>/help', :new_partial => '/re_rule_definitions/<%=rule_name%>/new', :edit_partial => '/re_rule_definitions/<%=rule_name%>/edit' } ################################################################## # set the rule data def data= data if data.nil? @title = nil @message = nil @plan = nil @re_<%=rule_name%>_data_id = nil else @title, @message, @plan, 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 \"#{message}\" and send matches to the plan : #{plan}" end def data [title, message, plan, 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 plan fails"} ] end ################################################################## # set the rule attributes def attributes=(params) param_hash = params.symbolize_keys @title = param_hash[:<%=rule_name%>_title] @message = param_hash[:<%=rule_name%>_message] @plan = param_hash[:<%=rule_name%>_plan] end ################################################################## # validation and errors def valid? @errors = {} @errors[:<%=rule_name%>_title] = "Title required" if title.blank? @errors[:<%=rule_name%>_message] = "Message required" if message.blank? @errors[:<%=rule_name%>_plan] = "Plan required" if plan.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() 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, 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(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 | sub_process_id = RulesEngine::Process.runner.create sub_data = RulesEngine::Publish.publisher.get(plan) RulesEngine::Process.auditor.audit(process_id, "Found Tweet : #{result.text}") RulesEngine::Process.auditor.audit(process_id, "Starting Sub Plan #{plan} - #{sub_process_id}", RulesEngine::Process::AUDIT_INFO) success = RulesEngine::Process.runner.run(sub_process_id, sub_data, data.merge(:tweet => result.text, :geo => result.geo)) RulesEngine::Process.auditor.audit(process_id, "Finished Sub Plan #{plan} - #{sub_process_id}", 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