- Refactor generate_sitemap method to support locale - Add setup_sitemap_config method for configuration - Implement sitemap generation for default and localized paths This update enhances the sitemap generation process by supporting multiple languages. Users can now access a sitemap with language prefixes, improving SEO and usability for different locales. Additionally, error handling has been improved to log specific errors related to locale generation.
130 lines
5.0 KiB
Ruby
130 lines
5.0 KiB
Ruby
class RefreshSitemapWorker
|
|
include Sidekiq::Worker
|
|
require "redis"
|
|
|
|
def perform
|
|
lock_key = "refresh_sitemap_lock"
|
|
lock_ttl = 60 # 锁的生存时间,单位为秒
|
|
|
|
redis = Redis.new(url: ENV.fetch("REDIS_URL", "redis://localhost:6379/1"))
|
|
|
|
if redis.set(lock_key, Time.current.to_s, nx: true, ex: lock_ttl)
|
|
begin
|
|
setup_sitemap_config
|
|
# 生成默认的不带语言前缀的 sitemap
|
|
generate_sitemap(nil)
|
|
|
|
# 为每个可用语言生成带前缀的 sitemap
|
|
I18n.available_locales.each do |locale|
|
|
generate_sitemap(locale)
|
|
end
|
|
ensure
|
|
redis.del(lock_key)
|
|
end
|
|
else
|
|
Rails.logger.info "Sitemap refresh is already in progress"
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def setup_sitemap_config
|
|
@host = Rails.env.production? ? "https://todayaiweather.com" : "http://127.0.0.1:3000"
|
|
Rails.application.routes.default_url_options[:host] = @host
|
|
SitemapGenerator::Sitemap.default_host = ENV.fetch("RAILS_SITEMAP_DEFAULT_HOST", @host)
|
|
|
|
if Rails.env.production?
|
|
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new(
|
|
ENV.fetch("AWS_BUCKET", Rails.application.credentials.dig(:minio, :bucket)),
|
|
aws_access_key_id: ENV.fetch("AWS_ACCESS_KEY_ID", Rails.application.credentials.dig(:minio, :access_key_id)),
|
|
aws_secret_access_key: ENV.fetch("AWS_SECRET_ACCESS_KEY_ID", Rails.application.credentials.dig(:minio, :secret_access_key)),
|
|
aws_region: ENV.fetch("AWS_REGION", Rails.application.credentials.dig(:minio, :region)),
|
|
force_path_style: ENV.fetch("AWS_FORCE_PATH_STYLE", Rails.application.credentials.dig(:minio, :force_path_style)),
|
|
endpoint: ENV.fetch("AWS_ENDPOINT", Rails.application.credentials.dig(:minio, :endpoint)),
|
|
)
|
|
else
|
|
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new(
|
|
ENV.fetch("AWS_DEV_BUCKET", Rails.application.credentials.dig(:minio_dev, :bucket)),
|
|
aws_access_key_id: ENV.fetch("AWS_DEV_ACCESS_KEY_ID", Rails.application.credentials.dig(:minio_dev, :access_key_id)),
|
|
aws_secret_access_key: ENV.fetch("AWS_DEV_SECRET_ACCESS_KEY_ID", Rails.application.credentials.dig(:minio_dev, :secret_access_key)),
|
|
aws_region: ENV.fetch("AWS_DEV_REGION", Rails.application.credentials.dig(:minio_dev, :region)),
|
|
force_path_style: ENV.fetch("AWS_FORCE_PATH_STYLE", Rails.application.credentials.dig(:minio_dev, :force_path_style)),
|
|
endpoint: ENV.fetch("AWS_DEV_ENDPOINT", Rails.application.credentials.dig(:minio_dev, :endpoint)),
|
|
)
|
|
end
|
|
SitemapGenerator::Sitemap.sitemaps_path = "sitemaps/"
|
|
end
|
|
|
|
def generate_sitemap(locale = nil)
|
|
# 设置当前语言环境
|
|
I18n.locale = locale || I18n.default_locale
|
|
Rails.application.routes.default_url_options[:locale] = locale
|
|
|
|
# 设置 sitemap 路径
|
|
# path_prefix = locale ? "sitemaps/#{locale}/" : "sitemaps/"
|
|
# SitemapGenerator::Sitemap.sitemaps_path = path_prefix
|
|
|
|
filename = locale==nil ? "sitemap" : "sitemap_#{locale}"
|
|
SitemapGenerator::Sitemap.create(filename: filename) do
|
|
available_locales = I18n.available_locales
|
|
|
|
# 首页
|
|
add root_path(locale: locale),
|
|
changefreq: "daily",
|
|
priority: 1.0,
|
|
alternate: available_locales.map { |al|
|
|
{ lang: al, href: root_url(locale: al) }
|
|
}
|
|
|
|
# 城市列表页
|
|
add cities_path(locale: locale),
|
|
changefreq: "daily",
|
|
priority: 0.9,
|
|
alternate: available_locales.map { |al|
|
|
{ lang: al, href: cities_url(locale: al) }
|
|
}
|
|
|
|
# 艺术作品列表页
|
|
add arts_path(locale: locale),
|
|
changefreq: "daily",
|
|
priority: 0.9,
|
|
alternate: available_locales.map { |al|
|
|
{ lang: al, href: arts_url(locale: al) }
|
|
}
|
|
|
|
# 城市详情页
|
|
City.find_each do |city|
|
|
add city_path(city, locale: locale),
|
|
changefreq: "daily",
|
|
priority: 0.8,
|
|
lastmod: city.updated_at,
|
|
alternate: available_locales.map { |al|
|
|
{ lang: al, href: city_url(city, locale: al) }
|
|
}
|
|
end
|
|
|
|
# 天气艺术作品页
|
|
WeatherArt.includes(:city).find_each do |art|
|
|
if art.image.attached?
|
|
add city_weather_art_path(art.city, art, locale: locale),
|
|
changefreq: "daily",
|
|
priority: 0.7,
|
|
lastmod: art.updated_at,
|
|
images: [ {
|
|
loc: url_for(art.image),
|
|
title: "#{art.city.name} Weather Art - #{art.weather_date.strftime('%B %d, %Y')}"
|
|
} ],
|
|
alternate: available_locales.map { |al|
|
|
{ lang: al, href: city_weather_art_url(art.city, art, locale: al) }
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
Rails.logger.info "Generated sitemap for #{locale || 'default'} version"
|
|
rescue => e
|
|
Rails.logger.error "Error generating sitemap for #{locale || 'default'}: #{e.message}"
|
|
raise e
|
|
end
|
|
end
|