Current section

Files

Jump to
snowhite lib modules weather server.ex
Raw

lib/modules/weather/server.ex

defmodule Snowhite.Modules.Weather.Server do
use GenServer
alias Snowhite.Helpers.TaskRunner
require Logger
def start_link(args) do
GenServer.start_link(__MODULE__, args, name: __MODULE__)
end
def update do
GenServer.cast(__MODULE__, :update)
end
def weather do
GenServer.call(__MODULE__, :weather)
end
def forecasts do
GenServer.call(__MODULE__, :forecasts)
end
def init(options) do
Logger.info("[#{inspect(__MODULE__)}] Started")
update()
Process.send_after(self(), :auto_sync, Keyword.fetch!(options, :refresh))
{:ok, %{options: options, forecasts: [], weather: nil}}
end
def handle_cast(:update, state) do
state = update(state)
send(self(), :notify)
{:noreply, state}
end
def handle_call(:weather, _, %{weather: weather} = state) do
{:reply, weather, state}
end
def handle_call(:forecasts, _, %{forecasts: forecasts} = state) do
{:reply, forecasts, state}
end
def handle_info(:auto_sync, %{options: options} = state) do
state = update(state)
send(self(), :notify)
Process.send_after(self(), :auto_sync, Keyword.fetch!(options, :refresh))
{:noreply, state}
end
def handle_info(:notify, state) do
Phoenix.PubSub.broadcast!(Snowhite.PubSub, "snowhite:modules:weather", :updated)
{:noreply, state}
end
defp update(%{options: options} = state) do
params = options_to_params(options)
api_key = Keyword.fetch!(options, :api_key)
results =
TaskRunner.run(%{
weather: fn -> current_weather(api_key, params) end,
forecasts: fn -> forecast(api_key, params) end
})
Map.merge(state, results)
end
defp current_weather(api_key, params) do
case OpenWeather.current_weather(api_key, params) do
{:ok, weather} -> weather
_ -> nil
end
end
defp forecast(api_key, params) do
case OpenWeather.forecast(api_key, params) do
{:ok, %{list: forecasts}} -> forecasts
_ -> []
end
end
defp options_to_params(options) do
%{
id: Keyword.fetch!(options, :city_id),
lang: Keyword.fetch!(options, :locale),
units: Keyword.fetch!(options, :units)
}
end
end