defmodule MetaInspector do @moduledoc false def get_info(link) do {200, data} = fetch_head(link) data |> get_all_meta_tags |> Enum.flat_map(&fetch_name_content/1) |> Enum.into(%{}) end def search(map, key) do map |> Enum.find(fn {k, _} -> k =~ key end) end defp fetch_head(link) do id = HTTPoison.get!(link, %{}, follow_redirect: true, stream_to: self).id loop(id) end defp get_all_meta_tags(string) do ~r// |> Regex.scan(string) |> List.flatten end defp fetch_name_content(string) do case Regex.run(~r/(name|property)=["'](.+?)["']/, string) do [_, _, name] -> case Regex.run(~r/content=["'](.+?)["']/, string) do [_, content] -> [{name, content}] nil -> [] end nil -> [] end end defp loop(id, code \\ nil, data \\ "") do receive do %HTTPoison.AsyncStatus{code: code, id: ^id} -> loop(id, code, data) %HTTPoison.AsyncHeaders{id: ^id} -> loop(id, code, data) %HTTPoison.AsyncChunk{chunk: chunk, id: ^id} -> data = data <> chunk if data =~ "" do {code, data} else loop(id, code, data <> chunk) end %HTTPoison.AsyncEnd{id: ^id} -> {code, data} end end end