2013-05-02 06:12:02 +08:00
class IncomingLinksReport
attr_accessor :type , :data , :y_titles
def initialize ( type )
@type = type
@y_titles = { }
@data = nil
end
def as_json
{
type : self . type ,
title : I18n . t ( " reports. #{ self . type } .title " ) ,
xaxis : I18n . t ( " reports. #{ self . type } .xaxis " ) ,
ytitles : self . y_titles ,
data : self . data
}
end
def self . find ( type , opts = { } )
report_method = :" report_ #{ type } "
return nil unless respond_to? ( report_method )
# Load the report
report = IncomingLinksReport . new ( type )
send ( report_method , report )
report
end
# Return top 10 users who brought traffic to the site within the last 30 days
def self . report_top_referrers ( report )
2013-05-06 23:56:35 +08:00
report . y_titles [ :num_clicks ] = I18n . t ( " reports. #{ report . type } .num_clicks " )
2013-05-02 06:12:02 +08:00
report . y_titles [ :num_topics ] = I18n . t ( " reports. #{ report . type } .num_topics " )
2013-05-06 23:56:35 +08:00
num_clicks = link_count_per_user
2013-05-02 06:12:02 +08:00
num_topics = topic_count_per_user
report . data = [ ]
2013-05-06 23:56:35 +08:00
num_clicks . keys . each do | username |
report . data << { username : username , num_clicks : num_clicks [ username ] , num_topics : num_topics [ username ] }
2013-05-02 06:12:02 +08:00
end
2013-05-06 23:56:35 +08:00
report . data = report . data . sort_by { | x | x [ :num_clicks ] } . reverse [ 0 , 10 ]
2013-05-02 06:12:02 +08:00
end
def self . per_user
@per_user_query || = IncomingLink . where ( 'incoming_links.created_at > ? AND incoming_links.user_id IS NOT NULL' , 30 . days . ago ) . joins ( :user ) . group ( 'users.username' )
end
def self . link_count_per_user
per_user . count
end
def self . topic_count_per_user
per_user . count ( 'incoming_links.topic_id' , distinct : true )
end
# Return top 10 domains that brought traffic to the site within the last 30 days
def self . report_top_traffic_sources ( report )
2013-05-06 23:56:35 +08:00
report . y_titles [ :num_clicks ] = I18n . t ( " reports. #{ report . type } .num_clicks " )
2013-05-02 06:12:02 +08:00
report . y_titles [ :num_topics ] = I18n . t ( " reports. #{ report . type } .num_topics " )
report . y_titles [ :num_users ] = I18n . t ( " reports. #{ report . type } .num_users " )
2013-05-06 23:56:35 +08:00
num_clicks = link_count_per_domain
2013-08-01 02:57:31 +08:00
num_topics = topic_count_per_domain ( num_clicks . keys )
num_users = user_count_per_domain ( num_clicks . keys )
2013-05-02 06:12:02 +08:00
report . data = [ ]
2013-05-06 23:56:35 +08:00
num_clicks . keys . each do | domain |
report . data << { domain : domain , num_clicks : num_clicks [ domain ] , num_topics : num_topics [ domain ] , num_users : num_users [ domain ] }
2013-05-02 06:12:02 +08:00
end
2013-05-06 23:56:35 +08:00
report . data = report . data . sort_by { | x | x [ :num_clicks ] } . reverse [ 0 , 10 ]
2013-05-02 06:12:02 +08:00
end
2013-08-01 02:57:31 +08:00
def self . link_count_per_domain ( limit = 10 )
IncomingLink . where ( 'created_at > ? AND domain IS NOT NULL' , 30 . days . ago ) . group ( 'domain' ) . order ( 'count_all DESC' ) . limit ( limit ) . count
2013-05-02 06:12:02 +08:00
end
2013-08-01 02:57:31 +08:00
def self . per_domain ( domains )
IncomingLink . where ( 'created_at > ? AND domain IN (?)' , 30 . days . ago , domains ) . group ( 'domain' )
2013-05-02 06:12:02 +08:00
end
2013-08-01 02:57:31 +08:00
def self . topic_count_per_domain ( domains )
# COUNT(DISTINCT) is slow
per_domain ( domains ) . count ( 'topic_id' , distinct : true )
2013-05-02 06:12:02 +08:00
end
2013-08-01 02:57:31 +08:00
def self . user_count_per_domain ( domains )
# COUNT(DISTINCT) is slow
per_domain ( domains ) . count ( 'user_id' , distinct : true )
2013-05-02 06:12:02 +08:00
end
def self . report_top_referred_topics ( report )
2013-05-06 23:56:35 +08:00
report . y_titles [ :num_clicks ] = I18n . t ( " reports. #{ report . type } .num_clicks " )
num_clicks = link_count_per_topic
num_clicks = num_clicks . to_a . sort_by { | x | x [ 1 ] } . last ( 10 ) . reverse # take the top 10
2013-05-02 06:12:02 +08:00
report . data = [ ]
2013-05-06 23:56:35 +08:00
topics = Topic . select ( 'id, slug, title' ) . where ( 'id in (?)' , num_clicks . map { | z | z [ 0 ] } ) . all
2013-06-10 13:08:10 +08:00
num_clicks . each do | topic_id , num_clicks_element |
2013-05-02 06:12:02 +08:00
topic = topics . find { | t | t . id == topic_id }
2013-05-02 07:10:31 +08:00
if topic
2013-06-10 13:08:10 +08:00
report . data << { topic_id : topic_id , topic_title : topic . title , topic_slug : topic . slug , num_clicks : num_clicks_element }
2013-05-02 07:10:31 +08:00
end
2013-05-02 06:12:02 +08:00
end
2013-05-02 07:10:31 +08:00
report . data
2013-05-02 06:12:02 +08:00
end
def self . link_count_per_topic
IncomingLink . where ( 'created_at > ? AND topic_id IS NOT NULL' , 30 . days . ago ) . group ( 'topic_id' ) . count
end
end