bd21d2a0e1eae9e8c87a671151fe24d70e30a76f
[akkoma] / lib / pleroma / web / rich_media / parser.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.RichMedia.Parser do
6 @parsers [
7 Pleroma.Web.RichMedia.Parsers.OGP,
8 Pleroma.Web.RichMedia.Parsers.TwitterCard,
9 Pleroma.Web.RichMedia.Parsers.OEmbed
10 ]
11
12 def parse(nil), do: {:error, "No URL provided"}
13
14 if Mix.env() == :test do
15 def parse(url), do: parse_url(url)
16 else
17 def parse(url) do
18 with {:ok, data} <- Cachex.fetch(:rich_media_cache, url, fn _ -> parse_url(url) end) do
19 data
20 else
21 _e ->
22 {:error, "Parsing error"}
23 end
24 end
25 end
26
27 defp parse_url(url) do
28 try do
29 {:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url)
30
31 html |> maybe_parse() |> get_parsed_data()
32 rescue
33 _e ->
34 {:error, "Parsing error"}
35 end
36 end
37
38 defp maybe_parse(html) do
39 Enum.reduce_while(@parsers, %{}, fn parser, acc ->
40 case parser.parse(html, acc) do
41 {:ok, data} -> {:halt, data}
42 {:error, _msg} -> {:cont, acc}
43 end
44 end)
45 end
46
47 defp get_parsed_data(data) when data == %{} do
48 {:error, "No metadata found"}
49 end
50
51 defp get_parsed_data(data) do
52 {:ok, data}
53 end
54 end