2025-01-23 19:02:52 +08:00
|
|
|
class RefreshSitemapWorker
|
|
|
|
include Sidekiq::Worker
|
2025-02-17 15:07:34 +08:00
|
|
|
require "redis"
|
2025-01-23 19:02:52 +08:00
|
|
|
|
|
|
|
def perform
|
2025-02-17 15:07:34 +08:00
|
|
|
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
|
2025-02-22 12:08:59 +08:00
|
|
|
setup_sitemap_config
|
|
|
|
# 生成默认的不带语言前缀的 sitemap
|
|
|
|
generate_sitemap(nil)
|
|
|
|
|
|
|
|
# 为每个可用语言生成带前缀的 sitemap
|
|
|
|
I18n.available_locales.each do |locale|
|
|
|
|
generate_sitemap(locale)
|
|
|
|
end
|
2025-02-17 15:07:34 +08:00
|
|
|
ensure
|
|
|
|
redis.del(lock_key)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
Rails.logger.info "Sitemap refresh is already in progress"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2025-02-22 12:08:59 +08:00
|
|
|
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)
|
|
|
|
|
2025-01-26 00:07:44 +08:00
|
|
|
if Rails.env.production?
|
|
|
|
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new(
|
2025-02-19 11:31:57 +08:00
|
|
|
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)),
|
2025-02-17 15:07:34 +08:00
|
|
|
)
|
2025-01-26 00:07:44 +08:00
|
|
|
else
|
|
|
|
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new(
|
2025-02-19 11:31:57 +08:00
|
|
|
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)),
|
2025-02-17 15:07:34 +08:00
|
|
|
)
|
2025-01-26 00:07:44 +08:00
|
|
|
end
|
|
|
|
SitemapGenerator::Sitemap.sitemaps_path = "sitemaps/"
|
2025-02-22 12:08:59 +08:00
|
|
|
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) }
|
|
|
|
}
|
2025-01-26 00:07:44 +08:00
|
|
|
|
2025-02-22 12:08:59 +08:00
|
|
|
# 艺术作品列表页
|
|
|
|
add arts_path(locale: locale),
|
|
|
|
changefreq: "daily",
|
|
|
|
priority: 0.9,
|
|
|
|
alternate: available_locales.map { |al|
|
|
|
|
{ lang: al, href: arts_url(locale: al) }
|
|
|
|
}
|
2025-01-23 19:02:52 +08:00
|
|
|
|
2025-02-22 12:08:59 +08:00
|
|
|
# 城市详情页
|
2025-01-23 19:02:52 +08:00
|
|
|
City.find_each do |city|
|
2025-02-22 12:08:59 +08:00
|
|
|
add city_path(city, locale: locale),
|
2025-01-23 19:02:52 +08:00
|
|
|
changefreq: "daily",
|
|
|
|
priority: 0.8,
|
2025-02-22 12:08:59 +08:00
|
|
|
lastmod: city.updated_at,
|
|
|
|
alternate: available_locales.map { |al|
|
|
|
|
{ lang: al, href: city_url(city, locale: al) }
|
|
|
|
}
|
2025-01-23 19:02:52 +08:00
|
|
|
end
|
|
|
|
|
2025-02-22 12:08:59 +08:00
|
|
|
# 天气艺术作品页
|
2025-01-23 19:02:52 +08:00
|
|
|
WeatherArt.includes(:city).find_each do |art|
|
|
|
|
if art.image.attached?
|
2025-02-22 12:08:59 +08:00
|
|
|
add city_weather_art_path(art.city, art, locale: locale),
|
2025-01-23 19:02:52 +08:00
|
|
|
changefreq: "daily",
|
|
|
|
priority: 0.7,
|
|
|
|
lastmod: art.updated_at,
|
2025-01-23 19:03:14 +08:00
|
|
|
images: [ {
|
2025-02-22 12:08:59 +08:00
|
|
|
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) }
|
|
|
|
}
|
2025-01-23 19:02:52 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2025-02-22 12:08:59 +08:00
|
|
|
Rails.logger.info "Generated sitemap for #{locale || 'default'} version"
|
2025-01-23 19:02:52 +08:00
|
|
|
rescue => e
|
2025-02-22 12:08:59 +08:00
|
|
|
Rails.logger.error "Error generating sitemap for #{locale || 'default'}: #{e.message}"
|
|
|
|
raise e
|
2025-01-23 19:02:52 +08:00
|
|
|
end
|
2025-01-23 19:03:14 +08:00
|
|
|
end
|