embedly 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +86 -0
- data/Rakefile +59 -0
- data/VERSION +1 -0
- data/bin/embedly_objectify +67 -0
- data/bin/embedly_oembed +67 -0
- data/bin/embedly_preview +67 -0
- data/cucumber.yml +1 -0
- data/features/oembed.feature +79 -0
- data/features/steps/api_steps.rb +38 -0
- data/features/steps/env.rb +3 -0
- data/lib/embedly.rb +17 -0
- data/lib/embedly/api.rb +153 -0
- metadata +130 -0
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.9.2@embedly
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Embed.ly, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
= embedly
|
2
|
+
|
3
|
+
Embedly ruby client library. To find out what Embedly is all about, please
|
4
|
+
visit http://embed.ly. To see our api documentation, visit
|
5
|
+
http://api.embed.ly/docs.
|
6
|
+
|
7
|
+
== Installing
|
8
|
+
|
9
|
+
To install the official latest stable version, please use rubygems.
|
10
|
+
|
11
|
+
gem install embedly
|
12
|
+
|
13
|
+
If you would like cutting edge, then you can clone and install HEAD.
|
14
|
+
|
15
|
+
git clone git@github.com:embedly/embedly-ruby.git
|
16
|
+
cd embedly-ruby
|
17
|
+
rake install
|
18
|
+
|
19
|
+
== Getting Started
|
20
|
+
|
21
|
+
You can find rdocs at http://embedly.github.com/embedly-ruby.
|
22
|
+
|
23
|
+
require 'embedly'
|
24
|
+
require 'json'
|
25
|
+
|
26
|
+
embedly_api = Embedly::API.new
|
27
|
+
|
28
|
+
# single url
|
29
|
+
obj = embedly_api.oembed :url => 'http://blog.embed.ly'
|
30
|
+
puts obj.marshal_dump
|
31
|
+
json_obj = JSON.pretty_generate(obj.marshal_dump)
|
32
|
+
puts json_obj
|
33
|
+
|
34
|
+
# multiple urls with opts
|
35
|
+
objs = embedly_api.oembed(
|
36
|
+
:urls => ['http://blog.embed.ly', 'http://blog.doki-pen.org'],
|
37
|
+
:maxWidth => 450,
|
38
|
+
:wmode => 'transparent',
|
39
|
+
:method => 'after'
|
40
|
+
)
|
41
|
+
puts obj.marshal_dump
|
42
|
+
json_obj = JSON.pretty_generate(objs.collect{|o| o.marshal_dump})
|
43
|
+
puts json_obj
|
44
|
+
|
45
|
+
# call pro with key (you'll need a real key)
|
46
|
+
embedly_pro = Embedly::API.new :key => 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
|
47
|
+
url = 'http://www.guardian.co.uk/media/2011/jan/21/andy-coulson-phone-hacking-statement'
|
48
|
+
obj = embedly_pro.preview :url => url
|
49
|
+
puts JSON.pretty_generate(obj.marshal_dump)
|
50
|
+
|
51
|
+
== Testing
|
52
|
+
|
53
|
+
gem install jeweler
|
54
|
+
rake rspec
|
55
|
+
rake features # if it complains of missing deps install them
|
56
|
+
|
57
|
+
Some tests will fail due to missing pro key. Set the EMBEDLY_KEY environmental
|
58
|
+
variable with your key to get them to pass.
|
59
|
+
|
60
|
+
EMBEDLY_KEY=xxxxxxxxxxxxx rake features
|
61
|
+
|
62
|
+
To turn on debugging, set the EMBEDLY_VERBOSE environmental variable.
|
63
|
+
|
64
|
+
EMBEDLY_VERBOSE=1 EMBEDLY_KEY=xxxxxxxxxxx rake features
|
65
|
+
|
66
|
+
We have provided some commandline tools to test the Embedly interface.
|
67
|
+
|
68
|
+
* embedly_oembed
|
69
|
+
* embedly_objectify
|
70
|
+
* embedly_preview
|
71
|
+
|
72
|
+
Using --help with the commands should give you a good idea of how to use them.
|
73
|
+
|
74
|
+
== Note on Patches/Pull Requests
|
75
|
+
|
76
|
+
* Fork the project.
|
77
|
+
* Make your feature addition or bug fix.
|
78
|
+
* Add tests for it. This is important so I don't break it in a
|
79
|
+
future version unintentionally.
|
80
|
+
* Commit, do not mess with rakefile, version, or history.
|
81
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
82
|
+
* Send me a pull request. Bonus points for topic branches.
|
83
|
+
|
84
|
+
== Copyright
|
85
|
+
|
86
|
+
Copyright (c) 2011 Embed.ly, Inc. See MIT-LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "embedly"
|
8
|
+
gem.summary = %Q{Ruby Embedly client library}
|
9
|
+
gem.description = %Q{Ruby Embedly client library}
|
10
|
+
gem.email = "bob@embed.ly"
|
11
|
+
gem.homepage = "http://github.com/embedly/embedly-ruby"
|
12
|
+
gem.authors = ["Bob Corsaro"]
|
13
|
+
gem.add_development_dependency "cucumber", ">= 0"
|
14
|
+
gem.add_development_dependency "jeweler", ">= 0"
|
15
|
+
gem.add_development_dependency "rspec", ">= 0"
|
16
|
+
gem.add_development_dependency "grancher", ">= 0"
|
17
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
22
|
+
end
|
23
|
+
|
24
|
+
begin
|
25
|
+
require 'cucumber/rake/task'
|
26
|
+
Cucumber::Rake::Task.new(:features)
|
27
|
+
rescue LoadError
|
28
|
+
task :features do
|
29
|
+
abort "Cucumber is not installed"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
require 'grancher/task'
|
35
|
+
Grancher::Task.new do |g|
|
36
|
+
g.branch = 'gh-pages'
|
37
|
+
g.push_to = 'origin'
|
38
|
+
g.message = 'Updated website'
|
39
|
+
g.directory 'rdoc'
|
40
|
+
end
|
41
|
+
rescue LoadError
|
42
|
+
task :publish do
|
43
|
+
abort "Grancher is not installed"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
task :features => :check_dependencies
|
48
|
+
|
49
|
+
task :default => :test
|
50
|
+
|
51
|
+
require 'rake/rdoctask'
|
52
|
+
Rake::RDocTask.new do |rdoc|
|
53
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
54
|
+
|
55
|
+
rdoc.rdoc_dir = 'rdoc'
|
56
|
+
rdoc.title = "embedly #{version}"
|
57
|
+
rdoc.rdoc_files.include('README*')
|
58
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
59
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
3
|
+
%w{embedly json optparse ostruct}.each {|l| require l}
|
4
|
+
|
5
|
+
options = OpenStruct.new({
|
6
|
+
:endpoint => nil,
|
7
|
+
:key => nil,
|
8
|
+
:verbose => false,
|
9
|
+
:args => {}
|
10
|
+
})
|
11
|
+
|
12
|
+
action = File.basename(__FILE__)[/embedly_(\w+)/, 1]
|
13
|
+
|
14
|
+
opts = OptionParser.new do |opts|
|
15
|
+
opts.banner = <<-DOC
|
16
|
+
Fetch JSON from the embedly #{action} service.
|
17
|
+
Usage #{action} [OPTIONS] <url> [url] ..
|
18
|
+
DOC
|
19
|
+
|
20
|
+
opts.separator ""
|
21
|
+
opts.separator "Options:"
|
22
|
+
|
23
|
+
opts.on("-e", "--endpoint ENDPOINT",
|
24
|
+
"Embedly host. If key is present, default is pro.embed.ly, else " +
|
25
|
+
"it is api.embed.ly.") do |e|
|
26
|
+
options.endpoint = e
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("-k", "--key KEY", "Embedly PRO key") do |k|
|
30
|
+
options.key = k
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-o", "--option NAME=VALUE", "Set option to be passed as query param.") do |o|
|
34
|
+
k,v = o.split('=')
|
35
|
+
options.args[k] = v
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.separator ""
|
39
|
+
opts.separator "Common Options:"
|
40
|
+
|
41
|
+
opts.on("-v", "--verbose", "Run verbosely") do
|
42
|
+
options.verbose = true
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on("-h", "--help", "Display this message") do
|
46
|
+
puts opts
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.separator ""
|
51
|
+
opts.separator "Bob Corsaro <bob@embed.ly>"
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.parse!
|
55
|
+
|
56
|
+
if ARGV.size < 1
|
57
|
+
$stderr.puts "ERROR: url required"
|
58
|
+
$stderr.puts opts
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
Embedly::Config.logging = true if options.verbose
|
63
|
+
|
64
|
+
options.args[:urls] = ARGV
|
65
|
+
api = Embedly::API.new options.marshal_dump
|
66
|
+
objs = [api.send(action, options.args)].flatten.collect{|o| o.marshal_dump}
|
67
|
+
puts JSON.pretty_generate(objs)
|
data/bin/embedly_oembed
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
3
|
+
%w{embedly json optparse ostruct}.each {|l| require l}
|
4
|
+
|
5
|
+
options = OpenStruct.new({
|
6
|
+
:endpoint => nil,
|
7
|
+
:key => nil,
|
8
|
+
:verbose => false,
|
9
|
+
:args => {}
|
10
|
+
})
|
11
|
+
|
12
|
+
action = File.basename(__FILE__)[/embedly_(\w+)/, 1]
|
13
|
+
|
14
|
+
opts = OptionParser.new do |opts|
|
15
|
+
opts.banner = <<-DOC
|
16
|
+
Fetch JSON from the embedly #{action} service.
|
17
|
+
Usage #{action} [OPTIONS] <url> [url] ..
|
18
|
+
DOC
|
19
|
+
|
20
|
+
opts.separator ""
|
21
|
+
opts.separator "Options:"
|
22
|
+
|
23
|
+
opts.on("-e", "--endpoint ENDPOINT",
|
24
|
+
"Embedly host. If key is present, default is pro.embed.ly, else " +
|
25
|
+
"it is api.embed.ly.") do |e|
|
26
|
+
options.endpoint = e
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("-k", "--key KEY", "Embedly PRO key") do |k|
|
30
|
+
options.key = k
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-o", "--option NAME=VALUE", "Set option to be passed as query param.") do |o|
|
34
|
+
k,v = o.split('=')
|
35
|
+
options.args[k] = v
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.separator ""
|
39
|
+
opts.separator "Common Options:"
|
40
|
+
|
41
|
+
opts.on("-v", "--verbose", "Run verbosely") do
|
42
|
+
options.verbose = true
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on("-h", "--help", "Display this message") do
|
46
|
+
puts opts
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.separator ""
|
51
|
+
opts.separator "Bob Corsaro <bob@embed.ly>"
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.parse!
|
55
|
+
|
56
|
+
if ARGV.size < 1
|
57
|
+
$stderr.puts "ERROR: url required"
|
58
|
+
$stderr.puts opts
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
Embedly::Config.logging = true if options.verbose
|
63
|
+
|
64
|
+
options.args[:urls] = ARGV
|
65
|
+
api = Embedly::API.new options.marshal_dump
|
66
|
+
objs = [api.send(action, options.args)].flatten.collect{|o| o.marshal_dump}
|
67
|
+
puts JSON.pretty_generate(objs)
|
data/bin/embedly_preview
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
3
|
+
%w{embedly json optparse ostruct}.each {|l| require l}
|
4
|
+
|
5
|
+
options = OpenStruct.new({
|
6
|
+
:endpoint => nil,
|
7
|
+
:key => nil,
|
8
|
+
:verbose => false,
|
9
|
+
:args => {}
|
10
|
+
})
|
11
|
+
|
12
|
+
action = File.basename(__FILE__)[/embedly_(\w+)/, 1]
|
13
|
+
|
14
|
+
opts = OptionParser.new do |opts|
|
15
|
+
opts.banner = <<-DOC
|
16
|
+
Fetch JSON from the embedly #{action} service.
|
17
|
+
Usage #{action} [OPTIONS] <url> [url] ..
|
18
|
+
DOC
|
19
|
+
|
20
|
+
opts.separator ""
|
21
|
+
opts.separator "Options:"
|
22
|
+
|
23
|
+
opts.on("-e", "--endpoint ENDPOINT",
|
24
|
+
"Embedly host. If key is present, default is pro.embed.ly, else " +
|
25
|
+
"it is api.embed.ly.") do |e|
|
26
|
+
options.endpoint = e
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("-k", "--key KEY", "Embedly PRO key") do |k|
|
30
|
+
options.key = k
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-o", "--option NAME=VALUE", "Set option to be passed as query param.") do |o|
|
34
|
+
k,v = o.split('=')
|
35
|
+
options.args[k] = v
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.separator ""
|
39
|
+
opts.separator "Common Options:"
|
40
|
+
|
41
|
+
opts.on("-v", "--verbose", "Run verbosely") do
|
42
|
+
options.verbose = true
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on("-h", "--help", "Display this message") do
|
46
|
+
puts opts
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.separator ""
|
51
|
+
opts.separator "Bob Corsaro <bob@embed.ly>"
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.parse!
|
55
|
+
|
56
|
+
if ARGV.size < 1
|
57
|
+
$stderr.puts "ERROR: url required"
|
58
|
+
$stderr.puts opts
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
Embedly::Config.logging = true if options.verbose
|
63
|
+
|
64
|
+
options.args[:urls] = ARGV
|
65
|
+
api = Embedly::API.new options.marshal_dump
|
66
|
+
objs = [api.send(action, options.args)].flatten.collect{|o| o.marshal_dump}
|
67
|
+
puts JSON.pretty_generate(objs)
|
data/cucumber.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
default: features
|
@@ -0,0 +1,79 @@
|
|
1
|
+
Feature: OEmbed
|
2
|
+
|
3
|
+
As an embedly user
|
4
|
+
I want to call the the embedly api
|
5
|
+
Because I want and oembed for a specific url
|
6
|
+
|
7
|
+
Scenario Outline: Get the provider_url
|
8
|
+
Given an embedly endpoint
|
9
|
+
When oembed is called with the <url> URL
|
10
|
+
Then the provider_url should be <provider_url>
|
11
|
+
|
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://tweetphoto.com/14784358 | http://plixi.com |
|
18
|
+
|
19
|
+
|
20
|
+
Scenario Outline: Get the provider_url with force flag
|
21
|
+
Given an embedly endpoint
|
22
|
+
When oembed is called with the <url> URL and force flag
|
23
|
+
Then the provider_url should be <provider_url>
|
24
|
+
|
25
|
+
Examples:
|
26
|
+
| url | provider_url |
|
27
|
+
| http://www.youtube.com/watch?v=Zk7dDekYej0 | http://www.youtube.com/ |
|
28
|
+
|
29
|
+
|
30
|
+
Scenario Outline: Get multiple provider_urls
|
31
|
+
Given an embedly endpoint
|
32
|
+
When oembed is called with the <urls> URLs
|
33
|
+
Then provider_url should be <provider_urls>
|
34
|
+
|
35
|
+
Examples:
|
36
|
+
| urls | provider_urls |
|
37
|
+
| http://www.scribd.com/doc/13994900/Easter,http://www.scribd.com/doc/28452730/Easter-Cards | http://www.scribd.com/,http://www.scribd.com/ |
|
38
|
+
| http://www.youtube.com/watch?v=Zk7dDekYej0,http://plixi.com/p/16044847 | http://www.youtube.com/,http://plixi.com |
|
39
|
+
|
40
|
+
|
41
|
+
Scenario Outline: Get the provider_url with pro
|
42
|
+
Given an embedly endpoint with key
|
43
|
+
When oembed is called with the <url> URL
|
44
|
+
Then the provider_url should be <provider_url>
|
45
|
+
|
46
|
+
Examples:
|
47
|
+
| url | provider_url |
|
48
|
+
| http://blog.embed.ly/bob | http://posterous.com |
|
49
|
+
| http://blog.doki-pen.org/cassandra-rules | http://posterous.com |
|
50
|
+
| http://www.guardian.co.uk/media/2011/jan/21/andy-coulson-phone-hacking-statement | http://www.guardian.co.uk/ |
|
51
|
+
|
52
|
+
|
53
|
+
Scenario Outline: Attempt to get 404 URL
|
54
|
+
Given an embedly endpoint
|
55
|
+
When oembed is called with the <url> URL
|
56
|
+
Then type should be error
|
57
|
+
And error_code should be 404
|
58
|
+
And type should be error
|
59
|
+
|
60
|
+
Examples:
|
61
|
+
| url |
|
62
|
+
| http://www.youtube.com/this/is/a/bad/url |
|
63
|
+
| http://blog.embed.ly/lsbsdlfldsf/asdfkljlas/klajsdlfkasdf |
|
64
|
+
| http://tweetphoto.com/alsdfldsf/asdfkljlas/klajsdlfkasdf |
|
65
|
+
|
66
|
+
|
67
|
+
Scenario Outline: Attempt multi get 404 URLs
|
68
|
+
Given an embedly endpoint
|
69
|
+
When oembed is called with the <urls> URLs
|
70
|
+
Then error_code should be <errcode>
|
71
|
+
And type should be <types>
|
72
|
+
|
73
|
+
Examples:
|
74
|
+
| urls | errcode | types |
|
75
|
+
| http://www.youtube.com/this/is/a/bad/url,http://blog.embed.ly/alsd/slsdlf/asdlfj | 404,404 | error,error |
|
76
|
+
| http://blog.embed.ly/lsbsdlfldsf/asdf/kl,http://tweetphoto.com/asdf/asdf/asdfl | 404,404 | error,error |
|
77
|
+
| http://blog.embed.ly/lsbsdlfldsf/asdf/kl,http://tweetphoto.com/14784358 | 404, | error,photo |
|
78
|
+
| http://tweetphoto.com/14784358,http://www.scribd.com/asdf/asdf/asdfasdf | ,404 | photo,error |
|
79
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
$:.unshift(File.expand_path('../../../lib',__FILE__))
|
2
|
+
require 'embedly'
|
3
|
+
|
4
|
+
Given /an embedly endpoint( [^\s]+)?( with key)?$/ do |endpoint, key_enabled|
|
5
|
+
opts = {}
|
6
|
+
opts[:endpoint] = endpoint
|
7
|
+
if key_enabled
|
8
|
+
raise 'Please set env variable $EMBEDLY_KEY' unless ENV['EMBEDLY_KEY']
|
9
|
+
opts[:key] = ENV["EMBEDLY_KEY"]
|
10
|
+
end
|
11
|
+
@api = Embedly::API.new opts
|
12
|
+
end
|
13
|
+
|
14
|
+
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
|
+
end
|
22
|
+
opts[flag.to_sym] = true if flag
|
23
|
+
@result = @api.send(method, opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
Then /([^\s]+) should be ([^\s]+)/ do |key, value|
|
27
|
+
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
|
37
|
+
end
|
38
|
+
|
data/lib/embedly.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module Embedly
|
5
|
+
VERSION = File.read(File.expand_path('../../VERSION', __FILE__)).strip
|
6
|
+
Config = OpenStruct.new
|
7
|
+
|
8
|
+
def self.logger(name)
|
9
|
+
@_loggers ||= {}
|
10
|
+
logging = Embedly::Config.logging
|
11
|
+
logger = @_loggers[name] ||= Logger.new(STDERR)
|
12
|
+
logger.level = logging ? Logger::DEBUG : Logger::ERROR
|
13
|
+
logger
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'embedly/api'
|
data/lib/embedly/api.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
# Performs api calls to embedly.
|
6
|
+
#
|
7
|
+
# You won't find methods. We are using method_missing and passing the method
|
8
|
+
# name to apicall.
|
9
|
+
#
|
10
|
+
# === Currently Supported Methods
|
11
|
+
#
|
12
|
+
# * +oembed+
|
13
|
+
# * +objectify+
|
14
|
+
# * +preview+ _pro-only_
|
15
|
+
#
|
16
|
+
# All methods return ostructs, so fields can be accessed with the dot operator. ex.
|
17
|
+
#
|
18
|
+
# api = Embedly::API.new
|
19
|
+
# obj = api.oembed :url => 'http://blog.doki-pen.org/'
|
20
|
+
# puts obj.title, obj.description, obj.thumbnail_url
|
21
|
+
#
|
22
|
+
# Call parameters should be passed as the opts parameter. If set, key will
|
23
|
+
# automatically be added to the query string of the call, so no need to set it.
|
24
|
+
#
|
25
|
+
# This API _would_ be future compatible, if not for the version. In order to
|
26
|
+
# add support for a new method, you will need to add a version to the
|
27
|
+
# api_version hash. Here is an example.
|
28
|
+
#
|
29
|
+
# api = Embedly::API.new
|
30
|
+
# api.api_version['new_method'] = 3
|
31
|
+
# api.new_method :arg1 => '1', :arg2 => '2'
|
32
|
+
#
|
33
|
+
class Embedly::API
|
34
|
+
attr_reader :key, :endpoint, :api_version, :user_agent
|
35
|
+
|
36
|
+
# === Options
|
37
|
+
#
|
38
|
+
# [:+endpoint+] Hostname of embedly server. Defaults to api.embed.ly if no key is provided, pro.embed.ly if key is provided.
|
39
|
+
# [:+key+] Your pro.embed.ly api key.
|
40
|
+
# [:+user_agent+] Your User-Agent header. Defaults to Mozilla/5.0 (compatible; embedly-ruby/VERSION;)
|
41
|
+
def initialize opts={}
|
42
|
+
@key = opts[:key]
|
43
|
+
if @key
|
44
|
+
logger.debug('using pro')
|
45
|
+
@endpoint = opts[:endpoint] || 'pro.embed.ly'
|
46
|
+
else
|
47
|
+
@endpoint = opts[:endpoint] || 'api.embed.ly'
|
48
|
+
end
|
49
|
+
@api_versions = Hash.new('1').merge!({'objectify' => '2'})
|
50
|
+
@user_agent = opts[:user_agent] || "Mozilla/5.0 (compatible; embedly-ruby/#{Embedly::VERSION};)"
|
51
|
+
end
|
52
|
+
|
53
|
+
# <b>Use methods oembed, objectify, preview in favor of this method.</b>
|
54
|
+
#
|
55
|
+
# Normalizes url and urls parameters and calls the endpoint. url OR urls
|
56
|
+
# must be present
|
57
|
+
#
|
58
|
+
# === Options
|
59
|
+
#
|
60
|
+
# [:+url+] _(optional)_ A single url
|
61
|
+
# [:+urls+] _(optional)_ An array of urls
|
62
|
+
# [:+action+] The method that should be called. ex. oembed, objectify, preview
|
63
|
+
# [:+version+] The api version number.
|
64
|
+
# [_others_] All other parameters are used as query strings.
|
65
|
+
def apicall opts
|
66
|
+
opts[:urls] ||= []
|
67
|
+
opts[:urls] << opts[:url] if opts[:url]
|
68
|
+
|
69
|
+
raise 'must pass urls' if opts[:urls].size == 0
|
70
|
+
|
71
|
+
if opts[:urls].size == 1
|
72
|
+
params = {:url => opts[:urls].first}
|
73
|
+
else
|
74
|
+
params = {:urls => opts[:urls]}
|
75
|
+
end
|
76
|
+
|
77
|
+
params[:key] = key if key
|
78
|
+
params.merge!Hash[
|
79
|
+
opts.select{|k,_| not [:url, :urls, :action, :version].index k}
|
80
|
+
]
|
81
|
+
|
82
|
+
path = "/#{opts[:version]}/#{opts[:action]}?#{q params}"
|
83
|
+
|
84
|
+
ep = endpoint
|
85
|
+
ep = "http://#{ep}" if endpoint !~ %r{^https?://.*}
|
86
|
+
logger.debug { "calling #{ep}#{path}" }
|
87
|
+
|
88
|
+
url = URI.parse(ep)
|
89
|
+
response = Net::HTTP.start(url.host, url.port) do |http|
|
90
|
+
http.get(path, {'User-Agent' => user_agent})
|
91
|
+
end
|
92
|
+
|
93
|
+
# passing url vs. urls causes different things to happen on errors (like a
|
94
|
+
# 404 for the URL). using the url parameter returns a non 200 error code
|
95
|
+
# in the response. Using urls causes an error json object to be returned,
|
96
|
+
# but the main call will still be status 200. Below, we try to canonize as
|
97
|
+
# best we can but it should really be changed server side.
|
98
|
+
if response.code.to_i == 200
|
99
|
+
logger.debug { response.body }
|
100
|
+
# [].flatten is to be sure we have an array
|
101
|
+
objs = [JSON.parse(response.body)].flatten.collect {|o| OpenStruct.new(o)}
|
102
|
+
else
|
103
|
+
objs = OpenStruct.new :type => 'error', :error_code => response.code.to_i
|
104
|
+
end
|
105
|
+
|
106
|
+
if objs.size == 1
|
107
|
+
objs.first
|
108
|
+
else
|
109
|
+
objs
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Performs api call based on method name
|
114
|
+
#
|
115
|
+
# === Currently supported
|
116
|
+
#
|
117
|
+
# - +oembed+
|
118
|
+
# - +objectify+
|
119
|
+
# - +preview+ _pro-only_
|
120
|
+
#
|
121
|
+
def method_missing(name, *args, &block)
|
122
|
+
opts = args[0]
|
123
|
+
opts[:action] = name
|
124
|
+
opts[:version] = @api_versions[name]
|
125
|
+
apicall opts
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
# Escapes url parameters
|
130
|
+
# TODO: move to utils
|
131
|
+
def escape s
|
132
|
+
s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/u) do
|
133
|
+
'%'+$1.unpack('H2'*$1.bytesize).join('%').upcase
|
134
|
+
end.tr(' ', '+')
|
135
|
+
end
|
136
|
+
|
137
|
+
# Creates query string
|
138
|
+
# TODO: move to utils
|
139
|
+
def q params
|
140
|
+
params.collect do |k,v|
|
141
|
+
if v.is_a?Array
|
142
|
+
"#{k.to_s}=#{v.collect{|i|escape(i)}.join(',')}"
|
143
|
+
else
|
144
|
+
"#{k.to_s}=#{escape(v)}"
|
145
|
+
end
|
146
|
+
end.join('&')
|
147
|
+
end
|
148
|
+
|
149
|
+
def logger
|
150
|
+
@logger ||= Embedly.logger('API')
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: embedly
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Bob Corsaro
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-21 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: cucumber
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :development
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: jeweler
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :development
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
prerelease: false
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id003
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: grancher
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
type: :development
|
71
|
+
version_requirements: *id004
|
72
|
+
description: Ruby Embedly client library
|
73
|
+
email: bob@embed.ly
|
74
|
+
executables:
|
75
|
+
- embedly_objectify
|
76
|
+
- embedly_oembed
|
77
|
+
- embedly_preview
|
78
|
+
extensions: []
|
79
|
+
|
80
|
+
extra_rdoc_files:
|
81
|
+
- README.rdoc
|
82
|
+
files:
|
83
|
+
- .rvmrc
|
84
|
+
- MIT-LICENSE
|
85
|
+
- README.rdoc
|
86
|
+
- Rakefile
|
87
|
+
- VERSION
|
88
|
+
- bin/embedly_objectify
|
89
|
+
- bin/embedly_oembed
|
90
|
+
- bin/embedly_preview
|
91
|
+
- cucumber.yml
|
92
|
+
- features/oembed.feature
|
93
|
+
- features/steps/api_steps.rb
|
94
|
+
- features/steps/env.rb
|
95
|
+
- lib/embedly.rb
|
96
|
+
- lib/embedly/api.rb
|
97
|
+
has_rdoc: true
|
98
|
+
homepage: http://github.com/embedly/embedly-ruby
|
99
|
+
licenses: []
|
100
|
+
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
version: "0"
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
segments:
|
120
|
+
- 0
|
121
|
+
version: "0"
|
122
|
+
requirements: []
|
123
|
+
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 1.3.7
|
126
|
+
signing_key:
|
127
|
+
specification_version: 3
|
128
|
+
summary: Ruby Embedly client library
|
129
|
+
test_files: []
|
130
|
+
|