Fix additional nesting depth issues across multiple files
Extracts nested logic into helper functions to comply with Credo requirements (max nesting depth 2): - data_builder.ex: Extract historical packet distance filtering (filter_historical_by_distance/3, packet_far_enough_from_most_recent?/3) Reduces depth 5 -> depth 3 - streaming_packets_pubsub.ex: Extract subscriber message sending (send_to_subscriber_if_alive/3) Reduces depth 4 -> depth 2 - aprs_symbol.ex: Extract symbol code calculation (get_symbol_code_ord/1) Reduces depth 3 -> depth 2 - mobile_channel.ex: Extract subscription bounds update (update_subscription_bounds/2) Reduces depth 3 -> depth 2 - core_components.ex: Extract SVG tag class insertion (add_class_to_svg_tag/2) Reduces depth 3 -> depth 2 - info_live/show.ex: Extract row mapping for database queries (map_digipeater_row/2, map_station_heard_row/2) Reduces depth 3 -> depth 2 (2 instances) Also updates .sobelow-skips with new line numbers from code changes. Fixes 7 Credo nesting depth issues (2 remaining)
This commit is contained in:
parent
74a19b0640
commit
318eb30046
7 changed files with 119 additions and 90 deletions
|
|
@ -20,4 +20,9 @@ XSS.Raw: XSS,lib/aprsme_web/live/info_live/show.ex:675,2E9B38C
|
|||
SQL.Query: SQL injection,lib/aprsme_web/live/info_live/show.ex:390,46E033F
|
||||
SQL.Query: SQL injection,lib/aprsme_web/live/info_live/show.ex:505,515E82C
|
||||
SQL.Query: SQL injection,lib/aprsme_web/live/info_live/show.ex:619,53BB748
|
||||
XSS.Raw: XSS,lib/aprsme_web/live/info_live/show.ex:693,EEA0E3
|
||||
XSS.Raw: XSS,lib/aprsme_web/live/info_live/show.ex:693,EEA0E3
|
||||
SQL.Query: SQL injection,lib/aprsme/packets.ex:664,17532E
|
||||
XSS.Raw: XSS,lib/aprsme_web/components/core_components.ex:48,1E00DD8
|
||||
SQL.Query: SQL injection,lib/aprsme_web/live/info_live/show.ex:603,52B452D
|
||||
XSS.Raw: XSS,lib/aprsme_web/live/info_live/show.ex:661,5C70BB5
|
||||
XSS.Raw: XSS,lib/aprsme_web/live/info_live/show.ex:643,692A7EC
|
||||
|
|
@ -123,14 +123,7 @@ defmodule Aprsme.StreamingPacketsPubSub do
|
|||
subscribers
|
||||
|> Stream.filter(fn {_pid, bounds} -> packet_in_bounds?(lat, lon, bounds) end)
|
||||
|> Enum.reduce([], fn {pid, _bounds}, acc ->
|
||||
# Only send if process is alive
|
||||
if Process.alive?(pid) do
|
||||
send(pid, {:streaming_packet, packet})
|
||||
acc
|
||||
else
|
||||
# Collect dead pid for cleanup
|
||||
[pid | acc]
|
||||
end
|
||||
send_to_subscriber_if_alive(pid, packet, acc)
|
||||
end)
|
||||
|
||||
# Send dead pids back to GenServer for cleanup
|
||||
|
|
@ -188,4 +181,14 @@ defmodule Aprsme.StreamingPacketsPubSub do
|
|||
|
||||
lat_in_bounds and lon_in_bounds
|
||||
end
|
||||
|
||||
defp send_to_subscriber_if_alive(pid, packet, acc) do
|
||||
if Process.alive?(pid) do
|
||||
send(pid, {:streaming_packet, packet})
|
||||
acc
|
||||
else
|
||||
# Collect dead pid for cleanup
|
||||
[pid | acc]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,11 +46,7 @@ defmodule AprsmeWeb.AprsSymbol do
|
|||
sprite_file = "/aprs-symbols/aprs-symbols-128-#{table_id}@2x.png"
|
||||
|
||||
# Get symbol position using ASCII-based calculation
|
||||
symbol_code_ord =
|
||||
symbol_code
|
||||
|> String.to_charlist()
|
||||
|> List.first()
|
||||
|> then(fn c -> if is_integer(c), do: c, else: 63 end)
|
||||
symbol_code_ord = get_symbol_code_ord(symbol_code)
|
||||
|
||||
index = symbol_code_ord - 33
|
||||
safe_index = max(0, min(index, 93))
|
||||
|
|
@ -369,4 +365,9 @@ defmodule AprsmeWeb.AprsSymbol do
|
|||
Map.get(data_extended, to_string(field)) ||
|
||||
default
|
||||
end
|
||||
|
||||
defp get_symbol_code_ord(symbol_code) do
|
||||
c = symbol_code |> String.to_charlist() |> List.first()
|
||||
if is_integer(c), do: c, else: 63
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -125,19 +125,7 @@ defmodule AprsmeWeb.MobileChannel do
|
|||
# Validate bounds
|
||||
case validate_bounds(bounds) do
|
||||
:ok ->
|
||||
# Unsubscribe from old bounds
|
||||
if socket.assigns[:bounds] do
|
||||
Aprsme.StreamingPacketsPubSub.unsubscribe(self())
|
||||
end
|
||||
|
||||
# Subscribe to new bounds
|
||||
Aprsme.StreamingPacketsPubSub.subscribe_to_bounds(self(), bounds)
|
||||
|
||||
socket = assign(socket, :bounds, bounds)
|
||||
|
||||
Logger.debug("Mobile client #{socket.assigns.client_id} updated bounds: #{inspect(bounds)}")
|
||||
|
||||
{:reply, {:ok, %{bounds: bounds, message: "Bounds updated"}}, socket}
|
||||
update_subscription_bounds(socket, bounds)
|
||||
|
||||
{:error, reason} ->
|
||||
{:reply, {:error, %{message: reason}}, socket}
|
||||
|
|
@ -501,4 +489,20 @@ defmodule AprsmeWeb.MobileChannel do
|
|||
false
|
||||
end
|
||||
end
|
||||
|
||||
defp update_subscription_bounds(socket, bounds) do
|
||||
# Unsubscribe from old bounds if they exist
|
||||
if socket.assigns[:bounds] do
|
||||
Aprsme.StreamingPacketsPubSub.unsubscribe(self())
|
||||
end
|
||||
|
||||
# Subscribe to new bounds
|
||||
Aprsme.StreamingPacketsPubSub.subscribe_to_bounds(self(), bounds)
|
||||
|
||||
socket = assign(socket, :bounds, bounds)
|
||||
|
||||
Logger.debug("Mobile client #{socket.assigns.client_id} updated bounds: #{inspect(bounds)}")
|
||||
|
||||
{:reply, {:ok, %{bounds: bounds, message: "Bounds updated"}}, socket}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -38,11 +38,7 @@ defmodule AprsmeWeb.CoreComponents do
|
|||
{:ok, contents} ->
|
||||
# Insert class attribute if not present
|
||||
Regex.replace(~r/<svg([^>]*?)>/, contents, fn _, attrs ->
|
||||
if String.contains?(attrs, "class=") do
|
||||
"<svg#{attrs}>"
|
||||
else
|
||||
"<svg class=\"#{class}\"#{attrs}>"
|
||||
end
|
||||
add_class_to_svg_tag(attrs, class)
|
||||
end)
|
||||
|
||||
_ ->
|
||||
|
|
@ -822,4 +818,12 @@ defmodule AprsmeWeb.CoreComponents do
|
|||
<% end %>
|
||||
"""
|
||||
end
|
||||
|
||||
defp add_class_to_svg_tag(attrs, class) do
|
||||
if String.contains?(attrs, "class=") do
|
||||
"<svg#{attrs}>"
|
||||
else
|
||||
"<svg class=\"#{class}\"#{attrs}>"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -505,23 +505,7 @@ defmodule AprsmeWeb.InfoLive.Show do
|
|||
case Repo.query(query, [callsign, one_month_ago]) do
|
||||
{:ok, result} ->
|
||||
result.rows
|
||||
|> Enum.map(fn row ->
|
||||
case row do
|
||||
[digipeater, first_heard, last_heard, packet_count, longest_path_time, longest_distance_km] ->
|
||||
%{
|
||||
digipeater: digipeater || "",
|
||||
first_heard: first_heard,
|
||||
last_heard: last_heard,
|
||||
packet_count: packet_count || 0,
|
||||
longest_distance_km: longest_distance_km,
|
||||
longest_distance: if(longest_distance_km, do: format_distance(longest_distance_km, locale)),
|
||||
longest_path_time: longest_path_time
|
||||
}
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end)
|
||||
|> Enum.map(fn row -> map_digipeater_row(row, locale) end)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|
||||
{:error, error} ->
|
||||
|
|
@ -619,23 +603,7 @@ defmodule AprsmeWeb.InfoLive.Show do
|
|||
case Repo.query(query, [callsign, one_month_ago]) do
|
||||
{:ok, result} ->
|
||||
result.rows
|
||||
|> Enum.map(fn row ->
|
||||
case row do
|
||||
[station, first_heard, last_heard, packet_count, longest_path_time, longest_distance_km] ->
|
||||
%{
|
||||
station: station || "",
|
||||
first_heard: first_heard,
|
||||
last_heard: last_heard,
|
||||
packet_count: packet_count || 0,
|
||||
longest_distance_km: longest_distance_km,
|
||||
longest_distance: if(longest_distance_km, do: format_distance(longest_distance_km, locale)),
|
||||
longest_path_time: longest_path_time
|
||||
}
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end)
|
||||
|> Enum.map(fn row -> map_station_heard_row(row, locale) end)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|
||||
{:error, error} ->
|
||||
|
|
@ -811,4 +779,40 @@ defmodule AprsmeWeb.InfoLive.Show do
|
|||
defp decode_tcpip_element("TCPIP"), do: gettext("TCPIP (Internet gateway)")
|
||||
defp decode_tcpip_element("TCPIP*"), do: gettext("TCPIP* (Internet gateway, no forward)")
|
||||
defp decode_tcpip_element(element), do: gettext("TCPIP gateway (%{element})", element: element)
|
||||
|
||||
defp map_digipeater_row(row, locale) do
|
||||
case row do
|
||||
[digipeater, first_heard, last_heard, packet_count, longest_path_time, longest_distance_km] ->
|
||||
%{
|
||||
digipeater: digipeater || "",
|
||||
first_heard: first_heard,
|
||||
last_heard: last_heard,
|
||||
packet_count: packet_count || 0,
|
||||
longest_distance_km: longest_distance_km,
|
||||
longest_distance: if(longest_distance_km, do: format_distance(longest_distance_km, locale)),
|
||||
longest_path_time: longest_path_time
|
||||
}
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
defp map_station_heard_row(row, locale) do
|
||||
case row do
|
||||
[station, first_heard, last_heard, packet_count, longest_path_time, longest_distance_km] ->
|
||||
%{
|
||||
station: station || "",
|
||||
first_heard: first_heard,
|
||||
last_heard: last_heard,
|
||||
packet_count: packet_count || 0,
|
||||
longest_distance_km: longest_distance_km,
|
||||
longest_distance: if(longest_distance_km, do: format_distance(longest_distance_km, locale)),
|
||||
longest_path_time: longest_path_time
|
||||
}
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -181,30 +181,7 @@ defmodule AprsmeWeb.MapLive.DataBuilder do
|
|||
|
||||
# Filter historical packets that are too close to most recent position
|
||||
filtered_historical =
|
||||
if most_recent_lat && most_recent_lon do
|
||||
Enum.filter(historical, fn packet ->
|
||||
{lat, lon, _} = get_coordinates(packet)
|
||||
|
||||
if lat && lon do
|
||||
distance_meters =
|
||||
CoordinateUtils.calculate_distance_meters(
|
||||
most_recent_lat,
|
||||
most_recent_lon,
|
||||
lat,
|
||||
lon
|
||||
)
|
||||
|
||||
# Only show if 10+ meters away
|
||||
distance_meters >= 10.0
|
||||
else
|
||||
# Skip packets without coordinates
|
||||
false
|
||||
end
|
||||
end)
|
||||
else
|
||||
# If most recent has no coordinates, include all historical
|
||||
historical
|
||||
end
|
||||
filter_historical_by_distance(historical, most_recent_lat, most_recent_lon)
|
||||
|
||||
# Build data for remaining historical packets
|
||||
historical_data =
|
||||
|
|
@ -620,4 +597,35 @@ defmodule AprsmeWeb.MapLive.DataBuilder do
|
|||
end
|
||||
|
||||
defp convert_rain(value, _locale), do: {value, "in"}
|
||||
|
||||
defp filter_historical_by_distance(historical, most_recent_lat, most_recent_lon) do
|
||||
if most_recent_lat && most_recent_lon do
|
||||
Enum.filter(historical, fn packet ->
|
||||
packet_far_enough_from_most_recent?(packet, most_recent_lat, most_recent_lon)
|
||||
end)
|
||||
else
|
||||
# If most recent has no coordinates, include all historical
|
||||
historical
|
||||
end
|
||||
end
|
||||
|
||||
defp packet_far_enough_from_most_recent?(packet, most_recent_lat, most_recent_lon) do
|
||||
{lat, lon, _} = get_coordinates(packet)
|
||||
|
||||
if lat && lon do
|
||||
distance_meters =
|
||||
CoordinateUtils.calculate_distance_meters(
|
||||
most_recent_lat,
|
||||
most_recent_lon,
|
||||
lat,
|
||||
lon
|
||||
)
|
||||
|
||||
# Only show if 10+ meters away
|
||||
distance_meters >= 10.0
|
||||
else
|
||||
# Skip packets without coordinates
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue