Skip to content

Commit

Permalink
Generate sitemaps with Controller and Actions instead of sitemap_gene…
Browse files Browse the repository at this point in the history
…rator (#268)

Related to #265

Implement sitemap generation with a primary index referencing a per-city index, and the per-city index listing out a sitemap per-city-per-day containing all service requests for that day.
  • Loading branch information
bensheldon authored Jul 30, 2024
1 parent 1a99f74 commit 265d959
Show file tree
Hide file tree
Showing 17 changed files with 142 additions and 56 deletions.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ gem 'rails', '~> 7.1'
gem 'sass-rails'
gem 'scenic'
gem 'sentry-raven'
gem 'sitemap_generator'
gem 'slim'
gem 'slim-rails'
gem 'terser'
Expand Down
3 changes: 0 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,6 @@ GEM
websocket (~> 1.0)
sentry-raven (2.13.0)
faraday (>= 0.7.6, < 1.0)
sitemap_generator (6.3.0)
builder (~> 3.0)
slim (5.2.1)
temple (~> 0.10.0)
tilt (>= 2.1.0)
Expand Down Expand Up @@ -552,7 +550,6 @@ DEPENDENCIES
scenic
selenium-webdriver
sentry-raven
sitemap_generator
slim
slim-rails
slim_lint
Expand Down
50 changes: 50 additions & 0 deletions app/controllers/sitemaps_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

class SitemapsController < ApplicationController
def index
@cities = City.all

respond_to do |format|
format.xml
end
end

def city_index
@city = City.find_by!(slug: params[:slug])

oldest_service_request = @city.service_requests.order(:created_at, :id).limit(1).pick(:created_at)&.to_date || Date.current
@dates = oldest_service_request..Date.current

respond_to do |format|
format.xml
end
end

def city_day
@city = City.find_by!(slug: params[:slug])
@date = Date.parse(params[:date])
@service_requests = @city.service_requests.where(requested_datetime: @date.all_day)

respond_to do |format|
format.xml
end
end

def static
@links = [
root_url,
about_url,
] + City.all.map { |city| city_url(city) }

respond_to do |format|
format.xml
end
end

private

def format_lastmod(updated)
updated.utc.strftime("%Y-%m-%d")
end
helper_method :format_lastmod
end
8 changes: 0 additions & 8 deletions app/jobs/sitemap_job.rb

This file was deleted.

4 changes: 4 additions & 0 deletions app/models/service_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ def raw_data=(json)
}
end

def raw_data
super || {}
end

def slug
description = raw_data['description'].presence || ''
slug = description.gsub(/(-|_)/, ' ').squish.encode.to_slug.normalize.to_s.downcase
Expand Down
10 changes: 10 additions & 0 deletions app/views/sitemaps/city_day.xml.builder
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true
xml.instruct! :xml, version: "1.0", encoding: "UTF-8"
xml.urlset xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9" do
@service_requests.each do |service_request|
xml.url do
xml.loc service_request_url(service_request, format: :xml)
xml.lastmod format_lastmod(service_request.updated_at)
end
end
end
10 changes: 10 additions & 0 deletions app/views/sitemaps/city_index.xml.builder
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true
xml.instruct! :xml, version: "1.0", encoding: "UTF-8"
xml.sitemapindex xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9" do
@dates.each do |date|
xml.sitemap do
xml.loc city_day_sitemap_url(@city.slug, date.strftime("%Y-%m-%d"), format: :xml)
xml.lastmod date.strftime("%Y-%m-%dT%H:%M:%S%:z")
end
end
end
13 changes: 13 additions & 0 deletions app/views/sitemaps/index.xml.builder
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true
xml.instruct! :xml, version: "1.0", encoding: "UTF-8"
xml.sitemapindex xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9" do
xml.sitemap do
xml.loc static_sitemap_url(format: :xml)
end

@cities.each do |city|
xml.sitemap do
xml.loc city_sitemap_index_url(city.slug, format: :xml)
end
end
end
9 changes: 9 additions & 0 deletions app/views/sitemaps/static.xml.builder
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true
xml.instruct! :xml, version: "1.0", encoding: "UTF-8"
xml.urlset xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9" do
@links.each do |link|
xml.url do
xml.loc link
end
end
end
5 changes: 0 additions & 5 deletions config/initializers/good_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@
class: 'RefreshJob',
description: "Update open311 statuses",
},
sitemap: {
cron: '0 7 * * *',
class: 'SitemapJob',
description: "Update Sitemap",
},
}

GoodJob::Engine.middleware.use(Rack::Auth::Basic) do |provided_username, provided_password|
Expand Down
5 changes: 4 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

mount GoodJob::Engine => 'good_job'

get '/sitemap.xml.gz', to: redirect("https://#{Rails.application.secrets.s3_bucket_name}.s3.amazonaws.com/sitemaps/sitemap.xml.gz")
get '/sitemap.xml', to: 'sitemaps#index', defaults: { format: 'xml' }, as: :sitemap
get '/sitemaps/static.xml', to: 'sitemaps#static', defaults: { format: 'xml' }, as: :static_sitemap
get '/sitemaps/:slug.xml', to: 'sitemaps#city_index', defaults: { format: 'xml' }, as: :city_sitemap_index
get '/sitemaps/:slug/:date.xml', to: 'sitemaps#city_day', defaults: { format: 'xml' }, as: :city_day_sitemap

resolve "ServiceRequest" do |service_request, options|
service_request.parameterize.merge(controller: 'cities/requests', action: 'show').merge(options)
Expand Down
4 changes: 0 additions & 4 deletions config/secrets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@

defaults: &defaults
default_host: <%= ENV.fetch('DEFAULT_HOST', 'localhost:3000') %>
upload_host: <%= ENV.fetch('UPLOAD_HOST', 'http://localhost:3000') %>
s3_bucket_name: <%= ENV['S3_BUCKET_NAME'] %>
aws_access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
aws_secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>

development:
<<: *defaults
Expand Down
32 changes: 0 additions & 32 deletions config/sitemap.rb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class AddOrderIndexToServiceRequests < ActiveRecord::Migration[7.1]
disable_ddl_transaction!

def change
add_index :service_requests, [:city_id, :created_at, :id], algorithm: :concurrently
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_07_30_143512) do
ActiveRecord::Schema[7.1].define(version: 2024_07_30_192533) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
enable_extension "pgcrypto"
Expand Down Expand Up @@ -133,6 +133,7 @@
t.datetime "updated_at", null: false
t.bigint "city_id"
t.geography "geometry", limit: {:srid=>4326, :type=>"geometry", :geographic=>true}
t.index ["city_id", "created_at", "id"], name: "index_service_requests_on_city_id_and_created_at_and_id"
t.index ["city_id", "requested_datetime"], name: "index_service_requests_on_city_id_and_requested_datetime", order: { requested_datetime: "DESC NULLS LAST" }
t.index ["city_id", "service_request_id"], name: "index_service_requests_on_city_id_and_service_request_id", unique: true
t.index ["city_id"], name: "index_service_requests_on_city_id"
Expand Down
2 changes: 1 addition & 1 deletion public/robots.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
#

User-agent: *
Sitemap: https://status.open311.org/sitemap.xml.gz
Sitemap: https://status.open311.org/sitemap.xml
32 changes: 32 additions & 0 deletions spec/system/sitemaps_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true
require 'rails_helper'

RSpec.describe 'Sitemaps' do
let(:city) { City.first }
let(:service_request) { create(:service_request, city:) }

before do
City.load!
end

it 'visits the primary sitemap index' do
visit '/sitemap.xml'
expect(page).to have_content static_sitemap_url(format: :xml)
expect(page).to have_content city_sitemap_index_url(City.first.slug, format: :xml)
end

it 'visits the per-city index' do
visit "/sitemaps/#{city.slug}.xml"
expect(page).to have_content city_day_sitemap_url(city.slug, date: Date.current, format: :xml)
end

it 'visits the per-city-per-day sitemap' do
visit "/sitemaps/#{city.slug}/#{service_request.requested_datetime.to_date}.xml"
expect(page).to have_content(service_request_url(service_request))
end

it 'visits the static sitemap' do
visit '/sitemaps/static.xml'
expect(page).to have_content(root_url)
end
end

0 comments on commit 265d959

Please sign in to comment.