embedly 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -27,8 +27,8 @@ You can find rdocs at http://rubydoc.info/github/embedly/embedly-ruby/master/fra
27
27
 
28
28
  # single url
29
29
  obj = embedly_api.oembed :url => 'http://blog.embed.ly'
30
- puts obj.marshal_dump
31
- json_obj = JSON.pretty_generate(obj.marshal_dump)
30
+ puts obj[0].marshal_dump
31
+ json_obj = JSON.pretty_generate(obj[0].marshal_dump)
32
32
  puts json_obj
33
33
 
34
34
  # multiple urls with opts
@@ -45,7 +45,7 @@ You can find rdocs at http://rubydoc.info/github/embedly/embedly-ruby/master/fra
45
45
  embedly_pro = Embedly::API.new :key => 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
46
46
  url = 'http://www.guardian.co.uk/media/2011/jan/21/andy-coulson-phone-hacking-statement'
47
47
  obj = embedly_pro.preview :url => url
48
- puts JSON.pretty_generate(obj.marshal_dump)
48
+ puts JSON.pretty_generate(obj[0].marshal_dump)
49
49
 
50
50
  == Testing
51
51
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -4,7 +4,7 @@ $:.unshift(File.expand_path('../../lib', __FILE__))
4
4
 
5
5
  options = OpenStruct.new({
6
6
  :endpoint => nil,
7
- :key => nil,
7
+ :key => ENV['EMBEDLY_KEY'],
8
8
  :verbose => false,
9
9
  :args => {}
10
10
  })
@@ -26,11 +26,13 @@ Usage #{action} [OPTIONS] <url> [url] ..
26
26
  options.endpoint = e
27
27
  end
28
28
 
29
- opts.on("-k", "--key KEY", "Embedly PRO key") do |k|
29
+ opts.on("-k", "--key KEY", "Embedly PRO key [default: " +
30
+ "EMBEDLY_KEY environmental variable]") do |k|
30
31
  options.key = k
31
32
  end
32
33
 
33
- opts.on("-o", "--option NAME=VALUE", "Set option to be passed as query param.") do |o|
34
+ opts.on("-o", "--option NAME=VALUE", "Set option to be passed as " +
35
+ "query param.") do |o|
34
36
  k,v = o.split('=')
35
37
  options.args[k] = v
36
38
  end
@@ -4,7 +4,7 @@ $:.unshift(File.expand_path('../../lib', __FILE__))
4
4
 
5
5
  options = OpenStruct.new({
6
6
  :endpoint => nil,
7
- :key => nil,
7
+ :key => ENV['EMBEDLY_KEY'],
8
8
  :verbose => false,
9
9
  :args => {}
10
10
  })
@@ -26,11 +26,13 @@ Usage #{action} [OPTIONS] <url> [url] ..
26
26
  options.endpoint = e
27
27
  end
28
28
 
29
- opts.on("-k", "--key KEY", "Embedly PRO key") do |k|
29
+ opts.on("-k", "--key KEY", "Embedly PRO key [default: " +
30
+ "EMBEDLY_KEY environmental variable]") do |k|
30
31
  options.key = k
31
32
  end
32
33
 
33
- opts.on("-o", "--option NAME=VALUE", "Set option to be passed as query param.") do |o|
34
+ opts.on("-o", "--option NAME=VALUE", "Set option to be passed as " +
35
+ "query param.") do |o|
34
36
  k,v = o.split('=')
35
37
  options.args[k] = v
36
38
  end
@@ -4,7 +4,7 @@ $:.unshift(File.expand_path('../../lib', __FILE__))
4
4
 
5
5
  options = OpenStruct.new({
6
6
  :endpoint => nil,
7
- :key => nil,
7
+ :key => ENV['EMBEDLY_KEY'],
8
8
  :verbose => false,
9
9
  :args => {}
10
10
  })
@@ -26,11 +26,13 @@ Usage #{action} [OPTIONS] <url> [url] ..
26
26
  options.endpoint = e
27
27
  end
28
28
 
29
- opts.on("-k", "--key KEY", "Embedly PRO key") do |k|
29
+ opts.on("-k", "--key KEY", "Embedly PRO key [default: " +
30
+ "EMBEDLY_KEY environmental variable]") do |k|
30
31
  options.key = k
31
32
  end
32
33
 
33
- opts.on("-o", "--option NAME=VALUE", "Set option to be passed as query param.") do |o|
34
+ opts.on("-o", "--option NAME=VALUE", "Set option to be passed as " +
35
+ "query param.") do |o|
34
36
  k,v = o.split('=')
35
37
  options.args[k] = v
36
38
  end
@@ -72,8 +72,8 @@ Feature: OEmbed
72
72
 
73
73
  Examples:
74
74
  | url |
75
- | http://www.youtube.com/this/is/a/bad/url |
76
- | http://blog.embed.ly/lsbsdlfldsf/asdfkljlas/klajsdlfkasdf |
75
+ | http://www.youtube.com/watch/is/a/bad/url |
76
+ | http://www.scribd.com/doc/zfldsf/asdfkljlas/klajsdlfkasdf |
77
77
  | http://tweetphoto.com/alsdfldsf/asdfkljlas/klajsdlfkasdf |
78
78
 
79
79
 
@@ -85,8 +85,22 @@ Feature: OEmbed
85
85
 
86
86
  Examples:
87
87
  | urls | errcode | types |
88
- | http://www.youtube.com/this/is/a/bad/url,http://blog.embed.ly/alsd/slsdlf/asdlfj | 404,404 | error,error |
89
- | http://blog.embed.ly/lsbsdlfldsf/asdf/kl,http://tweetphoto.com/asdf/asdf/asdfl | 404,404 | error,error |
90
- | http://blog.embed.ly/lsbsdlfldsf/asdf/kl,http://tweetphoto.com/14784358 | 404, | error,photo |
91
- | http://tweetphoto.com/14784358,http://www.scribd.com/asdf/asdf/asdfasdf | ,404 | photo,error |
88
+ | 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
+ | http://www.youtube.com/watch/zzzzasdf/kl,http://tweetphoto.com/14784358 | 404, | error,photo |
91
+ | http://tweetphoto.com/14784358,http://www.scribd.com/doc/asdfasdfasdf | ,404 | photo,error |
92
92
 
93
+ Scenario Outline: Attempt at non-api service without key
94
+ Given an embedly endpoint
95
+ When oembed is called with the <url> URL
96
+ Then error_code should be 401
97
+ And error_message should be This service requires an Embedly Pro account
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 |
@@ -1,6 +1,9 @@
1
1
  $:.unshift(File.expand_path('../../../lib',__FILE__))
2
2
  require 'embedly'
3
3
 
4
+ # cache for endpoints
5
+ ENDPOINTS = {}
6
+
4
7
  Given /an embedly endpoint( [^\s]+)?( with key)?$/ do |endpoint, key_enabled|
5
8
  opts = {}
6
9
  opts[:endpoint] = endpoint
@@ -8,38 +11,47 @@ Given /an embedly endpoint( [^\s]+)?( with key)?$/ do |endpoint, key_enabled|
8
11
  raise 'Please set env variable $EMBEDLY_KEY' unless ENV['EMBEDLY_KEY']
9
12
  opts[:key] = ENV["EMBEDLY_KEY"]
10
13
  end
11
- @api = Embedly::API.new opts
14
+ if not ENDPOINTS[opts]
15
+ ENDPOINTS[opts] = Embedly::API.new opts
16
+ end
17
+ @api = ENDPOINTS[opts]
12
18
  end
13
19
 
14
20
  When /(\w+) is called with the (.*) URLs?( and ([^\s]+) flag)?$/ do |method, urls, _, flag|
15
- urls = urls.split(',')
16
- opts = {}
17
- if urls.size == 1
18
- opts[:url] = urls.first
19
- else
20
- opts[:urls] = urls
21
+ @result = nil
22
+ begin
23
+ urls = urls.split(',')
24
+ opts = {}
25
+ if urls.size == 1
26
+ opts[:url] = urls.first
27
+ else
28
+ opts[:urls] = urls
29
+ end
30
+ opts[flag.to_sym] = true if flag
31
+ @result = @api.send(method, opts)
32
+ rescue
33
+ @error = $!
21
34
  end
22
- opts[flag.to_sym] = true if flag
23
- @result = @api.send(method, opts)
24
35
  end
25
36
 
26
- Then /([^\s]+) should be ([^\s]+)/ do |key, value|
37
+ Then /an? (\w+) error should get thrown/ do |error|
38
+ @error.class.to_s.should == error
39
+ end
40
+
41
+ Then /([^\s]+) should be (.+)$/ do |key, value|
42
+ raise @error if @error
27
43
  logger = Embedly.logger('api_steps')
28
- if @result.is_a?Array
29
- @result.collect do |o|
30
- logger.debug { "result: #{o.marshal_dump}"}
31
- o.send(key).to_s
32
- end.join(',').should == value
33
- else
34
- logger.debug { "result: #{@result.marshal_dump}"}
35
- @result.send(key).to_s.should == value
36
- end
44
+ @result.collect do |o|
45
+ logger.debug { "result: #{o.marshal_dump}"}
46
+ o.send(key).to_s
47
+ end.join(',').should == value
37
48
  end
38
49
 
39
50
  Then /([^\s]+) should start with ([^\s]+)/ do |key, value|
51
+ raise @error if @error
40
52
  logger = Embedly.logger('api_steps')
41
- logger.debug { "result: #{@result.marshal_dump}"}
42
- v = key.split('.').inject(@result){|o,c| o.send(c)}.to_s
53
+ logger.debug { "result: #{@result[0].marshal_dump}"}
54
+ v = key.split('.').inject(@result[0]){|o,c| o.send(c)}.to_s
43
55
  v.to_s.should match(/^#{value}/)
44
56
  end
45
57
 
@@ -20,7 +20,7 @@ include ::Embedly
20
20
  #
21
21
  # api = Embedly::API.new
22
22
  # obj = api.oembed :url => 'http://blog.doki-pen.org/'
23
- # puts obj.title, obj.description, obj.thumbnail_url
23
+ # puts obj[0].title, obj[0].description, obj[0].thumbnail_url
24
24
  #
25
25
  # Call parameters should be passed as the opts parameter. If set, key will
26
26
  # automatically be added to the query string of the call, so no need to set it.
@@ -49,7 +49,7 @@ class Embedly::API
49
49
  else
50
50
  @endpoint = opts[:endpoint] || 'api.embed.ly'
51
51
  end
52
- @api_versions = Hash.new('1').merge!({'objectify' => '2'})
52
+ @api_version = Hash.new('1').merge!({'objectify' => '2'})
53
53
  @user_agent = opts[:user_agent] || "Mozilla/5.0 (compatible; embedly-ruby/#{Embedly::VERSION};)"
54
54
  end
55
55
 
@@ -71,46 +71,82 @@ class Embedly::API
71
71
 
72
72
  raise 'must pass urls' if opts[:urls].size == 0
73
73
 
74
- if opts[:urls].size == 1
75
- params = {:url => opts[:urls].first}
76
- else
77
- params = {:urls => opts[:urls]}
74
+ params = {:urls => opts[:urls]}
75
+
76
+ # store unsupported services as errors and don't send them to embedly
77
+ rejects = []
78
+ if not key
79
+ params[:urls].reject!.with_index do |url, i|
80
+ if url !~ services_regex
81
+ rejects << [i,
82
+ EmbedlyObject.new(
83
+ :type => 'error',
84
+ :error_code => 401,
85
+ :error_message => 'This service requires an Embedly Pro account'
86
+ )
87
+ ]
88
+ end
89
+ end
78
90
  end
79
91
 
80
- params[:key] = key if key
81
- params.merge!Hash[
82
- opts.select{|k,_| not [:url, :urls, :action, :version].index k}
83
- ]
92
+ if params[:urls].size > 0
93
+ params[:key] = key if key
94
+ params.merge!Hash[
95
+ opts.select{|k,_| not [:url, :urls, :action, :version].index k}
96
+ ]
84
97
 
85
- path = "/#{opts[:version]}/#{opts[:action]}?#{q params}"
98
+ path = "/#{opts[:version]}/#{opts[:action]}?#{q params}"
86
99
 
87
- ep = endpoint
88
- ep = "http://#{ep}" if endpoint !~ %r{^https?://.*}
89
- logger.debug { "calling #{ep}#{path}" }
100
+ logger.debug { "calling #{endpoint}#{path}" }
90
101
 
91
- url = URI.parse(ep)
92
- response = Net::HTTP.start(url.host, url.port) do |http|
93
- http.get(path, {'User-Agent' => user_agent})
94
- end
102
+ url = URI.parse(absurl(endpoint))
103
+ response = Net::HTTP.start(url.host, url.port) do |http|
104
+ http.get(path, {'User-Agent' => user_agent})
105
+ end
106
+
107
+ if response.code.to_i == 200
108
+ logger.debug { response.body }
109
+ # [].flatten is to be sure we have an array
110
+ objs = [JSON.parse(response.body)].flatten.collect {|o| EmbedlyObject.new(o)}
111
+ else
112
+ logger.error { response.inspect }
113
+ raise 'An unexpected error occurred'
114
+ end
95
115
 
96
- # passing url vs. urls causes different things to happen on errors (like a
97
- # 404 for the URL). using the url parameter returns a non 200 error code
98
- # in the response. Using urls causes an error json object to be returned,
99
- # but the main call will still be status 200. Below, we try to canonize as
100
- # best we can but it should really be changed server side.
101
- if response.code.to_i == 200
102
- logger.debug { response.body }
103
- # [].flatten is to be sure we have an array
104
- objs = [JSON.parse(response.body)].flatten.collect {|o| EmbedlyObject.new(o)}
116
+ # re-insert rejects into response
117
+ rejects.each do |i, obj|
118
+ objs.insert i, obj
119
+ end
120
+
121
+ objs
105
122
  else
106
- objs = EmbedlyObject.new :type => 'error', :error_code => response.code.to_i
123
+ # we only have rejects, return them without calling embedly
124
+ rejects.collect{|i, obj| obj}
107
125
  end
126
+ end
108
127
 
109
- if objs.size == 1
110
- objs.first
111
- else
112
- objs
128
+ # Returns structured data from the services API method.
129
+ #
130
+ # Response is cached per API object.
131
+ #
132
+ # see http://api.embed.ly/docs/service for a description of the response.
133
+ def services
134
+ logger.warn { "services isn't availble on the pro endpoint" } if key
135
+ if not @services
136
+ url = URI.parse(absurl(endpoint))
137
+ response = Net::HTTP.start(url.host, url.port) do |http|
138
+ http.get('/1/services/ruby', {'User-Agent' => user_agent})
139
+ end
140
+ raise 'services call failed', response if response.code.to_i != 200
141
+ @services = JSON.parse(response.body)
113
142
  end
143
+ @services
144
+ end
145
+
146
+ # Returns a regex suitable for checking urls against for non-Pro usage
147
+ def services_regex
148
+ r = services.collect {|p| p["regex"].join("|")}.join("|")
149
+ Regexp.new r
114
150
  end
115
151
 
116
152
  # Performs api call based on method name
@@ -124,11 +160,15 @@ class Embedly::API
124
160
  def method_missing(name, *args, &block)
125
161
  opts = args[0]
126
162
  opts[:action] = name
127
- opts[:version] = @api_versions[name]
163
+ opts[:version] = @api_version[name]
128
164
  apicall opts
129
165
  end
130
166
 
131
167
  private
168
+ def absurl uri
169
+ uri !~ %r{^https?://.*} ? "http://#{uri}" : uri
170
+ end
171
+
132
172
  # Escapes url parameters
133
173
  # TODO: move to utils
134
174
  def escape s
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
7
+ - 3
8
8
  - 0
9
- version: 0.2.0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Bob Corsaro
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-26 00:00:00 -05:00
17
+ date: 2011-02-04 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency