Remove unused data from 2025 annual reports (#37033)

This commit is contained in:
Claire 2025-11-28 09:58:34 +01:00 committed by GitHub
parent 5f33ac208f
commit 945ef5a8e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 2 additions and 260 deletions

View File

@ -8,14 +8,11 @@ class AnnualReport
AnnualReport::TypeDistribution,
AnnualReport::TopStatuses,
AnnualReport::MostUsedApps,
AnnualReport::CommonlyInteractedWithAccounts,
AnnualReport::TimeSeries,
AnnualReport::TopHashtags,
AnnualReport::MostRebloggedAccounts,
AnnualReport::Percentiles,
].freeze
SCHEMA = 1
SCHEMA = 2
def self.table_name_prefix
'annual_report_'
@ -26,12 +23,6 @@ class AnnualReport
@year = year
end
def self.prepare(year)
SOURCES.each do |klass|
klass.prepare(year)
end
end
def generate
return if GeneratedAnnualReport.exists?(account: @account, year: @year)

View File

@ -1,27 +0,0 @@
# frozen_string_literal: true
class AnnualReport::CommonlyInteractedWithAccounts < AnnualReport::Source
MINIMUM_INTERACTIONS = 1
SET_SIZE = 40
def generate
{
commonly_interacted_with_accounts: commonly_interacted_with_accounts.map do |(account_id, count)|
{
account_id: account_id.to_s,
count: count,
}
end,
}
end
private
def commonly_interacted_with_accounts
report_statuses.not_replying_to_account(@account).group(:in_reply_to_account_id).having(minimum_interaction_count).order(count_all: :desc).limit(SET_SIZE).count
end
def minimum_interaction_count
Arel.star.count.gt(MINIMUM_INTERACTIONS)
end
end

View File

@ -1,27 +0,0 @@
# frozen_string_literal: true
class AnnualReport::MostRebloggedAccounts < AnnualReport::Source
MINIMUM_REBLOGS = 1
SET_SIZE = 10
def generate
{
most_reblogged_accounts: most_reblogged_accounts.map do |(account_id, count)|
{
account_id: account_id.to_s,
count: count,
}
end,
}
end
private
def most_reblogged_accounts
report_statuses.only_reblogs.joins(reblog: :account).group(accounts: [:id]).having(minimum_reblog_count).order(count_all: :desc).limit(SET_SIZE).count
end
def minimum_reblog_count
Arel.star.count.gt(MINIMUM_REBLOGS)
end
end

View File

@ -1,37 +0,0 @@
# frozen_string_literal: true
class AnnualReport::Percentiles < AnnualReport::Source
def self.prepare(year)
AnnualReport::StatusesPerAccountCount.connection.exec_query(<<~SQL.squish, nil, [year, Mastodon::Snowflake.id_at(DateTime.new(year).beginning_of_year), Mastodon::Snowflake.id_at(DateTime.new(year).end_of_year)])
INSERT INTO annual_report_statuses_per_account_counts (year, account_id, statuses_count)
SELECT $1, account_id, count(*)
FROM statuses
WHERE id BETWEEN $2 AND $3
AND (local OR uri IS NULL)
GROUP BY account_id
ON CONFLICT (year, account_id) DO NOTHING
SQL
end
def generate
{
percentiles: {
statuses: 100.0 - ((total_with_fewer_statuses / (total_with_any_statuses + 1.0)) * 100),
},
}
end
private
def statuses_created
@statuses_created ||= report_statuses.count
end
def total_with_fewer_statuses
@total_with_fewer_statuses ||= AnnualReport::StatusesPerAccountCount.where(year: year).where(statuses_count: ...statuses_created).count
end
def total_with_any_statuses
@total_with_any_statuses ||= AnnualReport::StatusesPerAccountCount.where(year: year).count
end
end

View File

@ -8,10 +8,6 @@ class AnnualReport::Source
@year = year
end
def self.prepare(_year)
# Use this method if any pre-calculations must be made before individual annual reports are generated
end
def generate
raise NotImplementedError
end

View File

@ -2,7 +2,7 @@
class AnnualReport::TopHashtags < AnnualReport::Source
MINIMUM_TAGGINGS = 1
SET_SIZE = 40
SET_SIZE = 5
def generate
{

View File

@ -1,50 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe AnnualReport::CommonlyInteractedWithAccounts do
describe '#generate' do
subject { described_class.new(account, Time.zone.now.year) }
context 'with an inactive account' do
let(:account) { Fabricate :account }
it 'builds a report for an account' do
expect(subject.generate)
.to include(
commonly_interacted_with_accounts: be_an(Array).and(be_empty)
)
end
end
context 'with an active account' do
let(:account) { Fabricate :account }
let(:other_account) { Fabricate :account }
let(:most_other_account) { Fabricate :account }
before do
_other = Fabricate :status
Fabricate :status, account: account, reply: true, in_reply_to_id: Fabricate(:status, account: other_account).id
Fabricate :status, account: account, reply: true, in_reply_to_id: Fabricate(:status, account: other_account).id
Fabricate :status, account: account, reply: true, in_reply_to_id: Fabricate(:status, account: most_other_account).id
Fabricate :status, account: account, reply: true, in_reply_to_id: Fabricate(:status, account: most_other_account).id
Fabricate :status, account: account, reply: true, in_reply_to_id: Fabricate(:status, account: most_other_account).id
end
it 'builds a report for an account' do
expect(subject.generate)
.to include(
commonly_interacted_with_accounts: eq(
[
{ account_id: most_other_account.id.to_s, count: 3 },
{ account_id: other_account.id.to_s, count: 2 },
]
)
)
end
end
end
end

View File

@ -1,49 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe AnnualReport::MostRebloggedAccounts do
describe '#generate' do
subject { described_class.new(account, Time.zone.now.year) }
context 'with an inactive account' do
let(:account) { Fabricate :account }
it 'builds a report for an account' do
expect(subject.generate)
.to include(
most_reblogged_accounts: be_an(Array).and(be_empty)
)
end
end
context 'with an active account' do
let(:account) { Fabricate :account }
let(:other_account) { Fabricate :account }
let(:most_other_account) { Fabricate :account }
before do
_other = Fabricate :status
Fabricate :status, account: account, reblog: Fabricate(:status, account: other_account)
Fabricate :status, account: account, reblog: Fabricate(:status, account: other_account)
Fabricate :status, account: account, reblog: Fabricate(:status, account: most_other_account)
Fabricate :status, account: account, reblog: Fabricate(:status, account: most_other_account)
Fabricate :status, account: account, reblog: Fabricate(:status, account: most_other_account)
end
it 'builds a report for an account' do
expect(subject.generate)
.to include(
most_reblogged_accounts: eq(
[
{ account_id: most_other_account.id.to_s, count: 3 },
{ account_id: other_account.id.to_s, count: 2 },
]
)
)
end
end
end
end

View File

@ -1,46 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe AnnualReport::Percentiles do
describe '#generate' do
subject { described_class.new(account, year) }
let(:year) { Time.zone.now.year }
context 'with an inactive account' do
let(:account) { Fabricate :account }
it 'builds a report for an account' do
described_class.prepare(year)
expect(subject.generate)
.to include(
percentiles: include(
statuses: 100
)
)
end
end
context 'with an active account' do
let(:account) { Fabricate :account }
before do
Fabricate.times 2, :status # Others as `account`
Fabricate.times 2, :status, account: account
end
it 'builds a report for an account' do
described_class.prepare(year)
expect(subject.generate)
.to include(
percentiles: include(
statuses: 50
)
)
end
end
end
end

View File

@ -13,13 +13,4 @@ RSpec.describe AnnualReport do
.to change(GeneratedAnnualReport, :count).by(1)
end
end
describe '.prepare' do
before { Fabricate :status }
it 'generates records from source class which prepare data' do
expect { described_class.prepare(Time.current.year) }
.to change(AnnualReport::StatusesPerAccountCount, :count).by(1)
end
end
end