63 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			63 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| class AnnualReport::Percentiles < AnnualReport::Source
 | |
|   def generate
 | |
|     {
 | |
|       percentiles: {
 | |
|         followers: (total_with_fewer_followers / (total_with_any_followers + 1.0)) * 100,
 | |
|         statuses: (total_with_fewer_statuses / (total_with_any_statuses + 1.0)) * 100,
 | |
|       },
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def followers_gained
 | |
|     @followers_gained ||= @account.passive_relationships.where("date_part('year', follows.created_at) = ?", @year).count
 | |
|   end
 | |
| 
 | |
|   def statuses_created
 | |
|     @statuses_created ||= report_statuses.count
 | |
|   end
 | |
| 
 | |
|   def total_with_fewer_followers
 | |
|     @total_with_fewer_followers ||= Follow.find_by_sql([<<~SQL.squish, { year: @year, comparison: followers_gained }]).first.total
 | |
|       WITH tmp0 AS (
 | |
|         SELECT follows.target_account_id
 | |
|         FROM follows
 | |
|         INNER JOIN accounts ON accounts.id = follows.target_account_id
 | |
|         WHERE date_part('year', follows.created_at) = :year
 | |
|           AND accounts.domain IS NULL
 | |
|         GROUP BY follows.target_account_id
 | |
|         HAVING COUNT(*) < :comparison
 | |
|       )
 | |
|       SELECT count(*) AS total
 | |
|       FROM tmp0
 | |
|     SQL
 | |
|   end
 | |
| 
 | |
|   def total_with_fewer_statuses
 | |
|     @total_with_fewer_statuses ||= Status.find_by_sql([<<~SQL.squish, { comparison: statuses_created, min_id: year_as_snowflake_range.first, max_id: year_as_snowflake_range.last }]).first.total
 | |
|       WITH tmp0 AS (
 | |
|         SELECT statuses.account_id
 | |
|         FROM statuses
 | |
|         INNER JOIN accounts ON accounts.id = statuses.account_id
 | |
|         WHERE statuses.id BETWEEN :min_id AND :max_id
 | |
|           AND accounts.domain IS NULL
 | |
|         GROUP BY statuses.account_id
 | |
|         HAVING count(*) < :comparison
 | |
|       )
 | |
|       SELECT count(*) AS total
 | |
|       FROM tmp0
 | |
|     SQL
 | |
|   end
 | |
| 
 | |
|   def total_with_any_followers
 | |
|     @total_with_any_followers ||= Follow.where("date_part('year', follows.created_at) = ?", @year).joins(:target_account).merge(Account.local).count('distinct follows.target_account_id')
 | |
|   end
 | |
| 
 | |
|   def total_with_any_statuses
 | |
|     @total_with_any_statuses ||= Status.where(id: year_as_snowflake_range).joins(:account).merge(Account.local).count('distinct statuses.account_id')
 | |
|   end
 | |
| end
 |