Class: Person
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Person
- Includes:
- Diaspora::Fields::Guid
- Defined in:
- app/models/person.rb
Overview
Copyright © 2010-2011, Diaspora Inc. This file is
licensed under the Affero General Public License version 3 or later. See
the COPYRIGHT file.
Class Method Summary collapse
- .by_account_identifier(diaspora_id) ⇒ Object
- .community_spotlight ⇒ Object
- .find_from_guid_or_username(params) ⇒ Object
-
.find_or_fetch_by_identifier(diaspora_id) ⇒ Object
discovery (webfinger).
- .name_from_attrs(first_name, last_name, diaspora_handle) ⇒ Object
- .search(search_str, user, only_contacts: false, mutual: false) ⇒ Object
- .search_query_string(query) ⇒ Object
Instance Method Summary collapse
-
#allowed_to_be_mentioned_in_a_comment_to ⇒ Person::ActiveRecord_Relation
Selects people who can be mentioned in a comment to a specific post.
- #as_json(opts = {}) ⇒ Object
- #atom_url ⇒ Object
- #author ⇒ Object
- #clear_profile! ⇒ Object
- #downcase_diaspora_handle ⇒ Object
- #exported_key ⇒ Object
-
#find_by_substring ⇒ Person::ActiveRecord_Relation
This scope selects people where the full name contains the search_str or diaspora ID starts with the search_str.
- #first_name ⇒ Object
- #has_photos? ⇒ Boolean
-
#initialize(params = {}) ⇒ Person
constructor
Set a default of an empty profile when a new Person record is instantiated.
-
#left_join_visible_post_interactions_on_authorship ⇒ Person::ActiveRecord_Relation
Left joins likes and comments to a specific post where people are authors of these comments and likes.
- #local? ⇒ Boolean
- #lock_access! ⇒ Object
- #name(opts = {}) ⇒ Object
- #owns?(obj) ⇒ Boolean
- #profile_url ⇒ Object
- #public_key ⇒ Object
- #public_key_hash ⇒ Object
- #receive_url ⇒ Object
- #remote? ⇒ Boolean
-
#sort_for_mention_suggestion ⇒ Person::ActiveRecord_Relation
This scope adds sorting of people in the order, appropriate for suggesting to a user (current user) who has requested a list of the people mentionable in a comment for a specific post.
- #to_param ⇒ Object
- #url ⇒ Object
- #url_to(path) ⇒ String
- #username ⇒ Object
Methods included from Diaspora::Fields::Guid
Constructor Details
#initialize(params = {}) ⇒ Person
Set a default of an empty profile when a new Person record is instantiated. Passing :profile => nil to Person.new will instantiate a person with no profile. Calling Person.new with a block:
Person.new do |p|
p.profile = nil
end
will not work! The nil profile will be overriden with an empty one.
206 207 208 209 210 211 212 213 |
# File 'app/models/person.rb', line 206 def initialize(params={}) params = {} if params.nil? profile_set = params.has_key?(:profile) || params.has_key?("profile") params[:profile_attributes] = params.delete(:profile) if params.has_key?(:profile) && params[:profile].is_a?(Hash) super self.profile ||= Profile.new unless profile_set end |
Class Method Details
.by_account_identifier(diaspora_id) ⇒ Object
347 348 349 |
# File 'app/models/person.rb', line 347 def self.by_account_identifier(diaspora_id) find_by(diaspora_handle: diaspora_id.strip.downcase) end |
.community_spotlight ⇒ Object
195 196 197 |
# File 'app/models/person.rb', line 195 def self.community_spotlight Person.joins(:roles).where(:roles => {:name => 'spotlight'}) end |
.find_from_guid_or_username(params) ⇒ Object
215 216 217 218 219 220 221 222 223 224 225 |
# File 'app/models/person.rb', line 215 def self.find_from_guid_or_username(params) p = if params[:id].present? Person.find_by(guid: params[:id]) elsif params[:username].present? && u = User.find_by_username(params[:username]) u.person else nil end raise ActiveRecord::RecordNotFound unless p.present? p end |
.find_or_fetch_by_identifier(diaspora_id) ⇒ Object
discovery (webfinger)
335 336 337 338 339 340 341 342 343 344 345 |
# File 'app/models/person.rb', line 335 def self.find_or_fetch_by_identifier(diaspora_id) # exiting person? person = by_account_identifier(diaspora_id) return person if person.present? && person.profile.present? # create or update person from webfinger logger.info "webfingering #{diaspora_id}, it is not known or needs updating" DiasporaFederation::Discovery::Discovery.new(diaspora_id).fetch_and_save by_account_identifier(diaspora_id) end |
.name_from_attrs(first_name, last_name, diaspora_handle) ⇒ Object
271 272 273 |
# File 'app/models/person.rb', line 271 def self.name_from_attrs(first_name, last_name, diaspora_handle) first_name.blank? && last_name.blank? ? diaspora_handle : "#{first_name.to_s.strip} #{last_name.to_s.strip}".strip end |
.search(search_str, user, only_contacts: false, mutual: false) ⇒ Object
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'app/models/person.rb', line 248 def self.search(search_str, user, only_contacts: false, mutual: false) query = find_by_substring(search_str) return query if query.is_a?(ActiveRecord::NullRelation) query = if only_contacts query.contacts_of(user) else query.searchable(user) end query = query.where(contacts: {sharing: true, receiving: true}) if mutual query.where(closed_account: false) .order([Arel.sql("contacts.user_id IS NULL"), "profiles.last_name ASC", "profiles.first_name ASC"]) end |
.search_query_string(query) ⇒ Object
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'app/models/person.rb', line 231 def self.search_query_string(query) query = query.downcase like_operator = AppConfig.postgres? ? "ILIKE" : "LIKE" where_clause = <<-SQL profiles.full_name #{like_operator} ? OR people.diaspora_handle #{like_operator} ? SQL q_tokens = [] q_tokens[0] = query.to_s.strip.gsub(/(\s|$|^)/) { "%#{$1}" } q_tokens[1] = q_tokens[0].gsub(/\s/,'').gsub('%','') q_tokens[1] << "%" [where_clause, q_tokens] end |
Instance Method Details
#allowed_to_be_mentioned_in_a_comment_to ⇒ Person::ActiveRecord_Relation
Selects people who can be mentioned in a comment to a specific post. For public posts all people are allowed, so no additional constraints are added. For private posts selection is limited to people who have posted comments or likes for this post.
157 158 159 160 161 162 163 164 165 |
# File 'app/models/person.rb', line 157 scope :allowed_to_be_mentioned_in_a_comment_to, ->(post) { allowed = if post.public? all else (post.id) .where("comments.id IS NOT NULL OR likes.id IS NOT NULL OR people.id = #{post.}") end allowed.distinct } |
#as_json(opts = {}) ⇒ Object
362 363 364 365 366 367 368 369 370 371 372 373 374 |
# File 'app/models/person.rb', line 362 def as_json( opts = {} ) opts ||= {} json = { id: id, guid: guid, name: name, avatar: profile.image_url(size: :thumb_small), handle: diaspora_handle, url: Rails.application.routes.url_helpers.person_path(self) } json.merge!(:tags => self.profile..map{|t| "##{t.name}"}) if opts[:includes] == "tags" json end |
#atom_url ⇒ Object
306 307 308 |
# File 'app/models/person.rb', line 306 def atom_url url_to "/public/#{username}.atom" end |
#author ⇒ Object
290 291 292 |
# File 'app/models/person.rb', line 290 def self end |
#clear_profile! ⇒ Object
381 382 383 384 |
# File 'app/models/person.rb', line 381 def clear_profile! self.profile.tombstone! self end |
#downcase_diaspora_handle ⇒ Object
34 35 36 |
# File 'app/models/person.rb', line 34 def downcase_diaspora_handle diaspora_handle.downcase! unless diaspora_handle.blank? end |
#exported_key ⇒ Object
330 331 332 |
# File 'app/models/person.rb', line 330 def exported_key serialized_public_key end |
#find_by_substring ⇒ Person::ActiveRecord_Relation
This scope selects people where the full name contains the search_str or diaspora ID starts with the search_str. However, if the search_str doesn’t have more than 1 non-whitespace character, it’ll return an empty set.
125 126 127 128 129 130 131 132 133 |
# File 'app/models/person.rb', line 125 scope :find_by_substring, ->(search_str) { search_str = search_str.strip if search_str.blank? || search_str.size < 2 none else sql, tokens = search_query_string(search_str) joins(:profile).where(sql, *tokens) end } |
#first_name ⇒ Object
275 276 277 278 279 280 281 282 283 284 |
# File 'app/models/person.rb', line 275 def first_name @first_name ||= if profile.nil? || profile.first_name.nil? || profile.first_name.blank? self.diaspora_handle.split('@').first else names = profile.first_name.to_s.split(/\s/) str = names[0...-1].join(' ') str = names[0] if str.blank? str end end |
#has_photos? ⇒ Boolean
358 359 360 |
# File 'app/models/person.rb', line 358 def has_photos? self.photos.exists? end |
#left_join_visible_post_interactions_on_authorship ⇒ Person::ActiveRecord_Relation
Left joins likes and comments to a specific post where people are authors of these comments and likes
138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'app/models/person.rb', line 138 scope :left_join_visible_post_interactions_on_authorship, ->(post_id) { comments_sql = <<-SQL LEFT OUTER JOIN comments ON comments.author_id = people.id AND comments.commentable_type = 'Post' AND comments.commentable_id = #{post_id} SQL likes_sql = <<-SQL LEFT OUTER JOIN likes ON likes.author_id = people.id AND likes.target_type = 'Post' AND likes.target_id = #{post_id} SQL joins(comments_sql).joins(likes_sql) } |
#local? ⇒ Boolean
354 355 356 |
# File 'app/models/person.rb', line 354 def local? !remote? end |
#lock_access! ⇒ Object
376 377 378 379 |
# File 'app/models/person.rb', line 376 def lock_access! self.closed_account = true self.save end |
#name(opts = {}) ⇒ Object
264 265 266 267 268 269 |
# File 'app/models/person.rb', line 264 def name(opts = {}) if self.profile.nil? fix_profile end @name ||= Person.name_from_attrs(self.profile.first_name, self.profile.last_name, self.diaspora_handle) end |
#owns?(obj) ⇒ Boolean
294 295 296 |
# File 'app/models/person.rb', line 294 def owns?(obj) self.id == obj. end |
#profile_url ⇒ Object
302 303 304 |
# File 'app/models/person.rb', line 302 def profile_url url_to "/u/#{username}" end |
#public_key ⇒ Object
324 325 326 327 328 |
# File 'app/models/person.rb', line 324 def public_key OpenSSL::PKey::RSA.new(serialized_public_key) rescue OpenSSL::PKey::RSAError nil end |
#public_key_hash ⇒ Object
320 321 322 |
# File 'app/models/person.rb', line 320 def public_key_hash Base64.encode64(OpenSSL::Digest::SHA256.new(serialized_public_key).to_s) end |
#receive_url ⇒ Object
310 311 312 |
# File 'app/models/person.rb', line 310 def receive_url url_to "/receive/users/#{guid}" end |
#remote? ⇒ Boolean
351 352 353 |
# File 'app/models/person.rb', line 351 def remote? owner_id.nil? end |
#sort_for_mention_suggestion ⇒ Person::ActiveRecord_Relation
This scope adds sorting of people in the order, appropriate for suggesting to a user (current user) who has requested a list of the people mentionable in a comment for a specific post. Sorts people in the following priority: post author > commenters > likers > contacts > non-contacts
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'app/models/person.rb', line 173 scope :sort_for_mention_suggestion, ->(post, user) { (post.id) .joins("LEFT OUTER JOIN contacts ON people.id = contacts.person_id AND contacts.user_id = #{user.id}") .joins(:profile) .select(<<-SQL people.id = #{unscoped { post. }} AS is_author, comments.id IS NOT NULL AS is_commenter, likes.id IS NOT NULL AS is_liker, contacts.id IS NOT NULL AS is_contact SQL ) .order(Arel.sql(<<-SQL is_author DESC, is_commenter DESC, is_liker DESC, is_contact DESC, profiles.full_name, people.diaspora_handle SQL )) } |
#to_param ⇒ Object
227 228 229 |
# File 'app/models/person.rb', line 227 def to_param self.guid end |
#url ⇒ Object
298 299 300 |
# File 'app/models/person.rb', line 298 def url url_to "/" end |
#url_to(path) ⇒ String
316 317 318 |
# File 'app/models/person.rb', line 316 def url_to(path) local? ? AppConfig.url_to(path) : pod.url_to(path) end |
#username ⇒ Object
286 287 288 |
# File 'app/models/person.rb', line 286 def username @username ||= owner ? owner.username : diaspora_handle.split("@")[0] end |