mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
DEV: Apply syntax_tree formatting to plugins/*
This commit is contained in:
@@ -4,33 +4,29 @@ module Jobs
|
||||
module DiscourseNarrativeBot
|
||||
class GrantBadges < ::Jobs::Onceoff
|
||||
def execute_onceoff(args)
|
||||
new_user_track_badge = Badge.find_by(
|
||||
name: ::DiscourseNarrativeBot::NewUserNarrative.badge_name
|
||||
)
|
||||
new_user_track_badge =
|
||||
Badge.find_by(name: ::DiscourseNarrativeBot::NewUserNarrative.badge_name)
|
||||
|
||||
advanced_user_track_badge = Badge.find_by(
|
||||
name: ::DiscourseNarrativeBot::AdvancedUserNarrative.badge_name
|
||||
)
|
||||
advanced_user_track_badge =
|
||||
Badge.find_by(name: ::DiscourseNarrativeBot::AdvancedUserNarrative.badge_name)
|
||||
|
||||
PluginStoreRow.where(
|
||||
plugin_name: ::DiscourseNarrativeBot::PLUGIN_NAME,
|
||||
type_name: 'JSON'
|
||||
).find_each do |row|
|
||||
PluginStoreRow
|
||||
.where(plugin_name: ::DiscourseNarrativeBot::PLUGIN_NAME, type_name: "JSON")
|
||||
.find_each do |row|
|
||||
value = JSON.parse(row.value)
|
||||
completed = value["completed"]
|
||||
user = User.find_by(id: row.key)
|
||||
|
||||
value = JSON.parse(row.value)
|
||||
completed = value["completed"]
|
||||
user = User.find_by(id: row.key)
|
||||
if user && completed
|
||||
if completed.include?(::DiscourseNarrativeBot::NewUserNarrative.to_s)
|
||||
BadgeGranter.grant(new_user_track_badge, user)
|
||||
end
|
||||
|
||||
if user && completed
|
||||
if completed.include?(::DiscourseNarrativeBot::NewUserNarrative.to_s)
|
||||
BadgeGranter.grant(new_user_track_badge, user)
|
||||
end
|
||||
|
||||
if completed.include?(::DiscourseNarrativeBot::AdvancedUserNarrative.to_s)
|
||||
BadgeGranter.grant(advanced_user_track_badge, user)
|
||||
if completed.include?(::DiscourseNarrativeBot::AdvancedUserNarrative.to_s)
|
||||
BadgeGranter.grant(advanced_user_track_badge, user)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,34 +4,40 @@ module Jobs
|
||||
module DiscourseNarrativeBot
|
||||
class RemapOldBotImages < ::Jobs::Onceoff
|
||||
def execute_onceoff(args)
|
||||
paths = [
|
||||
"/images/font-awesome-link.png",
|
||||
"/images/unicorn.png",
|
||||
"/images/font-awesome-ellipsis.png",
|
||||
"/images/font-awesome-bookmark.png",
|
||||
"/images/font-awesome-smile.png",
|
||||
"/images/font-awesome-flag.png",
|
||||
"/images/font-awesome-search.png",
|
||||
"/images/capybara-eating.gif",
|
||||
"/images/font-awesome-pencil.png",
|
||||
"/images/font-awesome-trash.png",
|
||||
"/images/font-awesome-rotate-left.png",
|
||||
"/images/font-awesome-gear.png",
|
||||
paths = %w[
|
||||
/images/font-awesome-link.png
|
||||
/images/unicorn.png
|
||||
/images/font-awesome-ellipsis.png
|
||||
/images/font-awesome-bookmark.png
|
||||
/images/font-awesome-smile.png
|
||||
/images/font-awesome-flag.png
|
||||
/images/font-awesome-search.png
|
||||
/images/capybara-eating.gif
|
||||
/images/font-awesome-pencil.png
|
||||
/images/font-awesome-trash.png
|
||||
/images/font-awesome-rotate-left.png
|
||||
/images/font-awesome-gear.png
|
||||
]
|
||||
|
||||
Post.raw_match("/images/").where(user_id: -2).find_each do |post|
|
||||
if (matches = post.raw.scan(/(?<!\/plugins\/discourse-narrative-bot)(#{paths.join("|")})/)).present?
|
||||
new_raw = post.raw
|
||||
Post
|
||||
.raw_match("/images/")
|
||||
.where(user_id: -2)
|
||||
.find_each do |post|
|
||||
if (
|
||||
matches =
|
||||
post.raw.scan(%r{(?<!/plugins/discourse-narrative-bot)(#{paths.join("|")})})
|
||||
).present?
|
||||
new_raw = post.raw
|
||||
|
||||
matches.each do |match|
|
||||
path = match.first
|
||||
new_raw = new_raw.gsub(path, "/plugins/discourse-narrative-bot#{path}")
|
||||
matches.each do |match|
|
||||
path = match.first
|
||||
new_raw = new_raw.gsub(path, "/plugins/discourse-narrative-bot#{path}")
|
||||
end
|
||||
|
||||
post.update_columns(raw: new_raw)
|
||||
post.rebake!
|
||||
end
|
||||
|
||||
post.update_columns(raw: new_raw)
|
||||
post.rebake!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
|
||||
module Jobs
|
||||
class BotInput < ::Jobs::Base
|
||||
|
||||
sidekiq_options queue: 'critical', retry: false
|
||||
sidekiq_options queue: "critical", retry: false
|
||||
|
||||
def execute(args)
|
||||
return unless user = User.find_by(id: args[:user_id])
|
||||
|
||||
I18n.with_locale(user.effective_locale) do
|
||||
::DiscourseNarrativeBot::TrackSelector.new(args[:input].to_sym, user,
|
||||
::DiscourseNarrativeBot::TrackSelector.new(
|
||||
args[:input].to_sym,
|
||||
user,
|
||||
post_id: args[:post_id],
|
||||
topic_id: args[:topic_id]
|
||||
topic_id: args[:topic_id],
|
||||
).select
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
|
||||
module Jobs
|
||||
class NarrativeInit < ::Jobs::Base
|
||||
sidekiq_options queue: 'critical'
|
||||
sidekiq_options queue: "critical"
|
||||
|
||||
def execute(args)
|
||||
if user = User.find_by(id: args[:user_id])
|
||||
I18n.with_locale(user.effective_locale) do
|
||||
args[:klass].constantize.new.input(:init, user)
|
||||
end
|
||||
I18n.with_locale(user.effective_locale) { args[:klass].constantize.new.input(:init, user) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,23 +4,24 @@ module Jobs
|
||||
class SendDefaultWelcomeMessage < ::Jobs::Base
|
||||
def execute(args)
|
||||
if user = User.find_by(id: args[:user_id])
|
||||
type = user.invited_by ? 'welcome_invite' : 'welcome_user'
|
||||
type = user.invited_by ? "welcome_invite" : "welcome_user"
|
||||
params = SystemMessage.new(user).defaults
|
||||
|
||||
title = I18n.t("system_messages.#{type}.subject_template", params)
|
||||
raw = I18n.t("system_messages.#{type}.text_body_template", params)
|
||||
discobot_user = ::DiscourseNarrativeBot::Base.new.discobot_user
|
||||
|
||||
post = PostCreator.create!(
|
||||
discobot_user,
|
||||
title: title,
|
||||
raw: raw,
|
||||
archetype: Archetype.private_message,
|
||||
target_usernames: user.username,
|
||||
skip_validations: true
|
||||
)
|
||||
post =
|
||||
PostCreator.create!(
|
||||
discobot_user,
|
||||
title: title,
|
||||
raw: raw,
|
||||
archetype: Archetype.private_message,
|
||||
target_usernames: user.username,
|
||||
skip_validations: true,
|
||||
)
|
||||
|
||||
post.topic.update_status('closed', true, discobot_user)
|
||||
post.topic.update_status("closed", true, discobot_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
discobot_username = 'discobot'
|
||||
discobot_username = "discobot"
|
||||
|
||||
def seed_primary_email
|
||||
UserEmail.seed do |ue|
|
||||
@@ -42,15 +42,13 @@ bot.create_user_option! if !bot.user_option
|
||||
|
||||
bot.user_option.update!(
|
||||
email_messages_level: UserOption.email_level_types[:never],
|
||||
email_level: UserOption.email_level_types[:never]
|
||||
email_level: UserOption.email_level_types[:never],
|
||||
)
|
||||
|
||||
bot.create_user_profile! if !bot.user_profile
|
||||
|
||||
if !bot.user_profile.bio_raw
|
||||
bot.user_profile.update!(
|
||||
bio_raw: I18n.t('discourse_narrative_bot.bio')
|
||||
)
|
||||
bot.user_profile.update!(bio_raw: I18n.t("discourse_narrative_bot.bio"))
|
||||
end
|
||||
|
||||
Group.user_trust_level_change!(DiscourseNarrativeBot::BOT_USER_ID, TrustLevel[4])
|
||||
|
||||
@@ -1,41 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Badge
|
||||
.where(name: 'Complete New User Track')
|
||||
.update_all(name: DiscourseNarrativeBot::NewUserNarrative::BADGE_NAME)
|
||||
Badge.where(name: "Complete New User Track").update_all(
|
||||
name: DiscourseNarrativeBot::NewUserNarrative::BADGE_NAME,
|
||||
)
|
||||
|
||||
Badge
|
||||
.where(name: 'Complete Discobot Advanced User Track')
|
||||
.update_all(name: DiscourseNarrativeBot::AdvancedUserNarrative::BADGE_NAME)
|
||||
Badge.where(name: "Complete Discobot Advanced User Track").update_all(
|
||||
name: DiscourseNarrativeBot::AdvancedUserNarrative::BADGE_NAME,
|
||||
)
|
||||
|
||||
new_user_narrative_badge = Badge.find_by(name: DiscourseNarrativeBot::NewUserNarrative::BADGE_NAME)
|
||||
|
||||
unless new_user_narrative_badge
|
||||
new_user_narrative_badge = Badge.create!(
|
||||
name: DiscourseNarrativeBot::NewUserNarrative::BADGE_NAME,
|
||||
badge_type_id: 3
|
||||
)
|
||||
new_user_narrative_badge =
|
||||
Badge.create!(name: DiscourseNarrativeBot::NewUserNarrative::BADGE_NAME, badge_type_id: 3)
|
||||
end
|
||||
|
||||
advanced_user_narrative_badge = Badge.find_by(name: DiscourseNarrativeBot::AdvancedUserNarrative::BADGE_NAME)
|
||||
advanced_user_narrative_badge =
|
||||
Badge.find_by(name: DiscourseNarrativeBot::AdvancedUserNarrative::BADGE_NAME)
|
||||
|
||||
unless advanced_user_narrative_badge
|
||||
advanced_user_narrative_badge = Badge.create!(
|
||||
name: DiscourseNarrativeBot::AdvancedUserNarrative::BADGE_NAME,
|
||||
badge_type_id: 2
|
||||
)
|
||||
advanced_user_narrative_badge =
|
||||
Badge.create!(name: DiscourseNarrativeBot::AdvancedUserNarrative::BADGE_NAME, badge_type_id: 2)
|
||||
end
|
||||
|
||||
badge_grouping = BadgeGrouping.find(1)
|
||||
|
||||
[
|
||||
[new_user_narrative_badge, I18n.t('badges.certified.description')],
|
||||
[advanced_user_narrative_badge, I18n.t('badges.licensed.description')]
|
||||
[new_user_narrative_badge, I18n.t("badges.certified.description")],
|
||||
[advanced_user_narrative_badge, I18n.t("badges.licensed.description")],
|
||||
].each do |badge, description|
|
||||
|
||||
badge.update!(
|
||||
badge_grouping: badge_grouping,
|
||||
description: description,
|
||||
system: true
|
||||
)
|
||||
badge.update!(badge_grouping: badge_grouping, description: description, system: true)
|
||||
end
|
||||
|
||||
@@ -23,18 +23,19 @@ module DiscourseNarrativeBot
|
||||
topic_id: post.topic_id,
|
||||
reply_to_post_number: post.post_number,
|
||||
post_alert_options: defaut_post_alert_opts,
|
||||
skip_validations: true
|
||||
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))
|
||||
PostCreator.create!(
|
||||
self.discobot_user,
|
||||
{ post_alert_options: defaut_post_alert_opts, raw: raw, skip_validations: true }.merge(
|
||||
opts,
|
||||
),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,7 +54,8 @@ module DiscourseNarrativeBot
|
||||
data = DiscourseNarrativeBot::Store.get(user.id.to_s)
|
||||
return unless data
|
||||
|
||||
key = "#{DiscourseNarrativeBot::PLUGIN_NAME}:reset-rate-limit:#{post.topic_id}:#{data['state']}"
|
||||
key =
|
||||
"#{DiscourseNarrativeBot::PLUGIN_NAME}:reset-rate-limit:#{post.topic_id}:#{data["state"]}"
|
||||
|
||||
if !(count = Discourse.redis.get(key))
|
||||
count = 0
|
||||
@@ -76,12 +78,14 @@ module DiscourseNarrativeBot
|
||||
|
||||
valid = false
|
||||
|
||||
doc.css(".mention").each do |mention|
|
||||
if User.normalize_username(mention.text) == "@#{self.discobot_username}"
|
||||
valid = true
|
||||
break
|
||||
doc
|
||||
.css(".mention")
|
||||
.each do |mention|
|
||||
if User.normalize_username(mention.text) == "@#{self.discobot_username}"
|
||||
valid = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
valid
|
||||
end
|
||||
@@ -94,8 +98,7 @@ module DiscourseNarrativeBot
|
||||
topic = post.topic
|
||||
return false if !topic
|
||||
|
||||
topic.pm_with_non_human_user? &&
|
||||
topic.topic_allowed_users.where(user_id: -2).exists?
|
||||
topic.pm_with_non_human_user? && topic.topic_allowed_users.where(user_id: -2).exists?
|
||||
end
|
||||
|
||||
def cancel_timeout_job(user)
|
||||
@@ -107,9 +110,11 @@ module DiscourseNarrativeBot
|
||||
|
||||
cancel_timeout_job(user)
|
||||
|
||||
Jobs.enqueue_in(TIMEOUT_DURATION, :narrative_timeout,
|
||||
Jobs.enqueue_in(
|
||||
TIMEOUT_DURATION,
|
||||
:narrative_timeout,
|
||||
user_id: user.id,
|
||||
klass: self.class.to_s
|
||||
klass: self.class.to_s,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,99 +3,101 @@
|
||||
module DiscourseNarrativeBot
|
||||
class AdvancedUserNarrative < Base
|
||||
I18N_KEY = "discourse_narrative_bot.advanced_user_narrative".freeze
|
||||
BADGE_NAME = 'Licensed'.freeze
|
||||
BADGE_NAME = "Licensed".freeze
|
||||
|
||||
TRANSITION_TABLE = {
|
||||
begin: {
|
||||
next_state: :tutorial_edit,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.edit.instructions", i18n_post_args) },
|
||||
init: {
|
||||
action: :start_advanced_track
|
||||
}
|
||||
action: :start_advanced_track,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_edit: {
|
||||
next_state: :tutorial_delete,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.delete.instructions", i18n_post_args) },
|
||||
edit: {
|
||||
action: :reply_to_edit
|
||||
action: :reply_to_edit,
|
||||
},
|
||||
reply: {
|
||||
next_state: :tutorial_edit,
|
||||
action: :missing_edit
|
||||
}
|
||||
action: :missing_edit,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_delete: {
|
||||
next_state: :tutorial_recover,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.recover.instructions", i18n_post_args) },
|
||||
delete: {
|
||||
action: :reply_to_delete
|
||||
action: :reply_to_delete,
|
||||
},
|
||||
reply: {
|
||||
next_state: :tutorial_delete,
|
||||
action: :missing_delete
|
||||
}
|
||||
action: :missing_delete,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_recover: {
|
||||
next_state: :tutorial_category_hashtag,
|
||||
next_instructions: Proc.new do
|
||||
category = Category.secured(Guardian.new(@user)).last
|
||||
slug = category.slug
|
||||
next_instructions:
|
||||
Proc.new do
|
||||
category = Category.secured(Guardian.new(@user)).last
|
||||
slug = category.slug
|
||||
|
||||
if parent_category = category.parent_category
|
||||
slug = "#{parent_category.slug}#{CategoryHashtag::SEPARATOR}#{slug}"
|
||||
end
|
||||
if parent_category = category.parent_category
|
||||
slug = "#{parent_category.slug}#{CategoryHashtag::SEPARATOR}#{slug}"
|
||||
end
|
||||
|
||||
I18n.t("#{I18N_KEY}.category_hashtag.instructions",
|
||||
i18n_post_args(category: "##{slug}")
|
||||
)
|
||||
end,
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.category_hashtag.instructions",
|
||||
i18n_post_args(category: "##{slug}"),
|
||||
)
|
||||
end,
|
||||
recover: {
|
||||
action: :reply_to_recover
|
||||
action: :reply_to_recover,
|
||||
},
|
||||
reply: {
|
||||
next_state: :tutorial_recover,
|
||||
action: :missing_recover
|
||||
}
|
||||
action: :missing_recover,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_category_hashtag: {
|
||||
next_state: :tutorial_change_topic_notification_level,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.change_topic_notification_level.instructions", i18n_post_args) },
|
||||
next_instructions:
|
||||
Proc.new do
|
||||
I18n.t("#{I18N_KEY}.change_topic_notification_level.instructions", i18n_post_args)
|
||||
end,
|
||||
reply: {
|
||||
action: :reply_to_category_hashtag
|
||||
}
|
||||
action: :reply_to_category_hashtag,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_change_topic_notification_level: {
|
||||
next_state: :tutorial_poll,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.poll.instructions", i18n_post_args) },
|
||||
topic_notification_level_changed: {
|
||||
action: :reply_to_topic_notification_level_changed
|
||||
action: :reply_to_topic_notification_level_changed,
|
||||
},
|
||||
reply: {
|
||||
next_state: :tutorial_change_topic_notification_level,
|
||||
action: :missing_topic_notification_level_change
|
||||
}
|
||||
action: :missing_topic_notification_level_change,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_poll: {
|
||||
prerequisite: Proc.new { SiteSetting.poll_enabled && @user.has_trust_level?(SiteSetting.poll_minimum_trust_level_to_create) },
|
||||
prerequisite:
|
||||
Proc.new do
|
||||
SiteSetting.poll_enabled &&
|
||||
@user.has_trust_level?(SiteSetting.poll_minimum_trust_level_to_create)
|
||||
end,
|
||||
next_state: :tutorial_details,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.details.instructions", i18n_post_args) },
|
||||
reply: {
|
||||
action: :reply_to_poll
|
||||
}
|
||||
action: :reply_to_poll,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_details: {
|
||||
next_state: :end,
|
||||
reply: {
|
||||
action: :reply_to_details
|
||||
}
|
||||
}
|
||||
action: :reply_to_details,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
def self.badge_name
|
||||
@@ -103,7 +105,7 @@ module DiscourseNarrativeBot
|
||||
end
|
||||
|
||||
def self.reset_trigger
|
||||
I18n.t('discourse_narrative_bot.advanced_user_narrative.reset_trigger')
|
||||
I18n.t("discourse_narrative_bot.advanced_user_narrative.reset_trigger")
|
||||
end
|
||||
|
||||
def reset_bot(user, post)
|
||||
@@ -123,13 +125,18 @@ module DiscourseNarrativeBot
|
||||
|
||||
fake_delay
|
||||
|
||||
post = PostCreator.create!(
|
||||
@user,
|
||||
raw: I18n.t("#{I18N_KEY}.edit.bot_created_post_raw", i18n_post_args(discobot_username: self.discobot_username)),
|
||||
topic_id: data[:topic_id],
|
||||
skip_bot: true,
|
||||
skip_validations: true
|
||||
)
|
||||
post =
|
||||
PostCreator.create!(
|
||||
@user,
|
||||
raw:
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.edit.bot_created_post_raw",
|
||||
i18n_post_args(discobot_username: self.discobot_username),
|
||||
),
|
||||
topic_id: data[:topic_id],
|
||||
skip_bot: true,
|
||||
skip_validations: true,
|
||||
)
|
||||
|
||||
set_state_data(:post_id, post.id)
|
||||
post
|
||||
@@ -138,13 +145,18 @@ module DiscourseNarrativeBot
|
||||
def init_tutorial_recover
|
||||
data = get_data(@user)
|
||||
|
||||
post = PostCreator.create!(
|
||||
@user,
|
||||
raw: I18n.t("#{I18N_KEY}.recover.deleted_post_raw", i18n_post_args(discobot_username: self.discobot_username)),
|
||||
topic_id: data[:topic_id],
|
||||
skip_bot: true,
|
||||
skip_validations: true
|
||||
)
|
||||
post =
|
||||
PostCreator.create!(
|
||||
@user,
|
||||
raw:
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.recover.deleted_post_raw",
|
||||
i18n_post_args(discobot_username: self.discobot_username),
|
||||
),
|
||||
topic_id: data[:topic_id],
|
||||
skip_bot: true,
|
||||
skip_validations: true,
|
||||
)
|
||||
|
||||
set_state_data(:post_id, post.id)
|
||||
|
||||
@@ -172,18 +184,15 @@ module DiscourseNarrativeBot
|
||||
opts = {
|
||||
title: I18n.t("#{I18N_KEY}.title"),
|
||||
target_usernames: @user.username,
|
||||
archetype: Archetype.private_message
|
||||
archetype: Archetype.private_message,
|
||||
}
|
||||
|
||||
if @post &&
|
||||
@post.topic.private_message? &&
|
||||
@post.topic.topic_allowed_users.pluck(:user_id).include?(@user.id)
|
||||
if @post && @post.topic.private_message? &&
|
||||
@post.topic.topic_allowed_users.pluck(:user_id).include?(@user.id)
|
||||
end
|
||||
|
||||
if @data[:topic_id]
|
||||
opts = opts
|
||||
.merge(topic_id: @data[:topic_id])
|
||||
.except(:title, :target_usernames, :archetype)
|
||||
opts = opts.merge(topic_id: @data[:topic_id]).except(:title, :target_usernames, :archetype)
|
||||
end
|
||||
post = reply_to(@post, raw, opts)
|
||||
|
||||
@@ -213,9 +222,10 @@ module DiscourseNarrativeBot
|
||||
fake_delay
|
||||
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.edit.not_found",
|
||||
i18n_post_args(url: Post.find_by(id: post_id).url)
|
||||
))
|
||||
reply_to(
|
||||
@post,
|
||||
I18n.t("#{I18N_KEY}.edit.not_found", i18n_post_args(url: Post.find_by(id: post_id).url)),
|
||||
)
|
||||
end
|
||||
|
||||
enqueue_timeout_job(@user)
|
||||
@@ -233,16 +243,15 @@ module DiscourseNarrativeBot
|
||||
#{instance_eval(&@next_instructions)}
|
||||
MD
|
||||
|
||||
PostCreator.create!(self.discobot_user,
|
||||
raw: raw,
|
||||
topic_id: @topic_id
|
||||
)
|
||||
PostCreator.create!(self.discobot_user, raw: raw, topic_id: @topic_id)
|
||||
end
|
||||
|
||||
def missing_delete
|
||||
return unless valid_topic?(@post.topic_id)
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.delete.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.delete.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -258,18 +267,19 @@ module DiscourseNarrativeBot
|
||||
#{instance_eval(&@next_instructions)}
|
||||
MD
|
||||
|
||||
PostCreator.create!(self.discobot_user,
|
||||
raw: raw,
|
||||
topic_id: @post.topic_id
|
||||
)
|
||||
PostCreator.create!(self.discobot_user, raw: raw, topic_id: @post.topic_id)
|
||||
end
|
||||
|
||||
def missing_recover
|
||||
return unless valid_topic?(@post.topic_id) &&
|
||||
post_id = get_state_data(:post_id) && @post.id != post_id
|
||||
unless valid_topic?(@post.topic_id) &&
|
||||
post_id = get_state_data(:post_id) && @post.id != post_id
|
||||
return
|
||||
end
|
||||
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.recover.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.recover.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -278,7 +288,7 @@ module DiscourseNarrativeBot
|
||||
topic_id = @post.topic_id
|
||||
return unless valid_topic?(topic_id)
|
||||
|
||||
if Nokogiri::HTML5.fragment(@post.cooked).css('.hashtag').size > 0
|
||||
if Nokogiri::HTML5.fragment(@post.cooked).css(".hashtag").size > 0
|
||||
raw = <<~MD
|
||||
#{I18n.t("#{I18N_KEY}.category_hashtag.reply", i18n_post_args)}
|
||||
|
||||
@@ -289,7 +299,9 @@ module DiscourseNarrativeBot
|
||||
reply_to(@post, raw)
|
||||
else
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.category_hashtag.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.category_hashtag.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -299,7 +311,12 @@ module DiscourseNarrativeBot
|
||||
return unless valid_topic?(@post.topic_id)
|
||||
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.change_topic_notification_level.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(
|
||||
@post,
|
||||
I18n.t("#{I18N_KEY}.change_topic_notification_level.not_found", i18n_post_args),
|
||||
)
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -316,10 +333,7 @@ module DiscourseNarrativeBot
|
||||
|
||||
fake_delay
|
||||
|
||||
post = PostCreator.create!(self.discobot_user,
|
||||
raw: raw,
|
||||
topic_id: @topic_id
|
||||
)
|
||||
post = PostCreator.create!(self.discobot_user, raw: raw, topic_id: @topic_id)
|
||||
|
||||
enqueue_timeout_job(@user)
|
||||
post
|
||||
@@ -340,7 +354,9 @@ module DiscourseNarrativeBot
|
||||
reply_to(@post, raw)
|
||||
else
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.poll.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.poll.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -355,7 +371,9 @@ module DiscourseNarrativeBot
|
||||
if Nokogiri::HTML5.fragment(@post.cooked).css("details").size > 0
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.details.reply", i18n_post_args))
|
||||
else
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.details.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.details.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -370,7 +388,9 @@ module DiscourseNarrativeBot
|
||||
if @post.wiki
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.wiki.reply", i18n_post_args))
|
||||
else
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.wiki.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.wiki.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -379,9 +399,10 @@ module DiscourseNarrativeBot
|
||||
def end_reply
|
||||
fake_delay
|
||||
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.end.message",
|
||||
i18n_post_args(certificate: certificate('advanced'))
|
||||
))
|
||||
reply_to(
|
||||
@post,
|
||||
I18n.t("#{I18N_KEY}.end.message", i18n_post_args(certificate: certificate("advanced"))),
|
||||
)
|
||||
end
|
||||
|
||||
def synchronize(user)
|
||||
|
||||
@@ -4,7 +4,8 @@ module DiscourseNarrativeBot
|
||||
class Base
|
||||
include Actions
|
||||
|
||||
class InvalidTransitionError < StandardError; end
|
||||
class InvalidTransitionError < StandardError
|
||||
end
|
||||
|
||||
def input(input, user, post: nil, topic_id: nil, skip: false)
|
||||
new_post = nil
|
||||
@@ -30,16 +31,18 @@ module DiscourseNarrativeBot
|
||||
next_opts = self.class::TRANSITION_TABLE.fetch(next_state)
|
||||
prerequisite = next_opts[:prerequisite]
|
||||
|
||||
if (!prerequisite || instance_eval(&prerequisite)) && !(
|
||||
SiteSetting.discourse_narrative_bot_skip_tutorials.present? &&
|
||||
SiteSetting.discourse_narrative_bot_skip_tutorials.split("|").include?(next_state.to_s))
|
||||
|
||||
if (!prerequisite || instance_eval(&prerequisite)) &&
|
||||
!(
|
||||
SiteSetting.discourse_narrative_bot_skip_tutorials.present? &&
|
||||
SiteSetting
|
||||
.discourse_narrative_bot_skip_tutorials
|
||||
.split("|")
|
||||
.include?(next_state.to_s)
|
||||
)
|
||||
break
|
||||
end
|
||||
|
||||
[:next_state, :next_instructions].each do |key|
|
||||
opts[key] = next_opts[key]
|
||||
end
|
||||
%i[next_state next_instructions].each { |key| opts[key] = next_opts[key] }
|
||||
end
|
||||
rescue InvalidTransitionError
|
||||
# For given input, no transition for current state
|
||||
@@ -78,16 +81,9 @@ module DiscourseNarrativeBot
|
||||
end_reply
|
||||
cancel_timeout_job(user)
|
||||
|
||||
BadgeGranter.grant(
|
||||
Badge.find_by(name: self.class.badge_name),
|
||||
user
|
||||
)
|
||||
BadgeGranter.grant(Badge.find_by(name: self.class.badge_name), user)
|
||||
|
||||
set_data(@user,
|
||||
topic_id: new_post.topic_id,
|
||||
state: :end,
|
||||
track: self.class.to_s
|
||||
)
|
||||
set_data(@user, topic_id: new_post.topic_id, state: :end, track: self.class.to_s)
|
||||
end
|
||||
end
|
||||
rescue => e
|
||||
@@ -116,25 +112,29 @@ module DiscourseNarrativeBot
|
||||
@data = get_data(user) || {}
|
||||
|
||||
if post = Post.find_by(id: @data[:last_post_id])
|
||||
reply_to(post, I18n.t("discourse_narrative_bot.timeout.message",
|
||||
i18n_post_args(
|
||||
username: user.username,
|
||||
skip_trigger: TrackSelector.skip_trigger,
|
||||
reset_trigger: "#{TrackSelector.reset_trigger} #{self.class.reset_trigger}"
|
||||
)
|
||||
), {}, skip_send_email: false)
|
||||
reply_to(
|
||||
post,
|
||||
I18n.t(
|
||||
"discourse_narrative_bot.timeout.message",
|
||||
i18n_post_args(
|
||||
username: user.username,
|
||||
skip_trigger: TrackSelector.skip_trigger,
|
||||
reset_trigger: "#{TrackSelector.reset_trigger} #{self.class.reset_trigger}",
|
||||
),
|
||||
),
|
||||
{},
|
||||
skip_send_email: false,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def certificate(type = nil)
|
||||
options = {
|
||||
user_id: @user.id,
|
||||
date: Time.zone.now.strftime('%b %d %Y'),
|
||||
format: :svg
|
||||
}
|
||||
options = { user_id: @user.id, date: Time.zone.now.strftime("%b %d %Y"), format: :svg }
|
||||
options.merge!(type: type) if type
|
||||
|
||||
src = Discourse.base_url + DiscourseNarrativeBot::Engine.routes.url_helpers.certificate_path(options)
|
||||
src =
|
||||
Discourse.base_url +
|
||||
DiscourseNarrativeBot::Engine.routes.url_helpers.certificate_path(options)
|
||||
alt = CGI.escapeHTML(I18n.t("#{self.class::I18N_KEY}.certificate.alt"))
|
||||
|
||||
"<iframe class='discobot-certificate' src='#{src}' width='650' height='464' alt='#{alt}'></iframe>"
|
||||
@@ -192,7 +192,7 @@ module DiscourseNarrativeBot
|
||||
end
|
||||
|
||||
def not_implemented
|
||||
raise 'Not implemented.'
|
||||
raise "Not implemented."
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -10,7 +10,7 @@ module DiscourseNarrativeBot
|
||||
begin
|
||||
Date.parse(date)
|
||||
rescue ArgumentError => e
|
||||
if e.message == 'invalid date'
|
||||
if e.message == "invalid date"
|
||||
Date.parse(Date.today.to_s)
|
||||
else
|
||||
raise e
|
||||
@@ -25,14 +25,20 @@ module DiscourseNarrativeBot
|
||||
svg_default_width = 538.583
|
||||
logo_container = logo_group(55, svg_default_width, 280)
|
||||
|
||||
ApplicationController.render(inline: read_template('new_user'), assigns: assign_options(svg_default_width, logo_container))
|
||||
ApplicationController.render(
|
||||
inline: read_template("new_user"),
|
||||
assigns: assign_options(svg_default_width, logo_container),
|
||||
)
|
||||
end
|
||||
|
||||
def advanced_user_track
|
||||
svg_default_width = 722.8
|
||||
logo_container = logo_group(40, svg_default_width, 350)
|
||||
|
||||
ApplicationController.render(inline: read_template('advanced_user'), assigns: assign_options(svg_default_width, logo_container))
|
||||
ApplicationController.render(
|
||||
inline: read_template("advanced_user"),
|
||||
assigns: assign_options(svg_default_width, logo_container),
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
@@ -48,7 +54,7 @@ module DiscourseNarrativeBot
|
||||
date: @date,
|
||||
avatar_url: @avatar_url,
|
||||
logo_group: logo_group,
|
||||
name: name
|
||||
name: name,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -7,25 +7,26 @@ module DiscourseNarrativeBot
|
||||
|
||||
def self.roll(num_of_dice, range_of_dice)
|
||||
if num_of_dice == 0 || range_of_dice == 0
|
||||
return I18n.t('discourse_narrative_bot.dice.invalid')
|
||||
return I18n.t("discourse_narrative_bot.dice.invalid")
|
||||
end
|
||||
|
||||
output = +''
|
||||
output = +""
|
||||
|
||||
if num_of_dice > MAXIMUM_NUM_OF_DICE
|
||||
output << I18n.t('discourse_narrative_bot.dice.not_enough_dice', count: MAXIMUM_NUM_OF_DICE)
|
||||
output << I18n.t("discourse_narrative_bot.dice.not_enough_dice", count: MAXIMUM_NUM_OF_DICE)
|
||||
output << "\n\n"
|
||||
num_of_dice = MAXIMUM_NUM_OF_DICE
|
||||
end
|
||||
|
||||
if range_of_dice > MAXIMUM_RANGE_OF_DICE
|
||||
output << I18n.t('discourse_narrative_bot.dice.out_of_range')
|
||||
output << I18n.t("discourse_narrative_bot.dice.out_of_range")
|
||||
output << "\n\n"
|
||||
range_of_dice = MAXIMUM_RANGE_OF_DICE
|
||||
end
|
||||
|
||||
output << I18n.t('discourse_narrative_bot.dice.results',
|
||||
results: num_of_dice.times.map { rand(1..range_of_dice) }.join(", ")
|
||||
output << I18n.t(
|
||||
"discourse_narrative_bot.dice.results",
|
||||
results: num_of_dice.times.map { rand(1..range_of_dice) }.join(", "),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
module DiscourseNarrativeBot
|
||||
class Magic8Ball
|
||||
def self.generate_answer
|
||||
I18n.t("discourse_narrative_bot.magic_8_ball.result", result: I18n.t(
|
||||
"discourse_narrative_bot.magic_8_ball.answers.#{rand(1..20)}"
|
||||
))
|
||||
I18n.t(
|
||||
"discourse_narrative_bot.magic_8_ball.result",
|
||||
result: I18n.t("discourse_narrative_bot.magic_8_ball.answers.#{rand(1..20)}"),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,136 +1,136 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'distributed_mutex'
|
||||
require "distributed_mutex"
|
||||
|
||||
module DiscourseNarrativeBot
|
||||
class NewUserNarrative < Base
|
||||
I18N_KEY = "discourse_narrative_bot.new_user_narrative".freeze
|
||||
BADGE_NAME = 'Certified'.freeze
|
||||
BADGE_NAME = "Certified".freeze
|
||||
|
||||
TRANSITION_TABLE = {
|
||||
begin: {
|
||||
init: {
|
||||
next_state: :tutorial_bookmark,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.bookmark.instructions", base_uri: Discourse.base_path) },
|
||||
action: :say_hello
|
||||
}
|
||||
next_instructions:
|
||||
Proc.new { I18n.t("#{I18N_KEY}.bookmark.instructions", base_uri: Discourse.base_path) },
|
||||
action: :say_hello,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_bookmark: {
|
||||
next_state: :tutorial_onebox,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.onebox.instructions", base_uri: Discourse.base_path) },
|
||||
|
||||
next_instructions:
|
||||
Proc.new { I18n.t("#{I18N_KEY}.onebox.instructions", base_uri: Discourse.base_path) },
|
||||
bookmark: {
|
||||
action: :reply_to_bookmark
|
||||
action: :reply_to_bookmark,
|
||||
},
|
||||
|
||||
reply: {
|
||||
next_state: :tutorial_bookmark,
|
||||
action: :missing_bookmark
|
||||
}
|
||||
action: :missing_bookmark,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_onebox: {
|
||||
next_state: :tutorial_emoji,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.emoji.instructions", base_uri: Discourse.base_path) },
|
||||
|
||||
next_instructions:
|
||||
Proc.new { I18n.t("#{I18N_KEY}.emoji.instructions", base_uri: Discourse.base_path) },
|
||||
reply: {
|
||||
action: :reply_to_onebox
|
||||
}
|
||||
action: :reply_to_onebox,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_emoji: {
|
||||
prerequisite: Proc.new { SiteSetting.enable_emoji },
|
||||
next_state: :tutorial_mention,
|
||||
next_instructions: Proc.new {
|
||||
I18n.t("#{I18N_KEY}.mention.instructions",
|
||||
discobot_username: self.discobot_username,
|
||||
base_uri: Discourse.base_path)
|
||||
},
|
||||
next_instructions:
|
||||
Proc.new do
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.mention.instructions",
|
||||
discobot_username: self.discobot_username,
|
||||
base_uri: Discourse.base_path,
|
||||
)
|
||||
end,
|
||||
reply: {
|
||||
action: :reply_to_emoji
|
||||
}
|
||||
action: :reply_to_emoji,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_mention: {
|
||||
prerequisite: Proc.new { SiteSetting.enable_mentions },
|
||||
next_state: :tutorial_formatting,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.formatting.instructions", base_uri: Discourse.base_path) },
|
||||
|
||||
next_instructions:
|
||||
Proc.new { I18n.t("#{I18N_KEY}.formatting.instructions", base_uri: Discourse.base_path) },
|
||||
reply: {
|
||||
action: :reply_to_mention
|
||||
}
|
||||
action: :reply_to_mention,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_formatting: {
|
||||
next_state: :tutorial_quote,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.quoting.instructions", base_uri: Discourse.base_path) },
|
||||
|
||||
next_instructions:
|
||||
Proc.new { I18n.t("#{I18N_KEY}.quoting.instructions", base_uri: Discourse.base_path) },
|
||||
reply: {
|
||||
action: :reply_to_formatting
|
||||
}
|
||||
action: :reply_to_formatting,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_quote: {
|
||||
next_state: :tutorial_images,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.images.instructions", base_uri: Discourse.base_path) },
|
||||
|
||||
next_instructions:
|
||||
Proc.new { I18n.t("#{I18N_KEY}.images.instructions", base_uri: Discourse.base_path) },
|
||||
reply: {
|
||||
action: :reply_to_quote
|
||||
}
|
||||
action: :reply_to_quote,
|
||||
},
|
||||
},
|
||||
|
||||
# Note: tutorial_images and tutorial_likes are mutually exclusive.
|
||||
# The prerequisites should ensure only one of them is called.
|
||||
tutorial_images: {
|
||||
prerequisite: Proc.new { @user.has_trust_level?(SiteSetting.min_trust_to_post_embedded_media) },
|
||||
prerequisite:
|
||||
Proc.new { @user.has_trust_level?(SiteSetting.min_trust_to_post_embedded_media) },
|
||||
next_state: :tutorial_likes,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.likes.instructions", base_uri: Discourse.base_path) },
|
||||
next_instructions:
|
||||
Proc.new { I18n.t("#{I18N_KEY}.likes.instructions", base_uri: Discourse.base_path) },
|
||||
reply: {
|
||||
action: :reply_to_image
|
||||
action: :reply_to_image,
|
||||
},
|
||||
like: {
|
||||
action: :track_images_like
|
||||
}
|
||||
action: :track_images_like,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_likes: {
|
||||
prerequisite: Proc.new { !@user.has_trust_level?(SiteSetting.min_trust_to_post_embedded_media) },
|
||||
prerequisite:
|
||||
Proc.new { !@user.has_trust_level?(SiteSetting.min_trust_to_post_embedded_media) },
|
||||
next_state: :tutorial_flag,
|
||||
next_instructions: Proc.new {
|
||||
I18n.t("#{I18N_KEY}.flag.instructions",
|
||||
guidelines_url: url_helpers(:guidelines_url),
|
||||
about_url: url_helpers(:about_index_url),
|
||||
base_uri: Discourse.base_path)
|
||||
},
|
||||
next_instructions:
|
||||
Proc.new do
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.flag.instructions",
|
||||
guidelines_url: url_helpers(:guidelines_url),
|
||||
about_url: url_helpers(:about_index_url),
|
||||
base_uri: Discourse.base_path,
|
||||
)
|
||||
end,
|
||||
like: {
|
||||
action: :reply_to_likes
|
||||
action: :reply_to_likes,
|
||||
},
|
||||
reply: {
|
||||
next_state: :tutorial_likes,
|
||||
action: :missing_likes_like
|
||||
}
|
||||
action: :missing_likes_like,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_flag: {
|
||||
prerequisite: Proc.new { SiteSetting.allow_flagging_staff },
|
||||
next_state: :tutorial_search,
|
||||
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.search.instructions", base_uri: Discourse.base_path) },
|
||||
next_instructions:
|
||||
Proc.new { I18n.t("#{I18N_KEY}.search.instructions", base_uri: Discourse.base_path) },
|
||||
flag: {
|
||||
action: :reply_to_flag
|
||||
action: :reply_to_flag,
|
||||
},
|
||||
reply: {
|
||||
next_state: :tutorial_flag,
|
||||
action: :missing_flag
|
||||
}
|
||||
action: :missing_flag,
|
||||
},
|
||||
},
|
||||
|
||||
tutorial_search: {
|
||||
next_state: :end,
|
||||
reply: {
|
||||
action: :reply_to_search
|
||||
}
|
||||
}
|
||||
action: :reply_to_search,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
def self.badge_name
|
||||
@@ -138,7 +138,7 @@ module DiscourseNarrativeBot
|
||||
end
|
||||
|
||||
def self.search_answer
|
||||
':herb:'
|
||||
":herb:"
|
||||
end
|
||||
|
||||
def self.search_answer_emoji
|
||||
@@ -146,7 +146,7 @@ module DiscourseNarrativeBot
|
||||
end
|
||||
|
||||
def self.reset_trigger
|
||||
I18n.t('discourse_narrative_bot.new_user_narrative.reset_trigger')
|
||||
I18n.t("discourse_narrative_bot.new_user_narrative.reset_trigger")
|
||||
end
|
||||
|
||||
def reset_bot(user, post)
|
||||
@@ -173,7 +173,7 @@ module DiscourseNarrativeBot
|
||||
topic = @post.topic
|
||||
post = topic.first_post
|
||||
|
||||
MessageBus.publish('/new_user_narrative/tutorial_search', {}, user_ids: [@user.id])
|
||||
MessageBus.publish("/new_user_narrative/tutorial_search", {}, user_ids: [@user.id])
|
||||
|
||||
raw = <<~MD
|
||||
#{post.raw}
|
||||
@@ -184,7 +184,8 @@ module DiscourseNarrativeBot
|
||||
PostRevisor.new(post, topic).revise!(
|
||||
self.discobot_user,
|
||||
{ raw: raw },
|
||||
skip_validations: true, force_new_version: true
|
||||
skip_validations: true,
|
||||
force_new_version: true,
|
||||
)
|
||||
|
||||
set_state_data(:post_version, post.reload.version || 0)
|
||||
@@ -198,13 +199,11 @@ module DiscourseNarrativeBot
|
||||
end
|
||||
|
||||
def say_hello
|
||||
raw = I18n.t(
|
||||
"#{I18N_KEY}.hello.message",
|
||||
i18n_post_args(
|
||||
username: @user.username,
|
||||
title: SiteSetting.title
|
||||
raw =
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.hello.message",
|
||||
i18n_post_args(username: @user.username, title: SiteSetting.title),
|
||||
)
|
||||
)
|
||||
|
||||
raw = <<~MD
|
||||
#{raw}
|
||||
@@ -213,9 +212,7 @@ module DiscourseNarrativeBot
|
||||
MD
|
||||
|
||||
title = I18n.t("#{I18N_KEY}.hello.title", title: SiteSetting.title)
|
||||
if SiteSetting.max_emojis_in_title == 0
|
||||
title = title.gsub(/:([\w\-+]+(?::t\d)?):/, '').strip
|
||||
end
|
||||
title = title.gsub(/:([\w\-+]+(?::t\d)?):/, "").strip if SiteSetting.max_emojis_in_title == 0
|
||||
|
||||
opts = {
|
||||
title: title,
|
||||
@@ -224,17 +221,13 @@ module DiscourseNarrativeBot
|
||||
subtype: TopicSubtype.system_message,
|
||||
}
|
||||
|
||||
if @post &&
|
||||
@post.topic.private_message? &&
|
||||
@post.topic.topic_allowed_users.pluck(:user_id).include?(@user.id)
|
||||
|
||||
if @post && @post.topic.private_message? &&
|
||||
@post.topic.topic_allowed_users.pluck(:user_id).include?(@user.id)
|
||||
opts = opts.merge(topic_id: @post.topic_id)
|
||||
end
|
||||
|
||||
if @data[:topic_id]
|
||||
opts = opts
|
||||
.merge(topic_id: @data[:topic_id])
|
||||
.except(:title, :target_usernames, :archetype)
|
||||
opts = opts.merge(topic_id: @data[:topic_id]).except(:title, :target_usernames, :archetype)
|
||||
end
|
||||
|
||||
post = reply_to(@post, raw, opts)
|
||||
@@ -249,7 +242,9 @@ module DiscourseNarrativeBot
|
||||
|
||||
fake_delay
|
||||
enqueue_timeout_job(@user)
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.bookmark.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.bookmark.not_found", i18n_post_args))
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
@@ -292,7 +287,9 @@ module DiscourseNarrativeBot
|
||||
reply
|
||||
else
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.onebox.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.onebox.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -302,11 +299,12 @@ module DiscourseNarrativeBot
|
||||
post_topic_id = @post.topic_id
|
||||
return unless valid_topic?(post_topic_id)
|
||||
|
||||
post_liked = PostAction.exists?(
|
||||
post_action_type_id: PostActionType.types[:like],
|
||||
post_id: @data[:last_post_id],
|
||||
user_id: @user.id
|
||||
)
|
||||
post_liked =
|
||||
PostAction.exists?(
|
||||
post_action_type_id: PostActionType.types[:like],
|
||||
post_id: @data[:last_post_id],
|
||||
user_id: @user.id,
|
||||
)
|
||||
|
||||
if post_liked
|
||||
set_state_data(:liked, true)
|
||||
@@ -358,18 +356,23 @@ module DiscourseNarrativeBot
|
||||
|
||||
like_post(@post)
|
||||
else
|
||||
raw = I18n.t(
|
||||
"#{I18N_KEY}.images.like_not_found",
|
||||
i18n_post_args(url: Post.find_by(id: @data[:last_post_id]).url)
|
||||
)
|
||||
raw =
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.images.like_not_found",
|
||||
i18n_post_args(url: Post.find_by(id: @data[:last_post_id]).url),
|
||||
)
|
||||
|
||||
transition = false
|
||||
end
|
||||
else
|
||||
raw = I18n.t(
|
||||
"#{I18N_KEY}.images.not_found",
|
||||
i18n_post_args(image_url: "#{Discourse.base_url}/plugins/discourse-narrative-bot/images/dog-walk.gif")
|
||||
)
|
||||
raw =
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.images.not_found",
|
||||
i18n_post_args(
|
||||
image_url:
|
||||
"#{Discourse.base_url}/plugins/discourse-narrative-bot/images/dog-walk.gif",
|
||||
),
|
||||
)
|
||||
|
||||
transition = false
|
||||
end
|
||||
@@ -398,11 +401,12 @@ module DiscourseNarrativeBot
|
||||
post_topic_id = @post.topic_id
|
||||
return unless valid_topic?(post_topic_id)
|
||||
|
||||
post_liked = PostAction.exists?(
|
||||
post_action_type_id: PostActionType.types[:like],
|
||||
post_id: @data[:last_post_id],
|
||||
user_id: @user.id
|
||||
)
|
||||
post_liked =
|
||||
PostAction.exists?(
|
||||
post_action_type_id: PostActionType.types[:like],
|
||||
post_id: @data[:last_post_id],
|
||||
user_id: @user.id,
|
||||
)
|
||||
|
||||
if post_liked
|
||||
raw = <<~MD
|
||||
@@ -425,7 +429,10 @@ module DiscourseNarrativeBot
|
||||
post_topic_id = @post.topic_id
|
||||
return unless valid_topic?(post_topic_id)
|
||||
|
||||
if Nokogiri::HTML5.fragment(@post.cooked).css("b", "strong", "em", "i", ".bbcode-i", ".bbcode-b").size > 0
|
||||
if Nokogiri::HTML5
|
||||
.fragment(@post.cooked)
|
||||
.css("b", "strong", "em", "i", ".bbcode-i", ".bbcode-b")
|
||||
.size > 0
|
||||
raw = <<~MD
|
||||
#{I18n.t("#{I18N_KEY}.formatting.reply", i18n_post_args)}
|
||||
|
||||
@@ -439,7 +446,9 @@ module DiscourseNarrativeBot
|
||||
reply
|
||||
else
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.formatting.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.formatting.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -465,7 +474,9 @@ module DiscourseNarrativeBot
|
||||
reply
|
||||
else
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.quoting.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.quoting.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -491,7 +502,9 @@ module DiscourseNarrativeBot
|
||||
reply
|
||||
else
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.emoji.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.emoji.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -517,13 +530,13 @@ module DiscourseNarrativeBot
|
||||
fake_delay
|
||||
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t(
|
||||
"#{I18N_KEY}.mention.not_found",
|
||||
i18n_post_args(
|
||||
username: @user.username,
|
||||
discobot_username: self.discobot_username
|
||||
)
|
||||
))
|
||||
reply_to(
|
||||
@post,
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.mention.not_found",
|
||||
i18n_post_args(username: @user.username, discobot_username: self.discobot_username),
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
enqueue_timeout_job(@user)
|
||||
@@ -536,9 +549,13 @@ module DiscourseNarrativeBot
|
||||
|
||||
# Remove any incorrect flags so that they can try again
|
||||
if @post.user_id == -2
|
||||
@post.post_actions
|
||||
@post
|
||||
.post_actions
|
||||
.where(user_id: @user.id)
|
||||
.where("post_action_type_id IN (?)", (PostActionType.flag_types.values - [PostActionType.types[:inappropriate]]))
|
||||
.where(
|
||||
"post_action_type_id IN (?)",
|
||||
(PostActionType.flag_types.values - [PostActionType.types[:inappropriate]]),
|
||||
)
|
||||
.destroy_all
|
||||
end
|
||||
|
||||
@@ -571,12 +588,18 @@ module DiscourseNarrativeBot
|
||||
post_topic_id = @post.topic_id
|
||||
return unless valid_topic?(post_topic_id)
|
||||
|
||||
if @post.raw.include?(NewUserNarrative.search_answer) || @post.raw.include?(NewUserNarrative.search_answer_emoji)
|
||||
if @post.raw.include?(NewUserNarrative.search_answer) ||
|
||||
@post.raw.include?(NewUserNarrative.search_answer_emoji)
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.search.reply", i18n_post_args(search_url: url_helpers(:search_url))))
|
||||
reply_to(
|
||||
@post,
|
||||
I18n.t("#{I18N_KEY}.search.reply", i18n_post_args(search_url: url_helpers(:search_url))),
|
||||
)
|
||||
else
|
||||
fake_delay
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.search.not_found", i18n_post_args)) unless @data[:attempted]
|
||||
unless @data[:attempted]
|
||||
reply_to(@post, I18n.t("#{I18N_KEY}.search.not_found", i18n_post_args))
|
||||
end
|
||||
enqueue_timeout_job(@user)
|
||||
false
|
||||
end
|
||||
@@ -587,16 +610,17 @@ module DiscourseNarrativeBot
|
||||
|
||||
reply_to(
|
||||
@post,
|
||||
I18n.t("#{I18N_KEY}.end.message",
|
||||
I18n.t(
|
||||
"#{I18N_KEY}.end.message",
|
||||
i18n_post_args(
|
||||
username: @user.username,
|
||||
base_url: Discourse.base_url,
|
||||
certificate: certificate,
|
||||
discobot_username: self.discobot_username,
|
||||
advanced_trigger: AdvancedUserNarrative.reset_trigger
|
||||
)
|
||||
advanced_trigger: AdvancedUserNarrative.reset_trigger,
|
||||
),
|
||||
),
|
||||
topic_id: @data[:topic_id]
|
||||
topic_id: @data[:topic_id],
|
||||
)
|
||||
end
|
||||
|
||||
@@ -605,15 +629,12 @@ module DiscourseNarrativeBot
|
||||
end
|
||||
|
||||
def welcome_topic
|
||||
Topic.find_by(slug: 'welcome-to-discourse', archetype: Archetype.default) ||
|
||||
Topic.find_by(slug: "welcome-to-discourse", archetype: Archetype.default) ||
|
||||
Topic.recent(1).first
|
||||
end
|
||||
|
||||
def url_helpers(url, opts = {})
|
||||
Rails.application.routes.url_helpers.public_send(
|
||||
url,
|
||||
opts.merge(host: Discourse.base_url)
|
||||
)
|
||||
Rails.application.routes.url_helpers.public_send(url, opts.merge(host: Discourse.base_url))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'excon'
|
||||
require "excon"
|
||||
|
||||
module DiscourseNarrativeBot
|
||||
class QuoteGenerator
|
||||
API_ENDPOINT = 'http://api.forismatic.com/api/1.0/'.freeze
|
||||
API_ENDPOINT = "http://api.forismatic.com/api/1.0/".freeze
|
||||
|
||||
def self.format_quote(quote, author)
|
||||
I18n.t('discourse_narrative_bot.quote.results', quote: quote, author: author)
|
||||
I18n.t("discourse_narrative_bot.quote.results", quote: quote, author: author)
|
||||
end
|
||||
|
||||
def self.generate(user)
|
||||
quote, author =
|
||||
if !user.effective_locale.start_with?('en')
|
||||
if !user.effective_locale.start_with?("en")
|
||||
translation_key = "discourse_narrative_bot.quote.#{rand(1..10)}"
|
||||
|
||||
[
|
||||
I18n.t("#{translation_key}.quote"),
|
||||
I18n.t("#{translation_key}.author")
|
||||
]
|
||||
[I18n.t("#{translation_key}.quote"), I18n.t("#{translation_key}.author")]
|
||||
else
|
||||
connection = Excon.new("#{API_ENDPOINT}?lang=en&format=json&method=getQuote")
|
||||
response = connection.request(expects: [200, 201], method: :Get)
|
||||
|
||||
@@ -4,18 +4,12 @@ module DiscourseNarrativeBot
|
||||
class TrackSelector
|
||||
include Actions
|
||||
|
||||
GENERIC_REPLIES_COUNT_PREFIX = 'discourse-narrative-bot:track-selector-count:'.freeze
|
||||
PUBLIC_DISPLAY_BOT_HELP_KEY = 'discourse-narrative-bot:track-selector:display-bot-help'.freeze
|
||||
GENERIC_REPLIES_COUNT_PREFIX = "discourse-narrative-bot:track-selector-count:".freeze
|
||||
PUBLIC_DISPLAY_BOT_HELP_KEY = "discourse-narrative-bot:track-selector:display-bot-help".freeze
|
||||
|
||||
TRACKS = [
|
||||
AdvancedUserNarrative,
|
||||
NewUserNarrative
|
||||
]
|
||||
TRACKS = [AdvancedUserNarrative, NewUserNarrative]
|
||||
|
||||
TOPIC_ACTIONS = [
|
||||
:delete,
|
||||
:topic_notification_level_changed
|
||||
].each(&:freeze)
|
||||
TOPIC_ACTIONS = %i[delete topic_notification_level_changed].each(&:freeze)
|
||||
|
||||
RESET_TRIGGER_EXACT_MATCH_LENGTH = 200
|
||||
|
||||
@@ -118,7 +112,7 @@ module DiscourseNarrativeBot
|
||||
trigger = "#{self.class.reset_trigger} #{klass.reset_trigger}"
|
||||
|
||||
if @post.raw.length < RESET_TRIGGER_EXACT_MATCH_LENGTH && @is_pm_to_bot
|
||||
@post.raw.match(Regexp.new("\\b\\W\?#{trigger}\\W\?\\b", 'i'))
|
||||
@post.raw.match(Regexp.new("\\b\\W\?#{trigger}\\W\?\\b", "i"))
|
||||
else
|
||||
match_trigger?(trigger)
|
||||
end
|
||||
@@ -127,7 +121,7 @@ module DiscourseNarrativeBot
|
||||
def bot_commands(hint = true)
|
||||
raw =
|
||||
if @user.manually_disabled_discobot?
|
||||
I18n.t(self.class.i18n_key('random_mention.discobot_disabled'))
|
||||
I18n.t(self.class.i18n_key("random_mention.discobot_disabled"))
|
||||
elsif match_data = match_trigger?("#{self.class.dice_trigger} (\\d+)d(\\d+)")
|
||||
DiscourseNarrativeBot::Dice.roll(match_data[1].to_i, match_data[2].to_i)
|
||||
elsif match_trigger?(self.class.quote_trigger)
|
||||
@@ -137,20 +131,23 @@ module DiscourseNarrativeBot
|
||||
elsif match_trigger?(self.class.help_trigger)
|
||||
help_message
|
||||
elsif hint
|
||||
message = I18n.t(self.class.i18n_key('random_mention.reply'),
|
||||
discobot_username: self.discobot_username,
|
||||
help_trigger: self.class.help_trigger
|
||||
)
|
||||
message =
|
||||
I18n.t(
|
||||
self.class.i18n_key("random_mention.reply"),
|
||||
discobot_username: self.discobot_username,
|
||||
help_trigger: self.class.help_trigger,
|
||||
)
|
||||
|
||||
if public_reply?
|
||||
key = "#{PUBLIC_DISPLAY_BOT_HELP_KEY}:#{@post.topic_id}"
|
||||
last_bot_help_post_number = Discourse.redis.get(key)
|
||||
|
||||
if !last_bot_help_post_number ||
|
||||
(last_bot_help_post_number &&
|
||||
@post.post_number - 10 > last_bot_help_post_number.to_i &&
|
||||
(1.day.to_i - Discourse.redis.ttl(key)) > 6.hours.to_i)
|
||||
|
||||
(
|
||||
last_bot_help_post_number &&
|
||||
@post.post_number - 10 > last_bot_help_post_number.to_i &&
|
||||
(1.day.to_i - Discourse.redis.ttl(key)) > 6.hours.to_i
|
||||
)
|
||||
Discourse.redis.setex(key, 1.day.to_i, @post.post_number)
|
||||
message
|
||||
end
|
||||
@@ -166,20 +163,24 @@ module DiscourseNarrativeBot
|
||||
end
|
||||
|
||||
def help_message
|
||||
message = I18n.t(
|
||||
self.class.i18n_key('random_mention.tracks'),
|
||||
discobot_username: self.discobot_username,
|
||||
reset_trigger: self.class.reset_trigger,
|
||||
tracks: [NewUserNarrative.reset_trigger, AdvancedUserNarrative.reset_trigger].join(', ')
|
||||
)
|
||||
message =
|
||||
I18n.t(
|
||||
self.class.i18n_key("random_mention.tracks"),
|
||||
discobot_username: self.discobot_username,
|
||||
reset_trigger: self.class.reset_trigger,
|
||||
tracks: [NewUserNarrative.reset_trigger, AdvancedUserNarrative.reset_trigger].join(", "),
|
||||
)
|
||||
|
||||
message << "\n\n#{I18n.t(self.class.i18n_key('random_mention.bot_actions'),
|
||||
discobot_username: self.discobot_username,
|
||||
dice_trigger: self.class.dice_trigger,
|
||||
quote_trigger: self.class.quote_trigger,
|
||||
quote_sample: DiscourseNarrativeBot::QuoteGenerator.generate(@user),
|
||||
magic_8_ball_trigger: self.class.magic_8_ball_trigger
|
||||
)}"
|
||||
message << "\n\n#{
|
||||
I18n.t(
|
||||
self.class.i18n_key("random_mention.bot_actions"),
|
||||
discobot_username: self.discobot_username,
|
||||
dice_trigger: self.class.dice_trigger,
|
||||
quote_trigger: self.class.quote_trigger,
|
||||
quote_sample: DiscourseNarrativeBot::QuoteGenerator.generate(@user),
|
||||
magic_8_ball_trigger: self.class.magic_8_ball_trigger,
|
||||
)
|
||||
}"
|
||||
end
|
||||
|
||||
def generic_replies_key(user)
|
||||
@@ -193,18 +194,23 @@ module DiscourseNarrativeBot
|
||||
|
||||
case count
|
||||
when 0
|
||||
raw = I18n.t(self.class.i18n_key('do_not_understand.first_response'))
|
||||
raw = I18n.t(self.class.i18n_key("do_not_understand.first_response"))
|
||||
|
||||
if state && state.to_sym != :end
|
||||
raw = "#{raw}\n\n#{I18n.t(self.class.i18n_key('do_not_understand.track_response'), reset_trigger: reset_trigger, skip_trigger: self.class.skip_trigger)}"
|
||||
raw =
|
||||
"#{raw}\n\n#{I18n.t(self.class.i18n_key("do_not_understand.track_response"), reset_trigger: reset_trigger, skip_trigger: self.class.skip_trigger)}"
|
||||
end
|
||||
|
||||
reply_to(@post, raw)
|
||||
when 1
|
||||
reply_to(@post, I18n.t(self.class.i18n_key('do_not_understand.second_response'),
|
||||
base_path: Discourse.base_path,
|
||||
reset_trigger: self.class.reset_trigger
|
||||
))
|
||||
reply_to(
|
||||
@post,
|
||||
I18n.t(
|
||||
self.class.i18n_key("do_not_understand.second_response"),
|
||||
base_path: Discourse.base_path,
|
||||
reset_trigger: self.class.reset_trigger,
|
||||
),
|
||||
)
|
||||
else
|
||||
# Stay out of the user's way
|
||||
end
|
||||
@@ -218,7 +224,9 @@ module DiscourseNarrativeBot
|
||||
|
||||
def skip_track?
|
||||
if @is_pm_to_bot
|
||||
@post.raw.match(/((^@#{self.discobot_username} #{self.class.skip_trigger})|(^#{self.class.skip_trigger}$))/i)
|
||||
@post.raw.match(
|
||||
/((^@#{self.discobot_username} #{self.class.skip_trigger})|(^#{self.class.skip_trigger}$))/i,
|
||||
)
|
||||
else
|
||||
false
|
||||
end
|
||||
@@ -233,24 +241,23 @@ module DiscourseNarrativeBot
|
||||
def match_trigger?(trigger)
|
||||
# we remove the leading <p> to allow for trigger to be at the end of a paragraph
|
||||
cooked_trigger = cook(trigger)[3..-1]
|
||||
regexp = Regexp.new(cooked_trigger, 'i')
|
||||
regexp = Regexp.new(cooked_trigger, "i")
|
||||
match = @post.cooked.match(regexp)
|
||||
|
||||
if @is_pm_to_bot
|
||||
match || @post.raw.strip.match(Regexp.new("^#{trigger}$", 'i'))
|
||||
match || @post.raw.strip.match(Regexp.new("^#{trigger}$", "i"))
|
||||
else
|
||||
match
|
||||
end
|
||||
end
|
||||
|
||||
def like_user_post
|
||||
if @post.raw.match(/thank/i)
|
||||
PostActionCreator.like(self.discobot_user, @post)
|
||||
end
|
||||
PostActionCreator.like(self.discobot_user, @post) if @post.raw.match(/thank/i)
|
||||
end
|
||||
|
||||
def bot_mentioned?
|
||||
@bot_mentioned ||= PostAnalyzer.new(@post.raw, @post.topic_id).raw_mentions.include?(self.discobot_username)
|
||||
@bot_mentioned ||=
|
||||
PostAnalyzer.new(@post.raw, @post.topic_id).raw_mentions.include?(self.discobot_username)
|
||||
end
|
||||
|
||||
def public_reply?
|
||||
|
||||
@@ -8,8 +8,14 @@ module DiscourseNarrativeBot
|
||||
|
||||
def self.values
|
||||
@values ||= [
|
||||
{ name: 'discourse_narrative_bot.welcome_post_type.new_user_track', value: 'new_user_track' },
|
||||
{ name: 'discourse_narrative_bot.welcome_post_type.welcome_message', value: 'welcome_message' }
|
||||
{
|
||||
name: "discourse_narrative_bot.welcome_post_type.new_user_track",
|
||||
value: "new_user_track",
|
||||
},
|
||||
{
|
||||
name: "discourse_narrative_bot.welcome_post_type.welcome_message",
|
||||
value: "welcome_message",
|
||||
},
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -18,34 +18,37 @@ if Rails.env == "development"
|
||||
# 3. we have a post_edited hook that queues a job for bot input
|
||||
# 4. if you are not running sidekiq in dev every time you save a post it will trigger it
|
||||
# 5. but the constant can not be autoloaded
|
||||
Rails.configuration.autoload_paths << File.expand_path('../autoload/jobs', __FILE__)
|
||||
Rails.configuration.autoload_paths << File.expand_path("../autoload/jobs", __FILE__)
|
||||
end
|
||||
|
||||
require_relative 'lib/discourse_narrative_bot/welcome_post_type_site_setting.rb'
|
||||
register_asset 'stylesheets/discourse-narrative-bot.scss'
|
||||
require_relative "lib/discourse_narrative_bot/welcome_post_type_site_setting.rb"
|
||||
register_asset "stylesheets/discourse-narrative-bot.scss"
|
||||
|
||||
after_initialize do
|
||||
SeedFu.fixture_paths << Rails.root.join("plugins", "discourse-narrative-bot", "db", "fixtures").to_s
|
||||
SeedFu.fixture_paths << Rails
|
||||
.root
|
||||
.join("plugins", "discourse-narrative-bot", "db", "fixtures")
|
||||
.to_s
|
||||
|
||||
Mime::Type.register "image/svg+xml", :svg
|
||||
|
||||
[
|
||||
'../autoload/jobs/regular/bot_input.rb',
|
||||
'../autoload/jobs/regular/narrative_timeout.rb',
|
||||
'../autoload/jobs/regular/narrative_init.rb',
|
||||
'../autoload/jobs/regular/send_default_welcome_message.rb',
|
||||
'../autoload/jobs/onceoff/discourse_narrative_bot/grant_badges.rb',
|
||||
'../autoload/jobs/onceoff/discourse_narrative_bot/remap_old_bot_images.rb',
|
||||
'../lib/discourse_narrative_bot/actions.rb',
|
||||
'../lib/discourse_narrative_bot/base.rb',
|
||||
'../lib/discourse_narrative_bot/new_user_narrative.rb',
|
||||
'../lib/discourse_narrative_bot/advanced_user_narrative.rb',
|
||||
'../lib/discourse_narrative_bot/track_selector.rb',
|
||||
'../lib/discourse_narrative_bot/certificate_generator.rb',
|
||||
'../lib/discourse_narrative_bot/dice.rb',
|
||||
'../lib/discourse_narrative_bot/quote_generator.rb',
|
||||
'../lib/discourse_narrative_bot/magic_8_ball.rb',
|
||||
'../lib/discourse_narrative_bot/welcome_post_type_site_setting.rb'
|
||||
%w[
|
||||
../autoload/jobs/regular/bot_input.rb
|
||||
../autoload/jobs/regular/narrative_timeout.rb
|
||||
../autoload/jobs/regular/narrative_init.rb
|
||||
../autoload/jobs/regular/send_default_welcome_message.rb
|
||||
../autoload/jobs/onceoff/discourse_narrative_bot/grant_badges.rb
|
||||
../autoload/jobs/onceoff/discourse_narrative_bot/remap_old_bot_images.rb
|
||||
../lib/discourse_narrative_bot/actions.rb
|
||||
../lib/discourse_narrative_bot/base.rb
|
||||
../lib/discourse_narrative_bot/new_user_narrative.rb
|
||||
../lib/discourse_narrative_bot/advanced_user_narrative.rb
|
||||
../lib/discourse_narrative_bot/track_selector.rb
|
||||
../lib/discourse_narrative_bot/certificate_generator.rb
|
||||
../lib/discourse_narrative_bot/dice.rb
|
||||
../lib/discourse_narrative_bot/quote_generator.rb
|
||||
../lib/discourse_narrative_bot/magic_8_ball.rb
|
||||
../lib/discourse_narrative_bot/welcome_post_type_site_setting.rb
|
||||
].each { |path| load File.expand_path(path, __FILE__) }
|
||||
|
||||
RailsMultisite::ConnectionManagement.safe_each_connection do
|
||||
@@ -55,12 +58,13 @@ after_initialize do
|
||||
|
||||
certificate_path = "#{Discourse.base_url}/discobot/certificate.svg"
|
||||
if !SiteSetting.allowed_iframes.include?(certificate_path)
|
||||
SiteSetting.allowed_iframes = SiteSetting.allowed_iframes.split('|').append(certificate_path).join('|')
|
||||
SiteSetting.allowed_iframes =
|
||||
SiteSetting.allowed_iframes.split("|").append(certificate_path).join("|")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require_dependency 'plugin_store'
|
||||
require_dependency "plugin_store"
|
||||
|
||||
module ::DiscourseNarrativeBot
|
||||
PLUGIN_NAME = "discourse-narrative-bot".freeze
|
||||
@@ -94,13 +98,15 @@ after_initialize do
|
||||
immutable_for(24.hours)
|
||||
|
||||
%i[date user_id].each do |key|
|
||||
raise Discourse::InvalidParameters.new("#{key} must be present") unless params[key]&.present?
|
||||
unless params[key]&.present?
|
||||
raise Discourse::InvalidParameters.new("#{key} must be present")
|
||||
end
|
||||
end
|
||||
|
||||
if params[:user_id].to_i != current_user.id
|
||||
rate_limiter = RateLimiter.new(current_user, 'svg_certificate', 3, 1.minute)
|
||||
rate_limiter = RateLimiter.new(current_user, "svg_certificate", 3, 1.minute)
|
||||
else
|
||||
rate_limiter = RateLimiter.new(current_user, 'svg_certificate_self', 30, 10.minutes)
|
||||
rate_limiter = RateLimiter.new(current_user, "svg_certificate_self", 30, 10.minutes)
|
||||
end
|
||||
rate_limiter.performed! unless current_user.staff?
|
||||
|
||||
@@ -110,33 +116,28 @@ after_initialize do
|
||||
hijack do
|
||||
generator = CertificateGenerator.new(user, params[:date], avatar_url(user))
|
||||
|
||||
svg = params[:type] == 'advanced' ? generator.advanced_user_track : generator.new_user_track
|
||||
svg =
|
||||
params[:type] == "advanced" ? generator.advanced_user_track : generator.new_user_track
|
||||
|
||||
respond_to do |format|
|
||||
format.svg { render inline: svg }
|
||||
end
|
||||
respond_to { |format| format.svg { render inline: svg } }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def avatar_url(user)
|
||||
UrlHelper.absolute(Discourse.base_path + user.avatar_template.gsub('{size}', '250'))
|
||||
UrlHelper.absolute(Discourse.base_path + user.avatar_template.gsub("{size}", "250"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
DiscourseNarrativeBot::Engine.routes.draw do
|
||||
get "/certificate" => "certificates#generate", format: :svg
|
||||
get "/certificate" => "certificates#generate", :format => :svg
|
||||
end
|
||||
|
||||
Discourse::Application.routes.append do
|
||||
mount ::DiscourseNarrativeBot::Engine, at: "/discobot"
|
||||
end
|
||||
Discourse::Application.routes.append { mount ::DiscourseNarrativeBot::Engine, at: "/discobot" }
|
||||
|
||||
self.add_model_callback(User, :after_destroy) do
|
||||
DiscourseNarrativeBot::Store.remove(self.id)
|
||||
end
|
||||
self.add_model_callback(User, :after_destroy) { DiscourseNarrativeBot::Store.remove(self.id) }
|
||||
|
||||
self.on(:user_created) do |user|
|
||||
if SiteSetting.discourse_narrative_bot_welcome_post_delay == 0 && !user.staged
|
||||
@@ -145,19 +146,13 @@ after_initialize do
|
||||
end
|
||||
|
||||
self.on(:user_first_logged_in) do |user|
|
||||
if SiteSetting.discourse_narrative_bot_welcome_post_delay > 0
|
||||
user.enqueue_bot_welcome_post
|
||||
end
|
||||
user.enqueue_bot_welcome_post if SiteSetting.discourse_narrative_bot_welcome_post_delay > 0
|
||||
end
|
||||
|
||||
self.on(:user_unstaged) do |user|
|
||||
user.enqueue_bot_welcome_post
|
||||
end
|
||||
self.on(:user_unstaged) { |user| user.enqueue_bot_welcome_post }
|
||||
|
||||
self.add_model_callback(UserOption, :after_save) do
|
||||
if saved_change_to_skip_new_user_tips? && self.skip_new_user_tips
|
||||
user.delete_bot_welcome_post
|
||||
end
|
||||
user.delete_bot_welcome_post if saved_change_to_skip_new_user_tips? && self.skip_new_user_tips
|
||||
end
|
||||
|
||||
self.add_to_class(:user, :enqueue_bot_welcome_post) do
|
||||
@@ -166,28 +161,29 @@ after_initialize do
|
||||
delay = SiteSetting.discourse_narrative_bot_welcome_post_delay
|
||||
|
||||
case SiteSetting.discourse_narrative_bot_welcome_post_type
|
||||
when 'new_user_track'
|
||||
when "new_user_track"
|
||||
if enqueue_narrative_bot_job? && !manually_disabled_discobot?
|
||||
Jobs.enqueue_in(delay, :narrative_init,
|
||||
Jobs.enqueue_in(
|
||||
delay,
|
||||
:narrative_init,
|
||||
user_id: self.id,
|
||||
klass: DiscourseNarrativeBot::NewUserNarrative.to_s
|
||||
klass: DiscourseNarrativeBot::NewUserNarrative.to_s,
|
||||
)
|
||||
end
|
||||
when 'welcome_message'
|
||||
when "welcome_message"
|
||||
Jobs.enqueue_in(delay, :send_default_welcome_message, user_id: self.id)
|
||||
end
|
||||
end
|
||||
|
||||
self.add_to_class(:user, :manually_disabled_discobot?) do
|
||||
user_option&.skip_new_user_tips
|
||||
end
|
||||
self.add_to_class(:user, :manually_disabled_discobot?) { user_option&.skip_new_user_tips }
|
||||
|
||||
self.add_to_class(:user, :enqueue_narrative_bot_job?) do
|
||||
SiteSetting.discourse_narrative_bot_enabled &&
|
||||
self.human? &&
|
||||
!self.anonymous? &&
|
||||
SiteSetting.discourse_narrative_bot_enabled && self.human? && !self.anonymous? &&
|
||||
!self.staged &&
|
||||
!SiteSetting.discourse_narrative_bot_ignored_usernames.split('|'.freeze).include?(self.username)
|
||||
!SiteSetting
|
||||
.discourse_narrative_bot_ignored_usernames
|
||||
.split("|".freeze)
|
||||
.include?(self.username)
|
||||
end
|
||||
|
||||
self.add_to_class(:user, :delete_bot_welcome_post) do
|
||||
@@ -219,42 +215,31 @@ after_initialize do
|
||||
user = post.user
|
||||
|
||||
if user&.enqueue_narrative_bot_job? && !options[:skip_bot]
|
||||
Jobs.enqueue(:bot_input,
|
||||
user_id: user.id,
|
||||
post_id: post.id,
|
||||
input: "reply"
|
||||
)
|
||||
Jobs.enqueue(:bot_input, user_id: user.id, post_id: post.id, input: "reply")
|
||||
end
|
||||
end
|
||||
|
||||
self.on(:post_edited) do |post|
|
||||
if post.user&.enqueue_narrative_bot_job?
|
||||
Jobs.enqueue(:bot_input,
|
||||
user_id: post.user.id,
|
||||
post_id: post.id,
|
||||
input: "edit"
|
||||
)
|
||||
Jobs.enqueue(:bot_input, user_id: post.user.id, post_id: post.id, input: "edit")
|
||||
end
|
||||
end
|
||||
|
||||
self.on(:post_destroyed) do |post, options, user|
|
||||
if user&.enqueue_narrative_bot_job? && !options[:skip_bot]
|
||||
Jobs.enqueue(:bot_input,
|
||||
Jobs.enqueue(
|
||||
:bot_input,
|
||||
user_id: user.id,
|
||||
post_id: post.id,
|
||||
topic_id: post.topic_id,
|
||||
input: "delete"
|
||||
input: "delete",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
self.on(:post_recovered) do |post, _, user|
|
||||
if user&.enqueue_narrative_bot_job?
|
||||
Jobs.enqueue(:bot_input,
|
||||
user_id: user.id,
|
||||
post_id: post.id,
|
||||
input: "recover"
|
||||
)
|
||||
Jobs.enqueue(:bot_input, user_id: user.id, post_id: post.id, input: "recover")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -268,20 +253,19 @@ after_initialize do
|
||||
"like"
|
||||
end
|
||||
|
||||
if input
|
||||
Jobs.enqueue(:bot_input,
|
||||
user_id: self.user.id,
|
||||
post_id: self.post.id,
|
||||
input: input
|
||||
)
|
||||
end
|
||||
Jobs.enqueue(:bot_input, user_id: self.user.id, post_id: self.post.id, input: input) if input
|
||||
end
|
||||
end
|
||||
|
||||
self.add_model_callback(Bookmark, :after_commit, on: :create) do
|
||||
if self.user.enqueue_narrative_bot_job?
|
||||
if self.bookmarkable_type == "Post"
|
||||
Jobs.enqueue(:bot_input, user_id: self.user_id, post_id: self.bookmarkable_id, input: "bookmark")
|
||||
Jobs.enqueue(
|
||||
:bot_input,
|
||||
user_id: self.user_id,
|
||||
post_id: self.bookmarkable_id,
|
||||
input: "bookmark",
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -290,31 +274,36 @@ after_initialize do
|
||||
user = User.find_by(id: user_id)
|
||||
|
||||
if user && user.enqueue_narrative_bot_job?
|
||||
Jobs.enqueue(:bot_input,
|
||||
Jobs.enqueue(
|
||||
:bot_input,
|
||||
user_id: user_id,
|
||||
topic_id: topic_id,
|
||||
input: "topic_notification_level_changed"
|
||||
input: "topic_notification_level_changed",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
UserAvatar.register_custom_user_gravatar_email_hash(
|
||||
DiscourseNarrativeBot::BOT_USER_ID,
|
||||
"discobot@discourse.org"
|
||||
"discobot@discourse.org",
|
||||
)
|
||||
|
||||
self.on(:system_message_sent) do |args|
|
||||
next if !SiteSetting.discourse_narrative_bot_enabled
|
||||
next if args[:message_type] != 'tl2_promotion_message'
|
||||
next if args[:message_type] != "tl2_promotion_message"
|
||||
|
||||
recipient = args[:post].topic.topic_users.where.not(user_id: args[:post].user_id).last&.user
|
||||
recipient ||= Discourse.site_contact_user if args[:post].user == Discourse.site_contact_user
|
||||
next if recipient.nil?
|
||||
|
||||
I18n.with_locale(recipient.effective_locale) do
|
||||
raw = I18n.t("discourse_narrative_bot.tl2_promotion_message.text_body_template",
|
||||
discobot_username: ::DiscourseNarrativeBot::Base.new.discobot_username,
|
||||
reset_trigger: "#{::DiscourseNarrativeBot::TrackSelector.reset_trigger} #{::DiscourseNarrativeBot::AdvancedUserNarrative.reset_trigger}")
|
||||
raw =
|
||||
I18n.t(
|
||||
"discourse_narrative_bot.tl2_promotion_message.text_body_template",
|
||||
discobot_username: ::DiscourseNarrativeBot::Base.new.discobot_username,
|
||||
reset_trigger:
|
||||
"#{::DiscourseNarrativeBot::TrackSelector.reset_trigger} #{::DiscourseNarrativeBot::AdvancedUserNarrative.reset_trigger}",
|
||||
)
|
||||
|
||||
PostCreator.create!(
|
||||
::DiscourseNarrativeBot::Base.new.discobot_user,
|
||||
@@ -322,7 +311,7 @@ after_initialize do
|
||||
raw: raw,
|
||||
skip_validations: true,
|
||||
archetype: Archetype.private_message,
|
||||
target_usernames: recipient.username
|
||||
target_usernames: recipient.username,
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -331,12 +320,12 @@ after_initialize do
|
||||
alias_method :existing_can_create_post?, :can_create_post?
|
||||
|
||||
def can_create_post?(parent)
|
||||
return true if SiteSetting.discourse_narrative_bot_enabled &&
|
||||
parent.try(:subtype) == "system_message" &&
|
||||
parent.try(:user) == ::DiscourseNarrativeBot::Base.new.discobot_user
|
||||
if SiteSetting.discourse_narrative_bot_enabled && parent.try(:subtype) == "system_message" &&
|
||||
parent.try(:user) == ::DiscourseNarrativeBot::Base.new.discobot_user
|
||||
return true
|
||||
end
|
||||
|
||||
existing_can_create_post?(parent)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,28 +1,28 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe DiscourseNarrativeBot::Store do
|
||||
describe '.set' do
|
||||
it 'should set the right value in the plugin store' do
|
||||
key = 'somekey'
|
||||
described_class.set(key, 'yay')
|
||||
describe ".set" do
|
||||
it "should set the right value in the plugin store" do
|
||||
key = "somekey"
|
||||
described_class.set(key, "yay")
|
||||
plugin_store_row = PluginStoreRow.last
|
||||
|
||||
expect(plugin_store_row.value).to eq('yay')
|
||||
expect(plugin_store_row.value).to eq("yay")
|
||||
expect(plugin_store_row.plugin_name).to eq(DiscourseNarrativeBot::PLUGIN_NAME)
|
||||
expect(plugin_store_row.key).to eq(key)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.get' do
|
||||
it 'should get the right value from the plugin store' do
|
||||
describe ".get" do
|
||||
it "should get the right value from the plugin store" do
|
||||
PluginStoreRow.create!(
|
||||
plugin_name: DiscourseNarrativeBot::PLUGIN_NAME,
|
||||
key: 'somekey',
|
||||
value: 'yay',
|
||||
type_name: 'string'
|
||||
key: "somekey",
|
||||
value: "yay",
|
||||
type_name: "string",
|
||||
)
|
||||
|
||||
expect(described_class.get('somekey')).to eq('yay')
|
||||
expect(described_class.get("somekey")).to eq("yay")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,13 +5,16 @@ RSpec.describe Jobs::DiscourseNarrativeBot::GrantBadges do
|
||||
let(:other_user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
DiscourseNarrativeBot::Store.set(user.id, completed: [
|
||||
DiscourseNarrativeBot::NewUserNarrative.to_s,
|
||||
DiscourseNarrativeBot::AdvancedUserNarrative.to_s
|
||||
])
|
||||
DiscourseNarrativeBot::Store.set(
|
||||
user.id,
|
||||
completed: [
|
||||
DiscourseNarrativeBot::NewUserNarrative.to_s,
|
||||
DiscourseNarrativeBot::AdvancedUserNarrative.to_s,
|
||||
],
|
||||
)
|
||||
end
|
||||
|
||||
it 'should grant the right badges' do
|
||||
it "should grant the right badges" do
|
||||
described_class.new.execute_onceoff({})
|
||||
|
||||
expect(user.badges.count).to eq(2)
|
||||
|
||||
@@ -3,14 +3,17 @@
|
||||
RSpec.describe Jobs::DiscourseNarrativeBot::RemapOldBotImages do
|
||||
context "when bot's post contains an old link" do
|
||||
let!(:post) do
|
||||
Fabricate(:post,
|
||||
Fabricate(
|
||||
:post,
|
||||
user: ::DiscourseNarrativeBot::Base.new.discobot_user,
|
||||
raw: 'If you’d like to learn more, select <img src="/images/font-awesome-gear.png" width="16" height="16"> <img src="/images/font-awesome-ellipsis.png" width="16" height="16"> below and <img src="/images/font-awesome-bookmark.png" width="16" height="16"> **bookmark this private message**. If you do, there may be a :gift: in your future!'
|
||||
raw:
|
||||
'If you’d like to learn more, select <img src="/images/font-awesome-gear.png" width="16" height="16"> <img src="/images/font-awesome-ellipsis.png" width="16" height="16"> below and <img src="/images/font-awesome-bookmark.png" width="16" height="16"> **bookmark this private message**. If you do, there may be a :gift: in your future!',
|
||||
)
|
||||
end
|
||||
|
||||
it 'should remap the links correctly' do
|
||||
expected_raw = 'If you’d like to learn more, select <img src="/plugins/discourse-narrative-bot/images/font-awesome-gear.png" width="16" height="16"> <img src="/plugins/discourse-narrative-bot/images/font-awesome-ellipsis.png" width="16" height="16"> below and <img src="/plugins/discourse-narrative-bot/images/font-awesome-bookmark.png" width="16" height="16"> **bookmark this private message**. If you do, there may be a :gift: in your future!'
|
||||
it "should remap the links correctly" do
|
||||
expected_raw =
|
||||
'If you’d like to learn more, select <img src="/plugins/discourse-narrative-bot/images/font-awesome-gear.png" width="16" height="16"> <img src="/plugins/discourse-narrative-bot/images/font-awesome-ellipsis.png" width="16" height="16"> below and <img src="/plugins/discourse-narrative-bot/images/font-awesome-bookmark.png" width="16" height="16"> **bookmark this private message**. If you do, there may be a :gift: in your future!'
|
||||
|
||||
2.times do
|
||||
described_class.new.execute_onceoff({})
|
||||
@@ -19,19 +22,21 @@ RSpec.describe Jobs::DiscourseNarrativeBot::RemapOldBotImages do
|
||||
end
|
||||
end
|
||||
|
||||
context 'with subfolder' do
|
||||
context "with subfolder" do
|
||||
let!(:post) do
|
||||
Fabricate(:post,
|
||||
Fabricate(
|
||||
:post,
|
||||
user: ::DiscourseNarrativeBot::Base.new.discobot_user,
|
||||
raw: 'If you’d like to learn more, select <img src="/community/images/font-awesome-ellipsis.png" width="16" height="16"> below and <img src="/community/images/font-awesome-bookmark.png" width="16" height="16"> **bookmark this private message**. If you do, there may be a :gift: in your future!'
|
||||
raw:
|
||||
'If you’d like to learn more, select <img src="/community/images/font-awesome-ellipsis.png" width="16" height="16"> below and <img src="/community/images/font-awesome-bookmark.png" width="16" height="16"> **bookmark this private message**. If you do, there may be a :gift: in your future!',
|
||||
)
|
||||
end
|
||||
|
||||
it 'should remap the links correctly' do
|
||||
it "should remap the links correctly" do
|
||||
described_class.new.execute_onceoff({})
|
||||
|
||||
expect(post.reload.raw).to eq(
|
||||
'If you’d like to learn more, select <img src="/community/plugins/discourse-narrative-bot/images/font-awesome-ellipsis.png" width="16" height="16"> below and <img src="/community/plugins/discourse-narrative-bot/images/font-awesome-bookmark.png" width="16" height="16"> **bookmark this private message**. If you do, there may be a :gift: in your future!'
|
||||
'If you’d like to learn more, select <img src="/community/plugins/discourse-narrative-bot/images/font-awesome-ellipsis.png" width="16" height="16"> below and <img src="/community/plugins/discourse-narrative-bot/images/font-awesome-bookmark.png" width="16" height="16"> **bookmark this private message**. If you do, there may be a :gift: in your future!',
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,42 +3,51 @@
|
||||
RSpec.describe Jobs::SendDefaultWelcomeMessage do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
it 'should send the right welcome message' do
|
||||
it "should send the right welcome message" do
|
||||
described_class.new.execute(user_id: user.id)
|
||||
|
||||
topic = Topic.last
|
||||
|
||||
expect(topic.title).to eq(I18n.t(
|
||||
"system_messages.welcome_user.subject_template",
|
||||
site_name: SiteSetting.title
|
||||
))
|
||||
expect(topic.title).to eq(
|
||||
I18n.t("system_messages.welcome_user.subject_template", site_name: SiteSetting.title),
|
||||
)
|
||||
|
||||
expect(topic.first_post.raw).to eq(I18n.t(
|
||||
"system_messages.welcome_user.text_body_template",
|
||||
SystemMessage.new(user).defaults
|
||||
).chomp)
|
||||
expect(topic.first_post.raw).to eq(
|
||||
I18n.t(
|
||||
"system_messages.welcome_user.text_body_template",
|
||||
SystemMessage.new(user).defaults,
|
||||
).chomp,
|
||||
)
|
||||
|
||||
expect(topic.closed).to eq(true)
|
||||
end
|
||||
|
||||
describe 'for an invited user' do
|
||||
let(:invite) { Fabricate(:invite, email: 'foo@bar.com') }
|
||||
let(:invited_user) { Fabricate(:invited_user, invite: invite, user: Fabricate(:user, email: 'foo@bar.com'), redeemed_at: Time.zone.now) }
|
||||
describe "for an invited user" do
|
||||
let(:invite) { Fabricate(:invite, email: "foo@bar.com") }
|
||||
let(:invited_user) do
|
||||
Fabricate(
|
||||
:invited_user,
|
||||
invite: invite,
|
||||
user: Fabricate(:user, email: "foo@bar.com"),
|
||||
redeemed_at: Time.zone.now,
|
||||
)
|
||||
end
|
||||
|
||||
it 'should send the right welcome message' do
|
||||
it "should send the right welcome message" do
|
||||
described_class.new.execute(user_id: invited_user.user_id)
|
||||
|
||||
topic = Topic.last
|
||||
|
||||
expect(topic.title).to eq(I18n.t(
|
||||
"system_messages.welcome_invite.subject_template",
|
||||
site_name: SiteSetting.title
|
||||
))
|
||||
expect(topic.title).to eq(
|
||||
I18n.t("system_messages.welcome_invite.subject_template", site_name: SiteSetting.title),
|
||||
)
|
||||
|
||||
expect(topic.first_post.raw).to eq(I18n.t(
|
||||
"system_messages.welcome_invite.text_body_template",
|
||||
SystemMessage.new(invited_user.user).defaults
|
||||
).chomp)
|
||||
expect(topic.first_post.raw).to eq(
|
||||
I18n.t(
|
||||
"system_messages.welcome_invite.text_body_template",
|
||||
SystemMessage.new(invited_user.user).defaults,
|
||||
).chomp,
|
||||
)
|
||||
|
||||
expect(topic.closed).to eq(true)
|
||||
end
|
||||
|
||||
@@ -2,24 +2,21 @@
|
||||
|
||||
RSpec.describe DiscourseNarrativeBot::CertificateGenerator do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:avatar_url) { 'http://test.localhost/cdn/avatar.png' }
|
||||
let(:avatar_url) { "http://test.localhost/cdn/avatar.png" }
|
||||
let(:date) { "2017-00-10" }
|
||||
|
||||
describe 'when an invalid date is given' do
|
||||
it 'should default to the current date' do
|
||||
describe "when an invalid date is given" do
|
||||
it "should default to the current date" do
|
||||
expect { described_class.new(user, date, avatar_url) }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe '#logo_group' do
|
||||
describe 'when SiteSetting.site_logo_small_url is blank' do
|
||||
before do
|
||||
SiteSetting.logo_small = ''
|
||||
end
|
||||
describe "#logo_group" do
|
||||
describe "when SiteSetting.site_logo_small_url is blank" do
|
||||
before { SiteSetting.logo_small = "" }
|
||||
|
||||
it 'should not try to fetch a image' do
|
||||
expect(described_class.new(user, date, avatar_url).send(:logo_group, 1, 1, 1))
|
||||
.to eq(nil)
|
||||
it "should not try to fetch a image" do
|
||||
expect(described_class.new(user, date, avatar_url).send(:logo_group, 1, 1, 1)).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,48 +1,43 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe "Discobot Certificate" do
|
||||
let(:user) { Fabricate(:user, name: 'Jeff Atwood') }
|
||||
let(:user) { Fabricate(:user, name: "Jeff Atwood") }
|
||||
|
||||
let(:params) {
|
||||
{
|
||||
date: Time.zone.now.strftime("%b %d %Y"),
|
||||
user_id: user.id
|
||||
}
|
||||
}
|
||||
let(:params) { { date: Time.zone.now.strftime("%b %d %Y"), user_id: user.id } }
|
||||
|
||||
describe 'when viewing the certificate' do
|
||||
describe 'when no logged in' do
|
||||
it 'should return the right response' do
|
||||
get '/discobot/certificate.svg', params: params
|
||||
describe "when viewing the certificate" do
|
||||
describe "when no logged in" do
|
||||
it "should return the right response" do
|
||||
get "/discobot/certificate.svg", params: params
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when logged in' do
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
describe "when logged in" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it 'should return the right text' do
|
||||
stub_request(:get, /letter_avatar_proxy/).to_return(status: 200, body: 'http://test.localhost/cdn/avatar.png')
|
||||
it "should return the right text" do
|
||||
stub_request(:get, /letter_avatar_proxy/).to_return(
|
||||
status: 200,
|
||||
body: "http://test.localhost/cdn/avatar.png",
|
||||
)
|
||||
stub_request(:get, /avatar.png/).to_return(status: 200)
|
||||
|
||||
stub_request(:get, SiteSetting.site_logo_small_url)
|
||||
.to_return(status: 200)
|
||||
stub_request(:get, SiteSetting.site_logo_small_url).to_return(status: 200)
|
||||
|
||||
get '/discobot/certificate.svg', params: params
|
||||
get "/discobot/certificate.svg", params: params
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to include('<svg')
|
||||
expect(response.body).to include(user.avatar_template.gsub('{size}', '250'))
|
||||
expect(response.body).to include("<svg")
|
||||
expect(response.body).to include(user.avatar_template.gsub("{size}", "250"))
|
||||
expect(response.body).to include(SiteSetting.site_logo_small_url)
|
||||
end
|
||||
|
||||
describe 'when params are missing' do
|
||||
describe "when params are missing" do
|
||||
it "should raise the right errors" do
|
||||
params.each do |key, _|
|
||||
get '/discobot/certificate.svg', params: params.except(key)
|
||||
get "/discobot/certificate.svg", params: params.except(key)
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,40 +3,39 @@
|
||||
RSpec.describe "Discobot welcome post" do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
SiteSetting.discourse_narrative_bot_enabled = true
|
||||
end
|
||||
before { SiteSetting.discourse_narrative_bot_enabled = true }
|
||||
|
||||
context 'when discourse_narrative_bot_welcome_post_delay is 0' do
|
||||
it 'should not delay the welcome post' do
|
||||
context "when discourse_narrative_bot_welcome_post_delay is 0" do
|
||||
it "should not delay the welcome post" do
|
||||
user
|
||||
expect { sign_in(user) }.to_not change { Jobs::NarrativeInit.jobs.count }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when discourse_narrative_bot_welcome_post_delay is greater than 0' do
|
||||
before do
|
||||
SiteSetting.discourse_narrative_bot_welcome_post_delay = 5
|
||||
end
|
||||
context "when discourse_narrative_bot_welcome_post_delay is greater than 0" do
|
||||
before { SiteSetting.discourse_narrative_bot_welcome_post_delay = 5 }
|
||||
|
||||
context 'when user logs in normally' do
|
||||
it 'should delay the welcome post until user logs in' do
|
||||
context "when user logs in normally" do
|
||||
it "should delay the welcome post until user logs in" do
|
||||
expect { sign_in(user) }.to change { Jobs::NarrativeInit.jobs.count }.by(1)
|
||||
expect(Jobs::NarrativeInit.jobs.first["args"].first["user_id"]).to eq(user.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user redeems an invite' do
|
||||
let!(:invite) { Fabricate(:invite, invited_by: Fabricate(:admin), email: 'testing@gmail.com') }
|
||||
context "when user redeems an invite" do
|
||||
let!(:invite) do
|
||||
Fabricate(:invite, invited_by: Fabricate(:admin), email: "testing@gmail.com")
|
||||
end
|
||||
|
||||
it 'should delay the welcome post until the user logs in' do
|
||||
it "should delay the welcome post until the user logs in" do
|
||||
expect do
|
||||
put "/invites/show/#{invite.invite_key}.json", params: {
|
||||
username: 'somename',
|
||||
name: 'testing',
|
||||
password: 'verystrongpassword',
|
||||
email_token: invite.email_token
|
||||
}
|
||||
put "/invites/show/#{invite.invite_key}.json",
|
||||
params: {
|
||||
username: "somename",
|
||||
name: "testing",
|
||||
password: "verystrongpassword",
|
||||
email_token: invite.email_token,
|
||||
}
|
||||
end.to change { User.count }.by(1)
|
||||
|
||||
expect(Jobs::NarrativeInit.jobs.first["args"].first["user_id"]).to eq(User.last.id)
|
||||
@@ -44,14 +43,12 @@ RSpec.describe "Discobot welcome post" do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is staged' do
|
||||
context "when user is staged" do
|
||||
let(:staged_user) { Fabricate(:user, staged: true) }
|
||||
|
||||
before do
|
||||
SiteSetting.discourse_narrative_bot_welcome_post_type = 'welcome_message'
|
||||
end
|
||||
before { SiteSetting.discourse_narrative_bot_welcome_post_type = "welcome_message" }
|
||||
|
||||
it 'should not send welcome message' do
|
||||
it "should not send welcome message" do
|
||||
expect { staged_user }.to_not change { Jobs::SendDefaultWelcomeMessage.jobs.count }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,79 +18,76 @@ RSpec.describe User do
|
||||
SiteSetting.discourse_narrative_bot_enabled = true
|
||||
end
|
||||
|
||||
describe 'when a user is created' do
|
||||
it 'should initiate the bot' do
|
||||
describe "when a user is created" do
|
||||
it "should initiate the bot" do
|
||||
NotificationEmailer.expects(:process_notification).never
|
||||
|
||||
user
|
||||
|
||||
expected_raw = i18n_t('discourse_narrative_bot.new_user_narrative.hello.message',
|
||||
username: user.username, title: SiteSetting.title
|
||||
)
|
||||
expected_raw =
|
||||
i18n_t(
|
||||
"discourse_narrative_bot.new_user_narrative.hello.message",
|
||||
username: user.username,
|
||||
title: SiteSetting.title,
|
||||
)
|
||||
|
||||
expect(Post.last.raw).to include(expected_raw.chomp)
|
||||
end
|
||||
|
||||
describe 'welcome post' do
|
||||
context 'when disabled' do
|
||||
before do
|
||||
SiteSetting.disable_discourse_narrative_bot_welcome_post = true
|
||||
end
|
||||
describe "welcome post" do
|
||||
context "when disabled" do
|
||||
before { SiteSetting.disable_discourse_narrative_bot_welcome_post = true }
|
||||
|
||||
it 'should not initiate the bot' do
|
||||
it "should not initiate the bot" do
|
||||
expect { user }.to_not change { Post.count }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with title emoji disabled' do
|
||||
context "with title emoji disabled" do
|
||||
before do
|
||||
SiteSetting.disable_discourse_narrative_bot_welcome_post = false
|
||||
SiteSetting.max_emojis_in_title = 0
|
||||
end
|
||||
|
||||
it 'initiates the bot' do
|
||||
it "initiates the bot" do
|
||||
expect { user }.to change { Topic.count }.by(1)
|
||||
|
||||
expect(Topic.last.title).to eq(i18n_t(
|
||||
'discourse_narrative_bot.new_user_narrative.hello.title'
|
||||
).gsub(/:robot:/, '').strip)
|
||||
expect(Topic.last.title).to eq(
|
||||
i18n_t("discourse_narrative_bot.new_user_narrative.hello.title").gsub(
|
||||
/:robot:/,
|
||||
"",
|
||||
).strip,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when enabled' do
|
||||
before do
|
||||
SiteSetting.disable_discourse_narrative_bot_welcome_post = false
|
||||
end
|
||||
context "when enabled" do
|
||||
before { SiteSetting.disable_discourse_narrative_bot_welcome_post = false }
|
||||
|
||||
it 'initiate the bot' do
|
||||
it "initiate the bot" do
|
||||
expect { user }.to change { Topic.count }.by(1)
|
||||
|
||||
expect(Topic.last.title).to eq(i18n_t(
|
||||
'discourse_narrative_bot.new_user_narrative.hello.title'
|
||||
))
|
||||
expect(Topic.last.title).to eq(
|
||||
i18n_t("discourse_narrative_bot.new_user_narrative.hello.title"),
|
||||
)
|
||||
end
|
||||
|
||||
describe "when send welcome message is selected" do
|
||||
before do
|
||||
SiteSetting.discourse_narrative_bot_welcome_post_type = 'welcome_message'
|
||||
end
|
||||
before { SiteSetting.discourse_narrative_bot_welcome_post_type = "welcome_message" }
|
||||
|
||||
it 'should send the right welcome message' do
|
||||
it "should send the right welcome message" do
|
||||
expect { user }.to change { Topic.count }.by(1)
|
||||
|
||||
expect(Topic.last.title).to eq(i18n_t(
|
||||
"system_messages.welcome_user.subject_template",
|
||||
site_name: SiteSetting.title
|
||||
))
|
||||
expect(Topic.last.title).to eq(
|
||||
i18n_t("system_messages.welcome_user.subject_template", site_name: SiteSetting.title),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when welcome message is configured to be delayed' do
|
||||
before do
|
||||
SiteSetting.discourse_narrative_bot_welcome_post_delay = 100
|
||||
end
|
||||
describe "when welcome message is configured to be delayed" do
|
||||
before { SiteSetting.discourse_narrative_bot_welcome_post_delay = 100 }
|
||||
|
||||
it 'should delay the welcome post until user logs in' do
|
||||
it "should delay the welcome post until user logs in" do
|
||||
user
|
||||
|
||||
expect(Jobs::NarrativeInit.jobs.count).to eq(0)
|
||||
@@ -99,41 +96,37 @@ RSpec.describe User do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is staged' do
|
||||
context "when user is staged" do
|
||||
let(:user) { Fabricate(:user, staged: true) }
|
||||
|
||||
it 'should not initiate the bot' do
|
||||
it "should not initiate the bot" do
|
||||
expect { user }.to_not change { Post.count }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user skipped the new user tips' do
|
||||
context "when user skipped the new user tips" do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
it 'should not initiate the bot' do
|
||||
it "should not initiate the bot" do
|
||||
SiteSetting.default_other_skip_new_user_tips = true
|
||||
expect { user }.to_not change { Post.count }
|
||||
end
|
||||
|
||||
it 'should delete the existing PM' do
|
||||
it "should delete the existing PM" do
|
||||
user.user_option.skip_new_user_tips = true
|
||||
|
||||
expect {
|
||||
user.user_option.save!
|
||||
}.to change { Topic.count }.by(-1)
|
||||
.and not_change { UserHistory.count }
|
||||
.and change { user.unread_high_priority_notifications }.by(-1)
|
||||
.and change { user.notifications.count }.by(-1)
|
||||
expect { user.user_option.save! }.to change { Topic.count }.by(-1).and not_change {
|
||||
UserHistory.count
|
||||
}.and change { user.unread_high_priority_notifications }.by(-1).and change {
|
||||
user.notifications.count
|
||||
}.by(-1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is anonymous?' do
|
||||
before do
|
||||
SiteSetting.allow_anonymous_posting = true
|
||||
end
|
||||
|
||||
it 'should initiate bot for real user only' do
|
||||
context "when user is anonymous?" do
|
||||
before { SiteSetting.allow_anonymous_posting = true }
|
||||
|
||||
it "should initiate bot for real user only" do
|
||||
user = Fabricate(:user, trust_level: 1)
|
||||
shadow = AnonymousShadowCreator.get(user)
|
||||
|
||||
@@ -145,21 +138,19 @@ RSpec.describe User do
|
||||
context "when user's username should be ignored" do
|
||||
let(:user) { Fabricate.build(:user) }
|
||||
|
||||
before do
|
||||
SiteSetting.discourse_narrative_bot_ignored_usernames = 'discourse|test'
|
||||
end
|
||||
before { SiteSetting.discourse_narrative_bot_ignored_usernames = "discourse|test" }
|
||||
|
||||
['discourse', 'test'].each do |username|
|
||||
it 'should not initiate the bot' do
|
||||
%w[discourse test].each do |username|
|
||||
it "should not initiate the bot" do
|
||||
expect { user.update!(username: username) }.to_not change { Post.count }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when a user has been destroyed' do
|
||||
describe "when a user has been destroyed" do
|
||||
it "should clean up plugin's store" do
|
||||
DiscourseNarrativeBot::Store.set(user.id, 'test')
|
||||
DiscourseNarrativeBot::Store.set(user.id, "test")
|
||||
|
||||
user.destroy!
|
||||
|
||||
@@ -167,8 +158,8 @@ RSpec.describe User do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#manually_disabled_discobot?' do
|
||||
it 'returns true if the user manually disabled new user tips' do
|
||||
describe "#manually_disabled_discobot?" do
|
||||
it "returns true if the user manually disabled new user tips" do
|
||||
user.user_option.skip_new_user_tips = true
|
||||
|
||||
expect(user.manually_disabled_discobot?).to eq(true)
|
||||
|
||||
Reference in New Issue
Block a user