# Portions of this file are derived from Pleroma: # Pleroma: A lightweight social networking server # Copyright © 2017-2020 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Mobilizon.Service.RichMedia.Parsers.OGP do @moduledoc """ Module to parse OpenGraph data in HTML pages """ require Logger alias Mobilizon.Service.RichMedia.Parsers.MetaTagsParser @opengraph_properties [ :title, :type, :image, :url, :audio, :description, :determiner, :locale, :"locale:alternate", :site_name, :video, :"image:url", :"image.secure_url", :"image:type", :"image:width", :"image:height", :"image:alt" ] @spec parse(String.t(), map()) :: {:ok, map()} def parse(html, data) do Logger.debug("Using OpenGraph card parser") with {:ok, data} <- MetaTagsParser.parse( html, data, "og", "No OGP metadata found", :property, :content, @opengraph_properties ) do data = transform_tags(data) Logger.debug("Data found with OpenGraph card parser") {:ok, data} end end @spec transform_tags(map()) :: map() defp transform_tags(data) do data |> Enum.reject(fn {_, v} -> is_nil(v) end) |> Enum.map(fn {k, v} -> {k, String.trim(v)} end) |> Map.new() |> Map.update(:image_remote_url, Map.get(data, :image), & &1) |> Map.update(:width, get_integer_value(data, :"image:width"), & &1) |> Map.update(:height, get_integer_value(data, :"image:height"), & &1) end @spec get_integer_value(map(), atom()) :: integer() | nil defp get_integer_value(data, key) do with value when not is_nil(value) <- Map.get(data, key), {value, ""} <- Integer.parse(value) do value else _ -> nil end end end