Class: Gravatar

Inherits:
Object
  • Object
show all
Defined in:
lib/gravatar.rb,
lib/gravatar/cache.rb,
lib/gravatar/version.rb

Overview

Errors ====

Errors usually come with a number and human readable text. Generally the text should be followed whenever possible, but a brief description of the numeric error codes are as follows:

-7  Use secure.gravatar.com
-8  Internal error
-9  Authentication error
-10 Method parameter missing
-11 Method parameter incorrect
-100  Misc error (see text)

Defined Under Namespace

Modules: TestCase, Version Classes: Cache

Constant Summary collapse

API_METHODS =
[
  :exists?, :addresses, :user_images, :save_data!, :save_image!, :save_url!, :use_image!, :use_user_image!,
  :remove_image!, :delete_user_image!, :test, :image_url, :image_data, :signup_url
]
VERSION =
Version::STRING

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(email, options = {}) ⇒ Gravatar

Creates a new instance of Gravatar. Valid options include:

:password                   => the password for this account, to be used instead of :api_key (don't supply both)
:api_key or :apikey or :key => the API key for this account, to be used instead of :password (don't supply both)
:duration                   => the cache duration to use for this instance
:logger                     => the logger to use for this instance

Note that :password and :api_key are both optional. If omitted, no web services will be available but this user’s Gravatar image can still be constructed using #image_uri or #image_data.

Raises:

  • (ArgumentError)


38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/gravatar.rb', line 38

def initialize(email, options = {})
  raise ArgumentError, "Expected :email" unless email
  @options = options || {}
  @email = email
  
  pw_or_key = auth.keys.first || :none
  @cache = Gravatar::Cache.new(self.class.cache, options[:duration] || self.class.duration,
                               "gravatar-#{email_hash}-#{pw_or_key}", options[:logger] || self.class.logger)
  self.rescue_errors = options[:rescue_errors]

  self.auth_with auth unless auth.empty?
end

Instance Attribute Details

#apiObject (readonly)

Returns the value of attribute api.



25
26
27
# File 'lib/gravatar.rb', line 25

def api
  @api
end

#emailObject (readonly)

Returns the value of attribute email.



25
26
27
# File 'lib/gravatar.rb', line 25

def email
  @email
end

Class Method Details

.cacheObject



108
109
110
# File 'lib/gravatar/cache.rb', line 108

def cache
  @cache ||= default_cache_instance
end

.cache=(instance) ⇒ Object



112
113
114
# File 'lib/gravatar/cache.rb', line 112

def cache=(instance)
  @cache = instance
end

.default_cache_instanceObject



100
101
102
# File 'lib/gravatar/cache.rb', line 100

def default_cache_instance
  defined?(Rails) ? Rails.cache : ActiveSupport::Cache::FileStore.new("tmp/cache")
end

.default_logger_instanceObject



104
105
106
# File 'lib/gravatar/cache.rb', line 104

def default_logger_instance
  defined?(Rails) ? Rails.logger : $stderr
end

.durationObject

How long is a cached object good for? Default is 30 minutes.



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

def duration
  @duration ||= 24.hours
end

.duration=(duration) ⇒ Object



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

def duration=(duration)
  @duration = duration
end

.loggerObject



116
117
118
# File 'lib/gravatar/cache.rb', line 116

def logger
  @logger ||= default_logger_instance
end

.logger=(logger) ⇒ Object



120
121
122
# File 'lib/gravatar/cache.rb', line 120

def logger=(logger)
  @logger = logger
end

.reset_cache!Object

Resets any changes to the cache and initializes a new cache. If using Rails, the new cache will be the Rails cache.



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

def reset_cache!
  @cache = nil
end

Instance Method Details

#addressesObject

Gets a list of addresses for this account, returning a hash following this format:

{
  address => {
    :rating => rating,
    :userimage => userimage,
    :userimage_url => userimage_url
  }
}

This method is cached for up to the value of @duration or Gravatar.duration.



101
102
103
104
105
106
107
108
# File 'lib/gravatar.rb', line 101

def addresses
  cache('addresses') do
    call('grav.addresses').inject({}) do |hash, (address, info)|
      hash[address] = info.merge(:rating => rating(info[:rating]))
      hash
    end
  end
end

#api_keyObject



302
303
304
# File 'lib/gravatar.rb', line 302

def api_key
  options[:apikey] || options[:api_key] || options[:key]
end

#authObject



298
299
300
# File 'lib/gravatar.rb', line 298

def auth
  api_key ? {:apikey => api_key} : (password ? {:password => password} : {})
end

#auth_with(options) ⇒ Object

Authenticates with the given API key or password, returning self.



287
288
289
290
291
292
293
294
295
296
# File 'lib/gravatar.rb', line 287

def auth_with(options)
  @options.delete(:apikey)
  @options.delete(:api_key)
  @options.delete(:key)
  @options.merge! options
  if !auth.empty?
    @api = XMLRPC::Client.new(host, path, 443, nil, nil, nil, nil, true)
  end
  self
end

#boolean(i) ⇒ Object



275
276
277
# File 'lib/gravatar.rb', line 275

def boolean(i)
  i.kind_of?(Numeric) ? i != 0 : i
end

#cache(*key, &block) ⇒ Object

If no arguments are given, the cache object for this instance is returned. Otherwise, the arguments are passed into Gravatar::Cache#cache.



230
231
232
233
234
235
236
# File 'lib/gravatar.rb', line 230

def cache(*key, &block)
  if key.empty? and not block_given?
    @cache
  else
    @cache.call(*key, &block)
  end
end

#cache_durationObject

The duration of the cache for this instance of Gravatar, independent of any other instance



64
65
66
# File 'lib/gravatar.rb', line 64

def cache_duration
  cache.duration
end

#cache_duration=(time) ⇒ Object

Sets the duration of the cache for this instance of Gravatar, independent of any other instance



69
70
71
# File 'lib/gravatar.rb', line 69

def cache_duration=(time)
  cache.duration = time
end

#call(name, args_hash = {}) ⇒ Object



279
280
281
282
283
284
# File 'lib/gravatar.rb', line 279

def call(name, args_hash = {})
  raise "No authentication data given" unless @api
  r = @api.call(name, auth.merge(args_hash))
  r = r.with_indifferent_access if r.kind_of?(Hash)
  r
end

#dehashify_emails(response, emails) ⇒ Object



242
243
244
245
246
247
248
249
250
# File 'lib/gravatar.rb', line 242

def dehashify_emails(response, emails)
  hashed_emails = emails.collect { |email| email_hash(email) }
  response.inject({}) do |hash, (hashed_email, value)|
    value = yield(value) if value
    email = emails[hashed_emails.index(hashed_email)]
    hash[email] = value
    hash
  end
end

#delete_user_image!(userimage) ⇒ Object

Remove a userimage from the account and any email addresses with which it is associated. Returns true or false.

This method is not cached.

This method will clear out the cache, since it may have an effect on what the API methods respond with.



172
173
174
175
176
# File 'lib/gravatar.rb', line 172

def delete_user_image!(userimage)
  boolean(call('grav.deleteUserimage', :userimage => userimage)).tap do
    expire_cache!
  end
end

#email_hash(email = self.email) ⇒ Object

Returns the MD5 hash for the specified email address, or the one associated with this object.



185
186
187
# File 'lib/gravatar.rb', line 185

def email_hash(email = self.email)
  Digest::MD5.hexdigest(email.downcase.strip)
end

#exists?(*emails) ⇒ Boolean

Check whether one or more email addresses have corresponding avatars. If no email addresses are specified, the one associated with this object is used.

Returns: Boolean for a single email address; a hash of emails => booleans for multiple addresses.

This method is cached for up to the value of @duration or Gravatar.duration.

Returns:

  • (Boolean)


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

def exists?(*emails)
  hashed_emails = normalize_email_addresses(emails)
  cache('exists', hashed_emails) do
    hash = call('grav.exists', :hashes => hashed_emails)
    if hash.length == 1
      boolean(hash.values.first)
    else
      dehashify_emails(hash, emails) { |value| boolean(value) }
    end
  end
end

#expire_cache!Object



238
239
240
# File 'lib/gravatar.rb', line 238

def expire_cache!
  cache.clear!
end

#extension_for_image(options) ⇒ Object



325
326
327
# File 'lib/gravatar.rb', line 325

def extension_for_image(options)
  options.key?(:filetype) || options.key?(:ext) ? "." + (options[:filetype] || options[:ext] || "jpg").to_s : ""
end

#hostObject



51
52
53
# File 'lib/gravatar.rb', line 51

def host
  "secure.gravatar.com"
end

#image_data(options = {}) ⇒ Object

Returns the image data for this user’s gravatar image. This is the same as reading the data at #image_url. See that method for more information.

This method is cached for up to the value of @duration or Gravatar.duration.



223
224
225
226
# File 'lib/gravatar.rb', line 223

def image_data(options = {})
  url = image_url(options)
  cache(url) { OpenURI.open_uri(URI.parse(url)).read }
end

#image_url(options = {}) ⇒ Object

Returns the URL for this user’s gravatar image. Options include:

:ssl     or :secure    if true, HTTPS will be used instead of HTTP. Default is false.
:rating  or :r         a rating threshold for this image. Can be one of [ :g, :pg, :r, :x ]. Default is :g.
:size    or :s         a size for this image. Can be anywhere between 1 and 512. Default is 80.
:default or :d         a default URL for this image to display if the specified user has no image;
                       or this can be one of [ :identicon, :monsterid, :wavatar, 404 ]. By default a generic
                       Gravatar image URL will be returned.
:filetype or :ext      an extension such as :jpg or :png. Default is omitted.
:forcedefault or :f    force a default image and ignore the user's specified image. Can be one of
                       [ :identicon, :monsterid, :wavatar, 404 ].

See en.gravatar.com/site/implement/url for much more detailed information.



202
203
204
205
206
207
208
# File 'lib/gravatar.rb', line 202

def image_url(options = {})
  secure = options[:ssl] || options[:secure]
  proto = "http#{secure ? 's' : ''}"
  sub = secure ? "secure" : "www"

  "#{proto}://#{sub}.gravatar.com/avatar/#{email_hash}#{extension_for_image(options)}#{query_for_image(options)}"
end

#normalize_email_addresses(addresses) ⇒ Object



252
253
254
255
256
# File 'lib/gravatar.rb', line 252

def normalize_email_addresses(addresses)
  addresses.flatten!
  addresses << @email if addresses.empty?
  addresses.map { |email| email_hash(email) }
end

#optionsObject



310
311
312
# File 'lib/gravatar.rb', line 310

def options
  @options
end

#passwordObject



306
307
308
# File 'lib/gravatar.rb', line 306

def password
  options[:password]
end

#pathObject



59
60
61
# File 'lib/gravatar.rb', line 59

def path
  "/xmlrpc?user=#{email_hash}"
end

#query_for_image(options) ⇒ Object



314
315
316
317
318
319
320
321
322
323
# File 'lib/gravatar.rb', line 314

def query_for_image(options)
  query = ''
  [:rating, :size, :default, :forcedefault, :r, :s, :d, :f].each do |key|
    if options.key?(key)
      query.blank? ? query.concat("?") : query.concat("&")
      query.concat("#{key}=#{CGI::escape options[key].to_s}")
    end
  end
  query
end

#rating(i) ⇒ Object Also known as: _rating



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/gravatar.rb', line 258

def rating(i)
  case i
    when -1, '-1' then :unknown
    when 0, '0' then :g
    when 1, '1' then :pg
    when 2, '2' then :r
    when 3, '3' then :x
    when :unknown then -1
    when :g  then 0
    when :pg then 1
    when :r  then 2
    when :x  then 3
    else raise ArgumentError, "Unexpected rating index: #{i} (expected between 0..3)"
  end
end

#remove_image!(emails) ⇒ Object

Remove the userimage associated with one or more email addresses. Returns a hash of booleans.

NOTE: This appears to always return false, even when it is really removing an image. If you
know what the deal with that is, drop me a line so I can update this documentation!

This method is not cached.

This method will clear out the cache, since it may have an effect on what the API methods respond with.



159
160
161
162
163
164
# File 'lib/gravatar.rb', line 159

def remove_image!(emails)
  emails = [emails] unless emails.is_a?(Array)
  hash = call('grav.removeImage', :addresses => emails)
  expire_cache!
  return hash
end

#save_data!(rating, data) ⇒ Object Also known as: save_image!

Saves binary image data as a userimage for this account and returns the ID of the image.

This method is not cached.



126
127
128
# File 'lib/gravatar.rb', line 126

def save_data!(rating, data)
  call('grav.saveData', :data => Base64.encode64(data), :rating => _rating(rating))
end

#save_url!(rating, url) ⇒ Object

Read an image via its URL and save that as a userimage for this account, returning true or false

This method is not cached.



134
135
136
# File 'lib/gravatar.rb', line 134

def save_url!(rating, url)
  call('grav.saveUrl', :url => url, :rating => _rating(rating))
end

#signup_url(options = {}) ⇒ Object

Returns the URL for Gravatar’s signup form, with the user’s email pre-filled. Options include:

:locale                if non-nil, wil be used to prefix the URL. Example: :en


213
214
215
216
217
# File 'lib/gravatar.rb', line 213

def (options = {})
  locale_prefix = options[:locale] ? "#{options[:locale]}." : ''

  "https://#{locale_prefix}gravatar.com/site/signup/#{CGI.escape(email)}"
end

#test(hash) ⇒ Object

Runs a simple Gravatar test. Useful for debugging. Gravatar will echo back any arguments you pass. This method is not cached.



180
181
182
# File 'lib/gravatar.rb', line 180

def test(hash)
  call('grav.test', hash)
end

#urlObject



55
56
57
# File 'lib/gravatar.rb', line 55

def url
  File.join("https://#{host}", path)
end

#use_user_image!(image_hash, emails) ⇒ Object Also known as: use_image!

Use a userimage as a gravatar for one or more addresses on this account. Returns a hash:

{ email_address => true/false }

This method is not cached.

This method will clear out the cache, since it may have an effect on what the API methods respond with.



144
145
146
147
148
149
# File 'lib/gravatar.rb', line 144

def use_user_image!(image_hash, emails)
  emails = [emails] unless emails.is_a?(Array)
  hash = call('grav.useUserimage', :userimage => image_hash, :addresses => emails)
  expire_cache!
  return hash
end

#user_imagesObject

Returns a hash of user images for this account in the following format:

{ user_img_hash => [rating, url] }

This method is cached for up to the value of @duration or Gravatar.duration.



114
115
116
117
118
119
120
121
# File 'lib/gravatar.rb', line 114

def user_images
  cache('user_images') do
    call('grav.userimages').inject({}) do |hash, (key, array)|
      hash[key] = [rating(array.first), array.last]
      hash
    end
  end
end