From 4b229e11d875d1a57a381eeb1a5d9ec9f72ec503 Mon Sep 17 00:00:00 2001 From: Fire Demon Date: Fri, 24 Jul 2020 04:38:43 -0500 Subject: [Command Tags] Preload statement handlers --- app/lib/command_tag/commands/hello_world.rb | 2 +- .../command_tag/commands/parent_status_tools.rb | 15 +++--- app/lib/command_tag/processor.rb | 60 +++++++++++++++++----- 3 files changed, 54 insertions(+), 23 deletions(-) (limited to 'app/lib') diff --git a/app/lib/command_tag/commands/hello_world.rb b/app/lib/command_tag/commands/hello_world.rb index 4cf17685e..581b21317 100644 --- a/app/lib/command_tag/commands/hello_world.rb +++ b/app/lib/command_tag/commands/hello_world.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module CommandTag::Commands::HelloWorld - def handle_hello_world_at_start + def handle_hello_world_at_start(_) @text << "\nHello, 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 index df3cd06c6..ab917e8f5 100644 --- a/app/lib/command_tag/commands/parent_status_tools.rb +++ b/app/lib/command_tag/commands/parent_status_tools.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true - -# rubocop:disable Layout/ExtraSpacing module CommandTag::Commands::ParentStatusTools - def handle_publish_once_at_end + def handle_publish_once_at_end(_) return unless author_of_parent? && !@parent.published? PublishStatusService.new.call(@parent) @@ -13,7 +11,7 @@ module CommandTag::Commands::ParentStatusTools alias handle_publish_toot_once_at_end handle_publish_once_at_end alias handle_publish_parent_once_at_end handle_publish_once_at_end - def handle_edit_once_before_save + def handle_edit_once_before_save(_) return unless author_of_parent? params = @parent.slice(*UpdateStatusService::ALLOWED_ATTRIBUTES).with_indifferent_access.compact @@ -27,7 +25,7 @@ module CommandTag::Commands::ParentStatusTools 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 + def handle_mute_once_at_end(_) return if author_of_parent? MuteStatusService.new.call(@account, @parent) @@ -43,7 +41,7 @@ module CommandTag::Commands::ParentStatusTools 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 + def handle_unmute_once_at_end(_) return if author_of_parent? @account.unmute_status!(@parent) @@ -59,7 +57,7 @@ module CommandTag::Commands::ParentStatusTools 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 + def handle_mute_thread_once_at_end(_) return if author_of_parent? MuteConversationService.new.call(@account, @conversation) @@ -69,7 +67,7 @@ module CommandTag::Commands::ParentStatusTools 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 + def handle_unmute_thread_once_at_end(_) return if author_of_parent? || @conversation.blank? @account.unmute_conversation!(@conversation) @@ -79,4 +77,3 @@ module CommandTag::Commands::ParentStatusTools 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 -# rubocop:enable Layout/ExtraSpacing diff --git a/app/lib/command_tag/processor.rb b/app/lib/command_tag/processor.rb index 66a507f23..864da6c59 100644 --- a/app/lib/command_tag/processor.rb +++ b/app/lib/command_tag/processor.rb @@ -1,7 +1,18 @@ # frozen_string_literal: true +# .~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~. # +################### Cthulhu Code! ################### +# `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~` # +# - Interprets and executes user input. THIS CAN BE VERY DANGEROUS! # +# - Has a high complexity level and needs tests. # +# - May destroy objects passed to it. # +# - Incurs a high performance penalty. # +# # +############################################################################### + class CommandTag::Processor include Redisable + include ImgProxyHelper include CommandTag::Commands STATEMENT_RE = /^\s*#!\s*([^\n]+ (?:start|begin|do)$.*)\n\s*#!\s*(?:end|stop|done)\s*$|^\s*#!\s*(.*?)\s*$/im.freeze @@ -15,6 +26,7 @@ class CommandTag::Processor @run_once = Set[] @vars = {} @text = prepare_input(status.text) + @statements = [] return unless @account.present? && @account.local? && @status.present? end @@ -22,7 +34,7 @@ class CommandTag::Processor def process! reset_status_caches - @statements = parse_statements + parse_statements @text = @text.gsub(STATEMENT_STRIP_RE, '').split("\n") %w(at_start once_at_start).each { |suffix| execute_statements(suffix) } @@ -39,10 +51,14 @@ class CommandTag::Processor end elsif @status.destroyed? %w(after_destroy once_after_destroy).each { |suffix| execute_statements(suffix) } - elsif @status.update(text: process_inline_images(@text)) - %w(after_save once_after_save).each { |suffix| execute_statements(suffix) } else - %w(after_save_fail once_after_save_fail).each { |suffix| execute_statements(suffix) } + @status.text = @text + process_inline_images! + if @status.save + %w(after_save once_after_save).each { |suffix| execute_statements(suffix) } + else + %w(after_save_fail once_after_save_fail).each { |suffix| execute_statements(suffix) } + end end %w(at_end once_at_end).each { |suffix| execute_statements(suffix) } @@ -57,21 +73,39 @@ class CommandTag::Processor end def parse_statements - @text.scan(STATEMENT_RE).flatten.map do |statement| + @text.scan(STATEMENT_RE).flatten.each do |statement| next if statement.blank? || statement[0]&.strip.blank? statement = statement.scan(/^(.*) (?:start|begin|do)$(.*)|'([^']*)'|"([^"]*)"|(\S+)/im).flatten.compact statement[0] = statement[0].strip.tr(':.\- ', '_').gsub(/__+/, '_').downcase - statement - end.compact + add_statement_handlers_for(statement) + end + end + + def potential_handlers_for(name) + ['_once', ''].each_with_index do |count_affix, index| + %w(at_start when_blank at_end).each do |when_affix| + yield ["handle_#{name}#{count_affix}_#{when_affix}", index.zero?] + end + + %w(destroy save postprocess save_fail).each do |event_affix| + %w(before after).each do |when_affix| + yield ["handle_#{name}#{count_affix}_#{when_affix}_#{event_affix}", index.zero?] + end + end + end + end + + def add_statement_handlers_for(statement_array) + potential_handlers_for(statement_array[0]) do |handler, once| + (@statements << [handler, statement_array[1..-1]]) if respond_to?(handler) && !(once && @run_once.include?(handler)) + @run_once << handler if once + end end - def execute_statements(suffix) - @statements.each do |statement| - name = "handle_#{statement[0]}_#{suffix}" - is_run_once = suffix.start_with?('once_') - public_send(name, statement[1..-1]) if respond_to?(name) && !(is_run_once && @run_once.include?(name)) - @run_once << name if is_run_once + def execute_statements(event) + @statements.select { |handler, _| handler.end_with?("_#{event}") }.each do |handler, arguments| + public_send(handler, arguments) end end -- cgit