5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-22 22:06:22 +00:00
panel/app/models/site/index.rb

132 lines
3.8 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
class Site
# Indexa todos los artículos de un sitio
#
# TODO: Hacer opcional
module Index
extend ActiveSupport::Concern
included do
has_many :indexed_posts, dependent: :destroy
2023-09-27 19:20:57 +00:00
MODIFIED_STATUSES = %i[added modified].freeze
DELETED_STATUSES = %i[deleted].freeze
LOCALE_FROM_PATH = /\A_/.freeze
def index_posts!
Site.transaction do
jekyll.read
jekyll.documents.each do |doc|
doc.read!
2023-10-27 14:33:24 +00:00
Post.build(document: doc, site: self, layout: doc['layout'].to_sym).index!
end
update(last_indexed_commit: repository.head_commit.oid)
end
end
2023-09-27 19:20:57 +00:00
# Encuentra los artículos modificados entre dos commits y los
# reindexa.
def reindex_changes!
return unless reindexable?
Site.transaction do
remove_deleted_posts!
reindex_modified_posts!
update(last_indexed_commit: repository.head_commit.oid)
end
end
# No hacer nada si el repositorio no cambió o no hubo cambios
# necesarios
def reindexable?
return false if last_indexed_commit.blank?
return false if last_indexed_commit == repository.head_commit.oid
!indexable_posts.empty?
end
private
# Trae el último commit indexado desde el repositorio
#
# @return [Rugged::Commit]
def indexed_commit
@indexed_commit ||= repository.rugged.lookup(last_indexed_commit)
end
# Calcula la diferencia entre el último commit indexado y el
# actual
#
# XXX: Esto no tiene en cuenta modificaciones en la historia como
# cambio de ramas, reverts y etc, solo asume que se mueve hacia
# adelante en la misma rama o las dos ramas están relacionadas.
#
# @return [Rugged::Diff]
def diff_with_head
@diff_with_head ||= indexed_commit.diff(repository.head_commit)
end
# Obtiene todos los archivos a reindexar
#
# @return [Array<Rugged::Delta>]
def indexable_posts
@indexable_posts ||=
diff_with_head.each_delta.select do |delta|
locales.any? do |locale|
delta.old_file[:path].start_with? "_#{locale}/"
end
end
end
# Elimina los artículos eliminados o que cambiaron de ubicación
# del índice
def remove_deleted_posts!
indexable_posts.select do |delta|
DELETED_STATUSES.include? delta.status
end.each do |delta|
locale, path = locale_and_path_from(delta.old_file[:path])
indexed_posts.destroy_by(locale: locale, path: path).tap do |destroyed_posts|
next unless destroyed_posts.empty?
Rails.logger.info I18n.t('indexed_posts.deleted', site: name, path: path, records: destroyed_posts.count)
end
end
end
2023-09-27 19:20:57 +00:00
# Reindexa artículos que cambiaron de ubicación, se agregaron
# o fueron modificados
def reindex_modified_posts!
indexable_posts.select do |delta|
MODIFIED_STATUSES.include? delta.status
end.each do |delta|
2024-06-04 15:49:37 +00:00
locale, = locale_and_path_from(delta.new_file[:path])
full_path = File.join(path, delta.new_file[:path])
2023-09-27 19:20:57 +00:00
Post.build(path: full_path, site: self, layout: Post.find_layout(full_path), locale: locale).index!
2023-09-27 19:20:57 +00:00
end
end
# Obtiene el idioma y la ruta del post a partir de la ubicación en
# el disco.
#
# Las rutas vienen en ASCII-9BIT desde Rugged, pero en realidad
# son UTF-8
2023-09-27 19:20:57 +00:00
#
# @return [Array<String>]
def locale_and_path_from(path)
locale, path = path.force_encoding('utf-8').split(File::SEPARATOR, 2)
2023-09-27 19:20:57 +00:00
[
locale.sub(LOCALE_FROM_PATH, ''),
File.basename(path, '.*')
]
end
end
end
end