From d9339677d6daa33dc020cf3400c3dec210b06f31 Mon Sep 17 00:00:00 2001 From: Fire Demon Date: Fri, 31 Jul 2020 10:58:52 -0500 Subject: [Command Tags] Add support for persistent variables --- app/lib/command_tag/command/account_tools.rb | 37 ++++++++++ app/lib/command_tag/command/hello_world.rb | 11 +++ app/lib/command_tag/command/parent_status_tools.rb | 80 ++++++++++++++++++++++ app/lib/command_tag/command/status_tools.rb | 31 +++++++++ app/lib/command_tag/command/text_tools.rb | 58 ++++++++++++++++ app/lib/command_tag/command/variables.rb | 40 +++++++++++ app/lib/command_tag/commands.rb | 5 +- app/lib/command_tag/commands/account_tools.rb | 37 ---------- app/lib/command_tag/commands/hello_world.rb | 11 --- .../command_tag/commands/parent_status_tools.rb | 80 ---------------------- app/lib/command_tag/commands/status_tools.rb | 31 --------- app/lib/command_tag/commands/text_tools.rb | 58 ---------------- app/lib/command_tag/commands/variables.rb | 22 ------ app/lib/command_tag/processor.rb | 2 + 14 files changed, 263 insertions(+), 240 deletions(-) create mode 100644 app/lib/command_tag/command/account_tools.rb create mode 100644 app/lib/command_tag/command/hello_world.rb create mode 100644 app/lib/command_tag/command/parent_status_tools.rb create mode 100644 app/lib/command_tag/command/status_tools.rb create mode 100644 app/lib/command_tag/command/text_tools.rb create mode 100644 app/lib/command_tag/command/variables.rb delete mode 100644 app/lib/command_tag/commands/account_tools.rb delete mode 100644 app/lib/command_tag/commands/hello_world.rb delete mode 100644 app/lib/command_tag/commands/parent_status_tools.rb delete mode 100644 app/lib/command_tag/commands/status_tools.rb delete mode 100644 app/lib/command_tag/commands/text_tools.rb delete mode 100644 app/lib/command_tag/commands/variables.rb (limited to 'app') diff --git a/app/lib/command_tag/command/account_tools.rb b/app/lib/command_tag/command/account_tools.rb new file mode 100644 index 000000000..6d2e8eca3 --- /dev/null +++ b/app/lib/command_tag/command/account_tools.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +module CommandTag::Command::AccountTools + def handle_account_at_start(args) + return if args[0].blank? + + case args[0].downcase + when 'set' + handle_account_set(args[1..-1]) + end + end + + alias handle_acct_at_start handle_account_at_start + + private + + def handle_account_set(args) + return if args[0].blank? + + case args[0].downcase + when 'v', 'p', 'visibility', 'privacy', 'default-visibility', 'default-privacy' + args[1] = read_visibility_from(args[1]) + return if args[1].blank? + + if args[2].blank? + @account.user.settings.default_privacy = args[1] + elsif args[1] == 'public' + domains = args[2..-1].map { |domain| normalize_domain(domain) unless domain == '*' }.uniq.compact + @account.domain_permissions.where(domain: domains).destroy_all if domains.present? + else + args[2..-1].flat_map(&:split).uniq.each do |domain| + domain = normalize_domain(domain) unless domain == '*' + @account.domain_permissions.create_or_update(domain: domain, visibility: args[1]) if domain.present? + end + end + end + end +end diff --git a/app/lib/command_tag/command/hello_world.rb b/app/lib/command_tag/command/hello_world.rb new file mode 100644 index 000000000..ab10b495b --- /dev/null +++ b/app/lib/command_tag/command/hello_world.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module CommandTag::Command::HelloWorld + def handle_helloworld_startup + @vars['hello_world'] = ['Hello, world!'] + end + + def handle_hello_world_with_return(_) + 'Hello, world!' + end +end diff --git a/app/lib/command_tag/command/parent_status_tools.rb b/app/lib/command_tag/command/parent_status_tools.rb new file mode 100644 index 000000000..5f127b2da --- /dev/null +++ b/app/lib/command_tag/command/parent_status_tools.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true +module CommandTag::Command::ParentStatusTools + def handle_publish_once_at_end(_) + is_blank = status_text_blank? + @status.published = true if @parent.blank? || !is_blank? + return unless is_blank && author_of_parent? && !@parent.published? + + PublishStatusService.new.call(@parent) + end + + alias handle_publish_post_once_at_end handle_publish_once_at_end + alias handle_publish_roar_once_at_end handle_publish_once_at_end + alias handle_publish_toot_once_at_end handle_publish_once_at_end + + def handle_edit_once_before_save(_) + return unless author_of_parent? + + params = @parent.slice(*UpdateStatusService::ALLOWED_ATTRIBUTES).with_indifferent_access.compact + params[:text] = @text + UpdateStatusService.new.call(@parent, params) + destroy_status! + end + + alias handle_edit_post_once_before_save handle_edit_once_before_save + alias handle_edit_roar_once_before_save handle_edit_once_before_save + alias handle_edit_toot_once_before_save handle_edit_once_before_save + alias handle_edit_parent_once_before_save handle_edit_once_before_save + + def handle_mute_once_at_end(_) + return if author_of_parent? + + MuteStatusService.new.call(@account, @parent) + end + + alias handle_mute_post_once_at_end handle_mute_once_at_end + alias handle_mute_roar_once_at_end handle_mute_once_at_end + alias handle_mute_toot_once_at_end handle_mute_once_at_end + alias handle_mute_parent_once_at_end handle_mute_once_at_end + alias handle_hide_once_at_end handle_mute_once_at_end + alias handle_hide_post_once_at_end handle_mute_once_at_end + alias handle_hide_roar_once_at_end handle_mute_once_at_end + alias handle_hide_toot_once_at_end handle_mute_once_at_end + alias handle_hide_parent_once_at_end handle_mute_once_at_end + + def handle_unmute_once_at_end(_) + return if author_of_parent? + + @account.unmute_status!(@parent) + end + + alias handle_unmute_post_once_at_end handle_unmute_once_at_end + alias handle_unmute_roar_once_at_end handle_unmute_once_at_end + alias handle_unmute_toot_once_at_end handle_unmute_once_at_end + alias handle_unmute_parent_once_at_end handle_unmute_once_at_end + alias handle_unhide_once_at_end handle_unmute_once_at_end + alias handle_unhide_post_once_at_end handle_unmute_once_at_end + alias handle_unhide_roar_once_at_end handle_unmute_once_at_end + alias handle_unhide_toot_once_at_end handle_unmute_once_at_end + alias handle_unhide_parent_once_at_end handle_unmute_once_at_end + + def handle_mute_thread_once_at_end(_) + return if author_of_parent? + + MuteConversationService.new.call(@account, @conversation) + end + + alias handle_mute_conversation_once_at_end handle_mute_thread_once_at_end + alias handle_hide_thread_once_at_end handle_mute_thread_once_at_end + alias handle_hide_conversation_once_at_end handle_mute_thread_once_at_end + + def handle_unmute_thread_once_at_end(_) + return if author_of_parent? || @conversation.blank? + + @account.unmute_conversation!(@conversation) + end + + alias handle_unmute_conversation_once_at_end handle_unmute_thread_once_at_end + alias handle_unhide_thread_once_at_end handle_unmute_thread_once_at_end + alias handle_unhide_conversation_once_at_end handle_unmute_thread_once_at_end +end diff --git a/app/lib/command_tag/command/status_tools.rb b/app/lib/command_tag/command/status_tools.rb new file mode 100644 index 000000000..7187ebd24 --- /dev/null +++ b/app/lib/command_tag/command/status_tools.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true +module CommandTag::Command::StatusTools + def handle_title_before_save(args) + return unless author_of_status? + + @status.title = args[0] + end + + def handle_visibility_before_save(args) + return unless author_of_status? && args[0].present? + + args[0] = read_visibility_from(args[0]) + return if args[0].blank? + + if args[1].blank? + @status.visibility = args[0].to_sym + elsif args[0] == @status.visibility.to_s + domains = args[1..-1].map { |domain| normalize_domain(domain) unless domain == '*' }.uniq.compact + @status.domain_permissions.where(domain: domains).destroy_all if domains.present? + else + args[1..-1].flat_map(&:split).uniq.each do |domain| + domain = normalize_domain(domain) unless domain == '*' + @status.domain_permissions.create_or_update(domain: domain, visibility: args[0]) if domain.present? + end + end + end + + alias handle_v_before_save handle_visibility_before_save + alias handle_p_before_save handle_visibility_before_save + alias handle_privacy_before_save handle_visibility_before_save +end diff --git a/app/lib/command_tag/command/text_tools.rb b/app/lib/command_tag/command/text_tools.rb new file mode 100644 index 000000000..2c44167b4 --- /dev/null +++ b/app/lib/command_tag/command/text_tools.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +module CommandTag::Command::TextTools + def handle_code_at_start(args) + return if args.count < 2 + + name = normalize(args[0]) + value = args.last.presence || '' + @vars[name] = case @status.content_type + when 'text/markdown' + ["```\n#{value}\n```"] + when 'text/html' + ["
#{html_encode(value).gsub("\n", '
')}
"] + else + ["----------\n#{value}\n----------"] + end + end + + def handle_code_with_return(args) + return if args.count > 1 + + value = args.last.presence || '' + case @status.content_type + when 'text/markdown' + ["```\n#{value}\n```"] + when 'text/html' + ["
#{html_encode(value).gsub("\n", '
')}
"] + else + ["----------\n#{value}\n----------"] + end + end + + def handle_prepend_before_save(args) + args.each { |arg| @text = "#{arg}\n#{text}" } + end + + def handle_append_before_save(args) + args.each { |arg| @text << "\n#{arg}" } + end + + def handle_replace_before_save(args) + @text.gsub!(args[0], args[1] || '') + end + + alias handle_sub_before_save handle_replace_before_save + + def handle_regex_replace_before_save(args) + flags = normalize(args[2]) + re_opts = (flags.include?('i') ? Regexp::IGNORECASE : 0) + re_opts |= (flags.include?('x') ? Regexp::EXTENDED : 0) + re_opts |= (flags.include?('m') ? Regexp::MULTILINE : 0) + + @text.gsub!(Regexp.new(args[0], re_opts), args[1] || '') + end + + alias handle_resub_before_save handle_replace_before_save + alias handle_regex_sub_before_save handle_replace_before_save +end diff --git a/app/lib/command_tag/command/variables.rb b/app/lib/command_tag/command/variables.rb new file mode 100644 index 000000000..b0781d1aa --- /dev/null +++ b/app/lib/command_tag/command/variables.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module CommandTag::Command::Variables + def handle_variables_startup + @vars.merge!(persistent_vars_from(@account.metadata.fields)) if @account.metadata.present? + end + + def handle_variables_shutdown + @account.metadata.update!(fields: nonpersistent_vars_from(@account.metadata.fields).merge(persistent_vars_from(@vars))) + end + + def handle_set_at_start(args) + return if args.blank? + + args[0] = normalize(args[0]) + + case args.count + when 1 + @vars.delete(args[0]) + else + @vars[args[0]] = args[1..-1] + end + end + + def do_unset_at_start(args) + args.each do |arg| + @vars.delete(normalize(arg)) + end + end + + private + + def persistent_vars_from(vars) + vars.select { |key, value| key.start_with?('persist:') && value.present? && value.is_a?(Array) } + end + + def nonpersistent_vars_from(vars) + vars.reject { |key, value| key.start_with?('persist:') || value.blank? } + end +end diff --git a/app/lib/command_tag/commands.rb b/app/lib/command_tag/commands.rb index 0248e6e99..f27486427 100644 --- a/app/lib/command_tag/commands.rb +++ b/app/lib/command_tag/commands.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true + +Dir[File.join(__dir__, 'command', '*.rb')].sort.each { |file| require file } + module CommandTag::Commands def self.included(base) - CommandTag::Commands.constants.map(&CommandTag::Commands.method(:const_get)).grep(Module) do |mod| + CommandTag::Command.constants.map(&CommandTag::Command.method(:const_get)).grep(Module) do |mod| base.include(mod) end end diff --git a/app/lib/command_tag/commands/account_tools.rb b/app/lib/command_tag/commands/account_tools.rb deleted file mode 100644 index 473df7a39..000000000 --- a/app/lib/command_tag/commands/account_tools.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true -module CommandTag::Commands::AccountTools - def handle_account_at_start(args) - return if args[0].blank? - - case args[0].downcase - when 'set' - handle_account_set(args[1..-1]) - end - end - - alias handle_acct_at_start handle_account_at_start - - private - - def handle_account_set(args) - return if args[0].blank? - - case args[0].downcase - when 'v', 'p', 'visibility', 'privacy', 'default-visibility', 'default-privacy' - args[1] = read_visibility_from(args[1]) - return if args[1].blank? - - if args[2].blank? - @account.user.settings.default_privacy = args[1] - elsif args[1] == 'public' - domains = args[2..-1].map { |domain| normalize_domain(domain) unless domain == '*' }.uniq.compact - @account.domain_permissions.where(domain: domains).destroy_all if domains.present? - else - args[2..-1].flat_map(&:split).uniq.each do |domain| - domain = normalize_domain(domain) unless domain == '*' - @account.domain_permissions.create_or_update(domain: domain, visibility: args[1]) if domain.present? - end - end - end - end -end diff --git a/app/lib/command_tag/commands/hello_world.rb b/app/lib/command_tag/commands/hello_world.rb deleted file mode 100644 index cc770ef80..000000000 --- a/app/lib/command_tag/commands/hello_world.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module CommandTag::Commands::HelloWorld - def handle_helloworld_startup - @vars['hello_world'] = ['Hello, world!'] - end - - def handle_hello_world_with_return(_) - 'Hello, world!' - end -end diff --git a/app/lib/command_tag/commands/parent_status_tools.rb b/app/lib/command_tag/commands/parent_status_tools.rb deleted file mode 100644 index d19cf902b..000000000 --- a/app/lib/command_tag/commands/parent_status_tools.rb +++ /dev/null @@ -1,80 +0,0 @@ -# frozen_string_literal: true -module CommandTag::Commands::ParentStatusTools - def handle_publish_once_at_end(_) - is_blank = status_text_blank? - @status.published = true if @parent.blank? || !is_blank? - return unless is_blank && author_of_parent? && !@parent.published? - - PublishStatusService.new.call(@parent) - end - - alias handle_publish_post_once_at_end handle_publish_once_at_end - alias handle_publish_roar_once_at_end handle_publish_once_at_end - alias handle_publish_toot_once_at_end handle_publish_once_at_end - - def handle_edit_once_before_save(_) - return unless author_of_parent? - - params = @parent.slice(*UpdateStatusService::ALLOWED_ATTRIBUTES).with_indifferent_access.compact - params[:text] = @text - UpdateStatusService.new.call(@parent, params) - destroy_status! - end - - alias handle_edit_post_once_before_save handle_edit_once_before_save - alias handle_edit_roar_once_before_save handle_edit_once_before_save - alias handle_edit_toot_once_before_save handle_edit_once_before_save - alias handle_edit_parent_once_before_save handle_edit_once_before_save - - def handle_mute_once_at_end(_) - return if author_of_parent? - - MuteStatusService.new.call(@account, @parent) - end - - alias handle_mute_post_once_at_end handle_mute_once_at_end - alias handle_mute_roar_once_at_end handle_mute_once_at_end - alias handle_mute_toot_once_at_end handle_mute_once_at_end - alias handle_mute_parent_once_at_end handle_mute_once_at_end - alias handle_hide_once_at_end handle_mute_once_at_end - alias handle_hide_post_once_at_end handle_mute_once_at_end - alias handle_hide_roar_once_at_end handle_mute_once_at_end - alias handle_hide_toot_once_at_end handle_mute_once_at_end - alias handle_hide_parent_once_at_end handle_mute_once_at_end - - def handle_unmute_once_at_end(_) - return if author_of_parent? - - @account.unmute_status!(@parent) - end - - alias handle_unmute_post_once_at_end handle_unmute_once_at_end - alias handle_unmute_roar_once_at_end handle_unmute_once_at_end - alias handle_unmute_toot_once_at_end handle_unmute_once_at_end - alias handle_unmute_parent_once_at_end handle_unmute_once_at_end - alias handle_unhide_once_at_end handle_unmute_once_at_end - alias handle_unhide_post_once_at_end handle_unmute_once_at_end - alias handle_unhide_roar_once_at_end handle_unmute_once_at_end - alias handle_unhide_toot_once_at_end handle_unmute_once_at_end - alias handle_unhide_parent_once_at_end handle_unmute_once_at_end - - def handle_mute_thread_once_at_end(_) - return if author_of_parent? - - MuteConversationService.new.call(@account, @conversation) - end - - alias handle_mute_conversation_once_at_end handle_mute_thread_once_at_end - alias handle_hide_thread_once_at_end handle_mute_thread_once_at_end - alias handle_hide_conversation_once_at_end handle_mute_thread_once_at_end - - def handle_unmute_thread_once_at_end(_) - return if author_of_parent? || @conversation.blank? - - @account.unmute_conversation!(@conversation) - end - - alias handle_unmute_conversation_once_at_end handle_unmute_thread_once_at_end - alias handle_unhide_thread_once_at_end handle_unmute_thread_once_at_end - alias handle_unhide_conversation_once_at_end handle_unmute_thread_once_at_end -end diff --git a/app/lib/command_tag/commands/status_tools.rb b/app/lib/command_tag/commands/status_tools.rb deleted file mode 100644 index d00efe054..000000000 --- a/app/lib/command_tag/commands/status_tools.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true -module CommandTag::Commands::StatusTools - def handle_title_before_save(args) - return unless author_of_status? - - @status.title = args[0] - end - - def handle_visibility_before_save(args) - return unless author_of_status? && args[0].present? - - args[0] = read_visibility_from(args[0]) - return if args[0].blank? - - if args[1].blank? - @status.visibility = args[0].to_sym - elsif args[0] == @status.visibility.to_s - domains = args[1..-1].map { |domain| normalize_domain(domain) unless domain == '*' }.uniq.compact - @status.domain_permissions.where(domain: domains).destroy_all if domains.present? - else - args[1..-1].flat_map(&:split).uniq.each do |domain| - domain = normalize_domain(domain) unless domain == '*' - @status.domain_permissions.create_or_update(domain: domain, visibility: args[0]) if domain.present? - end - end - end - - alias handle_v_before_save handle_visibility_before_save - alias handle_p_before_save handle_visibility_before_save - alias handle_privacy_before_save handle_visibility_before_save -end diff --git a/app/lib/command_tag/commands/text_tools.rb b/app/lib/command_tag/commands/text_tools.rb deleted file mode 100644 index e004c7bec..000000000 --- a/app/lib/command_tag/commands/text_tools.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -module CommandTag::Commands::TextTools - def handle_code_at_start(args) - return if args.count < 2 - - name = normalize(args[0]) - value = args.last.presence || '' - @vars[name] = case @status.content_type - when 'text/markdown' - ["```\n#{value}\n```"] - when 'text/html' - ["
#{html_encode(value).gsub("\n", '
')}
"] - else - ["----------\n#{value}\n----------"] - end - end - - def handle_code_with_return(args) - return if args.count > 1 - - value = args.last.presence || '' - case @status.content_type - when 'text/markdown' - ["```\n#{value}\n```"] - when 'text/html' - ["
#{html_encode(value).gsub("\n", '
')}
"] - else - ["----------\n#{value}\n----------"] - end - end - - def handle_prepend_before_save(args) - args.each { |arg| @text = "#{arg}\n#{text}" } - end - - def handle_append_before_save(args) - args.each { |arg| @text << "\n#{arg}" } - end - - def handle_replace_before_save(args) - @text.gsub!(args[0], args[1] || '') - end - - alias handle_sub_before_save handle_replace_before_save - - def handle_regex_replace_before_save(args) - flags = normalize(args[2]) - re_opts = (flags.include?('i') ? Regexp::IGNORECASE : 0) - re_opts |= (flags.include?('x') ? Regexp::EXTENDED : 0) - re_opts |= (flags.include?('m') ? Regexp::MULTILINE : 0) - - @text.gsub!(Regexp.new(args[0], re_opts), args[1] || '') - end - - alias handle_resub_before_save handle_replace_before_save - alias handle_regex_sub_before_save handle_replace_before_save -end diff --git a/app/lib/command_tag/commands/variables.rb b/app/lib/command_tag/commands/variables.rb deleted file mode 100644 index 997131cd9..000000000 --- a/app/lib/command_tag/commands/variables.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module CommandTag::Commands::Variables - def handle_set_at_start(args) - return if args.blank? - - args[0] = normalize(args[0]) - - case args.count - when 1 - @vars.delete(args[0]) - else - @vars[args[0]] = args[1..-1] - end - end - - def do_unset_at_start(args) - args.each do |arg| - @vars.delete(normalize(arg)) - end - end -end diff --git a/app/lib/command_tag/processor.rb b/app/lib/command_tag/processor.rb index aba7be158..13c987fec 100644 --- a/app/lib/command_tag/processor.rb +++ b/app/lib/command_tag/processor.rb @@ -10,6 +10,8 @@ # # ############################################################################### +require_relative 'commands' + class CommandTag::Processor include Redisable include ImgProxyHelper -- cgit