t 0.4.0 → 0.5.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.
- data/.gitignore +0 -1
- data/.travis.yml +0 -1
- data/README.md +28 -99
- data/lib/t.rb +0 -13
- data/lib/t/cli.rb +385 -147
- data/lib/t/collectable.rb +1 -1
- data/lib/t/delete.rb +84 -0
- data/lib/t/list.rb +103 -0
- data/lib/t/search.rb +133 -0
- data/lib/t/set.rb +57 -0
- data/lib/t/version.rb +1 -1
- data/spec/cli_spec.rb +330 -201
- data/spec/{cli/delete_spec.rb → delete_spec.rb} +86 -124
- data/spec/fixtures/recommendations.json +1 -1
- data/spec/fixtures/users.json +1 -0
- data/spec/helper.rb +0 -1
- data/spec/{cli/list_spec.rb → list_spec.rb} +77 -6
- data/spec/rcfile_spec.rb +0 -4
- data/spec/{cli/search_spec.rb → search_spec.rb} +1 -1
- data/spec/{cli/set_spec.rb → set_spec.rb} +1 -1
- data/t.gemspec +2 -2
- metadata +26 -36
- data/lib/t/cli/delete.rb +0 -85
- data/lib/t/cli/follow.rb +0 -78
- data/lib/t/cli/list.rb +0 -58
- data/lib/t/cli/list/add.rb +0 -144
- data/lib/t/cli/list/remove.rb +0 -136
- data/lib/t/cli/search.rb +0 -124
- data/lib/t/cli/set.rb +0 -59
- data/lib/t/cli/unfollow.rb +0 -121
- data/spec/cli/follow_spec.rb +0 -240
- data/spec/cli/list/add_spec.rb +0 -518
- data/spec/cli/list/remove_spec.rb +0 -422
- data/spec/cli/unfollow_spec.rb +0 -410
data/t.gemspec
CHANGED
@@ -6,9 +6,9 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.add_dependency 'activesupport', ['>= 2.3.11', '< 4']
|
7
7
|
gem.add_dependency 'launchy', '~> 2.0'
|
8
8
|
gem.add_dependency 'geokit', '~> 1.6'
|
9
|
+
gem.add_dependency 'highline', '~> 1.6'
|
10
|
+
gem.add_dependency 'json', '~> 1.6'
|
9
11
|
gem.add_dependency 'oauth', '~> 0.4'
|
10
|
-
gem.add_dependency 'oj', '~> 1.2'
|
11
|
-
gem.add_dependency 'pager', '~> 1.0'
|
12
12
|
gem.add_dependency 'retryable', '~> 1.2'
|
13
13
|
gem.add_dependency 'thor', '~> 0.15.0.rc2'
|
14
14
|
gem.add_dependency 'twitter', '~> 2.2'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: t
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -88,13 +88,13 @@ dependencies:
|
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '1.6'
|
90
90
|
- !ruby/object:Gem::Dependency
|
91
|
-
name:
|
91
|
+
name: highline
|
92
92
|
requirement: !ruby/object:Gem::Requirement
|
93
93
|
none: false
|
94
94
|
requirements:
|
95
95
|
- - ~>
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
97
|
+
version: '1.6'
|
98
98
|
type: :runtime
|
99
99
|
prerelease: false
|
100
100
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -102,15 +102,15 @@ dependencies:
|
|
102
102
|
requirements:
|
103
103
|
- - ~>
|
104
104
|
- !ruby/object:Gem::Version
|
105
|
-
version: '
|
105
|
+
version: '1.6'
|
106
106
|
- !ruby/object:Gem::Dependency
|
107
|
-
name:
|
107
|
+
name: json
|
108
108
|
requirement: !ruby/object:Gem::Requirement
|
109
109
|
none: false
|
110
110
|
requirements:
|
111
111
|
- - ~>
|
112
112
|
- !ruby/object:Gem::Version
|
113
|
-
version: '1.
|
113
|
+
version: '1.6'
|
114
114
|
type: :runtime
|
115
115
|
prerelease: false
|
116
116
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -118,15 +118,15 @@ dependencies:
|
|
118
118
|
requirements:
|
119
119
|
- - ~>
|
120
120
|
- !ruby/object:Gem::Version
|
121
|
-
version: '1.
|
121
|
+
version: '1.6'
|
122
122
|
- !ruby/object:Gem::Dependency
|
123
|
-
name:
|
123
|
+
name: oauth
|
124
124
|
requirement: !ruby/object:Gem::Requirement
|
125
125
|
none: false
|
126
126
|
requirements:
|
127
127
|
- - ~>
|
128
128
|
- !ruby/object:Gem::Version
|
129
|
-
version: '
|
129
|
+
version: '0.4'
|
130
130
|
type: :runtime
|
131
131
|
prerelease: false
|
132
132
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -134,7 +134,7 @@ dependencies:
|
|
134
134
|
requirements:
|
135
135
|
- - ~>
|
136
136
|
- !ruby/object:Gem::Version
|
137
|
-
version: '
|
137
|
+
version: '0.4'
|
138
138
|
- !ruby/object:Gem::Dependency
|
139
139
|
name: retryable
|
140
140
|
requirement: !ruby/object:Gem::Requirement
|
@@ -296,29 +296,18 @@ files:
|
|
296
296
|
- bin/t
|
297
297
|
- lib/t.rb
|
298
298
|
- lib/t/cli.rb
|
299
|
-
- lib/t/cli/delete.rb
|
300
|
-
- lib/t/cli/follow.rb
|
301
|
-
- lib/t/cli/list.rb
|
302
|
-
- lib/t/cli/list/add.rb
|
303
|
-
- lib/t/cli/list/remove.rb
|
304
|
-
- lib/t/cli/search.rb
|
305
|
-
- lib/t/cli/set.rb
|
306
|
-
- lib/t/cli/unfollow.rb
|
307
299
|
- lib/t/collectable.rb
|
308
300
|
- lib/t/core_ext/enumerable.rb
|
309
301
|
- lib/t/core_ext/string.rb
|
302
|
+
- lib/t/delete.rb
|
303
|
+
- lib/t/list.rb
|
310
304
|
- lib/t/rcfile.rb
|
311
305
|
- lib/t/requestable.rb
|
306
|
+
- lib/t/search.rb
|
307
|
+
- lib/t/set.rb
|
312
308
|
- lib/t/version.rb
|
313
|
-
- spec/cli/delete_spec.rb
|
314
|
-
- spec/cli/follow_spec.rb
|
315
|
-
- spec/cli/list/add_spec.rb
|
316
|
-
- spec/cli/list/remove_spec.rb
|
317
|
-
- spec/cli/list_spec.rb
|
318
|
-
- spec/cli/search_spec.rb
|
319
|
-
- spec/cli/set_spec.rb
|
320
|
-
- spec/cli/unfollow_spec.rb
|
321
309
|
- spec/cli_spec.rb
|
310
|
+
- spec/delete_spec.rb
|
322
311
|
- spec/fixtures/.trc
|
323
312
|
- spec/fixtures/501_ids.json
|
324
313
|
- spec/fixtures/501_users_list.json
|
@@ -340,10 +329,14 @@ files:
|
|
340
329
|
- spec/fixtures/sferik.json
|
341
330
|
- spec/fixtures/status.json
|
342
331
|
- spec/fixtures/statuses.json
|
332
|
+
- spec/fixtures/users.json
|
343
333
|
- spec/fixtures/users_list.json
|
344
334
|
- spec/fixtures/xml.gp
|
345
335
|
- spec/helper.rb
|
336
|
+
- spec/list_spec.rb
|
346
337
|
- spec/rcfile_spec.rb
|
338
|
+
- spec/search_spec.rb
|
339
|
+
- spec/set_spec.rb
|
347
340
|
- t.gemspec
|
348
341
|
homepage: http://github.com/sferik/t
|
349
342
|
licenses: []
|
@@ -365,20 +358,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
365
358
|
version: 1.3.6
|
366
359
|
requirements: []
|
367
360
|
rubyforge_project:
|
368
|
-
rubygems_version: 1.8.
|
361
|
+
rubygems_version: 1.8.23
|
369
362
|
signing_key:
|
370
363
|
specification_version: 3
|
371
364
|
summary: CLI for Twitter
|
372
365
|
test_files:
|
373
|
-
- spec/cli/delete_spec.rb
|
374
|
-
- spec/cli/follow_spec.rb
|
375
|
-
- spec/cli/list/add_spec.rb
|
376
|
-
- spec/cli/list/remove_spec.rb
|
377
|
-
- spec/cli/list_spec.rb
|
378
|
-
- spec/cli/search_spec.rb
|
379
|
-
- spec/cli/set_spec.rb
|
380
|
-
- spec/cli/unfollow_spec.rb
|
381
366
|
- spec/cli_spec.rb
|
367
|
+
- spec/delete_spec.rb
|
382
368
|
- spec/fixtures/.trc
|
383
369
|
- spec/fixtures/501_ids.json
|
384
370
|
- spec/fixtures/501_users_list.json
|
@@ -400,8 +386,12 @@ test_files:
|
|
400
386
|
- spec/fixtures/sferik.json
|
401
387
|
- spec/fixtures/status.json
|
402
388
|
- spec/fixtures/statuses.json
|
389
|
+
- spec/fixtures/users.json
|
403
390
|
- spec/fixtures/users_list.json
|
404
391
|
- spec/fixtures/xml.gp
|
405
392
|
- spec/helper.rb
|
393
|
+
- spec/list_spec.rb
|
406
394
|
- spec/rcfile_spec.rb
|
395
|
+
- spec/search_spec.rb
|
396
|
+
- spec/set_spec.rb
|
407
397
|
has_rdoc:
|
data/lib/t/cli/delete.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
require 't/core_ext/string'
|
2
|
-
require 't/rcfile'
|
3
|
-
require 't/requestable'
|
4
|
-
require 'thor'
|
5
|
-
|
6
|
-
module T
|
7
|
-
class CLI
|
8
|
-
class Delete < Thor
|
9
|
-
include T::Requestable
|
10
|
-
|
11
|
-
check_unknown_options!
|
12
|
-
|
13
|
-
def initialize(*)
|
14
|
-
super
|
15
|
-
@rcfile = RCFile.instance
|
16
|
-
end
|
17
|
-
|
18
|
-
desc "block SCREEN_NAME", "Unblock a user."
|
19
|
-
def block(screen_name)
|
20
|
-
screen_name = screen_name.strip_at
|
21
|
-
user = client.unblock(screen_name, :include_entities => false)
|
22
|
-
say "@#{@rcfile.default_profile[0]} unblocked @#{user.screen_name}."
|
23
|
-
say
|
24
|
-
say "Run `#{File.basename($0)} block #{user.screen_name}` to block."
|
25
|
-
end
|
26
|
-
|
27
|
-
desc "dm", "Delete the last Direct Message sent."
|
28
|
-
def dm
|
29
|
-
direct_message = client.direct_messages_sent(:count => 1, :include_entities => false).first
|
30
|
-
if direct_message
|
31
|
-
unless parent_options['force']
|
32
|
-
return unless yes? "Are you sure you want to permanently delete the direct message to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\"?"
|
33
|
-
end
|
34
|
-
direct_message = client.direct_message_destroy(direct_message.id, :include_entities => false)
|
35
|
-
say "@#{direct_message.sender.screen_name} deleted the direct message sent to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\""
|
36
|
-
else
|
37
|
-
raise Thor::Error, "Direct Message not found"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
map %w(m) => :dm
|
41
|
-
|
42
|
-
desc "favorite", "Deletes the last favorite."
|
43
|
-
def favorite
|
44
|
-
status = client.favorites(:count => 1, :include_entities => false).first
|
45
|
-
if status
|
46
|
-
unless parent_options['force']
|
47
|
-
return unless yes? "Are you sure you want to delete the favorite of @#{status.user.screen_name}'s latest status: \"#{status.text}\"?"
|
48
|
-
end
|
49
|
-
client.unfavorite(status.id, :include_entities => false)
|
50
|
-
say "@#{@rcfile.default_profile[0]} unfavorited @#{status.user.screen_name}'s latest status: \"#{status.text}\""
|
51
|
-
say
|
52
|
-
say "Run `#{File.basename($0)} favorite #{status.user.screen_name}` to favorite."
|
53
|
-
else
|
54
|
-
raise Thor::Error, "Tweet not found"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
map %w(fave) => :favorite
|
58
|
-
|
59
|
-
desc "list LIST_NAME", "Delete a list."
|
60
|
-
def list(list_name)
|
61
|
-
unless parent_options['force']
|
62
|
-
return unless yes? "Are you sure you want to permanently delete the list \"#{list_name}\"?"
|
63
|
-
end
|
64
|
-
status = client.list_destroy(list_name)
|
65
|
-
say "@#{@rcfile.default_profile[0]} deleted the list \"#{list_name}\"."
|
66
|
-
end
|
67
|
-
|
68
|
-
desc "status", "Delete a Tweet."
|
69
|
-
def status
|
70
|
-
user = client.user(:include_entities => false)
|
71
|
-
if user.status
|
72
|
-
unless parent_options['force']
|
73
|
-
return unless yes? "Are you sure you want to permanently delete @#{@rcfile.default_profile[0]}'s latest status: \"#{user.status.text}\"?"
|
74
|
-
end
|
75
|
-
status = client.status_destroy(user.status.id, :include_entities => false, :trim_user => true)
|
76
|
-
say "@#{@rcfile.default_profile[0]} deleted the status: \"#{status.text}\""
|
77
|
-
else
|
78
|
-
raise Thor::Error, "Tweet not found"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
map %w(post tweet update) => :status
|
82
|
-
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
data/lib/t/cli/follow.rb
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'retryable'
|
2
|
-
require 't/core_ext/enumerable'
|
3
|
-
require 't/core_ext/string'
|
4
|
-
require 't/collectable'
|
5
|
-
require 't/rcfile'
|
6
|
-
require 't/requestable'
|
7
|
-
require 'thor'
|
8
|
-
|
9
|
-
module T
|
10
|
-
class CLI
|
11
|
-
class Follow < Thor
|
12
|
-
include T::Collectable
|
13
|
-
include T::Requestable
|
14
|
-
|
15
|
-
check_unknown_options!
|
16
|
-
|
17
|
-
def initialize(*)
|
18
|
-
super
|
19
|
-
@rcfile = RCFile.instance
|
20
|
-
end
|
21
|
-
|
22
|
-
desc "followers", "Follow all followers."
|
23
|
-
def followers
|
24
|
-
follower_ids = collect_with_cursor do |cursor|
|
25
|
-
client.follower_ids(:cursor => cursor)
|
26
|
-
end
|
27
|
-
friend_ids = collect_with_cursor do |cursor|
|
28
|
-
client.friend_ids(:cursor => cursor)
|
29
|
-
end
|
30
|
-
follow_ids = (follower_ids - friend_ids)
|
31
|
-
number = follow_ids.length
|
32
|
-
return say "@#{@rcfile.default_profile[0]} is already following all followers." if number.zero?
|
33
|
-
return unless yes? "Are you sure you want to follow #{number} #{number == 1 ? 'user' : 'users'}?"
|
34
|
-
screen_names = follow_ids.threaded_map do |follow_id|
|
35
|
-
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
36
|
-
client.follow(follow_id, :include_entities => false)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
say "@#{@rcfile.default_profile[0]} is now following #{number} more #{number == 1 ? 'user' : 'users'}."
|
40
|
-
say
|
41
|
-
say "Run `#{File.basename($0)} unfollow all followers` to stop."
|
42
|
-
end
|
43
|
-
|
44
|
-
desc "listed LIST_NAME", "Follow all members of a list."
|
45
|
-
def listed(list_name)
|
46
|
-
list_member_collection = collect_with_cursor do |cursor|
|
47
|
-
client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
|
48
|
-
end
|
49
|
-
number = list_member_collection.length
|
50
|
-
return say "@#{@rcfile.default_profile[0]} is already following all list members." if number.zero?
|
51
|
-
return unless yes? "Are you sure you want to follow #{number} #{number == 1 ? 'user' : 'users'}?"
|
52
|
-
list_member_collection.threaded_map do |list_member|
|
53
|
-
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
54
|
-
client.follow(list_member.id, :include_entities => false)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
say "@#{@rcfile.default_profile[0]} is now following #{number} more #{number == 1 ? 'user' : 'users'}."
|
58
|
-
say
|
59
|
-
say "Run `#{File.basename($0)} unfollow all listed #{list_name}` to stop."
|
60
|
-
end
|
61
|
-
|
62
|
-
desc "users SCREEN_NAME [SCREEN_NAME...]", "Allows you to start following users."
|
63
|
-
def users(screen_name, *screen_names)
|
64
|
-
screen_names.unshift(screen_name)
|
65
|
-
screen_names.threaded_map do |screen_name|
|
66
|
-
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
67
|
-
client.follow(screen_name, :include_entities => false)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
number = screen_names.length
|
71
|
-
say "@#{@rcfile.default_profile[0]} is now following #{number} more #{number == 1 ? 'user' : 'users'}."
|
72
|
-
say
|
73
|
-
say "Run `#{File.basename($0)} unfollow users #{screen_names.join(' ')}` to stop."
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
data/lib/t/cli/list.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'action_view'
|
2
|
-
require 'pager'
|
3
|
-
require 't/rcfile'
|
4
|
-
require 't/requestable'
|
5
|
-
require 'thor'
|
6
|
-
|
7
|
-
module T
|
8
|
-
class CLI
|
9
|
-
class List < Thor
|
10
|
-
include ActionView::Helpers::DateHelper
|
11
|
-
include Pager
|
12
|
-
include T::Requestable
|
13
|
-
|
14
|
-
DEFAULT_NUM_RESULTS = 20
|
15
|
-
MAX_SCREEN_NAME_SIZE = 20
|
16
|
-
|
17
|
-
check_unknown_options!
|
18
|
-
|
19
|
-
def initialize(*)
|
20
|
-
super
|
21
|
-
@rcfile = RCFile.instance
|
22
|
-
end
|
23
|
-
|
24
|
-
desc "create LIST_NAME [DESCRIPTION]", "Create a new list."
|
25
|
-
method_option :private, :aliases => "-p", :type => :boolean
|
26
|
-
def create(list_name, description="")
|
27
|
-
defaults = description.blank? ? {} : {:description => description}
|
28
|
-
defaults.merge!(:mode => 'private') if options['private']
|
29
|
-
client.list_create(list_name, defaults)
|
30
|
-
say "@#{@rcfile.default_profile[0]} created the list \"#{list_name}\"."
|
31
|
-
end
|
32
|
-
|
33
|
-
desc "timeline LIST_NAME", "Show tweet timeline for members of the specified list."
|
34
|
-
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
|
35
|
-
method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
|
36
|
-
def timeline(list_name)
|
37
|
-
defaults = {:include_entities => false}
|
38
|
-
defaults.merge!(:per_page => options['number']) if options['number']
|
39
|
-
timeline = client.list_timeline(list_name, defaults)
|
40
|
-
timeline.reverse! if options['reverse']
|
41
|
-
page unless T.env.test?
|
42
|
-
timeline.each do |status|
|
43
|
-
say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
map %w(tl) => :timeline
|
47
|
-
|
48
|
-
desc "add SUBCOMMAND ...ARGS", "Add users to a list."
|
49
|
-
require 't/cli/list/add'
|
50
|
-
subcommand 'add', CLI::List::Add
|
51
|
-
|
52
|
-
desc "remove SUBCOMMAND ...ARGS", "Remove users from a list."
|
53
|
-
require 't/cli/list/remove'
|
54
|
-
subcommand 'remove', CLI::List::Remove
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
data/lib/t/cli/list/add.rb
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/array/grouping'
|
2
|
-
require 'retryable'
|
3
|
-
require 't/core_ext/enumerable'
|
4
|
-
require 't/core_ext/string'
|
5
|
-
require 't/collectable'
|
6
|
-
require 't/rcfile'
|
7
|
-
require 't/requestable'
|
8
|
-
require 'thor'
|
9
|
-
|
10
|
-
module T
|
11
|
-
class CLI
|
12
|
-
class List
|
13
|
-
class Add < Thor
|
14
|
-
include T::Collectable
|
15
|
-
include T::Requestable
|
16
|
-
|
17
|
-
MAX_USERS_PER_LIST = 500
|
18
|
-
MAX_USERS_PER_REQUEST = 100
|
19
|
-
|
20
|
-
check_unknown_options!
|
21
|
-
|
22
|
-
def initialize(*)
|
23
|
-
super
|
24
|
-
@rcfile = RCFile.instance
|
25
|
-
end
|
26
|
-
|
27
|
-
desc "friends LIST_NAME", "Add all friends to a list."
|
28
|
-
def friends(list_name)
|
29
|
-
list_member_ids = collect_with_cursor do |cursor|
|
30
|
-
client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
|
31
|
-
end
|
32
|
-
existing_list_members = list_member_ids.length
|
33
|
-
if existing_list_members >= MAX_USERS_PER_LIST
|
34
|
-
return say "The list \"#{list_name}\" are already contains the maximum of #{MAX_USERS_PER_LIST} members."
|
35
|
-
end
|
36
|
-
friend_ids = collect_with_cursor do |cursor|
|
37
|
-
client.friend_ids(:cursor => cursor)
|
38
|
-
end
|
39
|
-
list_member_ids_to_add = (friend_ids - list_member_ids)
|
40
|
-
number = list_member_ids_to_add.length
|
41
|
-
if number.zero?
|
42
|
-
return say "All of @#{@rcfile.default_profile[0]}'s friends are already members of the list \"#{list_name}\"."
|
43
|
-
elsif existing_list_members + number > MAX_USERS_PER_LIST
|
44
|
-
return unless yes? "Lists can't have more than #{MAX_USERS_PER_LIST} members. Do you want to add up to #{MAX_USERS_PER_LIST} friends to the list \"#{list_name}\"?"
|
45
|
-
else
|
46
|
-
return unless yes? "Are you sure you want to add #{number} #{number == 1 ? 'friend' : 'friends'} to the list \"#{list_name}\"?"
|
47
|
-
end
|
48
|
-
max_members_to_add = MAX_USERS_PER_LIST - existing_list_members
|
49
|
-
list_member_ids_to_add[0...max_members_to_add].in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
|
50
|
-
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
51
|
-
client.list_add_members(list_name, user_id_group)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
number_added = [number, max_members_to_add].min
|
55
|
-
say "@#{@rcfile.default_profile[0]} added #{number_added} #{number_added == 1 ? 'friend' : 'friends'} to the list \"#{list_name}\"."
|
56
|
-
say
|
57
|
-
say "Run `#{File.basename($0)} list remove all friends #{list_name}` to undo."
|
58
|
-
end
|
59
|
-
|
60
|
-
desc "followers LIST_NAME", "Add all followers to a list."
|
61
|
-
def followers(list_name)
|
62
|
-
list_member_ids = collect_with_cursor do |cursor|
|
63
|
-
client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
|
64
|
-
end
|
65
|
-
existing_list_members = list_member_ids.length
|
66
|
-
if existing_list_members >= MAX_USERS_PER_LIST
|
67
|
-
return say "The list \"#{list_name}\" are already contains the maximum of #{MAX_USERS_PER_LIST} members."
|
68
|
-
end
|
69
|
-
follower_ids = collect_with_cursor do |cursor|
|
70
|
-
followers = client.follower_ids(:cursor => cursor)
|
71
|
-
end
|
72
|
-
list_member_ids_to_add = (follower_ids - list_member_ids)
|
73
|
-
number = list_member_ids_to_add.length
|
74
|
-
if number.zero?
|
75
|
-
return say "All of @#{@rcfile.default_profile[0]}'s followers are already members of the list \"#{list_name}\"."
|
76
|
-
elsif existing_list_members + number > MAX_USERS_PER_LIST
|
77
|
-
return unless yes? "Lists can't have more than #{MAX_USERS_PER_LIST} members. Do you want to add up to #{MAX_USERS_PER_LIST} followers to the list \"#{list_name}\"?"
|
78
|
-
else
|
79
|
-
return unless yes? "Are you sure you want to add #{number} #{number == 1 ? 'follower' : 'followers'} to the list \"#{list_name}\"?"
|
80
|
-
end
|
81
|
-
max_members_to_add = MAX_USERS_PER_LIST - existing_list_members
|
82
|
-
list_member_ids_to_add[0...max_members_to_add].in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
|
83
|
-
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
84
|
-
client.list_add_members(list_name, user_id_group)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
number_added = [number, max_members_to_add].min
|
88
|
-
say "@#{@rcfile.default_profile[0]} added #{number_added} #{number_added == 1 ? 'follower' : 'followers'} to the list \"#{list_name}\"."
|
89
|
-
say
|
90
|
-
say "Run `#{File.basename($0)} list remove all followers #{list_name}` to undo."
|
91
|
-
end
|
92
|
-
|
93
|
-
desc "listed FROM_LIST_NAME TO_LIST_NAME", "Add all list memebers to a list."
|
94
|
-
def listed(from_list_name, to_list_name)
|
95
|
-
to_list_members = collect_with_cursor do |cursor|
|
96
|
-
client.list_members(to_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
|
97
|
-
end
|
98
|
-
existing_list_members = to_list_members.length
|
99
|
-
if existing_list_members >= MAX_USERS_PER_LIST
|
100
|
-
return say "The list \"#{to_list_name}\" are already contains the maximum of #{MAX_USERS_PER_LIST} members."
|
101
|
-
end
|
102
|
-
from_list_members = collect_with_cursor do |cursor|
|
103
|
-
client.list_members(from_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
|
104
|
-
end
|
105
|
-
list_member_ids_to_add = (from_list_members.collect(&:id) - to_list_members.collect(&:id))
|
106
|
-
number = list_member_ids_to_add.length
|
107
|
-
if number.zero?
|
108
|
-
return say "All of the members of the list \"#{from_list_name}\" are already members of the list \"#{to_list_name}\"."
|
109
|
-
elsif existing_list_members + number > MAX_USERS_PER_LIST
|
110
|
-
return unless yes? "Lists can't have more than #{MAX_USERS_PER_LIST} members. Do you want to add up to #{MAX_USERS_PER_LIST} members to the list \"#{to_list_name}\"?"
|
111
|
-
else
|
112
|
-
return unless yes? "Are you sure you want to add #{number} #{number == 1 ? 'member' : 'members'} to the list \"#{to_list_name}\"?"
|
113
|
-
end
|
114
|
-
max_members_to_add = MAX_USERS_PER_LIST - existing_list_members
|
115
|
-
list_member_ids_to_add[0...max_members_to_add].in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
|
116
|
-
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
117
|
-
client.list_add_members(to_list_name, user_id_group)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
number_added = [number, max_members_to_add].min
|
121
|
-
say "@#{@rcfile.default_profile[0]} added #{number_added} #{number_added == 1 ? 'member' : 'members'} to the list \"#{to_list_name}\"."
|
122
|
-
say
|
123
|
-
say "Run `#{File.basename($0)} list remove all listed #{from_list_name} #{to_list_name}` to undo."
|
124
|
-
end
|
125
|
-
|
126
|
-
desc "users LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Add users to a list."
|
127
|
-
def users(list_name, screen_name, *screen_names)
|
128
|
-
screen_names.unshift(screen_name)
|
129
|
-
screen_names.map!(&:strip_at)
|
130
|
-
screen_names.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
|
131
|
-
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
132
|
-
client.list_add_members(list_name, user_id_group)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
number = screen_names.length
|
136
|
-
say "@#{@rcfile.default_profile[0]} added #{number} #{number == 1 ? 'user' : 'users'} to the list \"#{list_name}\"."
|
137
|
-
say
|
138
|
-
say "Run `#{File.basename($0)} list remove users #{list_name} #{screen_names.join(' ')}` to undo."
|
139
|
-
end
|
140
|
-
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|