diff --git a/db/migrations/014_bingo_updated_at.rb b/db/migrations/014_bingo_updated_at.rb new file mode 100644 index 0000000..2df7048 --- /dev/null +++ b/db/migrations/014_bingo_updated_at.rb @@ -0,0 +1,13 @@ +Sequel.migration do + up do + # Last change to the row, for the "updated" date and sitemap lastmod. + %i[bingo_datacenters bingo_incidents].each do |t| + add_column t, :updated_at, DateTime + from(t).update(updated_at: :created_at) + end + end + + down do + %i[bingo_datacenters bingo_incidents].each { |t| drop_column t, :updated_at } + end +end diff --git a/lib/bingo.rb b/lib/bingo.rb index b1fb328..707e96c 100644 --- a/lib/bingo.rb +++ b/lib/bingo.rb @@ -99,6 +99,11 @@ module Bingo super end + def before_save + self.updated_at = Time.now.utc + super + end + def operational? = status == 'operational' def planned? = status == 'planned' @@ -126,10 +131,21 @@ module Bingo include Localized many_to_one :datacenter, class: 'Bingo::Datacenter' + # A removed incident changes its datacenter's cell. + def after_destroy + super + Datacenter.where(id: datacenter_id).update(updated_at: Time.now.utc) + end + def before_create self.created_at ||= Time.now.utc super end + + def before_save + self.updated_at = Time.now.utc + super + end end # Board state for rendering: ordered cells, hits and completed lines. @@ -145,7 +161,7 @@ module Bingo hit = cells.map { |dc| dc.incidents.any? } wins = LINES.select { |line| line.all? { |i| hit[i] } } incidents = cells.flat_map(&:incidents).sort_by { |i| [i.occurred_on, i.id] }.reverse - updated = [Datacenter.max(:created_at), Incident.max(:created_at)].compact.max + updated = [Datacenter.max(:updated_at), Incident.max(:updated_at)].compact.max new(cells, hit, wins, incidents, updated, view) end @@ -364,7 +380,10 @@ module Bingo end def self.renumber!(ids = Datacenter.order(:position, :id).select_map(:id)) - ids.each_with_index { |id, i| Datacenter.where(id: id).update(position: i + 1) } + now = Time.now.utc + ids.each_with_index do |id, i| + Datacenter.where(id: id).exclude(position: i + 1).update(position: i + 1, updated_at: now) + end end # "64" → 64.0, "25–30" → 30.0, ">40" → 40.0, "13,7" → 13.7, "" → nil @@ -388,14 +407,14 @@ module Bingo path = File.join($root, 'db', 'bingo_seed.json') return unless File.exist?(path) seed = JSON.parse(File.read(path, encoding: 'UTF-8')) - cols = Datacenter.columns.map(&:to_s) - %w[id created_at] + cols = Datacenter.columns.map(&:to_s) - %w[id created_at updated_at] DB.connection.transaction do ids = seed.fetch('datacenters').each_with_index.to_h do |row, i| dc = Datacenter.create(row.slice(*cols).merge('position' => row['position'] || i + 1)) [dc.slug, dc.id] end seed.fetch('incidents', []).each do |row| - Incident.create(row.slice(*(Incident.columns.map(&:to_s) - %w[id created_at datacenter_id])) + Incident.create(row.slice(*(Incident.columns.map(&:to_s) - %w[id created_at updated_at datacenter_id])) .merge('datacenter_id' => ids.fetch(row.fetch('slug')))) end end diff --git a/lib/bingo_admin.rb b/lib/bingo_admin.rb index ac443a8..e010bbe 100644 --- a/lib/bingo_admin.rb +++ b/lib/bingo_admin.rb @@ -221,7 +221,7 @@ module BingoAdmin app.post '/admin/bingo/incidents/:id/delete' do inc = Bingo::Incident[params[:id].to_i] - Bingo::Incident.where(id: params[:id].to_i).delete + inc&.destroy # hook bumps the datacenter's updated_at audit!('bingo.incident_delete', inc&.datacenter&.slug, inc && "#{inc.occurred_on} #{inc.title_ru}") session[:bingo_flash] = 'Incident deleted.' redirect '/admin/bingo' diff --git a/test/bingo_test.rb b/test/bingo_test.rb index 9d6ab31..22a97e8 100644 --- a/test/bingo_test.rb +++ b/test/bingo_test.rb @@ -175,6 +175,21 @@ class BingoTest < Minitest::Test assert last_response.ok? %w[ru en uk].each { |l| assert_includes last_response.body, "https://example.org/#{l}" } assert_includes last_response.body, 'hreflang="x-default"' + refute_includes last_response.body, 'changefreq' + assert_match %r{\n \d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ\n , old + DB.connection[:bingo_datacenters].update(updated_at: old) + inc = hit!(2) + DB.connection[:bingo_incidents].update(created_at: old, updated_at: old) + inc.refresh.destroy + assert_operator Bingo::Board.load.updated_on, :>, old end def test_asxpio_static_files_not_served diff --git a/views/bingo/sitemap.erb b/views/bingo/sitemap.erb index 6267d6e..fe49fef 100644 --- a/views/bingo/sitemap.erb +++ b/views/bingo/sitemap.erb @@ -3,8 +3,8 @@ <% Bingo::LOCALES.each do |l| %> <%= base_url %>/<%= l %> -<% if @lastmod %> <%= @lastmod.utc.strftime('%Y-%m-%d') %> -<% end %> daily +<% if @lastmod %> <%= @lastmod.utc.iso8601 %> +<% end %> <% Bingo::LOCALES.each do |alt| %> <% end %>