2014-05-22 02:37:02 -05:00
|
|
|
require_dependency 'letter_avatar'
|
|
|
|
|
2014-05-26 04:46:43 -05:00
|
|
|
class UserAvatarsController < ApplicationController
|
2014-05-27 07:29:27 -05:00
|
|
|
DOT = Base64.decode64("R0lGODlhAQABALMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//wBiZCH5BAEAAA8ALAAAAAABAAEAAAQC8EUAOw==")
|
|
|
|
|
2015-09-10 17:11:48 -05:00
|
|
|
skip_before_filter :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show, :show_letter, :show_letter_svg]
|
2014-05-26 04:46:43 -05:00
|
|
|
|
|
|
|
def refresh_gravatar
|
|
|
|
user = User.find_by(username_lower: params[:username].downcase)
|
|
|
|
guardian.ensure_can_edit!(user)
|
|
|
|
|
|
|
|
if user
|
|
|
|
user.create_user_avatar(user_id: user.id) unless user.user_avatar
|
|
|
|
user.user_avatar.update_gravatar!
|
|
|
|
|
2015-02-03 11:44:18 -06:00
|
|
|
render json: { upload_id: user.user_avatar.gravatar_upload_id }
|
2014-05-26 04:46:43 -05:00
|
|
|
else
|
|
|
|
raise Discourse::NotFound
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-09-10 17:11:48 -05:00
|
|
|
def show_letter_svg
|
|
|
|
params.require(:username)
|
|
|
|
params.require(:version)
|
|
|
|
params.require(:size)
|
|
|
|
|
|
|
|
no_cookies
|
|
|
|
|
|
|
|
size = params[:size].to_i
|
|
|
|
username = params[:username]
|
|
|
|
|
|
|
|
identity = LetterAvatar::Identity.from_username(username)
|
|
|
|
color = identity.color
|
|
|
|
|
|
|
|
svg = <<-SVG
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="#{size}" height="#{size}">
|
|
|
|
<rect width="100%" height="100%" fill="rgb(#{color[0]},#{color[1]},#{color[2]})" />
|
|
|
|
<text font-size="#{size * 0.7}" font-weight="normal" font-family="Helvetica, sans-serif" fill="#FFF" fill-opacity=".8" text-anchor="middle" x="50%" y="75%">#{username[0].capitalize}</text>
|
|
|
|
</svg>
|
|
|
|
SVG
|
|
|
|
|
|
|
|
expires_in 1.year, public: true
|
|
|
|
render inline: svg, content_type: "image/svg+xml"
|
|
|
|
end
|
|
|
|
|
2014-05-29 23:17:35 -05:00
|
|
|
def show_letter
|
|
|
|
params.require(:username)
|
|
|
|
params.require(:version)
|
|
|
|
params.require(:size)
|
|
|
|
|
2015-05-22 01:15:46 -05:00
|
|
|
no_cookies
|
|
|
|
|
2015-04-19 15:41:08 -05:00
|
|
|
return render_dot if params[:version] != LetterAvatar.version
|
2014-05-29 23:17:35 -05:00
|
|
|
|
|
|
|
image = LetterAvatar.generate(params[:username].to_s, params[:size].to_i)
|
2014-10-22 08:39:51 -05:00
|
|
|
|
2014-07-08 02:20:27 -05:00
|
|
|
response.headers["Last-Modified"] = File.ctime(image).httpdate
|
2014-10-22 08:39:51 -05:00
|
|
|
response.headers["Content-Length"] = File.size(image).to_s
|
2014-05-29 23:17:35 -05:00
|
|
|
expires_in 1.year, public: true
|
|
|
|
send_file image, disposition: nil
|
|
|
|
end
|
|
|
|
|
2014-05-22 02:37:02 -05:00
|
|
|
def show
|
2015-05-22 01:15:46 -05:00
|
|
|
no_cookies
|
|
|
|
|
2014-05-27 08:13:42 -05:00
|
|
|
# we need multisite support to keep a single origin pull for CDNs
|
|
|
|
RailsMultisite::ConnectionManagement.with_hostname(params[:hostname]) do
|
2015-05-29 11:51:17 -05:00
|
|
|
show_in_site(params[:hostname])
|
2014-05-27 08:13:42 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
protected
|
|
|
|
|
2014-05-27 09:15:09 -05:00
|
|
|
def show_in_site(hostname)
|
2014-05-22 02:37:02 -05:00
|
|
|
username = params[:username].to_s
|
2014-05-27 07:29:27 -05:00
|
|
|
return render_dot unless user = User.find_by(username_lower: username.downcase)
|
2014-05-22 02:37:02 -05:00
|
|
|
|
2015-05-29 12:19:41 -05:00
|
|
|
upload_id, version = params[:version].split("_")
|
|
|
|
|
|
|
|
version = (version || OptimizedImage::VERSION).to_i
|
|
|
|
return render_dot if version != OptimizedImage::VERSION
|
|
|
|
|
|
|
|
upload_id = upload_id.to_i
|
|
|
|
return render_dot unless upload_id > 0 && user_avatar = user.user_avatar
|
2014-05-22 02:37:02 -05:00
|
|
|
|
2015-05-26 08:54:25 -05:00
|
|
|
size = params[:size].to_i
|
|
|
|
return render_dot if size < 8 || size > 500
|
2015-05-26 00:41:50 -05:00
|
|
|
|
|
|
|
if !Discourse.avatar_sizes.include?(size) && Discourse.store.external?
|
2015-05-29 02:57:54 -05:00
|
|
|
closest = Discourse.avatar_sizes.to_a.min { |a,b| (size-a).abs <=> (size-b).abs }
|
2015-05-29 12:19:41 -05:00
|
|
|
avatar_url = UserAvatar.local_avatar_url(hostname, user.username_lower, upload_id, closest)
|
2015-05-29 11:51:17 -05:00
|
|
|
return redirect_to cdn_path(avatar_url)
|
2015-05-26 00:41:50 -05:00
|
|
|
end
|
|
|
|
|
2015-05-29 12:19:41 -05:00
|
|
|
upload = Upload.find_by(id: upload_id) if user_avatar.contains_upload?(upload_id)
|
|
|
|
upload ||= user.uploaded_avatar if user.uploaded_avatar_id == upload_id
|
2014-05-22 02:37:02 -05:00
|
|
|
|
|
|
|
if user.uploaded_avatar && !upload
|
2015-05-29 11:51:17 -05:00
|
|
|
avatar_url = UserAvatar.local_avatar_url(hostname, user.username_lower, user.uploaded_avatar_id, size)
|
|
|
|
return redirect_to cdn_path(avatar_url)
|
2015-06-01 10:49:58 -05:00
|
|
|
elsif upload && optimized = get_optimized_image(upload, size)
|
|
|
|
if optimized.local?
|
|
|
|
optimized_path = Discourse.store.path_for(optimized)
|
|
|
|
image = optimized_path if File.exists?(optimized_path)
|
|
|
|
else
|
|
|
|
expires_in 1.day, public: true
|
|
|
|
return redirect_to Discourse.store.cdn_url(optimized.url)
|
2014-05-22 02:37:02 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if image
|
2014-07-08 02:16:07 -05:00
|
|
|
response.headers["Last-Modified"] = File.ctime(image).httpdate
|
2014-10-22 08:39:51 -05:00
|
|
|
response.headers["Content-Length"] = File.size(image).to_s
|
2014-05-22 02:37:02 -05:00
|
|
|
expires_in 1.year, public: true
|
|
|
|
send_file image, disposition: nil
|
|
|
|
else
|
2014-05-27 07:29:27 -05:00
|
|
|
render_dot
|
2014-05-22 02:37:02 -05:00
|
|
|
end
|
|
|
|
end
|
2014-05-26 23:40:46 -05:00
|
|
|
|
2014-05-27 07:29:27 -05:00
|
|
|
# this protects us from a DoS
|
|
|
|
def render_dot
|
|
|
|
expires_in 10.minutes, public: true
|
|
|
|
render text: DOT, content_type: "image/png"
|
|
|
|
end
|
|
|
|
|
2014-05-26 23:40:46 -05:00
|
|
|
def get_optimized_image(upload, size)
|
|
|
|
OptimizedImage.create_for(
|
|
|
|
upload,
|
|
|
|
size,
|
|
|
|
size,
|
|
|
|
allow_animation: SiteSetting.allow_animated_avatars
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2014-05-22 02:37:02 -05:00
|
|
|
end
|