module Birdwatcher module Commands class Status < Birdwatcher::Command self.meta = { :description => "Manage statuses", :names => %w(status statuses tweet tweets), :usage => "status [ACTION]" } def self.detailed_usage <<-USAGE The #{'status'.bold} command manipulates statuses in the current workspace. #{'USAGE:'.bold} #{'List the last 1000 statuses from all users:'.bold} status list #{'List the last 1000 statuses from specific users:'.bold} status list [USER1[ USER2 ... USERN]] #{'Fetch and process new statuses from all users:'.bold} status fetch #{'Search all statuses for a specific word:'.bold} status search SEARCHTERM USAGE end def run if !arguments? error("You must provide an action") return false end action = arguments.first.downcase case action when "list", "-l", "show", "-s" list_statuses(arguments[1..-1]) when "search", "-s", "find" search_statuses when "fetch", "-f", "update", "-u" fetch_statuses else list_statuses(arguments) end end private def fetch_statuses current_workspace.users_dataset.order(:screen_name).each do |user| statuses = [] task("Fetching statuses for #{user.screen_name.bold}...") do statuses = get_statuses_for_user(user) end task("Processing #{Birdwatcher::Util.pluralize(statuses.count, 'status', 'statuses')}...") do threads = thread_pool statuses.each do |status| threads.process do save_status(status, user) end end threads.shutdown end end end def search_statuses search_term = arguments[1..-1].join(" ").downcase if search_term.empty? error("You must provide a search term") return false end statuses = current_workspace.statuses_dataset .where("lower(text) LIKE ?", "%#{search_term}%") .order(Sequel.desc(:posted_at)) .eager(:user) .limit(1000) texts = statuses.map { |s| make_status_summary_output(s) }.join("\n#{Birdwatcher::Console::LINE_SEPARATOR}\n\n") page_text(texts) end def list_statuses(screen_names = nil) if screen_names.nil? || screen_names.empty? statuses = current_workspace.statuses_dataset.order(Sequel.desc(:posted_at)).eager(:user).limit(1000) else user_ids = current_workspace.users_dataset.where("screen_name IN ?", screen_names).map(:id) statuses = current_workspace.statuses_dataset.where("user_id IN ?", user_ids).order(Sequel.desc(:posted_at)).eager(:user).limit(1000) end texts = statuses.map { |s| make_status_summary_output(s) }.join("\n#{Birdwatcher::Console::LINE_SEPARATOR}\n\n") page_text(texts) end def collect_with_max_id(collection = [], max_id = nil, pages = 5, &block) return collection.flatten if pages.zero? response = yield(max_id) collection += response response.empty? ? collection.flatten : collect_with_max_id(collection, response.last.id - 1, pages - 1, &block) end def get_statuses_for_user(user) if last_status = user.statuses_dataset.order(Sequel.desc(:posted_at)).first since_id = last_status.twitter_id end collect_with_max_id do |max_id| options = {:count => 200, :include_rts => true} options[:since_id] = since_id unless since_id.nil? options[:max_id] = max_id unless max_id.nil? twitter_client.user_timeline(user.screen_name, options) end end end end end