2014-05-22 03:37:02 -04:00
|
|
|
require_dependency 'letter_avatar'
|
2017-05-10 18:16:57 -04:00
|
|
|
require_dependency 'upload_creator'
|
2014-05-22 03:37:02 -04:00
|
|
|
|
|
|
|
class UserAvatar < ActiveRecord::Base
|
|
|
|
belongs_to :user
|
|
|
|
belongs_to :gravatar_upload, class_name: 'Upload', dependent: :destroy
|
|
|
|
belongs_to :custom_upload, class_name: 'Upload', dependent: :destroy
|
|
|
|
|
|
|
|
def contains_upload?(id)
|
2014-05-30 00:17:35 -04:00
|
|
|
gravatar_upload_id == id || custom_upload_id == id
|
2014-05-22 03:37:02 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def update_gravatar!
|
2015-09-17 13:42:44 -04:00
|
|
|
DistributedMutex.synchronize("update_gravatar_#{user_id}") do
|
2015-05-06 19:00:13 -04:00
|
|
|
begin
|
|
|
|
# special logic for our system user
|
2015-09-17 13:42:44 -04:00
|
|
|
email_hash = user_id == Discourse::SYSTEM_USER_ID ? User.email_hash("info@discourse.org") : user.email_hash
|
2015-05-06 19:00:13 -04:00
|
|
|
|
|
|
|
self.last_gravatar_download_attempt = Time.new
|
|
|
|
|
2015-05-29 12:09:47 -04:00
|
|
|
max = Discourse.avatar_sizes.max
|
2017-09-28 02:35:27 -04:00
|
|
|
gravatar_url = "https://www.gravatar.com/avatar/#{email_hash}.png?s=#{max}&d=404"
|
|
|
|
|
|
|
|
# follow redirects in case gravatar change rules on us
|
2017-05-24 13:42:52 -04:00
|
|
|
tempfile = FileHelper.download(
|
|
|
|
gravatar_url,
|
|
|
|
max_file_size: SiteSetting.max_image_size_kb.kilobytes,
|
2017-05-24 13:46:57 -04:00
|
|
|
tmp_file_name: "gravatar",
|
2017-09-27 21:32:26 -04:00
|
|
|
skip_rate_limit: true,
|
2017-09-28 02:35:27 -04:00
|
|
|
verbose: false,
|
|
|
|
follow_redirect: true
|
2017-05-24 13:42:52 -04:00
|
|
|
)
|
2017-09-28 02:35:27 -04:00
|
|
|
|
2017-05-24 13:29:50 -04:00
|
|
|
if tempfile
|
|
|
|
upload = UploadCreator.new(tempfile, 'gravatar.png', origin: gravatar_url, type: "avatar").create_for(user_id)
|
|
|
|
|
|
|
|
if gravatar_upload_id != upload.id
|
|
|
|
gravatar_upload.try(:destroy!) rescue nil
|
|
|
|
self.gravatar_upload = upload
|
|
|
|
save!
|
|
|
|
end
|
2015-05-06 19:00:13 -04:00
|
|
|
end
|
|
|
|
rescue OpenURI::HTTPError
|
|
|
|
save!
|
|
|
|
rescue SocketError
|
|
|
|
# skip saving, we are not connected to the net
|
|
|
|
ensure
|
|
|
|
tempfile.try(:close!)
|
|
|
|
end
|
2014-05-26 05:46:43 -04:00
|
|
|
end
|
2014-05-22 03:37:02 -04:00
|
|
|
end
|
|
|
|
|
2015-05-29 12:51:17 -04:00
|
|
|
def self.local_avatar_url(hostname, username, upload_id, size)
|
2015-09-11 09:18:17 -04:00
|
|
|
self.local_avatar_template(hostname, username, upload_id).gsub("{size}", size.to_s)
|
2015-05-29 12:51:17 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.local_avatar_template(hostname, username, upload_id)
|
|
|
|
version = self.version(upload_id)
|
|
|
|
"#{Discourse.base_uri}/user_avatar/#{hostname}/#{username}/{size}/#{version}.png"
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.external_avatar_url(user_id, upload_id, size)
|
2015-09-11 09:18:17 -04:00
|
|
|
self.external_avatar_template(user_id, upload_id).gsub("{size}", size.to_s)
|
2015-05-29 12:51:17 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.external_avatar_template(user_id, upload_id)
|
|
|
|
version = self.version(upload_id)
|
|
|
|
"#{Discourse.store.absolute_base_url}/avatars/#{user_id}/{size}/#{version}.png"
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.version(upload_id)
|
|
|
|
"#{upload_id}_#{OptimizedImage::VERSION}"
|
|
|
|
end
|
|
|
|
|
2017-07-27 21:20:09 -04:00
|
|
|
def self.import_url_for_user(avatar_url, user, options = nil)
|
2017-05-24 13:42:52 -04:00
|
|
|
tempfile = FileHelper.download(
|
|
|
|
avatar_url,
|
|
|
|
max_file_size: SiteSetting.max_image_size_kb.kilobytes,
|
|
|
|
tmp_file_name: "sso-avatar",
|
|
|
|
follow_redirect: true
|
|
|
|
)
|
2015-06-23 15:59:50 -04:00
|
|
|
|
2017-05-25 23:33:12 -04:00
|
|
|
return unless tempfile
|
|
|
|
|
2015-06-23 15:59:50 -04:00
|
|
|
ext = FastImage.type(tempfile).to_s
|
|
|
|
tempfile.rewind
|
|
|
|
|
2017-05-10 18:16:57 -04:00
|
|
|
upload = UploadCreator.new(tempfile, "external-avatar." + ext, origin: avatar_url, type: "avatar").create_for(user.id)
|
2015-06-23 15:59:50 -04:00
|
|
|
|
2016-10-17 09:43:40 -04:00
|
|
|
user.create_user_avatar unless user.user_avatar
|
2015-06-23 15:59:50 -04:00
|
|
|
|
|
|
|
if !user.user_avatar.contains_upload?(upload.id)
|
2016-09-19 01:10:02 -04:00
|
|
|
user.user_avatar.update_columns(custom_upload_id: upload.id)
|
|
|
|
|
|
|
|
override_gravatar = !options || options[:override_gravatar]
|
|
|
|
|
|
|
|
if user.uploaded_avatar_id.nil? ||
|
|
|
|
!user.user_avatar.contains_upload?(user.uploaded_avatar_id) ||
|
|
|
|
override_gravatar
|
|
|
|
user.update_columns(uploaded_avatar_id: upload.id)
|
|
|
|
end
|
2015-06-23 15:59:50 -04:00
|
|
|
end
|
2016-09-19 01:10:02 -04:00
|
|
|
|
2017-05-17 12:38:18 -04:00
|
|
|
rescue Net::ReadTimeout, OpenURI::HTTPError
|
2015-06-23 15:59:50 -04:00
|
|
|
# skip saving, we are not connected to the net
|
|
|
|
ensure
|
|
|
|
tempfile.close! if tempfile && tempfile.respond_to?(:close!)
|
|
|
|
end
|
|
|
|
|
2014-05-22 03:37:02 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: user_avatars
|
|
|
|
#
|
|
|
|
# id :integer not null, primary key
|
|
|
|
# user_id :integer not null
|
|
|
|
# custom_upload_id :integer
|
|
|
|
# gravatar_upload_id :integer
|
|
|
|
# last_gravatar_download_attempt :datetime
|
2014-08-27 01:19:25 -04:00
|
|
|
# created_at :datetime not null
|
|
|
|
# updated_at :datetime not null
|
2014-05-27 21:50:49 -04:00
|
|
|
#
|
|
|
|
# Indexes
|
|
|
|
#
|
2016-11-23 21:13:03 -05:00
|
|
|
# index_user_avatars_on_custom_upload_id (custom_upload_id)
|
|
|
|
# index_user_avatars_on_gravatar_upload_id (gravatar_upload_id)
|
|
|
|
# index_user_avatars_on_user_id (user_id)
|
2014-05-22 03:37:02 -04:00
|
|
|
#
|