Class: Embedly::API

Inherits:
Object
  • Object
show all
Defined in:
lib/embedly/api.rb

Overview

Performs api calls to embedly.

You won't find methods. We are using method_missing and passing the method name to apicall.

Currently Supported Methods

  • oembed

  • objectify

  • preview

  • extract

All methods return ostructs, so fields can be accessed with the dot operator. ex.

api = Embedly::API.new
obj = api.oembed :url => 'http://blog.doki-pen.org/'
puts obj[0].title, obj[0].description, obj[0].thumbnail_url

Call parameters should be passed as the opts parameter. If set, key will automatically be added to the query string of the call, so no need to set it.

This API would be future compatible, if not for the version. In order to add support for a new method, you will need to add a version to the api_version hash. Here is an example.

api = Embedly::API.new
api.api_version[:new_method] = 3
api.new_method :arg1 => '1', :arg2 => '2'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ API

Options

:hostname

Hostname of embedly server. Defaults to api.embed.ly.

:key

Your api.embed.ly key.

:secret

Your api.embed.ly secret if you are using oauth.

:user_agent

Your User-Agent header. Defaults to Mozilla/5.0 (compatible; embedly-ruby/VERSION;)

:timeout

Request timeout (in seconds). Defaults to 180 seconds or 3 minutes

:headers

Additional headers to send with requests.

:proxy

Proxy settings in format => '', :port => '', :user => '', :password => ''


51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/embedly/api.rb', line 51

def initialize opts={}
  @endpoints = [:oembed, :objectify, :preview, :extract]
  @key = opts[:key] || configuration.key
  @secret = opts[:secret] == "" ? nil : opts[:secret]
  @api_version = Hash.new('1')
  @api_version.merge!({:objectify => '2'})
  @hostname = opts[:hostname] || 'http://api.embed.ly'
  @timeout = opts[:timeout] || 180
  @headers = {
    'User-Agent' => opts[:user_agent] || "Mozilla/5.0 (compatible; embedly-ruby/#{Embedly::VERSION};)"
  }.merge(opts[:headers]||{})
  @proxy = opts[:proxy]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object

Performs api call based on method name

Currently supported

  • oembed

  • objectify

  • preview

  • extract


197
198
199
200
201
202
203
204
205
206
# File 'lib/embedly/api.rb', line 197

def method_missing(name, *args, &block)
  if @endpoints.include?name
    opts = args[0]
    opts[:action] = name
    opts[:version] = @api_version[name]
    apicall opts
  else
    super
  end
end

Instance Attribute Details

#api_versionObject (readonly)

Returns the value of attribute api_version


40
41
42
# File 'lib/embedly/api.rb', line 40

def api_version
  @api_version
end

#headersObject (readonly)

Returns the value of attribute headers


40
41
42
# File 'lib/embedly/api.rb', line 40

def headers
  @headers
end

#hostnameObject (readonly)

Returns the value of attribute hostname


40
41
42
# File 'lib/embedly/api.rb', line 40

def hostname
  @hostname
end

#keyObject (readonly)

Returns the value of attribute key


40
41
42
# File 'lib/embedly/api.rb', line 40

def key
  @key
end

#proxyObject (readonly)

Returns the value of attribute proxy


40
41
42
# File 'lib/embedly/api.rb', line 40

def proxy
  @proxy
end

#secretObject (readonly)

Returns the value of attribute secret


40
41
42
# File 'lib/embedly/api.rb', line 40

def secret
  @secret
end

Instance Method Details

#_do_call(path) ⇒ Object


81
82
83
84
85
86
87
88
89
# File 'lib/embedly/api.rb', line 81

def _do_call path
  if key and secret
    _do_oauth_call path
  else
    uri = URI.join(hostname, path)
    logger.debug { "calling #{uri} with headers #{headers} using #{request}" }
    request.get(uri, :headers => headers, :timeout => @timeout, :proxy => @proxy)
  end
end

#_do_oauth_call(path) ⇒ Object


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/embedly/api.rb', line 65

def _do_oauth_call path
  consumer = OAuth::Consumer.new(key, secret,
    :site => site,
    :http_method => :get,
    :scheme => :query_string)
  # our implementation is broken for header authorization, thus the
  # query_string
  logger.debug "Calling with OAuth %s" % [path]
  req = consumer.create_signed_request(:get, path)
  signedpath = req.path

  logger.debug { "calling #{site}#{signedpath} with headers #{headers} using #{request}" }
  uri = URI.join(hostname, signedpath)
  request.get(uri, :headers => headers, :timeout => @timeout, :proxy => @proxy)
end

#apicall(opts) ⇒ Object

Use methods oembed, objectify, preview and extract in favor of this method.

Normalizes url and urls parameters and calls the endpoint. url OR urls must be present

Options

:url

_(optional)_ A single url

:urls

_(optional)_ An array of urls

:action

The method that should be called. ex. oembed, objectify,

preview, extract [:+version+] The api version number.
others

All other parameters are used as query strings.


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/embedly/api.rb', line 104

def apicall opts
  opts[:urls] ||= []
  opts[:urls] << opts[:url] if opts[:url]

  raise 'must pass urls' if opts[:urls].size == 0

  params = {:urls => opts[:urls]}

  # store unsupported services as errors and don't send them to embedly
  rejects = []

  params[:urls].reject!.with_index do |url, i|
    if !key && url !~ services_regex
      rejects << [i,
        Embedly::EmbedlyObject.new(
          :type => 'error',
          :error_code => 401,
          :error_message => 'Embedly api key is required.'
        )
      ]
    elsif url.length > 2048
      rejects << [i,
        Embedly::EmbedlyObject.new(
          :type => 'error',
          :error_code => 414,
          :error_message => 'URL too long.'
        )
      ]
    end
  end

  if params[:urls].size > 0
    params[:key] = key if key and not secret
    params.merge!Hash[
      opts.select{|k,_| not [:url, :urls, :action, :version].index k}
    ]

    path = "/#{opts[:version]}/#{opts[:action]}?#{QueryString.stringify(params)}"

    response = _do_call path

    if response.code.to_i == 200
      logger.debug { response.body }
      # [].flatten is to be sure we have an array
      objs = [JSON.parse(response.body)].flatten.collect do |o|
        Embedly::EmbedlyObject.new(o)
      end
    else
      logger.debug { response }
      raise Embedly::BadResponseException.new(response, path)
    end

    # re-insert rejects into response
    rejects.each do |i, obj|
      objs.insert i, obj
    end

    objs
  else
    # we only have rejects, return them without calling embedly
    rejects.collect{|i, obj| obj}
  end
end

#requestObject


208
209
210
# File 'lib/embedly/api.rb', line 208

def request
  configuration.current_requester.call(self)
end

#servicesObject

Returns structured data from the services API method.

Response is cached per API object.

see api.embed.ly/docs/service for a description of the response.


173
174
175
176
177
178
179
180
# File 'lib/embedly/api.rb', line 173

def services
  if not @services
    response = _do_call '/1/services/ruby'
    raise 'services call failed', response if response.code.to_i != 200
    @services = JSON.parse(response.body)
  end
  @services
end

#services_regexObject

Returns a regex suitable for checking urls against for non-key usage


183
184
185
186
# File 'lib/embedly/api.rb', line 183

def services_regex
  r = services.collect {|p| p["regex"].join("|")}.join("|")
  Regexp.new r
end