2022-06-13 23:32:34 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Onebox
|
|
|
|
class JsonLd < Normalizer
|
|
|
|
# Full schema.org hierarchy can be found here: https://schema.org/docs/full.html
|
|
|
|
MOVIE_JSON_LD_TYPE = "Movie"
|
2022-06-24 01:02:01 +08:00
|
|
|
SUPPORTED_TYPES = [MOVIE_JSON_LD_TYPE]
|
2022-06-13 23:32:34 +08:00
|
|
|
|
|
|
|
def initialize(doc)
|
|
|
|
@data = extract(doc)
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def extract(doc)
|
2023-10-08 01:54:26 +08:00
|
|
|
return {} if doc.blank?
|
2023-01-09 20:10:19 +08:00
|
|
|
|
2022-06-15 08:55:55 +08:00
|
|
|
doc
|
|
|
|
.css('script[type="application/ld+json"]')
|
|
|
|
.each do |element|
|
|
|
|
parsed_json = parse_json(element.text)
|
2023-01-09 20:10:19 +08:00
|
|
|
|
2022-06-24 01:02:01 +08:00
|
|
|
if parsed_json.kind_of?(Array)
|
|
|
|
parsed_json = parsed_json.detect { |x| SUPPORTED_TYPES.include?(x["@type"]) }
|
|
|
|
return {} if !parsed_json
|
2023-01-09 20:10:19 +08:00
|
|
|
end
|
|
|
|
|
2022-06-13 23:32:34 +08:00
|
|
|
case parsed_json["@type"]
|
|
|
|
when MOVIE_JSON_LD_TYPE
|
2022-06-15 08:55:55 +08:00
|
|
|
return Onebox::Movie.new(parsed_json).to_h
|
2023-01-09 20:10:19 +08:00
|
|
|
end
|
2022-06-24 01:02:01 +08:00
|
|
|
end
|
|
|
|
|
2022-06-15 08:55:55 +08:00
|
|
|
{}
|
2022-06-13 23:32:34 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def parse_json(json)
|
|
|
|
begin
|
|
|
|
JSON[json]
|
|
|
|
rescue JSON::ParserError => e
|
2022-06-15 08:55:55 +08:00
|
|
|
Discourse.warn_exception(e, message: "Error parsing JSON-LD: #{json}")
|
2022-06-13 23:32:34 +08:00
|
|
|
{}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|