discourse-legacy_links/plugin.rb
2024-09-09 12:34:53 +10:00

138 lines
5.4 KiB
Ruby

# plugins/discourse-legacy_links/plugin.rb
# frozen_string_literal: true
# name: discourse-legacy_links
# about: A plugin to handle legacy Gossamer Forums URLs
# version: 0.50
# authors: saint@federated.computer
# url: https://gitea.federated.computer/saint/discourse-legacy_links.git
# enabled_site_setting :discourse_legacy_links_enabled
after_initialize do
module ::DiscourseLegacyLinks
class Engine < ::Rails::Engine
engine_name "discourse_legacy_links"
isolate_namespace DiscourseLegacyLinks
end
end
require_dependency "application_controller"
class ::DiscourseLegacyLinks::LegacyLinksController < ::ApplicationController
skip_before_action :check_xhr, only: [:index]
def index2
render plain: "Legacy Links from Discourse plugin! Current user: #{current_user&.username || 'Guest'}"
end
def index
Rails.logger.info("DiscourseLegacyLinks: Handling request for URL: #{request.original_url}")
post_id = extract_post_id_from_request
if post_id
Rails.logger.info("DiscourseLegacyLinks: Extracted post_id: #{post_id}")
post = find_post_by_custom_field(post_id)
if post
Rails.logger.info("DiscourseLegacyLinks: Found matching post with id: #{post.id}")
redirect_to_post(post)
else
Rails.logger.warn("DiscourseLegacyLinks: No matching post found for post_id: #{post_id}")
render_not_found
end
else
Rails.logger.warn("DiscourseLegacyLinks: Unable to extract post_id from request")
render_bad_request
end
end
private
# Attempts to extract a post ID from various parts of the request
def extract_post_id_from_request
# post_id = params[:post_id].presence ||
# request.path.match(%r{/forum/[^/]+/P(\d+)/?})&.[](1) ||
# request.query_string.match(/post=(\d+)/)&.[](1) ||
# request.query_string.match(/parent_post_id=(\d+)/)&.[](1)
# post_id = params[:post_id].presence ||
# request.path.match(%r{/P(\d+)/?})&. || # Matches URLs like /P40796/
# request.path.match(%r{/forum/ || # Matches URLs like /forum/.../P6751045/
# request.query_string.match(/post=(\d+)/)&. || # Matches URLs with ?post= in query string
# request.query_string.match(/parent_post_id=(\d+)/)&. || # Matches URLs with ?parent_post_id= in query string
# request.path.match(%r{/forum/.*?_P(\d+)/?})&. # Matches URLs like /forum/..._P6751045/
post_id = params[:post_id].presence ||
request.path.match(%r{/P(\d+)(?:/|$)})&. || # Matches URLs like /P40796/ or /P40796 (no trailing slash)
request.path.match(%r{/forum/.*_P(\d+)(?:/|$)})&. || # Matches URLs like /forum/.../P6751045/ or /forum/.../P6751045
request.query_string.match(/post=(\d+)/)&. || # Matches URLs with ?post= in query string
request.query_string.match(/parent_post_id=(\d+)/)&. # Matches URLs with ?parent_post_id= in query string
Rails.logger.info("DiscourseLegacyLinks: Extracted raw post_id: #{post_id || 'nil'}")
post_id.to_i if post_id
end
# Finds a post by looking up the custom field on the associated topic
def find_post_by_custom_field(post_id)
Rails.logger.info("DiscourseLegacyLinks: Searching for post with original_gossamer_id: #{post_id}")
post_custom_field = PostCustomField.find_by(name: 'original_gossamer_id', value: post_id.to_s)
if post_custom_field
post = post_custom_field.post
Rails.logger.info("DiscourseLegacyLinks: Found post with id: #{post.id}")
post
else
Rails.logger.warn("DiscourseLegacyLinks: No post found with original_gossamer_id: #{post_id}")
nil
end
end
# def find_post_by_custom_field(post_id)
# Rails.logger.info("DiscourseLegacyLinks: Searching for post with original_gossamer_id: #{post_id}")
#
# topic = Topic.joins(:custom_fields)
# .where(topic_custom_fields: { name: 'original_gossamer_id', value: post_id.to_s })
# .first
#
# if topic
# post = topic.posts.first
# Rails.logger.info("DiscourseLegacyLinks: Found topic #{topic.id}, first post id: #{post&.id || 'nil'}")
# post
# else
# Rails.logger.warn("DiscourseLegacyLinks: No topic found with original_gossamer_id: #{post_id}")
# nil
# end
# end
# Redirects to the URL of the found post
def redirect_to_post(post)
Rails.logger.info("DiscourseLegacyLinks: Redirecting to post URL: #{post.url}")
redirect_to post.url, status: :moved_permanently
end
# Renders a 404 Not Found response
def render_not_found
Rails.logger.info("DiscourseLegacyLinks: Rendering 404 Not Found")
render plain: 'Post not found', status: :not_found
end
# Renders a 400 Bad Request response
def render_bad_request
Rails.logger.info("DiscourseLegacyLinks: Rendering 400 Bad Request")
render plain: 'Invalid URL', status: :bad_request
end
end
# Rails.logger.info("DiscourseLegacyLinks: initialistaion")
DiscourseLegacyLinks::Engine.routes.draw do
get "/forum" => "legacy_links#index"
get "/forum/*path" => "legacy_links#index"
end
Discourse::Application.routes.append do
mount ::DiscourseLegacyLinks::Engine, at: "/"
end
end