闭社主体 forked from https://github.com/tootsuite/mastodon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.3 KiB

  1. # frozen_string_literal: true
  2. module JsonLdHelper
  3. def equals_or_includes?(haystack, needle)
  4. haystack.is_a?(Array) ? haystack.include?(needle) : haystack == needle
  5. end
  6. def first_of_value(value)
  7. value.is_a?(Array) ? value.first : value
  8. end
  9. # The url attribute can be a string, an array of strings, or an array of objects.
  10. # The objects could include a mimeType. Not-included mimeType means it's text/html.
  11. def url_to_href(value, preferred_type = nil)
  12. single_value = if value.is_a?(Array) && !value.first.is_a?(String)
  13. value.find { |link| preferred_type.nil? || ((link['mimeType'].presence || 'text/html') == preferred_type) }
  14. elsif value.is_a?(Array)
  15. value.first
  16. else
  17. value
  18. end
  19. if single_value.nil? || single_value.is_a?(String)
  20. single_value
  21. else
  22. single_value['href']
  23. end
  24. end
  25. def as_array(value)
  26. value.is_a?(Array) ? value : [value]
  27. end
  28. def value_or_id(value)
  29. value.is_a?(String) || value.nil? ? value : value['id']
  30. end
  31. def supported_context?(json)
  32. !json.nil? && equals_or_includes?(json['@context'], ActivityPub::TagManager::CONTEXT)
  33. end
  34. def unsupported_uri_scheme?(uri)
  35. !uri.start_with?('http://', 'https://')
  36. end
  37. def canonicalize(json)
  38. graph = RDF::Graph.new << JSON::LD::API.toRdf(json)
  39. graph.dump(:normalize)
  40. end
  41. def fetch_resource(uri, id)
  42. unless id
  43. json = fetch_resource_without_id_validation(uri)
  44. return unless json
  45. uri = json['id']
  46. end
  47. json = fetch_resource_without_id_validation(uri)
  48. json.present? && json['id'] == uri ? json : nil
  49. end
  50. def fetch_resource_without_id_validation(uri)
  51. response = build_request(uri).perform
  52. return if response.code != 200
  53. body_to_json(response.to_s)
  54. end
  55. def body_to_json(body)
  56. body.is_a?(String) ? Oj.load(body, mode: :strict) : body
  57. rescue Oj::ParseError
  58. nil
  59. end
  60. def merge_context(context, new_context)
  61. if context.is_a?(Array)
  62. context << new_context
  63. else
  64. [context, new_context]
  65. end
  66. end
  67. private
  68. def build_request(uri)
  69. request = Request.new(:get, uri)
  70. request.add_headers('Accept' => 'application/activity+json, application/ld+json')
  71. request
  72. end
  73. end