discourse/app/models/user_profile.rb

174 lines
4.7 KiB
Ruby
Raw Normal View History

require_dependency 'upload_creator'
class UserProfile < ActiveRecord::Base
# TODO: remove this after Nov 1, 2018
self.ignored_columns = %w{card_image_badge_id}
2014-06-10 13:19:08 +08:00
belongs_to :user, inverse_of: :user_profile
validates :bio_raw, length: { maximum: 3000 }
validates :website, url: true, allow_blank: true, if: Proc.new { |c| c.new_record? || c.website_changed? }
2014-06-10 13:19:08 +08:00
validates :user, presence: true
before_save :cook
after_save :trigger_badges
2014-06-10 13:19:08 +08:00
validates :profile_background, upload_url: true, if: :profile_background_changed?
validates :card_background, upload_url: true, if: :card_background_changed?
validate :website_domain_validator, if: Proc.new { |c| c.new_record? || c.website_changed? }
2015-09-14 15:51:17 +08:00
has_many :user_profile_views, dependent: :destroy
2014-08-05 14:37:56 +08:00
BAKED_VERSION = 1
2017-07-28 09:20:09 +08:00
def bio_excerpt(length = 350, opts = {})
excerpt = PrettyText.excerpt(bio_cooked, length, opts).sub(/<br>$/, '')
return excerpt if excerpt.blank? || (user.has_trust_level?(TrustLevel[1]) && !user.suspended?)
2014-06-10 13:19:08 +08:00
PrettyText.strip_links(excerpt)
end
def bio_processed
return bio_cooked if bio_cooked.blank? || (user.has_trust_level?(TrustLevel[1]) && !user.suspended?)
2014-06-10 13:19:08 +08:00
PrettyText.strip_links(bio_cooked)
end
def bio_summary
return nil unless bio_cooked.present?
bio_excerpt(500, strip_links: true, text_entities: true)
2014-06-10 13:19:08 +08:00
end
def recook_bio
self.bio_raw_will_change!
cook
end
def upload_card_background(upload)
self.card_background = upload.url
self.save!
end
def clear_card_background
self.card_background = ""
self.save!
end
def upload_profile_background(upload)
self.profile_background = upload.url
self.save!
end
def clear_profile_background
self.profile_background = ""
self.save!
end
2014-08-05 14:37:56 +08:00
def self.rebake_old(limit)
problems = []
UserProfile.where('bio_cooked_version IS NULL OR bio_cooked_version < ?', BAKED_VERSION)
2017-07-28 09:20:09 +08:00
.limit(limit).each do |p|
2014-08-05 14:37:56 +08:00
begin
p.rebake!
rescue => e
2017-07-28 09:20:09 +08:00
problems << { profile: p, ex: e }
2014-08-05 14:37:56 +08:00
end
end
problems
end
def rebake!
update_columns(bio_cooked: cooked, bio_cooked_version: BAKED_VERSION)
end
def self.import_url_for_user(background_url, user, options = nil)
tempfile = FileHelper.download(
background_url,
max_file_size: SiteSetting.max_image_size_kb.kilobytes,
tmp_file_name: "sso-profile-background",
follow_redirect: true
)
return unless tempfile
ext = FastImage.type(tempfile).to_s
tempfile.rewind
is_card_background = !options || options[:is_card_background]
type = is_card_background ? "card_background" : "profile_background"
upload = UploadCreator.new(tempfile, "external-profile-background." + ext, origin: background_url, type: type).create_for(user.id)
if (is_card_background)
user.user_profile.upload_card_background(upload)
else
user.user_profile.upload_profile_background(upload)
end
rescue Net::ReadTimeout, OpenURI::HTTPError
# skip saving, we are not connected to the net
ensure
tempfile.close! if tempfile && tempfile.respond_to?(:close!)
end
protected
def trigger_badges
BadgeGranter.queue_badge_grant(Badge::Trigger::UserChange, user: self)
end
2014-06-10 13:19:08 +08:00
private
2014-08-05 14:37:56 +08:00
def cooked
if self.bio_raw.present?
PrettyText.cook(self.bio_raw, omit_nofollow: user.has_trust_level?(TrustLevel[3]) && !SiteSetting.tl3_links_no_follow)
2014-08-05 14:37:56 +08:00
else
nil
end
end
2014-06-10 13:19:08 +08:00
def cook
if self.bio_raw.present?
2014-08-05 14:37:56 +08:00
if bio_raw_changed?
self.bio_cooked = cooked
self.bio_cooked_version = BAKED_VERSION
end
2014-06-10 13:19:08 +08:00
else
self.bio_cooked = nil
end
end
def website_domain_validator
allowed_domains = SiteSetting.user_website_domains_whitelist
return if (allowed_domains.blank? || self.website.blank?)
2018-05-17 15:51:24 +08:00
domain = begin
URI.parse(self.website).host
rescue URI::InvalidURIError
end
self.errors.add :base, (I18n.t('user.website.domain_not_allowed', domains: allowed_domains.split('|').join(", "))) unless allowed_domains.split('|').include?(domain)
end
end
# == Schema Information
#
# Table name: user_profiles
#
# user_id :integer not null, primary key
2018-02-20 14:28:58 +08:00
# location :string
# website :string
# bio_raw :text
# bio_cooked :text
2017-12-05 23:29:14 +08:00
# profile_background :string(255)
2018-02-20 14:28:58 +08:00
# dismissed_banner_key :integer
2014-08-07 11:33:11 +08:00
# bio_cooked_version :integer
# badge_granted_title :boolean default(FALSE)
# card_background :string(255)
2015-09-14 11:50:59 +08:00
# views :integer default(0), not null
2014-08-07 11:33:11 +08:00
#
# Indexes
#
# index_user_profiles_on_bio_cooked_version (bio_cooked_version)
2016-11-24 10:13:03 +08:00
# index_user_profiles_on_card_background (card_background)
# index_user_profiles_on_profile_background (profile_background)
#