From 510088411000af5b31b0f996d2315c1627253184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Mon, 26 Sep 2022 22:20:27 +0200 Subject: [PATCH] Generate one sitemap per tenant Note that the `sitemap:refresh` task only pings search engines at the end, so it only does so for the `Sitemap.default_host` defined last. So we're using the `sitemap:refresh:no_ping` task instead and pinging search engines after creating each sitemap. Note we're pinging search engines in staging and preproduction environments. I'm leaving it that way because that's what we've done until now, but I wonder whether we should only do so on production. Since we're creating a new method to get the current url_options, we're also using it in the dev_seeds. --- .dockerignore | 1 + .gitignore | 1 + app/models/tenant.rb | 4 ++ config/schedule.rb | 2 +- config/sitemap.rb | 86 ++++++++++++++++------------- db/dev_seeds/admin_notifications.rb | 2 +- spec/lib/tasks/sitemap_spec.rb | 44 ++++++++++++++- 7 files changed, 98 insertions(+), 42 deletions(-) diff --git a/.dockerignore b/.dockerignore index a85b5fb6b..41853f5ae 100644 --- a/.dockerignore +++ b/.dockerignore @@ -20,6 +20,7 @@ storage/ # Files generated by scripts or compiled public/sitemap.xml +public/tenants/*/sitemap.xml public/assets/ public/machine_learning/data/ diff --git a/.gitignore b/.gitignore index 7e10963eb..3ac23e93f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ tmp/ # Files generated by scripts or compiled /public/sitemap.xml +/public/tenants/*/sitemap.xml /public/assets/ /public/machine_learning/data/ diff --git a/app/models/tenant.rb b/app/models/tenant.rb index 6e82f3e9a..b808de150 100644 --- a/app/models/tenant.rb +++ b/app/models/tenant.rb @@ -35,6 +35,10 @@ class Tenant < ApplicationRecord Apartment::Tenant.current end + def self.current_url_options + ApplicationMailer.new.default_url_options + end + def self.default? current_schema == "public" end diff --git a/config/schedule.rb b/config/schedule.rb index 4e7675dc5..b9e3be61c 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -24,7 +24,7 @@ every 1.minute do end every 1.day, at: "5:00 am" do - rake "-s sitemap:refresh" + rake "-s sitemap:refresh:no_ping" end every 2.hours do diff --git a/config/sitemap.rb b/config/sitemap.rb index 3a2664e55..31f973f2b 100644 --- a/config/sitemap.rb +++ b/config/sitemap.rb @@ -6,49 +6,59 @@ class SitemapGenerator::FileAdapter end end SitemapGenerator::Sitemap.namer = SitemapGenerator::SimpleNamer.new(:sitemap, extension: ".xml") - -# default host SitemapGenerator::Sitemap.verbose = false if Rails.env.test? -SitemapGenerator::Sitemap.default_host = root_url(ActionMailer::Base.default_url_options) -# sitemap generator -SitemapGenerator::Sitemap.create do - add help_path - add how_to_use_path - add faq_path +Tenant.run_on_each do + SitemapGenerator::Sitemap.default_host = root_url(Tenant.current_url_options) - if Setting["process.debates"] - add debates_path, priority: 0.7, changefreq: "daily" - Debate.find_each do |debate| - add debate_path(debate), lastmod: debate.updated_at + if Tenant.default? + SitemapGenerator::Sitemap.sitemaps_path = nil + else + SitemapGenerator::Sitemap.sitemaps_path = "tenants/#{Tenant.current_schema}" + end + + SitemapGenerator::Sitemap.create do + add help_path + add how_to_use_path + add faq_path + + if Setting["process.debates"] + add debates_path, priority: 0.7, changefreq: "daily" + Debate.find_each do |debate| + add debate_path(debate), lastmod: debate.updated_at + end + end + + if Setting["process.proposals"] + add proposals_path, priority: 0.7, changefreq: "daily" + Proposal.find_each do |proposal| + add proposal_path(proposal), lastmod: proposal.updated_at + end + end + + if Setting["process.budgets"] + add budgets_path, priority: 0.7, changefreq: "daily" + Budget.find_each do |budget| + add budget_path(budget), lastmod: budget.updated_at + end + end + + if Setting["process.polls"] + add polls_path, priority: 0.7, changefreq: "daily" + Poll.find_each do |poll| + add poll_path(poll), lastmod: poll.starts_at + end + end + + if Setting["process.legislation"] + add legislation_processes_path, priority: 0.7, changefreq: "daily" + Legislation::Process.find_each do |process| + add legislation_process_path(process), lastmod: process.start_date + end end end - if Setting["process.proposals"] - add proposals_path, priority: 0.7, changefreq: "daily" - Proposal.find_each do |proposal| - add proposal_path(proposal), lastmod: proposal.updated_at - end - end - - if Setting["process.budgets"] - add budgets_path, priority: 0.7, changefreq: "daily" - Budget.find_each do |budget| - add budget_path(budget), lastmod: budget.updated_at - end - end - - if Setting["process.polls"] - add polls_path, priority: 0.7, changefreq: "daily" - Poll.find_each do |poll| - add poll_path(poll), lastmod: poll.starts_at - end - end - - if Setting["process.legislation"] - add legislation_processes_path, priority: 0.7, changefreq: "daily" - Legislation::Process.find_each do |process| - add legislation_process_path(process), lastmod: process.start_date - end + unless Rails.env.development? || Rails.env.test? + SitemapGenerator::Sitemap.ping_search_engines end end diff --git a/db/dev_seeds/admin_notifications.rb b/db/dev_seeds/admin_notifications.rb index e75139c7d..132976cf6 100644 --- a/db/dev_seeds/admin_notifications.rb +++ b/db/dev_seeds/admin_notifications.rb @@ -5,7 +5,7 @@ section "Creating Admin Notifications & Templates" do -> { I18n.t("seeds.admin_notifications.proposal.#{attribute}") } end ).merge( - link: Rails.application.routes.url_helpers.proposals_url(ActionMailer::Base.default_url_options), + link: Rails.application.routes.url_helpers.proposals_url(Tenant.current_url_options), segment_recipient: "administrators" ) ).deliver diff --git a/spec/lib/tasks/sitemap_spec.rb b/spec/lib/tasks/sitemap_spec.rb index 0edbf19f4..be989a92c 100644 --- a/spec/lib/tasks/sitemap_spec.rb +++ b/spec/lib/tasks/sitemap_spec.rb @@ -2,6 +2,7 @@ require "rails_helper" describe "rake sitemap:create", type: :system do let(:file) { Rails.root.join("public", "sitemap.xml") } + let(:run_rake_task) { Rake.application.invoke_task("sitemap:create") } before do FileUtils.rm_f(file) @@ -9,7 +10,7 @@ describe "rake sitemap:create", type: :system do end describe "when processes are enabled" do - before { Rake.application.invoke_task("sitemap:create") } + before { run_rake_task } it "generates a valid sitemap" do sitemap = Nokogiri::XML(File.open(file)) @@ -44,7 +45,7 @@ describe "rake sitemap:create", type: :system do Setting["process.polls"] = nil Setting["process.legislation"] = nil - Rake.application.invoke_task("sitemap:create") + run_rake_task end it "generates a valid sitemap" do @@ -71,4 +72,43 @@ describe "rake sitemap:create", type: :system do expect(sitemap).not_to have_content("daily") end end + + it "generates a sitemap for every tenant" do + allow(ActionMailer::Base).to receive(:default_url_options).and_return({ host: "consul.dev" }) + FileUtils.rm_f(Dir.glob(Rails.root.join("public", "tenants", "*", "sitemap.xml"))) + + create(:tenant, schema: "debates") + create(:tenant, schema: "proposals") + + Setting["process.debates"] = false + Setting["process.proposals"] = false + + Tenant.switch("debates") do + Setting["process.budgets"] = false + Setting["process.proposals"] = false + end + + Tenant.switch("proposals") do + Setting["process.budgets"] = false + Setting["process.debates"] = false + end + + run_rake_task + + public_sitemap = File.read(file) + debates_sitemap = File.read(Rails.root.join("public", "tenants", "debates", "sitemap.xml")) + proposals_sitemap = File.read(Rails.root.join("public", "tenants", "proposals", "sitemap.xml")) + + expect(public_sitemap).to have_content budgets_url(host: "consul.dev") + expect(public_sitemap).not_to have_content debates_path + expect(public_sitemap).not_to have_content proposals_path + + expect(debates_sitemap).to have_content debates_url(host: "debates.consul.dev") + expect(debates_sitemap).not_to have_content budgets_path + expect(debates_sitemap).not_to have_content proposals_path + + expect(proposals_sitemap).to have_content proposals_url(host: "proposals.consul.dev") + expect(proposals_sitemap).not_to have_content budgets_path + expect(proposals_sitemap).not_to have_content debates_path + end end