mirror of
https://github.com/discourse/discourse.git
synced 2024-12-30 15:43:42 +08:00
f7c57fbc19
We discussed the use of `unless` internally and decided to enforce available rules from rubocop to restrict its most problematic uses.
122 lines
2.8 KiB
Ruby
122 lines
2.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module DiscourseNarrativeBot
|
|
module Actions
|
|
TIMEOUT_DURATION = 900 # 15 mins
|
|
|
|
def discobot_user
|
|
@discobot ||= User.find(-2)
|
|
end
|
|
|
|
def discobot_username
|
|
self.discobot_user.username_lower
|
|
end
|
|
|
|
private
|
|
|
|
def reply_to(post, raw, opts = {}, post_alert_options = {})
|
|
defaut_post_alert_opts = { skip_send_email: true }.merge(post_alert_options)
|
|
|
|
if post
|
|
default_opts = {
|
|
raw: raw,
|
|
topic_id: post.topic_id,
|
|
reply_to_post_number: post.post_number,
|
|
post_alert_options: defaut_post_alert_opts,
|
|
skip_validations: true,
|
|
}
|
|
|
|
new_post = PostCreator.create!(self.discobot_user, default_opts.merge(opts))
|
|
reset_rate_limits(post) if new_post
|
|
new_post
|
|
else
|
|
PostCreator.create!(
|
|
self.discobot_user,
|
|
{ post_alert_options: defaut_post_alert_opts, raw: raw, skip_validations: true }.merge(
|
|
opts,
|
|
),
|
|
)
|
|
end
|
|
end
|
|
|
|
def reset_rate_limits(post)
|
|
user = post.user
|
|
|
|
duration =
|
|
if user && user.new_user?
|
|
SiteSetting.rate_limit_new_user_create_post
|
|
else
|
|
SiteSetting.rate_limit_create_post
|
|
end
|
|
|
|
return if duration <= 0
|
|
|
|
data = DiscourseNarrativeBot::Store.get(user.id.to_s)
|
|
return unless data
|
|
|
|
key =
|
|
"#{DiscourseNarrativeBot::PLUGIN_NAME}:reset-rate-limit:#{post.topic_id}:#{data["state"]}"
|
|
|
|
if !(count = Discourse.redis.get(key))
|
|
count = 0
|
|
Discourse.redis.setex(key, duration, count)
|
|
end
|
|
|
|
if count.to_i < 2
|
|
post.default_rate_limiter.rollback!
|
|
post.limit_posts_per_day&.rollback!
|
|
Discourse.redis.incr(key)
|
|
end
|
|
end
|
|
|
|
def fake_delay
|
|
sleep(rand(1.0..2.0)) if Rails.env.production?
|
|
end
|
|
|
|
def bot_mentioned?(post)
|
|
doc = Nokogiri::HTML5.fragment(post.cooked)
|
|
|
|
valid = false
|
|
|
|
doc
|
|
.css(".mention")
|
|
.each do |mention|
|
|
if User.normalize_username(mention.text) == "@#{self.discobot_username}"
|
|
valid = true
|
|
break
|
|
end
|
|
end
|
|
|
|
valid
|
|
end
|
|
|
|
def reply_to_bot_post?(post)
|
|
post&.reply_to_post && post.reply_to_post.user_id == -2
|
|
end
|
|
|
|
def pm_to_bot?(post)
|
|
topic = post.topic
|
|
return false if !topic
|
|
|
|
topic.pm_with_non_human_user? && topic.topic_allowed_users.where(user_id: -2).exists?
|
|
end
|
|
|
|
def cancel_timeout_job(user)
|
|
Jobs.cancel_scheduled_job(:narrative_timeout, user_id: user.id, klass: self.class.to_s)
|
|
end
|
|
|
|
def enqueue_timeout_job(user)
|
|
return if Rails.env.test?
|
|
|
|
cancel_timeout_job(user)
|
|
|
|
Jobs.enqueue_in(
|
|
TIMEOUT_DURATION,
|
|
:narrative_timeout,
|
|
user_id: user.id,
|
|
klass: self.class.to_s,
|
|
)
|
|
end
|
|
end
|
|
end
|