embedly 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
1
  source :rubygems
2
2
 
3
3
  gem "querystring"
4
+ gem "oauth"
4
5
 
5
6
  group :development do
6
7
  gem "jeweler"
data/README.rdoc CHANGED
@@ -45,11 +45,11 @@ You can find rdocs at http://rubydoc.info/github/embedly/embedly-ruby/master/fra
45
45
  json_obj = JSON.pretty_generate(objs.collect{|o| o.marshal_dump})
46
46
  puts json_obj
47
47
 
48
- # call pro with key (you'll need a real key)
49
- embedly_pro = Embedly::API.new :key => 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
48
+ # call api with key (you'll need a real key)
49
+ embedly_api = Embedly::API.new :key => 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
50
50
  :user_agent => 'Mozilla/5.0 (compatible; mytestapp/1.0; my@email.com)'
51
51
  url = 'http://www.guardian.co.uk/media/2011/jan/21/andy-coulson-phone-hacking-statement'
52
- obj = embedly_pro.preview :url => url
52
+ obj = embedly_api.preview :url => url
53
53
  puts JSON.pretty_generate(obj[0].marshal_dump)
54
54
 
55
55
  == Testing
@@ -58,7 +58,7 @@ You can find rdocs at http://rubydoc.info/github/embedly/embedly-ruby/master/fra
58
58
  rake rspec
59
59
  rake features # if it complains of missing deps install them
60
60
 
61
- Some tests will fail due to missing pro key. Set the EMBEDLY_KEY environmental
61
+ Some tests will fail due to missing api key. Set the EMBEDLY_KEY environmental
62
62
  variable with your key to get them to pass.
63
63
 
64
64
  EMBEDLY_KEY=xxxxxxxxxxxxx rake features
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.0
@@ -1,79 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
  $:.unshift(File.expand_path('../../lib', __FILE__))
3
- %w{embedly json optparse ostruct}.each {|l| require l}
3
+ %w{embedly embedly/command_line json optparse ostruct}.each {|l| require l}
4
4
 
5
- options = OpenStruct.new({
6
- :hostname => nil,
7
- :key => ENV['EMBEDLY_KEY'] == '' ? nil : ENV['EMBEDLY_KEY'],
8
- :verbose => false,
9
- :args => {},
10
- :headers => {}
11
- })
5
+ api = Embedly::CommandLine.run!(:objectify, ARGV)
12
6
 
13
- action = File.basename(__FILE__)[/embedly_(\w+)/, 1]
14
-
15
- opts = OptionParser.new do |opts|
16
- opts.banner = <<-DOC
17
- Fetch JSON from the embedly #{action} service.
18
- Usage #{action} [OPTIONS] <url> [url] ..
19
- DOC
20
-
21
- opts.separator ""
22
- opts.separator "Options:"
23
-
24
- opts.on("-H", "--hostname ENDPOINT",
25
- "Embedly host. Default is api.embed.ly.") do |e|
26
- options.hostname = e
27
- end
28
-
29
- opts.on("--header NAME=VALUE",
30
- "HTTP header to send with requests.") do |header|
31
- n,v = header.split '='
32
- options.headers[n] = v
33
- end
34
-
35
- opts.on("-k", "--key KEY", "Embedly key [default: " +
36
- "EMBEDLY_KEY environmental variable]") do |k|
37
- options.key = k
38
- end
39
-
40
- opts.on("-N", "--no-key", "Ignore EMBEDLY_KEY environmental variable") do
41
- options.key = nil
42
- end
43
-
44
- opts.on("-o", "--option NAME=VALUE", "Set option to be passed as " +
45
- "query param.") do |o|
46
- k,v = o.split('=')
47
- options.args[k] = v
48
- end
49
-
50
- opts.separator ""
51
- opts.separator "Common Options:"
52
-
53
- opts.on("-v", "--verbose", "Run verbosely") do
54
- options.verbose = true
55
- end
56
-
57
- opts.on("-h", "--help", "Display this message") do
58
- puts opts
59
- exit
60
- end
61
-
62
- opts.separator ""
63
- opts.separator "Bob Corsaro <bob@embed.ly>"
64
- end
65
-
66
- opts.parse!
67
-
68
- if ARGV.size < 1
69
- $stderr.puts "ERROR: url required"
70
- $stderr.puts opts
71
- exit 1
7
+ begin
8
+ data = api.flatten.collect { |o| o.marshal_dump }
9
+ puts JSON.pretty_generate(data)
10
+ rescue Embedly::BadResponseException => e
11
+ puts "#{e.response.code} :: #{e.response.message}"
72
12
  end
73
-
74
- Embedly::Config.logging = true if options.verbose
75
-
76
- options.args[:urls] = ARGV
77
- api = Embedly::API.new options.marshal_dump
78
- objs = [api.send(action.to_sym, options.args)].flatten.collect{|o| o.marshal_dump}
79
- puts JSON.pretty_generate(objs)
data/bin/embedly_oembed CHANGED
@@ -1,79 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
  $:.unshift(File.expand_path('../../lib', __FILE__))
3
- %w{embedly json optparse ostruct}.each {|l| require l}
3
+ %w{embedly embedly/command_line json optparse ostruct}.each {|l| require l}
4
4
 
5
- options = OpenStruct.new({
6
- :hostname => nil,
7
- :key => ENV['EMBEDLY_KEY'] == '' ? nil : ENV['EMBEDLY_KEY'],
8
- :verbose => false,
9
- :args => {},
10
- :headers => {}
11
- })
5
+ api = Embedly::CommandLine.run!(:oembed, ARGV)
12
6
 
13
- action = File.basename(__FILE__)[/embedly_(\w+)/, 1]
14
-
15
- opts = OptionParser.new do |opts|
16
- opts.banner = <<-DOC
17
- Fetch JSON from the embedly #{action} service.
18
- Usage #{action} [OPTIONS] <url> [url] ..
19
- DOC
20
-
21
- opts.separator ""
22
- opts.separator "Options:"
23
-
24
- opts.on("-H", "--hostname ENDPOINT",
25
- "Embedly host. Default is api.embed.ly.") do |e|
26
- options.hostname = e
27
- end
28
-
29
- opts.on("--header NAME=VALUE",
30
- "HTTP header to send with requests.") do |header|
31
- n,v = header.split '='
32
- options.headers[n] = v
33
- end
34
-
35
- opts.on("-k", "--key KEY", "Embedly key [default: " +
36
- "EMBEDLY_KEY environmental variable]") do |k|
37
- options.key = k
38
- end
39
-
40
- opts.on("-N", "--no-key", "Ignore EMBEDLY_KEY environmental variable") do
41
- options.key = nil
42
- end
43
-
44
- opts.on("-o", "--option NAME=VALUE", "Set option to be passed as " +
45
- "query param.") do |o|
46
- k,v = o.split('=')
47
- options.args[k] = v
48
- end
49
-
50
- opts.separator ""
51
- opts.separator "Common Options:"
52
-
53
- opts.on("-v", "--verbose", "Run verbosely") do
54
- options.verbose = true
55
- end
56
-
57
- opts.on("-h", "--help", "Display this message") do
58
- puts opts
59
- exit
60
- end
61
-
62
- opts.separator ""
63
- opts.separator "Bob Corsaro <bob@embed.ly>"
64
- end
65
-
66
- opts.parse!
67
-
68
- if ARGV.size < 1
69
- $stderr.puts "ERROR: url required"
70
- $stderr.puts opts
71
- exit 1
7
+ begin
8
+ data = api.flatten.collect { |o| o.marshal_dump }
9
+ puts JSON.pretty_generate(data)
10
+ rescue Embedly::BadResponseException => e
11
+ puts "#{e.response.code} :: #{e.response.message}"
72
12
  end
73
-
74
- Embedly::Config.logging = true if options.verbose
75
-
76
- options.args[:urls] = ARGV
77
- api = Embedly::API.new options.marshal_dump
78
- objs = [api.send(action.to_sym, options.args)].flatten.collect{|o| o.marshal_dump}
79
- puts JSON.pretty_generate(objs)
data/bin/embedly_preview CHANGED
@@ -1,79 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
  $:.unshift(File.expand_path('../../lib', __FILE__))
3
- %w{embedly json optparse ostruct}.each {|l| require l}
3
+ %w{embedly embedly/command_line json optparse ostruct}.each {|l| require l}
4
4
 
5
- options = OpenStruct.new({
6
- :hostname => nil,
7
- :key => ENV['EMBEDLY_KEY'] == '' ? nil : ENV['EMBEDLY_KEY'],
8
- :verbose => false,
9
- :args => {},
10
- :headers => {}
11
- })
5
+ api = Embedly::CommandLine.run!(:preview, ARGV)
12
6
 
13
- action = File.basename(__FILE__)[/embedly_(\w+)/, 1]
14
-
15
- opts = OptionParser.new do |opts|
16
- opts.banner = <<-DOC
17
- Fetch JSON from the embedly #{action} service.
18
- Usage #{action} [OPTIONS] <url> [url] ..
19
- DOC
20
-
21
- opts.separator ""
22
- opts.separator "Options:"
23
-
24
- opts.on("-H", "--hostname ENDPOINT",
25
- "Embedly host. Default is api.embed.ly.") do |e|
26
- options.hostname = e
27
- end
28
-
29
- opts.on("--header NAME=VALUE",
30
- "HTTP header to send with requests.") do |header|
31
- n,v = header.split '='
32
- options.headers[n] = v
33
- end
34
-
35
- opts.on("-k", "--key KEY", "Embedly key [default: " +
36
- "EMBEDLY_KEY environmental variable]") do |k|
37
- options.key = k
38
- end
39
-
40
- opts.on("-N", "--no-key", "Ignore EMBEDLY_KEY environmental variable") do
41
- options.key = nil
42
- end
43
-
44
- opts.on("-o", "--option NAME=VALUE", "Set option to be passed as " +
45
- "query param.") do |o|
46
- k,v = o.split('=')
47
- options.args[k] = v
48
- end
49
-
50
- opts.separator ""
51
- opts.separator "Common Options:"
52
-
53
- opts.on("-v", "--verbose", "Run verbosely") do
54
- options.verbose = true
55
- end
56
-
57
- opts.on("-h", "--help", "Display this message") do
58
- puts opts
59
- exit
60
- end
61
-
62
- opts.separator ""
63
- opts.separator "Bob Corsaro <bob@embed.ly>"
64
- end
65
-
66
- opts.parse!
67
-
68
- if ARGV.size < 1
69
- $stderr.puts "ERROR: url required"
70
- $stderr.puts opts
71
- exit 1
7
+ begin
8
+ data = api.flatten.collect { |o| o.marshal_dump }
9
+ puts JSON.pretty_generate(data)
10
+ rescue Embedly::BadResponseException => e
11
+ puts "#{e.response.code} :: #{e.response.message}"
72
12
  end
73
-
74
- Embedly::Config.logging = true if options.verbose
75
-
76
- options.args[:urls] = ARGV
77
- api = Embedly::API.new options.marshal_dump
78
- objs = [api.send(action.to_sym, options.args)].flatten.collect{|o| o.marshal_dump}
79
- puts JSON.pretty_generate(objs)
@@ -11,5 +11,5 @@ Feature: Objectify
11
11
  And objectify api_version is 2
12
12
 
13
13
  Examples:
14
- | url | metadesc |
15
- | http://tweetphoto.com/14784358 | Earn PTZ when you watch |
14
+ | url | metadesc |
15
+ | http://lockerz.com/s/136425091 | Quentin Richardson's Photo on Lockerz.com |
@@ -5,20 +5,23 @@ Feature: OEmbed
5
5
  Because I want and oembed for a specific url
6
6
 
7
7
  Scenario Outline: Get the provider_url
8
- Given an embedly api
8
+ Given an embedly api with key
9
9
  When oembed is called with the <url> URL
10
10
  Then the provider_url should be <provider_url>
11
11
 
12
12
  Examples:
13
- | url | provider_url |
14
- | http://www.scribd.com/doc/13994900/Easter | http://www.scribd.com/ |
15
- | http://www.scribd.com/doc/28452730/Easter-Cards | http://www.scribd.com/ |
16
- | http://www.youtube.com/watch?v=Zk7dDekYej0 | http://www.youtube.com/ |
17
- | http://yfrog.com/h7qqespj | http://yfrog.com |
13
+ | url | provider_url |
14
+ | http://www.scribd.com/doc/13994900/Easter | http://www.scribd.com/ |
15
+ | http://www.scribd.com/doc/28452730/Easter-Cards | http://www.scribd.com/ |
16
+ | http://www.youtube.com/watch?v=Zk7dDekYej0 | http://www.youtube.com/ |
17
+ | http://yfrog.com/h7qqespj | http://yfrog.com |
18
+ | http://blog.embed.ly/bob | http://posterous.com |
19
+ | http://blog.doki-pen.org/cassandra-rules | http://posterous.com |
20
+ | http://www.guardian.co.uk/media/2011/jan/21/andy-coulson-phone-hacking-statement | http://www.guardian.co.uk/ |
18
21
 
19
22
 
20
23
  Scenario Outline: Get the types
21
- Given an embedly api
24
+ Given an embedly api with key
22
25
  When oembed is called with the <url> URL
23
26
  Then the type should be <type>
24
27
 
@@ -31,7 +34,7 @@ Feature: OEmbed
31
34
 
32
35
 
33
36
  Scenario Outline: Get the provider_url with force flag
34
- Given an embedly api
37
+ Given an embedly api with key
35
38
  When oembed is called with the <url> URL and force flag
36
39
  Then the provider_url should be <provider_url>
37
40
 
@@ -41,7 +44,7 @@ Feature: OEmbed
41
44
 
42
45
 
43
46
  Scenario Outline: Get multiple provider_urls
44
- Given an embedly api
47
+ Given an embedly api with key
45
48
  When oembed is called with the <urls> URLs
46
49
  Then provider_url should be <provider_urls>
47
50
 
@@ -51,20 +54,8 @@ Feature: OEmbed
51
54
  | http://www.youtube.com/watch?v=Zk7dDekYej0,http://yfrog.com/h7qqespj | http://www.youtube.com/,http://yfrog.com |
52
55
 
53
56
 
54
- Scenario Outline: Get the provider_url with pro
55
- Given an embedly api with key
56
- When oembed is called with the <url> URL
57
- Then the provider_url should be <provider_url>
58
-
59
- Examples:
60
- | url | provider_url |
61
- | http://blog.embed.ly/bob | http://posterous.com |
62
- | http://blog.doki-pen.org/cassandra-rules | http://posterous.com |
63
- | http://www.guardian.co.uk/media/2011/jan/21/andy-coulson-phone-hacking-statement | http://www.guardian.co.uk/ |
64
-
65
-
66
57
  Scenario Outline: Attempt to get 404 URL
67
- Given an embedly api
58
+ Given an embedly api with key
68
59
  When oembed is called with the <url> URL
69
60
  Then type should be error
70
61
  And error_code should be 404
@@ -73,12 +64,11 @@ Feature: OEmbed
73
64
  Examples:
74
65
  | url |
75
66
  | http://www.youtube.com/watch/is/a/bad/url |
76
- | http://www.scribd.com/doc/zfldsf/asdfkljlas/klajsdlfkasdf |
77
67
  | http://fav.me/alsfsdf |
78
68
 
79
69
 
80
70
  Scenario Outline: Attempt multi get 404 URLs
81
- Given an embedly api
71
+ Given an embedly api with key
82
72
  When oembed is called with the <urls> URLs
83
73
  Then error_code should be <errcode>
84
74
  And type should be <types>
@@ -86,21 +76,5 @@ Feature: OEmbed
86
76
  Examples:
87
77
  | urls | errcode | types |
88
78
  | http://www.youtube.com/watch/a/bassd/url,http://www.youtube.com/watch/ldf/asdlfj | 404,404 | error,error |
89
- | http://www.scribd.com/doc/lsbsdlfldsf/kl,http://www.scribd.com/doc/zasdf/asdfl | 404,404 | error,error |
90
79
  | http://www.youtube.com/watch/zzzzasdf/kl,http://yfrog.com/h7qqespj | 404, | error,photo |
91
- | http://yfrog.com/h7qqespj,http://www.scribd.com/doc/asdfasdfasdf | ,404 | photo,error |
92
-
93
- Scenario Outline: Attempt at non-api service without key
94
- Given an embedly api
95
- When oembed is called with the <url> URL
96
- Then error_code should be 401
97
- And error_message should be Embedly api key is required.
98
- And type should be error
99
-
100
- Examples:
101
- | urls |
102
- | http://hn.embed.ly/ |
103
- | http://bit.ly/enZRxO |
104
- | http://techcrunch.com/2011/02/03/linkedins-next-data-dive-professional-skills/ |
105
- | http://teachertube.com/rssPhoto.php |
106
- | http://goo.gl/y1i9p |
80
+ | http://yfrog.com/h7qqespj,http://www.youtube.com/watch/asdfasdfasdf | ,404 | photo,error |
@@ -9,6 +9,7 @@ Given /an embedly api( with key)?$/ do |key_enabled|
9
9
  if key_enabled
10
10
  raise 'Please set env variable $EMBEDLY_KEY' unless ENV['EMBEDLY_KEY']
11
11
  opts[:key] = ENV["EMBEDLY_KEY"]
12
+ opts[:secret] = ENV["EMBEDLY_SECRET"]
12
13
  end
13
14
  if not HOSTNAMES[opts]
14
15
  HOSTNAMES[opts] = Embedly::API.new opts
data/lib/embedly/api.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  require 'net/http'
2
+ require 'net/https'
2
3
  require 'json'
3
4
  require 'ostruct'
4
5
  require 'embedly/model'
6
+ require 'embedly/exceptions'
5
7
  require 'querystring'
8
+ require 'oauth'
6
9
 
7
10
 
8
11
  # Performs api calls to embedly.
@@ -34,7 +37,7 @@ require 'querystring'
34
37
  # api.new_method :arg1 => '1', :arg2 => '2'
35
38
  #
36
39
  class Embedly::API
37
- attr_reader :key, :hostname, :api_version, :headers
40
+ attr_reader :key, :hostname, :api_version, :headers, :secret
38
41
 
39
42
  def logger *args
40
43
  Embedly.logger *args
@@ -44,16 +47,48 @@ class Embedly::API
44
47
  #
45
48
  # [:+hostname+] Hostname of embedly server. Defaults to api.embed.ly.
46
49
  # [:+key+] Your api.embed.ly key.
50
+ # [:+secret+] Your api.embed.ly secret if you are using oauth.
47
51
  # [:+user_agent+] Your User-Agent header. Defaults to Mozilla/5.0 (compatible; embedly-ruby/VERSION;)
48
52
  # [:+headers+] Additional headers to send with requests.
49
53
  def initialize opts={}
50
54
  @endpoints = [:oembed, :objectify, :preview]
51
55
  @key = opts[:key]
56
+ @secret = opts[:secret] == "" ? nil : opts[:secret]
52
57
  @api_version = Hash.new('1')
53
58
  @api_version.merge!({:objectify => '2'})
54
59
  @hostname = opts[:hostname] || 'api.embed.ly'
55
- @headers = opts[:headers] || {}
56
- @headers['User-Agent'] = opts[:user_agent] || "Mozilla/5.0 (compatible; embedly-ruby/#{Embedly::VERSION};)"
60
+ @headers = {
61
+ 'User-Agent' => opts[:user_agent] || "Mozilla/5.0 (compatible; embedly-ruby/#{Embedly::VERSION};)"
62
+ }.merge(opts[:headers]||{})
63
+ end
64
+
65
+ def _do_basic_call path
66
+ scheme, host, port = uri_parse hostname
67
+ logger.debug { "calling #{site}#{path} with headers #{headers}" }
68
+ Net::HTTP.start(host, port, :use_ssl => scheme == 'https') do |http|
69
+ http.get(path, headers)
70
+ end
71
+ end
72
+
73
+ def _do_oauth_call path
74
+ consumer = OAuth::Consumer.new(key, secret,
75
+ :site => site,
76
+ :http_method => :get,
77
+ :scheme => :query_string)
78
+ # our implementation is broken for header authorization, thus the
79
+ # query_string
80
+
81
+ access_token = OAuth::AccessToken.new consumer
82
+ logger.debug { "calling #{site}#{path} with headers #{headers} via OAuth" }
83
+ access_token.get path, headers
84
+ end
85
+
86
+ def _do_call path
87
+ if key and secret
88
+ _do_oauth_call path
89
+ else
90
+ _do_basic_call path
91
+ end
57
92
  end
58
93
 
59
94
  # <b>Use methods oembed, objectify, preview in favor of this method.</b>
@@ -93,19 +128,14 @@ class Embedly::API
93
128
  end
94
129
 
95
130
  if params[:urls].size > 0
96
- params[:key] = key if key
131
+ params[:key] = key if key and not secret
97
132
  params.merge!Hash[
98
133
  opts.select{|k,_| not [:url, :urls, :action, :version].index k}
99
134
  ]
100
135
 
101
136
  path = "/#{opts[:version]}/#{opts[:action]}?#{QueryString.stringify(params)}"
102
137
 
103
- logger.debug { "calling #{hostname}#{path} with headers #{headers}" }
104
-
105
- host, port = uri_parse(hostname)
106
- response = Net::HTTP.start(host, port) do |http|
107
- http.get(path, headers)
108
- end
138
+ response = _do_call path
109
139
 
110
140
  if response.code.to_i == 200
111
141
  logger.debug { response.body }
@@ -114,8 +144,8 @@ class Embedly::API
114
144
  Embedly::EmbedlyObject.new(o)
115
145
  end
116
146
  else
117
- logger.error { response.inspect }
118
- raise 'An unexpected error occurred'
147
+ logger.debug { response }
148
+ raise Embedly::BadResponseException.new response
119
149
  end
120
150
 
121
151
  # re-insert rejects into response
@@ -137,10 +167,7 @@ class Embedly::API
137
167
  # see http://api.embed.ly/docs/service for a description of the response.
138
168
  def services
139
169
  if not @services
140
- host, port = uri_parse(hostname)
141
- response = Net::HTTP.start(host, port) do |http|
142
- http.get('/1/services/ruby', headers)
143
- end
170
+ response = _do_call '/1/services/ruby'
144
171
  raise 'services call failed', response if response.code.to_i != 200
145
172
  @services = JSON.parse(response.body)
146
173
  end
@@ -174,10 +201,20 @@ class Embedly::API
174
201
 
175
202
  private
176
203
  def uri_parse uri
177
- uri =~ %r{^(http(s?)://)?([^:/]+)(:([\d]+))?(/.*)?$}
178
- host = $3
179
- port = $5 ? $5 : ( $2 ? 443 : 80)
180
- [host, port.to_i]
204
+ uri =~ %r{^((http(s?))://)?([^:/]+)(:([\d]+))?(/.*)?$}
205
+ scheme = $2 || 'http'
206
+ host = $4
207
+ port = $6 ? $6 : ( scheme == 'https' ? 443 : 80)
208
+ [scheme, host, port.to_i]
209
+ end
210
+
211
+ def site
212
+ scheme, host, port = uri_parse hostname
213
+ if (scheme == 'http' and port == 80) or (scheme == 'https' and port == 443)
214
+ "#{scheme}://#{host}"
215
+ else
216
+ "#{scheme}://#{host}:#{port}"
217
+ end
181
218
  end
182
219
 
183
220
  def logger
@@ -0,0 +1,126 @@
1
+ require "optparse"
2
+
3
+ module Embedly
4
+ class CommandLine
5
+
6
+ class Parser
7
+ attr_accessor :options
8
+
9
+ def initialize(args)
10
+ @options, @args = default, args
11
+ end
12
+
13
+ def parse!
14
+ parser.parse!(@args)
15
+ set_urls!
16
+ reject_nil!
17
+ options
18
+ rescue OptionParser::InvalidOption => error
19
+ puts "ERROR: #{error.message}"
20
+ puts parser.on_tail
21
+ exit
22
+ end
23
+
24
+ def self.parse!(args)
25
+ new(args).parse!
26
+ end
27
+
28
+ private
29
+
30
+ def default
31
+ {
32
+ :key => ENV['EMBEDLY_KEY'],
33
+ :secret => ENV['EMBEDLY_SECRET'],
34
+ :headers => {},
35
+ :query => {}
36
+ }
37
+ end
38
+
39
+ def reject_nil!
40
+ options.reject! { |_, opt| opt.nil? }
41
+ end
42
+
43
+ def set_urls!
44
+ raise(OptionParser::InvalidOption, "url required") if @args.empty?
45
+ options[:query][:urls] = @args
46
+ end
47
+
48
+ def parser
49
+ OptionParser.new do |parser|
50
+ parser.banner = %{
51
+ Fetch JSON from the embedly service.
52
+ Usage [OPTIONS] <url> [url] ..
53
+ }
54
+
55
+ parser.separator ""
56
+ parser.separator "Options:"
57
+
58
+ parser.on('-H', '--hostname ENDPOINT', 'Embedly host. Default is api.embed.ly.') do |hostname|
59
+ options[:hostname] = hostname
60
+ end
61
+
62
+ parser.on("--header NAME=VALUE", "HTTP header to send with requests.") do |hash|
63
+ header, value = hash.split '='
64
+ options[:headers][header] = value
65
+ end
66
+
67
+ parser.on("-k", "--key KEY", "Embedly key [default: EMBEDLY_KEY environmental variable]") do |key|
68
+ options[:key] = key
69
+ end
70
+
71
+ parser.on("-N", "--no-key", "Ignore EMBEDLY_KEY environmental variable") do |key|
72
+ options[:key] = nil
73
+ end
74
+
75
+ parser.on("-s", "--secret SECRET", "Embedly secret [default: EMBEDLY_SECRET environmental variable]") do |secret|
76
+ options[:secret] = secret
77
+ end
78
+
79
+ parser.on("--no-secret", "Ignore EMBEDLY_SECRET environmental variable") do
80
+ options[:secret] = nil
81
+ end
82
+
83
+ parser.on("-o", "--option NAME=VALUE", "Set option to be passed as query param.") do |option|
84
+ key, value = option.split('=')
85
+ options[:query][key.to_sym] = value
86
+ end
87
+
88
+ parser.separator ""
89
+ parser.separator "Common Options:"
90
+
91
+ parser.on("-v", "--[no-]verbose", "Run verbosely") do |verbose|
92
+ Embedly::Config.logging = verbose
93
+ end
94
+
95
+ parser.on("-h", "--help", "Display this message") do
96
+ puts parser
97
+ exit
98
+ end
99
+
100
+ parser.separator ""
101
+ parser.separator "Bob Corsaro <bob@embed.ly>"
102
+ end
103
+ end
104
+ end
105
+
106
+ class << self
107
+ def run!(endpoint, args = [])
108
+ new(args).run(endpoint)
109
+ end
110
+ end
111
+
112
+ def initialize(args)
113
+ @options, @args = {}, args
114
+ end
115
+
116
+ def run(endpoint = :oembed)
117
+ api_options = options.dup
118
+ query = api_options.delete(:query)
119
+ Embedly::API.new(api_options).send(endpoint, query)
120
+ end
121
+
122
+ def options
123
+ @options = Parser.parse!(@args.dup)
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,7 @@
1
+ class Embedly::BadResponseException < RuntimeError
2
+ attr_accessor :response
3
+
4
+ def initialize response
5
+ @response ||= response
6
+ end
7
+ end
@@ -0,0 +1,118 @@
1
+ require "spec_helper"
2
+ require "embedly/command_line"
3
+
4
+ module Embedly
5
+ describe CommandLine do
6
+ after do
7
+ ENV['EMBEDLY_KEY'] = nil
8
+ ENV['EMBEDLY_SECRET'] = nil
9
+ end
10
+
11
+ describe "::run!" do
12
+ let(:arguments) { ['-k', 'MY_KEY', 'http://yfrog.com/h7qqespj', '-o', 'maxwidth=10'] }
13
+ let(:api) { mock(API) }
14
+
15
+ it "calls api with options" do
16
+ API.should_receive(:new).with(:key => 'MY_KEY', :headers => {}) { api }
17
+ api.should_receive(:oembed).with(:urls => ['http://yfrog.com/h7qqespj'], :maxwidth => '10')
18
+ CommandLine.run!(:oembed, arguments)
19
+ end
20
+
21
+ it "raises an error if the arguments are empty" do
22
+ $stdout = StringIO.new
23
+ expect {
24
+ CommandLine.run!(:oembed, [])
25
+ }.to raise_error(SystemExit)
26
+ end
27
+ end
28
+
29
+ describe "#run" do
30
+ before do
31
+ API.any_instance.stub(:oembed)
32
+ end
33
+
34
+ describe "with option --hostname" do
35
+ %w[-H --hostname].each do |option|
36
+ it "sets the hostname using #{option}" do
37
+ command([option, "sth.embed.ly"])[:hostname].should == 'sth.embed.ly'
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "with --header" do
43
+ it "sets the header" do
44
+ command(%w[--header Header=value])[:headers].should == { 'Header' => 'value' }
45
+ end
46
+ end
47
+
48
+ describe "with --key" do
49
+ %w[-k --key].each do |option|
50
+ it "sets the key using #{option}" do
51
+ command([option, "SOME_KEY"])[:key].should == 'SOME_KEY'
52
+ end
53
+ end
54
+
55
+ it "gets the key from environment variables if no key was set" do
56
+ ENV['EMBEDLY_KEY'] = 'ENVIRONMENT_KEY'
57
+
58
+ command([])[:key].should == 'ENVIRONMENT_KEY'
59
+ end
60
+ end
61
+
62
+ describe "with --secret" do
63
+ %w[-s --secret].each do |option|
64
+ it "sets the secret using #{option}" do
65
+ command([option, "SECRET"])[:secret].should == 'SECRET'
66
+ end
67
+ end
68
+
69
+ it "gets the secret from environment variables if no secret was set" do
70
+ ENV['EMBEDLY_SECRET'] = 'ENVIRONMENT_SECRET'
71
+
72
+ command([])[:secret].should == 'ENVIRONMENT_SECRET'
73
+ end
74
+ end
75
+
76
+ describe "with --no-key" do
77
+ %w[-N --no-key].each do |option|
78
+ it "unsets the key using #{option}" do
79
+ command([option])[:key].should be_nil
80
+ end
81
+ end
82
+ end
83
+
84
+ describe "with --no-secret" do
85
+ it "unsets the secret" do
86
+ command(['--no-secret'])[:secret].should be_nil
87
+ end
88
+ end
89
+
90
+ describe "with --option" do
91
+ %w[-o --option].each do |option|
92
+ it "sets custom option with #{option}" do
93
+ command([option, "maxwidth=100"])[:query][:maxwidth].should == '100'
94
+ end
95
+ end
96
+ end
97
+
98
+ describe "with --verbose" do
99
+ it "enables logging" do
100
+ command(["--verbose"])
101
+ Embedly::Config.logging.should be_true
102
+ end
103
+
104
+ it "disables logging" do
105
+ command(["--no-verbose"])
106
+ Embedly::Config.logging.should be_false
107
+ end
108
+ end
109
+ end
110
+
111
+ def command(arguments)
112
+ arguments << 'testurl.com'
113
+ command = CommandLine.new(arguments)
114
+ command.run
115
+ command.options
116
+ end
117
+ end
118
+ end
@@ -0,0 +1 @@
1
+ require "embedly"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embedly
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-06-22 00:00:00.000000000 -04:00
12
+ date: 2011-09-06 00:00:00.000000000 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: querystring
17
- requirement: &72141180 !ruby/object:Gem::Requirement
17
+ requirement: &72100880 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,21 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *72141180
25
+ version_requirements: *72100880
26
+ - !ruby/object:Gem::Dependency
27
+ name: oauth
28
+ requirement: &72100640 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *72100640
26
37
  - !ruby/object:Gem::Dependency
27
38
  name: jeweler
28
- requirement: &72195490 !ruby/object:Gem::Requirement
39
+ requirement: &72100400 !ruby/object:Gem::Requirement
29
40
  none: false
30
41
  requirements:
31
42
  - - ! '>='
@@ -33,10 +44,10 @@ dependencies:
33
44
  version: '0'
34
45
  type: :development
35
46
  prerelease: false
36
- version_requirements: *72195490
47
+ version_requirements: *72100400
37
48
  - !ruby/object:Gem::Dependency
38
49
  name: cucumber
39
- requirement: &72195250 !ruby/object:Gem::Requirement
50
+ requirement: &72100160 !ruby/object:Gem::Requirement
40
51
  none: false
41
52
  requirements:
42
53
  - - ! '>='
@@ -44,10 +55,10 @@ dependencies:
44
55
  version: '0'
45
56
  type: :development
46
57
  prerelease: false
47
- version_requirements: *72195250
58
+ version_requirements: *72100160
48
59
  - !ruby/object:Gem::Dependency
49
60
  name: rake
50
- requirement: &72195010 !ruby/object:Gem::Requirement
61
+ requirement: &72099920 !ruby/object:Gem::Requirement
51
62
  none: false
52
63
  requirements:
53
64
  - - ! '>='
@@ -55,10 +66,10 @@ dependencies:
55
66
  version: '0'
56
67
  type: :development
57
68
  prerelease: false
58
- version_requirements: *72195010
69
+ version_requirements: *72099920
59
70
  - !ruby/object:Gem::Dependency
60
71
  name: rspec
61
- requirement: &72194770 !ruby/object:Gem::Requirement
72
+ requirement: &72099680 !ruby/object:Gem::Requirement
62
73
  none: false
63
74
  requirements:
64
75
  - - ! '>='
@@ -66,10 +77,10 @@ dependencies:
66
77
  version: '0'
67
78
  type: :development
68
79
  prerelease: false
69
- version_requirements: *72194770
80
+ version_requirements: *72099680
70
81
  - !ruby/object:Gem::Dependency
71
82
  name: yard
72
- requirement: &72194530 !ruby/object:Gem::Requirement
83
+ requirement: &72099440 !ruby/object:Gem::Requirement
73
84
  none: false
74
85
  requirements:
75
86
  - - ! '>='
@@ -77,7 +88,7 @@ dependencies:
77
88
  version: '0'
78
89
  type: :development
79
90
  prerelease: false
80
- version_requirements: *72194530
91
+ version_requirements: *72099440
81
92
  description: Ruby Embedly client library
82
93
  email: bob@embed.ly
83
94
  executables:
@@ -106,7 +117,11 @@ files:
106
117
  - features/steps/env.rb
107
118
  - lib/embedly.rb
108
119
  - lib/embedly/api.rb
120
+ - lib/embedly/command_line.rb
121
+ - lib/embedly/exceptions.rb
109
122
  - lib/embedly/model.rb
123
+ - spec/embedly/command_line_spec.rb
124
+ - spec/spec_helper.rb
110
125
  has_rdoc: true
111
126
  homepage: http://github.com/embedly/embedly-ruby
112
127
  licenses:
@@ -123,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
138
  version: '0'
124
139
  segments:
125
140
  - 0
126
- hash: 44977427
141
+ hash: 930401473
127
142
  required_rubygems_version: !ruby/object:Gem::Requirement
128
143
  none: false
129
144
  requirements: