class Flickr

Constants

BASE58_ALPHABET
END_POINT
FLICKR_OAUTH_ACCESS_TOKEN
FLICKR_OAUTH_AUTHORIZE
FLICKR_OAUTH_REQUEST_TOKEN
PHOTO_SOURCE_URL
REPLACE_PATH
REST_PATH
UPLOAD_END_POINT
UPLOAD_PATH
URL_PHOTOSTREAM
URL_PROFILE
URL_SHORT
USER_AGENT
VERSION

Attributes

api_key[RW]

Your flickr API key, see www.flickr.com/services/api/keys for more information

ca_file[RW]

Set path of a CA certificate file in PEM format (ssl connection only)

ca_path[RW]

Set path to a directory of CA certificate files in PEM format (ssl connection only)

cache[RW]

Set path to a file that can be used to store endpoints

check_certificate[RW]

Check the server certificate (ssl connection only)

proxy[RW]

Use a proxy

secure[RW]

Use ssl connection

shared_secret[RW]

The shared secret of api_key, see www.flickr.com/services/api/keys for more information

access_secret[RW]

Authenticated access token secret

access_token[RW]

Authenticated access token

client[R]

Public Class Methods

new(api_key = ENV['FLICKR_API_KEY'], shared_secret = ENV['FLICKR_SHARED_SECRET']) click to toggle source
# File lib/flickr.rb, line 38
def initialize(api_key = ENV['FLICKR_API_KEY'], shared_secret = ENV['FLICKR_SHARED_SECRET'])

  raise FlickrAppNotConfigured.new("No API key defined!") if api_key.nil?
  raise FlickrAppNotConfigured.new("No shared secret defined!") if shared_secret.nil?

  @access_token = @access_secret = nil
  @oauth_consumer = oauth_consumer api_key, shared_secret

  @@mutex.synchronize do
    unless @@initialized
      build_classes retrieve_endpoints
      @@initialized = true
    end
  end
  @client = self # used for propagating the client to sub-classes
end

Private Class Methods

base58(id) click to toggle source
# File lib/flickr.rb, line 235
def base58(id)
  id = id.to_i
  alphabet = BASE58_ALPHABET.split(//)
  base = alphabet.length
  begin
    id, m = id.divmod(base)
    r = alphabet[m] + (r || '')
  end while id > 0
  r
end
gen_url(r, type) click to toggle source
# File lib/flickr.rb, line 246
def gen_url(r, type)
  PHOTO_SOURCE_URL % [r.farm, r.server, r.id, r.secret, type, 'jpg']
end
url(r) click to toggle source
# File lib/flickr.rb, line 250
def url(r); gen_url(r, '') end
url_o(r) click to toggle source
# File lib/flickr.rb, line 258
def url_o(r); PHOTO_SOURCE_URL % [r.farm, r.server, r.id, r.originalsecret, '_o', r.originalformat] end
url_photopage(r) click to toggle source
# File lib/flickr.rb, line 260
def url_photopage(r); url_photostream(r) + r.id end
url_photoset(r) click to toggle source
# File lib/flickr.rb, line 262
def url_photoset(r); url_photosets(r) + r.id end
url_photosets(r) click to toggle source
# File lib/flickr.rb, line 261
def url_photosets(r); url_photostream(r) + 'sets/' end
url_photostream(r) click to toggle source
# File lib/flickr.rb, line 269
def url_photostream(r)
  URL_PHOTOSTREAM +
    if r.respond_to?(:pathalias) && r.pathalias
      r.pathalias
    elsif r.owner.respond_to?(:nsid)
      r.owner.nsid
    else
      r.owner
    end + '/'
end
url_profile(r) click to toggle source
# File lib/flickr.rb, line 259
def url_profile(r); URL_PROFILE + (r.owner.respond_to?(:nsid) ? r.owner.nsid : r.owner) + '/' end
url_short(r) click to toggle source
# File lib/flickr.rb, line 263
def url_short(r); URL_SHORT + base58(r.id) end
url_short_m(r) click to toggle source
# File lib/flickr.rb, line 264
def url_short_m(r); URL_SHORT + 'img/' + base58(r.id) + '_m.jpg' end
url_short_n(r) click to toggle source
# File lib/flickr.rb, line 268
def url_short_n(r); URL_SHORT + 'img/' + base58(r.id) + '_n.jpg' end
url_short_q(r) click to toggle source
# File lib/flickr.rb, line 267
def url_short_q(r); URL_SHORT + 'img/' + base58(r.id) + '_q.jpg' end
url_short_s(r) click to toggle source
# File lib/flickr.rb, line 265
def url_short_s(r); URL_SHORT + 'img/' + base58(r.id) + '.jpg'   end
url_short_t(r) click to toggle source
# File lib/flickr.rb, line 266
def url_short_t(r); URL_SHORT + 'img/' + base58(r.id) + '_t.jpg' end

Public Instance Methods

call(req, args = {}, &block) click to toggle source

This is the central method. It does the actual request to the Flickr server.

Raises FailedResponse if the response status is failed.

# File lib/flickr.rb, line 58
def call(req, args = {}, &block)
  oauth_args = args.delete(:oauth) || {}
  http_response = @oauth_consumer.post_form(REST_PATH, @access_secret, {:oauth_token => @access_token}.merge(oauth_args), build_args(args, req))
  process_response(req, http_response.body)
end
get_access_token(token, secret, verify) click to toggle source

Get an oauth access token.

flickr.get_access_token(token['oauth_token'], token['oauth_token_secret'], oauth_verifier)
# File lib/flickr.rb, line 81
def get_access_token(token, secret, verify)
  access_token = @oauth_consumer.access_token(FLICKR_OAUTH_ACCESS_TOKEN, secret, :oauth_token => token, :oauth_verifier => verify)
  @access_token, @access_secret = access_token['oauth_token'], access_token['oauth_token_secret']
  access_token
end
get_authorize_url(token, args = {}) click to toggle source

Get the oauth authorize url.

auth_url = flickr.get_authorize_url(token['oauth_token'], :perms => 'delete')
# File lib/flickr.rb, line 74
def get_authorize_url(token, args = {})
  @oauth_consumer.authorize_url(FLICKR_OAUTH_AUTHORIZE, args.merge(:oauth_token => token))
end
get_request_token(args = {}) click to toggle source

Get an oauth request token.

token = flickr.get_request_token(:oauth_callback => "https://example.com")
# File lib/flickr.rb, line 67
def get_request_token(args = {})
  @oauth_consumer.request_token(FLICKR_OAUTH_REQUEST_TOKEN, args)
end
replace_photo(file, args = {}) click to toggle source

Use this to replace the photo with :photo_id with the photo in file.

flickr.replace_photo '/path/to/the/photo', :photo_id => id

See www.flickr.com/services/api/replace.api.html for more information on the arguments.

# File lib/flickr.rb, line 101
def replace_photo(file, args = {})
  upload_flickr(REPLACE_PATH, file, args)
end
upload_photo(file, args = {}) click to toggle source

Use this to upload the photo in file.

flickr.upload_photo '/path/to/the/photo', :title => 'Title', :description => 'This is the description'

See www.flickr.com/services/api/upload.api.html for more information on the arguments.

# File lib/flickr.rb, line 92
def upload_photo(file, args = {})
  upload_flickr(UPLOAD_PATH, file, args)
end

Private Instance Methods

build_args(args = {}, method_name = nil) click to toggle source
# File lib/flickr.rb, line 161
def build_args(args = {}, method_name = nil)
  args['method'] = method_name if method_name
  args.merge('format' => 'json', 'nojsoncallback' => '1')
end
build_classes(endpoints) click to toggle source
# File lib/flickr.rb, line 129
def build_classes(endpoints)

  endpoints.sort.each do |endpoint|

    *breadcrumbs, tail = endpoint.split '.'

    raise "Invalid namespace" unless 'flickr' == breadcrumbs.shift

    base_class = breadcrumbs.reduce(::Flickr) do |memo, klass|

      cklass = klass.capitalize

      if memo.const_defined? cklass, false
        memo.const_get cklass
      else
        new_class = Class.new { include ::Flickr::Request }
        memo.const_set cklass, new_class
        memo.send(:define_method, klass) do
          new_class.new @client
        end
        new_class
      end
    end

    base_class.send(:define_method, tail) do |*args, &block|
      @client.call(endpoint, *args, &block)
    end unless base_class.method_defined? tail

  end

end
oauth_consumer(api_key, shared_secret) click to toggle source
# File lib/flickr.rb, line 119
def oauth_consumer(api_key, shared_secret)
  client = OAuthClient.new api_key, shared_secret
  client.proxy = Flickr.proxy
  client.check_certificate = Flickr.check_certificate
  client.ca_file = Flickr.ca_file
  client.ca_path = Flickr.ca_path
  client.user_agent = USER_AGENT
  client
end
process_response(req, response) click to toggle source
# File lib/flickr.rb, line 166
def process_response(req, response)
  puts response.inspect if ENV['FLICKR_DEBUG']

  if /\A<\?xml / === response # upload_photo returns xml data whatever we ask
    if response[/stat="(\w+)"/, 1] == 'fail'
      msg = response[/msg="([^"]+)"/, 1]
      code = response[/code="([^"]+)"/, 1]
      raise FailedResponse.new(msg, code, req)
    end

    type = response[/<(\w+)/, 1]
    h = {
      'secret'         => response[/secret="([^"]+)"/, 1],
      'originalsecret' => response[/originalsecret="([^"]+)"/, 1],
      '_content'       => response[/>([^<]+)<\//, 1]
    }.delete_if { |_, v| v.nil? }

    Response.build h, type
  else
    json = JSON.load(response.empty? ? '{}' : response)
    raise FailedResponse.new(json['message'], json['code'], req) if json.delete('stat') == 'fail'
    type, json = json.to_a.first if json.size == 1 and json.values.all? { |x| Hash === x }

    Response.build json, type
  end
end
retrieve_endpoints() click to toggle source
# File lib/flickr.rb, line 107
def retrieve_endpoints
  if Flickr.cache and File.exist?(Flickr.cache)
    YAML.load_file Flickr.cache
  else
    endpoints = call('flickr.reflection.getMethods').to_a
    File.open(Flickr.cache, 'w') do |file|
      file.write(YAML.dump endpoints)
    end if Flickr.cache
    endpoints
  end
end
upload_flickr(method, file, args = {}) click to toggle source
# File lib/flickr.rb, line 193
def upload_flickr(method, file, args = {})
  oauth_args = args.delete(:oauth) || {}
  args = build_args(args)
  if file.respond_to? :read
    args['photo'] = file
  else
    args['photo'] = open(file, 'rb')
    close_after = true
  end

  http_response = @oauth_consumer.post_multipart(method, @access_secret, {:oauth_token => @access_token}.merge(oauth_args), args)
  args['photo'].close if close_after
  process_response(method, http_response.body)
end