From 821c7bc2a502fa15d1a5285cf0ec474eb428407f Mon Sep 17 00:00:00 2001 From: r888888888 Date: Wed, 14 Oct 2015 15:32:35 -0700 Subject: [PATCH] add dmail notices for mentions in forum posts --- app/logical/d_text.rb | 4 +++- app/logical/mentionable.rb | 41 ++++++++++++++++++++++++++++++++++++ app/models/forum_post.rb | 8 +++++++ test/unit/forum_post_test.rb | 16 ++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 app/logical/mentionable.rb diff --git a/app/logical/d_text.rb b/app/logical/d_text.rb index 1326e4497..39daefbb1 100644 --- a/app/logical/d_text.rb +++ b/app/logical/d_text.rb @@ -2,6 +2,8 @@ require 'cgi' require 'uri' class DText + MENTION_REGEXP = /(?:^| )@\S+/ + def self.u(string) CGI.escape(string) end @@ -36,7 +38,7 @@ class DText str.gsub!(/&/, "&") str.gsub!(//, ">") - str.gsub!(/(?:^| )@\S+/) do |name| + str.gsub!(MENTION_REGEXP) do |name| if name =~ /([:;,.!?\)\]<>])$/ name.chop! ch = $1 diff --git a/app/logical/mentionable.rb b/app/logical/mentionable.rb new file mode 100644 index 000000000..ad52df56f --- /dev/null +++ b/app/logical/mentionable.rb @@ -0,0 +1,41 @@ +module Mentionable + extend ActiveSupport::Concern + + module ClassMethods + # options: + # - message_field + # - user_field + def mentionable(options = {}) + @mentionable_options = options + + after_create :queue_mention_messages + end + + def mentionable_option(key) + @mentionable_options[key] + end + end + + def queue_mention_messages + title = self.class.mentionable_option(:title) + from_id = read_attribute(self.class.mentionable_option(:user_field)) + text = read_attribute(self.class.mentionable_option(:message_field)) + + text.scan(DText::MENTION_REGEXP).each do |mention| + mention.gsub!(/(?:^\s*@)|(?:[:;,.!?\)\]<>]$)/, "") + user = User.find_by_name(mention) + body = self.class.mentionable_option(:body).call(self, user.name) + + if user + dmail = Dmail.new( + from_id: from_id, + to_id: user.id, + title: title, + body: body + ) + dmail.owner_id = user.id + dmail.save + end + end + end +end diff --git a/app/models/forum_post.rb b/app/models/forum_post.rb index 8b749e6b8..d7a9f5b44 100644 --- a/app/models/forum_post.rb +++ b/app/models/forum_post.rb @@ -1,4 +1,6 @@ class ForumPost < ActiveRecord::Base + include Mentionable + attr_accessible :body, :topic_id, :as => [:member, :builder, :janitor, :gold, :platinum, :contributor, :admin, :moderator, :default] attr_accessible :is_locked, :is_sticky, :is_deleted, :as => [:admin, :moderator] attr_readonly :topic_id @@ -16,6 +18,12 @@ class ForumPost < ActiveRecord::Base validate :topic_id_not_invalid before_destroy :validate_topic_is_unlocked after_save :delete_topic_if_original_post + mentionable( + :message_field => :body, + :user_field => :creator_id, + :title => "You were mentioned in a forum topic", + :body => lambda {|rec, user_name| "You were mentioned in the forum topic \"#{rec.topic.title}\":#{Danbooru.config.hostname}/forum_topics/#{rec.topic_id}?page=#{rec.forum_topic_page}\n\n
\n\n#{ActionController::Base.helpers.excerpt(rec.body, user_name)}"} + ) module SearchMethods def body_matches(body) diff --git a/test/unit/forum_post_test.rb b/test/unit/forum_post_test.rb index d931d595b..36da3b624 100644 --- a/test/unit/forum_post_test.rb +++ b/test/unit/forum_post_test.rb @@ -14,6 +14,22 @@ class ForumPostTest < ActiveSupport::TestCase CurrentUser.ip_addr = nil end + context "that mentions a user" do + setup do + @user2 = FactoryGirl.create(:user) + @post = FactoryGirl.build(:forum_post, :topic_id => @topic.id, :body => "Hey @#{@user2.name} check this out!") + end + + should "create a dmail" do + assert_difference("Dmail.count", 1) do + @post.save + end + + dmail = Dmail.last + assert_equal("You were mentioned in the forum topic \"#{@topic.title}\":#{Danbooru.config.hostname}/forum_topics/#{@topic.id}?page=1\n\n
\n\nHey @#{@user2.name} check this out!", dmail.body) + end + end + context "that belongs to a topic with several pages of posts" do setup do Danbooru.config.stubs(:posts_per_page).returns(3)