/
list.rb
132 lines (120 loc) · 6.5 KB
/
list.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
require 'thor'
require 'twitter'
require 't/collectable'
require 't/printable'
require 't/rcfile'
require 't/requestable'
require 't/utils'
module T
class List < Thor
include T::Collectable
include T::Printable
include T::Requestable
include T::Utils
DEFAULT_NUM_RESULTS = 20
MAX_USERS_PER_LIST = 500
MAX_USERS_PER_REQUEST = 100
check_unknown_options!
class_option "host", :aliases => "-H", :type => :string, :default => T::Requestable::DEFAULT_HOST, :desc => "Twitter API server"
class_option "no-color", :aliases => "-N", :type => :boolean, :desc => "Disable colorization in output"
class_option "no-ssl", :aliases => "-U", :type => :boolean, :default => false, :desc => "Disable SSL"
class_option "profile", :aliases => "-P", :type => :string, :default => File.join(File.expand_path("~"), T::RCFile::FILE_NAME), :desc => "Path to RC file", :banner => "FILE"
def initialize(*)
@rcfile = T::RCFile.instance
super
end
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, number = fetch_users(users.unshift(user), options) do |users|
client.list_add_members(list, users)
users
end
say "@#{@rcfile.active_profile[0]} added #{pluralize(number, 'member')} to the list \"#{list}\"."
say
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 [DESCRIPTION]", "Create a new list."
method_option "private", :aliases => "-p", :type => :boolean
def create(list, description=nil)
opts = description ? {:description => description} : {}
opts.merge!(:mode => 'private') if options['private']
client.list_create(list, opts)
say "@#{@rcfile.active_profile[0]} created the list \"#{list}\"."
end
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 = extract_owner(list, options)
list = client.list(owner, list)
if options['csv']
require 'csv'
require 'fastercsv' unless Array.new.respond_to?(:to_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, csv_formatted_time(list), 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}"]
array << ["Created at", "#{ls_formatted_time(list)} (#{time_ago_in_words(list.created_at)} ago)"]
array << ["Members", number_with_delimiter(list.member_count)]
array << ["Subscribers", number_with_delimiter(list.subscriber_count)]
array << ["Status", list.following ? "Following" : "Not following"]
array << ["Mode", list.mode]
array << ["URL", "https://twitter.com#{list.uri}"]
print_table(array)
end
end
map %w(details) => :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 "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 "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
method_option "sort", :aliases => "-s", :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => "screen_name", :desc => "Specify the order of the results.", :banner => "ORDER"
method_option "unsorted", :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
def members(list)
owner, list = extract_owner(list, options)
users = collect_with_cursor do |cursor|
client.list_members(owner, list, :cursor => cursor, :skip_status => true)
end
print_users(users)
end
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, number = fetch_users(users.unshift(user), options) do |users|
client.list_remove_members(list, users)
users
end
say "@#{@rcfile.active_profile[0]} removed #{pluralize(number, 'member')} from the list \"#{list}\"."
say
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 [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."
def timeline(list)
owner, list = extract_owner(list, options)
count = options['number'] || DEFAULT_NUM_RESULTS
tweets = collect_with_count(count) do |opts|
client.list_timeline(owner, list, opts)
end
print_tweets(tweets)
end
map %w(tl) => :timeline
end
end