about summary refs log tree commit diff
path: root/app/lib
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2021-09-26 18:28:59 +0200
committerClaire <claire.github-309c@sitedethib.com>2021-09-26 18:28:59 +0200
commit36221107784ad26735ca2703d4d597c90eacf526 (patch)
treeb52d1ee733383b3e702fe1562bd9962724fde8f5 /app/lib
parent4b7e43602691193b5d2a8e7e0ed6044bc8ee9774 (diff)
parenta0d4129893c797f78d28ba9df5d35646f7bb0d80 (diff)
Merge branch 'main' into glitch-soc/merge-upstream
Conflicts:
- `streaming/index.js`:
  Filtering code for streaming notifications has been refactored upstream, but
  glitch-soc had similar code for local-only toots in the same places.
  Ported upstream changes, but did not refactor local-only filtering.
Diffstat (limited to 'app/lib')
-rw-r--r--app/lib/permalink_redirector.rb63
1 files changed, 63 insertions, 0 deletions
diff --git a/app/lib/permalink_redirector.rb b/app/lib/permalink_redirector.rb
new file mode 100644
index 000000000..e48bce060
--- /dev/null
+++ b/app/lib/permalink_redirector.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+class PermalinkRedirector
+  include RoutingHelper
+
+  def initialize(path)
+    @path = path
+  end
+
+  def redirect_path
+    if path_segments[0] == 'web'
+      if path_segments[1].present? && path_segments[1].start_with?('@') && path_segments[2] =~ /\d/
+        find_status_url_by_id(path_segments[2])
+      elsif path_segments[1].present? && path_segments[1].start_with?('@')
+        find_account_url_by_name(path_segments[1])
+      elsif path_segments[1] == 'statuses' && path_segments[2] =~ /\d/
+        find_status_url_by_id(path_segments[2])
+      elsif path_segments[1] == 'accounts' && path_segments[2] =~ /\d/
+        find_account_url_by_id(path_segments[2])
+      elsif path_segments[1] == 'timelines' && path_segments[2] == 'tag' && path_segments[3].present?
+        find_tag_url_by_name(path_segments[3])
+      elsif path_segments[1] == 'tags' && path_segments[2].present?
+        find_tag_url_by_name(path_segments[2])
+      end
+    end
+  end
+
+  private
+
+  def path_segments
+    @path_segments ||= @path.gsub(/\A\//, '').split('/')
+  end
+
+  def find_status_url_by_id(id)
+    status = Status.find_by(id: id)
+
+    return unless status&.distributable?
+
+    ActivityPub::TagManager.instance.url_for(status)
+  end
+
+  def find_account_url_by_id(id)
+    account = Account.find_by(id: id)
+
+    return unless account
+
+    ActivityPub::TagManager.instance.url_for(account)
+  end
+
+  def find_account_url_by_name(name)
+    username, domain = name.gsub(/\A@/, '').split('@')
+    domain           = nil if TagManager.instance.local_domain?(domain)
+    account          = Account.find_remote(username, domain)
+
+    return unless account
+
+    ActivityPub::TagManager.instance.url_for(account)
+  end
+
+  def find_tag_url_by_name(name)
+    tag_path(CGI.unescape(name))
+  end
+end