2024-02-27 15:32:09 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'httparty'
|
|
|
|
|
|
|
|
# Listas de bloqueo y sus URLs de descarga
|
|
|
|
class ActivityPub
|
|
|
|
class Fediblock < ApplicationRecord
|
|
|
|
class Client
|
|
|
|
include ::HTTParty
|
|
|
|
|
|
|
|
# @param url [String]
|
|
|
|
# @return [HTTParty::Response]
|
|
|
|
def get(url)
|
|
|
|
self.class.get(url, parser: csv_parser)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Procesa el CSV
|
|
|
|
#
|
|
|
|
# @return [Proc]
|
|
|
|
def csv_parser
|
|
|
|
@csv_parser ||=
|
|
|
|
begin
|
|
|
|
require 'csv'
|
|
|
|
|
|
|
|
proc do |body, _|
|
|
|
|
CSV.parse(body, headers: true)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class FediblockDownloadError < ::StandardError; end
|
|
|
|
|
2024-03-19 12:47:24 +00:00
|
|
|
validates_presence_of :title, :url, :format
|
|
|
|
validates_inclusion_of :format, in: %w[mastodon fediblock none]
|
2024-02-27 15:32:09 +00:00
|
|
|
|
|
|
|
HOSTNAME_HEADERS = {
|
|
|
|
'mastodon' => '#domain',
|
|
|
|
'fediblock' => 'domain'
|
|
|
|
}
|
|
|
|
|
|
|
|
def client
|
|
|
|
@client ||= Client.new
|
|
|
|
end
|
|
|
|
|
2024-02-28 18:47:40 +00:00
|
|
|
# Todas las instancias de este fediblock
|
|
|
|
def instances
|
|
|
|
ActivityPub::Instance.where(hostname: hostnames)
|
|
|
|
end
|
|
|
|
|
2024-02-27 15:32:09 +00:00
|
|
|
# Descarga la lista y crea las instancias con el estado necesario
|
|
|
|
def process!
|
|
|
|
response = client.get(download_url)
|
|
|
|
|
|
|
|
raise FediblockDownloadError unless response.ok?
|
|
|
|
|
|
|
|
Fediblock.transaction do
|
|
|
|
csv = response.parsed_response
|
|
|
|
process_csv! csv
|
|
|
|
|
2024-02-28 18:47:40 +00:00
|
|
|
update(hostnames: csv.map { |r| r[hostname_header] })
|
2024-02-27 15:32:09 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def hostname_header
|
|
|
|
HOSTNAME_HEADERS[format]
|
|
|
|
end
|
|
|
|
|
|
|
|
# Crea o encuentra instancias que ya existían y las bloquea
|
|
|
|
#
|
|
|
|
# @param csv [CSV::Table]
|
|
|
|
def process_csv!(csv)
|
|
|
|
csv.each do |row|
|
|
|
|
ActivityPub::Instance.find_or_create_by(hostname: row[hostname_header]).tap do |i|
|
|
|
|
i.block! if i.may_block?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|