5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-07-02 16:46:06 +00:00
panel/app/controllers/stats_controller.rb

125 lines
3.3 KiB
Ruby
Raw Normal View History

2019-08-02 00:20:42 +00:00
# frozen_string_literal: true
# Estadísticas del sitio
class StatsController < ApplicationController
include Pundit
2021-10-08 21:35:40 +00:00
include ActionView::Helpers::DateHelper
2019-08-02 00:20:42 +00:00
before_action :authenticate_usuarie!
before_action :authorize_stats
2019-08-02 00:20:42 +00:00
2021-10-08 21:36:31 +00:00
INTERVALS = %i[hour day week month year].freeze
RESOURCES = %i[builds space_used build_time].freeze
2021-10-08 19:31:02 +00:00
# XXX: Permitir a Chart.js inyectar su propio CSS
content_security_policy only: :index do |policy|
policy.style_src :self, :unsafe_inline
policy.script_src :self, :unsafe_inline
end
2019-08-02 00:20:42 +00:00
def index
2021-10-08 19:31:02 +00:00
@chart_params = { interval: interval }
hostnames
last_stat
2021-10-08 21:35:40 +00:00
chart_options
2021-10-08 19:31:02 +00:00
end
# Genera un gráfico de visitas por dominio asociado a este sitio
def host
if stale? [last_stat, hostnames, interval]
stats = Rollup.where_dimensions(host: hostnames).multi_series('host', interval: interval).tap do |series|
series.each do |serie|
serie[:name] = serie.dig(:dimensions, 'host')
serie[:data].transform_values! do |value|
value * nodes
end
2021-10-08 19:31:02 +00:00
end
end
render json: stats
2021-10-08 19:31:02 +00:00
end
end
2021-10-08 19:31:02 +00:00
def resources
if stale? [last_stat, interval, resource]
options = {
interval: interval,
dimensions: {
deploy_id: @site.deploys.where(type: 'DeployLocal').pluck(:id).first
}
}
render json: Rollup.series(resource, **options)
end
2021-10-08 19:31:02 +00:00
end
private
def last_stat
@last_stat ||= Stat.last
end
def authorize_stats
@site = find_site
authorize SiteStat.new(@site)
end
2021-10-08 19:31:02 +00:00
# TODO: Eliminar cuando mergeemos referer-origin
def hostnames
@hostnames ||= [@site.hostname, @site.alternative_hostnames].flatten
end
2021-10-08 21:35:40 +00:00
# Opciones por defecto para los gráficos.
#
# La invitación a volver dentro de X tiempo es para dar un estimado de
# cuándo habrá información disponible, porque Rollup genera intervalos
# completos (¿aunque dice que no?)
#
# La diferencia se calcula sumando el intervalo a la hora de última
# toma de estadísticas y restando el tiempo que pasó desde ese
# momento.
def chart_options
time = last_stat.created_at + (1.send(interval))
please_return_at = { please_return_at: distance_of_time_in_words(Time.now, time) }
@chart_options ||= {
locale: I18n.locale,
empty: I18n.t('stats.index.empty', **please_return_at),
loading: I18n.t('stats.index.loading'),
html: %(<div id="%{id}" class="d-flex align-items-center justify-content-center" style="height: %{height}; width: %{width};">%{loading}</div>)
}
end
2021-10-08 19:31:02 +00:00
# Obtiene y valida los intervalos
#
# @return [Symbol]
def interval
@interval ||= begin
i = params[:interval].to_sym
INTERVALS.include?(i) ? i : :day
end
end
def resource
@resource ||= begin
r = params[:resource].to_sym
RESOURCES.include?(r) ? r : :builds
end
end
2021-10-08 19:31:02 +00:00
# Obtiene la cantidad de nodos de Sutty, para poder calcular la
# cantidad de visitas.
#
# Como repartimos las visitas por nodo rotando las IPs en el
# nameserver y los resolvedores de DNS eligen un nameserver
# aleatoriamente, la cantidad de visitas se reparte
# equitativamente.
#
# XXX: Remover cuando podamos centralizar los AccessLog
#
# @return [Integer]
def nodes
@nodes ||= ENV.fetch('NODES', 1).to_i
2019-08-02 00:20:42 +00:00
end
end