96 lines
2.6 KiB
Elixir
96 lines
2.6 KiB
Elixir
defmodule SomethingErlang.AwfulApi.Client do
|
|
@base_url "https://forums.somethingawful.com/"
|
|
@user_agent "SomethingErlangClient/0.1"
|
|
|
|
require Logger
|
|
|
|
def thread_doc(id, page, user) do
|
|
resp = new(user) |> get_thread(id, page)
|
|
Logger.debug("Client reply in #{resp.private.time}ms ")
|
|
:unicode.characters_to_binary(resp.body, :latin1)
|
|
end
|
|
|
|
def thread_lastseen_page(id, user) do
|
|
resp = new(user) |> get_thread_newpost(id)
|
|
%{status: 302, headers: headers} = resp
|
|
{"location", redir_url} = List.keyfind(headers, "location", 0)
|
|
[_, page] = Regex.run(~r/pagenumber=(\d+)/, redir_url)
|
|
page |> String.to_integer()
|
|
end
|
|
|
|
def bookmarks_doc(page, user) do
|
|
resp = new(user) |> get_bookmarks(page)
|
|
:unicode.characters_to_binary(resp.body, :latin1)
|
|
end
|
|
|
|
defp get_thread(req, id, page) do
|
|
url = "showthread.php"
|
|
params = [threadid: id, pagenumber: page]
|
|
Req.get!(req, url: url, params: params)
|
|
end
|
|
|
|
defp get_thread_newpost(req, id) do
|
|
url = "showthread.php"
|
|
params = [threadid: id, goto: "newpost"]
|
|
Req.get!(req, url: url, params: params, follow_redirects: false)
|
|
end
|
|
|
|
defp get_bookmarks(req, page) do
|
|
url = "bookmarkthreads.php"
|
|
params = [pagenumber: page]
|
|
Req.get!(req, url: url, params: params)
|
|
end
|
|
|
|
def login(username, password) do
|
|
form = [action: "login", username: username, password: password]
|
|
url = "account.php"
|
|
|
|
new()
|
|
|> Req.post!(url: url, form: form)
|
|
|> extract_cookies()
|
|
end
|
|
|
|
defp extract_cookies(%Req.Response{} = response) do
|
|
cookies = response.headers["set-cookie"]
|
|
|
|
for cookie <- cookies, String.starts_with?(cookie, "bb"), into: %{} do
|
|
cookie
|
|
|> String.split(";", parts: 2)
|
|
|> List.first()
|
|
|> String.split("=")
|
|
|> then(fn [k, v] -> {String.to_existing_atom(k), v} end)
|
|
end
|
|
end
|
|
|
|
defp new(user) do
|
|
Req.new(
|
|
base_url: @base_url,
|
|
user_agent: @user_agent,
|
|
cache: false,
|
|
headers: [cookie: [cookies(%{bbuserid: user.id, bbpassword: user.hash})]]
|
|
)
|
|
|> Req.Request.append_request_steps(
|
|
time: fn req -> Req.Request.put_private(req, :time, Time.utc_now()) end
|
|
)
|
|
|> Req.Request.prepend_response_steps(
|
|
time: fn {req, res} ->
|
|
start = req.private.time
|
|
diff = Time.diff(Time.utc_now(), start, :millisecond)
|
|
{req, Req.Response.put_private(res, :time, diff)}
|
|
end
|
|
)
|
|
end
|
|
|
|
defp new() do
|
|
Req.new(
|
|
base_url: @base_url,
|
|
user_agent: @user_agent,
|
|
redirect: false
|
|
)
|
|
end
|
|
|
|
defp cookies(args) when is_map(args) do
|
|
Enum.map_join(args, "; ", fn {k, v} -> "#{k}=#{v}" end)
|
|
end
|
|
end
|