From 3ae870047a6cb5bda37f612c5918f9cae81abb9b Mon Sep 17 00:00:00 2001 From: songtianlun Date: Mon, 24 Feb 2025 17:28:21 +0800 Subject: [PATCH] feat: add sitemap management feature - Implement index action to list sitemaps - Create view for displaying sitemaps with details - Add helper method for generating sitemap URLs - Enhance error handling for S3 service errors This commit introduces a new feature for managing sitemaps in the application. It includes an index view that lists all available sitemaps with their last modified date and size, along with a link to view each sitemap. The error handling for S3 interactions has also been improved to log errors and return appropriate responses. --- app/controllers/sitemaps_controller.rb | 65 +++++++++++++++++++++++--- app/helpers/sitemaps_helper.rb | 3 ++ app/views/sitemaps/index.html.erb | 43 +++++++++++++++++ config/routes.rb | 1 + 4 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 app/views/sitemaps/index.html.erb diff --git a/app/controllers/sitemaps_controller.rb b/app/controllers/sitemaps_controller.rb index 21cef9f..683c3b7 100644 --- a/app/controllers/sitemaps_controller.rb +++ b/app/controllers/sitemaps_controller.rb @@ -1,16 +1,24 @@ class SitemapsController < ApplicationController + include SitemapsHelper + before_action :set_bucket_name + + def index + @sitemaps = list_sitemaps + respond_to do |format| + format.html + format.xml { render_sitemap_index } + end + rescue Aws::S3::Errors::ServiceError => e + Rails.logger.error "S3 Error: #{e.message}" + render status: :internal_server_error + end def show path = params[:path] - bucket_name = - Rails.env.production? ? - ENV.fetch("AWS_BUCKET", Rails.application.credentials.dig(:minio, :bucket)) : - ENV.fetch("AWS_DEV_BUCKET", Rails.application.credentials.dig(:minio_dev, :bucket)) Rails.logger.info "Sitemap: #{path}" begin - s3_client = Aws::S3::Client.new response = s3_client.get_object( - bucket: bucket_name, + bucket: @bucket_name, key: "sitemaps/#{path}" ) @@ -30,4 +38,49 @@ class SitemapsController < ApplicationController render status: :internal_server_error end end + + private + + def set_bucket_name + @bucket_name = Rails.env.production? ? + ENV.fetch("AWS_BUCKET", Rails.application.credentials.dig(:minio, :bucket)) : + ENV.fetch("AWS_DEV_BUCKET", Rails.application.credentials.dig(:minio_dev, :bucket)) + end + + def s3_client + @s3_client ||= Aws::S3::Client.new + end + + def list_sitemaps + response = s3_client.list_objects_v2( + bucket: @bucket_name, + prefix: "sitemaps/" + ) + + response.contents.map do |object| + { + key: object.key.sub("sitemaps/", ""), + last_modified: object.last_modified, + size: object.size, + url: sitemap_url(object.key.sub("sitemaps/", "")) + } + end.reject { |obj| obj[:key].empty? } + end + + def render_sitemap_index + base_url = "#{request.protocol}#{request.host_with_port}" + + builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| + xml.sitemapindex(xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9") do + @sitemaps.each do |sitemap| + xml.sitemap do + xml.loc "#{base_url}/sitemaps/#{sitemap[:key]}" + xml.lastmod sitemap[:last_modified].iso8601 + end + end + end + end + + render xml: builder.to_xml + end end diff --git a/app/helpers/sitemaps_helper.rb b/app/helpers/sitemaps_helper.rb index 509e433..3ed93d2 100644 --- a/app/helpers/sitemaps_helper.rb +++ b/app/helpers/sitemaps_helper.rb @@ -1,2 +1,5 @@ module SitemapsHelper + def sitemap_url(filename) + "/sitemaps/#{filename}" + end end diff --git a/app/views/sitemaps/index.html.erb b/app/views/sitemaps/index.html.erb new file mode 100644 index 0000000..0c64ee3 --- /dev/null +++ b/app/views/sitemaps/index.html.erb @@ -0,0 +1,43 @@ +<%# app/views/sitemaps/index.html.erb %> +
+
+

Sitemaps Index

+ +
+
+ + + + + + + + + + + <% @sitemaps.each do |sitemap| %> + + + + + + + <% end %> + +
FilenameLast ModifiedSizeActions
<%= sitemap[:key] %><%= sitemap[:last_modified].strftime("%Y-%m-%d %H:%M:%S") %><%= number_to_human_size(sitemap[:size]) %> + <%= link_to "View", sitemap[:url], + class: "btn btn-sm btn-primary", + target: "_blank" %> +
+
+
+ +
+

For Search Engines

+

Sitemap Index URL:

+ + <%= sitemaps_url(format: :xml) %> + +
+
+
\ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index deb73f3..b1ace4e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -25,6 +25,7 @@ Rails.application.routes.draw do get "cities/index" get "cities/show" get "home/index" + get "sitemaps", to: "sitemaps#index" get "sitemaps/*path", to: "sitemaps#show", format: false get "feed", to: "rss#feed", format: "rss", as: :rss_feed