5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-16 17:46:21 +00:00
panel/app/jobs/uri_collection_job.rb

171 lines
4.5 KiB
Ruby
Raw Normal View History

2021-10-20 16:08:21 +00:00
# frozen_string_literal: true
# Procesar una lista de URIs para una lista de dominios. Esto nos
# permite procesar estadísticas a demanda.
#
# Hay varias cosas acá que van a convertirse en métodos propios, como la
# detección de URIs de un sitio (aunque la versión actual detecta todas
# las páginas y no solo las de posts como tenemos planeado, hay que
# resolver eso).
#
# Los hostnames de un sitio van a poder obtenerse a partir de
# Site#hostnames con la garantía de que son únicos.
class UriCollectionJob < PeriodicJob
2022-04-23 23:32:20 +00:00
include RecursiveRollup
# Ignoramos imágenes porque suelen ser demasiadas y no aportan a las
# estadísticas.
2022-04-23 21:56:34 +00:00
IMAGES = %w[.png .jpg .jpeg .gif .webp .jfif].freeze
STAT_NAME = 'uri_collection_job'
def perform(site_id:, once: true)
@site = Site.find site_id
2022-04-26 19:57:16 +00:00
return unless File.directory? destination
2021-10-20 16:08:21 +00:00
2022-04-23 20:50:36 +00:00
# Recordar la última vez que se corrió la tarea
stat = site.stats.create! name: STAT_NAME
2022-04-23 23:32:20 +00:00
beginning = beginning_of_interval
2022-04-29 18:04:42 +00:00
# Recorremos todos los hostnames y uris posibles y luego agrupamos
# recursivamente para no tener que recalcular, asumiendo que es más
# rápido buscar en los rollups indexados que en la tabla en bruto.
#
# Los referers solo se agrupan por host.
site.hostnames.each do |host|
2022-04-23 23:32:20 +00:00
break if stop?
2022-04-23 20:50:36 +00:00
2022-04-29 18:04:42 +00:00
dimensions = { host: host }
2021-10-20 16:08:21 +00:00
uris.each do |uri|
2022-04-23 23:32:20 +00:00
break if stop?
2022-04-29 18:04:42 +00:00
dimensions[:uri] = uri
2022-04-26 19:59:02 +00:00
2022-04-29 18:04:42 +00:00
rollup('host|uri', beginning, **dimensions)
reduce_rollup('host|uri', beginning, **dimensions)
end
2022-04-23 23:32:20 +00:00
2022-04-29 18:04:42 +00:00
dimensions.delete(:uri)
# Reducir todas las visitas a cantidad de visitas por host
recursive_rollup(name: 'host|uri',
new_name: 'host',
interval_previous: starting_interval,
interval: starting_interval,
dimensions: dimensions)
# Acumular por mes y año
reduce_rollup('host', beginning, **dimensions)
2022-04-26 19:59:02 +00:00
2022-04-29 18:04:42 +00:00
# Obtener orígenes de visitas por host
2022-04-26 19:59:02 +00:00
AccessLog.where(host: host).distinct(:http_referer).pluck(:http_referer).each do |http_referer|
2022-04-29 18:04:42 +00:00
dimensions[:http_referer] = http_referer
rollup('host|referer', beginning, **dimensions)
reduce_rollup('host|referer', beginning, **dimensions)
2022-04-26 19:59:02 +00:00
end
end
2022-04-23 20:50:36 +00:00
stat.touch
run_again! unless once
end
private
2022-04-29 18:04:42 +00:00
# Generar un rollup de access logs
2022-04-26 19:59:02 +00:00
#
# @param :name [String]
# @param :beginning [Time]
# @param :dimensions [Hash]
# @return [nil]
def rollup(name, beginning, **dimensions)
2022-04-23 23:32:20 +00:00
AccessLog.where(**dimensions)
.where('created_at >= ?', beginning)
.completed_requests
.non_robots
.group(*dimensions.keys)
.rollup(name, interval: starting_interval, update: true)
2022-04-29 18:04:42 +00:00
end
2022-04-23 23:32:20 +00:00
2022-04-29 18:04:42 +00:00
# Reducir las estadísticas calculadas aplicando un rollup sobre el
# intervalo más amplio.
#
# @param :name [String]
# @param :beginning [Time]
# @param :dimensions [Hash]
# @return [nil]
def reduce_rollup(name, beginning, **dimensions)
2022-04-23 23:32:20 +00:00
Stat::INTERVALS.reduce do |previous, current|
recursive_rollup(name: name,
interval_previous: previous,
interval: current,
dimensions: dimensions,
beginning: beginning)
# Devolver el intervalo actual
current
end
2022-04-29 18:04:42 +00:00
nil
2022-04-23 23:32:20 +00:00
end
def stat_name
STAT_NAME
end
# @return [String]
#
# TODO: Cambiar al mergear origin-referer
def destination
@destination ||= site.deploys.find_by(type: 'DeployLocal').destination
end
# Recolecta todas las URIs menos imágenes
#
# @return [Array]
def uris
2022-04-23 21:56:34 +00:00
@uris ||=
locales.map do |locale|
uri = "/#{locale}/".squeeze('/')
dir = File.join(destination, locale)
files(dir).map do |f|
uri + f
end
2022-04-23 21:56:34 +00:00
end.flatten(2)
end
# @return [Array]
def locales
@locales ||= ['', site.locales.map(&:to_s)].flatten(1)
end
# @param :dir [String]
# @return [Array]
def files(dir)
Dir.chdir(dir) do
pages = Dir.glob('**/*.html')
files = Dir.glob('public/**/*')
files = remove_directories files
files = remove_images files
[pages, files].flatten(1)
end
end
# @param :files [Array]
# @return [Array]
def remove_directories(files)
files.reject do |f|
File.directory? f
end
end
def remove_images(files)
files.reject do |f|
IMAGES.include? File.extname(f).downcase
2021-10-20 16:08:21 +00:00
end
end
end