embedly 1.0.0 → 1.1.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.
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: