* Add trending links * Add overriding specific links trendability * Add link type to preview cards and only trend articles Change trends review notifications from being sent every 5 minutes to being sent every 2 hours Change threshold from 5 unique accounts to 15 unique accounts * Fix tests
		
			
				
	
	
		
			99 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
class Trends::History
 | 
						|
  include Enumerable
 | 
						|
 | 
						|
  class Aggregate
 | 
						|
    include Redisable
 | 
						|
 | 
						|
    def initialize(prefix, id, date_range)
 | 
						|
      @days = date_range.map { |date| Day.new(prefix, id, date.to_time(:utc)) }
 | 
						|
    end
 | 
						|
 | 
						|
    def uses
 | 
						|
      redis.mget(*@days.map { |day| day.key_for(:uses) }).map(&:to_i).sum
 | 
						|
    end
 | 
						|
 | 
						|
    def accounts
 | 
						|
      redis.pfcount(*@days.map { |day| day.key_for(:accounts) })
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  class Day
 | 
						|
    include Redisable
 | 
						|
 | 
						|
    EXPIRE_AFTER = 14.days.seconds
 | 
						|
 | 
						|
    def initialize(prefix, id, day)
 | 
						|
      @prefix = prefix
 | 
						|
      @id     = id
 | 
						|
      @day    = day.beginning_of_day
 | 
						|
    end
 | 
						|
 | 
						|
    attr_reader :day
 | 
						|
 | 
						|
    def accounts
 | 
						|
      redis.pfcount(key_for(:accounts))
 | 
						|
    end
 | 
						|
 | 
						|
    def uses
 | 
						|
      redis.get(key_for(:uses))&.to_i || 0
 | 
						|
    end
 | 
						|
 | 
						|
    def add(account_id)
 | 
						|
      redis.pipelined do
 | 
						|
        redis.incrby(key_for(:uses), 1)
 | 
						|
        redis.pfadd(key_for(:accounts), account_id)
 | 
						|
        redis.expire(key_for(:uses), EXPIRE_AFTER)
 | 
						|
        redis.expire(key_for(:accounts), EXPIRE_AFTER)
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    def as_json
 | 
						|
      { day: day.to_i.to_s, accounts: accounts.to_s, uses: uses.to_s }
 | 
						|
    end
 | 
						|
 | 
						|
    def key_for(suffix)
 | 
						|
      case suffix
 | 
						|
      when :accounts
 | 
						|
        "#{key_prefix}:#{suffix}"
 | 
						|
      when :uses
 | 
						|
        key_prefix
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    def key_prefix
 | 
						|
      "activity:#{@prefix}:#{@id}:#{day.to_i}"
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  def initialize(prefix, id)
 | 
						|
    @prefix = prefix
 | 
						|
    @id     = id
 | 
						|
  end
 | 
						|
 | 
						|
  def get(date)
 | 
						|
    Day.new(@prefix, @id, date)
 | 
						|
  end
 | 
						|
 | 
						|
  def add(account_id, at_time = Time.now.utc)
 | 
						|
    Day.new(@prefix, @id, at_time).add(account_id)
 | 
						|
  end
 | 
						|
 | 
						|
  def aggregate(date_range)
 | 
						|
    Aggregate.new(@prefix, @id, date_range)
 | 
						|
  end
 | 
						|
 | 
						|
  def each(&block)
 | 
						|
    if block_given?
 | 
						|
      (0...7).map { |i| block.call(get(i.days.ago)) }
 | 
						|
    else
 | 
						|
      to_enum(:each)
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  def as_json(*)
 | 
						|
    map(&:as_json)
 | 
						|
  end
 | 
						|
end
 |