Robin 0.0.3
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/bin/robin +5 -0
- data/lib/robin.rb +11 -0
- data/lib/robin/actions/authenticate.rb +38 -0
- data/lib/robin/actions/empty_tweet.rb +7 -0
- data/lib/robin/actions/followers.rb +22 -0
- data/lib/robin/actions/help.rb +16 -0
- data/lib/robin/actions/home_timeline.rb +9 -0
- data/lib/robin/actions/new_tweet.rb +11 -0
- data/lib/robin/actions/unknown_flag.rb +11 -0
- data/lib/robin/actions/user_timeline.rb +19 -0
- data/lib/robin/args_parser.rb +70 -0
- data/lib/robin/client.rb +38 -0
- data/lib/robin/config.rb +11 -0
- data/lib/robin/pin_authenticator.rb +31 -0
- data/lib/robin/user.rb +36 -0
- metadata +61 -0
data/bin/robin
ADDED
data/lib/robin.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../pin_authenticator'
|
2
|
+
|
3
|
+
module Robin::Actions
|
4
|
+
class Authenticate
|
5
|
+
def execute(client, output, input)
|
6
|
+
output.print instructions(PinAuthenticator.authorize_url)
|
7
|
+
pin = input.gets.chomp
|
8
|
+
if PinAuthenticator.authenticate(pin)
|
9
|
+
output.puts success
|
10
|
+
else
|
11
|
+
output.puts failed
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def instructions(url)
|
16
|
+
instructions = <<EOF
|
17
|
+
In order to use Robin you need to authenticate with your Twitter account.
|
18
|
+
To do this, first, point your browser to the following URL:
|
19
|
+
|
20
|
+
#{url}
|
21
|
+
|
22
|
+
Log in if required.
|
23
|
+
You must now authorize the app and type the given PIN.
|
24
|
+
|
25
|
+
PIN >>
|
26
|
+
EOF
|
27
|
+
instructions.chomp
|
28
|
+
end
|
29
|
+
|
30
|
+
def success
|
31
|
+
"Great. You can now use Robin."
|
32
|
+
end
|
33
|
+
|
34
|
+
def failed
|
35
|
+
"Pin was incorrect"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Robin::Actions
|
2
|
+
class Followers
|
3
|
+
def initialize(user = nil)
|
4
|
+
@user = user
|
5
|
+
end
|
6
|
+
|
7
|
+
def execute(client, output, input)
|
8
|
+
begin
|
9
|
+
if @user
|
10
|
+
followers = client.followers(@user)
|
11
|
+
else
|
12
|
+
followers = client.followers
|
13
|
+
end
|
14
|
+
followers.each do |follower|
|
15
|
+
output.puts "#{follower.name} (#{follower.screen_name})"
|
16
|
+
end
|
17
|
+
rescue Twitter::Error::NotFound => e
|
18
|
+
output.puts "This user does not exist"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Robin::Actions
|
2
|
+
class Help
|
3
|
+
HELP = <<EOF
|
4
|
+
Usage:
|
5
|
+
-user - Authenticate new user
|
6
|
+
[-s] - Authenticated user's home timeline
|
7
|
+
<tweet>, -t <tweet> - New Tweet
|
8
|
+
-fr [<user>] - Followers for the authenticated user or a specific user handle
|
9
|
+
-i [<user>] - The user timeline for the authenticated user or specified user handle
|
10
|
+
-h - This help message
|
11
|
+
EOF
|
12
|
+
def execute(client, output, input)
|
13
|
+
output.puts HELP
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Robin::Actions
|
2
|
+
class UserTimeline
|
3
|
+
def initialize(user = nil)
|
4
|
+
@user = user
|
5
|
+
end
|
6
|
+
|
7
|
+
def execute(client, output, input)
|
8
|
+
if @user
|
9
|
+
timeline = client.user_timeline(@user)
|
10
|
+
else
|
11
|
+
timeline = client.user_timeline
|
12
|
+
end
|
13
|
+
|
14
|
+
timeline.each do |tweet|
|
15
|
+
output.puts tweet.full_text
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative 'actions/new_tweet'
|
2
|
+
require_relative 'actions/home_timeline'
|
3
|
+
require_relative 'actions/user_timeline'
|
4
|
+
require_relative 'actions/followers'
|
5
|
+
require_relative 'actions/unknown_flag'
|
6
|
+
require_relative 'actions/help'
|
7
|
+
require_relative 'actions/empty_tweet'
|
8
|
+
require_relative 'actions/authenticate'
|
9
|
+
|
10
|
+
module Robin
|
11
|
+
class ArgsParser
|
12
|
+
USER_TIMELINE = ['i']
|
13
|
+
NEW_TWEET = ['t']
|
14
|
+
FOLLOWERS = ['fr']
|
15
|
+
HOME_TIMELINE = ['s']
|
16
|
+
HELP = ['h', '-help']
|
17
|
+
NEW_USER = ['user']
|
18
|
+
|
19
|
+
def self.parse(args)
|
20
|
+
if args.empty?
|
21
|
+
Robin::Actions::HomeTimeline.new
|
22
|
+
else
|
23
|
+
parse_args(args)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.parse_args(args)
|
30
|
+
if args[0].start_with?('-')
|
31
|
+
using_flag(args)
|
32
|
+
else
|
33
|
+
Robin::Actions::NewTweet.new(args[0])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.using_flag(args)
|
38
|
+
flag = args[0][1..args[0].length]
|
39
|
+
option = args[1]
|
40
|
+
|
41
|
+
if USER_TIMELINE.include?(flag)
|
42
|
+
Robin::Actions::UserTimeline.new(option)
|
43
|
+
elsif NEW_USER.include?(flag)
|
44
|
+
Robin::Actions::Authenticate.new
|
45
|
+
elsif NEW_TWEET.include?(flag)
|
46
|
+
tweet(option)
|
47
|
+
elsif FOLLOWERS.include?(flag)
|
48
|
+
followers(option)
|
49
|
+
elsif HOME_TIMELINE.include?(flag)
|
50
|
+
Robin::Actions::HomeTimeline.new
|
51
|
+
elsif HELP.include?(flag)
|
52
|
+
Robin::Actions::Help.new
|
53
|
+
else
|
54
|
+
Robin::Actions::UnknownFlag.new(flag)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.tweet(option)
|
59
|
+
if option && !option.empty?
|
60
|
+
Robin::Actions::NewTweet.new(option)
|
61
|
+
else
|
62
|
+
Robin::Actions::EmptyTweet.new
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.followers(option)
|
67
|
+
Robin::Actions::Followers.new(option)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/robin/client.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'config'
|
2
|
+
require_relative 'user'
|
3
|
+
require 'twitter'
|
4
|
+
|
5
|
+
module Robin
|
6
|
+
class Client
|
7
|
+
Robin::User.load_credentials
|
8
|
+
@client = Twitter::Client.new(
|
9
|
+
:consumer_key => Robin::Config.key,
|
10
|
+
:consumer_secret => Robin::Config.secret,
|
11
|
+
:oauth_token => Robin::User.token,
|
12
|
+
:oauth_token_secret => Robin::User.secret)
|
13
|
+
|
14
|
+
def self.home_timeline
|
15
|
+
@client.home_timeline
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.user_timeline(user = nil)
|
19
|
+
if user
|
20
|
+
@client.user_timeline(user)
|
21
|
+
else
|
22
|
+
@client.user_timeline
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.tweet(message)
|
27
|
+
@client.update(message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.followers(user = nil)
|
31
|
+
if user
|
32
|
+
@client.followers(user).users
|
33
|
+
else
|
34
|
+
@client.followers.users
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/robin/config.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require_relative 'user'
|
3
|
+
|
4
|
+
class PinAuthenticator
|
5
|
+
|
6
|
+
def self.authorize_url
|
7
|
+
consumer = OAuth::Consumer.new(Robin::Config.key,
|
8
|
+
Robin::Config.secret,
|
9
|
+
{ :site => 'http://twitter.com/',
|
10
|
+
:request_token_path => '/oauth/request_token',
|
11
|
+
:access_token_path => '/oauth/access_token',
|
12
|
+
:authorize_path => '/oauth/authorize' })
|
13
|
+
begin
|
14
|
+
@request_token = consumer.get_request_token
|
15
|
+
rescue Net::HTTPRetriableError => e
|
16
|
+
@request_token = consumer.get_request_token
|
17
|
+
end
|
18
|
+
@request_token.authorize_url()
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.authenticate(pin)
|
22
|
+
begin
|
23
|
+
access_token = @request_token.get_access_token(:oauth_verifier => pin)
|
24
|
+
Robin::User.register_new(access_token.token,
|
25
|
+
access_token.secret)
|
26
|
+
true
|
27
|
+
rescue OAuth::Unauthorized => e
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/robin/user.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module Robin
|
2
|
+
class User
|
3
|
+
CREDENTIALS = File.expand_path('~/.robin')
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_reader :token, :secret
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.load_credentials
|
10
|
+
credentials = read_credentials.split(/\n/)
|
11
|
+
@token = credentials[0]
|
12
|
+
@secret = credentials[1]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.read_credentials
|
16
|
+
raise NoCredentials.new unless File.exists?(CREDENTIALS)
|
17
|
+
credentials = File.expand_path(CREDENTIALS)
|
18
|
+
File.read(credentials)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.register_new(token, secret)
|
22
|
+
write_credentials(token, secret)
|
23
|
+
load_credentials
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def self.write_credentials(token, secret)
|
28
|
+
File.open(CREDENTIALS, 'w') do |file|
|
29
|
+
file.write("#{token}\n#{secret}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class NoCredentials < Exception
|
35
|
+
end
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: Robin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Radu Busuioc
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-13 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A twitter client for the command line
|
15
|
+
email: ra.busuioc@gmail.com
|
16
|
+
executables:
|
17
|
+
- robin
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/robin/actions/authenticate.rb
|
22
|
+
- lib/robin/actions/empty_tweet.rb
|
23
|
+
- lib/robin/actions/followers.rb
|
24
|
+
- lib/robin/actions/help.rb
|
25
|
+
- lib/robin/actions/home_timeline.rb
|
26
|
+
- lib/robin/actions/new_tweet.rb
|
27
|
+
- lib/robin/actions/unknown_flag.rb
|
28
|
+
- lib/robin/actions/user_timeline.rb
|
29
|
+
- lib/robin/args_parser.rb
|
30
|
+
- lib/robin/client.rb
|
31
|
+
- lib/robin/config.rb
|
32
|
+
- lib/robin/pin_authenticator.rb
|
33
|
+
- lib/robin/user.rb
|
34
|
+
- lib/robin.rb
|
35
|
+
- bin/robin
|
36
|
+
homepage: https://github.com/zduci/robin
|
37
|
+
licenses: []
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
requirements: []
|
55
|
+
rubyforge_project:
|
56
|
+
rubygems_version: 1.8.24
|
57
|
+
signing_key:
|
58
|
+
specification_version: 3
|
59
|
+
summary: A twitter client for the command line
|
60
|
+
test_files: []
|
61
|
+
has_rdoc:
|