From 4e057513466884050eb17b0d3c4b091852399ee4 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 5 May 2017 15:37:02 -0400 Subject: [PATCH] Move account header and avatar methods to a concern (#2825) --- app/models/account.rb | 72 ++----------------- app/models/concerns/account_avatar.rb | 41 +++++++++++ app/models/concerns/account_header.rb | 41 +++++++++++ app/services/update_remote_profile_service.rb | 2 +- 4 files changed, 89 insertions(+), 67 deletions(-) create mode 100644 app/models/concerns/account_avatar.rb create mode 100644 app/models/concerns/account_header.rb diff --git a/app/models/account.rb b/app/models/account.rb index 87b97a20d..d5b55174e 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -39,28 +39,18 @@ # class Account < ApplicationRecord - include Targetable - MENTION_RE = /(?:^|[^\/\w])@([a-z0-9_]+(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i - IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze + + include AccountAvatar + include AccountHeader + include Attachmentable + include Targetable # Local users has_one :user, inverse_of: :account validates :username, presence: true, format: { with: /\A[a-z0-9_]+\z/i }, uniqueness: { scope: :domain, case_sensitive: false }, length: { maximum: 30 }, if: 'local?' validates :username, presence: true, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?' - # Avatar upload - has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-quality 80 -strip' } - validates_attachment_content_type :avatar, content_type: IMAGE_MIME_TYPES - validates_attachment_size :avatar, less_than: 2.megabytes - - # Header upload - has_attached_file :header, styles: ->(f) { header_styles(f) }, convert_options: { all: '-quality 80 -strip' } - validates_attachment_content_type :header, content_type: IMAGE_MIME_TYPES - validates_attachment_size :header, less_than: 2.megabytes - - include Attachmentable - # Local user profile validations validates :display_name, length: { maximum: 30 }, if: 'local?' validates :note, length: { maximum: 160 }, if: 'local?' @@ -206,7 +196,7 @@ class Account < ApplicationRecord OStatus2::Subscription.new(remote_url, secret: secret, lease_seconds: 86_400 * 30, webhook: webhook_url, hub: hub_url) end - def save_with_optional_avatar! + def save_with_optional_media! save! rescue ActiveRecord::RecordInvalid self.avatar = nil @@ -216,44 +206,6 @@ class Account < ApplicationRecord save! end - def avatar_original_url - avatar.url(:original) - end - - def avatar_static_url - avatar_content_type == 'image/gif' ? avatar.url(:static) : avatar_original_url - end - - def header_original_url - header.url(:original) - end - - def header_static_url - header_content_type == 'image/gif' ? header.url(:static) : header_original_url - end - - def avatar_remote_url=(url) - parsed_url = Addressable::URI.parse(url).normalize - - return if !%w(http https).include?(parsed_url.scheme) || parsed_url.host.empty? || self[:avatar_remote_url] == url - - self.avatar = URI.parse(parsed_url.to_s) - self[:avatar_remote_url] = url - rescue OpenURI::HTTPError => e - Rails.logger.debug "Error fetching remote avatar: #{e}" - end - - def header_remote_url=(url) - parsed_url = Addressable::URI.parse(url).normalize - - return if !%w(http https).include?(parsed_url.scheme) || parsed_url.host.empty? || self[:header_remote_url] == url - - self.header = URI.parse(parsed_url.to_s) - self[:header_remote_url] = url - rescue OpenURI::HTTPError => e - Rails.logger.debug "Error fetching remote header: #{e}" - end - def object_type :person end @@ -372,18 +324,6 @@ class Account < ApplicationRecord def follow_mapping(query, field) query.pluck(field).each_with_object({}) { |id, mapping| mapping[id] = true } end - - def avatar_styles(file) - styles = { original: '120x120#' } - styles[:static] = { format: 'png' } if file.content_type == 'image/gif' - styles - end - - def header_styles(file) - styles = { original: '700x335#' } - styles[:static] = { format: 'png' } if file.content_type == 'image/gif' - styles - end end before_create :generate_keys diff --git a/app/models/concerns/account_avatar.rb b/app/models/concerns/account_avatar.rb new file mode 100644 index 000000000..38e32864a --- /dev/null +++ b/app/models/concerns/account_avatar.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module AccountAvatar + extend ActiveSupport::Concern + IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze + + class_methods do + def avatar_styles(file) + styles = { original: '120x120#' } + styles[:static] = { format: 'png' } if file.content_type == 'image/gif' + styles + end + private :avatar_styles + end + + included do + # Avatar upload + has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-quality 80 -strip' } + validates_attachment_content_type :avatar, content_type: IMAGE_MIME_TYPES + validates_attachment_size :avatar, less_than: 2.megabytes + + def avatar_original_url + avatar.url(:original) + end + + def avatar_static_url + avatar_content_type == 'image/gif' ? avatar.url(:static) : avatar_original_url + end + + def avatar_remote_url=(url) + parsed_url = Addressable::URI.parse(url).normalize + + return if !%w(http https).include?(parsed_url.scheme) || parsed_url.host.empty? || self[:avatar_remote_url] == url + + self.avatar = URI.parse(parsed_url.to_s) + self[:avatar_remote_url] = url + rescue OpenURI::HTTPError => e + Rails.logger.debug "Error fetching remote avatar: #{e}" + end + end +end diff --git a/app/models/concerns/account_header.rb b/app/models/concerns/account_header.rb new file mode 100644 index 000000000..8fa5e1616 --- /dev/null +++ b/app/models/concerns/account_header.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module AccountHeader + extend ActiveSupport::Concern + IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze + + class_methods do + def header_styles(file) + styles = { original: '700x335#' } + styles[:static] = { format: 'png' } if file.content_type == 'image/gif' + styles + end + private :header_styles + end + + included do + # Header upload + has_attached_file :header, styles: ->(f) { header_styles(f) }, convert_options: { all: '-quality 80 -strip' } + validates_attachment_content_type :header, content_type: IMAGE_MIME_TYPES + validates_attachment_size :header, less_than: 2.megabytes + + def header_original_url + header.url(:original) + end + + def header_static_url + header_content_type == 'image/gif' ? header.url(:static) : header_original_url + end + + def header_remote_url=(url) + parsed_url = Addressable::URI.parse(url).normalize + + return if !%w(http https).include?(parsed_url.scheme) || parsed_url.host.empty? || self[:header_remote_url] == url + + self.header = URI.parse(parsed_url.to_s) + self[:header_remote_url] = url + rescue OpenURI::HTTPError => e + Rails.logger.debug "Error fetching remote header: #{e}" + end + end +end diff --git a/app/services/update_remote_profile_service.rb b/app/services/update_remote_profile_service.rb index f0c39ecc0..6607bc84e 100644 --- a/app/services/update_remote_profile_service.rb +++ b/app/services/update_remote_profile_service.rb @@ -26,7 +26,7 @@ class UpdateRemoteProfileService < BaseService old_hub_url = account.hub_url account.hub_url = hub_link['href'] if !hub_link.nil? && !hub_link['href'].blank? && (hub_link['href'] != old_hub_url) - account.save_with_optional_avatar! + account.save_with_optional_media! Pubsubhubbub::SubscribeWorker.perform_async(account.id) if resubscribe && (account.hub_url != old_hub_url) end