From e534076aee8779535f663a47a54754bad9152555 Mon Sep 17 00:00:00 2001 From: Keith Lawrence Date: Mon, 31 Jul 2023 14:51:16 +0100 Subject: [PATCH] Add task to return statistics for future changes to a given path. --- lib/reports/concerns/notification_stats.rb | 19 ++++ .../content_change_statistics_report.rb | 35 ------- ...future_content_change_statistics_report.rb | 98 +++++++++++++++++++ ...orical_content_change_statistics_report.rb | 31 ++++++ lib/tasks/report.rake | 16 ++- 5 files changed, 160 insertions(+), 39 deletions(-) create mode 100644 lib/reports/concerns/notification_stats.rb delete mode 100644 lib/reports/content_change_statistics_report.rb create mode 100644 lib/reports/future_content_change_statistics_report.rb create mode 100644 lib/reports/historical_content_change_statistics_report.rb diff --git a/lib/reports/concerns/notification_stats.rb b/lib/reports/concerns/notification_stats.rb new file mode 100644 index 000000000..3f329562a --- /dev/null +++ b/lib/reports/concerns/notification_stats.rb @@ -0,0 +1,19 @@ +module Reports::Concerns::NotificationStats + def list_names_array(lists) + lists.collect(&:title) + end + + def list_stats_array(lists) + total_subs = lists.sum { |l| l.subscriptions.active.count } + immediately_subs = lists.sum { |l| l.subscriptions.active.immediately.count } + daily_subs = lists.sum { |l| l.subscriptions.active.daily.count } + weekly_subs = lists.sum { |l| l.subscriptions.active.weekly.count } + + [ + "notified immediately: #{immediately_subs}", + "notified next day: #{daily_subs}", + "notified at weekend: #{weekly_subs}", + "notified total: #{total_subs}", + ] + end +end diff --git a/lib/reports/content_change_statistics_report.rb b/lib/reports/content_change_statistics_report.rb deleted file mode 100644 index 10196172a..000000000 --- a/lib/reports/content_change_statistics_report.rb +++ /dev/null @@ -1,35 +0,0 @@ -class Reports::ContentChangeStatisticsReport - attr_reader :url - - def initialize(url) - @url = url - end - - def call - content_changes = ContentChange.where(base_path: url).order(:public_updated_at) - - if content_changes.any? - output_string = "#{content_changes.count} content changes registered for #{url}.\n\n" - - content_changes.each do |cc| - output_string += "Content change on #{cc.public_updated_at}:\n" - - lists = SubscriberListQuery.new(content_id: cc.content_id, tags: cc.tags, links: cc.links, document_type: cc.document_type, email_document_supertype: cc.email_document_supertype, government_document_supertype: cc.government_document_supertype).lists - - total_subs = lists.sum { |l| l.subscriptions.active.count } - immediately_subs = lists.sum { |l| l.subscriptions.active.immediately.count } - daily_subs = lists.sum { |l| l.subscriptions.active.daily.count } - weekly_subs = lists.sum { |l| l.subscriptions.active.weekly.count } - - output_string += " - notified immediately: #{immediately_subs}\n" - output_string += " - notified next day: #{daily_subs}\n" - output_string += " - notified at weekend: #{weekly_subs}\n" - output_string += " - notified total: #{total_subs}\n\n" - end - - output_string - else - "No content changes registered for that URL: #{url}" - end - end -end diff --git a/lib/reports/future_content_change_statistics_report.rb b/lib/reports/future_content_change_statistics_report.rb new file mode 100644 index 000000000..88164e4e8 --- /dev/null +++ b/lib/reports/future_content_change_statistics_report.rb @@ -0,0 +1,98 @@ +require "reports/concerns/notification_stats" + +class Reports::FutureContentChangeStatisticsReport + include Reports::Concerns::NotificationStats + + attr_reader :govuk_path, :draft + + def initialize(govuk_path, draft) + @govuk_path = govuk_path + @draft = draft + end + + def call + content_item = content_store_client.content_item(govuk_path).to_hash + + lists = SubscriberListQuery.new( + content_id: content_item["content_id"], + tags: tags_from_content_item(content_item), + links: links_from_content_item(content_item), + document_type: content_item["document_type"], + email_document_supertype: supertypes(content_item)["email_document_supertype"], + government_document_supertype: supertypes(content_item)["government_document_supertype"], + ).lists + + output_string = change_messages.join + + list_names_array(lists).each { |ln| output_string += " - #{ln}\n" } + + output_string += "\nResulting in:\n" + + list_stats_array(lists).each { |ls| output_string += " - #{ls}\n" } + + output_string + end + + def change_messages + if draft + [ + "Publishing the drafted changes to #{govuk_path} will trigger alerts on these lists:\n", + "(NB: publishing as a minor change will not trigger alerts)", + ] + else + [ + "Publishing major changes to the information on #{govuk_path} will trigger alerts on these lists:\n", + "(NB: If major changes involve changes to the taxons/links/etc these lists will change)\n", + ] + end + end + + def content_store_client + return GdsApi.content_store unless draft + + # We don't appear to need a token for the #content_item method? + GdsApi::ContentStore.new(Plek.find("draft-content-store"), bearer_token: "") + end + + def supertypes(content_item) + GovukDocumentTypes.supertypes(document_type: content_item["document_type"]) + end + + def tags_from_content_item(content_item) + content_item["details"]["tags"].merge(additional_items(content_item)) + end + + def links_from_content_item(content_item) + compressed_links(content_item).merge(additional_items(content_item).merge("taxon_tree" => taxon_tree(content_item))) + end + + def compressed_links(content_item) + keys = content_item["links"].keys - %w[available_translations taxons] + compressed_links = {} + keys.each do |k| + compressed_links[k] = content_item["links"][k].collect { |i| i["content_id"] } + end + compressed_links + end + + def additional_items(content_item) + { "content_store_document_type" => content_item["document_type"] }.merge(supertypes(content_item)) + end + + def taxon_tree(content_item) + [content_item["links"]["taxons"].first["content_id"]] + get_parent_links(content_item["links"]["taxons"].first) + end + + def get_parent_links(taxon_struct) + return [] unless taxon_struct["links"].key?("parent_taxons") + return [] unless taxon_struct["links"]["parent_taxons"].any? + + tree = [] + taxon_struct["links"]["parent_taxons"].each do |parent_taxon| + tree += [parent_taxon["content_id"]] + tree += get_parent_links(parent_taxon) + end + + tree + end +end diff --git a/lib/reports/historical_content_change_statistics_report.rb b/lib/reports/historical_content_change_statistics_report.rb new file mode 100644 index 000000000..19421a819 --- /dev/null +++ b/lib/reports/historical_content_change_statistics_report.rb @@ -0,0 +1,31 @@ +require "reports/concerns/notification_stats" + +class Reports::HistoricalContentChangeStatisticsReport + include Reports::Concerns::NotificationStats + + attr_reader :govuk_path + + def initialize(govuk_path) + @govuk_path = govuk_path + end + + def call + content_changes = ContentChange.where(base_path: govuk_path).order(:public_updated_at) + + if content_changes.any? + output_string = "#{content_changes.count} content changes registered for #{govuk_path}.\n\n" + + content_changes.each do |cc| + output_string += "Content change on #{cc.public_updated_at}:\n" + + lists = SubscriberListQuery.new(content_id: cc.content_id, tags: cc.tags, links: cc.links, document_type: cc.document_type, email_document_supertype: cc.email_document_supertype, government_document_supertype: cc.government_document_supertype).lists + + list_stats_array(lists).each { |ls| output_string += " - #{ls}\n" } + end + + output_string + else + "No content changes registered for path: #{govuk_path}" + end + end +end diff --git a/lib/tasks/report.rake b/lib/tasks/report.rake index bf560cbd5..e042fbfcf 100644 --- a/lib/tasks/report.rake +++ b/lib/tasks/report.rake @@ -29,10 +29,18 @@ namespace :report do puts Reports::SinglePageNotificationsReport.new(args[:limit] || 25).call.join("\n") end - desc "Output content-change information for a page URL" - task :content_change_statistics, %i[url] => :environment do |_t, args| - puts Reports::ContentChangeStatisticsReport.new( - args.fetch(:url), + desc "Output how many people were notified for recent content changes to the page at the given path" + task :historical_content_change_statistics, %i[govuk_path] => :environment do |_t, args| + puts Reports::HistoricalContentChangeStatisticsReport.new( + args.fetch(:govuk_path), + ).call + end + + desc "Output how many people would be notified if a major change were published at the given path" + task :future_content_change_statistics, %i[govuk_path draft] => :environment do |_t, args| + puts Reports::FutureContentChangeStatisticsReport.new( + args.fetch(:govuk_path), + args.fetch(:draft).downcase == "true", ).call end end