158 lines
4.1 KiB
Ruby
158 lines
4.1 KiB
Ruby
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
|
# licensed under the Affero General Public License version 3 or later. See
|
|
# the COPYRIGHT file.
|
|
|
|
class StatusMessage < Post
|
|
include Diaspora::Taggable
|
|
|
|
include PeopleHelper
|
|
|
|
acts_as_taggable_on :tags
|
|
extract_tags_from :raw_message
|
|
|
|
validates_length_of :text, :maximum => 65535, :message => proc {|p, v| I18n.t('status_messages.too_long', :count => 65535, :current_length => v[:value].length)}
|
|
|
|
# don't allow creation of empty status messages
|
|
validate :presence_of_content, on: :create, if: proc {|sm| sm.author && sm.author.local? }
|
|
|
|
has_many :photos, :dependent => :destroy, :foreign_key => :status_message_guid, :primary_key => :guid
|
|
|
|
has_one :location
|
|
has_one :poll, autosave: true
|
|
|
|
|
|
# a StatusMessage is federated before its photos are so presence_of_content() fails erroneously if no text is present
|
|
# therefore, we put the validation in a before_destory callback instead of a validation
|
|
before_destroy :absence_of_content
|
|
|
|
attr_accessor :oembed_url
|
|
attr_accessor :open_graph_url
|
|
|
|
after_create :create_mentions
|
|
after_commit :queue_gather_oembed_data, :on => :create, :if => :contains_oembed_url_in_text?
|
|
after_commit :queue_gather_open_graph_data, :on => :create, :if => :contains_open_graph_url_in_text?
|
|
|
|
#scopes
|
|
scope :where_person_is_mentioned, ->(person) {
|
|
joins(:mentions).where(:mentions => {:person_id => person.id})
|
|
}
|
|
|
|
def self.guids_for_author(person)
|
|
Post.connection.select_values(Post.where(:author_id => person.id).select('posts.guid').to_sql)
|
|
end
|
|
|
|
def self.user_tag_stream(user, tag_ids)
|
|
owned_or_visible_by_user(user).
|
|
tag_stream(tag_ids)
|
|
end
|
|
|
|
def self.public_tag_stream(tag_ids)
|
|
all_public.
|
|
tag_stream(tag_ids)
|
|
end
|
|
|
|
def raw_message
|
|
read_attribute(:text) || ""
|
|
end
|
|
|
|
def raw_message=(text)
|
|
write_attribute(:text, text)
|
|
end
|
|
|
|
def nsfw
|
|
self.raw_message.match(/#nsfw/i) || super
|
|
end
|
|
|
|
def message
|
|
@message ||= Diaspora::MessageRenderer.new raw_message, mentioned_people: mentioned_people
|
|
end
|
|
|
|
def mentioned_people
|
|
if self.persisted?
|
|
create_mentions if self.mentions.empty?
|
|
self.mentions.includes(:person => :profile).map{ |mention| mention.person }
|
|
else
|
|
Diaspora::Mentionable.people_from_string(self.raw_message)
|
|
end
|
|
end
|
|
|
|
## TODO ----
|
|
# don't put presentation logic in the model!
|
|
def mentioned_people_names
|
|
self.mentioned_people.map(&:name).join(', ')
|
|
end
|
|
## ---- ----
|
|
|
|
def create_mentions
|
|
ppl = Diaspora::Mentionable.people_from_string(self.raw_message)
|
|
ppl.each do |person|
|
|
self.mentions.find_or_create_by(person_id: person.id)
|
|
end
|
|
end
|
|
|
|
def mentions?(person)
|
|
mentioned_people.include? person
|
|
end
|
|
|
|
def comment_email_subject
|
|
message.title
|
|
end
|
|
|
|
def first_photo_url(*args)
|
|
photos.first.url(*args)
|
|
end
|
|
|
|
def text_and_photos_blank?
|
|
self.raw_message.blank? && self.photos.blank?
|
|
end
|
|
|
|
def queue_gather_oembed_data
|
|
Workers::GatherOEmbedData.perform_async(self.id, self.oembed_url)
|
|
end
|
|
|
|
def queue_gather_open_graph_data
|
|
Workers::GatherOpenGraphData.perform_async(self.id, self.open_graph_url)
|
|
end
|
|
|
|
def contains_oembed_url_in_text?
|
|
urls = self.message.urls
|
|
self.oembed_url = urls.find{ |url| !TRUSTED_OEMBED_PROVIDERS.find(url).nil? }
|
|
end
|
|
|
|
def contains_open_graph_url_in_text?
|
|
return nil if self.contains_oembed_url_in_text?
|
|
self.open_graph_url = self.message.urls[0]
|
|
end
|
|
|
|
def post_location
|
|
{
|
|
address: location.try(:address),
|
|
lat: location.try(:lat),
|
|
lng: location.try(:lng)
|
|
}
|
|
end
|
|
|
|
protected
|
|
def presence_of_content
|
|
if text_and_photos_blank?
|
|
errors[:base] << "Cannot create a StatusMessage without content"
|
|
end
|
|
end
|
|
|
|
def absence_of_content
|
|
unless text_and_photos_blank?
|
|
errors[:base] << "Cannot destory a StatusMessage with text and/or photos present"
|
|
end
|
|
end
|
|
|
|
private
|
|
def self.tag_stream(tag_ids)
|
|
joins(:taggings).where('taggings.tag_id IN (?)', tag_ids)
|
|
end
|
|
|
|
def after_parse
|
|
# Make sure already received photos don't invalidate the model
|
|
self.photos = photos.select(&:valid?)
|
|
end
|
|
end
|
|
|