embedly 0.2.0 → 0.3.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/README.rdoc +3 -3
- data/VERSION +1 -1
- data/bin/embedly_objectify +5 -3
- data/bin/embedly_oembed +5 -3
- data/bin/embedly_preview +5 -3
- data/features/oembed.feature +20 -6
- data/features/steps/api_steps.rb +33 -21
- data/lib/embedly/api.rb +73 -33
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -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.
|
1
|
+
0.3.0
|
data/bin/embedly_objectify
CHANGED
@@ -4,7 +4,7 @@ $:.unshift(File.expand_path('../../lib', __FILE__))
|
|
4
4
|
|
5
5
|
options = OpenStruct.new({
|
6
6
|
:endpoint => nil,
|
7
|
-
:key =>
|
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"
|
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
|
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
|
data/bin/embedly_oembed
CHANGED
@@ -4,7 +4,7 @@ $:.unshift(File.expand_path('../../lib', __FILE__))
|
|
4
4
|
|
5
5
|
options = OpenStruct.new({
|
6
6
|
:endpoint => nil,
|
7
|
-
:key =>
|
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"
|
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
|
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
|
data/bin/embedly_preview
CHANGED
@@ -4,7 +4,7 @@ $:.unshift(File.expand_path('../../lib', __FILE__))
|
|
4
4
|
|
5
5
|
options = OpenStruct.new({
|
6
6
|
:endpoint => nil,
|
7
|
-
:key =>
|
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"
|
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
|
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
|
data/features/oembed.feature
CHANGED
@@ -72,8 +72,8 @@ Feature: OEmbed
|
|
72
72
|
|
73
73
|
Examples:
|
74
74
|
| url |
|
75
|
-
| http://www.youtube.com/
|
76
|
-
| http://
|
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/
|
89
|
-
| http://
|
90
|
-
| http://
|
91
|
-
| http://tweetphoto.com/14784358,http://www.scribd.com/
|
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 |
|
data/features/steps/api_steps.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
opts
|
19
|
-
|
20
|
-
|
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 /(
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
|
data/lib/embedly/api.rb
CHANGED
@@ -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
|
-
@
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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[:
|
81
|
-
|
82
|
-
|
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
|
-
|
98
|
+
path = "/#{opts[:version]}/#{opts[:action]}?#{q params}"
|
86
99
|
|
87
|
-
|
88
|
-
ep = "http://#{ep}" if endpoint !~ %r{^https?://.*}
|
89
|
-
logger.debug { "calling #{ep}#{path}" }
|
100
|
+
logger.debug { "calling #{endpoint}#{path}" }
|
90
101
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
123
|
+
# we only have rejects, return them without calling embedly
|
124
|
+
rejects.collect{|i, obj| obj}
|
107
125
|
end
|
126
|
+
end
|
108
127
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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] = @
|
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
|
-
-
|
7
|
+
- 3
|
8
8
|
- 0
|
9
|
-
version: 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-
|
17
|
+
date: 2011-02-04 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|