From 7f75aed146b87e2e70e597dec70f289fedd31a70 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 14:31:54 +0000 Subject: [PATCH] feat: Add sitemap generator Adds the `sitemap_generator` gem to generate a sitemap. - Includes static routes and dynamic routes for active crops, plantings, seeds, photos, posts, and members. - Implements a caching mechanism to ensure the sitemap is generated no more frequently than every 72 hours. - Updates `robots.txt` to point to the new sitemap. - Includes a unit test for the caching Rake task. --- Gemfile | 2 ++ config/sitemap.rb | 50 +++++++++++++++++++++++++++++++ lib/tasks/sitemap_cached.rake | 19 ++++++++++++ public/robots.txt | 2 ++ spec/tasks/sitemap_cached_spec.rb | 38 +++++++++++++++++++++++ 5 files changed, 111 insertions(+) create mode 100644 config/sitemap.rb create mode 100644 lib/tasks/sitemap_cached.rake create mode 100644 spec/tasks/sitemap_cached_spec.rb diff --git a/Gemfile b/Gemfile index 8c85fe032..a633539a1 100644 --- a/Gemfile +++ b/Gemfile @@ -202,3 +202,5 @@ end gem "i18n_data", "~> 1.1" gem "paper_trail", "~> 17.0" + +gem 'sitemap_generator' diff --git a/config/sitemap.rb b/config/sitemap.rb new file mode 100644 index 000000000..7c13f356a --- /dev/null +++ b/config/sitemap.rb @@ -0,0 +1,50 @@ +require 'rubygems' +require 'sitemap_generator' + +SitemapGenerator::Sitemap.default_host = 'https://growstuff.org' +SitemapGenerator::Sitemap.sitemaps_host = ENV['SITEMAP_HOST'] +SitemapGenerator::Sitemap.public_path = 'public/' +SitemapGenerator::Sitemap.sitemaps_path = 'sitemaps/' + +SitemapGenerator::Sitemap.create do + # static pages + add '/community', changefreq: 'weekly', priority: 0.7 + add '/terms', changefreq: 'yearly', priority: 0.2 + add '/privacy', changefreq: 'yearly', priority: 0.2 + add '/about', changefreq: 'monthly', priority: 0.4 + add '/faq', changefreq: 'monthly', priority: 0.4 + add '/contact', changefreq: 'yearly', priority: 0.2 + add '/members', changefreq: 'weekly', priority: 0.6 + add '/gardens', changefreq: 'weekly', priority: 0.6 + add '/plantings', changefreq: 'weekly', priority: 0.6 + add '/harvests', changefreq: 'weekly', priority: 0.6 + add '/seeds', changefreq: 'weekly', priority: 0.6 + add '/crops', changefreq: 'weekly', priority: 0.6 + add '/posts', changefreq: 'daily', priority: 0.8 + add '/forums', changefreq: 'daily', priority: 0.8 + add '/photos', changefreq: 'daily', priority: 0.8 + + Crop.approved.find_each do |crop| + add crop_path(crop), lastmod: crop.updated_at + end + + Planting.active.find_each do |planting| + add planting_path(planting), lastmod: planting.updated_at + end + + Seed.active.find_each do |seed| + add seed_path(seed), lastmod: seed.updated_at + end + + Photo.find_each do |photo| + add photo_path(photo), lastmod: photo.updated_at + end + + Post.find_each do |post| + add post_path(post), lastmod: post.updated_at + end + + Member.kept.find_each do |member| + add member_path(member), lastmod: member.updated_at + end +end diff --git a/lib/tasks/sitemap_cached.rake b/lib/tasks/sitemap_cached.rake new file mode 100644 index 000000000..9d6b43073 --- /dev/null +++ b/lib/tasks/sitemap_cached.rake @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +namespace :sitemap do + desc 'Generate sitemap, but only if it has not been generated in the last 72 hours' + task cached_refresh: :environment do + sitemap_file = Rails.root.join('tmp', 'sitemap_generated_at.txt') + if File.exist?(sitemap_file) + last_generated_at = Time.parse(File.read(sitemap_file)) + if last_generated_at > 72.hours.ago + puts 'Sitemap has been generated within the last 72 hours. Skipping.' + exit + end + end + + Rake::Task['sitemap:refresh'].invoke + + File.write(sitemap_file, Time.now.to_s) + end +end diff --git a/public/robots.txt b/public/robots.txt index da250e302..d9421bb8c 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -140,3 +140,5 @@ Crawl-delay: 5 # User-agent: * Disallow: /api/ + +Sitemap: https://growstuff.org/sitemaps/sitemap.xml.gz diff --git a/spec/tasks/sitemap_cached_spec.rb b/spec/tasks/sitemap_cached_spec.rb new file mode 100644 index 000000000..1dbb0855a --- /dev/null +++ b/spec/tasks/sitemap_cached_spec.rb @@ -0,0 +1,38 @@ +require 'rails_helper' +require 'rake' + +describe 'sitemap:cached_refresh' do + let(:sitemap_file) { Rails.root.join('tmp', 'sitemap_generated_at.txt') } + + before :all do + Rails.application.load_tasks + end + + before :each do + Rake::Task['sitemap:refresh'].clear + File.delete(sitemap_file) if File.exist?(sitemap_file) + end + + after :each do + File.delete(sitemap_file) if File.exist?(sitemap_file) + end + + it 'calls sitemap:refresh if the cache file does not exist' do + expect(Rake::Task['sitemap:refresh']).to receive(:invoke) + Rake::Task['sitemap:cached_refresh'].invoke + end + + it 'calls sitemap:refresh if the cache file is older than 72 hours' do + File.write(sitemap_file, 73.hours.ago.to_s) + expect(Rake::Task['sitemap:refresh']).to receive(:invoke) + Rake::Task['sitemap:cached_refresh'].reenable + Rake::Task['sitemap:cached_refresh'].invoke + end + + it 'does not call sitemap:refresh if the cache file is newer than 72 hours' do + File.write(sitemap_file, 71.hours.ago.to_s) + expect(Rake::Task['sitemap:refresh']).not_to receive(:invoke) + Rake::Task['sitemap:cached_refresh'].reenable + Rake::Task['sitemap:cached_refresh'].invoke + end +end