lib/vishnu.rb in vishnu-1.2.2 vs lib/vishnu.rb in vishnu-2.0.0
- old
+ new
@@ -1,128 +1,148 @@
#
-# The Libravatar class generates the avatar URL provided by the libravatar
-# web service at http://www.libravatar.org
+# The Vishnu class generates the avatar URL provided by the libravatar
+# web service at https://www.libravatar.org
#
# Users may associate their avatar images with multiple OpenIDs and Emails.
#
-# Author:: Kang-min Liu (http://gugod.org)
+# Original Author:: Kang-min Liu (http://gugod.org/)
+# Fork Author:: Anton Smirnov (https://sandfox.me/)
# Copyright:: Copyright (c) 2011 Kang-min Liu
# License:: MIT
-# Contributors:: https://github.com/gugod/libravatar/contributors
+# Contributors:: https://github.com/sandfoxme/vishnu/graphs/contributors
#
+require_relative 'vishnu/version'
+
require 'digest/md5'
require 'digest/sha2'
require 'uri'
require 'resolv'
class Vishnu
attr_accessor :email, :openid, :size, :default, :https
# The options should contain :email or :openid values. If both are
# given, email will be used. The value of openid and email will be
- # normalized by the rule described in http://www.libravatar.org/api
+ # normalized by the rule described in https://wiki.libravatar.org/api/
#
# List of option keys:
#
# - :email
# - :openid
# - :size An integer ranged 1 - 512, default is 80.
# - :https Set to true to serve avatars over SSL
# - :default URL to redirect missing avatars to, or one of these specials: "404", "mm", "identicon", "monsterid", "wavatar", "retro"
#
- def initialize(options = {})
- @email = options[:email]
- @openid = options[:openid]
- @size = options[:size]
- @default = options[:default]
- @https = options[:https]
+ def initialize(email: nil, openid: nil, size: nil, default: nil, https: nil)
+ @email = email
+ @openid = openid
+ @size = size
+ @default = default
+ @https = https
end
- def get_target_domain
- return @email.split('@')[1] if @email
- return URI.parse(@openid).host
- end
-
# All the values which are different between HTTP and HTTPS methods.
- @@profiles = [
- { :scheme => 'http://',
- :host => 'cdn.libravatar.org',
- :srv => '_avatars._tcp.',
- :port => 80 },
- { :scheme => 'https://',
- :host => 'seccdn.libravatar.org',
- :srv => '_avatars-sec._tcp.',
- :port => 443 }
- ]
+ PROFILES = [
+ {
+ scheme: 'http://',
+ host: 'cdn.libravatar.org',
+ srv: '_avatars._tcp.',
+ port: 80,
+ },
+ {
+ scheme: 'https://',
+ host: 'seccdn.libravatar.org',
+ srv: '_avatars-sec._tcp.',
+ port: 443,
+ }
+ ]
- # Grab the DNS SRV records associated with the target domain,
- # and choose one according to RFC2782.
- def srv_lookup
- profile = @@profiles[ @https ? 1 : 0 ]
- Resolv::DNS::open do |dns|
- rrs = dns.getresources(profile[:srv] + get_target_domain(),
- Resolv::DNS::Resource::IN::SRV).to_a
- return [nil, nil] unless rrs.any?
+ # Generate the libravatar URL
+ def url
+ if @email
+ id = Digest::MD5.hexdigest(normalize_email(@email))
+ else
+ id = Digest::SHA2.hexdigest(normalize_openid(@openid))
+ end
+ size = @size ? "s=#{@size}" : nil
+ default = @default ? "d=#{@default}" : nil
- min_priority = rrs.map{ |r| r.priority }.min
- rrs.delete_if{ |r| r.priority != min_priority }
+ query = [ size, default ].reject{ |x| !x }.join('&')
+ query = "?#{query}" unless query == ''
- weight_sum = rrs.inject(0) { |a,r| a+r.weight }.to_f
+ baseurl = get_base_url + '/avatar/'
- r = rrs.max_by { |r| r.weight == 0 ? 0 : rand ** (weight_sum / r.weight) }
+ baseurl + id + query
+ end
- return [r.target, r.port]
+ alias_method :to_s, :url
+
+ private
+
+ def get_target_domain
+ if @email
+ @email.split('@')[1]
+ else
+ URI.parse(@openid).host
+ end
end
- end
- def get_base_url
- profile = @@profiles[ @https ? 1 : 0 ]
- target, port = srv_lookup
+ # Grab the DNS SRV records associated with the target domain,
+ # and choose one according to RFC2782.
+ def srv_lookup
+ profile = PROFILES[ @https ? 1 : 0 ]
+ Resolv::DNS::open do |dns|
+ resources = dns.getresources(profile[:srv] + get_target_domain,
+ Resolv::DNS::Resource::IN::SRV).to_a
+ return [nil, nil] unless resources.any?
- if (target && port)
- port_fragment = port != profile[:port] ? ':' + port.to_s : ''
- return profile[:scheme] + target.to_s + port_fragment
- else
- return profile[:scheme] + profile[:host]
+
+ min_priority = resources.map{ |r| r.priority }.min
+ resources.delete_if{ |r| r.priority != min_priority }
+
+ weight_sum = resources.inject(0) { |sum, r| sum + r.weight }.to_f
+
+ r = resources.max_by { |r| r.weight == 0 ? 0 : rand ** (weight_sum / r.weight) }
+
+ return sanitize_srv_lookup(r.target.to_s, r.port)
+ end
end
- end
- # Generate the libravatar URL
- def to_s
- if @email
- @email.downcase!
- id = Digest::MD5.hexdigest(@email)
- else
- id = Digest::SHA2.hexdigest(normalize_openid(@openid))
+ def get_base_url
+ profile = PROFILES[ @https ? 1 : 0 ]
+ target, port = srv_lookup
+
+ if target && port
+ port_fragment = port != profile[:port] ? ':' + port.to_s : ''
+ profile[:scheme] + target.to_s + port_fragment
+ else
+ profile[:scheme] + profile[:host]
+ end
end
- s = @size ? "s=#{@size}" : nil
- d = @default ? "d=#{@default}" : nil
- query = [s,d].reject{|x|!x}.join("&")
- query = "?#{query}" unless query == ""
- baseurl = get_base_url() + '/avatar/'
- return baseurl + id + query
- end
+ def sanitize_srv_lookup(hostname, port)
+ unless hostname.match(/^[0-9a-zA-Z\-.]+$/) && 1 <= port && port <= 65535
+ return [nil, nil]
+ end
- private
+ [hostname, port]
+ end
- def sanitize_srv_lookup(hostname, port)
- unless hostname.match(/^[0-9a-zA-Z\-.]+$/) && 1 <= port && port <= 65535
- return [nil, nil]
+ def normalize_email(email)
+ email.downcase
end
- return [hostname, port]
- end
+ # Normalize an openid URL following the description on libravatar.org
+ def normalize_openid(url)
+ parsed_url = URI.parse(url)
+ parsed_url.host = parsed_url.host.downcase
+ parsed_url.scheme = parsed_url.scheme.downcase
+ if parsed_url.path == '' && parsed_url.fragment == nil
+ parsed_url.path = '/'
+ end
- # Normalize an openid URL following the description on libravatar.org
- def normalize_openid(s)
- x = URI.parse(s)
- x.host.downcase!
- x.scheme = x.scheme.downcase
- if (x.path == "" && x.fragment == nil)
- x.path = "/"
+ parsed_url.to_s
end
- return x.to_s
- end
+
end