2013-05-01 18:12:02 -04:00
class IncomingLinksReport
attr_accessor :type , :data , :y_titles
def initialize ( type )
@type = type
@y_titles = { }
@data = nil
end
2014-08-20 23:44:19 +05:30
def as_json ( _options = nil )
2013-05-01 18:12:02 -04:00
{
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
2014-08-20 23:44:19 +05:30
def self . find ( type , _opts = { } )
2013-05-01 18:12:02 -04:00
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 11:56:35 -04:00
report . y_titles [ :num_clicks ] = I18n . t ( " reports. #{ report . type } .num_clicks " )
2013-05-01 18:12:02 -04:00
report . y_titles [ :num_topics ] = I18n . t ( " reports. #{ report . type } .num_topics " )
2013-05-06 11:56:35 -04:00
num_clicks = link_count_per_user
2013-05-01 18:12:02 -04:00
num_topics = topic_count_per_user
2016-02-22 14:30:58 -05:00
user_id_lookup = User . where ( username : num_clicks . keys ) . select ( :id , :username ) . inject ( { } ) { | sum , v | sum [ v . username ] = v . id ; sum ; }
2013-05-01 18:12:02 -04:00
report . data = [ ]
2015-04-18 21:53:53 +10:00
num_clicks . each_key do | username |
2016-02-22 14:30:58 -05:00
report . data << { username : username , user_id : user_id_lookup [ username ] , num_clicks : num_clicks [ username ] , num_topics : num_topics [ username ] }
2013-05-01 18:12:02 -04:00
end
2013-05-06 11:56:35 -04:00
report . data = report . data . sort_by { | x | x [ :num_clicks ] } . reverse [ 0 , 10 ]
2013-05-01 18:12:02 -04:00
end
def self . per_user
2014-08-04 16:43:57 +10:00
@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' )
2013-05-01 18:12:02 -04:00
end
def self . link_count_per_user
per_user . count
end
def self . topic_count_per_user
2014-11-24 10:04:06 -08:00
per_user . joins ( :post ) . count ( " DISTINCT posts.topic_id " )
2013-05-01 18:12:02 -04:00
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 11:56:35 -04:00
report . y_titles [ :num_clicks ] = I18n . t ( " reports. #{ report . type } .num_clicks " )
2013-05-01 18:12:02 -04: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 11:56:35 -04:00
num_clicks = link_count_per_domain
2013-07-31 14:57:31 -04:00
num_topics = topic_count_per_domain ( num_clicks . keys )
2013-05-01 18:12:02 -04:00
report . data = [ ]
2015-04-18 21:53:53 +10:00
num_clicks . each_key do | domain |
2013-08-02 16:37:24 -04:00
report . data << { domain : domain , num_clicks : num_clicks [ domain ] , num_topics : num_topics [ domain ] }
2013-05-01 18:12:02 -04:00
end
2013-05-06 11:56:35 -04:00
report . data = report . data . sort_by { | x | x [ :num_clicks ] } . reverse [ 0 , 10 ]
2013-05-01 18:12:02 -04:00
end
2013-07-31 14:57:31 -04:00
def self . link_count_per_domain ( limit = 10 )
2014-08-04 16:43:57 +10:00
IncomingLink . where ( 'incoming_links.created_at > ?' , 30 . days . ago )
. joins ( :incoming_referer = > :incoming_domain )
. group ( 'incoming_domains.name' )
. order ( 'count_all DESC' )
. limit ( limit ) . count
2013-05-01 18:12:02 -04:00
end
2013-07-31 14:57:31 -04:00
def self . per_domain ( domains )
2014-08-04 16:43:57 +10:00
IncomingLink
. joins ( :incoming_referer = > :incoming_domain )
. where ( 'incoming_links.created_at > ? AND incoming_domains.name IN (?)' , 30 . days . ago , domains )
. group ( 'incoming_domains.name' )
2013-05-01 18:12:02 -04:00
end
2013-07-31 14:57:31 -04:00
def self . topic_count_per_domain ( domains )
# COUNT(DISTINCT) is slow
2014-11-24 10:04:06 -08:00
per_domain ( domains ) . joins ( :post ) . count ( " DISTINCT posts.topic_id " )
2013-05-01 18:12:02 -04:00
end
def self . report_top_referred_topics ( report )
2013-05-06 11:56:35 -04: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-01 18:12:02 -04:00
report . data = [ ]
2013-08-25 23:18:11 +02:00
topics = Topic . select ( 'id, slug, title' ) . where ( 'id in (?)' , num_clicks . map { | z | z [ 0 ] } )
2013-06-10 10:38:10 +05:30
num_clicks . each do | topic_id , num_clicks_element |
2013-05-01 18:12:02 -04:00
topic = topics . find { | t | t . id == topic_id }
2013-05-01 19:10:31 -04:00
if topic
2013-06-10 10:38:10 +05:30
report . data << { topic_id : topic_id , topic_title : topic . title , topic_slug : topic . slug , num_clicks : num_clicks_element }
2013-05-01 19:10:31 -04:00
end
2013-05-01 18:12:02 -04:00
end
2013-05-01 19:10:31 -04:00
report . data
2013-05-01 18:12:02 -04:00
end
def self . link_count_per_topic
2014-08-04 16:43:57 +10:00
IncomingLink . joins ( :post )
. where ( 'incoming_links.created_at > ? AND topic_id IS NOT NULL' , 30 . days . ago )
. group ( 'topic_id' )
. count
2013-05-01 18:12:02 -04:00
end
2013-08-25 23:18:11 +02:00
end