t 0.6.4 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,9 @@
1
1
  class String
2
2
 
3
+ def prepend_at
4
+ "@#{self}"
5
+ end
6
+
3
7
  def strip_ats
4
8
  self.tr('@', '')
5
9
  end
data/lib/t/delete.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 't/core_ext/enumerable'
1
2
  require 't/core_ext/string'
2
3
  require 't/rcfile'
3
4
  require 't/requestable'
@@ -14,69 +15,83 @@ module T
14
15
  @rcfile = RCFile.instance
15
16
  end
16
17
 
17
- desc "block SCREEN_NAME [SCREEN_NAME...]", "Unblock users."
18
- def block(screen_name, *screen_names)
19
- screen_names.unshift(screen_name)
20
- screen_names.map!(&:strip_ats)
21
- screen_names.threaded_each do |screen_name|
22
- screen_name.strip_ats
18
+ desc "block USER [USER...]", "Unblock users."
19
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
20
+ method_option :force, :aliases => "-f", :type => :boolean, :default => false
21
+ def block(user, *users)
22
+ users.unshift(user)
23
+ if options['id']
24
+ users.map!(&:to_i)
25
+ else
26
+ users.map!(&:strip_ats)
27
+ end
28
+ users = users.threaded_map do |user|
23
29
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
24
- client.unblock(screen_name, :include_entities => false)
30
+ client.unblock(user, :include_entities => false)
25
31
  end
26
32
  end
27
- number = screen_names.length
33
+ number = users.length
28
34
  say "@#{@rcfile.default_profile[0]} unblocked #{number} #{number == 1 ? 'user' : 'users'}."
29
35
  say
30
- say "Run `#{File.basename($0)} block #{screen_names.map{|screen_name| "@#{screen_name}"}.join(' ')}` to block."
36
+ say "Run `#{File.basename($0)} block #{users.map{|user| "@#{user.screen_name}"}.join(' ')}` to block."
31
37
  end
32
38
 
33
39
  desc "dm [DIRECT_MESSAGE_ID] [DIRECT_MESSAGE_ID...]", "Delete the last Direct Message sent."
40
+ method_option :force, :aliases => "-f", :type => :boolean, :default => false
34
41
  def dm(direct_message_id, *direct_message_ids)
35
42
  direct_message_ids.unshift(direct_message_id)
36
- direct_message_ids.map!(&:strip_commas).map!(&:to_i)
43
+ direct_message_ids.map!(&:strip_commas)
37
44
  direct_message_ids.each do |direct_message_id|
38
45
  unless options['force']
39
- direct_message = client.direct_message(direct_message_id, :include_entities => false)
46
+ direct_message = client.direct_message(direct_message_id.to_i, :include_entities => false)
40
47
  return unless yes? "Are you sure you want to permanently delete the direct message to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\"? [y/N]"
41
48
  end
42
- direct_message = client.direct_message_destroy(direct_message_id, :include_entities => false)
49
+ direct_message = client.direct_message_destroy(direct_message_id.to_i, :include_entities => false)
43
50
  say "@#{@rcfile.default_profile[0]} deleted the direct message sent to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\""
44
51
  end
45
52
  end
46
- map %w(m) => :dm
53
+ map %w(d m) => :dm
47
54
 
48
55
  desc "favorite STATUS_ID [STATUS_ID...]", "Delete favorites."
56
+ method_option :force, :aliases => "-f", :type => :boolean, :default => false
49
57
  def favorite(status_id, *status_ids)
50
58
  status_ids.unshift(status_id)
59
+ status_ids.map!(&:strip_commas)
51
60
  status_ids.each do |status_id|
52
61
  unless options['force']
53
- status = client.status(status_id, :include_entities => false, :include_my_retweet => false, :trim_user => true)
62
+ status = client.status(status_id.to_i, :include_entities => false, :include_my_retweet => false, :trim_user => true)
54
63
  return unless yes? "Are you sure you want to remove @#{status.user.screen_name}'s status: \"#{status.text}\" from your favorites? [y/N]"
55
64
  end
56
- status = client.unfavorite(status_id, :include_entities => false)
65
+ status = client.unfavorite(status_id.to_i, :include_entities => false)
57
66
  say "@#{@rcfile.default_profile[0]} unfavorited @#{status.user.screen_name}'s status: \"#{status.text}\""
58
67
  end
59
68
  end
60
- map %w(post tweet update) => :status
69
+ map %w(fave favourite) => :favorite
61
70
 
62
- desc "list LIST_NAME", "Delete a list."
63
- def list(list_name)
71
+ desc "list LIST", "Delete a list."
72
+ method_option :force, :aliases => "-f", :type => :boolean, :default => false
73
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify list via ID instead of slug."
74
+ def list(list)
75
+ list = list.to_i if options['id']
76
+ list = client.list(list)
64
77
  unless options['force']
65
- return unless yes? "Are you sure you want to permanently delete the list \"#{list_name}\"? [y/N]"
78
+ return unless yes? "Are you sure you want to permanently delete the list \"#{list.name}\"? [y/N]"
66
79
  end
67
- status = client.list_destroy(list_name)
68
- say "@#{@rcfile.default_profile[0]} deleted the list \"#{list_name}\"."
80
+ list = client.list_destroy(list.id)
81
+ say "@#{@rcfile.default_profile[0]} deleted the list \"#{list.name}\"."
69
82
  end
70
83
 
71
84
  desc "status STATUS_ID [STATUS_ID...]", "Delete Tweets."
85
+ method_option :force, :aliases => "-f", :type => :boolean, :default => false
72
86
  def status(status_id, *status_ids)
73
87
  status_ids.unshift(status_id)
88
+ status_ids.map!(&:strip_commas)
74
89
  status_ids.each do |status_id|
75
90
  unless options['force']
76
- status = client.status(status_id, :include_entities => false, :include_my_retweet => false, :trim_user => true)
91
+ status = client.status(status_id.to_i, :include_entities => false, :include_my_retweet => false, :trim_user => true)
77
92
  return unless yes? "Are you sure you want to permanently delete @#{status.user.screen_name}'s status: \"#{status.text}\"? [y/N]"
78
93
  end
79
- status = client.status_destroy(status_id, :include_entities => false, :trim_user => true)
94
+ status = client.status_destroy(status_id.to_i, :include_entities => false, :trim_user => true)
80
95
  say "@#{@rcfile.default_profile[0]} deleted the status: \"#{status.text}\""
81
96
  end
82
97
  end
data/lib/t/list.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  require 'action_view'
2
2
  require 'active_support/core_ext/array/grouping'
3
+ require 'csv'
4
+ # 'fastercsv' required on Ruby versions < 1.9
5
+ require 'fastercsv' unless Array.new.respond_to?(:to_csv)
3
6
  require 'retryable'
4
7
  require 't/collectable'
5
8
  require 't/core_ext/enumerable'
@@ -28,83 +31,151 @@ module T
28
31
  @rcfile = RCFile.instance
29
32
  end
30
33
 
31
- desc "add LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Add members to a list."
32
- def add(list_name, screen_name, *screen_names)
33
- screen_names.unshift(screen_name)
34
- screen_names.map!(&:strip_ats)
35
- screen_names.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
34
+ desc "add LIST USER [USER...]", "Add members to a list."
35
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
36
+ def add(list, user, *users)
37
+ users.unshift(user)
38
+ if options['id']
39
+ users.map!(&:to_i)
40
+ else
41
+ users.map!(&:strip_ats)
42
+ end
43
+ users.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
36
44
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
37
- client.list_add_members(list_name, user_id_group)
45
+ client.list_add_members(list, user_id_group)
38
46
  end
39
47
  end
40
- number = screen_names.length
41
- say "@#{@rcfile.default_profile[0]} added #{number} #{number == 1 ? 'member' : 'members'} to the list \"#{list_name}\"."
48
+ number = users.length
49
+ say "@#{@rcfile.default_profile[0]} added #{number} #{number == 1 ? 'member' : 'members'} to the list \"#{list}\"."
42
50
  say
43
- say "Run `#{File.basename($0)} list remove #{list_name} #{screen_names.join(' ')}` to undo."
51
+ if options['id']
52
+ say "Run `#{File.basename($0)} list remove --id #{list} #{users.join(' ')}` to undo."
53
+ else
54
+ say "Run `#{File.basename($0)} list remove #{list} #{users.map{|user| "@#{user}"}.join(' ')}` to undo."
55
+ end
44
56
  end
45
57
 
46
- desc "create LIST_NAME [DESCRIPTION]", "Create a new list."
58
+ desc "create LIST [DESCRIPTION]", "Create a new list."
47
59
  method_option :private, :aliases => "-p", :type => :boolean
48
- def create(list_name, description="")
60
+ def create(list, description="")
49
61
  opts = description.blank? ? {} : {:description => description}
50
62
  opts.merge!(:mode => 'private') if options['private']
51
- client.list_create(list_name, opts)
52
- say "@#{@rcfile.default_profile[0]} created the list \"#{list_name}\"."
63
+ client.list_create(list, opts)
64
+ say "@#{@rcfile.default_profile[0]} created the list \"#{list}\"."
53
65
  end
54
66
 
55
- desc "members [SCREEN_NAME] LIST_NAME", "Returns the members of a Twitter list."
56
- method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
67
+ desc "information [USER/]LIST", "Retrieves detailed information about a Twitter list."
68
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
69
+ def information(list)
70
+ owner, list = list.split('/')
71
+ if list.nil?
72
+ list = owner
73
+ owner = @rcfile.default_profile[0]
74
+ else
75
+ owner = if options['id']
76
+ owner.to_i
77
+ else
78
+ owner.strip_ats
79
+ end
80
+ end
81
+ list = client.list(owner, list)
82
+ if options['csv']
83
+ say ["ID", "Description", "Slug", "Screen name", "Created at", "Members", "Subscribers", "Following", "Mode", "URL"].to_csv
84
+ 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
85
+ else
86
+ array = []
87
+ array << ["ID", list.id.to_s]
88
+ array << ["Description", list.description] unless list.description.nil?
89
+ array << ["Slug", list.slug]
90
+ array << ["Screen name", "@#{list.user.screen_name}"]
91
+ created_at = list.created_at > 6.months.ago ? list.created_at.strftime("%b %e %H:%M") : list.created_at.strftime("%b %e %Y")
92
+ array << ["Created at", created_at]
93
+ array << ["Members", number_with_delimiter(list.member_count)]
94
+ array << ["Subscribers", number_with_delimiter(list.subscriber_count)]
95
+ status = list.following ? "Following" : "Not following"
96
+ array << ["Status", status]
97
+ array << ["Mode", list.mode]
98
+ array << ["URL", "https://twitter.com#{list.uri}"]
99
+ print_table(array)
100
+ end
101
+ end
102
+ map %w(detail) => :information
103
+
104
+ desc "members [USER/]LIST", "Returns the members of a Twitter list."
105
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
57
106
  method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
58
107
  method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
59
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
60
- method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
61
- method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
108
+ method_option :friends, :aliases => "-e", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
109
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify user via ID instead of screen name."
110
+ method_option :listed, :aliases => "-s", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
111
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
112
+ method_option :posted, :aliases => "-p", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter account was posted."
62
113
  method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
63
114
  method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
64
115
  method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
65
- def members(*args)
66
- list = args.pop
67
- owner = args.pop || @rcfile.default_profile[0]
68
- owner = owner.strip_ats
116
+ def members(list)
117
+ owner, list = list.split('/')
118
+ if list.nil?
119
+ list = owner
120
+ owner = @rcfile.default_profile[0]
121
+ else
122
+ owner = if options['id']
123
+ owner.to_i
124
+ else
125
+ owner.strip_ats
126
+ end
127
+ end
69
128
  users = collect_with_cursor do |cursor|
70
129
  client.list_members(owner, list, :cursor => cursor, :include_entities => false, :skip_status => true)
71
130
  end
72
- print_user_list(users)
131
+ print_users(users)
73
132
  end
74
133
 
75
- desc "remove LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Remove members from a list."
76
- def remove(list_name, screen_name, *screen_names)
77
- screen_names.unshift(screen_name)
78
- screen_names.map!(&:strip_ats)
79
- screen_names.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
134
+ desc "remove LIST USER [USER...]", "Remove members from a list."
135
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
136
+ def remove(list, user, *users)
137
+ users.unshift(user)
138
+ if options['id']
139
+ users.map!(&:to_i)
140
+ else
141
+ users.map!(&:strip_ats)
142
+ end
143
+ users.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
80
144
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
81
- client.list_remove_members(list_name, user_id_group)
145
+ client.list_remove_members(list, user_id_group)
82
146
  end
83
147
  end
84
- number = screen_names.length
85
- say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{list_name}\"."
148
+ number = users.length
149
+ say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{list}\"."
86
150
  say
87
- say "Run `#{File.basename($0)} list add #{list_name} #{screen_names.join(' ')}` to undo."
151
+ if options['id']
152
+ say "Run `#{File.basename($0)} list add --id #{list} #{users.join(' ')}` to undo."
153
+ else
154
+ say "Run `#{File.basename($0)} list add #{list} #{users.map{|user| "@#{user}"}.join(' ')}` to undo."
155
+ end
88
156
  end
89
157
 
90
- desc "timeline [SCREEN_NAME] LIST_NAME", "Show tweet timeline for members of the specified list."
91
- method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
92
- method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
93
- method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
94
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
95
- method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
96
- method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
158
+ desc "timeline [USER/]LIST", "Show tweet timeline for members of the specified list."
159
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
160
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify user via ID instead of screen name."
161
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
97
162
  method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
98
163
  method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
99
- method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
100
- method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
101
- def timeline(*args)
102
- list = args.pop
103
- owner = args.pop || @rcfile.default_profile[0]
104
- owner = owner.strip_ats
164
+ def timeline(list)
165
+ owner, list = list.split('/')
166
+ if list.nil?
167
+ list = owner
168
+ owner = @rcfile.default_profile[0]
169
+ else
170
+ owner = if options['id']
171
+ owner.to_i
172
+ else
173
+ owner.strip_ats
174
+ end
175
+ end
105
176
  per_page = options['number'] || DEFAULT_NUM_RESULTS
106
177
  statuses = client.list_timeline(owner, list, :include_entities => false, :per_page => per_page)
107
- print_status_list(statuses)
178
+ print_statuses(statuses)
108
179
  end
109
180
  map %w(tl) => :timeline
110
181
 
data/lib/t/printable.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  require 'action_view'
2
+ require 'csv'
3
+ # 'fastercsv' required on Ruby versions < 1.9
4
+ require 'fastercsv' unless Array.new.respond_to?(:to_csv)
2
5
  require 'highline'
3
6
 
4
7
  module T
@@ -20,9 +23,52 @@ module T
20
23
  puts
21
24
  end
22
25
 
23
- def print_status_list(statuses)
26
+ def print_lists(lists)
27
+ lists = lists.sort_by{|list| list.slug.downcase} unless options['unsorted']
28
+ if options['posted']
29
+ lists = lists.sort_by{|user| user.created_at}
30
+ elsif options['members']
31
+ lists = lists.sort_by{|user| user.member_count}
32
+ elsif options['mode']
33
+ lists = lists.sort_by{|user| user.mode}
34
+ elsif options['subscribers']
35
+ lists = lists.sort_by{|user| user.subscriber_count}
36
+ end
37
+ lists.reverse! if options['reverse']
38
+ if options['csv']
39
+ say ["ID", "Created at", "Screen name", "Slug", "Members", "Subscribers", "Mode", "Description"].to_csv unless lists.empty?
40
+ lists.each do |list|
41
+ say [list.id, list.created_at.utc.strftime("%Y-%m-%d %H:%M:%S %z"), list.user.screen_name, list.slug, list.member_count, list.subscriber_count, list.mode, list.description].to_csv
42
+ end
43
+ elsif options['long']
44
+ array = lists.map do |list|
45
+ created_at = list.created_at > 6.months.ago ? list.created_at.strftime("%b %e %H:%M") : list.created_at.strftime("%b %e %Y")
46
+ [list.id.to_s, created_at, list.full_name, number_with_delimiter(list.member_count), number_with_delimiter(list.subscriber_count), list.mode, list.description]
47
+ end
48
+ if STDOUT.tty?
49
+ headings = ["ID", "Created at", "Slug", "Members", "Subscribers", "Mode", "Description"]
50
+ array.unshift(headings) unless lists.empty?
51
+ end
52
+ print_table(array)
53
+ else
54
+ if STDOUT.tty?
55
+ print_in_columns(lists.map(&:full_name))
56
+ else
57
+ lists.each do |list|
58
+ say list.full_name
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def print_statuses(statuses)
24
65
  statuses.reverse! if options['reverse']
25
- if options['long']
66
+ if options['csv']
67
+ say ["ID", "Posted at", "Screen name", "Text"].to_csv unless statuses.empty?
68
+ statuses.each do |status|
69
+ say [status.id, status.created_at.utc.strftime("%Y-%m-%d %H:%M:%S %z"), status.user.screen_name, status.text].to_csv
70
+ end
71
+ elsif options['long']
26
72
  array = statuses.map do |status|
27
73
  created_at = status.created_at > 6.months.ago ? status.created_at.strftime("%b %e %H:%M") : status.created_at.strftime("%b %e %Y")
28
74
  [status.id.to_s, created_at, "@#{status.user.screen_name}", status.text.gsub(/\n+/, ' ')]
@@ -39,9 +85,9 @@ module T
39
85
  end
40
86
  end
41
87
 
42
- def print_user_list(users)
88
+ def print_users(users)
43
89
  users = users.sort_by{|user| user.screen_name.downcase} unless options['unsorted']
44
- if options['created']
90
+ if options['posted']
45
91
  users = users.sort_by{|user| user.created_at}
46
92
  elsif options['favorites']
47
93
  users = users.sort_by{|user| user.favourites_count}
@@ -55,7 +101,12 @@ module T
55
101
  users = users.sort_by{|user| user.statuses_count}
56
102
  end
57
103
  users.reverse! if options['reverse']
58
- if options['long']
104
+ if options['csv']
105
+ say ["ID", "Since", "Tweets", "Favorites", "Listed", "Following", "Followers", "Screen name", "Name"].to_csv unless users.empty?
106
+ users.each do |user|
107
+ say [user.id, user.created_at.utc.strftime("%Y-%m-%d %H:%M:%S %z"), user.statuses_count, user.favourites_count, user.listed_count, user.friends_count, user.followers_count, user.screen_name, user.name].to_csv
108
+ end
109
+ elsif options['long']
59
110
  array = users.map do |user|
60
111
  created_at = user.created_at > 6.months.ago ? user.created_at.strftime("%b %e %H:%M") : user.created_at.strftime("%b %e %Y")
61
112
  [user.id.to_s, created_at, number_with_delimiter(user.statuses_count), number_with_delimiter(user.favourites_count), number_with_delimiter(user.listed_count), number_with_delimiter(user.friends_count), number_with_delimiter(user.followers_count), "@#{user.screen_name}", user.name]
data/lib/t/search.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  require 'action_view'
2
+ require 'csv'
3
+ # 'fastercsv' required on Ruby versions < 1.9
4
+ require 'fastercsv' unless Array.new.respond_to?(:to_csv)
2
5
  require 'retryable'
3
6
  require 't/core_ext/enumerable'
4
7
  require 't/printable'
@@ -25,11 +28,18 @@ module T
25
28
  end
26
29
 
27
30
  desc "all QUERY", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets that match a specified query."
31
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
32
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
28
33
  method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
29
34
  def all(query)
30
35
  rpp = options['number'] || DEFAULT_NUM_RESULTS
31
36
  statuses = client.search(query, :include_entities => false, :rpp => rpp)
32
- if options['long']
37
+ if options['csv']
38
+ say ["ID", "Posted at", "Screen name", "Text"].to_csv unless statuses.empty?
39
+ statuses.each do |status|
40
+ say [status.id, status.created_at.utc.strftime("%Y-%m-%d %H:%M:%S %z"), status.from_user, status.text].to_csv
41
+ end
42
+ elsif options['long']
33
43
  array = statuses.map do |status|
34
44
  created_at = status.created_at > 6.months.ago ? status.created_at.strftime("%b %e %H:%M") : status.created_at.strftime("%b %e %Y")
35
45
  [status.id.to_s, created_at, "@#{status.from_user}", status.text.gsub(/\n+/, ' ')]
@@ -47,6 +57,8 @@ module T
47
57
  end
48
58
 
49
59
  desc "favorites QUERY", "Returns Tweets you've favorited that mach a specified query."
60
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
61
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
50
62
  def favorites(query)
51
63
  statuses = 1.upto(MAX_PAGES).threaded_map do |page|
52
64
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
@@ -55,11 +67,13 @@ module T
55
67
  end
56
68
  end
57
69
  end.flatten.compact
58
- print_status_list(statuses)
70
+ print_statuses(statuses)
59
71
  end
60
72
  map %w(faves) => :favorites
61
73
 
62
74
  desc "mentions QUERY", "Returns Tweets mentioning you that mach a specified query."
75
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
76
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
63
77
  def mentions(query)
64
78
  statuses = 1.upto(MAX_PAGES).threaded_map do |page|
65
79
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
@@ -68,11 +82,13 @@ module T
68
82
  end
69
83
  end
70
84
  end.flatten.compact
71
- print_status_list(statuses)
85
+ print_statuses(statuses)
72
86
  end
73
87
  map %w(replies) => :mentions
74
88
 
75
89
  desc "retweets QUERY", "Returns Tweets you've retweeted that mach a specified query."
90
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
91
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
76
92
  def retweets(query)
77
93
  statuses = 1.upto(MAX_PAGES).threaded_map do |page|
78
94
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
@@ -81,11 +97,13 @@ module T
81
97
  end
82
98
  end
83
99
  end.flatten.compact
84
- print_status_list(statuses)
100
+ print_statuses(statuses)
85
101
  end
86
102
  map %w(rts) => :retweets
87
103
 
88
104
  desc "timeline QUERY", "Returns Tweets in your timeline that match a specified query."
105
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
106
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
89
107
  def timeline(query)
90
108
  statuses = 1.upto(MAX_PAGES).threaded_map do |page|
91
109
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
@@ -94,21 +112,28 @@ module T
94
112
  end
95
113
  end
96
114
  end.flatten.compact
97
- print_status_list(statuses)
115
+ print_statuses(statuses)
98
116
  end
99
117
  map %w(tl) => :timeline
100
118
 
101
- desc "user SCREEN_NAME QUERY", "Returns Tweets in a user's timeline that match a specified query."
102
- def user(screen_name, query)
103
- screen_name = screen_name.strip_ats
119
+ desc "user USER QUERY", "Returns Tweets in a user's timeline that match a specified query."
120
+ method_option :csv, :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
121
+ method_option :id, :aliases => "-i", :type => "boolean", :default => false, :desc => "Specify user via ID instead of screen name."
122
+ method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
123
+ def user(user, query)
124
+ user = if options['id']
125
+ user.to_i
126
+ else
127
+ user.strip_ats
128
+ end
104
129
  statuses = 1.upto(MAX_PAGES).threaded_map do |page|
105
130
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
106
- client.user_timeline(screen_name, :page => page, :count => MAX_NUM_RESULTS).select do |status|
131
+ client.user_timeline(user, :page => page, :count => MAX_NUM_RESULTS).select do |status|
107
132
  /#{query}/i.match(status.text)
108
133
  end
109
134
  end
110
135
  end.flatten.compact
111
- print_status_list(statuses)
136
+ print_statuses(statuses)
112
137
  end
113
138
 
114
139
  end