t 0.1.0 → 0.2.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.
@@ -0,0 +1,169 @@
1
+ require 'active_support/core_ext/array/grouping'
2
+ require 't/rcfile'
3
+ require 'thor'
4
+ require 'twitter'
5
+
6
+ module T
7
+ class CLI
8
+ class List
9
+ class Add
10
+ class All < Thor
11
+ DEFAULT_HOST = 'api.twitter.com'
12
+ DEFAULT_PROTOCOL = 'https'
13
+ MAX_USERS_PER_LIST = 500
14
+
15
+ check_unknown_options!
16
+
17
+ def initialize(*)
18
+ super
19
+ @rcfile = RCFile.instance
20
+ end
21
+
22
+ desc "friends LIST_NAME", "Add all friends to a list."
23
+ def friends(list_name)
24
+ list_member_ids = []
25
+ cursor = -1
26
+ until cursor == 0
27
+ list_members = client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
28
+ list_member_ids += list_members.users.collect{|user| user.id}
29
+ cursor = list_members.next_cursor
30
+ end
31
+ existing_list_members = list_member_ids.length
32
+ if existing_list_members >= MAX_USERS_PER_LIST
33
+ return say "The list \"#{list_name}\" are already contains the maximum of #{MAX_USERS_PER_LIST} members."
34
+ end
35
+ friend_ids = []
36
+ cursor = -1
37
+ until cursor == 0
38
+ friends = client.friend_ids(:cursor => cursor)
39
+ friend_ids += friends.ids
40
+ cursor = friends.next_cursor
41
+ end
42
+ list_member_ids_to_add = (friend_ids - list_member_ids)
43
+ number = list_member_ids_to_add.length
44
+ if number.zero?
45
+ return say "All of @#{@rcfile.default_profile[0]}'s friends are already members of the list \"#{list_name}\"."
46
+ elsif existing_list_members + number > MAX_USERS_PER_LIST
47
+ 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}\"?"
48
+ else
49
+ return unless yes? "Are you sure you want to add #{number} #{number == 1 ? 'friend' : 'friends'} to the list \"#{list_name}\"?"
50
+ end
51
+ max_members_to_add = MAX_USERS_PER_LIST - existing_list_members
52
+ list_member_ids_to_add[0...max_members_to_add].in_groups_of(100, false) do |user_id_group|
53
+ client.list_add_members(list_name, user_id_group)
54
+ end
55
+ number_added = [number, max_members_to_add].min
56
+ say "@#{@rcfile.default_profile[0]} added #{number_added} #{number_added == 1 ? 'friend' : 'friends'} to the list \"#{list_name}\"."
57
+ say
58
+ say "Run `#{$0} list remove all friends #{list_name}` to undo."
59
+ end
60
+
61
+ desc "followers LIST_NAME", "Add all followers to a list."
62
+ def followers(list_name)
63
+ list_member_ids = []
64
+ cursor = -1
65
+ until cursor == 0
66
+ list_members = client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
67
+ list_member_ids += list_members.users.collect{|user| user.id}
68
+ cursor = list_members.next_cursor
69
+ end
70
+ existing_list_members = list_member_ids.length
71
+ if existing_list_members >= MAX_USERS_PER_LIST
72
+ return say "The list \"#{list_name}\" are already contains the maximum of #{MAX_USERS_PER_LIST} members."
73
+ end
74
+ follower_ids = []
75
+ cursor = -1
76
+ until cursor == 0
77
+ followers = client.follower_ids(:cursor => cursor)
78
+ follower_ids += followers.ids
79
+ cursor = followers.next_cursor
80
+ end
81
+ list_member_ids_to_add = (follower_ids - list_member_ids)
82
+ number = list_member_ids_to_add.length
83
+ if number.zero?
84
+ return say "All of @#{@rcfile.default_profile[0]}'s followers are already members of the list \"#{list_name}\"."
85
+ elsif existing_list_members + number > MAX_USERS_PER_LIST
86
+ 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}\"?"
87
+ else
88
+ return unless yes? "Are you sure you want to add #{number} #{number == 1 ? 'follower' : 'followers'} to the list \"#{list_name}\"?"
89
+ end
90
+ max_members_to_add = MAX_USERS_PER_LIST - existing_list_members
91
+ list_member_ids_to_add[0...max_members_to_add].in_groups_of(100, false) do |user_id_group|
92
+ client.list_add_members(list_name, user_id_group)
93
+ end
94
+ number_added = [number, max_members_to_add].min
95
+ say "@#{@rcfile.default_profile[0]} added #{number_added} #{number_added == 1 ? 'follower' : 'followers'} to the list \"#{list_name}\"."
96
+ say
97
+ say "Run `#{$0} list remove all followers #{list_name}` to undo."
98
+ end
99
+
100
+ desc "listed FROM_LIST_NAME TO_LIST_NAME", "Add all list memebers to a list."
101
+ def listed(from_list_name, to_list_name)
102
+ to_list_member_ids = []
103
+ cursor = -1
104
+ until cursor == 0
105
+ list_members = client.list_members(to_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
106
+ to_list_member_ids += list_members.users.collect{|user| user.id}
107
+ cursor = list_members.next_cursor
108
+ end
109
+ existing_list_members = to_list_member_ids.length
110
+ if existing_list_members >= MAX_USERS_PER_LIST
111
+ return say "The list \"#{to_list_name}\" are already contains the maximum of #{MAX_USERS_PER_LIST} members."
112
+ end
113
+ from_list_member_ids = []
114
+ cursor = -1
115
+ until cursor == 0
116
+ list_members = client.list_members(from_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
117
+ from_list_member_ids += list_members.users.collect{|user| user.id}
118
+ cursor = list_members.next_cursor
119
+ end
120
+ list_member_ids_to_add = (from_list_member_ids - to_list_member_ids)
121
+ number = list_member_ids_to_add.length
122
+ if number.zero?
123
+ return say "All of the members of the list \"#{from_list_name}\" are already members of the list \"#{to_list_name}\"."
124
+ elsif existing_list_members + number > MAX_USERS_PER_LIST
125
+ 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}\"?"
126
+ else
127
+ return unless yes? "Are you sure you want to add #{number} #{number == 1 ? 'member' : 'members'} to the list \"#{to_list_name}\"?"
128
+ end
129
+ max_members_to_add = MAX_USERS_PER_LIST - existing_list_members
130
+ list_member_ids_to_add[0...max_members_to_add].in_groups_of(100, false) do |user_id_group|
131
+ client.list_add_members(to_list_name, user_id_group)
132
+ end
133
+ number_added = [number, max_members_to_add].min
134
+ say "@#{@rcfile.default_profile[0]} added #{number_added} #{number_added == 1 ? 'member' : 'members'} to the list \"#{to_list_name}\"."
135
+ say
136
+ say "Run `#{$0} list remove all listed #{from_list_name} #{to_list_name}` to undo."
137
+ end
138
+
139
+ private
140
+
141
+ def base_url
142
+ "#{protocol}://#{host}"
143
+ end
144
+
145
+ def client
146
+ return @client if @client
147
+ @rcfile.path = parent_options['profile'] if parent_options['profile']
148
+ @client = Twitter::Client.new(
149
+ :endpoint => base_url,
150
+ :consumer_key => @rcfile.default_consumer_key,
151
+ :consumer_secret => @rcfile.default_consumer_secret,
152
+ :oauth_token => @rcfile.default_token,
153
+ :oauth_token_secret => @rcfile.default_secret
154
+ )
155
+ end
156
+
157
+ def host
158
+ parent_options['host'] || DEFAULT_HOST
159
+ end
160
+
161
+ def protocol
162
+ parent_options['no_ssl'] ? 'http' : DEFAULT_PROTOCOL
163
+ end
164
+
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,67 @@
1
+ require 't/core_ext/string'
2
+ require 't/rcfile'
3
+ require 'thor'
4
+ require 'twitter'
5
+
6
+ module T
7
+ class CLI
8
+ class List
9
+ class Remove < Thor
10
+ DEFAULT_HOST = 'api.twitter.com'
11
+ DEFAULT_PROTOCOL = 'https'
12
+
13
+ check_unknown_options!
14
+
15
+ def initialize(*)
16
+ super
17
+ @rcfile = RCFile.instance
18
+ end
19
+
20
+ desc "users LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Remove users from a list."
21
+ def users(list_name, screen_name, *screen_names)
22
+ screen_names.unshift(screen_name)
23
+ screen_names.each do |screen_name|
24
+ screen_name = screen_name.strip_at
25
+ client.list_remove_member(list_name, screen_name)
26
+ say "@#{@rcfile.default_profile[0]} removed @#{screen_name} from the list \"#{list_name}\"."
27
+ end
28
+ number = screen_names.length
29
+ say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'user' : 'users'} from the list \"#{list_name}\"."
30
+ say
31
+ say "Run `#{$0} list add users #{list_name} #{screen_names.join(' ')}` to undo."
32
+ end
33
+
34
+ desc "all SUBCOMMAND ...ARGS", "Remove all users to a list."
35
+ require 't/cli/list/remove/all'
36
+ subcommand 'all', CLI::List::Remove::All
37
+
38
+ private
39
+
40
+ def base_url
41
+ "#{protocol}://#{host}"
42
+ end
43
+
44
+ def client
45
+ return @client if @client
46
+ @rcfile.path = parent_options['profile'] if parent_options['profile']
47
+ @client = Twitter::Client.new(
48
+ :endpoint => base_url,
49
+ :consumer_key => @rcfile.default_consumer_key,
50
+ :consumer_secret => @rcfile.default_consumer_secret,
51
+ :oauth_token => @rcfile.default_token,
52
+ :oauth_token_secret => @rcfile.default_secret
53
+ )
54
+ end
55
+
56
+ def host
57
+ parent_options['host'] || DEFAULT_HOST
58
+ end
59
+
60
+ def protocol
61
+ parent_options['no_ssl'] ? 'http' : DEFAULT_PROTOCOL
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,162 @@
1
+ require 't/rcfile'
2
+ require 'thor'
3
+ require 'twitter'
4
+
5
+ module T
6
+ class CLI
7
+ class List
8
+ class Remove
9
+ class All < Thor
10
+ DEFAULT_HOST = 'api.twitter.com'
11
+ DEFAULT_PROTOCOL = 'https'
12
+
13
+ check_unknown_options!
14
+
15
+ def initialize(*)
16
+ super
17
+ @rcfile = RCFile.instance
18
+ end
19
+
20
+ desc "friends LIST_NAME", "Remove all friends from a list."
21
+ def friends(list_name)
22
+ list_member_ids = []
23
+ cursor = -1
24
+ until cursor == 0
25
+ list_members = client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
26
+ list_member_ids += list_members.users.collect{|user| user.id}
27
+ cursor = list_members.next_cursor
28
+ end
29
+ friend_ids = []
30
+ cursor = -1
31
+ until cursor == 0
32
+ friends = client.friend_ids(:cursor => cursor)
33
+ friend_ids += friends.ids
34
+ cursor = friends.next_cursor
35
+ end
36
+ list_member_ids_to_remove = (friend_ids - list_member_ids)
37
+ number = list_member_ids_to_remove.length
38
+ if number.zero?
39
+ return say "None of @#{@rcfile.default_profile[0]}'s friends are members of the list \"#{list_name}\"."
40
+ else
41
+ return unless yes? "Are you sure you want to remove #{number} #{number == 1 ? 'friend' : 'friends'} from the list \"#{list_name}\"?"
42
+ end
43
+ list_member_ids_to_remove.each do |list_member_id|
44
+ client.list_remove_member(list_name, list_member_id)
45
+ end
46
+ say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'friend' : 'friends'} from the list \"#{list_name}\"."
47
+ say
48
+ say "Run `#{$0} list add all friends #{list_name}` to undo."
49
+ end
50
+
51
+ desc "followers LIST_NAME", "Remove all followers from a list."
52
+ def followers(list_name)
53
+ list_member_ids = []
54
+ cursor = -1
55
+ until cursor == 0
56
+ list_members = client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
57
+ list_member_ids += list_members.users.collect{|user| user.id}
58
+ cursor = list_members.next_cursor
59
+ end
60
+ follower_ids = []
61
+ cursor = -1
62
+ until cursor == 0
63
+ followers = client.follower_ids(:cursor => cursor)
64
+ follower_ids += followers.ids
65
+ cursor = followers.next_cursor
66
+ end
67
+ list_member_ids_to_remove = (follower_ids - list_member_ids)
68
+ number = list_member_ids_to_remove.length
69
+ if number.zero?
70
+ return say "None of @#{@rcfile.default_profile[0]}'s followers are members of the list \"#{list_name}\"."
71
+ else
72
+ return unless yes? "Are you sure you want to remove #{number} #{number == 1 ? 'follower' : 'followers'} from the list \"#{list_name}\"?"
73
+ end
74
+ list_member_ids_to_remove.each do |list_member_id|
75
+ client.list_remove_member(list_name, list_member_id)
76
+ end
77
+ say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'follower' : 'followers'} from the list \"#{list_name}\"."
78
+ say
79
+ say "Run `#{$0} list add all followers #{list_name}` to undo."
80
+ end
81
+
82
+ desc "listed FROM_LIST_NAME TO_LIST_NAME", "Remove all list members from a list."
83
+ def listed(from_list_name, to_list_name)
84
+ to_list_member_ids = []
85
+ cursor = -1
86
+ until cursor == 0
87
+ list_members = client.list_members(to_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
88
+ to_list_member_ids += list_members.users.collect{|user| user.id}
89
+ cursor = list_members.next_cursor
90
+ end
91
+ from_list_member_ids = []
92
+ cursor = -1
93
+ until cursor == 0
94
+ list_members = client.list_members(from_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
95
+ from_list_member_ids += list_members.users.collect{|user| user.id}
96
+ cursor = list_members.next_cursor
97
+ end
98
+ list_member_ids_to_remove = (from_list_member_ids - to_list_member_ids)
99
+ number = list_member_ids_to_remove.length
100
+ if number.zero?
101
+ return say "None of the members of the list \"#{from_list_name}\" are members of the list \"#{to_list_name}\"."
102
+ else
103
+ return unless yes? "Are you sure you want to remove #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{to_list_name}\"?"
104
+ end
105
+ list_member_ids_to_remove.each do |list_member_id|
106
+ client.list_remove_member(to_list_name, list_member_id)
107
+ end
108
+ say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{to_list_name}\"."
109
+ say
110
+ say "Run `#{$0} list add all listed #{from_list_name} #{to_list_name}` to undo."
111
+ end
112
+
113
+ desc "members LIST_NAME", "Remove all members from a list."
114
+ def members(list_name)
115
+ list_member_ids = []
116
+ cursor = -1
117
+ until cursor == 0
118
+ list_members = client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
119
+ list_member_ids += list_members.users.collect{|user| user.id}
120
+ cursor = list_members.next_cursor
121
+ end
122
+ number = list_member_ids.length
123
+ return say "The list \"#{list_name}\" doesn't have any members." if number.zero?
124
+ return unless yes? "Are you sure you want to remove #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{list_name}\"?"
125
+ list_member_ids.each do |list_member_id|
126
+ client.list_remove_member(list_name, list_member_id)
127
+ end
128
+ say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{list_name}\"."
129
+ end
130
+ map %w(users) => :members
131
+
132
+ private
133
+
134
+ def base_url
135
+ "#{protocol}://#{host}"
136
+ end
137
+
138
+ def client
139
+ return @client if @client
140
+ @rcfile.path = parent_options['profile'] if parent_options['profile']
141
+ @client = Twitter::Client.new(
142
+ :endpoint => base_url,
143
+ :consumer_key => @rcfile.default_consumer_key,
144
+ :consumer_secret => @rcfile.default_consumer_secret,
145
+ :oauth_token => @rcfile.default_token,
146
+ :oauth_token_secret => @rcfile.default_secret
147
+ )
148
+ end
149
+
150
+ def host
151
+ parent_options['host'] || DEFAULT_HOST
152
+ end
153
+
154
+ def protocol
155
+ parent_options['no_ssl'] ? 'http' : DEFAULT_PROTOCOL
156
+ end
157
+
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,86 @@
1
+ require 't/core_ext/string'
2
+ require 't/rcfile'
3
+ require 'thor'
4
+ require 'twitter'
5
+
6
+ module T
7
+ class CLI
8
+ class Set < Thor
9
+ DEFAULT_HOST = 'api.twitter.com'
10
+ DEFAULT_PROTOCOL = 'https'
11
+
12
+ check_unknown_options!
13
+
14
+ def initialize(*)
15
+ super
16
+ @rcfile = RCFile.instance
17
+ end
18
+
19
+ desc "bio DESCRIPTION", "Edits your Bio information on your Twitter profile."
20
+ def bio(description)
21
+ client.update_profile(:description => description, :include_entities => false)
22
+ say "@#{@rcfile.default_profile[0]}'s bio has been updated."
23
+ end
24
+
25
+ desc "default SCREEN_NAME [CONSUMER_KEY]", "Set your default account."
26
+ def default(screen_name, consumer_key=nil)
27
+ screen_name = screen_name.strip_at
28
+ @rcfile.path = parent_options['profile'] if parent_options['profile']
29
+ consumer_key = rcfile[screen_name].keys.last if consumer_key.nil?
30
+ @rcfile.default_profile = {'username' => screen_name, 'consumer_key' => consumer_key}
31
+ say "Default account has been updated."
32
+ end
33
+
34
+ desc "language LANGUAGE_NAME", "Selects the language you'd like to receive notifications in."
35
+ def language(language_name)
36
+ client.settings(:lang => language_name)
37
+ say "@#{@rcfile.default_profile[0]}'s language has been updated."
38
+ end
39
+
40
+ desc "location PLACE_NAME", "Updates the location field in your profile."
41
+ def location(place_name)
42
+ client.update_profile(:location => place_name, :include_entities => false)
43
+ say "@#{@rcfile.default_profile[0]}'s location has been updated."
44
+ end
45
+
46
+ desc "name NAME", "Sets the name field on your Twitter profile."
47
+ def name(name)
48
+ client.update_profile(:name => name, :include_entities => false)
49
+ say "@#{@rcfile.default_profile[0]}'s name has been updated."
50
+ end
51
+
52
+ desc "url URL", "Sets the URL field on your profile."
53
+ def url(url)
54
+ client.update_profile(:url => url, :include_entities => false)
55
+ say "@#{@rcfile.default_profile[0]}'s URL has been updated."
56
+ end
57
+
58
+ private
59
+
60
+ def base_url
61
+ "#{protocol}://#{host}"
62
+ end
63
+
64
+ def client
65
+ return @client if @client
66
+ @rcfile.path = parent_options['profile'] if parent_options['profile']
67
+ @client = Twitter::Client.new(
68
+ :endpoint => base_url,
69
+ :consumer_key => @rcfile.default_consumer_key,
70
+ :consumer_secret => @rcfile.default_consumer_secret,
71
+ :oauth_token => @rcfile.default_token,
72
+ :oauth_token_secret => @rcfile.default_secret
73
+ )
74
+ end
75
+
76
+ def host
77
+ parent_options['host'] || DEFAULT_HOST
78
+ end
79
+
80
+ def protocol
81
+ parent_options['no_ssl'] ? 'http' : DEFAULT_PROTOCOL
82
+ end
83
+
84
+ end
85
+ end
86
+ end