Black + fix some invalid code issues

This commit is contained in:
Alexandre Aubin 2021-09-05 00:20:12 +02:00
parent a062254402
commit 1bf0196ff8
4 changed files with 116 additions and 73 deletions

View file

@ -287,7 +287,9 @@ def service_reload_or_restart(names, test_conf=True):
out, _ = p.communicate() out, _ = p.communicate()
if p.returncode != 0: if p.returncode != 0:
errors = out.strip().split("\n") errors = out.strip().split("\n")
logger.error(m18n.("service_not_reloading_because_conf_broken", errors=errors)) logger.error(
m18n.n("service_not_reloading_because_conf_broken", errors=errors)
)
continue continue
if _run_service_command("reload-or-restart", name): if _run_service_command("reload-or-restart", name):

View file

@ -29,7 +29,6 @@ from collections import OrderedDict
from moulinette.interfaces.cli import colorize from moulinette.interfaces.cli import colorize
from moulinette import Moulinette, m18n from moulinette import Moulinette, m18n
from moulinette.utils.log import getActionLogger from moulinette.utils.log import getActionLogger
from moulinette.utils.process import check_output
from moulinette.utils.filesystem import ( from moulinette.utils.filesystem import (
write_to_file, write_to_file,
read_toml, read_toml,
@ -80,16 +79,22 @@ class ConfigPanel:
result = {} result = {}
for panel, section, option in self._iterate(): for panel, section, option in self._iterate():
key = f"{panel['id']}.{section['id']}.{option['id']}" key = f"{panel['id']}.{section['id']}.{option['id']}"
if mode == 'export': if mode == "export":
result[option['id']] = option.get('current_value') result[option["id"]] = option.get("current_value")
else: else:
if 'ask' in option: if "ask" in option:
result[key] = {'ask': _value_for_locale(option['ask'])} result[key] = {"ask": _value_for_locale(option["ask"])}
elif 'i18n' in self.config: elif "i18n" in self.config:
result[key] = {'ask': m18n.n(self.config['i18n'] + '_' + option['id'])} result[key] = {
if 'current_value' in option: "ask": m18n.n(self.config["i18n"] + "_" + option["id"])
question_class = ARGUMENTS_TYPE_PARSERS[option.get("type", "string")] }
result[key]['value'] = question_class.humanize(option['current_value'], option) if "current_value" in option:
question_class = ARGUMENTS_TYPE_PARSERS[
option.get("type", "string")
]
result[key]["value"] = question_class.humanize(
option["current_value"], option
)
return result return result
@ -294,8 +299,11 @@ class ConfigPanel:
self.errors = None self.errors = None
def _get_default_values(self): def _get_default_values(self):
return { option['id']: option['default'] return {
for _, _, option in self._iterate() if 'default' in option } option["id"]: option["default"]
for _, _, option in self._iterate()
if "default" in option
}
def _load_current_values(self): def _load_current_values(self):
""" """
@ -319,9 +327,11 @@ class ConfigPanel:
mkdir(dir_path, mode=0o700) mkdir(dir_path, mode=0o700)
values_to_save = {**self.values, **self.new_values} values_to_save = {**self.values, **self.new_values}
if self.save_mode == 'diff': if self.save_mode == "diff":
defaults = self._get_default_values() defaults = self._get_default_values()
values_to_save = {k: v for k, v in values_to_save.items() if defaults.get(k) != v} values_to_save = {
k: v for k, v in values_to_save.items() if defaults.get(k) != v
}
# Save the settings to the .yaml file # Save the settings to the .yaml file
write_to_yaml(self.save_path, self.new_values) write_to_yaml(self.save_path, self.new_values)
@ -360,17 +370,17 @@ class Question(object):
def __init__(self, question, user_answers): def __init__(self, question, user_answers):
self.name = question["name"] self.name = question["name"]
self.type = question.get("type", 'string') self.type = question.get("type", "string")
self.default = question.get("default", None) self.default = question.get("default", None)
self.current_value = question.get("current_value") self.current_value = question.get("current_value")
self.optional = question.get("optional", False) self.optional = question.get("optional", False)
self.choices = question.get("choices", []) self.choices = question.get("choices", [])
self.pattern = question.get("pattern") self.pattern = question.get("pattern")
self.ask = question.get("ask", {'en': self.name}) self.ask = question.get("ask", {"en": self.name})
self.help = question.get("help") self.help = question.get("help")
self.helpLink = question.get("helpLink") self.helpLink = question.get("helpLink")
self.value = user_answers.get(self.name) self.value = user_answers.get(self.name)
self.redact = question.get('redact', False) self.redact = question.get("redact", False)
# Empty value is parsed as empty string # Empty value is parsed as empty string
if self.default == "": if self.default == "":
@ -384,11 +394,10 @@ class Question(object):
def normalize(value, option={}): def normalize(value, option={}):
return value return value
def ask_if_needed(self): def ask_if_needed(self):
while True: while True:
# Display question if no value filled or if it's a readonly message # Display question if no value filled or if it's a readonly message
if Moulinette.interface.type== 'cli': if Moulinette.interface.type == "cli":
text_for_user_input_in_cli = self._format_text_for_user_input_in_cli() text_for_user_input_in_cli = self._format_text_for_user_input_in_cli()
if getattr(self, "readonly", False): if getattr(self, "readonly", False):
Moulinette.display(text_for_user_input_in_cli) Moulinette.display(text_for_user_input_in_cli)
@ -433,7 +442,6 @@ class Question(object):
return (self.value, self.argument_type) return (self.value, self.argument_type)
def _prevalidate(self): def _prevalidate(self):
if self.value in [None, ""] and not self.optional: if self.value in [None, ""] and not self.optional:
raise YunohostValidationError("app_argument_required", name=self.name) raise YunohostValidationError("app_argument_required", name=self.name)
@ -442,9 +450,9 @@ class Question(object):
if self.value is not None: if self.value is not None:
if self.choices and self.value not in self.choices: if self.choices and self.value not in self.choices:
self._raise_invalid_answer() self._raise_invalid_answer()
if self.pattern and not re.match(self.pattern['regexp'], str(self.value)): if self.pattern and not re.match(self.pattern["regexp"], str(self.value)):
raise YunohostValidationError( raise YunohostValidationError(
self.pattern['error'], self.pattern["error"],
name=self.name, name=self.name,
value=self.value, value=self.value,
) )
@ -494,7 +502,10 @@ class Question(object):
if self.operation_logger: if self.operation_logger:
self.operation_logger.data_to_redact.extend(data_to_redact) self.operation_logger.data_to_redact.extend(data_to_redact)
elif data_to_redact: elif data_to_redact:
raise YunohostError(f"Can't redact {question.name} because no operation logger available in the context", raw_msg=True) raise YunohostError(
f"Can't redact {self.name} because no operation logger available in the context",
raw_msg=True,
)
return self.value return self.value
@ -510,7 +521,7 @@ class TagsQuestion(Question):
@staticmethod @staticmethod
def humanize(value, option={}): def humanize(value, option={}):
if isinstance(value, list): if isinstance(value, list):
return ','.join(value) return ",".join(value)
return value return value
def _prevalidate(self): def _prevalidate(self):
@ -540,7 +551,7 @@ class PasswordQuestion(Question):
@staticmethod @staticmethod
def humanize(value, option={}): def humanize(value, option={}):
if value: if value:
return '***' # Avoid to display the password on screen return "********" # Avoid to display the password on screen
return "" return ""
def _prevalidate(self): def _prevalidate(self):
@ -571,32 +582,32 @@ class BooleanQuestion(Question):
@staticmethod @staticmethod
def humanize(value, option={}): def humanize(value, option={}):
yes = option.get('yes', 1) yes = option.get("yes", 1)
no = option.get('no', 0) no = option.get("no", 0)
value = str(value).lower() value = str(value).lower()
if value == str(yes).lower(): if value == str(yes).lower():
return 'yes' return "yes"
if value == str(no).lower(): if value == str(no).lower():
return 'no' return "no"
if value in BooleanQuestion.yes_answers: if value in BooleanQuestion.yes_answers:
return 'yes' return "yes"
if value in BooleanQuestion.no_answers: if value in BooleanQuestion.no_answers:
return 'no' return "no"
if value in ['none', ""]: if value in ["none", ""]:
return '' return ""
raise YunohostValidationError( raise YunohostValidationError(
"app_argument_choice_invalid", "app_argument_choice_invalid",
name=self.name, name=self.name, # FIXME ...
value=self.value, value=value,
choices="yes, no, y, n, 1, 0", choices="yes, no, y, n, 1, 0",
) )
@staticmethod @staticmethod
def normalize(value, option={}): def normalize(value, option={}):
yes = option.get('yes', 1) yes = option.get("yes", 1)
no = option.get('no', 0) no = option.get("no", 0)
if str(value).lower() in BooleanQuestion.yes_answers: if str(value).lower() in BooleanQuestion.yes_answers:
return yes return yes
@ -608,19 +619,18 @@ class BooleanQuestion(Question):
return None return None
raise YunohostValidationError( raise YunohostValidationError(
"app_argument_choice_invalid", "app_argument_choice_invalid",
name=self.name, name=self.name, # FIXME....
value=self.value, value=value,
choices="yes, no, y, n, 1, 0", choices="yes, no, y, n, 1, 0",
) )
def __init__(self, question, user_answers): def __init__(self, question, user_answers):
super().__init__(question, user_answers) super().__init__(question, user_answers)
self.yes = question.get('yes', 1) self.yes = question.get("yes", 1)
self.no = question.get('no', 0) self.no = question.get("no", 0)
if self.default is None: if self.default is None:
self.default = False self.default = False
def _format_text_for_user_input_in_cli(self): def _format_text_for_user_input_in_cli(self):
text_for_user_input_in_cli = _value_for_locale(self.ask) text_for_user_input_in_cli = _value_for_locale(self.ask)
@ -652,7 +662,6 @@ class DomainQuestion(Question):
self.choices = domain_list()["domains"] self.choices = domain_list()["domains"]
def _raise_invalid_answer(self): def _raise_invalid_answer(self):
raise YunohostValidationError( raise YunohostValidationError(
"app_argument_invalid", field=self.name, error=m18n.n("domain_unknown") "app_argument_invalid", field=self.name, error=m18n.n("domain_unknown")
@ -675,7 +684,6 @@ class UserQuestion(Question):
self.default = user self.default = user
break break
def _raise_invalid_answer(self): def _raise_invalid_answer(self):
raise YunohostValidationError( raise YunohostValidationError(
"app_argument_invalid", "app_argument_invalid",
@ -698,7 +706,6 @@ class NumberQuestion(Question):
self.max = question.get("max", None) self.max = question.get("max", None)
self.step = question.get("step", None) self.step = question.get("step", None)
def _prevalidate(self): def _prevalidate(self):
super()._prevalidate() super()._prevalidate()
if not isinstance(self.value, int) and not ( if not isinstance(self.value, int) and not (
@ -744,8 +751,7 @@ class DisplayTextQuestion(Question):
super().__init__(question, user_answers) super().__init__(question, user_answers)
self.optional = True self.optional = True
self.style = question.get("style", "info") self.style = question.get("style", "info")
def _format_text_for_user_input_in_cli(self): def _format_text_for_user_input_in_cli(self):
text = self.ask["en"] text = self.ask["en"]
@ -780,7 +786,7 @@ class FileQuestion(Question):
self.accept = question.get("accept").replace(" ", "").split(",") self.accept = question.get("accept").replace(" ", "").split(",")
else: else:
self.accept = [] self.accept = []
if Moulinette.interface.type== "api": if Moulinette.interface.type == "api":
if user_answers.get(f"{self.name}[name]"): if user_answers.get(f"{self.name}[name]"):
self.value = { self.value = {
"content": self.value, "content": self.value,
@ -790,10 +796,13 @@ class FileQuestion(Question):
if self.value and str(self.value) == self.current_value: if self.value and str(self.value) == self.current_value:
self.value = None self.value = None
def _prevalidate(self): def _prevalidate(self):
super()._prevalidate() super()._prevalidate()
if isinstance(self.value, str) and self.value and not os.path.exists(self.value): if (
isinstance(self.value, str)
and self.value
and not os.path.exists(self.value)
):
raise YunohostValidationError( raise YunohostValidationError(
"app_argument_invalid", "app_argument_invalid",
field=self.name, field=self.name,
@ -807,10 +816,11 @@ class FileQuestion(Question):
raise YunohostValidationError( raise YunohostValidationError(
"app_argument_invalid", "app_argument_invalid",
field=self.name, field=self.name,
error=m18n.n("file_extension_not_accepted", file=filename, accept=self.accept), error=m18n.n(
"file_extension_not_accepted", file=filename, accept=self.accept
),
) )
def _post_parse_value(self): def _post_parse_value(self):
from base64 import b64decode from base64 import b64decode
@ -833,7 +843,10 @@ class FileQuestion(Question):
# i.e. os.path.join("/foo", "/etc/passwd") == "/etc/passwd" # i.e. os.path.join("/foo", "/etc/passwd") == "/etc/passwd"
file_path = os.path.normpath(upload_dir + "/" + filename) file_path = os.path.normpath(upload_dir + "/" + filename)
if not file_path.startswith(upload_dir + "/"): if not file_path.startswith(upload_dir + "/"):
raise YunohostError(f"Filename '{filename}' received from the API got a relative parent path, which is forbidden", raw_msg=True) raise YunohostError(
f"Filename '{filename}' received from the API got a relative parent path, which is forbidden",
raw_msg=True,
)
i = 2 i = 2
while os.path.exists(file_path): while os.path.exists(file_path):
file_path = os.path.normpath(upload_dir + "/" + filename + (".%d" % i)) file_path = os.path.normpath(upload_dir + "/" + filename + (".%d" % i))

View file

@ -27,11 +27,17 @@ def fix_locale(locale_file):
# should also be in the translated string, otherwise the .format # should also be in the translated string, otherwise the .format
# will trigger an exception! # will trigger an exception!
subkeys_in_ref = [k[0] for k in re.findall(r"{(\w+)(:\w)?}", string)] subkeys_in_ref = [k[0] for k in re.findall(r"{(\w+)(:\w)?}", string)]
subkeys_in_this_locale = [k[0] for k in re.findall(r"{(\w+)(:\w)?}", this_locale[key])] subkeys_in_this_locale = [
k[0] for k in re.findall(r"{(\w+)(:\w)?}", this_locale[key])
]
if set(subkeys_in_ref) != set(subkeys_in_this_locale) and (len(subkeys_in_ref) == len(subkeys_in_this_locale)): if set(subkeys_in_ref) != set(subkeys_in_this_locale) and (
len(subkeys_in_ref) == len(subkeys_in_this_locale)
):
for i, subkey in enumerate(subkeys_in_ref): for i, subkey in enumerate(subkeys_in_ref):
this_locale[key] = this_locale[key].replace('{%s}' % subkeys_in_this_locale[i], '{%s}' % subkey) this_locale[key] = this_locale[key].replace(
"{%s}" % subkeys_in_this_locale[i], "{%s}" % subkey
)
fixed_stuff = True fixed_stuff = True
if fixed_stuff: if fixed_stuff:

View file

@ -1,5 +1,6 @@
import re import re
def reformat(lang, transformations): def reformat(lang, transformations):
locale = open(f"locales/{lang}.json").read() locale = open(f"locales/{lang}.json").read()
@ -8,31 +9,52 @@ def reformat(lang, transformations):
open(f"locales/{lang}.json", "w").write(locale) open(f"locales/{lang}.json", "w").write(locale)
###################################################### ######################################################
godamn_spaces_of_hell = ["\u00a0", "\u2000", "\u2001", "\u2002", "\u2003", "\u2004", "\u2005", "\u2006", "\u2007", "\u2008", "\u2009", "\u200A", "\u202f", "\u202F", "\u3000"] godamn_spaces_of_hell = [
"\u00a0",
"\u2000",
"\u2001",
"\u2002",
"\u2003",
"\u2004",
"\u2005",
"\u2006",
"\u2007",
"\u2008",
"\u2009",
"\u200A",
"\u202f",
"\u202F",
"\u3000",
]
transformations = {s: " " for s in godamn_spaces_of_hell} transformations = {s: " " for s in godamn_spaces_of_hell}
transformations.update({ transformations.update(
"": "...", {
}) "": "...",
}
)
reformat("en", transformations) reformat("en", transformations)
###################################################### ######################################################
transformations.update({ transformations.update(
"courriel": "email", {
"e-mail": "email", "courriel": "email",
"Courriel": "Email", "e-mail": "email",
"E-mail": "Email", "Courriel": "Email",
"« ": "'", "E-mail": "Email",
"«": "'", "« ": "'",
" »": "'", "«": "'",
"»": "'", " »": "'",
"": "'", "»": "'",
#r"$(\w{1,2})'|( \w{1,2})'": r"\1\2", "": "'",
}) # r"$(\w{1,2})'|( \w{1,2})'": r"\1\2",
}
)
reformat("fr", transformations) reformat("fr", transformations)