Fix CSV parsing and page number input validation
- RFC 4180 CSV parser: handles quoted fields with commas and escaped
quotes ("Smith, John" no longer breaks parsing)
- Safe page number parsing: non-numeric input defaults to page 1
instead of raising ArgumentError
This commit is contained in:
parent
79af4e4959
commit
2b14e836f1
2 changed files with 48 additions and 2 deletions
|
|
@ -56,7 +56,7 @@ defmodule Microwaveprop.Radio.CsvImport do
|
|||
end
|
||||
|
||||
defp parse_and_import_row(line, submitter_email) do
|
||||
fields = line |> String.split(",") |> Enum.map(&String.trim/1)
|
||||
fields = parse_csv_fields(line)
|
||||
|
||||
if length(fields) == @expected_columns do
|
||||
attrs =
|
||||
|
|
@ -174,6 +174,48 @@ defmodule Microwaveprop.Radio.CsvImport do
|
|||
{:ok, "#{y}-#{m}-#{d}T#{h}:#{mi}:#{s}Z"}
|
||||
end
|
||||
|
||||
# RFC 4180 CSV field parser. Handles quoted fields with commas and escaped quotes.
|
||||
defp parse_csv_fields(line) do
|
||||
line
|
||||
|> String.trim()
|
||||
|> do_parse_fields([], "")
|
||||
|> Enum.reverse()
|
||||
|> Enum.map(&String.trim/1)
|
||||
end
|
||||
|
||||
defp do_parse_fields("", acc, current), do: [current | acc]
|
||||
|
||||
defp do_parse_fields(<<"\"", rest::binary>>, acc, "") do
|
||||
parse_quoted_field(rest, acc, "")
|
||||
end
|
||||
|
||||
defp do_parse_fields(<<",", rest::binary>>, acc, current) do
|
||||
do_parse_fields(rest, [current | acc], "")
|
||||
end
|
||||
|
||||
defp do_parse_fields(<<c, rest::binary>>, acc, current) do
|
||||
do_parse_fields(rest, acc, current <> <<c>>)
|
||||
end
|
||||
|
||||
defp parse_quoted_field(<<"\"\"", rest::binary>>, acc, current) do
|
||||
parse_quoted_field(rest, acc, current <> "\"")
|
||||
end
|
||||
|
||||
defp parse_quoted_field(<<"\"", rest::binary>>, acc, current) do
|
||||
# End of quoted field — skip to next comma or end
|
||||
case rest do
|
||||
<<"," , rest2::binary>> -> do_parse_fields(rest2, [current | acc], "")
|
||||
"" -> [current | acc]
|
||||
_ -> do_parse_fields(rest, [current | acc], "")
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_quoted_field(<<c, rest::binary>>, acc, current) do
|
||||
parse_quoted_field(rest, acc, current <> <<c>>)
|
||||
end
|
||||
|
||||
defp parse_quoted_field("", acc, current), do: [current | acc]
|
||||
|
||||
defp changeset_error_strings(changeset) do
|
||||
changeset
|
||||
|> Ecto.Changeset.traverse_errors(fn {message, opts} ->
|
||||
|
|
|
|||
|
|
@ -15,7 +15,11 @@ defmodule MicrowavepropWeb.ContactLive.Index do
|
|||
|
||||
@impl true
|
||||
def handle_params(params, _uri, socket) do
|
||||
page = params |> Map.get("page", "1") |> String.to_integer() |> max(1)
|
||||
page =
|
||||
case Integer.parse(Map.get(params, "page", "1")) do
|
||||
{n, _} -> max(n, 1)
|
||||
:error -> 1
|
||||
end
|
||||
sort_by = validate_sort_field(Map.get(params, "sort_by", @default_sort_by))
|
||||
sort_order = validate_sort_order(Map.get(params, "sort_order", @default_sort_order))
|
||||
search = Map.get(params, "search", "")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue