diff --git a/NAMESPACE b/NAMESPACE index 83be4f0..99c6b86 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,7 @@ # Generated by roxygen2: do not edit by hand export("%>%") +export(check_translation_csv) export(connect) export(generate_datasets) export(get_active_species) @@ -17,6 +18,7 @@ import(shiny) import(tmap) importFrom(DBI,dbConnect) importFrom(RPostgres,Postgres) +importFrom(dplyr,mutate_all) importFrom(golem,activate_js) importFrom(golem,add_resource_path) importFrom(golem,bundle_resources) diff --git a/R/app_ui.R b/R/app_ui.R index ca30d73..ed5265e 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -42,19 +42,19 @@ app_ui <- function(request) { menu = menu( menuItem( "d", "Sit", - i18n = "nav-sit" + i18n = "nav-catch" ), menuItem( "a", "Lorem", - i18n = "nav-lorem" + i18n = "nav-present" ), menuItem( "b", "Ipsum", - i18n = "nav-ipsum" + i18n = "nav-climate" ), menuItem( "c", "Dolor", - i18n = "nav-dolor" + i18n = "nav-future" ) ), content = tabItems( diff --git a/R/utils_csv_check.R b/R/utils_csv_check.R new file mode 100644 index 0000000..e394095 --- /dev/null +++ b/R/utils_csv_check.R @@ -0,0 +1,50 @@ +#' csv_check +#' +#' @description Check the CSV written by hand +#' +#' @param path path to file to check +#' @param source_encoding Encoding of the source file +#' @param new_path Where to save the modified file +#' @return The return value, if any, from executing the utility. +#' @importFrom dplyr mutate_all +#' @export +check_translation_csv <- function(path, source_encoding = "latin1", new_path = path) { + if (!file.exists(path)) { + stop("File doesn't exists") + } + if (tools::file_ext(path) != "csv") { + stop("path should be a csv file") + } + if (tools::file_ext(new_path) != "csv") { + stop("new_path should be a csv file") + } + fls <- read.csv(path, encoding = source_encoding) + if ( + names(fls)[1] != "entry" + ) { + stop("The first column should be named 'entry'") + } + if ( + !"en" %in% names(fls) + ) { + stop("Their is no 'en' column") + } + if ( + !"fr" %in% names(fls) + ) { + stop("Their is no 'fr' column") + } + if (source_encoding != "UTF-8") { + fls <- fls %>% mutate_all(enc2utf8) + write.csv(fls, file = new_path, + fileEncoding = "UTF-8", + # col.names = TRUE, + row.names = FALSE) + cli::cli_alert_success("CSV was re-encoded to UTF-8") + } else { + file.copy(path, new_path) + } + cli::cli_alert_success("CSV seems correct") + + return(fls) +} \ No newline at end of file diff --git a/dev/species_translation.R b/dev/species_translation.R deleted file mode 100644 index 88ea5d9..0000000 --- a/dev/species_translation.R +++ /dev/null @@ -1,65 +0,0 @@ -pkgload::load_all(export_all = FALSE, helpers = FALSE, attach_testthat = FALSE) -options("golem.app.prod" = FALSE) - -se <- new.env() -connect(se) - -species_list <- DBI::dbGetQuery( - get_con(se), - "SELECT *, diadesatlas.translate(english_name, 'fr') AS french_name from diadesatlas.species WHERE active=TRUE" -) - -species_list %>% - dplyr::select(entry = local_name, en = english_name, fr = french_name) %>% - readr::write_csv("inst/translation_species.csv") - -# IUCN - -# TODO : get the translation inside the DB -stats <- strsplit( - # https://uicn.fr/liste-rouge-mondiale/ - "Éteinte (EX), Éteinte à l’état sauvage (EW), En danger critique (CR), En danger (EN), Vulnérable (VU), Quasi menacée (NT), Préoccupation mineure (LC), Données insuffisantes (DD), Non évaluée (NE)", - split = ", " -)[[1]] - -french_iucn <- data.frame( - fr_vals = gsub( - "([^\\(]+) \\(([^\\(]+)\\)", - "\\1,\\2", - stats - ) -) %>% - tidyr::separate( - fr_vals, - into = c("french_name", "iucn_level_code"), sep = "," - ) - -session <- new.env() -connect(session) - -en_iucn <- DBI::dbGetQuery(get_con(session), "select distinct iucn_level_code,iucn_level_name AS english_name from v_iucn") - -en_iucn %>% - dplyr::full_join(french_iucn) %>% - dplyr::select(entry = iucn_level_code, en = english_name, fr = french_name) %>% - readr::write_csv("inst/translation_iucn.csv") - -# TODO écrire depuis la base - -DBI::dbGetQuery( - con, - "select * from abundance_level" -) %>% - select( - entry = abundance_level_name, - en = abundance_level_interpretation_short - ) %>% - mutate( - fr = c( - "Non enregistré sur la période", - "Présence occasionnelle", - "Populations fonctionnelles", - "Populations fonctionnelles abondante" - ) - ) %>% - readr::write_csv("inst/translation_abundance_level.csv") \ No newline at end of file diff --git a/dev/translation.Rmd b/dev/translation.Rmd new file mode 100644 index 0000000..40fee03 --- /dev/null +++ b/dev/translation.Rmd @@ -0,0 +1,146 @@ +--- +title: "Tab 1" +author: "Colin Fay" +date: "`r Sys.Date()`" +output: html_document +--- + +```{r} +pkgload::load_all(attach_testthat = FALSE) +se <- new.env() +connect(se) +library(dplyr) +``` + +## Comment est organisée la traduction + +### Pour le front-end + +Pour l'interface utilisateur, l'application met ensemble 4 fichiers CSV, contenus dans le dossier `inst/`. +Trois de ces fichiers sont automatiquement générés, un est à modifier à la main. + +Tous ces fichiers contiennent au moins 3 colonnes: + ++ `entry` : la clé d'entrée dans le front pour i18n ++ `en` : la traduction en anglais ++ `fr` : la traduction en français + +### Fichiers générés automatiquement + ++ `translation_abundance_level.csv` : contient les traductions pour les éléments de niveau d'abondance. +Se génère via le code suivant : + +```{r} +# TODO écrire depuis la base + +DBI::dbGetQuery( + get_con(se), + "select abundance_level_name AS entry, abundance_level_interpretation_short AS en from abundance_level" + # "select abundance_level_name AS entry, abundance_level_interpretation_short AS en, diadesatlas.translate(abundance_level_interpretation_short, 'fr') AS fr from abundance_level" +) %>% + # Cette traduction est temporaire, il FAUDRA utiliser la traduction depuis la base de données, + # via le code SQL commenté + mutate( + fr = c( + "Non enregistré sur la période", + "Présence occasionnelle", + "Populations fonctionnelles", + "Populations fonctionnelles abondante" + ) + ) %>% + readr::write_csv( + here::here("inst/translation_abundance_level.csv") + ) +``` + ++ `translation_iucn.csv` : contient les traductions pour status IUCN. +Se génère via le code suivant : + +```{r} +# TODO : get the translation inside the DB +# On utilise ici la description trouvée sur +# https://uicn.fr/liste-rouge-mondiale/ +desc <- strsplit( + "Éteinte (EX), Éteinte à l’état sauvage (EW), En danger critique (CR), En danger (EN), Vulnérable (VU), Quasi menacée (NT), Préoccupation mineure (LC), Données insuffisantes (DD), Non évaluée (NE)", + split = ", " +)[[1]] + +french_iucn <- data.frame( + fr_vals = gsub( + "([^\\(]+) \\(([^\\(]+)\\)", + "\\1,\\2", + desc + ) +) %>% + tidyr::separate( + fr_vals, + into = c("fr", "entry"), sep = "," + ) + +en_iucn <- DBI::dbGetQuery( + get_con(se), + "SELECT distinct iucn_level_code AS entry,iucn_level_name AS en FROM v_iucn" +) + +en_iucn %>% + dplyr::full_join(french_iucn) %>% + readr::write_csv("inst/translation_iucn.csv") +``` + ++ `translation_abundance_level.csv` : contient les traductions pour les éléments de niveau d'abondance. +Se génère via le code suivant : + +```{r} +DBI::dbGetQuery( + get_con(se), + "SELECT local_name AS entry, english_name AS en, diadesatlas.translate(english_name, 'fr') AS fr from diadesatlas.species WHERE active=TRUE" +) %>% + readr::write_csv("inst/translation_species.csv") +``` + +### Fichier à compléter à la main + ++ `inst/translation.csv` est le fichier à compléter à la main. +Il peut être ouvert avec Excel et __doit__ être sauvegardé en `.csv`. + +Vous devez vérifier l'intégrité du csv via et indiquer avec quel encodage vous avez créé le fichier : + +- `source_encoding = "UTF-8"` a priori, si créé sous Linux/MacOS +- `source_encoding = "latin1"` a priori, si créé sur Excel/LibreOffice avec Windows + +Ainsi, si vous rencontrez des problèmes d'encodage sur l'application, vous pouvez modifier de nouveau le csv et changer le paramètre ci-dessous. +Vous pouvez aussi le vérifier en regardant le fichier lu avec `output` ci-dessous. + +```{r} +output <- check_translation_csv("inst/translation.csv", source_encoding = "latin1") +head(output) +``` + +## Notes pour les dévelopeurs + +Comment créer un nouvel élément "traductible" dans l'UI? + ++ La traduction est assurée par le module JS `i18n` et la fonction `with_i18()` dans l'app + +```{r} +with_i18( + "Text de base", + "text_de_base" +) +``` + +Va créer `Text de base`. + ++ L'élément `Text de base` est affiché si `i18n` plante ++ L'élément `data-i18n="text_de_base"` correspond à la clé d'entrée dans le data.frame de traduction, i.e. la valeur dans la colonne entry. + +Schématiquement, lorsque le JavaScript va traduire la page, il va aller chercher pour chaque tag l'entrée `data-i18n`, en tirer la valeur, et aller chercher la traduction correspondante. + +Par exemple, si nous traduisons en "fr", la localisation fait (en JavaScript) l'action suivante + +```{r eval = FALSE} +df_traduction %>% + filter(entry == "text_de_base") %>% + pull(fr) +``` + diff --git a/inst/reprex/trad_latin1.csv b/inst/reprex/trad_latin1.csv new file mode 100644 index 0000000..7de257a --- /dev/null +++ b/inst/reprex/trad_latin1.csv @@ -0,0 +1,2 @@ +entry,en,fr +toto,tùtù,tàtà diff --git a/inst/reprex/trad_utf8.csv b/inst/reprex/trad_utf8.csv new file mode 100644 index 0000000..c9a94c3 --- /dev/null +++ b/inst/reprex/trad_utf8.csv @@ -0,0 +1,2 @@ +entry,en,fr +toto,tùtù,tàtà diff --git a/inst/translation.csv b/inst/translation.csv index 6e3e7e6..19e00e6 100644 --- a/inst/translation.csv +++ b/inst/translation.csv @@ -3,10 +3,10 @@ title-first,Situation in Present Time,Situation Présente title-second,Diadromous species distribution and climate change,Deuxième title-third,Diadromous species distribution and climate change,Troisieme title-fourth,Situation in Present Time,Quatrieme -nav-lorem,Present,Situation Présente -nav-ipsum,Climate Change,Changement climatique -nav-dolor,Future,Futur -nav-sit,Catch and ByCatch,Catch et ByCatch +nav-present,Present,Situation Présente +nav-climate,Climate Change,Changement climatique +nav-future,Future,Futur +nav-catch,Catch and ByCatch,Catch et ByCatch h3-case-studies,Case Studies,Étude de cas h3-species,Species,Espèces h3-ecosystem,Ecosystem services listing,Liste des services écosystémiques diff --git a/man/check_translation_csv.Rd b/man/check_translation_csv.Rd new file mode 100644 index 0000000..5ee51d2 --- /dev/null +++ b/man/check_translation_csv.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils_csv_check.R +\name{check_translation_csv} +\alias{check_translation_csv} +\title{csv_check} +\usage{ +check_translation_csv(path, source_encoding = "latin1", new_path = path) +} +\arguments{ +\item{path}{path to file to check} + +\item{source_encoding}{Encoding of the source file} + +\item{new_path}{Where to save the modified file} +} +\value{ +The return value, if any, from executing the utility. +} +\description{ +Check the CSV written by hand +} diff --git a/tests/testthat/test-check_translation_csv.R b/tests/testthat/test-check_translation_csv.R new file mode 100644 index 0000000..d474680 --- /dev/null +++ b/tests/testthat/test-check_translation_csv.R @@ -0,0 +1,42 @@ +trad_latin <- system.file("reprex", "trad_latin1.csv", package = "diades.atlas") + +new_output_test <- tempfile(fileext = ".csv") + +test_that("check_translation_csv works with encoding Latin1", { + output <- check_translation_csv( + path = trad_latin, + source_encoding = "latin1", new_path = new_output_test) + expect_equal(names(output), c("entry", "en", "fr")) + expect_equal(as.character(output[1,]), c("toto", "t\u00f9t\u00f9", "t\u00e0t\u00e0")) + expect_equal( + readLines(new_output_test)[1], + c("\"entry\",\"en\",\"fr\"") + ) + + # Read re-encoded one: new_output_test + output <- check_translation_csv( + path = new_output_test, + source_encoding = "UTF-8", new_path = new_output_test) + expect_equal(names(output), c("entry", "en", "fr")) + expect_equal(as.character(output[1,]), c("toto", "t\u00f9t\u00f9", "t\u00e0t\u00e0")) + expect_equal( + readLines(new_output_test)[1], + c("\"entry\",\"en\",\"fr\"") # Copied with write.csv + ) +}) + +# with uf8 ---- +trad_utf8 <- system.file("reprex", "trad_utf8.csv", package = "diades.atlas") +new_output_test <- tempfile(fileext = ".csv") + +test_that("check_translation_csv works with encoding UTF8 directly", { + output <- check_translation_csv( + path = trad_utf8, + source_encoding = "UTF-8", new_path = new_output_test) + expect_equal(names(output), c("entry", "en", "fr")) + expect_equal(as.character(output[1,]), c("toto", "t\u00f9t\u00f9", "t\u00e0t\u00e0")) + expect_equal( + readLines(new_output_test)[1], + c("entry,en,fr") # Copied as is + ) +}) \ No newline at end of file