From 1cbf180d570782b6f337153cb992ed9c2772bc2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Tue, 20 Aug 2024 11:00:03 +0200 Subject: [PATCH 01/23] Extract helpers for enRoute Chouette Valid --- .../enroute_chouette_valid_client_helpers.ex | 32 +++++++++++++++++++ .../validators/netex_validator_test.exs | 27 +--------------- 2 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 apps/transport/test/support/enroute_chouette_valid_client_helpers.ex diff --git a/apps/transport/test/support/enroute_chouette_valid_client_helpers.ex b/apps/transport/test/support/enroute_chouette_valid_client_helpers.ex new file mode 100644 index 0000000000..43112901ac --- /dev/null +++ b/apps/transport/test/support/enroute_chouette_valid_client_helpers.ex @@ -0,0 +1,32 @@ +defmodule Transport.Test.EnRouteChouetteValidClientHelpers do + @moduledoc """ + This module defines helpers to setup a mock enRoute Chouette Valid client. + """ + import Mox + + def expect_create_validation do + validation_id = Ecto.UUID.generate() + expect(Transport.EnRouteChouetteValidClient.Mock, :create_a_validation, fn _ -> validation_id end) + validation_id + end + + def expect_pending_validation(validation_id) do + expect(Transport.EnRouteChouetteValidClient.Mock, :get_a_validation, fn ^validation_id -> :pending end) + end + + def expect_successful_validation(validation_id, elapsed) do + expect(Transport.EnRouteChouetteValidClient.Mock, :get_a_validation, fn ^validation_id -> + {:successful, "http://localhost:9999/chouette-valid/#{validation_id}", elapsed} + end) + end + + def expect_failed_validation(validation_id, elapsed) do + expect(Transport.EnRouteChouetteValidClient.Mock, :get_a_validation, fn ^validation_id -> {:failed, elapsed} end) + end + + def expect_get_messages(validation_id, result) do + expect(Transport.EnRouteChouetteValidClient.Mock, :get_messages, fn ^validation_id -> + {"http://localhost:9999/chouette-valid/#{validation_id}/messages", result} + end) + end +end diff --git a/apps/transport/test/transport/validators/netex_validator_test.exs b/apps/transport/test/transport/validators/netex_validator_test.exs index 70714a1755..1f0e579deb 100644 --- a/apps/transport/test/transport/validators/netex_validator_test.exs +++ b/apps/transport/test/transport/validators/netex_validator_test.exs @@ -3,6 +3,7 @@ defmodule Transport.Validators.NeTExTest do import DB.Factory import Mox import ExUnit.CaptureLog + import Transport.Test.EnRouteChouetteValidClientHelpers alias Transport.Validators.NeTEx @@ -230,32 +231,6 @@ defmodule Transport.Validators.NeTExTest do end end - defp expect_create_validation do - validation_id = Ecto.UUID.generate() - expect(Transport.EnRouteChouetteValidClient.Mock, :create_a_validation, fn _ -> validation_id end) - validation_id - end - - defp expect_pending_validation(validation_id) do - expect(Transport.EnRouteChouetteValidClient.Mock, :get_a_validation, fn ^validation_id -> :pending end) - end - - defp expect_successful_validation(validation_id, elapsed) do - expect(Transport.EnRouteChouetteValidClient.Mock, :get_a_validation, fn ^validation_id -> - {:successful, "http://localhost:9999/chouette-valid/#{validation_id}", elapsed} - end) - end - - defp expect_failed_validation(validation_id, elapsed) do - expect(Transport.EnRouteChouetteValidClient.Mock, :get_a_validation, fn ^validation_id -> {:failed, elapsed} end) - end - - defp expect_get_messages(validation_id, result) do - expect(Transport.EnRouteChouetteValidClient.Mock, :get_messages, fn ^validation_id -> - {"http://localhost:9999/chouette-valid/#{validation_id}/messages", result} - end) - end - defp mk_netex_resource do dataset = insert(:dataset) From dbb123f12252c8809ca0f20d311bf35af1ecbe60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Thu, 25 Jul 2024 17:01:17 +0200 Subject: [PATCH 02/23] On demand NeTEx validation with enRoute --- .../lib/jobs/on_demand_validation_job.ex | 23 ++++++ .../controllers/resource_controller.ex | 4 +- .../controllers/validation_controller.ex | 47 +++++++----- .../live/on_demand_validation_live.ex | 6 +- .../resource/_netex_generic_issue.html.heex | 23 ++++++ .../resource/_resources_details.html.heex | 4 +- .../resource/_validation_summary.html.heex | 4 +- .../templates/resource/gtfs_details.html.heex | 2 +- .../{show.html.heex => show_gtfs.html.heex} | 9 ++- .../templates/validation/show_netex.html.heex | 61 +++++++++++++++ .../lib/transport_web/views/resource_view.ex | 17 +++-- .../transport_web/views/validation_view.ex | 2 +- .../validators/gtfs_transport_validator.ex | 4 + .../lib/validators/netex_validator.ex | 10 ++- .../gettext/en/LC_MESSAGES/netex-validator.po | 4 + .../LC_MESSAGES/validations-explanations.po | 16 ++++ .../gettext/en/LC_MESSAGES/validations.po | 6 +- .../gettext/fr/LC_MESSAGES/netex-validator.po | 4 + .../LC_MESSAGES/validations-explanations.po | 16 ++++ .../gettext/fr/LC_MESSAGES/validations.po | 6 +- .../priv/gettext/netex-validator.pot | 4 + .../priv/gettext/validations-explanations.pot | 16 ++++ apps/transport/priv/gettext/validations.pot | 4 + .../jobs/on_demand_validation_job_test.exs | 76 ++++++++++++++++++- 24 files changed, 325 insertions(+), 43 deletions(-) create mode 100644 apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex rename apps/transport/lib/transport_web/templates/validation/{show.html.heex => show_gtfs.html.heex} (89%) create mode 100644 apps/transport/lib/transport_web/templates/validation/show_netex.html.heex diff --git a/apps/transport/lib/jobs/on_demand_validation_job.ex b/apps/transport/lib/jobs/on_demand_validation_job.ex index a1f977a0a1..b657c1d449 100644 --- a/apps/transport/lib/jobs/on_demand_validation_job.ex +++ b/apps/transport/lib/jobs/on_demand_validation_job.ex @@ -15,6 +15,7 @@ defmodule Transport.Jobs.OnDemandValidationJob do alias Transport.DataVisualization alias Transport.Validators.GTFSRT alias Transport.Validators.GTFSTransport + alias Transport.Validators.NeTEx @download_timeout_ms 10_000 @impl Oban.Worker @@ -71,6 +72,28 @@ defmodule Transport.Jobs.OnDemandValidationJob do end end + defp perform_validation(%{"type" => "netex", "permanent_url" => url}) do + validator = NeTEx.validator_name() + + case NeTEx.validate(url, []) do + {:error, msg} -> + %{oban_args: %{"state" => "error", "error_reason" => msg}, validator: validator} + + {:ok, %{"validations" => validation, "metadata" => metadata}} -> + %{ + result: validation, + metadata: metadata, + data_vis: nil, + validator: validator, + validated_data_name: url, + max_error: NeTEx.get_max_severity_error(validation), + oban_args: %{ + "state" => "completed" + } + } + end + end + defp perform_validation(%{ "type" => "tableschema", "permanent_url" => url, diff --git a/apps/transport/lib/transport_web/controllers/resource_controller.ex b/apps/transport/lib/transport_web/controllers/resource_controller.ex index 38eb7aed04..9db1312ac5 100644 --- a/apps/transport/lib/transport_web/controllers/resource_controller.ex +++ b/apps/transport/lib/transport_web/controllers/resource_controller.ex @@ -6,7 +6,7 @@ defmodule TransportWeb.ResourceController do require Logger import Ecto.Query - import TransportWeb.ResourceView, only: [issue_type: 1, latest_validations_nb_days: 0] + import TransportWeb.ResourceView, only: [latest_validations_nb_days: 0] import TransportWeb.DatasetView, only: [availability_number_days: 0] @enabled_validators MapSet.new([ @@ -146,7 +146,7 @@ defmodule TransportWeb.ResourceController do issue_type = case params["issue_type"] do - nil -> issue_type(issues) + nil -> Transport.Validators.GTFSTransport.issue_type(issues) issue_type -> issue_type end diff --git a/apps/transport/lib/transport_web/controllers/validation_controller.ex b/apps/transport/lib/transport_web/controllers/validation_controller.ex index 633d350962..4d9c14fec6 100644 --- a/apps/transport/lib/transport_web/controllers/validation_controller.ex +++ b/apps/transport/lib/transport_web/controllers/validation_controller.ex @@ -2,7 +2,6 @@ defmodule TransportWeb.ValidationController do use TransportWeb, :controller alias DB.{MultiValidation, Repo} alias Transport.DataVisualization - import TransportWeb.ResourceView, only: [issue_type: 1] import Ecto.Query def validate(%Plug.Conn{} = conn, %{"upload" => %{"url" => url, "type" => "gbfs"} = params}) do @@ -98,31 +97,32 @@ defmodule TransportWeb.ValidationController do unauthorized(conn) %MultiValidation{oban_args: %{"state" => "completed", "type" => "gtfs"}} = validation -> - current_issues = Transport.Validators.GTFSTransport.get_issues(validation.result, params) + validator = Transport.Validators.GTFSTransport + current_issues = validator.get_issues(validation.result, params) issue_type = case params["issue_type"] do - nil -> issue_type(current_issues) + nil -> validator.issue_type(current_issues) issue_type -> issue_type end conn - |> assign(:validation_id, params["id"]) - |> assign(:other_resources, []) - |> assign(:issues, Scrivener.paginate(current_issues, make_pagination_config(params))) - |> assign( - :validation_summary, - Transport.Validators.GTFSTransport.summary(validation.result) - ) - |> assign( - :severities_count, - Transport.Validators.GTFSTransport.count_by_severity(validation.result) - ) + |> assign_base_validation_details(validator, validation, params, current_issues) |> assign(:metadata, validation.metadata.metadata) |> assign(:modes, validation.metadata.modes) |> assign(:data_vis, data_vis(validation, issue_type)) - |> assign(:token, token) - |> render("show.html") + |> render("show_gtfs.html") + + %MultiValidation{oban_args: %{"state" => "completed", "type" => "netex"}} = validation -> + validator = Transport.Validators.NeTEx + current_issues = validator.get_issues(validation.result, params) + + conn + |> assign_base_validation_details(validator, validation, params, current_issues) + |> assign(:metadata, %{}) + |> assign(:modes, []) + |> assign(:data_vis, nil) + |> render("show_netex.html") # Handles waiting for validation to complete, errors and # validation for schemas @@ -130,12 +130,24 @@ defmodule TransportWeb.ValidationController do live_render(conn, TransportWeb.Live.OnDemandValidationLive, session: %{ "validation_id" => params["id"], + "issue_type" => params["issue_type"], "current_url" => validation_path(conn, :show, params["id"], token: token) } ) end end + defp assign_base_validation_details(conn, validator, validation, params, current_issues) do + conn + |> assign(:validator, validator) + |> assign(:validation_id, params["id"]) + |> assign(:other_resources, []) + |> assign(:issues, Scrivener.paginate(current_issues, make_pagination_config(params))) + |> assign(:validation_summary, validator.summary(validation.result)) + |> assign(:severities_count, validator.count_by_severity(validation.result)) + |> assign(:token, params["token"]) + end + defp data_vis(%MultiValidation{} = validation, issue_type) do data_vis = validation.data_vis[issue_type] has_features = DataVisualization.has_features(data_vis["geojson"]) @@ -150,7 +162,7 @@ defmodule TransportWeb.ValidationController do defp filepath(type) do cond do type == "tableschema" -> Ecto.UUID.generate() <> ".csv" - type in ["jsonschema", "gtfs"] -> Ecto.UUID.generate() + type in ["jsonschema", "gtfs", "netex"] -> Ecto.UUID.generate() end end @@ -215,6 +227,7 @@ defmodule TransportWeb.ValidationController do args = case type do "gtfs" -> %{"type" => "gtfs"} + "netex" -> %{"type" => "netex"} schema_name -> %{"schema_name" => schema_name, "type" => schema_type(schema_name)} end diff --git a/apps/transport/lib/transport_web/live/on_demand_validation_live.ex b/apps/transport/lib/transport_web/live/on_demand_validation_live.ex index 9b1f2b70c2..9cae1b91b3 100644 --- a/apps/transport/lib/transport_web/live/on_demand_validation_live.ex +++ b/apps/transport/lib/transport_web/live/on_demand_validation_live.ex @@ -35,7 +35,7 @@ defmodule TransportWeb.Live.OnDemandValidationLive do schedule_next_update_data() end - if gtfs_validation_completed?(socket) do + if gtfs_or_netex_validation_completed?(socket) do redirect(socket, to: socket_value(socket, :current_url)) else socket @@ -57,10 +57,10 @@ defmodule TransportWeb.Live.OnDemandValidationLive do end end - defp gtfs_validation_completed?(socket) do + defp gtfs_or_netex_validation_completed?(socket) do case socket_value(socket, :validation) do %DB.MultiValidation{oban_args: oban_args} -> - oban_args["type"] == "gtfs" and oban_args["state"] == "completed" + oban_args["type"] in ["gtfs", "netex"] and oban_args["state"] == "completed" _ -> false diff --git a/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex b/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex new file mode 100644 index 0000000000..b7e2178f5c --- /dev/null +++ b/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex @@ -0,0 +1,23 @@ + + + + + + + + <%= for issue <- @issues do %> + + + + + + <% end %> +
<%= dgettext("validations-explanations", "Message") %><%= dgettext("validations-explanations", "Location") %><%= dgettext("validations-explanations", "Debug") %>
<%= issue["message"] %> + <%= if is_nil(issue["resource"]) or is_nil(issue["resource"]["filename"]) or is_nil(issue["resource"]["line"]) do %> + <%= dgettext("validations-explanations", "Unknown location") %> + <% else %> + <%= issue["resource"]["filename"] %>:<%= issue["resource"]["line"] %> + <% end %> + + <%= to_string(Jason.encode!(issue, pretty: true)) %> +
diff --git a/apps/transport/lib/transport_web/templates/resource/_resources_details.html.heex b/apps/transport/lib/transport_web/templates/resource/_resources_details.html.heex index e09fbfe35d..28ee6f4774 100644 --- a/apps/transport/lib/transport_web/templates/resource/_resources_details.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/_resources_details.html.heex @@ -30,8 +30,8 @@ stats = @metadata["stats"] %>
  • - <%= dngettext("validations", "network", "networks", length(@metadata["networks"])) %> : - <%= Enum.join(@metadata["networks"], ", ") %> + <%= dngettext("validations", "network", "networks", length(networks)) %> : + <%= Enum.join(networks, ", ") %>
  • diff --git a/apps/transport/lib/transport_web/templates/resource/_validation_summary.html.heex b/apps/transport/lib/transport_web/templates/resource/_validation_summary.html.heex index b46707a082..cea0917ff0 100644 --- a/apps/transport/lib/transport_web/templates/resource/_validation_summary.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/_validation_summary.html.heex @@ -3,7 +3,7 @@ <%= for {severity, issues} <- @validation_summary do %> <%= if Map.get(@severities_count, severity, 0) > 0 do %>
    -

    <%= @severities_count[severity] %> <%= severity(severity).text %>

    +

    <%= @severities_count[severity] %> <%= @validator.severity(severity).text %>

      <%= for {key, issue} <- issues do %>
    • @@ -12,7 +12,7 @@ "#{issue.title} (#{issue.count})", to: "#{current_url(@conn, %{"issue_type" => key, "token" => @token} |> Map.reject(fn {_, v} -> is_nil(v) end))}#issues", - class: if(key == issue_type(@issues.entries), do: "active") + class: if(key == @validator.issue_type(@issues.entries), do: "active") ) %> <% end %>
    • diff --git a/apps/transport/lib/transport_web/templates/resource/gtfs_details.html.heex b/apps/transport/lib/transport_web/templates/resource/gtfs_details.html.heex index b7099eaf3a..c49e46183f 100644 --- a/apps/transport/lib/transport_web/templates/resource/gtfs_details.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/gtfs_details.html.heex @@ -108,7 +108,7 @@ associated_netex = get_associated_netex(@related_files) %>
      <%= pagination_links(@conn, @issues, [@resource.id], - issue_type: issue_type(@issues.entries), + issue_type: Transport.Validators.GTFSTransport.issue_type(@issues.entries), path: &resource_path/4, action: :details ) %> diff --git a/apps/transport/lib/transport_web/templates/validation/show.html.heex b/apps/transport/lib/transport_web/templates/validation/show_gtfs.html.heex similarity index 89% rename from apps/transport/lib/transport_web/templates/validation/show.html.heex rename to apps/transport/lib/transport_web/templates/validation/show_gtfs.html.heex index d3ad86ac72..a3b765be56 100644 --- a/apps/transport/lib/transport_web/templates/validation/show.html.heex +++ b/apps/transport/lib/transport_web/templates/validation/show_gtfs.html.heex @@ -3,7 +3,7 @@

      <%= dgettext("validations", "GTFS review report") %>

      - <%= dgettext("validations", "explanations") %> + <%= dgettext("validations", "explanations", format: "GTFS") %>

      <%= dgettext("validations", "This report can be shared with") %> @@ -27,7 +27,8 @@ conn: @conn, issues: @issues, data_vis: @data_vis, - token: @token + token: @token, + validator: @validator ) %> <% end %> @@ -35,7 +36,7 @@

      <%= if has_errors?(@validation_summary) do %> <%= pagination_links(@conn, @issues, [@validation_id], - issue_type: issue_type(@issues.entries), + issue_type: @validator.issue_type(@issues.entries), token: @token, path: &validation_path/4, action: :show @@ -43,7 +44,7 @@ <%= render(gtfs_template(@issues), issues: @issues || [], conn: @conn) %>
      <%= pagination_links(@conn, @issues, [@validation_id], - issue_type: issue_type(@issues.entries), + issue_type: @validator.issue_type(@issues.entries), token: @token, path: &validation_path/4, action: :show diff --git a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex new file mode 100644 index 0000000000..41632fd2f9 --- /dev/null +++ b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex @@ -0,0 +1,61 @@ +
      +
      +
      +

      <%= dgettext("validations", "NeTEx review report") %>

      +

      + <%= dgettext("validations", "explanations", format: "NeTEx") %> +

      +

      + <%= dgettext("validations", "This report can be shared with") %> + <%= link(dgettext("validations", "this permanent link"), to: current_url(@conn)) %>. +

      +
      +
      + +
      +
      + <%= if has_errors?(@validation_summary) do %> + <%= render("_validation_summary.html", + validation_summary: @validation_summary, + severities_count: @severities_count, + conn: @conn, + issues: @issues, + data_vis: @data_vis, + token: @token, + validator: @validator + ) %> + <% end %> + +
      +
      + <%= if has_errors?(@validation_summary) do %> + <%= pagination_links(@conn, @issues, [@validation_id], + issue_type: @validator.issue_type(@issues.entries), + token: @token, + path: &validation_path/4, + action: :show + ) %> + <%= render(netex_template(@issues), issues: @issues || [], conn: @conn) %> +
      + <%= pagination_links(@conn, @issues, [@validation_id], + issue_type: @validator.issue_type(@issues.entries), + token: @token, + path: &validation_path/4, + action: :show + ) %> +
      + <% else %> +

      <%= dgettext("validations", "Nice work, there are no issues!") %>

      + <% end %> +
      +
      +
      +
      +
      + +
      + <%= live_render(@conn, TransportWeb.Live.FeedbackLive, session: %{"feature" => "on_demand_validation"}) %> +
      + + diff --git a/apps/transport/lib/transport_web/views/resource_view.ex b/apps/transport/lib/transport_web/views/resource_view.ex index 8326046b20..a30bf8ee4f 100644 --- a/apps/transport/lib/transport_web/views/resource_view.ex +++ b/apps/transport/lib/transport_web/views/resource_view.ex @@ -2,7 +2,6 @@ defmodule TransportWeb.ResourceView do use TransportWeb, :view use Phoenix.Component import TransportWeb.PaginationHelpers - import Transport.Validators.GTFSTransport import Phoenix.Controller, only: [current_url: 2] import TransportWeb.BreadCrumbs, only: [breadcrumbs: 1] @@ -21,9 +20,6 @@ defmodule TransportWeb.ResourceView do for %{"id" => id, "name" => name} <- related_objects, do: content_tag(:li, "#{name} (#{id})") end - def issue_type([]), do: nil - def issue_type([h | _]), do: h["issue_type"] - def gtfs_template(issues) do template = Map.get( @@ -47,13 +43,24 @@ defmodule TransportWeb.ResourceView do "SubFolder" => "_subfolder_issue.html", "NegativeStopDuration" => "_negative_stop_duration_issue.html" }, - issue_type(issues.entries), + Transport.Validators.GTFSTransport.issue_type(issues.entries), "_generic_issue.html" ) "_gtfs#{template}" end + def netex_template(issues) do + template = + Map.get( + %{}, + Transport.Validators.NeTEx.issue_type(issues.entries), + "_generic_issue.html" + ) + + "_netex#{template}" + end + @spec action_path(Plug.Conn.t()) :: any def action_path(%Plug.Conn{params: %{"resource_id" => r_id} = params} = conn), do: resource_path(conn, :post_file, params["dataset_id"], r_id) diff --git a/apps/transport/lib/transport_web/views/validation_view.ex b/apps/transport/lib/transport_web/views/validation_view.ex index 1ac865d3f3..4bf7958bd2 100644 --- a/apps/transport/lib/transport_web/views/validation_view.ex +++ b/apps/transport/lib/transport_web/views/validation_view.ex @@ -1,7 +1,7 @@ defmodule TransportWeb.ValidationView do use TransportWeb, :view import Phoenix.Controller, only: [current_url: 1] - import TransportWeb.ResourceView, only: [issue_type: 1, gtfs_template: 1] + import TransportWeb.ResourceView, only: [gtfs_template: 1, netex_template: 1] import TransportWeb.PaginationHelpers def render("_" <> _ = partial, assigns) do diff --git a/apps/transport/lib/validators/gtfs_transport_validator.ex b/apps/transport/lib/validators/gtfs_transport_validator.ex index 421d6e4914..66f37f7933 100644 --- a/apps/transport/lib/validators/gtfs_transport_validator.ex +++ b/apps/transport/lib/validators/gtfs_transport_validator.ex @@ -77,6 +77,10 @@ defmodule Transport.Validators.GTFSTransport do @spec severity(binary()) :: %{level: integer(), text: binary()} def severity(key), do: severities_map()[key] + @spec issue_type(list()) :: nil | binary() + def issue_type([]), do: nil + def issue_type([h | _]), do: h["issue_type"] + @doc """ Get issues from validation results. For a specific issue type if specified, or the most severe. diff --git a/apps/transport/lib/validators/netex_validator.ex b/apps/transport/lib/validators/netex_validator.ex index 9e9d05daf1..71aec2282e 100644 --- a/apps/transport/lib/validators/netex_validator.ex +++ b/apps/transport/lib/validators/netex_validator.ex @@ -11,6 +11,8 @@ defmodule Transport.Validators.NeTEx do @max_retries 100 + @unknown_code "unknown-code" + @behaviour Transport.Validators.Validator @impl Transport.Validators.Validator @@ -257,7 +259,7 @@ defmodule Transport.Validators.NeTEx do def index_messages(messages), do: Enum.group_by(messages, &get_code/1) defp get_code(%{"code" => code}), do: code - defp get_code(%{}), do: "unknown-code" + defp get_code(%{}), do: @unknown_code # This will change with an actual versioning of the validator def validator_version, do: "saas-production" @@ -304,9 +306,13 @@ defmodule Transport.Validators.NeTEx do "uic-operating-period" => dgettext("netex-validator", "UIC operating period"), "valid-day-bits" => dgettext("netex-validator", "Valid day bits"), "version-any" => dgettext("netex-validator", "Version any"), - "unknown-code" => dgettext("netex-validator", "Unspecified error") + @unknown_code => dgettext("netex-validator", "Unspecified error") } + @spec issue_type(list()) :: nil | binary() + def issue_type([]), do: nil + def issue_type([h | _]), do: h["code"] || @unknown_code + @doc """ Get issues from validation results. For a specific issue type if specified, or the most severe. diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/netex-validator.po b/apps/transport/priv/gettext/en/LC_MESSAGES/netex-validator.po index 9d2dc078e6..e63b2e1656 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/netex-validator.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/netex-validator.po @@ -55,6 +55,10 @@ msgstr "" msgid "Version any" msgstr "" +#, elixir-autogen, elixir-format +msgid "Unspecified error" +msgstr "" + #, elixir-autogen, elixir-format msgid "errors" msgstr "" diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/validations-explanations.po b/apps/transport/priv/gettext/en/LC_MESSAGES/validations-explanations.po index f2a23dd45a..08f113b6c8 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/validations-explanations.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/validations-explanations.po @@ -130,3 +130,19 @@ msgstr ".txt files are in subfolder (%{folder}). Files must reside at the root l #, elixir-autogen, elixir-format msgid "NegativeStopDuration" msgstr "The departure time at a stop is earlier than its arrival time." + +#, elixir-autogen, elixir-format +msgid "Location" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Message" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Unknown location" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Debug" +msgstr "" diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po index 15bc028447..74076e7a01 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po @@ -76,7 +76,7 @@ msgstr "" #, elixir-autogen, elixir-format msgid "explanations" -msgstr "This is the automated evalation of the GTFS datafile. " +msgstr "This is the automated evaluation of the %{format} datafile. " "This validation only considers the datastructure and does not give any information about completeness nor exactitude of the timetables. " #, elixir-autogen, elixir-format @@ -420,3 +420,7 @@ msgstr "" #, elixir-autogen, elixir-format msgid "The GTFS file %{gtfs_original_file_name_2} has differences with the GTFS file %{gtfs_original_file_name_1}, as summarized below:" msgstr "" + +#, elixir-autogen, elixir-format, fuzzy +msgid "NeTEx review report" +msgstr "" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/netex-validator.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/netex-validator.po index 7b30b0cebd..3739764876 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/netex-validator.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/netex-validator.po @@ -55,6 +55,10 @@ msgstr "" msgid "Version any" msgstr "" +#, elixir-autogen, elixir-format +msgid "Unspecified error" +msgstr "Erreur inconnue" + #, elixir-autogen, elixir-format msgid "errors" msgstr "erreurs" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po index cc18b6db11..4a4429105b 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po @@ -130,3 +130,19 @@ msgstr "Les fichiers .txt sont dans un sous-dossier (%{folder}). Les fichiers do #, elixir-autogen, elixir-format msgid "NegativeStopDuration" msgstr "L'heure de départ d'un arrêt (departure_time) est antérieure à son heure d'arrivée (arrival_time)." + +#, elixir-autogen, elixir-format +msgid "Location" +msgstr "Emplacement" + +#, elixir-autogen, elixir-format +msgid "Message" +msgstr "Message" + +#, elixir-autogen, elixir-format +msgid "Unknown location" +msgstr "Emplacement inconnu" + +#, elixir-autogen, elixir-format +msgid "Debug" +msgstr "" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po index 09ccb087b0..281a5dbd19 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po @@ -76,7 +76,7 @@ msgstr "au" #, elixir-autogen, elixir-format msgid "explanations" -msgstr "Voici le bilan automatisé sur la qualité du fichier GTFS. " +msgstr "Voici le bilan automatisé sur la qualité du fichier %{format}. " "Cette validation ne concerne que la structure des données et pas la complétude ni l’exactitude des horaires. " #, elixir-autogen, elixir-format @@ -420,3 +420,7 @@ msgstr "nombre d'arrêts :" #, elixir-autogen, elixir-format msgid "The GTFS file %{gtfs_original_file_name_2} has differences with the GTFS file %{gtfs_original_file_name_1}, as summarized below:" msgstr "Le fichier GTFS %{gtfs_original_file_name_2} comporte les différences ci-dessous par rapport au fichier GTFS %{gtfs_original_file_name_1} :" + +#, elixir-autogen, elixir-format, fuzzy +msgid "NeTEx review report" +msgstr "Rapport de l’analyse de fichier NeTEx" diff --git a/apps/transport/priv/gettext/netex-validator.pot b/apps/transport/priv/gettext/netex-validator.pot index 82d778082e..b9bf5eb447 100644 --- a/apps/transport/priv/gettext/netex-validator.pot +++ b/apps/transport/priv/gettext/netex-validator.pot @@ -55,6 +55,10 @@ msgstr "" msgid "Version any" msgstr "" +#, elixir-autogen, elixir-format +msgid "Unspecified error" +msgstr "" + #, elixir-autogen, elixir-format msgid "errors" msgstr "" diff --git a/apps/transport/priv/gettext/validations-explanations.pot b/apps/transport/priv/gettext/validations-explanations.pot index 0a91a13aa9..7828983911 100644 --- a/apps/transport/priv/gettext/validations-explanations.pot +++ b/apps/transport/priv/gettext/validations-explanations.pot @@ -129,3 +129,19 @@ msgstr "" #, elixir-autogen, elixir-format msgid "NegativeStopDuration" msgstr "" + +#, elixir-autogen, elixir-format +msgid "Location" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Message" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Unknown location" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Debug" +msgstr "" diff --git a/apps/transport/priv/gettext/validations.pot b/apps/transport/priv/gettext/validations.pot index eb93d61ee4..578962239a 100644 --- a/apps/transport/priv/gettext/validations.pot +++ b/apps/transport/priv/gettext/validations.pot @@ -419,3 +419,7 @@ msgstr "" #, elixir-autogen, elixir-format msgid "The GTFS file %{gtfs_original_file_name_2} has differences with the GTFS file %{gtfs_original_file_name_1}, as summarized below:" msgstr "" + +#, elixir-autogen, elixir-format +msgid "NeTEx review report" +msgstr "" diff --git a/apps/transport/test/transport/jobs/on_demand_validation_job_test.exs b/apps/transport/test/transport/jobs/on_demand_validation_job_test.exs index 7cfd976fe0..2ed35b6add 100644 --- a/apps/transport/test/transport/jobs/on_demand_validation_job_test.exs +++ b/apps/transport/test/transport/jobs/on_demand_validation_job_test.exs @@ -3,6 +3,7 @@ defmodule Transport.Test.Transport.Jobs.OnDemandValidationJobTest do use Oban.Testing, repo: DB.Repo import DB.Factory import Mox + import Transport.Test.EnRouteChouetteValidClientHelpers import Transport.Test.S3TestUtils alias Transport.Jobs.OnDemandValidationJob alias Transport.Validators.GTFSRT @@ -389,14 +390,68 @@ defmodule Transport.Test.Transport.Jobs.OnDemandValidationJobTest do refute File.exists?(gtfs_rt_path) refute File.exists?(OnDemandValidationJob.gtfs_rt_result_path(gtfs_rt_path)) end + + test "with a NeTEx" do + url = mk_raw_netex_resource() + validation = create_validation(%{"type" => "netex"}, url) + + errors = [ + %{ + "code" => "xsd-1871", + "criticity" => "error", + "message" => + "Element '{http://www.netex.org.uk/netex}OppositeDIrectionRef': This element is not expected. Expected is ( {http://www.netex.org.uk/netex}OppositeDirectionRef )." + }, + %{ + "code" => "uic-operating-period", + "message" => "Resource 23504000009 hasn't expected class but Netex::OperatingPeriod", + "criticity" => "error" + }, + %{ + "code" => "valid-day-bits", + "message" => "Mandatory attribute valid_day_bits not found", + "criticity" => "error" + }, + %{ + "code" => "frame-arret-resources", + "message" => "Tag frame_id doesn't match ''", + "criticity" => "warning" + } + ] + + expect_netex_with_errors(errors) + + s3_mocks_delete_object(Transport.S3.bucket_name(:on_demand_validation), @filename) + + assert :ok == run_job(validation) + + assert %{ + validation_timestamp: date, + result: result, + max_error: "error", + oban_args: %{"state" => "completed", "type" => "netex"}, + metadata: %{}, + data_vis: nil + } = validation |> DB.Repo.reload() |> DB.Repo.preload(:metadata) + + assert %{"xsd-1871" => a1, "uic-operating-period" => a2, "valid-day-bits" => a3, "frame-arret-resources" => a4} = + result + + assert length(a1) == 1 + assert length(a2) == 1 + assert length(a3) == 1 + assert length(a4) == 1 + + assert DateTime.diff(date, DateTime.utc_now()) <= 1 + end end - defp create_validation(details) do + defp create_validation(details, url \\ @url) do details = if details["type"] == "gtfs-rt" do details else - Map.merge(details, %{"filename" => @filename, "permanent_url" => @url}) + Map.merge(details, %{"filename" => @filename, "permanent_url" => url}) end oban_args = Map.merge(%{"state" => "waiting"}, details) @@ -404,10 +459,27 @@ defmodule Transport.Test.Transport.Jobs.OnDemandValidationJobTest do insert(:multi_validation, oban_args: oban_args) end + def expect_netex_with_errors(messages) do + validation_id = expect_create_validation() + expect_failed_validation(validation_id, 10) + + expect_get_messages(validation_id, messages) + end + defp run_job(%DB.MultiValidation{} = validation) do payload = Map.merge(%{"id" => validation.id}, validation.oban_args) perform_job(OnDemandValidationJob, payload) end defp validator_path, do: Path.join(Application.fetch_env!(:transport, :transport_tools_folder), @validator_filename) + + defp mk_raw_netex_resource do + resource_url = "http://localhost:9999/netex-#{Ecto.UUID.generate()}.zip" + + expect(Transport.Req.Mock, :get!, 1, fn ^resource_url, [{:compressed, false}, {:into, _}] -> + {:ok, %Req.Response{status: 200, body: %{"data" => "some_zip_file"}}} + end) + + resource_url + end end From 19801985646c2e9c6ab2ec5e2bcec24950ef67a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Wed, 4 Sep 2024 13:56:57 +0200 Subject: [PATCH 03/23] Validation NeTEx : meilleur affichage des erreurs --- .../resource/_netex_generic_issue.html.heex | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex b/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex index b7e2178f5c..5e59b6a5e9 100644 --- a/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex @@ -1,12 +1,42 @@ - + + +
      - <%= for issue <- @issues do %> - + - + + <% end %> From 8b53c2f514dc30a6c4a16f2fb54eede0ade92326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Wed, 4 Sep 2024 18:44:43 +0200 Subject: [PATCH 04/23] Affichage des metadata de la validation NeTEx --- .../lib/transport_web/controllers/validation_controller.ex | 2 +- .../templates/resource/_resources_details_netex.html.heex | 5 +++++ .../transport_web/templates/validation/show_netex.html.heex | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex diff --git a/apps/transport/lib/transport_web/controllers/validation_controller.ex b/apps/transport/lib/transport_web/controllers/validation_controller.ex index 4d9c14fec6..7cdb472f26 100644 --- a/apps/transport/lib/transport_web/controllers/validation_controller.ex +++ b/apps/transport/lib/transport_web/controllers/validation_controller.ex @@ -119,7 +119,7 @@ defmodule TransportWeb.ValidationController do conn |> assign_base_validation_details(validator, validation, params, current_issues) - |> assign(:metadata, %{}) + |> assign(:metadata, validation.metadata.metadata) |> assign(:modes, []) |> assign(:data_vis, nil) |> render("show_netex.html") diff --git a/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex b/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex new file mode 100644 index 0000000000..b636955d82 --- /dev/null +++ b/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex @@ -0,0 +1,5 @@ +
      +
        +
      • Elapsed time : <%= @metadata["elapsed_seconds"] %>s
      • +
      +
      diff --git a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex index 41632fd2f9..a1c1e8441c 100644 --- a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex +++ b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex @@ -14,6 +14,12 @@
      + <%= unless is_nil(@metadata) or @metadata == %{} do %> + + <% end %> + <%= if has_errors?(@validation_summary) do %> <%= render("_validation_summary.html", validation_summary: @validation_summary, From 0d8e3314233dbb92741d41782e8a05f5366f173b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Thu, 5 Sep 2024 18:52:29 +0200 Subject: [PATCH 05/23] =?UTF-8?q?Validateur=20NeTEx=20:=20meilleur=20affic?= =?UTF-8?q?hage=20de=20la=20dur=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/shared/lib/date_time_display.ex | 65 +++++++++++++++++++ .../_resources_details_netex.html.heex | 7 +- .../lib/transport_web/views/resource_view.ex | 2 +- .../gettext/en/LC_MESSAGES/validations.po | 4 ++ .../gettext/fr/LC_MESSAGES/validations.po | 4 ++ apps/transport/priv/gettext/validations.pot | 4 ++ 6 files changed, 82 insertions(+), 4 deletions(-) diff --git a/apps/shared/lib/date_time_display.ex b/apps/shared/lib/date_time_display.ex index 88d5dcedc6..f61d20527f 100644 --- a/apps/shared/lib/date_time_display.ex +++ b/apps/shared/lib/date_time_display.ex @@ -104,6 +104,71 @@ defmodule Shared.DateTimeDisplay do def format_datetime_to_paris(nil, _, _), do: "" + @doc """ + Formats a duration in seconds to display, according to a locale. + + Supported locales: "fr" and "en". + + iex> format_duration(0, "en") + "0 second" + iex> format_duration(1, "en") + "1 second" + iex> format_duration(3, "en") + "3 seconds" + iex> format_duration(60, "en") + "1 minute" + iex> format_duration(61, "en") + "1 minute 1 second" + iex> format_duration(65, "en") + "1 minute 5 seconds" + iex> format_duration(120, "en") + "2 minutes" + iex> format_duration(125, "en") + "2 minutes 5 seconds" + + iex> format_duration(0, "fr") + "0 seconde" + iex> format_duration(1, "fr") + "1 seconde" + iex> format_duration(3, "fr") + "3 secondes" + iex> format_duration(60, "fr") + "1 minute" + iex> format_duration(61, "fr") + "1 minute 1 seconde" + iex> format_duration(65, "fr") + "1 minute 5 secondes" + iex> format_duration(120, "fr") + "2 minutes" + iex> format_duration(125, "fr") + "2 minutes 5 secondes" + """ + @spec format_duration(non_neg_integer(), binary()) :: binary() + def format_duration(duration_in_seconds, locale) do + minutes = div(duration_in_seconds, 60) + seconds = rem(duration_in_seconds, 60) + + cond do + minutes > 0 and seconds > 0 -> "#{format_minutes(minutes, locale)} #{format_seconds(seconds, locale)}" + minutes > 0 -> format_minutes(minutes, locale) + true -> format_seconds(seconds, locale) + end + end + + defp format_seconds(seconds, "en"), do: format_duration_unit(seconds, "second") + defp format_seconds(seconds, _locale), do: format_duration_unit(seconds, "seconde") + + defp format_minutes(seconds, "en"), do: format_duration_unit(seconds, "minute") + defp format_minutes(seconds, _locale), do: format_duration_unit(seconds, "minute") + + defp format_duration_unit(duration, unit) do + if duration > 1 do + "#{duration} #{unit}s" + else + "#{duration} #{unit}" + end + end + @spec convert_to_paris_time(DateTime.t() | NaiveDateTime.t()) :: DateTime.t() defp convert_to_paris_time(%DateTime{} = dt) do case Timex.Timezone.convert(dt, "Europe/Paris") do diff --git a/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex b/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex index b636955d82..a235e99002 100644 --- a/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex @@ -1,5 +1,6 @@ +<% locale = get_session(@conn, :locale) %>
      -
        -
      • Elapsed time : <%= @metadata["elapsed_seconds"] %>s
      • -
      + <%= dgettext("validations", "Elapsed time: %{duration}.", + duration: format_duration(@metadata["elapsed_seconds"], locale) + ) %>
      diff --git a/apps/transport/lib/transport_web/views/resource_view.ex b/apps/transport/lib/transport_web/views/resource_view.ex index a30bf8ee4f..b72d899519 100644 --- a/apps/transport/lib/transport_web/views/resource_view.ex +++ b/apps/transport/lib/transport_web/views/resource_view.ex @@ -9,7 +9,7 @@ defmodule TransportWeb.ResourceView do only: [documentation_url: 1, errors_count: 1, warnings_count: 1, multi_validation_performed?: 1, description: 1] import DB.ResourceUnavailability, only: [floor_float: 2] - import Shared.DateTimeDisplay, only: [format_datetime_to_paris: 2] + import Shared.DateTimeDisplay, only: [format_datetime_to_paris: 2, format_duration: 2] import Shared.Validation.TableSchemaValidator, only: [validata_web_url: 1] import Transport.GBFSUtils, only: [gbfs_validation_link: 1] import Transport.Shared.Schemas.Wrapper, only: [schema_type: 1] diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po index 74076e7a01..e11b9f6542 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po @@ -424,3 +424,7 @@ msgstr "" #, elixir-autogen, elixir-format, fuzzy msgid "NeTEx review report" msgstr "" + +#, elixir-autogen, elixir-format +msgid "Elapsed time: %{duration}." +msgstr "" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po index 281a5dbd19..066c6b36cf 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po @@ -424,3 +424,7 @@ msgstr "Le fichier GTFS %{gtfs_original_file_name_2} comporte les différences c #, elixir-autogen, elixir-format, fuzzy msgid "NeTEx review report" msgstr "Rapport de l’analyse de fichier NeTEx" + +#, elixir-autogen, elixir-format +msgid "Elapsed time: %{duration}." +msgstr "Temps passé : %{duration}." diff --git a/apps/transport/priv/gettext/validations.pot b/apps/transport/priv/gettext/validations.pot index 578962239a..58c29d72d5 100644 --- a/apps/transport/priv/gettext/validations.pot +++ b/apps/transport/priv/gettext/validations.pot @@ -423,3 +423,7 @@ msgstr "" #, elixir-autogen, elixir-format msgid "NeTEx review report" msgstr "" + +#, elixir-autogen, elixir-format +msgid "Elapsed time: %{duration}." +msgstr "" From ffd4b22ff73bab8986df75cfbd32b27040449eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Mon, 9 Sep 2024 11:53:57 +0200 Subject: [PATCH 06/23] NeTEx errors grouped by nature --- apps/transport/lib/validators/netex_validator.ex | 13 +++++++++++-- .../priv/gettext/en/LC_MESSAGES/netex-validator.po | 2 +- .../priv/gettext/fr/LC_MESSAGES/netex-validator.po | 4 ++-- apps/transport/priv/gettext/netex-validator.pot | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/transport/lib/validators/netex_validator.ex b/apps/transport/lib/validators/netex_validator.ex index 71aec2282e..cc7bb0fa9d 100644 --- a/apps/transport/lib/validators/netex_validator.ex +++ b/apps/transport/lib/validators/netex_validator.ex @@ -284,14 +284,23 @@ defmodule Transport.Validators.NeTEx do {code, %{ count: length(errors), - criticity: Map.get(hd(errors), "criticity"), - title: Map.get(issues_short_translation(), code, code) + criticity: errors |> hd() |> Map.get("criticity"), + title: issues_short_translation_per_code(code) }} end) |> Enum.group_by(fn {_, details} -> details.criticity end) |> Enum.sort_by(fn {criticity, _} -> severity(criticity).level end) end + @spec issues_short_translation_per_code(binary()) :: binary() + def issues_short_translation_per_code(code) do + if String.starts_with?(code, "xsd-") do + dgettext("netex-validator", "XSD validation") + else + Map.get(issues_short_translation(), code, code) + end + end + @spec issues_short_translation() :: %{binary() => binary()} def issues_short_translation, do: %{ diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/netex-validator.po b/apps/transport/priv/gettext/en/LC_MESSAGES/netex-validator.po index e63b2e1656..a6e706cf3b 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/netex-validator.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/netex-validator.po @@ -72,5 +72,5 @@ msgid "warnings" msgstr "" #, elixir-autogen, elixir-format -msgid "Unspecified error" +msgid "XSD validation" msgstr "" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/netex-validator.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/netex-validator.po index 3739764876..abcf16b526 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/netex-validator.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/netex-validator.po @@ -72,5 +72,5 @@ msgid "warnings" msgstr "avertissements" #, elixir-autogen, elixir-format -msgid "Unspecified error" -msgstr "" +msgid "XSD validation" +msgstr "Validation XSD" diff --git a/apps/transport/priv/gettext/netex-validator.pot b/apps/transport/priv/gettext/netex-validator.pot index b9bf5eb447..669ae75503 100644 --- a/apps/transport/priv/gettext/netex-validator.pot +++ b/apps/transport/priv/gettext/netex-validator.pot @@ -72,5 +72,5 @@ msgid "warnings" msgstr "" #, elixir-autogen, elixir-format -msgid "Unspecified error" +msgid "XSD validation" msgstr "" From f81f14645f03d75ce37edcf773528b51fab23d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Tue, 3 Sep 2024 11:10:14 +0200 Subject: [PATCH 07/23] =?UTF-8?q?OnDemand:=20validateur=20NeTEx=20d=C3=A9s?= =?UTF-8?q?ormais=20disponible?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../live/on_demand_validation_select_live.ex | 1 - .../on_demand_validation_select_live.html.heex | 17 +---------------- .../priv/gettext/en/LC_MESSAGES/validations.po | 8 -------- .../priv/gettext/fr/LC_MESSAGES/validations.po | 8 -------- apps/transport/priv/gettext/validations.pot | 8 -------- .../controllers/validation_controller_test.exs | 17 +++++------------ 6 files changed, 6 insertions(+), 53 deletions(-) diff --git a/apps/transport/lib/transport_web/live/on_demand_validation_select_live.ex b/apps/transport/lib/transport_web/live/on_demand_validation_select_live.ex index 09ced2116b..e594e46bc4 100644 --- a/apps/transport/lib/transport_web/live/on_demand_validation_select_live.ex +++ b/apps/transport/lib/transport_web/live/on_demand_validation_select_live.ex @@ -53,7 +53,6 @@ defmodule TransportWeb.Live.OnDemandValidationSelectLive do def determine_input_type(type) when type in ["gbfs"], do: "link" def determine_input_type(type) when type in ["gtfs-rt"], do: "gtfs-rt" - def determine_input_type(type) when type in ["netex"], do: nil def determine_input_type(_), do: "file" def handle_event("form_changed", %{"upload" => params, "_target" => target}, socket) do diff --git a/apps/transport/lib/transport_web/live/on_demand_validation_select_live.html.heex b/apps/transport/lib/transport_web/live/on_demand_validation_select_live.html.heex index 6655eeda03..9cff00c6bb 100644 --- a/apps/transport/lib/transport_web/live/on_demand_validation_select_live.html.heex +++ b/apps/transport/lib/transport_web/live/on_demand_validation_select_live.html.heex @@ -38,28 +38,13 @@ type: "url" ) %> <% end %> - <%= unless @input_type == "file" or @type == "netex" do %> + <%= unless @input_type == "file" do %> <%= submit(dgettext("validations", "Validate"), nodiv: true) %> <% end %>

      <%= TransportWeb.Gettext.dgettext("validations", "Upload in progress") %>

      -
      -

      - <%= raw( - TransportWeb.Gettext.dgettext("validations", "netex-siri-validator", link: "https://greenlight.itxpt.eu") - ) %> -

      - -

      - <%= raw( - TransportWeb.Gettext.dgettext("validations", "doc-eu-formats", - link: "https://doc.transport.data.gouv.fr/documentation/normes-europeennes" - ) - ) %> -

      -
      diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po index e11b9f6542..ba6b95a32e 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po @@ -285,14 +285,6 @@ msgstr "" msgid "from" msgstr "" -#, elixir-autogen, elixir-format -msgid "doc-eu-formats" -msgstr "To access information related to European standards, you can browse our documentation." - -#, elixir-autogen, elixir-format -msgid "netex-siri-validator" -msgstr "The European program DATA4PT is in charge of deploying the NeTEx and SIRI standards. They publish a NeTEx validator available online." - #, elixir-autogen, elixir-format msgid "%{count} times (%{percentage} % of validations)" msgstr "" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po index 066c6b36cf..5289715c0a 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po @@ -285,14 +285,6 @@ msgstr "Validation effectuée en utilisant le fichier G msgid "from" msgstr "du" -#, elixir-autogen, elixir-format -msgid "doc-eu-formats" -msgstr "Pour accéder aux ressources autour des normes européennes, vous pouvez consulter notre documentation." - -#, elixir-autogen, elixir-format -msgid "netex-siri-validator" -msgstr "Le projet européen DATA4PT assure aujourd'hui l'accompagnement au déploiement des normes européennes NeTEx et SIRI. Dans ce cadre, il est mis à disposition un outil de validation NeTEx accessible en ligne." - #, elixir-autogen, elixir-format msgid "%{count} times (%{percentage} % of validations)" msgstr "%{count} fois (%{percentage} % des validations)" diff --git a/apps/transport/priv/gettext/validations.pot b/apps/transport/priv/gettext/validations.pot index 58c29d72d5..5bbe429d08 100644 --- a/apps/transport/priv/gettext/validations.pot +++ b/apps/transport/priv/gettext/validations.pot @@ -284,14 +284,6 @@ msgstr "" msgid "from" msgstr "" -#, elixir-autogen, elixir-format -msgid "doc-eu-formats" -msgstr "" - -#, elixir-autogen, elixir-format -msgid "netex-siri-validator" -msgstr "" - #, elixir-autogen, elixir-format msgid "%{count} times (%{percentage} % of validations)" msgstr "" diff --git a/apps/transport/test/transport_web/controllers/validation_controller_test.exs b/apps/transport/test/transport_web/controllers/validation_controller_test.exs index 7f699cfb06..7d5a6df586 100644 --- a/apps/transport/test/transport_web/controllers/validation_controller_test.exs +++ b/apps/transport/test/transport_web/controllers/validation_controller_test.exs @@ -39,21 +39,14 @@ defmodule TransportWeb.ValidationControllerTest do refute view |> has_element?("input[name='upload[url]']") assert view |> has_element?("input[name='upload[file]']") - render_change(view, "form_changed", %{"upload" => %{"type" => "gtfs-rt"}, "_target" => ["upload", "type"]}) - assert view |> has_element?("input[name='upload[url]']") - assert view |> has_element?("input[name='upload[feed_url]']") - end - - test "no inputs but explanations when selecting NeTEx", %{conn: conn} do - Transport.Shared.Schemas.Mock |> expect(:transport_schemas, 2, fn -> %{} end) - {:ok, view, _html} = conn |> get(live_path(conn, OnDemandValidationSelectLive)) |> live() - render_change(view, "form_changed", %{"upload" => %{"type" => "netex"}, "_target" => ["upload", "type"]}) assert_patched(view, live_path(conn, OnDemandValidationSelectLive, type: "netex")) refute view |> has_element?("input[name='upload[url]']") - refute view |> has_element?("input[name='upload[file]']") - refute view |> has_element?("input[type='submit']") - assert view |> has_element?("#netex-explanations") + assert view |> has_element?("input[name='upload[file]']") + + render_change(view, "form_changed", %{"upload" => %{"type" => "gtfs-rt"}, "_target" => ["upload", "type"]}) + assert view |> has_element?("input[name='upload[url]']") + assert view |> has_element?("input[name='upload[feed_url]']") end test "takes into account query params", %{conn: conn} do From 1cacb61b01d1d8b79f5dc2316e2d62f4216a549f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Mon, 9 Sep 2024 17:23:36 +0200 Subject: [PATCH 08/23] Meilleur message --- .../templates/resource/_netex_generic_issue.html.heex | 2 +- .../priv/gettext/en/LC_MESSAGES/validations-explanations.po | 2 +- .../priv/gettext/fr/LC_MESSAGES/validations-explanations.po | 4 ++-- apps/transport/priv/gettext/validations-explanations.pot | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex b/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex index 5e59b6a5e9..7d802501ed 100644 --- a/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex @@ -49,7 +49,7 @@
      diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/validations-explanations.po b/apps/transport/priv/gettext/en/LC_MESSAGES/validations-explanations.po index 08f113b6c8..094412efc1 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/validations-explanations.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/validations-explanations.po @@ -144,5 +144,5 @@ msgid "Unknown location" msgstr "" #, elixir-autogen, elixir-format -msgid "Debug" +msgid "Details for debugging purposes" msgstr "" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po index 4a4429105b..08e030c6ce 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po @@ -144,5 +144,5 @@ msgid "Unknown location" msgstr "Emplacement inconnu" #, elixir-autogen, elixir-format -msgid "Debug" -msgstr "" +msgid "Details for debugging purposes" +msgstr "Détails à fin de debugging" diff --git a/apps/transport/priv/gettext/validations-explanations.pot b/apps/transport/priv/gettext/validations-explanations.pot index 7828983911..e1e89c104f 100644 --- a/apps/transport/priv/gettext/validations-explanations.pot +++ b/apps/transport/priv/gettext/validations-explanations.pot @@ -143,5 +143,5 @@ msgid "Unknown location" msgstr "" #, elixir-autogen, elixir-format -msgid "Debug" +msgid "Details for debugging purposes" msgstr "" From 8b10adb57d2f0c7e767196cd99d55725073e9391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Tue, 10 Sep 2024 11:24:52 +0200 Subject: [PATCH 09/23] Adjust metadata display --- .../templates/validation/show_netex.html.heex | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex index a1c1e8441c..e2c9a83e06 100644 --- a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex +++ b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex @@ -10,16 +10,14 @@ <%= link(dgettext("validations", "this permanent link"), to: current_url(@conn)) %>.

      + + <%= unless is_nil(@metadata) or @metadata == %{} do %> + <%= render("_resources_details_netex.html", metadata: @metadata, conn: @conn) %> + <% end %>
      - <%= unless is_nil(@metadata) or @metadata == %{} do %> - - <% end %> - <%= if has_errors?(@validation_summary) do %> <%= render("_validation_summary.html", validation_summary: @validation_summary, From 21a0ef9944fe4b29bbc2b114056bc59db733da14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Tue, 10 Sep 2024 11:42:53 +0200 Subject: [PATCH 10/23] Display warning about errors levels --- .../templates/validation/show_netex.html.heex | 5 +++++ apps/transport/priv/gettext/en/LC_MESSAGES/validations.po | 8 ++++++++ apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po | 8 ++++++++ apps/transport/priv/gettext/validations.pot | 8 ++++++++ 4 files changed, 29 insertions(+) diff --git a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex index e2c9a83e06..37507d1228 100644 --- a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex +++ b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex @@ -18,6 +18,11 @@
      +

      + <%= dgettext("validations", "NeTEx validation is in beta.") %>
      + <%= dgettext("validations", "Warnings are work in progress. Only XSD errors are considerd for now.") %> +

      + <%= if has_errors?(@validation_summary) do %> <%= render("_validation_summary.html", validation_summary: @validation_summary, diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po index ba6b95a32e..06929186c5 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po @@ -420,3 +420,11 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Elapsed time: %{duration}." msgstr "" + +#, elixir-autogen, elixir-format +msgid "NeTEx validation is in beta." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Warnings are work in progress. Only XSD errors are considerd for now." +msgstr "" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po index 5289715c0a..53f0ab4ce6 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po @@ -420,3 +420,11 @@ msgstr "Rapport de l’analyse de fichier NeTEx" #, elixir-autogen, elixir-format msgid "Elapsed time: %{duration}." msgstr "Temps passé : %{duration}." + +#, elixir-autogen, elixir-format +msgid "NeTEx validation is in beta." +msgstr "Validation NeTEx est en beta." + +#, elixir-autogen, elixir-format +msgid "Warnings are work in progress. Only XSD errors are considerd for now." +msgstr "Les avertissements sont temporaires. Seules les erreurs XSD sont prises en considération pour l’instant." diff --git a/apps/transport/priv/gettext/validations.pot b/apps/transport/priv/gettext/validations.pot index 5bbe429d08..8a9ddea88e 100644 --- a/apps/transport/priv/gettext/validations.pot +++ b/apps/transport/priv/gettext/validations.pot @@ -419,3 +419,11 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Elapsed time: %{duration}." msgstr "" + +#, elixir-autogen, elixir-format +msgid "NeTEx validation is in beta." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Warnings are work in progress. Only XSD errors are considerd for now." +msgstr "" From 8403b889f80c6bde9a0f41aae2a63f28b3c7b756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Thu, 12 Sep 2024 11:59:45 +0200 Subject: [PATCH 11/23] Simplify NeTEx issue template dispatcher --- .../lib/transport_web/views/resource_view.ex | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/apps/transport/lib/transport_web/views/resource_view.ex b/apps/transport/lib/transport_web/views/resource_view.ex index b72d899519..f18cc0ad68 100644 --- a/apps/transport/lib/transport_web/views/resource_view.ex +++ b/apps/transport/lib/transport_web/views/resource_view.ex @@ -50,15 +50,10 @@ defmodule TransportWeb.ResourceView do "_gtfs#{template}" end - def netex_template(issues) do - template = - Map.get( - %{}, - Transport.Validators.NeTEx.issue_type(issues.entries), - "_generic_issue.html" - ) - - "_netex#{template}" + def netex_template(_issues) do + # For now only 1 template has been designed. More to come when the validator + # has matured. + "_netex_generic_issue.html" end @spec action_path(Plug.Conn.t()) :: any From ba62d66f2d5aefff8013f75c57fe48151bdb13ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Thu, 12 Sep 2024 15:20:23 +0200 Subject: [PATCH 12/23] Meilleur message pour les validations rapides --- .../templates/resource/_resources_details_netex.html.heex | 5 ++--- apps/transport/priv/gettext/en/LC_MESSAGES/validations.po | 4 ++++ apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po | 4 ++++ apps/transport/priv/gettext/validations.pot | 4 ++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex b/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex index a235e99002..b175341249 100644 --- a/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex @@ -1,6 +1,5 @@ <% locale = get_session(@conn, :locale) %> +<% duration = if @metadata["elapsed_seconds"] < 1 do dgettext("validations", "less than 1 second") else format_duration(@metadata["elapsed_seconds"], locale) end %>
      - <%= dgettext("validations", "Elapsed time: %{duration}.", - duration: format_duration(@metadata["elapsed_seconds"], locale) - ) %> + <%= dgettext("validations", "Elapsed time: %{duration}.", duration: duration) %>
      diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po index 06929186c5..63a3e882d4 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po @@ -428,3 +428,7 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Warnings are work in progress. Only XSD errors are considerd for now." msgstr "" + +#, elixir-autogen, elixir-format +msgid "less than 1 second" +msgstr "" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po index 53f0ab4ce6..5142ca178b 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po @@ -428,3 +428,7 @@ msgstr "Validation NeTEx est en beta." #, elixir-autogen, elixir-format msgid "Warnings are work in progress. Only XSD errors are considerd for now." msgstr "Les avertissements sont temporaires. Seules les erreurs XSD sont prises en considération pour l’instant." + +#, elixir-autogen, elixir-format +msgid "less than 1 second" +msgstr "moins d’une seconde" diff --git a/apps/transport/priv/gettext/validations.pot b/apps/transport/priv/gettext/validations.pot index 8a9ddea88e..4b3d8fd647 100644 --- a/apps/transport/priv/gettext/validations.pot +++ b/apps/transport/priv/gettext/validations.pot @@ -427,3 +427,7 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Warnings are work in progress. Only XSD errors are considerd for now." msgstr "" + +#, elixir-autogen, elixir-format +msgid "less than 1 second" +msgstr "" From ec3370c1ee4158b3e99fd044bcb9551fe7229922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Thu, 12 Sep 2024 15:24:50 +0200 Subject: [PATCH 13/23] Please the linter --- .../templates/resource/_resources_details_netex.html.heex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex b/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex index b175341249..e0e40c96c8 100644 --- a/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/_resources_details_netex.html.heex @@ -1,5 +1,10 @@ <% locale = get_session(@conn, :locale) %> -<% duration = if @metadata["elapsed_seconds"] < 1 do dgettext("validations", "less than 1 second") else format_duration(@metadata["elapsed_seconds"], locale) end %> +<% duration = + if @metadata["elapsed_seconds"] < 1 do + dgettext("validations", "less than 1 second") + else + format_duration(@metadata["elapsed_seconds"], locale) + end %>
      <%= dgettext("validations", "Elapsed time: %{duration}.", duration: duration) %>
      From 238b8e0a82e65dae69a062637c0034bbc6dc2b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Mon, 16 Sep 2024 17:17:46 +0200 Subject: [PATCH 14/23] No inline stylesheet for CSP implementation --- .../stylesheets/components/_validation.scss | 29 ++++++++++++++++ .../resource/_netex_generic_issue.html.heex | 33 +------------------ 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/apps/transport/client/stylesheets/components/_validation.scss b/apps/transport/client/stylesheets/components/_validation.scss index a88979a24d..04654c3899 100644 --- a/apps/transport/client/stylesheets/components/_validation.scss +++ b/apps/transport/client/stylesheets/components/_validation.scss @@ -123,3 +123,32 @@ details > code { display: inline; } } + +table.netex_generic_issue tr.message td { + vertical-align: top; +} + +table.netex_generic_issue th:nth-child(1) { + width: 60%; +} + +table.netex_generic_issue tr.debug:hover { + background: revert; +} + +table.netex_generic_issue tr.debug td { + border-top: none; + padding-top: 0; +} + +table.netex_generic_issue tr.debug td summary { + cursor: pointer; +} + +table.netex_generic_issue tr.debug td pre { + margin-block: 0; +} + +table.netex_generic_issue tr.debug td code { + width: 100%; +} diff --git a/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex b/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex index 7d802501ed..865cccc4b6 100644 --- a/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/_netex_generic_issue.html.heex @@ -1,35 +1,4 @@ - - -
      <%= dgettext("validations-explanations", "Message") %> <%= dgettext("validations-explanations", "Location") %><%= dgettext("validations-explanations", "Debug") %>
      <%= issue["message"] %> <%= if is_nil(issue["resource"]) or is_nil(issue["resource"]["filename"]) or is_nil(issue["resource"]["line"]) do %> @@ -15,8 +45,13 @@ <%= issue["resource"]["filename"] %>:<%= issue["resource"]["line"] %> <% end %> - <%= to_string(Jason.encode!(issue, pretty: true)) %> +
      +
      + <%= dgettext("validations-explanations", "Debug") %> +
      <%= to_string(Jason.encode!(issue, pretty: true)) %>
      +
      - <%= dgettext("validations-explanations", "Debug") %> + <%= dgettext("validations-explanations", "Details for debugging purposes") %>
      <%= to_string(Jason.encode!(issue, pretty: true)) %>
      +
      From 85c16c8340309d3624ef7bb5d92e3ca1c03fa4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Mon, 16 Sep 2024 17:23:24 +0200 Subject: [PATCH 15/23] Fix misusage of heex templates --- .../templates/resource/_resources_details.html.heex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/transport/lib/transport_web/templates/resource/_resources_details.html.heex b/apps/transport/lib/transport_web/templates/resource/_resources_details.html.heex index 28ee6f4774..d505eae14f 100644 --- a/apps/transport/lib/transport_web/templates/resource/_resources_details.html.heex +++ b/apps/transport/lib/transport_web/templates/resource/_resources_details.html.heex @@ -27,7 +27,7 @@ stats = @metadata["stats"] %> <% else %> -
    • +
    • <%= dngettext("validations", "network", "networks", length(networks)) %> : @@ -36,7 +36,7 @@ stats = @metadata["stats"] %>
    • <% end %> -
    • 0}> +
    • 0}> <%= dngettext("validations", "transport mode", "transport modes", length(@modes)) %> : <%= Enum.join(@modes, ", ") %>
    • From dac5d5d0067defa67bcb0cf0fd5123d883515619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Mon, 16 Sep 2024 17:24:17 +0200 Subject: [PATCH 16/23] Fix typo in i18n --- .../lib/transport_web/templates/validation/show_netex.html.heex | 2 +- apps/transport/priv/gettext/en/LC_MESSAGES/validations.po | 2 +- apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po | 2 +- apps/transport/priv/gettext/validations.pot | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex index 37507d1228..d2b2ead9da 100644 --- a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex +++ b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex @@ -20,7 +20,7 @@

      <%= dgettext("validations", "NeTEx validation is in beta.") %>
      - <%= dgettext("validations", "Warnings are work in progress. Only XSD errors are considerd for now.") %> + <%= dgettext("validations", "Warnings are work in progress. Only XSD errors are considered for now.") %>

      <%= if has_errors?(@validation_summary) do %> diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po index 63a3e882d4..25775e6aa9 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po @@ -426,7 +426,7 @@ msgid "NeTEx validation is in beta." msgstr "" #, elixir-autogen, elixir-format -msgid "Warnings are work in progress. Only XSD errors are considerd for now." +msgid "Warnings are work in progress. Only XSD errors are considered for now." msgstr "" #, elixir-autogen, elixir-format diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po index 5142ca178b..f70c1efdab 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po @@ -426,7 +426,7 @@ msgid "NeTEx validation is in beta." msgstr "Validation NeTEx est en beta." #, elixir-autogen, elixir-format -msgid "Warnings are work in progress. Only XSD errors are considerd for now." +msgid "Warnings are work in progress. Only XSD errors are considered for now." msgstr "Les avertissements sont temporaires. Seules les erreurs XSD sont prises en considération pour l’instant." #, elixir-autogen, elixir-format diff --git a/apps/transport/priv/gettext/validations.pot b/apps/transport/priv/gettext/validations.pot index 4b3d8fd647..f970fa6a64 100644 --- a/apps/transport/priv/gettext/validations.pot +++ b/apps/transport/priv/gettext/validations.pot @@ -425,7 +425,7 @@ msgid "NeTEx validation is in beta." msgstr "" #, elixir-autogen, elixir-format -msgid "Warnings are work in progress. Only XSD errors are considerd for now." +msgid "Warnings are work in progress. Only XSD errors are considered for now." msgstr "" #, elixir-autogen, elixir-format From bf1c301559383178ea4490044753f58feaa53bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Mon, 16 Sep 2024 17:24:44 +0200 Subject: [PATCH 17/23] i18n: better French version --- .../priv/gettext/fr/LC_MESSAGES/validations-explanations.po | 2 +- apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po index 08e030c6ce..55adbefc56 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations-explanations.po @@ -145,4 +145,4 @@ msgstr "Emplacement inconnu" #, elixir-autogen, elixir-format msgid "Details for debugging purposes" -msgstr "Détails à fin de debugging" +msgstr "Détails à fin de débogage" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po index f70c1efdab..9059b71436 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po @@ -423,7 +423,7 @@ msgstr "Temps passé : %{duration}." #, elixir-autogen, elixir-format msgid "NeTEx validation is in beta." -msgstr "Validation NeTEx est en beta." +msgstr "La validation NeTEx est en beta." #, elixir-autogen, elixir-format msgid "Warnings are work in progress. Only XSD errors are considered for now." From dcd3b225c0aaeb8a076f8ba49c7bfb7028ad2165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Mon, 16 Sep 2024 18:20:12 +0200 Subject: [PATCH 18/23] =?UTF-8?q?Formatage=20de=20dur=C3=A9e=20:=20utiliso?= =?UTF-8?q?ns=20Cldr.Calendar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/shared/lib/cldr.ex | 2 +- apps/shared/lib/date_time_display.ex | 55 +++++++++++----------------- apps/shared/mix.exs | 3 ++ mix.lock | 3 ++ 4 files changed, 28 insertions(+), 35 deletions(-) diff --git a/apps/shared/lib/cldr.ex b/apps/shared/lib/cldr.ex index 2c37c71d09..c0ac98f300 100644 --- a/apps/shared/lib/cldr.ex +++ b/apps/shared/lib/cldr.ex @@ -3,5 +3,5 @@ defmodule Transport.Cldr do Declares a backend for Cldr as required. https://hexdocs.pm/ex_cldr_numbers/readme.html#introduction-and-getting-started """ - use Cldr, locales: ["en", "fr"], providers: [Cldr.Number], default_locale: "fr" + use Cldr, locales: ["en", "fr"], providers: [Cldr.Number, Cldr.Calendar, Cldr.Unit, Cldr.List], default_locale: "fr" end diff --git a/apps/shared/lib/date_time_display.ex b/apps/shared/lib/date_time_display.ex index f61d20527f..39620b75a9 100644 --- a/apps/shared/lib/date_time_display.ex +++ b/apps/shared/lib/date_time_display.ex @@ -109,8 +109,6 @@ defmodule Shared.DateTimeDisplay do Supported locales: "fr" and "en". - iex> format_duration(0, "en") - "0 second" iex> format_duration(1, "en") "1 second" iex> format_duration(3, "en") @@ -118,55 +116,44 @@ defmodule Shared.DateTimeDisplay do iex> format_duration(60, "en") "1 minute" iex> format_duration(61, "en") - "1 minute 1 second" + "1 minute and 1 second" iex> format_duration(65, "en") - "1 minute 5 seconds" + "1 minute and 5 seconds" iex> format_duration(120, "en") "2 minutes" iex> format_duration(125, "en") - "2 minutes 5 seconds" + "2 minutes and 5 seconds" + iex> format_duration(3601, "en") + "1 hour and 1 second" + iex> format_duration(3661, "en") + "1 hour, 1 minute, and 1 second" - iex> format_duration(0, "fr") - "0 seconde" iex> format_duration(1, "fr") - "1 seconde" + "1 seconde" iex> format_duration(3, "fr") - "3 secondes" + "3 secondes" iex> format_duration(60, "fr") "1 minute" iex> format_duration(61, "fr") - "1 minute 1 seconde" + "1 minute et 1 seconde" iex> format_duration(65, "fr") - "1 minute 5 secondes" + "1 minute et 5 secondes" iex> format_duration(120, "fr") "2 minutes" iex> format_duration(125, "fr") - "2 minutes 5 secondes" + "2 minutes et 5 secondes" + iex> format_duration(3601, "fr") + "1 heure et 1 seconde" + iex> format_duration(3661, "fr") + "1 heure, 1 minute et 1 seconde" """ - @spec format_duration(non_neg_integer(), binary()) :: binary() + @spec format_duration(pos_integer(), binary()) :: binary() def format_duration(duration_in_seconds, locale) do - minutes = div(duration_in_seconds, 60) - seconds = rem(duration_in_seconds, 60) + locale = Cldr.Locale.new!(locale, Transport.Cldr) - cond do - minutes > 0 and seconds > 0 -> "#{format_minutes(minutes, locale)} #{format_seconds(seconds, locale)}" - minutes > 0 -> format_minutes(minutes, locale) - true -> format_seconds(seconds, locale) - end - end - - defp format_seconds(seconds, "en"), do: format_duration_unit(seconds, "second") - defp format_seconds(seconds, _locale), do: format_duration_unit(seconds, "seconde") - - defp format_minutes(seconds, "en"), do: format_duration_unit(seconds, "minute") - defp format_minutes(seconds, _locale), do: format_duration_unit(seconds, "minute") - - defp format_duration_unit(duration, unit) do - if duration > 1 do - "#{duration} #{unit}s" - else - "#{duration} #{unit}" - end + duration_in_seconds + |> Cldr.Calendar.Duration.new_from_seconds() + |> Cldr.Calendar.Duration.to_string!(locale: locale) end @spec convert_to_paris_time(DateTime.t() | NaiveDateTime.t()) :: DateTime.t() diff --git a/apps/shared/mix.exs b/apps/shared/mix.exs index 6c6b785d9a..36e5797b6a 100644 --- a/apps/shared/mix.exs +++ b/apps/shared/mix.exs @@ -57,6 +57,9 @@ defmodule Shared.MixProject do # be required no matter what. {:jason, ">= 0.0.0"}, {:ex_cldr_numbers, "~> 2.0"}, + {:ex_cldr_calendars, "~> 1.26"}, + {:ex_cldr_lists, "~> 2.11"}, + {:ex_cldr_units, "~> 3.17"}, {:cachex, "~> 3.5"}, {:ex_json_schema, "~> 0.10"}, # added because of `TransportWeb.Plugs.AppSignalFilter` diff --git a/mix.lock b/mix.lock index 2a5082b786..1732baf12c 100644 --- a/mix.lock +++ b/mix.lock @@ -39,8 +39,11 @@ "ex_aws": {:hex, :ex_aws, "2.5.4", "86c5bb870a49e0ab6f5aa5dd58cf505f09d2624ebe17530db3c1b61c88a673af", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8 or ~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:mime, "~> 1.2 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e82bd0091bb9a5bb190139599f922ff3fc7aebcca4374d65c99c4e23aa6d1625"}, "ex_aws_s3": {:hex, :ex_aws_s3, "2.5.3", "422468e5c3e1a4da5298e66c3468b465cfd354b842e512cb1f6fbbe4e2f5bdaf", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "4f09dd372cc386550e484808c5ac5027766c8d0cd8271ccc578b82ee6ef4f3b8"}, "ex_cldr": {:hex, :ex_cldr, "2.40.0", "624717778dbf0a8cd307f1576eabbd44470c16190172abf293fed24150440a5a", [:mix], [{:cldr_utils, "~> 2.28", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.19", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: true]}], "hexpm", "113394b6dd23aaf7912da583aab103d9cf082b9821bc4a6e287543a895af7cb4"}, + "ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.26.2", "5f15d1673f46fd1d7b0c770bf65b40ce060465328637d24212ec9e79310eca87", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:ex_cldr_lists, "~> 2.10", [hex: :ex_cldr_lists, repo: "hexpm", optional: true]}, {:ex_cldr_numbers, "~> 2.31", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.16", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:ex_doc, "~> 0.21", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "b689847f3fbbd145954a9205e19b1e4850a79c2a27cdae1c7912b9b262a8ef35"}, "ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.16.2", "670d96cc4fb18cfebd82488ed687742683be2d0725d66ec051578d4b13539aa8", [:mix], [{:ex_cldr, "~> 2.38", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "2ccfac2838f4df8c8e5424dbc68eb2f3ac9eeb45e10365050901f7ac7a914ce1"}, + "ex_cldr_lists": {:hex, :ex_cldr_lists, "2.11.1", "ad18f861d7c5ca82aac6d173469c6a2339645c96790172ab0aa255b64fb7303b", [:mix], [{:ex_cldr_numbers, "~> 2.25", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.18", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "00161c04510ccb3f18b19a6b8562e50c21f1e9c15b8ff4c934bea5aad0b4ade2"}, "ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.33.2", "c5587a8d84214d9cc42e7827e4c3bed2aa9e52505a55b10540020725954ded2c", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:digital_token, "~> 0.3 or ~> 1.0", [hex: :digital_token, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.38", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.16", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "49f1dbaddc1ad6e3f496a97fa425d25b3ae89e8178ce0416d9909deaf2e5ad80"}, + "ex_cldr_units": {:hex, :ex_cldr_units, "3.17.2", "b0483d5c61c6c8649aafdcafc7372dd71a7a30f52dd4c9b072576467bf721454", [:mix], [{:cldr_utils, "~> 2.25", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr_lists, "~> 2.10", [hex: :ex_cldr_lists, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.33.0", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.18", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "457d76c6e3b548bd7aba3c7b5d157213be2842d1162c2283abf81d9e2f1e1fc7"}, "ex_json_schema": {:hex, :ex_json_schema, "0.10.2", "7c4b8c1481fdeb1741e2ce66223976edfb9bccebc8014f6aec35d4efe964fb71", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "37f43be60f8407659d4d0155a7e45e7f406dab1f827051d3d35858a709baf6a6"}, "ex_machina": {:hex, :ex_machina, "2.8.0", "a0e847b5712065055ec3255840e2c78ef9366634d62390839d4880483be38abe", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "79fe1a9c64c0c1c1fab6c4fa5d871682cb90de5885320c187d117004627a7729"}, "ex_phone_number": {:hex, :ex_phone_number, "0.4.4", "8e994abe583496a3308cf56af013dca9b47a0424b0a9940af41cb0d66b848dd3", [:mix], [{:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: false]}], "hexpm", "a59875692ec57b3392959a7740f3e9a5cb08da88bcaee4efd480c770f5bb0f2c"}, From 0f3733a93f6e4682f54aa90bf4698aed648ca669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Tue, 17 Sep 2024 13:12:24 +0200 Subject: [PATCH 19/23] Please dialyzer --- .dialyzer_ignore.exs | 3 ++- apps/shared/lib/date_time_display.ex | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.dialyzer_ignore.exs b/.dialyzer_ignore.exs index fbd5600ea4..a427acda3f 100644 --- a/.dialyzer_ignore.exs +++ b/.dialyzer_ignore.exs @@ -8,5 +8,6 @@ # See https://github.com/danielberkompas/cloak_ecto/issues/55 {"lib/db/contact.ex", :unknown_type, 0}, {"lib/db/user_feedback.ex", :unknown_type, 0}, - {"lib/db/notification.ex", :unknown_type, 0} + {"lib/db/notification.ex", :unknown_type, 0}, + ~r/lib\/cldr.ex/ ] diff --git a/apps/shared/lib/date_time_display.ex b/apps/shared/lib/date_time_display.ex index 39620b75a9..7a0e787a00 100644 --- a/apps/shared/lib/date_time_display.ex +++ b/apps/shared/lib/date_time_display.ex @@ -109,6 +109,10 @@ defmodule Shared.DateTimeDisplay do Supported locales: "fr" and "en". + iex> format_duration(1, :en) + "1 second" + iex> format_duration(1, Transport.Cldr.Locale.new!("en")) + "1 second" iex> format_duration(1, "en") "1 second" iex> format_duration(3, "en") @@ -128,6 +132,10 @@ defmodule Shared.DateTimeDisplay do iex> format_duration(3661, "en") "1 hour, 1 minute, and 1 second" + iex> format_duration(1, :fr) + "1 seconde" + iex> format_duration(1, Transport.Cldr.Locale.new!("fr")) + "1 seconde" iex> format_duration(1, "fr") "1 seconde" iex> format_duration(3, "fr") @@ -147,7 +155,7 @@ defmodule Shared.DateTimeDisplay do iex> format_duration(3661, "fr") "1 heure, 1 minute et 1 seconde" """ - @spec format_duration(pos_integer(), binary()) :: binary() + @spec format_duration(pos_integer(), atom() | %Cldr.LanguageTag{}) :: binary() def format_duration(duration_in_seconds, locale) do locale = Cldr.Locale.new!(locale, Transport.Cldr) From 097521c6e7a33a838b9e5562cef2a81db29a279f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Tue, 17 Sep 2024 13:29:34 +0200 Subject: [PATCH 20/23] Please dialyzer --- apps/shared/lib/date_time_display.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/shared/lib/date_time_display.ex b/apps/shared/lib/date_time_display.ex index 7a0e787a00..2524f2a543 100644 --- a/apps/shared/lib/date_time_display.ex +++ b/apps/shared/lib/date_time_display.ex @@ -155,7 +155,7 @@ defmodule Shared.DateTimeDisplay do iex> format_duration(3661, "fr") "1 heure, 1 minute et 1 seconde" """ - @spec format_duration(pos_integer(), atom() | %Cldr.LanguageTag{}) :: binary() + @spec format_duration(pos_integer(), atom() | Cldr.LanguageTag.t()) :: binary() def format_duration(duration_in_seconds, locale) do locale = Cldr.Locale.new!(locale, Transport.Cldr) From e6018cac3da2824bbb3b960ea63e81cee21c2781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Tue, 17 Sep 2024 13:59:08 +0200 Subject: [PATCH 21/23] Dialyzer: keep track of the exclusions --- .dialyzer_ignore.exs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.dialyzer_ignore.exs b/.dialyzer_ignore.exs index a427acda3f..ca22a3ecb4 100644 --- a/.dialyzer_ignore.exs +++ b/.dialyzer_ignore.exs @@ -9,5 +9,9 @@ {"lib/db/contact.ex", :unknown_type, 0}, {"lib/db/user_feedback.ex", :unknown_type, 0}, {"lib/db/notification.ex", :unknown_type, 0}, + + # Workaround for "Overloaded contract for Transport.Cldr.Calendar.localize/3 + # has overlapping domains; such contracts are currently unsupported and are + # simply ignored." ~r/lib\/cldr.ex/ ] From bf94ba4c77c7c911372860b49183d046e4973538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Tue, 17 Sep 2024 14:12:49 +0200 Subject: [PATCH 22/23] Better NeTEx validation introduction --- .../templates/validation/show_gtfs.html.heex | 2 +- .../templates/validation/show_netex.html.heex | 2 +- .../transport/priv/gettext/en/LC_MESSAGES/validations.po | 9 +++++++-- .../transport/priv/gettext/fr/LC_MESSAGES/validations.po | 9 +++++++-- apps/transport/priv/gettext/validations.pot | 6 +++++- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/apps/transport/lib/transport_web/templates/validation/show_gtfs.html.heex b/apps/transport/lib/transport_web/templates/validation/show_gtfs.html.heex index a3b765be56..cffc5b678d 100644 --- a/apps/transport/lib/transport_web/templates/validation/show_gtfs.html.heex +++ b/apps/transport/lib/transport_web/templates/validation/show_gtfs.html.heex @@ -3,7 +3,7 @@

      <%= dgettext("validations", "GTFS review report") %>

      - <%= dgettext("validations", "explanations", format: "GTFS") %> + <%= dgettext("validations", "explanations-gtfs") %>

      <%= dgettext("validations", "This report can be shared with") %> diff --git a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex index d2b2ead9da..3862e57783 100644 --- a/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex +++ b/apps/transport/lib/transport_web/templates/validation/show_netex.html.heex @@ -3,7 +3,7 @@

      <%= dgettext("validations", "NeTEx review report") %>

      - <%= dgettext("validations", "explanations", format: "NeTEx") %> + <%= dgettext("validations", "explanations-netex") %>

      <%= dgettext("validations", "This report can be shared with") %> diff --git a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po index fbf4a7de6d..7855b78a86 100644 --- a/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/en/LC_MESSAGES/validations.po @@ -75,10 +75,15 @@ msgid "to" msgstr "" #, elixir-autogen, elixir-format -msgid "explanations" -msgstr "This is the automated evaluation of the %{format} datafile. " +msgid "explanations-gtfs" +msgstr "This is the automated evaluation of the GTFS datafile. " "This validation only considers the datastructure and does not give any information about completeness nor exactitude of the timetables. " +#, elixir-autogen, elixir-format +msgid "explanations-netex" +msgstr "This is the automated evaluation of the NeTEx datafile. " +"This validation only considers the datastructure and does not give any information about completeness nor exactitude of the data. " + #, elixir-autogen, elixir-format msgid "Show anyway" msgstr "" diff --git a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po index c29d383ef5..133abd1a25 100644 --- a/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po +++ b/apps/transport/priv/gettext/fr/LC_MESSAGES/validations.po @@ -75,10 +75,15 @@ msgid "to" msgstr "au" #, elixir-autogen, elixir-format -msgid "explanations" -msgstr "Voici le bilan automatisé sur la qualité du fichier %{format}. " +msgid "explanations-gtfs" +msgstr "Voici le bilan automatisé sur la qualité du fichier GTFS. " "Cette validation ne concerne que la structure des données et pas la complétude ni l’exactitude des horaires. " +#, elixir-autogen, elixir-format +msgid "explanations-netex" +msgstr "Voici le bilan automatisé sur la qualité du fichier NeTEx. " +"Cette validation ne concerne que la structure des données et pas la complétude ni l’exactitude des données. " + #, elixir-autogen, elixir-format msgid "Show anyway" msgstr "Afficher quand même" diff --git a/apps/transport/priv/gettext/validations.pot b/apps/transport/priv/gettext/validations.pot index dd31c46c9b..15362901e9 100644 --- a/apps/transport/priv/gettext/validations.pot +++ b/apps/transport/priv/gettext/validations.pot @@ -75,7 +75,11 @@ msgid "to" msgstr "" #, elixir-autogen, elixir-format -msgid "explanations" +msgid "explanations-gtfs" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "explanations-netex" msgstr "" #, elixir-autogen, elixir-format From add29cfdf6fad9c85c12bff78bb9161af6b04260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Menou?= Date: Tue, 17 Sep 2024 14:23:07 +0200 Subject: [PATCH 23/23] Simplify file generation for on demand validation --- .../lib/transport_web/controllers/validation_controller.ex | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/transport/lib/transport_web/controllers/validation_controller.ex b/apps/transport/lib/transport_web/controllers/validation_controller.ex index 7cdb472f26..bf836afe49 100644 --- a/apps/transport/lib/transport_web/controllers/validation_controller.ex +++ b/apps/transport/lib/transport_web/controllers/validation_controller.ex @@ -160,9 +160,10 @@ defmodule TransportWeb.ValidationController do end defp filepath(type) do - cond do - type == "tableschema" -> Ecto.UUID.generate() <> ".csv" - type in ["jsonschema", "gtfs", "netex"] -> Ecto.UUID.generate() + if type == "tableschema" do + Ecto.UUID.generate() <> ".csv" + else + Ecto.UUID.generate() end end

      <%= dgettext("validations-explanations", "Message") %> <%= dgettext("validations-explanations", "Location") %>