diff --git a/app/controllers/carto/superadmin/metrics_controller_helper.rb b/app/controllers/carto/superadmin/metrics_controller_helper.rb new file mode 100644 index 0000000000..19cc971283 --- /dev/null +++ b/app/controllers/carto/superadmin/metrics_controller_helper.rb @@ -0,0 +1,37 @@ +require_dependency 'carto/metrics/mapviews_usage_metrics' +require_dependency 'carto/metrics/usage_metrics_retriever' +require_dependency 'carto/metrics/twitter_imports_retriever' + +module Carto::Superadmin + module MetricsControllerHelper + USAGE_METRICS_CLASSES = [ + CartoDB::GeocoderUsageMetrics, + CartoDB::IsolinesUsageMetrics, + CartoDB::ObservatoryGeneralUsageMetrics, + CartoDB::ObservatorySnapshotUsageMetrics, + CartoDB::RoutingUsageMetrics, + Carto::Metrics::MapviewsUsageMetrics + ].freeze + + USAGE_METRICS_RETRIEVERS = ( + USAGE_METRICS_CLASSES.map { |cls| Carto::Metrics::UsageMetricsRetriever.new(cls) } + + [Carto::Metrics::TwitterImportsRetriever.new] + ).freeze + + private + + def get_usage(user, org, date_from, date_to) + usage = {} + USAGE_METRICS_RETRIEVERS.each do |retriever| + retriever.services.each do |service| + usage[service] = {} + retriever.metrics.each do |metric| + usage[service][metric] = retriever.get_range(user, org, service, metric, date_from, date_to) + end + end + end + + usage + end + end +end diff --git a/app/controllers/carto/superadmin/users_controller.rb b/app/controllers/carto/superadmin/users_controller.rb new file mode 100644 index 0000000000..1f4a77fbfb --- /dev/null +++ b/app/controllers/carto/superadmin/users_controller.rb @@ -0,0 +1,32 @@ +# encoding: UTF-8 + +require_dependency 'carto/superadmin/metrics_controller_helper' + +module Carto + module Superadmin + class UsersController < ::Superadmin::SuperadminController + include MetricsControllerHelper + + respond_to :json + + ssl_required :usage + before_filter :load_user + + def usage + date_to = (params[:to] ? params[:to].to_date : Date.today) + date_from = (params[:from] ? params[:from].to_date : Date.today) + + usage = get_usage(@user, nil, date_from, date_to) + + respond_with(usage) + end + + private + + def load_user + @user = Carto::User.where(id: params[:id]).first + render json: { error: 'User not found' }, status: 404 unless @user + end + end + end +end diff --git a/app/models/carto/search_tweet.rb b/app/models/carto/search_tweet.rb index ea4586bc55..7ebbd33cc4 100644 --- a/app/models/carto/search_tweet.rb +++ b/app/models/carto/search_tweet.rb @@ -10,10 +10,20 @@ module Carto def self.twitter_imports_count(query, date_from, date_to) query - .where('search_tweets.state' => ::SearchTweet::STATE_COMPLETE) - .where('search_tweets.created_at >= ? AND search_tweets.created_at <= ?', date_from, date_to + 1.days) - .sum("search_tweets.retrieved_items".lit).to_i + .where('search_tweets.state' => ::SearchTweet::STATE_COMPLETE) + .where('search_tweets.created_at >= ? AND search_tweets.created_at <= ?', date_from, date_to + 1.days) + .sum("search_tweets.retrieved_items".lit).to_i end + def self.twitter_imports_count_by_date(query, date_from, date_to) + query + .where('search_tweets.state' => ::SearchTweet::STATE_COMPLETE) + .where('search_tweets.created_at >= ? AND search_tweets.created_at <= ?', date_from, date_to + 1.days) + .group("date_trunc('day', search_tweets.created_at)") + .select("date_trunc('day', search_tweets.created_at), SUM(search_tweets.retrieved_items)") + .all + .map { |t| { t.date_trunc => t.sum } } + .reduce({}, &:merge) + end end end diff --git a/config/routes.rb b/config/routes.rb index 47327e1f06..1c9f4557d8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -610,6 +610,11 @@ CartoDB::Application.routes.draw do namespace :superadmin do resources :user_migration_exports, only: [:show, :create] resources :user_migration_imports, only: [:show, :create] + resources :users, only: [] do + member do + get '/usage' => 'users#usage' + end + end end end diff --git a/lib/carto/metrics/mapviews_usage_metrics.rb b/lib/carto/metrics/mapviews_usage_metrics.rb new file mode 100644 index 0000000000..863bbd8900 --- /dev/null +++ b/lib/carto/metrics/mapviews_usage_metrics.rb @@ -0,0 +1,19 @@ +module Carto::Metrics + class MapviewsUsageMetrics + VALID_METRICS = [ + :total_views + ].freeze + + VALID_SERVICES = [ + :mapviews + ].freeze + + def initialize(user, _org) + @user = user + end + + def get(_service, _metric, date) + CartoDB::Stats::APICalls.new.get_api_calls_from_redis_source(@user, 'mapviews', from: date, to: date).values[0] + end + end +end diff --git a/lib/carto/metrics/twitter_imports_retriever.rb b/lib/carto/metrics/twitter_imports_retriever.rb new file mode 100644 index 0000000000..e76813589e --- /dev/null +++ b/lib/carto/metrics/twitter_imports_retriever.rb @@ -0,0 +1,15 @@ +module Carto::Metrics + class TwitterImportsRetriever + def metrics + [:retrieved_items] + end + + def services + [:twitter_imports] + end + + def get_range(user, _org, _service, _metric, date_from, date_to) + Carto::SearchTweet.twitter_imports_count_by_date(user.search_tweets, date_from, date_to) + end + end +end diff --git a/lib/carto/metrics/usage_metrics_retriever.rb b/lib/carto/metrics/usage_metrics_retriever.rb new file mode 100644 index 0000000000..c750985fe2 --- /dev/null +++ b/lib/carto/metrics/usage_metrics_retriever.rb @@ -0,0 +1,27 @@ +module Carto::Metrics + class UsageMetricsRetriever + def initialize(cls) + @cls = cls + end + + def services + @cls::VALID_SERVICES + end + + def metrics + @cls::VALID_METRICS + end + + def get_range(user, org, service, metric, date_from, date_to) + user = user + org = org + usage_metrics = @cls.new(user.username, org ? org.name : nil) + + result = {} + date_from.upto(date_to).each do |date| + result[date] = usage_metrics.get(service, metric, date) + end + result + end + end +end