Current section

Files

Jump to
open_graphx lib open_graphx.ex
Raw

lib/open_graphx.ex

defmodule OpenGraphx do
defstruct description: nil, image: nil, site_name: nil, title: nil, type: nil, url: nil
@doc """
Load url and returns OpenGraphx data structure.
iex> OpenGraphx.load("http://matome.naver.jp/odai/2140474323219875301")
%OpenGraphx{description: "海外で行われているバスケットボールの練習動画を、今回はドリブルとハンドリングにしぼってまとめてみました。",
image: "http://rr.img.naver.jp:80/mig?src=http%3A%2F%2Fcdn3-www.hoopsvibe.com%2Fassets%2Fuploads%2F2006%2F11%2Ffile_45069_0_arton36313.jpg&twidth=200&theight=200&qlt=80&res_format=jpg&op=r",
site_name: "NAVER まとめ",
title: "バスケットボール動画 〜ドリブル&ハンドリング〜 - NAVER まとめ",
type: "article", url: "http://matome.naver.jp/odai/2140474323219875301"}
"""
def load(url) do
with {:ok, response} <- request(url),
{:ok, parsed} <- parse(response), do: parsed
end
defp request(url) do
HTTPoison.start
url
|> HTTPoison.get!
|> process_response
end
defp process_response(%HTTPoison.Response{body: body, status_code: status_code}) when status_code in 200..299 do
{:ok, body}
end
defp process_response(%HTTPoison.Response{body: body, status_code: _}), do: {:error, body}
defp parse(html) do
html
|> Floki.find("head meta")
|> Enum.filter(&exists_proeprty?/1)
|> to_struct
end
defp exists_proeprty?({_, attributes, _}) do
Enum.find(attributes,
fn {"property", _} -> true
_ -> false
end) != nil
end
defp to_struct(body) do
graph = body
|> Enum.map(&prop_content/1)
|> Enum.reduce(%OpenGraphx{}, &encode_node/2)
{:ok, graph}
end
defp encode_node({"og:description", description}, graph) do
%{graph | description: description}
end
defp encode_node({"og:image", image}, graph) do
%{graph | image: image}
end
defp encode_node({"og:site_name", site_name}, graph) do
%{graph | site_name: site_name}
end
defp encode_node({"og:title", title}, graph) do
%{graph | title: title}
end
defp encode_node({"og:type", type}, graph) do
%{graph | type: type}
end
defp encode_node({"og:url", url}, graph) do
%{graph | url: url}
end
defp encode_node(_, graph), do: graph
defp prop_content({"meta", args, _}) do
args = Enum.into(args, Map.new)
{args["property"], args["content"]}
end
defp prop_content(body) do
IO.inspect "error: #{body}"
end
end