Class: Flickr

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

Overview

Flickr client class. Requires an API key

Defined Under Namespace

Classes: Config, Group, Photo, PhotoCollection, Photoset, User

Constant Summary collapse

HOST_URL =
'https://api.flickr.com'
API_PATH =
'/services/rest'
VALID_SIZES =

Flickr, annoyingly, uses a number of representations to specify the size of a photo, depending on the context. It gives a label such a “Small” or “Medium” to a size of photo, when returning all possible sizes. However, when generating the uri for the page that features that size of photo, or the source url for the image itself it uses a single letter. Bizarrely, these letters are different depending on whether you want the Flickr page for the photo or the source uri – e.g. a “Small” photo (240 pixels on its longest side) may be viewed at “www.flickr.com/photos/sco/2397458775/sizes/s/” but its source is at “”. The VALID_SIZES hash associates the correct letter with a label

{ "Square" => ["s", "sq"],
  "Large Square" => ["q", "q"],
  "Thumbnail" => ["t", "t"],
  "Small" => ["m", "s"],
  "Small 320" => ["n", "n"],
  "Medium" => [nil, "m"],
  "Medium 640" => ["z", "z"],
  "Large" => ["b", "l"]
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_key_or_params = {}) ⇒ Flickr

To use the Flickr API you need an api key (see www.flickr.com/services/api/misc.api_keys.html), and the flickr client object shuld be initialized with this. You’ll also need a shared secret code if you want to use authentication (e.g. to get a user’s private photos) There are two ways to initialize the Flickr client. The preferred way is with a hash of params, e.g. ‘api_key’ => ‘your_api_key’, ‘shared_secret’ => ‘shared_secret_code’, ‘verify_ssl’ => true, ‘ca_file’ => ‘/path/to/cert.pem’. Other way is to use in Rails an config file RAILS_ROOT/config/flickr.api.yml and there use params as key/values even specified for every environment.



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

def initialize(api_key_or_params={})
  @host = HOST_URL
  @api = API_PATH
  @verify_ssl = true
  api_key_or_params={} if api_key_or_params.nil? # fix for nil value as argument
  api_key_or_params = {:api_key => api_key_or_params} if api_key_or_params.is_a?(String)
  api_key_or_params = Config.get if Config.parsed? and api_key_or_params.empty?
  set_up_configuration api_key_or_params if api_key_or_params.is_a? Hash
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_id, params = {}) ⇒ Object

Implements everything else. Any method not defined explicitly will be passed on to the Flickr API, and return an XmlSimple document. For example, Flickr#test_echo is not defined, so it will pass the call to the flickr.test.echo method.



179
180
181
# File 'lib/flickr.rb', line 179

def method_missing(method_id, params={})
  request(method_id.id2name.gsub(/_/, '.'), params)
end

Instance Attribute Details

#api_keyObject (readonly)

Returns the value of attribute api_key.



43
44
45
# File 'lib/flickr.rb', line 43

def api_key
  @api_key
end

#auth_tokenObject (readonly)

Returns the value of attribute auth_token.



43
44
45
# File 'lib/flickr.rb', line 43

def auth_token
  @auth_token
end

#userObject

Returns the value of attribute user.



44
45
46
# File 'lib/flickr.rb', line 44

def user
  @user
end

Instance Method Details

#find_by_url(url) ⇒ Object

Implements flickr.urls.lookupGroup and flickr.urls.lookupUser



113
114
115
116
# File 'lib/flickr.rb', line 113

def find_by_url(url)
  response = urls_lookupUser('url'=>url) rescue urls_lookupGroup('url'=>url) rescue nil
  (response['user']) ? User.new(response['user']['id'], nil, nil, nil, @api_key) : Group.new(response['group']['id'], @api_key) unless response.nil?
end

#get_token_from(frob) ⇒ Object

Gets authentication token given a Flickr frob, which is returned when user allows access to their account for the application with the api_key which made the request



102
103
104
105
106
107
108
109
110
# File 'lib/flickr.rb', line 102

def get_token_from(frob)
  auth_response = request("auth.getToken", :frob => frob)['auth']
  @auth_token = auth_response['token']
  @user = User.new( 'id' => auth_response['user']['nsid'],
                    'username' => auth_response['user']['username'],
                    'name' => auth_response['user']['fullname'],
                    'client' => self)
  @auth_token
end

#groups(group_name, options = {}) ⇒ Object

Implements flickr.groups.search



146
147
148
149
150
151
152
153
154
# File 'lib/flickr.rb', line 146

def groups(group_name, options={})
  collection = groups_search({"text" => group_name}.merge(options))['groups']['group']
  collection = [collection] if collection.is_a? Hash

  collection.collect { |group| Group.new( "id" => group['nsid'],
                                          "name" => group['name'],
                                          "eighteenplus" => group['eighteenplus'],
                                          "client" => self) }
end

#http_get(url) ⇒ Object

Does an HTTP GET on a given URL and returns the response body



184
185
186
187
188
189
190
191
192
193
# File 'lib/flickr.rb', line 184

def http_get(url)
  url = URI.parse(url)
  http = Net::HTTP.new url.host, url.port
  http.use_ssl = true
  http.verify_mode = (@verify_ssl ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE)
  http.ca_file = @ca_file if @ca_file
  http.start do |res|
    res.request_get(url.request_uri).body.to_s
  end
end

#licensesObject

Implements flickr.photos.licenses.getInfo



166
167
168
# File 'lib/flickr.rb', line 166

def licenses
  photos_licenses_getInfo['licenses']['license']
end

#login_url(perms) ⇒ Object

Returns url for user to login in to Flickr to authenticate app for a user



171
172
173
# File 'lib/flickr.rb', line 171

def (perms)
  "https://flickr.com/services/auth/?api_key=#{@api_key}&perms=#{perms}&api_sig=#{signature_from('api_key'=>@api_key, 'perms' => perms)}"
end

#photos(*criteria) ⇒ Object

Implements flickr.photos.getRecent and flickr.photos.search



119
120
121
# File 'lib/flickr.rb', line 119

def photos(*criteria)
  not criteria.empty? and photos_search(*criteria) or recent
end

#photos_request(method, params = {}, list_node = "photos") ⇒ Object

acts like request but returns a PhotoCollection (a list of Photo objects)



204
205
206
207
# File 'lib/flickr.rb', line 204

def photos_request(method, params={}, list_node="photos")
  photos = request(method, params)
  PhotoCollection.new(photos, @api_key, list_node)
end

#photos_search(params = {}) ⇒ Object Also known as: search



129
130
131
# File 'lib/flickr.rb', line 129

def photos_search(params={})
  photos_request('photos.search', params)
end

#photoset(photoset_id) ⇒ Object



156
157
158
# File 'lib/flickr.rb', line 156

def photoset(photoset_id)
  Photoset.new(photoset_id, @api_key)
end

#recentObject

flickr.photos.getRecent 100 newest photos from everyone



125
126
127
# File 'lib/flickr.rb', line 125

def recent
  photos_request('photos.getRecent')
end

Implements flickr.tags.getRelated



161
162
163
# File 'lib/flickr.rb', line 161

def related_tags(tag)
  tags_getRelated('tag'=>tag)['tags']['tag']
end

#request(method, params = {}) ⇒ Object

Takes a Flickr API method name and set of parameters; returns an XmlSimple object with the response



196
197
198
199
200
201
# File 'lib/flickr.rb', line 196

def request(method, params={})
  url = request_url(method, params)
  response = XmlSimple.xml_in(http_get(url), { 'ForceArray' => false })
  raise response['err']['msg'] if response['stat'] != 'ok'
  response
end

#request_url(method, params = {}) ⇒ Object

Builds url for Flickr API REST request from given the flickr method name (exclusing the ‘flickr.’ that begins each method call) and params (where applicable) which should be supplied as a Hash (e.g ‘user_id’ => “foo123”)



212
213
214
215
216
217
218
219
# File 'lib/flickr.rb', line 212

def request_url(method, params={})
  method = 'flickr.' + method
  url = "#{@host}#{@api}/?api_key=#{@api_key}&method=#{method}"
  params.merge!('api_key' => @api_key, 'method' => method, 'auth_token' => @auth_token)
  signature = signature_from(params)

  url = "#{@host}#{@api}/?" + params.merge('api_sig' => signature).collect { |k,v| "#{k}=" + CGI::escape(v.to_s) unless v.nil? }.compact.join("&")
end

#set_up_configuration(api_key_or_params = {}) ⇒ Object



91
92
93
94
95
96
97
# File 'lib/flickr.rb', line 91

def set_up_configuration api_key_or_params = {}
  @api_key = api_key_or_params[:api_key]
  @shared_secret = api_key_or_params[:shared_secret]
  @auth_token = api_key_or_params[:auth_token]
  @ca_file = api_key_or_params[:ca_file]
  @verify_ssl = !(api_key_or_params[:verify_ssl].to_s === 'false')
end

#signature_from(params = {}) ⇒ Object



221
222
223
224
225
# File 'lib/flickr.rb', line 221

def signature_from(params={})
  return unless @shared_secret # don't both getting signature if no shared_secret
  request_str = params.reject {|k,v| v.nil?}.collect {|p| "#{p[0].to_s}#{p[1]}"}.sort.join # build key value pairs, sort in alpha order then join them, ignoring those with nil value
  return Digest::MD5.hexdigest("#{@shared_secret}#{request_str}")
end

#tag(tag) ⇒ Object

Gets public photos with a given tag



135
136
137
# File 'lib/flickr.rb', line 135

def tag(tag)
  photos('tags'=>tag)
end

#users(lookup = nil) ⇒ Object

Implements flickr.people.findByEmail and flickr.people.findByUsername.



140
141
142
143
# File 'lib/flickr.rb', line 140

def users(lookup=nil)
  user = people_findByEmail('find_email'=>lookup)['user'] rescue people_findByUsername('username'=>lookup)['user']
  return User.new("id" => user["nsid"], "username" => user["username"], "client" => self)
end