cartodb/lib/cartodb/trending_maps.rb
2020-06-15 10:58:47 +08:00

86 lines
3.1 KiB
Ruby

require 'uuidtools'
module CartoDB
class TrendingMaps
# The ratio for this sequence is 2
GEOMETRIC_SEQUENCE_BASE = 500
DAYS_TO_CHECK = 1
def get_trending_maps(simulation=false)
trending_maps = {}
stats_manager = CartoDB::Stats::APICalls.new
date = Date.today - DAYS_TO_CHECK.days
date_key = date.strftime("%Y%m%d")
$users_metadata.scan_each(:match => "user:*") do |key|
next if key =~ /global/
key_parts = key.split(':')
username = key_parts[1]
visualization_id = key_parts[4]
next unless valid_uuid?(visualization_id)
yesterday_mapviews = stats_manager.get_api_calls_from_redis(
username,
from: date,
to: date,
stat_tag: visualization_id
)
total_mapviews = stats_manager.get_total_api_calls_from_redis(username, visualization_id)
if is_trending_map?(yesterday_mapviews[date_key], total_mapviews)
trending_map_data = build_trending_map(visualization_id, username, total_mapviews)
trending_maps[visualization_id] = trending_map_data unless trending_map_data.blank?
end
end
trending_maps
end
def valid_uuid?(visualization_id)
UUIDTools::UUID.parse(visualization_id)
true
rescue ArgumentError
false
end
def build_trending_map(visualization_id, username, total_mapviews)
visualization = Carto::Visualization.find(visualization_id)
{
user: username,
user_mail: visualization.user.email,
user_public_url: visualization.user.public_url,
mapviews: total_mapviews,
visualization_name: visualization.name
}
rescue => e
CartoDB.notify_error("Trending map visualization unknown", visualization: visualization_id, error: e.inspect)
{}
end
def notify_trending_map(visualization_id, mapviews, preview_image = nil)
::Resque.enqueue(::Resque::UserJobs::Mail::TrendingMap, visualization_id, mapviews, preview_image)
end
def send_trending_map_report(trending_visualizations)
reports_mail_to = Cartodb.get_config(:reports, 'mail_to')
if reports_mail_to.blank?
CartoDB.notify_error("Reporter mail_to property missing")
else
::Resque.enqueue(
::Resque::Reporter::Mail::TrendingMapsReport,
reports_mail_to,
trending_visualizations
)
end
end
def is_trending_map?(mapviews_number_before, total_mapviews_today)
return false if total_mapviews_today < GEOMETRIC_SEQUENCE_BASE
total_mapviews_yesterday = total_mapviews_today - mapviews_number_before
geometric_sequence_position_yesterday = Math.log2(total_mapviews_yesterday/GEOMETRIC_SEQUENCE_BASE)
geometric_sequence_position_today = Math.log2(total_mapviews_today/GEOMETRIC_SEQUENCE_BASE)
# Base case where yesterday was minor than 500 and now is 500 or more
return true if geometric_sequence_position_yesterday < 0 && geometric_sequence_position_today >= 0
geometric_sequence_position_today.to_i > geometric_sequence_position_yesterday.to_i
end
end
end