summaryrefslogtreecommitdiff
path: root/lib/nola_plugins/link_plugin/reddit.ex
blob: 79102e03947f5057c9f443d4b43dc080f2c195ce (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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
defmodule Nola.IRC.LinkPlugin.Reddit do
  @behaviour Nola.IRC.LinkPlugin

  @impl true
  def match(uri = %URI{host: "reddit.com", path: path}, _) do
    case String.split(path, "/") do
      ["", "r", sub, "comments", post_id, _slug] ->
        {true, %{mode: :post, path: path, sub: sub, post_id: post_id}}
      ["", "r", sub, "comments", post_id, _slug, ""] ->
        {true, %{mode: :post, path: path, sub: sub, post_id: post_id}}
      ["", "r", sub, ""] ->
        {true, %{mode: :sub, path: path, sub: sub}}
      ["", "r", sub] ->
        {true, %{mode: :sub, path: path, sub: sub}}
#      ["", "u", user] ->
#        {true, %{mode: :user, path: path, user: user}}
      _ ->
        false
    end
  end

  def match(uri = %URI{host: host, path: path}, opts) do
    if String.ends_with?(host, ".reddit.com") do
      match(%URI{uri | host: "reddit.com"}, opts)
    else
      false
    end
  end

  @impl true
  def post_match(_, _, _, _), do: false

  @impl true
  def expand(_, %{mode: :sub, sub: sub}, _opts) do
    url = "https://api.reddit.com/r/#{sub}/about"
    case HTTPoison.get(url) do
      {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
        sr = Jason.decode!(body)
             |> Map.get("data")
                      |> IO.inspect(limit: :infinity)
        description = Map.get(sr, "public_description")||Map.get(sr, "description", "")
                      |> String.split("\n")
                      |> List.first()
        name = if title = Map.get(sr, "title") do
          Map.get(sr, "display_name_prefixed") <> ": " <> title
        else
          Map.get(sr, "display_name_prefixed")
        end
        nsfw = if Map.get(sr, "over18") do
          "[NSFW] "
        else
          ""
        end
        quarantine = if Map.get(sr, "quarantine") do
          "[Quarantined] "
        else
          ""
        end
        count = "#{Map.get(sr, "subscribers")} subscribers, #{Map.get(sr, "active_user_count")} active"
        preview = "#{quarantine}#{nsfw}#{name}#{description} (#{count})"
        {:ok, preview}
      _ ->
        :error
    end
  end

  def expand(_uri, %{mode: :post, path: path, sub: sub, post_id: post_id}, _opts) do
    case HTTPoison.get("https://api.reddit.com#{path}?sr_detail=true") do
      {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
        json = Jason.decode!(body)
        op = List.first(json)
             |> Map.get("data")
             |> Map.get("children")
             |> List.first()
             |> Map.get("data")
             |> IO.inspect(limit: :infinity)
        sr = get_in(op, ["sr_detail", "display_name_prefixed"])
        {self?, url} = if Map.get(op, "selftext") == "" do
          {false, Map.get(op, "url")}
        else
          {true, nil}
        end

        self_str = if(self?, do: "text", else: url)
        up = Map.get(op, "ups")
        down = Map.get(op, "downs")
        comments = Map.get(op, "num_comments")
        nsfw = if Map.get(op, "over_18") do
          "[NSFW] "
        else
          ""
        end
        state = cond do
          Map.get(op, "hidden") -> "hidden"
          Map.get(op, "archived") -> "archived"
          Map.get(op, "locked") -> "locked"
          Map.get(op, "quarantine") -> "quarantined"
          Map.get(op, "removed_by") || Map.get(op, "removed_by_category") -> "removed"
          Map.get(op, "banned_by") -> "banned"
          Map.get(op, "pinned") -> "pinned"
          Map.get(op, "stickied") -> "stickied"
          true -> nil
        end
        flair = if flair = Map.get(op, "link_flair_text") do
          "[#{flair}] "
        else
          ""
        end
        title = "#{nsfw}#{sr}: #{flair}#{Map.get(op, "title")}"
        state_str = if(state, do: "#{state}, ")
        content = "by u/#{Map.get(op, "author")} - #{state_str}#{up} up, #{down} down, #{comments} comments - #{self_str}"

        {:ok, [title, content]}
      err ->
        :error
    end
  end

end