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.
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'robin'
4
+
5
+ main(STDOUT, STDIN, ARGV)
@@ -0,0 +1,11 @@
1
+ require_relative 'robin/client'
2
+ require_relative 'robin/args_parser'
3
+
4
+ def main(output, input, args)
5
+ action = Robin::ArgsParser.parse(args)
6
+ action.execute(Robin::Client, output, input)
7
+ end
8
+
9
+ if __FILE__ == $0
10
+ main(STDOUT, STDIN, ARGV)
11
+ end
@@ -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,7 @@
1
+ module Robin::Actions
2
+ class EmptyTweet
3
+ def execute(client, output, input)
4
+ output.puts "You cannot tweet an empty message!"
5
+ end
6
+ end
7
+ 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,9 @@
1
+ module Robin::Actions
2
+ class HomeTimeline
3
+ def execute(client, output, input)
4
+ client.home_timeline.each do |tweet|
5
+ output.puts tweet.full_text
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Robin::Actions
2
+ class NewTweet
3
+ def initialize(text)
4
+ @text = text
5
+ end
6
+
7
+ def execute(client, output, input)
8
+ output.puts client.tweet(@text).full_text
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Robin::Actions
2
+ class UnknownFlag
3
+ def initialize(flag)
4
+ @flag = flag
5
+ end
6
+
7
+ def execute(client, output, input)
8
+ output.puts "Unknown flag '#{@flag}'. Try -h for help."
9
+ end
10
+ end
11
+ 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
@@ -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
@@ -0,0 +1,11 @@
1
+ module Robin
2
+ class Config
3
+ def self.key
4
+ 'WgyUHBHODrfuzwGYdfukw'
5
+ end
6
+
7
+ def self.secret
8
+ '7MdWF7SXLTICfToz118RhHV07eMXKakbWmyIhlKE'
9
+ end
10
+ end
11
+ end
@@ -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
@@ -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: