Skip to content

Commit

Permalink
Mise à jour du contenu des notifications (#3624)
Browse files Browse the repository at this point in the history
* Mise à jour du contenu des notifications

* Rework dataset_with_error_reuser

* Rework resource_unavailable_reuser

* Rework resource_unavailable_producer

* Only use .md templates

* Add resource titles in expiration_producer

---------

Co-authored-by: Thibaut Barrère <[email protected]>
  • Loading branch information
AntoineAugusti and thbar authored Dec 7, 2023
1 parent 5b8cd97 commit f804e27
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ defmodule Transport.Jobs.DatasetNowOnNAPNotificationJob do
Phoenix.View.render_to_string(TransportWeb.EmailView, "dataset_now_on_nap.html",
dataset_url: TransportWeb.Router.Helpers.dataset_url(TransportWeb.Endpoint, :details, dataset.slug),
dataset_custom_title: dataset.custom_title,
contact_email_address: Application.get_env(:transport, :contact_email)
contact_email_address: Application.get_env(:transport, :contact_email),
espace_producteur_url: TransportWeb.Router.Helpers.page_url(TransportWeb.Endpoint, :espace_producteur)
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ defmodule Transport.Jobs.MultiValidationWithErrorNotificationJob do
end

defp send_to_reusers(emails, %DB.Dataset{} = dataset, producer_warned: producer_warned) do
Enum.each(emails, &send_mail(&1, :reuser, dataset: dataset, producer_warned: producer_warned))
Enum.each(
emails,
&send_mail(&1, :reuser, dataset: dataset, producer_warned: producer_warned)
)
end

defp send_to_producers(emails, %DB.Dataset{} = dataset, multi_validations) do
Expand Down
118 changes: 79 additions & 39 deletions apps/transport/lib/transport/data_checker.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ defmodule Transport.DataChecker do
import Ecto.Query
require Logger

@type delay_and_records :: {integer(), [{DB.Dataset.t(), [DB.Resource.t()]}]}
@expiration_reason DB.NotificationSubscription.reason(:expiration)
@new_dataset_reason DB.NotificationSubscription.reason(:new_dataset)
@default_outdated_data_delays [-7, -3, 0, 7, 14]
# If delay < 0, the resource is already expired
@default_outdated_data_delays [-90, -60, -30, -45, -15, -7, -3, 0, 7, 14]

@doc """
This method is a scheduled job which does two things:
Expand Down Expand Up @@ -103,21 +105,24 @@ defmodule Transport.DataChecker do
date = Date.add(Date.utc_today(), delay) do
{delay, gtfs_datasets_expiring_on(date)}
end
|> Enum.reject(fn {_, d} -> d == [] end)
|> Enum.reject(fn {_, records} -> Enum.empty?(records) end)
|> send_outdated_data_mail()
|> Enum.map(&send_outdated_data_notifications/1)
end

@spec gtfs_datasets_expiring_on(Date.t()) :: [{DB.Dataset.t(), [DB.Resource.t()]}]
def gtfs_datasets_expiring_on(%Date{} = date) do
DB.Dataset.base_query()
|> DB.Dataset.join_from_dataset_to_metadata(Transport.Validators.GTFSTransport.validator_name())
|> where(
[metadata: m, resource: r],
fragment("TO_DATE(?->>'end_date', 'YYYY-MM-DD')", m.metadata) == ^date and r.format == "GTFS"
)
|> select([dataset: d], d)
|> select([dataset: d, resource: r], {d, r})
|> distinct(true)
|> DB.Repo.all()
|> Enum.group_by(fn {%DB.Dataset{} = d, _} -> d end, fn {_, %DB.Resource{} = r} -> r end)
|> Enum.to_list()
end

def possible_delays do
Expand Down Expand Up @@ -163,25 +168,26 @@ defmodule Transport.DataChecker do
end)
end

def send_outdated_data_notifications({delay, datasets} = payload) do
Enum.each(datasets, fn dataset ->
@spec send_outdated_data_notifications(delay_and_records()) :: delay_and_records()
def send_outdated_data_notifications({delay, records} = payload) do
Enum.each(records, fn {%DB.Dataset{} = dataset, resources} ->
emails =
@expiration_reason
|> DB.NotificationSubscription.subscriptions_for_reason_dataset_and_role(dataset, :producer)
|> DB.NotificationSubscription.subscriptions_to_emails()

emails
|> Enum.each(fn email ->
Enum.each(emails, fn email ->
Transport.EmailSender.impl().send_mail(
"transport.data.gouv.fr",
Application.get_env(:transport, :contact_email),
email,
Application.get_env(:transport, :contact_email),
"Jeu de données arrivant à expiration",
email_subject(delay),
"",
Phoenix.View.render_to_string(TransportWeb.EmailView, "expiration_producer.html",
delay_str: delay_str(delay, :expire),
dataset: dataset
delay_str: delay_str(delay, :périment),
dataset: dataset,
resource_titles: resource_titles(resources)
)
)

Expand All @@ -192,6 +198,34 @@ defmodule Transport.DataChecker do
payload
end

@doc """
iex> resource_titles([%DB.Resource{title: "B"}])
"B"
iex> resource_titles([%DB.Resource{title: "B"}, %DB.Resource{title: "A"}])
"A, B"
"""
def resource_titles(resources) do
resources
|> Enum.sort_by(fn %DB.Resource{title: title} -> title end)
|> Enum.map_join(", ", fn %DB.Resource{title: title} -> title end)
end

@doc """
iex> email_subject(7)
"Jeu de données arrivant à expiration"
iex> email_subject(0)
"Jeu de données arrivant à expiration"
iex> email_subject(-3)
"Jeu de données périmé"
"""
def email_subject(delay) when delay >= 0 do
"Jeu de données arrivant à expiration"
end

def email_subject(delay) when delay < 0 do
"Jeu de données périmé"
end

defp save_notification(reason, %Dataset{} = dataset, email) do
DB.Notification.insert!(reason, dataset, email)
end
Expand All @@ -218,45 +252,50 @@ defmodule Transport.DataChecker do
end
end

defp make_str({delay, datasets}) do
@spec make_str(delay_and_records()) :: binary()
defp make_str({delay, records}) do
datasets = Enum.map(records, fn {%DB.Dataset{} = d, _} -> d end)

dataset_str = fn %Dataset{} = dataset ->
"#{link_and_name(dataset)} (#{expiration_notification_enabled_str(dataset)}) #{climate_resilience_str(dataset)}"
|> String.trim()
end

"""
Jeux de données #{delay_str(delay, :expirant)} :
Jeux de données #{delay_str(delay, :périmant)} :
#{Enum.map_join(datasets, "\n", &dataset_str.(&1))}
"""
end

@doc """
iex> delay_str(0, :expirant)
"expirant demain"
iex> delay_str(0, :expire)
"expire demain"
iex> delay_str(2, :expirant)
"expirant dans 2 jours"
iex> delay_str(2, :expire)
"expire dans 2 jours"
iex> delay_str(-1, :expirant)
"expirés depuis hier"
iex> delay_str(-1, :expire)
"est expirée depuis hier"
iex> delay_str(-2, :expirant)
"expirés depuis 2 jours"
iex> delay_str(-2, :expire)
"est expirée depuis 2 jours"
iex> delay_str(0, :périmant)
"périmant demain"
iex> delay_str(0, :périment)
"périment demain"
iex> delay_str(2, :périmant)
"périmant dans 2 jours"
iex> delay_str(2, :périment)
"périment dans 2 jours"
iex> delay_str(-1, :périmant)
"périmé depuis hier"
iex> delay_str(-1, :périment)
"sont périmées depuis hier"
iex> delay_str(-2, :périmant)
"périmés depuis 2 jours"
iex> delay_str(-2, :périment)
"sont périmées depuis 2 jours"
iex> delay_str(-60, :périment)
"sont périmées depuis 60 jours"
"""
@spec delay_str(integer(), :expire | :expirant) :: binary()
@spec delay_str(integer(), :périment | :périmant) :: binary()
def delay_str(0, verb), do: "#{verb} demain"
def delay_str(1, verb), do: "#{verb} dans 1 jour"
def delay_str(d, verb) when d >= 2, do: "#{verb} dans #{d} jours"
def delay_str(-1, :expirant), do: "expirés depuis hier"
def delay_str(-1, :expire), do: "est expirée depuis hier"
def delay_str(d, :expirant) when d <= -2, do: "expirés depuis #{-d} jours"
def delay_str(d, :expire) when d <= -2, do: "est expirée depuis #{-d} jours"
def delay_str(-1, :périmant), do: "périmé depuis hier"
def delay_str(-1, :périment), do: "sont périmées depuis hier"
def delay_str(d, :périmant) when d <= -2, do: "périmés depuis #{-d} jours"
def delay_str(d, :périment) when d <= -2, do: "sont périmées depuis #{-d} jours"

def link(%Dataset{slug: slug}), do: dataset_url(TransportWeb.Endpoint, :details, slug)

Expand All @@ -267,30 +306,31 @@ defmodule Transport.DataChecker do
" * #{custom_title} - #{link}"
end

defp make_outdated_data_body(datasets) do
defp make_outdated_data_body(records) do
"""
Bonjour,
Voici un résumé des jeux de données arrivant à expiration
#{Enum.map_join(datasets, "\n---------------------\n", &make_str/1)}
#{Enum.map_join(records, "\n---------------------\n", &make_str/1)}
"""
end

defp send_outdated_data_mail([] = _datasets), do: []
@spec send_outdated_data_mail([delay_and_records()]) :: [delay_and_records()]
defp send_outdated_data_mail([] = _records), do: []

defp send_outdated_data_mail(datasets) do
defp send_outdated_data_mail(records) do
Transport.EmailSender.impl().send_mail(
"transport.data.gouv.fr",
Application.get_env(:transport, :contact_email),
Application.get_env(:transport, :bizdev_email),
Application.get_env(:transport, :contact_email),
"Jeux de données arrivant à expiration",
make_outdated_data_body(datasets),
make_outdated_data_body(records),
""
)

datasets
records
end

defp fmt_inactive_datasets([]), do: ""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
Bonjour,

Votre jeu de données [<%= @dataset_custom_title %>](<%= @dataset_url %>) a bien été référencé sur le [Point d'Accès National aux données de transport, transport.data.gouv.fr](https://doc.transport.data.gouv.fr/le-point-d-acces-national/generalites/le-point-dacces-national).
Votre jeu de données [<%= @dataset_custom_title %>](<%= @dataset_url %>) a bien été référencé sur le Point dAccès National aux données de transport, [transport.data.gouv.fr](https://transport.data.gouv.fr).

Pour gérer la qualité de vos données : [les mettre à jour](https://doc.transport.data.gouv.fr/producteurs/mettre-a-jour-des-donnees), vous [inscrire à des notifications](https://doc.transport.data.gouv.fr/administration-des-donnees/procedures-de-publication/gerer-la-qualite-des-donnees#sinscrire-aux-notifications) etc. nous vous encourageons à passer par l'[espace producteur du PAN](https://transport.data.gouv.fr/espace_producteur).
Rendez-vous sur votre [Espace Producteur](<%= @espace_producteur_url %>) pour mettre à jour vos données ou vous inscrire à des notifications en cas de péremption, d’indisponibilité ou d’erreurs bloquantes sur votre jeu de données.

Si vous avez des questions, n'hésitez pas à contacter notre équipe à l'adresse : <%= @contact_email_address %>.
Si vous avez des questions, nhésitez pas à contacter notre équipe à ladresse : <%= @contact_email_address %>.

Bien à vous,
À bientôt,

L’équipe transport.data.gouv.fr
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ Nous vous invitons à les corriger en vous appuyant sur les rapports de validati
<%= link_for_resource(resource) %>
<% end %>

Nous restons disponible pour vous accompagner si besoin.
Nous restons disponibles pour vous accompagner si besoin.

Merci par avance pour votre action,

À bientôt,

L'équipe du PAN
Léquipe transport.data.gouv.fr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Bonjour,
Des erreurs bloquantes ont été détectées dans le jeu de données <%= link_for_dataset(@dataset) %> que vous réutilisez.

<%= if @producer_warned do %>
Le producteur de ces données a été informé de ces erreurs.
Nous avons déjà informé le producteur de ces données. Si les erreurs ne sont pas corrigées, vous pouvez contacter le producteur à partir de <%= link_for_dataset_discussions(@dataset) %>.
<% end %>

L’équipe du PAN
L’équipe transport.data.gouv.fr
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
Bonjour,

Une ressource associée au jeu de données <%= link_for_dataset(@dataset) %> <%= @delay_str %>.
Les données GTFS <%= @resource_titles %> associées au jeu de données <%= link_for_dataset(@dataset) %> <%= @delay_str %>.

Afin qu’il puisse continuer à être utilisé par les différents acteurs, il faut qu’il soit mis à jour. Pour cela, veuillez [remplacer la ressource périmée par la nouvelle ressource](https://doc.transport.data.gouv.fr/administration-des-donnees/procedures-de-publication/mettre-a-jour-des-donnees#remplacer-un-jeu-de-donnees-existant-plutot-quen-creer-un-nouveau).
Nous vous invitons à les mettre à jour en [remplaçant la ressource périmée par la nouvelle](https://doc.transport.data.gouv.fr/administration-des-donnees/procedures-de-publication/mettre-a-jour-des-donnees#remplacer-un-jeu-de-donnees-existant-plutot-quen-creer-un-nouveau) afin que vos données puissent être utilisées par les différents acteurs.

Veuillez également anticiper vos prochaines mises à jour, au moins 7 jours avant l’expiration de votre fichier.
Afin de garantir une continuité dans l’utilisation de vos données, nous vous encourageons à anticiper les futures mises à jour au moins 7 jours avant la date d’expiration.

L’équipe transport.data.gouv.fr
À bientôt,

---
Retrouvez comment gérer ces notifications [dans notre documentation](https://doc.transport.data.gouv.fr/administration-des-donnees/procedures-de-publication/gerer-la-qualite-des-donnees).
L’équipe transport.data.gouv.fr
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@ Bonjour,
Les ressources <%= @resource_titles %> dans votre jeu de données <%= link_for_dataset(@dataset) %> ne sont plus disponibles au téléchargement depuis plus de <%= @hours_consecutive_downtime %>h.

<%= if @deleted_recreated_on_datagouv do %>
Il semble que vous ayez supprimé et créé une nouvelle ressource. Lors de la mise à jour de vos données, remplacez plutôt le fichier au sein de la ressource existante. Retrouvez la procédure pas à pas [sur notre documentation](https://doc.transport.data.gouv.fr/producteurs/mettre-a-jour-des-donnees).
Il semble que vous ayez supprimé puis créé une nouvelle ressource : l’URL de téléchargement a donc été modifiée ce qui risque de perturber la réutilisation de vos données. Si ce constat est avéré, nous vous encourageons à prévenir les réutilisateurs de la modification de l’URL de téléchargement via <%= link_for_dataset_discussions(@dataset) %>.

Pour corriger le problème pour cette fois-ci :
1. Mettez à jour l’ancienne ressource avec les nouvelles données en [suivant notre documentation](https://doc.transport.data.gouv.fr/producteurs/mettre-a-jour-des-donnees) ;
2. Supprimez la ressource nouvellement créée qui sera alors en doublon.
Pour les prochaines mises à jour, afin de garantir une URL stable, nous vous invitons à remplacer votre ressource obsolète par la nouvelle.

Pour cela, rendez-vous sur votre [Espace Producteur](<%= TransportWeb.Router.Helpers.page_url(TransportWeb.Endpoint, :espace_producteur) %>) à partir duquel vous pourrez procéder à ces mises à jour.

Retrouvez la procédure pas à pas [sur notre documentation](https://doc.transport.data.gouv.fr/producteurs/mettre-a-jour-des-donnees).
<% else %>
Ces erreurs provoquent des difficultés pour les réutilisateurs. Nous vous invitons à corriger l’accès de vos données dès que possible.
Nous vous invitons à corriger l’accès à vos données dès que possible afin de ne pas perturber leur réutilisation.
<% end %>

Nous restons disponible pour vous accompagner si besoin.

Merci par avance pour votre action,
Nous restons disponibles pour vous accompagner si besoin.

À bientôt,

L’équipe du PAN
L’équipe transport.data.gouv.fr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ Bonjour,
Les ressources <%= @resource_titles %> du jeu de données <%= link_for_dataset(@dataset) %> que vous réutilisez ne sont plus disponibles au téléchargement depuis plus de <%= @hours_consecutive_downtime %>h.

<%= if @producer_warned do %>
Le producteur de ces données a été informé de cette indisponibilité.
Nous avons déjà informé le producteur de ces données. Si l’indisponibilité perdure, vous pouvez contacter le producteur à partir de <%= link_for_dataset_discussions(@dataset) %>.
<% end %>

L’équipe du PAN
À bientôt,

L’équipe transport.data.gouv.fr
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ Bonjour,

Les ressources du jeu de données <%= link_for_dataset(@dataset) %> viennent d'être modifiées (ajout/suppression de ressources ou modification d'URLs de téléchargement).

L’équipe du PAN
L’équipe transport.data.gouv.fr
5 changes: 5 additions & 0 deletions apps/transport/lib/transport_web/views/email_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ defmodule TransportWeb.EmailView do
link(custom_title, to: url)
end

def link_for_dataset_discussions(%DB.Dataset{slug: slug}) do
url = TransportWeb.Router.Helpers.dataset_url(TransportWeb.Endpoint, :details, slug)
link("l’espace de discussion du jeu de données", to: url <> "#dataset-discussions")
end

def link_for_resource(%DB.Resource{id: id, title: title}) do
url = TransportWeb.Router.Helpers.resource_url(TransportWeb.Endpoint, :details, id)
link(title, to: url)
Expand Down
Loading

0 comments on commit f804e27

Please sign in to comment.