Display trending hashtags on admin dashboard (#8038)
This commit is contained in:
		| @ -27,6 +27,7 @@ module Admin | ||||
|       @saml_enabled          = ENV['SAML_ENABLED'] == 'true' | ||||
|       @pam_enabled           = ENV['PAM_ENABLED'] == 'true' | ||||
|       @hidden_service        = ENV['ALLOW_ACCESS_TO_HIDDEN_SERVICE'] == 'true' | ||||
|       @trending_hashtags     = TrendingTags.get(7) | ||||
|     end | ||||
|  | ||||
|     private | ||||
|  | ||||
| @ -1,7 +1,10 @@ | ||||
| # frozen_string_literal: true | ||||
|  | ||||
| class TrendingTags | ||||
|   KEY                  = 'trending_tags' | ||||
|   EXPIRE_HISTORY_AFTER = 7.days.seconds | ||||
|   EXPIRE_TRENDS_AFTER  = 1.day.seconds | ||||
|   THRESHOLD            = 5 | ||||
|  | ||||
|   class << self | ||||
|     def record_use!(tag, account, at_time = Time.now.utc) | ||||
| @ -9,6 +12,14 @@ class TrendingTags | ||||
|  | ||||
|       increment_historical_use!(tag.id, at_time) | ||||
|       increment_unique_use!(tag.id, account.id, at_time) | ||||
|       increment_vote!(tag.id, at_time) | ||||
|     end | ||||
|  | ||||
|     def get(limit) | ||||
|       key     = "#{KEY}:#{Time.now.utc.beginning_of_day.to_i}" | ||||
|       tag_ids = redis.zrevrange(key, 0, limit).map(&:to_i) | ||||
|       tags    = Tag.where(id: tag_ids).to_a.map { |tag| [tag.id, tag] }.to_h | ||||
|       tag_ids.map { |tag_id| tags[tag_id] }.compact | ||||
|     end | ||||
|  | ||||
|     private | ||||
| @ -25,6 +36,22 @@ class TrendingTags | ||||
|       redis.expire(key, EXPIRE_HISTORY_AFTER) | ||||
|     end | ||||
|  | ||||
|     def increment_vote!(tag_id, at_time) | ||||
|       key      = "#{KEY}:#{at_time.beginning_of_day.to_i}" | ||||
|       expected = redis.pfcount("activity:tags:#{tag_id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts").to_f | ||||
|       expected = 1.0 if expected.zero? | ||||
|       observed = redis.pfcount("activity:tags:#{tag_id}:#{at_time.beginning_of_day.to_i}:accounts").to_f | ||||
|  | ||||
|       if expected > observed || observed < THRESHOLD | ||||
|         redis.zrem(key, tag_id.to_s) | ||||
|       else | ||||
|         score = ((observed - expected)**2) / expected | ||||
|         redis.zadd(key, score, tag_id.to_s) | ||||
|       end | ||||
|  | ||||
|       redis.expire(key, EXPIRE_TRENDS_AFTER) | ||||
|     end | ||||
|  | ||||
|     def disallowed_hashtags | ||||
|       return @disallowed_hashtags if defined?(@disallowed_hashtags) | ||||
|  | ||||
|  | ||||
| @ -138,3 +138,12 @@ | ||||
|             %span.pull-right.positive-hint= fa_icon 'check fw' | ||||
|           - else | ||||
|             %span.pull-right.negative-hint= fa_icon 'times fw' | ||||
|  | ||||
|   .dashboard__widgets__trends | ||||
|     %div | ||||
|       %h4= t 'admin.dashboard.trends' | ||||
|       %ul | ||||
|         - @trending_hashtags.each do |tag| | ||||
|           %li | ||||
|             = link_to "##{tag.name}", web_url("timelines/tag/#{tag.name}") | ||||
|             %span.pull-right= number_with_delimiter(tag.history[0]['accounts'].to_i) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user