Compare commits

...

2 commits

Author SHA1 Message Date
90947b5578 feat: ability to resolve domainname 2025-02-07 08:01:59 +01:00
f33713231e feat: better error messages 2025-02-07 07:46:53 +01:00
8 changed files with 198 additions and 73 deletions

View file

@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tiramisu\n" "Project-Id-Version: Tiramisu\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-15 11:03+0100\n" "POT-Creation-Date: 2025-02-07 07:55+0100\n"
"PO-Revision-Date: \n" "PO-Revision-Date: \n"
"Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n" "Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
"Language-Team: Tiramisu's team <egarette@cadoles.com>\n" "Language-Team: Tiramisu's team <egarette@cadoles.com>\n"
@ -205,14 +205,16 @@ msgstr ""
"l'option {0} n'est pas une dynoptiondescription ou n'est pas dans une " "l'option {0} n'est pas une dynoptiondescription ou n'est pas dans une "
"dynoptiondescription" "dynoptiondescription"
#: tiramisu/autolib.py:685 #: tiramisu/autolib.py:687
msgid "" msgid ""
"cannot calculate arguments for \"{0}\", cannot find dynamic variable \"{1}\"" "cannot calculate arguments for \"{0}\", cannot find dynamic variable \"{1}\" "
"with identifier \"{2}\", list of valid identifiers: {3}"
msgstr "" msgstr ""
"impossible de calculer les arguments de \"{0}\", la variable dynamic \"{1}\" " "impossible de calculer les arguments de \"{0}\", ne peut trouver la variable "
"ne peut être trouvée" "dynamique \"{1}\" avec l'identifiant \"{2}\", voici la liste des "
"identifiants valables : {3}"
#: tiramisu/autolib.py:864 #: tiramisu/autolib.py:866
msgid "" msgid ""
"the \"{}\" function with positional arguments \"{}\" and keyword arguments " "the \"{}\" function with positional arguments \"{}\" and keyword arguments "
"\"{}\" must not return a list (\"{}\") for the follower option {}" "\"{}\" must not return a list (\"{}\") for the follower option {}"
@ -221,7 +223,7 @@ msgstr ""
"nommés \"{}\" ne doit pas retourner une liste (\"{}\") pour l'option " "nommés \"{}\" ne doit pas retourner une liste (\"{}\") pour l'option "
"suiveuse {}" "suiveuse {}"
#: tiramisu/autolib.py:879 #: tiramisu/autolib.py:881
msgid "" msgid ""
"the \"{}\" function must not return a list (\"{}\") for the follower option " "the \"{}\" function must not return a list (\"{}\") for the follower option "
"{}" "{}"
@ -229,7 +231,7 @@ msgstr ""
"la fonction \"{}\" ne doit pas retourner une liste (\"{}\") pour l'option " "la fonction \"{}\" ne doit pas retourner une liste (\"{}\") pour l'option "
"suiveuse {}" "suiveuse {}"
#: tiramisu/autolib.py:920 #: tiramisu/autolib.py:922
msgid "" msgid ""
"unexpected error \"{0}\" in function \"{1}\" with arguments \"{3}\" and " "unexpected error \"{0}\" in function \"{1}\" with arguments \"{3}\" and "
"\"{4}\" for option {2}" "\"{4}\" for option {2}"
@ -237,7 +239,7 @@ msgstr ""
"erreur inattendue \"{0}\" dans la fonction \"{1}\" avec les arguments " "erreur inattendue \"{0}\" dans la fonction \"{1}\" avec les arguments "
"\"{3}\" et \"{4}\" pour l'option {2}" "\"{3}\" et \"{4}\" pour l'option {2}"
#: tiramisu/autolib.py:931 #: tiramisu/autolib.py:933
msgid "unexpected error \"{0}\" in function \"{1}\" for option {2}" msgid "unexpected error \"{0}\" in function \"{1}\" for option {2}"
msgstr "erreur inattendue \"{0}\" dans la fonction \"{1}\" pour l'option {2}" msgstr "erreur inattendue \"{0}\" dans la fonction \"{1}\" pour l'option {2}"
@ -382,14 +384,23 @@ msgstr "ne peut accéder à l'{0} {1} à cause {2} {3}"
msgid "invalid value" msgid "invalid value"
msgstr "valeur invalide" msgstr "valeur invalide"
#: tiramisu/error.py:201 #: tiramisu/error.py:202
msgid "attention, \"{0}\" could be an invalid {1} for \"{2}\"" msgid "attention, \"{0}\" could be an invalid {1} for \"{2}\""
msgstr "attention, \"{0}\" peut être un {1} invalide pour \"{2}\"" msgstr "attention, \"{0}\" peut être un {1} invalide pour \"{2}\""
#: tiramisu/error.py:219 tiramisu/error.py:228 #: tiramisu/error.py:204
msgid "attention, \"{0}\" could be an invalid {1} for \"{2}\" at index \"{3}\""
msgstr ""
"attention, \"{0}\" peut être un {1} invalide pour \"{2}\" à l'index \"{3}\""
#: tiramisu/error.py:223 tiramisu/error.py:234
msgid "\"{0}\" is an invalid {1} for \"{2}\"" msgid "\"{0}\" is an invalid {1} for \"{2}\""
msgstr "\"{0}\" est une valeur invalide pour l'option \"{2}\" de type {1}" msgstr "\"{0}\" est une valeur invalide pour l'option \"{2}\" de type {1}"
#: tiramisu/error.py:225
msgid "\"{0}\" is an invalid {1} for \"{2}\" at index \"{3}\""
msgstr "\"{0}\" est un {1} invalide pour \"{2}\" à l'index \"{3}\""
#: tiramisu/function.py:65 #: tiramisu/function.py:65
msgid "network \"{0}\" ({1}) does not match with this netmask" msgid "network \"{0}\" ({1}) does not match with this netmask"
msgstr "le réseau \"{0}\" (\"{1}\") ne correspond pas avec le masque de réseau" msgstr "le réseau \"{0}\" (\"{1}\") ne correspond pas avec le masque de réseau"
@ -511,27 +522,27 @@ msgstr "seul \"{0}\" est autorisé"
msgid "only {0} are allowed" msgid "only {0} are allowed"
msgstr "seul {0} sont autorisées" msgstr "seul {0} sont autorisées"
#: tiramisu/option/domainnameoption.py:60 #: tiramisu/option/domainnameoption.py:62
msgid "unknown type {0} for hostname" msgid "unknown type {0} for hostname"
msgstr "type_ inconnu {0} pour le nom d'hôte" msgstr "type_ inconnu {0} pour le nom d'hôte"
#: tiramisu/option/domainnameoption.py:63 #: tiramisu/option/domainnameoption.py:65
msgid "allow_ip must be a boolean" msgid "allow_ip must be a boolean"
msgstr "allow_ip doit être un booléen" msgstr "allow_ip doit être un booléen"
#: tiramisu/option/domainnameoption.py:65 #: tiramisu/option/domainnameoption.py:67
msgid "allow_cidr_network must be a boolean" msgid "allow_cidr_network must be a boolean"
msgstr "allow_cidr_network doit être un booléen" msgstr "allow_cidr_network doit être un booléen"
#: tiramisu/option/domainnameoption.py:67 #: tiramisu/option/domainnameoption.py:69
msgid "allow_without_dot must be a boolean" msgid "allow_without_dot must be a boolean"
msgstr "allow_without_dot doit être un booléen" msgstr "allow_without_dot doit être un booléen"
#: tiramisu/option/domainnameoption.py:69 #: tiramisu/option/domainnameoption.py:71
msgid "allow_startswith_dot must be a boolean" msgid "allow_startswith_dot must be a boolean"
msgstr "allow_startswith_dot doit être un booléen" msgstr "allow_startswith_dot doit être un booléen"
#: tiramisu/option/domainnameoption.py:81 #: tiramisu/option/domainnameoption.py:82
msgid "" msgid ""
"must start with lowercase characters followed by lowercase characters, " "must start with lowercase characters followed by lowercase characters, "
"number, \"-\" and \".\" characters are allowed" "number, \"-\" and \".\" characters are allowed"
@ -539,7 +550,7 @@ msgstr ""
"doit démarrer par un caractère en minuscule suivi par des caractères en " "doit démarrer par un caractère en minuscule suivi par des caractères en "
"minuscule, des nombres, \"-\" et \".\" sont autorisés" "minuscule, des nombres, \"-\" et \".\" sont autorisés"
#: tiramisu/option/domainnameoption.py:84 #: tiramisu/option/domainnameoption.py:85
msgid "" msgid ""
"must start with lowercase characters followed by lowercase characters, " "must start with lowercase characters followed by lowercase characters, "
"number, \"-\" and \".\" characters are recommanded" "number, \"-\" and \".\" characters are recommanded"
@ -547,32 +558,56 @@ msgstr ""
"doit démarrer par un caractère en minuscule suivi par des caractères en " "doit démarrer par un caractère en minuscule suivi par des caractères en "
"minuscule, des nombres, \"-\" et \".\" sont recommandés" "minuscule, des nombres, \"-\" et \".\" sont recommandés"
#: tiramisu/option/domainnameoption.py:88 #: tiramisu/option/domainnameoption.py:90
#: tiramisu/option/domainnameoption.py:89 msgid ""
"must start with lowercase characters followed by lowercase characters, "
"number and \"-\" characters are allowed"
msgstr ""
"doit démarrer par un caractère en minuscule suivi par des caractères en "
"minuscule, des nombres et \"-\" sont autorisés"
#: tiramisu/option/domainnameoption.py:93
msgid ""
"must start with lowercase characters followed by lowercase characters, "
"number and \"-\" characters are recommanded"
msgstr ""
"doit démarrer par un caractère en minuscule suivi par des caractères en "
"minuscule, des nombres et\"-\" sont recommandés"
#: tiramisu/option/domainnameoption.py:97
#: tiramisu/option/domainnameoption.py:98
msgid "could be a IP, otherwise {}" msgid "could be a IP, otherwise {}"
msgstr "peut être une IP, autrement {}" msgstr "peut être une IP, autrement {}"
#: tiramisu/option/domainnameoption.py:134 #: tiramisu/option/domainnameoption.py:143
msgid "invalid length (min 1)" msgid "invalid length (min 1)"
msgstr "longueur invalide (min 1)" msgstr "longueur invalide (min 1)"
#: tiramisu/option/domainnameoption.py:137 #: tiramisu/option/domainnameoption.py:146
msgid "invalid length (max {0})" msgid "invalid length (max {0})"
msgstr "longueur invalide (max {0})" msgstr "longueur invalide (max {0})"
#: tiramisu/option/domainnameoption.py:143 #: tiramisu/option/domainnameoption.py:152
msgid "must have dot" msgid "must have dot"
msgstr "doit avoir un point" msgstr "doit avoir un point"
#: tiramisu/option/domainnameoption.py:145 #: tiramisu/option/domainnameoption.py:154
msgid "invalid length (max 255)" msgid "invalid length (max 255)"
msgstr "longueur invalide (max 255)" msgstr "longueur invalide (max 255)"
#: tiramisu/option/domainnameoption.py:163 #: tiramisu/option/domainnameoption.py:175
msgid "DNS resolution failed"
msgstr "la résolution DNS a échoué"
#: tiramisu/option/domainnameoption.py:179
msgid "error resolving DNS: {1}"
msgstr "erreur de résolution DNS : {1}"
#: tiramisu/option/domainnameoption.py:186
msgid "must not be an IP" msgid "must not be an IP"
msgstr "ne doit pas être une IP" msgstr "ne doit pas être une IP"
#: tiramisu/option/domainnameoption.py:186 #: tiramisu/option/domainnameoption.py:209
msgid "some characters are uppercase" msgid "some characters are uppercase"
msgstr "des caractères sont en majuscule" msgstr "des caractères sont en majuscule"
@ -723,15 +758,15 @@ msgstr "validators doit être une liste de Calculation pour \"{0}\""
msgid "validators must be a Calculation for \"{0}\"" msgid "validators must be a Calculation for \"{0}\""
msgstr "validators doit être un Calculation pour \"{0}\"" msgstr "validators doit être un Calculation pour \"{0}\""
#: tiramisu/option/option.py:146 #: tiramisu/option/option.py:141
msgid "invalid default_multi value \"{0}\" for option {1}" msgid "invalid default_multi value \"{0}\" for option {1}"
msgstr "la valeur default_multi est invalide {0} pour l'option {1}" msgstr "la valeur default_multi est invalide {0} pour l'option {1}"
#: tiramisu/option/option.py:154 #: tiramisu/option/option.py:149
msgid "invalid default_multi value \"{0}\" for option {1}, {2}" msgid "invalid default_multi value \"{0}\" for option {1}, {2}"
msgstr "la valeur default_multi est invalide \"{0}\" pour l'option {1}, {2}" msgstr "la valeur default_multi est invalide \"{0}\" pour l'option {1}, {2}"
#: tiramisu/option/option.py:167 #: tiramisu/option/option.py:162
msgid "" msgid ""
"invalid default_multi value \"{0}\" for option {1}, must be a list for a " "invalid default_multi value \"{0}\" for option {1}, must be a list for a "
"submulti" "submulti"
@ -739,19 +774,19 @@ msgstr ""
"valeur invalide pour default_multi \"{0}\" pour l'option {1}, doit être une " "valeur invalide pour default_multi \"{0}\" pour l'option {1}, doit être une "
"liste pour une submulti" "liste pour une submulti"
#: tiramisu/option/option.py:290 #: tiramisu/option/option.py:285
msgid "the value \"{}\" is not unique" msgid "the value \"{}\" is not unique"
msgstr "la valeur de \"{}\" n'est pas unique" msgstr "la valeur de \"{}\" n'est pas unique"
#: tiramisu/option/option.py:352 #: tiramisu/option/option.py:347
msgid "which must not be a list" msgid "which must not be a list"
msgstr "qui ne doit pas être une liste" msgstr "qui ne doit pas être une liste"
#: tiramisu/option/option.py:404 tiramisu/option/option.py:430 #: tiramisu/option/option.py:399 tiramisu/option/option.py:425
msgid "which must be a list" msgid "which must be a list"
msgstr "qui doit être une liste" msgstr "qui doit être une liste"
#: tiramisu/option/option.py:424 #: tiramisu/option/option.py:419
msgid "which \"{}\" must be a list of list" msgid "which \"{}\" must be a list of list"
msgstr "lequel \"{}\" doit être une liste de liste" msgstr "lequel \"{}\" doit être une liste de liste"
@ -858,6 +893,10 @@ msgstr "devrait être une nombre entre {0} et {1}"
msgid "must be between {0} and {1}" msgid "must be between {0} and {1}"
msgstr "doit être une nombre entre {0} et {1}" msgstr "doit être une nombre entre {0} et {1}"
#: tiramisu/option/stroption.py:41
msgid "which is not a string"
msgstr "qui n'est pas une chaîne de caractères"
#: tiramisu/option/symlinkoption.py:51 #: tiramisu/option/symlinkoption.py:51
msgid "" msgid ""
"malformed symlink second parameters must be an option for \"{0}\", not {1}" "malformed symlink second parameters must be an option for \"{0}\", not {1}"
@ -869,7 +908,15 @@ msgstr ""
msgid "must start with http:// or https://" msgid "must start with http:// or https://"
msgstr "doit débuter par http:// ou https://" msgstr "doit débuter par http:// ou https://"
#: tiramisu/option/urloption.py:119 #: tiramisu/option/urloption.py:116
msgid "the port \"{0}\" is invalid: {1}"
msgstr "le port \"{0}\" est invalide : {1}"
#: tiramisu/option/urloption.py:123
msgid "the domain \"{0}\" is invalid: {1}"
msgstr "le domaine \"{0}\" est invalide : {1}"
#: tiramisu/option/urloption.py:127
msgid "must ends with a valid resource name" msgid "must ends with a valid resource name"
msgstr "doit finir par un nom de ressource valide" msgstr "doit finir par un nom de ressource valide"

View file

@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-12-15 11:06+0100\n" "POT-Creation-Date: 2025-02-07 08:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -187,23 +187,23 @@ msgstr ""
msgid "option {0} is not a dynoptiondescription or in a dynoptiondescription" msgid "option {0} is not a dynoptiondescription or in a dynoptiondescription"
msgstr "" msgstr ""
#: tiramisu/autolib.py:685 #: tiramisu/autolib.py:687
msgid "cannot calculate arguments for \"{0}\", cannot find dynamic variable \"{1}\"" msgid "cannot calculate arguments for \"{0}\", cannot find dynamic variable \"{1}\" with identifier \"{2}\", list of valid identifiers: {3}"
msgstr "" msgstr ""
#: tiramisu/autolib.py:864 #: tiramisu/autolib.py:866
msgid "the \"{}\" function with positional arguments \"{}\" and keyword arguments \"{}\" must not return a list (\"{}\") for the follower option {}" msgid "the \"{}\" function with positional arguments \"{}\" and keyword arguments \"{}\" must not return a list (\"{}\") for the follower option {}"
msgstr "" msgstr ""
#: tiramisu/autolib.py:879 #: tiramisu/autolib.py:881
msgid "the \"{}\" function must not return a list (\"{}\") for the follower option {}" msgid "the \"{}\" function must not return a list (\"{}\") for the follower option {}"
msgstr "" msgstr ""
#: tiramisu/autolib.py:920 #: tiramisu/autolib.py:922
msgid "unexpected error \"{0}\" in function \"{1}\" with arguments \"{3}\" and \"{4}\" for option {2}" msgid "unexpected error \"{0}\" in function \"{1}\" with arguments \"{3}\" and \"{4}\" for option {2}"
msgstr "" msgstr ""
#: tiramisu/autolib.py:931 #: tiramisu/autolib.py:933
msgid "unexpected error \"{0}\" in function \"{1}\" for option {2}" msgid "unexpected error \"{0}\" in function \"{1}\" for option {2}"
msgstr "" msgstr ""
@ -331,14 +331,22 @@ msgstr ""
msgid "invalid value" msgid "invalid value"
msgstr "" msgstr ""
#: tiramisu/error.py:201 #: tiramisu/error.py:202
msgid "attention, \"{0}\" could be an invalid {1} for \"{2}\"" msgid "attention, \"{0}\" could be an invalid {1} for \"{2}\""
msgstr "" msgstr ""
#: tiramisu/error.py:219 tiramisu/error.py:228 #: tiramisu/error.py:204
msgid "attention, \"{0}\" could be an invalid {1} for \"{2}\" at index \"{3}\""
msgstr ""
#: tiramisu/error.py:223 tiramisu/error.py:234
msgid "\"{0}\" is an invalid {1} for \"{2}\"" msgid "\"{0}\" is an invalid {1} for \"{2}\""
msgstr "" msgstr ""
#: tiramisu/error.py:225
msgid "\"{0}\" is an invalid {1} for \"{2}\" at index \"{3}\""
msgstr ""
#: tiramisu/function.py:65 #: tiramisu/function.py:65
msgid "network \"{0}\" ({1}) does not match with this netmask" msgid "network \"{0}\" ({1}) does not match with this netmask"
msgstr "" msgstr ""
@ -443,60 +451,76 @@ msgstr ""
msgid "only {0} are allowed" msgid "only {0} are allowed"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:60 #: tiramisu/option/domainnameoption.py:62
msgid "unknown type {0} for hostname" msgid "unknown type {0} for hostname"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:63 #: tiramisu/option/domainnameoption.py:65
msgid "allow_ip must be a boolean" msgid "allow_ip must be a boolean"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:65 #: tiramisu/option/domainnameoption.py:67
msgid "allow_cidr_network must be a boolean" msgid "allow_cidr_network must be a boolean"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:67 #: tiramisu/option/domainnameoption.py:69
msgid "allow_without_dot must be a boolean" msgid "allow_without_dot must be a boolean"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:69 #: tiramisu/option/domainnameoption.py:71
msgid "allow_startswith_dot must be a boolean" msgid "allow_startswith_dot must be a boolean"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:81 #: tiramisu/option/domainnameoption.py:82
msgid "must start with lowercase characters followed by lowercase characters, number, \"-\" and \".\" characters are allowed" msgid "must start with lowercase characters followed by lowercase characters, number, \"-\" and \".\" characters are allowed"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:84 #: tiramisu/option/domainnameoption.py:85
msgid "must start with lowercase characters followed by lowercase characters, number, \"-\" and \".\" characters are recommanded" msgid "must start with lowercase characters followed by lowercase characters, number, \"-\" and \".\" characters are recommanded"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:88 #: tiramisu/option/domainnameoption.py:90
#: tiramisu/option/domainnameoption.py:89 msgid "must start with lowercase characters followed by lowercase characters, number and \"-\" characters are allowed"
msgstr ""
#: tiramisu/option/domainnameoption.py:93
msgid "must start with lowercase characters followed by lowercase characters, number and \"-\" characters are recommanded"
msgstr ""
#: tiramisu/option/domainnameoption.py:97
#: tiramisu/option/domainnameoption.py:98
msgid "could be a IP, otherwise {}" msgid "could be a IP, otherwise {}"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:134 #: tiramisu/option/domainnameoption.py:143
msgid "invalid length (min 1)" msgid "invalid length (min 1)"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:137 #: tiramisu/option/domainnameoption.py:146
msgid "invalid length (max {0})" msgid "invalid length (max {0})"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:143 #: tiramisu/option/domainnameoption.py:152
msgid "must have dot" msgid "must have dot"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:145 #: tiramisu/option/domainnameoption.py:154
msgid "invalid length (max 255)" msgid "invalid length (max 255)"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:163 #: tiramisu/option/domainnameoption.py:175
msgid "must not be an IP" msgid "DNS resolution failed"
msgstr ""
#: tiramisu/option/domainnameoption.py:179
msgid "error resolving DNS: {1}"
msgstr "" msgstr ""
#: tiramisu/option/domainnameoption.py:186 #: tiramisu/option/domainnameoption.py:186
msgid "must not be an IP"
msgstr ""
#: tiramisu/option/domainnameoption.py:209
msgid "some characters are uppercase" msgid "some characters are uppercase"
msgstr "" msgstr ""
@ -632,31 +656,31 @@ msgstr ""
msgid "validators must be a Calculation for \"{0}\"" msgid "validators must be a Calculation for \"{0}\""
msgstr "" msgstr ""
#: tiramisu/option/option.py:146 #: tiramisu/option/option.py:141
msgid "invalid default_multi value \"{0}\" for option {1}" msgid "invalid default_multi value \"{0}\" for option {1}"
msgstr "" msgstr ""
#: tiramisu/option/option.py:154 #: tiramisu/option/option.py:149
msgid "invalid default_multi value \"{0}\" for option {1}, {2}" msgid "invalid default_multi value \"{0}\" for option {1}, {2}"
msgstr "" msgstr ""
#: tiramisu/option/option.py:167 #: tiramisu/option/option.py:162
msgid "invalid default_multi value \"{0}\" for option {1}, must be a list for a submulti" msgid "invalid default_multi value \"{0}\" for option {1}, must be a list for a submulti"
msgstr "" msgstr ""
#: tiramisu/option/option.py:290 #: tiramisu/option/option.py:285
msgid "the value \"{}\" is not unique" msgid "the value \"{}\" is not unique"
msgstr "" msgstr ""
#: tiramisu/option/option.py:352 #: tiramisu/option/option.py:347
msgid "which must not be a list" msgid "which must not be a list"
msgstr "" msgstr ""
#: tiramisu/option/option.py:404 tiramisu/option/option.py:430 #: tiramisu/option/option.py:399 tiramisu/option/option.py:425
msgid "which must be a list" msgid "which must be a list"
msgstr "" msgstr ""
#: tiramisu/option/option.py:424 #: tiramisu/option/option.py:419
msgid "which \"{}\" must be a list of list" msgid "which \"{}\" must be a list of list"
msgstr "" msgstr ""
@ -757,6 +781,10 @@ msgstr ""
msgid "must be between {0} and {1}" msgid "must be between {0} and {1}"
msgstr "" msgstr ""
#: tiramisu/option/stroption.py:41
msgid "which is not a string"
msgstr ""
#: tiramisu/option/symlinkoption.py:51 #: tiramisu/option/symlinkoption.py:51
msgid "malformed symlink second parameters must be an option for \"{0}\", not {1}" msgid "malformed symlink second parameters must be an option for \"{0}\", not {1}"
msgstr "" msgstr ""
@ -765,7 +793,15 @@ msgstr ""
msgid "must start with http:// or https://" msgid "must start with http:// or https://"
msgstr "" msgstr ""
#: tiramisu/option/urloption.py:119 #: tiramisu/option/urloption.py:116
msgid "the port \"{0}\" is invalid: {1}"
msgstr ""
#: tiramisu/option/urloption.py:123
msgid "the domain \"{0}\" is invalid: {1}"
msgstr ""
#: tiramisu/option/urloption.py:127
msgid "must ends with a valid resource name" msgid "must ends with a valid resource name"
msgstr "" msgstr ""

View file

@ -275,3 +275,9 @@ def test_url(config_type):
with pytest.raises(ValueError): with pytest.raises(ValueError):
cfg.option('u').value.set('https://FOO.COM:8443') cfg.option('u').value.set('https://FOO.COM:8443')
# assert not list_sessions() # assert not list_sessions()
def test_domainname_existence():
DomainnameOption('d', '', 'google.fr', test_existence=True)
with pytest.raises(ValueError):
DomainnameOption('d', '', 'ljijouuuehyfr.com', test_existence=True)

View file

@ -22,7 +22,7 @@ from typing import Any, Optional, Union, Callable, Dict, List
from itertools import chain from itertools import chain
import weakref import weakref
from .error import PropertiesOptionError, ConfigError, LeadershipError, ValueWarning, CancelParam from .error import PropertiesOptionError, ConfigError, LeadershipError, ValueWarning, CancelParam, display_list
from .i18n import _ from .i18n import _
from .setting import undefined, ConfigBag from .setting import undefined, ConfigBag
from .function import FUNCTION_WAITING_FOR_DICT, FUNCTION_WAITING_FOR_ERROR from .function import FUNCTION_WAITING_FOR_DICT, FUNCTION_WAITING_FOR_ERROR
@ -682,7 +682,9 @@ def manager_callback(
child_path = name child_path = name
if param.optional: if param.optional:
raise CancelParam(callbk_option.impl_getpath(), child_path) raise CancelParam(callbk_option.impl_getpath(), child_path)
msg = _('cannot calculate arguments for "{0}", cannot find dynamic variable "{1}"').format(subconfig.path, child_path)
identifiers = display_list(doption.get_identifiers(parent), add_quote=True)
msg = _('cannot calculate arguments for "{0}", cannot find dynamic variable "{1}" with identifier "{2}", list of valid identifiers: {3}').format(subconfig.path, doption.impl_getpath(), identifier, identifiers)
raise ConfigError(msg) from err raise ConfigError(msg) from err
new_parents.append( new_parents.append(
parent.get_child( parent.get_child(

View file

@ -220,9 +220,9 @@ class ValueOptionError(_CommonError, ValueError):
def __init__(self, **kwargs): def __init__(self, **kwargs):
if ValueOptionError.tmpl is None: if ValueOptionError.tmpl is None:
if kwargs.get('index') is None: if kwargs.get('index') is None:
ValueOptionError.tmpl = _('"{0}" is an invalid {1} for "{2}"') self.tmpl = _('"{0}" is an invalid {1} for "{2}"')
else: else:
ValueOptionError.tmpl = _('"{0}" is an invalid {1} for "{2}" at index "{3}"') self.tmpl = _('"{0}" is an invalid {1} for "{2}" at index "{3}"')
super().__init__(**kwargs) super().__init__(**kwargs)
@ -240,3 +240,12 @@ class CancelParam(Exception):
super().__init__() super().__init__()
self.origin_path = origin_path self.origin_path = origin_path
self.current_path = current_path self.current_path = current_path
def __ne__(self, value):
return value is None or value == ""
def __eq__(self, value):
return value is None or value == ""
def __bool__(self):
return False

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2024 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2025 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -21,6 +21,7 @@
"""DomainnameOption """DomainnameOption
""" """
import re import re
import socket
from ipaddress import ip_interface from ipaddress import ip_interface
from typing import Any, Optional, List from typing import Any, Optional, List
@ -53,6 +54,7 @@ class DomainnameOption(StrOption):
type: str = "domainname", type: str = "domainname",
allow_without_dot: bool = False, allow_without_dot: bool = False,
allow_startswith_dot: bool = False, allow_startswith_dot: bool = False,
test_existence: bool = False,
**kwargs, **kwargs,
) -> None: ) -> None:
# pylint: disable=too-many-branches,too-many-locals,too-many-arguments # pylint: disable=too-many-branches,too-many-locals,too-many-arguments
@ -68,6 +70,7 @@ class DomainnameOption(StrOption):
if not isinstance(allow_startswith_dot, bool): if not isinstance(allow_startswith_dot, bool):
raise ValueError(_("allow_startswith_dot must be a boolean")) raise ValueError(_("allow_startswith_dot must be a boolean"))
extra["_allow_without_dot"] = allow_without_dot extra["_allow_without_dot"] = allow_without_dot
extra["_test_existence"] = test_existence
if type == "domainname": if type == "domainname":
if allow_without_dot: if allow_without_dot:
min_time = 0 min_time = 0
@ -161,6 +164,20 @@ class DomainnameOption(StrOption):
_valid_length(dom) _valid_length(dom)
else: else:
_valid_length(value) _valid_length(value)
self._validate_domain_resolution(value)
def _validate_domain_resolution(self, value: str) -> None:
if not value.startswith(".") and self.impl_get_extra("_test_existence") is True:
try:
socket.gethostbyname(value)
except socket.gaierror as err:
raise ValueError(
_("DNS resolution failed").format(value)
) from err
except Exception as err:
raise ValueError(
_("error resolving DNS: {1}").format(value, err)
) from err
def _validate_ip_network(self, value: str) -> None: def _validate_ip_network(self, value: str) -> None:
allow_ip = self.impl_get_extra("_allow_ip") allow_ip = self.impl_get_extra("_allow_ip")

View file

@ -110,10 +110,18 @@ class URLOption(StrOption):
domain, port, files = self._get_domain_port_files(value) domain, port, files = self._get_domain_port_files(value)
# validate port # validate port
portoption = self.impl_get_extra("_port") portoption = self.impl_get_extra("_port")
try:
portoption.validate(port) portoption.validate(port)
except ValueError as err:
msg = _('the port "{0}" is invalid: {1}').format(domain, err)
raise ValueError(msg) from err
# validate domainname # validate domainname
domainnameoption = self.impl_get_extra("_domainname") domainnameoption = self.impl_get_extra("_domainname")
try:
domainnameoption.validate(domain) domainnameoption.validate(domain)
except ValueError as err:
msg = _('the domain "{0}" is invalid: {1}').format(domain, err)
raise ValueError(msg) from err
# validate files # validate files
if files is not None and files != "" and not self.path_re.search(files): if files is not None and files != "" and not self.path_re.search(files):
raise ValueError(_("must ends with a valid resource name")) raise ValueError(_("must ends with a valid resource name"))