summaryrefslogtreecommitdiff
path: root/lib/plugins/link/github.ex
blob: 77fa81fc0d7de1f1eb2437808bd05f5070952097 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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