defmodule LSG.IRC.LinkPlugin.Reddit do @behaviour LSG.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