lib/t/list.rb in t-0.6.4 vs lib/t/list.rb in t-0.7.0
- old
+ new
@@ -1,7 +1,10 @@
require 'action_view'
require 'active_support/core_ext/array/grouping'
+require 'csv'
+# 'fastercsv' required on Ruby versions < 1.9
+require 'fastercsv' unless Array.new.respond_to?(:to_csv)
require 'retryable'
require 't/collectable'
require 't/core_ext/enumerable'
require 't/core_ext/string'
require 't/printable'
@@ -26,86 +29,154 @@
def initialize(*)
super
@rcfile = RCFile.instance
end
- desc "add LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Add members to a list."
- def add(list_name, screen_name, *screen_names)
- screen_names.unshift(screen_name)
- screen_names.map!(&:strip_ats)
- screen_names.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
+ desc "add LIST USER [USER...]", "Add members to a list."
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
+ def add(list, user, *users)
+ users.unshift(user)
+ if options['id']
+ users.map!(&:to_i)
+ else
+ users.map!(&:strip_ats)
+ end
+ users.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
- client.list_add_members(list_name, user_id_group)
+ client.list_add_members(list, user_id_group)
end
end
- number = screen_names.length
- say "@#{@rcfile.default_profile[0]} added #{number} #{number == 1 ? 'member' : 'members'} to the list \"#{list_name}\"."
+ number = users.length
+ say "@#{@rcfile.default_profile[0]} added #{number} #{number == 1 ? 'member' : 'members'} to the list \"#{list}\"."
say
- say "Run `#{File.basename($0)} list remove #{list_name} #{screen_names.join(' ')}` to undo."
+ if options['id']
+ say "Run `#{File.basename($0)} list remove --id #{list} #{users.join(' ')}` to undo."
+ else
+ say "Run `#{File.basename($0)} list remove #{list} #{users.map{|user| "@#{user}"}.join(' ')}` to undo."
+ end
end
- desc "create LIST_NAME [DESCRIPTION]", "Create a new list."
+ desc "create LIST [DESCRIPTION]", "Create a new list."
method_option :private, :aliases => "-p", :type => :boolean
- def create(list_name, description="")
+ def create(list, description="")
opts = description.blank? ? {} : {:description => description}
opts.merge!(:mode => 'private') if options['private']
- client.list_create(list_name, opts)
- say "@#{@rcfile.default_profile[0]} created the list \"#{list_name}\"."
+ client.list_create(list, opts)
+ say "@#{@rcfile.default_profile[0]} created the list \"#{list}\"."
end
- desc "members [SCREEN_NAME] LIST_NAME", "Returns the members of a Twitter list."
- method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
+ desc "information [USER/]LIST", "Retrieves detailed information about a Twitter list."
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
+ def information(list)
+ owner, list = list.split('/')
+ if list.nil?
+ list = owner
+ owner = @rcfile.default_profile[0]
+ else
+ owner = if options['id']
+ owner.to_i
+ else
+ owner.strip_ats
+ end
+ end
+ list = client.list(owner, list)
+ if options['csv']
+ say ["ID", "Description", "Slug", "Screen name", "Created at", "Members", "Subscribers", "Following", "Mode", "URL"].to_csv
+ say [list.id, list.description, list.slug, list.user.screen_name, list.created_at.utc.strftime("%Y-%m-%d %H:%M:%S %z"), list.member_count, list.subscriber_count, list.following?, list.mode, "https://twitter.com#{list.uri}"].to_csv
+ else
+ array = []
+ array << ["ID", list.id.to_s]
+ array << ["Description", list.description] unless list.description.nil?
+ array << ["Slug", list.slug]
+ array << ["Screen name", "@#{list.user.screen_name}"]
+ created_at = list.created_at > 6.months.ago ? list.created_at.strftime("%b %e %H:%M") : list.created_at.strftime("%b %e %Y")
+ array << ["Created at", created_at]
+ array << ["Members", number_with_delimiter(list.member_count)]
+ array << ["Subscribers", number_with_delimiter(list.subscriber_count)]
+ status = list.following ? "Following" : "Not following"
+ array << ["Status", status]
+ array << ["Mode", list.mode]
+ array << ["URL", "https://twitter.com#{list.uri}"]
+ print_table(array)
+ end
+ end
+ map %w(detail) => :information
+
+ desc "members [USER/]LIST", "Returns the members of a Twitter list."
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
- method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
- method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
+ method_option :friends, :aliases => "-e", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify user via ID instead of screen name."
+ method_option :listed, :aliases => "-s", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
+ method_option :posted, :aliases => "-p", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter account was posted."
method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
- def members(*args)
- list = args.pop
- owner = args.pop || @rcfile.default_profile[0]
- owner = owner.strip_ats
+ def members(list)
+ owner, list = list.split('/')
+ if list.nil?
+ list = owner
+ owner = @rcfile.default_profile[0]
+ else
+ owner = if options['id']
+ owner.to_i
+ else
+ owner.strip_ats
+ end
+ end
users = collect_with_cursor do |cursor|
client.list_members(owner, list, :cursor => cursor, :include_entities => false, :skip_status => true)
end
- print_user_list(users)
+ print_users(users)
end
- desc "remove LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Remove members from a list."
- def remove(list_name, screen_name, *screen_names)
- screen_names.unshift(screen_name)
- screen_names.map!(&:strip_ats)
- screen_names.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
+ desc "remove LIST USER [USER...]", "Remove members from a list."
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
+ def remove(list, user, *users)
+ users.unshift(user)
+ if options['id']
+ users.map!(&:to_i)
+ else
+ users.map!(&:strip_ats)
+ end
+ users.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
- client.list_remove_members(list_name, user_id_group)
+ client.list_remove_members(list, user_id_group)
end
end
- number = screen_names.length
- say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{list_name}\"."
+ number = users.length
+ say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{list}\"."
say
- say "Run `#{File.basename($0)} list add #{list_name} #{screen_names.join(' ')}` to undo."
+ if options['id']
+ say "Run `#{File.basename($0)} list add --id #{list} #{users.join(' ')}` to undo."
+ else
+ say "Run `#{File.basename($0)} list add #{list} #{users.map{|user| "@#{user}"}.join(' ')}` to undo."
+ end
end
- desc "timeline [SCREEN_NAME] LIST_NAME", "Show tweet timeline for members of the specified list."
- method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
- method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
- method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
- method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
- method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
+ desc "timeline [USER/]LIST", "Show tweet timeline for members of the specified list."
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify user via ID instead of screen name."
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
- method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
- method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
- def timeline(*args)
- list = args.pop
- owner = args.pop || @rcfile.default_profile[0]
- owner = owner.strip_ats
+ def timeline(list)
+ owner, list = list.split('/')
+ if list.nil?
+ list = owner
+ owner = @rcfile.default_profile[0]
+ else
+ owner = if options['id']
+ owner.to_i
+ else
+ owner.strip_ats
+ end
+ end
per_page = options['number'] || DEFAULT_NUM_RESULTS
statuses = client.list_timeline(owner, list, :include_entities => false, :per_page => per_page)
- print_status_list(statuses)
+ print_statuses(statuses)
end
map %w(tl) => :timeline
end
end