+ else
+ e ->
+ Logger.debug(fn -> "Couldn't gather info for #{username}" end)
+ {:error, e}
+ end
+ end
+
+ # Regex-based 'parsing' so we don't have to pull in a full html parser
+ # It's a hack anyway. Maybe revisit this in the future
+ @mastodon_regex ~r/<link href='(.*)' rel='alternate' type='application\/atom\+xml'>/
+ @gs_regex ~r/<link title=.* href="(.*)" type="application\/atom\+xml" rel="alternate">/
+ @gs_classic_regex ~r/<link rel="alternate" href="(.*)" type="application\/atom\+xml" title=.*>/
+ def get_atom_url(body) do
+ cond do
+ Regex.match?(@mastodon_regex, body) ->
+ [[_, match]] = Regex.scan(@mastodon_regex, body)
+ {:ok, match}
+
+ Regex.match?(@gs_regex, body) ->
+ [[_, match]] = Regex.scan(@gs_regex, body)
+ {:ok, match}
+
+ Regex.match?(@gs_classic_regex, body) ->
+ [[_, match]] = Regex.scan(@gs_classic_regex, body)
+ {:ok, match}
+
+ true ->
+ Logger.debug(fn -> "Couldn't find Atom link in #{inspect(body)}" end)
+ {:error, "Couldn't find the Atom link"}
+ end
+ end
+
+ def fetch_activity_from_atom_url(url) do
+ with true <- String.starts_with?(url, "http"),
+ {:ok, %{body: body, status_code: code}} when code in 200..299 <-
+ @httpoison.get(
+ url,
+ [Accept: "application/atom+xml"],
+ follow_redirect: true,
+ timeout: 10000,
+ recv_timeout: 20000
+ ) do
+ Logger.debug("Got document from #{url}, handling...")
+ handle_incoming(body)
+ else
+ e ->
+ Logger.debug("Couldn't get #{url}: #{inspect(e)}")
+ e
+ end
+ end
+
+ def fetch_activity_from_html_url(url) do
+ Logger.debug("Trying to fetch #{url}")
+
+ with true <- String.starts_with?(url, "http"),
+ {:ok, %{body: body}} <-
+ @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000),
+ {:ok, atom_url} <- get_atom_url(body) do
+ fetch_activity_from_atom_url(atom_url)
+ else
+ e ->
+ Logger.debug("Couldn't get #{url}: #{inspect(e)}")
+ e
+ end
+ end
+
+ def fetch_activity_from_url(url) do
+ try do
+ with {:ok, activities} when length(activities) > 0 <- fetch_activity_from_atom_url(url) do
+ {:ok, activities}
+ else
+ _e ->
+ with {:ok, activities} <- fetch_activity_from_html_url(url) do
+ {:ok, activities}
+ end
+ end
+ rescue
+ e ->
+ Logger.debug("Couldn't get #{url}: #{inspect(e)}")
+ {:error, "Couldn't get #{url}: #{inspect(e)}"}