twitter-lists-cli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ twitter-lists-cli
2
+ =================
3
+ A command-line client for manipulating large Twitter lists in the shell, shell scripts, etc.
4
+
5
+ Currently supports
6
+ ------------------
7
+ - OAuth authentication
8
+ - Showing a users's followers/following
9
+ - Following and unfollowing users
10
+ - Showing, adding, and removing a members from a list
11
+
12
+ License
13
+ -------
14
+ Copyright (c) 2010 Dwayne Litzenberger
15
+
16
+ Permission is hereby granted, free of charge, to any person obtaining
17
+ a copy of this software and associated documentation files (the
18
+ "Software"), to deal in the Software without restriction, including
19
+ without limitation the rights to use, copy, modify, merge, publish,
20
+ distribute, sublicense, and/or sell copies of the Software, and to
21
+ permit persons to whom the Software is furnished to do so, subject to
22
+ the following conditions:
23
+
24
+ The above copyright notice and this permission notice shall be
25
+ included in all copies or substantial portions of the Software.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,26 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |s|
4
+ s.name = "twitter-lists-cli"
5
+ s.executables = ["twitter-auth", "twitter-follow", "twitter-following", "twitter-lists"]
6
+ s.summary = "Command-line client for manipulating Twitter lists."
7
+ s.email = "dlitz@dlitz.net"
8
+ s.homepage = "http://github.com/dlitz/twitter-lists-cli"
9
+ s.description = <<EOF
10
+ A command-line client for manipulating large Twitter lists in the shell, shell scripts, etc.
11
+
12
+ Currently supports
13
+ ------------------
14
+ - OAuth authentication
15
+ - Showing a users's followers/following
16
+ - Following and unfollowing users
17
+ - Showing, adding, and removing a members from a list
18
+ EOF
19
+ s.authors = ["Dwayne Litzenberger"]
20
+ s.files = FileList["[A-Z]*", "bin/**/*"]
21
+ s.add_dependency "twitter", "~> 0.9.5" # John Nunemaker's twitter gem
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: gem install jeweler"
26
+ end
@@ -0,0 +1,5 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 0
4
+ :minor: 1
5
+ :build:
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'twitter'
4
+
5
+ # Parse arguments
6
+ options = {:only => false, :unfollow=>false}
7
+ OptionParser.new do |opts|
8
+ opts.banner = "#{opts.program_name}"
9
+ opts.separator "Get OAuth credentials"
10
+ opts.separator ""
11
+ opts.separator "Global Options:"
12
+ opts.on("--auth FILE", "Read authentication data from the specified FILE") do |optarg|
13
+ options[:auth_file] = optarg
14
+ end
15
+ opts.separator ""
16
+ end.parse!
17
+ options[:auth_file] ||= ENV["TWITTER_AUTHFILE"]
18
+ options[:auth_file] ||= File.expand_path("~/.twitter")
19
+ raise "No --auth file specified" unless options[:auth_file] # XXX TODO - output usage information
20
+ raise "Too many arguments" unless ARGV.empty?
21
+
22
+ auth = YAML.load_file(options[:auth_file])
23
+ oauth = Twitter::OAuth.new(auth["token"], auth["secret"])
24
+ rt = oauth.request_token
25
+ puts "Go to https://#{rt.authorize_url}"
26
+ print "Enter the PIN here: "
27
+ $stdout.flush
28
+ pin = $stdin.readline.strip
29
+
30
+ atoken, asecret = oauth.authorize_from_request(rt.token, rt.secret, pin)
31
+
32
+ puts({"atoken" => atoken, "asecret" => asecret}.to_yaml)
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'twitter'
4
+
5
+ # Parse arguments
6
+ options = {:only => false, :unfollow=>false}
7
+ OptionParser.new do |opts|
8
+ opts.banner = "#{opts.program_name} [-l LISTNAME] [--only | -d] [USER...]"
9
+ opts.separator "Follow or unfollow users"
10
+ opts.separator ""
11
+ opts.on("-l", "--list LISTNAME", "act on the specified LISTNAME instead of the logged-in user") do |optarg|
12
+ options[:list] = optarg
13
+ end
14
+ opts.on("-d", "--unfollow", "unfollow the specified users") do |optarg|
15
+ options[:unfollow] = optarg
16
+ end
17
+ opts.separator ""
18
+ opts.separator "If no USERs are specified on the command line, they will be read from stdin."
19
+ opts.separator ""
20
+ opts.separator "Global Options:"
21
+ opts.on("--auth FILE", "Read authentication data from the specified FILE") do |optarg|
22
+ options[:auth_file] = optarg
23
+ end
24
+ opts.separator ""
25
+ end.parse!
26
+ options[:auth_file] ||= ENV["TWITTER_AUTHFILE"]
27
+ options[:auth_file] ||= File.expand_path("~/.twitter")
28
+ raise "No --auth file specified" unless options[:auth_file] # XXX TODO - output usage information
29
+ raise "--unfollow and --only are mutually exclusive" if options[:unfollow] and options[:only]
30
+ raise "--only not implemented yet" if options[:only]
31
+ if ARGV.empty?
32
+ users = []
33
+ begin
34
+ loop do
35
+ users << STDIN.readline.strip
36
+ end
37
+ rescue EOFError
38
+ end
39
+ users = users.select{|u| u =~ /[^\s]/} # skip blank lines
40
+ options[:users] = users
41
+ else
42
+ options[:users] = ARGV
43
+ end
44
+
45
+ auth = YAML.load_file(options[:auth_file])
46
+ oauth = Twitter::OAuth.new(auth["token"], auth["secret"])
47
+ oauth.authorize_from_access(auth["atoken"], auth["asecret"])
48
+ base = Twitter::Base.new(oauth)
49
+
50
+ # Knowing our own screen name is required when fetching list members
51
+ if options[:list]
52
+ options[:user] ||= auth["user"]
53
+ options[:user] ||= base.verify_credentials.screen_name
54
+ end
55
+
56
+ options[:users].each do |user|
57
+ if options[:list]
58
+ if options[:unfollow]
59
+ begin
60
+ base.list_remove_member(options[:user], options[:list], user)
61
+ rescue Twitter::TwitterError => e
62
+ # Don't raise exception if the user is already removed
63
+ raise unless e.data['error'] == "The user you are trying to remove from the list is not a member"
64
+ end
65
+ else
66
+ base.list_add_member(options[:user], options[:list], user)
67
+ end
68
+ else
69
+ if options[:unfollow]
70
+ begin
71
+ base.friendship_destroy(user)
72
+ rescue Twitter::TwitterError => e
73
+ raise unless e.data["error"] == "You are not friends with the specified user."
74
+ end
75
+ else
76
+ begin
77
+ base.friendship_create(user, true)
78
+ rescue Twitter::TwitterError => e
79
+ raise unless e.data["error"] =~ /\ACould not follow user: (.* is already on your list\.|You've already requested to follow .*)\Z/
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'twitter'
4
+
5
+ # Parse arguments
6
+ options = {}
7
+ OptionParser.new do |opts|
8
+ opts.banner = "#{opts.program_name} [-r] [-u USER] [LISTNAME]"
9
+ opts.separator "Show who is being followed by a user or a list"
10
+ opts.separator ""
11
+ opts.on("-u", "--user USER", "specify a username (default is the logged-in user)") do |optarg|
12
+ options[:user] = optarg
13
+ end
14
+ opts.on("-r", "--reverse", "show followers instead of who is following") do |optarg|
15
+ options[:reverse] = optarg
16
+ end
17
+ opts.separator ""
18
+ opts.separator "Global options:"
19
+ opts.on("--auth FILE", "Read authentication data from the specified FILE") do |optarg|
20
+ options[:auth_file] = optarg
21
+ end
22
+ opts.separator ""
23
+ end.parse!
24
+ options[:auth_file] ||= ENV["TWITTER_AUTHFILE"]
25
+ options[:auth_file] ||= File.expand_path("~/.twitter")
26
+ raise "No --auth file specified" unless options[:auth_file] # XXX TODO - output usage information
27
+ raise "Too many arguments specified" if ARGV.length > 1 # XXX TODO - output usage information
28
+ options[:list] = ARGV[0]
29
+
30
+ auth = YAML.load_file(options[:auth_file])
31
+ oauth = Twitter::OAuth.new(auth["token"], auth["secret"])
32
+ oauth.authorize_from_access(auth["atoken"], auth["asecret"])
33
+ base = Twitter::Base.new(oauth)
34
+
35
+ # Knowing our own screen name is required when fetching list members
36
+ if options[:list]
37
+ options[:user] ||= auth["user"]
38
+ options[:user] ||= base.verify_credentials.screen_name
39
+ end
40
+
41
+ cursor = -1
42
+ begin
43
+ query = {}
44
+ if options[:list]
45
+ if options[:reverse]
46
+ result = base.list_subscribers(options[:user], options[:list], query.merge(:cursor => cursor))
47
+ else
48
+ result = base.list_members(options[:user], options[:list], query.merge(:cursor => cursor))
49
+ end
50
+ else
51
+ query[:screen_name] = options[:user] if options[:user]
52
+ if options[:reverse]
53
+ result = base.followers(query.merge(:cursor => cursor))
54
+ else
55
+ result = base.friends(query.merge(:cursor => cursor))
56
+ end
57
+ end
58
+ result.users.each do |u|
59
+ puts u.screen_name
60
+ end
61
+ cursor = result.next_cursor
62
+ end until cursor == 0
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'twitter'
4
+
5
+ # Parse arguments
6
+ options = {:create => false, :delete => false}
7
+ OptionParser.new do |opts|
8
+ opts.banner = "#{opts.program_name} [-s] [-u USER] [-c LISTNAME... | -d LISTNAME...]"
9
+ opts.separator "Show, create, or delete lists"
10
+ opts.on("-u", "--user USER", "specify a username (default is the logged-in user)") do |optarg|
11
+ options[:user] = optarg
12
+ end
13
+ opts.on("-c", "--create", "create the specified list(s)") do |optarg|
14
+ options[:create] = true
15
+ end
16
+ opts.on("-d", "--delete", "delete the specified list(s)") do |optarg|
17
+ options[:delete] = true
18
+ end
19
+ opts.on("-s", "--slugs", "Use slugs instead of (possibly non-unique) names") do |optarg|
20
+ options[:slugs] = optarg
21
+ end
22
+ opts.separator ""
23
+ opts.separator "If no LISTNAMEs are specified on the command line, they will be read from stdin."
24
+ opts.separator ""
25
+ opts.separator "Global options:"
26
+ opts.on("--auth FILE", "Read authentication data from the specified FILE") do |optarg|
27
+ options[:auth_file] = optarg
28
+ end
29
+ opts.separator ""
30
+ end.parse!
31
+ options[:auth_file] ||= ENV["TWITTER_AUTHFILE"]
32
+ options[:auth_file] ||= File.expand_path("~/.twitter")
33
+ raise "No --auth file specified" unless options[:auth_file] # XXX TODO - output usage information
34
+ raise "--create and --delete are mutually exclusive" if options[:create] and options[:delete]
35
+ if (options[:create] || options[:delete])
36
+ if ARGV.empty?
37
+ lists = []
38
+ begin
39
+ loop do
40
+ lists << STDIN.readline.strip
41
+ end
42
+ rescue EOFError
43
+ end
44
+ lists = lists.select{|u| u =~ /[^\s]/} # skip blank lines
45
+ options[:lists] = lists
46
+ else
47
+ options[:lists] = ARGV
48
+ end
49
+ else
50
+ raise "No arguments are allowed without --create or --delete" unless ARGV.empty?
51
+ end
52
+
53
+ auth = YAML.load_file(options[:auth_file])
54
+ oauth = Twitter::OAuth.new(auth["token"], auth["secret"])
55
+ oauth.authorize_from_access(auth["atoken"], auth["asecret"])
56
+ base = Twitter::Base.new(oauth)
57
+
58
+ # Knowing our own screen name is required
59
+ options[:user] ||= auth["user"]
60
+ options[:user] ||= base.verify_credentials.screen_name
61
+
62
+ if options[:create]
63
+ options[:lists].each do |list|
64
+ base.list_create(options[:user], :name => list)
65
+ end
66
+ elsif options[:delete]
67
+ options[:lists].each do |list|
68
+ unless options[:slugs]
69
+ # convert list name to slug
70
+ list = list.downcase.gsub(/[^a-z0-9]+/, '-').gsub(/\A-+|-+\Z/, '').gsub(/-+/, '-')
71
+ end
72
+ base.list_delete(options[:user], list)
73
+ end
74
+ else
75
+ cursor = -1
76
+ begin
77
+ query = {}
78
+ result = base.lists(options[:user], query.merge(:cursor => cursor))
79
+ result.lists.each do |list|
80
+ puts options[:slugs] ? list.slug : list.name
81
+ end
82
+ cursor = result.next_cursor
83
+ end until cursor == 0
84
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: twitter-lists-cli
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Dwayne Litzenberger
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-07-10 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: twitter
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 9
30
+ - 5
31
+ version: 0.9.5
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: |
35
+ A command-line client for manipulating large Twitter lists in the shell, shell scripts, etc.
36
+
37
+ Currently supports
38
+ ------------------
39
+ - OAuth authentication
40
+ - Showing a users's followers/following
41
+ - Following and unfollowing users
42
+ - Showing, adding, and removing a members from a list
43
+
44
+ email: dlitz@dlitz.net
45
+ executables:
46
+ - twitter-auth
47
+ - twitter-follow
48
+ - twitter-following
49
+ - twitter-lists
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - README.md
54
+ files:
55
+ - README.md
56
+ - Rakefile
57
+ - VERSION.yml
58
+ - bin/twitter-auth
59
+ - bin/twitter-follow
60
+ - bin/twitter-following
61
+ - bin/twitter-lists
62
+ has_rdoc: true
63
+ homepage: http://github.com/dlitz/twitter-lists-cli
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --charset=UTF-8
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.3.6
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Command-line client for manipulating Twitter lists.
92
+ test_files: []
93
+