about summary refs log tree commit diff
path: root/app/lib/command_tag/command
diff options
context:
space:
mode:
authorFire Demon <firedemon@creature.cafe>2020-07-31 10:58:52 -0500
committerFire Demon <firedemon@creature.cafe>2020-08-30 05:45:16 -0500
commitd9339677d6daa33dc020cf3400c3dec210b06f31 (patch)
tree38de2c33e4f61df299348b89da2e9c8600d78247 /app/lib/command_tag/command
parent4c47a96f67d303dec7b6047474380050053ac3d7 (diff)
[Command Tags] Add support for persistent variables
Diffstat (limited to 'app/lib/command_tag/command')
-rw-r--r--app/lib/command_tag/command/account_tools.rb37
-rw-r--r--app/lib/command_tag/command/hello_world.rb11
-rw-r--r--app/lib/command_tag/command/parent_status_tools.rb80
-rw-r--r--app/lib/command_tag/command/status_tools.rb31
-rw-r--r--app/lib/command_tag/command/text_tools.rb58
-rw-r--r--app/lib/command_tag/command/variables.rb40
6 files changed, 257 insertions, 0 deletions
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'
+                    ["<pre><code>#{html_encode(value).gsub("\n", '<br/>')}</code></pre>"]
+                  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'
+      ["<pre><code>#{html_encode(value).gsub("\n", '<br/>')}</code></pre>"]
+    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