2013-08-14 04:08:43 +08:00
|
|
|
require "image_sorcery"
|
|
|
|
|
|
|
|
module Jobs
|
|
|
|
|
|
|
|
class GenerateAvatars < Jobs::Base
|
|
|
|
|
|
|
|
def execute(args)
|
2013-11-06 02:04:47 +08:00
|
|
|
raise Discourse::ImageMagickMissing.new unless system("command -v convert >/dev/null;")
|
2013-10-12 16:55:41 +08:00
|
|
|
|
2013-11-06 02:04:47 +08:00
|
|
|
upload_id, user_id = args[:upload_id], args[:user_id]
|
|
|
|
raise Discourse::InvalidParameters.new(:upload_id) if upload_id.blank?
|
|
|
|
raise Discourse::InvalidParameters.new(:user_id) if user_id.blank?
|
2013-10-12 16:55:41 +08:00
|
|
|
|
|
|
|
upload = Upload.where(id: upload_id).first
|
|
|
|
user = User.where(id: user_id).first
|
2013-11-06 02:04:47 +08:00
|
|
|
return if upload.nil? || user.nil?
|
2013-08-14 04:08:43 +08:00
|
|
|
|
|
|
|
external_copy = Discourse.store.download(upload) if Discourse.store.external?
|
|
|
|
original_path = if Discourse.store.external?
|
|
|
|
external_copy.path
|
|
|
|
else
|
|
|
|
Discourse.store.path_for(upload)
|
|
|
|
end
|
|
|
|
|
2013-08-24 00:48:29 +08:00
|
|
|
source = original_path
|
2013-11-06 02:04:47 +08:00
|
|
|
# extract the first frame when it's a gif
|
2013-08-24 00:48:29 +08:00
|
|
|
source << "[0]" unless SiteSetting.allow_animated_avatars
|
2013-11-06 02:04:47 +08:00
|
|
|
image = ImageSorcery.new(source)
|
|
|
|
extension = File.extname(original_path)
|
2013-08-24 00:48:29 +08:00
|
|
|
|
2013-08-14 04:08:43 +08:00
|
|
|
[120, 45, 32, 25, 20].each do |s|
|
|
|
|
# handle retina too
|
|
|
|
[s, s * 2].each do |size|
|
2013-11-06 02:04:47 +08:00
|
|
|
begin
|
|
|
|
# create a temp file with the same extension as the original
|
|
|
|
temp_file = Tempfile.new(["discourse-avatar", extension])
|
|
|
|
# create a transparent centered square thumbnail
|
|
|
|
if image.convert(temp_file.path,
|
|
|
|
gravity: "center",
|
|
|
|
thumbnail: "#{size}x#{size}^",
|
|
|
|
extent: "#{size}x#{size}",
|
|
|
|
background: "transparent")
|
|
|
|
if Discourse.store.store_avatar(temp_file, upload, size).blank?
|
|
|
|
Rails.logger.error("Failed to store avatar #{size} for #{upload.url} from #{source}")
|
|
|
|
end
|
|
|
|
else
|
|
|
|
Rails.logger.error("Failed to create avatar #{size} for #{upload.url} from #{source}")
|
|
|
|
end
|
|
|
|
ensure
|
|
|
|
# close && remove temp file
|
|
|
|
temp_file && temp_file.close!
|
2013-08-16 15:58:20 +08:00
|
|
|
end
|
2013-08-14 04:08:43 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# make sure we remove the cached copy from external stores
|
|
|
|
external_copy.close! if Discourse.store.external?
|
|
|
|
|
2013-10-12 16:55:41 +08:00
|
|
|
# attach the avatar to the user
|
2014-01-08 00:45:06 +08:00
|
|
|
user.uploaded_avatar_template = Discourse.store.avatar_template(upload)
|
2013-08-14 04:08:43 +08:00
|
|
|
user.save!
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|