diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 44529a9b2..79e48b807 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -66,14 +66,12 @@ def update
end
def update_avatar
- avatar = params[:avatar]
- errors = validate_avatar(avatar)
+ operation = AvatarGenerator.new(current_user, params)
- if errors.blank?
- current_user.avatar.purge if current_user.avatar.attached?
- crop_image_and_save(current_user, avatar)
+ if operation.errors.empty?
+ operation.call
else
- flash[:error] = errors.join("
")
+ flash[:error] = operation.errors.join("
")
end
redirect_to current_user
@@ -130,38 +128,4 @@ def redirect_to_after_create
name: @user.username)
end
end
-
- def crop_image_and_save(user, avatar)
- orig_width = params[:original_width].to_i
- width = params[:height_width].to_i
- left = params[:width_offset].to_i
- top = params[:height_offset].to_i
-
- image_processed = ImageProcessing::MiniMagick.
- source(avatar.tempfile).
- resize_to_fit(orig_width, nil).
- crop("#{width}x#{width}+#{left}+#{top}!").
- convert("png").
- call
-
- user.avatar.attach(
- io: image_processed,
- filename: user.username,
- content_type: avatar.content_type
- )
- end
-
- def validate_avatar(file)
- errors = []
-
- if User::AVATAR_CONTENT_TYPES.exclude?(file.content_type)
- errors << t("users.show.invalid_format")
- end
-
- if file.size.to_f > User::AVATAR_MAX_SIZE.megabytes
- errors << t("users.avatar.max_size_warning", size: User::AVATAR_MAX_SIZE)
- end
-
- errors
- end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index a0eb4bc9a..4f3e006c8 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -9,8 +9,6 @@ class User < ApplicationRecord
:timeoutable
]
- AVATAR_MAX_SIZE = 5
- AVATAR_CONTENT_TYPES = %w[image/jpeg image/pjpeg image/png image/x-png]
GENDERS = %w(
female
male
diff --git a/app/services/avatar_generator.rb b/app/services/avatar_generator.rb
new file mode 100644
index 000000000..d04187f4c
--- /dev/null
+++ b/app/services/avatar_generator.rb
@@ -0,0 +1,51 @@
+class AvatarGenerator
+ MAX_SIZE = 5
+ CONTENT_TYPES = %w[image/jpeg image/pjpeg image/png image/x-png]
+
+ attr_accessor :errors
+
+ def initialize(user, params)
+ @user = user
+ @params = params
+ @avatar = params[:avatar]
+ @errors = []
+
+ validate_avatar
+ end
+
+ def call
+ @user.avatar.purge if @user.avatar.attached?
+
+ @user.avatar.attach(
+ io: process_image,
+ filename: @user.username,
+ content_type: @avatar.content_type
+ )
+ end
+
+ private
+
+ def process_image
+ orig_width = @params[:original_width].to_i
+ width = @params[:height_width].to_i
+ left = @params[:width_offset].to_i
+ top = @params[:height_offset].to_i
+
+ ImageProcessing::MiniMagick.
+ source(@avatar.tempfile).
+ resize_to_fit(orig_width, nil).
+ crop("#{width}x#{width}+#{left}+#{top}!").
+ convert("png").
+ call
+ end
+
+ def validate_avatar
+ if CONTENT_TYPES.exclude?(@avatar.content_type)
+ @errors << I18n.t("users.show.invalid_format")
+ end
+
+ if @avatar.size.to_f > MAX_SIZE.megabytes
+ @errors << I18n.t("users.avatar.max_size_warning", size: MAX_SIZE)
+ end
+ end
+end
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index aac98519f..16676d9fb 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -433,7 +433,7 @@
end
it "don't change the photo attached if the file size it too big" do
- allow_any_instance_of(ActionDispatch::Http::UploadedFile).to receive(:size) { User::AVATAR_MAX_SIZE.megabytes + 1.megabyte }
+ allow_any_instance_of(ActionDispatch::Http::UploadedFile).to receive(:size) { AvatarGenerator::MAX_SIZE.megabytes + 1.megabyte }
put :update_avatar, params: { avatar: uploaded_file }