Split translation file in multiple files: one per language
This commit is contained in:
parent
ec36391ec8
commit
6010c8600f
6 changed files with 339 additions and 331 deletions
|
|
@ -9,7 +9,7 @@ pub const FILE_CONF: &str = "conf.ron";
|
||||||
|
|
||||||
/// The name of the translation file.
|
/// The name of the translation file.
|
||||||
/// it's located in the current directory.
|
/// it's located in the current directory.
|
||||||
pub const TRANSLATION_FILE: &str = "translation.ron";
|
pub const TRANSLATION_DIR: &str = "translations";
|
||||||
|
|
||||||
/// Filename of the database.
|
/// Filename of the database.
|
||||||
/// It's located in the `DB_DIRECTORY` directory.
|
/// It's located in the `DB_DIRECTORY` directory.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{borrow::Borrow, fs::File, sync::LazyLock};
|
use std::{borrow::Borrow, fs::File, path::Path, sync::LazyLock};
|
||||||
|
|
||||||
use chrono::Weekday;
|
use chrono::Weekday;
|
||||||
pub use common::translation::Sentence;
|
pub use common::translation::Sentence;
|
||||||
|
|
@ -6,7 +6,7 @@ use common::utils;
|
||||||
use ron::de::from_reader;
|
use ron::de::from_reader;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use strum::EnumCount;
|
use strum::EnumCount;
|
||||||
use tracing::warn;
|
use tracing::{error, warn};
|
||||||
|
|
||||||
use crate::consts;
|
use crate::consts;
|
||||||
|
|
||||||
|
|
@ -215,28 +215,38 @@ fn get_language_translation(code: &str) -> &'static Language {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Lazy load all translation files.
|
||||||
static TRANSLATIONS: LazyLock<Vec<Language>> =
|
static TRANSLATIONS: LazyLock<Vec<Language>> =
|
||||||
LazyLock::new(|| match File::open(consts::TRANSLATION_FILE) {
|
LazyLock::new(|| match Path::new(consts::TRANSLATION_DIR).read_dir() {
|
||||||
Ok(file) => {
|
Ok(entries) => entries
|
||||||
let stored_languages: Vec<StoredLanguage> = from_reader(file).unwrap_or_else(|error| {
|
.filter_map(|entry| {
|
||||||
{
|
match entry {
|
||||||
panic!(
|
Ok(entry) => match File::open(entry.path()) {
|
||||||
"Failed to read translation file {}: {}",
|
Ok(file) => match from_reader(file) {
|
||||||
consts::TRANSLATION_FILE,
|
Ok(language) => return Some(Language::from_stored_language(language)),
|
||||||
error
|
Err(error) => {
|
||||||
)
|
error!(
|
||||||
|
"Error when reading translation file {}: {}",
|
||||||
|
entry.path().to_str().unwrap_or_default(),
|
||||||
|
error
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(error) => {
|
||||||
|
error!("Unable to read translation file: {}", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(error) => error!("Unable to read translation entry: {}", error),
|
||||||
}
|
}
|
||||||
});
|
None
|
||||||
stored_languages
|
})
|
||||||
.into_iter()
|
.collect(),
|
||||||
.map(Language::from_stored_language)
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!(
|
error!(
|
||||||
"Failed to open translation file {}: {}",
|
"Unable to read translations directory {}: {}",
|
||||||
consts::TRANSLATION_FILE,
|
consts::TRANSLATION_DIR,
|
||||||
error
|
error
|
||||||
)
|
);
|
||||||
|
vec![]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,308 +0,0 @@
|
||||||
[
|
|
||||||
(
|
|
||||||
code: "en",
|
|
||||||
territory: "US",
|
|
||||||
name: "English",
|
|
||||||
translation: [
|
|
||||||
(MainTitle, "Cooking Recipes"),
|
|
||||||
(CreateNewRecipe, "Create a new recipe"),
|
|
||||||
(PrivateRecipes, "Private recipes"),
|
|
||||||
(UntitledRecipe, "Untitled recipe"),
|
|
||||||
|
|
||||||
(Name, "Name"),
|
|
||||||
(EmailAddress, "Email address"),
|
|
||||||
(Password, "Password"),
|
|
||||||
|
|
||||||
(SignOut, "Sign out"),
|
|
||||||
(Save, "Save"),
|
|
||||||
(NotLoggedIn, "No logged in"),
|
|
||||||
|
|
||||||
(ActionNotAuthorized, "Action not authorized"),
|
|
||||||
|
|
||||||
(DatabaseError, "Database error"),
|
|
||||||
(TemplateError, "Template error"),
|
|
||||||
|
|
||||||
(SignInMenu, "Sign in"),
|
|
||||||
(SignInTitle, "Sign in"),
|
|
||||||
(SignInButton, "Sign in"),
|
|
||||||
(SignInSuccess, "Sign in successful"),
|
|
||||||
(WrongEmailOrPassword, "Wrong email or password"),
|
|
||||||
|
|
||||||
(AccountMustBeValidatedFirst, "This account must be validated first"),
|
|
||||||
(InvalidEmail, "Invalid email"),
|
|
||||||
(PasswordDontMatch, "Passwords don't match"),
|
|
||||||
(InvalidPassword, "Password must have at least {} characters"),
|
|
||||||
(EmailAlreadyTaken, "This email is not available"),
|
|
||||||
(UnableToSendEmail, "Unable to send the validation email"),
|
|
||||||
|
|
||||||
(ValidationSuccessful, "Email validation successful"),
|
|
||||||
(ValidationExpired, "The validation has expired. Try to sign up again with the same email"),
|
|
||||||
(ValidationErrorTryToSignUpAgain, "Validation error. Try to sign up again with the same email"),
|
|
||||||
(ValidationError, "Validation error"),
|
|
||||||
(ValidationUserAlreadyExists, "User already exists"),
|
|
||||||
|
|
||||||
(SignUpMenu, "Sign up"),
|
|
||||||
(SignUpTitle, "Sign up"),
|
|
||||||
(SignUpButton, "Sign up"),
|
|
||||||
(SignUpEmailSent, "An email has been sent, follow the link to validate your account"),
|
|
||||||
(SignUpEmailTitle, "Cooking Recipes: Account validation"),
|
|
||||||
(SignUpFollowEmailLink, "Follow this link to confirm your inscription, {}"),
|
|
||||||
(SignUpEmailValidationSuccess, "Email validation successful, your account has been created"),
|
|
||||||
(SignUpValidationExpired, "The validation has expired. Try to sign up again"),
|
|
||||||
(SignUpValidationErrorTryAgain, "Validation error. Try to sign up again"),
|
|
||||||
(SignUpClosed, "New registration are closed"),
|
|
||||||
(ChooseAPassword, "Choose a password (minimum {} characters)"),
|
|
||||||
(ReEnterPassword, "Re-enter password"),
|
|
||||||
|
|
||||||
(LostPassword, "Lost password"),
|
|
||||||
(AskResetChooseNewPassword, "Choose a new password (minimum {} characters)"),
|
|
||||||
(AskResetButton, "Ask reset"),
|
|
||||||
(AskResetAlreadyLoggedInError, "Can't ask to reset password when already logged in"),
|
|
||||||
(AskResetEmailAlreadyResetError, "The password has already been reset for this email"),
|
|
||||||
(AskResetEmailTitle, "Cooking Recipes: Reset password"),
|
|
||||||
(AskResetFollowEmailLink, "Follow this link to reset your password, {}"),
|
|
||||||
(AskResetEmailSent, "An email has been sent, follow the link to reset your password"),
|
|
||||||
(AskResetTokenMissing, "Reset token missing"),
|
|
||||||
(AskResetTokenExpired, "Token expired, try to reset password again"),
|
|
||||||
(PasswordReset, "Your password has been reset"),
|
|
||||||
(EmailUnknown, "Email unknown"),
|
|
||||||
(UnableToSendResetEmail, "Unable to send the reset password email"),
|
|
||||||
|
|
||||||
(ProfileTitle, "Profile"),
|
|
||||||
(ProfileEmail, "Email (need to be revalidated if changed)"),
|
|
||||||
(ProfileDefaultServings, "Default servings"),
|
|
||||||
(ProfileFirstDayOfWeek, "First day of the week"),
|
|
||||||
(ProfileNewPassword, "New password (minimum {} characters)"),
|
|
||||||
(ProfileFollowEmailTitle, "Cooking Recipes: Email validation"),
|
|
||||||
(ProfileFollowEmailLink, "Follow this link to validate this email address, {}"),
|
|
||||||
(ProfileEmailSent, "An email has been sent, follow the link to validate your new email"),
|
|
||||||
(ProfileSaved, "Profile saved"),
|
|
||||||
|
|
||||||
(RecipeNotAllowedToEdit, "Not allowed to edit this recipe"),
|
|
||||||
(RecipeNotAllowedToView, "Not allowed the view the recipe {}"),
|
|
||||||
(RecipeNotFound, "Recipe not found"),
|
|
||||||
(RecipeTitle, "Title"),
|
|
||||||
(RecipeDescription, "Description"),
|
|
||||||
(RecipeServings, "Servings"),
|
|
||||||
(RecipeEstimatedTime, "Estimated time [min]"),
|
|
||||||
(RecipeDifficulty, "Difficulty"),
|
|
||||||
(RecipeDifficultyEasy, "Easy"),
|
|
||||||
(RecipeDifficultyMedium, "Medium"),
|
|
||||||
(RecipeDifficultyHard, "Hard"),
|
|
||||||
(RecipeTags, "Tags"),
|
|
||||||
(RecipeLanguage, "Language"),
|
|
||||||
(RecipeIsPublic, "Is public"),
|
|
||||||
(RecipeDelete, "Delete recipe"),
|
|
||||||
(RecipeAddAGroup, "Add a group"),
|
|
||||||
(RecipeRemoveGroup, "Remove group"),
|
|
||||||
(RecipeGroupName, "Name"),
|
|
||||||
(RecipeGroupComment, "Comment"),
|
|
||||||
(RecipeAddAStep, "Add a step"),
|
|
||||||
(RecipeRemoveStep, "Remove step"),
|
|
||||||
(RecipeStepAction, "Action"),
|
|
||||||
(RecipeAddAnIngredient, "Add an ingredient"),
|
|
||||||
(RecipeRemoveIngredient, "Remove ingredient"),
|
|
||||||
(RecipeIngredientName, "Name"),
|
|
||||||
(RecipeIngredientQuantity, "Quantity"),
|
|
||||||
(RecipeIngredientUnit, "Unit"),
|
|
||||||
(RecipeIngredientComment, "Comment"),
|
|
||||||
(RecipeDeleteConfirmation, "Are you sure to delete the recipe: '{}'?"),
|
|
||||||
(RecipeSuccessfullyDeleted, "Recipe successfully deleted"),
|
|
||||||
(RecipeGroupDeleteConfirmation, "Are you sure to delete the group: '{}'?"),
|
|
||||||
(RecipeStepDeleteConfirmation, "Are you sure to delete the step: '{}'?"),
|
|
||||||
(RecipeIngredientDeleteConfirmation, "Are you sure to delete the ingredient: '{}'?"),
|
|
||||||
|
|
||||||
(RecipeOneServing, "1 serving"),
|
|
||||||
(RecipeSomeServings, "{} servings"),
|
|
||||||
(RecipeEstimatedTimeMinAbbreviation, "min"),
|
|
||||||
|
|
||||||
(CalendarMonday, "Monday"),
|
|
||||||
(CalendarTuesday, "Tuesday"),
|
|
||||||
(CalendarWednesday, "Wednesday"),
|
|
||||||
(CalendarThursday, "Thursday"),
|
|
||||||
(CalendarFriday, "Friday"),
|
|
||||||
(CalendarSaturday, "Saturday"),
|
|
||||||
(CalendarSunday, "Sunday"),
|
|
||||||
(CalendarMondayAbbreviation, "Mon"),
|
|
||||||
(CalendarTuesdayAbbreviation, "Tue"),
|
|
||||||
(CalendarWednesdayAbbreviation, "Wed"),
|
|
||||||
(CalendarThursdayAbbreviation, "Thu"),
|
|
||||||
(CalendarFridayAbbreviation, "Fri"),
|
|
||||||
(CalendarSaturdayAbbreviation, "Sat"),
|
|
||||||
(CalendarSundayAbbreviation, "Sun"),
|
|
||||||
(CalendarJanuary, "January"),
|
|
||||||
(CalendarFebruary, "February"),
|
|
||||||
(CalendarMarch, "March"),
|
|
||||||
(CalendarApril, "April"),
|
|
||||||
(CalendarMay, "May"),
|
|
||||||
(CalendarJune, "June"),
|
|
||||||
(CalendarJuly, "July"),
|
|
||||||
(CalendarAugust, "August"),
|
|
||||||
(CalendarSeptember, "September"),
|
|
||||||
(CalendarOctober, "October"),
|
|
||||||
(CalendarNovember, "November"),
|
|
||||||
(CalendarDecember, "December"),
|
|
||||||
(CalendarAddToPlanner, "Add to planner"),
|
|
||||||
(CalendarAddToPlannerSuccess, "Recipe {title} has been scheduled for {date}"),
|
|
||||||
(CalendarAddToPlannerAlreadyExists, "Recipe {title} has already been scheduled for {date}"),
|
|
||||||
(CalendarDateFormat, "%A, %-d %B, %C%y"), // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
|
||||||
(CalendarAddIngredientsToShoppingList, "Add ingredients to shopping list"),
|
|
||||||
(CalendarRemoveIngredientsFromShoppingList, "Remove ingredients from shopping list"),
|
|
||||||
(CalendarUnschedule, "Remove"),
|
|
||||||
(CalendarUnscheduleConfirmation, "Are you sure to remove {title} on {date}"),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
(
|
|
||||||
code: "fr",
|
|
||||||
territory: "FR",
|
|
||||||
name: "Français",
|
|
||||||
translation: [
|
|
||||||
(MainTitle, "Recettes de Cuisine"),
|
|
||||||
(CreateNewRecipe, "Créer une nouvelle recette"),
|
|
||||||
(PrivateRecipes, "Recettes privées"),
|
|
||||||
(UntitledRecipe, "Recette sans nom"),
|
|
||||||
|
|
||||||
(Name, "Nom"),
|
|
||||||
(EmailAddress, "Adresse email"),
|
|
||||||
(Password, "Mot de passe"),
|
|
||||||
|
|
||||||
(SignOut, "Se déconnecter"),
|
|
||||||
(Save, "Sauvegarder"),
|
|
||||||
(NotLoggedIn, "Pas connecté"),
|
|
||||||
|
|
||||||
(ActionNotAuthorized, "Action non autorisée"),
|
|
||||||
|
|
||||||
(DatabaseError, "Erreur de la base de données (Database error)"),
|
|
||||||
(TemplateError, "Erreur du moteur de modèles (Template error)"),
|
|
||||||
|
|
||||||
(SignInMenu, "Se connecter"),
|
|
||||||
(SignInTitle, "Se connecter"),
|
|
||||||
(SignInButton, "Se connecter"),
|
|
||||||
(SignInSuccess, "Connexion réussie"),
|
|
||||||
(WrongEmailOrPassword, "Mot de passe ou email invalide"),
|
|
||||||
|
|
||||||
(AccountMustBeValidatedFirst, "Ce compte doit d'abord être validé"),
|
|
||||||
(InvalidEmail, "Adresse email invalide"),
|
|
||||||
(PasswordDontMatch, "Les mots de passe ne correspondent pas"),
|
|
||||||
(InvalidPassword, "Le mot de passe doit avoir au moins {} caractères"),
|
|
||||||
(EmailAlreadyTaken, "Cette adresse email n'est pas disponible"),
|
|
||||||
(UnableToSendEmail, "L'email de validation n'a pas pu être envoyé"),
|
|
||||||
|
|
||||||
(ValidationSuccessful, "Email validé avec succès"),
|
|
||||||
(ValidationExpired, "La validation a expiré. Essayez de vous inscrire à nouveau avec la même adresse email"),
|
|
||||||
(ValidationErrorTryToSignUpAgain, "Erreur de validation. Essayez de vous inscrire à nouveau avec la même adresse email"),
|
|
||||||
(ValidationError, "Erreur de validation"),
|
|
||||||
(ValidationUserAlreadyExists, "Utilisateur déjà existant"),
|
|
||||||
|
|
||||||
(SignUpMenu, "S'inscrire"),
|
|
||||||
(SignUpTitle, "Inscription"),
|
|
||||||
(SignUpButton, "Valider"),
|
|
||||||
(SignUpEmailSent, "Un email a été envoyé, suivez le lien pour valider votre compte"),
|
|
||||||
(SignUpEmailTitle, "Recettes de Cuisine: Validation du compte"),
|
|
||||||
(SignUpFollowEmailLink, "Suivez ce lien pour valider votre inscription, {}"),
|
|
||||||
(SignUpEmailValidationSuccess, "La validation de votre email s'est déroulée avec succès, votre compte a été créé"),
|
|
||||||
(SignUpValidationExpired, "La validation a expiré. Essayez de vous inscrire à nouveau"),
|
|
||||||
(SignUpValidationErrorTryAgain, "Erreur de validation. Essayez de vous inscrire à nouveau"),
|
|
||||||
(SignUpClosed, "Les inscriptions sont actuellement fermées"),
|
|
||||||
(ChooseAPassword, "Choisir un mot de passe (minimum {} caractères)"),
|
|
||||||
(ReEnterPassword, "Entrez à nouveau le mot de passe"),
|
|
||||||
|
|
||||||
(LostPassword, "Mot de passe perdu"),
|
|
||||||
(AskResetChooseNewPassword, "Choisir un nouveau mot de passe (minimum {} caractères)"),
|
|
||||||
(AskResetButton, "Demander la réinitialisation"),
|
|
||||||
(AskResetAlreadyLoggedInError, "Impossible de demander une réinitialisation du mot de passe lorsque déjà connecté"),
|
|
||||||
(AskResetEmailAlreadyResetError, "Le mot de passe a déjà été réinitialisé pour cette adresse email"),
|
|
||||||
(AskResetEmailTitle, "Recettes de Cuisine: Réinitialisation du mot de passe"),
|
|
||||||
(AskResetFollowEmailLink, "Suivez ce lien pour réinitialiser votre mot de passe, {}"),
|
|
||||||
(AskResetEmailSent, "Un email a été envoyé, suivez le lien pour réinitialiser votre mot de passe"),
|
|
||||||
(AskResetTokenMissing, "Jeton de réinitialisation manquant"),
|
|
||||||
(AskResetTokenExpired, "Jeton expiré, essayez de réinitialiser votre mot de passe à nouveau"),
|
|
||||||
(PasswordReset, "Votre mot de passe a été réinitialisé"),
|
|
||||||
(EmailUnknown, "Email inconnu"),
|
|
||||||
(UnableToSendResetEmail, "Impossible d'envoyer l'email pour la réinitialisation du mot de passe"),
|
|
||||||
|
|
||||||
(ProfileTitle, "Profile"),
|
|
||||||
(ProfileEmail, "Email (doit être revalidé si changé)"),
|
|
||||||
(ProfileDefaultServings, "Nombre de portions par défaut"),
|
|
||||||
(ProfileFirstDayOfWeek, "Premier jour de la semaine"),
|
|
||||||
(ProfileNewPassword, "Nouveau mot de passe (minimum {} caractères)"),
|
|
||||||
(ProfileFollowEmailTitle, "Recettes de Cuisine: Validation de l'adresse email"),
|
|
||||||
(ProfileFollowEmailLink, "Suivez ce lien pour valider l'adresse email, {}"),
|
|
||||||
(ProfileEmailSent, "Un email a été envoyé, suivez le lien pour valider la nouvelle adresse email"),
|
|
||||||
(ProfileSaved, "Profile sauvegardé"),
|
|
||||||
|
|
||||||
(RecipeNotAllowedToEdit, "Vous n'êtes pas autorisé à éditer cette recette"),
|
|
||||||
(RecipeNotAllowedToView, "Vous n'êtes pas autorisé à voir la recette {}"),
|
|
||||||
(RecipeNotFound, "Recette non-trouvée"),
|
|
||||||
(RecipeTitle, "Titre"),
|
|
||||||
(RecipeDescription, "Description"),
|
|
||||||
(RecipeServings, "Nombre de portions"),
|
|
||||||
(RecipeEstimatedTime, "Temps estimé"),
|
|
||||||
(RecipeDifficulty, "Difficulté"),
|
|
||||||
(RecipeDifficultyEasy, "Facile"),
|
|
||||||
(RecipeDifficultyMedium, "Moyen"),
|
|
||||||
(RecipeDifficultyHard, "Difficile"),
|
|
||||||
(RecipeTags, "Tags"),
|
|
||||||
(RecipeLanguage, "Langue"),
|
|
||||||
(RecipeIsPublic, "Est public"),
|
|
||||||
(RecipeDelete, "Supprimer la recette"),
|
|
||||||
(RecipeAddAGroup, "Ajouter un groupe"),
|
|
||||||
(RecipeRemoveGroup, "Supprimer le groupe"),
|
|
||||||
(RecipeGroupName, "Nom"),
|
|
||||||
(RecipeGroupComment, "Commentaire"),
|
|
||||||
(RecipeAddAStep, "Ajouter une étape"),
|
|
||||||
(RecipeRemoveStep, "Supprimer l'étape"),
|
|
||||||
(RecipeStepAction, "Action"),
|
|
||||||
(RecipeAddAnIngredient, "Ajouter un ingrédient"),
|
|
||||||
(RecipeRemoveIngredient, "Supprimer l'ingrédient"),
|
|
||||||
(RecipeIngredientName, "Nom"),
|
|
||||||
(RecipeIngredientQuantity, "Quantité"),
|
|
||||||
(RecipeIngredientUnit, "Unité"),
|
|
||||||
(RecipeIngredientComment, "Commentaire"),
|
|
||||||
(RecipeDeleteConfirmation, "Êtes-vous sûr de vouloir supprimer la recette : '{}' ?"),
|
|
||||||
(RecipeSuccessfullyDeleted, "Recette supprimée avec succès"),
|
|
||||||
(RecipeGroupDeleteConfirmation, "Êtes-vous sûr de vouloir supprimer le groupe : '{}' ?"),
|
|
||||||
(RecipeStepDeleteConfirmation, "Êtes-vous sûr de vouloir supprimer l'étape : '{}' ?"),
|
|
||||||
(RecipeIngredientDeleteConfirmation, "Êtes-vous sûr de vouloir supprimer 'ingrédient : '{}' ?"),
|
|
||||||
|
|
||||||
(RecipeOneServing, "pour 1 personne"),
|
|
||||||
(RecipeSomeServings, "pour {} personnes"),
|
|
||||||
(RecipeEstimatedTimeMinAbbreviation, "min"),
|
|
||||||
|
|
||||||
(CalendarMonday, "lundi"),
|
|
||||||
(CalendarTuesday, "mardi"),
|
|
||||||
(CalendarWednesday, "mercredi"),
|
|
||||||
(CalendarThursday, "jeudi"),
|
|
||||||
(CalendarFriday, "vendredi"),
|
|
||||||
(CalendarSaturday, "samedi"),
|
|
||||||
(CalendarSunday, "dimanche"),
|
|
||||||
(CalendarMondayAbbreviation, "Lun"),
|
|
||||||
(CalendarTuesdayAbbreviation, "Mar"),
|
|
||||||
(CalendarWednesdayAbbreviation, "Mer"),
|
|
||||||
(CalendarThursdayAbbreviation, "Jeu"),
|
|
||||||
(CalendarFridayAbbreviation, "Ven"),
|
|
||||||
(CalendarSaturdayAbbreviation, "Sam"),
|
|
||||||
(CalendarSundayAbbreviation, "Dim"),
|
|
||||||
(CalendarJanuary, "janvier"),
|
|
||||||
(CalendarFebruary, "février"),
|
|
||||||
(CalendarMarch, "mars"),
|
|
||||||
(CalendarApril, "avril"),
|
|
||||||
(CalendarMay, "mai"),
|
|
||||||
(CalendarJune, "juin"),
|
|
||||||
(CalendarJuly, "juillet"),
|
|
||||||
(CalendarAugust, "août"),
|
|
||||||
(CalendarSeptember, "septembre"),
|
|
||||||
(CalendarOctober, "octobre"),
|
|
||||||
(CalendarNovember, "novembre"),
|
|
||||||
(CalendarDecember, "décembre"),
|
|
||||||
(CalendarAddToPlanner, "Ajouter au planificateur"),
|
|
||||||
(CalendarAddToPlannerSuccess, "La recette {title} a été agendée pour le {date}"),
|
|
||||||
(CalendarAddToPlannerAlreadyExists, "La recette {title} a été déjà été agendée pour le {date}"),
|
|
||||||
(CalendarDateFormat, "%A %-d %B %C%y"), // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
|
||||||
(CalendarAddIngredientsToShoppingList, "Ajouter les ingrédients à la liste de course"),
|
|
||||||
(CalendarRemoveIngredientsFromShoppingList, "Enlever les ingrédients de la liste de course"),
|
|
||||||
(CalendarUnschedule, "Enlever"),
|
|
||||||
(CalendarUnscheduleConfirmation, "Êtes-vous sûr de vouloir enlever {title} du {date}"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
153
backend/translations/english.ron
Normal file
153
backend/translations/english.ron
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
(
|
||||||
|
code: "en",
|
||||||
|
territory: "US",
|
||||||
|
name: "English",
|
||||||
|
translation: [
|
||||||
|
(MainTitle, "Cooking Recipes"),
|
||||||
|
(CreateNewRecipe, "Create a new recipe"),
|
||||||
|
(PrivateRecipes, "Private recipes"),
|
||||||
|
(UntitledRecipe, "Untitled recipe"),
|
||||||
|
|
||||||
|
(Name, "Name"),
|
||||||
|
(EmailAddress, "Email address"),
|
||||||
|
(Password, "Password"),
|
||||||
|
|
||||||
|
(SignOut, "Sign out"),
|
||||||
|
(Save, "Save"),
|
||||||
|
(NotLoggedIn, "No logged in"),
|
||||||
|
|
||||||
|
(ActionNotAuthorized, "Action not authorized"),
|
||||||
|
|
||||||
|
(DatabaseError, "Database error"),
|
||||||
|
(TemplateError, "Template error"),
|
||||||
|
|
||||||
|
(SignInMenu, "Sign in"),
|
||||||
|
(SignInTitle, "Sign in"),
|
||||||
|
(SignInButton, "Sign in"),
|
||||||
|
(SignInSuccess, "Sign in successful"),
|
||||||
|
(WrongEmailOrPassword, "Wrong email or password"),
|
||||||
|
|
||||||
|
(AccountMustBeValidatedFirst, "This account must be validated first"),
|
||||||
|
(InvalidEmail, "Invalid email"),
|
||||||
|
(PasswordDontMatch, "Passwords don't match"),
|
||||||
|
(InvalidPassword, "Password must have at least {} characters"),
|
||||||
|
(EmailAlreadyTaken, "This email is not available"),
|
||||||
|
(UnableToSendEmail, "Unable to send the validation email"),
|
||||||
|
|
||||||
|
(ValidationSuccessful, "Email validation successful"),
|
||||||
|
(ValidationExpired, "The validation has expired. Try to sign up again with the same email"),
|
||||||
|
(ValidationErrorTryToSignUpAgain, "Validation error. Try to sign up again with the same email"),
|
||||||
|
(ValidationError, "Validation error"),
|
||||||
|
(ValidationUserAlreadyExists, "User already exists"),
|
||||||
|
|
||||||
|
(SignUpMenu, "Sign up"),
|
||||||
|
(SignUpTitle, "Sign up"),
|
||||||
|
(SignUpButton, "Sign up"),
|
||||||
|
(SignUpEmailSent, "An email has been sent, follow the link to validate your account"),
|
||||||
|
(SignUpEmailTitle, "Cooking Recipes: Account validation"),
|
||||||
|
(SignUpFollowEmailLink, "Follow this link to confirm your inscription, {}"),
|
||||||
|
(SignUpEmailValidationSuccess, "Email validation successful, your account has been created"),
|
||||||
|
(SignUpValidationExpired, "The validation has expired. Try to sign up again"),
|
||||||
|
(SignUpValidationErrorTryAgain, "Validation error. Try to sign up again"),
|
||||||
|
(SignUpClosed, "New registration are closed"),
|
||||||
|
(ChooseAPassword, "Choose a password (minimum {} characters)"),
|
||||||
|
(ReEnterPassword, "Re-enter password"),
|
||||||
|
|
||||||
|
(LostPassword, "Lost password"),
|
||||||
|
(AskResetChooseNewPassword, "Choose a new password (minimum {} characters)"),
|
||||||
|
(AskResetButton, "Ask reset"),
|
||||||
|
(AskResetAlreadyLoggedInError, "Can't ask to reset password when already logged in"),
|
||||||
|
(AskResetEmailAlreadyResetError, "The password has already been reset for this email"),
|
||||||
|
(AskResetEmailTitle, "Cooking Recipes: Reset password"),
|
||||||
|
(AskResetFollowEmailLink, "Follow this link to reset your password, {}"),
|
||||||
|
(AskResetEmailSent, "An email has been sent, follow the link to reset your password"),
|
||||||
|
(AskResetTokenMissing, "Reset token missing"),
|
||||||
|
(AskResetTokenExpired, "Token expired, try to reset password again"),
|
||||||
|
(PasswordReset, "Your password has been reset"),
|
||||||
|
(EmailUnknown, "Email unknown"),
|
||||||
|
(UnableToSendResetEmail, "Unable to send the reset password email"),
|
||||||
|
|
||||||
|
(ProfileTitle, "Profile"),
|
||||||
|
(ProfileEmail, "Email (need to be revalidated if changed)"),
|
||||||
|
(ProfileDefaultServings, "Default servings"),
|
||||||
|
(ProfileFirstDayOfWeek, "First day of the week"),
|
||||||
|
(ProfileNewPassword, "New password (minimum {} characters)"),
|
||||||
|
(ProfileFollowEmailTitle, "Cooking Recipes: Email validation"),
|
||||||
|
(ProfileFollowEmailLink, "Follow this link to validate this email address, {}"),
|
||||||
|
(ProfileEmailSent, "An email has been sent, follow the link to validate your new email"),
|
||||||
|
(ProfileSaved, "Profile saved"),
|
||||||
|
|
||||||
|
(RecipeNotAllowedToEdit, "Not allowed to edit this recipe"),
|
||||||
|
(RecipeNotAllowedToView, "Not allowed the view the recipe {}"),
|
||||||
|
(RecipeNotFound, "Recipe not found"),
|
||||||
|
(RecipeTitle, "Title"),
|
||||||
|
(RecipeDescription, "Description"),
|
||||||
|
(RecipeServings, "Servings"),
|
||||||
|
(RecipeEstimatedTime, "Estimated time [min]"),
|
||||||
|
(RecipeDifficulty, "Difficulty"),
|
||||||
|
(RecipeDifficultyEasy, "Easy"),
|
||||||
|
(RecipeDifficultyMedium, "Medium"),
|
||||||
|
(RecipeDifficultyHard, "Hard"),
|
||||||
|
(RecipeTags, "Tags"),
|
||||||
|
(RecipeLanguage, "Language"),
|
||||||
|
(RecipeIsPublic, "Is public"),
|
||||||
|
(RecipeDelete, "Delete recipe"),
|
||||||
|
(RecipeAddAGroup, "Add a group"),
|
||||||
|
(RecipeRemoveGroup, "Remove group"),
|
||||||
|
(RecipeGroupName, "Name"),
|
||||||
|
(RecipeGroupComment, "Comment"),
|
||||||
|
(RecipeAddAStep, "Add a step"),
|
||||||
|
(RecipeRemoveStep, "Remove step"),
|
||||||
|
(RecipeStepAction, "Action"),
|
||||||
|
(RecipeAddAnIngredient, "Add an ingredient"),
|
||||||
|
(RecipeRemoveIngredient, "Remove ingredient"),
|
||||||
|
(RecipeIngredientName, "Name"),
|
||||||
|
(RecipeIngredientQuantity, "Quantity"),
|
||||||
|
(RecipeIngredientUnit, "Unit"),
|
||||||
|
(RecipeIngredientComment, "Comment"),
|
||||||
|
(RecipeDeleteConfirmation, "Are you sure to delete the recipe: '{}'?"),
|
||||||
|
(RecipeSuccessfullyDeleted, "Recipe successfully deleted"),
|
||||||
|
(RecipeGroupDeleteConfirmation, "Are you sure to delete the group: '{}'?"),
|
||||||
|
(RecipeStepDeleteConfirmation, "Are you sure to delete the step: '{}'?"),
|
||||||
|
(RecipeIngredientDeleteConfirmation, "Are you sure to delete the ingredient: '{}'?"),
|
||||||
|
|
||||||
|
(RecipeOneServing, "1 serving"),
|
||||||
|
(RecipeSomeServings, "{} servings"),
|
||||||
|
(RecipeEstimatedTimeMinAbbreviation, "min"),
|
||||||
|
|
||||||
|
(CalendarMonday, "Monday"),
|
||||||
|
(CalendarTuesday, "Tuesday"),
|
||||||
|
(CalendarWednesday, "Wednesday"),
|
||||||
|
(CalendarThursday, "Thursday"),
|
||||||
|
(CalendarFriday, "Friday"),
|
||||||
|
(CalendarSaturday, "Saturday"),
|
||||||
|
(CalendarSunday, "Sunday"),
|
||||||
|
(CalendarMondayAbbreviation, "Mon"),
|
||||||
|
(CalendarTuesdayAbbreviation, "Tue"),
|
||||||
|
(CalendarWednesdayAbbreviation, "Wed"),
|
||||||
|
(CalendarThursdayAbbreviation, "Thu"),
|
||||||
|
(CalendarFridayAbbreviation, "Fri"),
|
||||||
|
(CalendarSaturdayAbbreviation, "Sat"),
|
||||||
|
(CalendarSundayAbbreviation, "Sun"),
|
||||||
|
(CalendarJanuary, "January"),
|
||||||
|
(CalendarFebruary, "February"),
|
||||||
|
(CalendarMarch, "March"),
|
||||||
|
(CalendarApril, "April"),
|
||||||
|
(CalendarMay, "May"),
|
||||||
|
(CalendarJune, "June"),
|
||||||
|
(CalendarJuly, "July"),
|
||||||
|
(CalendarAugust, "August"),
|
||||||
|
(CalendarSeptember, "September"),
|
||||||
|
(CalendarOctober, "October"),
|
||||||
|
(CalendarNovember, "November"),
|
||||||
|
(CalendarDecember, "December"),
|
||||||
|
(CalendarAddToPlanner, "Add to planner"),
|
||||||
|
(CalendarAddToPlannerSuccess, "Recipe {title} has been scheduled for {date}"),
|
||||||
|
(CalendarAddToPlannerAlreadyExists, "Recipe {title} has already been scheduled for {date}"),
|
||||||
|
(CalendarDateFormat, "%A, %-d %B, %C%y"), // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
||||||
|
(CalendarAddIngredientsToShoppingList, "Add ingredients to shopping list"),
|
||||||
|
(CalendarRemoveIngredientsFromShoppingList, "Remove ingredients from shopping list"),
|
||||||
|
(CalendarUnschedule, "Remove"),
|
||||||
|
(CalendarUnscheduleConfirmation, "Are you sure to remove {title} on {date}"),
|
||||||
|
]
|
||||||
|
)
|
||||||
153
backend/translations/french.ron
Normal file
153
backend/translations/french.ron
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
(
|
||||||
|
code: "fr",
|
||||||
|
territory: "FR",
|
||||||
|
name: "Français",
|
||||||
|
translation: [
|
||||||
|
(MainTitle, "Recettes de Cuisine"),
|
||||||
|
(CreateNewRecipe, "Créer une nouvelle recette"),
|
||||||
|
(PrivateRecipes, "Recettes privées"),
|
||||||
|
(UntitledRecipe, "Recette sans nom"),
|
||||||
|
|
||||||
|
(Name, "Nom"),
|
||||||
|
(EmailAddress, "Adresse email"),
|
||||||
|
(Password, "Mot de passe"),
|
||||||
|
|
||||||
|
(SignOut, "Se déconnecter"),
|
||||||
|
(Save, "Sauvegarder"),
|
||||||
|
(NotLoggedIn, "Pas connecté"),
|
||||||
|
|
||||||
|
(ActionNotAuthorized, "Action non autorisée"),
|
||||||
|
|
||||||
|
(DatabaseError, "Erreur de la base de données (Database error)"),
|
||||||
|
(TemplateError, "Erreur du moteur de modèles (Template error)"),
|
||||||
|
|
||||||
|
(SignInMenu, "Se connecter"),
|
||||||
|
(SignInTitle, "Se connecter"),
|
||||||
|
(SignInButton, "Se connecter"),
|
||||||
|
(SignInSuccess, "Connexion réussie"),
|
||||||
|
(WrongEmailOrPassword, "Mot de passe ou email invalide"),
|
||||||
|
|
||||||
|
(AccountMustBeValidatedFirst, "Ce compte doit d'abord être validé"),
|
||||||
|
(InvalidEmail, "Adresse email invalide"),
|
||||||
|
(PasswordDontMatch, "Les mots de passe ne correspondent pas"),
|
||||||
|
(InvalidPassword, "Le mot de passe doit avoir au moins {} caractères"),
|
||||||
|
(EmailAlreadyTaken, "Cette adresse email n'est pas disponible"),
|
||||||
|
(UnableToSendEmail, "L'email de validation n'a pas pu être envoyé"),
|
||||||
|
|
||||||
|
(ValidationSuccessful, "Email validé avec succès"),
|
||||||
|
(ValidationExpired, "La validation a expiré. Essayez de vous inscrire à nouveau avec la même adresse email"),
|
||||||
|
(ValidationErrorTryToSignUpAgain, "Erreur de validation. Essayez de vous inscrire à nouveau avec la même adresse email"),
|
||||||
|
(ValidationError, "Erreur de validation"),
|
||||||
|
(ValidationUserAlreadyExists, "Utilisateur déjà existant"),
|
||||||
|
|
||||||
|
(SignUpMenu, "S'inscrire"),
|
||||||
|
(SignUpTitle, "Inscription"),
|
||||||
|
(SignUpButton, "Valider"),
|
||||||
|
(SignUpEmailSent, "Un email a été envoyé, suivez le lien pour valider votre compte"),
|
||||||
|
(SignUpEmailTitle, "Recettes de Cuisine: Validation du compte"),
|
||||||
|
(SignUpFollowEmailLink, "Suivez ce lien pour valider votre inscription, {}"),
|
||||||
|
(SignUpEmailValidationSuccess, "La validation de votre email s'est déroulée avec succès, votre compte a été créé"),
|
||||||
|
(SignUpValidationExpired, "La validation a expiré. Essayez de vous inscrire à nouveau"),
|
||||||
|
(SignUpValidationErrorTryAgain, "Erreur de validation. Essayez de vous inscrire à nouveau"),
|
||||||
|
(SignUpClosed, "Les inscriptions sont actuellement fermées"),
|
||||||
|
(ChooseAPassword, "Choisir un mot de passe (minimum {} caractères)"),
|
||||||
|
(ReEnterPassword, "Entrez à nouveau le mot de passe"),
|
||||||
|
|
||||||
|
(LostPassword, "Mot de passe perdu"),
|
||||||
|
(AskResetChooseNewPassword, "Choisir un nouveau mot de passe (minimum {} caractères)"),
|
||||||
|
(AskResetButton, "Demander la réinitialisation"),
|
||||||
|
(AskResetAlreadyLoggedInError, "Impossible de demander une réinitialisation du mot de passe lorsque déjà connecté"),
|
||||||
|
(AskResetEmailAlreadyResetError, "Le mot de passe a déjà été réinitialisé pour cette adresse email"),
|
||||||
|
(AskResetEmailTitle, "Recettes de Cuisine: Réinitialisation du mot de passe"),
|
||||||
|
(AskResetFollowEmailLink, "Suivez ce lien pour réinitialiser votre mot de passe, {}"),
|
||||||
|
(AskResetEmailSent, "Un email a été envoyé, suivez le lien pour réinitialiser votre mot de passe"),
|
||||||
|
(AskResetTokenMissing, "Jeton de réinitialisation manquant"),
|
||||||
|
(AskResetTokenExpired, "Jeton expiré, essayez de réinitialiser votre mot de passe à nouveau"),
|
||||||
|
(PasswordReset, "Votre mot de passe a été réinitialisé"),
|
||||||
|
(EmailUnknown, "Email inconnu"),
|
||||||
|
(UnableToSendResetEmail, "Impossible d'envoyer l'email pour la réinitialisation du mot de passe"),
|
||||||
|
|
||||||
|
(ProfileTitle, "Profile"),
|
||||||
|
(ProfileEmail, "Email (doit être revalidé si changé)"),
|
||||||
|
(ProfileDefaultServings, "Nombre de portions par défaut"),
|
||||||
|
(ProfileFirstDayOfWeek, "Premier jour de la semaine"),
|
||||||
|
(ProfileNewPassword, "Nouveau mot de passe (minimum {} caractères)"),
|
||||||
|
(ProfileFollowEmailTitle, "Recettes de Cuisine: Validation de l'adresse email"),
|
||||||
|
(ProfileFollowEmailLink, "Suivez ce lien pour valider l'adresse email, {}"),
|
||||||
|
(ProfileEmailSent, "Un email a été envoyé, suivez le lien pour valider la nouvelle adresse email"),
|
||||||
|
(ProfileSaved, "Profile sauvegardé"),
|
||||||
|
|
||||||
|
(RecipeNotAllowedToEdit, "Vous n'êtes pas autorisé à éditer cette recette"),
|
||||||
|
(RecipeNotAllowedToView, "Vous n'êtes pas autorisé à voir la recette {}"),
|
||||||
|
(RecipeNotFound, "Recette non-trouvée"),
|
||||||
|
(RecipeTitle, "Titre"),
|
||||||
|
(RecipeDescription, "Description"),
|
||||||
|
(RecipeServings, "Nombre de portions"),
|
||||||
|
(RecipeEstimatedTime, "Temps estimé"),
|
||||||
|
(RecipeDifficulty, "Difficulté"),
|
||||||
|
(RecipeDifficultyEasy, "Facile"),
|
||||||
|
(RecipeDifficultyMedium, "Moyen"),
|
||||||
|
(RecipeDifficultyHard, "Difficile"),
|
||||||
|
(RecipeTags, "Tags"),
|
||||||
|
(RecipeLanguage, "Langue"),
|
||||||
|
(RecipeIsPublic, "Est public"),
|
||||||
|
(RecipeDelete, "Supprimer la recette"),
|
||||||
|
(RecipeAddAGroup, "Ajouter un groupe"),
|
||||||
|
(RecipeRemoveGroup, "Supprimer le groupe"),
|
||||||
|
(RecipeGroupName, "Nom"),
|
||||||
|
(RecipeGroupComment, "Commentaire"),
|
||||||
|
(RecipeAddAStep, "Ajouter une étape"),
|
||||||
|
(RecipeRemoveStep, "Supprimer l'étape"),
|
||||||
|
(RecipeStepAction, "Action"),
|
||||||
|
(RecipeAddAnIngredient, "Ajouter un ingrédient"),
|
||||||
|
(RecipeRemoveIngredient, "Supprimer l'ingrédient"),
|
||||||
|
(RecipeIngredientName, "Nom"),
|
||||||
|
(RecipeIngredientQuantity, "Quantité"),
|
||||||
|
(RecipeIngredientUnit, "Unité"),
|
||||||
|
(RecipeIngredientComment, "Commentaire"),
|
||||||
|
(RecipeDeleteConfirmation, "Êtes-vous sûr de vouloir supprimer la recette : '{}' ?"),
|
||||||
|
(RecipeSuccessfullyDeleted, "Recette supprimée avec succès"),
|
||||||
|
(RecipeGroupDeleteConfirmation, "Êtes-vous sûr de vouloir supprimer le groupe : '{}' ?"),
|
||||||
|
(RecipeStepDeleteConfirmation, "Êtes-vous sûr de vouloir supprimer l'étape : '{}' ?"),
|
||||||
|
(RecipeIngredientDeleteConfirmation, "Êtes-vous sûr de vouloir supprimer 'ingrédient : '{}' ?"),
|
||||||
|
|
||||||
|
(RecipeOneServing, "pour 1 personne"),
|
||||||
|
(RecipeSomeServings, "pour {} personnes"),
|
||||||
|
(RecipeEstimatedTimeMinAbbreviation, "min"),
|
||||||
|
|
||||||
|
(CalendarMonday, "lundi"),
|
||||||
|
(CalendarTuesday, "mardi"),
|
||||||
|
(CalendarWednesday, "mercredi"),
|
||||||
|
(CalendarThursday, "jeudi"),
|
||||||
|
(CalendarFriday, "vendredi"),
|
||||||
|
(CalendarSaturday, "samedi"),
|
||||||
|
(CalendarSunday, "dimanche"),
|
||||||
|
(CalendarMondayAbbreviation, "Lun"),
|
||||||
|
(CalendarTuesdayAbbreviation, "Mar"),
|
||||||
|
(CalendarWednesdayAbbreviation, "Mer"),
|
||||||
|
(CalendarThursdayAbbreviation, "Jeu"),
|
||||||
|
(CalendarFridayAbbreviation, "Ven"),
|
||||||
|
(CalendarSaturdayAbbreviation, "Sam"),
|
||||||
|
(CalendarSundayAbbreviation, "Dim"),
|
||||||
|
(CalendarJanuary, "janvier"),
|
||||||
|
(CalendarFebruary, "février"),
|
||||||
|
(CalendarMarch, "mars"),
|
||||||
|
(CalendarApril, "avril"),
|
||||||
|
(CalendarMay, "mai"),
|
||||||
|
(CalendarJune, "juin"),
|
||||||
|
(CalendarJuly, "juillet"),
|
||||||
|
(CalendarAugust, "août"),
|
||||||
|
(CalendarSeptember, "septembre"),
|
||||||
|
(CalendarOctober, "octobre"),
|
||||||
|
(CalendarNovember, "novembre"),
|
||||||
|
(CalendarDecember, "décembre"),
|
||||||
|
(CalendarAddToPlanner, "Ajouter au planificateur"),
|
||||||
|
(CalendarAddToPlannerSuccess, "La recette {title} a été agendée pour le {date}"),
|
||||||
|
(CalendarAddToPlannerAlreadyExists, "La recette {title} a été déjà été agendée pour le {date}"),
|
||||||
|
(CalendarDateFormat, "%A %-d %B %C%y"), // See https://docs.rs/chrono/latest/chrono/format/strftime/index.html.
|
||||||
|
(CalendarAddIngredientsToShoppingList, "Ajouter les ingrédients à la liste de course"),
|
||||||
|
(CalendarRemoveIngredientsFromShoppingList, "Enlever les ingrédients de la liste de course"),
|
||||||
|
(CalendarUnschedule, "Enlever"),
|
||||||
|
(CalendarUnscheduleConfirmation, "Êtes-vous sûr de vouloir enlever {title} du {date}"),
|
||||||
|
]
|
||||||
|
)
|
||||||
2
do.nu
2
do.nu
|
|
@ -56,7 +56,7 @@ def "main deploy" [
|
||||||
invoke_ssh [rm -rf recipes/static]
|
invoke_ssh [rm -rf recipes/static]
|
||||||
copy_ssh ./backend/static/ $destination
|
copy_ssh ./backend/static/ $destination
|
||||||
copy_ssh ./backend/sql/ $destination
|
copy_ssh ./backend/sql/ $destination
|
||||||
copy_ssh ./backend/translation.ron $destination
|
copy_ssh ./backend/translations/ $destination
|
||||||
invoke_ssh [chmod u+x recipes/recipes]
|
invoke_ssh [chmod u+x recipes/recipes]
|
||||||
invoke_ssh [sudo systemctl start recipes]
|
invoke_ssh [sudo systemctl start recipes]
|
||||||
print "Deployment finished"
|
print "Deployment finished"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue