47 lines
1.8 KiB
Ruby
47 lines
1.8 KiB
Ruby
module DiasporaFederation
|
|
module Federation
|
|
# This module is for fetching entities from other pods.
|
|
module Fetcher
|
|
# Fetches a public entity from a remote pod
|
|
# @param [String] author the diaspora* ID of the author of the entity
|
|
# @param [Symbol, String] entity_type snake_case version of the entity class
|
|
# @param [String] guid guid of the entity to fetch
|
|
def self.fetch_public(author, entity_type, guid)
|
|
type = entity_name(entity_type).to_s
|
|
raise "Already fetching ..." if fetching[type].include?(guid)
|
|
fetch_from_url(author, type, guid)
|
|
rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
|
|
raise NotFetchable, "Failed to fetch #{entity_type}:#{guid} from #{author}: #{e.class}: #{e.message}"
|
|
end
|
|
|
|
private_class_method def self.entity_name(class_name)
|
|
return class_name if class_name =~ /\A#{Entity::ENTITY_NAME_REGEX}\z/
|
|
|
|
raise DiasporaFederation::Entity::UnknownEntity, class_name unless Entities.const_defined?(class_name)
|
|
|
|
class_name.gsub(/(.)([A-Z])/, '\1_\2').downcase
|
|
end
|
|
|
|
private_class_method def self.fetch_from_url(author, type, guid)
|
|
fetching[type] << guid
|
|
|
|
url = DiasporaFederation.callbacks.trigger(:fetch_person_url_to, author, "/fetch/#{type}/#{guid}")
|
|
response = HttpClient.get(url)
|
|
raise "Failed to fetch #{url}: #{response.status}" unless response.success?
|
|
|
|
Receiver.receive_public(response.body)
|
|
ensure
|
|
fetching[type].delete(guid)
|
|
end
|
|
|
|
# currently fetching entities in the same thread
|
|
private_class_method def self.fetching
|
|
Thread.current[:fetching_entities] ||= Hash.new {|h, k| h[k] = [] }
|
|
end
|
|
|
|
# Raised, if the entity is not fetchable
|
|
class NotFetchable < RuntimeError
|
|
end
|
|
end
|
|
end
|
|
end
|