diff options
Diffstat (limited to 'app/lib/command_tag/processor.rb')
-rw-r--r-- | app/lib/command_tag/processor.rb | 60 |
1 files changed, 47 insertions, 13 deletions
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 |