From 5a750b947a2cd6acb98c9136ef73789c0670bcd5 Mon Sep 17 00:00:00 2001 From: saint Date: Mon, 9 Sep 2024 11:54:02 +1000 Subject: [PATCH] 0.46 More rewrite based on recent success with blocker. --- plugin.first | 174 +++++++++++++++++++++++++++++++++++++++++++ plugin.rb | 204 ++++++++++++++++++--------------------------------- 2 files changed, 244 insertions(+), 134 deletions(-) create mode 100644 plugin.first diff --git a/plugin.first b/plugin.first new file mode 100644 index 0000000..6d8643c --- /dev/null +++ b/plugin.first @@ -0,0 +1,174 @@ +# 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.44 +# 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" + + # Define the custom controller, inheriting from Discourse's CustomPostController + # This gives us access to post-related functionality and user authentication +# class DiscourseLegacyLinks::CustomPostController < ::ApplicationController +# class LegacyLinksController::CustomPostController < ::ApplicationController +# class LegacyLinksController < ::ApplicationController::CustomPostController + +# layout false + + # Skip certain before_actions for our index method. + # This allows the route to be accessed directly via a browser +## skip_before_action :check_xhr, only: [:index2] +## skip_before_action :verify_authenticity_token, only: [:index2] +# skip_before_action :verify_authenticity_token +# skip_before_action :ensure_logged_in +# skip_before_action :redirect_to_login_if_required +# skip_before_action :check_xhr +# skip_before_action :ensure_staff + + def index2 + Rails.logger.warn "[WARN WARN WARN WARN WARN WARN WARN WARN WARN WARN AMDG JMJ PAX WARN WARN WARN WARN]" + render plain: "Test route JMJ" +# render html: '

JMJ

' + end + + # Match URLs that include a post_id at the end or query parameter + # Main action triggered when the route is matched. + def index + Rails.logger.warn "[DEBUG] Reached the index action" + + # Log all incoming parameters to see what's being passed + Rails.logger.warn "[DEBUG] Params: #{params.inspect}" + post_id = extract_post_id_from_request + + if post_id + Rails.logger.warn "[DEBUG] Processing request for post_id: #{post_id}" + post = find_post_by_custom_field(post_id) + + if post + # Redirect to the post URL if found + Rails.logger.warn "[DEBUG] Redirecting to post with ID: #{post.id}" + # redirect_to post_url(post) + redirect_to_post(post) + else + # Return 404 if the post is not found + Rails.logger.warn "[ERROR] Post with original_gossamer_id #{post_id} not found" + render plain: 'Post not found', status: 404 + end + else + # Handle cases where the post_id cannot be extracted + Rails.logger.warn "[ERROR] Could not extract post_id from the request" + render plain: 'Invalid URL', status: 400 + end + end + + private + + # Extracts the post ID from the request URL or query string. + # Supports various formats of legacy forum URLs. + # @return [Integer, nil] The extracted post ID or nil if not found + def extract_post_id_from_request + # Check if post_id is passed as a query parameter (?post=post_id) + if params[:post_id] + post_id = params[:post_id].to_i + Rails.logger.warn "[DEBUG] Extracted post_id from query param: #{post_id}" + return post_id + end + + # Check for post_id in the URL path (e.g., /forum/.../P12345/) + if match = request.path.match(%r{/forum/[^/]+/P(\d+)/?}) + post_id = match[1].to_i + Rails.logger.warn "[DEBUG] Extracted post_id from URL path: #{post_id}" + return post_id + end + + # Check for post_id in the query string (e.g., ?post=12345) + if match = request.query_string.match(/post=(\d+)/) + post_id = match[1].to_i + Rails.logger.warn "[DEBUG] Extracted post_id from query string (?post=): #{post_id}" + return post_id + end + + # Check for parent_post_id in the query string (e.g., ?parent_post_id=12345) + if match = request.query_string.match(/parent_post_id=(\d+)/) + post_id = match[1].to_i + Rails.logger.warn "[DEBUG] Extracted parent_post_id from query string: #{post_id}" + return post_id + end + + # If no post_id was found in any format + Rails.logger.warn "[DEBUG] Could not extract post_id from request" + nil + end + + # Finds the Discourse post that has the specified custom field value. + # The custom field used is 'original_gossamer_id'. + # @param post_id [Integer] The extracted Gossamer forum post ID + # @return [Post, nil] The corresponding Discourse post or nil if not found + def find_post_by_custom_field(post_id) + Rails.logger.warn "[DEBUG] Searching for post with custom field 'original_gossamer_id' and value #{post_id}" + + # Use ActiveRecord query to find the post by the custom field value + post = Post.joins(:topic_custom_fields) + .where(topic_custom_fields: { name: 'original_gossamer_id', value: post_id.to_s }) + .first + + if post + Rails.logger.warn "[DEBUG] Found post with ID: #{post.id} for original_gossamer_id: #{post_id}" + else + Rails.logger.warn "[DEBUG] No post found for original_gossamer_id: #{post_id}" + end + + post + end + + # Redirects to the specified Discourse post. + # @param post [Post] The Discourse post to redirect to + def redirect_to_post(post) + topic_url = "#{Discourse.base_url}/t/#{post.topic_id}/#{post.post_number}" + Rails.logger.warn "[DEBUG] Redirecting to topic URL: #{topic_url}" + redirect topic_url + end + end + end + + Rails.logger.warn "[DEBUG DEBUG DEBUG DEBUG DEBUG WOW WOW WOW]" +# Rails.application.routes.routes.each do |route| +# Rails.logger.warn "[ROUTE] #{route.path.spec}" +# end +# +# Discourse::Application.routes.append do +# Discourse::Application.routes.prepend do +# get '/forum/*path', to: 'discourse_legacy_links/custom_post#index', constraints: lambda { |req| !Permalink.exists?(url: req.path) } +# get '/forum', to: 'discourse_legacy_links/custom_post#index', constraints: lambda { |request| Rails.logger.warn("[DEBUG] NoStarForum Route matched: #{request.path}") } +# get '/forum/*path', to: 'discourse_legacy_links/custom_post#index', constraints: lambda { |request| Rails.logger.warn("[DEBUG] StarForum Route matched: #{request.path}") } +# get '/forum2', to: 'discourse_legacy_links/custom_post#index2', constraints: lambda { |request| Rails.logger.warn("[DEBUG] NoStarTestRoute Route matched: #{request.path}") } +# get '/forum2/*path', to: 'discourse_legacy_links/custom_post#index2', constraints: lambda { |request| Rails.logger.warn("[DEBUG] StarTestRoute Route matched: #{request.path}") } +# get '/forum2' => "'discourse_legacy_links/custom_post#index2' +# get '/forum/*path' => 'discourse_legacy_links/custom_post#index' +# get '/forum' => 'discourse_legacy_links/custom_post#index' + +# # Register custom routes to handle legacy URLs +# DiscourseLegacyLinks::Engine.routes.draw do +# get "/forum2" => "legacy_links#index2" +# end + +# Discourse::Application.routes.append do +# mount ::DiscourseLegacyLinks::Engine, at: "/" +# end + +end + diff --git a/plugin.rb b/plugin.rb index b1c0e3a..a6fd50d 100644 --- a/plugin.rb +++ b/plugin.rb @@ -4,173 +4,109 @@ # name: discourse-legacy_links # about: A plugin to handle legacy Gossamer Forums URLs -# version: 0.41 +# version: 0.46 # authors: saint@federated.computer # url: https://gitea.federated.computer/saint/discourse-legacy_links.git -# require 'digest' - # enabled_site_setting :discourse_legacy_links_enabled -# after_initialize do after_initialize do - -# require_dependency 'application_controller' - module ::DiscourseLegacyLinks class Engine < ::Rails::Engine engine_name "discourse_legacy_links" isolate_namespace DiscourseLegacyLinks end + end - # Define the custom controller, inheriting from Discourse's CustomPostController - # This gives us access to post-related functionality and user authentication -# class DiscourseLegacyLinks::CustomPostController < ::ApplicationController - class LegacyLinksController::CustomPostController < ::ApplicationController -# class LegacyLinksController < ::ApplicationController::CustomPostController + 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 -# layout false + def index + Rails.logger.info("DiscourseLegacyLinks: Handling request for URL: #{request.original_url}") - # Skip certain before_actions for our index method. - # This allows the route to be accessed directly via a browser -## skip_before_action :check_xhr, only: [:index2] -## skip_before_action :verify_authenticity_token, only: [:index2] -# skip_before_action :verify_authenticity_token -# skip_before_action :ensure_logged_in -# skip_before_action :redirect_to_login_if_required -# skip_before_action :check_xhr -# skip_before_action :ensure_staff + post_id = extract_post_id_from_request - def index2 - Rails.logger.warn "[WARN WARN WARN WARN WARN WARN WARN WARN WARN WARN AMDG JMJ PAX WARN WARN WARN WARN]" - render plain: "Test route JMJ" -# render html: '

JMJ

' - end + if post_id + Rails.logger.info("DiscourseLegacyLinks: Extracted post_id: #{post_id}") + post = find_post_by_custom_field(post_id) - # Match URLs that include a post_id at the end or query parameter - # Main action triggered when the route is matched. - def index - Rails.logger.warn "[DEBUG] Reached the index action" - - # Log all incoming parameters to see what's being passed - Rails.logger.warn "[DEBUG] Params: #{params.inspect}" - post_id = extract_post_id_from_request - - if post_id - Rails.logger.warn "[DEBUG] Processing request for post_id: #{post_id}" - post = find_post_by_custom_field(post_id) - - if post - # Redirect to the post URL if found - Rails.logger.warn "[DEBUG] Redirecting to post with ID: #{post.id}" - # redirect_to post_url(post) - redirect_to_post(post) - else - # Return 404 if the post is not found - Rails.logger.warn "[ERROR] Post with original_gossamer_id #{post_id} not found" - render plain: 'Post not found', status: 404 - end + if post + Rails.logger.info("DiscourseLegacyLinks: Found matching post with id: #{post.id}") + redirect_to_post(post) else - # Handle cases where the post_id cannot be extracted - Rails.logger.warn "[ERROR] Could not extract post_id from the request" - render plain: 'Invalid URL', status: 400 + 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 + private - # Extracts the post ID from the request URL or query string. - # Supports various formats of legacy forum URLs. - # @return [Integer, nil] The extracted post ID or nil if not found - def extract_post_id_from_request - # Check if post_id is passed as a query parameter (?post=post_id) - if params[:post_id] - post_id = params[:post_id].to_i - Rails.logger.warn "[DEBUG] Extracted post_id from query param: #{post_id}" - return post_id - end + # 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) - # Check for post_id in the URL path (e.g., /forum/.../P12345/) - if match = request.path.match(%r{/forum/[^/]+/P(\d+)/?}) - post_id = match[1].to_i - Rails.logger.warn "[DEBUG] Extracted post_id from URL path: #{post_id}" - return post_id - end + Rails.logger.info("DiscourseLegacyLinks: Extracted raw post_id: #{post_id || 'nil'}") + post_id.to_i if post_id + end - # Check for post_id in the query string (e.g., ?post=12345) - if match = request.query_string.match(/post=(\d+)/) - post_id = match[1].to_i - Rails.logger.warn "[DEBUG] Extracted post_id from query string (?post=): #{post_id}" - return post_id - end - - # Check for parent_post_id in the query string (e.g., ?parent_post_id=12345) - if match = request.query_string.match(/parent_post_id=(\d+)/) - post_id = match[1].to_i - Rails.logger.warn "[DEBUG] Extracted parent_post_id from query string: #{post_id}" - return post_id - end - - # If no post_id was found in any format - Rails.logger.warn "[DEBUG] Could not extract post_id from request" - nil - end - - # Finds the Discourse post that has the specified custom field value. - # The custom field used is 'original_gossamer_id'. - # @param post_id [Integer] The extracted Gossamer forum post ID - # @return [Post, nil] The corresponding Discourse post or nil if not found - def find_post_by_custom_field(post_id) - Rails.logger.warn "[DEBUG] Searching for post with custom field 'original_gossamer_id' and value #{post_id}" - - # Use ActiveRecord query to find the post by the custom field value - post = Post.joins(:topic_custom_fields) + # 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 post - Rails.logger.warn "[DEBUG] Found post with ID: #{post.id} for original_gossamer_id: #{post_id}" - else - Rails.logger.warn "[DEBUG] No post found for original_gossamer_id: #{post_id}" - end - + 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 specified Discourse post. - # @param post [Post] The Discourse post to redirect to - def redirect_to_post(post) - topic_url = "#{Discourse.base_url}/t/#{post.topic_id}/#{post.post_number}" - Rails.logger.warn "[DEBUG] Redirecting to topic URL: #{topic_url}" - redirect topic_url - 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.warn "[DEBUG DEBUG DEBUG DEBUG DEBUG WOW WOW WOW]" -# Rails.application.routes.routes.each do |route| -# Rails.logger.warn "[ROUTE] #{route.path.spec}" -# end -# -# Discourse::Application.routes.append do -# Discourse::Application.routes.prepend do -# get '/forum/*path', to: 'discourse_legacy_links/custom_post#index', constraints: lambda { |req| !Permalink.exists?(url: req.path) } -# get '/forum', to: 'discourse_legacy_links/custom_post#index', constraints: lambda { |request| Rails.logger.warn("[DEBUG] NoStarForum Route matched: #{request.path}") } -# get '/forum/*path', to: 'discourse_legacy_links/custom_post#index', constraints: lambda { |request| Rails.logger.warn("[DEBUG] StarForum Route matched: #{request.path}") } -# get '/forum2', to: 'discourse_legacy_links/custom_post#index2', constraints: lambda { |request| Rails.logger.warn("[DEBUG] NoStarTestRoute Route matched: #{request.path}") } -# get '/forum2/*path', to: 'discourse_legacy_links/custom_post#index2', constraints: lambda { |request| Rails.logger.warn("[DEBUG] StarTestRoute Route matched: #{request.path}") } -# get '/forum2' => "'discourse_legacy_links/custom_post#index2' -# get '/forum/*path' => 'discourse_legacy_links/custom_post#index' -# get '/forum' => 'discourse_legacy_links/custom_post#index' +# Rails.logger.info("DiscourseLegacyLinks: initialistaion") -# # Register custom routes to handle legacy URLs -# DiscourseLegacyLinks::Engine.routes.draw do -# get "/forum2" => "legacy_links#index2" -# end - -# Discourse::Application.routes.append do -# mount ::DiscourseLegacyLinks::Engine, at: "/" -# end + DiscourseLegacyLinks::Engine.routes.draw do + get "/legacy" => "legacy_links#index" + get "/legacy/*path" => "legacy_links#index" + end + Discourse::Application.routes.append do + mount ::DiscourseLegacyLinks::Engine, at: "/" + end end