defmodule Nola.Plugins.Link.Github do @behaviour Nola.Plugins.Link @impl true def match(uri = %URI{host: "github.com", path: path}, _) do with ["", user, repo] <- String.split(path, "/") do {true, %{user: user, repo: repo, path: "#{user}/#{repo}"}} else _ -> false end end def match(_, _), do: false @impl true def post_match(_, _, _, _), do: false @impl true def expand(_uri, %{user: user, repo: repo}, _opts) do with {:ok, response} <- HTTPoison.get("https://api.github.com/repos/#{user}/#{repo}"), {:ok, json} <- Jason.decode(response.body) do info = %{ full_name: json["full_name"], disabled: json["disabled"], archived: json["archived"], source: json["source"], description: json["description"], topics: json["topics"], language: json["language"], open_issues_count: json["open_issues_count"], pushed_at: json["pushed_at"], stargazers_count: json["stargazers_count"], subscribers_count: json["subscribers_count"], forks_count: json["forks_count"] } start = build_start(info) tags = build_tags(info) network = build_network(info) {:ok, [start, tags, network]} else _ -> :error end end defp build_start(info) do parts = [] |> maybe_add(info.disabled, " (disabled)") |> maybe_add(info.archived, " (archived)") |> maybe_add(info.source && info.source["full_name"] != info.full_name, " (⑂ #{info.source["full_name"]})") "#{info.full_name}#{parts} - #{info.description}" end defp build_tags(info) do for(t <- info.topics || [], do: "##{t}") |> Enum.intersperse(", ") |> Enum.join("") end defp build_network(info) do lang = info.language && "#{info.language} - " || "" issues = info.open_issues_count && "#{info.open_issues_count} issues - " || "" last_push = if at = info.pushed_at do {:ok, date, _} = DateTime.from_iso8601(at) " - last pushed #{DateTime.to_string(date)}" else "" end "#{lang}#{issues}#{info.stargazers_count} stars - #{info.subscribers_count} watchers - #{info.forks_count} forks#{last_push}" end defp maybe_add(acc, condition, value) do if condition, do: acc ++ [value], else: acc end end