aliases/implications: change automatic retirement rules.

Change the rules for automatically retiring aliases and implications:

* Retire aliases to tags that are empty, or that are for a general or
  artist tag that hasn't received any new posts in the last two years.
* Retire implications from tags that are empty.
* Don't retire aliases or implications for character, copyright, or
  meta tags any more, unless the tags are empty.
This commit is contained in:
evazion
2021-11-05 05:46:50 -05:00
parent 65ab7f1eb5
commit a5f589f9e0
6 changed files with 136 additions and 92 deletions

View File

@@ -1,6 +1,9 @@
# Removes tag aliases and implications if they haven't had any new uploads in
# the last two years. Runs weekly. Posts a message to the forum when aliases or
# implications are retired.
# Removes inactive aliases and implications. 'Inactive' means aliases to empty
# tags, implications from empty tags, and gentag and artist aliases that
# haven't had any new posts in the last two years.
#
# Runs weekly. Posts a message to the forum when aliases or implications are
# retired.
#
# @see DanbooruMaintenance#weekly
module TagRelationshipRetirementService
@@ -8,20 +11,15 @@ module TagRelationshipRetirementService
THRESHOLD = 2.years
def forum_topic_title
"Retired tag aliases & implications"
end
def forum_topic_body
"This topic deals with tag relationships created two or more years ago that have not been used since. They will be retired. This topic will be updated as an automated system retires expired relationships."
end
FORUM_TOPIC_TITLE = "Retired tag aliases & implications"
FORUM_TOPIC_BODY = "This topic deals with tag relationships created two or more years ago that have not been used since. They will be retired. This topic will be updated as an automated system retires expired relationships."
def forum_topic
topic = ForumTopic.where(title: forum_topic_title).first
topic = ForumTopic.where(title: FORUM_TOPIC_TITLE).first
if topic.nil?
CurrentUser.scoped(User.system) do
topic = ForumTopic.create!(creator: User.system, title: forum_topic_title, category_id: 1)
ForumPost.create!(creator: User.system, body: forum_topic_body, topic: topic)
topic = ForumTopic.create!(creator: User.system, title: FORUM_TOPIC_TITLE, category_id: 1)
ForumPost.create!(creator: User.system, body: FORUM_TOPIC_BODY, topic: topic)
end
end
topic
@@ -30,26 +28,23 @@ module TagRelationshipRetirementService
def find_and_retire!
messages = []
[TagAlias, TagImplication].each do |model|
each_candidate(model) do |rel|
rel.update(status: "retired")
messages << rel.retirement_message
end
inactive_relationships.each do |rel|
rel.update!(status: "retired")
messages << "The #{rel.relationship} [[#{rel.antecedent_name}]] -> [[#{rel.consequent_name}]] has been retired."
end
updater = ForumUpdater.new(forum_topic)
updater.update(messages.sort.join("\n"))
end
def each_candidate(model)
model.active.where("created_at < ?", THRESHOLD.ago).find_each do |rel|
if is_unused?(rel.consequent_name)
yield(rel)
end
end
def inactive_relationships
(inactive_aliases + TagAlias.active.empty + TagImplication.active.empty).uniq
end
def is_unused?(name)
!Post.raw_tag_match(name).exists?(["created_at > ?", THRESHOLD.ago])
def inactive_aliases
aliases = TagAlias.general.or(TagAlias.artist).active.where("tag_aliases.created_at < ?", THRESHOLD.ago)
aliases.select do |tag_alias|
!tag_alias.consequent_tag.posts.exists?(["created_at > ?", THRESHOLD.ago])
end
end
end

View File

@@ -6,6 +6,8 @@ class TagAlias < TagRelationship
before_create :delete_conflicting_relationships
scope :empty, -> { joins(:consequent_tag).merge(Tag.empty) }
def self.to_aliased(names)
names = Array(names).map(&:to_s)
return [] if names.empty?

View File

@@ -15,6 +15,8 @@ class TagImplication < TagRelationship
validate :meets_tag_size_requirements, on: :request
validate :has_wiki_page, on: :request
scope :empty, -> { joins(:antecedent_tag).merge(Tag.empty) }
concerning :HierarchyMethods do
class_methods do
def ancestors_of(names)

View File

@@ -16,6 +16,12 @@ class TagRelationship < ApplicationRecord
scope :deleted, -> {where(status: "deleted")}
scope :retired, -> {where(status: "retired")}
# TagAlias.artist, TagAlias.general, TagAlias.character, TagAlias.copyright, TagAlias.meta
# TagImplication.artist, TagImplication.general, TagImplication.character, TagImplication.copyright, TagImplication.meta
TagCategory.categories.each do |category|
scope category, -> { joins(:consequent_tag).where(consequent_tag: { category: TagCategory.mapping[category] }) }
end
before_validation :normalize_names
validates :status, inclusion: { in: STATUSES }
validates :antecedent_name, presence: true
@@ -103,10 +109,6 @@ class TagRelationship < ApplicationRecord
# "TagAlias" -> "tag alias", "TagImplication" -> "tag implication"
self.class.name.underscore.tr("_", " ")
end
def retirement_message
"The #{relationship} [[#{antecedent_name}]] -> [[#{consequent_name}]] has been retired."
end
end
def antecedent_and_consequent_are_different