diff --git a/lib/microwaveprop/radio/callsign_client.ex b/lib/microwaveprop/radio/callsign_client.ex new file mode 100644 index 00000000..da4a0481 --- /dev/null +++ b/lib/microwaveprop/radio/callsign_client.ex @@ -0,0 +1,37 @@ +defmodule Microwaveprop.Radio.CallsignClient do + @moduledoc "Looks up amateur radio callsign locations via gridmap.org." + + @doc """ + Fetch location for a callsign. Returns {:ok, %{callsign, gridsquare, lat, lon}} or {:error, reason}. + """ + def locate(callsign) do + url = "https://gridmap.org/locate/#{URI.encode(callsign)}" + + case Req.get(url, req_options() ++ [receive_timeout: 10_000]) do + {:ok, %{status: 200, body: %{"latitude" => lat, "longitude" => lon} = body}} when is_number(lat) -> + {:ok, + %{ + callsign: body["callsign"] || callsign, + gridsquare: body["gridsquare"], + lat: lat, + lon: lon + }} + + {:ok, %{status: 200, body: _}} -> + {:error, "callsign not found"} + + {:ok, %{status: 404}} -> + {:error, "callsign not found"} + + {:ok, %{status: status}} -> + {:error, "gridmap.org HTTP #{status}"} + + {:error, reason} -> + {:error, "gridmap.org failed: #{inspect(reason)}"} + end + end + + defp req_options do + Application.get_env(:microwaveprop, :callsign_req_options, []) + end +end diff --git a/lib/microwaveprop_web/components/layouts.ex b/lib/microwaveprop_web/components/layouts.ex index 49948635..0c24a22d 100644 --- a/lib/microwaveprop_web/components/layouts.ex +++ b/lib/microwaveprop_web/components/layouts.ex @@ -41,6 +41,7 @@ defmodule MicrowavepropWeb.Layouts do NTMS Propagation Prediction