diff --git a/.circleci/config.yml b/.circleci/config.yml
index f6963bf8c..ea4f9427a 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -44,7 +44,6 @@ jobs:
docker-compose -f config/docker/compose.yml exec archives dockerize -wait tcp://$PGHOST:$PGPORT bash -l -c 'cd /app ; bundle exec rake db:create ; bundle exec rake db:migrate'
docker-compose -f config/docker/compose.yml exec web dockerize -wait tcp://$PGHOST:$PGPORT bash -l -c 'cd /app ; bin/rake db:create ; bin/rake db:migrate'
- run:
-
name: Run tests
command: |
circleci tests glob test/**/*_test.rb | circleci tests split --split-by=timings | xargs -I{} docker-compose -f config/docker/compose.yml exec -T web bash -l -c 'cd /app ; bin/rails test --no-ci-clean {}'
diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb
index 681c466ce..ac21b899e 100644
--- a/app/helpers/posts_helper.rb
+++ b/app/helpers/posts_helper.rb
@@ -147,6 +147,10 @@ module PostsHelper
return params[:pool_id].to_i == pool.id
end
+ def show_tag_change_notice?
+ Tag.scan_query(params[:tags]).size == 1 && TagChangeNoticeService.get_forum_topic_id(params[:tags])
+ end
+
private
def nav_params_for(page)
diff --git a/app/logical/alias_and_implication_importer.rb b/app/logical/alias_and_implication_importer.rb
index 7fe6e5382..3ccb0f3b0 100644
--- a/app/logical/alias_and_implication_importer.rb
+++ b/app/logical/alias_and_implication_importer.rb
@@ -100,6 +100,30 @@ class AliasAndImplicationImporter
end
end
+ def affected_tags
+ tokens = self.class.tokenize(text)
+ tokens.inject([]) do |all, token|
+ case token[0]
+ when :create_alias, :remove_alias, :create_implication, :remove_implication
+ all << token[1]
+ all << token[2]
+ all
+
+ when :mass_update
+ all += Tag.scan_tags(token[1])
+ all += Tag.scan_tags(token[2])
+ all
+
+ when :change_category
+ all << token[1]
+ all
+
+ else
+ all
+ end
+ end
+ end
+
private
def parse(tokens, approver)
diff --git a/app/logical/tag_change_notice_service.rb b/app/logical/tag_change_notice_service.rb
new file mode 100644
index 000000000..cb43b59ee
--- /dev/null
+++ b/app/logical/tag_change_notice_service.rb
@@ -0,0 +1,18 @@
+module TagChangeNoticeService
+ extend self
+
+ def redis_client
+ ::Redis.new(url: Danbooru.config.redis_url)
+ end
+
+ def get_forum_topic_id(tag)
+ redis_client.get("tcn:#{tag}")
+ end
+
+ def update_cache(affected_tags, forum_topic_id)
+ rc = redis_client
+ affected_tags.each do |tag|
+ rc.setex("tcn:#{tag}", 1.week, forum_topic_id)
+ end
+ end
+end
diff --git a/app/models/bulk_update_request.rb b/app/models/bulk_update_request.rb
index e0c73dc17..fd6abda69 100644
--- a/app/models/bulk_update_request.rb
+++ b/app/models/bulk_update_request.rb
@@ -16,6 +16,7 @@ class BulkUpdateRequest < ApplicationRecord
before_validation :initialize_attributes, :on => :create
before_validation :normalize_text
after_create :create_forum_topic
+ after_save :update_notice
scope :pending_first, -> { order(Arel.sql("(case status when 'pending' then 0 when 'approved' then 1 else 2 end)")) }
scope :pending, -> {where(status: "pending")}
@@ -241,4 +242,11 @@ class BulkUpdateRequest < ApplicationRecord
def estimate_update_count
AliasAndImplicationImporter.new(script, nil).estimate_update_count
end
+
+ def update_notice
+ TagChangeNoticeService.update_cache(
+ AliasAndImplicationImporter.new(script, nil).affected_tags,
+ forum_topic_id
+ )
+ end
end
diff --git a/app/models/tag_relationship.rb b/app/models/tag_relationship.rb
index 0a0d1dcb5..537df4504 100644
--- a/app/models/tag_relationship.rb
+++ b/app/models/tag_relationship.rb
@@ -32,6 +32,7 @@ class TagRelationship < ApplicationRecord
validates :approver, presence: { message: "must exist" }, if: -> { approver_id.present? }
validates :forum_topic, presence: { message: "must exist" }, if: -> { forum_topic_id.present? }
validate :antecedent_and_consequent_are_different
+ after_save :update_notice
def initialize_creator
self.creator_id = CurrentUser.user.id
@@ -204,6 +205,13 @@ class TagRelationship < ApplicationRecord
Post.fast_count(antecedent_name, skip_cache: true)
end
+ def update_notice
+ TagChangeNoticeService.update_cache(
+ [antecedent_name, consequent_name],
+ forum_topic_id
+ )
+ end
+
extend SearchMethods
include MessageMethods
end
diff --git a/app/views/posts/partials/index/_posts.html.erb b/app/views/posts/partials/index/_posts.html.erb
index 53a33e3f9..f45c00a25 100644
--- a/app/views/posts/partials/index/_posts.html.erb
+++ b/app/views/posts/partials/index/_posts.html.erb
@@ -19,6 +19,12 @@
<% end %>
+ <% if show_tag_change_notice? %>
+
+
This tag is the subject of an ongoing discussion. If you have any relevant information, please join the <%= link_to "discussion", forum_topic_path(TagChangeNoticeService.get_forum_topic_id(params[:tags]) || 1) %>.
+
+ <% end %>
+
<% unless post_set.is_random? %>
<%= numbered_paginator(post_set.posts) %>
<% end %>
diff --git a/config/docker/compose.yml b/config/docker/compose.yml
index 1ca8228fa..7c9a36414 100644
--- a/config/docker/compose.yml
+++ b/config/docker/compose.yml
@@ -6,6 +6,10 @@ services:
- "5432:5432"
environment:
- POSTGRES_PASSWORD
+ redis:
+ image: redis:latest
+ ports:
+ - "6379:6379"
memcached:
image: memcached:alpine
ports:
@@ -63,3 +67,4 @@ services:
- db
- memcached
- archives
+ - redis
\ No newline at end of file
diff --git a/test/unit/alias_and_implication_importer_test.rb b/test/unit/alias_and_implication_importer_test.rb
index 5690e11db..326b580f5 100644
--- a/test/unit/alias_and_implication_importer_test.rb
+++ b/test/unit/alias_and_implication_importer_test.rb
@@ -26,6 +26,28 @@ class AliasAndImplicationImporterTest < ActiveSupport::TestCase
end
end
+ context "#affected_tags" do
+ setup do
+ FactoryBot.create(:post, tag_string: "aaa")
+ FactoryBot.create(:post, tag_string: "bbb")
+ FactoryBot.create(:post, tag_string: "ccc")
+ FactoryBot.create(:post, tag_string: "ddd")
+ FactoryBot.create(:post, tag_string: "eee")
+
+ @script = "create alias aaa -> 000\n" +
+ "create implication bbb -> 111\n" +
+ "remove alias ccc -> 222\n" +
+ "remove implication ddd -> 333\n" +
+ "mass update eee -> 444\n"
+ end
+
+ subject { AliasAndImplicationImporter.new(@script, nil) }
+
+ should "return the correct tags" do
+ assert_equal(%w(aaa 000 bbb 111 ccc 222 ddd 333 eee 444), subject.affected_tags)
+ end
+ end
+
context "#estimate_update_count" do
setup do
FactoryBot.create(:post, tag_string: "aaa")
diff --git a/test/unit/bulk_update_request_test.rb b/test/unit/bulk_update_request_test.rb
index 83c226465..aff2ca660 100644
--- a/test/unit/bulk_update_request_test.rb
+++ b/test/unit/bulk_update_request_test.rb
@@ -35,6 +35,33 @@ class BulkUpdateRequestTest < ActiveSupport::TestCase
end
end
+ context "#update_notice" do
+ setup do
+ @mock_redis = MockRedis.new
+ @forum_topic = FactoryBot.create(:forum_topic)
+ TagChangeNoticeService.stubs(:redis_client).returns(@mock_redis)
+ end
+
+ should "update redis" do
+ @script = "create alias aaa -> 000\n" +
+ "create implication bbb -> 111\n" +
+ "remove alias ccc -> 222\n" +
+ "remove implication ddd -> 333\n" +
+ "mass update eee -> 444\n"
+ FactoryBot.create(:bulk_update_request, script: @script, forum_topic: @forum_topic)
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:aaa"))
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:000"))
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:bbb"))
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:111"))
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:ccc"))
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:222"))
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:ddd"))
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:333"))
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:eee"))
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:444"))
+ end
+ end
+
context "on approval" do
setup do
@script = %q(
diff --git a/test/unit/tag_alias_test.rb b/test/unit/tag_alias_test.rb
index 2df827697..97046dc77 100644
--- a/test/unit/tag_alias_test.rb
+++ b/test/unit/tag_alias_test.rb
@@ -69,6 +69,19 @@ class TagAliasTest < ActiveSupport::TestCase
end
end
+ context "#update_notice" do
+ setup do
+ @mock_redis = MockRedis.new
+ @forum_topic = FactoryBot.create(:forum_topic)
+ TagChangeNoticeService.stubs(:redis_client).returns(@mock_redis)
+ end
+
+ should "update redis" do
+ FactoryBot.create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", skip_secondary_validations: true, forum_topic: @forum_topic)
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:aaa"))
+ end
+ end
+
context "on secondary validation" do
should "warn about missing wiki pages" do
ti = FactoryBot.build(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", skip_secondary_validations: false)
diff --git a/test/unit/tag_implication_test.rb b/test/unit/tag_implication_test.rb
index 76e474852..261abc0e3 100644
--- a/test/unit/tag_implication_test.rb
+++ b/test/unit/tag_implication_test.rb
@@ -65,6 +65,19 @@ class TagImplicationTest < ActiveSupport::TestCase
end
end
+ context "#update_notice" do
+ setup do
+ @mock_redis = MockRedis.new
+ @forum_topic = FactoryBot.create(:forum_topic)
+ TagChangeNoticeService.stubs(:redis_client).returns(@mock_redis)
+ end
+
+ should "update redis" do
+ FactoryBot.create(:tag_implication, antecedent_name: "aaa", consequent_name: "bbb", skip_secondary_validations: true, forum_topic: @forum_topic)
+ assert_equal(@forum_topic.id.to_s, @mock_redis.get("tcn:aaa"))
+ end
+ end
+
context "on secondary validation" do
should "warn if either tag is missing a wiki" do
ti = FactoryBot.build(:tag_implication, antecedent_name: "aaa", consequent_name: "bbb", skip_secondary_validations: false)