# 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.47 # 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) 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}") 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