Add Twitter Card parser
authorMaxim Filippov <colixer@gmail.com>
Thu, 10 Jan 2019 18:09:56 +0000 (18:09 +0000)
committerkaniini <nenolod@gmail.com>
Thu, 10 Jan 2019 18:09:56 +0000 (18:09 +0000)
lib/pleroma/web/rich_media/parser.ex
lib/pleroma/web/rich_media/parsers/meta_tags_parser.ex [new file with mode: 0644]
lib/pleroma/web/rich_media/parsers/ogp.ex
lib/pleroma/web/rich_media/parsers/twitter_card.ex [new file with mode: 0644]
test/fixtures/rich_media/twitter_card.html [new file with mode: 0644]
test/web/rich_media/parser_test.exs

index 18d9e2df5cdb56f28c8cd31ef788c9a3ae5518fe..fe092bf193b547184a15048bc34744b163fd8dd0 100644 (file)
@@ -1,5 +1,5 @@
 defmodule Pleroma.Web.RichMedia.Parser do
-  @parsers [Pleroma.Web.RichMedia.Parsers.OGP]
+  @parsers [Pleroma.Web.RichMedia.Parsers.OGP, Pleroma.Web.RichMedia.Parsers.TwitterCard]
 
   if Mix.env() == :test do
     def parse(url), do: parse_url(url)
diff --git a/lib/pleroma/web/rich_media/parsers/meta_tags_parser.ex b/lib/pleroma/web/rich_media/parsers/meta_tags_parser.ex
new file mode 100644 (file)
index 0000000..4a7c5ea
--- /dev/null
@@ -0,0 +1,30 @@
+defmodule Pleroma.Web.RichMedia.Parsers.MetaTagsParser do
+  def parse(html, data, prefix, error_message, key_name, value_name \\ "content") do
+    with elements = [_ | _] <- get_elements(html, key_name, prefix),
+         meta_data =
+           Enum.reduce(elements, data, fn el, acc ->
+             attributes = normalize_attributes(el, prefix, key_name, value_name)
+
+             Map.merge(acc, attributes)
+           end) do
+      {:ok, meta_data}
+    else
+      _e -> {:error, error_message}
+    end
+  end
+
+  defp get_elements(html, key_name, prefix) do
+    html |> Floki.find("meta[#{key_name}^='#{prefix}:']")
+  end
+
+  defp normalize_attributes(html_node, prefix, key_name, value_name) do
+    {_tag, attributes, _children} = html_node
+
+    data =
+      Enum.into(attributes, %{}, fn {name, value} ->
+        {name, String.trim_leading(value, "#{prefix}:")}
+      end)
+
+    %{String.to_atom(data[key_name]) => data[value_name]}
+  end
+end
index 5773a52632f476ec328996c525102d16ed03189a..0e1a0e7199452e3763b5320fafd0c54c1b99c3b6 100644 (file)
@@ -1,30 +1,11 @@
 defmodule Pleroma.Web.RichMedia.Parsers.OGP do
   def parse(html, data) do
-    with elements = [_ | _] <- get_elements(html),
-         ogp_data =
-           Enum.reduce(elements, data, fn el, acc ->
-             attributes = normalize_attributes(el)
-
-             Map.merge(acc, attributes)
-           end) do
-      {:ok, ogp_data}
-    else
-      _e -> {:error, "No OGP metadata found"}
-    end
-  end
-
-  defp get_elements(html) do
-    html |> Floki.find("meta[property^='og:']")
-  end
-
-  defp normalize_attributes(html_node) do
-    {_tag, attributes, _children} = html_node
-
-    data =
-      Enum.into(attributes, %{}, fn {name, value} ->
-        {name, String.trim_leading(value, "og:")}
-      end)
-
-    %{String.to_atom(data["property"]) => data["content"]}
+    Pleroma.Web.RichMedia.Parsers.MetaTagsParser.parse(
+      html,
+      data,
+      "og",
+      "No OGP metadata found",
+      "property"
+    )
   end
 end
diff --git a/lib/pleroma/web/rich_media/parsers/twitter_card.ex b/lib/pleroma/web/rich_media/parsers/twitter_card.ex
new file mode 100644 (file)
index 0000000..a317c3e
--- /dev/null
@@ -0,0 +1,11 @@
+defmodule Pleroma.Web.RichMedia.Parsers.TwitterCard do
+  def parse(html, data) do
+    Pleroma.Web.RichMedia.Parsers.MetaTagsParser.parse(
+      html,
+      data,
+      "twitter",
+      "No twitter card metadata found",
+      "name"
+    )
+  end
+end
diff --git a/test/fixtures/rich_media/twitter_card.html b/test/fixtures/rich_media/twitter_card.html
new file mode 100644 (file)
index 0000000..34c7c6c
--- /dev/null
@@ -0,0 +1,5 @@
+<meta name="twitter:card" content="summary" />
+<meta name="twitter:site" content="@flickr" />
+<meta name="twitter:title" content="Small Island Developing States Photo Submission" />
+<meta name="twitter:description" content="View the album on Flickr." />
+<meta name="twitter:image" content="https://farm6.staticflickr.com/5510/14338202952_93595258ff_z.jpg" />
index caf81e9fa44b6ced32ed0bbb69c1e0513e5ad99e..ff3486a6d5e5765114ec900d63130de7fcbd9303 100644 (file)
@@ -9,6 +9,12 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
       } ->
         %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}
 
+      %{
+        method: :get,
+        url: "http://example.com/twitter-card"
+      } ->
+        %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/twitter_card.html")}
+
       %{method: :get, url: "http://example.com/empty"} ->
         %Tesla.Env{status: 200, body: "hello"}
     end)
@@ -30,4 +36,16 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
                 url: "http://www.imdb.com/title/tt0117500/"
               }}
   end
+
+  test "parses twitter card" do
+    assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/twitter-card") ==
+             {:ok,
+              %{
+                card: "summary",
+                site: "@flickr",
+                image: "https://farm6.staticflickr.com/5510/14338202952_93595258ff_z.jpg",
+                title: "Small Island Developing States Photo Submission",
+                description: "View the album on Flickr."
+              }}
+  end
 end