Skip to content

Instantly share code, notes, and snippets.

@leite
Last active November 12, 2020 17:02
Show Gist options
  • Save leite/e36763a64744e3cacabbe70fbc139035 to your computer and use it in GitHub Desktop.
Save leite/e36763a64744e3cacabbe70fbc139035 to your computer and use it in GitHub Desktop.
weather responder ...
defmodule Docinho.Responders.Weather do
@moduledoc false
use Bitwise, only_operators: true
use Hedwig.Responder
require Logger
@openweathermap "http://api.openweathermap.org/data/2.5/weather"
@appid "fa821a2bed0d38581d64585d8e1ef3cc"
@moon_phases ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"]
@usage """
/tempo (cidade) - mostra tempo em determinada cidade
"""
hear ~r/^\/(tempo|clima) (.*,.*)$/, msg do
String.split(msg.matches[2], ",")
|> Enum.map(&(
if byte_size(&1) == 0, do: get_weather("sao+paulo"), else: clean(&1) |> get_weather
))
|> weather_reply(msg)
end
hear ~r/^\/(tempo|clima) ([^,]*)$/, msg do
clean(msg.matches[2])
|> get_weather
|> weather_reply(msg)
end
hear ~r/^\/(tempo|clima)$/, msg do
Enum.map(["sao+paulo", "lagarto", "araraquara"], &(get_weather(&1)))
|> weather_reply(msg)
end
defp get_weather city do
case HTTPoison.get("#{@openweathermap}?q=#{city}&units=metric&APPID=#{@appid}") do
{:ok, %{status_code: 200, body: body}} ->
Poison.decode(body)
|> weather_summary
{:ok, _} ->
Logger.error("[weather] Something happened")
{:error, %{reason: reason}} ->
Logger.error("[weather] #{inspect(reason)}")
end
end
defp weather_summary(
{:ok, %{
"name" => name,
"dt" => now,
"sys" => %{"country" => country,"sunrise" => sunrise,"sunset" => sunset},
"main" => %{"feels_like" => temp},
"weather" => [%{"main" => is} | _]
}}
) do
icon = case is do
"Clear" ->
if now > sunset or now < sunrise, do: moon_phase, else: "☀"
"Snow" -> "❄️"
"Clouds" -> "☁"
"Drizzle" -> "🌧️"
"Rain" -> "☔"
"Thunderstorm" -> "⛈️"
_ -> "🌫️"
end
"#{name} (#{country}) - #{trunc(temp)}°C #{icon}"
end
defp weather_summary(_), do: ""
defp weather_reply [head, second | tail], msg do
weather_reply ["#{head}\n#{second}" | tail], msg
end
defp weather_reply([content], msg), do: reply msg, content
defp weather_reply(content, msg), do: reply msg, content
@doc """
Returns the current moon phase, ref: https://gist.github.com/miklb/ed145757971096565723
"""
defp moon_phase do
{:ok, ref} = DateTime.from_unix(978307200)
diff = 0.20439731 + (((DateTime.utc_now |> DateTime.diff(ref)) / 86400) * 0.03386319269)
Enum.at(@moon_phases, floor(((diff - trunc(diff)) * 8.0) + 0.5) &&& 7)
end
defp clean value do
String.replace(value, ~r/[àáâãäå]/u, "a")
|> String.replace(~r/æ/u, "ae")
|> String.replace(~r/ç/u, "c")
|> String.replace(~r/[èéêë]/u, "e")
|> String.replace(~r/[ìíîï]/u, "i")
|> String.replace(~r/ñ/u, "n")
|> String.replace(~r/[òóôõö]/u, "o")
|> String.replace(~r/œ/u, "oe")
|> String.replace(~r/[ùúûü]/u, "u")
|> String.replace(~r/[ýÿ]/u, "y")
|> String.replace(" ", "+")
|> String.trim
|> String.to_charlist
|> Enum.filter(&(&1 in 0..127))
|> List.to_string
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment