Move user images to Active Storage with paperclip as a fallback

This commit is contained in:
Tom Hughes 2019-07-02 22:31:31 +01:00
parent ba627420a3
commit 6c202448ad
14 changed files with 78 additions and 41 deletions

View file

@ -126,6 +126,9 @@ gem "mimemagic"
# Used for browser detection
gem "browser"
# Used to resize user images
gem "mini_magick"
# Gems useful for development
group :development do
gem "annotate"

View file

@ -241,6 +241,7 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0331)
mimemagic (0.3.3)
mini_magick (4.9.3)
mini_mime (1.0.1)
mini_portile2 (2.4.0)
minitest (5.11.3)
@ -482,6 +483,7 @@ DEPENDENCIES
listen
logstasher
mimemagic
mini_magick
minitest (~> 5.1)
oauth-plugin (>= 0.5.1)
omniauth

View file

Before

Width:  |  Height:  |  Size: 489 B

After

Width:  |  Height:  |  Size: 489 B

View file

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 311 B

View file

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View file

@ -85,8 +85,8 @@ $(document).ready(function () {
$("select#user_auth_provider").on("change", updateAuthUID);
$("input#user_image").on("change", function () {
$("#image_action_new").prop("checked", true);
$("input#user_avatar").on("change", function () {
$("#avatar_action_new").prop("checked", true);
});
function enableAuth() {

View file

@ -660,15 +660,15 @@ class UsersController < ApplicationController
user.languages = params[:user][:languages].split(",")
case params[:image_action]
case params[:avatar_action]
when "new" then
user.image = params[:user][:image]
user.avatar.attach(params[:user][:avatar])
user.image_use_gravatar = false
when "delete" then
user.image = nil
user.avatar.purge
user.image_use_gravatar = false
when "gravatar" then
user.image = nil
user.avatar.purge
user.image_use_gravatar = true
end

View file

@ -7,8 +7,12 @@ module UserHelper
if user.image_use_gravatar
user_gravatar_tag(user, options)
else
elsif user.avatar.attached?
image_tag user.avatar.variant(:resize => "100x100>"), options
elsif user.image.file?
image_tag user.image.url(:large), options
else
image_tag "avatar_large.png", options
end
end
@ -18,8 +22,12 @@ module UserHelper
if user.image_use_gravatar
user_gravatar_tag(user, options)
else
elsif user.avatar.attached?
image_tag user.avatar.variant(:resize => "50x50>"), options
elsif user.image.file?
image_tag user.image.url(:small), options
else
image_tag "avatar_small.png", options
end
end
@ -29,16 +37,24 @@ module UserHelper
if user.image_use_gravatar
user_gravatar_tag(user, options)
else
elsif user.avatar.attached?
image_tag user.avatar.variant(:resize => "50x50>"), options
elsif user.image.file?
image_tag user.image.url(:small), options
else
image_tag "avatar_small.png", options
end
end
def user_image_url(user, options = {})
if user.image_use_gravatar
user_gravatar_url(user, options)
else
elsif user.avatar.attached?
url_for(user.avatar.variant(:resize => "100x100>"))
elsif user.image.file?
image_url(user.image.url(:large))
else
image_url("avatar_large.png")
end
end
@ -65,7 +81,7 @@ module UserHelper
def user_gravatar_url(user, options = {})
size = options[:size] || 100
hash = Digest::MD5.hexdigest(user.email.downcase)
default_image_url = image_url("users/images/large.png")
default_image_url = image_url("avatar_large.png")
"#{request.protocol}www.gravatar.com/avatar/#{hash}.jpg?s=#{size}&d=#{u(default_image_url)}"
end

View file

@ -1,4 +1,6 @@
class Notifier < ActionMailer::Base
include ActionView::Helpers::AssetUrlHelper
default :from => Settings.email_from,
:return_path => Settings.email_return_path,
:auto_submitted => "auto-generated"
@ -177,7 +179,16 @@ class Notifier < ActionMailer::Base
end
def attach_user_avatar(user)
attachments.inline["avatar.png"] = File.read(user_avatar_file_path(user))
attachments.inline["avatar.png"] = user_avatar_file(user)
end
def user_avatar_file(user)
avatar = user&.avatar
if avatar&.attached?
return avatar.variant(:resize => "50x50>").blob.download
else
return File.read(user_avatar_file_path(user))
end
end
def user_avatar_file_path(user)
@ -185,7 +196,7 @@ class Notifier < ActionMailer::Base
if image&.file?
return image.path(:small)
else
return Rails.root.join("app", "assets", "images", "users", "images", "small.png")
return Rails.root.join("app", "assets", "images", "avatar_small.png")
end
end

View file

@ -85,6 +85,8 @@ class User < ActiveRecord::Base
scope :active, -> { where(:status => %w[active confirmed]) }
scope :identifiable, -> { where(:data_public => true) }
has_one_attached :avatar
has_attached_file :image,
:default_url => "/assets/:class/:attachment/:style.png",
:styles => { :large => "100x100>", :small => "50x50>" }
@ -267,6 +269,8 @@ class User < ActiveRecord::Base
##
# delete a user - leave the account but purge most personal data
def delete
avatar.purge
self.display_name = "user_#{id}"
self.description = ""
self.home_lat = nil
@ -277,6 +281,7 @@ class User < ActiveRecord::Base
self.auth_provider = nil
self.auth_uid = nil
self.status = "deleted"
save
end

View file

@ -8,7 +8,7 @@ xml.tag! "user", :id => user.id,
else
xml.tag! "contributor-terms", :agreed => user.terms_agreed.present?
end
xml.tag! "img", :href => user_image_url(user) if user.image.file? || user.image_use_gravatar
xml.tag! "img", :href => user_image_url(user) if user.avatar.attached? || user.image.file? || user.image_use_gravatar
xml.tag! "roles" do
user.roles.each do |role|
xml.tag! role.role

View file

@ -104,40 +104,40 @@
<label class="standard-label"><%= t ".image" %></label>
<%= user_image current_user %>
<ul class='form-list accountImage-options'>
<% if current_user.image.file? %>
<% if current_user.avatar.attached? || current_user.image.file? %>
<li>
<%= radio_button_tag "image_action", "keep", !current_user.image_use_gravatar %>
<label class='standard-label' for='image_action_keep'><%= t ".keep image" %></label>
<%= radio_button_tag "avatar_action", "keep", !current_user.image_use_gravatar %>
<label class='standard-label' for='avatar_action_keep'><%= t ".keep image" %></label>
</li>
<% end %>
<% if current_user.image.file? || current_user.image_use_gravatar? %>
<% if current_user.avatar.attached? || current_user.image.file? || current_user.image_use_gravatar? %>
<li>
<%= radio_button_tag "image_action", "delete" %>
<label class='standard-label' for='image_action_delete'><%= t ".delete image" %></label>
<%= radio_button_tag "avatar_action", "delete" %>
<label class='standard-label' for='avatar_action_delete'><%= t ".delete image" %></label>
</li>
<% end %>
<% if current_user.image.file? %>
<% if current_user.avatar.attached? || current_user.image.file? %>
<li>
<%= radio_button_tag "image_action", "new" %>
<label class='standard-label' for='image_action_new'>
<%= radio_button_tag "avatar_action", "new" %>
<label class='standard-label' for='avatar_action_new'>
<%= t ".replace image" %>
<span class="form-help deemphasize"><%= t ".image size hint" %></span>
</label>
<%= f.file_field :image %>
<%= f.file_field :avatar %>
</li>
<% else %>
<li>
<%= radio_button_tag "image_action", "new" %>
<label class='standard-label' for='image_action_new'>
<%= radio_button_tag "avatar_action", "new" %>
<label class='standard-label' for='avatar_action_new'>
<%= t ".new image" %>
<span class="form-help deemphasize"><%= t ".image size hint" %></span>
</label>
<%= f.file_field :image %>
<%= f.file_field :avatar %>
</li>
<% end %>
<li>
<%= radio_button_tag "image_action", "gravatar", current_user.image_use_gravatar %>
<label class='standard-label' for='image_action_gravatar'>
<%= radio_button_tag "avatar_action", "gravatar", current_user.image_use_gravatar %>
<label class='standard-label' for='avatar_action_gravatar'>
<%= t ".gravatar.gravatar" %>
<span class='form-help deemphasize'> (<a href="<%= t ".gravatar.link" %>" target="_new"><%= t ".gravatar.link text" %></a>)</span>
</label>

View file

@ -876,28 +876,28 @@ class UsersControllerTest < ActionController::TestCase
# Changing to an uploaded image should work
image = Rack::Test::UploadedFile.new("test/gpx/fixtures/a.gif", "image/gif")
post :account, :params => { :display_name => user.display_name, :image_action => "new", :user => user.attributes.merge(:image => image) }, :session => { :user => user }
post :account, :params => { :display_name => user.display_name, :avatar_action => "new", :user => user.attributes.merge(:avatar => image) }, :session => { :user => user }
assert_response :success
assert_template :account
assert_select "div#errorExplanation", false
assert_select ".notice", /^User information updated successfully/
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=image_action][checked][value=?]", "keep"
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=avatar_action][checked][value=?]", "keep"
# Changing to a gravatar image should work
post :account, :params => { :display_name => user.display_name, :image_action => "gravatar", :user => user.attributes }, :session => { :user => user }
post :account, :params => { :display_name => user.display_name, :avatar_action => "gravatar", :user => user.attributes }, :session => { :user => user }
assert_response :success
assert_template :account
assert_select "div#errorExplanation", false
assert_select ".notice", /^User information updated successfully/
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=image_action][checked][value=?]", "gravatar"
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=avatar_action][checked][value=?]", "gravatar"
# Removing the image should work
post :account, :params => { :display_name => user.display_name, :image_action => "delete", :user => user.attributes }, :session => { :user => user }
post :account, :params => { :display_name => user.display_name, :avatar_action => "delete", :user => user.attributes }, :session => { :user => user }
assert_response :success
assert_template :account
assert_select "div#errorExplanation", false
assert_select ".notice", /^User information updated successfully/
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=image_action][checked]", false
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=avatar_action][checked]", false
# Adding external authentication should redirect to the auth provider
post :account, :params => { :display_name => user.display_name, :user => user.attributes.merge(:auth_provider => "openid", :auth_uid => "gmail.com") }, :session => { :user => user }

View file

@ -8,10 +8,10 @@ class UserHelperTest < ActionView::TestCase
gravatar_user = create(:user, :image_use_gravatar => true)
image = user_image(user)
assert_match %r{^<img class="user_image" .* src="/assets/users/images/large-.*" />$}, image
assert_match %r{^<img class="user_image" .* src="/images/avatar_large.png" />$}, image
image = user_image(user, :class => "foo")
assert_match %r{^<img class="foo" .* src="/assets/users/images/large-.*" />$}, image
assert_match %r{^<img class="foo" .* src="/images/avatar_large.png" />$}, image
image = user_image(gravatar_user)
assert_match %r{^<img class="user_image" .* src="http://www.gravatar.com/avatar/.*" />$}, image
@ -25,10 +25,10 @@ class UserHelperTest < ActionView::TestCase
gravatar_user = create(:user, :image_use_gravatar => true)
image = user_thumbnail(user)
assert_match %r{^<img class="user_thumbnail" .* src="/assets/users/images/small-.*" />$}, image
assert_match %r{^<img class="user_thumbnail" .* src="/images/avatar_small.png" />$}, image
image = user_thumbnail(user, :class => "foo")
assert_match %r{^<img class="foo" .* src="/assets/users/images/small-.*" />$}, image
assert_match %r{^<img class="foo" .* src="/images/avatar_small.png" />$}, image
image = user_thumbnail(gravatar_user)
assert_match %r{^<img class="user_thumbnail" .* src="http://www.gravatar.com/avatar/.*" />$}, image
@ -42,10 +42,10 @@ class UserHelperTest < ActionView::TestCase
gravatar_user = create(:user, :image_use_gravatar => true)
image = user_thumbnail_tiny(user)
assert_match %r{^<img class="user_thumbnail_tiny" .* src="/assets/users/images/small-.*" />$}, image
assert_match %r{^<img class="user_thumbnail_tiny" .* src="/images/avatar_small.png" />$}, image
image = user_thumbnail_tiny(user, :class => "foo")
assert_match %r{^<img class="foo" .* src="/assets/users/images/small-.*" />$}, image
assert_match %r{^<img class="foo" .* src="/images/avatar_small.png" />$}, image
image = user_thumbnail_tiny(gravatar_user)
assert_match %r{^<img class="user_thumbnail_tiny" .* src="http://www.gravatar.com/avatar/.*" />$}, image