From 2315e811fa1f418a832ca9b8f732aeb23c18e4b7 Mon Sep 17 00:00:00 2001 From: ljf Date: Mon, 30 Nov 2020 10:58:50 +0100 Subject: [PATCH 001/101] [wip] Import users with a CSV --- data/actionsmap/yunohost.yml | 17 +++++++++++++++++ src/yunohost/user.py | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index b2f5a349b..075e429ec 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -206,6 +206,23 @@ user: arguments: username: help: Username or email to get information + + ### user_import() + import: + action_help: Import several users from CSV + api: POST /users/import + arguments: + csv: + help: "CSV file with columns username, email, quota, groups(separated by coma) and optionally password" + type: open + -u: + full: --update + help: Update all existing users contained in the csv file (by default those users are ignored) + action: store_true + -d: + full: --delete + help: Delete all existing users that are not contained in the csv file (by default those users are ignored) + action: store_true subcategories: group: diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 266c2774c..7b920b8a9 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -566,6 +566,17 @@ def user_info(username): return result_dict +def user_import(csv, update=False, delete=False): + """ + Import users from CSV + + Keyword argument: + csv -- CSV file with columns username, email, quota, groups and optionnally password + + """ + logger.warning(type(csv)) + return {} + # # Group subcategory # From fdc2337e0f9ccc624ac1d293d98f5714ee8a844e Mon Sep 17 00:00:00 2001 From: ljf Date: Thu, 3 Dec 2020 18:04:09 +0100 Subject: [PATCH 002/101] [wip] Import users by csv --- src/yunohost/user.py | 95 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 7b920b8a9..a9010c060 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -566,7 +566,8 @@ def user_info(username): return result_dict -def user_import(csv, update=False, delete=False): +@is_unit_operation() +def user_import(operation_logger, csv, update=False, delete=False): """ Import users from CSV @@ -574,8 +575,96 @@ def user_import(csv, update=False, delete=False): csv -- CSV file with columns username, email, quota, groups and optionnally password """ - logger.warning(type(csv)) - return {} + import csv # CSV are needed only in this function + + # Prepare what should be done + actions = { + 'created': [], + 'updated': [], + 'deleted': [] + } + is_well_formatted = True + + existing_users = user_list()['users'].keys() + reader = csv.DictReader(csv, delimiter=';', quotechar='"') + for user in reader: + if user['username']:#TODO better check + logger.error(m18n.n('user_import_bad_line', line=reader.line_num)) + is_well_formatted = False + continue + + if user['username'] not in existing_users: + actions['created'].append(user) + else: + if update: + actions['updated'].append(user) + existing_users.remove(user['username']) + + if delete: + for user in existing_users: + actions['deleted'].append(user) + + if not is_well_formatted: + raise YunohostError('user_import_bad_file') + + total = len(actions['created'] + actions['updated'] + actions['deleted']) + + # Apply creation, update and deletion operation + result = { + 'created': 0, + 'updated': 0, + 'deleted': 0, + 'errors': 0 + } + + if total == 0: + logger.info(m18n.n('nothing_to_do')) + return + + def on_failure(user, exception): + result['errors'] += 1 + logger.error(user + ': ' + str(exception)) + + operation_logger.start() + for user in actions['created']: + try: + user_create(operation_logger, user['username'], + user['firstname'], user['lastname'], + user['domain'], user['password'], + user['mailbox_quota'], user['mail']) + result['created'] += 1 + except Exception as e: + on_failure(user['username'], e) + + if update: + for user in actions['updated']: + try: + user_update(operation_logger, user['username'], + user['firstname'], user['lastname'], + user['mail'], user['password'], + mailbox_quota=user['mailbox_quota']) + result['updated'] += 1 + except Exception as e: + on_failure(user['username'], e) + + if delete: + for user in actions['deleted']: + try: + user_delete(operation_logger, user, purge=True) + result['deleted'] += 1 + except Exception as e: + on_failure(user, e) + + if result['errors']: + msg = m18n.n('user_import_partial_failed') + if result['created'] + result['updated'] + result['deleted'] == 0: + msg = m18n.n('user_import_failed') + logger.error(msg) + operation_logger.error(msg) + else: + logger.success(m18n.n('user_import_success')) + operation_logger.success() + return result # # Group subcategory From 2ae0ec46f44a55eb98dbdca90711ab6708912604 Mon Sep 17 00:00:00 2001 From: ljf Date: Tue, 8 Dec 2020 16:47:28 +0100 Subject: [PATCH 003/101] [wip] Import users from csv --- src/yunohost/user.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index a9010c060..7745ec56a 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -588,7 +588,7 @@ def user_import(operation_logger, csv, update=False, delete=False): existing_users = user_list()['users'].keys() reader = csv.DictReader(csv, delimiter=';', quotechar='"') for user in reader: - if user['username']:#TODO better check + if re.match(r'^[a-z0-9_]+$', user['username']:#TODO better check logger.error(m18n.n('user_import_bad_line', line=reader.line_num)) is_well_formatted = False continue @@ -636,6 +636,7 @@ def user_import(operation_logger, csv, update=False, delete=False): except Exception as e: on_failure(user['username'], e) +<<<<<<< Updated upstream if update: for user in actions['updated']: try: @@ -654,6 +655,24 @@ def user_import(operation_logger, csv, update=False, delete=False): result['deleted'] += 1 except Exception as e: on_failure(user, e) +======= + for user in actions['updated']: + try: + user_update(operation_logger, user['username'], + user['firstname'], user['lastname'], + user['mail'], user['password'], + mailbox_quota=user['mailbox_quota']) + result['updated'] += 1 + except Exception as e: + on_failure(user['username'], e) + + for user in actions['deleted']: + try: + user_delete(operation_logger, user, purge=True) + result['deleted'] += 1 + except Exception as e: + on_failure(user, e) +>>>>>>> Stashed changes if result['errors']: msg = m18n.n('user_import_partial_failed') From 3e047c4b943881c1e8a14311006773cc583893bb Mon Sep 17 00:00:00 2001 From: ljf Date: Sun, 13 Dec 2020 03:24:18 +0100 Subject: [PATCH 004/101] [fix] CSV import --- data/actionsmap/yunohost.yml | 2 +- locales/en.json | 5 + src/yunohost/log.py | 3 + src/yunohost/user.py | 265 ++++++++++++++++++++++------------- 4 files changed, 173 insertions(+), 102 deletions(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index 075e429ec..a3ff431e7 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -212,7 +212,7 @@ user: action_help: Import several users from CSV api: POST /users/import arguments: - csv: + csvfile: help: "CSV file with columns username, email, quota, groups(separated by coma) and optionally password" type: open -u: diff --git a/locales/en.json b/locales/en.json index 938a38e20..367183a8a 100644 --- a/locales/en.json +++ b/locales/en.json @@ -400,6 +400,7 @@ "log_regen_conf": "Regenerate system configurations '{}'", "log_user_create": "Add '{}' user", "log_user_delete": "Delete '{}' user", + "log_user_import": "Import users", "log_user_group_create": "Create '{}' group", "log_user_group_delete": "Delete '{}' group", "log_user_group_update": "Update '{}' group", @@ -630,6 +631,10 @@ "user_unknown": "Unknown user: {user:s}", "user_update_failed": "Could not update user {user}: {error}", "user_updated": "User info changed", + "user_import_bad_line": "Incorrect line {line}: {details} ", + "user_import_partial_failed": "The users import operation partially failed", + "user_import_failed": "The users import operation completely failed", + "user_import_success": "Users have been imported", "yunohost_already_installed": "YunoHost is already installed", "yunohost_configured": "YunoHost is now configured", "yunohost_installing": "Installing YunoHost...", diff --git a/src/yunohost/log.py b/src/yunohost/log.py index f8da40002..9ea2c2024 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -371,6 +371,9 @@ def is_unit_operation( for field in exclude: if field in context: context.pop(field, None) + for field, value in context.items(): + if isinstance(value, file): + context[field] = value.name operation_logger = OperationLogger(op_key, related_to, args=context) try: diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 7745ec56a..0489a34fa 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -99,6 +99,7 @@ def user_create( password, mailbox_quota="0", mail=None, + imported=False ): from yunohost.domain import domain_list, _get_maindomain @@ -167,7 +168,8 @@ def user_create( if mail in aliases: raise YunohostValidationError("mail_unavailable") - operation_logger.start() + if not imported: + operation_logger.start() # Get random UID/GID all_uid = {str(x.pw_uid) for x in pwd.getpwall()} @@ -247,13 +249,14 @@ def user_create( hook_callback("post_user_create", args=[username, mail], env=env_dict) # TODO: Send a welcome mail to user - logger.success(m18n.n("user_created")) + if not imported: + logger.success(m18n.n('user_created')) return {"fullname": fullname, "username": username, "mail": mail} -@is_unit_operation([("username", "user")]) -def user_delete(operation_logger, username, purge=False): +@is_unit_operation([('username', 'user')]) +def user_delete(operation_logger, username, purge=False, imported=False): """ Delete user @@ -268,7 +271,8 @@ def user_delete(operation_logger, username, purge=False): if username not in user_list()["users"]: raise YunohostValidationError("user_unknown", user=username) - operation_logger.start() + if not imported: + operation_logger.start() user_group_update("all_users", remove=username, force=True, sync_perm=False) for group, infos in user_group_list()["groups"].items(): @@ -295,13 +299,13 @@ def user_delete(operation_logger, username, purge=False): subprocess.call(["nscd", "-i", "passwd"]) if purge: - subprocess.call(["rm", "-rf", "/home/{0}".format(username)]) - subprocess.call(["rm", "-rf", "/var/mail/{0}".format(username)]) + subprocess.call(['rm', '-rf', '/home/{0}'.format(username)]) + subprocess.call(['rm', '-rf', '/var/mail/{0}'.format(username)]) - hook_callback("post_user_delete", args=[username, purge]) - - logger.success(m18n.n("user_deleted")) + hook_callback('post_user_delete', args=[username, purge]) + if not imported: + logger.success(m18n.n('user_deleted')) @is_unit_operation([("username", "user")], exclude=["change_password"]) def user_update( @@ -316,6 +320,7 @@ def user_update( add_mailalias=None, remove_mailalias=None, mailbox_quota=None, + imported=False ): """ Update user informations @@ -394,34 +399,38 @@ def user_update( "admin@" + main_domain, "webmaster@" + main_domain, "postmaster@" + main_domain, + 'abuse@' + main_domain, ] - try: - ldap.validate_uniqueness({"mail": mail}) - except Exception as e: - raise YunohostValidationError("user_update_failed", user=username, error=e) - if mail[mail.find("@") + 1 :] not in domains: - raise YunohostValidationError( - "mail_domain_unknown", domain=mail[mail.find("@") + 1 :] - ) + if mail in user['mail']: + user['mail'].remove(mail) + else: + try: + ldap.validate_uniqueness({'mail': mail}) + except Exception as e: + raise YunohostError('user_update_failed', user=username, error=e) + if mail[mail.find('@') + 1:] not in domains: + raise YunohostError('mail_domain_unknown', domain=mail[mail.find('@') + 1:]) if mail in aliases: raise YunohostValidationError("mail_unavailable") - del user["mail"][0] - new_attr_dict["mail"] = [mail] + user["mail"] + new_attr_dict['mail'] = [mail] + user['mail'][1:] if add_mailalias: if not isinstance(add_mailalias, list): add_mailalias = [add_mailalias] for mail in add_mailalias: - try: - ldap.validate_uniqueness({"mail": mail}) - except Exception as e: - raise YunohostValidationError( - "user_update_failed", user=username, error=e - ) - if mail[mail.find("@") + 1 :] not in domains: - raise YunohostValidationError( - "mail_domain_unknown", domain=mail[mail.find("@") + 1 :] + if mail in user["mail"]: + user["mail"].remove(mail) + else: + try: + ldap.validate_uniqueness({"mail": mail}) + except Exception as e: + raise YunohostError( + "user_update_failed", user=username, error=e + ) + if mail[mail.find("@") + 1:] not in domains: + raise YunohostError( + "mail_domain_unknown", domain=mail[mail.find("@") + 1:] ) user["mail"].append(mail) new_attr_dict["mail"] = user["mail"] @@ -465,7 +474,8 @@ def user_update( new_attr_dict["mailuserquota"] = [mailbox_quota] env_dict["YNH_USER_MAILQUOTA"] = mailbox_quota - operation_logger.start() + if not imported: + operation_logger.start() try: ldap.update("uid=%s,ou=users" % username, new_attr_dict) @@ -475,9 +485,10 @@ def user_update( # Trigger post_user_update hooks hook_callback("post_user_update", env=env_dict) - logger.success(m18n.n("user_updated")) - app_ssowatconf() - return user_info(username) + if not imported: + app_ssowatconf() + logger.success(m18n.n('user_updated')) + return user_info(username) def user_info(username): @@ -507,11 +518,13 @@ def user_info(username): raise YunohostValidationError("user_unknown", user=username) result_dict = { - "username": user["uid"][0], - "fullname": user["cn"][0], - "firstname": user["givenName"][0], - "lastname": user["sn"][0], - "mail": user["mail"][0], + 'username': user['uid'][0], + 'fullname': user['cn'][0], + 'firstname': user['givenName'][0], + 'lastname': user['sn'][0], + 'mail': user['mail'][0], + 'mail-aliases': [], + 'mail-forward': [] } if len(user["mail"]) > 1: @@ -567,7 +580,7 @@ def user_info(username): @is_unit_operation() -def user_import(operation_logger, csv, update=False, delete=False): +def user_import(operation_logger, csvfile, update=False, delete=False): """ Import users from CSV @@ -576,24 +589,51 @@ def user_import(operation_logger, csv, update=False, delete=False): """ import csv # CSV are needed only in this function - - # Prepare what should be done + from moulinette.utils.text import random_ascii + from yunohost.permission import permission_sync_to_user + from yunohost.app import app_ssowatconf + # Pre-validate data and prepare what should be done actions = { 'created': [], 'updated': [], 'deleted': [] } is_well_formatted = True - + validators = { + 'username': r'^[a-z0-9_]+$', + 'firstname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', #FIXME Merge first and lastname and support more name (arabish, chinese...) + 'lastname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', + 'password': r'^|(.{3,})$', + 'mailbox_quota': r'^(\d+[bkMGT])|0$', + 'mail': r'^([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}))$', + 'alias': r'^|([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', + 'forward': r'^|([\w\+.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', + 'groups': r'^|([a-z0-9_]+(,?[a-z0-9_]+)*)$' + } + def to_list(str_list): + return str_list.split(',') if str_list else [] existing_users = user_list()['users'].keys() - reader = csv.DictReader(csv, delimiter=';', quotechar='"') + reader = csv.DictReader(csvfile, delimiter=';', quotechar='"') for user in reader: - if re.match(r'^[a-z0-9_]+$', user['username']:#TODO better check - logger.error(m18n.n('user_import_bad_line', line=reader.line_num)) + format_errors = [key + ':' + user[key] + for key, validator in validators.items() + if not re.match(validator, user[key])] + if format_errors: + logger.error(m18n.n('user_import_bad_line', + line=reader.line_num, + details=', '.join(format_errors))) is_well_formatted = False continue + user['groups'] = to_list(user['groups']) + user['alias'] = to_list(user['alias']) + user['forward'] = to_list(user['forward']) + user['domain'] = user['mail'].split('@')[1] if user['username'] not in existing_users: + # Generate password if not exists + # This could be used when reset password will be merged + if not user['password']: + user['password'] = random_ascii(70) actions['created'].append(user) else: if update: @@ -609,6 +649,10 @@ def user_import(operation_logger, csv, update=False, delete=False): total = len(actions['created'] + actions['updated'] + actions['deleted']) + if total == 0: + logger.info(m18n.n('nothing_to_do')) + return + # Apply creation, update and deletion operation result = { 'created': 0, @@ -617,62 +661,71 @@ def user_import(operation_logger, csv, update=False, delete=False): 'errors': 0 } - if total == 0: - logger.info(m18n.n('nothing_to_do')) - return - def on_failure(user, exception): result['errors'] += 1 logger.error(user + ': ' + str(exception)) + def update(user, created=False): + remove_alias = None + remove_forward = None + if not created: + info = user_info(user['username']) + user['mail'] = None if info['mail'] == user['mail'] else user['mail'] + remove_alias = list(set(info['mail-aliases']) - set(user['alias'])) + remove_forward = list(set(info['mail-forward']) - set(user['forward'])) + user['alias'] = list(set(user['alias']) - set(info['mail-aliases'])) + user['forward'] = list(set(user['forward']) - set(info['mail-forward'])) + for group, infos in user_group_list()["groups"].items(): + if group == "all_users": + continue + # If the user is in this group (and it's not the primary group), + # remove the member from the group + if user['username'] != group and user['username'] in infos["members"]: + user_group_update(group, remove=user['username'], sync_perm=False, imported=True) + + user_update(user['username'], + user['firstname'], user['lastname'], + user['mail'], user['password'], + mailbox_quota=user['mailbox_quota'], + mail=user['mail'], add_mailalias=user['alias'], + remove_mailalias=remove_alias, + remove_mailforward=remove_forward, + add_mailforward=user['forward'], imported=True) + + for group in user['groups']: + user_group_update(group, add=user['username'], sync_perm=False, imported=True) + operation_logger.start() - for user in actions['created']: - try: - user_create(operation_logger, user['username'], - user['firstname'], user['lastname'], - user['domain'], user['password'], - user['mailbox_quota'], user['mail']) - result['created'] += 1 - except Exception as e: - on_failure(user['username'], e) - -<<<<<<< Updated upstream - if update: - for user in actions['updated']: - try: - user_update(operation_logger, user['username'], - user['firstname'], user['lastname'], - user['mail'], user['password'], - mailbox_quota=user['mailbox_quota']) - result['updated'] += 1 - except Exception as e: - on_failure(user['username'], e) - - if delete: - for user in actions['deleted']: - try: - user_delete(operation_logger, user, purge=True) - result['deleted'] += 1 - except Exception as e: - on_failure(user, e) -======= - for user in actions['updated']: - try: - user_update(operation_logger, user['username'], - user['firstname'], user['lastname'], - user['mail'], user['password'], - mailbox_quota=user['mailbox_quota']) - result['updated'] += 1 - except Exception as e: - on_failure(user['username'], e) - + # We do delete and update before to avoid mail uniqueness issues for user in actions['deleted']: try: - user_delete(operation_logger, user, purge=True) + user_delete(user, purge=True, imported=True) result['deleted'] += 1 - except Exception as e: + except YunohostError as e: on_failure(user, e) ->>>>>>> Stashed changes + + for user in actions['updated']: + try: + update(user) + result['updated'] += 1 + except YunohostError as e: + on_failure(user['username'], e) + + for user in actions['created']: + try: + user_create(user['username'], + user['firstname'], user['lastname'], + user['domain'], user['password'], + user['mailbox_quota'], imported=True) + update(user, created=True) + result['created'] += 1 + except YunohostError as e: + on_failure(user['username'], e) + + + + permission_sync_to_user() + app_ssowatconf() if result['errors']: msg = m18n.n('user_import_partial_failed') @@ -685,6 +738,7 @@ def user_import(operation_logger, csv, update=False, delete=False): operation_logger.success() return result + # # Group subcategory # @@ -857,9 +911,15 @@ def user_group_delete(operation_logger, groupname, force=False, sync_perm=True): logger.debug(m18n.n("group_deleted", group=groupname)) -@is_unit_operation([("groupname", "group")]) +@is_unit_operation([('groupname', 'group')]) def user_group_update( - operation_logger, groupname, add=None, remove=None, force=False, sync_perm=True + operation_logger, + groupname, + add=None, + remove=None, + force=False, + sync_perm=True, + imported=False ): """ Update user informations @@ -929,7 +989,8 @@ def user_group_update( ] if set(new_group) != set(current_group): - operation_logger.start() + if not imported: + operation_logger.start() ldap = _get_ldap_interface() try: ldap.update( @@ -939,14 +1000,16 @@ def user_group_update( except Exception as e: raise YunohostError("group_update_failed", group=groupname, error=e) - if groupname != "all_users": - logger.success(m18n.n("group_updated", group=groupname)) - else: - logger.debug(m18n.n("group_updated", group=groupname)) - if sync_perm: permission_sync_to_user() - return user_group_info(groupname) + + if not imported: + if groupname != "all_users": + logger.success(m18n.n("group_updated", group=groupname)) + else: + logger.debug(m18n.n("group_updated", group=groupname)) + + return user_group_info(groupname) def user_group_info(groupname): From 9e2f4a56f33ded262d6beb2dcf260e194807f905 Mon Sep 17 00:00:00 2001 From: ljf Date: Sun, 20 Dec 2020 23:13:22 +0100 Subject: [PATCH 005/101] [enh] Add export feature and refactor user_list --- data/actionsmap/yunohost.yml | 7 +- locales/en.json | 5 +- src/yunohost/user.py | 164 +++++++++++++++++++++++++---------- 3 files changed, 129 insertions(+), 47 deletions(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index a3ff431e7..a5fdf5872 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -67,7 +67,7 @@ user: api: GET /users arguments: --fields: - help: fields to fetch + help: fields to fetch (username, fullname, mail, mail-alias, mail-forward, mailbox-quota, groups, shell, home-path) nargs: "+" ### user_create() @@ -207,6 +207,11 @@ user: username: help: Username or email to get information + ### user_export() + export: + action_help: Export users into CSV + api: GET /users/export + ### user_import() import: action_help: Import several users from CSV diff --git a/locales/en.json b/locales/en.json index 367183a8a..6a092d108 100644 --- a/locales/en.json +++ b/locales/en.json @@ -631,9 +631,12 @@ "user_unknown": "Unknown user: {user:s}", "user_update_failed": "Could not update user {user}: {error}", "user_updated": "User info changed", - "user_import_bad_line": "Incorrect line {line}: {details} ", + "user_import_bad_line": "Incorrect line {line}: {details}", + "user_import_bad_file": "Your CSV file is not correctly formatted it will be ignored to avoid potential data loss", + "user_import_missing_column": "The column {column} is missing", "user_import_partial_failed": "The users import operation partially failed", "user_import_failed": "The users import operation completely failed", + "user_import_nothing_to_do": "No user needs to be imported", "user_import_success": "Users have been imported", "yunohost_already_installed": "YunoHost is already installed", "yunohost_configured": "YunoHost is now configured", diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 0489a34fa..0fae9cf43 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -48,27 +48,48 @@ def user_list(fields=None): from yunohost.utils.ldap import _get_ldap_interface - user_attrs = { - "uid": "username", - "cn": "fullname", - "mail": "mail", - "maildrop": "mail-forward", - "homeDirectory": "home_path", - "mailuserquota": "mailbox-quota", + ldap_attrs = { + 'username': 'uid', + 'password': 'uid', + 'fullname': 'cn', + 'firstname': 'givenName', + 'lastname': 'sn', + 'mail': 'mail', + 'mail-alias': 'mail', + 'mail-forward': 'maildrop', + 'mailbox-quota': 'mailuserquota', + 'groups': 'memberOf', + 'shell': 'loginShell', + 'home-path': 'homeDirectory' } - attrs = ["uid"] + def display_default(values, _): + return values[0] if len(values) == 1 else values + + display = { + 'password': lambda values, user: '', + 'mail': lambda values, user: display_default(values[:1], user), + 'mail-alias': lambda values, _: values[1:], + 'mail-forward': lambda values, user: [forward for forward in values if forward != user['uid'][0]], + 'groups': lambda values, user: [ + group[3:].split(',')[0] + for group in values + if not group.startswith('cn=all_users,') and + not group.startswith('cn=' + user['uid'][0] + ',')], + 'shell': lambda values, _: len(values) > 0 and values[0].strip() == "/bin/false" + } + + attrs = set(['uid']) users = {} - if fields: - keys = user_attrs.keys() - for attr in fields: - if attr in keys: - attrs.append(attr) - else: - raise YunohostError("field_invalid", attr) - else: - attrs = ["uid", "cn", "mail", "mailuserquota"] + if not fields: + fields = ['username', 'fullname', 'mail', 'mailbox-quota', 'shell'] + + for field in fields: + if field in ldap_attrs: + attrs|=set([ldap_attrs[field]]) + else: + raise YunohostError('field_invalid', field) ldap = _get_ldap_interface() result = ldap.search( @@ -79,12 +100,13 @@ def user_list(fields=None): for user in result: entry = {} - for attr, values in user.items(): - if values: - entry[user_attrs[attr]] = values[0] + for field in fields: + values = [] + if ldap_attrs[field] in user: + values = user[ldap_attrs[field]] + entry[field] = display.get(field, display_default)(values, user) - uid = entry[user_attrs["uid"]] - users[uid] = entry + users[entry['username']] = entry return {"users": users} @@ -579,13 +601,49 @@ def user_info(username): return result_dict +def user_export(): + """ + Export users into CSV + + Keyword argument: + csv -- CSV file with columns username;firstname;lastname;password;mailbox_quota;mail;alias;forward;groups + + """ + import csv # CSV are needed only in this function + from io import BytesIO + fieldnames = [u'username', u'firstname', u'lastname', u'password', u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', u'groups'] + with BytesIO() as csv_io: + writer = csv.DictWriter(csv_io, fieldnames, delimiter=';', quotechar='"') + writer.writeheader() + users = user_list(fieldnames)['users'] + for username, user in users.items(): + user['mail-alias'] = ','.join(user['mail-alias']) + user['mail-forward'] = ','.join(user['mail-forward']) + user['groups'] = ','.join(user['groups']) + writer.writerow(user) + + body = csv_io.getvalue() + if msettings.get('interface') == 'api': + # We return a raw bottle HTTPresponse (instead of serializable data like + # list/dict, ...), which is gonna be picked and used directly by moulinette + from bottle import LocalResponse + response = LocalResponse(body=body, + headers={ + "Content-Disposition": "attachment; filename='users.csv'", + "Content-Type": "text/csv", + } + ) + return response + else: + return body + @is_unit_operation() def user_import(operation_logger, csvfile, update=False, delete=False): """ Import users from CSV Keyword argument: - csv -- CSV file with columns username, email, quota, groups and optionnally password + csv -- CSV file with columns username;firstname;lastname;password;mailbox_quota;mail;alias;forward;groups """ import csv # CSV are needed only in this function @@ -604,20 +662,35 @@ def user_import(operation_logger, csvfile, update=False, delete=False): 'firstname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', #FIXME Merge first and lastname and support more name (arabish, chinese...) 'lastname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', 'password': r'^|(.{3,})$', - 'mailbox_quota': r'^(\d+[bkMGT])|0$', 'mail': r'^([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}))$', - 'alias': r'^|([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', - 'forward': r'^|([\w\+.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', + 'mail-alias': r'^|([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', + 'mail-forward': r'^|([\w\+.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', + 'mailbox-quota': r'^(\d+[bkMGT])|0$', 'groups': r'^|([a-z0-9_]+(,?[a-z0-9_]+)*)$' } + def to_list(str_list): return str_list.split(',') if str_list else [] - existing_users = user_list()['users'].keys() + + existing_users = user_list()['users'] + past_lines = [] reader = csv.DictReader(csvfile, delimiter=';', quotechar='"') for user in reader: - format_errors = [key + ':' + user[key] - for key, validator in validators.items() - if not re.match(validator, user[key])] + # Validation + try: + format_errors = [key + ':' + str(user[key]) + for key, validator in validators.items() + if user[key] is None or not re.match(validator, user[key])] + except KeyError, e: + logger.error(m18n.n('user_import_missing_column', + column=str(e))) + is_well_formatted = False + break + + if 'username' in user: + if user['username'] in past_lines: + format_errors.append('username: %s (duplicated)' % user['username']) + past_lines.append(user['username']) if format_errors: logger.error(m18n.n('user_import_bad_line', line=reader.line_num, @@ -625,9 +698,10 @@ def user_import(operation_logger, csvfile, update=False, delete=False): is_well_formatted = False continue + # Choose what to do with this line and prepare data user['groups'] = to_list(user['groups']) - user['alias'] = to_list(user['alias']) - user['forward'] = to_list(user['forward']) + user['mail-alias'] = to_list(user['mail-alias']) + user['mail-forward'] = to_list(user['mail-forward']) user['domain'] = user['mail'].split('@')[1] if user['username'] not in existing_users: # Generate password if not exists @@ -638,7 +712,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): else: if update: actions['updated'].append(user) - existing_users.remove(user['username']) + del existing_users[user['username']] if delete: for user in existing_users: @@ -650,7 +724,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): total = len(actions['created'] + actions['updated'] + actions['deleted']) if total == 0: - logger.info(m18n.n('nothing_to_do')) + logger.info(m18n.n('user_import_nothing_to_do')) return # Apply creation, update and deletion operation @@ -665,14 +739,13 @@ def user_import(operation_logger, csvfile, update=False, delete=False): result['errors'] += 1 logger.error(user + ': ' + str(exception)) - def update(user, created=False): + def update(user, info=False): remove_alias = None remove_forward = None - if not created: - info = user_info(user['username']) + if info: user['mail'] = None if info['mail'] == user['mail'] else user['mail'] - remove_alias = list(set(info['mail-aliases']) - set(user['alias'])) - remove_forward = list(set(info['mail-forward']) - set(user['forward'])) + remove_alias = list(set(info['mail-aliases']) - set(user['mail-alias'])) + remove_forward = list(set(info['mail-forward']) - set(user['mail-forward'])) user['alias'] = list(set(user['alias']) - set(info['mail-aliases'])) user['forward'] = list(set(user['forward']) - set(info['mail-forward'])) for group, infos in user_group_list()["groups"].items(): @@ -686,15 +759,16 @@ def user_import(operation_logger, csvfile, update=False, delete=False): user_update(user['username'], user['firstname'], user['lastname'], user['mail'], user['password'], - mailbox_quota=user['mailbox_quota'], - mail=user['mail'], add_mailalias=user['alias'], + mailbox_quota=user['mailbox-quota'], + mail=user['mail'], add_mailalias=user['mail-alias'], remove_mailalias=remove_alias, remove_mailforward=remove_forward, - add_mailforward=user['forward'], imported=True) + add_mailforward=user['mail-forward'], imported=True) for group in user['groups']: user_group_update(group, add=user['username'], sync_perm=False, imported=True) + users = user_list()['users'] operation_logger.start() # We do delete and update before to avoid mail uniqueness issues for user in actions['deleted']: @@ -706,7 +780,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): for user in actions['updated']: try: - update(user) + update(user, users[user['username']]) result['updated'] += 1 except YunohostError as e: on_failure(user['username'], e) @@ -716,8 +790,8 @@ def user_import(operation_logger, csvfile, update=False, delete=False): user_create(user['username'], user['firstname'], user['lastname'], user['domain'], user['password'], - user['mailbox_quota'], imported=True) - update(user, created=True) + user['mailbox-quota'], imported=True) + update(user) result['created'] += 1 except YunohostError as e: on_failure(user['username'], e) From fd06430e8f1a93f5b3236bbe0b48d9ca6e574b07 Mon Sep 17 00:00:00 2001 From: ljf Date: Mon, 21 Dec 2020 02:29:17 +0100 Subject: [PATCH 006/101] [fix] Import user with update mode some unit test --- src/yunohost/tests/test_user-group.py | 64 +++++++++++++++++++++++++ src/yunohost/user.py | 69 ++++++++++++--------------- 2 files changed, 94 insertions(+), 39 deletions(-) diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index 251029796..e83425df9 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -1,5 +1,6 @@ import pytest +<<<<<<< HEAD from .conftest import message, raiseYunohostError from yunohost.user import ( @@ -8,6 +9,10 @@ from yunohost.user import ( user_create, user_delete, user_update, + user_import, + user_export, + CSV_FIELDNAMES, + FIRST_ALIASES, user_group_list, user_group_create, user_group_delete, @@ -110,6 +115,65 @@ def test_del_user(mocker): assert "alice" not in group_res["all_users"]["members"] +def test_import_user(mocker): + import csv + from io import BytesIO + fieldnames = [u'username', u'firstname', u'lastname', u'password', + u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', + u'groups'] + with BytesIO() as csv_io: + writer = csv.DictWriter(csv_io, fieldnames, delimiter=';', + quotechar='"') + writer.writeheader() + writer.writerow({ + 'username': "albert", + 'firstname': "Albert", + 'lastname': "Good", + 'password': "", + 'mailbox-quota': "1G", + 'mail': "albert@" + maindomain, + 'mail-alias': "albert2@" + maindomain, + 'mail-forward': "albert@example.com", + 'groups': "dev", + }) + writer.writerow({ + 'username': "alice", + 'firstname': "Alice", + 'lastname': "White", + 'password': "", + 'mailbox-quota': "1G", + 'mail': "alice@" + maindomain, + 'mail-alias': "alice1@" + maindomain + ",alice2@" + maindomain, + 'mail-forward': "", + 'groups': "apps", + }) + csv_io.seek(0) + with message(mocker, "user_import_success"): + user_import(csv_io, update=True, delete=True) + + group_res = user_group_list()['groups'] + user_res = user_list(CSV_FIELDNAMES)['users'] + assert "albert" in user_res + assert "alice" in user_res + assert "bob" not in user_res + assert len(user_res['alice']['mail-alias']) == 2 + assert "albert" in group_res['dev']['members'] + assert "alice" in group_res['apps']['members'] + + +def test_export_user(mocker): + result = user_export() + should_be = "username;firstname;lastname;password;" + should_be += "mailbox-quota;mail;mail-alias;mail-forward;groups" + should_be += "\r\nbob;Bob;Snow;;0;bob@" + maindomain + ";;;apps" + should_be += "\r\nalice;Alice;White;;0;alice@" + maindomain + ";" + should_be += ','.join([alias + maindomain for alias in FIRST_ALIASES]) + should_be += ";;dev" + should_be += "\r\njack;Jack;Black;;0;jack@" + maindomain + ";;;" + + assert result == should_be + + def test_create_group(mocker): with message(mocker, "group_created", group="adminsys"): diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 0fae9cf43..0bcce9cbc 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -43,6 +43,19 @@ from yunohost.log import is_unit_operation logger = getActionLogger("yunohost.user") +CSV_FIELDNAMES = [u'username', u'firstname', u'lastname', u'password', u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', u'groups'] +VALIDATORS = { + 'username': r'^[a-z0-9_]+$', + 'firstname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', #FIXME Merge first and lastname and support more name (arabish, chinese...) + 'lastname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', + 'password': r'^|(.{3,})$', + 'mail': r'^([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}))$', + 'mail-alias': r'^|([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', + 'mail-forward': r'^|([\w\+.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', + 'mailbox-quota': r'^(\d+[bkMGT])|0$', + 'groups': r'^|([a-z0-9_]+(,?[a-z0-9_]+)*)$' +} +FIRST_ALIASES = ['root@', 'admin@', 'webmaster@', 'postmaster@', 'abuse@'] def user_list(fields=None): @@ -87,7 +100,7 @@ def user_list(fields=None): for field in fields: if field in ldap_attrs: - attrs|=set([ldap_attrs[field]]) + attrs |= set([ldap_attrs[field]]) else: raise YunohostError('field_invalid', field) @@ -179,13 +192,7 @@ def user_create( raise YunohostValidationError("system_username_exists") main_domain = _get_maindomain() - aliases = [ - "root@" + main_domain, - "admin@" + main_domain, - "webmaster@" + main_domain, - "postmaster@" + main_domain, - "abuse@" + main_domain, - ] + aliases = [alias + main_domain for alias in FIRST_ALIASES] if mail in aliases: raise YunohostValidationError("mail_unavailable") @@ -416,13 +423,8 @@ def user_update( if mail: main_domain = _get_maindomain() - aliases = [ - "root@" + main_domain, - "admin@" + main_domain, - "webmaster@" + main_domain, - "postmaster@" + main_domain, - 'abuse@' + main_domain, - ] + aliases = [alias + main_domain for alias in FIRST_ALIASES] + if mail in user['mail']: user['mail'].remove(mail) else: @@ -606,23 +608,23 @@ def user_export(): Export users into CSV Keyword argument: - csv -- CSV file with columns username;firstname;lastname;password;mailbox_quota;mail;alias;forward;groups + csv -- CSV file with columns username;firstname;lastname;password;mailbox-quota;mail;mail-alias;mail-forward;groups """ - import csv # CSV are needed only in this function + import csv # CSV are needed only in this function from io import BytesIO - fieldnames = [u'username', u'firstname', u'lastname', u'password', u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', u'groups'] with BytesIO() as csv_io: - writer = csv.DictWriter(csv_io, fieldnames, delimiter=';', quotechar='"') + writer = csv.DictWriter(csv_io, CSV_FIELDNAMES, + delimiter=';', quotechar='"') writer.writeheader() - users = user_list(fieldnames)['users'] + users = user_list(CSV_FIELDNAMES)['users'] for username, user in users.items(): user['mail-alias'] = ','.join(user['mail-alias']) user['mail-forward'] = ','.join(user['mail-forward']) user['groups'] = ','.join(user['groups']) writer.writerow(user) - body = csv_io.getvalue() + body = csv_io.getvalue().rstrip() if msettings.get('interface') == 'api': # We return a raw bottle HTTPresponse (instead of serializable data like # list/dict, ...), which is gonna be picked and used directly by moulinette @@ -631,12 +633,12 @@ def user_export(): headers={ "Content-Disposition": "attachment; filename='users.csv'", "Content-Type": "text/csv", - } - ) + }) return response else: return body + @is_unit_operation() def user_import(operation_logger, csvfile, update=False, delete=False): """ @@ -657,17 +659,6 @@ def user_import(operation_logger, csvfile, update=False, delete=False): 'deleted': [] } is_well_formatted = True - validators = { - 'username': r'^[a-z0-9_]+$', - 'firstname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', #FIXME Merge first and lastname and support more name (arabish, chinese...) - 'lastname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', - 'password': r'^|(.{3,})$', - 'mail': r'^([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}))$', - 'mail-alias': r'^|([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', - 'mail-forward': r'^|([\w\+.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', - 'mailbox-quota': r'^(\d+[bkMGT])|0$', - 'groups': r'^|([a-z0-9_]+(,?[a-z0-9_]+)*)$' - } def to_list(str_list): return str_list.split(',') if str_list else [] @@ -679,7 +670,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): # Validation try: format_errors = [key + ':' + str(user[key]) - for key, validator in validators.items() + for key, validator in VALIDATORS.items() if user[key] is None or not re.match(validator, user[key])] except KeyError, e: logger.error(m18n.n('user_import_missing_column', @@ -744,10 +735,10 @@ def user_import(operation_logger, csvfile, update=False, delete=False): remove_forward = None if info: user['mail'] = None if info['mail'] == user['mail'] else user['mail'] - remove_alias = list(set(info['mail-aliases']) - set(user['mail-alias'])) + remove_alias = list(set(info['mail-alias']) - set(user['mail-alias'])) remove_forward = list(set(info['mail-forward']) - set(user['mail-forward'])) - user['alias'] = list(set(user['alias']) - set(info['mail-aliases'])) - user['forward'] = list(set(user['forward']) - set(info['mail-forward'])) + user['mail-alias'] = list(set(user['mail-alias']) - set(info['mail-alias'])) + user['mail-forward'] = list(set(user['mail-forward']) - set(info['mail-forward'])) for group, infos in user_group_list()["groups"].items(): if group == "all_users": continue @@ -768,7 +759,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): for group in user['groups']: user_group_update(group, add=user['username'], sync_perm=False, imported=True) - users = user_list()['users'] + users = user_list(CSV_FIELDNAMES)['users'] operation_logger.start() # We do delete and update before to avoid mail uniqueness issues for user in actions['deleted']: From 57dcf45a7c838d2fecb633a1f1f2f04929b305ce Mon Sep 17 00:00:00 2001 From: ljf Date: Mon, 21 Dec 2020 03:40:20 +0100 Subject: [PATCH 007/101] [fix] User import unit test --- src/yunohost/log.py | 3 +++ src/yunohost/tests/test_user-group.py | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 9ea2c2024..a8a3281d2 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -32,6 +32,7 @@ import psutil from datetime import datetime, timedelta from logging import FileHandler, getLogger, Formatter +from io import IOBase from moulinette import m18n, msettings from moulinette.core import MoulinetteError @@ -374,6 +375,8 @@ def is_unit_operation( for field, value in context.items(): if isinstance(value, file): context[field] = value.name + elif isinstance(value, IOBase): + context[field] = 'IOBase' operation_logger = OperationLogger(op_key, related_to, args=context) try: diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index e83425df9..3252f0ef8 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -1,6 +1,5 @@ import pytest -<<<<<<< HEAD from .conftest import message, raiseYunohostError from yunohost.user import ( @@ -27,7 +26,7 @@ maindomain = "" def clean_user_groups(): for u in user_list()["users"]: - user_delete(u) + user_delete(u, purge=True) for g in user_group_list()["groups"]: if g not in ["all_users", "visitors"]: From c7c29285795c6823eaaa074e2f163af9136bb0a3 Mon Sep 17 00:00:00 2001 From: ljf Date: Mon, 21 Dec 2020 04:27:03 +0100 Subject: [PATCH 008/101] [fix] Column list --- data/actionsmap/yunohost.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index a5fdf5872..4ef9ad008 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -218,7 +218,7 @@ user: api: POST /users/import arguments: csvfile: - help: "CSV file with columns username, email, quota, groups(separated by coma) and optionally password" + help: "CSV file with columns username, firstname, lastname, password, mail, mailbox-quota, mail-alias, mail-forward, groups (separated by coma)" type: open -u: full: --update From 59d7e2f247687143d3cc6fca462e5557e9e37621 Mon Sep 17 00:00:00 2001 From: ljf Date: Mon, 21 Dec 2020 04:27:23 +0100 Subject: [PATCH 009/101] [fix] LDAP Size limits --- data/templates/slapd/slapd.ldif | 1 + 1 file changed, 1 insertion(+) diff --git a/data/templates/slapd/slapd.ldif b/data/templates/slapd/slapd.ldif index d3ed2e053..8692d2664 100644 --- a/data/templates/slapd/slapd.ldif +++ b/data/templates/slapd/slapd.ldif @@ -33,6 +33,7 @@ olcAuthzPolicy: none olcConcurrency: 0 olcConnMaxPending: 100 olcConnMaxPendingAuth: 1000 +olcSizeLimit: 10000 olcIdleTimeout: 0 olcIndexSubstrIfMaxLen: 4 olcIndexSubstrIfMinLen: 2 From 8e2f1c696b191b06d40a1646699d81f758aa1d6a Mon Sep 17 00:00:00 2001 From: ljf Date: Mon, 21 Dec 2020 04:27:50 +0100 Subject: [PATCH 010/101] [fix] Home not created --- locales/en.json | 2 +- src/yunohost/user.py | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/locales/en.json b/locales/en.json index 6a092d108..faa9e4556 100644 --- a/locales/en.json +++ b/locales/en.json @@ -627,7 +627,7 @@ "user_creation_failed": "Could not create user {user}: {error}", "user_deleted": "User deleted", "user_deletion_failed": "Could not delete user {user}: {error}", - "user_home_creation_failed": "Could not create 'home' folder for user", + "user_home_creation_failed": "Could not create '{home}' folder for user", "user_unknown": "Unknown user: {user:s}", "user_update_failed": "Could not update user {user}: {error}", "user_updated": "User info changed", diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 0bcce9cbc..0680af89d 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -254,6 +254,10 @@ def user_create( except subprocess.CalledProcessError: if not os.path.isdir("/home/{0}".format(username)): logger.warning(m18n.n("user_home_creation_failed"), exc_info=1) + home = '/home/{0}'.format(username) + if not os.path.isdir(home): + logger.warning(m18n.n('user_home_creation_failed', home=home), + exc_info=1) try: subprocess.check_call( @@ -726,6 +730,20 @@ def user_import(operation_logger, csvfile, update=False, delete=False): 'errors': 0 } + def progress(info=""): + progress.nb += 1 + width = 20 + bar = int(progress.nb * width / total) + bar = "[" + "#" * bar + "." * (width - bar) + "]" + if info: + bar += " > " + info + if progress.old == bar: + return + progress.old = bar + logger.info(bar) + progress.nb = 0 + progress.old = "" + def on_failure(user, exception): result['errors'] += 1 logger.error(user + ': ' + str(exception)) @@ -768,6 +786,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): result['deleted'] += 1 except YunohostError as e: on_failure(user, e) + progress("Deletion") for user in actions['updated']: try: @@ -775,6 +794,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): result['updated'] += 1 except YunohostError as e: on_failure(user['username'], e) + progress("Update") for user in actions['created']: try: @@ -786,6 +806,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): result['created'] += 1 except YunohostError as e: on_failure(user['username'], e) + progress("Creation") From a07314e66169b81efe270ee8018ee4d6f0629931 Mon Sep 17 00:00:00 2001 From: ljf Date: Sun, 3 Jan 2021 19:44:46 +0100 Subject: [PATCH 011/101] [fix] Download CSV from webadmin - missing commit --- src/yunohost/user.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 0680af89d..88279997b 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -632,10 +632,10 @@ def user_export(): if msettings.get('interface') == 'api': # We return a raw bottle HTTPresponse (instead of serializable data like # list/dict, ...), which is gonna be picked and used directly by moulinette - from bottle import LocalResponse - response = LocalResponse(body=body, + from bottle import HTTPResponse + response = HTTPResponse(body=body, headers={ - "Content-Disposition": "attachment; filename='users.csv'", + "Content-Disposition": "attachment; filename=users.csv", "Content-Type": "text/csv", }) return response @@ -652,6 +652,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): csv -- CSV file with columns username;firstname;lastname;password;mailbox_quota;mail;alias;forward;groups """ + import csv # CSV are needed only in this function from moulinette.utils.text import random_ascii from yunohost.permission import permission_sync_to_user From a78e4c8eacca2d221b3b91693928437e0577ec05 Mon Sep 17 00:00:00 2001 From: ljf Date: Sun, 3 Jan 2021 19:51:43 +0100 Subject: [PATCH 012/101] [fix] 1 letter firstname or lastname --- src/yunohost/user.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 88279997b..fe114da4b 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -46,8 +46,8 @@ logger = getActionLogger("yunohost.user") CSV_FIELDNAMES = [u'username', u'firstname', u'lastname', u'password', u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', u'groups'] VALIDATORS = { 'username': r'^[a-z0-9_]+$', - 'firstname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', #FIXME Merge first and lastname and support more name (arabish, chinese...) - 'lastname': r'^([^\W\d_]{2,30}[ ,.\'-]{0,3})+$', + 'firstname': r'^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$', #FIXME Merge first and lastname and support more name (arabish, chinese...) + 'lastname': r'^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$', 'password': r'^|(.{3,})$', 'mail': r'^([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}))$', 'mail-alias': r'^|([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', From 1d33f333cdff0ea7700b488a695ba8a3cd8b8b30 Mon Sep 17 00:00:00 2001 From: ljf Date: Sat, 8 May 2021 23:39:33 +0200 Subject: [PATCH 013/101] [fix] Python3 migration for export user feature --- src/yunohost/user.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index fe114da4b..5487ef18b 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -616,8 +616,8 @@ def user_export(): """ import csv # CSV are needed only in this function - from io import BytesIO - with BytesIO() as csv_io: + from io import StringIO + with StringIO() as csv_io: writer = csv.DictWriter(csv_io, CSV_FIELDNAMES, delimiter=';', quotechar='"') writer.writeheader() @@ -677,7 +677,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): format_errors = [key + ':' + str(user[key]) for key, validator in VALIDATORS.items() if user[key] is None or not re.match(validator, user[key])] - except KeyError, e: + except KeyError as e: logger.error(m18n.n('user_import_missing_column', column=str(e))) is_well_formatted = False From 91e7e5e1c80652a8977bba99d7a01075a1c86e2e Mon Sep 17 00:00:00 2001 From: ljf Date: Sat, 8 May 2021 23:58:36 +0200 Subject: [PATCH 014/101] [fix] Python3 migration: File args with log --- src/yunohost/log.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index a8a3281d2..9e6c8f165 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -373,10 +373,11 @@ def is_unit_operation( if field in context: context.pop(field, None) for field, value in context.items(): - if isinstance(value, file): - context[field] = value.name - elif isinstance(value, IOBase): - context[field] = 'IOBase' + if isinstance(value, IOBase): + try: + context[field] = value.name + except: + context[field] = 'IOBase' operation_logger = OperationLogger(op_key, related_to, args=context) try: From 6e880c8219846ce94a1a870c535334f16c5b1bcd Mon Sep 17 00:00:00 2001 From: ljf Date: Sun, 9 May 2021 01:02:51 +0200 Subject: [PATCH 015/101] [fix] Avoid password too small error during import operation --- src/yunohost/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 5487ef18b..ee26533e8 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -413,7 +413,7 @@ def user_update( ] # change_password is None if user_update is not called to change the password - if change_password is not None: + if change_password is not None and change_password != '': # when in the cli interface if the option to change the password is called # without a specified value, change_password will be set to the const 0. # In this case we prompt for the new password. From ad73c29dad7d61db122436e75d394ee12bf70119 Mon Sep 17 00:00:00 2001 From: ljf Date: Sun, 9 May 2021 01:08:43 +0200 Subject: [PATCH 016/101] [fix] Error in import user tests --- src/yunohost/tests/test_user-group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index 3252f0ef8..ee5d07c40 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -116,7 +116,7 @@ def test_del_user(mocker): def test_import_user(mocker): import csv - from io import BytesIO + from io import StringIO fieldnames = [u'username', u'firstname', u'lastname', u'password', u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', u'groups'] From 8cf151668fda88b57e765e742e673bd6d1227efc Mon Sep 17 00:00:00 2001 From: ljf Date: Tue, 11 May 2021 12:08:00 +0200 Subject: [PATCH 017/101] [fix] CI test --- locales/de.json | 2 +- src/yunohost/tests/test_user-group.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/de.json b/locales/de.json index 53297ed6d..73efca434 100644 --- a/locales/de.json +++ b/locales/de.json @@ -590,5 +590,5 @@ "diagnosis_sshd_config_insecure": "Die SSH-Konfiguration wurde scheinbar manuell abgeändert, und ist unsicher, weil sie keine 'AllowGroups'- oder 'AllowUsers' -Direktiven für die Begrenzung des Zugriffs durch autorisierte Benutzer enthält.", "backup_create_size_estimation": "Das Archiv wird etwa {size} Daten enthalten", "app_restore_script_failed": "Im Wiederherstellungsskript der Anwendung ist ein Fehler aufgetreten", - "app_restore_failed": "Konnte {apps:s} nicht wiederherstellen: {error:s}" + "app_restore_failed": "Konnte {app:s} nicht wiederherstellen: {error:s}" } diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index ee5d07c40..63d9a1930 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -120,7 +120,7 @@ def test_import_user(mocker): fieldnames = [u'username', u'firstname', u'lastname', u'password', u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', u'groups'] - with BytesIO() as csv_io: + with StringIO() as csv_io: writer = csv.DictWriter(csv_io, fieldnames, delimiter=';', quotechar='"') writer.writeheader() @@ -164,10 +164,10 @@ def test_export_user(mocker): result = user_export() should_be = "username;firstname;lastname;password;" should_be += "mailbox-quota;mail;mail-alias;mail-forward;groups" - should_be += "\r\nbob;Bob;Snow;;0;bob@" + maindomain + ";;;apps" should_be += "\r\nalice;Alice;White;;0;alice@" + maindomain + ";" should_be += ','.join([alias + maindomain for alias in FIRST_ALIASES]) should_be += ";;dev" + should_be += "\r\nbob;Bob;Snow;;0;bob@" + maindomain + ";;;apps" should_be += "\r\njack;Jack;Black;;0;jack@" + maindomain + ";;;" assert result == should_be From 4a22f6b390ec4277de478d50f49e9d7df8fa2773 Mon Sep 17 00:00:00 2001 From: ljf Date: Thu, 10 Jun 2021 19:28:49 +0200 Subject: [PATCH 018/101] [fix] yunohost user list --fields mail-alias --- src/yunohost/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index ee26533e8..1037d417f 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -119,7 +119,7 @@ def user_list(fields=None): values = user[ldap_attrs[field]] entry[field] = display.get(field, display_default)(values, user) - users[entry['username']] = entry + users[user['uid'][0]] = entry return {"users": users} From b9e231241b53019a634bc0d43a80284732796611 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 13 Aug 2021 00:49:42 +0200 Subject: [PATCH 019/101] user imports: imported -> from_import, try to improve semantics --- src/yunohost/user.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 1037d417f..545d46a87 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -134,7 +134,7 @@ def user_create( password, mailbox_quota="0", mail=None, - imported=False + from_import=False ): from yunohost.domain import domain_list, _get_maindomain @@ -197,7 +197,7 @@ def user_create( if mail in aliases: raise YunohostValidationError("mail_unavailable") - if not imported: + if not from_import: operation_logger.start() # Get random UID/GID @@ -282,14 +282,14 @@ def user_create( hook_callback("post_user_create", args=[username, mail], env=env_dict) # TODO: Send a welcome mail to user - if not imported: + if not from_import: logger.success(m18n.n('user_created')) return {"fullname": fullname, "username": username, "mail": mail} @is_unit_operation([('username', 'user')]) -def user_delete(operation_logger, username, purge=False, imported=False): +def user_delete(operation_logger, username, purge=False, from_import=False): """ Delete user @@ -304,7 +304,7 @@ def user_delete(operation_logger, username, purge=False, imported=False): if username not in user_list()["users"]: raise YunohostValidationError("user_unknown", user=username) - if not imported: + if not from_import: operation_logger.start() user_group_update("all_users", remove=username, force=True, sync_perm=False) @@ -337,7 +337,7 @@ def user_delete(operation_logger, username, purge=False, imported=False): hook_callback('post_user_delete', args=[username, purge]) - if not imported: + if not from_import: logger.success(m18n.n('user_deleted')) @is_unit_operation([("username", "user")], exclude=["change_password"]) @@ -353,7 +353,7 @@ def user_update( add_mailalias=None, remove_mailalias=None, mailbox_quota=None, - imported=False + from_import=False ): """ Update user informations @@ -502,7 +502,7 @@ def user_update( new_attr_dict["mailuserquota"] = [mailbox_quota] env_dict["YNH_USER_MAILQUOTA"] = mailbox_quota - if not imported: + if not from_import: operation_logger.start() try: @@ -513,7 +513,7 @@ def user_update( # Trigger post_user_update hooks hook_callback("post_user_update", env=env_dict) - if not imported: + if not from_import: app_ssowatconf() logger.success(m18n.n('user_updated')) return user_info(username) @@ -764,7 +764,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): # If the user is in this group (and it's not the primary group), # remove the member from the group if user['username'] != group and user['username'] in infos["members"]: - user_group_update(group, remove=user['username'], sync_perm=False, imported=True) + user_group_update(group, remove=user['username'], sync_perm=False, from_import=True) user_update(user['username'], user['firstname'], user['lastname'], @@ -773,17 +773,17 @@ def user_import(operation_logger, csvfile, update=False, delete=False): mail=user['mail'], add_mailalias=user['mail-alias'], remove_mailalias=remove_alias, remove_mailforward=remove_forward, - add_mailforward=user['mail-forward'], imported=True) + add_mailforward=user['mail-forward'], from_import=True) for group in user['groups']: - user_group_update(group, add=user['username'], sync_perm=False, imported=True) + user_group_update(group, add=user['username'], sync_perm=False, from_import=True) users = user_list(CSV_FIELDNAMES)['users'] operation_logger.start() # We do delete and update before to avoid mail uniqueness issues for user in actions['deleted']: try: - user_delete(user, purge=True, imported=True) + user_delete(user, purge=True, from_import=True) result['deleted'] += 1 except YunohostError as e: on_failure(user, e) @@ -802,7 +802,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): user_create(user['username'], user['firstname'], user['lastname'], user['domain'], user['password'], - user['mailbox-quota'], imported=True) + user['mailbox-quota'], from_import=True) update(user) result['created'] += 1 except YunohostError as e: @@ -1006,7 +1006,7 @@ def user_group_update( remove=None, force=False, sync_perm=True, - imported=False + from_import=False ): """ Update user informations @@ -1076,7 +1076,7 @@ def user_group_update( ] if set(new_group) != set(current_group): - if not imported: + if not from_import: operation_logger.start() ldap = _get_ldap_interface() try: @@ -1090,7 +1090,7 @@ def user_group_update( if sync_perm: permission_sync_to_user() - if not imported: + if not from_import: if groupname != "all_users": logger.success(m18n.n("group_updated", group=groupname)) else: From 5c9fd158d9b31c83c4c9975e8f4609647f9fe17d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 13 Aug 2021 00:52:42 +0200 Subject: [PATCH 020/101] user imports: more attempts to improve semantics --- src/yunohost/user.py | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 545d46a87..dfa71708a 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -749,34 +749,34 @@ def user_import(operation_logger, csvfile, update=False, delete=False): result['errors'] += 1 logger.error(user + ': ' + str(exception)) - def update(user, info=False): + def update(new_infos, old_infos=False): remove_alias = None remove_forward = None if info: - user['mail'] = None if info['mail'] == user['mail'] else user['mail'] - remove_alias = list(set(info['mail-alias']) - set(user['mail-alias'])) - remove_forward = list(set(info['mail-forward']) - set(user['mail-forward'])) - user['mail-alias'] = list(set(user['mail-alias']) - set(info['mail-alias'])) - user['mail-forward'] = list(set(user['mail-forward']) - set(info['mail-forward'])) + new_infos['mail'] = None if old_infos['mail'] == new_infos['mail'] else new_infos['mail'] + remove_alias = list(set(old_infos['mail-alias']) - set(new_infos['mail-alias'])) + remove_forward = list(set(old_infos['mail-forward']) - set(new_infos['mail-forward'])) + new_infos['mail-alias'] = list(set(new_infos['mail-alias']) - set(old_infos['mail-alias'])) + new_infos['mail-forward'] = list(set(new_infos['mail-forward']) - set(old_infos['mail-forward'])) for group, infos in user_group_list()["groups"].items(): if group == "all_users": continue # If the user is in this group (and it's not the primary group), # remove the member from the group - if user['username'] != group and user['username'] in infos["members"]: - user_group_update(group, remove=user['username'], sync_perm=False, from_import=True) + if new_infos['username'] != group and new_infos['username'] in infos["members"]: + user_group_update(group, remove=new_infos['username'], sync_perm=False, from_import=True) - user_update(user['username'], - user['firstname'], user['lastname'], - user['mail'], user['password'], - mailbox_quota=user['mailbox-quota'], - mail=user['mail'], add_mailalias=user['mail-alias'], - remove_mailalias=remove_alias, - remove_mailforward=remove_forward, - add_mailforward=user['mail-forward'], from_import=True) + user_update(new_infos['username'], + new_infos['firstname'], new_infos['lastname'], + new_infos['mail'], new_infos['password'], + mailbox_quota=new_infos['mailbox-quota'], + mail=new_infos['mail'], add_mailalias=new_infos['mail-alias'], + remove_mailalias=remove_alias, + remove_mailforward=remove_forward, + add_mailforward=new_infos['mail-forward'], from_import=True) - for group in user['groups']: - user_group_update(group, add=user['username'], sync_perm=False, from_import=True) + for group in new_infos['groups']: + user_group_update(group, add=new_infos['username'], sync_perm=False, from_import=True) users = user_list(CSV_FIELDNAMES)['users'] operation_logger.start() @@ -809,8 +809,6 @@ def user_import(operation_logger, csvfile, update=False, delete=False): on_failure(user['username'], e) progress("Creation") - - permission_sync_to_user() app_ssowatconf() From b1102ba56e29f311f400648c9f0b6ff27394985a Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 13 Aug 2021 01:10:59 +0200 Subject: [PATCH 021/101] user imports: misc formating, comments --- locales/en.json | 2 +- src/yunohost/user.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/locales/en.json b/locales/en.json index f8b26c0b1..5b93dbb9f 100644 --- a/locales/en.json +++ b/locales/en.json @@ -638,7 +638,7 @@ "user_import_partial_failed": "The users import operation partially failed", "user_import_failed": "The users import operation completely failed", "user_import_nothing_to_do": "No user needs to be imported", - "user_import_success": "Users have been imported", + "user_import_success": "Users successfully imported", "yunohost_already_installed": "YunoHost is already installed", "yunohost_configured": "YunoHost is now configured", "yunohost_installing": "Installing YunoHost...", diff --git a/src/yunohost/user.py b/src/yunohost/user.py index ca226f654..459b0decf 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -96,11 +96,11 @@ def user_list(fields=None): users = {} if not fields: - fields = ['username', 'fullname', 'mail', 'mailbox-quota', 'shell'] + fields = ['username', 'fullname', 'mail', 'mailbox-quota'] for field in fields: if field in ldap_attrs: - attrs |= set([ldap_attrs[field]]) + attrs.add(ldap_attrs[field]) else: raise YunohostError('field_invalid', field) @@ -252,7 +252,7 @@ def user_create( # Attempt to create user home folder subprocess.check_call(["mkhomedir_helper", username]) except subprocess.CalledProcessError: - home = '/home/{0}'.format(username) + home = f'/home/{username}' if not os.path.isdir(home): logger.warning(m18n.n('user_home_creation_failed', home=home), exc_info=1) @@ -427,8 +427,10 @@ def user_update( main_domain = _get_maindomain() aliases = [alias + main_domain for alias in FIRST_ALIASES] + # If the requested mail address is already as main address or as an alias by this user if mail in user['mail']: user['mail'].remove(mail) + # Othewise, check that this mail address is not already used by this user else: try: ldap.validate_uniqueness({'mail': mail}) @@ -445,6 +447,7 @@ def user_update( if not isinstance(add_mailalias, list): add_mailalias = [add_mailalias] for mail in add_mailalias: + # (c.f. similar stuff as before) if mail in user["mail"]: user["mail"].remove(mail) else: @@ -647,7 +650,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): Import users from CSV Keyword argument: - csv -- CSV file with columns username;firstname;lastname;password;mailbox_quota;mail;alias;forward;groups + csvfile -- CSV file with columns username;firstname;lastname;password;mailbox_quota;mail;alias;forward;groups """ @@ -655,6 +658,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): from moulinette.utils.text import random_ascii from yunohost.permission import permission_sync_to_user from yunohost.app import app_ssowatconf + # Pre-validate data and prepare what should be done actions = { 'created': [], From 781bc1cf7fdf3d3de8e1d7eddd9a9562d2149e39 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Sat, 14 Aug 2021 16:38:21 +0200 Subject: [PATCH 022/101] Wording Co-authored-by: Alexandre Aubin --- data/actionsmap/yunohost.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index 91e369dfe..64cef606d 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -222,7 +222,7 @@ user: type: open -u: full: --update - help: Update all existing users contained in the csv file (by default those users are ignored) + help: Update all existing users contained in the csv file (by default existing users are ignored) action: store_true -d: full: --delete From 2e745d2806dfbe416a03cd60197d3175106d3084 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Sat, 14 Aug 2021 16:38:55 +0200 Subject: [PATCH 023/101] Wording Co-authored-by: Alexandre Aubin --- data/actionsmap/yunohost.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index 64cef606d..817adeb92 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -226,7 +226,7 @@ user: action: store_true -d: full: --delete - help: Delete all existing users that are not contained in the csv file (by default those users are ignored) + help: Delete all existing users that are not contained in the csv file (by default existing users are kept) action: store_true subcategories: From 61bc676552a8b388beb5d49a4a0187c695b7482d Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Sat, 14 Aug 2021 16:41:58 +0200 Subject: [PATCH 024/101] [enh] Add a comment --- src/yunohost/log.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 10ac097f5..f9f9334fb 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -372,6 +372,8 @@ def is_unit_operation( for field in exclude: if field in context: context.pop(field, None) + + # Manage file or stream for field, value in context.items(): if isinstance(value, IOBase): try: From 16f564622ee7fe2ff0ee8aa1b9916b1cc7d83e6b Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Sat, 14 Aug 2021 16:46:48 +0200 Subject: [PATCH 025/101] [enh] Remove uneeded comment --- src/yunohost/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 459b0decf..11e82146a 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -46,7 +46,7 @@ logger = getActionLogger("yunohost.user") CSV_FIELDNAMES = [u'username', u'firstname', u'lastname', u'password', u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', u'groups'] VALIDATORS = { 'username': r'^[a-z0-9_]+$', - 'firstname': r'^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$', #FIXME Merge first and lastname and support more name (arabish, chinese...) + 'firstname': r'^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$', 'lastname': r'^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$', 'password': r'^|(.{3,})$', 'mail': r'^([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}))$', From 9e63142748813889fc9282c90fd97aa627fc929c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 19 Aug 2021 01:10:54 +0200 Subject: [PATCH 026/101] Diagnosis: report suspiciously high number of auth failures --- data/hooks/diagnosis/00-basesystem.py | 21 +++++++++++++++++++++ locales/en.json | 1 + 2 files changed, 22 insertions(+) diff --git a/data/hooks/diagnosis/00-basesystem.py b/data/hooks/diagnosis/00-basesystem.py index 3623c10e2..5b4b3394c 100644 --- a/data/hooks/diagnosis/00-basesystem.py +++ b/data/hooks/diagnosis/00-basesystem.py @@ -133,6 +133,13 @@ class BaseSystemDiagnoser(Diagnoser): summary="diagnosis_backports_in_sources_list", ) + if self.number_of_recent_auth_failure() > 500: + yield dict( + meta={"test": "high_number_auth_failure"}, + status="WARNING", + summary="diagnosis_high_number_auth_failures", + ) + def bad_sury_packages(self): packages_to_check = ["openssl", "libssl1.1", "libssl-dev"] @@ -154,6 +161,20 @@ class BaseSystemDiagnoser(Diagnoser): cmd = "grep -q -nr '^ *deb .*-backports' /etc/apt/sources.list*" return os.system(cmd) == 0 + def number_of_recent_auth_failure(self): + + # Those syslog facilities correspond to auth and authpriv + # c.f. https://unix.stackexchange.com/a/401398 + # and https://wiki.archlinux.org/title/Systemd/Journal#Facility + cmd = "journalctl -q SYSLOG_FACILITY=10 SYSLOG_FACILITY=4 --since '1day ago' | grep 'authentication failure' | wc -l" + + n_failures = check_output(cmd) + try: + return int(n_failures) + except Exception: + self.logger_warning("Failed to parse number of recent auth failures, expected an int, got '%s'" % n_failures) + return -1 + def is_vulnerable_to_meltdown(self): # meltdown CVE: https://security-tracker.debian.org/tracker/CVE-2017-5754 diff --git a/locales/en.json b/locales/en.json index 693e9d24d..f6641f224 100644 --- a/locales/en.json +++ b/locales/en.json @@ -239,6 +239,7 @@ "diagnosis_rootfstotalspace_critical": "The root filesystem only has a total of {space} which is quite worrisome! You will likely run out of disk space very quickly! It's recommended to have at least 16 GB for the root filesystem.", "diagnosis_security_vulnerable_to_meltdown": "You appear vulnerable to the Meltdown criticial security vulnerability", "diagnosis_security_vulnerable_to_meltdown_details": "To fix this, you should upgrade your system and reboot to load the new linux kernel (or contact your server provider if this doesn't work). See https://meltdownattack.com/ for more infos.", + "diagnosis_high_number_auth_failures": "There's been a suspiciously high number of authentication failures recently. You may want to make sure that fail2ban is running and is correctly configured, or use a custom port for SSH as explained in https://yunohost.org/security.", "diagnosis_description_basesystem": "Base system", "diagnosis_description_ip": "Internet connectivity", "diagnosis_description_dnsrecords": "DNS records", From efec34a3a654f5ec312c9dde03e9b13f7b05224d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 26 Aug 2021 20:31:20 +0200 Subject: [PATCH 027/101] tests: Improve code formatting --- src/yunohost/tests/test_user-group.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index 63d9a1930..344a20fed 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -162,14 +162,13 @@ def test_import_user(mocker): def test_export_user(mocker): result = user_export() - should_be = "username;firstname;lastname;password;" - should_be += "mailbox-quota;mail;mail-alias;mail-forward;groups" - should_be += "\r\nalice;Alice;White;;0;alice@" + maindomain + ";" - should_be += ','.join([alias + maindomain for alias in FIRST_ALIASES]) - should_be += ";;dev" - should_be += "\r\nbob;Bob;Snow;;0;bob@" + maindomain + ";;;apps" - should_be += "\r\njack;Jack;Black;;0;jack@" + maindomain + ";;;" - + aliases = ','.join([alias + maindomain for alias in FIRST_ALIASES]) + should_be = ( + "username;firstname;lastname;password;mailbox-quota;mail;mail-alias;mail-forward;groups\r\n" + f"alice;Alice;White;;0;alice@{maindomain};{aliases};;dev\r\n" + f"bob;Bob;Snow;;0;bob@{maindomain};;;apps\r\n" + f"jack;Jack;Black;;0;jack@{maindomain};;;" + ) assert result == should_be From ad975a2dbb748b19f6abea17527452010ef30ba4 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 26 Aug 2021 20:45:06 +0200 Subject: [PATCH 028/101] user import: clarify user deletion handling --- src/yunohost/user.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 11e82146a..076d930ca 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -670,6 +670,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): def to_list(str_list): return str_list.split(',') if str_list else [] + users_in_csv = [] existing_users = user_list()['users'] past_lines = [] reader = csv.DictReader(csvfile, delimiter=';', quotechar='"') @@ -701,20 +702,26 @@ def user_import(operation_logger, csvfile, update=False, delete=False): user['mail-alias'] = to_list(user['mail-alias']) user['mail-forward'] = to_list(user['mail-forward']) user['domain'] = user['mail'].split('@')[1] + + # User creation if user['username'] not in existing_users: # Generate password if not exists # This could be used when reset password will be merged if not user['password']: user['password'] = random_ascii(70) actions['created'].append(user) - else: - if update: - actions['updated'].append(user) - del existing_users[user['username']] + # User update + elif update: + actions['updated'].append(user) + + users_in_csv.add(user['username']) if delete: - for user in existing_users: - actions['deleted'].append(user) + actions['deleted'] = [user for user in existing_users if user not in users_in_csv] + + if delete and not users_in_csv: + logger.error("You used the delete option with an empty csv file ... You probably did not really mean to do that, did you !?") + is_well_formatted = False if not is_well_formatted: raise YunohostError('user_import_bad_file') From 128eb6a7d46f06c4bb2a0079134a20cf5d687b43 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 26 Aug 2021 21:06:16 +0200 Subject: [PATCH 029/101] user import: Clarify fields validation --- locales/en.json | 2 +- src/yunohost/tests/test_user-group.py | 4 +-- src/yunohost/user.py | 43 +++++++++++++-------------- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/locales/en.json b/locales/en.json index 5b93dbb9f..06d2df0a4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -634,7 +634,7 @@ "user_updated": "User info changed", "user_import_bad_line": "Incorrect line {line}: {details}", "user_import_bad_file": "Your CSV file is not correctly formatted it will be ignored to avoid potential data loss", - "user_import_missing_column": "The column {column} is missing", + "user_import_missing_columns": "The following columns are missing: {columns}", "user_import_partial_failed": "The users import operation partially failed", "user_import_failed": "The users import operation completely failed", "user_import_nothing_to_do": "No user needs to be imported", diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index 344a20fed..bbedfc27f 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -10,7 +10,7 @@ from yunohost.user import ( user_update, user_import, user_export, - CSV_FIELDNAMES, + FIELDS_FOR_IMPORT, FIRST_ALIASES, user_group_list, user_group_create, @@ -151,7 +151,7 @@ def test_import_user(mocker): user_import(csv_io, update=True, delete=True) group_res = user_group_list()['groups'] - user_res = user_list(CSV_FIELDNAMES)['users'] + user_res = user_list(list(FIELDS_FOR_IMPORT.keys()))['users'] assert "albert" in user_res assert "alice" in user_res assert "bob" not in user_res diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 076d930ca..b055d2cdb 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -43,8 +43,7 @@ from yunohost.log import is_unit_operation logger = getActionLogger("yunohost.user") -CSV_FIELDNAMES = [u'username', u'firstname', u'lastname', u'password', u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', u'groups'] -VALIDATORS = { +FIELDS_FOR_IMPORT = { 'username': r'^[a-z0-9_]+$', 'firstname': r'^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$', 'lastname': r'^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$', @@ -619,10 +618,10 @@ def user_export(): import csv # CSV are needed only in this function from io import StringIO with StringIO() as csv_io: - writer = csv.DictWriter(csv_io, CSV_FIELDNAMES, + writer = csv.DictWriter(csv_io, list(FIELDS_FOR_IMPORT.keys()), delimiter=';', quotechar='"') writer.writeheader() - users = user_list(CSV_FIELDNAMES)['users'] + users = user_list(list(FIELDS_FOR_IMPORT.keys()))['users'] for username, user in users.items(): user['mail-alias'] = ','.join(user['mail-alias']) user['mail-forward'] = ','.join(user['mail-forward']) @@ -672,24 +671,24 @@ def user_import(operation_logger, csvfile, update=False, delete=False): users_in_csv = [] existing_users = user_list()['users'] - past_lines = [] reader = csv.DictReader(csvfile, delimiter=';', quotechar='"') - for user in reader: - # Validation - try: - format_errors = [key + ':' + str(user[key]) - for key, validator in VALIDATORS.items() - if user[key] is None or not re.match(validator, user[key])] - except KeyError as e: - logger.error(m18n.n('user_import_missing_column', - column=str(e))) - is_well_formatted = False - break - if 'username' in user: - if user['username'] in past_lines: - format_errors.append('username: %s (duplicated)' % user['username']) - past_lines.append(user['username']) + missing_columns = [key for key in FIELDS_FOR_IMPORT.keys() if key not in reader.fieldnames] + if missing_columns: + raise YunohostValidationError("user_import_missing_columns", columns=', '.join(missing_columns)) + + for user in reader: + + # Validate column values against regexes + format_errors = [key + ':' + str(user[key]) + for key, validator in FIELDS_FOR_IMPORT.items() + if user[key] is None or not re.match(validator, user[key])] + + # Check for duplicated username lines + if user['username'] in users_in_csv: + format_errors.append(f'username: {user[username]} (duplicated)') + users_in_csv.append(user['username']) + if format_errors: logger.error(m18n.n('user_import_bad_line', line=reader.line_num, @@ -714,8 +713,6 @@ def user_import(operation_logger, csvfile, update=False, delete=False): elif update: actions['updated'].append(user) - users_in_csv.add(user['username']) - if delete: actions['deleted'] = [user for user in existing_users if user not in users_in_csv] @@ -787,7 +784,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): for group in new_infos['groups']: user_group_update(group, add=new_infos['username'], sync_perm=False, from_import=True) - users = user_list(CSV_FIELDNAMES)['users'] + users = user_list(list(FIELDS_FOR_IMPORT.keys()))['users'] operation_logger.start() # We do delete and update before to avoid mail uniqueness issues for user in actions['deleted']: From 8e35cd8103e8eb40c103ed92d80a2086b35a65b0 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Aug 2021 13:52:10 +0200 Subject: [PATCH 030/101] user import: strip spaces --- src/yunohost/user.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index b055d2cdb..ce2c2c34f 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -667,7 +667,9 @@ def user_import(operation_logger, csvfile, update=False, delete=False): is_well_formatted = True def to_list(str_list): - return str_list.split(',') if str_list else [] + L = str_list.split(',') if str_list else [] + L = [l.strip() for l in L] + return L users_in_csv = [] existing_users = user_list()['users'] From 24d87ea40eefbd5ae4fcda45be72314a30bb28d1 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Aug 2021 14:09:13 +0200 Subject: [PATCH 031/101] user import: validate that groups and domains exists --- src/yunohost/user.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index ce2c2c34f..1b0e47f80 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -671,9 +671,12 @@ def user_import(operation_logger, csvfile, update=False, delete=False): L = [l.strip() for l in L] return L - users_in_csv = [] existing_users = user_list()['users'] + existing_groups = user_group_list()["groups"] + existing_domains = domain_list()["domains"] + reader = csv.DictReader(csvfile, delimiter=';', quotechar='"') + users_in_csv = [] missing_columns = [key for key in FIELDS_FOR_IMPORT.keys() if key not in reader.fieldnames] if missing_columns: @@ -688,9 +691,29 @@ def user_import(operation_logger, csvfile, update=False, delete=False): # Check for duplicated username lines if user['username'] in users_in_csv: - format_errors.append(f'username: {user[username]} (duplicated)') + format_errors.append(f"username '{user[username]}' duplicated") users_in_csv.append(user['username']) + # Validate that groups exist + user['groups'] = to_list(user['groups']) + unknown_groups = [g for g in user['groups'] if g not in existing_groups] + if unknown_groups: + format_errors.append(f"username '{user[username]}': unknown groups %s" % ', '.join(unknown_groups)) + + # Validate that domains exist + user['mail-alias'] = to_list(user['mail-alias']) + user['mail-forward'] = to_list(user['mail-forward']) + user['domain'] = user['mail'].split('@')[1] + + unknown_domains = [] + if user['domain'] not in existing_domains: + unknown_domains.append(user['domain']) + + unknown_domains += [mail.split('@')[1:] for mail in user['mail-alias'] if mail.split('@')[1:] not in existing_domains] + + if unknown_domains: + format_errors.append(f"username '{user[username]}': unknown domains %s" % ', '.join(unknown_domains)) + if format_errors: logger.error(m18n.n('user_import_bad_line', line=reader.line_num, @@ -699,10 +722,6 @@ def user_import(operation_logger, csvfile, update=False, delete=False): continue # Choose what to do with this line and prepare data - user['groups'] = to_list(user['groups']) - user['mail-alias'] = to_list(user['mail-alias']) - user['mail-forward'] = to_list(user['mail-forward']) - user['domain'] = user['mail'].split('@')[1] # User creation if user['username'] not in existing_users: From a40084460b96254c4f2b8a3a1ff7031168b60afe Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Aug 2021 14:10:20 +0200 Subject: [PATCH 032/101] csv -> CSV --- data/actionsmap/yunohost.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index 6e9509bab..0c1895c47 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -222,11 +222,11 @@ user: type: open -u: full: --update - help: Update all existing users contained in the csv file (by default existing users are ignored) + help: Update all existing users contained in the CSV file (by default existing users are ignored) action: store_true -d: full: --delete - help: Delete all existing users that are not contained in the csv file (by default existing users are kept) + help: Delete all existing users that are not contained in the CSV file (by default existing users are kept) action: store_true subcategories: From 4de6bbdf84eb7965517395adacb7319506dc5ad3 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Aug 2021 14:38:40 +0200 Subject: [PATCH 033/101] user import: Try to optimize group operations --- src/yunohost/user.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 1b0e47f80..bc684ec0c 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -54,8 +54,10 @@ FIELDS_FOR_IMPORT = { 'mailbox-quota': r'^(\d+[bkMGT])|0$', 'groups': r'^|([a-z0-9_]+(,?[a-z0-9_]+)*)$' } + FIRST_ALIASES = ['root@', 'admin@', 'webmaster@', 'postmaster@', 'abuse@'] + def user_list(fields=None): from yunohost.utils.ldap import _get_ldap_interface @@ -779,18 +781,26 @@ def user_import(operation_logger, csvfile, update=False, delete=False): def update(new_infos, old_infos=False): remove_alias = None remove_forward = None - if info: + remove_groups = [] + add_groups = new_infos["groups"] + if old_infos: new_infos['mail'] = None if old_infos['mail'] == new_infos['mail'] else new_infos['mail'] remove_alias = list(set(old_infos['mail-alias']) - set(new_infos['mail-alias'])) remove_forward = list(set(old_infos['mail-forward']) - set(new_infos['mail-forward'])) new_infos['mail-alias'] = list(set(new_infos['mail-alias']) - set(old_infos['mail-alias'])) new_infos['mail-forward'] = list(set(new_infos['mail-forward']) - set(old_infos['mail-forward'])) - for group, infos in user_group_list()["groups"].items(): - if group == "all_users": + + remove_groups = list(set(old_infos["groups"]) - set(new_infos["groups"])) + add_groups = list(set(new_infos["groups"]) - set(old_infos["groups"])) + + for group, infos in existing_groups: + # Loop only on groups in 'remove_groups' + # Ignore 'all_users' and primary group + if group in ["all_users", new_infos['username']] or group not in remove_groups: continue # If the user is in this group (and it's not the primary group), # remove the member from the group - if new_infos['username'] != group and new_infos['username'] in infos["members"]: + if new_infos['username'] in infos["members"]: user_group_update(group, remove=new_infos['username'], sync_perm=False, from_import=True) user_update(new_infos['username'], @@ -802,7 +812,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): remove_mailforward=remove_forward, add_mailforward=new_infos['mail-forward'], from_import=True) - for group in new_infos['groups']: + for group in add_groups: user_group_update(group, add=new_infos['username'], sync_perm=False, from_import=True) users = user_list(list(FIELDS_FOR_IMPORT.keys()))['users'] From 865d8e2c8c7838d8ccab813eb2d3b271e8168545 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Aug 2021 14:48:30 +0200 Subject: [PATCH 034/101] user import: fix typo --- src/yunohost/user.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index bc684ec0c..07f3e546a 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -693,14 +693,14 @@ def user_import(operation_logger, csvfile, update=False, delete=False): # Check for duplicated username lines if user['username'] in users_in_csv: - format_errors.append(f"username '{user[username]}' duplicated") + format_errors.append(f"username '{user['username']}' duplicated") users_in_csv.append(user['username']) # Validate that groups exist user['groups'] = to_list(user['groups']) unknown_groups = [g for g in user['groups'] if g not in existing_groups] if unknown_groups: - format_errors.append(f"username '{user[username]}': unknown groups %s" % ', '.join(unknown_groups)) + format_errors.append(f"username '{user['username']}': unknown groups %s" % ', '.join(unknown_groups)) # Validate that domains exist user['mail-alias'] = to_list(user['mail-alias']) @@ -714,7 +714,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): unknown_domains += [mail.split('@')[1:] for mail in user['mail-alias'] if mail.split('@')[1:] not in existing_domains] if unknown_domains: - format_errors.append(f"username '{user[username]}': unknown domains %s" % ', '.join(unknown_domains)) + format_errors.append(f"username '{user['username']}': unknown domains %s" % ', '.join(unknown_domains)) if format_errors: logger.error(m18n.n('user_import_bad_line', From 4f6166f8bba942e420239bb3f8b32327ac3f915e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Aug 2021 15:47:40 +0200 Subject: [PATCH 035/101] ldap config: Bump DbMaxSize to allow up to 100MB --- data/templates/slapd/config.ldif | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/templates/slapd/config.ldif b/data/templates/slapd/config.ldif index 4d72ab7cc..e1fe3b1b5 100644 --- a/data/templates/slapd/config.ldif +++ b/data/templates/slapd/config.ldif @@ -33,7 +33,7 @@ olcAuthzPolicy: none olcConcurrency: 0 olcConnMaxPending: 100 olcConnMaxPendingAuth: 1000 -olcSizeLimit: 10000 +olcSizeLimit: 50000 olcIdleTimeout: 0 olcIndexSubstrIfMaxLen: 4 olcIndexSubstrIfMinLen: 2 @@ -189,7 +189,7 @@ olcDbIndex: memberUid eq olcDbIndex: uniqueMember eq olcDbIndex: virtualdomain eq olcDbIndex: permission eq -olcDbMaxSize: 10485760 +olcDbMaxSize: 104857600 structuralObjectClass: olcMdbConfig # From 3ad48fd8bc323ad2bd42f4197f0b61cef54dac01 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Aug 2021 16:34:34 +0200 Subject: [PATCH 036/101] Fixes after tests on the battlefield --- src/yunohost/user.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 07f3e546a..f6cbeb9bc 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -655,10 +655,11 @@ def user_import(operation_logger, csvfile, update=False, delete=False): """ - import csv # CSV are needed only in this function + import csv # CSV are needed only in this function from moulinette.utils.text import random_ascii from yunohost.permission import permission_sync_to_user from yunohost.app import app_ssowatconf + from yunohost.domain import domain_list # Pre-validate data and prepare what should be done actions = { @@ -711,7 +712,8 @@ def user_import(operation_logger, csvfile, update=False, delete=False): if user['domain'] not in existing_domains: unknown_domains.append(user['domain']) - unknown_domains += [mail.split('@')[1:] for mail in user['mail-alias'] if mail.split('@')[1:] not in existing_domains] + unknown_domains += [mail.split('@', 1)[1] for mail in user['mail-alias'] if mail.split('@', 1)[1] not in existing_domains] + unknown_domains = set(unknown_domains) if unknown_domains: format_errors.append(f"username '{user['username']}': unknown domains %s" % ', '.join(unknown_domains)) @@ -744,7 +746,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): is_well_formatted = False if not is_well_formatted: - raise YunohostError('user_import_bad_file') + raise YunohostValidationError('user_import_bad_file') total = len(actions['created'] + actions['updated'] + actions['deleted']) @@ -793,7 +795,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): remove_groups = list(set(old_infos["groups"]) - set(new_infos["groups"])) add_groups = list(set(new_infos["groups"]) - set(old_infos["groups"])) - for group, infos in existing_groups: + for group, infos in existing_groups.items(): # Loop only on groups in 'remove_groups' # Ignore 'all_users' and primary group if group in ["all_users", new_infos['username']] or group not in remove_groups: @@ -813,6 +815,8 @@ def user_import(operation_logger, csvfile, update=False, delete=False): add_mailforward=new_infos['mail-forward'], from_import=True) for group in add_groups: + if group in ["all_users", new_infos['username']]: + continue user_group_update(group, add=new_infos['username'], sync_perm=False, from_import=True) users = user_list(list(FIELDS_FOR_IMPORT.keys()))['users'] @@ -824,7 +828,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): result['deleted'] += 1 except YunohostError as e: on_failure(user, e) - progress("Deletion") + progress(f"Deleting {user}") for user in actions['updated']: try: @@ -832,7 +836,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): result['updated'] += 1 except YunohostError as e: on_failure(user['username'], e) - progress("Update") + progress(f"Updating {user['username']}") for user in actions['created']: try: @@ -844,7 +848,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): result['created'] += 1 except YunohostError as e: on_failure(user['username'], e) - progress("Creation") + progress(f"Creating {user['username']}") permission_sync_to_user() app_ssowatconf() From 0e2105311f1e376328a911dc0f961a5e99e87c28 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Aug 2021 16:36:38 +0200 Subject: [PATCH 037/101] user import: fix tests --- src/yunohost/tests/test_user-group.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index bbedfc27f..d3b3c81aa 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -164,10 +164,10 @@ def test_export_user(mocker): result = user_export() aliases = ','.join([alias + maindomain for alias in FIRST_ALIASES]) should_be = ( - "username;firstname;lastname;password;mailbox-quota;mail;mail-alias;mail-forward;groups\r\n" - f"alice;Alice;White;;0;alice@{maindomain};{aliases};;dev\r\n" - f"bob;Bob;Snow;;0;bob@{maindomain};;;apps\r\n" - f"jack;Jack;Black;;0;jack@{maindomain};;;" + "username;firstname;lastname;password;mail;mail-alias;mail-forward;mailbox-quota;groups\r\n" + f"alice;Alice;White;;alice@{maindomain};{aliases};;0;dev\r\n" + f"bob;Bob;Snow;;bob@{maindomain};;;0;apps\r\n" + f"jack;Jack;Black;;jack@{maindomain};;;0;" ) assert result == should_be From 5af70af47d0612378cccde87823fe85326825ccb Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Aug 2021 17:09:46 +0200 Subject: [PATCH 038/101] user import: Allow empty value for mailbox quota --- src/yunohost/user.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index f6cbeb9bc..0cdd0d3ae 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -51,7 +51,7 @@ FIELDS_FOR_IMPORT = { 'mail': r'^([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}))$', 'mail-alias': r'^|([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', 'mail-forward': r'^|([\w\+.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', - 'mailbox-quota': r'^(\d+[bkMGT])|0$', + 'mailbox-quota': r'^(\d+[bkMGT])|0|$', 'groups': r'^|([a-z0-9_]+(,?[a-z0-9_]+)*)$' } @@ -688,7 +688,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): for user in reader: # Validate column values against regexes - format_errors = [key + ':' + str(user[key]) + format_errors = [f"{key}: '{user[key]}' doesn't match the expected format" for key, validator in FIELDS_FOR_IMPORT.items() if user[key] is None or not re.match(validator, user[key])] @@ -726,6 +726,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False): continue # Choose what to do with this line and prepare data + user['mailbox-quota'] = user['mailbox-quota'] or "0" # User creation if user['username'] not in existing_users: From 2885fef1567bbd6db16af53f97b08b455f574761 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 27 Aug 2021 11:26:45 +0000 Subject: [PATCH 039/101] Translated using Weblate (German) Currently translated at 99.0% (633 of 639 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/de.json b/locales/de.json index ea20c7d7f..0580eac1d 100644 --- a/locales/de.json +++ b/locales/de.json @@ -378,7 +378,7 @@ "diagnosis_mail_ehlo_wrong_details": "Die vom Remote-Diagnose-Server per IPv{ipversion} empfangene EHLO weicht von der Domäne Ihres Servers ab.
Empfangene EHLO: {wrong_ehlo}
Erwartet: {right_ehlo}
Die geläufigste Ursache für dieses Problem ist, dass der Port 25 nicht korrekt auf Ihren Server weitergeleitet wird. Sie können sich zusätzlich auch versichern, dass keine Firewall oder Reverse-Proxy interferiert.", "diagnosis_mail_ehlo_bad_answer_details": "Das könnte daran liegen, dass anstelle Ihres Servers eine andere Maschine antwortet.", "ask_user_domain": "Domäne, welche für die E-Mail-Adresse und den XMPP-Account des Benutzers verwendet werden soll", - "app_manifest_install_ask_is_public": "Soll diese Applikation für anonyme Benutzer sichtbar sein?", + "app_manifest_install_ask_is_public": "Soll diese Applikation für anonyme Benutzer:innen sichtbar sein?", "app_manifest_install_ask_admin": "Wählen Sie einen Administrator für diese Applikation", "app_manifest_install_ask_path": "Wählen Sie den Pfad, in welchem die Applikation installiert werden soll", "diagnosis_mail_blacklist_listed_by": "Ihre IP-Adresse oder Domäne {item} ist auf der Blacklist auf {blacklist_name}", @@ -635,4 +635,4 @@ "global_settings_setting_security_webadmin_allowlist_enabled": "Erlaube nur bestimmten IP-Adressen den Zugriff auf die Verwaltungsseite.", "disk_space_not_sufficient_update": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu aktuallisieren", "disk_space_not_sufficient_install": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu installieren" -} \ No newline at end of file +} From 23b06252e3518eacd061e26fd67f4d7c444f2b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M?= Date: Fri, 27 Aug 2021 13:38:21 +0000 Subject: [PATCH 040/101] Translated using Weblate (Galician) Currently translated at 85.1% (544 of 639 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/gl/ --- locales/gl.json | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/locales/gl.json b/locales/gl.json index 5c0bec604..10322d2e8 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -75,7 +75,7 @@ "app_manifest_install_ask_is_public": "Debería esta app estar exposta ante visitantes anónimas?", "app_manifest_install_ask_admin": "Elixe unha usuaria administradora para esta app", "app_manifest_install_ask_password": "Elixe un contrasinal de administración para esta app", - "app_manifest_install_ask_path": "Elixe a ruta onde queres instalar esta app", + "app_manifest_install_ask_path": "Elixe a ruta URL (após o dominio) onde será instalada esta app", "app_manifest_install_ask_domain": "Elixe o dominio onde queres instalar esta app", "app_manifest_invalid": "Hai algún erro no manifesto da app: {error}", "app_location_unavailable": "Este URL ou ben non está dispoñible ou entra en conflito cunha app(s) xa instalada:\n{apps}", @@ -436,7 +436,7 @@ "log_regen_conf": "Rexerar configuración do sistema '{}'", "log_letsencrypt_cert_renew": "Anovar certificado Let's Encrypt para '{}'", "log_selfsigned_cert_install": "Instalar certificado auto-asinado para o dominio '{}'", - "log_permission_url": "Actualizar url relativo ao permiso '{}'", + "log_permission_url": "Actualizar URL relativo ao permiso '{}'", "migration_0015_general_warning": "Ten en conta que a migración é unha operación delicada. O equipo YunoHost esforzouse revisando e comprobandoa, aínda así algo podería fallar en partes do teu sistema ou as súas apps.\n\nPor tanto, é recomendable:\n- realiza unha copia de apoio de tódolos datos ou apps importantes. Máis info en https://yunohost.org/backup;\n - ten paciencia tras iniciar o proceso: dependendo da túa conexión de internet e hardware podería demorar varias horas a actualización de tódolos compoñentes.", "migration_0015_system_not_fully_up_to_date": "O teu sistema non está ao día. Realiza unha actualización común antes de realizar a migración a Buster.", "migration_0015_not_enough_free_space": "Queda moi pouco espazo en /var/! Deberías ter polo menos 1GB libre para realizar a migración.", @@ -522,5 +522,26 @@ "permission_deletion_failed": "Non se puido eliminar o permiso '{permission}': {error}", "permission_deleted": "O permiso '{permission}' foi eliminado", "permission_cant_add_to_all_users": "O permiso {permission} non pode ser concecido a tódalas usuarias.", - "permission_currently_allowed_for_all_users": "Este permiso está concedido actualmente a tódalas usuarias ademáis de a outros grupos. Probablemente queiras ben eliminar o permiso 'all_users' ou ben eliminar os outros grupos que teñen permiso." + "permission_currently_allowed_for_all_users": "Este permiso está concedido actualmente a tódalas usuarias ademáis de a outros grupos. Probablemente queiras ben eliminar o permiso 'all_users' ou ben eliminar os outros grupos que teñen permiso.", + "restore_failed": "Non se puido restablecer o sistema", + "restore_extracting": "Extraendo os ficheiros necesarios desde o arquivo…", + "restore_confirm_yunohost_installed": "Tes a certeza de querer restablecer un sistema xa instalado? [{answers}]", + "restore_complete": "Restablecemento completado", + "restore_cleaning_failed": "Non se puido despexar o directorio temporal de restablecemento", + "restore_backup_too_old": "Este arquivo de apoio non pode ser restaurado porque procede dunha versión YunoHost demasiado antiga.", + "restore_already_installed_apps": "As seguintes apps non se poden restablecer porque xa están instaladas: {apps}", + "restore_already_installed_app": "Unha app con ID '{app}' xa está instalada", + "regex_with_only_domain": "Agora xa non podes usar un regex para o dominio, só para ruta", + "regex_incompatible_with_tile": "/!\\ Empacadoras! O permiso '{permission}' agora ten show_tile establecido como 'true' polo que non podes definir o regex URL como URL principal", + "regenconf_need_to_explicitly_specify_ssh": "A configuración ssh foi modificada manualmente, pero tes que indicar explícitamente a categoría 'ssh' con --force para realmente aplicar os cambios.", + "regenconf_pending_applying": "Aplicando a configuración pendente para categoría '{category}'...", + "regenconf_failed": "Non se rexenerou a configuración para a categoría(s): {categories}", + "regenconf_dry_pending_applying": "Comprobando as configuracións pendentes que deberían aplicarse á categoría '{category}'…", + "regenconf_would_be_updated": "A configuración debería ser actualizada para a categoría '{category}'", + "regenconf_updated": "Configuración actualizada para '{category}'", + "regenconf_up_to_date": "A configuración xa está ao día para a categoría '{category}'", + "regenconf_now_managed_by_yunohost": "O ficheiro de configuración '{conf}' agora está xestionado por YunoHost (categoría {category}).", + "regenconf_file_updated": "Actualizado o ficheiro de configuración '{conf}'", + "regenconf_file_removed": "Eliminado o ficheiro de configuración '{conf}'", + "regenconf_file_remove_failed": "Non se puido eliminar o ficheiro de configuración '{conf}'" } From 75879d486df336cac2745b5bfbf8586a22d45997 Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 27 Aug 2021 14:18:43 +0000 Subject: [PATCH 041/101] Translated using Weblate (Ukrainian) Currently translated at 5.4% (35 of 639 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 607 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 606 insertions(+), 1 deletion(-) diff --git a/locales/uk.json b/locales/uk.json index c85b4fd0a..71d7ee897 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -32,5 +32,610 @@ "additional_urls_already_added": "Додаткова URL-адреса '{url}' вже додана в додаткову URL-адресу для дозволу '{permission}'", "action_invalid": "Неприпустима дія '{action}'", "aborting": "Переривання.", - "diagnosis_description_web": "Мережа" + "diagnosis_description_web": "Мережа", + "service_reloaded_or_restarted": "Служба '{service}' була перезавантажена або перезапущено", + "service_reload_or_restart_failed": "Не вдалося перезавантажити або перезапустити службу '{service}' Recent service logs: {logs}", + "service_restarted": "Служба '{service}' перезапущено", + "service_restart_failed": "Не вдалося запустити службу '{service}' Недавні журнали служб: {logs}", + "service_reloaded": "Служба '{service}' перезавантажена", + "service_reload_failed": "Не вдалося перезавантажити службу '{service}' Останні журнали служби: {logs}", + "service_removed": "Служба '{service}' вилучена", + "service_remove_failed": "Не вдалося видалити службу '{service}'", + "service_regen_conf_is_deprecated": "'Yunohost service regen-conf' застарів! Будь ласка, використовуйте 'yunohost tools regen-conf' замість цього.", + "service_enabled": "Служба '{service}' тепер буде автоматично запускатися при завантаженні системи.", + "service_enable_failed": "Неможливо змусити службу '{service}' автоматично запускатися при завантаженні. Недавні журнали служб: {logs}", + "service_disabled": "Служба '{service}' більше не буде запускатися при завантаженні системи.", + "service_disable_failed": "Неможливо змусити службу '{service} \"не запускатися при завантаженні. Останні журнали служби: {logs}", + "service_description_yunohost-firewall": "Управляє відкритими і закритими портами підключення до сервісів", + "service_description_yunohost-api": "Управляє взаємодією між веб-інтерфейсом YunoHost і системою", + "service_description_ssh": "Дозволяє віддалено підключатися до сервера через термінал (протокол SSH)", + "service_description_slapd": "Зберігає користувачів, домени і пов'язану з ними інформацію", + "service_description_rspamd": "Фільтрує спам і інші функції, пов'язані з електронною поштою", + "service_description_redis-server": "Спеціалізована база даних, яка використовується для швидкого доступу до даних, черги завдань і зв'язку між програмами", + "service_description_postfix": "Використовується для відправки та отримання електронної пошти", + "service_description_php7.3-fpm": "Запускає програми, написані на мові програмування PHP, за допомогою NGINX", + "service_description_nginx": "Обслуговує або надає доступ до всіх веб-сайтів, розміщених на вашому сервері", + "service_description_mysql": "Зберігає дані додатків (база даних SQL)", + "service_description_metronome": "Служба захисту миттєвого обміну повідомленнями XMPP", + "service_description_fail2ban": "Захист від перебору та інших видів атак з Інтернету", + "service_description_dovecot": "Дозволяє поштовим клієнтам отримувати доступ до електронної пошти (через IMAP і POP3)", + "service_description_dnsmasq": "Обробляє дозвіл доменних імен (DNS)", + "service_description_yunomdns": "Дозволяє вам отримати доступ до вашого сервера, використовуючи 'yunohost.local' у вашій локальній мережі", + "service_cmd_exec_failed": "Не вдалося виконати команду '{команда}'", + "service_already_stopped": "Служба '{service}' вже зупинена", + "service_already_started": "Служба '{service}' вже запущена", + "service_added": "Служба '{service}' була додана", + "service_add_failed": "Не вдалося додати службу '{service}'", + "server_reboot_confirm": "Сервер негайно перезавантажиться, ви впевнені? [{Відповіді}]", + "server_reboot": "сервер перезавантажиться", + "server_shutdown_confirm": "Сервер буде негайно виключений, ви впевнені? [{Відповіді}].", + "server_shutdown": "сервер вимкнеться", + "root_password_replaced_by_admin_password": "Ваш кореневої пароль був замінений на пароль адміністратора.", + "root_password_desynchronized": "Пароль адміністратора був змінений, але YunoHost не зміг поширити це на пароль root!", + "restore_system_part_failed": "Не вдалося відновити системну частину '{part}'.", + "restore_running_hooks": "Запуск хуков відновлення…", + "restore_running_app_script": "Відновлення програми \"{app} '…", + "restore_removing_tmp_dir_failed": "Неможливо видалити старий тимчасовий каталог", + "restore_nothings_done": "Нічого не було відновлено", + "restore_not_enough_disk_space": "Недостатньо місця (простір: {free_space: d} B, необхідний простір: {needed_space: d} B, маржа безпеки: {margin: d} B)", + "restore_may_be_not_enough_disk_space": "Схоже, у вашій системі недостатньо місця (вільного: {free_space: d} B, необхідний простір: {needed_space: d} B, запас міцності: {margin: d} B)", + "restore_hook_unavailable": "Сценарій відновлення для '{part}' недоступним у вашій системі і в архіві його теж немає", + "restore_failed": "Не вдалося відновити систему", + "restore_extracting": "Витяг необхідних файлів з архіву…", + "restore_confirm_yunohost_installed": "Ви дійсно хочете відновити вже встановлену систему? [{Відповіді}].", + "restore_complete": "відновлення завершено", + "restore_cleaning_failed": "Не вдалося очистити тимчасовий каталог відновлення", + "restore_backup_too_old": "Цей архів резервних копій не може бути відновлений, бо він отриманий з дуже старою версією YunoHost.", + "restore_already_installed_apps": "Наступні програми не можуть бути відновлені, тому що вони вже встановлені: {apps}", + "restore_already_installed_app": "Додаток з ідентифікатором \"{app} 'вже встановлено", + "regex_with_only_domain": "Ви не можете використовувати regex для домену, тільки для шляху.", + "regex_incompatible_with_tile": "/! \\ Packagers! Дозвіл '{permission}' має значення show_tile 'true', тому ви не можете визначити regex URL в якості основного URL.", + "regenconf_need_to_explicitly_specify_ssh": "Конфігурація ssh була змінена вручну, але вам потрібно явно вказати категорію 'ssh' з --force, щоб застосувати зміни.", + "regenconf_pending_applying": "Застосування очікує конфігурації для категорії '{категорія}'...", + "regenconf_failed": "Не вдалося відновити конфігурацію для категорії (категорій): {categories}", + "regenconf_dry_pending_applying": "Перевірка очікує конфігурації, яка була б застосована для категорії '{категорія}'…", + "regenconf_would_be_updated": "Конфігурація була б оновлена для категорії '{категорія}'", + "regenconf_updated": "Конфігурація оновлена для категорії '{category}'", + "regenconf_up_to_date": "Конфігурація вже оновлена для категорії '{категорія}'", + "regenconf_now_managed_by_yunohost": "Конфігураційний файл '{conf}' тепер управляється YunoHost (категорія {category}).", + "regenconf_file_updated": "Конфігураційний файл '{conf}' оновлений", + "regenconf_file_removed": "Конфігураційний файл '{conf}' видалений", + "regenconf_file_remove_failed": "Неможливо видалити файл конфігурації '{conf}'", + "regenconf_file_manually_removed": "Конфігураційний файл '{conf}' був видалений вручну і не буде створено", + "regenconf_file_manually_modified": "Конфігураційний файл '{conf}' був змінений вручну і не буде оновлено", + "regenconf_file_kept_back": "Конфігураційний файл '{conf}' повинен був бути вилучений regen-conf (категорія {category}), але був збережений.", + "regenconf_file_copy_failed": "Не вдалося скопіювати новий файл конфігурації '{new}' в '{conf}'", + "regenconf_file_backed_up": "Конфігураційний файл '{conf}' збережений в '{backup}'", + "postinstall_low_rootfsspace": "Загальна площа кореневої файлової системи становить менше 10 ГБ, що викликає занепокоєння! Швидше за все, дисковий простір закінчиться дуже швидко! Рекомендується мати не менше 16 ГБ для кореневої файлової системи. Якщо ви хочете встановити YunoHost, незважаючи на це попередження, повторно запустіть постінсталляцію з параметром --force-diskspace", + "port_already_opened": "Порт {port: d} вже відкритий для з'єднань {ip_version}.", + "port_already_closed": "Порт {port: d} вже закритий для з'єднань {ip_version}.", + "permission_require_account": "Дозвіл {permission} має сенс тільки для користувачів, що мають обліковий запис, і тому не може бути включено для відвідувачів.", + "permission_protected": "Дозвіл {permission} захищено. Ви не можете додавати або видаляти групу відвідувачів в/з цього дозволу.", + "permission_updated": "Дозвіл '{permission}' оновлено", + "permission_update_failed": "Не вдалося оновити дозвіл '{permission}': {error}", + "permission_not_found": "Дозвіл '{permission}', не знайдено", + "permission_deletion_failed": "Не вдалося видалити дозвіл '{permission}': {помилка}", + "permission_deleted": "Дозвіл '{permission}' видалено", + "permission_cant_add_to_all_users": "Дозвіл {permission} не може бути додано всім користувачам.", + "permission_currently_allowed_for_all_users": "В даний час цей дозвіл надається всім користувачам на додаток до інших груп. Ймовірно, вам потрібно або видалити дозвіл 'all_users', або видалити інші групи, яким воно зараз надано.", + "permission_creation_failed": "Не вдалося створити дозвіл '{permission}': {error}", + "permission_created": "Дозвіл '{permission}' створено", + "permission_cannot_remove_main": "Видалення основного дозволу заборонено", + "permission_already_up_to_date": "Дозвіл не було оновлено, тому що запити на додавання/видалення вже відповідають поточному стану.", + "permission_already_exist": "Дозвіл '{permission}' вже існує", + "permission_already_disallowed": "Група '{group}' вже має дозвіл \"{permission} 'відключено", + "permission_already_allowed": "Для гурту \"{group} 'вже включено дозвіл' {permission} '", + "pattern_password_app": "На жаль, паролі не можуть містити такі символи: {forbidden_chars}", + "pattern_username": "Повинен складатися тільки з букв і цифр в нижньому регістрі і символів підкреслення.", + "pattern_positive_number": "Повинно бути позитивним числом", + "pattern_port_or_range": "Повинен бути дійсний номер порту (наприклад, 0-65535) або діапазон портів (наприклад, 100: 200).", + "pattern_password": "Повинен бути довжиною не менше 3 символів", + "pattern_mailbox_quota": "Повинен бути розмір з суфіксом b/k/M/G/T або 0, щоб не мати квоти.", + "pattern_lastname": "Повинна бути дійсне прізвище", + "pattern_firstname": "Повинно бути дійсне ім'я", + "pattern_email": "Повинен бути дійсною адресою електронної пошти, без символу '+' (наприклад, someone@example.com ).", + "pattern_email_forward": "Повинен бути дійсну адресу електронної пошти, символ '+' приймається (наприклад, someone+tag@example.com )", + "pattern_domain": "Повинно бути дійсне доменне ім'я (наприклад, my-domain.org)", + "pattern_backup_archive_name": "Повинно бути правильне ім'я файлу, що містить не більше 30 символів, тільки букви і цифри символи і символ -_.", + "password_too_simple_4": "Пароль повинен бути довжиною не менше 12 символів і містити цифру, верхні, нижні і спеціальні символи.", + "password_too_simple_3": "Пароль повинен бути довжиною не менше 8 символів і містити цифру, верхні, нижні і спеціальні символи", + "password_too_simple_2": "Пароль повинен складатися не менше ніж з 8 символів і містити цифру, верхній і нижній символи", + "password_too_simple_1": "Пароль повинен складатися не менше ніж з 8 символів", + "password_listed": "Цей пароль входить в число найбільш часто використовуваних паролів в світі. Будь ласка, виберіть щось більш унікальне.", + "packages_upgrade_failed": "Не вдалося оновити всі пакети", + "operation_interrupted": "Операція була перервана вручну?", + "invalid_number": "Повинно бути число", + "not_enough_disk_space": "Недостатньо вільного місця на \"{шлях} '.", + "migrations_to_be_ran_manually": "Міграція {id} повинна бути запущена вручну. Будь ласка, перейдіть в розділ Інструменти → Міграції на сторінці веб-адміністратора або виконайте команду `yunohost tools migrations run`.", + "migrations_success_forward": "Міграція {id} завершена", + "migrations_skip_migration": "Пропуск міграції {id}...", + "migrations_running_forward": "Виконання міграції {id}...", + "migrations_pending_cant_rerun": "Ці міграції ще не завершені, тому не можуть бути запущені знову: {ids}", + "migrations_not_pending_cant_skip": "Ці міграції не очікують виконання, тому не можуть бути пропущені: {ids}", + "migrations_no_such_migration": "Не існує міграції під назвою '{id}'.", + "migrations_no_migrations_to_run": "Немає міграцій для запуску", + "migrations_need_to_accept_disclaimer": "Щоб запустити міграцію {id}, ви повинні прийняти наступний відмова від відповідальності: --- {disclaimer} --- Якщо ви згодні запустити міграцію, будь ласка, повторіть команду з опцією '--accept-disclaimer'.", + "migrations_must_provide_explicit_targets": "Ви повинні вказати явні цілі при використанні '--skip' або '--force-rerun'.", + "migrations_migration_has_failed": "Міграція {id} не завершена, переривається. Помилка: {exception}.", + "migrations_loading_migration": "Завантаження міграції {id}...", + "migrations_list_conflict_pending_done": "Ви не можете одночасно використовувати '--previous' і '--done'.", + "migrations_exclusive_options": "'--Auto', '--skip' і '--force-rerun' є взаємовиключними опціями.", + "migrations_failed_to_load_migration": "Не вдалося завантажити міграцію {id}: {error}", + "migrations_dependencies_not_satisfied": "Запустіть ці міграції: '{dependencies_id}', перед міграцією {id}.", + "migrations_cant_reach_migration_file": "Не вдалося отримати доступ до файлів міграцій по шляху '% s'.", + "migrations_already_ran": "Ці міграції вже виконані: {ids}", + "migration_0019_slapd_config_will_be_overwritten": "Схоже, що ви вручну відредагували конфігурацію slapd. Для цього критичного переходу YunoHost повинен примусово оновити конфігурацію slapd. Оригінальні файли будуть збережені в {conf_backup_folder}.", + "migration_0019_add_new_attributes_in_ldap": "Додавання нових атрибутів для дозволів в базі даних LDAP", + "migration_0018_failed_to_reset_legacy_rules": "Не вдалося скинути застарілі правила iptables: {error}", + "migration_0018_failed_to_migrate_iptables_rules": "Не вдалося перенести застарілі правила iptables в nftables: {error}", + "migration_0017_not_enough_space": "Звільніть достатньо місця в {path} для запуску міграції.", + "migration_0017_postgresql_11_not_installed": "PostgreSQL 9.6 встановлений, але не postgresql 11‽ Можливо, у вашій системі відбулося щось дивне: (...", + "migration_0017_postgresql_96_not_installed": "PostgreSQL ні встановлено у вашій системі. Нічого не потрібно робити.", + "migration_0015_weak_certs": "Було виявлено, що такі сертифікати все ще використовують слабкі алгоритми підпису і повинні бути оновлені для сумісності з наступною версією nginx: {certs}", + "migration_0015_cleaning_up": "Очищення кеш-пам'яті і пакетів, які більше не потрібні...", + "migration_0015_specific_upgrade": "Початок поновлення системних пакетів, які повинні бути оновлені незалежно...", + "migration_0015_modified_files": "Зверніть увагу, що такі файли були змінені вручну і можуть бути перезаписані після поновлення: {manually_modified_files}.", + "migration_0015_problematic_apps_warning": "Зверніть увагу, що були виявлені наступні, можливо, проблемні встановлені додатки. Схоже, що вони не були встановлені з каталогу додатків YunoHost або не зазначені як \"робочі\". Отже, не можна гарантувати, що вони будуть працювати після оновлення: {problematic_apps}.", + "migration_0015_general_warning": "Будь ласка, зверніть увагу, що ця міграція є делікатною операцією. Команда YunoHost зробила все можливе, щоб перевірити і протестувати її, але міграція все ще може порушити частина системи або її додатків. Тому рекомендується: - Виконати резервне копіювання всіх важливих даних або додатків. Більш детальна інформація на сайті https://yunohost.org/backup; - Наберіться терпіння після запуску міграції: В залежності від вашого підключення до Інтернету і апаратного забезпечення, оновлення може зайняти до декількох годин.", + "migration_0015_system_not_fully_up_to_date": "Ваша система не повністю оновлена. Будь ласка, виконайте регулярне оновлення перед запуском міграції на Buster.", + "migration_0015_not_enough_free_space": "Вільного місця в/var/досить мало! У вас повинно бути не менше 1 ГБ вільного місця, щоб запустити цю міграцію.", + "migration_0015_not_stretch": "Поточний дистрибутив Debian не є Stretch!", + "migration_0015_yunohost_upgrade": "Починаємо оновлення ядра YunoHost...", + "migration_0015_still_on_stretch_after_main_upgrade": "Щось пішло не так під час основного поновлення, система, схоже, все ще знаходиться на Debian Stretch", + "migration_0015_main_upgrade": "Початок основного поновлення...", + "migration_0015_patching_sources_list": "Виправлення sources.lists...", + "migration_0015_start": "Початок міграції на Buster", + "migration_update_LDAP_schema": "Оновлення схеми LDAP...", + "migration_ldap_rollback_success": "Система відкотилася.", + "migration_ldap_migration_failed_trying_to_rollback": "Не вдалося виконати міграцію... спроба відкату системи.", + "migration_ldap_can_not_backup_before_migration": "Не вдалося завершити резервне копіювання системи перед невдалої міграцією. Помилка: {error}", + "migration_ldap_backup_before_migration": "Створення резервної копії бази даних LDAP і установки додатків перед фактичної міграцією.", + "migration_description_0020_ssh_sftp_permissions": "Додайте підтримку дозволів SSH і SFTP", + "migration_description_0019_extend_permissions_features": "Розширення/переробка системи управління дозволами додатків", + "migration_description_0018_xtable_to_nftable": "Перенесення старих правил мережевого трафіку в нову систему nftable", + "migration_description_0017_postgresql_9p6_to_11": "Перенесення баз даних з PostgreSQL 9.6 на 11", + "migration_description_0016_php70_to_php73_pools": "Перенесіть php7.0-fpm 'pool' conf файли на php7.3", + "migration_description_0015_migrate_to_buster": "Оновлення системи до Debian Buster і YunoHost 4.x", + "migrating_legacy_permission_settings": "Перенесення застарілих налаштувань дозволів...", + "main_domain_changed": "Основний домен був змінений", + "main_domain_change_failed": "Неможливо змінити основний домен", + "mail_unavailable": "Ця електронна адреса зарезервований і буде автоматично виділено найпершого користувачеві", + "mailbox_used_space_dovecot_down": "Поштова служба Dovecot повинна бути запущена, якщо ви хочете отримати використане місце в поштовій скриньці.", + "mailbox_disabled": "Електронна пошта відключена для користувача {user}", + "mail_forward_remove_failed": "Не вдалося видалити переадресацію електронної пошти '{mail}'", + "mail_domain_unknown": "Неправильну адресу електронної пошти для домену '{domain}'. Будь ласка, використовуйте домен, адмініструється цим сервером.", + "mail_alias_remove_failed": "Не вдалося видалити псевдонім електронної пошти '{mail}'", + "log_tools_reboot": "перезавантажити сервер", + "log_tools_shutdown": "Вимкнути ваш сервер", + "log_tools_upgrade": "Оновлення системних пакетів", + "log_tools_postinstall": "Постінсталляція вашого сервера YunoHost", + "log_tools_migrations_migrate_forward": "запустіть міграції", + "log_domain_main_domain": "Зробити '{}' основним доменом", + "log_user_permission_reset": "Скинути дозвіл \"{} '", + "log_user_permission_update": "Оновити доступи для дозволу '{}'", + "log_user_update": "Оновити інформацію для користувача '{}'", + "log_user_group_update": "Оновити групу '{}'", + "log_user_group_delete": "Видалити групу \"{} '", + "log_user_group_create": "Створити групу '{}'", + "log_user_delete": "Видалити користувача '{}'", + "log_user_create": "Додати користувача '{}'", + "log_regen_conf": "Регенерувати системні конфігурації '{}'", + "log_letsencrypt_cert_renew": "Оновити сертифікат Let's Encrypt на домені '{}'", + "log_selfsigned_cert_install": "Встановити самоподпісанний сертифікат на домені '{}'", + "log_permission_url": "Оновити URL, пов'язаний з дозволом '{}'", + "log_permission_delete": "Видалити дозвіл \"{} '", + "log_permission_create": "Створити дозвіл \"{} '", + "log_letsencrypt_cert_install": "Встановіть сертифікат Let's Encrypt на домен '{}'", + "log_dyndns_update": "Оновити IP, пов'язаний з вашим піддоменом YunoHost '{}'", + "log_dyndns_subscribe": "Підписка на піддомен YunoHost '{}'", + "log_domain_remove": "Видалити домен '{}' з конфігурації системи", + "log_domain_add": "Додати домен '{}' в конфігурацію системи", + "log_remove_on_failed_install": "Видалити '{}' після невдалої установки", + "log_remove_on_failed_restore": "Видалити '{}' після невдалого відновлення з резервного архіву", + "log_backup_restore_app": "Відновлення '{}' з архіву резервних копій", + "log_backup_restore_system": "Відновлення системи з резервного архіву", + "log_backup_create": "Створення резервного архіву", + "log_available_on_yunopaste": "Цей журнал тепер доступний за посиланням {url}", + "log_app_config_apply": "Застосувати конфігурацію до додатка \"{} '", + "log_app_config_show_panel": "Показати панель конфігурації програми \"{} '", + "log_app_action_run": "Активації дії додатка \"{} '", + "log_app_makedefault": "Зробити '{}' додатком за замовчуванням", + "log_app_upgrade": "Оновити додаток '{}'", + "log_app_remove": "Для видалення програми '{}'", + "log_app_install": "Встановіть додаток '{}'", + "log_app_change_url": "Змініть URL-адресу додатка \"{} '", + "log_operation_unit_unclosed_properly": "Блок операцій не був закритий належним чином", + "log_does_exists": "Немає журналу операцій з ім'ям '{log}', використовуйте 'yunohost log list', щоб подивитися всі публічні журнали операцій", + "log_help_to_get_failed_log": "Операція '{desc}' не може бути завершена. Будь ласка, поділіться повним журналом цієї операції, використовуючи команду 'yunohost log share {name}', щоб отримати допомогу.", + "log_link_to_failed_log": "Не вдалося завершити операцію '{desc}'. Будь ласка, надайте повний журнал цієї операції, натиснувши тут , щоб отримати допомогу.", + "log_help_to_get_log": "Щоб переглянути журнал операції '{desc}', використовуйте команду 'yunohost log show {name} {name}'.", + "log_link_to_log": "Повний журнал цієї операції: ' {desc} '", + "log_corrupted_md_file": "Файл метаданих YAML, пов'язаний з журналами, пошкоджений: '{md_file} Помилка: {error}'", + "iptables_unavailable": "Ви не можете грати з iptables тут. Ви перебуваєте або в контейнері, або ваше ядро не підтримує його.", + "ip6tables_unavailable": "Ви не можете грати з ip6tables тут. Ви перебуваєте або в контейнері, або ваше ядро не підтримує його.", + "invalid_regex": "Невірний regex: '{regex}'", + "installation_complete": "установка завершена", + "hook_name_unknown": "Невідоме ім'я хука '{name}'", + "hook_list_by_invalid": "Це властивість не може бути використано для перерахування хуков", + "hook_json_return_error": "Не вдалося розпізнати повернення з хука {шлях}. Помилка: {msg}. Необроблений контент: {raw_content}.", + "hook_exec_not_terminated": "Скрипт не завершився належним чином: {шлях}", + "hook_exec_failed": "Не вдалося запустити скрипт: {path}", + "group_user_not_in_group": "Користувач {user} не входить в групу {group}", + "group_user_already_in_group": "Користувач {user} вже в групі {group}", + "group_update_failed": "Не вдалося оновити групу '{group}': {error}", + "group_updated": "Група '{group}' оновлена", + "group_unknown": "Група '{group}' невідома.", + "group_deletion_failed": "Не вдалося видалити групу '{group}': {error}", + "group_deleted": "Група '{group}' вилучена", + "group_cannot_be_deleted": "Група {group} не може бути видалена вручну.", + "group_cannot_edit_primary_group": "Група '{group}' не може бути відредаговано вручну. Це основна група, призначена тільки для одного конкретного користувача.", + "group_cannot_edit_visitors": "Група 'visitors' не може бути відредаговано вручну. Це спеціальна група, що представляє анонімних відвідувачів.", + "group_cannot_edit_all_users": "Група 'all_users' не може бути відредаговано вручну. Це спеціальна група, призначена для всіх користувачів, зареєстрованих в YunoHost.", + "group_creation_failed": "Не вдалося створити групу \"{group} ': {error}", + "group_created": "Група '{group}' створена", + "group_already_exist_on_system_but_removing_it": "Група {group} вже існує в групах системи, але YunoHost видалить її...", + "group_already_exist_on_system": "Група {group} вже існує в групах системи", + "group_already_exist": "Група {group} вже існує", + "good_practices_about_user_password": "Зараз ви маєте визначити новий пароль користувача. Пароль повинен складатися не менше ніж з 8 символів, але хорошою практикою є використання більш довгого пароля (тобто парольної фрази) і/або використання різних символів (заголовних, малих, цифр і спеціальних символів).", + "good_practices_about_admin_password": "Зараз ви збираєтеся поставити новий пароль адміністратора. Пароль повинен складатися не менше ніж з 8 символів, але хорошою практикою є використання більш довгого пароля (тобто парольної фрази) і/або використання різних символів (прописних, малих, цифр і спеціальних символів).", + "global_settings_unknown_type": "Несподівана ситуація, параметр {setting} має тип {unknown_type}, але це не тип, підтримуваний системою.", + "global_settings_setting_backup_compress_tar_archives": "При створенні нових резервних копій стискати архіви (.tar.gz) замість незжатих архівів (.tar). NB: включення цієї опції означає створення більш легких архівів резервних копій, але початкова процедура резервного копіювання буде значно довше і важче для CPU.", + "global_settings_setting_security_webadmin_allowlist": "IP-адреси, яким дозволений доступ до веб-адміну. Через кому.", + "global_settings_setting_security_webadmin_allowlist_enabled": "Дозволити доступ до веб-адміну тільки деяким IP-адресами.", + "global_settings_setting_smtp_relay_password": "Пароль хоста SMTP-ретрансляції", + "global_settings_setting_smtp_relay_user": "Обліковий запис користувача SMTP-реле", + "global_settings_setting_smtp_relay_port": "Порт SMTP-реле", + "global_settings_setting_smtp_relay_host": "SMTP релейний хост, який буде використовуватися для відправки пошти замість цього примірника yunohost. Корисно, якщо ви знаходитеся в одній із цих ситуацій: ваш 25 порт заблокований вашим провайдером або VPS провайдером, у вас є житловий IP в списку DUHL, ви не можете налаштувати зворотний DNS або цей сервер не доступний безпосередньо в інтернеті і ви хочете використовувати інший сервер для відправки пошти.", + "global_settings_setting_smtp_allow_ipv6": "Дозволити використання IPv6 для отримання і відправки пошти", + "global_settings_setting_ssowat_panel_overlay_enabled": "Включити накладення панелі SSOwat", + "global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Дозволити використання (застарілого) ключа DSA для конфігурації демона SSH", + "global_settings_unknown_setting_from_settings_file": "Невідомий ключ в настройках: '{setting_key}', відкиньте його і збережіть в /etc/yunohost/settings-unknown.json", + "global_settings_setting_security_ssh_port": "SSH-порт", + "global_settings_setting_security_postfix_compatibility": "Компроміс між сумісністю і безпекою для сервера Postfix. Впливає на шифри (і інші аспекти, пов'язані з безпекою)", + "global_settings_setting_security_ssh_compatibility": "Сумісність і співвідношення безпеки для SSH-сервера. Впливає на шифри (і інші аспекти, пов'язані з безпекою)", + "global_settings_setting_security_password_user_strength": "Надійність пароля користувача", + "global_settings_setting_security_password_admin_strength": "Надійність пароля адміністратора", + "global_settings_setting_security_nginx_compatibility": "Компроміс між сумісністю і безпекою для веб-сервера NGINX. Впливає на шифри (і інші аспекти, пов'язані з безпекою)", + "global_settings_setting_pop3_enabled": "Включити протокол POP3 для поштового сервера.", + "global_settings_reset_success": "Попередні настройки тепер збережені в {шлях}.", + "global_settings_key_doesnt_exists": "Ключ '{settings_key}' не існує в глобальних налаштуваннях, ви можете побачити всі доступні ключі, виконавши команду 'yunohost settings list'.", + "global_settings_cant_write_settings": "Неможливо зберегти файл настройок, причина: {причина}", + "global_settings_cant_serialize_settings": "Не вдалося серіалізовать дані налаштувань, причина: {причина}", + "global_settings_cant_open_settings": "Не вдалося відкрити файл настройок, причина: {причина}", + "global_settings_bad_type_for_setting": "Поганий тип для настройки {setting}, отриманий {received_type}, очікується {expected_type}", + "global_settings_bad_choice_for_enum": "Поганий вибір для настройки {setting}, отримано '{choice}', але доступні наступні варіанти: {available_choices}.", + "firewall_rules_cmd_failed": "Деякі команди правил брандмауера не спрацювали. Більш детальна інформація в журналі.", + "firewall_reloaded": "брандмауер перезавантажений", + "firewall_reload_failed": "Не вдалося перезавантажити брандмауер", + "file_does_not_exist": "Файл {шлях} не існує.", + "field_invalid": "Неприпустиме поле '{}'", + "experimental_feature": "Попередження: Ця функція є експериментальною і не вважається стабільною, ви не повинні використовувати її, якщо не знаєте, що робите.", + "extracting": "Витяг...", + "dyndns_unavailable": "Домен '{domain}' недоступний.", + "dyndns_domain_not_provided": "DynDNS провайдер {provider} не може надати домен {domain}.", + "dyndns_registration_failed": "Не вдалося зареєструвати домен DynDNS: {error}.", + "dyndns_registered": "Домен DynDNS зареєстрований", + "dyndns_provider_unreachable": "Неможливо зв'язатися з провайдером DynDNS {provider}: або ваш YunoHost неправильно підключений до інтернету, або сервер dynette не працює.", + "dyndns_no_domain_registered": "Домен не зареєстрований в DynDNS", + "dyndns_key_not_found": "DNS-ключ не знайдений для домену", + "dyndns_key_generating": "Генерація DNS-ключа... Це може зайняти деякий час.", + "dyndns_ip_updated": "Оновлення свій IP-адресу в DynDNS", + "dyndns_ip_update_failed": "Не вдалося оновити IP-адреса в DynDNS", + "dyndns_could_not_check_available": "Не вдалося перевірити наявність певної {домен} на {провайдера}.", + "dyndns_could_not_check_provide": "Не вдалося перевірити, чи може {провайдер} надати {домен}.", + "dpkg_lock_not_available": "Ця команда не може бути виконана прямо зараз, тому що інша програма, схоже, використовує блокування dpkg (системного менеджера пакетів).", + "dpkg_is_broken": "Ви не можете зробити це прямо зараз, тому що dpkg/APT (системні менеджери пакетів), схоже, знаходяться в зламаному стані... Ви можете спробувати вирішити цю проблему, підключившись через SSH і виконавши `sudo apt install --fix-broken` і/або `sudo dpkg --configure -a`.", + "downloading": "Завантаження…", + "done": "Готово", + "domains_available": "Доступні домени:", + "domain_unknown": "невідомий домен", + "domain_name_unknown": "Домен '{domain}' невідомий", + "domain_uninstall_app_first": "Ці додатки все ще встановлені на вашому домені: {apps} ласка, видаліть їх за допомогою 'yunohost app remove the_app_id' або перемістити їх на інший домен за допомогою 'yunohost app change-url the_app_id', перш ніж приступити до видалення домену.", + "domain_remove_confirm_apps_removal": "Видалення цього домену призведе до видалення цих додатків: {apps} Ви впевнені, що хочете це зробити? [{Відповіді}].", + "domain_hostname_failed": "Неможливо встановити нове ім'я хоста. Це може викликати проблеми в подальшому (можливо, все буде в порядку).", + "domain_exists": "Домен вже існує", + "domain_dyndns_root_unknown": "Невідомий кореневої домен DynDNS", + "domain_dyndns_already_subscribed": "Ви вже підписалися на домен DynDNS", + "domain_dns_conf_is_just_a_recommendation": "Ця команда показує * рекомендовану * конфігурацію. Насправді вона не встановлює конфігурацію DNS для вас. Ви самі повинні налаштувати свою зону DNS у реєстратора відповідно до цих рекомендацій.", + "domain_deletion_failed": "Неможливо видалити домен {domain}: {помилка}", + "domain_deleted": "домен видалений", + "domain_creation_failed": "Неможливо створити домен {domain}: {помилка}", + "domain_created": "домен створений", + "domain_cert_gen_failed": "Не вдалося згенерувати сертифікат", + "domain_cannot_remove_main_add_new_one": "Ви не можете видалити '{domain}', так як це основний домен і ваш єдиний домен, вам потрібно спочатку додати інший домен за допомогою 'yunohost domain add ', потім встановити його як основний домен за допомогою ' yunohost domain main-domain -n 'і потім ви можете видалити домен' {domain} 'за допомогою' yunohost domain remove {domain} ''.", + "domain_cannot_add_xmpp_upload": "Ви не можете додавати домени, що починаються з 'xmpp-upload.'. Таке ім'я зарезервовано для функції XMPP upload, вбудованої в YunoHost.", + "domain_cannot_remove_main": "Ви не можете видалити '{domain}', так як це основний домен, спочатку вам потрібно встановити інший домен в якості основного за допомогою 'yunohost domain main-domain -n '; ось список доменів-кандидатів: {other_domains}", + "disk_space_not_sufficient_update": "Недостатньо місця на диску для поновлення цього додатка", + "disk_space_not_sufficient_install": "Бракує місця на диску для установки цього додатка", + "diagnosis_sshd_config_inconsistent_details": "Будь ласка, виконайте yunohost settings set security.ssh.port -v YOUR_SSH_PORT , щоб визначити порт SSH, і перевірте yunohost tools regen-conf ssh --dry-run --with-diff yunohost tools regen-conf ssh --force , щоб скинути ваш conf на рекомендований YunoHost.", + "diagnosis_sshd_config_inconsistent": "Схоже, що порт SSH був вручну змінений в/etc/ssh/sshd_config. Починаючи з версії YunoHost 4.2, доступний новий глобальний параметр 'security.ssh.port', що дозволяє уникнути ручного редагування конфігурації.", + "diagnosis_sshd_config_insecure": "Схоже, що конфігурація SSH була змінена вручну і є небезпечною, оскільки не містить директив 'AllowGroups' або 'AllowUsers' для обмеження доступу авторизованих користувачів.", + "diagnosis_processes_killed_by_oom_reaper": "Деякі процеси були недавно вбито системою через брак пам'яті. Зазвичай це є симптомом нестачі пам'яті в системі або процесу, який з'їв дуже багато пам'яті. Зведення убитих процесів: {kills_summary}", + "diagnosis_never_ran_yet": "Схоже, що цей сервер був налаштований недавно, і поки немає звіту про діагностику. Вам слід почати з повної діагностики, або з веб-адміністратора, або використовуючи 'yunohost diagnosis run' з командного рядка.", + "diagnosis_unknown_categories": "Наступні категорії невідомі: {categories}", + "diagnosis_http_nginx_conf_not_up_to_date_details": "Щоб виправити ситуацію, перевірте різницю за допомогою командного рядка, використовуючи yunohost tools regen-conf nginx --dry-run --with-diff , і якщо все в порядку, застосуйте зміни за допомогою yunohost tools regen-conf nginx --force .", + "diagnosis_http_nginx_conf_not_up_to_date": "Схоже, що конфігурація nginx цього домену була змінена вручну, що не дозволяє YunoHost визначити, чи доступний він по HTTP.", + "diagnosis_http_partially_unreachable": "Домен {domain} здається недоступним по HTTP ззовні локальної мережі в IPv {failed}, хоча він працює в IPv {passed}.", + "diagnosis_http_unreachable": "Домен {domain} здається недоступним через HTTP ззовні локальної мережі.", + "diagnosis_http_bad_status_code": "Схоже, що замість вашого сервера відповіла інша машина (можливо, ваш маршрутизатор).
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", + "diagnosis_http_connection_error": "Помилка підключення: не вдалося підключитися до запитуваного домену, швидше за все, він недоступний.", + "diagnosis_http_timeout": "При спробі зв'язатися з вашим сервером ззовні стався тайм-аут. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. Ви також повинні переконатися, що служба nginx запущена
3. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", + "diagnosis_http_ok": "Домен {domain} доступний по HTTP ззовні локальної мережі.", + "diagnosis_http_localdomain": "Домен {domain} з доменом .local TLD не може бути доступний ззовні локальної мережі.", + "diagnosis_http_could_not_diagnose_details": "Помилка: {error}.", + "diagnosis_http_could_not_diagnose": "Не вдалося діагностувати досяжність доменів ззовні в IPv {ipversion}.", + "diagnosis_http_hairpinning_issue_details": "Можливо, це пов'язано з блоком/маршрутизатором вашого інтернет-провайдера. В результаті, люди ззовні вашої локальної мережі зможуть отримати доступ до вашого сервера, як і очікувалося, але не люди зсередини локальної мережі (як ви, ймовірно?) При використанні доменного імені або глобального IP. Можливо, ви зможете поліпшити ситуацію, глянувши на https://yunohost.org/dns_local_network .", + "diagnosis_http_hairpinning_issue": "Схоже, що у вашій локальній мережі не включена проброска.", + "diagnosis_ports_forwarding_tip": "Щоб вирішити цю проблему, вам, швидше за все, потрібно налаштувати кидок портів на вашому інтернет-маршрутизатор, як описано в https://yunohost.org/isp_box_config.", + "diagnosis_ports_needed_by": "Відкриття цього порту необхідно для функцій {категорії} (служба {сервіс}).", + "diagnosis_ports_ok": "Порт {port} доступний ззовні.", + "diagnosis_ports_partially_unreachable": "Порт {port} не доступний ззовні в IPv {failed}.", + "diagnosis_ports_unreachable": "Порт {port} недоступний ззовні.", + "diagnosis_ports_could_not_diagnose_details": "Помилка: {error}", + "diagnosis_ports_could_not_diagnose": "Не вдалося діагностувати досяжність портів ззовні в IPv {ipversion}.", + "diagnosis_description_regenconf": "Конфігурації системи", + "diagnosis_description_mail": "Електронна пошта", + "diagnosis_description_ports": "виявлення портів", + "diagnosis_description_systemresources": "Системні ресурси", + "diagnosis_description_services": "Перевірка стану служб", + "diagnosis_description_dnsrecords": "записи DNS", + "diagnosis_description_ip": "Інтернет-з'єднання", + "diagnosis_description_basesystem": "Базова система", + "diagnosis_security_vulnerable_to_meltdown_details": "Щоб виправити це, вам слід оновити систему і перезавантажитися, щоб завантажити нове ядро linux (або звернутися до вашого серверного провайдеру, якщо це не спрацює). Додаткову інформацію див. На сайті https://meltdownattack.com/.", + "diagnosis_security_vulnerable_to_meltdown": "Схоже, що ви уразливі до критичної уразливості безпеки Meltdown.", + "diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {простір}, що вельми тривожно! Швидше за все, дисковий простір закінчиться дуже швидко! Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", + "diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {простір}. Це може бути нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", + "diagnosis_regenconf_manually_modified_details": "Це можливо нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що поновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою yunohost tools regen- conf {category} --force .", + "diagnosis_regenconf_manually_modified": "Конфігураційний файл {file} , схоже, був змінений вручну.", + "diagnosis_regenconf_allgood": "Всі конфігураційні файли відповідають рекомендованої конфігурації!", + "diagnosis_mail_queue_too_big": "Занадто багато відкладених листів в поштовій черзі ({nb_pending} emails)", + "diagnosis_mail_queue_unavailable_details": "Помилка: {error}", + "diagnosis_mail_queue_unavailable": "Неможливо дізнатися кількість очікують листів в черзі", + "diagnosis_mail_queue_ok": "{nb_pending} відкладені листи в поштових чергах", + "diagnosis_mail_blacklist_website": "Після визначення причини, по якій ви потрапили в чорний список, і її усунення, ви можете попросити видалити ваш IP або домен на {blacklist_website}.", + "diagnosis_mail_blacklist_reason": "Причина внесення в чорний список: {причина}", + "diagnosis_mail_blacklist_listed_by": "Ваш IP або домен {item} знаходиться в чорному списку {blacklist_name}.", + "diagnosis_mail_blacklist_ok": "IP-адреси і домени, які використовуються цим сервером, не внесені в чорний список", + "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Поточний зворотний DNS: {rdns_domain}
Очікуване значення: {ehlo_domain} .", + "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Зворотний DNS неправильно налаштований в IPv {ipversion}. Деякі електронні листи можуть бути не доставлені або можуть бути відзначені як спам.", + "diagnosis_mail_fcrdns_nok_alternatives_6": "Деякі провайдери не дозволяють вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ваш зворотний DNS правильно налаштований для IPv4, ви можете спробувати відключити використання IPv6 при відправці листів, виконавши команду yunohost settings set smtp.allow_ipv6 -v off . Примітка: останнє рішення означає, що ви не зможете відправляти або отримувати електронну пошту з нечисленних серверів, що використовують тільки IPv6.", + "diagnosis_mail_fcrdns_nok_alternatives_4": "Деякі провайдери не дозволять вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ви відчуваєте проблеми з-за цього, розгляньте наступні рішення:
- Деякі провайдери надають альтернативу
використання ретранслятора поштового сервера , хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN * з виділеним публічним IP * для обходу подібних обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Або можна переключитися на іншого провайдера .", + "diagnosis_mail_fcrdns_nok_details": "Спочатку спробуйте налаштувати зворотний DNS з {ehlo_domain} в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм тікет підтримки для цього).", + "diagnosis_mail_fcrdns_dns_missing": "У IPv {ipversion} не визначений зворотний DNS. Деякі листи можуть не доставлятися або позначатися як спам.", + "diagnosis_mail_fcrdns_ok": "Ваш зворотний DNS налаштований правильно!", + "diagnosis_mail_ehlo_could_not_diagnose_details": "Помилка: {error}.", + "diagnosis_mail_ehlo_could_not_diagnose": "Не вдалося діагностувати наявність певної поштовий сервер postfix ззовні в IPv {ipversion}.", + "diagnosis_mail_ehlo_wrong_details": "EHLO, отриманий віддаленим діагностичним центром в IPv {ipversion}, відрізняється від домену вашого сервера.
Отриманий EHLO: {wrong_ehlo}
Очікуваний: {right_ehlo} < br> найпоширенішою причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер . Крім того, переконайтеся, що в роботу сервера не втручається брандмауер або зворотний проксі-сервер.", + "diagnosis_mail_ehlo_wrong": "Інший поштовий SMTP-сервер відповідає на IPv {ipversion}. Ваш сервер, ймовірно, не зможе отримувати електронну пошту.", + "diagnosis_mail_ehlo_bad_answer_details": "Це може бути викликано тим, що замість вашого сервера відповідає інша машина.", + "diagnosis_mail_ehlo_bad_answer": "Ні-SMTP служба відповідає на порту 25 на IPv {ipversion}.", + "diagnosis_mail_ehlo_unreachable_details": "Не вдалося відкрити з'єднання по порту 25 з вашим сервером на IPv {ipversion}. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер .
2. Ви також повинні переконатися, що служба postfix запущена.
3. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", + "diagnosis_mail_ehlo_unreachable": "Поштовий сервер SMTP недоступний ззовні по IPv {ipversion}. Він не зможе отримувати повідомлення електронної пошти.", + "diagnosis_mail_ehlo_ok": "Поштовий сервер SMTP доступний ззовні і тому може отримувати електронну пошту!", + "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Деякі провайдери не дозволять вам розблокувати вихідний порт 25, тому що вони не піклуються про Net Neutrality.
- Деякі з них пропонують альтернативу використання ретранслятора поштового сервера , хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN * з виділеним публічним IP * для обходу такого роду обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Ви також можете розглянути можливість переходу на более дружнього до мережевого нейтралітету провайдера .", + "diagnosis_mail_outgoing_port_25_blocked_details": "Спочатку спробуйте розблокувати вихідний порт 25 в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм заявку в службу підтримки).", + "diagnosis_mail_outgoing_port_25_blocked": "Поштовий сервер SMTP не може відправляти електронні листи на інші сервери, оскільки вихідний порт 25 заблокований в IPv {ipversion}.", + "app_manifest_install_ask_path": "Оберіть шлях URL (після домену), за яким має бути встановлено цей застосунок", + "yunohost_postinstall_end_tip": "Постінсталляція завершена! Щоб завершити установку, будь ласка, розгляньте наступні варіанти: - додавання першого користувача через розділ 'Користувачі' веб-адміністратора (або 'yunohost user create ' в командному рядку); - діагностику можливих проблем через розділ 'Діагностика' веб-адміністратора (або 'yunohost diagnosis run' в командному рядку); - читання розділів 'Завершення установки' і 'Знайомство з YunoHost' в документації адміністратора: https://yunohost.org/admindoc.", + "yunohost_not_installed": "YunoHost встановлений неправильно. Будь ласка, запустіть 'yunohost tools postinstall'.", + "yunohost_installing": "Установлення YunoHost...", + "yunohost_configured": "YunoHost вже налаштований", + "yunohost_already_installed": "YunoHost вже встановлено", + "user_updated": "Інформація про користувача змінена", + "user_update_failed": "Не вдалося оновити користувача {user}: {error}", + "user_unknown": "Невідомий користувач: {user}", + "user_home_creation_failed": "Не вдалося створити домашню папку для користувача", + "user_deletion_failed": "Не вдалося видалити користувача {user}: {error}", + "user_deleted": "користувача видалено", + "user_creation_failed": "Не вдалося створити користувача {user}: {помилка}", + "user_created": "Аккаунт було створено", + "user_already_exists": "Користувач '{user}' вже існує", + "upnp_port_open_failed": "Не вдалося відкрити порт через UPnP", + "upnp_enabled": "UPnP включено", + "upnp_disabled": "UPnP вимкнено", + "upnp_dev_not_found": "UPnP-пристрій, не знайдено", + "upgrading_packages": "Оновлення пакетів...", + "upgrade_complete": "оновлення завершено", + "updating_apt_cache": "Вибірка доступних оновлень для системних пакетів...", + "update_apt_cache_warning": "Щось пішло не так при оновленні кеша APT (менеджера пакунків Debian). Ось дамп рядків sources.list, який може допомогти визначити проблемні рядки: {sourceslist}", + "update_apt_cache_failed": "Неможливо оновити кеш APT (менеджер пакетів Debian). Ось дамп рядків sources.list, який може допомогти визначити проблемні рядки: {sourceslist}", + "unrestore_app": "{App} не буде поновлено", + "unlimit": "немає квоти", + "unknown_main_domain_path": "Невідомий домен або шлях для '{app}'. Вам необхідно вказати домен і шлях, щоб мати можливість вказати URL для дозволу.", + "unexpected_error": "Щось пішло не так: {error}", + "unbackup_app": "{App} НЕ буде збережений", + "tools_upgrade_special_packages_completed": "Оновлення пакета YunoHost завершено. Натисніть [Enter] для повернення командного рядка", + "tools_upgrade_special_packages_explanation": "Спеціальне оновлення триватиме у фоновому режимі. Будь ласка, не запускайте ніяких інших дій на вашому сервері протягом наступних ~ 10 хвилин (в залежності від швидкості обладнання). Після цього вам, можливо, доведеться заново увійти в веб-адмін. Журнал поновлення буде доступний в Інструменти → Журнал (в веб-адміном) або за допомогою 'yunohost log list' (з командного рядка).", + "tools_upgrade_special_packages": "Тепер оновлюємо \"спеціальні\" (пов'язані з yunohost) пакети…", + "tools_upgrade_regular_packages_failed": "Не вдалося оновити пакети: {packages_list}", + "tools_upgrade_regular_packages": "Тепер оновлюємо \"звичайні\" (не пов'язані з yunohost) пакети…", + "tools_upgrade_cant_unhold_critical_packages": "Не вдалося утримати критичні пакети…", + "tools_upgrade_cant_hold_critical_packages": "Не вдалося утримати критичні пакети…", + "tools_upgrade_cant_both": "Неможливо оновити систему і програми одночасно", + "tools_upgrade_at_least_one": "Будь ласка, вкажіть 'apps', або 'system'.", + "this_action_broke_dpkg": "Ця дія порушило dpkg/APT (системні менеджери пакетів)... Ви можете спробувати вирішити цю проблему, підключившись по SSH і запустивши `sudo apt install --fix-broken` і/або` sudo dpkg --configure -a`.", + "system_username_exists": "Ім'я користувача вже існує в списку користувачів системи", + "system_upgraded": "система оновлена", + "ssowat_conf_updated": "Конфігурація SSOwat оновлена", + "ssowat_conf_generated": "Регенерувати конфігурація SSOwat", + "show_tile_cant_be_enabled_for_regex": "Ви не можете включити 'show_tile' прямо зараз, тому що URL для дозволу '{permission}' являє собою регекс", + "show_tile_cant_be_enabled_for_url_not_defined": "Ви не можете включити 'show_tile' прямо зараз, тому що спочатку ви повинні визначити URL для дозволу '{permission}'", + "service_unknown": "Невідома служба '{service}'", + "service_stopped": "Служба '{service}' зупинена", + "service_stop_failed": "Неможливо зупинити службу '{service}' Недавні журнали служб: {logs}", + "service_started": "Служба '{service}' запущена", + "service_start_failed": "Не вдалося запустити службу '{service}' Recent service logs: {logs}", + "diagnosis_mail_outgoing_port_25_ok": "Поштовий сервер SMTP може відправляти електронні листи (вихідний порт 25 не заблокований).", + "diagnosis_swap_tip": "Будь ласка, будьте обережні і знайте, що якщо сервер розміщує своп на SD-карті або SSD-накопичувачі, це може різко скоротити термін служби устройства`.", + "diagnosis_swap_ok": "Система має {усього} свопу!", + "diagnosis_swap_notsomuch": "Система має тільки {усього} свопу. Щоб уникнути ситуацій, коли в системі закінчується пам'ять, слід передбачити наявність не менше {рекомендованого} обсягу підкачки.", + "diagnosis_swap_none": "В системі повністю відсутній своп. Ви повинні розглянути можливість додавання принаймні {рекомендованого} обсягу підкачки, щоб уникнути ситуацій, коли системі не вистачає пам'яті.", + "diagnosis_ram_ok": "Система все ще має {доступно} ({доступний_процент}%) оперативної пам'яті з {усього}.", + "diagnosis_ram_low": "У системі є {доступно} ({доступний_процент}%) оперативної пам'яті (з {усього}). Будьте уважні.", + "diagnosis_ram_verylow": "Система має тільки {доступне} ({доступний_процент}%) оперативної пам'яті! (З {усього})", + "diagnosis_diskusage_ok": "У сховищі {mountpoint} (на пристрої {device} ) залишилося {free} ({free_percent}%) вільного місця (з {total})!", + "diagnosis_diskusage_low": "Сховище {mountpoint} (на пристрої {device} ) має тільки {free} ({free_percent}%) вільного місця (з {total}). Будьте уважні.", + "diagnosis_diskusage_verylow": "Сховище {mountpoint} (на пристрої {device} ) має тільки {free} ({free_percent}%) вільного місця (з {total}). Вам дійсно варто подумати про очищення простору!", + "diagnosis_services_bad_status_tip": "Ви можете спробувати перезапустити службу , а якщо це не допоможе, подивіться журнали служби в webadmin (з командного рядка це можна зробити за допомогою yunohost service restart {service} yunohost service log {service} ).", + "diagnosis_services_bad_status": "Сервіс {service} знаходиться в {status} :(", + "diagnosis_services_conf_broken": "Конфігурація порушена для служби {service}!", + "diagnosis_services_running": "Служба {service} запущена!", + "diagnosis_domain_expires_in": "Термін дії {домену} закінчується через {днів} днів.", + "diagnosis_domain_expiration_error": "Термін дії деяких доменів закінчується ДУЖЕ СКОРО!", + "diagnosis_domain_expiration_warning": "Термін дії деяких доменів закінчиться найближчим часом!", + "diagnosis_domain_expiration_success": "Ваші домени зареєстровані і не збираються спливати найближчим часом.", + "diagnosis_domain_expiration_not_found_details": "Інформація WHOIS для домену {domain} не містить інформації про термін дії?", + "diagnosis_domain_not_found_details": "Домен {domain} не існує в базі даних WHOIS або термін його дії закінчився!", + "diagnosis_domain_expiration_not_found": "Неможливо перевірити термін дії деяких доменів", + "diagnosis_dns_specialusedomain": "Домен {domain} заснований на домені верхнього рівня спеціального призначення (TLD) і тому не очікується, що у нього будуть актуальні записи DNS.", + "diagnosis_dns_try_dyndns_update_force": "Конфігурація DNS цього домену повинна автоматично управлятися YunoHost. Якщо це не так, ви можете спробувати примусово оновити її за допомогою команди yunohost dyndns update --force .", + "diagnosis_dns_point_to_doc": "Якщо вам потрібна допомога з налаштування DNS-записів, зверніться до документації на сайті https://yunohost.org/dns_config .", + "diagnosis_dns_discrepancy": "Наступний запис DNS, схоже, не відповідає рекомендованої конфігурації:
Type: {type}
Name: {name}
Поточне значення: {current}
Очікуване значення: {value} ", + "diagnosis_dns_missing_record": "Згідно рекомендованої конфігурації DNS, ви повинні додати запис DNS з наступною інформацією.
Тип: {type}
Name: {name}
Value: < code> {value} .", + "diagnosis_dns_bad_conf": "Деякі DNS-записи відсутні або невірні для домену {домен} (категорія {категорія})", + "diagnosis_dns_good_conf": "DNS-записи правильно налаштовані для домену {домен} (категорія {категорія})", + "diagnosis_ip_weird_resolvconf_details": "Файл /etc/resolv.conf повинен бути симлінк на /etc/resolvconf/run/resolv.conf , що вказує на 127.0.0.1 (dnsmasq ). Якщо ви хочете вручну налаштувати DNS Резолвер, відредагуйте /etc/resolv.dnsmasq.conf .", + "diagnosis_ip_weird_resolvconf": "Дозвіл DNS, схоже, працює, але схоже, що ви використовуєте для користувача /etc/resolv.conf .", + "diagnosis_ip_broken_resolvconf": "Схоже, що дозвіл доменних імен на вашому сервері порушено, що пов'язано з тим, що /etc/resolv.conf не вказує на 127.0.0.1 .", + "diagnosis_ip_broken_dnsresolution": "Дозвіл доменних імен, схоже, з якоїсь причини не працює... Брандмауер блокує DNS-запити?", + "diagnosis_ip_dnsresolution_working": "Дозвіл доменних імен працює!", + "diagnosis_ip_not_connected_at_all": "Здається, що сервер взагалі не підключений до Інтернету !?", + "diagnosis_ip_local": "Локальний IP: {local} .", + "diagnosis_ip_global": "Глобальний IP: {global} ", + "diagnosis_ip_no_ipv6_tip": "Наявність працюючого IPv6 не є обов'язковим для роботи вашого сервера, але це краще для здоров'я Інтернету в цілому. IPv6 зазвичай автоматично налаштовується системою або вашим провайдером, якщо він доступний. В іншому випадку вам, можливо, доведеться налаштувати деякі речі вручну, як пояснюється в документації тут: https://yunohost.org/#/ipv6. Якщо ви не можете включити IPv6 або якщо це здається вам занадто технічним, ви також можете сміливо ігнорувати це попередження.", + "diagnosis_ip_no_ipv6": "Сервер не має працюючого IPv6.", + "diagnosis_ip_connected_ipv6": "Сервер підключений до Інтернету через IPv6!", + "diagnosis_ip_no_ipv4": "Сервер не має працюючого IPv4.", + "diagnosis_ip_connected_ipv4": "Сервер підключений до Інтернету через IPv4!", + "diagnosis_no_cache": "Для категорії \"{категорія} 'ще немає кеша діагнозів.", + "diagnosis_failed": "Не вдалося результат діагностики для категорії '{категорія}': {error}", + "diagnosis_everything_ok": "Все виглядає добре для {категорії}!", + "diagnosis_found_warnings": "Знайдено {попередження} пунктів, які можна поліпшити для {категорії}.", + "diagnosis_found_errors_and_warnings": "Знайдено {помилки} істотний (і) питання (и) (і {попередження} попередження (я)), що відносяться до {категорії}!", + "diagnosis_found_errors": "Знайдена {помилка} важлива проблема (і), пов'язана з {категорією}!", + "diagnosis_ignored_issues": "(+ {Nb_ignored} проігнорована проблема (проблеми))", + "diagnosis_cant_run_because_of_dep": "Неможливо запустити діагностику для {категорії}, поки є важливі проблеми, пов'язані з {глибиною}.", + "diagnosis_cache_still_valid": "(Кеш все ще дійсний для діагностики {категорії}. Повторна діагностика поки не проводиться!)", + "diagnosis_failed_for_category": "Не вдалося провести діагностику для категорії '{категорія}': {error}", + "diagnosis_display_tip": "Щоб побачити знайдені проблеми, ви можете перейти в розділ Diagnosis в веб-адміном або виконати команду 'yunohost diagnosis show --issues --human-readable' з командного рядка.", + "diagnosis_package_installed_from_sury_details": "Деякі пакети були ненавмисно встановлені з стороннього сховища під назвою Sury. Команда YunoHost поліпшила стратегію роботи з цими пакетами, але очікується, що в деяких системах, які встановили додатки PHP7.3 ще на Stretch, залишаться деякі невідповідності. Щоб виправити цю ситуацію, спробуйте виконати наступну команду: {cmd_to_fix} .", + "diagnosis_package_installed_from_sury": "Деякі системні пакети повинні бути знижені в статусі", + "diagnosis_backports_in_sources_list": "Схоже, що apt (менеджер пакетів) налаштований на використання сховища backports. Якщо ви не знаєте, що робите, ми настійно не рекомендуємо встановлювати пакети з backports, тому що це може привести до нестабільності або конфліктів у вашій системі.", + "diagnosis_basesystem_ynh_inconsistent_versions": "Ви використовуєте несумісні версії пакетів YunoHost... швидше за все, через невдалий або часткового оновлення.", + "diagnosis_basesystem_ynh_main_version": "Сервер працює під управлінням YunoHost {main_version} ({repo})", + "diagnosis_basesystem_ynh_single_version": "{Пакет} версія: {версія} ({repo})", + "diagnosis_basesystem_kernel": "Сервер працює під управлінням ядра Linux {kernel_version}", + "diagnosis_basesystem_host": "Сервер працює під управлінням Debian {debian_version}", + "diagnosis_basesystem_hardware_model": "Модель сервера - {model}", + "diagnosis_basesystem_hardware": "Архітектура апаратного забезпечення сервера - {virt} {arch}", + "custom_app_url_required": "Ви повинні надати URL для оновлення вашого призначеного для користувача додатки {app}.", + "confirm_app_install_thirdparty": "НЕБЕЗПЕЧНО! Ця програма не входить в каталог додатків YunoHost. Установлення сторонніх додатків може порушити цілісність і безпеку вашої системи. Вам не слід встановлювати його, якщо ви не знаєте, що робите. НІЯКОЇ ПІДТРИМКИ НЕ БУДЕ, якщо цей додаток не буде працювати або зламає вашу систему... Якщо ви все одно готові піти на такий ризик, введіть '{answers}'.", + "confirm_app_install_danger": "НЕБЕЗПЕЧНО! Відомо, що це додаток все ще експериментальне (якщо не сказати, що воно явно не працює)! Вам не слід встановлювати його, якщо ви не знаєте, що робите. Ніякої підтримки не буде надано, якщо цей додаток не буде працювати або зламає вашу систему... Якщо ви все одно готові ризикнути, введіть '{answers}'.", + "confirm_app_install_warning": "Попередження: Ця програма може працювати, але не дуже добре інтегровано в YunoHost. Деякі функції, такі як єдина реєстрація та резервне копіювання/відновлення, можуть бути недоступні. Все одно встановити? [{Відповіді}]. ", + "certmanager_unable_to_parse_self_CA_name": "Не вдалося розібрати ім'я самоподпісивающегося центру (файл: {file})", + "certmanager_self_ca_conf_file_not_found": "Не вдалося знайти файл конфігурації для самоподпісивающегося центру (файл: {file})", + "certmanager_no_cert_file": "Не вдалося розпізнати файл сертифіката для домену {domain} (файл: {file})", + "certmanager_hit_rate_limit": "Для цього набору доменів {domain} недавно було випущено дуже багато сертифікатів. Будь ласка, спробуйте ще раз пізніше. Див. Https://letsencrypt.org/docs/rate-limits/ для отримання більш докладної інформації.", + "certmanager_warning_subdomain_dns_record": "Піддомен '{subdomain} \"не дозволяється на той же IP-адресу, що і' {domain} '. Деякі функції будуть недоступні, поки ви не виправите це і не перегенеріруете сертифікат.", + "certmanager_domain_http_not_working": "Домен {domain}, схоже, не доступний через HTTP. Будь ласка, перевірте категорію 'Web' в діагностиці для отримання додаткової інформації. (Якщо ви знаєте, що робите, використовуйте '--no-checks', щоб відключити ці перевірки).", + "certmanager_domain_dns_ip_differs_from_public_ip": "DNS-записи для домену '{domain}' відрізняються від IP цього сервера. Будь ласка, перевірте категорію 'DNS-записи' (основні) в діагностиці для отримання додаткової інформації. Якщо ви недавно змінили запис A, будь ласка, зачекайте, поки вона пошириться (деякі програми перевірки поширення DNS доступні в Інтернеті). (Якщо ви знаєте, що робите, використовуйте '--no-checks', щоб відключити ці перевірки).", + "certmanager_domain_cert_not_selfsigned": "Сертифікат для домену {domain} не є самоподпісанного. Ви впевнені, що хочете замінити його? (Для цього використовуйте '--force').", + "certmanager_domain_not_diagnosed_yet": "Поки немає результатів діагностики для домену {domain}. Будь ласка, повторно проведіть діагностику для категорій 'DNS-записи' і 'Web' в розділі діагностики, щоб перевірити, чи готовий домен до Let's Encrypt. (Або, якщо ви знаєте, що робите, використовуйте '--no-checks', щоб відключити ці перевірки).", + "certmanager_certificate_fetching_or_enabling_failed": "Спроба використовувати новий сертифікат для {domain} не спрацювала...", + "certmanager_cert_signing_failed": "Не вдалося підписати новий сертифікат", + "certmanager_cert_renew_success": "Сертифікат Let's Encrypt оновлений для домену '{domain}'", + "certmanager_cert_install_success_selfsigned": "Самоподпісанний сертифікат тепер встановлений для домену '{domain}'", + "certmanager_cert_install_success": "Сертифікат Let's Encrypt тепер встановлений для домену '{domain}'", + "certmanager_cannot_read_cert": "Щось не так сталося при спробі відкрити поточний сертифікат для домену {domain} (файл: {файл}), причина: {причина}", + "certmanager_attempt_to_replace_valid_cert": "Ви намагаєтеся перезаписати хороший і дійсний сертифікат для домену {domain}! (Використовуйте --force для обходу)", + "certmanager_attempt_to_renew_valid_cert": "Термін дії сертифіката для домену '{domain} \"не закінчується! (Ви можете використовувати --force, якщо знаєте, що робите)", + "certmanager_attempt_to_renew_nonLE_cert": "Сертифікат для домену '{domain}' не випущено Let's Encrypt. Неможливо продовжити його автоматично!", + "certmanager_acme_not_configured_for_domain": "Завдання ACME не може бути запущена для {domain} прямо зараз, тому що в його nginx conf відсутній відповідний фрагмент коду... Будь ласка, переконайтеся, що конфігурація nginx оновлена за допомогою `yunohost tools regen-conf nginx --dry-run - with-diff`.", + "backup_with_no_restore_script_for_app": "{App} не має скрипта відновлення, ви не зможете автоматично відновити резервну копію цього додатка.", + "backup_with_no_backup_script_for_app": "Додаток '{app}' не має скрипта резервного копіювання. Ігнорування.", + "backup_unable_to_organize_files": "Неможливо використовувати швидкий метод для організації файлів в архіві", + "backup_system_part_failed": "Не вдалося створити резервну копію системної частини '{part}'.", + "backup_running_hooks": "Запуск гачків резервного копіювання...", + "backup_permission": "Дозвіл на резервне копіювання для {app}", + "backup_output_symlink_dir_broken": "Ваш архівний каталог '{path}' є непрацюючою симлінк. Можливо, ви забули перемонтувати або підключити носій, на який вона вказує.", + "backup_output_directory_required": "Ви повинні вказати вихідний каталог для резервного копіювання", + "backup_output_directory_not_empty": "Ви повинні вибрати порожній вихідний каталог", + "backup_output_directory_forbidden": "Виберіть інший вихідний каталог. Резервні копії не можуть бути створені в підкаталогах/bin,/boot,/dev,/etc,/lib,/root,/run,/sbin,/sys,/usr,/var або /home/yunohost.backup/archives.", + "backup_nothings_done": "нічого зберігати", + "backup_no_uncompress_archive_dir": "Немає такого каталогу нестислого архіву", + "backup_mount_archive_for_restore": "Підготовка архіву для відновлення...", + "backup_method_tar_finished": "Створено архів резервного копіювання TAR", + "backup_method_custom_finished": "Призначений для користувача метод резервного копіювання '{метод}' завершено", + "backup_method_copy_finished": "Резервне копіювання завершено", + "backup_hook_unknown": "Гачок резервного копіювання '{hook}' невідомий", + "backup_deleted": "Резервна копія видалена", + "backup_delete_error": "Не вдалося видалити '{path}'", + "backup_custom_mount_error": "Призначений для користувача метод резервного копіювання не зміг пройти етап 'монтування'", + "backup_custom_backup_error": "Призначений для користувача метод резервного копіювання не зміг пройти етап 'резервне копіювання'", + "backup_csv_creation_failed": "Не вдалося створити CSV-файл, необхідний для відновлення", + "backup_csv_addition_failed": "Не вдалося додати файли для резервного копіювання в CSV-файл", + "backup_creation_failed": "Не вдалося створити архів резервного копіювання", + "backup_create_size_estimation": "Архів буде містити близько {розмір} даних.", + "backup_created": "Резервна копія створена", + "backup_couldnt_bind": "Не вдалося зв'язати {src} з {dest}.", + "backup_copying_to_organize_the_archive": "Копіювання {size} MB для організації архіву", + "backup_cleaning_failed": "Не вдалося очистити тимчасову папку резервного копіювання", + "backup_cant_mount_uncompress_archive": "Не вдалося змонтувати нестислий архів як захищений від запису", + "backup_ask_for_copying_if_needed": "Чи хочете ви тимчасово виконати резервне копіювання з використанням {size} MB? (Цей спосіб використовується, оскільки деякі файли не можуть бути підготовлені більш ефективним методом).", + "backup_archive_writing_error": "Не вдалося додати файли '{source}' (названі в архіві '{dest}') для резервного копіювання в стислий архів '{archive}'.", + "backup_archive_system_part_not_available": "Системна частина '{part}' недоступна в цій резервної копії", + "backup_archive_corrupted": "Схоже, що архів резервної копії \"{archive} 'пошкоджений: {error}", + "backup_archive_cant_retrieve_info_json": "Не вдалося завантажити інформацію для архіву '{archive}'... info.json не може бути отриманий (або не є коректним json).", + "backup_archive_open_failed": "Не вдалося відкрити архів резервних копій", + "backup_archive_name_unknown": "Невідомий локальний архів резервного копіювання з ім'ям '{name}'", + "backup_archive_name_exists": "Архів резервного копіювання з таким ім'ям вже існує.", + "backup_archive_broken_link": "Не вдалося отримати доступ до архіву резервного копіювання (непрацююча посилання на {path})", + "backup_archive_app_not_found": "Не вдалося знайти {app} в архіві резервного копіювання", + "backup_applying_method_tar": "Створення резервного TAR-архіву...", + "backup_applying_method_custom": "Виклик для користувача методу резервного копіювання '{метод}'...", + "backup_applying_method_copy": "Копіювання всіх файлів в резервну копію...", + "backup_app_failed": "Не вдалося створити резервну копію {app}", + "backup_actually_backuping": "Створення резервного архіву з зібраних файлів...", + "backup_abstract_method": "Цей метод резервного копіювання ще не реалізований", + "ask_password": "пароль", + "ask_new_path": "Новий шлях", + "ask_new_domain": "новий домен", + "ask_new_admin_password": "Новий адміністративний пароль", + "ask_main_domain": "основний домен", + "ask_lastname": "Прізвище", + "ask_firstname": "ім'я", + "ask_user_domain": "Домен для адреси електронної пошти користувача і облікового запису XMPP", + "apps_catalog_update_success": "Каталог додатків був оновлений!", + "apps_catalog_obsolete_cache": "Кеш каталогу додатків порожній або застарів.", + "apps_catalog_failed_to_download": "Неможливо завантажити каталог додатків {apps_catalog}: {помилка}.", + "apps_catalog_updating": "Оновлення каталогу додатків…", + "apps_catalog_init_success": "Система каталогу додатків инициализирована!", + "apps_already_up_to_date": "Всі додатки вже оновлені", + "app_packaging_format_not_supported": "Ця програма не може бути встановлено, тому що формат його упаковки не підтримується вашою версією YunoHost. Можливо, вам слід оновити вашу систему.", + "app_upgraded": "{App} оновлено", + "app_upgrade_some_app_failed": "Деякі програми не можуть бути оновлені", + "app_upgrade_script_failed": "Сталася помилка в сценарії оновлення програми", + "app_upgrade_failed": "Не вдалося оновити {app}: {error}", + "app_upgrade_app_name": "Зараз оновлюємо {app}...", + "app_upgrade_several_apps": "Наступні додатки будуть оновлені: {apps}", + "app_unsupported_remote_type": "Для додатка використовується непідтримуваний віддалений тип.", + "app_unknown": "невідоме додаток", + "app_start_restore": "Відновлення {app}...", + "app_start_backup": "Збір файлів для резервного копіювання {app}...", + "app_start_remove": "Видалення {app}...", + "app_start_install": "Установлення {app}...", + "app_sources_fetch_failed": "Не вдалося вихідні файли, URL коректний?", + "app_restore_script_failed": "Сталася помилка всередині скрипта відновити оригінальну програму", + "app_restore_failed": "Не вдалося відновити {app}: {error}", + "app_remove_after_failed_install": "Видалення програми після збою установки...", + "app_requirements_unmeet": "Вимоги не виконані для {app}, пакет {pkgname} ({version}) повинен бути {spec}.", + "app_requirements_checking": "Перевірка необхідних пакетів для {app}...", + "app_removed": "{App} видалено", + "app_not_properly_removed": "{App} не було видалено належним чином", + "app_not_installed": "Не вдалося знайти {app} в списку встановлених додатків: {all_apps}", + "app_not_correctly_installed": "{App}, схоже, неправильно встановлено", + "app_not_upgraded": "Додаток '{failed_app}' не вдалося оновити, і, як наслідок, оновлення таких програмах було скасовано: {apps}", + "app_manifest_install_ask_is_public": "Чи повинно це додаток бути відкрито для анонімних відвідувачів?", + "app_manifest_install_ask_admin": "Виберіть користувача-адміністратора для цього додатка", + "app_manifest_install_ask_password": "Виберіть пароль адміністратора для цього додатка" } From d0cd3437ba6f1d47a388817398aab7e1a368f3a7 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Sat, 28 Aug 2021 00:45:56 +0000 Subject: [PATCH 042/101] [CI] Format code --- data/hooks/diagnosis/80-apps.py | 34 ++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/data/hooks/diagnosis/80-apps.py b/data/hooks/diagnosis/80-apps.py index 4ab5a6c0d..177ec590f 100644 --- a/data/hooks/diagnosis/80-apps.py +++ b/data/hooks/diagnosis/80-apps.py @@ -6,6 +6,7 @@ from yunohost.app import app_list from yunohost.diagnosis import Diagnoser + class AppDiagnoser(Diagnoser): id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1] @@ -30,13 +31,17 @@ class AppDiagnoser(Diagnoser): if not app["issues"]: continue - level = "ERROR" if any(issue[0] == "error" for issue in app["issues"]) else "WARNING" + level = ( + "ERROR" + if any(issue[0] == "error" for issue in app["issues"]) + else "WARNING" + ) yield dict( meta={"test": "apps", "app": app["name"]}, status=level, summary="diagnosis_apps_issue", - details=[issue[1] for issue in app["issues"]] + details=[issue[1] for issue in app["issues"]], ) def issues(self, app): @@ -45,14 +50,19 @@ class AppDiagnoser(Diagnoser): if not app.get("from_catalog") or app["from_catalog"].get("state") != "working": yield ("error", "diagnosis_apps_not_in_app_catalog") - elif not isinstance(app["from_catalog"].get("level"), int) or app["from_catalog"]["level"] == 0: + elif ( + not isinstance(app["from_catalog"].get("level"), int) + or app["from_catalog"]["level"] == 0 + ): yield ("error", "diagnosis_apps_broken") elif app["from_catalog"]["level"] <= 4: yield ("warning", "diagnosis_apps_bad_quality") # Check for super old, deprecated practices - yunohost_version_req = app["manifest"].get("requirements", {}).get("yunohost", "").strip(">= ") + yunohost_version_req = ( + app["manifest"].get("requirements", {}).get("yunohost", "").strip(">= ") + ) if yunohost_version_req.startswith("2."): yield ("error", "diagnosis_apps_outdated_ynh_requirement") @@ -64,11 +74,21 @@ class AppDiagnoser(Diagnoser): "yunohost tools port-available", ] for deprecated_helper in deprecated_helpers: - if os.system(f"grep -nr -q '{deprecated_helper}' {app['setting_path']}/scripts/") == 0: + if ( + os.system( + f"grep -nr -q '{deprecated_helper}' {app['setting_path']}/scripts/" + ) + == 0 + ): yield ("error", "diagnosis_apps_deprecated_practices") - old_arg_regex = r'^domain=\${?[0-9]' - if os.system(f"grep -q '{old_arg_regex}' {app['setting_path']}/scripts/install") == 0: + old_arg_regex = r"^domain=\${?[0-9]" + if ( + os.system( + f"grep -q '{old_arg_regex}' {app['setting_path']}/scripts/install" + ) + == 0 + ): yield ("error", "diagnosis_apps_deprecated_practices") From a73b74a52db395a2f26fa4cb3a54042bb6da568a Mon Sep 17 00:00:00 2001 From: Weblate Date: Sat, 28 Aug 2021 21:46:54 +0000 Subject: [PATCH 043/101] Added translation using Weblate (Persian) --- locales/fa.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 locales/fa.json diff --git a/locales/fa.json b/locales/fa.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/locales/fa.json @@ -0,0 +1 @@ +{} From 27f6492f8b852bee40871ff810c4c49586aed1c4 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 30 Aug 2021 14:14:32 +0000 Subject: [PATCH 044/101] Added translation using Weblate (Kurdish (Central)) --- locales/ckb.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 locales/ckb.json diff --git a/locales/ckb.json b/locales/ckb.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/locales/ckb.json @@ -0,0 +1 @@ +{} From 82bc5a93483e74bbd8ff78bf88e3dc4934bab00f Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Tue, 31 Aug 2021 09:56:27 +0000 Subject: [PATCH 045/101] Translated using Weblate (Persian) Currently translated at 0.3% (2 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/fa.json b/locales/fa.json index 0967ef424..3c8761b5a 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -1 +1,4 @@ -{} +{ + "action_invalid": "اقدام نامعتبر '{action}'", + "aborting": "رها کردن." +} From e7e891574e7600a5ae47cc5d9910e480410abb03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Gaspar?= Date: Tue, 31 Aug 2021 10:11:18 +0000 Subject: [PATCH 046/101] Translated using Weblate (French) Currently translated at 100.0% (643 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 1cac6bbba..0b5a5e93f 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -571,7 +571,7 @@ "diagnosis_dns_try_dyndns_update_force": "La configuration DNS de ce domaine devrait être automatiquement gérée par YunoHost. Si ce n'est pas le cas, vous pouvez essayer de forcer une mise à jour en utilisant yunohost dyndns update --force.", "app_packaging_format_not_supported": "Cette application ne peut pas être installée car son format n'est pas pris en charge par votre version de YunoHost. Vous devriez probablement envisager de mettre à jour votre système.", "migration_0015_weak_certs": "Il a été constaté que les certificats suivants utilisent encore des algorithmes de signature peu robustes et doivent être mis à jour pour être compatibles avec la prochaine version de NGINX : {certs}", - "global_settings_setting_backup_compress_tar_archives": "Compresser les archives (.tar.gz) au lieu de créer des archives non-compressées lors de la création des sauvegardes. N.B. Activer cette option permet de créer des archives plus légères, mais aussi d'avoir des procédures de sauvegarde significativement plus longues et plus gourmandes en CPU.", + "global_settings_setting_backup_compress_tar_archives": "Lors de la création de nouvelles sauvegardes, compressez les archives (.tar.gz) au lieu des archives non compressées (.tar). N.B. : activer cette option permet de créer des archives plus légères, mais la procédure de sauvegarde initiale sera significativement plus longues et plus gourmandes en CPU.", "migration_description_0018_xtable_to_nftable": "Migrer les anciennes règles de trafic réseau vers le nouveau système basé sur nftables", "service_description_php7.3-fpm": "Exécute les applications écrites en PHP avec NGINX", "migration_0018_failed_to_reset_legacy_rules": "La réinitialisation des règles iptable par défaut a échoué : {error}", @@ -586,7 +586,7 @@ "app_manifest_install_ask_is_public": "Cette application devrait-elle être visible par les visiteurs anonymes ?", "app_manifest_install_ask_admin": "Choisissez un administrateur pour cette application", "app_manifest_install_ask_password": "Choisissez un mot de passe administrateur pour cette application", - "app_manifest_install_ask_path": "Choisissez le chemin sur lequel vous souhaitez installer cette application", + "app_manifest_install_ask_path": "Choisissez le chemin d'URL (après le domaine) où cette application doit être installée", "app_manifest_install_ask_domain": "Choisissez le domaine sur lequel vous souhaitez installer cette application", "global_settings_setting_smtp_relay_user": "Compte utilisateur du relais SMTP", "global_settings_setting_smtp_relay_port": "Port du relais SMTP", @@ -637,5 +637,9 @@ "global_settings_setting_security_webadmin_allowlist": "Adresses IP autorisées à accéder à la page web du portail d'administration (webadmin). Elles doivent être séparées par une virgule.", "global_settings_setting_security_webadmin_allowlist_enabled": "Autorisez seulement certaines IP à accéder à la page web du portail d'administration (webadmin).", "diagnosis_http_localdomain": "Le domaine {domain}, avec un TLD .local, ne devrait pas être atteint depuis l'extérieur du réseau local.", - "diagnosis_dns_specialusedomain": "Le domaine {domain} est basé sur un domaine de premier niveau (TLD) à usage spécial et ne devrait donc pas avoir d'enregistrements DNS réels." -} \ No newline at end of file + "diagnosis_dns_specialusedomain": "Le domaine {domain} est basé sur un domaine de premier niveau (TLD) à usage spécial et ne devrait donc pas avoir d'enregistrements DNS réels.", + "invalid_password": "Mot de passe incorrect", + "ldap_server_is_down_restart_it": "Le service LDAP est en panne, essayez de le redémarrer...", + "ldap_server_down": "Impossible d'atteindre le serveur LDAP", + "global_settings_setting_security_experimental_enabled": "Activez les fonctionnalités de sécurité expérimentales (ne l'activez pas si vous ne savez pas ce que vous faites !)" +} From dd6c58a7dac71c3ecc6831be93d0b216875b1381 Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Tue, 31 Aug 2021 11:27:56 +0000 Subject: [PATCH 047/101] Translated using Weblate (Persian) Currently translated at 2.9% (19 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/locales/fa.json b/locales/fa.json index 3c8761b5a..5a2b61bc1 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -1,4 +1,21 @@ { "action_invalid": "اقدام نامعتبر '{action}'", - "aborting": "رها کردن." + "aborting": "رها کردن.", + "app_change_url_failed_nginx_reload": "NGINX بارگیری نشد. در اینجا خروجی 'nginx -t' است:\n{nginx_errors}", + "app_argument_required": "استدلال '{name}' الزامی است", + "app_argument_password_no_default": "خطا هنگام تجزیه گذرواژه '{name}': به دلایل امنیتی استدلال رمز عبور نمی تواند مقدار پیش فرض داشته باشد", + "app_argument_invalid": "یک مقدار معتبر انتخاب کنید برای استدلال '{name}':{error}", + "app_argument_choice_invalid": "برای آرگومان '{name}' از یکی از این گزینه ها '{choices}' استفاده کنید", + "app_already_up_to_date": "{app} در حال حاضر به روز است", + "app_already_installed_cant_change_url": "این برنامه قبلاً نصب شده است. URL فقط با این عملکرد قابل تغییر نیست. در صورت موجود بودن برنامه `app changeurl` را بررسی کنید.", + "app_already_installed": "{app} قبلاً نصب شده است", + "app_action_broke_system": "این اقدام به نظر می رسد سرویس های مهمی را خراب کرده است: {services}", + "app_action_cannot_be_ran_because_required_services_down": "برای اجرای این عملیات سرویس هایی که مورد نیازاند و باید اجرا شوند: {services}. سعی کنید آنها را مجدداً راه اندازی کنید (و علت خرابی احتمالی آنها را بررسی کنید).", + "already_up_to_date": "کاری برای انجام دادن نیست. همه چیز در حال حاضر به روز است.", + "admin_password_too_long": "لطفاً گذرواژه ای کوتاهتر از 127 کاراکتر انتخاب کنید", + "admin_password_changed": "رمز مدیریت تغییر کرد", + "admin_password_change_failed": "تغییر رمز امکان پذیر نیست", + "admin_password": "رمز عبور مدیریت", + "additional_urls_already_removed": "نشانی اینترنتی اضافی '{url}' قبلاً در نشانی اینترنتی اضافی برای اجازه '{permission}'حذف شده است", + "additional_urls_already_added": "نشانی اینترنتی اضافی '{url}' قبلاً در نشانی اینترنتی اضافی برای اجازه '{permission}' اضافه شده است" } From 3264c4fc2d5030d1ea3c64184a35b80d876677be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M?= Date: Tue, 31 Aug 2021 15:58:42 +0000 Subject: [PATCH 048/101] Translated using Weblate (Galician) Currently translated at 90.9% (585 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/gl/ --- locales/gl.json | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/locales/gl.json b/locales/gl.json index 35a1b7390..e752716cd 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -543,5 +543,46 @@ "regenconf_now_managed_by_yunohost": "O ficheiro de configuración '{conf}' agora está xestionado por YunoHost (categoría {category}).", "regenconf_file_updated": "Actualizado o ficheiro de configuración '{conf}'", "regenconf_file_removed": "Eliminado o ficheiro de configuración '{conf}'", - "regenconf_file_remove_failed": "Non se puido eliminar o ficheiro de configuración '{conf}'" + "regenconf_file_remove_failed": "Non se puido eliminar o ficheiro de configuración '{conf}'", + "service_enable_failed": "Non se puido facer que o servizo '{service}' se inicie automáticamente no inicio.\n\nRexistros recentes do servizo: {logs}", + "service_disabled": "O servizo '{service}' xa non vai volver a ser iniciado ao inicio do sistema.", + "service_disable_failed": "Non se puido iniciar o servizo '{servizo}' ao inicio.\n\nRexistro recente do servizo: {logs}", + "service_description_yunohost-firewall": "Xestiona, abre e pecha a conexións dos portos aos servizos", + "service_description_yunohost-api": "Xestiona as interaccións entre a interface web de YunoHost e o sistema", + "service_description_ssh": "Permíteche conectar de xeito remoto co teu servidor a través dun terminal (protocolo SSH)", + "service_description_slapd": "Almacena usuarias, dominios e info relacionada", + "service_description_rspamd": "Filtra spam e outras características relacionadas co email", + "service_description_redis-server": "Unha base de datos especial utilizada para o acceso rápido a datos, cola de tarefas e comunicación entre programas", + "service_description_postfix": "Utilizado para enviar e recibir emails", + "service_description_php7.3-fpm": "Executa aplicacións escritas en PHP con NGINX", + "service_description_nginx": "Serve ou proporciona acceso a tódolos sitios web hospedados no teu servidor", + "service_description_mysql": "Almacena datos da app (base de datos SQL)", + "service_description_metronome": "Xestiona as contas de mensaxería instantánea XMPP", + "service_description_fail2ban": "Protexe contra ataques de forza bruta e outro tipo de ataques desde internet", + "service_description_dovecot": "Permite aos clientes de email acceder/obter o correo (vía IMAP e POP3)", + "service_description_dnsmasq": "Xestiona a resolución de nomes de dominio (DNS)", + "service_description_yunomdns": "Permíteche chegar ao teu servidor utilizando 'yunohost.local' na túa rede local", + "service_cmd_exec_failed": "Non se puido executar o comando '{command}'", + "service_already_stopped": "O servizo '{sevice}' xa está detido", + "service_already_started": "O servizo '{service}' xa se está a executar", + "service_added": "Foi engadido o servizo '{service}'", + "service_add_failed": "Non se puido engadir o servizo '{service}'", + "server_reboot_confirm": "Queres reiniciar o servidor inmediatamente? [{answers}]", + "server_reboot": "Vaise reiniciar o servidor", + "server_shutdown_confirm": "Queres apagar o servidor inmediatamente? [{answers}]", + "server_shutdown": "Vaise apagar o servidor", + "root_password_replaced_by_admin_password": "O contrasinal root foi substituído polo teu contrasinal de administración.", + "root_password_desynchronized": "Mudou o contrasinal de administración, pero YunoHost non puido transferir este cambio ao contrasinal root!", + "restore_system_part_failed": "Non se restableceu a parte do sistema '{part}'", + "restore_running_hooks": "Executando os ganchos do restablecemento…", + "restore_running_app_script": "Restablecendo a app '{app}'…", + "restore_removing_tmp_dir_failed": "Non se puido eliminar o directorio temporal antigo", + "restore_nothings_done": "Nada foi restablecido", + "restore_not_enough_disk_space": "Non hai espazo abondo (espazo: {free_space.d} B, espazo necesario: {needed_space} B, marxe de seguridade: {margin:d} B)", + "restore_may_be_not_enough_disk_space": "O teu sistema semella que non ten espazo abondo (libre: {free_space:d} B, espazo necesario: {needed_space:d} B, marxe de seguridade {margin:d} B)", + "restore_hook_unavailable": "O script de restablecemento para '{part}' non está dispoñible no teu sistema nin no arquivo", + "invalid_password": "Contrasinal non válido", + "ldap_server_is_down_restart_it": "O servidor LDAP está caído, intenta reinicialo...", + "ldap_server_down": "Non se chegou ao servidor LDAP", + "global_settings_setting_security_experimental_enabled": "Activar características de seguridade experimentais (non actives isto se non sabes o que estás a facer!)" } From 2b2335a08c2241a4cec2c531de08538052f9756b Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Tue, 31 Aug 2021 18:16:51 +0000 Subject: [PATCH 049/101] Translated using Weblate (Persian) Currently translated at 30.7% (198 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 181 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 1 deletion(-) diff --git a/locales/fa.json b/locales/fa.json index 5a2b61bc1..48e18a78e 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -17,5 +17,184 @@ "admin_password_change_failed": "تغییر رمز امکان پذیر نیست", "admin_password": "رمز عبور مدیریت", "additional_urls_already_removed": "نشانی اینترنتی اضافی '{url}' قبلاً در نشانی اینترنتی اضافی برای اجازه '{permission}'حذف شده است", - "additional_urls_already_added": "نشانی اینترنتی اضافی '{url}' قبلاً در نشانی اینترنتی اضافی برای اجازه '{permission}' اضافه شده است" + "additional_urls_already_added": "نشانی اینترنتی اضافی '{url}' قبلاً در نشانی اینترنتی اضافی برای اجازه '{permission}' اضافه شده است", + "diagnosis_diskusage_low": "‏ذخیره سازی {mountpoint} (روی دستگاه {device}) فقط {free} ({free_percent}%) فضا باقی مانده است (از {total}). مراقب باشید.", + "diagnosis_diskusage_verylow": "‏ذخیره سازی {mountpoint} (روی دستگاه {device}) فقط {free} ({free_percent}%) فضا باقی مانده است (از {total}). شما واقعاً باید پاکسازی فضای ذخیره ساز را در نظر بگیرید!", + "diagnosis_services_bad_status_tip": "می توانید سعی کنید سرویس را راه اندازی مجدد کنید، و اگر کار نمی کند ، نگاهی داشته باشید بهسرویس در webadmin ثبت می شود (از خط فرمان ، می توانید این کار را انجام دهید با yunohost service restart {service} و yunohost service log {service}).", + "diagnosis_services_bad_status": "سرویس {service} {status} است :(", + "diagnosis_services_conf_broken": "پیکربندی سرویس {service} خراب است!", + "diagnosis_services_running": "سرویس {service} در حال اجرا است!", + "diagnosis_domain_expires_in": "{domain} در {days} روز منقضی می شود.", + "diagnosis_domain_expiration_error": "برخی از دامنه ها به زودی منقضی می شوند!", + "diagnosis_domain_expiration_warning": "برخی از دامنه ها به زودی منقضی می شوند!", + "diagnosis_domain_expiration_success": "دامنه های شما ثبت شده است و به این زودی منقضی نمی شود.", + "diagnosis_domain_expiration_not_found_details": "به نظر می رسد اطلاعات WHOIS برای دامنه {domain} حاوی اطلاعات مربوط به تاریخ انقضا نیست؟", + "diagnosis_domain_not_found_details": "دامنه {domain} در پایگاه داده WHOIS وجود ندارد یا منقضی شده است!", + "diagnosis_domain_expiration_not_found": "بررسی تاریخ انقضا برخی از دامنه ها امکان پذیر نیست", + "diagnosis_dns_specialusedomain": "دامنه {domain} بر اساس یک دامنه سطح بالا (TLD) مخصوص استفاده است و بنابراین انتظار نمی رود که دارای سوابق DNS واقعی باشد.", + "diagnosis_dns_try_dyndns_update_force": "پیکربندی DNS این دامنه باید به طور خودکار توسط YunoHost مدیریت شود. اگر اینطور نیست ، می توانید سعی کنید به زور یک به روز رسانی را با استفاده از yunohost dyndns update --force.", + "diagnosis_dns_point_to_doc": "لطفاً اسناد را در https://yunohost.org/dns_config برسی و مطالعه کنید، اگر در مورد پیکربندی سوابق DNS به کمک نیاز دارید.", + "diagnosis_dns_discrepancy": "به نظر می رسد پرونده DNS زیر از پیکربندی توصیه شده پیروی نمی کند:
نوع: {type}
نام: {name}
ارزش فعلی: {current}
مقدار مورد انتظار: {value}", + "diagnosis_dns_missing_record": "با توجه به پیکربندی DNS توصیه شده ، باید یک رکورد DNS با اطلاعات زیر اضافه کنید.
نوع: {type}
نام: {name}
ارزش: {value}", + "diagnosis_dns_bad_conf": "برخی از سوابق DNS برای دامنه {domain} (دسته {category}) وجود ندارد یا نادرست است", + "diagnosis_dns_good_conf": "سوابق DNS برای دامنه {domain} (دسته {category}) به درستی پیکربندی شده است", + "diagnosis_ip_weird_resolvconf_details": "پرونده /etc/resolv.conf باید یک پیوند همراه برای /etc/resolvconf/run/resolv.conf خود اشاره می کند به 127.0.0.1 (dnsmasq). اگر می خواهید راه حل های DNS را به صورت دستی پیکربندی کنید ، لطفاً ویرایش کنید /etc/resolv.dnsmasq.conf.", + "diagnosis_ip_weird_resolvconf": "اینطور که پیداست تفکیک پذیری DNS کار می کند ، اما به نظر می رسد از سفارشی استفاده می کنید /etc/resolv.conf.", + "diagnosis_ip_broken_resolvconf": "به نظر می رسد تفکیک پذیری نام دامنه در سرور شما شکسته شده است ، که به نظر می رسد مربوط به /etc/resolv.conf و اشاره نکردن به 127.0.0.1 میباشد.", + "diagnosis_ip_broken_dnsresolution": "به نظر می رسد تفکیک پذیری نام دامنه به دلایلی خراب شده است... آیا فایروال درخواست های DNS را مسدود می کند؟", + "diagnosis_ip_dnsresolution_working": "تفکیک پذیری نام دامنه کار می کند!", + "diagnosis_ip_not_connected_at_all": "به نظر می رسد سرور اصلا به اینترنت متصل نیست !؟", + "diagnosis_ip_local": "IP محلی: {local}", + "diagnosis_ip_global": "IP جهانی: {global}", + "diagnosis_ip_no_ipv6_tip": "داشتن یک IPv6 فعال برای کار سرور شما اجباری نیست ، اما برای سلامت اینترنت به طور کلی بهتر است. IPv6 معمولاً باید در صورت موجود بودن توسط سیستم یا ارائه دهنده اینترنت شما به طور خودکار پیکربندی شود. در غیر این صورت ، ممکن است لازم باشد چند مورد را به صورت دستی پیکربندی کنید ، همانطور که در اسناد اینجا توضیح داده شده است: https://yunohost.org/#/ipv6.اگر نمی توانید IPv6 را فعال کنید یا اگر برای شما بسیار فنی به نظر می رسد ، می توانید با خیال راحت این هشدار را نادیده بگیرید.", + "diagnosis_ip_no_ipv6": "سرور IPv6 کار نمی کند.", + "diagnosis_ip_connected_ipv6": "سرور از طریق IPv6 به اینترنت متصل است!", + "diagnosis_ip_no_ipv4": "سرور IPv4 کار نمی کند.", + "diagnosis_ip_connected_ipv4": "سرور از طریق IPv4 به اینترنت متصل است!", + "diagnosis_no_cache": "هنوز هیچ حافظه نهانی معاینه و عیب یابی برای دسته '{category}' وجود ندارد", + "diagnosis_failed": "نتیجه معاینه و عیب یابی برای دسته '{category}' واکشی نشد: {error}", + "diagnosis_everything_ok": "همه چیز برای {category} خوب به نظر می رسد!", + "diagnosis_found_warnings": "مورد (های) {warnings} یافت شده که می تواند دسته {category} را بهبود بخشد.", + "diagnosis_found_errors_and_warnings": "{errors} مسائل مهم (و {warnings} هشدارها) مربوط به {category} پیدا شد!", + "diagnosis_found_errors": "{errors} مشکلات مهم مربوط به {category} پیدا شد!", + "diagnosis_ignored_issues": "(+ {nb_ignored} مسئله (ها) نادیده گرفته شده)", + "diagnosis_cant_run_because_of_dep": "در حالی که مشکلات مهمی در ارتباط با {dep} وجود دارد ، نمی توان عیب یابی را برای {category} اجرا کرد.", + "diagnosis_cache_still_valid": "(حافظه پنهان هنوز برای عیب یابی {category} معتبر است. هنوز دوباره تشخیص داده نمی شود!)", + "diagnosis_failed_for_category": "عیب یابی برای دسته '{category}' ناموفق بود: {error}", + "diagnosis_display_tip": "برای مشاهده مسائل پیدا شده ، می توانید به بخش تشخیص webadmin بروید یا از خط فرمان 'yunohost diagnosis show --issues --human-readable' را اجرا کنید.", + "diagnosis_package_installed_from_sury_details": "برخی از بسته ها ناخواسته از مخزن شخص ثالث به نام Sury نصب شده اند. تیم YunoHost استراتژی مدیریت این بسته ها را بهبود بخشیده ، اما انتظار می رود برخی از تنظیماتی که برنامه های PHP7.3 را در حالی که هنوز بر روی Stretch نصب شده اند نصب کرده اند ، ناسازگاری های باقی مانده ای داشته باشند. برای رفع این وضعیت ، باید دستور زیر را اجرا کنید: {cmd_to_fix}", + "diagnosis_package_installed_from_sury": "برخی از بسته های سیستمی باید کاهش یابد", + "diagnosis_backports_in_sources_list": "به نظر می رسد apt (مدیریت بسته) برای استفاده از مخزن پشتیبان پیکربندی شده است. مگر اینکه واقعاً بدانید چه کار می کنید ، ما به شدت از نصب بسته های پشتیبان خودداری می کنیم، زیرا به احتمال زیاد باعث ایجاد ناپایداری یا تداخل در سیستم شما می شود.", + "diagnosis_basesystem_ynh_inconsistent_versions": "شما نسخه های ناسازگار از بسته های YunoHost را اجرا می کنید... به احتمال زیاد به دلیل ارتقاء ناموفق یا جزئی است.", + "diagnosis_basesystem_ynh_main_version": "سرور نسخه YunoHost {main_version} ({repo}) را اجرا می کند", + "diagnosis_basesystem_ynh_single_version": "{package} نسخه: {version} ({repo})", + "diagnosis_basesystem_kernel": "سرور نسخه {kernel_version} هسته لینوکس را اجرا می کند", + "diagnosis_basesystem_host": "سرور نسخه {debian_version} دبیان را اجرا می کند", + "diagnosis_basesystem_hardware_model": "مدل سرور {model} میباشد", + "diagnosis_basesystem_hardware": "معماری سخت افزاری سرور {virt} {arch} است", + "custom_app_url_required": "برای ارتقاء سفارشی برنامه {app} خود باید نشانی اینترنتی ارائه دهید", + "confirm_app_install_thirdparty": "خطرناک! این برنامه بخشی از فهرست برنامه YunoHost نیست. نصب برنامه های شخص ثالث ممکن است یکپارچگی و امنیت سیستم شما را به خطر بیندازد. احتمالاً نباید آن را نصب کنید مگر اینکه بدانید در حال انجام چه کاری هستید. اگر این برنامه کار نکرد یا سیستم شما را خراب کرد ، هیچ پشتیبانی ارائه نخواهدشد... به هر حال اگر مایل به پذیرش این خطر هستید ، '{answers}' را تایپ کنید", + "confirm_app_install_danger": "خطرناک! این برنامه هنوز آزمایشی است (اگر صراحتاً کار نکند)! احتمالاً نباید آن را نصب کنید مگر اینکه بدانید در حال انجام چه کاری هستید. اگر این برنامه کار نکرد یا سیستم شما را خراب کرد، هیچ پشتیبانی ارائه نخواهد شد... اگر به هر حال مایل به پذیرش این خطر هستید ، '{answers}' را تایپ کنید", + "confirm_app_install_warning": "هشدار: این برنامه ممکن است کار کند ، اما در YunoHost یکپارچه نشده است. برخی از ویژگی ها مانند ورود به سیستم و پشتیبان گیری/بازیابی ممکن است در دسترس نباشد. به هر حال نصب شود؟ [{answers}] ", + "certmanager_unable_to_parse_self_CA_name": "نتوانست نام مرجع خودامضائی را تجزیه و تحلیل کند (فایل: {file})", + "certmanager_self_ca_conf_file_not_found": "فایل پیکربندی برای اجازه خود امضائی پیدا نشد (فایل: {file})", + "certmanager_no_cert_file": "فایل گواهینامه برای دامنه {domain} خوانده نشد (فایل: {file})", + "certmanager_hit_rate_limit": "اخیراً تعداد زیادی گواهی برای این مجموعه دقیق از دامنه ها {domain} صادر شده است. لطفاً بعداً دوباره امتحان کنید. برای جزئیات بیشتر به https://letsencrypt.org/docs/rate-limits/ مراجعه کنید", + "certmanager_warning_subdomain_dns_record": "آدرس زیر دامنه '{subdomain}' به آدرس IP مشابه '{domain}' تبدیل نمی شود. تا زمانی که این مشکل را برطرف نکنید و گواهی را دوباره ایجاد نکنید ، برخی از ویژگی ها در دسترس نخواهند بود.", + "certmanager_domain_http_not_working": "به نظر می رسد دامنه {domain} از طریق HTTP قابل دسترسی نیست. لطفاً برای اطلاعات بیشتر ، دسته \"وب\" را در عیب یابی بررسی کنید. (اگر می دانید چه کار می کنید ، از '--no-checks' برای خاموش کردن این چک ها استفاده کنید.)", + "certmanager_domain_dns_ip_differs_from_public_ip": "سوابق DNS برای دامنه '{domain}' با IP این سرور متفاوت است. لطفاً برای اطلاعات بیشتر ، دسته 'DNS records' (پایه) را در عیب یابی بررسی کنید. اگر اخیراً رکورد A خود را تغییر داده اید ، لطفاً منتظر انتشار آن باشید (برخی از چکرهای انتشار DNS بصورت آنلاین در دسترس هستند). (اگر می دانید چه کار می کنید ، از '--no-checks' برای خاموش کردن این چک ها استفاده کنید.)", + "certmanager_domain_cert_not_selfsigned": "گواهی دامنه {domain} خود امضا نشده است. آیا مطمئن هستید که می خواهید آن را جایگزین کنید؟ (برای این کار از '--force' استفاده کنید.)", + "certmanager_domain_not_diagnosed_yet": "هنوز هیچ نتیجه تشخیصی و عیب یابی دامنه {domain} وجود ندارد. لطفاً در بخش عیب یابی ، دسته های 'DNS records' و 'Web'مجدداً عیب یابی را اجرا کنید تا بررسی شود که آیا دامنه ای برای گواهی اجازه رمزنگاری آماده است. (یا اگر می دانید چه کار می کنید ، از '--no-checks' برای خاموش کردن این بررسی ها استفاده کنید.)", + "certmanager_certificate_fetching_or_enabling_failed": "تلاش برای استفاده از گواهینامه جدید برای {domain} جواب نداد...", + "certmanager_cert_signing_failed": "گواهی جدید امضا نشده است", + "certmanager_cert_renew_success": "گواهی اجازه رمزنگاری برای دامنه '{domain}' تمدید شد", + "certmanager_cert_install_success_selfsigned": "گواهی خود امضا شده اکنون برای دامنه '{domain}' نصب شده است", + "certmanager_cert_install_success": "هم اینک گواهی اجازه رمزگذاری برای دامنه '{domain}' نصب شده است", + "certmanager_cannot_read_cert": "هنگام باز کردن گواهینامه فعلی مشکلی پیش آمده است برای دامنه {domain} (فایل: {file}) ، علّت: {reason}", + "certmanager_attempt_to_replace_valid_cert": "شما در حال تلاش برای بازنویسی یک گواهی خوب و معتبر برای دامنه {domain} هستید! (استفاده از --force برای bypass)", + "certmanager_attempt_to_renew_valid_cert": "گواهی دامنه '{domain}' در حال انقضا نیست! (اگر می دانید چه کار می کنید می توانید از --force استفاده کنید)", + "certmanager_attempt_to_renew_nonLE_cert": "گواهی دامنه '{domain}' توسط Let's Encrypt صادر نشده است. به طور خودکار تمدید نمی شود!", + "certmanager_acme_not_configured_for_domain": "در حال حاضر نمی توان چالش ACME را برای {domain} اجرا کرد زیرا nginx conf آن فاقد قطعه کد مربوطه است... لطفاً مطمئن شوید که پیکربندی nginx شما به روز است با استفاده از دستور `yunohost tools regen-conf nginx --dry-run --with-diff`.", + "backup_with_no_restore_script_for_app": "{app} فاقد اسکریپت بازگردانی است ، نمی توانید پشتیبان گیری این برنامه را به طور خودکار بازیابی کنید.", + "backup_with_no_backup_script_for_app": "برنامه '{app}' فاقد اسکریپت پشتیبان است. نادیده گرفتن.", + "backup_unable_to_organize_files": "نمی توان از روش سریع برای سازماندهی فایل ها در بایگانی استفاده کرد", + "backup_system_part_failed": "از بخش سیستم '{part}' پشتیبان گیری نشد", + "backup_running_hooks": "درحال اجرای قلاب پشتیبان گیری...", + "backup_permission": "مجوز پشتیبان گیری برای {app}", + "backup_output_symlink_dir_broken": "فهرست بایگانی شما '{path}' یک پیوند symlink خراب است. شاید فراموش کرده اید که مجدداً محل ذخیره سازی که به آن اشاره می کند را دوباره نصب یا وصل کنید.", + "backup_output_directory_required": "شما باید یک پوشه خروجی برای نسخه پشتیبان تهیه کنید", + "backup_output_directory_not_empty": "شما باید یک دایرکتوری خروجی خالی انتخاب کنید", + "backup_output_directory_forbidden": "دایرکتوری خروجی دیگری را انتخاب کنید. پشتیبان گیری نمی تواند در /bin، /boot، /dev ، /etc ، /lib ، /root ، /run ، /sbin ، /sys ، /usr ، /var یا /home/yunohost.backup/archives ایجاد شود", + "backup_nothings_done": "چیزی برای ذخیره کردن وجود ندارد", + "backup_no_uncompress_archive_dir": "چنین فهرست بایگانی فشرده نشده ایی وجود ندارد", + "backup_mount_archive_for_restore": "در حال آماده سازی بایگانی برای بازگردانی...", + "backup_method_tar_finished": "بایگانی پشتیبان TAR ایجاد شد", + "backup_method_custom_finished": "روش پشتیبان گیری سفارشی '{method}' به پایان رسید", + "backup_method_copy_finished": "نسخه پشتیبان نهایی شد", + "backup_hook_unknown": "قلاب پشتیبان '{hook}' ناشناخته است", + "backup_deleted": "نسخه پشتیبان حذف شد", + "backup_delete_error": "'{path}' حذف نشد", + "backup_custom_mount_error": "روش پشتیبان گیری سفارشی نمی تواند از مرحله 'mount' عبور کند", + "backup_custom_backup_error": "روش پشتیبان گیری سفارشی نمی تواند مرحله 'backup' را پشت سر بگذارد", + "backup_csv_creation_failed": "فایل CSV مورد نیاز برای بازیابی ایجاد نشد", + "backup_csv_addition_failed": "فایلهای پشتیبان به فایل CSV اضافه نشد", + "backup_creation_failed": "نسخه پشتیبان بایگانی ایجاد نشد", + "backup_create_size_estimation": "بایگانی حاوی حدود {size} داده است.", + "backup_created": "نسخه پشتیبان ایجاد شد", + "backup_couldnt_bind": "نمی توان {src} را به {dest} متصل کرد.", + "backup_copying_to_organize_the_archive": "در حال کپی {size} مگابایت برای سازماندهی بایگانی", + "backup_cleaning_failed": "پوشه موقت پشتیبان گیری پاکسازی نشد", + "backup_cant_mount_uncompress_archive": "بایگانی فشرده سازی نشده را نمی توان به عنوان حفاظت از نوشتن مستقر کرد", + "backup_ask_for_copying_if_needed": "آیا می خواهید پشتیبان گیری را با استفاده از {size} مگابایت به طور موقت انجام دهید؟ (این روش استفاده می شود زیرا برخی از پرونده ها با استفاده از روش کارآمدتری تهیه نمی شوند.)", + "backup_archive_writing_error": "فایل های '{source}' (که در بایگانی '{dest}' نامگذاری شده اند) برای پشتیبان گیری به بایگانی فشرده '{archive}' اضافه نشد", + "backup_archive_system_part_not_available": "بخش سیستم '{part}' در این نسخه پشتیبان در دسترس نیست", + "backup_archive_corrupted": "به نظر می رسد بایگانی پشتیبان '{archive}' خراب است: {error}", + "backup_archive_cant_retrieve_info_json": "اطلاعات مربوط به بایگانی '{archive}' بارگیری نشد... info.json بازیابی نمی شود (یا json معتبری نیست).", + "backup_archive_open_failed": "بایگانی پشتیبان باز نشد", + "backup_archive_name_unknown": "بایگانی پشتیبان محلی ناشناخته با نام '{name}'", + "backup_archive_name_exists": "بایگانی پشتیبان با این نام در حال حاضر وجود دارد.", + "backup_archive_broken_link": "دسترسی به بایگانی پشتیبان امکان پذیر نیست (پیوند خراب به {path})", + "backup_archive_app_not_found": "در بایگانی پشتیبان {app} پیدا نشد", + "backup_applying_method_tar": "ایجاد آرشیو پشتیبان TAR...", + "backup_applying_method_custom": "فراخوانی روش پشتیبان گیری سفارشی '{method}'...", + "backup_applying_method_copy": "در حال کپی تمام فایل ها برای پشتیبان گیری...", + "backup_app_failed": "{app} پشتیبان گیری نشد", + "backup_actually_backuping": "ایجاد آرشیو پشتیبان از پرونده های جمع آوری شده...", + "backup_abstract_method": "این روش پشتیبان گیری هنوز اجرا نشده است", + "ask_password": "رمز عبور", + "ask_new_path": "مسیر جدید", + "ask_new_domain": "دامنه جدید", + "ask_new_admin_password": "رمز جدید مدیریت", + "ask_main_domain": "دامنه اصلی", + "ask_lastname": "نام خانوادگی", + "ask_firstname": "نام کوچک", + "ask_user_domain": "دامنه ای که برای آدرس ایمیل کاربر و حساب XMPP استفاده می شود", + "apps_catalog_update_success": "کاتالوگ برنامه به روز شد!", + "apps_catalog_obsolete_cache": "حافظه پنهان کاتالوگ برنامه خالی یا منسوخ شده است.", + "apps_catalog_failed_to_download": "بارگیری کاتالوگ برنامه {apps_catalog} امکان پذیر نیست: {error}", + "apps_catalog_updating": "در حال به روز رسانی کاتالوگ برنامه…", + "apps_catalog_init_success": "سیستم کاتالوگ برنامه راه اندازی اولیه شد!", + "apps_already_up_to_date": "همه برنامه ها در حال حاضر به روز هستند", + "app_packaging_format_not_supported": "این برنامه قابل نصب نیست زیرا قالب بسته بندی آن توسط نسخه YunoHost شما پشتیبانی نمی شود. احتمالاً باید ارتقاء سیستم خود را در نظر بگیرید.", + "app_upgraded": "{app} ارتقا یافت", + "app_upgrade_some_app_failed": "برخی از برنامه ها را نمی توان ارتقا داد", + "app_upgrade_script_failed": "خطایی در داخل اسکریپت ارتقاء برنامه رخ داده است", + "app_upgrade_failed": "{app} ارتقاء نیافت: {error}", + "app_upgrade_app_name": "در حال ارتقاء {app}...", + "app_upgrade_several_apps": "برنامه های زیر ارتقا می یابند: {apps}", + "app_unsupported_remote_type": "نوع راه دور پشتیبانی نشده برای برنامه استفاده می شود", + "app_unknown": "برنامه ناشناخته", + "app_start_restore": "درحال بازیابی {app}...", + "app_start_backup": "در حال جمع آوری فایل ها برای پشتیبان گیری {app}...", + "app_start_remove": "در حال حذف {app}...", + "app_start_install": "در حال نصب {app}...", + "app_sources_fetch_failed": "نمی توان فایل های منبع را واکشی کرد ، آیا URL درست است؟", + "app_restore_script_failed": "خطایی در داخل اسکریپت بازیابی برنامه رخ داده است", + "app_restore_failed": "{app} بازیابی نشد: {error}", + "app_remove_after_failed_install": "حذف برنامه در پی شکست نصب...", + "app_requirements_unmeet": "شرایط مورد نیاز برای {app} برآورده نمی شود ، بسته {pkgname} ({version}) باید {spec} باشد", + "app_requirements_checking": "در حال بررسی بسته های مورد نیاز برای {app}...", + "app_removed": "{app} حذف نصب شد", + "app_not_properly_removed": "{app} به درستی حذف نشده است", + "app_not_installed": "{app} در لیست برنامه های نصب شده یافت نشد: {all_apps}", + "app_not_correctly_installed": "به نظر می رسد {app} به اشتباه نصب شده است", + "app_not_upgraded": "برنامه '{failed_app}' ارتقا پیدا نکرد و در نتیجه ارتقا برنامه های زیر لغو شد: {apps}", + "app_manifest_install_ask_is_public": "آیا این برنامه باید در معرض دید بازدیدکنندگان ناشناس قرار گیرد؟", + "app_manifest_install_ask_admin": "برای این برنامه یک کاربر سرپرست انتخاب کنید", + "app_manifest_install_ask_password": "گذرواژه مدیریتی را برای این برنامه انتخاب کنید", + "app_manifest_install_ask_path": "مسیر URL (بعد از دامنه) را انتخاب کنید که این برنامه باید در آن نصب شود", + "app_manifest_install_ask_domain": "دامنه ای را انتخاب کنید که این برنامه باید در آن نصب شود", + "app_manifest_invalid": "مشکلی در مانیفست برنامه وجود دارد: {error}", + "app_location_unavailable": "این نشانی وب یا در دسترس نیست یا با برنامه (هایی) که قبلاً نصب شده در تعارض است:\n{apps}", + "app_label_deprecated": "این دستور منسوخ شده است! لطفاً برای مدیریت برچسب برنامه از فرمان جدید'yunohost به روز رسانی مجوز کاربر' استفاده کنید.", + "app_make_default_location_already_used": "نمی توان '{app}' را برنامه پیش فرض در دامنه قرار داد ، '{domain}' قبلاً توسط '{other_app}' استفاده می شود", + "app_install_script_failed": "خطایی در درون اسکریپت نصب برنامه رخ داده است", + "app_install_failed": "نصب {app} امکان پذیر نیست: {error}", + "app_install_files_invalid": "این فایل ها قابل نصب نیستند", + "app_id_invalid": "شناسه برنامه نامعتبر است", + "app_full_domain_unavailable": "متأسفیم ، این برنامه باید در دامنه خود نصب شود ، اما سایر برنامه ها قبلاً در دامنه '{domain}' نصب شده اند.شما به جای آن می توانید از یک زیر دامنه اختصاص داده شده به این برنامه استفاده کنید.", + "app_extraction_failed": "فایل های نصبی استخراج نشد", + "app_change_url_success": "{app} URL اکنون {domain} {path} است", + "app_change_url_no_script": "برنامه '{app_name}' هنوز از تغییر URL پشتیبانی نمی کند. شاید باید آن را ارتقا دهید.", + "app_change_url_identical_domains": "دامنه /url_path قدیمی و جدیدیکسان هستند ('{domain}{path}') ، کاری برای انجام دادن نیست." } From 4ee759855af1d845e9aa88fa0a36b119fc021f66 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 31 Aug 2021 21:42:27 +0200 Subject: [PATCH 050/101] Implement global settings for https redirect --- data/hooks/conf_regen/15-nginx | 1 + data/templates/nginx/server.tpl.conf | 10 ++++++---- locales/en.json | 1 + src/yunohost/settings.py | 8 ++++++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/data/hooks/conf_regen/15-nginx b/data/hooks/conf_regen/15-nginx index a2d8f1259..040ed090d 100755 --- a/data/hooks/conf_regen/15-nginx +++ b/data/hooks/conf_regen/15-nginx @@ -60,6 +60,7 @@ do_pre_regen() { main_domain=$(cat /etc/yunohost/current_host) # Support different strategy for security configurations + export redirect_to_https="$(yunohost settings get 'security.nginx.redirect_to_https')" export compatibility="$(yunohost settings get 'security.nginx.compatibility')" export experimental="$(yunohost settings get 'security.experimental.enabled')" ynh_render_template "security.conf.inc" "${nginx_conf_dir}/security.conf.inc" diff --git a/data/templates/nginx/server.tpl.conf b/data/templates/nginx/server.tpl.conf index 8bd689a92..7133dfba2 100644 --- a/data/templates/nginx/server.tpl.conf +++ b/data/templates/nginx/server.tpl.conf @@ -14,10 +14,6 @@ server { include /etc/nginx/conf.d/{{ domain }}.d/*.conf; - location /yunohost { - return 301 https://$http_host$request_uri; - } - location ^~ '/.well-known/ynh-diagnosis/' { alias /tmp/.well-known/ynh-diagnosis/; } @@ -26,6 +22,12 @@ server { alias /var/www/.well-known/{{ domain }}/autoconfig/mail/; } + {% if redirect_to_https != "False" %} + location / { + return 301 https://$http_host$request_uri; + } + {% endif %} + access_log /var/log/nginx/{{ domain }}-access.log; error_log /var/log/nginx/{{ domain }}-error.log; } diff --git a/locales/en.json b/locales/en.json index 4c9f3e7fe..cde7c5e66 100644 --- a/locales/en.json +++ b/locales/en.json @@ -334,6 +334,7 @@ "global_settings_key_doesnt_exists": "The key '{settings_key}' does not exist in the global settings, you can see all the available keys by running 'yunohost settings list'", "global_settings_reset_success": "Previous settings now backed up to {path}", "global_settings_setting_pop3_enabled": "Enable the POP3 protocol for the mail server", + "global_settings_setting_security_nginx_redirect_to_https": "Redirect HTTP requests to HTTPs by default (DO NOT TURN OFF unless you really know what you're doing!)", "global_settings_setting_security_nginx_compatibility": "Compatibility vs. security tradeoff for the web server NGINX. Affects the ciphers (and other security-related aspects)", "global_settings_setting_security_password_admin_strength": "Admin password strength", "global_settings_setting_security_password_user_strength": "User password strength", diff --git a/src/yunohost/settings.py b/src/yunohost/settings.py index fe072cddb..475ac70d1 100644 --- a/src/yunohost/settings.py +++ b/src/yunohost/settings.py @@ -76,6 +76,13 @@ DEFAULTS = OrderedDict( "security.ssh.port", {"type": "int", "default": 22}, ), + ( + "security.nginx.redirect_to_https", + { + "type": "bool", + "default": True, + }, + ), ( "security.nginx.compatibility", { @@ -392,6 +399,7 @@ def trigger_post_change_hook(setting_name, old_value, new_value): @post_change_hook("ssowat.panel_overlay.enabled") +@post_change_hook("security.nginx.redirect_to_https") @post_change_hook("security.nginx.compatibility") @post_change_hook("security.webadmin.allowlist.enabled") @post_change_hook("security.webadmin.allowlist") From b2a67c4f86f52d17e4848054ec166e9b374d30ca Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 31 Aug 2021 23:12:56 +0200 Subject: [PATCH 051/101] https redirect: don't include app conf snippets if https redirect is enabled --- data/templates/nginx/server.tpl.conf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/templates/nginx/server.tpl.conf b/data/templates/nginx/server.tpl.conf index 7133dfba2..379b597a7 100644 --- a/data/templates/nginx/server.tpl.conf +++ b/data/templates/nginx/server.tpl.conf @@ -12,8 +12,6 @@ server { include /etc/nginx/conf.d/acme-challenge.conf.inc; - include /etc/nginx/conf.d/{{ domain }}.d/*.conf; - location ^~ '/.well-known/ynh-diagnosis/' { alias /tmp/.well-known/ynh-diagnosis/; } @@ -22,10 +20,14 @@ server { alias /var/www/.well-known/{{ domain }}/autoconfig/mail/; } + {# Note that this != "False" is meant to be failure-safe, in the case the redrect_to_https would happen to contain empty string or whatever value. We absolutely don't want to disable the HTTPS redirect *except* when it's explicitly being asked to be disabled. #} {% if redirect_to_https != "False" %} location / { return 301 https://$http_host$request_uri; } + {# The app config snippets are not included in the HTTP conf unless HTTPS redirect is disabled, because app's location may blocks will conflict or bypass/ignore the HTTPS redirection. #} + {% else %} + include /etc/nginx/conf.d/{{ domain }}.d/*.conf; {% endif %} access_log /var/log/nginx/{{ domain }}-access.log; From 199e65e41ccb34b3f097b58a7dd2124174dc8110 Mon Sep 17 00:00:00 2001 From: mifegui Date: Tue, 31 Aug 2021 22:11:22 +0000 Subject: [PATCH 052/101] Translated using Weblate (Portuguese) Currently translated at 14.4% (93 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/pt/ --- locales/pt.json | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/locales/pt.json b/locales/pt.json index cc47da946..4b4248f09 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -8,12 +8,12 @@ "app_id_invalid": "App ID invaĺido", "app_install_files_invalid": "Esses arquivos não podem ser instalados", "app_manifest_invalid": "Manifesto da aplicação inválido: {error}", - "app_not_installed": "{app} não está instalada", - "app_removed": "{app} removida com êxito", - "app_sources_fetch_failed": "Incapaz obter os ficheiros fonte", + "app_not_installed": "Não foi possível encontrar {app} na lista de aplicações instaladas: {all_apps}", + "app_removed": "{app} desinstalada", + "app_sources_fetch_failed": "Não foi possível carregar os arquivos de código fonte, a URL está correta?", "app_unknown": "Aplicação desconhecida", - "app_upgrade_failed": "Não foi possível atualizar {app}", - "app_upgraded": "{app} atualizada com sucesso", + "app_upgrade_failed": "Não foi possível atualizar {app}: {error}", + "app_upgraded": "{app} atualizado", "ask_firstname": "Primeiro nome", "ask_lastname": "Último nome", "ask_main_domain": "Domínio principal", @@ -114,8 +114,8 @@ "app_argument_invalid": "Escolha um valor válido para o argumento '{name}': {error}", "app_argument_required": "O argumento '{name}' é obrigatório", "app_change_url_failed_nginx_reload": "Não foi possível reiniciar o nginx. Aqui está o retorno de 'nginx -t':\n{nginx_errors}", - "app_location_unavailable": "Esta url não está disponível ou está em conflito com outra aplicação já instalada", - "app_upgrade_app_name": "Atualizando aplicação {app}…", + "app_location_unavailable": "Esta url ou não está disponível ou está em conflito com outra(s) aplicação(ões) já instalada(s):\n{apps}", + "app_upgrade_app_name": "Atualizando {app}…", "app_upgrade_some_app_failed": "Não foi possível atualizar algumas aplicações", "backup_abstract_method": "Este metodo de backup ainda não foi implementado", "backup_app_failed": "Não foi possível fazer o backup dos aplicativos '{app}'", @@ -140,5 +140,29 @@ "app_install_script_failed": "Ocorreu um erro dentro do script de instalação do aplicativo", "app_install_failed": "Não foi possível instalar {app}: {error}", "app_full_domain_unavailable": "Desculpe, esse app deve ser instalado num domínio próprio mas já há outros apps instalados no domínio '{domain}'. Você pode usar um subdomínio dedicado a esse aplicativo.", - "app_change_url_success": "A URL agora é {domain}{path}" -} \ No newline at end of file + "app_change_url_success": "A URL agora é {domain}{path}", + "apps_catalog_obsolete_cache": "O cache do catálogo de aplicações está vazio ou obsoleto.", + "apps_catalog_failed_to_download": "Não foi possível fazer o download do catálogo de aplicações {apps_catalog}: {error}", + "apps_catalog_updating": "Atualizado o catálogo de aplicações…", + "apps_catalog_init_success": "Catálogo de aplicações do sistema inicializado!", + "apps_already_up_to_date": "Todas as aplicações já estão atualizadas", + "app_packaging_format_not_supported": "Essa aplicação não pode ser instalada porque o formato dela não é suportado pela sua versão do YunoHost. Considere atualizar seu sistema.", + "app_upgrade_script_failed": "Ocorreu um erro dentro do script de atualização da aplicação", + "app_upgrade_several_apps": "As seguintes aplicações serão atualizadas: {apps}", + "app_start_restore": "Restaurando {app}...", + "app_start_backup": "Obtendo os arquivos para fazer o backup de {app}...", + "app_start_remove": "Removendo {app}...", + "app_start_install": "Instalando {app}...", + "app_restore_script_failed": "Ocorreu um erro dentro do script de restauração da aplicação", + "app_restore_failed": "Não foi possível restaurar {app}: {error}", + "app_remove_after_failed_install": "Removendo a aplicação após a falha da instalação...", + "app_requirements_unmeet": "Os requisitos para a aplicação {app} não foram satisfeitos, o pacote {pkgname} ({version}) devem ser {spec}", + "app_not_upgraded": "Não foi possível atualizar a aplicação '{failed_app}' e, como consequência, a atualização das seguintes aplicações foi cancelada: {apps}", + "app_manifest_install_ask_is_public": "Essa aplicação deve ser visível para visitantes anônimos?", + "app_manifest_install_ask_admin": "Escolha um usuário de administrador para essa aplicação", + "app_manifest_install_ask_password": "Escolha uma senha de administrador para essa aplicação", + "app_manifest_install_ask_path": "Escolha o caminho da url (depois do domínio) em que essa aplicação deve ser instalada", + "app_manifest_install_ask_domain": "Escolha o domínio em que esta aplicação deve ser instalada", + "app_label_deprecated": "Este comando está deprecado! Por favor use o novo comando 'yunohost user permission update' para gerenciar a etiqueta da aplicação.", + "app_make_default_location_already_used": "Não foi passível fazer a aplicação '{app}' ser a padrão no domínio, '{domain}' já está sendo usado por '{other_app}'" +} From 516a77a4914c63537a52d0041323c09ac758b9b5 Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Tue, 31 Aug 2021 21:22:47 +0000 Subject: [PATCH 053/101] Translated using Weblate (Persian) Currently translated at 41.2% (265 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 73 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/locales/fa.json b/locales/fa.json index 48e18a78e..c744a8637 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -18,8 +18,8 @@ "admin_password": "رمز عبور مدیریت", "additional_urls_already_removed": "نشانی اینترنتی اضافی '{url}' قبلاً در نشانی اینترنتی اضافی برای اجازه '{permission}'حذف شده است", "additional_urls_already_added": "نشانی اینترنتی اضافی '{url}' قبلاً در نشانی اینترنتی اضافی برای اجازه '{permission}' اضافه شده است", - "diagnosis_diskusage_low": "‏ذخیره سازی {mountpoint} (روی دستگاه {device}) فقط {free} ({free_percent}%) فضا باقی مانده است (از {total}). مراقب باشید.", - "diagnosis_diskusage_verylow": "‏ذخیره سازی {mountpoint} (روی دستگاه {device}) فقط {free} ({free_percent}%) فضا باقی مانده است (از {total}). شما واقعاً باید پاکسازی فضای ذخیره ساز را در نظر بگیرید!", + "diagnosis_diskusage_low": "‏ذخیره سازی {mountpoint} (روی دستگاه {device}) فقط {free} ({free_percent}%) فضا باقی مانده(از {total}). مراقب باشید.", + "diagnosis_diskusage_verylow": "‏ذخیره سازی {mountpoint} (روی دستگاه {device}) فقط {free} ({free_percent}%) فضا باقی مانده (از {total}). شما واقعاً باید پاکسازی فضای ذخیره ساز را در نظر بگیرید!", "diagnosis_services_bad_status_tip": "می توانید سعی کنید سرویس را راه اندازی مجدد کنید، و اگر کار نمی کند ، نگاهی داشته باشید بهسرویس در webadmin ثبت می شود (از خط فرمان ، می توانید این کار را انجام دهید با yunohost service restart {service} و yunohost service log {service}).", "diagnosis_services_bad_status": "سرویس {service} {status} است :(", "diagnosis_services_conf_broken": "پیکربندی سرویس {service} خراب است!", @@ -196,5 +196,72 @@ "app_extraction_failed": "فایل های نصبی استخراج نشد", "app_change_url_success": "{app} URL اکنون {domain} {path} است", "app_change_url_no_script": "برنامه '{app_name}' هنوز از تغییر URL پشتیبانی نمی کند. شاید باید آن را ارتقا دهید.", - "app_change_url_identical_domains": "دامنه /url_path قدیمی و جدیدیکسان هستند ('{domain}{path}') ، کاری برای انجام دادن نیست." + "app_change_url_identical_domains": "دامنه /url_path قدیمی و جدیدیکسان هستند ('{domain}{path}') ، کاری برای انجام دادن نیست.", + "diagnosis_http_connection_error": "خطای اتصال: ارتباط با دامنه درخواست شده امکان پذیر نیست، به احتمال زیاد غیرقابل دسترسی است.", + "diagnosis_http_timeout": "زمان تلاش برای تماس با سرور از خارج به پایان رسید. به نظر می رسد غیرقابل دسترسی است.
1. شایع ترین علت برای این مشکل ، پورت 80 است (و 443) به درستی به سرور شما ارسال نمی شوند.
2. همچنین باید مطمئن شوید که سرویس nginx در حال اجرا است
3. در تنظیمات پیچیده تر: مطمئن شوید که هیچ فایروال یا پروکسی معکوسی تداخل نداشته باشد.", + "diagnosis_http_ok": "دامنه {domain} از طریق HTTP از خارج از شبکه محلی قابل دسترسی است.", + "diagnosis_http_localdomain": "انتظار نمی رود که دامنه {domain} ، با TLD محلی. از خارج از شبکه محلی به آن دسترسی پیدا کند.", + "diagnosis_http_could_not_diagnose_details": "خطا: {error}", + "diagnosis_http_could_not_diagnose": "نمی توان تشخیص داد که در IPv{ipversion} دامنه ها از خارج قابل دسترسی هستند یا خیر.", + "diagnosis_http_hairpinning_issue_details": "این احتمالاً به دلیل جعبه / روتر ISP شما است. در نتیجه ، افراد خارج از شبکه محلی شما می توانند به سرور شما مطابق انتظار دسترسی پیدا کنند ، اما افراد داخل شبکه محلی (احتمالاً مثل شما؟) هنگام استفاده از نام دامنه یا IP جهانی. ممکن است بتوانید وضعیت را بهبود بخشید با نگاهی به https://yunohost.org/dns_local_network", + "diagnosis_http_hairpinning_issue": "به نظر می رسد در شبکه محلی شما hairpinning فعال نشده است.", + "diagnosis_ports_forwarding_tip": "برای رفع این مشکل، به احتمال زیاد باید انتقال پورت را در روتر اینترنت خود پیکربندی کنید همانطور که شرح داده شده در https://yunohost.org/isp_box_config", + "diagnosis_ports_needed_by": "افشای این پورت برای ویژگی های {category} (سرویس {service}) مورد نیاز است", + "diagnosis_ports_ok": "پورت {port} از خارج قابل دسترسی است.", + "diagnosis_ports_partially_unreachable": "پورت {port} از خارج در {failed}IPv قابل دسترسی نیست.", + "diagnosis_ports_unreachable": "پورت {port} از خارج قابل دسترسی نیست.", + "diagnosis_ports_could_not_diagnose_details": "خطا: {error}", + "diagnosis_ports_could_not_diagnose": "نمی توان تشخیص داد پورت ها از خارج در IPv{ipversion} قابل دسترسی هستند یا خیر.", + "diagnosis_description_regenconf": "تنظیمات سیستم", + "diagnosis_description_mail": "ایمیل", + "diagnosis_description_web": "وب", + "diagnosis_description_ports": "ارائه پورت ها", + "diagnosis_description_systemresources": "منابع سیستم", + "diagnosis_description_services": "بررسی وضعیّت سرویس ها", + "diagnosis_description_dnsrecords": "رکورد DNS", + "diagnosis_description_ip": "اتصال به اینترنت", + "diagnosis_description_basesystem": "سیستم پایه", + "diagnosis_security_vulnerable_to_meltdown_details": "برای رفع این مشکل ، باید سیستم خود را ارتقا دهید و مجدداً راه اندازی کنید تا هسته لینوکس جدید بارگیری شود (یا در صورت عدم کارکرد با ارائه دهنده سرور خود تماس بگیرید). برای اطلاعات بیشتر به https://meltdownattack.com/ مراجعه کنید.", + "diagnosis_security_vulnerable_to_meltdown": "به نظر می رسد شما در برابر آسیب پذیری امنیتی بحرانی Meltdown آسیب پذیر هستید", + "diagnosis_rootfstotalspace_critical": "کل سیستم فایل فقط دارای {space} است که بسیار نگران کننده است! احتمالاً خیلی زود فضای دیسک شما تمام می شود! توصیه می شود حداقل 16 گیگابایت و بیشتر فضا برای سیستم فایل ریشه داشته باشید.", + "diagnosis_rootfstotalspace_warning": "سیستم فایل ریشه در مجموع فقط {space} دارد. ممکن است اشکالی نداشته باشد ، اما مراقب باشید زیرا در نهایت ممکن است فضای دیسک شما به سرعت تمام شود... توصیه می شود حداقل 16 گیگابایت و بیشتر فضا برای سیستم فایل ریشه داشته باشید.", + "diagnosis_regenconf_manually_modified_details": "اگر بدانید چه کار می کنید ، احتمالاً خوب است! YunoHost به روز رسانی خودکار این فایل را متوقف می کند... اما مراقب باشید که ارتقاء YunoHost می تواند شامل تغییرات مهم توصیه شده باشد. اگر می خواهید ، می توانید تفاوت ها را با yunohost tools regen-conf {category} --dry-run --with-diff و تنظیم مجدد پیکربندی توصیه شده به زور با فرمان yunohost tools regen-conf {category} --force", + "diagnosis_regenconf_manually_modified": "به نظر می رسد فایل پیکربندی {file} به صورت دستی اصلاح شده است.", + "diagnosis_regenconf_allgood": "همه فایلهای پیکربندی مطابق با تنظیمات توصیه شده است!", + "diagnosis_mail_queue_too_big": "تعداد زیادی ایمیل معلق در صف پست ({nb_pending} ایمیل)", + "diagnosis_mail_queue_unavailable_details": "خطا: {error}", + "diagnosis_mail_queue_unavailable": "نمی توان با تعدادی از ایمیل های معلق در صف مشورت کرد", + "diagnosis_mail_queue_ok": "{nb_pending} ایمیل های معلق در صف های ایمیل", + "diagnosis_mail_blacklist_website": "پس از شناسایی دلیل لیست شدن و رفع آن، با خیال راحت درخواست کنید IP یا دامنه شما حذف شود از {blacklist_website}", + "diagnosis_mail_blacklist_reason": "دلیل لیست سیاه: {reason}", + "diagnosis_mail_blacklist_listed_by": "IP یا دامنه شما {item}در لیست سیاه {blacklist_name} قرار دارد", + "diagnosis_mail_blacklist_ok": "به نظر می رسد IP ها و دامنه های مورد استفاده این سرور در لیست سیاه قرار ندارند", + "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "DNS معکوس فعلی: {rdns_domain}
مقدار مورد انتظار: {ehlo_domain}", + "diagnosis_mail_fcrdns_different_from_ehlo_domain": "DNS معکوس به درستی در IPv{ipversion} پیکربندی نشده است. ممکن است برخی از ایمیل ها تحویل داده نشوند یا به عنوان هرزنامه پرچم گذاری شوند.", + "diagnosis_mail_fcrdns_nok_alternatives_6": "برخی از ارائه دهندگان به شما اجازه نمی دهند DNS معکوس خود را پیکربندی کنید (یا ممکن است ویژگی آنها شکسته شود...). اگر DNS معکوس شما به درستی برای IPv4 پیکربندی شده است، با استفاده از آن می توانید هنگام ارسال ایمیل، استفاده از IPv6 را غیرفعال کنید. yunohost settings set smtp.allow_ipv6 -v off. توجه: این راه حل آخری به این معنی است که شما نمی توانید از چند سرور IPv6 موجود ایمیل ارسال یا دریافت کنید.", + "diagnosis_mail_fcrdns_nok_alternatives_4": "برخی از ارائه دهندگان به شما اجازه نمی دهند DNS معکوس خود را پیکربندی کنید (یا ممکن است ویژگی آنها شکسته شود...). اگر به همین دلیل مشکلاتی را تجربه می کنید ، راه حل های زیر را در نظر بگیرید: - برخی از ISP ها جایگزین ارائه می دهند با استفاده از رله سرور ایمیل اگرچه به این معنی است که رله می تواند از ترافیک ایمیل شما جاسوسی کند.
- یک جایگزین دوستدار حریم خصوصی استفاده از VPN * با IP عمومی اختصاصی * برای دور زدن این نوع محدودیت ها است. ببینید https://yunohost.org/#/vpn_advantage
- یا ممکن است به ارائه دهنده دیگری بروید", + "diagnosis_mail_fcrdns_nok_details": "ابتدا باید DNS معکوس را پیکربندی کنید با {ehlo_domain} در رابط روتر اینترنت یا رابط ارائه دهنده میزبانی تان. (ممکن است برخی از ارائه دهندگان میزبانی از شما بخواهند که برای این کار تیکت پشتیبانی ارسال کنید).", + "diagnosis_mail_fcrdns_dns_missing": "در IPv{ipversion} هیچ DNS معکوسی تعریف نشده است. ممکن است برخی از ایمیل ها تحویل داده نشوند یا به عنوان هرزنامه پرچم گذاری شوند.", + "diagnosis_mail_fcrdns_ok": "DNS معکوس شما به درستی پیکربندی شده است!", + "diagnosis_mail_ehlo_could_not_diagnose_details": "خطا: {error}", + "diagnosis_mail_ehlo_could_not_diagnose": "نمی توان تشخیص داد که آیا سرور ایمیل postfix از خارج در IPv{ipversion} قابل دسترسی است یا خیر.", + "diagnosis_mail_ehlo_wrong_details": "EHLO دریافت شده توسط تشخیص دهنده از راه دور در IPv{ipversion} با دامنه سرور شما متفاوت است.
EHLO دریافت شده: {wrong_ehlo}
انتظار می رود: {right_ehlo}
شایع ترین علت این مشکل ، پورت 25 است به درستی به سرور شما ارسال نشده است. از سوی دیگر اطمینان حاصل کنید که هیچ فایروال یا پروکسی معکوسی تداخل ایجاد نمی کند.", + "diagnosis_mail_ehlo_wrong": "یک سرور ایمیل SMTP متفاوت در IPv{ipversion} پاسخ می دهد. سرور شما احتمالاً نمی تواند ایمیل دریافت کند.", + "diagnosis_mail_ehlo_bad_answer_details": "ممکن است به دلیل پاسخ دادن دستگاه دیگری به جای سرور شما باشد.", + "diagnosis_mail_ehlo_bad_answer": "یک سرویس غیر SMTP در پورت 25 در IPv{ipversion} پاسخ داد", + "diagnosis_mail_ehlo_unreachable_details": "اتصال روی پورت 25 سرور شما در IPv{ipversion} باز نشد. به نظر می رسد غیرقابل دسترس است.
1. شایع ترین علت این مشکل ، پورت 25 است به درستی به سرور شما ارسال نشده است.
2. همچنین باید مطمئن شوید که سرویس postfix در حال اجرا است.
3. در تنظیمات پیچیده تر: مطمئن شوید که هیچ فایروال یا پروکسی معکوسی تداخل نداشته باشد.", + "diagnosis_mail_ehlo_unreachable": "سرور ایمیل SMTP از خارج در IPv {ipversion} غیرقابل دسترسی است. قادر به دریافت ایمیل نخواهد بود.", + "diagnosis_mail_ehlo_ok": "سرور ایمیل SMTP از خارج قابل دسترسی است و بنابراین می تواند ایمیل دریافت کند!", + "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "برخی از ارائه دهندگان به شما اجازه نمی دهند پورت خروجی 25 را رفع انسداد کنید زیرا به بی طرفی شبکه اهمیتی نمی دهند.
- برخی از آنها جایگزین را ارائه می دهند با استفاده از رله سرور ایمیل اگرچه به این معنی است که رله می تواند از ترافیک ایمیل شما جاسوسی کند.
- یک جایگزین دوستدار حریم خصوصی استفاده از VPN * با IP عمومی اختصاصی * برای دور زدن این نوع محدودیت ها است. ببینید https://yunohost.org/#/vpn_advantage
- همچنین می توانید تغییر را در نظر بگیرید به یک ارائه دهنده بی طرف خالص تر", + "diagnosis_mail_outgoing_port_25_blocked_details": "ابتدا باید سعی کنید پورت خروجی 25 را در رابط اینترنت روتر یا رابط ارائه دهنده میزبانی خود باز کنید. (ممکن است برخی از ارائه دهندگان میزبانی از شما بخواهند که برای این کار تیکت پشتیبانی ارسال کنید).", + "diagnosis_mail_outgoing_port_25_blocked": "سرور ایمیل SMTP نمی تواند به سرورهای دیگر ایمیل ارسال کند زیرا درگاه خروجی 25 در IPv {ipversion} مسدود شده است.", + "diagnosis_mail_outgoing_port_25_ok": "سرور ایمیل SMTP قادر به ارسال ایمیل است (پورت خروجی 25 مسدود نشده است).", + "diagnosis_swap_tip": "لطفاً مراقب و آگاه باشید، اگر سرور میزبانی swap را روی کارت SD یا حافظه SSD انجام دهد ، ممکن است طول عمر دستگاه را به شدت کاهش دهد.", + "diagnosis_swap_ok": "سیستم {total} swap دارد!", + "diagnosis_swap_notsomuch": "سیستم فقط {total} swap دارد. برای جلوگیری از شرایطی که حافظه سیستم شما تمام می شود ، باید حداقل {recommended} را در نظر بگیرید.", + "diagnosis_swap_none": "این سیستم به هیچ وجه swap ندارد. برای جلوگیری از شرایطی که حافظه سیستم شما تمام می شود ، باید حداقل {recommended} swap را در نظر بگیرید.", + "diagnosis_ram_ok": "این سیستم هنوز {available} ({available_percent}٪) حافظه در دسترس دارد از مجموع {total}.", + "diagnosis_ram_low": "این سیستم فقط {available} ({available_percent}٪) حافظه در دسترس دارد! (از {total}). مراقب باشید.", + "diagnosis_ram_verylow": "این سیستم فقط {available} ({available_percent}٪) حافظه در دسترس دارد! (از {total})", + "diagnosis_diskusage_ok": "‏ذخیره سازی {mountpoint} (روی دستگاه {device}) هنوز {free} فضا در دسترس دارد ({free_percent}%) فضای باقی مانده (از {total})!" } From 2f944d6258c68997482d3dfa180995ceb810cb0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M?= Date: Wed, 1 Sep 2021 04:04:55 +0000 Subject: [PATCH 054/101] Translated using Weblate (Galician) Currently translated at 100.0% (643 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/gl/ --- locales/gl.json | 65 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/locales/gl.json b/locales/gl.json index e752716cd..56204a9ea 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -481,9 +481,9 @@ "pattern_email_forward": "Ten que ser un enderezo de email válido, está aceptado o símbolo '+' (ex. persoa+etiqueta@exemplo.com)", "pattern_domain": "Ten que ser un nome de dominio válido (ex. dominiopropio.org)", "pattern_backup_archive_name": "Ten que ser un nome de ficheiro válido con 30 caracteres como máximo, alfanuméricos ou só caracteres -_.", - "password_too_simple_4": "O contrasinal debe ter 12 caracteres como mínimo e conter un díxito, maiúsculas, minúsculas e caracteres especiais", - "password_too_simple_3": "O contrasinal debe ter 8 caracteres como mínimo e conter un díxito, maiúsculas, minúsculas e caracteres especiais", - "password_too_simple_2": "O contrasinal debe ter 8 caracteres como mínimo e conter un díxito, maiúsculas e minúsculas", + "password_too_simple_4": "O contrasinal ten que ter 12 caracteres como mínimo e conter un díxito, maiúsculas, minúsculas e caracteres especiais", + "password_too_simple_3": "O contrasinal ten que ter 8 caracteres como mínimo e conter un díxito, maiúsculas, minúsculas e caracteres especiais", + "password_too_simple_2": "O contrasinal ten que ter 8 caracteres como mínimo e conter un díxito, maiúsculas e minúsculas", "password_listed": "Este contrasinal está entre os máis utilizados no mundo. Por favor elixe outro que sexa máis orixinal.", "packages_upgrade_failed": "Non se puideron actualizar tódolos paquetes", "operation_interrupted": "Foi interrumpida manualmente a operación?", @@ -584,5 +584,62 @@ "invalid_password": "Contrasinal non válido", "ldap_server_is_down_restart_it": "O servidor LDAP está caído, intenta reinicialo...", "ldap_server_down": "Non se chegou ao servidor LDAP", - "global_settings_setting_security_experimental_enabled": "Activar características de seguridade experimentais (non actives isto se non sabes o que estás a facer!)" + "global_settings_setting_security_experimental_enabled": "Activar características de seguridade experimentais (non actives isto se non sabes o que estás a facer!)", + "yunohost_postinstall_end_tip": "Post-install completada! Para rematar a configuración considera:\n- engadir unha primeira usuaria na sección 'Usuarias' na webadmin (ou 'yunohost user create ' na liña de comandos);\n- diagnosticar potenciais problemas na sección 'Diagnóstico' na webadmin (ou 'yunohost diagnosis run' na liña de comandos);\n- ler 'Rematando a configuración' e 'Coñece YunoHost' na documentación da administración: https://yunohost.org/admindoc.", + "yunohost_not_installed": "YunoHost non está instalado correctamente. Executa 'yunohost tools postinstall'", + "yunohost_installing": "Instalando YunoHost...", + "yunohost_configured": "YunoHost está configurado", + "yunohost_already_installed": "YunoHost xa está instalado", + "user_updated": "Cambiada a info da usuaria", + "user_update_failed": "Non se actualizou usuaria {user}: {error}", + "user_unknown": "Usuaria descoñecida: {user}", + "user_home_creation_failed": "Non se puido crear cartafol 'home' para a usuaria", + "user_deletion_failed": "Non se puido eliminar a usuaria {user}: {error}", + "user_deleted": "Usuaria eliminada", + "user_creation_failed": "Non se puido crear a usuaria {user}: {error}", + "user_created": "Usuaria creada", + "user_already_exists": "A usuaria '{user}' xa existe", + "upnp_port_open_failed": "Non se puido abrir porto a través de UPnP", + "upnp_dev_not_found": "Non se atopa dispositivo UPnP", + "upgrading_packages": "Actualizando paquetes...", + "upgrade_complete": "Actualización completa", + "updating_apt_cache": "Obtendo actualizacións dispoñibles para os paquetes do sistema...", + "update_apt_cache_warning": "Algo fallou ao actualizar a caché de APT (xestor de paquetes Debian). Aquí tes un volcado de sources.list, que podería axudar a identificar liñas problemáticas:\n{sourceslist}", + "update_apt_cache_failed": "Non se puido actualizar a caché de APT (xestor de paquetes de Debian). Aquí tes un volcado do sources.list, que podería axudarche a identificar liñas incorrectas:\n{sourceslist}", + "unrestore_app": "{app} non vai ser restablecida", + "unlimit": "Sen cota", + "unknown_main_domain_path": "Dominio ou ruta descoñecida '{app}'. Tes que indicar un dominio e ruta para poder especificar un URL para o permiso.", + "unexpected_error": "Aconteceu un fallo non agardado: {error}", + "unbackup_app": "{app} non vai ser gardada", + "tools_upgrade_special_packages_completed": "Completada a actualización dos paquetes YunoHost.\nPreme [Enter] para recuperar a liña de comandos", + "tools_upgrade_special_packages_explanation": "A actualización especial continuará en segundo plano. Non inicies outras tarefas no servidor nos seguintes ~10 minutos (depende do hardware). Após isto, podes volver a conectar na webadmin. O rexistro da actualización estará dispoñible en Ferramentas → Rexistro (na webadmin) ou con 'yunohost log list' (na liña de comandos).", + "tools_upgrade_special_packages": "Actualizando paquetes 'special' (yunohost-related)…", + "tools_upgrade_regular_packages_failed": "Non se actualizaron os paquetes: {packages_list}", + "tools_upgrade_regular_packages": "Actualizando os paquetes 'regular' (non-yunohost-related)…", + "tools_upgrade_cant_unhold_critical_packages": "Non se desbloquearon os paquetes críticos…", + "tools_upgrade_cant_hold_critical_packages": "Non se puideron bloquear os paquetes críticos…", + "tools_upgrade_cant_both": "Non se pode actualizar o sistema e as apps ao mesmo tempo", + "tools_upgrade_at_least_one": "Por favor indica 'apps', ou 'system'", + "this_action_broke_dpkg": "Esta acción rachou dpkg/APT (xestores de paquetes do sistema)... Podes intentar resolver o problema conectando a través de SSH e executando `sudo apt install --fix-broken`e/ou `sudo dpkg --configure -a`.", + "system_username_exists": "Xa existe este nome de usuaria na lista de usuarias do sistema", + "system_upgraded": "Sistema actualizado", + "ssowat_conf_updated": "Actualizada a configuración SSOwat", + "ssowat_conf_generated": "Rexenerada a configuración para SSOwat", + "show_tile_cant_be_enabled_for_regex": "Non podes activar 'show_tile' neste intre, porque o URL para o permiso '{permission}' é un regex", + "show_tile_cant_be_enabled_for_url_not_defined": "Non podes activar 'show_tile' neste intre, primeiro tes que definir un URL para o permiso '{permission}'", + "service_unknown": "Servizo descoñecido '{service}'", + "service_stopped": "Detívose o servizo '{service}'", + "service_stop_failed": "Non se puido deter o servizo '{service}'\n\nRexistros recentes do servizo: {logs}", + "service_started": "Iniciado o servizo '{service}'", + "service_start_failed": "Non se puido iniciar o servizo '{service}'\n\nRexistros recentes do servizo: {logs}", + "service_reloaded_or_restarted": "O servizo '{service}' foi recargado ou reiniciado", + "service_reload_or_restart_failed": "Non se recargou ou reiniciou o servizo '{service}'\n\nRexistros recentes do servizo: {logs}", + "service_restarted": "Reiniciado o servizo '{service}'", + "service_restart_failed": "Non se reiniciou o servizo '{service}'\n\nRexistros recentes do servizo: {logs}", + "service_reloaded": "Recargado o servizo '{service}'", + "service_reload_failed": "Non se recargou o servizo '{service}'\n\nRexistros recentes do servizo: {logs}", + "service_removed": "Eliminado o servizo '{service}'", + "service_remove_failed": "Non se eliminou o servizo '{service}'", + "service_regen_conf_is_deprecated": "'yunohost service regen-conf' xa non se utiliza! Executa 'yunohost tools regen-conf' no seu lugar.", + "service_enabled": "O servizo '{service}' vai ser iniciado automáticamente no inicio do sistema." } From 868c9c7f78eab6c09a34d6380275ec563d2150d5 Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Wed, 1 Sep 2021 05:40:50 +0000 Subject: [PATCH 055/101] Translated using Weblate (Persian) Currently translated at 41.8% (269 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/fa.json b/locales/fa.json index c744a8637..18db28fdc 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -263,5 +263,9 @@ "diagnosis_ram_ok": "این سیستم هنوز {available} ({available_percent}٪) حافظه در دسترس دارد از مجموع {total}.", "diagnosis_ram_low": "این سیستم فقط {available} ({available_percent}٪) حافظه در دسترس دارد! (از {total}). مراقب باشید.", "diagnosis_ram_verylow": "این سیستم فقط {available} ({available_percent}٪) حافظه در دسترس دارد! (از {total})", - "diagnosis_diskusage_ok": "‏ذخیره سازی {mountpoint} (روی دستگاه {device}) هنوز {free} فضا در دسترس دارد ({free_percent}%) فضای باقی مانده (از {total})!" + "diagnosis_diskusage_ok": "‏ذخیره سازی {mountpoint} (روی دستگاه {device}) هنوز {free} فضا در دسترس دارد ({free_percent}%) فضای باقی مانده (از {total})!", + "diagnosis_http_nginx_conf_not_up_to_date": "به نظر می رسد که پیکربندی nginx این دامنه به صورت دستی تغییر کرده است و از تشخیص YunoHost در صورت دسترسی به HTTP جلوگیری می کند.", + "diagnosis_http_partially_unreachable": "به نظر می رسد که دامنه {domain} از طریق HTTP از خارج از شبکه محلی در IPv{failed} غیرقابل دسترسی است، اگرچه در IPv{passed} کار می کند.", + "diagnosis_http_unreachable": "به نظر می رسد دامنه {domain} از خارج از شبکه محلی از طریق HTTP قابل دسترسی نیست.", + "diagnosis_http_bad_status_code": "به نظر می رسد دستگاه دیگری (شاید روتر اینترنتی شما) به جای سرور شما پاسخ داده است.
1. شایع ترین علت برای این مشکل ، پورت 80 است (و 443) به درستی به سرور شما ارسال نمی شوند.
2. در تنظیمات پیچیده تر: مطمئن شوید که هیچ فایروال یا پروکسی معکوسی تداخل نداشته باشد." } From 10b813b6bb285f34e60be897ddeb58ecbbb6c961 Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Wed, 1 Sep 2021 06:14:39 +0000 Subject: [PATCH 056/101] Translated using Weblate (Persian) Currently translated at 43.2% (278 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/locales/fa.json b/locales/fa.json index 18db28fdc..2e943fe31 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -267,5 +267,14 @@ "diagnosis_http_nginx_conf_not_up_to_date": "به نظر می رسد که پیکربندی nginx این دامنه به صورت دستی تغییر کرده است و از تشخیص YunoHost در صورت دسترسی به HTTP جلوگیری می کند.", "diagnosis_http_partially_unreachable": "به نظر می رسد که دامنه {domain} از طریق HTTP از خارج از شبکه محلی در IPv{failed} غیرقابل دسترسی است، اگرچه در IPv{passed} کار می کند.", "diagnosis_http_unreachable": "به نظر می رسد دامنه {domain} از خارج از شبکه محلی از طریق HTTP قابل دسترسی نیست.", - "diagnosis_http_bad_status_code": "به نظر می رسد دستگاه دیگری (شاید روتر اینترنتی شما) به جای سرور شما پاسخ داده است.
1. شایع ترین علت برای این مشکل ، پورت 80 است (و 443) به درستی به سرور شما ارسال نمی شوند.
2. در تنظیمات پیچیده تر: مطمئن شوید که هیچ فایروال یا پروکسی معکوسی تداخل نداشته باشد." + "diagnosis_http_bad_status_code": "به نظر می رسد دستگاه دیگری (شاید روتر اینترنتی شما) به جای سرور شما پاسخ داده است.
1. شایع ترین علت برای این مشکل ، پورت 80 است (و 443) به درستی به سرور شما ارسال نمی شوند.
2. در تنظیمات پیچیده تر: مطمئن شوید که هیچ فایروال یا پروکسی معکوسی تداخل نداشته باشد.", + "disk_space_not_sufficient_update": "برای به روزرسانی این برنامه فضای دیسک کافی باقی نمانده است", + "disk_space_not_sufficient_install": "فضای کافی برای نصب این برنامه در دیسک باقی نمانده است", + "diagnosis_sshd_config_inconsistent_details": "لطفاً اجراکنید yunohost settings set security.ssh.port -v YOUR_SSH_PORT برای تعریف پورت SSH و بررسی کنید yunohost tools regen-conf ssh --dry-run --with-diff و yunohost tools regen-conf ssh --force برای تنظیم مجدد تنظیمات خود به توصیه YunoHost.", + "diagnosis_sshd_config_inconsistent": "به نظر می رسد که پورت SSH به صورت دستی در/etc/ssh/sshd_config تغییر یافته است. از زمان YunoHost 4.2 ، یک تنظیم جهانی جدید 'security.ssh.port' برای جلوگیری از ویرایش دستی پیکربندی در دسترس است.", + "diagnosis_sshd_config_insecure": "به نظر می رسد که پیکربندی SSH به صورت دستی تغییر یافته است و مطمئن نیست زیرا هیچ دستورالعمل 'AllowGroups' یا 'AllowUsers' برای محدود کردن دسترسی به کاربران مجاز ندارد.", + "diagnosis_processes_killed_by_oom_reaper": "برخی از فرآیندها اخیراً توسط سیستم از بین رفته اند زیرا حافظه آن تمام شده است. این به طور معمول نشانه کمبود حافظه در سیستم یا فرآیندی است که حافظه زیادی را از بین می برد. خلاصه فرآیندهای کشته شده:\n{kills_summary}", + "diagnosis_never_ran_yet": "به نظر می رسد این سرور به تازگی راه اندازی شده است و هنوز هیچ گزارش تشخیصی برای نمایش وجود ندارد. شما باید با اجرای یک عیب یابی و تشخیص کامل، از طریق رابط مدیریت تحت وب webadmin یا با استفاده از 'yunohost diagnosis run' از خط فرمان معاینه و تشخیص عیب یابی را شروع کنید.", + "diagnosis_unknown_categories": "دسته های زیر ناشناخته است: {categories}", + "diagnosis_http_nginx_conf_not_up_to_date_details": "برای برطرف کردن وضعیّت ، تفاوت را با استفاده از خط فرمان بررسی کنیدyunohost tools regen-conf nginx --dry-run --with-diff و اگر خوب است ، تغییرات را اعمال کنید با استفاده از فرمان yunohost tools regen-conf nginx --force." } From d9afb8507bc9ba37649cb2f1ceb36358a3e779e7 Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Wed, 1 Sep 2021 06:37:42 +0000 Subject: [PATCH 057/101] Translated using Weblate (Persian) Currently translated at 43.7% (281 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/fa.json b/locales/fa.json index 2e943fe31..19536c9c7 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -276,5 +276,8 @@ "diagnosis_processes_killed_by_oom_reaper": "برخی از فرآیندها اخیراً توسط سیستم از بین رفته اند زیرا حافظه آن تمام شده است. این به طور معمول نشانه کمبود حافظه در سیستم یا فرآیندی است که حافظه زیادی را از بین می برد. خلاصه فرآیندهای کشته شده:\n{kills_summary}", "diagnosis_never_ran_yet": "به نظر می رسد این سرور به تازگی راه اندازی شده است و هنوز هیچ گزارش تشخیصی برای نمایش وجود ندارد. شما باید با اجرای یک عیب یابی و تشخیص کامل، از طریق رابط مدیریت تحت وب webadmin یا با استفاده از 'yunohost diagnosis run' از خط فرمان معاینه و تشخیص عیب یابی را شروع کنید.", "diagnosis_unknown_categories": "دسته های زیر ناشناخته است: {categories}", - "diagnosis_http_nginx_conf_not_up_to_date_details": "برای برطرف کردن وضعیّت ، تفاوت را با استفاده از خط فرمان بررسی کنیدyunohost tools regen-conf nginx --dry-run --with-diff و اگر خوب است ، تغییرات را اعمال کنید با استفاده از فرمان yunohost tools regen-conf nginx --force." + "diagnosis_http_nginx_conf_not_up_to_date_details": "برای برطرف کردن وضعیّت ، تفاوت را با استفاده از خط فرمان بررسی کنیدyunohost tools regen-conf nginx --dry-run --with-diff و اگر خوب است ، تغییرات را اعمال کنید با استفاده از فرمان yunohost tools regen-conf nginx --force.", + "domain_cannot_remove_main_add_new_one": "شما نمی توانید '{domain}' را حذف کنید زیرا دامنه اصلی و تنها دامنه شما است، ابتدا باید دامنه دیگری را با 'yunohost domain add ' اضافه کنید، سپس با استفاده از 'yunohost domain main-domain -n ' به عنوان دامنه اصلی تنظیم شده. و بعد از آن می توانید با استفاده از' yunohost domain remove '{domain}''دامنه '{domain}'را حذف کنید.", + "domain_cannot_add_xmpp_upload": "شما نمی توانید دامنه هایی را که با \"xmpp-upload\" شروع می شوند اضافه کنید. این نوع نام مختص ویژگی بارگذاری XMPP است که در YunoHost یکپارچه شده است.", + "domain_cannot_remove_main": "شما نمی توانید '{domain}' را حذف کنید زیرا دامنه اصلی است ، ابتدا باید با استفاده از 'yunohost domain main-domain -n ' دامنه دیگری را به عنوان دامنه اصلی تعیین کنید. در اینجا لیست دامنه های کاندید وجود دارد: {other_domains}" } From 8d7eaae1f0124df433c940c1f3eb5ed74a94c445 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 1 Sep 2021 11:32:21 +0200 Subject: [PATCH 058/101] Typos in french strings --- locales/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 0b5a5e93f..9d382304d 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -571,7 +571,7 @@ "diagnosis_dns_try_dyndns_update_force": "La configuration DNS de ce domaine devrait être automatiquement gérée par YunoHost. Si ce n'est pas le cas, vous pouvez essayer de forcer une mise à jour en utilisant yunohost dyndns update --force.", "app_packaging_format_not_supported": "Cette application ne peut pas être installée car son format n'est pas pris en charge par votre version de YunoHost. Vous devriez probablement envisager de mettre à jour votre système.", "migration_0015_weak_certs": "Il a été constaté que les certificats suivants utilisent encore des algorithmes de signature peu robustes et doivent être mis à jour pour être compatibles avec la prochaine version de NGINX : {certs}", - "global_settings_setting_backup_compress_tar_archives": "Lors de la création de nouvelles sauvegardes, compressez les archives (.tar.gz) au lieu des archives non compressées (.tar). N.B. : activer cette option permet de créer des archives plus légères, mais la procédure de sauvegarde initiale sera significativement plus longues et plus gourmandes en CPU.", + "global_settings_setting_backup_compress_tar_archives": "Lors de la création de nouvelles sauvegardes, compresser automatiquement les archives (.tar.gz) au lieu des archives non compressées (.tar). N.B. : activer cette option permet de créer des archives plus légères, mais la procédure de sauvegarde initiale sera significativement plus longues et plus gourmandes en CPU.", "migration_description_0018_xtable_to_nftable": "Migrer les anciennes règles de trafic réseau vers le nouveau système basé sur nftables", "service_description_php7.3-fpm": "Exécute les applications écrites en PHP avec NGINX", "migration_0018_failed_to_reset_legacy_rules": "La réinitialisation des règles iptable par défaut a échoué : {error}", @@ -641,5 +641,5 @@ "invalid_password": "Mot de passe incorrect", "ldap_server_is_down_restart_it": "Le service LDAP est en panne, essayez de le redémarrer...", "ldap_server_down": "Impossible d'atteindre le serveur LDAP", - "global_settings_setting_security_experimental_enabled": "Activez les fonctionnalités de sécurité expérimentales (ne l'activez pas si vous ne savez pas ce que vous faites !)" + "global_settings_setting_security_experimental_enabled": "Activer les fonctionnalités de sécurité expérimentales (ne l'activez pas si vous ne savez pas ce que vous faites !)" } From e30063743a02c8eceb97bdb3b0d45ccf33c2a46a Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Wed, 1 Sep 2021 09:25:20 +0000 Subject: [PATCH 059/101] Translated using Weblate (Persian) Currently translated at 57.5% (370 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 93 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/locales/fa.json b/locales/fa.json index 19536c9c7..31a24e269 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -277,7 +277,96 @@ "diagnosis_never_ran_yet": "به نظر می رسد این سرور به تازگی راه اندازی شده است و هنوز هیچ گزارش تشخیصی برای نمایش وجود ندارد. شما باید با اجرای یک عیب یابی و تشخیص کامل، از طریق رابط مدیریت تحت وب webadmin یا با استفاده از 'yunohost diagnosis run' از خط فرمان معاینه و تشخیص عیب یابی را شروع کنید.", "diagnosis_unknown_categories": "دسته های زیر ناشناخته است: {categories}", "diagnosis_http_nginx_conf_not_up_to_date_details": "برای برطرف کردن وضعیّت ، تفاوت را با استفاده از خط فرمان بررسی کنیدyunohost tools regen-conf nginx --dry-run --with-diff و اگر خوب است ، تغییرات را اعمال کنید با استفاده از فرمان yunohost tools regen-conf nginx --force.", - "domain_cannot_remove_main_add_new_one": "شما نمی توانید '{domain}' را حذف کنید زیرا دامنه اصلی و تنها دامنه شما است، ابتدا باید دامنه دیگری را با 'yunohost domain add ' اضافه کنید، سپس با استفاده از 'yunohost domain main-domain -n ' به عنوان دامنه اصلی تنظیم شده. و بعد از آن می توانید با استفاده از' yunohost domain remove '{domain}''دامنه '{domain}'را حذف کنید.", + "domain_cannot_remove_main_add_new_one": "شما نمی توانید '{domain}' را حذف کنید زیرا دامنه اصلی و تنها دامنه شما است، ابتدا باید دامنه دیگری را با 'yunohost domain add ' اضافه کنید، سپس با استفاده از 'yunohost domain main-domain -n ' به عنوان دامنه اصلی تنظیم شده. و بعد از آن می توانید'{domain}' را حذف کنید با استفاده از'yunohost domain remove {domain}'.'", "domain_cannot_add_xmpp_upload": "شما نمی توانید دامنه هایی را که با \"xmpp-upload\" شروع می شوند اضافه کنید. این نوع نام مختص ویژگی بارگذاری XMPP است که در YunoHost یکپارچه شده است.", - "domain_cannot_remove_main": "شما نمی توانید '{domain}' را حذف کنید زیرا دامنه اصلی است ، ابتدا باید با استفاده از 'yunohost domain main-domain -n ' دامنه دیگری را به عنوان دامنه اصلی تعیین کنید. در اینجا لیست دامنه های کاندید وجود دارد: {other_domains}" + "domain_cannot_remove_main": "شما نمی توانید '{domain}' را حذف کنید زیرا دامنه اصلی است ، ابتدا باید با استفاده از 'yunohost domain main-domain -n ' دامنه دیگری را به عنوان دامنه اصلی تعیین کنید. در اینجا لیست دامنه های کاندید وجود دارد: {other_domains}", + "installation_complete": "نصب تکمیل شد", + "hook_name_unknown": "نام قلاب ناشناخته '{name}'", + "hook_list_by_invalid": "از این ویژگی نمی توان برای فهرست قلاب ها استفاده کرد", + "hook_json_return_error": "بازگشت از قلاب {path} خوانده نشد. خطا: {msg}. محتوای خام: {raw_content}", + "hook_exec_not_terminated": "اسکریپت به درستی به پایان نرسید: {path}", + "hook_exec_failed": "اسکریپت اجرا نشد: {path}", + "group_user_not_in_group": "کاربر {user} در گروه {group} نیست", + "group_user_already_in_group": "کاربر {user} در حال حاضر در گروه {group} است", + "group_update_failed": "گروه '{group}' به روز نشد: {error}", + "group_updated": "گروه '{group}' به روز شد", + "group_unknown": "گروه '{group}' ناشناخته است", + "group_deletion_failed": "گروه '{group}' حذف نشد: {error}", + "group_deleted": "گروه '{group}' حذف شد", + "group_cannot_be_deleted": "گروه {group} را نمی توان به صورت دستی حذف کرد.", + "group_cannot_edit_primary_group": "گروه '{group}' را نمی توان به صورت دستی ویرایش کرد. این گروه اصلی شامل تنها یک کاربر خاص است.", + "group_cannot_edit_visitors": "ویرایش گروه 'visitors' بازدیدکنندگان به صورت دستی امکان پذیر نیست. این گروه ویژه، نمایانگر بازدیدکنندگان ناشناس است", + "group_cannot_edit_all_users": "گروه 'all_users' را نمی توان به صورت دستی ویرایش کرد. این یک گروه ویژه است که شامل همه کاربران ثبت شده در YunoHost میباشد", + "group_creation_failed": "گروه '{group}' ایجاد نشد: {error}", + "group_created": "گروه '{group}' ایجاد شد", + "group_already_exist_on_system_but_removing_it": "گروه {group} از قبل در گروه های سیستم وجود دارد ، اما YunoHost آن را حذف می کند...", + "group_already_exist_on_system": "گروه {group} از قبل در گروه های سیستم وجود دارد", + "group_already_exist": "گروه {group} از قبل وجود دارد", + "good_practices_about_user_password": "گذرواژه باید حداقل 8 کاراکتر باشد - اگرچه استفاده از گذرواژه طولانی تر (به عنوان مثال عبارت عبور) و/یا استفاده از تنوع کاراکترها (بزرگ ، کوچک ، رقم و کاراکتر های خاص) تمرین خوبی است.", + "good_practices_about_admin_password": "اکنون می خواهید گذرواژه جدیدی برای مدیریت تعریف کنید. گذرواژه باید حداقل 8 کاراکتر باشد - اگرچه استفاده از گذرواژه طولانی تر (به عنوان مثال عبارت عبور) و/یا استفاده از تنوع کاراکترها (بزرگ ، کوچک ، رقم و کاراکتر های خاص) تمرین خوبی است.", + "global_settings_unknown_type": "وضعیت غیرمنتظره ، به نظر می رسد که تنظیمات {setting} دارای نوع {unknown_type} است اما از نوع پشتیبانی شده توسط سیستم نیست.", + "global_settings_setting_backup_compress_tar_archives": "هنگام ایجاد پشتیبان جدید ، بایگانی های فشرده (.tar.gz) را به جای بایگانی های فشرده نشده (.tar) انتخاب کنید. N.B. : فعال کردن این گزینه به معنای ایجاد آرشیوهای پشتیبان سبک تر است ، اما روش پشتیبان گیری اولیه به طور قابل توجهی طولانی تر و سنگین تر بر روی CPU خواهد بود.", + "global_settings_setting_security_experimental_enabled": "فعال کردن ویژگی های امنیتی آزمایشی (اگر نمی دانید در حال انجام چه کاری هستید این کار را انجام ندهید!)", + "global_settings_setting_security_webadmin_allowlist": "آدرس های IP که مجاز به دسترسی مدیر وب هستند. جدا شده با ویرگول.", + "global_settings_setting_security_webadmin_allowlist_enabled": "فقط به برخی از IP ها اجازه دسترسی به مدیریت وب را بدهید.", + "global_settings_setting_smtp_relay_password": "رمز عبور میزبان رله SMTP", + "global_settings_setting_smtp_relay_user": "حساب کاربری رله SMTP", + "global_settings_setting_smtp_relay_port": "پورت رله SMTP", + "global_settings_setting_smtp_relay_host": "میزبان رله SMTP برای ارسال نامه به جای این نمونه yunohost استفاده می شود. اگر در یکی از این شرایط قرار دارید مفید است: پورت 25 شما توسط ارائه دهنده ISP یا VPS شما مسدود شده است، شما یک IP مسکونی دارید که در DUHL ذکر شده است، نمی توانید DNS معکوس را پیکربندی کنید یا این سرور مستقیماً در اینترنت نمایش داده نمی شود و می خواهید از یکی دیگر برای ارسال ایمیل استفاده کنید.", + "global_settings_setting_smtp_allow_ipv6": "اجازه دهید از IPv6 برای دریافت و ارسال نامه استفاده شود", + "global_settings_setting_ssowat_panel_overlay_enabled": "همپوشانی پانل SSOwat را فعال کنید", + "global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "اجازه دهید از کلید میزبان DSA (منسوخ شده) برای پیکربندی SH daemon استفاده شود", + "global_settings_unknown_setting_from_settings_file": "کلید ناشناخته در تنظیمات: '{setting_key}'، آن را کنار گذاشته و در /etc/yunohost/settings-unknown.json ذخیره کنید", + "global_settings_setting_security_ssh_port": "درگاه SSH", + "global_settings_setting_security_postfix_compatibility": "سازگاری در مقابل مبادله امنیتی برای سرور Postfix. روی رمزها (و سایر جنبه های مرتبط با امنیت) تأثیر می گذارد", + "global_settings_setting_security_ssh_compatibility": "سازگاری در مقابل مبادله امنیتی برای سرور SSH. روی رمزها (و سایر جنبه های مرتبط با امنیت) تأثیر می گذارد", + "global_settings_setting_security_password_user_strength": "قدرت رمز عبور کاربر", + "global_settings_setting_security_password_admin_strength": "قدرت رمز عبور مدیر", + "global_settings_setting_security_nginx_compatibility": "سازگاری در مقابل مبادله امنیتی برای وب سرور NGINX. روی رمزها (و سایر جنبه های مرتبط با امنیت) تأثیر می گذارد", + "global_settings_setting_pop3_enabled": "پروتکل POP3 را برای سرور ایمیل فعال کنید", + "global_settings_reset_success": "تنظیمات قبلی اکنون در {path} پشتیبان گیری شده است", + "global_settings_key_doesnt_exists": "کلید '{settings_key}' در تنظیمات جهانی وجود ندارد ، با اجرای 'لیست تنظیمات yunohost' می توانید همه کلیدهای موجود را مشاهده کنید", + "global_settings_cant_write_settings": "فایل تنظیمات ذخیره نشد، به دلیل: {reason}", + "global_settings_cant_serialize_settings": "سریال سازی داده های تنظیمات انجام نشد، به دلیل: {reason}", + "global_settings_cant_open_settings": "فایل تنظیمات باز نشد ، به دلیل: {reason}", + "global_settings_bad_type_for_setting": "نوع نادرست برای تنظیم {setting} ، دریافت شده {received_type}، مورد انتظار {expected_type}", + "global_settings_bad_choice_for_enum": "انتخاب نادرست برای تنظیم {setting} ، '{choice}' دریافت شد ، اما گزینه های موجود عبارتند از: {available_choices}", + "firewall_rules_cmd_failed": "برخی از دستورات قانون فایروال شکست خورده است. اطلاعات بیشتر در گزارش.", + "firewall_reloaded": "فایروال بارگیری مجدد شد", + "firewall_reload_failed": "بارگیری مجدد فایروال امکان پذیر نیست", + "file_does_not_exist": "فایل {path} وجود ندارد.", + "field_invalid": "فیلد نامعتبر '{}'", + "experimental_feature": "هشدار: این ویژگی آزمایشی است و پایدار تلقی نمی شود ، نباید از آن استفاده کنید مگر اینکه بدانید در حال انجام چه کاری هستید.", + "extracting": "استخراج...", + "dyndns_unavailable": "دامنه '{domain}' در دسترس نیست.", + "dyndns_domain_not_provided": "ارائه دهنده DynDNS {provider} نمی تواند دامنه {domain} را ارائه دهد.", + "dyndns_registration_failed": "دامنه DynDNS ثبت نشد: {error}", + "dyndns_registered": "دامنه DynDNS ثبت شد", + "dyndns_provider_unreachable": "دسترسی به ارائه دهنده DynDNS {provider} امکان پذیر نیست: یا YunoHost شما به درستی به اینترنت متصل نیست یا سرور dynette خراب است.", + "dyndns_no_domain_registered": "هیچ دامنه ای با DynDNS ثبت نشده است", + "dyndns_key_not_found": "کلید DNS برای دامنه یافت نشد", + "dyndns_key_generating": "ایجاد کلید DNS... ممکن است مدتی طول بکشد.", + "dyndns_ip_updated": "IP خود را در DynDNS به روز کرد", + "dyndns_ip_update_failed": "آدرس IP را به DynDNS به روز نکرد", + "dyndns_could_not_check_available": "بررسی نشد که آیا {domain} در {provider} در دسترس است یا خیر.", + "dyndns_could_not_check_provide": "بررسی نشد که آیا {provider} می تواند {domain} را ارائه دهد یا خیر.", + "dpkg_lock_not_available": "این دستور در حال حاضر قابل اجرا نیست زیرا به نظر می رسد برنامه دیگری از قفل dpkg (مدیر بسته سیستم) استفاده می کند", + "dpkg_is_broken": "شما نمی توانید این کار را در حال حاضر انجام دهید زیرا dpkg/APT (اداره کنندگان سیستم بسته ها) به نظر می رسد در وضعیت خرابی است… می توانید با اتصال از طریق SSH و اجرا این فرمان `sudo apt install --fix-broken` and/or `sudo dpkg --configure -a` مشکل را حل کنید.", + "downloading": "در حال بارگیری…", + "done": "انجام شد", + "domains_available": "دامنه های موجود:", + "domain_unknown": "دامنه ناشناخته", + "domain_name_unknown": "دامنه '{domain}' ناشناخته است", + "domain_uninstall_app_first": "این برنامه ها هنوز روی دامنه شما نصب هستند:\n{apps}\n\nلطفاً قبل از اقدام به حذف دامنه ، آنها را با استفاده از 'برنامه yunohost remove the_app_id' حذف کرده یا با استفاده از 'yunohost app change-url the_app_id' به دامنه دیگری منتقل کنید", + "domain_remove_confirm_apps_removal": "حذف این دامنه برنامه های زیر را حذف می کند:\n{apps}\n\nآیا طمئن هستید که میخواهید انجام دهید؟ [{answers}]", + "domain_hostname_failed": "نام میزبان جدید قابل تنظیم نیست. این ممکن است بعداً مشکلی ایجاد کند (ممکن هم هست خوب باشد).", + "domain_exists": "دامنه از قبل وجود دارد", + "domain_dyndns_root_unknown": "دامنه ریشه DynDNS ناشناخته", + "domain_dyndns_already_subscribed": "شما قبلاً در یک دامنه DynDNS مشترک شده اید", + "domain_dns_conf_is_just_a_recommendation": "این دستور پیکربندی * توصیه شده * را به شما نشان می دهد. در واقع پیکربندی DNS را برای شما تنظیم نمی کند. این وظیفه شماست که مطابق این توصیه ، منطقه DNS خود را در ثبت کننده خود پیکربندی کنید.", + "domain_deletion_failed": "حذف دامنه {domain} امکان پذیر نیست: {error}", + "domain_deleted": "دامنه حذف شد", + "domain_creation_failed": "ایجاد دامنه {domain} امکان پذیر نیست: {error}", + "domain_created": "دامنه ایجاد شد", + "domain_cert_gen_failed": "گواهی تولید نشد" } From 5501556dffb359153b9c1073dd2e89364318122d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 1 Sep 2021 15:02:30 +0200 Subject: [PATCH 060/101] ci: fix test jobs for i18n keys --- .gitlab/ci/test.gitlab-ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitlab/ci/test.gitlab-ci.yml b/.gitlab/ci/test.gitlab-ci.yml index a9e14b6e4..e0e0e001a 100644 --- a/.gitlab/ci/test.gitlab-ci.yml +++ b/.gitlab/ci/test.gitlab-ci.yml @@ -53,15 +53,17 @@ full-tests: test-i18n-keys: extends: .test-stage script: - - python3 -m pytest tests tests/test_i18n_keys.py + - python3 -m pytest tests/test_i18n_keys.py only: changes: - - locales/* + - locales/en.json + - src/yunohost/*.py + - data/hooks/diagnosis/*.py test-translation-format-consistency: extends: .test-stage script: - - python3 -m pytest tests tests/test_translation_format_consistency.py + - python3 -m pytest tests/test_translation_format_consistency.py only: changes: - locales/* From 9dc0c9b087f62e69cb04d893fe6b0ec2d4e5f0be Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 1 Sep 2021 15:08:14 +0200 Subject: [PATCH 061/101] tests: use https instead of http to check app is indeed installed --- src/yunohost/tests/test_apps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/tests/test_apps.py b/src/yunohost/tests/test_apps.py index eba5a5916..43125341b 100644 --- a/src/yunohost/tests/test_apps.py +++ b/src/yunohost/tests/test_apps.py @@ -132,7 +132,7 @@ def app_is_exposed_on_http(domain, path, message_in_page): try: r = requests.get( - "http://127.0.0.1" + path + "/", + "https://127.0.0.1" + path + "/", headers={"Host": domain}, timeout=10, verify=False, From e8a63f21be7d95b31530f51b95c6de0480964c81 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 1 Sep 2021 15:21:07 +0200 Subject: [PATCH 062/101] ci: push a remove-stale-strings only if there are some non-whitespace changes --- .gitlab/ci/translation.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/ci/translation.gitlab-ci.yml b/.gitlab/ci/translation.gitlab-ci.yml index eef57ca22..d7962436c 100644 --- a/.gitlab/ci/translation.gitlab-ci.yml +++ b/.gitlab/ci/translation.gitlab-ci.yml @@ -16,7 +16,7 @@ remove-stale-translated-strings: # create a local branch that will overwrite distant one - git checkout -b "ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}" --no-track - python3 remove_stale_translated_strings.py - - '[ $(git diff | wc -l) != 0 ] || exit 0' # stop if there is nothing to commit + - '[ $(git diff -w | wc -l) != 0 ] || exit 0' # stop if there is nothing to commit - git commit -am "[CI] Remove stale translated strings" || true - git push -f origin "ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}":"ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}" - hub pull-request -m "[CI] Remove stale translated strings" -b Yunohost:dev -p || true # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd From fe9ca56f8810e567705a33a925142c94804ed216 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 1 Sep 2021 15:48:35 +0200 Subject: [PATCH 063/101] README: translation status: use horizontal display + only 'core' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa3c839c9..9fc93740d 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Webadmin ([Yunohost-Admin](https://github.com/YunoHost/yunohost-admin)) | Single - You can help translate YunoHost on our [translation platform](https://translate.yunohost.org/engage/yunohost/?utm_source=widget)

-Translation status +Translation status

## License From 1966b200b85b73e248ab12841ec739ff4b1ab890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Gaspar?= Date: Wed, 1 Sep 2021 10:26:50 +0000 Subject: [PATCH 064/101] Translated using Weblate (French) Currently translated at 100.0% (651 of 651 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index 9d382304d..7473f2d7d 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -641,5 +641,13 @@ "invalid_password": "Mot de passe incorrect", "ldap_server_is_down_restart_it": "Le service LDAP est en panne, essayez de le redémarrer...", "ldap_server_down": "Impossible d'atteindre le serveur LDAP", - "global_settings_setting_security_experimental_enabled": "Activer les fonctionnalités de sécurité expérimentales (ne l'activez pas si vous ne savez pas ce que vous faites !)" + "global_settings_setting_security_experimental_enabled": "Activer les fonctionnalités de sécurité expérimentales (ne l'activez pas si vous ne savez pas ce que vous faites !)", + "diagnosis_apps_deprecated_practices": "La version installée de cette application utilise toujours certaines pratiques de packaging obsolètes. Vous devriez vraiment envisager de mettre l'application à jour..", + "diagnosis_apps_outdated_ynh_requirement": "La version installée de cette application nécessite uniquement YunoHost> = 2.x, cela indique que l'application n'est pas à jour avec les bonnes pratiques de packaging et les helpers recommandées. Vous devriez vraiment envisager de mettre l'application à jour.", + "diagnosis_apps_bad_quality": "Cette application est actuellement signalée comme cassée dans le catalogue d'applications de YunoHost. Cela peut être un problème temporaire. En attendant que les mainteneurs tentent de résoudre le problème, la mise à jour de cette application est désactivée.", + "diagnosis_apps_broken": "Cette application est actuellement signalée comme cassée dans le catalogue d'applications de YunoHost. Cela peut être un problème temporaire. En attendant que les mainteneurs tentent de résoudre le problème, la mise à jour de cette application est désactivée.", + "diagnosis_apps_not_in_app_catalog": "Cette application est absente ou ne figure plus dans le catalogue d'applications de YunoHost. Vous devriez envisager de la désinstaller car elle ne recevra pas de mise à jour et pourrait compromettre l'intégrité et la sécurité de votre système.", + "diagnosis_apps_issue": "Un problème a été détecté pour l'application {app}", + "diagnosis_apps_allgood": "Toutes les applications installées respectent les pratiques de packaging de base", + "diagnosis_description_apps": "Applications" } From 33606404c451e8bc9c237b5e0cdb4f44eeff598c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Gaspar?= Date: Wed, 1 Sep 2021 12:42:40 +0000 Subject: [PATCH 065/101] Translated using Weblate (Ukrainian) Currently translated at 7.5% (49 of 651 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index 71d7ee897..2e466685b 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -114,7 +114,7 @@ "permission_updated": "Дозвіл '{permission}' оновлено", "permission_update_failed": "Не вдалося оновити дозвіл '{permission}': {error}", "permission_not_found": "Дозвіл '{permission}', не знайдено", - "permission_deletion_failed": "Не вдалося видалити дозвіл '{permission}': {помилка}", + "permission_deletion_failed": "Не вдалося видалити дозвіл '{permission}': {error}", "permission_deleted": "Дозвіл '{permission}' видалено", "permission_cant_add_to_all_users": "Дозвіл {permission} не може бути додано всім користувачам.", "permission_currently_allowed_for_all_users": "В даний час цей дозвіл надається всім користувачам на додаток до інших груп. Ймовірно, вам потрібно або видалити дозвіл 'all_users', або видалити інші групи, яким воно зараз надано.", @@ -257,7 +257,7 @@ "installation_complete": "установка завершена", "hook_name_unknown": "Невідоме ім'я хука '{name}'", "hook_list_by_invalid": "Це властивість не може бути використано для перерахування хуков", - "hook_json_return_error": "Не вдалося розпізнати повернення з хука {шлях}. Помилка: {msg}. Необроблений контент: {raw_content}.", + "hook_json_return_error": "Не вдалося розпізнати повернення з хука {path}. Помилка: {msg}. Необроблений контент: {raw_content}", "hook_exec_not_terminated": "Скрипт не завершився належним чином: {шлях}", "hook_exec_failed": "Не вдалося запустити скрипт: {path}", "group_user_not_in_group": "Користувач {user} не входить в групу {group}", @@ -337,9 +337,9 @@ "domain_dyndns_root_unknown": "Невідомий кореневої домен DynDNS", "domain_dyndns_already_subscribed": "Ви вже підписалися на домен DynDNS", "domain_dns_conf_is_just_a_recommendation": "Ця команда показує * рекомендовану * конфігурацію. Насправді вона не встановлює конфігурацію DNS для вас. Ви самі повинні налаштувати свою зону DNS у реєстратора відповідно до цих рекомендацій.", - "domain_deletion_failed": "Неможливо видалити домен {domain}: {помилка}", + "domain_deletion_failed": "Неможливо видалити домен {domain}: {error}", "domain_deleted": "домен видалений", - "domain_creation_failed": "Неможливо створити домен {domain}: {помилка}", + "domain_creation_failed": "Неможливо створити домен {domain}: {error}", "domain_created": "домен створений", "domain_cert_gen_failed": "Не вдалося згенерувати сертифікат", "domain_cannot_remove_main_add_new_one": "Ви не можете видалити '{domain}', так як це основний домен і ваш єдиний домен, вам потрібно спочатку додати інший домен за допомогою 'yunohost domain add ', потім встановити його як основний домен за допомогою ' yunohost domain main-domain -n 'і потім ви можете видалити домен' {domain} 'за допомогою' yunohost domain remove {domain} ''.", @@ -362,7 +362,7 @@ "diagnosis_http_timeout": "При спробі зв'язатися з вашим сервером ззовні стався тайм-аут. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. Ви також повинні переконатися, що служба nginx запущена
3. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", "diagnosis_http_ok": "Домен {domain} доступний по HTTP ззовні локальної мережі.", "diagnosis_http_localdomain": "Домен {domain} з доменом .local TLD не може бути доступний ззовні локальної мережі.", - "diagnosis_http_could_not_diagnose_details": "Помилка: {error}.", + "diagnosis_http_could_not_diagnose_details": "Помилка: {error}", "diagnosis_http_could_not_diagnose": "Не вдалося діагностувати досяжність доменів ззовні в IPv {ipversion}.", "diagnosis_http_hairpinning_issue_details": "Можливо, це пов'язано з блоком/маршрутизатором вашого інтернет-провайдера. В результаті, люди ззовні вашої локальної мережі зможуть отримати доступ до вашого сервера, як і очікувалося, але не люди зсередини локальної мережі (як ви, ймовірно?) При використанні доменного імені або глобального IP. Можливо, ви зможете поліпшити ситуацію, глянувши на https://yunohost.org/dns_local_network .", "diagnosis_http_hairpinning_issue": "Схоже, що у вашій локальній мережі не включена проброска.", @@ -403,7 +403,7 @@ "diagnosis_mail_fcrdns_nok_details": "Спочатку спробуйте налаштувати зворотний DNS з {ehlo_domain} в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм тікет підтримки для цього).", "diagnosis_mail_fcrdns_dns_missing": "У IPv {ipversion} не визначений зворотний DNS. Деякі листи можуть не доставлятися або позначатися як спам.", "diagnosis_mail_fcrdns_ok": "Ваш зворотний DNS налаштований правильно!", - "diagnosis_mail_ehlo_could_not_diagnose_details": "Помилка: {error}.", + "diagnosis_mail_ehlo_could_not_diagnose_details": "Помилка: {error}", "diagnosis_mail_ehlo_could_not_diagnose": "Не вдалося діагностувати наявність певної поштовий сервер postfix ззовні в IPv {ipversion}.", "diagnosis_mail_ehlo_wrong_details": "EHLO, отриманий віддаленим діагностичним центром в IPv {ipversion}, відрізняється від домену вашого сервера.
Отриманий EHLO: {wrong_ehlo}
Очікуваний: {right_ehlo} < br> найпоширенішою причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер . Крім того, переконайтеся, що в роботу сервера не втручається брандмауер або зворотний проксі-сервер.", "diagnosis_mail_ehlo_wrong": "Інший поштовий SMTP-сервер відповідає на IPv {ipversion}. Ваш сервер, ймовірно, не зможе отримувати електронну пошту.", @@ -427,7 +427,7 @@ "user_home_creation_failed": "Не вдалося створити домашню папку для користувача", "user_deletion_failed": "Не вдалося видалити користувача {user}: {error}", "user_deleted": "користувача видалено", - "user_creation_failed": "Не вдалося створити користувача {user}: {помилка}", + "user_creation_failed": "Не вдалося створити користувача {user}: {error}", "user_created": "Аккаунт було створено", "user_already_exists": "Користувач '{user}' вже існує", "upnp_port_open_failed": "Не вдалося відкрити порт через UPnP", @@ -511,8 +511,8 @@ "diagnosis_failed": "Не вдалося результат діагностики для категорії '{категорія}': {error}", "diagnosis_everything_ok": "Все виглядає добре для {категорії}!", "diagnosis_found_warnings": "Знайдено {попередження} пунктів, які можна поліпшити для {категорії}.", - "diagnosis_found_errors_and_warnings": "Знайдено {помилки} істотний (і) питання (и) (і {попередження} попередження (я)), що відносяться до {категорії}!", - "diagnosis_found_errors": "Знайдена {помилка} важлива проблема (і), пов'язана з {категорією}!", + "diagnosis_found_errors_and_warnings": "Знайдено {errors} істотний (і) питання (и) (і {попередження} попередження (я)), що відносяться до {category}!", + "diagnosis_found_errors": "Знайдена {errors} важлива проблема (і), пов'язана з {category}!", "diagnosis_ignored_issues": "(+ {Nb_ignored} проігнорована проблема (проблеми))", "diagnosis_cant_run_because_of_dep": "Неможливо запустити діагностику для {категорії}, поки є важливі проблеми, пов'язані з {глибиною}.", "diagnosis_cache_still_valid": "(Кеш все ще дійсний для діагностики {категорії}. Повторна діагностика поки не проводиться!)", @@ -607,7 +607,7 @@ "ask_user_domain": "Домен для адреси електронної пошти користувача і облікового запису XMPP", "apps_catalog_update_success": "Каталог додатків був оновлений!", "apps_catalog_obsolete_cache": "Кеш каталогу додатків порожній або застарів.", - "apps_catalog_failed_to_download": "Неможливо завантажити каталог додатків {apps_catalog}: {помилка}.", + "apps_catalog_failed_to_download": "Неможливо завантажити каталог додатків {apps_catalog}: {error}", "apps_catalog_updating": "Оновлення каталогу додатків…", "apps_catalog_init_success": "Система каталогу додатків инициализирована!", "apps_already_up_to_date": "Всі додатки вже оновлені", From 90d78348084d5aa86718fbf7b598be97bff29040 Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Wed, 1 Sep 2021 15:43:49 +0000 Subject: [PATCH 066/101] Translated using Weblate (Persian) Currently translated at 79.1% (509 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 141 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/locales/fa.json b/locales/fa.json index 31a24e269..9e33d02d7 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -368,5 +368,144 @@ "domain_deleted": "دامنه حذف شد", "domain_creation_failed": "ایجاد دامنه {domain} امکان پذیر نیست: {error}", "domain_created": "دامنه ایجاد شد", - "domain_cert_gen_failed": "گواهی تولید نشد" + "domain_cert_gen_failed": "گواهی تولید نشد", + "permission_creation_failed": "مجوز '{permission}' را نمیتوان ایجاد کرد: {error}", + "permission_created": "مجوز '{permission}' ایجاد شد", + "permission_cannot_remove_main": "حذف مجوز اصلی مجاز نیست", + "permission_already_up_to_date": "مجوز به روز نشد زیرا درخواست های افزودن/حذف هم اینک با وضعیّت فعلی مطابقت دارد.", + "permission_already_exist": "مجوز '{permission}' در حال حاضر وجود دارد", + "permission_already_disallowed": "گروه '{group}' قبلاً مجوز '{permission}' را غیرفعال کرده است", + "permission_already_allowed": "گروه '{group}' قبلاً مجوز '{permission}' را فعال کرده است", + "pattern_password_app": "متأسفیم ، گذرواژه ها نمی توانند شامل کاراکترهای زیر باشند: {forbidden_chars}", + "pattern_username": "باید فقط حروف الفبایی کوچک و خط زیر باشد", + "pattern_positive_number": "باید یک عدد مثبت باشد", + "pattern_port_or_range": "باید یک شماره پورت معتبر (یعنی 0-65535) یا محدوده پورت (به عنوان مثال 100: 200) باشد", + "pattern_password": "باید حداقل 3 کاراکتر داشته باشد", + "pattern_mailbox_quota": "باید اندازه ای با پسوند b / k / M / G / T یا 0 داشته باشد تا سهمیه نداشته باشد", + "pattern_lastname": "باید نام خانوادگی معتبر باشد", + "pattern_firstname": "باید یک نام کوچک معتبر باشد", + "pattern_email": "باید یک آدرس ایمیل معتبر باشد ، بدون نماد '+' (به عنوان مثال someone@example.com)", + "pattern_email_forward": "باید یک آدرس ایمیل معتبر باشد ، نماد '+' پذیرفته شده است (به عنوان مثال someone+tag@example.com)", + "pattern_domain": "باید یک نام دامنه معتبر باشد (به عنوان مثال my-domain.org)", + "pattern_backup_archive_name": "باید یک نام فایل معتبر با حداکثر 30 کاراکتر حرف و عدد و -_ باشد. فقط کاراکترها", + "password_too_simple_4": "گذرواژه باید حداقل 12 کاراکتر طول داشته باشد و شامل عدد ، حروف الفبائی کوچک و بزرگ و کاراکترهای خاص باشد", + "password_too_simple_3": "گذرواژه باید حداقل 8 کاراکتر طول داشته باشد و شامل عدد ، حروف الفبائی کوچک و بزرگ و کاراکترهای خاص باشد", + "password_too_simple_2": "گذرواژه باید حداقل 8 کاراکتر طول داشته باشد و شامل عدد ، حروف الفبائی کوچک و بزرگ باشد", + "password_too_simple_1": "رمز عبور باید حداقل 8 کاراکتر باشد", + "password_listed": "این رمز در بین پر استفاده ترین رمزهای عبور در جهان قرار دارد. لطفاً چیزی منحصر به فرد تر انتخاب کنید.", + "packages_upgrade_failed": "همه بسته ها را نمی توان ارتقا داد", + "operation_interrupted": "عملیات به صورت دستی قطع شد؟", + "invalid_password": "رمز عبور نامعتبر", + "invalid_number": "باید یک عدد باشد", + "not_enough_disk_space": "فضای آزاد کافی در '{path}' وجود ندارد", + "migrations_to_be_ran_manually": "مهاجرت {id} باید به صورت دستی اجرا شود. لطفاً به صفحه Tools → Migrations در صفحه webadmin بروید، یا `yunohost tools migrations run` را اجرا کنید.", + "migrations_success_forward": "مهاجرت {id} تکمیل شد", + "migrations_skip_migration": "رد کردن مهاجرت {id}...", + "migrations_running_forward": "مهاجرت در حال اجرا {id}»...", + "migrations_pending_cant_rerun": "این مهاجرت ها هنوز در انتظار هستند ، بنابراین نمی توان آنها را دوباره اجرا کرد: {ids}", + "migrations_not_pending_cant_skip": "این مهاجرت ها معلق نیستند ، بنابراین نمی توان آنها را رد کرد: {ids}", + "migrations_no_such_migration": "مهاجرتی به نام '{id}' وجود ندارد", + "migrations_no_migrations_to_run": "مهاجرتی برای اجرا وجود ندارد", + "migrations_need_to_accept_disclaimer": "برای اجرای مهاجرت {id} ، باید سلب مسئولیت زیر را بپذیرید:\n---\n{disclaimer}\n---\nاگر می خواهید مهاجرت را اجرا کنید ، لطفاً فرمان را با گزینه '--accept-disclaimer' دوباره اجرا کنید.", + "migrations_must_provide_explicit_targets": "هنگام استفاده '--skip' یا '--force-rerun' باید اهداف مشخصی را ارائه دهید", + "migrations_migration_has_failed": "مهاجرت {id} کامل نشد ، لغو شد. خطا: {exception}", + "migrations_loading_migration": "بارگیری مهاجرت {id}...", + "migrations_list_conflict_pending_done": "شما نمیتوانید از هر دو انتخاب '--previous' و '--done' به طور همزمان استفاده کنید.", + "migrations_exclusive_options": "'--auto', '--skip'، و '--force-rerun' گزینه های متقابل هستند.", + "migrations_failed_to_load_migration": "مهاجرت بار نشد {id}: {error}", + "migrations_dependencies_not_satisfied": "این مهاجرت ها را اجرا کنید: '{dependencies_id}' ، قبل از مهاجرت {id}.", + "migrations_cant_reach_migration_file": "دسترسی به پرونده های مهاجرت در مسیر '٪ s' امکان پذیر نیست", + "migrations_already_ran": "این مهاجرت ها قبلاً انجام شده است: {ids}", + "migration_0019_slapd_config_will_be_overwritten": "به نظر می رسد که شما پیکربندی slapd را به صورت دستی ویرایش کرده اید. برای این مهاجرت بحرانی ، YunoHost باید به روز رسانی پیکربندی slapd را مجبور کند. فایلهای اصلی در {conf_backup_folder} پشتیبان گیری می شوند.", + "migration_0019_add_new_attributes_in_ldap": "اضافه کردن ویژگی های جدید برای مجوزها در پایگاه داده LDAP", + "migration_0018_failed_to_reset_legacy_rules": "تنظیم مجدد قوانین iptables قدیمی انجام نشد: {error}", + "migration_0018_failed_to_migrate_iptables_rules": "انتقال قوانین قدیمی iptables به nftables انجام نشد: {error}", + "migration_0017_not_enough_space": "فضای کافی در {path} برای اجرای مهاجرت در دسترس قرار دهید.", + "migration_0017_postgresql_11_not_installed": "PostgreSQL 9.6 نصب شده است ، اما postgresql 11 نه؟ ممکن است اتفاق عجیبی در سیستم شما رخ داده باشد:(...", + "migration_0017_postgresql_96_not_installed": "PostgreSQL روی سیستم شما نصب نشده است. کاری برای انجام دادن نیست.", + "migration_0015_weak_certs": "گواهینامه های زیر هنوز از الگوریتم های امضای ضعیف استفاده می کنند و برای سازگاری با نسخه بعدی nginx باید ارتقاء یابند: {certs}", + "migration_0015_cleaning_up": "پاک کردن حافظه پنهان و بسته ها دیگر مفید نیست...", + "migration_0015_specific_upgrade": "شروع به روزرسانی بسته های سیستم که باید به طور مستقل ارتقا یابد...", + "migration_0015_modified_files": "لطفاً توجه داشته باشید که فایل های زیر به صورت دستی اصلاح شده اند و ممکن است پس از ارتقاء رونویسی شوند: {manually_modified_files}", + "migration_0015_problematic_apps_warning": "لطفاً توجه داشته باشید که احتمالاً برنامه های نصب شده مشکل ساز تشخیص داده شده. به نظر می رسد که آنها از فهرست برنامه YunoHost نصب نشده اند یا به عنوان 'working' علامت گذاری نشده اند. در نتیجه ، نمی توان تضمین کرد که پس از ارتقاء همچنان کار خواهند کرد: {problematic_apps}", + "migration_0015_general_warning": "لطفاً توجه داشته باشید که این مهاجرت یک عملیات ظریف است. تیم YunoHost تمام تلاش خود را برای بررسی و آزمایش آن انجام داد ، اما مهاجرت ممکن است بخشهایی از سیستم یا برنامه های آن را خراب کند.\n\nبنابراین ، توصیه می شود:\n- پشتیبان گیری از هرگونه داده یا برنامه حیاتی را انجام دهید. اطلاعات بیشتر در https://yunohost.org/backup ؛\n- پس از راه اندازی مهاجرت صبور باشید: بسته به اتصال به اینترنت و سخت افزار شما ، ممکن است چند ساعت طول بکشد تا همه چیز ارتقا یابد.", + "migration_0015_system_not_fully_up_to_date": "سیستم شما کاملاً به روز نیست. لطفاً قبل از اجرای مهاجرت به Buster ، یک ارتقاء منظم انجام دهید.", + "migration_0015_not_enough_free_space": "فضای آزاد در /var /بسیار کم است! برای اجرای این مهاجرت باید حداقل 1 گیگابایت فضای آزاد داشته باشید.", + "migration_0015_not_stretch": "توزیع دبیان فعلی استرچ نیست!", + "migration_0015_yunohost_upgrade": "شروع به روز رسانی اصلی YunoHost...", + "migration_0015_still_on_stretch_after_main_upgrade": "هنگام ارتقاء اصلی مشکلی پیش آمد ، به نظر می رسد سیستم هنوز در Debian Stretch است", + "migration_0015_main_upgrade": "شروع به روزرسانی اصلی...", + "migration_0015_patching_sources_list": "وصله منابع. لیست ها...", + "migration_0015_start": "شروع مهاجرت به باستر", + "migration_update_LDAP_schema": "در حال به روزرسانی طرح وشمای LDAP...", + "migration_ldap_rollback_success": "سیستم برگردانده شد.", + "migration_ldap_migration_failed_trying_to_rollback": "نمی توان مهاجرت کرد... تلاش برای بازگرداندن سیستم.", + "migration_ldap_can_not_backup_before_migration": "نمی توان پشتیبان گیری سیستم را قبل از شکست مهاجرت تکمیل کرد. خطا: {error}", + "migration_ldap_backup_before_migration": "ایجاد پشتیبان از پایگاه داده LDAP و تنظیمات برنامه ها قبل از مهاجرت واقعی.", + "migration_description_0020_ssh_sftp_permissions": "پشتیبانی مجوزهای SSH و SFTP را اضافه کنید", + "migration_description_0019_extend_permissions_features": "سیستم مدیریت مجوز برنامه را تمدید / دوباره کار بندازید", + "migration_description_0018_xtable_to_nftable": "مهاجرت از قوانین قدیمی ترافیک شبکه به سیستم جدید nftable", + "migration_description_0017_postgresql_9p6_to_11": "مهاجرت پایگاه های داده از PostgreSQL 9.6 به 11", + "migration_description_0016_php70_to_php73_pools": "انتقال فایلهای conf php7.0-fpm 'pool' به php7.3", + "migration_description_0015_migrate_to_buster": "سیستم را به Debian Buster و YunoHost 4.x ارتقا دهید", + "migrating_legacy_permission_settings": "در حال انتقال تنظیمات مجوز قدیمی...", + "main_domain_changed": "دامنه اصلی تغییر کرده است", + "main_domain_change_failed": "تغییر دامنه اصلی امکان پذیر نیست", + "mail_unavailable": "این آدرس ایمیل محفوظ است و باید به طور خودکار به اولین کاربر اختصاص داده شود", + "mailbox_used_space_dovecot_down": "اگر می خواهید فضای صندوق پستی استفاده شده را واکشی کنید ، سرویس صندوق پستی Dovecot باید فعال باشد", + "mailbox_disabled": "ایمیل برای کاربر {user} خاموش است", + "mail_forward_remove_failed": "ارسال ایمیل '{mail}' حذف نشد", + "mail_domain_unknown": "آدرس ایمیل نامعتبر برای دامنه '{domain}'. لطفاً از دامنه ای که توسط این سرور اداره می شود استفاده کنید.", + "mail_alias_remove_failed": "نام مستعار ایمیل '{mail}' حذف نشد", + "log_tools_reboot": "سرور خود را راه اندازی مجدد کنید", + "log_tools_shutdown": "سرور خود را خاموش کنید", + "log_tools_upgrade": "بسته های سیستم را ارتقا دهید", + "log_tools_postinstall": "اسکریپت پس از نصب سرور YunoHost خود را نصب کنید", + "log_tools_migrations_migrate_forward": "اجرای مهاجرت ها", + "log_domain_main_domain": "'{}' را دامنه اصلی کنید", + "log_user_permission_reset": "بازنشانی مجوز '{}'", + "log_user_permission_update": "دسترسی ها را برای مجوزهای '{}' به روز کنید", + "log_user_update": "به روزرسانی اطلاعات کاربر '{}'", + "log_user_group_update": "به روزرسانی گروه '{}'", + "log_user_group_delete": "حذف گروه '{}'", + "log_user_group_create": "ایجاد گروه '{}'", + "log_user_delete": "کاربر '{}' را حذف کنید", + "log_user_create": "کاربر '{}' را اضافه کنید", + "log_regen_conf": "بازسازی تنظیمات سیستم '{}'", + "log_letsencrypt_cert_renew": "تمدید '{}' گواهی اجازه رمزگذاری", + "log_selfsigned_cert_install": "گواهی خود امضا شده را در دامنه '{}' نصب کنید", + "log_permission_url": "به روزرسانی نشانی اینترنتی مربوط به مجوز دسترسی '{}'", + "log_permission_delete": "حذف مجوز دسترسی '{}'", + "log_permission_create": "ایجاد مجوز دسترسی '{}'", + "log_letsencrypt_cert_install": "گواهی اجازه رمزگذاری را در دامنه '{}' نصب کنید", + "log_dyndns_update": "IP مرتبط با '{}' زیر دامنه YunoHost خود را به روز کنید", + "log_dyndns_subscribe": "مشترک شدن در زیر دامنه YunoHost '{}'", + "log_domain_remove": "دامنه '{}' را از پیکربندی سیستم حذف کنید", + "log_domain_add": "دامنه '{}' را به پیکربندی سیستم اضافه کنید", + "log_remove_on_failed_install": "پس از نصب ناموفق '{}' را حذف کنید", + "log_remove_on_failed_restore": "پس از بازیابی ناموفق از بایگانی پشتیبان، '{}' را حذف کنید", + "log_backup_restore_app": "بازیابی '{}' از بایگانی پشتیبان", + "log_backup_restore_system": "بازیابی سیستم بوسیله آرشیو پشتیبان", + "log_backup_create": "بایگانی پشتیبان ایجاد کنید", + "log_available_on_yunopaste": "این گزارش اکنون از طریق {url} در دسترس است", + "log_app_config_apply": "پیکربندی را در برنامه '{}' اعمال کنید", + "log_app_config_show_panel": "پانل پیکربندی برنامه '{}' را نشان دهید", + "log_app_action_run": "عملکرد برنامه '{}' را اجرا کنید", + "log_app_makedefault": "\"{}\" را برنامه پیش فرض قرار دهید", + "log_app_upgrade": "برنامه '{}' را ارتقاء دهید", + "log_app_remove": "برنامه '{}' را حذف کنید", + "log_app_install": "برنامه '{}' را نصب کنید", + "log_app_change_url": "نشانی وب برنامه '{}' را تغییر دهید", + "log_operation_unit_unclosed_properly": "واحد عملیّات به درستی بسته نشده است", + "log_does_exists": "هیچ گزارش عملیاتی با نام '{log}' وجود ندارد ، برای مشاهده همه گزارش عملیّات های موجود در خط فرمان از دستور 'yunohost log list' استفاده کنید", + "log_help_to_get_failed_log": "عملیات '{desc}' کامل نشد. لطفاً برای دریافت راهنمایی و کمک ، گزارش کامل این عملیات را با استفاده از دستور 'yunohost log share {name}' به اشتراک بگذارید", + "log_link_to_failed_log": "عملیّات '{desc}' کامل نشد. لطفاً گزارش کامل این عملیات را ارائه دهید بواسطه اینجا را کلیک کنید برای دریافت کمک", + "log_help_to_get_log": "برای مشاهده گزارش عملیات '{desc}'، از دستور 'yunohost log show {name}{name}' استفاده کنید", + "log_link_to_log": "گزارش کامل این عملیات: {desc}'", + "log_corrupted_md_file": "فایل فوق داده YAML مربوط به گزارش ها آسیب دیده است: '{md_file}\nخطا: {error} '", + "ldap_server_is_down_restart_it": "سرویس LDAP خاموش است ، سعی کنید آن را دوباره راه اندازی کنید...", + "ldap_server_down": "دسترسی به سرور LDAP امکان پذیر نیست", + "iptables_unavailable": "در اینجا نمی توانید با iptables بازی کنید. شما یا در ظرفی هستید یا هسته شما آن را پشتیبانی نمی کند", + "ip6tables_unavailable": "در اینجا نمی توانید با جدول های ipv6 کار کنید. شما یا در کانتینتر هستید یا هسته شما آن را پشتیبانی نمی کند", + "invalid_regex": "عبارت منظم نامعتبر: '{regex}'" } From 11e70881cede7eb98a0af73ac806d2515294cd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Gaspar?= Date: Wed, 1 Sep 2021 17:21:14 +0000 Subject: [PATCH 067/101] Translated using Weblate (French) Currently translated at 100.0% (651 of 651 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 54 ++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 7473f2d7d..e3a32d639 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -57,7 +57,7 @@ "domain_uninstall_app_first": "Ces applications sont toujours installées sur votre domaine :\n{apps}\n\nVeuillez les désinstaller avec la commande 'yunohost app remove nom-de-l-application' ou les déplacer vers un autre domaine avec la commande 'yunohost app change-url nom-de-l-application' avant de procéder à la suppression du domaine", "domain_unknown": "Domaine inconnu", "done": "Terminé", - "downloading": "Téléchargement en cours …", + "downloading": "Téléchargement en cours…", "dyndns_ip_update_failed": "Impossible de mettre à jour l’adresse IP sur le domaine DynDNS", "dyndns_ip_updated": "Mise à jour de votre IP pour le domaine DynDNS", "dyndns_key_generating": "Génération de la clé DNS..., cela peut prendre un certain temps.", @@ -79,8 +79,8 @@ "ip6tables_unavailable": "Vous ne pouvez pas jouer avec ip6tables ici. Vous êtes soit dans un conteneur, soit votre noyau ne le prend pas en charge", "iptables_unavailable": "Vous ne pouvez pas jouer avec iptables ici. Vous êtes soit dans un conteneur, soit votre noyau ne le prend pas en charge", "mail_alias_remove_failed": "Impossible de supprimer l’alias de courriel '{mail}'", - "mail_domain_unknown": "Le domaine '{domain}' de cette adresse de courriel n’est pas valide. Merci d’utiliser un domaine administré par ce serveur.", - "mail_forward_remove_failed": "Impossible de supprimer le courriel de transfert '{mail}'", + "mail_domain_unknown": "Le domaine '{domain}' de cette adresse email n’est pas valide. Merci d’utiliser un domaine administré par ce serveur.", + "mail_forward_remove_failed": "Impossible de supprimer l'email de transfert '{mail}'", "main_domain_change_failed": "Impossible de modifier le domaine principal", "main_domain_changed": "Le domaine principal a été modifié", "not_enough_disk_space": "L’espace disque est insuffisant sur '{path}'", @@ -158,8 +158,8 @@ "certmanager_domain_http_not_working": "Le domaine {domain} ne semble pas être accessible via HTTP. Merci de vérifier la catégorie 'Web' dans le diagnostic pour plus d'informations. (Ou si vous savez ce que vous faites, utilisez '--no-checks' pour désactiver la vérification.)", "certmanager_domain_dns_ip_differs_from_public_ip": "Les enregistrements DNS du domaine '{domain}' sont différents de l’adresse IP de ce serveur. Pour plus d'informations, veuillez consulter la catégorie \"Enregistrements DNS\" dans la section diagnostic. Si vous avez récemment modifié votre enregistrement A, veuillez attendre sa propagation (des vérificateurs de propagation DNS sont disponibles en ligne). (Si vous savez ce que vous faites, utilisez '--no-checks' pour désactiver ces contrôles)", "certmanager_cannot_read_cert": "Quelque chose s’est mal passé lors de la tentative d’ouverture du certificat actuel pour le domaine {domain} (fichier : {file}), la cause est : {reason}", - "certmanager_cert_install_success_selfsigned": "Le certificat auto-signé est maintenant installé pour le domaine « {domain} »", - "certmanager_cert_install_success": "Le certificat Let’s Encrypt est maintenant installé pour le domaine « {domain} »", + "certmanager_cert_install_success_selfsigned": "Le certificat auto-signé est maintenant installé pour le domaine '{domain}'", + "certmanager_cert_install_success": "Le certificat Let’s Encrypt est maintenant installé pour le domaine '{domain}'", "certmanager_cert_renew_success": "Certificat Let’s Encrypt renouvelé pour le domaine '{domain}'", "certmanager_cert_signing_failed": "Impossible de signer le nouveau certificat", "certmanager_no_cert_file": "Impossible de lire le fichier du certificat pour le domaine {domain} (fichier : {file})", @@ -170,7 +170,7 @@ "mailbox_used_space_dovecot_down": "Le service de courriel Dovecot doit être démarré si vous souhaitez voir l’espace disque occupé par la messagerie", "domains_available": "Domaines disponibles :", "backup_archive_broken_link": "Impossible d’accéder à l’archive de sauvegarde (lien invalide vers {path})", - "certmanager_acme_not_configured_for_domain": "Le challenge ACME n'a pas pu être validé pour le domaine {domain} pour le moment car le code de la configuration nginx est manquant... Merci de vérifier que votre configuration nginx est à jour avec la commande: `yunohost tools regen-conf nginx --dry-run --with-diff`.", + "certmanager_acme_not_configured_for_domain": "Le challenge ACME n'a pas pu être validé pour le domaine {domain} pour le moment car le code de la configuration NGINX est manquant... Merci de vérifier que votre configuration NGINX est à jour avec la commande: `yunohost tools regen-conf nginx --dry-run --with-diff`.", "domain_hostname_failed": "Échec de l’utilisation d’un nouveau nom d’hôte. Cela pourrait causer des soucis plus tard (cela n’en causera peut-être pas).", "app_already_installed_cant_change_url": "Cette application est déjà installée. L’URL ne peut pas être changé simplement par cette fonction. Vérifiez si cela est disponible avec `app changeurl`.", "app_change_url_failed_nginx_reload": "Le redémarrage de NGINX a échoué. Voici la sortie de 'nginx -t' :\n{nginx_errors}", @@ -217,10 +217,10 @@ "backup_couldnt_bind": "Impossible de lier {src} avec {dest}.", "domain_dns_conf_is_just_a_recommendation": "Cette commande vous montre la configuration *recommandée*. Elle ne configure pas le DNS pour vous. Il est de votre ressort de configurer votre zone DNS chez votre registrar/fournisseur conformément à cette recommandation.", "migrations_cant_reach_migration_file": "Impossible d’accéder aux fichiers de migration via le chemin '%s'", - "migrations_loading_migration": "Chargement de la migration {id} ...", + "migrations_loading_migration": "Chargement de la migration {id}...", "migrations_migration_has_failed": "La migration {id} a échoué avec l’exception {exception} : annulation", "migrations_no_migrations_to_run": "Aucune migration à lancer", - "migrations_skip_migration": "Ignorer et passer la migration {id} ...", + "migrations_skip_migration": "Ignorer et passer la migration {id}...", "server_shutdown": "Le serveur va s’éteindre", "server_shutdown_confirm": "Le serveur va être éteint immédiatement, le voulez-vous vraiment ? [{answers}]", "server_reboot": "Le serveur va redémarrer", @@ -236,14 +236,14 @@ "migrations_need_to_accept_disclaimer": "Pour lancer la migration {id}, vous devez accepter cet avertissement :\n---\n{disclaimer}\n---\nSi vous acceptez de lancer la migration, veuillez relancer la commande avec l’option --accept-disclaimer.", "service_description_yunomdns": "Vous permet d’atteindre votre serveur en utilisant « yunohost.local » sur votre réseau local", "service_description_dnsmasq": "Gère la résolution des noms de domaine (DNS)", - "service_description_dovecot": "Permet aux clients de messagerie d’accéder/récupérer les courriels (via IMAP et POP3)", + "service_description_dovecot": "Permet aux clients de messagerie d’accéder/récupérer les emails (via IMAP et POP3)", "service_description_fail2ban": "Protège contre les attaques brute-force et autres types d’attaques venant d’Internet", "service_description_metronome": "Gère les comptes de messagerie instantanée XMPP", "service_description_mysql": "Stocke les données des applications (bases de données SQL)", "service_description_nginx": "Sert ou permet l’accès à tous les sites web hébergés sur votre serveur", - "service_description_postfix": "Utilisé pour envoyer et recevoir des courriels", + "service_description_postfix": "Utilisé pour envoyer et recevoir des emails", "service_description_redis-server": "Une base de données spécialisée utilisée pour l’accès rapide aux données, les files d’attentes et la communication entre les programmes", - "service_description_rspamd": "Filtre le pourriel, et d’autres fonctionnalités liées au courriel", + "service_description_rspamd": "Filtre le pourriel, et d’autres fonctionnalités liées aux emails", "service_description_slapd": "Stocke les utilisateurs, domaines et leurs informations liées", "service_description_ssh": "Vous permet de vous connecter à distance à votre serveur via un terminal (protocole SSH)", "service_description_yunohost-api": "Permet les interactions entre l’interface web de YunoHost et le système", @@ -282,7 +282,7 @@ "log_tools_upgrade": "Mettre à jour les paquets du système", "log_tools_shutdown": "Éteindre votre serveur", "log_tools_reboot": "Redémarrer votre serveur", - "mail_unavailable": "Cette adresse de courriel est réservée et doit être automatiquement attribuée au tout premier utilisateur", + "mail_unavailable": "Cette adresse d'email est réservée et doit être automatiquement attribuée au tout premier utilisateur", "good_practices_about_admin_password": "Vous êtes sur le point de définir un nouveau mot de passe d'administration. Le mot de passe doit comporter au moins 8 caractères, bien qu'il soit recommandé d'utiliser un mot de passe plus long (c'est-à-dire une phrase secrète) et/ou d'utiliser une combinaison de caractères (majuscules, minuscules, chiffres et caractères spéciaux).", "good_practices_about_user_password": "Vous êtes sur le point de définir un nouveau mot de passe utilisateur. Le mot de passe doit comporter au moins 8 caractères, bien qu'il soit recommandé d'utiliser un mot de passe plus long (c'est-à-dire une phrase secrète) et/ou une combinaison de caractères (majuscules, minuscules, chiffres et caractères spéciaux).", "password_listed": "Ce mot de passe fait partie des mots de passe les plus utilisés dans le monde. Veuillez en choisir un autre moins commun et plus robuste.", @@ -303,7 +303,7 @@ "backup_actually_backuping": "Création d’une archive de sauvegarde à partir des fichiers collectés...", "backup_mount_archive_for_restore": "Préparation de l’archive pour restauration...", "confirm_app_install_warning": "Avertissement : cette application peut fonctionner mais n’est pas bien intégrée dans YunoHost. Certaines fonctionnalités telles que l’authentification unique et la sauvegarde/restauration peuvent ne pas être disponibles. L’installer quand même ? [{answers}] ", - "confirm_app_install_danger": "DANGER ! Cette application est connue pour être encore expérimentale (si elle ne fonctionne pas explicitement) ! Vous ne devriez probablement PAS l’installer à moins de savoir ce que vous faites. AUCUN SUPPORT ne sera fourni si cette application ne fonctionne pas ou casse votre système … Si vous êtes prêt à prendre ce risque de toute façon, tapez '{answers}'", + "confirm_app_install_danger": "DANGER ! Cette application est connue pour être encore expérimentale (si elle ne fonctionne pas explicitement) ! Vous ne devriez probablement PAS l’installer à moins de savoir ce que vous faites. AUCUN SUPPORT ne sera fourni si cette application ne fonctionne pas ou casse votre système... Si vous êtes prêt à prendre ce risque de toute façon, tapez '{answers}'", "confirm_app_install_thirdparty": "DANGER ! Cette application ne fait pas partie du catalogue d'applications de YunoHost. L'installation d'applications tierces peut compromettre l'intégrité et la sécurité de votre système. Vous ne devriez probablement PAS l'installer à moins de savoir ce que vous faites. AUCUN SUPPORT ne sera fourni si cette application ne fonctionne pas ou casse votre système... Si vous êtes prêt à prendre ce risque de toute façon, tapez '{answers}'", "dpkg_is_broken": "Vous ne pouvez pas faire ça maintenant car dpkg/apt (le gestionnaire de paquets du système) semble avoir laissé des choses non configurées. Vous pouvez essayer de résoudre ce problème en vous connectant via SSH et en exécutant `sudo apt install --fix-broken` et/ou `sudo dpkg --configure -a'.", "dyndns_could_not_check_available": "Impossible de vérifier si {domain} est disponible chez {provider}.", @@ -342,7 +342,7 @@ "regenconf_would_be_updated": "La configuration aurait dû être mise à jour pour la catégorie '{category}'", "regenconf_dry_pending_applying": "Vérification de la configuration en attente qui aurait été appliquée pour la catégorie '{category}'…", "regenconf_failed": "Impossible de régénérer la configuration pour la ou les catégorie(s) : '{categories}'", - "regenconf_pending_applying": "Applique la configuration en attente pour la catégorie '{category}' ...", + "regenconf_pending_applying": "Applique la configuration en attente pour la catégorie '{category}'...", "service_regen_conf_is_deprecated": "'yunohost service regen-conf' est obsolète ! Veuillez plutôt utiliser 'yunohost tools regen-conf' à la place.", "tools_upgrade_at_least_one": "Veuillez spécifier '--apps' ou '--system'", "tools_upgrade_cant_both": "Impossible de mettre à niveau le système et les applications en même temps", @@ -381,7 +381,7 @@ "migrations_already_ran": "Ces migrations sont déjà effectuées : {ids}", "migrations_dependencies_not_satisfied": "Exécutez ces migrations : '{dependencies_id}', avant migration {id}.", "migrations_failed_to_load_migration": "Impossible de charger la migration {id} : {error}", - "migrations_running_forward": "Exécution de la migration {id} ...", + "migrations_running_forward": "Exécution de la migration {id}...", "migrations_success_forward": "Migration {id} terminée", "operation_interrupted": "L'opération a-t-elle été interrompue manuellement ?", "permission_already_exist": "L’autorisation '{permission}' existe déjà", @@ -473,7 +473,7 @@ "apps_catalog_updating": "Mise à jour du catalogue d’applications…", "apps_catalog_obsolete_cache": "Le cache du catalogue d'applications est vide ou obsolète.", "apps_catalog_update_success": "Le catalogue des applications a été mis à jour !", - "diagnosis_description_mail": "E-mail", + "diagnosis_description_mail": "Email", "diagnosis_ports_unreachable": "Le port {port} n’est pas accessible de l’extérieur.", "diagnosis_ports_ok": "Le port {port} est accessible de l’extérieur.", "diagnosis_http_could_not_diagnose": "Impossible de diagnostiquer si le domaine est accessible de l’extérieur.", @@ -509,16 +509,16 @@ "diagnosis_mail_ehlo_wrong": "Un autre serveur de messagerie SMTP répond sur IPv{ipversion}. Votre serveur ne sera probablement pas en mesure de recevoir des courriel.", "diagnosis_mail_ehlo_could_not_diagnose": "Impossible de diagnostiquer si le serveur de messagerie postfix est accessible de l’extérieur en IPv{ipversion}.", "diagnosis_mail_ehlo_could_not_diagnose_details": "Erreur : {error}", - "diagnosis_mail_fcrdns_dns_missing": "Aucun DNS inverse n’est défini pour IPv{ipversion}. Certains e-mails seront peut-être refusés ou considérés comme des spam.", + "diagnosis_mail_fcrdns_dns_missing": "Aucun DNS inverse n’est défini pour IPv{ipversion}. Certains emails seront peut-être refusés ou considérés comme des spam.", "diagnosis_mail_fcrdns_ok": "Votre DNS inverse est correctement configuré !", "diagnosis_mail_fcrdns_nok_details": "Vous devez d’abord essayer de configurer le DNS inverse avec {ehlo_domain} dans votre interface de routeur Internet ou votre interface d’hébergement. (Certains hébergeurs peuvent vous demander de leur envoyer un ticket de support pour cela).", - "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Le DNS inverse n'est pas correctement configuré en IPv{ipversion}. Certains e-mails seront peut-être refusés ou considérés comme des spam.", + "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Le DNS inverse n'est pas correctement configuré en IPv{ipversion}. Certains emails seront peut-être refusés ou considérés comme des spam.", "diagnosis_mail_blacklist_ok": "Les adresses IP et les domaines utilisés par ce serveur ne semblent pas être sur liste noire", "diagnosis_mail_blacklist_reason": "La raison de la liste noire est : {reason}", "diagnosis_mail_blacklist_website": "Après avoir identifié la raison pour laquelle vous êtes répertorié et l'avoir corrigé, n’hésitez pas à demander le retrait de votre IP ou domaine sur {blacklist_website}", - "diagnosis_mail_queue_ok": "{nb_pending} e-mails en attente dans les files d'attente de messagerie", + "diagnosis_mail_queue_ok": "{nb_pending} emails en attente dans les files d'attente de messagerie", "diagnosis_mail_queue_unavailable_details": "Erreur : {error}", - "diagnosis_mail_queue_too_big": "Trop d’e-mails en attente dans la file d'attente ({nb_pending} e-mails)", + "diagnosis_mail_queue_too_big": "Trop d’emails en attente dans la file d'attente ({nb_pending} e-mails)", "global_settings_setting_smtp_allow_ipv6": "Autoriser l'utilisation d’IPv6 pour recevoir et envoyer du courrier", "diagnosis_display_tip": "Pour voir les problèmes détectés, vous pouvez accéder à la section Diagnostic du webadmin ou exécuter « yunohost diagnosis show --issues --human-readable» à partir de la ligne de commande.", "diagnosis_ip_global": "IP globale : {global}", @@ -529,11 +529,11 @@ "diagnosis_mail_ehlo_unreachable": "Le serveur de messagerie SMTP est inaccessible de l’extérieur en IPv{ipversion}. Il ne pourra pas recevoir des courriels.", "diagnosis_mail_ehlo_unreachable_details": "Impossible d'ouvrir une connexion sur le port 25 à votre serveur en IPv{ipversion}. Il semble inaccessible.
1. La cause la plus courante de ce problème est que le port 25 n'est pas correctement redirigé vers votre serveur.
2. Vous devez également vous assurer que le service postfix est en cours d'exécution.
3. Sur les configurations plus complexes: assurez-vous qu'aucun pare-feu ou proxy inversé n'interfère.", "diagnosis_mail_ehlo_wrong_details": "Le EHLO reçu par le serveur de diagnostique distant en IPv{ipversion} est différent du domaine de votre serveur.
EHLO reçu: {wrong_ehlo}
Attendu : {right_ehlo}
La cause la plus courante ce problème est que le port 25 n’est pas correctement redirigé vers votre serveur . Vous pouvez également vous assurer qu’aucun pare-feu ou proxy inversé n’interfère.", - "diagnosis_mail_fcrdns_nok_alternatives_4": "Certains fournisseurs ne vous laisseront pas configurer votre DNS inversé (ou leur fonctionnalité pourrait être cassée …). Si vous rencontrez des problèmes à cause de cela, envisagez les solutions suivantes :
- Certains FAI fournissent l’alternative de à l’aide d’un relais de serveur de messagerie bien que cela implique que le relais pourra espionner votre trafic de messagerie.
- Une alternative respectueuse de la vie privée consiste à utiliser un VPN *avec une IP publique dédiée* pour contourner ce type de limites. Voir https://yunohost.org/#/vpn_advantage
- Enfin, il est également possible de changer de fournisseur", - "diagnosis_mail_fcrdns_nok_alternatives_6": "Certains fournisseurs ne vous laisseront pas configurer votre DNS inversé (ou leur fonctionnalité pourrait être cassée ...). Si votre DNS inversé est correctement configuré en IPv4, vous pouvez essayer de désactiver l'utilisation d'IPv6 lors de l'envoi d'e-mails en exécutant yunohost settings set smtp.allow_ipv6 -v off. Remarque: cette dernière solution signifie que vous ne pourrez pas envoyer ou recevoir de courriels avec les quelques serveurs qui ont uniquement de l'IPv6.", + "diagnosis_mail_fcrdns_nok_alternatives_4": "Certains fournisseurs ne vous laisseront pas configurer votre DNS inversé (ou leur fonctionnalité pourrait être cassée...). Si vous rencontrez des problèmes à cause de cela, envisagez les solutions suivantes :
- Certains FAI fournissent l’alternative de à l’aide d’un relais de serveur de messagerie bien que cela implique que le relais pourra espionner votre trafic de messagerie.
- Une alternative respectueuse de la vie privée consiste à utiliser un VPN *avec une IP publique dédiée* pour contourner ce type de limites. Voir https://yunohost.org/#/vpn_advantage
- Enfin, il est également possible de changer de fournisseur", + "diagnosis_mail_fcrdns_nok_alternatives_6": "Certains fournisseurs ne vous laisseront pas configurer votre DNS inversé (ou leur fonctionnalité pourrait être cassée...). Si votre DNS inversé est correctement configuré en IPv4, vous pouvez essayer de désactiver l'utilisation d'IPv6 lors de l'envoi d'emails en exécutant yunohost settings set smtp.allow_ipv6 -v off. Remarque : cette dernière solution signifie que vous ne pourrez pas envoyer ou recevoir de courriels avec les quelques serveurs qui ont uniquement de l'IPv6.", "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "DNS inverse actuel : {rdns_domain}
Valeur attendue : {ehlo_domain}", "diagnosis_mail_blacklist_listed_by": "Votre IP ou domaine {item} est sur liste noire sur {blacklist_name}", - "diagnosis_mail_queue_unavailable": "Impossible de consulter le nombre d’e-mails en attente dans la file d'attente", + "diagnosis_mail_queue_unavailable": "Impossible de consulter le nombre d’emails en attente dans la file d'attente", "diagnosis_ports_partially_unreachable": "Le port {port} n'est pas accessible de l'extérieur en IPv{failed}.", "diagnosis_http_hairpinning_issue": "Votre réseau local ne semble pas supporter l'hairpinning.", "diagnosis_http_hairpinning_issue_details": "C'est probablement à cause de la box/routeur de votre fournisseur d'accès internet. Par conséquent, les personnes extérieures à votre réseau local pourront accéder à votre serveur comme prévu, mais pas les personnes internes au réseau local (comme vous, probablement ?) si elles utilisent le nom de domaine ou l'IP globale. Vous pourrez peut-être améliorer la situation en consultant https://yunohost.org/dns_local_network", @@ -555,7 +555,7 @@ "restore_already_installed_apps": "Les applications suivantes ne peuvent pas être restaurées car elles sont déjà installées : {apps}", "regenconf_need_to_explicitly_specify_ssh": "La configuration de ssh a été modifiée manuellement. Vous devez explicitement indiquer la mention --force à \"ssh\" pour appliquer les changements.", "migration_0015_cleaning_up": "Nettoyage du cache et des paquets qui ne sont plus nécessaires ...", - "migration_0015_specific_upgrade": "Démarrage de la mise à jour des paquets du système qui doivent être mis à jour séparément ...", + "migration_0015_specific_upgrade": "Démarrage de la mise à jour des paquets du système qui doivent être mis à jour séparément...", "migration_0015_modified_files": "Veuillez noter que les fichiers suivants ont été modifiés manuellement et pourraient être écrasés à la suite de la mise à niveau : {manually_modified_files}", "migration_0015_problematic_apps_warning": "Veuillez noter que des applications qui peuvent poser problèmes ont été détectées. Il semble qu'elles n'aient pas été installées à partir du catalogue d'applications YunoHost, ou bien qu'elles ne soient pas signalées comme \"fonctionnelles\". Par conséquent, il n'est pas possible de garantir que les applications suivantes fonctionneront encore après la mise à niveau : {problematic_apps}", "migration_0015_general_warning": "Veuillez noter que cette migration est une opération délicate. L'équipe YunoHost a fait de son mieux pour la revérifier et la tester, mais la migration pourrait quand même casser des éléments du système ou de ses applications.\n\nIl est donc recommandé :\n…- de faire une sauvegarde de toute donnée ou application critique. Plus d'informations ici https://yunohost.org/backup ;\n…- d'être patient après le lancement de la migration. Selon votre connexion internet et votre matériel, la mise à niveau peut prendre jusqu'à quelques heures.", @@ -564,8 +564,8 @@ "migration_0015_not_stretch": "La distribution Debian actuelle n'est pas Stretch !", "migration_0015_yunohost_upgrade": "Démarrage de la mise à jour de YunoHost ...", "migration_0015_still_on_stretch_after_main_upgrade": "Quelque chose s'est mal passé lors de la mise à niveau, le système semble toujours être sous Debian Stretch", - "migration_0015_main_upgrade": "Démarrage de la mise à niveau générale ...", - "migration_0015_patching_sources_list": "Mise à jour du fichier sources.lists ...", + "migration_0015_main_upgrade": "Démarrage de la mise à niveau générale...", + "migration_0015_patching_sources_list": "Mise à jour du fichier sources.lists...", "migration_0015_start": "Démarrage de la migration vers Buster", "migration_description_0015_migrate_to_buster": "Mise à niveau du système vers Debian Buster et YunoHost 4.x", "diagnosis_dns_try_dyndns_update_force": "La configuration DNS de ce domaine devrait être automatiquement gérée par YunoHost. Si ce n'est pas le cas, vous pouvez essayer de forcer une mise à jour en utilisant yunohost dyndns update --force.", @@ -642,7 +642,7 @@ "ldap_server_is_down_restart_it": "Le service LDAP est en panne, essayez de le redémarrer...", "ldap_server_down": "Impossible d'atteindre le serveur LDAP", "global_settings_setting_security_experimental_enabled": "Activer les fonctionnalités de sécurité expérimentales (ne l'activez pas si vous ne savez pas ce que vous faites !)", - "diagnosis_apps_deprecated_practices": "La version installée de cette application utilise toujours certaines pratiques de packaging obsolètes. Vous devriez vraiment envisager de mettre l'application à jour..", + "diagnosis_apps_deprecated_practices": "La version installée de cette application utilise toujours certaines pratiques de packaging obsolètes. Vous devriez vraiment envisager de mettre l'application à jour.", "diagnosis_apps_outdated_ynh_requirement": "La version installée de cette application nécessite uniquement YunoHost> = 2.x, cela indique que l'application n'est pas à jour avec les bonnes pratiques de packaging et les helpers recommandées. Vous devriez vraiment envisager de mettre l'application à jour.", "diagnosis_apps_bad_quality": "Cette application est actuellement signalée comme cassée dans le catalogue d'applications de YunoHost. Cela peut être un problème temporaire. En attendant que les mainteneurs tentent de résoudre le problème, la mise à jour de cette application est désactivée.", "diagnosis_apps_broken": "Cette application est actuellement signalée comme cassée dans le catalogue d'applications de YunoHost. Cela peut être un problème temporaire. En attendant que les mainteneurs tentent de résoudre le problème, la mise à jour de cette application est désactivée.", From a0c20dd4e54222afcfb6bf46229385cc809f200a Mon Sep 17 00:00:00 2001 From: Parviz Homayun Date: Wed, 1 Sep 2021 18:18:24 +0000 Subject: [PATCH 068/101] Translated using Weblate (Persian) Currently translated at 100.0% (643 of 643 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fa/ --- locales/fa.json | 144 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 5 deletions(-) diff --git a/locales/fa.json b/locales/fa.json index 9e33d02d7..a644716cf 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -280,7 +280,7 @@ "domain_cannot_remove_main_add_new_one": "شما نمی توانید '{domain}' را حذف کنید زیرا دامنه اصلی و تنها دامنه شما است، ابتدا باید دامنه دیگری را با 'yunohost domain add ' اضافه کنید، سپس با استفاده از 'yunohost domain main-domain -n ' به عنوان دامنه اصلی تنظیم شده. و بعد از آن می توانید'{domain}' را حذف کنید با استفاده از'yunohost domain remove {domain}'.'", "domain_cannot_add_xmpp_upload": "شما نمی توانید دامنه هایی را که با \"xmpp-upload\" شروع می شوند اضافه کنید. این نوع نام مختص ویژگی بارگذاری XMPP است که در YunoHost یکپارچه شده است.", "domain_cannot_remove_main": "شما نمی توانید '{domain}' را حذف کنید زیرا دامنه اصلی است ، ابتدا باید با استفاده از 'yunohost domain main-domain -n ' دامنه دیگری را به عنوان دامنه اصلی تعیین کنید. در اینجا لیست دامنه های کاندید وجود دارد: {other_domains}", - "installation_complete": "نصب تکمیل شد", + "installation_complete": "عملیّات نصب کامل شد", "hook_name_unknown": "نام قلاب ناشناخته '{name}'", "hook_list_by_invalid": "از این ویژگی نمی توان برای فهرست قلاب ها استفاده کرد", "hook_json_return_error": "بازگشت از قلاب {path} خوانده نشد. خطا: {msg}. محتوای خام: {raw_content}", @@ -302,8 +302,8 @@ "group_already_exist_on_system_but_removing_it": "گروه {group} از قبل در گروه های سیستم وجود دارد ، اما YunoHost آن را حذف می کند...", "group_already_exist_on_system": "گروه {group} از قبل در گروه های سیستم وجود دارد", "group_already_exist": "گروه {group} از قبل وجود دارد", - "good_practices_about_user_password": "گذرواژه باید حداقل 8 کاراکتر باشد - اگرچه استفاده از گذرواژه طولانی تر (به عنوان مثال عبارت عبور) و/یا استفاده از تنوع کاراکترها (بزرگ ، کوچک ، رقم و کاراکتر های خاص) تمرین خوبی است.", - "good_practices_about_admin_password": "اکنون می خواهید گذرواژه جدیدی برای مدیریت تعریف کنید. گذرواژه باید حداقل 8 کاراکتر باشد - اگرچه استفاده از گذرواژه طولانی تر (به عنوان مثال عبارت عبور) و/یا استفاده از تنوع کاراکترها (بزرگ ، کوچک ، رقم و کاراکتر های خاص) تمرین خوبی است.", + "good_practices_about_user_password": "گذرواژه باید حداقل 8 کاراکتر باشد - اگرچه استفاده از گذرواژه طولانی تر تمرین خوبی است (به عنوان مثال عبارت عبور) و/یا استفاده از تنوع کاراکترها (بزرگ ، کوچک ، رقم و کاراکتر های خاص).", + "good_practices_about_admin_password": "اکنون می خواهید گذرواژه جدیدی برای مدیریت تعریف کنید. گذرواژه باید حداقل 8 کاراکتر باشد - اگرچه استفاده از گذرواژه طولانی تر تمرین خوبی است (به عنوان مثال عبارت عبور) و/یا استفاده از تنوع کاراکترها (بزرگ ، کوچک ، رقم و کاراکتر های خاص).", "global_settings_unknown_type": "وضعیت غیرمنتظره ، به نظر می رسد که تنظیمات {setting} دارای نوع {unknown_type} است اما از نوع پشتیبانی شده توسط سیستم نیست.", "global_settings_setting_backup_compress_tar_archives": "هنگام ایجاد پشتیبان جدید ، بایگانی های فشرده (.tar.gz) را به جای بایگانی های فشرده نشده (.tar) انتخاب کنید. N.B. : فعال کردن این گزینه به معنای ایجاد آرشیوهای پشتیبان سبک تر است ، اما روش پشتیبان گیری اولیه به طور قابل توجهی طولانی تر و سنگین تر بر روی CPU خواهد بود.", "global_settings_setting_security_experimental_enabled": "فعال کردن ویژگی های امنیتی آزمایشی (اگر نمی دانید در حال انجام چه کاری هستید این کار را انجام ندهید!)", @@ -363,7 +363,7 @@ "domain_exists": "دامنه از قبل وجود دارد", "domain_dyndns_root_unknown": "دامنه ریشه DynDNS ناشناخته", "domain_dyndns_already_subscribed": "شما قبلاً در یک دامنه DynDNS مشترک شده اید", - "domain_dns_conf_is_just_a_recommendation": "این دستور پیکربندی * توصیه شده * را به شما نشان می دهد. در واقع پیکربندی DNS را برای شما تنظیم نمی کند. این وظیفه شماست که مطابق این توصیه ، منطقه DNS خود را در ثبت کننده خود پیکربندی کنید.", + "domain_dns_conf_is_just_a_recommendation": "این دستور پیکربندی * توصیه شده * را به شما نشان می دهد. این وظیفه شماست که مطابق این توصیه ، منطقه DNS خود را در ثبت کننده خود پیکربندی کنید. در واقع پیکربندی DNS را برای شما تنظیم نمی کند.", "domain_deletion_failed": "حذف دامنه {domain} امکان پذیر نیست: {error}", "domain_deleted": "دامنه حذف شد", "domain_creation_failed": "ایجاد دامنه {domain} امکان پذیر نیست: {error}", @@ -507,5 +507,139 @@ "ldap_server_down": "دسترسی به سرور LDAP امکان پذیر نیست", "iptables_unavailable": "در اینجا نمی توانید با iptables بازی کنید. شما یا در ظرفی هستید یا هسته شما آن را پشتیبانی نمی کند", "ip6tables_unavailable": "در اینجا نمی توانید با جدول های ipv6 کار کنید. شما یا در کانتینتر هستید یا هسته شما آن را پشتیبانی نمی کند", - "invalid_regex": "عبارت منظم نامعتبر: '{regex}'" + "invalid_regex": "عبارت منظم نامعتبر: '{regex}'", + "yunohost_postinstall_end_tip": "پس از نصب کامل شد! برای نهایی کردن تنظیمات خود ، لطفاً موارد زیر را در نظر بگیرید:\n - افزودن اولین کاربر از طریق بخش \"کاربران\" webadmin (یا 'yunohost user create ' در خط فرمان) ؛\n - تشخیص مشکلات احتمالی از طریق بخش \"عیب یابی\" webadmin (یا 'yunohost diagnosis run' در خط فرمان) ؛\n - خواندن قسمت های \"نهایی کردن راه اندازی خود\" و \"آشنایی با YunoHost\" در اسناد مدیریت: https://yunohost.org/admindoc.", + "yunohost_not_installed": "YunoHost به درستی نصب نشده است. لطفا 'yunohost tools postinstall' را اجرا کنید", + "yunohost_installing": "در حال نصب YunoHost...", + "yunohost_configured": "YunoHost اکنون پیکربندی شده است", + "yunohost_already_installed": "YunoHost قبلاً نصب شده است", + "user_updated": "اطلاعات کاربر تغییر کرد", + "user_update_failed": "کاربر {user} به روز نشد: {error}", + "user_unknown": "کاربر ناشناس: {user}", + "user_home_creation_failed": "پوشه 'home' برای کاربر ایجاد نشد", + "user_deletion_failed": "کاربر {user} حذف نشد: {error}", + "user_deleted": "کاربر حذف شد", + "user_creation_failed": "کاربر {user} ایجاد نشد: {error}", + "user_created": "کاربر ایجاد شد", + "user_already_exists": "کاربر '{user}' در حال حاضر وجود دارد", + "upnp_port_open_failed": "پورت از طریق UPnP باز نشد", + "upnp_enabled": "UPnP روشن شد", + "upnp_disabled": "UPnP خاموش شد", + "upnp_dev_not_found": "هیچ دستگاه UPnP یافت نشد", + "upgrading_packages": "در حال ارتقاء بسته ها...", + "upgrade_complete": "ارتقا کامل شد", + "updating_apt_cache": "در حال واکشی و دریافت ارتقاء موجود برای بسته های سیستم...", + "update_apt_cache_warning": "هنگام به روز رسانی حافظه پنهان APT (مدیر بسته دبیان) مشکلی پیش آمده. در اینجا مجموعه ای از خطوط source.list موجود میباشد که ممکن است به شناسایی خطوط مشکل ساز کمک کند:\n{sourceslist}", + "update_apt_cache_failed": "امکان بروزرسانی حافظه پنهان APT (مدیر بسته دبیان) وجود ندارد. در اینجا مجموعه ای از خطوط source.list هست که ممکن است به شناسایی خطوط مشکل ساز کمک کند:\n{sourceslist}", + "unrestore_app": "{app} بازیابی نمی شود", + "unlimit": "بدون سهمیه", + "unknown_main_domain_path": "دامنه یا مسیر ناشناخته برای '{app}'. شما باید یک دامنه و یک مسیر را مشخص کنید تا بتوانید یک آدرس اینترنتی برای مجوز تعیین کنید.", + "unexpected_error": "مشکل غیر منتظره ای پیش آمده: {error}", + "unbackup_app": "{app} ذخیره نمی شود", + "tools_upgrade_special_packages_completed": "ارتقاء بسته YunoHost به پایان رسید\nبرای بازگرداندن خط فرمان [Enter] را فشار دهید", + "tools_upgrade_special_packages_explanation": "ارتقاء ویژه در پس زمینه ادامه خواهد یافت. لطفاً تا 10 دقیقه دیگر (بسته به سرعت سخت افزار) هیچ اقدام دیگری را روی سرور خود شروع نکنید. پس از این کار ، ممکن است مجبور شوید دوباره وارد webadmin شوید. گزارش ارتقاء در Tools → Log (در webadmin) یا با استفاده از 'yunohost log list' (در خط فرمان) در دسترس خواهد بود.", + "tools_upgrade_special_packages": "در حال ارتقاء بسته های 'special' (مربوط به yunohost)…", + "tools_upgrade_regular_packages_failed": "بسته ها را نمی توان ارتقا داد: {packages_list}", + "tools_upgrade_regular_packages": "در حال ارتقاء بسته های 'regular' (غیر مرتبط با yunohost)…", + "tools_upgrade_cant_unhold_critical_packages": "بسته های مهم و حیاتی را نمی توان نگه نداشت…", + "tools_upgrade_cant_hold_critical_packages": "بسته های مهم و حیاتی را نمی توان نگه داشت…", + "tools_upgrade_cant_both": "نمی توان سیستم و برنامه ها را به طور همزمان ارتقا داد", + "tools_upgrade_at_least_one": "لطفاً مشخص کنید 'apps' ، یا 'system'", + "this_action_broke_dpkg": "این اقدام dpkg/APT (مدیران بسته های سیستم) را خراب کرد... می توانید با اتصال از طریق SSH و اجرای فرمان `sudo apt install --fix -break` و/یا` sudo dpkg --configure -a` این مشکل را حل کنید.", + "system_username_exists": "نام کاربری قبلاً در لیست کاربران سیستم وجود دارد", + "system_upgraded": "سیستم ارتقا یافت", + "ssowat_conf_updated": "پیکربندی SSOwat به روزرسانی شد", + "ssowat_conf_generated": "پیکربندی SSOwat بازسازی شد", + "show_tile_cant_be_enabled_for_regex": "شما نمی توانید \"show_tile\" را درست فعال کنید ، چرا که آدرس اینترنتی مجوز '{permission}' یک عبارت منظم است", + "show_tile_cant_be_enabled_for_url_not_defined": "شما نمی توانید \"show_tile\" را در حال حاضر فعال کنید ، زیرا ابتدا باید یک آدرس اینترنتی برای مجوز '{permission}' تعریف کنید", + "service_unknown": "سرویس ناشناخته '{service}'", + "service_stopped": "سرویس '{service}' متوقف شد", + "service_stop_failed": "سرویس '{service}' متوقف نمی شود\n\nگزارشات اخیر سرویس: {logs}", + "service_started": "سرویس '{service}' شروع شد", + "service_start_failed": "سرویس '{service}' شروع نشد\n\nگزارشات اخیر سرویس: {logs}", + "service_reloaded_or_restarted": "سرویس '{service}' بارگیری یا راه اندازی مجدد شد", + "service_reload_or_restart_failed": "سرویس \"{service}\" بارگیری یا راه اندازی مجدد نشد\n\nگزارشات اخیر سرویس: {logs}", + "service_restarted": "سرویس '{service}' راه اندازی مجدد شد", + "service_restart_failed": "سرویس \"{service}\" راه اندازی مجدد نشد\n\nگزارشات اخیر سرویس: {logs}", + "service_reloaded": "سرویس '{service}' بارگیری مجدد شد", + "service_reload_failed": "سرویس '{service}' بارگیری نشد\n\nگزارشات اخیر سرویس: {logs}", + "service_removed": "سرویس '{service}' حذف شد", + "service_remove_failed": "سرویس '{service}' حذف نشد", + "service_regen_conf_is_deprecated": "فرمان 'yunohost service regen-conf' منسوخ شده است! لطفاً به جای آن از 'yunohost tools regen-conf' استفاده کنید.", + "service_enabled": "سرویس '{service}' اکنون بطور خودکار در هنگام بوت شدن سیستم راه اندازی می شود.", + "service_enable_failed": "انجام سرویس '{service}' به طور خودکار در هنگام راه اندازی امکان پذیر نیست.\n\nگزارشات اخیر سرویس: {logs}", + "service_disabled": "هنگام راه اندازی سیستم ، سرویس '{service}' دیگر راه اندازی نمی شود.", + "service_disable_failed": "نتوانست باعث شود سرویس '{service}' در هنگام راه اندازی شروع نشود.\n\nگزارشات سرویس اخیر: {logs}", + "service_description_yunohost-firewall": "باز و بسته شدن پورت های اتصال به سرویس ها را مدیریت می کند", + "service_description_yunohost-api": "تعاملات بین رابط وب YunoHost و سیستم را مدیریت می کند", + "service_description_ssh": "به شما امکان می دهد از راه دور از طریق ترمینال (پروتکل SSH) به سرور خود متصل شوید", + "service_description_slapd": "کاربران ، دامنه ها و اطلاعات مرتبط را ذخیره می کند", + "service_description_rspamd": "هرزنامه ها و سایر ویژگی های مربوط به ایمیل را فیلتر می کند", + "service_description_redis-server": "یک پایگاه داده تخصصی برای دسترسی سریع به داده ها ، صف وظیفه و ارتباط بین برنامه ها استفاده می شود", + "service_description_postfix": "برای ارسال و دریافت ایمیل استفاده می شود", + "service_description_php7.3-fpm": "برنامه های نوشته شده با PHP را با NGINX اجرا می کند", + "service_description_nginx": "به همه وب سایت هایی که روی سرور شما میزبانی شده اند سرویس می دهد یا دسترسی به آنها را فراهم می کند", + "service_description_mysql": "ذخیره داده های برنامه (پایگاه داده SQL)", + "service_description_metronome": "مدیریت حساب های پیام رسانی فوری XMPP", + "service_description_fail2ban": "در برابر حملات وحشیانه و انواع دیگر حملات از طریق اینترنت محافظت می کند", + "service_description_dovecot": "به کلاینت های ایمیل اجازه می دهد تا به ایمیل دسترسی/واکشی داشته باشند (از طریق IMAP و POP3)", + "service_description_dnsmasq": "کنترل تفکیک پذیری نام دامنه (DNS)", + "service_description_yunomdns": "به شما امکان می دهد با استفاده از 'yunohost.local' در شبکه محلی به سرور خود برسید", + "service_cmd_exec_failed": "نمی توان دستور '{command}' را اجرا کرد", + "service_already_stopped": "سرویس '{service}' قبلاً متوقف شده است", + "service_already_started": "سرویس '{service}' در حال اجرا است", + "service_added": "سرویس '{service}' اضافه شد", + "service_add_failed": "سرویس '{service}' اضافه نشد", + "server_reboot_confirm": "سرور بلافاصله راه اندازی مجدد می شود، آیا مطمئن هستید؟ [{answers}]", + "server_reboot": "سرور راه اندازی مجدد می شود", + "server_shutdown_confirm": "آیا مطمئن هستید که سرور بلافاصله خاموش می شود؟ [{answers}]", + "server_shutdown": "سرور خاموش می شود", + "root_password_replaced_by_admin_password": "گذرواژه ریشه شما با رمز مدیریت جایگزین شده است.", + "root_password_desynchronized": "گذرواژه مدیریت تغییر کرد ، اما YunoHost نتوانست این را به رمز عبور ریشه منتقل کند!", + "restore_system_part_failed": "بخش سیستم '{part}' بازیابی و ترمیم نشد", + "restore_running_hooks": "در حال اجرای قلاب های ترمیم و بازیابی…", + "restore_running_app_script": "ترمیم و بازیابی برنامه '{app}'…", + "restore_removing_tmp_dir_failed": "پوشه موقت قدیمی حذف نشد", + "restore_nothings_done": "هیچ چیز ترمیم و بازسازی نشد", + "restore_not_enough_disk_space": "فضای کافی موجود نیست (فضا: {free_space:d} B ، فضای مورد نیاز: {needed_space:d} B ، حاشیه امنیتی: {margin:d} B)", + "restore_may_be_not_enough_disk_space": "به نظر می رسد سیستم شما فضای کافی ندارد (فضای آزاد: {free_space:d} B ، فضای مورد نیاز: {space_space:d} B ، حاشیه امنیتی: {margin:d} B)", + "restore_hook_unavailable": "اسکریپت ترمیم و بازسازی برای '{part}' در سیستم شما در دسترس نیست و همچنین در بایگانی نیز وجود ندارد", + "restore_failed": "سیستم بازیابی نشد", + "restore_extracting": "استخراج فایل های مورد نیاز از بایگانی…", + "restore_confirm_yunohost_installed": "آیا واقعاً می خواهید سیستمی که هم اکنون نصب شده را بازیابی کنید؟ [{answers}]", + "restore_complete": "مرمت به پایان رسید", + "restore_cleaning_failed": "فهرست بازسازی موقت پاک نشد", + "restore_backup_too_old": "این بایگانی پشتیبان را نمی توان بازیابی کرد زیرا با نسخه خیلی قدیمی YunoHost تهیه شده است.", + "restore_already_installed_apps": "برنامه های زیر به دلیل نصب بودن قابل بازیابی نیستند: {apps}", + "restore_already_installed_app": "برنامه ای با شناسه '{app}' در حال حاضر نصب شده است", + "regex_with_only_domain": "شما نمی توانید از عبارات منظم برای دامنه استفاده کنید، فقط برای مسیر قابل استفاده است", + "regex_incompatible_with_tile": "/!\\ بسته بندی کنندگان! مجوز '{permission}' show_tile را روی 'true' تنظیم کرده اند و بنابراین نمی توانید عبارت منظم آدرس اینترنتی را به عنوان URL اصلی تعریف کنید", + "regenconf_need_to_explicitly_specify_ssh": "پیکربندی ssh به صورت دستی تغییر یافته است ، اما شما باید صراحتاً دسته \"ssh\" را با --force برای اعمال تغییرات در واقع مشخص کنید.", + "regenconf_pending_applying": "در حال اعمال پیکربندی معلق برای دسته '{category}'...", + "regenconf_failed": "پیکربندی برای دسته (ها) بازسازی نشد: {categories}", + "regenconf_dry_pending_applying": "در حال بررسی پیکربندی معلق که برای دسته '{category}' اعمال می شد…", + "regenconf_would_be_updated": "پیکربندی برای دسته '{category}' به روز می شد", + "regenconf_updated": "پیکربندی برای دسته '{category}' به روز شد", + "regenconf_up_to_date": "پیکربندی در حال حاضر برای دسته '{category}' به روز است", + "regenconf_now_managed_by_yunohost": "فایل پیکربندی '{conf}' اکنون توسط YunoHost (دسته {category}) مدیریت می شود.", + "regenconf_file_updated": "فایل پیکربندی '{conf}' به روز شد", + "regenconf_file_removed": "فایل پیکربندی '{conf}' حذف شد", + "regenconf_file_remove_failed": "فایل پیکربندی '{conf}' حذف نشد", + "regenconf_file_manually_removed": "فایل پیکربندی '{conf}' به صورت دستی حذف شد، و ایجاد نخواهد شد", + "regenconf_file_manually_modified": "فایل پیکربندی '{conf}' به صورت دستی اصلاح شده است و به روز نمی شود", + "regenconf_file_kept_back": "انتظار میرفت که فایل پیکربندی '{conf}' توسط regen-conf (دسته {category}) حذف شود ، اما پس گرفته شد.", + "regenconf_file_copy_failed": "فایل پیکربندی جدید '{new}' در '{conf}' کپی نشد", + "regenconf_file_backed_up": "فایل پیکربندی '{conf}' در '{backup}' پشتیبان گیری شد", + "postinstall_low_rootfsspace": "فضای فایل سیستم اصلی کمتر از 10 گیگابایت است که بسیار نگران کننده است! به احتمال زیاد خیلی زود فضای دیسک شما تمام می شود! توصیه می شود حداقل 16 گیگابایت برای سیستم فایل ریشه داشته باشید. اگر می خواهید YunoHost را با وجود این هشدار نصب کنید ، فرمان نصب را مجدد با این آپشن --force-diskspace اجرا کنید", + "port_already_opened": "پورت {port:d} قبلاً برای اتصالات {ip_version} باز شده است", + "port_already_closed": "پورت {port:d} قبلاً برای اتصالات {ip_version} بسته شده است", + "permission_require_account": "مجوز {permission} فقط برای کاربران دارای حساب کاربری منطقی است و بنابراین نمی تواند برای بازدیدکنندگان فعال شود.", + "permission_protected": "مجوز {permission} محافظت می شود. شما نمی توانید گروه بازدیدکنندگان را از/به این مجوز اضافه یا حذف کنید.", + "permission_updated": "مجوز '{permission}' به روز شد", + "permission_update_failed": "مجوز '{permission}' به روز نشد: {error}", + "permission_not_found": "مجوز '{permission}' پیدا نشد", + "permission_deletion_failed": "اجازه '{permission}' حذف نشد: {error}", + "permission_deleted": "مجوز '{permission}' حذف شد", + "permission_cant_add_to_all_users": "مجوز {permission} را نمی توان به همه کاربران اضافه کرد.", + "permission_currently_allowed_for_all_users": "این مجوز در حال حاضر به همه کاربران علاوه بر آن گروه های دیگر نیز اعطا شده. احتمالاً بخواهید مجوز 'all_users' را حذف کنید یا سایر گروه هایی را که در حال حاضر مجوز به آنها اعطا شده است را هم حذف کنید." } From f96f7dd1fdd70d438e5651b191653803543022ee Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 2 Sep 2021 03:53:52 +0200 Subject: [PATCH 069/101] Fuck orthotypography, let's enforce practices for fr i18n --- .gitlab/ci/translation.gitlab-ci.yml | 5 +- locales/fr.json | 478 +++++++++++++-------------- tests/reformat_fr_translations.py | 27 ++ 3 files changed, 269 insertions(+), 241 deletions(-) create mode 100644 tests/reformat_fr_translations.py diff --git a/.gitlab/ci/translation.gitlab-ci.yml b/.gitlab/ci/translation.gitlab-ci.yml index d7962436c..c8fbb9147 100644 --- a/.gitlab/ci/translation.gitlab-ci.yml +++ b/.gitlab/ci/translation.gitlab-ci.yml @@ -16,10 +16,11 @@ remove-stale-translated-strings: # create a local branch that will overwrite distant one - git checkout -b "ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}" --no-track - python3 remove_stale_translated_strings.py + - python3 reformat_fr_translations.py - '[ $(git diff -w | wc -l) != 0 ] || exit 0' # stop if there is nothing to commit - - git commit -am "[CI] Remove stale translated strings" || true + - git commit -am "[CI] Reformat / remove stale translated strings" || true - git push -f origin "ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}":"ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}" - - hub pull-request -m "[CI] Remove stale translated strings" -b Yunohost:dev -p || true # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd + - hub pull-request -m "[CI] Reformat / remove stale translated strings" -b Yunohost:dev -p || true # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd only: variables: - $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH diff --git a/locales/fr.json b/locales/fr.json index e3a32d639..53c486f26 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -1,46 +1,46 @@ { "action_invalid": "Action '{action}' incorrecte", - "admin_password": "Mot de passe d’administration", + "admin_password": "Mot de passe d'administration", "admin_password_change_failed": "Impossible de changer le mot de passe", - "admin_password_changed": "Le mot de passe d’administration a été modifié", + "admin_password_changed": "Le mot de passe d'administration a été modifié", "app_already_installed": "{app} est déjà installé", - "app_argument_choice_invalid": "Choix invalide pour le paramètre '{name}', il doit être l’un de {choices}", + "app_argument_choice_invalid": "Choix invalide pour le paramètre '{name}', il doit être l'un de {choices}", "app_argument_invalid": "Valeur invalide pour le paramètre '{name}' : {error}", "app_argument_required": "Le paramètre '{name}' est requis", - "app_extraction_failed": "Impossible d’extraire les fichiers d’installation", - "app_id_invalid": "Identifiant d’application invalide", - "app_install_files_invalid": "Fichiers d’installation incorrects", - "app_manifest_invalid": "Manifeste d’application incorrect : {error}", + "app_extraction_failed": "Impossible d'extraire les fichiers d'installation", + "app_id_invalid": "Identifiant d'application invalide", + "app_install_files_invalid": "Fichiers d'installation incorrects", + "app_manifest_invalid": "Manifeste d'application incorrect : {error}", "app_not_correctly_installed": "{app} semble être mal installé", - "app_not_installed": "Nous n’avons pas trouvé {app} dans la liste des applications installées : {all_apps}", - "app_not_properly_removed": "{app} n’a pas été supprimé correctement", + "app_not_installed": "Nous n'avons pas trouvé {app} dans la liste des applications installées : {all_apps}", + "app_not_properly_removed": "{app} n'a pas été supprimé correctement", "app_removed": "{app} désinstallé", "app_requirements_checking": "Vérification des paquets requis pour {app}...", "app_requirements_unmeet": "Les pré-requis de {app} ne sont pas satisfaits, le paquet {pkgname} ({version}) doit être {spec}", - "app_sources_fetch_failed": "Impossible de récupérer les fichiers sources, l’URL est-elle correcte ?", + "app_sources_fetch_failed": "Impossible de récupérer les fichiers sources, l'URL est-elle correcte ?", "app_unknown": "Application inconnue", - "app_unsupported_remote_type": "Ce type de commande à distance utilisé pour cette application n’est pas supporté", + "app_unsupported_remote_type": "Ce type de commande à distance utilisé pour cette application n'est pas supporté", "app_upgrade_failed": "Impossible de mettre à jour {app} : {error}", "app_upgraded": "{app} mis à jour", "ask_firstname": "Prénom", "ask_lastname": "Nom", "ask_main_domain": "Domaine principal", - "ask_new_admin_password": "Nouveau mot de passe d’administration", + "ask_new_admin_password": "Nouveau mot de passe d'administration", "ask_password": "Mot de passe", "backup_app_failed": "Impossible de sauvegarder {app}", - "backup_archive_app_not_found": "{app} n’a pas été trouvée dans l’archive de la sauvegarde", + "backup_archive_app_not_found": "{app} n'a pas été trouvée dans l'archive de la sauvegarde", "backup_archive_name_exists": "Une archive de sauvegarde avec ce nom existe déjà.", - "backup_archive_name_unknown": "L’archive locale de sauvegarde nommée '{name}' est inconnue", - "backup_archive_open_failed": "Impossible d’ouvrir l’archive de la sauvegarde", + "backup_archive_name_unknown": "L'archive locale de sauvegarde nommée '{name}' est inconnue", + "backup_archive_open_failed": "Impossible d'ouvrir l'archive de la sauvegarde", "backup_cleaning_failed": "Impossible de nettoyer le dossier temporaire de sauvegarde", "backup_created": "Sauvegarde terminée", - "backup_creation_failed": "Impossible de créer l’archive de la sauvegarde", + "backup_creation_failed": "Impossible de créer l'archive de la sauvegarde", "backup_delete_error": "Impossible de supprimer '{path}'", "backup_deleted": "La sauvegarde a été supprimée", "backup_hook_unknown": "Script de sauvegarde '{hook}' inconnu", - "backup_nothings_done": "Il n’y a rien à sauvegarder", + "backup_nothings_done": "Il n'y a rien à sauvegarder", "backup_output_directory_forbidden": "Choisissez un répertoire de destination différent. Les sauvegardes ne peuvent pas être créées dans les sous-dossiers /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ou /home/yunohost.backup/archives", - "backup_output_directory_not_empty": "Le répertoire de destination n’est pas vide", + "backup_output_directory_not_empty": "Le répertoire de destination n'est pas vide", "backup_output_directory_required": "Vous devez spécifier un dossier de destination pour la sauvegarde", "backup_running_hooks": "Exécution des scripts de sauvegarde...", "custom_app_url_required": "Vous devez spécifier une URL pour mettre à jour votre application personnalisée {app}", @@ -57,33 +57,33 @@ "domain_uninstall_app_first": "Ces applications sont toujours installées sur votre domaine :\n{apps}\n\nVeuillez les désinstaller avec la commande 'yunohost app remove nom-de-l-application' ou les déplacer vers un autre domaine avec la commande 'yunohost app change-url nom-de-l-application' avant de procéder à la suppression du domaine", "domain_unknown": "Domaine inconnu", "done": "Terminé", - "downloading": "Téléchargement en cours…", - "dyndns_ip_update_failed": "Impossible de mettre à jour l’adresse IP sur le domaine DynDNS", + "downloading": "Téléchargement en cours...", + "dyndns_ip_update_failed": "Impossible de mettre à jour l'adresse IP sur le domaine DynDNS", "dyndns_ip_updated": "Mise à jour de votre IP pour le domaine DynDNS", "dyndns_key_generating": "Génération de la clé DNS..., cela peut prendre un certain temps.", "dyndns_key_not_found": "Clé DNS introuvable pour le domaine", "dyndns_no_domain_registered": "Aucun domaine n'a été enregistré avec DynDNS", "dyndns_registered": "Domaine DynDNS enregistré", - "dyndns_registration_failed": "Impossible d’enregistrer le domaine DynDNS : {error}", + "dyndns_registration_failed": "Impossible d'enregistrer le domaine DynDNS : {error}", "dyndns_unavailable": "Le domaine {domain} est indisponible.", "extracting": "Extraction en cours...", "field_invalid": "Champ incorrect : '{}'", "firewall_reload_failed": "Impossible de recharger le pare-feu", "firewall_reloaded": "Pare-feu rechargé", "firewall_rules_cmd_failed": "Certaines commandes de règles de pare-feu ont échoué. Plus d'informations dans le journal.", - "hook_exec_failed": "Échec de l’exécution du script : {path}", - "hook_exec_not_terminated": "L’exécution du script {path} ne s’est pas terminée correctement", + "hook_exec_failed": "Échec de l'exécution du script : {path}", + "hook_exec_not_terminated": "L'exécution du script {path} ne s'est pas terminée correctement", "hook_list_by_invalid": "Propriété invalide pour lister les actions par celle-ci", - "hook_name_unknown": "Nom de l’action '{name}' inconnu", + "hook_name_unknown": "Nom de l'action '{name}' inconnu", "installation_complete": "Installation terminée", "ip6tables_unavailable": "Vous ne pouvez pas jouer avec ip6tables ici. Vous êtes soit dans un conteneur, soit votre noyau ne le prend pas en charge", "iptables_unavailable": "Vous ne pouvez pas jouer avec iptables ici. Vous êtes soit dans un conteneur, soit votre noyau ne le prend pas en charge", - "mail_alias_remove_failed": "Impossible de supprimer l’alias de courriel '{mail}'", - "mail_domain_unknown": "Le domaine '{domain}' de cette adresse email n’est pas valide. Merci d’utiliser un domaine administré par ce serveur.", + "mail_alias_remove_failed": "Impossible de supprimer l'alias de email '{mail}'", + "mail_domain_unknown": "Le domaine '{domain}' de cette adresse email n'est pas valide. Merci d'utiliser un domaine administré par ce serveur.", "mail_forward_remove_failed": "Impossible de supprimer l'email de transfert '{mail}'", "main_domain_change_failed": "Impossible de modifier le domaine principal", "main_domain_changed": "Le domaine principal a été modifié", - "not_enough_disk_space": "L’espace disque est insuffisant sur '{path}'", + "not_enough_disk_space": "L'espace disque est insuffisant sur '{path}'", "packages_upgrade_failed": "Impossible de mettre à jour tous les paquets", "pattern_backup_archive_name": "Doit être un nom de fichier valide avec un maximum de 30 caractères, et composé de caractères alphanumériques et -_. uniquement", "pattern_domain": "Doit être un nom de domaine valide (ex : mon-domaine.fr)", @@ -91,42 +91,42 @@ "pattern_firstname": "Doit être un prénom valide", "pattern_lastname": "Doit être un nom valide", "pattern_mailbox_quota": "Doit avoir une taille suffixée avec b/k/M/G/T ou 0 pour désactiver le quota", - "pattern_password": "Doit être composé d’au moins 3 caractères", + "pattern_password": "Doit être composé d'au moins 3 caractères", "pattern_port_or_range": "Doit être un numéro de port valide compris entre 0 et 65535, ou une gamme de ports (exemple : 100:200)", "pattern_positive_number": "Doit être un nombre positif", "pattern_username": "Doit être composé uniquement de caractères alphanumériques minuscules et de tirets bas (aussi appelé tiret du 8 ou underscore)", "port_already_closed": "Le port {port:d} est déjà fermé pour les connexions {ip_version}", "port_already_opened": "Le port {port:d} est déjà ouvert pour les connexions {ip_version}", - "restore_already_installed_app": "Une application est déjà installée avec l’identifiant '{app}'", - "app_restore_failed": "Impossible de restaurer {app} : {error}", + "restore_already_installed_app": "Une application est déjà installée avec l'identifiant '{app}'", + "app_restore_failed": "Impossible de restaurer {app} : {error}", "restore_cleaning_failed": "Impossible de nettoyer le dossier temporaire de restauration", "restore_complete": "Restauration terminée", "restore_confirm_yunohost_installed": "Voulez-vous vraiment restaurer un système déjà installé ? [{answers}]", "restore_failed": "Impossible de restaurer le système", - "restore_hook_unavailable": "Le script de restauration '{part}' n’est pas disponible sur votre système, et ne l’est pas non plus dans l’archive", - "restore_nothings_done": "Rien n’a été restauré", - "restore_running_app_script": "Exécution du script de restauration de l’application '{app}'…", - "restore_running_hooks": "Exécution des scripts de restauration…", - "service_add_failed": "Impossible d’ajouter le service '{service}'", + "restore_hook_unavailable": "Le script de restauration '{part}' n'est pas disponible sur votre système, et ne l'est pas non plus dans l'archive", + "restore_nothings_done": "Rien n'a été restauré", + "restore_running_app_script": "Exécution du script de restauration de l'application '{app}'...", + "restore_running_hooks": "Exécution des scripts de restauration...", + "service_add_failed": "Impossible d'ajouter le service '{service}'", "service_added": "Le service '{service}' a été ajouté", - "service_already_started": "Le service '{service}' est déjà en cours d’exécution", + "service_already_started": "Le service '{service}' est déjà en cours d'exécution", "service_already_stopped": "Le service '{service}' est déjà arrêté", - "service_cmd_exec_failed": "Impossible d’exécuter la commande '{command}'", - "service_disable_failed": "Impossible de ne pas lancer le service « {service} » au démarrage.\n\nJournaux récents du service : {logs}", - "service_disabled": "Le service « {service} » ne sera plus lancé au démarrage du système.", - "service_enable_failed": "Impossible de lancer automatiquement le service « {service} » au démarrage.\n\nJournaux récents du service : {logs}", - "service_enabled": "Le service « {service} » sera désormais lancé automatiquement au démarrage du système.", + "service_cmd_exec_failed": "Impossible d'exécuter la commande '{command}'", + "service_disable_failed": "Impossible de ne pas lancer le service '{service}' au démarrage.\n\nJournaux récents du service : {logs}", + "service_disabled": "Le service '{service}' ne sera plus lancé au démarrage du système.", + "service_enable_failed": "Impossible de lancer automatiquement le service '{service}' au démarrage.\n\nJournaux récents du service : {logs}", + "service_enabled": "Le service '{service}' sera désormais lancé automatiquement au démarrage du système.", "service_remove_failed": "Impossible de supprimer le service '{service}'", - "service_removed": "Le service « {service} » a été supprimé", + "service_removed": "Le service '{service}' a été supprimé", "service_start_failed": "Impossible de démarrer le service '{service}'\n\nJournaux historisés récents : {logs}", - "service_started": "Le service « {service} » a été démarré", - "service_stop_failed": "Impossible d’arrêter le service '{service}'\n\nJournaux récents de service : {logs}", - "service_stopped": "Le service « {service} » a été arrêté", + "service_started": "Le service '{service}' a été démarré", + "service_stop_failed": "Impossible d'arrêter le service '{service}'\n\nJournaux récents de service : {logs}", + "service_stopped": "Le service '{service}' a été arrêté", "service_unknown": "Le service '{service}' est inconnu", "ssowat_conf_generated": "La configuration de SSOwat a été regénérée", "ssowat_conf_updated": "La configuration de SSOwat a été mise à jour", "system_upgraded": "Système mis à jour", - "system_username_exists": "Ce nom d’utilisateur existe déjà dans les utilisateurs système", + "system_username_exists": "Ce nom d'utilisateur existe déjà dans les utilisateurs système", "unbackup_app": "'{app}' ne sera pas sauvegardée", "unexpected_error": "Une erreur inattendue est survenue : {error}", "unlimit": "Pas de quota", @@ -134,133 +134,133 @@ "updating_apt_cache": "Récupération des mises à jour disponibles pour les paquets du système...", "upgrade_complete": "Mise à jour terminée", "upgrading_packages": "Mise à jour des paquets en cours...", - "upnp_dev_not_found": "Aucun périphérique compatible UPnP n’a été trouvé", + "upnp_dev_not_found": "Aucun périphérique compatible UPnP n'a été trouvé", "upnp_disabled": "L'UPnP est désactivé", "upnp_enabled": "L'UPnP est activé", - "upnp_port_open_failed": "Impossible d’ouvrir les ports UPnP", - "user_created": "L’utilisateur a été créé", - "user_creation_failed": "Impossible de créer l’utilisateur {user} : {error}", - "user_deleted": "L’utilisateur a été supprimé", - "user_deletion_failed": "Impossible de supprimer l’utilisateur {user} : {error}", - "user_home_creation_failed": "Impossible de créer le dossier personnel de l’utilisateur", - "user_unknown": "L’utilisateur {user} est inconnu", - "user_update_failed": "Impossible de mettre à jour l’utilisateur {user} : {error}", - "user_updated": "L’utilisateur a été modifié", + "upnp_port_open_failed": "Impossible d'ouvrir les ports UPnP", + "user_created": "L'utilisateur a été créé", + "user_creation_failed": "Impossible de créer l'utilisateur {user} : {error}", + "user_deleted": "L'utilisateur a été supprimé", + "user_deletion_failed": "Impossible de supprimer l'utilisateur {user} : {error}", + "user_home_creation_failed": "Impossible de créer le dossier personnel de l'utilisateur", + "user_unknown": "L'utilisateur {user} est inconnu", + "user_update_failed": "Impossible de mettre à jour l'utilisateur {user} : {error}", + "user_updated": "L'utilisateur a été modifié", "yunohost_already_installed": "YunoHost est déjà installé", "yunohost_configured": "YunoHost est maintenant configuré", - "yunohost_installing": "L’installation de YunoHost est en cours...", - "yunohost_not_installed": "YunoHost n’est pas correctement installé. Veuillez exécuter 'yunohost tools postinstall'", + "yunohost_installing": "L'installation de YunoHost est en cours...", + "yunohost_not_installed": "YunoHost n'est pas correctement installé. Veuillez exécuter 'yunohost tools postinstall'", "certmanager_attempt_to_replace_valid_cert": "Vous êtes en train de vouloir remplacer un certificat correct et valide pour le domaine {domain} ! (Utilisez --force pour contourner cela)", - "certmanager_domain_cert_not_selfsigned": "Le certificat du domaine {domain} n’est pas auto-signé. Voulez-vous vraiment le remplacer ? (Utilisez --force pour cela)", - "certmanager_certificate_fetching_or_enabling_failed": "Il semble que l’activation du nouveau certificat pour {domain} a échoué...", - "certmanager_attempt_to_renew_nonLE_cert": "Le certificat pour le domaine {domain} n’est pas émis par Let’s Encrypt. Impossible de le renouveler automatiquement !", - "certmanager_attempt_to_renew_valid_cert": "Le certificat pour le domaine {domain} n’est pas sur le point d’expirer ! (Vous pouvez utiliser --force si vous savez ce que vous faites)", + "certmanager_domain_cert_not_selfsigned": "Le certificat du domaine {domain} n'est pas auto-signé. Voulez-vous vraiment le remplacer ? (Utilisez --force pour cela)", + "certmanager_certificate_fetching_or_enabling_failed": "Il semble que l'activation du nouveau certificat pour {domain} a échoué...", + "certmanager_attempt_to_renew_nonLE_cert": "Le certificat pour le domaine {domain} n'est pas émis par Let's Encrypt. Impossible de le renouveler automatiquement !", + "certmanager_attempt_to_renew_valid_cert": "Le certificat pour le domaine {domain} n'est pas sur le point d'expirer ! (Vous pouvez utiliser --force si vous savez ce que vous faites)", "certmanager_domain_http_not_working": "Le domaine {domain} ne semble pas être accessible via HTTP. Merci de vérifier la catégorie 'Web' dans le diagnostic pour plus d'informations. (Ou si vous savez ce que vous faites, utilisez '--no-checks' pour désactiver la vérification.)", - "certmanager_domain_dns_ip_differs_from_public_ip": "Les enregistrements DNS du domaine '{domain}' sont différents de l’adresse IP de ce serveur. Pour plus d'informations, veuillez consulter la catégorie \"Enregistrements DNS\" dans la section diagnostic. Si vous avez récemment modifié votre enregistrement A, veuillez attendre sa propagation (des vérificateurs de propagation DNS sont disponibles en ligne). (Si vous savez ce que vous faites, utilisez '--no-checks' pour désactiver ces contrôles)", - "certmanager_cannot_read_cert": "Quelque chose s’est mal passé lors de la tentative d’ouverture du certificat actuel pour le domaine {domain} (fichier : {file}), la cause est : {reason}", + "certmanager_domain_dns_ip_differs_from_public_ip": "Les enregistrements DNS du domaine '{domain}' sont différents de l'adresse IP de ce serveur. Pour plus d'informations, veuillez consulter la catégorie \"Enregistrements DNS\" dans la section diagnostic. Si vous avez récemment modifié votre enregistrement A, veuillez attendre sa propagation (des vérificateurs de propagation DNS sont disponibles en ligne). (Si vous savez ce que vous faites, utilisez '--no-checks' pour désactiver ces contrôles)", + "certmanager_cannot_read_cert": "Quelque chose s'est mal passé lors de la tentative d'ouverture du certificat actuel pour le domaine {domain} (fichier : {file}), la cause est : {reason}", "certmanager_cert_install_success_selfsigned": "Le certificat auto-signé est maintenant installé pour le domaine '{domain}'", - "certmanager_cert_install_success": "Le certificat Let’s Encrypt est maintenant installé pour le domaine '{domain}'", - "certmanager_cert_renew_success": "Certificat Let’s Encrypt renouvelé pour le domaine '{domain}'", + "certmanager_cert_install_success": "Le certificat Let's Encrypt est maintenant installé pour le domaine '{domain}'", + "certmanager_cert_renew_success": "Certificat Let's Encrypt renouvelé pour le domaine '{domain}'", "certmanager_cert_signing_failed": "Impossible de signer le nouveau certificat", "certmanager_no_cert_file": "Impossible de lire le fichier du certificat pour le domaine {domain} (fichier : {file})", "certmanager_hit_rate_limit": "Trop de certificats ont déjà été émis récemment pour ce même ensemble de domaines {domain}. Veuillez réessayer plus tard. Lisez https://letsencrypt.org/docs/rate-limits/ pour obtenir plus de détails sur les ratios et limitations", - "domain_cannot_remove_main": "Vous ne pouvez pas supprimer '{domain}' car il s’agit du domaine principal. Vous devez d’abord définir un autre domaine comme domaine principal à l’aide de 'yunohost domain main-domain -n ', voici la liste des domaines candidats : {other_domains}", - "certmanager_self_ca_conf_file_not_found": "Le fichier de configuration pour l’autorité du certificat auto-signé est introuvable (fichier : {file})", - "certmanager_unable_to_parse_self_CA_name": "Impossible d’analyser le nom de l’autorité du certificat auto-signé (fichier : {file})", - "mailbox_used_space_dovecot_down": "Le service de courriel Dovecot doit être démarré si vous souhaitez voir l’espace disque occupé par la messagerie", + "domain_cannot_remove_main": "Vous ne pouvez pas supprimer '{domain}' car il s'agit du domaine principal. Vous devez d'abord définir un autre domaine comme domaine principal à l'aide de 'yunohost domain main-domain -n ', voici la liste des domaines candidats : {other_domains}", + "certmanager_self_ca_conf_file_not_found": "Le fichier de configuration pour l'autorité du certificat auto-signé est introuvable (fichier : {file})", + "certmanager_unable_to_parse_self_CA_name": "Impossible d'analyser le nom de l'autorité du certificat auto-signé (fichier : {file})", + "mailbox_used_space_dovecot_down": "Le service de email Dovecot doit être démarré si vous souhaitez voir l'espace disque occupé par la messagerie", "domains_available": "Domaines disponibles :", - "backup_archive_broken_link": "Impossible d’accéder à l’archive de sauvegarde (lien invalide vers {path})", + "backup_archive_broken_link": "Impossible d'accéder à l'archive de sauvegarde (lien invalide vers {path})", "certmanager_acme_not_configured_for_domain": "Le challenge ACME n'a pas pu être validé pour le domaine {domain} pour le moment car le code de la configuration NGINX est manquant... Merci de vérifier que votre configuration NGINX est à jour avec la commande: `yunohost tools regen-conf nginx --dry-run --with-diff`.", - "domain_hostname_failed": "Échec de l’utilisation d’un nouveau nom d’hôte. Cela pourrait causer des soucis plus tard (cela n’en causera peut-être pas).", - "app_already_installed_cant_change_url": "Cette application est déjà installée. L’URL ne peut pas être changé simplement par cette fonction. Vérifiez si cela est disponible avec `app changeurl`.", + "domain_hostname_failed": "Échec de l'utilisation d'un nouveau nom d'hôte. Cela pourrait causer des soucis plus tard (cela n'en causera peut-être pas).", + "app_already_installed_cant_change_url": "Cette application est déjà installée. L'URL ne peut pas être changé simplement par cette fonction. Vérifiez si cela est disponible avec `app changeurl`.", "app_change_url_failed_nginx_reload": "Le redémarrage de NGINX a échoué. Voici la sortie de 'nginx -t' :\n{nginx_errors}", - "app_change_url_identical_domains": "L’ancien et le nouveau couple domaine/chemin_de_l’URL sont identiques pour ('{domain}{path}'), rien à faire.", - "app_change_url_no_script": "L’application '{app_name}' ne prend pas encore en charge le changement d’URL. Vous devriez peut-être la mettre à jour.", - "app_change_url_success": "L’URL de l’application {app} a été changée en {domain}{path}", - "app_location_unavailable": "Cette URL n’est pas disponible ou est en conflit avec une application existante :\n{apps}", + "app_change_url_identical_domains": "L'ancien et le nouveau couple domaine/chemin_de_l'URL sont identiques pour ('{domain}{path}'), rien à faire.", + "app_change_url_no_script": "L'application '{app_name}' ne prend pas encore en charge le changement d'URL. Vous devriez peut-être la mettre à jour.", + "app_change_url_success": "L'URL de l'application {app} a été changée en {domain}{path}", + "app_location_unavailable": "Cette URL n'est pas disponible ou est en conflit avec une application existante :\n{apps}", "app_already_up_to_date": "{app} est déjà à jour", - "global_settings_bad_choice_for_enum": "Valeur du paramètre {setting} incorrecte. Reçu : {choice}, mais les valeurs possibles sont : {available_choices}", + "global_settings_bad_choice_for_enum": "Valeur du paramètre {setting} incorrecte. Reçu : {choice}, mais les valeurs possibles sont : {available_choices}", "global_settings_bad_type_for_setting": "Le type du paramètre {setting} est incorrect. Reçu {received_type} alors que {expected_type} était attendu", - "global_settings_cant_open_settings": "Échec de l’ouverture du ficher de configurations car : {reason}", - "global_settings_cant_write_settings": "Échec d’écriture du fichier de configurations car : {reason}", - "global_settings_key_doesnt_exists": "La clef '{settings_key}' n’existe pas dans les configurations générales, vous pouvez voir toutes les clefs disponibles en saisissant 'yunohost settings list'", + "global_settings_cant_open_settings": "Échec de l'ouverture du ficher de configurations car : {reason}", + "global_settings_cant_write_settings": "Échec d'écriture du fichier de configurations car : {reason}", + "global_settings_key_doesnt_exists": "La clef '{settings_key}' n'existe pas dans les configurations générales, vous pouvez voir toutes les clefs disponibles en saisissant 'yunohost settings list'", "global_settings_reset_success": "Vos configurations précédentes ont été sauvegardées dans {path}", - "global_settings_unknown_type": "Situation inattendue : la configuration {setting} semble avoir le type {unknown_type} mais celui-ci n’est pas pris en charge par le système.", + "global_settings_unknown_type": "Situation inattendue : la configuration {setting} semble avoir le type {unknown_type} mais celui-ci n'est pas pris en charge par le système.", "global_settings_unknown_setting_from_settings_file": "Clé inconnue dans les paramètres : '{setting_key}', rejet de cette clé et sauvegarde de celle-ci dans /etc/yunohost/unkown_settings.json", "backup_abstract_method": "Cette méthode de sauvegarde reste à implémenter", - "backup_applying_method_tar": "Création de l’archive TAR de la sauvegarde...", + "backup_applying_method_tar": "Création de l'archive TAR de la sauvegarde...", "backup_applying_method_copy": "Copie de tous les fichiers à sauvegarder...", "backup_applying_method_custom": "Appel de la méthode de sauvegarde personnalisée '{method}'...", - "backup_archive_system_part_not_available": "La partie '{part}' du système n’est pas disponible dans cette sauvegarde", - "backup_archive_writing_error": "Impossible d’ajouter des fichiers '{source}' (nommés dans l’archive : '{dest}') à sauvegarder dans l’archive compressée '{archive}'", - "backup_ask_for_copying_if_needed": "Voulez-vous effectuer la sauvegarde en utilisant {size}Mo temporairement ? (Cette méthode est utilisée car certains fichiers n’ont pas pu être préparés avec une méthode plus efficace.)", - "backup_cant_mount_uncompress_archive": "Impossible de monter en lecture seule le dossier de l’archive décompressée", - "backup_copying_to_organize_the_archive": "Copie de {size} Mo pour organiser l’archive", + "backup_archive_system_part_not_available": "La partie '{part}' du système n'est pas disponible dans cette sauvegarde", + "backup_archive_writing_error": "Impossible d'ajouter des fichiers '{source}' (nommés dans l'archive : '{dest}') à sauvegarder dans l'archive compressée '{archive}'", + "backup_ask_for_copying_if_needed": "Voulez-vous effectuer la sauvegarde en utilisant {size}Mo temporairement ? (Cette méthode est utilisée car certains fichiers n'ont pas pu être préparés avec une méthode plus efficace.)", + "backup_cant_mount_uncompress_archive": "Impossible de monter en lecture seule le dossier de l'archive décompressée", + "backup_copying_to_organize_the_archive": "Copie de {size} Mo pour organiser l'archive", "backup_csv_creation_failed": "Impossible de créer le fichier CSV nécessaire à la restauration", - "backup_csv_addition_failed": "Impossible d’ajouter des fichiers à sauvegarder dans le fichier CSV", - "backup_custom_backup_error": "Échec de la méthode de sauvegarde personnalisée à l’étape 'backup'", - "backup_custom_mount_error": "Échec de la méthode de sauvegarde personnalisée à l’étape 'mount'", - "backup_no_uncompress_archive_dir": "Ce dossier d’archive décompressée n’existe pas", - "backup_method_tar_finished": "L’archive TAR de la sauvegarde a été créée", + "backup_csv_addition_failed": "Impossible d'ajouter des fichiers à sauvegarder dans le fichier CSV", + "backup_custom_backup_error": "Échec de la méthode de sauvegarde personnalisée à l'étape 'backup'", + "backup_custom_mount_error": "Échec de la méthode de sauvegarde personnalisée à l'étape 'mount'", + "backup_no_uncompress_archive_dir": "Ce dossier d'archive décompressée n'existe pas", + "backup_method_tar_finished": "L'archive TAR de la sauvegarde a été créée", "backup_method_copy_finished": "La copie de la sauvegarde est terminée", "backup_method_custom_finished": "La méthode de sauvegarde personnalisée '{method}' est terminée", "backup_system_part_failed": "Impossible de sauvegarder la partie '{part}' du système", - "backup_unable_to_organize_files": "Impossible d’utiliser la méthode rapide pour organiser les fichiers dans l’archive", - "backup_with_no_backup_script_for_app": "L’application {app} n’a pas de script de sauvegarde. Ignorer.", - "backup_with_no_restore_script_for_app": "{app} n’a pas de script de restauration, vous ne pourrez pas restaurer automatiquement la sauvegarde de cette application.", + "backup_unable_to_organize_files": "Impossible d'utiliser la méthode rapide pour organiser les fichiers dans l'archive", + "backup_with_no_backup_script_for_app": "L'application {app} n'a pas de script de sauvegarde. Ignorer.", + "backup_with_no_restore_script_for_app": "{app} n'a pas de script de restauration, vous ne pourrez pas restaurer automatiquement la sauvegarde de cette application.", "global_settings_cant_serialize_settings": "Échec de la sérialisation des données de paramétrage car : {reason}", "restore_removing_tmp_dir_failed": "Impossible de sauvegarder un ancien dossier temporaire", - "restore_extracting": "Extraction des fichiers nécessaires depuis l’archive…", - "restore_may_be_not_enough_disk_space": "Votre système ne semble pas avoir suffisamment d’espace (libre : {free_space:d} B, espace nécessaire : {needed_space:d} B, marge de sécurité : {margin:d} B)", - "restore_not_enough_disk_space": "Espace disponible insuffisant (L’espace libre est de {free_space:d} octets. Le besoin d’espace nécessaire est de {needed_space:d} octets. En appliquant une marge de sécurité, la quantité d’espace nécessaire est de {margin:d} octets)", + "restore_extracting": "Extraction des fichiers nécessaires depuis l'archive...", + "restore_may_be_not_enough_disk_space": "Votre système ne semble pas avoir suffisamment d'espace (libre : {free_space:d} B, espace nécessaire : {needed_space:d} B, marge de sécurité : {margin:d} B)", + "restore_not_enough_disk_space": "Espace disponible insuffisant (L'espace libre est de {free_space:d} octets. Le besoin d'espace nécessaire est de {needed_space:d} octets. En appliquant une marge de sécurité, la quantité d'espace nécessaire est de {margin:d} octets)", "restore_system_part_failed": "Impossible de restaurer la partie '{part}' du système", "backup_couldnt_bind": "Impossible de lier {src} avec {dest}.", "domain_dns_conf_is_just_a_recommendation": "Cette commande vous montre la configuration *recommandée*. Elle ne configure pas le DNS pour vous. Il est de votre ressort de configurer votre zone DNS chez votre registrar/fournisseur conformément à cette recommandation.", - "migrations_cant_reach_migration_file": "Impossible d’accéder aux fichiers de migration via le chemin '%s'", + "migrations_cant_reach_migration_file": "Impossible d'accéder aux fichiers de migration via le chemin '%s'", "migrations_loading_migration": "Chargement de la migration {id}...", - "migrations_migration_has_failed": "La migration {id} a échoué avec l’exception {exception} : annulation", + "migrations_migration_has_failed": "La migration {id} a échoué avec l'exception {exception} : annulation", "migrations_no_migrations_to_run": "Aucune migration à lancer", "migrations_skip_migration": "Ignorer et passer la migration {id}...", - "server_shutdown": "Le serveur va s’éteindre", + "server_shutdown": "Le serveur va s'éteindre", "server_shutdown_confirm": "Le serveur va être éteint immédiatement, le voulez-vous vraiment ? [{answers}]", "server_reboot": "Le serveur va redémarrer", "server_reboot_confirm": "Le serveur va redémarrer immédiatement, le voulez-vous vraiment ? [{answers}]", - "app_upgrade_some_app_failed": "Certaines applications n’ont pas été mises à jour", + "app_upgrade_some_app_failed": "Certaines applications n'ont pas été mises à jour", "dyndns_could_not_check_provide": "Impossible de vérifier si {provider} peut fournir {domain}.", "dyndns_domain_not_provided": "Le fournisseur DynDNS {provider} ne peut pas fournir le domaine {domain}.", - "app_make_default_location_already_used": "Impossible de configurer l’application '{app}' par défaut pour le domaine '{domain}' car il est déjà utilisé par l'application '{other_app}'", + "app_make_default_location_already_used": "Impossible de configurer l'application '{app}' par défaut pour le domaine '{domain}' car il est déjà utilisé par l'application '{other_app}'", "app_upgrade_app_name": "Mise à jour de {app}...", - "backup_output_symlink_dir_broken": "Votre répertoire d’archivage '{path}' est un lien symbolique brisé. Peut-être avez-vous oublié de re/monter ou de brancher le support de stockage sur lequel il pointe.", + "backup_output_symlink_dir_broken": "Votre répertoire d'archivage '{path}' est un lien symbolique brisé. Peut-être avez-vous oublié de re/monter ou de brancher le support de stockage sur lequel il pointe.", "migrations_list_conflict_pending_done": "Vous ne pouvez pas utiliser --previous et --done simultanément.", - "migrations_to_be_ran_manually": "La migration {id} doit être lancée manuellement. Veuillez aller dans Outils > Migrations dans l’interface admin, ou lancer `yunohost tools migrations run`.", - "migrations_need_to_accept_disclaimer": "Pour lancer la migration {id}, vous devez accepter cet avertissement :\n---\n{disclaimer}\n---\nSi vous acceptez de lancer la migration, veuillez relancer la commande avec l’option --accept-disclaimer.", - "service_description_yunomdns": "Vous permet d’atteindre votre serveur en utilisant « yunohost.local » sur votre réseau local", + "migrations_to_be_ran_manually": "La migration {id} doit être lancée manuellement. Veuillez aller dans Outils > Migrations dans l'interface admin, ou lancer `yunohost tools migrations run`.", + "migrations_need_to_accept_disclaimer": "Pour lancer la migration {id}, vous devez accepter cet avertissement :\n---\n{disclaimer}\n---\nSi vous acceptez de lancer la migration, veuillez relancer la commande avec l'option --accept-disclaimer.", + "service_description_yunomdns": "Vous permet d'atteindre votre serveur en utilisant 'yunohost.local' sur votre réseau local", "service_description_dnsmasq": "Gère la résolution des noms de domaine (DNS)", - "service_description_dovecot": "Permet aux clients de messagerie d’accéder/récupérer les emails (via IMAP et POP3)", - "service_description_fail2ban": "Protège contre les attaques brute-force et autres types d’attaques venant d’Internet", + "service_description_dovecot": "Permet aux clients de messagerie d'accéder/récupérer les emails (via IMAP et POP3)", + "service_description_fail2ban": "Protège contre les attaques brute-force et autres types d'attaques venant d'Internet", "service_description_metronome": "Gère les comptes de messagerie instantanée XMPP", "service_description_mysql": "Stocke les données des applications (bases de données SQL)", - "service_description_nginx": "Sert ou permet l’accès à tous les sites web hébergés sur votre serveur", + "service_description_nginx": "Sert ou permet l'accès à tous les sites web hébergés sur votre serveur", "service_description_postfix": "Utilisé pour envoyer et recevoir des emails", - "service_description_redis-server": "Une base de données spécialisée utilisée pour l’accès rapide aux données, les files d’attentes et la communication entre les programmes", - "service_description_rspamd": "Filtre le pourriel, et d’autres fonctionnalités liées aux emails", + "service_description_redis-server": "Une base de données spécialisée utilisée pour l'accès rapide aux données, les files d'attentes et la communication entre les programmes", + "service_description_rspamd": "Filtre le pourriel, et d'autres fonctionnalités liées aux emails", "service_description_slapd": "Stocke les utilisateurs, domaines et leurs informations liées", "service_description_ssh": "Vous permet de vous connecter à distance à votre serveur via un terminal (protocole SSH)", - "service_description_yunohost-api": "Permet les interactions entre l’interface web de YunoHost et le système", - "service_description_yunohost-firewall": "Gère l’ouverture et la fermeture des ports de connexion aux services", - "experimental_feature": "Attention : cette fonctionnalité est expérimentale et ne doit pas être considérée comme stable, vous ne devriez pas l’utiliser à moins que vous ne sachiez ce que vous faites.", - "log_corrupted_md_file": "Le fichier YAML de métadonnées associé aux logs est corrompu : '{md_file}'\nErreur : {error}", + "service_description_yunohost-api": "Permet les interactions entre l'interface web de YunoHost et le système", + "service_description_yunohost-firewall": "Gère l'ouverture et la fermeture des ports de connexion aux services", + "experimental_feature": "Attention : cette fonctionnalité est expérimentale et ne doit pas être considérée comme stable, vous ne devriez pas l'utiliser à moins que vous ne sachiez ce que vous faites.", + "log_corrupted_md_file": "Le fichier YAML de métadonnées associé aux logs est corrompu : '{md_file}'\nErreur : {error}", "log_link_to_log": "Journal complet de cette opération : ' {desc} '", "log_help_to_get_log": "Pour voir le journal de cette opération '{desc}', utilisez la commande 'yunohost log show {name}{name}'", - "log_link_to_failed_log": "L’opération '{desc}' a échoué ! Pour obtenir de l’aide, merci de partager le journal de l’opération en cliquant ici", - "log_help_to_get_failed_log": "L’opération '{desc}' a échoué ! Pour obtenir de l’aide, merci de partager le journal de l’opération en utilisant la commande 'yunohost log share {name}'", - "log_does_exists": "Il n’y a pas de journal des opérations avec le nom '{log}', utilisez 'yunohost log list' pour voir tous les journaux d’opérations disponibles", - "log_operation_unit_unclosed_properly": "L’opération ne s’est pas terminée correctement", - "log_app_change_url": "Changer l’URL de l’application '{}'", - "log_app_install": "Installer l’application '{}'", - "log_app_remove": "Enlever l’application '{}'", - "log_app_upgrade": "Mettre à jour l’application '{}'", - "log_app_makedefault": "Faire de '{}' l’application par défaut", + "log_link_to_failed_log": "L'opération '{desc}' a échoué ! Pour obtenir de l'aide, merci de partager le journal de l'opération en cliquant ici", + "log_help_to_get_failed_log": "L'opération '{desc}' a échoué ! Pour obtenir de l'aide, merci de partager le journal de l'opération en utilisant la commande 'yunohost log share {name}'", + "log_does_exists": "Il n'y a pas de journal des opérations avec le nom '{log}', utilisez 'yunohost log list' pour voir tous les journaux d'opérations disponibles", + "log_operation_unit_unclosed_properly": "L'opération ne s'est pas terminée correctement", + "log_app_change_url": "Changer l'URL de l'application '{}'", + "log_app_install": "Installer l'application '{}'", + "log_app_remove": "Enlever l'application '{}'", + "log_app_upgrade": "Mettre à jour l'application '{}'", + "log_app_makedefault": "Faire de '{}' l'application par défaut", "log_available_on_yunopaste": "Le journal est désormais disponible via {url}", "log_backup_restore_system": "Restaurer le système depuis une archive de sauvegarde", "log_backup_restore_app": "Restaurer '{}' depuis une sauvegarde", @@ -269,13 +269,13 @@ "log_domain_add": "Ajouter le domaine '{}' dans la configuration du système", "log_domain_remove": "Enlever le domaine '{}' de la configuration du système", "log_dyndns_subscribe": "Souscrire au sous-domaine YunoHost '{}'", - "log_dyndns_update": "Mettre à jour l’adresse IP associée à votre sous-domaine YunoHost '{}'", - "log_letsencrypt_cert_install": "Installer le certificat Let’s Encrypt sur le domaine '{}'", + "log_dyndns_update": "Mettre à jour l'adresse IP associée à votre sous-domaine YunoHost '{}'", + "log_letsencrypt_cert_install": "Installer le certificat Let's Encrypt sur le domaine '{}'", "log_selfsigned_cert_install": "Installer un certificat auto-signé sur le domaine '{}'", - "log_letsencrypt_cert_renew": "Renouveler le certificat Let’s Encrypt de '{}'", - "log_user_create": "Ajouter l’utilisateur '{}'", - "log_user_delete": "Supprimer l’utilisateur '{}'", - "log_user_update": "Mettre à jour les informations de l’utilisateur '{}'", + "log_letsencrypt_cert_renew": "Renouveler le certificat Let's Encrypt de '{}'", + "log_user_create": "Ajouter l'utilisateur '{}'", + "log_user_delete": "Supprimer l'utilisateur '{}'", + "log_user_update": "Mettre à jour les informations de l'utilisateur '{}'", "log_domain_main_domain": "Faire de '{}' le domaine principal", "log_tools_migrations_migrate_forward": "Exécuter les migrations", "log_tools_postinstall": "Faire la post-installation de votre serveur YunoHost", @@ -290,9 +290,9 @@ "password_too_simple_2": "Le mot de passe doit comporter au moins 8 caractères et contenir des chiffres, des majuscules et des minuscules", "password_too_simple_3": "Le mot de passe doit comporter au moins 8 caractères et contenir des chiffres, des majuscules, des minuscules et des caractères spéciaux", "password_too_simple_4": "Le mot de passe doit comporter au moins 12 caractères et contenir des chiffres, des majuscules, des minuscules et des caractères spéciaux", - "root_password_desynchronized": "Le mot de passe administrateur a été changé, mais YunoHost n’a pas pu le propager au mot de passe root !", + "root_password_desynchronized": "Le mot de passe administrateur a été changé, mais YunoHost n'a pas pu le propager au mot de passe root !", "aborting": "Annulation en cours.", - "app_not_upgraded": "L’application {failed_app} n’a pas été mise à jour et par conséquence les applications suivantes n’ont pas été mises à jour : {apps}", + "app_not_upgraded": "L'application {failed_app} n'a pas été mise à jour et par conséquence les applications suivantes n'ont pas été mises à jour : {apps}", "app_start_install": "Installation de {app}...", "app_start_remove": "Suppression de {app}...", "app_start_backup": "Collecte des fichiers devant être sauvegardés pour {app}...", @@ -300,28 +300,28 @@ "app_upgrade_several_apps": "Les applications suivantes seront mises à jour : {apps}", "ask_new_domain": "Nouveau domaine", "ask_new_path": "Nouveau chemin", - "backup_actually_backuping": "Création d’une archive de sauvegarde à partir des fichiers collectés...", - "backup_mount_archive_for_restore": "Préparation de l’archive pour restauration...", - "confirm_app_install_warning": "Avertissement : cette application peut fonctionner mais n’est pas bien intégrée dans YunoHost. Certaines fonctionnalités telles que l’authentification unique et la sauvegarde/restauration peuvent ne pas être disponibles. L’installer quand même ? [{answers}] ", - "confirm_app_install_danger": "DANGER ! Cette application est connue pour être encore expérimentale (si elle ne fonctionne pas explicitement) ! Vous ne devriez probablement PAS l’installer à moins de savoir ce que vous faites. AUCUN SUPPORT ne sera fourni si cette application ne fonctionne pas ou casse votre système... Si vous êtes prêt à prendre ce risque de toute façon, tapez '{answers}'", + "backup_actually_backuping": "Création d'une archive de sauvegarde à partir des fichiers collectés...", + "backup_mount_archive_for_restore": "Préparation de l'archive pour restauration...", + "confirm_app_install_warning": "Avertissement : cette application peut fonctionner mais n'est pas bien intégrée dans YunoHost. Certaines fonctionnalités telles que l'authentification unique et la sauvegarde/restauration peuvent ne pas être disponibles. L'installer quand même ? [{answers}] ", + "confirm_app_install_danger": "DANGER ! Cette application est connue pour être encore expérimentale (si elle ne fonctionne pas explicitement) ! Vous ne devriez probablement PAS l'installer à moins de savoir ce que vous faites. AUCUN SUPPORT ne sera fourni si cette application ne fonctionne pas ou casse votre système... Si vous êtes prêt à prendre ce risque de toute façon, tapez '{answers}'", "confirm_app_install_thirdparty": "DANGER ! Cette application ne fait pas partie du catalogue d'applications de YunoHost. L'installation d'applications tierces peut compromettre l'intégrité et la sécurité de votre système. Vous ne devriez probablement PAS l'installer à moins de savoir ce que vous faites. AUCUN SUPPORT ne sera fourni si cette application ne fonctionne pas ou casse votre système... Si vous êtes prêt à prendre ce risque de toute façon, tapez '{answers}'", "dpkg_is_broken": "Vous ne pouvez pas faire ça maintenant car dpkg/apt (le gestionnaire de paquets du système) semble avoir laissé des choses non configurées. Vous pouvez essayer de résoudre ce problème en vous connectant via SSH et en exécutant `sudo apt install --fix-broken` et/ou `sudo dpkg --configure -a'.", "dyndns_could_not_check_available": "Impossible de vérifier si {domain} est disponible chez {provider}.", - "file_does_not_exist": "Le fichier dont le chemin est {path} n’existe pas.", + "file_does_not_exist": "Le fichier dont le chemin est {path} n'existe pas.", "global_settings_setting_security_password_admin_strength": "Qualité du mot de passe administrateur", - "global_settings_setting_security_password_user_strength": "Qualité du mot de passe de l’utilisateur", - "global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Autoriser l’utilisation de la clé hôte DSA (obsolète) pour la configuration du service SSH", + "global_settings_setting_security_password_user_strength": "Qualité du mot de passe de l'utilisateur", + "global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Autoriser l'utilisation de la clé hôte DSA (obsolète) pour la configuration du service SSH", "hook_json_return_error": "Échec de la lecture au retour du script {path}. Erreur : {msg}. Contenu brut : {raw_content}", - "pattern_password_app": "Désolé, les mots de passe ne peuvent pas contenir les caractères suivants : {forbidden_chars}", + "pattern_password_app": "Désolé, les mots de passe ne peuvent pas contenir les caractères suivants : {forbidden_chars}", "root_password_replaced_by_admin_password": "Votre mot de passe root a été remplacé par votre mot de passe administrateur.", "service_reload_failed": "Impossible de recharger le service '{service}'.\n\nJournaux historisés récents de ce service : {logs}", - "service_reloaded": "Le service « {service} » a été rechargé", + "service_reloaded": "Le service '{service}' a été rechargé", "service_restart_failed": "Impossible de redémarrer le service '{service}'\n\nJournaux historisés récents de ce service : {logs}", - "service_restarted": "Le service « {service} » a été redémarré", + "service_restarted": "Le service '{service}' a été redémarré", "service_reload_or_restart_failed": "Impossible de recharger ou de redémarrer le service '{service}'\n\nJournaux historisés récents de ce service : {logs}", - "service_reloaded_or_restarted": "Le service « {service} » a été rechargé ou redémarré", - "this_action_broke_dpkg": "Cette action a laissé des paquets non configurés par dpkg/apt (les gestionnaires de paquets du système) … Vous pouvez essayer de résoudre ce problème en vous connectant via SSH et en exécutant `sudo apt install --fix-broken` et/ou `sudo dpkg --configure -a`.", - "app_action_cannot_be_ran_because_required_services_down": "Ces services requis doivent être en cours d’exécution pour exécuter cette action : {services}. Essayez de les redémarrer pour continuer (et éventuellement rechercher pourquoi ils sont en panne).", + "service_reloaded_or_restarted": "Le service '{service}' a été rechargé ou redémarré", + "this_action_broke_dpkg": "Cette action a laissé des paquets non configurés par dpkg/apt (les gestionnaires de paquets du système) ... Vous pouvez essayer de résoudre ce problème en vous connectant via SSH et en exécutant `sudo apt install --fix-broken` et/ou `sudo dpkg --configure -a`.", + "app_action_cannot_be_ran_because_required_services_down": "Ces services requis doivent être en cours d'exécution pour exécuter cette action : {services}. Essayez de les redémarrer pour continuer (et éventuellement rechercher pourquoi ils sont en panne).", "admin_password_too_long": "Veuillez choisir un mot de passe comportant moins de 127 caractères", "log_regen_conf": "Régénérer les configurations du système '{}'", "regenconf_file_backed_up": "Le fichier de configuration '{conf}' a été sauvegardé sous '{backup}'", @@ -333,26 +333,26 @@ "regenconf_file_updated": "Le fichier de configuration '{conf}' a été mis à jour", "regenconf_now_managed_by_yunohost": "Le fichier de configuration '{conf}' est maintenant géré par YunoHost (catégorie {category}).", "regenconf_up_to_date": "La configuration est déjà à jour pour la catégorie '{category}'", - "already_up_to_date": "Il n’y a rien à faire. Tout est déjà à jour.", - "global_settings_setting_security_nginx_compatibility": "Compatibilité versus compromis sécuritaire pour le serveur web Nginx. Affecte les cryptogrammes (et d’autres aspects liés à la sécurité)", - "global_settings_setting_security_ssh_compatibility": "Compatibilité versus compromis sécuritaire pour le serveur SSH. Affecte les cryptogrammes (et d’autres aspects liés à la sécurité)", - "global_settings_setting_security_postfix_compatibility": "Compatibilité versus compromis sécuritaire pour le serveur Postfix. Affecte les cryptogrammes (et d’autres aspects liés à la sécurité)", - "regenconf_file_kept_back": "Le fichier de configuration '{conf}' devait être supprimé par « regen-conf » (catégorie {category}) mais a été conservé.", + "already_up_to_date": "Il n'y a rien à faire. Tout est déjà à jour.", + "global_settings_setting_security_nginx_compatibility": "Compatibilité versus compromis sécuritaire pour le serveur web Nginx. Affecte les cryptogrammes (et d'autres aspects liés à la sécurité)", + "global_settings_setting_security_ssh_compatibility": "Compatibilité versus compromis sécuritaire pour le serveur SSH. Affecte les cryptogrammes (et d'autres aspects liés à la sécurité)", + "global_settings_setting_security_postfix_compatibility": "Compatibilité versus compromis sécuritaire pour le serveur Postfix. Affecte les cryptogrammes (et d'autres aspects liés à la sécurité)", + "regenconf_file_kept_back": "Le fichier de configuration '{conf}' devait être supprimé par 'regen-conf' (catégorie {category}) mais a été conservé.", "regenconf_updated": "La configuration a été mise à jour pour '{category}'", "regenconf_would_be_updated": "La configuration aurait dû être mise à jour pour la catégorie '{category}'", - "regenconf_dry_pending_applying": "Vérification de la configuration en attente qui aurait été appliquée pour la catégorie '{category}'…", + "regenconf_dry_pending_applying": "Vérification de la configuration en attente qui aurait été appliquée pour la catégorie '{category}'...", "regenconf_failed": "Impossible de régénérer la configuration pour la ou les catégorie(s) : '{categories}'", "regenconf_pending_applying": "Applique la configuration en attente pour la catégorie '{category}'...", "service_regen_conf_is_deprecated": "'yunohost service regen-conf' est obsolète ! Veuillez plutôt utiliser 'yunohost tools regen-conf' à la place.", "tools_upgrade_at_least_one": "Veuillez spécifier '--apps' ou '--system'", "tools_upgrade_cant_both": "Impossible de mettre à niveau le système et les applications en même temps", - "tools_upgrade_cant_hold_critical_packages": "Impossibilité d'ajouter le drapeau 'hold' pour les paquets critiques…", - "tools_upgrade_regular_packages": "Mise à jour des paquets du système (non liés a YunoHost)…", + "tools_upgrade_cant_hold_critical_packages": "Impossibilité d'ajouter le drapeau 'hold' pour les paquets critiques...", + "tools_upgrade_regular_packages": "Mise à jour des paquets du système (non liés a YunoHost)...", "tools_upgrade_regular_packages_failed": "Impossible de mettre à jour les paquets suivants : {packages_list}", - "tools_upgrade_special_packages": "Mise à jour des paquets 'spécifiques' (liés a YunoHost)…", + "tools_upgrade_special_packages": "Mise à jour des paquets 'spécifiques' (liés a YunoHost)...", "tools_upgrade_special_packages_completed": "La mise à jour des paquets de YunoHost est finie !\nPressez [Entrée] pour revenir à la ligne de commande", "dpkg_lock_not_available": "Cette commande ne peut pas être exécutée pour le moment car un autre programme semble utiliser le verrou de dpkg (le gestionnaire de package système)", - "tools_upgrade_cant_unhold_critical_packages": "Impossible d'enlever le drapeau 'hold' pour les paquets critiques…", + "tools_upgrade_cant_unhold_critical_packages": "Impossible d'enlever le drapeau 'hold' pour les paquets critiques...", "tools_upgrade_special_packages_explanation": "La mise à niveau spécifique à YunoHost se poursuivra en arrière-plan. Veuillez ne pas lancer d'autres actions sur votre serveur pendant les 10 prochaines minutes (selon la vitesse du matériel). Après cela, vous devrez peut-être vous reconnecter à la webadmin. Le journal de mise à niveau sera disponible dans Outils → Journal (dans le webadmin) ou en utilisant 'yunohost log list' (à partir de la ligne de commande).", "update_apt_cache_failed": "Impossible de mettre à jour le cache APT (gestionnaire de paquets Debian). Voici un extrait du fichier sources.list qui pourrait vous aider à identifier les lignes problématiques :\n{sourceslist}", "update_apt_cache_warning": "Des erreurs se sont produites lors de la mise à jour du cache APT (gestionnaire de paquets Debian). Voici un extrait des lignes du fichier sources.list qui pourrait vous aider à identifier les lignes problématiques :\n{sourceslist}", @@ -366,62 +366,62 @@ "group_deletion_failed": "Échec de la suppression du groupe '{group}' : {error}", "log_user_group_delete": "Supprimer le groupe '{}'", "log_user_group_update": "Mettre à jour '{}' pour le groupe", - "mailbox_disabled": "La boîte aux lettres est désactivée pour l’utilisateur {user}", + "mailbox_disabled": "La boîte aux lettres est désactivée pour l'utilisateur {user}", "app_action_broke_system": "Cette action semble avoir cassé des services importants : {services}", "apps_already_up_to_date": "Toutes les applications sont déjà à jour", "migrations_must_provide_explicit_targets": "Vous devez fournir des cibles explicites lorsque vous utilisez '--skip' ou '--force-rerun'", - "migrations_no_such_migration": "Il n’y a pas de migration appelée '{id}'", + "migrations_no_such_migration": "Il n'y a pas de migration appelée '{id}'", "migrations_pending_cant_rerun": "Ces migrations étant toujours en attente, vous ne pouvez pas les exécuter à nouveau : {ids}", "migrations_exclusive_options": "'auto', '--skip' et '--force-rerun' sont des options mutuellement exclusives.", "migrations_not_pending_cant_skip": "Ces migrations ne sont pas en attente et ne peuvent donc pas être ignorées : {ids}", "permission_not_found": "Permission '{permission}' introuvable", "permission_update_failed": "Impossible de mettre à jour la permission '{permission}' : {error}", "permission_updated": "Permission '{permission}' mise à jour", - "dyndns_provider_unreachable": "Impossible d’atteindre le fournisseur DynDNS {provider} : votre YunoHost n’est pas correctement connecté à Internet ou le serveur Dynette est en panne.", + "dyndns_provider_unreachable": "Impossible d'atteindre le fournisseur DynDNS {provider} : votre YunoHost n'est pas correctement connecté à Internet ou le serveur Dynette est en panne.", "migrations_already_ran": "Ces migrations sont déjà effectuées : {ids}", "migrations_dependencies_not_satisfied": "Exécutez ces migrations : '{dependencies_id}', avant migration {id}.", "migrations_failed_to_load_migration": "Impossible de charger la migration {id} : {error}", "migrations_running_forward": "Exécution de la migration {id}...", "migrations_success_forward": "Migration {id} terminée", "operation_interrupted": "L'opération a-t-elle été interrompue manuellement ?", - "permission_already_exist": "L’autorisation '{permission}' existe déjà", + "permission_already_exist": "L'autorisation '{permission}' existe déjà", "permission_created": "Permission '{permission}' créée", - "permission_creation_failed": "Impossible de créer l’autorisation '{permission}' : {error}", + "permission_creation_failed": "Impossible de créer l'autorisation '{permission}' : {error}", "permission_deleted": "Permission '{permission}' supprimée", "permission_deletion_failed": "Impossible de supprimer la permission '{permission}' : {error}", "group_already_exist": "Le groupe {group} existe déjà", "group_already_exist_on_system": "Le groupe {group} existe déjà dans les groupes système", "group_cannot_be_deleted": "Le groupe {group} ne peut pas être supprimé manuellement.", - "group_user_already_in_group": "L’utilisateur {user} est déjà dans le groupe {group}", - "group_user_not_in_group": "L’utilisateur {user} n’est pas dans le groupe {group}", + "group_user_already_in_group": "L'utilisateur {user} est déjà dans le groupe {group}", + "group_user_not_in_group": "L'utilisateur {user} n'est pas dans le groupe {group}", "log_permission_create": "Créer permission '{}'", "log_permission_delete": "Supprimer permission '{}'", "log_user_group_create": "Créer le groupe '{}'", "log_user_permission_update": "Mise à jour des accès pour la permission '{}'", "log_user_permission_reset": "Réinitialiser la permission '{}'", - "permission_already_allowed": "Le groupe '{group}' a déjà l’autorisation '{permission}' activée", - "permission_already_disallowed": "Le groupe '{group}' a déjà l’autorisation '{permission}' désactivé", - "permission_cannot_remove_main": "Supprimer une autorisation principale n’est pas autorisé", - "user_already_exists": "L’utilisateur '{user}' existe déjà", - "app_full_domain_unavailable": "Désolé, cette application doit être installée sur un domaine qui lui est propre, mais d’autres applications sont déjà installées sur le domaine '{domain}'. Vous pouvez utiliser un sous-domaine dédié à cette application à la place.", - "group_cannot_edit_all_users": "Le groupe 'all_users' ne peut pas être édité manuellement. C’est un groupe spécial destiné à contenir tous les utilisateurs enregistrés dans YunoHost", - "group_cannot_edit_visitors": "Le groupe 'visiteurs' ne peut pas être édité manuellement. C’est un groupe spécial représentant les visiteurs anonymes", - "group_cannot_edit_primary_group": "Le groupe '{group}' ne peut pas être édité manuellement. C’est le groupe principal destiné à ne contenir qu’un utilisateur spécifique.", - "log_permission_url": "Mise à jour de l’URL associée à l’autorisation '{}'", - "permission_already_up_to_date": "L’autorisation n’a pas été mise à jour car les demandes d’ajout/suppression correspondent déjà à l’état actuel.", - "permission_currently_allowed_for_all_users": "Cette autorisation est actuellement accordée à tous les utilisateurs en plus des autres groupes. Vous voudrez probablement soit supprimer l’autorisation 'all_users', soit supprimer les autres groupes auxquels il est actuellement autorisé.", - "app_install_failed": "Impossible d’installer {app} : {error}", - "app_install_script_failed": "Une erreur est survenue dans le script d’installation de l’application", - "permission_require_account": "Permission {permission} n’a de sens que pour les utilisateurs ayant un compte et ne peut donc pas être activé pour les visiteurs.", - "app_remove_after_failed_install": "Supprimer l’application après l’échec de l’installation...", - "diagnosis_cant_run_because_of_dep": "Impossible d’exécuter le diagnostic pour {category} alors qu’il existe des problèmes importants liés à {dep}.", + "permission_already_allowed": "Le groupe '{group}' a déjà l'autorisation '{permission}' activée", + "permission_already_disallowed": "Le groupe '{group}' a déjà l'autorisation '{permission}' désactivé", + "permission_cannot_remove_main": "Supprimer une autorisation principale n'est pas autorisé", + "user_already_exists": "L'utilisateur '{user}' existe déjà", + "app_full_domain_unavailable": "Désolé, cette application doit être installée sur un domaine qui lui est propre, mais d'autres applications sont déjà installées sur le domaine '{domain}'. Vous pouvez utiliser un sous-domaine dédié à cette application à la place.", + "group_cannot_edit_all_users": "Le groupe 'all_users' ne peut pas être édité manuellement. C'est un groupe spécial destiné à contenir tous les utilisateurs enregistrés dans YunoHost", + "group_cannot_edit_visitors": "Le groupe 'visiteurs' ne peut pas être édité manuellement. C'est un groupe spécial représentant les visiteurs anonymes", + "group_cannot_edit_primary_group": "Le groupe '{group}' ne peut pas être édité manuellement. C'est le groupe principal destiné à ne contenir qu'un utilisateur spécifique.", + "log_permission_url": "Mise à jour de l'URL associée à l'autorisation '{}'", + "permission_already_up_to_date": "L'autorisation n'a pas été mise à jour car les demandes d'ajout/suppression correspondent déjà à l'état actuel.", + "permission_currently_allowed_for_all_users": "Cette autorisation est actuellement accordée à tous les utilisateurs en plus des autres groupes. Vous voudrez probablement soit supprimer l'autorisation 'all_users', soit supprimer les autres groupes auxquels il est actuellement autorisé.", + "app_install_failed": "Impossible d'installer {app} : {error}", + "app_install_script_failed": "Une erreur est survenue dans le script d'installation de l'application", + "permission_require_account": "Permission {permission} n'a de sens que pour les utilisateurs ayant un compte et ne peut donc pas être activé pour les visiteurs.", + "app_remove_after_failed_install": "Supprimer l'application après l'échec de l'installation...", + "diagnosis_cant_run_because_of_dep": "Impossible d'exécuter le diagnostic pour {category} alors qu'il existe des problèmes importants liés à {dep}.", "diagnosis_found_errors": "Trouvé {errors} problème(s) significatif(s) lié(s) à {category} !", "diagnosis_found_errors_and_warnings": "Trouvé {errors} problème(s) significatif(s) (et {warnings} (avertissement(s)) en relation avec {category} !", "diagnosis_ip_not_connected_at_all": "Le serveur ne semble pas du tout connecté à Internet !?", "diagnosis_ip_weird_resolvconf": "La résolution DNS semble fonctionner, mais il semble que vous utilisez un /etc/resolv.conf personnalisé.", "diagnosis_ip_weird_resolvconf_details": "Le fichier /etc/resolv.conf doit être un lien symbolique vers /etc/resolvconf/run/resolv.conf lui-même pointant vers 127.0.0.1 (dnsmasq). Si vous souhaitez configurer manuellement les résolveurs DNS, veuillez modifier /etc/resolv.dnsmasq.conf.", "diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS
Type : {type}
Nom : {name}
Valeur: {value}", - "diagnosis_diskusage_ok": "L’espace de stockage {mountpoint} (sur le périphérique {device}) a encore {free} ({free_percent}%) espace restant (sur {total}) !", + "diagnosis_diskusage_ok": "L'espace de stockage {mountpoint} (sur le périphérique {device}) a encore {free} ({free_percent}%) espace restant (sur {total}) !", "diagnosis_ram_ok": "Le système dispose encore de {available} ({available_percent}%) de RAM sur {total}.", "diagnosis_regenconf_allgood": "Tous les fichiers de configuration sont conformes à la configuration recommandée !", "diagnosis_security_vulnerable_to_meltdown": "Vous semblez vulnérable à la vulnérabilité de sécurité critique de Meltdown", @@ -429,7 +429,7 @@ "diagnosis_basesystem_kernel": "Le serveur utilise le noyau Linux {kernel_version}", "diagnosis_basesystem_ynh_single_version": "{package} version : {version} ({repo})", "diagnosis_basesystem_ynh_main_version": "Le serveur utilise YunoHost {main_version} ({repo})", - "diagnosis_basesystem_ynh_inconsistent_versions": "Vous exécutez des versions incohérentes des packages YunoHost ... très probablement en raison d’une mise à niveau échouée ou partielle.", + "diagnosis_basesystem_ynh_inconsistent_versions": "Vous exécutez des versions incohérentes des packages YunoHost ... très probablement en raison d'une mise à niveau échouée ou partielle.", "diagnosis_failed_for_category": "Échec du diagnostic pour la catégorie '{category}': {error}", "diagnosis_cache_still_valid": "(Le cache est encore valide pour le diagnostic {category}. Il ne sera pas re-diagnostiqué pour le moment!)", "diagnosis_ignored_issues": "(+ {nb_ignored} problème(s) ignoré(s))", @@ -437,30 +437,30 @@ "diagnosis_everything_ok": "Tout semble bien pour {category} !", "diagnosis_failed": "Échec de la récupération du résultat du diagnostic pour la catégorie '{category}' : {error}", "diagnosis_ip_connected_ipv4": "Le serveur est connecté à Internet en IPv4 !", - "diagnosis_ip_no_ipv4": "Le serveur ne dispose pas d’une adresse IPv4.", + "diagnosis_ip_no_ipv4": "Le serveur ne dispose pas d'une adresse IPv4.", "diagnosis_ip_connected_ipv6": "Le serveur est connecté à Internet en IPv6 !", - "diagnosis_ip_no_ipv6": "Le serveur ne dispose pas d’une adresse IPv6.", + "diagnosis_ip_no_ipv6": "Le serveur ne dispose pas d'une adresse IPv6.", "diagnosis_ip_dnsresolution_working": "La résolution de nom de domaine fonctionne !", - "diagnosis_ip_broken_dnsresolution": "La résolution du nom de domaine semble interrompue pour une raison quelconque … Un pare-feu bloque-t-il les requêtes DNS ?", + "diagnosis_ip_broken_dnsresolution": "La résolution du nom de domaine semble interrompue pour une raison quelconque ... Un pare-feu bloque-t-il les requêtes DNS ?", "diagnosis_ip_broken_resolvconf": "La résolution du nom de domaine semble être cassée sur votre serveur, ce qui semble lié au fait que /etc/resolv.conf ne pointe pas vers 127.0.0.1.", "diagnosis_dns_good_conf": "Les enregistrements DNS sont correctement configurés pour le domaine {domain} (catégorie {category})", "diagnosis_dns_bad_conf": "Certains enregistrements DNS sont manquants ou incorrects pour le domaine {domain} (catégorie {category})", "diagnosis_dns_discrepancy": "Cet enregistrement DNS ne semble pas correspondre à la configuration recommandée :
Type : {type}
Nom : {name}
La valeur actuelle est : {current}
La valeur attendue est : {value}", "diagnosis_services_bad_status": "Le service {service} est {status} :-(", - "diagnosis_diskusage_verylow": "L'espace de stockage {mountpoint} (sur l’appareil {device}) ne dispose que de {free} ({free_percent}%) espace restant (sur {total}). Vous devriez vraiment envisager de nettoyer de l’espace !", + "diagnosis_diskusage_verylow": "L'espace de stockage {mountpoint} (sur l'appareil {device}) ne dispose que de {free} ({free_percent}%) espace restant (sur {total}). Vous devriez vraiment envisager de nettoyer de l'espace !", "diagnosis_diskusage_low": "L'espace de stockage {mountpoint} (sur l'appareil {device}) ne dispose que de {free} ({free_percent}%) espace restant (sur {total}). Faites attention.", "diagnosis_ram_verylow": "Le système ne dispose plus que de {available} ({available_percent}%)! (sur {total})", - "diagnosis_ram_low": "Le système n’a plus de {available} ({available_percent}%) RAM sur {total}. Faites attention.", - "diagnosis_swap_none": "Le système n’a aucun espace de swap. Vous devriez envisager d’ajouter au moins {recommended} de swap pour éviter les situations où le système manque de mémoire.", - "diagnosis_swap_notsomuch": "Le système ne dispose que de {total} de swap. Vous devez envisager d’avoir au moins {recommended} pour éviter les situations où le système manque de mémoire.", + "diagnosis_ram_low": "Le système n'a plus de {available} ({available_percent}%) RAM sur {total}. Faites attention.", + "diagnosis_swap_none": "Le système n'a aucun espace de swap. Vous devriez envisager d'ajouter au moins {recommended} de swap pour éviter les situations où le système manque de mémoire.", + "diagnosis_swap_notsomuch": "Le système ne dispose que de {total} de swap. Vous devez envisager d'avoir au moins {recommended} pour éviter les situations où le système manque de mémoire.", "diagnosis_swap_ok": "Le système dispose de {total} de swap !", "diagnosis_regenconf_manually_modified": "Le fichier de configuration {file} semble avoir été modifié manuellement.", - "diagnosis_regenconf_manually_modified_details": "C’est probablement OK si vous savez ce que vous faites ! YunoHost cessera de mettre à jour ce fichier automatiquement ... Mais attention, les mises à jour de YunoHost pourraient contenir d’importantes modifications recommandées. Si vous le souhaitez, vous pouvez inspecter les différences avec yunohost tools regen-conf {category} --dry-run --with-diff et forcer la réinitialisation à la configuration recommandée avec yunohost tools regen-conf {category} --force", - "apps_catalog_init_success": "Système de catalogue d’applications initialisé !", + "diagnosis_regenconf_manually_modified_details": "C'est probablement OK si vous savez ce que vous faites ! YunoHost cessera de mettre à jour ce fichier automatiquement ... Mais attention, les mises à jour de YunoHost pourraient contenir d'importantes modifications recommandées. Si vous le souhaitez, vous pouvez inspecter les différences avec yunohost tools regen-conf {category} --dry-run --with-diff et forcer la réinitialisation à la configuration recommandée avec yunohost tools regen-conf {category} --force", + "apps_catalog_init_success": "Système de catalogue d'applications initialisé !", "apps_catalog_failed_to_download": "Impossible de télécharger le catalogue des applications {apps_catalog} : {error}", - "diagnosis_mail_outgoing_port_25_blocked": "Le port sortant 25 semble être bloqué. Vous devriez essayer de le débloquer dans le panneau de configuration de votre fournisseur de services Internet (ou hébergeur). En attendant, le serveur ne pourra pas envoyer des courriels à d’autres serveurs.", - "domain_cannot_remove_main_add_new_one": "Vous ne pouvez pas supprimer '{domain}' car il s’agit du domaine principal et de votre seul domaine. Vous devez d’abord ajouter un autre domaine à l’aide de 'yunohost domain add ', puis définir comme domaine principal à l’aide de 'yunohost domain main-domain -n ' et vous pouvez ensuite supprimer le domaine '{domain}' à l’aide de 'yunohost domain remove {domain}'.'", - "diagnosis_security_vulnerable_to_meltdown_details": "Pour résoudre ce problème, vous devez mettre à niveau votre système et redémarrer pour charger le nouveau noyau Linux (ou contacter votre fournisseur de serveur si cela ne fonctionne pas). Voir https://meltdownattack.com/ pour plus d’informations.", + "diagnosis_mail_outgoing_port_25_blocked": "Le port sortant 25 semble être bloqué. Vous devriez essayer de le débloquer dans le panneau de configuration de votre fournisseur de services Internet (ou hébergeur). En attendant, le serveur ne pourra pas envoyer des emails à d'autres serveurs.", + "domain_cannot_remove_main_add_new_one": "Vous ne pouvez pas supprimer '{domain}' car il s'agit du domaine principal et de votre seul domaine. Vous devez d'abord ajouter un autre domaine à l'aide de 'yunohost domain add ', puis définir comme domaine principal à l'aide de 'yunohost domain main-domain -n ' et vous pouvez ensuite supprimer le domaine '{domain}' à l'aide de 'yunohost domain remove {domain}'.'", + "diagnosis_security_vulnerable_to_meltdown_details": "Pour résoudre ce problème, vous devez mettre à niveau votre système et redémarrer pour charger le nouveau noyau Linux (ou contacter votre fournisseur de serveur si cela ne fonctionne pas). Voir https://meltdownattack.com/ pour plus d'informations.", "diagnosis_description_basesystem": "Système de base", "diagnosis_description_ip": "Connectivité Internet", "diagnosis_description_dnsrecords": "Enregistrements DNS", @@ -470,76 +470,76 @@ "diagnosis_description_regenconf": "Configurations système", "diagnosis_ports_could_not_diagnose": "Impossible de diagnostiquer si les ports sont accessibles de l'extérieur.", "diagnosis_ports_could_not_diagnose_details": "Erreur : {error}", - "apps_catalog_updating": "Mise à jour du catalogue d’applications…", + "apps_catalog_updating": "Mise à jour du catalogue d'applications...", "apps_catalog_obsolete_cache": "Le cache du catalogue d'applications est vide ou obsolète.", "apps_catalog_update_success": "Le catalogue des applications a été mis à jour !", "diagnosis_description_mail": "Email", - "diagnosis_ports_unreachable": "Le port {port} n’est pas accessible de l’extérieur.", - "diagnosis_ports_ok": "Le port {port} est accessible de l’extérieur.", - "diagnosis_http_could_not_diagnose": "Impossible de diagnostiquer si le domaine est accessible de l’extérieur.", + "diagnosis_ports_unreachable": "Le port {port} n'est pas accessible de l'extérieur.", + "diagnosis_ports_ok": "Le port {port} est accessible de l'extérieur.", + "diagnosis_http_could_not_diagnose": "Impossible de diagnostiquer si le domaine est accessible de l'extérieur.", "diagnosis_http_could_not_diagnose_details": "Erreur : {error}", - "diagnosis_http_ok": "Le domaine {domain} est accessible en HTTP depuis l’extérieur.", - "diagnosis_http_unreachable": "Le domaine {domain} est inaccessible en HTTP depuis l’extérieur.", + "diagnosis_http_ok": "Le domaine {domain} est accessible en HTTP depuis l'extérieur.", + "diagnosis_http_unreachable": "Le domaine {domain} est inaccessible en HTTP depuis l'extérieur.", "diagnosis_unknown_categories": "Les catégories suivantes sont inconnues : {categories}", - "app_upgrade_script_failed": "Une erreur s’est produite durant l’exécution du script de mise à niveau de l’application", + "app_upgrade_script_failed": "Une erreur s'est produite durant l'exécution du script de mise à niveau de l'application", "diagnosis_services_running": "Le service {service} est en cours de fonctionnement !", "diagnosis_services_conf_broken": "La configuration est cassée pour le service {service} !", "diagnosis_ports_needed_by": "Rendre ce port accessible est nécessaire pour les fonctionnalités de type {category} (service {service})", "diagnosis_ports_forwarding_tip": "Pour résoudre ce problème, vous devez probablement configurer la redirection de port sur votre routeur Internet comme décrit dans https://yunohost.org/isp_box_config", - "diagnosis_http_connection_error": "Erreur de connexion : impossible de se connecter au domaine demandé, il est probablement injoignable.", - "diagnosis_no_cache": "Pas encore de cache de diagnostique pour la catégorie « {category} »", - "yunohost_postinstall_end_tip": "La post-installation terminée ! Pour finaliser votre configuration, il est recommandé de :\n- ajouter un premier utilisateur depuis la section \"Utilisateurs\" de l’interface web (ou 'yunohost user create ' en ligne de commande) ;\n- diagnostiquer les potentiels problèmes dans la section \"Diagnostic\" de l'interface web (ou 'yunohost diagnosis run' en ligne de commande) ;\n- lire les parties 'Finalisation de votre configuration' et 'Découverte de YunoHost' dans le guide de l’administrateur : https://yunohost.org/admindoc.", + "diagnosis_http_connection_error": "Erreur de connexion : impossible de se connecter au domaine demandé, il est probablement injoignable.", + "diagnosis_no_cache": "Pas encore de cache de diagnostique pour la catégorie '{category}'", + "yunohost_postinstall_end_tip": "La post-installation terminée ! Pour finaliser votre configuration, il est recommandé de :\n- ajouter un premier utilisateur depuis la section \"Utilisateurs\" de l'interface web (ou 'yunohost user create ' en ligne de commande) ;\n- diagnostiquer les potentiels problèmes dans la section \"Diagnostic\" de l'interface web (ou 'yunohost diagnosis run' en ligne de commande) ;\n- lire les parties 'Finalisation de votre configuration' et 'Découverte de YunoHost' dans le guide de l'administrateur : https://yunohost.org/admindoc.", "diagnosis_services_bad_status_tip": "Vous pouvez essayer de redémarrer le service, et si cela ne fonctionne pas, consultez les journaux de service dans le webadmin (à partir de la ligne de commande, vous pouvez le faire avec yunohost service restart {service} et yunohost service log {service} ).", - "diagnosis_http_bad_status_code": "Le système de diagnostique n’a pas réussi à contacter votre serveur. Il se peut qu’une autre machine réponde à la place de votre serveur. Vérifiez que le port 80 est correctement redirigé, que votre configuration Nginx est à jour et qu’un reverse-proxy n’interfère pas.", - "diagnosis_http_timeout": "Expiration du délai en essayant de contacter votre serveur de l’extérieur. Il semble être inaccessible. Vérifiez que vous transférez correctement le port 80, que Nginx est en cours d’exécution et qu’un pare-feu n’interfère pas.", + "diagnosis_http_bad_status_code": "Le système de diagnostique n'a pas réussi à contacter votre serveur. Il se peut qu'une autre machine réponde à la place de votre serveur. Vérifiez que le port 80 est correctement redirigé, que votre configuration Nginx est à jour et qu'un reverse-proxy n'interfère pas.", + "diagnosis_http_timeout": "Expiration du délai en essayant de contacter votre serveur de l'extérieur. Il semble être inaccessible. Vérifiez que vous transférez correctement le port 80, que Nginx est en cours d'exécution et qu'un pare-feu n'interfère pas.", "global_settings_setting_pop3_enabled": "Activer le protocole POP3 pour le serveur de messagerie", - "log_app_action_run": "Lancer l’action de l’application '{}'", - "log_app_config_show_panel": "Montrer le panneau de configuration de l’application '{}'", - "log_app_config_apply": "Appliquer la configuration à l’application '{}'", - "diagnosis_never_ran_yet": "Il apparaît que le serveur a été installé récemment et qu’il n’y a pas encore eu de diagnostic. Vous devriez en lancer un depuis la web-admin ou en utilisant 'yunohost diagnosis run' depuis la ligne de commande.", + "log_app_action_run": "Lancer l'action de l'application '{}'", + "log_app_config_show_panel": "Montrer le panneau de configuration de l'application '{}'", + "log_app_config_apply": "Appliquer la configuration à l'application '{}'", + "diagnosis_never_ran_yet": "Il apparaît que le serveur a été installé récemment et qu'il n'y a pas encore eu de diagnostic. Vous devriez en lancer un depuis la web-admin ou en utilisant 'yunohost diagnosis run' depuis la ligne de commande.", "diagnosis_description_web": "Web", - "diagnosis_basesystem_hardware": "L’architecture du serveur est {virt} {arch}", + "diagnosis_basesystem_hardware": "L'architecture du serveur est {virt} {arch}", "group_already_exist_on_system_but_removing_it": "Le groupe {group} est déjà présent dans les groupes du système, mais YunoHost va le supprimer...", - "certmanager_warning_subdomain_dns_record": "Le sous-domaine '{subdomain}' ne résout pas vers la même adresse IP que '{domain}'. Certaines fonctionnalités seront indisponibles tant que vous n’aurez pas corrigé cela et regénéré le certificat.", - "domain_cannot_add_xmpp_upload": "Vous ne pouvez pas ajouter de domaine commençant par 'xmpp-upload.'. Ce type de nom est réservé à la fonctionnalité d’upload XMPP intégrée dans YunoHost.", - "diagnosis_mail_outgoing_port_25_ok": "Le serveur de messagerie SMTP peut envoyer des courriels (le port sortant 25 n'est pas bloqué).", - "diagnosis_mail_outgoing_port_25_blocked_details": "Vous devez d’abord essayer de débloquer le port sortant 25 dans votre interface de routeur Internet ou votre interface d’hébergement. (Certains hébergeurs peuvent vous demander de leur envoyer un ticket de support pour cela).", + "certmanager_warning_subdomain_dns_record": "Le sous-domaine '{subdomain}' ne résout pas vers la même adresse IP que '{domain}'. Certaines fonctionnalités seront indisponibles tant que vous n'aurez pas corrigé cela et regénéré le certificat.", + "domain_cannot_add_xmpp_upload": "Vous ne pouvez pas ajouter de domaine commençant par 'xmpp-upload.'. Ce type de nom est réservé à la fonctionnalité d'upload XMPP intégrée dans YunoHost.", + "diagnosis_mail_outgoing_port_25_ok": "Le serveur de messagerie SMTP peut envoyer des emails (le port sortant 25 n'est pas bloqué).", + "diagnosis_mail_outgoing_port_25_blocked_details": "Vous devez d'abord essayer de débloquer le port sortant 25 dans votre interface de routeur Internet ou votre interface d'hébergement. (Certains hébergeurs peuvent vous demander de leur envoyer un ticket de support pour cela).", "diagnosis_mail_ehlo_bad_answer": "Un service non SMTP a répondu sur le port 25 en IPv{ipversion}", "diagnosis_mail_ehlo_bad_answer_details": "Cela peut être dû à une autre machine qui répond au lieu de votre serveur.", - "diagnosis_mail_ehlo_wrong": "Un autre serveur de messagerie SMTP répond sur IPv{ipversion}. Votre serveur ne sera probablement pas en mesure de recevoir des courriel.", - "diagnosis_mail_ehlo_could_not_diagnose": "Impossible de diagnostiquer si le serveur de messagerie postfix est accessible de l’extérieur en IPv{ipversion}.", + "diagnosis_mail_ehlo_wrong": "Un autre serveur de messagerie SMTP répond sur IPv{ipversion}. Votre serveur ne sera probablement pas en mesure de recevoir des email.", + "diagnosis_mail_ehlo_could_not_diagnose": "Impossible de diagnostiquer si le serveur de messagerie postfix est accessible de l'extérieur en IPv{ipversion}.", "diagnosis_mail_ehlo_could_not_diagnose_details": "Erreur : {error}", - "diagnosis_mail_fcrdns_dns_missing": "Aucun DNS inverse n’est défini pour IPv{ipversion}. Certains emails seront peut-être refusés ou considérés comme des spam.", + "diagnosis_mail_fcrdns_dns_missing": "Aucun DNS inverse n'est défini pour IPv{ipversion}. Certains emails seront peut-être refusés ou considérés comme des spam.", "diagnosis_mail_fcrdns_ok": "Votre DNS inverse est correctement configuré !", - "diagnosis_mail_fcrdns_nok_details": "Vous devez d’abord essayer de configurer le DNS inverse avec {ehlo_domain} dans votre interface de routeur Internet ou votre interface d’hébergement. (Certains hébergeurs peuvent vous demander de leur envoyer un ticket de support pour cela).", + "diagnosis_mail_fcrdns_nok_details": "Vous devez d'abord essayer de configurer le DNS inverse avec {ehlo_domain} dans votre interface de routeur Internet ou votre interface d'hébergement. (Certains hébergeurs peuvent vous demander de leur envoyer un ticket de support pour cela).", "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Le DNS inverse n'est pas correctement configuré en IPv{ipversion}. Certains emails seront peut-être refusés ou considérés comme des spam.", "diagnosis_mail_blacklist_ok": "Les adresses IP et les domaines utilisés par ce serveur ne semblent pas être sur liste noire", "diagnosis_mail_blacklist_reason": "La raison de la liste noire est : {reason}", - "diagnosis_mail_blacklist_website": "Après avoir identifié la raison pour laquelle vous êtes répertorié et l'avoir corrigé, n’hésitez pas à demander le retrait de votre IP ou domaine sur {blacklist_website}", + "diagnosis_mail_blacklist_website": "Après avoir identifié la raison pour laquelle vous êtes répertorié et l'avoir corrigé, n'hésitez pas à demander le retrait de votre IP ou domaine sur {blacklist_website}", "diagnosis_mail_queue_ok": "{nb_pending} emails en attente dans les files d'attente de messagerie", "diagnosis_mail_queue_unavailable_details": "Erreur : {error}", - "diagnosis_mail_queue_too_big": "Trop d’emails en attente dans la file d'attente ({nb_pending} e-mails)", - "global_settings_setting_smtp_allow_ipv6": "Autoriser l'utilisation d’IPv6 pour recevoir et envoyer du courrier", - "diagnosis_display_tip": "Pour voir les problèmes détectés, vous pouvez accéder à la section Diagnostic du webadmin ou exécuter « yunohost diagnosis show --issues --human-readable» à partir de la ligne de commande.", + "diagnosis_mail_queue_too_big": "Trop d'emails en attente dans la file d'attente ({nb_pending} emails)", + "global_settings_setting_smtp_allow_ipv6": "Autoriser l'utilisation d'IPv6 pour recevoir et envoyer du courrier", + "diagnosis_display_tip": "Pour voir les problèmes détectés, vous pouvez accéder à la section Diagnostic du webadmin ou exécuter 'yunohost diagnosis show --issues --human-readable' à partir de la ligne de commande.", "diagnosis_ip_global": "IP globale : {global}", "diagnosis_ip_local": "IP locale : {local}", - "diagnosis_dns_point_to_doc": "Veuillez consulter la documentation sur https://yunohost.org/dns_config si vous avez besoin d’aide pour configurer les enregistrements DNS.", - "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Certains fournisseurs ne vous laisseront pas débloquer le port sortant 25 parce qu’ils ne se soucient pas de la neutralité du Net.
- Certains d’entre eux offrent l’alternative d'utiliser un serveur de messagerie relai bien que cela implique que le relai sera en mesure d’espionner votre trafic de messagerie.
- Une alternative respectueuse de la vie privée consiste à utiliser un VPN *avec une IP publique dédiée* pour contourner ce type de limites. Voir https://yunohost.org/#/vpn_advantage
- Vous pouvez également envisager de passer à un fournisseur plus respectueux de la neutralité du net", - "diagnosis_mail_ehlo_ok": "Le serveur de messagerie SMTP est accessible de l'extérieur et peut donc recevoir des courriels !", - "diagnosis_mail_ehlo_unreachable": "Le serveur de messagerie SMTP est inaccessible de l’extérieur en IPv{ipversion}. Il ne pourra pas recevoir des courriels.", + "diagnosis_dns_point_to_doc": "Veuillez consulter la documentation sur https://yunohost.org/dns_config si vous avez besoin d'aide pour configurer les enregistrements DNS.", + "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Certains fournisseurs ne vous laisseront pas débloquer le port sortant 25 parce qu'ils ne se soucient pas de la neutralité du Net.
- Certains d'entre eux offrent l'alternative d'utiliser un serveur de messagerie relai bien que cela implique que le relai sera en mesure d'espionner votre trafic de messagerie.
- Une alternative respectueuse de la vie privée consiste à utiliser un VPN *avec une IP publique dédiée* pour contourner ce type de limites. Voir https://yunohost.org/#/vpn_advantage
- Vous pouvez également envisager de passer à un fournisseur plus respectueux de la neutralité du net", + "diagnosis_mail_ehlo_ok": "Le serveur de messagerie SMTP est accessible de l'extérieur et peut donc recevoir des emails !", + "diagnosis_mail_ehlo_unreachable": "Le serveur de messagerie SMTP est inaccessible de l'extérieur en IPv{ipversion}. Il ne pourra pas recevoir des emails.", "diagnosis_mail_ehlo_unreachable_details": "Impossible d'ouvrir une connexion sur le port 25 à votre serveur en IPv{ipversion}. Il semble inaccessible.
1. La cause la plus courante de ce problème est que le port 25 n'est pas correctement redirigé vers votre serveur.
2. Vous devez également vous assurer que le service postfix est en cours d'exécution.
3. Sur les configurations plus complexes: assurez-vous qu'aucun pare-feu ou proxy inversé n'interfère.", - "diagnosis_mail_ehlo_wrong_details": "Le EHLO reçu par le serveur de diagnostique distant en IPv{ipversion} est différent du domaine de votre serveur.
EHLO reçu: {wrong_ehlo}
Attendu : {right_ehlo}
La cause la plus courante ce problème est que le port 25 n’est pas correctement redirigé vers votre serveur . Vous pouvez également vous assurer qu’aucun pare-feu ou proxy inversé n’interfère.", - "diagnosis_mail_fcrdns_nok_alternatives_4": "Certains fournisseurs ne vous laisseront pas configurer votre DNS inversé (ou leur fonctionnalité pourrait être cassée...). Si vous rencontrez des problèmes à cause de cela, envisagez les solutions suivantes :
- Certains FAI fournissent l’alternative de à l’aide d’un relais de serveur de messagerie bien que cela implique que le relais pourra espionner votre trafic de messagerie.
- Une alternative respectueuse de la vie privée consiste à utiliser un VPN *avec une IP publique dédiée* pour contourner ce type de limites. Voir https://yunohost.org/#/vpn_advantage
- Enfin, il est également possible de changer de fournisseur", - "diagnosis_mail_fcrdns_nok_alternatives_6": "Certains fournisseurs ne vous laisseront pas configurer votre DNS inversé (ou leur fonctionnalité pourrait être cassée...). Si votre DNS inversé est correctement configuré en IPv4, vous pouvez essayer de désactiver l'utilisation d'IPv6 lors de l'envoi d'emails en exécutant yunohost settings set smtp.allow_ipv6 -v off. Remarque : cette dernière solution signifie que vous ne pourrez pas envoyer ou recevoir de courriels avec les quelques serveurs qui ont uniquement de l'IPv6.", + "diagnosis_mail_ehlo_wrong_details": "Le EHLO reçu par le serveur de diagnostique distant en IPv{ipversion} est différent du domaine de votre serveur.
EHLO reçu: {wrong_ehlo}
Attendu : {right_ehlo}
La cause la plus courante ce problème est que le port 25 n'est pas correctement redirigé vers votre serveur . Vous pouvez également vous assurer qu'aucun pare-feu ou proxy inversé n'interfère.", + "diagnosis_mail_fcrdns_nok_alternatives_4": "Certains fournisseurs ne vous laisseront pas configurer votre DNS inversé (ou leur fonctionnalité pourrait être cassée...). Si vous rencontrez des problèmes à cause de cela, envisagez les solutions suivantes :
- Certains FAI fournissent l'alternative de à l'aide d'un relais de serveur de messagerie bien que cela implique que le relais pourra espionner votre trafic de messagerie.
- Une alternative respectueuse de la vie privée consiste à utiliser un VPN *avec une IP publique dédiée* pour contourner ce type de limites. Voir https://yunohost.org/#/vpn_advantage
- Enfin, il est également possible de changer de fournisseur", + "diagnosis_mail_fcrdns_nok_alternatives_6": "Certains fournisseurs ne vous laisseront pas configurer votre DNS inversé (ou leur fonctionnalité pourrait être cassée...). Si votre DNS inversé est correctement configuré en IPv4, vous pouvez essayer de désactiver l'utilisation d'IPv6 lors de l'envoi d'emails en exécutant yunohost settings set smtp.allow_ipv6 -v off. Remarque : cette dernière solution signifie que vous ne pourrez pas envoyer ou recevoir de emails avec les quelques serveurs qui ont uniquement de l'IPv6.", "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "DNS inverse actuel : {rdns_domain}
Valeur attendue : {ehlo_domain}", "diagnosis_mail_blacklist_listed_by": "Votre IP ou domaine {item} est sur liste noire sur {blacklist_name}", - "diagnosis_mail_queue_unavailable": "Impossible de consulter le nombre d’emails en attente dans la file d'attente", + "diagnosis_mail_queue_unavailable": "Impossible de consulter le nombre d'emails en attente dans la file d'attente", "diagnosis_ports_partially_unreachable": "Le port {port} n'est pas accessible de l'extérieur en IPv{failed}.", "diagnosis_http_hairpinning_issue": "Votre réseau local ne semble pas supporter l'hairpinning.", "diagnosis_http_hairpinning_issue_details": "C'est probablement à cause de la box/routeur de votre fournisseur d'accès internet. Par conséquent, les personnes extérieures à votre réseau local pourront accéder à votre serveur comme prévu, mais pas les personnes internes au réseau local (comme vous, probablement ?) si elles utilisent le nom de domaine ou l'IP globale. Vous pourrez peut-être améliorer la situation en consultant https://yunohost.org/dns_local_network", - "diagnosis_http_partially_unreachable": "Le domaine {domain} semble inaccessible en HTTP depuis l’extérieur du réseau local en IPv{failed}, bien qu’il fonctionne en IPv{passed}.", + "diagnosis_http_partially_unreachable": "Le domaine {domain} semble inaccessible en HTTP depuis l'extérieur du réseau local en IPv{failed}, bien qu'il fonctionne en IPv{passed}.", "diagnosis_http_nginx_conf_not_up_to_date": "La configuration Nginx de ce domaine semble avoir été modifiée manuellement et empêche YunoHost de diagnostiquer si elle est accessible en HTTP.", - "diagnosis_http_nginx_conf_not_up_to_date_details": "Pour corriger la situation, inspectez la différence avec la ligne de commande en utilisant les outils yunohost tools regen-conf nginx --dry-run --with-diff et si vous êtes d’accord, appliquez les modifications avec yunohost tools regen-conf nginx --force.", + "diagnosis_http_nginx_conf_not_up_to_date_details": "Pour corriger la situation, inspectez la différence avec la ligne de commande en utilisant les outils yunohost tools regen-conf nginx --dry-run --with-diff et si vous êtes d'accord, appliquez les modifications avec yunohost tools regen-conf nginx --force.", "backup_archive_cant_retrieve_info_json": "Impossible d'avoir des informations sur l'archive '{archive}'... Le fichier info.json ne peut pas être trouvé (ou n'est pas un fichier json valide).", "backup_archive_corrupted": "Il semble que l'archive de la sauvegarde '{archive}' est corrompue : {error}", "diagnosis_ip_no_ipv6_tip": "L'utilisation de IPv6 n'est pas obligatoire pour le fonctionnement de votre serveur, mais cela contribue à la santé d'Internet dans son ensemble. IPv6 généralement configuré automatiquement par votre système ou votre FAI s'il est disponible. Autrement, vous devrez prendre quelque minutes pour le configurer manuellement à l'aide de cette documentation: https://yunohost.org/#/ipv6. Si vous ne pouvez pas activer IPv6 ou si c'est trop technique pour vous, vous pouvez aussi ignorer cet avertissement sans que cela pose problème.", @@ -551,14 +551,14 @@ "diagnosis_domain_expiration_error": "Certains domaines vont expirer TRÈS PROCHAINEMENT !", "diagnosis_domain_expires_in": "{domain} expire dans {days} jours.", "certmanager_domain_not_diagnosed_yet": "Il n'y a pas encore de résultat de diagnostic pour le domaine {domain}. Merci de relancer un diagnostic pour les catégories 'Enregistrements DNS' et 'Web' dans la section Diagnostique pour vérifier si le domaine est prêt pour Let's Encrypt. (Ou si vous savez ce que vous faites, utilisez '--no-checks' pour désactiver la vérification.)", - "diagnosis_swap_tip": "Merci d'être prudent et conscient que si vous hébergez une partition SWAP sur une carte SD ou un disque SSD, cela risque de réduire drastiquement l’espérance de vie du périphérique.", + "diagnosis_swap_tip": "Merci d'être prudent et conscient que si vous hébergez une partition SWAP sur une carte SD ou un disque SSD, cela risque de réduire drastiquement l'espérance de vie du périphérique.", "restore_already_installed_apps": "Les applications suivantes ne peuvent pas être restaurées car elles sont déjà installées : {apps}", "regenconf_need_to_explicitly_specify_ssh": "La configuration de ssh a été modifiée manuellement. Vous devez explicitement indiquer la mention --force à \"ssh\" pour appliquer les changements.", "migration_0015_cleaning_up": "Nettoyage du cache et des paquets qui ne sont plus nécessaires ...", "migration_0015_specific_upgrade": "Démarrage de la mise à jour des paquets du système qui doivent être mis à jour séparément...", "migration_0015_modified_files": "Veuillez noter que les fichiers suivants ont été modifiés manuellement et pourraient être écrasés à la suite de la mise à niveau : {manually_modified_files}", "migration_0015_problematic_apps_warning": "Veuillez noter que des applications qui peuvent poser problèmes ont été détectées. Il semble qu'elles n'aient pas été installées à partir du catalogue d'applications YunoHost, ou bien qu'elles ne soient pas signalées comme \"fonctionnelles\". Par conséquent, il n'est pas possible de garantir que les applications suivantes fonctionneront encore après la mise à niveau : {problematic_apps}", - "migration_0015_general_warning": "Veuillez noter que cette migration est une opération délicate. L'équipe YunoHost a fait de son mieux pour la revérifier et la tester, mais la migration pourrait quand même casser des éléments du système ou de ses applications.\n\nIl est donc recommandé :\n…- de faire une sauvegarde de toute donnée ou application critique. Plus d'informations ici https://yunohost.org/backup ;\n…- d'être patient après le lancement de la migration. Selon votre connexion internet et votre matériel, la mise à niveau peut prendre jusqu'à quelques heures.", + "migration_0015_general_warning": "Veuillez noter que cette migration est une opération délicate. L'équipe YunoHost a fait de son mieux pour la revérifier et la tester, mais la migration pourrait quand même casser des éléments du système ou de ses applications.\n\nIl est donc recommandé :\n...- de faire une sauvegarde de toute donnée ou application critique. Plus d'informations ici https://yunohost.org/backup ;\n...- d'être patient après le lancement de la migration. Selon votre connexion internet et votre matériel, la mise à niveau peut prendre jusqu'à quelques heures.", "migration_0015_system_not_fully_up_to_date": "Votre système n'est pas entièrement à jour. Veuillez effectuer une mise à jour normale avant de lancer la migration vers Buster.", "migration_0015_not_enough_free_space": "L'espace libre est très faible dans /var/ ! Vous devriez avoir au moins 1 Go de libre pour effectuer cette migration.", "migration_0015_not_stretch": "La distribution Debian actuelle n'est pas Stretch !", @@ -615,9 +615,9 @@ "diagnosis_basesystem_hardware_model": "Le modèle/architecture du serveur est {model}", "diagnosis_backports_in_sources_list": "Il semble qu'apt (le gestionnaire de paquets) soit configuré pour utiliser le dépôt des rétroportages (backports). A moins que vous ne sachiez vraiment ce que vous faites, nous vous déconseillons fortement d'installer des paquets provenant des rétroportages, car cela risque de créer des instabilités ou des conflits sur votre système.", "postinstall_low_rootfsspace": "Le système de fichiers a une taille totale inférieure à 10 Go, ce qui est préoccupant et devrait attirer votre attention ! Vous allez certainement arriver à court d'espace disque (très) rapidement ! Il est recommandé d'avoir au moins 16 Go à la racine pour ce système de fichiers. Si vous voulez installer YunoHost malgré cet avertissement, relancez la post-installation avec --force-diskspace", - "domain_remove_confirm_apps_removal": "Le retrait de ce domaine retirera aussi ces applications :\n{apps}\n\nÊtes vous sûr de vouloir cela ? [{answers}]", - "diagnosis_rootfstotalspace_critical": "Le système de fichiers racine ne fait que {space} ! Vous allez certainement le remplir très rapidement ! Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers.", - "diagnosis_rootfstotalspace_warning": "Le système de fichiers racine n'est que de {space}. Cela peut suffire, mais faites attention car vous risquez de les remplir rapidement... Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers.", + "domain_remove_confirm_apps_removal": "Le retrait de ce domaine retirera aussi ces applications :\n{apps}\n\nÊtes vous sûr de vouloir cela ? [{answers}]", + "diagnosis_rootfstotalspace_critical": "Le système de fichiers racine ne fait que {space} ! Vous allez certainement le remplir très rapidement ! Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers.", + "diagnosis_rootfstotalspace_warning": "Le système de fichiers racine n'est que de {space}. Cela peut suffire, mais faites attention car vous risquez de les remplir rapidement... Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers.", "app_restore_script_failed": "Une erreur s'est produite dans le script de restauration de l'application", "restore_backup_too_old": "Cette sauvegarde ne peut pas être restaurée car elle provient d'une version trop ancienne de YunoHost.", "migration_update_LDAP_schema": "Mise à jour du schéma LDAP...", @@ -626,7 +626,7 @@ "migration_ldap_rollback_success": "Système rétabli dans son état initial.", "permission_cant_add_to_all_users": "L'autorisation {permission} ne peut pas être ajoutée à tous les utilisateurs.", "migration_ldap_migration_failed_trying_to_rollback": "Impossible de migrer... tentative de restauration du système.", - "migration_ldap_can_not_backup_before_migration": "La sauvegarde du système n'a pas pu être terminée avant l'échec de la migration. Erreur : {error }", + "migration_ldap_can_not_backup_before_migration": "La sauvegarde du système n'a pas pu être terminée avant l'échec de la migration. Erreur : {error }", "migration_ldap_backup_before_migration": "Création d'une sauvegarde de la base de données LDAP et des paramètres des applications avant la migration proprement dite.", "migration_description_0020_ssh_sftp_permissions": "Ajouter la prise en charge des autorisations SSH et SFTP", "global_settings_setting_security_ssh_port": "Port SSH", diff --git a/tests/reformat_fr_translations.py b/tests/reformat_fr_translations.py new file mode 100644 index 000000000..473ed99d4 --- /dev/null +++ b/tests/reformat_fr_translations.py @@ -0,0 +1,27 @@ +import re + +locale_folder = "locales/" +locale = open(locale_folder + "fr.json").read() + +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.update({ + "courriel": "email", + "e-mail": "email", + "Courriel": "Email", + "E-mail": "Email", + "« ": "'", + "«": "'", + " »": "'", + "»": "'", + "…": "...", + "’": "'", + #r"$(\w{1,2})'|( \w{1,2})'": r"\1\2’", +}) + +for pattern, replace in transformations.items(): + locale = re.compile(pattern).sub(replace, locale) + +open(locale_folder + "fr.json", "w").write(locale) From 33750f24d703a32bef94af345a1146280d16b4c4 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 2 Sep 2021 04:23:13 +0200 Subject: [PATCH 070/101] Remove unecessary :d} in i18n strings --- locales/ca.json | 8 ++++---- locales/de.json | 8 ++++---- locales/en.json | 8 ++++---- locales/eo.json | 8 ++++---- locales/es.json | 8 ++++---- locales/fa.json | 8 ++++---- locales/fr.json | 8 ++++---- locales/gl.json | 8 ++++---- locales/it.json | 8 ++++---- locales/nl.json | 4 ++-- locales/oc.json | 8 ++++---- locales/zh_Hans.json | 8 ++++---- 12 files changed, 46 insertions(+), 46 deletions(-) diff --git a/locales/ca.json b/locales/ca.json index d01c0da0b..5a128ebb8 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -240,8 +240,8 @@ "pattern_positive_number": "Ha de ser un nombre positiu", "pattern_username": "Ha d'estar compost per caràcters alfanumèrics en minúscula i guió baix exclusivament", "pattern_password_app": "Les contrasenyes no poden de tenir els següents caràcters: {forbidden_chars}", - "port_already_closed": "El port {port:d} ja està tancat per les connexions {ip_version}", - "port_already_opened": "El port {port:d} ja està obert per les connexions {ip_version}", + "port_already_closed": "El port {port} ja està tancat per les connexions {ip_version}", + "port_already_opened": "El port {port} ja està obert per les connexions {ip_version}", "regenconf_file_backed_up": "S'ha guardat una còpia de seguretat del fitxer de configuració «{conf}» a «{backup}»", "regenconf_file_copy_failed": "No s'ha pogut copiar el nou fitxer de configuració «{new}» a «{conf}»", "regenconf_file_kept_back": "S'espera que el fitxer de configuració «{conf}» sigui suprimit per regen-conf (categoria {category}) però s'ha mantingut.", @@ -265,8 +265,8 @@ "restore_extracting": "Extracció dels fitxers necessaris de l'arxiu…", "restore_failed": "No s'ha pogut restaurar el sistema", "restore_hook_unavailable": "El script de restauració «{part}» no està disponible en el sistema i tampoc és en l'arxiu", - "restore_may_be_not_enough_disk_space": "Sembla que no hi ha prou espai disponible en el sistema (lliure: {free_space:d} B, espai necessari: {needed_space:d} B, marge de seguretat: {margin:d} B)", - "restore_not_enough_disk_space": "No hi ha prou espai disponible (espai: {free_space:d} B, espai necessari: {needed_space:d} B, marge de seguretat: {margin:d} B)", + "restore_may_be_not_enough_disk_space": "Sembla que no hi ha prou espai disponible en el sistema (lliure: {free_space} B, espai necessari: {needed_space} B, marge de seguretat: {margin} B)", + "restore_not_enough_disk_space": "No hi ha prou espai disponible (espai: {free_space} B, espai necessari: {needed_space} B, marge de seguretat: {margin} B)", "restore_nothings_done": "No s'ha restaurat res", "restore_removing_tmp_dir_failed": "No s'ha pogut eliminar un directori temporal antic", "restore_running_app_script": "Restaurant l'aplicació «{app}»…", diff --git a/locales/de.json b/locales/de.json index 0580eac1d..fe4112934 100644 --- a/locales/de.json +++ b/locales/de.json @@ -83,8 +83,8 @@ "pattern_password": "Muss mindestens drei Zeichen lang sein", "pattern_port_or_range": "Muss ein valider Port (z.B. 0-65535) oder ein Bereich (z.B. 100:200) sein", "pattern_username": "Darf nur aus klein geschriebenen alphanumerischen Zeichen und Unterstrichen bestehen", - "port_already_closed": "Der Port {port:d} wurde bereits für {ip_version} Verbindungen geschlossen", - "port_already_opened": "Der Port {port:d} wird bereits von {ip_version} benutzt", + "port_already_closed": "Der Port {port} wurde bereits für {ip_version} Verbindungen geschlossen", + "port_already_opened": "Der Port {port} wird bereits von {ip_version} benutzt", "restore_already_installed_app": "Eine Applikation mit der ID '{app}' ist bereits installiert", "restore_cleaning_failed": "Das temporäre Dateiverzeichnis für Systemrestaurierung konnte nicht gelöscht werden", "restore_complete": "Vollständig wiederhergestellt", @@ -570,8 +570,8 @@ "regenconf_would_be_updated": "Die Konfiguration wäre für die Kategorie '{category}' aktualisiert worden", "restore_system_part_failed": "Die Systemteile '{part}' konnten nicht wiederhergestellt werden", "restore_removing_tmp_dir_failed": "Ein altes, temporäres Directory konnte nicht entfernt werden", - "restore_not_enough_disk_space": "Nicht genug Speicher (Speicher: {free_space:d} B, benötigter Speicher: {needed_space:d} B, Sicherheitspuffer: {margin:d} B)", - "restore_may_be_not_enough_disk_space": "Ihr System scheint nicht genug Speicherplatz zu haben (frei: {free_space:d} B, benötigter Platz: {needed_space:d} B, Sicherheitspuffer: {margin:d} B)", + "restore_not_enough_disk_space": "Nicht genug Speicher (Speicher: {free_space} B, benötigter Speicher: {needed_space} B, Sicherheitspuffer: {margin} B)", + "restore_may_be_not_enough_disk_space": "Ihr System scheint nicht genug Speicherplatz zu haben (frei: {free_space} B, benötigter Platz: {needed_space} B, Sicherheitspuffer: {margin} B)", "restore_extracting": "Packe die benötigten Dateien aus dem Archiv aus…", "restore_already_installed_apps": "Folgende Apps können nicht wiederhergestellt werden, weil sie schon installiert sind: {apps}", "regex_with_only_domain": "Du kannst regex nicht als Domain verwenden, sondern nur als Pfad", diff --git a/locales/en.json b/locales/en.json index 4c9f3e7fe..65d98d9d1 100644 --- a/locales/en.json +++ b/locales/en.json @@ -525,8 +525,8 @@ "permission_updated": "Permission '{permission}' updated", "permission_protected": "Permission {permission} is protected. You cannot add or remove the visitors group to/from this permission.", "permission_require_account": "Permission {permission} only makes sense for users having an account, and therefore cannot be enabled for visitors.", - "port_already_closed": "Port {port:d} is already closed for {ip_version} connections", - "port_already_opened": "Port {port:d} is already opened for {ip_version} connections", + "port_already_closed": "Port {port} is already closed for {ip_version} connections", + "port_already_opened": "Port {port} is already opened for {ip_version} connections", "postinstall_low_rootfsspace": "The root filesystem has a total space less than 10 GB, which is quite worrisome! You will likely run out of disk space very quickly! It's recommended to have at least 16GB for the root filesystem. If you want to install YunoHost despite this warning, re-run the postinstall with --force-diskspace", "regenconf_file_backed_up": "Configuration file '{conf}' backed up to '{backup}'", "regenconf_file_copy_failed": "Could not copy the new configuration file '{new}' to '{conf}'", @@ -555,8 +555,8 @@ "restore_extracting": "Extracting needed files from the archive…", "restore_failed": "Could not restore system", "restore_hook_unavailable": "Restoration script for '{part}' not available on your system and not in the archive either", - "restore_may_be_not_enough_disk_space": "Your system does not seem to have enough space (free: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)", - "restore_not_enough_disk_space": "Not enough space (space: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)", + "restore_may_be_not_enough_disk_space": "Your system does not seem to have enough space (free: {free_space} B, needed space: {needed_space} B, security margin: {margin} B)", + "restore_not_enough_disk_space": "Not enough space (space: {free_space} B, needed space: {needed_space} B, security margin: {margin} B)", "restore_nothings_done": "Nothing was restored", "restore_removing_tmp_dir_failed": "Could not remove an old temporary directory", "restore_running_app_script": "Restoring the app '{app}'…", diff --git a/locales/eo.json b/locales/eo.json index 76cec1264..f40111f04 100644 --- a/locales/eo.json +++ b/locales/eo.json @@ -155,7 +155,7 @@ "permission_deleted": "Permesita \"{permission}\" forigita", "permission_deletion_failed": "Ne povis forigi permeson '{permission}': {error}", "permission_not_found": "Permesita \"{permission}\" ne trovita", - "restore_not_enough_disk_space": "Ne sufiĉa spaco (spaco: {free_space:d} B, necesa spaco: {needed_space:d} B, sekureca marĝeno: {margin:d} B)", + "restore_not_enough_disk_space": "Ne sufiĉa spaco (spaco: {free_space} B, necesa spaco: {needed_space} B, sekureca marĝeno: {margin} B)", "tools_upgrade_regular_packages": "Nun ĝisdatigi 'regulajn' (ne-yunohost-rilatajn) pakojn …", "tools_upgrade_special_packages_explanation": "La speciala ĝisdatigo daŭros en la fono. Bonvolu ne komenci aliajn agojn en via servilo dum la sekvaj ~ 10 minutoj (depende de la aparata rapideco). Post tio, vi eble devos re-ensaluti al la retadreso. La ĝisdatiga registro estos havebla en Iloj → Ensaluto (en la retadreso) aŭ uzante 'yunohost logliston' (el la komandlinio).", "unrestore_app": "App '{app}' ne restarigos", @@ -182,7 +182,7 @@ "service_added": "La servo '{service}' estis aldonita", "upnp_disabled": "UPnP malŝaltis", "service_started": "Servo '{service}' komenciĝis", - "port_already_opened": "Haveno {port:d} estas jam malfermita por {ip_version} rilatoj", + "port_already_opened": "Haveno {port} estas jam malfermita por {ip_version} rilatoj", "upgrading_packages": "Ĝisdatigi pakojn…", "custom_app_url_required": "Vi devas provizi URL por altgradigi vian kutimon app {app}", "service_reload_failed": "Ne povis reŝargi la servon '{service}'\n\nLastatempaj servaj protokoloj: {logs}", @@ -244,7 +244,7 @@ "upnp_port_open_failed": "Ne povis malfermi havenon per UPnP", "log_app_upgrade": "Ĝisdatigu la aplikon '{}'", "log_help_to_get_failed_log": "La operacio '{desc}' ne povis finiĝi. Bonvolu dividi la plenan ŝtipon de ĉi tiu operacio per la komando 'yunohost log share {name}' por akiri helpon", - "port_already_closed": "Haveno {port:d} estas jam fermita por {ip_version} rilatoj", + "port_already_closed": "Haveno {port} estas jam fermita por {ip_version} rilatoj", "hook_name_unknown": "Nekonata hoko-nomo '{name}'", "dyndns_could_not_check_provide": "Ne povis kontroli ĉu {provider} povas provizi {domain}.", "restore_nothings_done": "Nenio estis restarigita", @@ -254,7 +254,7 @@ "root_password_replaced_by_admin_password": "Via radika pasvorto estis anstataŭigita per via administra pasvorto.", "domain_unknown": "Nekonata domajno", "global_settings_setting_security_password_user_strength": "Uzanto pasvorta forto", - "restore_may_be_not_enough_disk_space": "Via sistemo ne ŝajnas havi sufiĉe da spaco (libera: {free_space:d} B, necesa spaco: {needed_space:d} B, sekureca marĝeno: {margin:d} B)", + "restore_may_be_not_enough_disk_space": "Via sistemo ne ŝajnas havi sufiĉe da spaco (libera: {free_space} B, necesa spaco: {needed_space} B, sekureca marĝeno: {margin} B)", "log_corrupted_md_file": "La YAD-metadata dosiero asociita kun protokoloj estas damaĝita: '{md_file}\nEraro: {error} '", "downloading": "Elŝutante …", "user_deleted": "Uzanto forigita", diff --git a/locales/es.json b/locales/es.json index 560bfe240..9af875898 100644 --- a/locales/es.json +++ b/locales/es.json @@ -93,8 +93,8 @@ "pattern_port_or_range": "Debe ser un número de puerto válido (es decir entre 0-65535) o un intervalo de puertos (por ejemplo 100:200)", "pattern_positive_number": "Deber ser un número positivo", "pattern_username": "Solo puede contener caracteres alfanuméricos o el guión bajo", - "port_already_closed": "El puerto {port:d} ya está cerrado para las conexiones {ip_version}", - "port_already_opened": "El puerto {port:d} ya está abierto para las conexiones {ip_version}", + "port_already_closed": "El puerto {port} ya está cerrado para las conexiones {ip_version}", + "port_already_opened": "El puerto {port} ya está abierto para las conexiones {ip_version}", "restore_already_installed_app": "Una aplicación con el ID «{app}» ya está instalada", "app_restore_failed": "No se pudo restaurar la aplicación «{app}»: {error}", "restore_cleaning_failed": "No se pudo limpiar el directorio temporal de restauración", @@ -246,8 +246,8 @@ "root_password_desynchronized": "La contraseña de administración ha sido cambiada pero ¡YunoHost no pudo propagar esto a la contraseña de root!", "restore_system_part_failed": "No se pudo restaurar la parte del sistema «{part}»", "restore_removing_tmp_dir_failed": "No se pudo eliminar un directorio temporal antiguo", - "restore_not_enough_disk_space": "Espacio insuficiente (espacio: {free_space:d} B, espacio necesario: {needed_space:d} B, margen de seguridad: {margin:d} B)", - "restore_may_be_not_enough_disk_space": "Parece que su sistema no tiene suficiente espacio libre (libre: {free_space:d} B, espacio necesario: {needed_space:d} B, margen de seguridad: {margin:d} B)", + "restore_not_enough_disk_space": "Espacio insuficiente (espacio: {free_space} B, espacio necesario: {needed_space} B, margen de seguridad: {margin} B)", + "restore_may_be_not_enough_disk_space": "Parece que su sistema no tiene suficiente espacio libre (libre: {free_space} B, espacio necesario: {needed_space} B, margen de seguridad: {margin} B)", "restore_extracting": "Extrayendo los archivos necesarios para el archivo…", "regenconf_pending_applying": "Aplicando la configuración pendiente para la categoría «{category}»…", "regenconf_failed": "No se pudo regenerar la configuración para la(s) categoría(s): {categories}", diff --git a/locales/fa.json b/locales/fa.json index a644716cf..faabff0ee 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -601,8 +601,8 @@ "restore_running_app_script": "ترمیم و بازیابی برنامه '{app}'…", "restore_removing_tmp_dir_failed": "پوشه موقت قدیمی حذف نشد", "restore_nothings_done": "هیچ چیز ترمیم و بازسازی نشد", - "restore_not_enough_disk_space": "فضای کافی موجود نیست (فضا: {free_space:d} B ، فضای مورد نیاز: {needed_space:d} B ، حاشیه امنیتی: {margin:d} B)", - "restore_may_be_not_enough_disk_space": "به نظر می رسد سیستم شما فضای کافی ندارد (فضای آزاد: {free_space:d} B ، فضای مورد نیاز: {space_space:d} B ، حاشیه امنیتی: {margin:d} B)", + "restore_not_enough_disk_space": "فضای کافی موجود نیست (فضا: {free_space} B ، فضای مورد نیاز: {needed_space} B ، حاشیه امنیتی: {margin} B)", + "restore_may_be_not_enough_disk_space": "به نظر می رسد سیستم شما فضای کافی ندارد (فضای آزاد: {free_space} B ، فضای مورد نیاز: {space_space} B ، حاشیه امنیتی: {margin} B)", "restore_hook_unavailable": "اسکریپت ترمیم و بازسازی برای '{part}' در سیستم شما در دسترس نیست و همچنین در بایگانی نیز وجود ندارد", "restore_failed": "سیستم بازیابی نشد", "restore_extracting": "استخراج فایل های مورد نیاز از بایگانی…", @@ -631,8 +631,8 @@ "regenconf_file_copy_failed": "فایل پیکربندی جدید '{new}' در '{conf}' کپی نشد", "regenconf_file_backed_up": "فایل پیکربندی '{conf}' در '{backup}' پشتیبان گیری شد", "postinstall_low_rootfsspace": "فضای فایل سیستم اصلی کمتر از 10 گیگابایت است که بسیار نگران کننده است! به احتمال زیاد خیلی زود فضای دیسک شما تمام می شود! توصیه می شود حداقل 16 گیگابایت برای سیستم فایل ریشه داشته باشید. اگر می خواهید YunoHost را با وجود این هشدار نصب کنید ، فرمان نصب را مجدد با این آپشن --force-diskspace اجرا کنید", - "port_already_opened": "پورت {port:d} قبلاً برای اتصالات {ip_version} باز شده است", - "port_already_closed": "پورت {port:d} قبلاً برای اتصالات {ip_version} بسته شده است", + "port_already_opened": "پورت {port} قبلاً برای اتصالات {ip_version} باز شده است", + "port_already_closed": "پورت {port} قبلاً برای اتصالات {ip_version} بسته شده است", "permission_require_account": "مجوز {permission} فقط برای کاربران دارای حساب کاربری منطقی است و بنابراین نمی تواند برای بازدیدکنندگان فعال شود.", "permission_protected": "مجوز {permission} محافظت می شود. شما نمی توانید گروه بازدیدکنندگان را از/به این مجوز اضافه یا حذف کنید.", "permission_updated": "مجوز '{permission}' به روز شد", diff --git a/locales/fr.json b/locales/fr.json index 53c486f26..bc69b573a 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -95,8 +95,8 @@ "pattern_port_or_range": "Doit être un numéro de port valide compris entre 0 et 65535, ou une gamme de ports (exemple : 100:200)", "pattern_positive_number": "Doit être un nombre positif", "pattern_username": "Doit être composé uniquement de caractères alphanumériques minuscules et de tirets bas (aussi appelé tiret du 8 ou underscore)", - "port_already_closed": "Le port {port:d} est déjà fermé pour les connexions {ip_version}", - "port_already_opened": "Le port {port:d} est déjà ouvert pour les connexions {ip_version}", + "port_already_closed": "Le port {port} est déjà fermé pour les connexions {ip_version}", + "port_already_opened": "Le port {port} est déjà ouvert pour les connexions {ip_version}", "restore_already_installed_app": "Une application est déjà installée avec l'identifiant '{app}'", "app_restore_failed": "Impossible de restaurer {app} : {error}", "restore_cleaning_failed": "Impossible de nettoyer le dossier temporaire de restauration", @@ -211,8 +211,8 @@ "global_settings_cant_serialize_settings": "Échec de la sérialisation des données de paramétrage car : {reason}", "restore_removing_tmp_dir_failed": "Impossible de sauvegarder un ancien dossier temporaire", "restore_extracting": "Extraction des fichiers nécessaires depuis l'archive...", - "restore_may_be_not_enough_disk_space": "Votre système ne semble pas avoir suffisamment d'espace (libre : {free_space:d} B, espace nécessaire : {needed_space:d} B, marge de sécurité : {margin:d} B)", - "restore_not_enough_disk_space": "Espace disponible insuffisant (L'espace libre est de {free_space:d} octets. Le besoin d'espace nécessaire est de {needed_space:d} octets. En appliquant une marge de sécurité, la quantité d'espace nécessaire est de {margin:d} octets)", + "restore_may_be_not_enough_disk_space": "Votre système ne semble pas avoir suffisamment d'espace (libre : {free_space} B, espace nécessaire : {needed_space} B, marge de sécurité : {margin} B)", + "restore_not_enough_disk_space": "Espace disponible insuffisant (L'espace libre est de {free_space} octets. Le besoin d'espace nécessaire est de {needed_space} octets. En appliquant une marge de sécurité, la quantité d'espace nécessaire est de {margin} octets)", "restore_system_part_failed": "Impossible de restaurer la partie '{part}' du système", "backup_couldnt_bind": "Impossible de lier {src} avec {dest}.", "domain_dns_conf_is_just_a_recommendation": "Cette commande vous montre la configuration *recommandée*. Elle ne configure pas le DNS pour vous. Il est de votre ressort de configurer votre zone DNS chez votre registrar/fournisseur conformément à cette recommandation.", diff --git a/locales/gl.json b/locales/gl.json index 56204a9ea..3dd2603b2 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -512,8 +512,8 @@ "regenconf_file_copy_failed": "Non se puido copiar o novo ficheiro de configuración '{new}' a '{conf}'", "regenconf_file_backed_up": "Ficheiro de configuración '{conf}' copiado a '{backup}'", "postinstall_low_rootfsspace": "O sistema de ficheiros raiz ten un espazo total menor de 10GB, que é pouco! Probablemente vas quedar sen espazo moi pronto! É recomendable ter polo menos 16GB para o sistema raíz. Se queres instalar YunoHost obviando este aviso, volve a executar a postinstalación con --force-diskspace", - "port_already_opened": "O porto {port:d} xa está aberto para conexións {ip_version}", - "port_already_closed": "O porto {port:d} xa está pechado para conexións {ip_version}", + "port_already_opened": "O porto {port} xa está aberto para conexións {ip_version}", + "port_already_closed": "O porto {port} xa está pechado para conexións {ip_version}", "permission_require_account": "O permiso {permission} só ten sentido para usuarias cunha conta, e por tanto non pode concederse a visitantes.", "permission_protected": "O permiso {permission} está protexido. Non podes engadir ou eliminar o grupo visitantes a/de este permiso.", "permission_updated": "Permiso '{permission}' actualizado", @@ -578,8 +578,8 @@ "restore_running_app_script": "Restablecendo a app '{app}'…", "restore_removing_tmp_dir_failed": "Non se puido eliminar o directorio temporal antigo", "restore_nothings_done": "Nada foi restablecido", - "restore_not_enough_disk_space": "Non hai espazo abondo (espazo: {free_space.d} B, espazo necesario: {needed_space} B, marxe de seguridade: {margin:d} B)", - "restore_may_be_not_enough_disk_space": "O teu sistema semella que non ten espazo abondo (libre: {free_space:d} B, espazo necesario: {needed_space:d} B, marxe de seguridade {margin:d} B)", + "restore_not_enough_disk_space": "Non hai espazo abondo (espazo: {free_space.d} B, espazo necesario: {needed_space} B, marxe de seguridade: {margin} B)", + "restore_may_be_not_enough_disk_space": "O teu sistema semella que non ten espazo abondo (libre: {free_space} B, espazo necesario: {needed_space} B, marxe de seguridade {margin} B)", "restore_hook_unavailable": "O script de restablecemento para '{part}' non está dispoñible no teu sistema nin no arquivo", "invalid_password": "Contrasinal non válido", "ldap_server_is_down_restart_it": "O servidor LDAP está caído, intenta reinicialo...", diff --git a/locales/it.json b/locales/it.json index c38bae59d..dc998d8d4 100644 --- a/locales/it.json +++ b/locales/it.json @@ -11,7 +11,7 @@ "domain_exists": "Il dominio esiste già", "pattern_email": "L'indirizzo email deve essere valido, senza simboli '+' (es. tizio@dominio.com)", "pattern_mailbox_quota": "La dimensione deve avere un suffisso b/k/M/G/T o 0 per disattivare la quota", - "port_already_opened": "La porta {port:d} è già aperta per {ip_version} connessioni", + "port_already_opened": "La porta {port} è già aperta per {ip_version} connessioni", "service_add_failed": "Impossibile aggiungere il servizio '{service}'", "service_cmd_exec_failed": "Impossibile eseguire il comando '{command}'", "service_disabled": "Il servizio '{service}' non partirà più al boot di sistema.", @@ -106,7 +106,7 @@ "pattern_port_or_range": "Deve essere un numero di porta valido (es. 0-65535) o una fascia di porte valida (es. 100:200)", "pattern_positive_number": "Deve essere un numero positivo", "pattern_username": "Caratteri minuscoli alfanumerici o trattini bassi soli", - "port_already_closed": "La porta {port:d} è già chiusa per le connessioni {ip_version}", + "port_already_closed": "La porta {port} è già chiusa per le connessioni {ip_version}", "restore_already_installed_app": "Un'applicazione con l'ID '{app}' è già installata", "app_restore_failed": "Impossibile ripristinare l'applicazione '{app}': {error}", "restore_cleaning_failed": "Impossibile pulire la directory temporanea di ripristino", @@ -436,8 +436,8 @@ "root_password_desynchronized": "La password d'amministratore è stata cambiata, ma YunoHost non ha potuto propagarla alla password di root!", "restore_system_part_failed": "Impossibile ripristinare la sezione di sistema '{part}'", "restore_removing_tmp_dir_failed": "Impossibile rimuovere una vecchia directory temporanea", - "restore_not_enough_disk_space": "Spazio libero insufficiente (spazio: {free_space:d}B, necessario: {needed_space:d}B, margine di sicurezza: {margin:d}B)", - "restore_may_be_not_enough_disk_space": "Il tuo sistema non sembra avere abbastanza spazio (libero: {free_space:d}B, necessario: {needed_space:d}B, margine di sicurezza: {margin:d}B)", + "restore_not_enough_disk_space": "Spazio libero insufficiente (spazio: {free_space}B, necessario: {needed_space}B, margine di sicurezza: {margin}B)", + "restore_may_be_not_enough_disk_space": "Il tuo sistema non sembra avere abbastanza spazio (libero: {free_space}B, necessario: {needed_space}B, margine di sicurezza: {margin}B)", "restore_extracting": "Sto estraendo i file necessari dall'archivio…", "restore_already_installed_apps": "Le seguenti app non possono essere ripristinate perché sono già installate: {apps}", "regex_with_only_domain": "Non puoi usare una regex per il dominio, solo per i percorsi", diff --git a/locales/nl.json b/locales/nl.json index e99a00575..1995cbf62 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -45,8 +45,8 @@ "pattern_email": "Moet een geldig emailadres bevatten (bv. abc@example.org)", "pattern_mailbox_quota": "Mailbox quota moet een waarde bevatten met b/k/M/G/T erachter of 0 om geen quota in te stellen", "pattern_password": "Wachtwoord moet tenminste 3 karakters lang zijn", - "port_already_closed": "Poort {port:d} is al gesloten voor {ip_version} verbindingen", - "port_already_opened": "Poort {port:d} is al open voor {ip_version} verbindingen", + "port_already_closed": "Poort {port} is al gesloten voor {ip_version} verbindingen", + "port_already_opened": "Poort {port} is al open voor {ip_version} verbindingen", "app_restore_failed": "De app '{app}' kon niet worden terug gezet: {error}", "restore_hook_unavailable": "De herstel-hook '{part}' is niet beschikbaar op dit systeem", "service_add_failed": "Kan service '{service}' niet toevoegen", diff --git a/locales/oc.json b/locales/oc.json index 906f67106..995c61b16 100644 --- a/locales/oc.json +++ b/locales/oc.json @@ -142,8 +142,8 @@ "pattern_password": "Deu conténer almens 3 caractèrs", "pattern_port_or_range": "Deu èsser un numèro de pòrt valid (ex : 0-65535) o un interval de pòrt (ex : 100:200)", "pattern_positive_number": "Deu èsser un nombre positiu", - "port_already_closed": "Lo pòrt {port:d} es ja tampat per las connexions {ip_version}", - "port_already_opened": "Lo pòrt {port:d} es ja dubèrt per las connexions {ip_version}", + "port_already_closed": "Lo pòrt {port} es ja tampat per las connexions {ip_version}", + "port_already_opened": "Lo pòrt {port} es ja dubèrt per las connexions {ip_version}", "restore_already_installed_app": "Una aplicacion es ja installada amb l’id « {app} »", "app_restore_failed": "Impossible de restaurar l’aplicacion « {app} »: {error}", "backup_ask_for_copying_if_needed": "Volètz far una salvagarda en utilizant {size} Mo temporàriament ? (Aqueste biais de far es emplegat perque unes fichièrs an pas pogut èsser preparats amb un metòde mai eficaç.)", @@ -206,8 +206,8 @@ "restore_extracting": "Extraccions dels fichièrs necessaris dins de l’archiu…", "restore_failed": "Impossible de restaurar lo sistèma", "restore_hook_unavailable": "Lo script de restauracion « {part} » es pas disponible sus vòstre sistèma e es pas tanpauc dins l’archiu", - "restore_may_be_not_enough_disk_space": "Lo sistèma sembla d’aver pas pro d’espaci disponible (liure : {free_space:d} octets, necessari : {needed_space:d} octets, marge de seguretat : {margin:d} octets)", - "restore_not_enough_disk_space": "Espaci disponible insufisent (liure : {free_space:d} octets, necessari : {needed_space:d} octets, marge de seguretat : {margin:d} octets)", + "restore_may_be_not_enough_disk_space": "Lo sistèma sembla d’aver pas pro d’espaci disponible (liure : {free_space} octets, necessari : {needed_space} octets, marge de seguretat : {margin} octets)", + "restore_not_enough_disk_space": "Espaci disponible insufisent (liure : {free_space} octets, necessari : {needed_space} octets, marge de seguretat : {margin} octets)", "restore_nothings_done": "Res es pas estat restaurat", "restore_removing_tmp_dir_failed": "Impossible de levar u ancian repertòri temporari", "restore_running_app_script": "Lançament del script de restauracion per l’aplicacion « {app} »…", diff --git a/locales/zh_Hans.json b/locales/zh_Hans.json index 5f076fa2e..560ee0db0 100644 --- a/locales/zh_Hans.json +++ b/locales/zh_Hans.json @@ -161,8 +161,8 @@ "app_action_cannot_be_ran_because_required_services_down": "这些必需的服务应该正在运行以执行以下操作:{services},尝试重新启动它们以继续操作(考虑调查为什么它们出现故障)。", "already_up_to_date": "无事可做。一切都已经是最新的了。", "postinstall_low_rootfsspace": "根文件系统的总空间小于10 GB,这非常令人担忧!您可能很快就会用完磁盘空间!建议根文件系统至少有16GB, 如果尽管出现此警告仍要安装YunoHost,请使用--force-diskspace重新运行postinstall", - "port_already_opened": "{ip_version}个连接的端口 {port:d} 已打开", - "port_already_closed": "{ip_version}个连接的端口 {port:d} 已关闭", + "port_already_opened": "{ip_version}个连接的端口 {port} 已打开", + "port_already_closed": "{ip_version}个连接的端口 {port} 已关闭", "permission_require_account": "权限{permission}只对有账户的用户有意义,因此不能对访客启用。", "permission_protected": "权限{permission}是受保护的。你不能向/从这个权限添加或删除访问者组。", "permission_updated": "权限 '{permission}' 已更新", @@ -185,7 +185,7 @@ "regenconf_file_manually_modified": "配置文件'{conf}' 已被手动修改,不会被更新", "regenconf_need_to_explicitly_specify_ssh": "ssh配置已被手动修改,但是您需要使用--force明确指定类别“ ssh”才能实际应用更改。", "restore_nothings_done": "什么都没有恢复", - "restore_may_be_not_enough_disk_space": "您的系统似乎没有足够的空间(可用空间: {free_space:d} B,所需空间: {needed_space:d} B,安全系数: {margin:d} B)", + "restore_may_be_not_enough_disk_space": "您的系统似乎没有足够的空间(可用空间: {free_space} B,所需空间: {needed_space} B,安全系数: {margin} B)", "restore_hook_unavailable": "'{part}'的恢复脚本在您的系统上和归档文件中均不可用", "restore_failed": "无法还原系统", "restore_extracting": "正在从存档中提取所需文件…", @@ -467,7 +467,7 @@ "diagnosis_package_installed_from_sury_details": "一些软件包被无意中从一个名为Sury的第三方仓库安装。YunoHost团队改进了处理这些软件包的策略,但预计一些安装了PHP7.3应用程序的设置在仍然使用Stretch的情况下还有一些不一致的地方。为了解决这种情况,你应该尝试运行以下命令:{cmd_to_fix}", "app_not_installed": "在已安装的应用列表中找不到 {app}:{all_apps}", "app_already_installed_cant_change_url": "这个应用程序已经被安装。URL不能仅仅通过这个函数来改变。在`app changeurl`中检查是否可用。", - "restore_not_enough_disk_space": "没有足够的空间(空间: {free_space:d} B,需要的空间: {needed_space:d} B,安全系数: {margin:d} B)", + "restore_not_enough_disk_space": "没有足够的空间(空间: {free_space} B,需要的空间: {needed_space} B,安全系数: {margin} B)", "regenconf_pending_applying": "正在为类别'{category}'应用挂起的配置..", "regenconf_up_to_date": "类别'{category}'的配置已经是最新的", "regenconf_file_kept_back": "配置文件'{conf}'预计将被regen-conf(类别{category})删除,但被保留了下来。", From 130c7293964c8f32f5cce63a4fedd8d5668fefe1 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 2 Sep 2021 04:27:56 +0200 Subject: [PATCH 071/101] Misc wording --- locales/en.json | 2 +- locales/fr.json | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/locales/en.json b/locales/en.json index 65d98d9d1..f267e2f5e 100644 --- a/locales/en.json +++ b/locales/en.json @@ -268,7 +268,7 @@ "diagnosis_http_hairpinning_issue_details": "This is probably because of your ISP box / router. As a result, people from outside your local network will be able to access your server as expected, but not people from inside the local network (like you, probably?) when using the domain name or global IP. You may be able to improve the situation by having a look at https://yunohost.org/dns_local_network", "diagnosis_http_could_not_diagnose": "Could not diagnose if domains are reachable from outside in IPv{ipversion}.", "diagnosis_http_could_not_diagnose_details": "Error: {error}", - "diagnosis_http_localdomain": "Domain {domain}, with a .local TLD, is not expected to be reached from outside the local network.", + "diagnosis_http_localdomain": "Domain {domain}, with a .local TLD, is not expected to be exposed outside the local network.", "diagnosis_http_ok": "Domain {domain} is reachable through HTTP from outside the local network.", "diagnosis_http_timeout": "Timed-out while trying to contact your server from outside. It appears to be unreachable.
1. The most common cause for this issue is that port 80 (and 443) are not correctly forwarded to your server.
2. You should also make sure that the service nginx is running
3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.", "diagnosis_http_connection_error": "Connection error: could not connect to the requested domain, it's very likely unreachable.", diff --git a/locales/fr.json b/locales/fr.json index bc69b573a..9df6b24be 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -170,7 +170,7 @@ "mailbox_used_space_dovecot_down": "Le service de email Dovecot doit être démarré si vous souhaitez voir l'espace disque occupé par la messagerie", "domains_available": "Domaines disponibles :", "backup_archive_broken_link": "Impossible d'accéder à l'archive de sauvegarde (lien invalide vers {path})", - "certmanager_acme_not_configured_for_domain": "Le challenge ACME n'a pas pu être validé pour le domaine {domain} pour le moment car le code de la configuration NGINX est manquant... Merci de vérifier que votre configuration NGINX est à jour avec la commande: `yunohost tools regen-conf nginx --dry-run --with-diff`.", + "certmanager_acme_not_configured_for_domain": "Le challenge ACME n'a pas pu être validé pour le domaine {domain} pour le moment car le code de la configuration NGINX est manquant... Merci de vérifier que votre configuration NGINX est à jour avec la commande : `yunohost tools regen-conf nginx --dry-run --with-diff`.", "domain_hostname_failed": "Échec de l'utilisation d'un nouveau nom d'hôte. Cela pourrait causer des soucis plus tard (cela n'en causera peut-être pas).", "app_already_installed_cant_change_url": "Cette application est déjà installée. L'URL ne peut pas être changé simplement par cette fonction. Vérifiez si cela est disponible avec `app changeurl`.", "app_change_url_failed_nginx_reload": "Le redémarrage de NGINX a échoué. Voici la sortie de 'nginx -t' :\n{nginx_errors}", @@ -232,7 +232,7 @@ "app_upgrade_app_name": "Mise à jour de {app}...", "backup_output_symlink_dir_broken": "Votre répertoire d'archivage '{path}' est un lien symbolique brisé. Peut-être avez-vous oublié de re/monter ou de brancher le support de stockage sur lequel il pointe.", "migrations_list_conflict_pending_done": "Vous ne pouvez pas utiliser --previous et --done simultanément.", - "migrations_to_be_ran_manually": "La migration {id} doit être lancée manuellement. Veuillez aller dans Outils > Migrations dans l'interface admin, ou lancer `yunohost tools migrations run`.", + "migrations_to_be_ran_manually": "La migration {id} doit être lancée manuellement. Veuillez aller dans Outils > Migrations dans la webadmin, ou lancer `yunohost tools migrations run`.", "migrations_need_to_accept_disclaimer": "Pour lancer la migration {id}, vous devez accepter cet avertissement :\n---\n{disclaimer}\n---\nSi vous acceptez de lancer la migration, veuillez relancer la commande avec l'option --accept-disclaimer.", "service_description_yunomdns": "Vous permet d'atteindre votre serveur en utilisant 'yunohost.local' sur votre réseau local", "service_description_dnsmasq": "Gère la résolution des noms de domaine (DNS)", @@ -420,7 +420,7 @@ "diagnosis_ip_not_connected_at_all": "Le serveur ne semble pas du tout connecté à Internet !?", "diagnosis_ip_weird_resolvconf": "La résolution DNS semble fonctionner, mais il semble que vous utilisez un /etc/resolv.conf personnalisé.", "diagnosis_ip_weird_resolvconf_details": "Le fichier /etc/resolv.conf doit être un lien symbolique vers /etc/resolvconf/run/resolv.conf lui-même pointant vers 127.0.0.1 (dnsmasq). Si vous souhaitez configurer manuellement les résolveurs DNS, veuillez modifier /etc/resolv.dnsmasq.conf.", - "diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS
Type : {type}
Nom : {name}
Valeur: {value}", + "diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS
Type : {type}
Nom : {name}
Valeur : {value}", "diagnosis_diskusage_ok": "L'espace de stockage {mountpoint} (sur le périphérique {device}) a encore {free} ({free_percent}%) espace restant (sur {total}) !", "diagnosis_ram_ok": "Le système dispose encore de {available} ({available_percent}%) de RAM sur {total}.", "diagnosis_regenconf_allgood": "Tous les fichiers de configuration sont conformes à la configuration recommandée !", @@ -431,7 +431,7 @@ "diagnosis_basesystem_ynh_main_version": "Le serveur utilise YunoHost {main_version} ({repo})", "diagnosis_basesystem_ynh_inconsistent_versions": "Vous exécutez des versions incohérentes des packages YunoHost ... très probablement en raison d'une mise à niveau échouée ou partielle.", "diagnosis_failed_for_category": "Échec du diagnostic pour la catégorie '{category}': {error}", - "diagnosis_cache_still_valid": "(Le cache est encore valide pour le diagnostic {category}. Il ne sera pas re-diagnostiqué pour le moment!)", + "diagnosis_cache_still_valid": "(Le cache est encore valide pour le diagnostic {category}. Il ne sera pas re-diagnostiqué pour le moment !)", "diagnosis_ignored_issues": "(+ {nb_ignored} problème(s) ignoré(s))", "diagnosis_found_warnings": "Trouvé {warnings} objet(s) pouvant être amélioré(s) pour {category}.", "diagnosis_everything_ok": "Tout semble bien pour {category} !", @@ -496,7 +496,7 @@ "log_app_action_run": "Lancer l'action de l'application '{}'", "log_app_config_show_panel": "Montrer le panneau de configuration de l'application '{}'", "log_app_config_apply": "Appliquer la configuration à l'application '{}'", - "diagnosis_never_ran_yet": "Il apparaît que le serveur a été installé récemment et qu'il n'y a pas encore eu de diagnostic. Vous devriez en lancer un depuis la web-admin ou en utilisant 'yunohost diagnosis run' depuis la ligne de commande.", + "diagnosis_never_ran_yet": "Il apparaît que le serveur a été installé récemment et qu'il n'y a pas encore eu de diagnostic. Vous devriez en lancer un depuis la webadmin ou en utilisant 'yunohost diagnosis run' depuis la ligne de commande.", "diagnosis_description_web": "Web", "diagnosis_basesystem_hardware": "L'architecture du serveur est {virt} {arch}", "group_already_exist_on_system_but_removing_it": "Le groupe {group} est déjà présent dans les groupes du système, mais YunoHost va le supprimer...", @@ -542,9 +542,9 @@ "diagnosis_http_nginx_conf_not_up_to_date_details": "Pour corriger la situation, inspectez la différence avec la ligne de commande en utilisant les outils yunohost tools regen-conf nginx --dry-run --with-diff et si vous êtes d'accord, appliquez les modifications avec yunohost tools regen-conf nginx --force.", "backup_archive_cant_retrieve_info_json": "Impossible d'avoir des informations sur l'archive '{archive}'... Le fichier info.json ne peut pas être trouvé (ou n'est pas un fichier json valide).", "backup_archive_corrupted": "Il semble que l'archive de la sauvegarde '{archive}' est corrompue : {error}", - "diagnosis_ip_no_ipv6_tip": "L'utilisation de IPv6 n'est pas obligatoire pour le fonctionnement de votre serveur, mais cela contribue à la santé d'Internet dans son ensemble. IPv6 généralement configuré automatiquement par votre système ou votre FAI s'il est disponible. Autrement, vous devrez prendre quelque minutes pour le configurer manuellement à l'aide de cette documentation: https://yunohost.org/#/ipv6. Si vous ne pouvez pas activer IPv6 ou si c'est trop technique pour vous, vous pouvez aussi ignorer cet avertissement sans que cela pose problème.", + "diagnosis_ip_no_ipv6_tip": "L'utilisation de IPv6 n'est pas obligatoire pour le fonctionnement de votre serveur, mais cela contribue à la santé d'Internet dans son ensemble. IPv6 généralement configuré automatiquement par votre système ou votre FAI s'il est disponible. Autrement, vous devrez prendre quelque minutes pour le configurer manuellement à l'aide de cette documentation : https://yunohost.org/#/ipv6. Si vous ne pouvez pas activer IPv6 ou si c'est trop technique pour vous, vous pouvez aussi ignorer cet avertissement sans que cela pose problème.", "diagnosis_domain_expiration_not_found": "Impossible de vérifier la date d'expiration de certains domaines", - "diagnosis_domain_expiration_not_found_details": "Les informations WHOIS pour le domaine {domain} ne semblent pas contenir les informations concernant la date d'expiration ?", + "diagnosis_domain_expiration_not_found_details": "Les informations WHOIS pour le domaine {domain} ne semblent pas contenir les informations concernant la date d'expiration ?", "diagnosis_domain_not_found_details": "Le domaine {domain} n'existe pas dans la base de donnée WHOIS ou est expiré !", "diagnosis_domain_expiration_success": "Vos domaines sont enregistrés et ne vont pas expirer prochainement.", "diagnosis_domain_expiration_warning": "Certains domaines vont expirer prochainement !", @@ -634,16 +634,16 @@ "diagnosis_sshd_config_inconsistent": "Il semble que le port SSH a été modifié manuellement dans /etc/ssh/sshd_config. Depuis YunoHost 4.2, un nouveau paramètre global 'security.ssh.port' est disponible pour éviter de modifier manuellement la configuration.", "diagnosis_sshd_config_insecure": "La configuration SSH semble avoir été modifiée manuellement et n'est pas sécurisée car elle ne contient aucune directive 'AllowGroups' ou 'AllowUsers' pour limiter l'accès aux utilisateurs autorisés.", "backup_create_size_estimation": "L'archive contiendra environ {size} de données.", - "global_settings_setting_security_webadmin_allowlist": "Adresses IP autorisées à accéder à la page web du portail d'administration (webadmin). Elles doivent être séparées par une virgule.", - "global_settings_setting_security_webadmin_allowlist_enabled": "Autorisez seulement certaines IP à accéder à la page web du portail d'administration (webadmin).", - "diagnosis_http_localdomain": "Le domaine {domain}, avec un TLD .local, ne devrait pas être atteint depuis l'extérieur du réseau local.", + "global_settings_setting_security_webadmin_allowlist": "Adresses IP autorisées à accéder à la webadmin. Elles doivent être séparées par une virgule.", + "global_settings_setting_security_webadmin_allowlist_enabled": "Autoriser seulement certaines IP à accéder à la webadmin.", + "diagnosis_http_localdomain": "Le domaine {domain}, avec un TLD .local, ne devrait pas être exposé en dehors du réseau local.", "diagnosis_dns_specialusedomain": "Le domaine {domain} est basé sur un domaine de premier niveau (TLD) à usage spécial et ne devrait donc pas avoir d'enregistrements DNS réels.", "invalid_password": "Mot de passe incorrect", "ldap_server_is_down_restart_it": "Le service LDAP est en panne, essayez de le redémarrer...", "ldap_server_down": "Impossible d'atteindre le serveur LDAP", "global_settings_setting_security_experimental_enabled": "Activer les fonctionnalités de sécurité expérimentales (ne l'activez pas si vous ne savez pas ce que vous faites !)", "diagnosis_apps_deprecated_practices": "La version installée de cette application utilise toujours certaines pratiques de packaging obsolètes. Vous devriez vraiment envisager de mettre l'application à jour.", - "diagnosis_apps_outdated_ynh_requirement": "La version installée de cette application nécessite uniquement YunoHost> = 2.x, cela indique que l'application n'est pas à jour avec les bonnes pratiques de packaging et les helpers recommandées. Vous devriez vraiment envisager de mettre l'application à jour.", + "diagnosis_apps_outdated_ynh_requirement": "La version installée de cette application nécessite uniquement YunoHost >= 2.x, cela indique que l'application n'est pas à jour avec les bonnes pratiques de packaging et les helpers recommandées. Vous devriez vraiment envisager de mettre l'application à jour.", "diagnosis_apps_bad_quality": "Cette application est actuellement signalée comme cassée dans le catalogue d'applications de YunoHost. Cela peut être un problème temporaire. En attendant que les mainteneurs tentent de résoudre le problème, la mise à jour de cette application est désactivée.", "diagnosis_apps_broken": "Cette application est actuellement signalée comme cassée dans le catalogue d'applications de YunoHost. Cela peut être un problème temporaire. En attendant que les mainteneurs tentent de résoudre le problème, la mise à jour de cette application est désactivée.", "diagnosis_apps_not_in_app_catalog": "Cette application est absente ou ne figure plus dans le catalogue d'applications de YunoHost. Vous devriez envisager de la désinstaller car elle ne recevra pas de mise à jour et pourrait compromettre l'intégrité et la sécurité de votre système.", From 59564f910662c0d4467245fcf804fae3c008a6e5 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 2 Sep 2021 04:44:37 +0200 Subject: [PATCH 072/101] Wording --- locales/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 9df6b24be..2772d839e 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -78,7 +78,7 @@ "installation_complete": "Installation terminée", "ip6tables_unavailable": "Vous ne pouvez pas jouer avec ip6tables ici. Vous êtes soit dans un conteneur, soit votre noyau ne le prend pas en charge", "iptables_unavailable": "Vous ne pouvez pas jouer avec iptables ici. Vous êtes soit dans un conteneur, soit votre noyau ne le prend pas en charge", - "mail_alias_remove_failed": "Impossible de supprimer l'alias de email '{mail}'", + "mail_alias_remove_failed": "Impossible de supprimer l'alias mail '{mail}'", "mail_domain_unknown": "Le domaine '{domain}' de cette adresse email n'est pas valide. Merci d'utiliser un domaine administré par ce serveur.", "mail_forward_remove_failed": "Impossible de supprimer l'email de transfert '{mail}'", "main_domain_change_failed": "Impossible de modifier le domaine principal", @@ -167,7 +167,7 @@ "domain_cannot_remove_main": "Vous ne pouvez pas supprimer '{domain}' car il s'agit du domaine principal. Vous devez d'abord définir un autre domaine comme domaine principal à l'aide de 'yunohost domain main-domain -n ', voici la liste des domaines candidats : {other_domains}", "certmanager_self_ca_conf_file_not_found": "Le fichier de configuration pour l'autorité du certificat auto-signé est introuvable (fichier : {file})", "certmanager_unable_to_parse_self_CA_name": "Impossible d'analyser le nom de l'autorité du certificat auto-signé (fichier : {file})", - "mailbox_used_space_dovecot_down": "Le service de email Dovecot doit être démarré si vous souhaitez voir l'espace disque occupé par la messagerie", + "mailbox_used_space_dovecot_down": "Le service Dovecot doit être démarré si vous souhaitez voir l'espace disque occupé par la messagerie", "domains_available": "Domaines disponibles :", "backup_archive_broken_link": "Impossible d'accéder à l'archive de sauvegarde (lien invalide vers {path})", "certmanager_acme_not_configured_for_domain": "Le challenge ACME n'a pas pu être validé pour le domaine {domain} pour le moment car le code de la configuration NGINX est manquant... Merci de vérifier que votre configuration NGINX est à jour avec la commande : `yunohost tools regen-conf nginx --dry-run --with-diff`.", From 46fb84e071a65699d7685896d6acdbee27e6e585 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 2 Sep 2021 04:46:31 +0200 Subject: [PATCH 073/101] Expand the reformat locale script to also cover en.json ... --- .gitlab/ci/translation.gitlab-ci.yml | 2 +- locales/en.json | 26 +++++++++---------- ...fr_translations.py => reformat_locales.py} | 25 +++++++++++++----- 3 files changed, 32 insertions(+), 21 deletions(-) rename tests/{reformat_fr_translations.py => reformat_locales.py} (52%) diff --git a/.gitlab/ci/translation.gitlab-ci.yml b/.gitlab/ci/translation.gitlab-ci.yml index c8fbb9147..b81d4a2be 100644 --- a/.gitlab/ci/translation.gitlab-ci.yml +++ b/.gitlab/ci/translation.gitlab-ci.yml @@ -16,7 +16,7 @@ remove-stale-translated-strings: # create a local branch that will overwrite distant one - git checkout -b "ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}" --no-track - python3 remove_stale_translated_strings.py - - python3 reformat_fr_translations.py + - python3 reformat_locales.py - '[ $(git diff -w | wc -l) != 0 ] || exit 0' # stop if there is nothing to commit - git commit -am "[CI] Reformat / remove stale translated strings" || true - git push -f origin "ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}":"ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}" diff --git a/locales/en.json b/locales/en.json index f267e2f5e..e0f6d4ac9 100644 --- a/locales/en.json +++ b/locales/en.json @@ -62,7 +62,7 @@ "app_packaging_format_not_supported": "This app cannot be installed because its packaging format is not supported by your YunoHost version. You should probably consider upgrading your system.", "apps_already_up_to_date": "All apps are already up-to-date", "apps_catalog_init_success": "App catalog system initialized!", - "apps_catalog_updating": "Updating application catalog…", + "apps_catalog_updating": "Updating application catalog...", "apps_catalog_failed_to_download": "Unable to download the {apps_catalog} app catalog: {error}", "apps_catalog_obsolete_cache": "The app catalog cache is empty or obsolete.", "apps_catalog_update_success": "The application catalog has been updated!", @@ -140,8 +140,8 @@ "certmanager_self_ca_conf_file_not_found": "Could not find configuration file for self-signing authority (file: {file})", "certmanager_unable_to_parse_self_CA_name": "Could not parse name of self-signing authority (file: {file})", "confirm_app_install_warning": "Warning: This app may work, but is not well-integrated in YunoHost. Some features such as single sign-on and backup/restore might not be available. Install anyway? [{answers}] ", - "confirm_app_install_danger": "DANGER! This app is known to be still experimental (if not explicitly not working)! You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system… If you are willing to take that risk anyway, type '{answers}'", - "confirm_app_install_thirdparty": "DANGER! This app is not part of YunoHost's app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system… If you are willing to take that risk anyway, type '{answers}'", + "confirm_app_install_danger": "DANGER! This app is known to be still experimental (if not explicitly not working)! You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system... If you are willing to take that risk anyway, type '{answers}'", + "confirm_app_install_thirdparty": "DANGER! This app is not part of YunoHost's app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system... If you are willing to take that risk anyway, type '{answers}'", "custom_app_url_required": "You must provide a URL to upgrade your custom app {app}", "diagnosis_basesystem_hardware": "Server hardware architecture is {virt} {arch}", "diagnosis_basesystem_hardware_model": "Server model is {model}", @@ -304,8 +304,8 @@ "domain_unknown": "Unknown domain", "domains_available": "Available domains:", "done": "Done", - "downloading": "Downloading…", - "dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state… You can try to solve this issue by connecting through SSH and running `sudo apt install --fix-broken` and/or `sudo dpkg --configure -a`.", + "downloading": "Downloading...", + "dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state... You can try to solve this issue by connecting through SSH and running `sudo apt install --fix-broken` and/or `sudo dpkg --configure -a`.", "dpkg_lock_not_available": "This command can't be run right now because another program seems to be using the lock of dpkg (the system package manager)", "dyndns_could_not_check_provide": "Could not check if {provider} can provide {domain}.", "dyndns_could_not_check_available": "Could not check if {domain} is available on {provider}.", @@ -540,7 +540,7 @@ "regenconf_up_to_date": "The configuration is already up-to-date for category '{category}'", "regenconf_updated": "Configuration updated for '{category}'", "regenconf_would_be_updated": "The configuration would have been updated for category '{category}'", - "regenconf_dry_pending_applying": "Checking pending configuration which would have been applied for category '{category}'…", + "regenconf_dry_pending_applying": "Checking pending configuration which would have been applied for category '{category}'...", "regenconf_failed": "Could not regenerate the configuration for category(s): {categories}", "regenconf_pending_applying": "Applying pending configuration for category '{category}'...", "regenconf_need_to_explicitly_specify_ssh": "The ssh configuration has been manually modified, but you need to explicitly specify category 'ssh' with --force to actually apply the changes.", @@ -552,15 +552,15 @@ "restore_cleaning_failed": "Could not clean up the temporary restoration directory", "restore_complete": "Restoration completed", "restore_confirm_yunohost_installed": "Do you really want to restore an already installed system? [{answers}]", - "restore_extracting": "Extracting needed files from the archive…", + "restore_extracting": "Extracting needed files from the archive...", "restore_failed": "Could not restore system", "restore_hook_unavailable": "Restoration script for '{part}' not available on your system and not in the archive either", "restore_may_be_not_enough_disk_space": "Your system does not seem to have enough space (free: {free_space} B, needed space: {needed_space} B, security margin: {margin} B)", "restore_not_enough_disk_space": "Not enough space (space: {free_space} B, needed space: {needed_space} B, security margin: {margin} B)", "restore_nothings_done": "Nothing was restored", "restore_removing_tmp_dir_failed": "Could not remove an old temporary directory", - "restore_running_app_script": "Restoring the app '{app}'…", - "restore_running_hooks": "Running restoration hooks…", + "restore_running_app_script": "Restoring the app '{app}'...", + "restore_running_hooks": "Running restoration hooks...", "restore_system_part_failed": "Could not restore the '{part}' system part", "root_password_desynchronized": "The admin password was changed, but YunoHost could not propagate this to the root password!", "root_password_replaced_by_admin_password": "Your root password have been replaced by your admin password.", @@ -615,11 +615,11 @@ "this_action_broke_dpkg": "This action broke dpkg/APT (the system package managers)... You can try to solve this issue by connecting through SSH and running `sudo apt install --fix-broken` and/or `sudo dpkg --configure -a`.", "tools_upgrade_at_least_one": "Please specify 'apps', or 'system'", "tools_upgrade_cant_both": "Cannot upgrade both system and apps at the same time", - "tools_upgrade_cant_hold_critical_packages": "Could not hold critical packages…", - "tools_upgrade_cant_unhold_critical_packages": "Could not unhold critical packages…", - "tools_upgrade_regular_packages": "Now upgrading 'regular' (non-yunohost-related) packages…", + "tools_upgrade_cant_hold_critical_packages": "Could not hold critical packages...", + "tools_upgrade_cant_unhold_critical_packages": "Could not unhold critical packages...", + "tools_upgrade_regular_packages": "Now upgrading 'regular' (non-yunohost-related) packages...", "tools_upgrade_regular_packages_failed": "Could not upgrade packages: {packages_list}", - "tools_upgrade_special_packages": "Now upgrading 'special' (yunohost-related) packages…", + "tools_upgrade_special_packages": "Now upgrading 'special' (yunohost-related) packages...", "tools_upgrade_special_packages_explanation": "The special upgrade will continue in the background. Please don't start any other actions on your server for the next ~10 minutes (depending on hardware speed). After this, you may have to re-log in to the webadmin. The upgrade log will be available in Tools → Log (in the webadmin) or using 'yunohost log list' (from the command-line).", "tools_upgrade_special_packages_completed": "YunoHost package upgrade completed.\nPress [Enter] to get the command line back", "unbackup_app": "{app} will not be saved", diff --git a/tests/reformat_fr_translations.py b/tests/reformat_locales.py similarity index 52% rename from tests/reformat_fr_translations.py rename to tests/reformat_locales.py index 473ed99d4..90251d040 100644 --- a/tests/reformat_fr_translations.py +++ b/tests/reformat_locales.py @@ -1,11 +1,26 @@ import re -locale_folder = "locales/" -locale = open(locale_folder + "fr.json").read() +def reformat(lang, transformations): + + locale = open(f"locales/{lang}.json").read() + for pattern, replace in transformations.items(): + locale = re.compile(pattern).sub(replace, 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"] transformations = {s: " " for s in godamn_spaces_of_hell} +transformations.update({ + "…": "...", +}) + + +reformat("en", transformations) + +###################################################### transformations.update({ "courriel": "email", @@ -16,12 +31,8 @@ transformations.update({ "«": "'", " »": "'", "»": "'", - "…": "...", "’": "'", #r"$(\w{1,2})'|( \w{1,2})'": r"\1\2’", }) -for pattern, replace in transformations.items(): - locale = re.compile(pattern).sub(replace, locale) - -open(locale_folder + "fr.json", "w").write(locale) +reformat("fr", transformations) From 5ec397d3545c0b9268fbfd98fcfbed86091aefcd Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 2 Sep 2021 12:30:49 +0200 Subject: [PATCH 074/101] Fix locales --- locales/fa.json | 2 +- locales/gl.json | 4 +- locales/uk.json | 106 ++++++++++++++++++++++++------------------------ 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/locales/fa.json b/locales/fa.json index a644716cf..5d9772459 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -602,7 +602,7 @@ "restore_removing_tmp_dir_failed": "پوشه موقت قدیمی حذف نشد", "restore_nothings_done": "هیچ چیز ترمیم و بازسازی نشد", "restore_not_enough_disk_space": "فضای کافی موجود نیست (فضا: {free_space:d} B ، فضای مورد نیاز: {needed_space:d} B ، حاشیه امنیتی: {margin:d} B)", - "restore_may_be_not_enough_disk_space": "به نظر می رسد سیستم شما فضای کافی ندارد (فضای آزاد: {free_space:d} B ، فضای مورد نیاز: {space_space:d} B ، حاشیه امنیتی: {margin:d} B)", + "restore_may_be_not_enough_disk_space": "به نظر می رسد سیستم شما فضای کافی ندارد (فضای آزاد: {free_space:d} B ، فضای مورد نیاز: {needed_space:d} B ، حاشیه امنیتی: {margin:d} B)", "restore_hook_unavailable": "اسکریپت ترمیم و بازسازی برای '{part}' در سیستم شما در دسترس نیست و همچنین در بایگانی نیز وجود ندارد", "restore_failed": "سیستم بازیابی نشد", "restore_extracting": "استخراج فایل های مورد نیاز از بایگانی…", diff --git a/locales/gl.json b/locales/gl.json index 56204a9ea..ca25fc303 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -546,7 +546,7 @@ "regenconf_file_remove_failed": "Non se puido eliminar o ficheiro de configuración '{conf}'", "service_enable_failed": "Non se puido facer que o servizo '{service}' se inicie automáticamente no inicio.\n\nRexistros recentes do servizo: {logs}", "service_disabled": "O servizo '{service}' xa non vai volver a ser iniciado ao inicio do sistema.", - "service_disable_failed": "Non se puido iniciar o servizo '{servizo}' ao inicio.\n\nRexistro recente do servizo: {logs}", + "service_disable_failed": "Non se puido iniciar o servizo '{service}' ao inicio.\n\nRexistro recente do servizo: {logs}", "service_description_yunohost-firewall": "Xestiona, abre e pecha a conexións dos portos aos servizos", "service_description_yunohost-api": "Xestiona as interaccións entre a interface web de YunoHost e o sistema", "service_description_ssh": "Permíteche conectar de xeito remoto co teu servidor a través dun terminal (protocolo SSH)", @@ -563,7 +563,7 @@ "service_description_dnsmasq": "Xestiona a resolución de nomes de dominio (DNS)", "service_description_yunomdns": "Permíteche chegar ao teu servidor utilizando 'yunohost.local' na túa rede local", "service_cmd_exec_failed": "Non se puido executar o comando '{command}'", - "service_already_stopped": "O servizo '{sevice}' xa está detido", + "service_already_stopped": "O servizo '{service}' xa está detido", "service_already_started": "O servizo '{service}' xa se está a executar", "service_added": "Foi engadido o servizo '{service}'", "service_add_failed": "Non se puido engadir o servizo '{service}'", diff --git a/locales/uk.json b/locales/uk.json index 2e466685b..a9b807981 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -61,14 +61,14 @@ "service_description_dovecot": "Дозволяє поштовим клієнтам отримувати доступ до електронної пошти (через IMAP і POP3)", "service_description_dnsmasq": "Обробляє дозвіл доменних імен (DNS)", "service_description_yunomdns": "Дозволяє вам отримати доступ до вашого сервера, використовуючи 'yunohost.local' у вашій локальній мережі", - "service_cmd_exec_failed": "Не вдалося виконати команду '{команда}'", + "service_cmd_exec_failed": "Не вдалося виконати команду '{command}'", "service_already_stopped": "Служба '{service}' вже зупинена", "service_already_started": "Служба '{service}' вже запущена", "service_added": "Служба '{service}' була додана", "service_add_failed": "Не вдалося додати службу '{service}'", - "server_reboot_confirm": "Сервер негайно перезавантажиться, ви впевнені? [{Відповіді}]", + "server_reboot_confirm": "Сервер негайно перезавантажиться, ви впевнені? [{answers}]", "server_reboot": "сервер перезавантажиться", - "server_shutdown_confirm": "Сервер буде негайно виключений, ви впевнені? [{Відповіді}].", + "server_shutdown_confirm": "Сервер буде негайно виключений, ви впевнені? [{answers}].", "server_shutdown": "сервер вимкнеться", "root_password_replaced_by_admin_password": "Ваш кореневої пароль був замінений на пароль адміністратора.", "root_password_desynchronized": "Пароль адміністратора був змінений, але YunoHost не зміг поширити це на пароль root!", @@ -82,7 +82,7 @@ "restore_hook_unavailable": "Сценарій відновлення для '{part}' недоступним у вашій системі і в архіві його теж немає", "restore_failed": "Не вдалося відновити систему", "restore_extracting": "Витяг необхідних файлів з архіву…", - "restore_confirm_yunohost_installed": "Ви дійсно хочете відновити вже встановлену систему? [{Відповіді}].", + "restore_confirm_yunohost_installed": "Ви дійсно хочете відновити вже встановлену систему? [{answers}].", "restore_complete": "відновлення завершено", "restore_cleaning_failed": "Не вдалося очистити тимчасовий каталог відновлення", "restore_backup_too_old": "Цей архів резервних копій не може бути відновлений, бо він отриманий з дуже старою версією YunoHost.", @@ -91,12 +91,12 @@ "regex_with_only_domain": "Ви не можете використовувати regex для домену, тільки для шляху.", "regex_incompatible_with_tile": "/! \\ Packagers! Дозвіл '{permission}' має значення show_tile 'true', тому ви не можете визначити regex URL в якості основного URL.", "regenconf_need_to_explicitly_specify_ssh": "Конфігурація ssh була змінена вручну, але вам потрібно явно вказати категорію 'ssh' з --force, щоб застосувати зміни.", - "regenconf_pending_applying": "Застосування очікує конфігурації для категорії '{категорія}'...", + "regenconf_pending_applying": "Застосування очікує конфігурації для категорії '{category}'...", "regenconf_failed": "Не вдалося відновити конфігурацію для категорії (категорій): {categories}", - "regenconf_dry_pending_applying": "Перевірка очікує конфігурації, яка була б застосована для категорії '{категорія}'…", - "regenconf_would_be_updated": "Конфігурація була б оновлена для категорії '{категорія}'", + "regenconf_dry_pending_applying": "Перевірка очікує конфігурації, яка була б застосована для категорії '{category}'…", + "regenconf_would_be_updated": "Конфігурація була б оновлена для категорії '{category}'", "regenconf_updated": "Конфігурація оновлена для категорії '{category}'", - "regenconf_up_to_date": "Конфігурація вже оновлена для категорії '{категорія}'", + "regenconf_up_to_date": "Конфігурація вже оновлена для категорії '{category}'", "regenconf_now_managed_by_yunohost": "Конфігураційний файл '{conf}' тепер управляється YunoHost (категорія {category}).", "regenconf_file_updated": "Конфігураційний файл '{conf}' оновлений", "regenconf_file_removed": "Конфігураційний файл '{conf}' видалений", @@ -145,7 +145,7 @@ "packages_upgrade_failed": "Не вдалося оновити всі пакети", "operation_interrupted": "Операція була перервана вручну?", "invalid_number": "Повинно бути число", - "not_enough_disk_space": "Недостатньо вільного місця на \"{шлях} '.", + "not_enough_disk_space": "Недостатньо вільного місця на \"{path} '.", "migrations_to_be_ran_manually": "Міграція {id} повинна бути запущена вручну. Будь ласка, перейдіть в розділ Інструменти → Міграції на сторінці веб-адміністратора або виконайте команду `yunohost tools migrations run`.", "migrations_success_forward": "Міграція {id} завершена", "migrations_skip_migration": "Пропуск міграції {id}...", @@ -258,7 +258,7 @@ "hook_name_unknown": "Невідоме ім'я хука '{name}'", "hook_list_by_invalid": "Це властивість не може бути використано для перерахування хуков", "hook_json_return_error": "Не вдалося розпізнати повернення з хука {path}. Помилка: {msg}. Необроблений контент: {raw_content}", - "hook_exec_not_terminated": "Скрипт не завершився належним чином: {шлях}", + "hook_exec_not_terminated": "Скрипт не завершився належним чином: {path}", "hook_exec_failed": "Не вдалося запустити скрипт: {path}", "group_user_not_in_group": "Користувач {user} не входить в групу {group}", "group_user_already_in_group": "Користувач {user} вже в групі {group}", @@ -297,17 +297,17 @@ "global_settings_setting_security_password_admin_strength": "Надійність пароля адміністратора", "global_settings_setting_security_nginx_compatibility": "Компроміс між сумісністю і безпекою для веб-сервера NGINX. Впливає на шифри (і інші аспекти, пов'язані з безпекою)", "global_settings_setting_pop3_enabled": "Включити протокол POP3 для поштового сервера.", - "global_settings_reset_success": "Попередні настройки тепер збережені в {шлях}.", + "global_settings_reset_success": "Попередні настройки тепер збережені в {path}.", "global_settings_key_doesnt_exists": "Ключ '{settings_key}' не існує в глобальних налаштуваннях, ви можете побачити всі доступні ключі, виконавши команду 'yunohost settings list'.", - "global_settings_cant_write_settings": "Неможливо зберегти файл настройок, причина: {причина}", - "global_settings_cant_serialize_settings": "Не вдалося серіалізовать дані налаштувань, причина: {причина}", - "global_settings_cant_open_settings": "Не вдалося відкрити файл настройок, причина: {причина}", + "global_settings_cant_write_settings": "Неможливо зберегти файл настройок, причина: {reason}", + "global_settings_cant_serialize_settings": "Не вдалося серіалізовать дані налаштувань, причина: {reason}", + "global_settings_cant_open_settings": "Не вдалося відкрити файл настройок, причина: {reason}", "global_settings_bad_type_for_setting": "Поганий тип для настройки {setting}, отриманий {received_type}, очікується {expected_type}", "global_settings_bad_choice_for_enum": "Поганий вибір для настройки {setting}, отримано '{choice}', але доступні наступні варіанти: {available_choices}.", "firewall_rules_cmd_failed": "Деякі команди правил брандмауера не спрацювали. Більш детальна інформація в журналі.", "firewall_reloaded": "брандмауер перезавантажений", "firewall_reload_failed": "Не вдалося перезавантажити брандмауер", - "file_does_not_exist": "Файл {шлях} не існує.", + "file_does_not_exist": "Файл {path} не існує.", "field_invalid": "Неприпустиме поле '{}'", "experimental_feature": "Попередження: Ця функція є експериментальною і не вважається стабільною, ви не повинні використовувати її, якщо не знаєте, що робите.", "extracting": "Витяг...", @@ -321,8 +321,8 @@ "dyndns_key_generating": "Генерація DNS-ключа... Це може зайняти деякий час.", "dyndns_ip_updated": "Оновлення свій IP-адресу в DynDNS", "dyndns_ip_update_failed": "Не вдалося оновити IP-адреса в DynDNS", - "dyndns_could_not_check_available": "Не вдалося перевірити наявність певної {домен} на {провайдера}.", - "dyndns_could_not_check_provide": "Не вдалося перевірити, чи може {провайдер} надати {домен}.", + "dyndns_could_not_check_available": "Не вдалося перевірити наявність певної {domain} на {provider}.", + "dyndns_could_not_check_provide": "Не вдалося перевірити, чи може {provider} надати {domain}.", "dpkg_lock_not_available": "Ця команда не може бути виконана прямо зараз, тому що інша програма, схоже, використовує блокування dpkg (системного менеджера пакетів).", "dpkg_is_broken": "Ви не можете зробити це прямо зараз, тому що dpkg/APT (системні менеджери пакетів), схоже, знаходяться в зламаному стані... Ви можете спробувати вирішити цю проблему, підключившись через SSH і виконавши `sudo apt install --fix-broken` і/або `sudo dpkg --configure -a`.", "downloading": "Завантаження…", @@ -331,7 +331,7 @@ "domain_unknown": "невідомий домен", "domain_name_unknown": "Домен '{domain}' невідомий", "domain_uninstall_app_first": "Ці додатки все ще встановлені на вашому домені: {apps} ласка, видаліть їх за допомогою 'yunohost app remove the_app_id' або перемістити їх на інший домен за допомогою 'yunohost app change-url the_app_id', перш ніж приступити до видалення домену.", - "domain_remove_confirm_apps_removal": "Видалення цього домену призведе до видалення цих додатків: {apps} Ви впевнені, що хочете це зробити? [{Відповіді}].", + "domain_remove_confirm_apps_removal": "Видалення цього домену призведе до видалення цих додатків: {apps} Ви впевнені, що хочете це зробити? [{answers}].", "domain_hostname_failed": "Неможливо встановити нове ім'я хоста. Це може викликати проблеми в подальшому (можливо, все буде в порядку).", "domain_exists": "Домен вже існує", "domain_dyndns_root_unknown": "Невідомий кореневої домен DynDNS", @@ -367,7 +367,7 @@ "diagnosis_http_hairpinning_issue_details": "Можливо, це пов'язано з блоком/маршрутизатором вашого інтернет-провайдера. В результаті, люди ззовні вашої локальної мережі зможуть отримати доступ до вашого сервера, як і очікувалося, але не люди зсередини локальної мережі (як ви, ймовірно?) При використанні доменного імені або глобального IP. Можливо, ви зможете поліпшити ситуацію, глянувши на https://yunohost.org/dns_local_network .", "diagnosis_http_hairpinning_issue": "Схоже, що у вашій локальній мережі не включена проброска.", "diagnosis_ports_forwarding_tip": "Щоб вирішити цю проблему, вам, швидше за все, потрібно налаштувати кидок портів на вашому інтернет-маршрутизатор, як описано в https://yunohost.org/isp_box_config.", - "diagnosis_ports_needed_by": "Відкриття цього порту необхідно для функцій {категорії} (служба {сервіс}).", + "diagnosis_ports_needed_by": "Відкриття цього порту необхідно для функцій {category} (служба {service}).", "diagnosis_ports_ok": "Порт {port} доступний ззовні.", "diagnosis_ports_partially_unreachable": "Порт {port} не доступний ззовні в IPv {failed}.", "diagnosis_ports_unreachable": "Порт {port} недоступний ззовні.", @@ -383,8 +383,8 @@ "diagnosis_description_basesystem": "Базова система", "diagnosis_security_vulnerable_to_meltdown_details": "Щоб виправити це, вам слід оновити систему і перезавантажитися, щоб завантажити нове ядро linux (або звернутися до вашого серверного провайдеру, якщо це не спрацює). Додаткову інформацію див. На сайті https://meltdownattack.com/.", "diagnosis_security_vulnerable_to_meltdown": "Схоже, що ви уразливі до критичної уразливості безпеки Meltdown.", - "diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {простір}, що вельми тривожно! Швидше за все, дисковий простір закінчиться дуже швидко! Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", - "diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {простір}. Це може бути нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", + "diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {space}, що вельми тривожно! Швидше за все, дисковий простір закінчиться дуже швидко! Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", + "diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {space}. Це може бути нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", "diagnosis_regenconf_manually_modified_details": "Це можливо нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що поновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою yunohost tools regen- conf {category} --force .", "diagnosis_regenconf_manually_modified": "Конфігураційний файл {file} , схоже, був змінений вручну.", "diagnosis_regenconf_allgood": "Всі конфігураційні файли відповідають рекомендованої конфігурації!", @@ -393,7 +393,7 @@ "diagnosis_mail_queue_unavailable": "Неможливо дізнатися кількість очікують листів в черзі", "diagnosis_mail_queue_ok": "{nb_pending} відкладені листи в поштових чергах", "diagnosis_mail_blacklist_website": "Після визначення причини, по якій ви потрапили в чорний список, і її усунення, ви можете попросити видалити ваш IP або домен на {blacklist_website}.", - "diagnosis_mail_blacklist_reason": "Причина внесення в чорний список: {причина}", + "diagnosis_mail_blacklist_reason": "Причина внесення в чорний список: {reason}", "diagnosis_mail_blacklist_listed_by": "Ваш IP або домен {item} знаходиться в чорному списку {blacklist_name}.", "diagnosis_mail_blacklist_ok": "IP-адреси і домени, які використовуються цим сервером, не внесені в чорний список", "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Поточний зворотний DNS: {rdns_domain}
Очікуване значення: {ehlo_domain} .", @@ -439,11 +439,11 @@ "updating_apt_cache": "Вибірка доступних оновлень для системних пакетів...", "update_apt_cache_warning": "Щось пішло не так при оновленні кеша APT (менеджера пакунків Debian). Ось дамп рядків sources.list, який може допомогти визначити проблемні рядки: {sourceslist}", "update_apt_cache_failed": "Неможливо оновити кеш APT (менеджер пакетів Debian). Ось дамп рядків sources.list, який може допомогти визначити проблемні рядки: {sourceslist}", - "unrestore_app": "{App} не буде поновлено", + "unrestore_app": "{app} не буде поновлено", "unlimit": "немає квоти", "unknown_main_domain_path": "Невідомий домен або шлях для '{app}'. Вам необхідно вказати домен і шлях, щоб мати можливість вказати URL для дозволу.", "unexpected_error": "Щось пішло не так: {error}", - "unbackup_app": "{App} НЕ буде збережений", + "unbackup_app": "{app} НЕ буде збережений", "tools_upgrade_special_packages_completed": "Оновлення пакета YunoHost завершено. Натисніть [Enter] для повернення командного рядка", "tools_upgrade_special_packages_explanation": "Спеціальне оновлення триватиме у фоновому режимі. Будь ласка, не запускайте ніяких інших дій на вашому сервері протягом наступних ~ 10 хвилин (в залежності від швидкості обладнання). Після цього вам, можливо, доведеться заново увійти в веб-адмін. Журнал поновлення буде доступний в Інструменти → Журнал (в веб-адміном) або за допомогою 'yunohost log list' (з командного рядка).", "tools_upgrade_special_packages": "Тепер оновлюємо \"спеціальні\" (пов'язані з yunohost) пакети…", @@ -467,12 +467,12 @@ "service_start_failed": "Не вдалося запустити службу '{service}' Recent service logs: {logs}", "diagnosis_mail_outgoing_port_25_ok": "Поштовий сервер SMTP може відправляти електронні листи (вихідний порт 25 не заблокований).", "diagnosis_swap_tip": "Будь ласка, будьте обережні і знайте, що якщо сервер розміщує своп на SD-карті або SSD-накопичувачі, це може різко скоротити термін служби устройства`.", - "diagnosis_swap_ok": "Система має {усього} свопу!", - "diagnosis_swap_notsomuch": "Система має тільки {усього} свопу. Щоб уникнути ситуацій, коли в системі закінчується пам'ять, слід передбачити наявність не менше {рекомендованого} обсягу підкачки.", - "diagnosis_swap_none": "В системі повністю відсутній своп. Ви повинні розглянути можливість додавання принаймні {рекомендованого} обсягу підкачки, щоб уникнути ситуацій, коли системі не вистачає пам'яті.", - "diagnosis_ram_ok": "Система все ще має {доступно} ({доступний_процент}%) оперативної пам'яті з {усього}.", - "diagnosis_ram_low": "У системі є {доступно} ({доступний_процент}%) оперативної пам'яті (з {усього}). Будьте уважні.", - "diagnosis_ram_verylow": "Система має тільки {доступне} ({доступний_процент}%) оперативної пам'яті! (З {усього})", + "diagnosis_swap_ok": "Система має {total} свопу!", + "diagnosis_swap_notsomuch": "Система має тільки {total} свопу. Щоб уникнути ситуацій, коли в системі закінчується пам'ять, слід передбачити наявність не менше {recommended} обсягу підкачки.", + "diagnosis_swap_none": "В системі повністю відсутній своп. Ви повинні розглянути можливість додавання принаймні {recommended} обсягу підкачки, щоб уникнути ситуацій, коли системі не вистачає пам'яті.", + "diagnosis_ram_ok": "Система все ще має {available} ({available_percent}%) оперативної пам'яті з {total}.", + "diagnosis_ram_low": "У системі є {available} ({available_percent}%) оперативної пам'яті (з {total}). Будьте уважні.", + "diagnosis_ram_verylow": "Система має тільки {available} ({available_percent}%) оперативної пам'яті! (З {total})", "diagnosis_diskusage_ok": "У сховищі {mountpoint} (на пристрої {device} ) залишилося {free} ({free_percent}%) вільного місця (з {total})!", "diagnosis_diskusage_low": "Сховище {mountpoint} (на пристрої {device} ) має тільки {free} ({free_percent}%) вільного місця (з {total}). Будьте уважні.", "diagnosis_diskusage_verylow": "Сховище {mountpoint} (на пристрої {device} ) має тільки {free} ({free_percent}%) вільного місця (з {total}). Вам дійсно варто подумати про очищення простору!", @@ -480,7 +480,7 @@ "diagnosis_services_bad_status": "Сервіс {service} знаходиться в {status} :(", "diagnosis_services_conf_broken": "Конфігурація порушена для служби {service}!", "diagnosis_services_running": "Служба {service} запущена!", - "diagnosis_domain_expires_in": "Термін дії {домену} закінчується через {днів} днів.", + "diagnosis_domain_expires_in": "Термін дії {domain} закінчується через {days} днів.", "diagnosis_domain_expiration_error": "Термін дії деяких доменів закінчується ДУЖЕ СКОРО!", "diagnosis_domain_expiration_warning": "Термін дії деяких доменів закінчиться найближчим часом!", "diagnosis_domain_expiration_success": "Ваші домени зареєстровані і не збираються спливати найближчим часом.", @@ -492,8 +492,8 @@ "diagnosis_dns_point_to_doc": "Якщо вам потрібна допомога з налаштування DNS-записів, зверніться до документації на сайті
https://yunohost.org/dns_config .", "diagnosis_dns_discrepancy": "Наступний запис DNS, схоже, не відповідає рекомендованої конфігурації:
Type: {type}
Name: {name}
Поточне значення: {current}
Очікуване значення: {value} ", "diagnosis_dns_missing_record": "Згідно рекомендованої конфігурації DNS, ви повинні додати запис DNS з наступною інформацією.
Тип: {type}
Name: {name}
Value: < code> {value} .", - "diagnosis_dns_bad_conf": "Деякі DNS-записи відсутні або невірні для домену {домен} (категорія {категорія})", - "diagnosis_dns_good_conf": "DNS-записи правильно налаштовані для домену {домен} (категорія {категорія})", + "diagnosis_dns_bad_conf": "Деякі DNS-записи відсутні або невірні для домену {domain} (категорія {category})", + "diagnosis_dns_good_conf": "DNS-записи правильно налаштовані для домену {domain} (категорія {category})", "diagnosis_ip_weird_resolvconf_details": "Файл /etc/resolv.conf повинен бути симлінк на /etc/resolvconf/run/resolv.conf , що вказує на 127.0.0.1 (dnsmasq ). Якщо ви хочете вручну налаштувати DNS Резолвер, відредагуйте /etc/resolv.dnsmasq.conf .", "diagnosis_ip_weird_resolvconf": "Дозвіл DNS, схоже, працює, але схоже, що ви використовуєте для користувача /etc/resolv.conf .", "diagnosis_ip_broken_resolvconf": "Схоже, що дозвіл доменних імен на вашому сервері порушено, що пов'язано з тим, що /etc/resolv.conf не вказує на 127.0.0.1 .", @@ -507,23 +507,23 @@ "diagnosis_ip_connected_ipv6": "Сервер підключений до Інтернету через IPv6!", "diagnosis_ip_no_ipv4": "Сервер не має працюючого IPv4.", "diagnosis_ip_connected_ipv4": "Сервер підключений до Інтернету через IPv4!", - "diagnosis_no_cache": "Для категорії \"{категорія} 'ще немає кеша діагнозів.", - "diagnosis_failed": "Не вдалося результат діагностики для категорії '{категорія}': {error}", - "diagnosis_everything_ok": "Все виглядає добре для {категорії}!", - "diagnosis_found_warnings": "Знайдено {попередження} пунктів, які можна поліпшити для {категорії}.", - "diagnosis_found_errors_and_warnings": "Знайдено {errors} істотний (і) питання (и) (і {попередження} попередження (я)), що відносяться до {category}!", + "diagnosis_no_cache": "Для категорії \"{category} 'ще немає кеша діагнозів.", + "diagnosis_failed": "Не вдалося результат діагностики для категорії '{category}': {error}", + "diagnosis_everything_ok": "Все виглядає добре для {category}!", + "diagnosis_found_warnings": "Знайдено {warnings} пунктів, які можна поліпшити для {category}.", + "diagnosis_found_errors_and_warnings": "Знайдено {errors} істотний (і) питання (и) (і {warnings} попередження (я)), що відносяться до {category}!", "diagnosis_found_errors": "Знайдена {errors} важлива проблема (і), пов'язана з {category}!", - "diagnosis_ignored_issues": "(+ {Nb_ignored} проігнорована проблема (проблеми))", - "diagnosis_cant_run_because_of_dep": "Неможливо запустити діагностику для {категорії}, поки є важливі проблеми, пов'язані з {глибиною}.", - "diagnosis_cache_still_valid": "(Кеш все ще дійсний для діагностики {категорії}. Повторна діагностика поки не проводиться!)", - "diagnosis_failed_for_category": "Не вдалося провести діагностику для категорії '{категорія}': {error}", + "diagnosis_ignored_issues": "(+ {nb_ignored} проігнорована проблема (проблеми))", + "diagnosis_cant_run_because_of_dep": "Неможливо запустити діагностику для {category}, поки є важливі проблеми, пов'язані з {dep}.", + "diagnosis_cache_still_valid": "(Кеш все ще дійсний для діагностики {category}. Повторна діагностика поки не проводиться!)", + "diagnosis_failed_for_category": "Не вдалося провести діагностику для категорії '{category}': {error}", "diagnosis_display_tip": "Щоб побачити знайдені проблеми, ви можете перейти в розділ Diagnosis в веб-адміном або виконати команду 'yunohost diagnosis show --issues --human-readable' з командного рядка.", "diagnosis_package_installed_from_sury_details": "Деякі пакети були ненавмисно встановлені з стороннього сховища під назвою Sury. Команда YunoHost поліпшила стратегію роботи з цими пакетами, але очікується, що в деяких системах, які встановили додатки PHP7.3 ще на Stretch, залишаться деякі невідповідності. Щоб виправити цю ситуацію, спробуйте виконати наступну команду: {cmd_to_fix} .", "diagnosis_package_installed_from_sury": "Деякі системні пакети повинні бути знижені в статусі", "diagnosis_backports_in_sources_list": "Схоже, що apt (менеджер пакетів) налаштований на використання сховища backports. Якщо ви не знаєте, що робите, ми настійно не рекомендуємо встановлювати пакети з backports, тому що це може привести до нестабільності або конфліктів у вашій системі.", "diagnosis_basesystem_ynh_inconsistent_versions": "Ви використовуєте несумісні версії пакетів YunoHost... швидше за все, через невдалий або часткового оновлення.", "diagnosis_basesystem_ynh_main_version": "Сервер працює під управлінням YunoHost {main_version} ({repo})", - "diagnosis_basesystem_ynh_single_version": "{Пакет} версія: {версія} ({repo})", + "diagnosis_basesystem_ynh_single_version": "{package} версія: {version} ({repo})", "diagnosis_basesystem_kernel": "Сервер працює під управлінням ядра Linux {kernel_version}", "diagnosis_basesystem_host": "Сервер працює під управлінням Debian {debian_version}", "diagnosis_basesystem_hardware_model": "Модель сервера - {model}", @@ -531,7 +531,7 @@ "custom_app_url_required": "Ви повинні надати URL для оновлення вашого призначеного для користувача додатки {app}.", "confirm_app_install_thirdparty": "НЕБЕЗПЕЧНО! Ця програма не входить в каталог додатків YunoHost. Установлення сторонніх додатків може порушити цілісність і безпеку вашої системи. Вам не слід встановлювати його, якщо ви не знаєте, що робите. НІЯКОЇ ПІДТРИМКИ НЕ БУДЕ, якщо цей додаток не буде працювати або зламає вашу систему... Якщо ви все одно готові піти на такий ризик, введіть '{answers}'.", "confirm_app_install_danger": "НЕБЕЗПЕЧНО! Відомо, що це додаток все ще експериментальне (якщо не сказати, що воно явно не працює)! Вам не слід встановлювати його, якщо ви не знаєте, що робите. Ніякої підтримки не буде надано, якщо цей додаток не буде працювати або зламає вашу систему... Якщо ви все одно готові ризикнути, введіть '{answers}'.", - "confirm_app_install_warning": "Попередження: Ця програма може працювати, але не дуже добре інтегровано в YunoHost. Деякі функції, такі як єдина реєстрація та резервне копіювання/відновлення, можуть бути недоступні. Все одно встановити? [{Відповіді}]. ", + "confirm_app_install_warning": "Попередження: Ця програма може працювати, але не дуже добре інтегровано в YunoHost. Деякі функції, такі як єдина реєстрація та резервне копіювання/відновлення, можуть бути недоступні. Все одно встановити? [{answers}]. ", "certmanager_unable_to_parse_self_CA_name": "Не вдалося розібрати ім'я самоподпісивающегося центру (файл: {file})", "certmanager_self_ca_conf_file_not_found": "Не вдалося знайти файл конфігурації для самоподпісивающегося центру (файл: {file})", "certmanager_no_cert_file": "Не вдалося розпізнати файл сертифіката для домену {domain} (файл: {file})", @@ -546,12 +546,12 @@ "certmanager_cert_renew_success": "Сертифікат Let's Encrypt оновлений для домену '{domain}'", "certmanager_cert_install_success_selfsigned": "Самоподпісанний сертифікат тепер встановлений для домену '{domain}'", "certmanager_cert_install_success": "Сертифікат Let's Encrypt тепер встановлений для домену '{domain}'", - "certmanager_cannot_read_cert": "Щось не так сталося при спробі відкрити поточний сертифікат для домену {domain} (файл: {файл}), причина: {причина}", + "certmanager_cannot_read_cert": "Щось не так сталося при спробі відкрити поточний сертифікат для домену {domain} (файл: {file}), причина: {reason}", "certmanager_attempt_to_replace_valid_cert": "Ви намагаєтеся перезаписати хороший і дійсний сертифікат для домену {domain}! (Використовуйте --force для обходу)", "certmanager_attempt_to_renew_valid_cert": "Термін дії сертифіката для домену '{domain} \"не закінчується! (Ви можете використовувати --force, якщо знаєте, що робите)", "certmanager_attempt_to_renew_nonLE_cert": "Сертифікат для домену '{domain}' не випущено Let's Encrypt. Неможливо продовжити його автоматично!", "certmanager_acme_not_configured_for_domain": "Завдання ACME не може бути запущена для {domain} прямо зараз, тому що в його nginx conf відсутній відповідний фрагмент коду... Будь ласка, переконайтеся, що конфігурація nginx оновлена за допомогою `yunohost tools regen-conf nginx --dry-run - with-diff`.", - "backup_with_no_restore_script_for_app": "{App} не має скрипта відновлення, ви не зможете автоматично відновити резервну копію цього додатка.", + "backup_with_no_restore_script_for_app": "{app} не має скрипта відновлення, ви не зможете автоматично відновити резервну копію цього додатка.", "backup_with_no_backup_script_for_app": "Додаток '{app}' не має скрипта резервного копіювання. Ігнорування.", "backup_unable_to_organize_files": "Неможливо використовувати швидкий метод для організації файлів в архіві", "backup_system_part_failed": "Не вдалося створити резервну копію системної частини '{part}'.", @@ -565,7 +565,7 @@ "backup_no_uncompress_archive_dir": "Немає такого каталогу нестислого архіву", "backup_mount_archive_for_restore": "Підготовка архіву для відновлення...", "backup_method_tar_finished": "Створено архів резервного копіювання TAR", - "backup_method_custom_finished": "Призначений для користувача метод резервного копіювання '{метод}' завершено", + "backup_method_custom_finished": "Призначений для користувача метод резервного копіювання '{method}' завершено", "backup_method_copy_finished": "Резервне копіювання завершено", "backup_hook_unknown": "Гачок резервного копіювання '{hook}' невідомий", "backup_deleted": "Резервна копія видалена", @@ -575,7 +575,7 @@ "backup_csv_creation_failed": "Не вдалося створити CSV-файл, необхідний для відновлення", "backup_csv_addition_failed": "Не вдалося додати файли для резервного копіювання в CSV-файл", "backup_creation_failed": "Не вдалося створити архів резервного копіювання", - "backup_create_size_estimation": "Архів буде містити близько {розмір} даних.", + "backup_create_size_estimation": "Архів буде містити близько {size} даних.", "backup_created": "Резервна копія створена", "backup_couldnt_bind": "Не вдалося зв'язати {src} з {dest}.", "backup_copying_to_organize_the_archive": "Копіювання {size} MB для організації архіву", @@ -592,7 +592,7 @@ "backup_archive_broken_link": "Не вдалося отримати доступ до архіву резервного копіювання (непрацююча посилання на {path})", "backup_archive_app_not_found": "Не вдалося знайти {app} в архіві резервного копіювання", "backup_applying_method_tar": "Створення резервного TAR-архіву...", - "backup_applying_method_custom": "Виклик для користувача методу резервного копіювання '{метод}'...", + "backup_applying_method_custom": "Виклик для користувача методу резервного копіювання '{method}'...", "backup_applying_method_copy": "Копіювання всіх файлів в резервну копію...", "backup_app_failed": "Не вдалося створити резервну копію {app}", "backup_actually_backuping": "Створення резервного архіву з зібраних файлів...", @@ -612,7 +612,7 @@ "apps_catalog_init_success": "Система каталогу додатків инициализирована!", "apps_already_up_to_date": "Всі додатки вже оновлені", "app_packaging_format_not_supported": "Ця програма не може бути встановлено, тому що формат його упаковки не підтримується вашою версією YunoHost. Можливо, вам слід оновити вашу систему.", - "app_upgraded": "{App} оновлено", + "app_upgraded": "{app} оновлено", "app_upgrade_some_app_failed": "Деякі програми не можуть бути оновлені", "app_upgrade_script_failed": "Сталася помилка в сценарії оновлення програми", "app_upgrade_failed": "Не вдалося оновити {app}: {error}", @@ -630,10 +630,10 @@ "app_remove_after_failed_install": "Видалення програми після збою установки...", "app_requirements_unmeet": "Вимоги не виконані для {app}, пакет {pkgname} ({version}) повинен бути {spec}.", "app_requirements_checking": "Перевірка необхідних пакетів для {app}...", - "app_removed": "{App} видалено", - "app_not_properly_removed": "{App} не було видалено належним чином", + "app_removed": "{app} видалено", + "app_not_properly_removed": "{app} не було видалено належним чином", "app_not_installed": "Не вдалося знайти {app} в списку встановлених додатків: {all_apps}", - "app_not_correctly_installed": "{App}, схоже, неправильно встановлено", + "app_not_correctly_installed": "{app}, схоже, неправильно встановлено", "app_not_upgraded": "Додаток '{failed_app}' не вдалося оновити, і, як наслідок, оновлення таких програмах було скасовано: {apps}", "app_manifest_install_ask_is_public": "Чи повинно це додаток бути відкрито для анонімних відвідувачів?", "app_manifest_install_ask_admin": "Виберіть користувача-адміністратора для цього додатка", From caef1e0577a1b0f3d0136d337193bc1c65280b4c Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Thu, 2 Sep 2021 14:08:18 +0200 Subject: [PATCH 075/101] Update src/yunohost/log.py --- src/yunohost/log.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index f9f9334fb..4994d608c 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -373,7 +373,11 @@ def is_unit_operation( if field in context: context.pop(field, None) - # Manage file or stream + # Context is made from args given to main function by argparse + # This context will be added in extra parameters in yml file, so this context should + # be serializable and short enough (it will be displayed in webadmin) + # Argparse can provide some File or Stream, so here we display the filename or + # the IOBase, if we have no name. for field, value in context.items(): if isinstance(value, IOBase): try: From f2487a2251fdc8c19dc5dbd14a8eb3707f97156f Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Thu, 2 Sep 2021 14:24:06 +0200 Subject: [PATCH 076/101] Avoid confusing things in user_list --- src/yunohost/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 0cdd0d3ae..65edf5821 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -64,7 +64,7 @@ def user_list(fields=None): ldap_attrs = { 'username': 'uid', - 'password': 'uid', + 'password': '', # We can't request password in ldap 'fullname': 'cn', 'firstname': 'givenName', 'lastname': 'sn', From e27f38ae69aeb9308d8166e366f764f8afd8378f Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Thu, 2 Sep 2021 14:33:06 +0200 Subject: [PATCH 077/101] Test group remove on csv import --- src/yunohost/tests/test_user-group.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index d3b3c81aa..ab7e72555 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -158,6 +158,7 @@ def test_import_user(mocker): assert len(user_res['alice']['mail-alias']) == 2 assert "albert" in group_res['dev']['members'] assert "alice" in group_res['apps']['members'] + assert "alice" not in group_res['dev']['members'] def test_export_user(mocker): From 57a2e4032fecb9eb4d2b59b4ab483fad50621eeb Mon Sep 17 00:00:00 2001 From: Kayou Date: Thu, 2 Sep 2021 16:52:16 +0200 Subject: [PATCH 078/101] replace msettings by Moulinette --- src/yunohost/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 57e8aac41..07d1773b3 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -631,7 +631,7 @@ def user_export(): writer.writerow(user) body = csv_io.getvalue().rstrip() - if msettings.get('interface') == 'api': + if Moulinette.interface.type == 'api': # We return a raw bottle HTTPresponse (instead of serializable data like # list/dict, ...), which is gonna be picked and used directly by moulinette from bottle import HTTPResponse From c197e171bbc3d18a095d0b9bb3a0f72d57afab3e Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Thu, 2 Sep 2021 15:04:02 +0000 Subject: [PATCH 079/101] [CI] Format code --- src/yunohost/log.py | 4 +- src/yunohost/tests/test_user-group.py | 80 +++--- src/yunohost/user.py | 386 +++++++++++++++----------- 3 files changed, 269 insertions(+), 201 deletions(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 6460d8d4a..3f6382af2 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -373,7 +373,7 @@ def is_unit_operation( context.pop(field, None) # Context is made from args given to main function by argparse - # This context will be added in extra parameters in yml file, so this context should + # This context will be added in extra parameters in yml file, so this context should # be serializable and short enough (it will be displayed in webadmin) # Argparse can provide some File or Stream, so here we display the filename or # the IOBase, if we have no name. @@ -382,7 +382,7 @@ def is_unit_operation( try: context[field] = value.name except: - context[field] = 'IOBase' + context[field] = "IOBase" operation_logger = OperationLogger(op_key, related_to, args=context) try: diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index ab7e72555..60e748108 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -117,53 +117,65 @@ def test_del_user(mocker): def test_import_user(mocker): import csv from io import StringIO - fieldnames = [u'username', u'firstname', u'lastname', u'password', - u'mailbox-quota', u'mail', u'mail-alias', u'mail-forward', - u'groups'] + + fieldnames = [ + "username", + "firstname", + "lastname", + "password", + "mailbox-quota", + "mail", + "mail-alias", + "mail-forward", + "groups", + ] with StringIO() as csv_io: - writer = csv.DictWriter(csv_io, fieldnames, delimiter=';', - quotechar='"') + writer = csv.DictWriter(csv_io, fieldnames, delimiter=";", quotechar='"') writer.writeheader() - writer.writerow({ - 'username': "albert", - 'firstname': "Albert", - 'lastname': "Good", - 'password': "", - 'mailbox-quota': "1G", - 'mail': "albert@" + maindomain, - 'mail-alias': "albert2@" + maindomain, - 'mail-forward': "albert@example.com", - 'groups': "dev", - }) - writer.writerow({ - 'username': "alice", - 'firstname': "Alice", - 'lastname': "White", - 'password': "", - 'mailbox-quota': "1G", - 'mail': "alice@" + maindomain, - 'mail-alias': "alice1@" + maindomain + ",alice2@" + maindomain, - 'mail-forward': "", - 'groups': "apps", - }) + writer.writerow( + { + "username": "albert", + "firstname": "Albert", + "lastname": "Good", + "password": "", + "mailbox-quota": "1G", + "mail": "albert@" + maindomain, + "mail-alias": "albert2@" + maindomain, + "mail-forward": "albert@example.com", + "groups": "dev", + } + ) + writer.writerow( + { + "username": "alice", + "firstname": "Alice", + "lastname": "White", + "password": "", + "mailbox-quota": "1G", + "mail": "alice@" + maindomain, + "mail-alias": "alice1@" + maindomain + ",alice2@" + maindomain, + "mail-forward": "", + "groups": "apps", + } + ) csv_io.seek(0) with message(mocker, "user_import_success"): user_import(csv_io, update=True, delete=True) - group_res = user_group_list()['groups'] - user_res = user_list(list(FIELDS_FOR_IMPORT.keys()))['users'] + group_res = user_group_list()["groups"] + user_res = user_list(list(FIELDS_FOR_IMPORT.keys()))["users"] assert "albert" in user_res assert "alice" in user_res assert "bob" not in user_res - assert len(user_res['alice']['mail-alias']) == 2 - assert "albert" in group_res['dev']['members'] - assert "alice" in group_res['apps']['members'] - assert "alice" not in group_res['dev']['members'] + assert len(user_res["alice"]["mail-alias"]) == 2 + assert "albert" in group_res["dev"]["members"] + assert "alice" in group_res["apps"]["members"] + assert "alice" not in group_res["dev"]["members"] def test_export_user(mocker): result = user_export() - aliases = ','.join([alias + maindomain for alias in FIRST_ALIASES]) + aliases = ",".join([alias + maindomain for alias in FIRST_ALIASES]) should_be = ( "username;firstname;lastname;password;mail;mail-alias;mail-forward;mailbox-quota;groups\r\n" f"alice;Alice;White;;alice@{maindomain};{aliases};;0;dev\r\n" diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 07d1773b3..c89f9a05f 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -44,18 +44,18 @@ from yunohost.log import is_unit_operation logger = getActionLogger("yunohost.user") FIELDS_FOR_IMPORT = { - 'username': r'^[a-z0-9_]+$', - 'firstname': r'^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$', - 'lastname': r'^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$', - 'password': r'^|(.{3,})$', - 'mail': r'^([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}))$', - 'mail-alias': r'^|([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', - 'mail-forward': r'^|([\w\+.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$', - 'mailbox-quota': r'^(\d+[bkMGT])|0|$', - 'groups': r'^|([a-z0-9_]+(,?[a-z0-9_]+)*)$' + "username": r"^[a-z0-9_]+$", + "firstname": r"^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$", + "lastname": r"^([^\W\d_]{1,30}[ ,.\'-]{0,3})+$", + "password": r"^|(.{3,})$", + "mail": r"^([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}))$", + "mail-alias": r"^|([\w.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$", + "mail-forward": r"^|([\w\+.-]+@([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}),?)+$", + "mailbox-quota": r"^(\d+[bkMGT])|0|$", + "groups": r"^|([a-z0-9_]+(,?[a-z0-9_]+)*)$", } -FIRST_ALIASES = ['root@', 'admin@', 'webmaster@', 'postmaster@', 'abuse@'] +FIRST_ALIASES = ["root@", "admin@", "webmaster@", "postmaster@", "abuse@"] def user_list(fields=None): @@ -63,47 +63,51 @@ def user_list(fields=None): from yunohost.utils.ldap import _get_ldap_interface ldap_attrs = { - 'username': 'uid', - 'password': '', # We can't request password in ldap - 'fullname': 'cn', - 'firstname': 'givenName', - 'lastname': 'sn', - 'mail': 'mail', - 'mail-alias': 'mail', - 'mail-forward': 'maildrop', - 'mailbox-quota': 'mailuserquota', - 'groups': 'memberOf', - 'shell': 'loginShell', - 'home-path': 'homeDirectory' + "username": "uid", + "password": "", # We can't request password in ldap + "fullname": "cn", + "firstname": "givenName", + "lastname": "sn", + "mail": "mail", + "mail-alias": "mail", + "mail-forward": "maildrop", + "mailbox-quota": "mailuserquota", + "groups": "memberOf", + "shell": "loginShell", + "home-path": "homeDirectory", } def display_default(values, _): return values[0] if len(values) == 1 else values display = { - 'password': lambda values, user: '', - 'mail': lambda values, user: display_default(values[:1], user), - 'mail-alias': lambda values, _: values[1:], - 'mail-forward': lambda values, user: [forward for forward in values if forward != user['uid'][0]], - 'groups': lambda values, user: [ - group[3:].split(',')[0] + "password": lambda values, user: "", + "mail": lambda values, user: display_default(values[:1], user), + "mail-alias": lambda values, _: values[1:], + "mail-forward": lambda values, user: [ + forward for forward in values if forward != user["uid"][0] + ], + "groups": lambda values, user: [ + group[3:].split(",")[0] for group in values - if not group.startswith('cn=all_users,') and - not group.startswith('cn=' + user['uid'][0] + ',')], - 'shell': lambda values, _: len(values) > 0 and values[0].strip() == "/bin/false" + if not group.startswith("cn=all_users,") + and not group.startswith("cn=" + user["uid"][0] + ",") + ], + "shell": lambda values, _: len(values) > 0 + and values[0].strip() == "/bin/false", } - attrs = set(['uid']) + attrs = set(["uid"]) users = {} if not fields: - fields = ['username', 'fullname', 'mail', 'mailbox-quota'] + fields = ["username", "fullname", "mail", "mailbox-quota"] for field in fields: if field in ldap_attrs: attrs.add(ldap_attrs[field]) else: - raise YunohostError('field_invalid', field) + raise YunohostError("field_invalid", field) ldap = _get_ldap_interface() result = ldap.search( @@ -120,7 +124,7 @@ def user_list(fields=None): values = user[ldap_attrs[field]] entry[field] = display.get(field, display_default)(values, user) - users[user['uid'][0]] = entry + users[user["uid"][0]] = entry return {"users": users} @@ -135,7 +139,7 @@ def user_create( password, mailbox_quota="0", mail=None, - from_import=False + from_import=False, ): from yunohost.domain import domain_list, _get_maindomain @@ -253,10 +257,9 @@ def user_create( # Attempt to create user home folder subprocess.check_call(["mkhomedir_helper", username]) except subprocess.CalledProcessError: - home = f'/home/{username}' + home = f"/home/{username}" if not os.path.isdir(home): - logger.warning(m18n.n('user_home_creation_failed', home=home), - exc_info=1) + logger.warning(m18n.n("user_home_creation_failed", home=home), exc_info=1) try: subprocess.check_call( @@ -282,12 +285,12 @@ def user_create( # TODO: Send a welcome mail to user if not from_import: - logger.success(m18n.n('user_created')) + logger.success(m18n.n("user_created")) return {"fullname": fullname, "username": username, "mail": mail} -@is_unit_operation([('username', 'user')]) +@is_unit_operation([("username", "user")]) def user_delete(operation_logger, username, purge=False, from_import=False): """ Delete user @@ -331,13 +334,14 @@ def user_delete(operation_logger, username, purge=False, from_import=False): subprocess.call(["nscd", "-i", "passwd"]) if purge: - subprocess.call(['rm', '-rf', '/home/{0}'.format(username)]) - subprocess.call(['rm', '-rf', '/var/mail/{0}'.format(username)]) + subprocess.call(["rm", "-rf", "/home/{0}".format(username)]) + subprocess.call(["rm", "-rf", "/var/mail/{0}".format(username)]) - hook_callback('post_user_delete', args=[username, purge]) + hook_callback("post_user_delete", args=[username, purge]) if not from_import: - logger.success(m18n.n('user_deleted')) + logger.success(m18n.n("user_deleted")) + @is_unit_operation([("username", "user")], exclude=["change_password"]) def user_update( @@ -352,7 +356,7 @@ def user_update( add_mailalias=None, remove_mailalias=None, mailbox_quota=None, - from_import=False + from_import=False, ): """ Update user informations @@ -412,7 +416,7 @@ def user_update( ] # change_password is None if user_update is not called to change the password - if change_password is not None and change_password != '': + if change_password is not None and change_password != "": # when in the cli interface if the option to change the password is called # without a specified value, change_password will be set to the const 0. # In this case we prompt for the new password. @@ -429,20 +433,22 @@ def user_update( aliases = [alias + main_domain for alias in FIRST_ALIASES] # If the requested mail address is already as main address or as an alias by this user - if mail in user['mail']: - user['mail'].remove(mail) + if mail in user["mail"]: + user["mail"].remove(mail) # Othewise, check that this mail address is not already used by this user else: try: - ldap.validate_uniqueness({'mail': mail}) + ldap.validate_uniqueness({"mail": mail}) except Exception as e: - raise YunohostError('user_update_failed', user=username, error=e) - if mail[mail.find('@') + 1:] not in domains: - raise YunohostError('mail_domain_unknown', domain=mail[mail.find('@') + 1:]) + raise YunohostError("user_update_failed", user=username, error=e) + if mail[mail.find("@") + 1 :] not in domains: + raise YunohostError( + "mail_domain_unknown", domain=mail[mail.find("@") + 1 :] + ) if mail in aliases: raise YunohostValidationError("mail_unavailable") - new_attr_dict['mail'] = [mail] + user['mail'][1:] + new_attr_dict["mail"] = [mail] + user["mail"][1:] if add_mailalias: if not isinstance(add_mailalias, list): @@ -455,12 +461,10 @@ def user_update( try: ldap.validate_uniqueness({"mail": mail}) except Exception as e: - raise YunohostError( - "user_update_failed", user=username, error=e - ) - if mail[mail.find("@") + 1:] not in domains: + raise YunohostError("user_update_failed", user=username, error=e) + if mail[mail.find("@") + 1 :] not in domains: raise YunohostError( - "mail_domain_unknown", domain=mail[mail.find("@") + 1:] + "mail_domain_unknown", domain=mail[mail.find("@") + 1 :] ) user["mail"].append(mail) new_attr_dict["mail"] = user["mail"] @@ -517,7 +521,7 @@ def user_update( if not from_import: app_ssowatconf() - logger.success(m18n.n('user_updated')) + logger.success(m18n.n("user_updated")) return user_info(username) @@ -548,13 +552,13 @@ def user_info(username): raise YunohostValidationError("user_unknown", user=username) result_dict = { - 'username': user['uid'][0], - 'fullname': user['cn'][0], - 'firstname': user['givenName'][0], - 'lastname': user['sn'][0], - 'mail': user['mail'][0], - 'mail-aliases': [], - 'mail-forward': [] + "username": user["uid"][0], + "fullname": user["cn"][0], + "firstname": user["givenName"][0], + "lastname": user["sn"][0], + "mail": user["mail"][0], + "mail-aliases": [], + "mail-forward": [], } if len(user["mail"]) > 1: @@ -619,27 +623,32 @@ def user_export(): """ import csv # CSV are needed only in this function from io import StringIO + with StringIO() as csv_io: - writer = csv.DictWriter(csv_io, list(FIELDS_FOR_IMPORT.keys()), - delimiter=';', quotechar='"') + writer = csv.DictWriter( + csv_io, list(FIELDS_FOR_IMPORT.keys()), delimiter=";", quotechar='"' + ) writer.writeheader() - users = user_list(list(FIELDS_FOR_IMPORT.keys()))['users'] + users = user_list(list(FIELDS_FOR_IMPORT.keys()))["users"] for username, user in users.items(): - user['mail-alias'] = ','.join(user['mail-alias']) - user['mail-forward'] = ','.join(user['mail-forward']) - user['groups'] = ','.join(user['groups']) + user["mail-alias"] = ",".join(user["mail-alias"]) + user["mail-forward"] = ",".join(user["mail-forward"]) + user["groups"] = ",".join(user["groups"]) writer.writerow(user) body = csv_io.getvalue().rstrip() - if Moulinette.interface.type == 'api': + if Moulinette.interface.type == "api": # We return a raw bottle HTTPresponse (instead of serializable data like # list/dict, ...), which is gonna be picked and used directly by moulinette from bottle import HTTPResponse - response = HTTPResponse(body=body, - headers={ - "Content-Disposition": "attachment; filename=users.csv", - "Content-Type": "text/csv", - }) + + response = HTTPResponse( + body=body, + headers={ + "Content-Disposition": "attachment; filename=users.csv", + "Content-Type": "text/csv", + }, + ) return response else: return body @@ -662,106 +671,121 @@ def user_import(operation_logger, csvfile, update=False, delete=False): from yunohost.domain import domain_list # Pre-validate data and prepare what should be done - actions = { - 'created': [], - 'updated': [], - 'deleted': [] - } + actions = {"created": [], "updated": [], "deleted": []} is_well_formatted = True def to_list(str_list): - L = str_list.split(',') if str_list else [] + L = str_list.split(",") if str_list else [] L = [l.strip() for l in L] return L - existing_users = user_list()['users'] + existing_users = user_list()["users"] existing_groups = user_group_list()["groups"] existing_domains = domain_list()["domains"] - reader = csv.DictReader(csvfile, delimiter=';', quotechar='"') + reader = csv.DictReader(csvfile, delimiter=";", quotechar='"') users_in_csv = [] - missing_columns = [key for key in FIELDS_FOR_IMPORT.keys() if key not in reader.fieldnames] + missing_columns = [ + key for key in FIELDS_FOR_IMPORT.keys() if key not in reader.fieldnames + ] if missing_columns: - raise YunohostValidationError("user_import_missing_columns", columns=', '.join(missing_columns)) + raise YunohostValidationError( + "user_import_missing_columns", columns=", ".join(missing_columns) + ) for user in reader: # Validate column values against regexes - format_errors = [f"{key}: '{user[key]}' doesn't match the expected format" - for key, validator in FIELDS_FOR_IMPORT.items() - if user[key] is None or not re.match(validator, user[key])] + format_errors = [ + f"{key}: '{user[key]}' doesn't match the expected format" + for key, validator in FIELDS_FOR_IMPORT.items() + if user[key] is None or not re.match(validator, user[key]) + ] # Check for duplicated username lines - if user['username'] in users_in_csv: + if user["username"] in users_in_csv: format_errors.append(f"username '{user['username']}' duplicated") - users_in_csv.append(user['username']) + users_in_csv.append(user["username"]) # Validate that groups exist - user['groups'] = to_list(user['groups']) - unknown_groups = [g for g in user['groups'] if g not in existing_groups] + user["groups"] = to_list(user["groups"]) + unknown_groups = [g for g in user["groups"] if g not in existing_groups] if unknown_groups: - format_errors.append(f"username '{user['username']}': unknown groups %s" % ', '.join(unknown_groups)) + format_errors.append( + f"username '{user['username']}': unknown groups %s" + % ", ".join(unknown_groups) + ) # Validate that domains exist - user['mail-alias'] = to_list(user['mail-alias']) - user['mail-forward'] = to_list(user['mail-forward']) - user['domain'] = user['mail'].split('@')[1] + user["mail-alias"] = to_list(user["mail-alias"]) + user["mail-forward"] = to_list(user["mail-forward"]) + user["domain"] = user["mail"].split("@")[1] unknown_domains = [] - if user['domain'] not in existing_domains: - unknown_domains.append(user['domain']) + if user["domain"] not in existing_domains: + unknown_domains.append(user["domain"]) - unknown_domains += [mail.split('@', 1)[1] for mail in user['mail-alias'] if mail.split('@', 1)[1] not in existing_domains] + unknown_domains += [ + mail.split("@", 1)[1] + for mail in user["mail-alias"] + if mail.split("@", 1)[1] not in existing_domains + ] unknown_domains = set(unknown_domains) if unknown_domains: - format_errors.append(f"username '{user['username']}': unknown domains %s" % ', '.join(unknown_domains)) + format_errors.append( + f"username '{user['username']}': unknown domains %s" + % ", ".join(unknown_domains) + ) if format_errors: - logger.error(m18n.n('user_import_bad_line', - line=reader.line_num, - details=', '.join(format_errors))) + logger.error( + m18n.n( + "user_import_bad_line", + line=reader.line_num, + details=", ".join(format_errors), + ) + ) is_well_formatted = False continue # Choose what to do with this line and prepare data - user['mailbox-quota'] = user['mailbox-quota'] or "0" + user["mailbox-quota"] = user["mailbox-quota"] or "0" # User creation - if user['username'] not in existing_users: + if user["username"] not in existing_users: # Generate password if not exists # This could be used when reset password will be merged - if not user['password']: - user['password'] = random_ascii(70) - actions['created'].append(user) + if not user["password"]: + user["password"] = random_ascii(70) + actions["created"].append(user) # User update elif update: - actions['updated'].append(user) + actions["updated"].append(user) if delete: - actions['deleted'] = [user for user in existing_users if user not in users_in_csv] + actions["deleted"] = [ + user for user in existing_users if user not in users_in_csv + ] if delete and not users_in_csv: - logger.error("You used the delete option with an empty csv file ... You probably did not really mean to do that, did you !?") + logger.error( + "You used the delete option with an empty csv file ... You probably did not really mean to do that, did you !?" + ) is_well_formatted = False if not is_well_formatted: - raise YunohostValidationError('user_import_bad_file') + raise YunohostValidationError("user_import_bad_file") - total = len(actions['created'] + actions['updated'] + actions['deleted']) + total = len(actions["created"] + actions["updated"] + actions["deleted"]) if total == 0: - logger.info(m18n.n('user_import_nothing_to_do')) + logger.info(m18n.n("user_import_nothing_to_do")) return # Apply creation, update and deletion operation - result = { - 'created': 0, - 'updated': 0, - 'deleted': 0, - 'errors': 0 - } + result = {"created": 0, "updated": 0, "deleted": 0, "errors": 0} def progress(info=""): progress.nb += 1 @@ -774,12 +798,13 @@ def user_import(operation_logger, csvfile, update=False, delete=False): return progress.old = bar logger.info(bar) + progress.nb = 0 progress.old = "" def on_failure(user, exception): - result['errors'] += 1 - logger.error(user + ': ' + str(exception)) + result["errors"] += 1 + logger.error(user + ": " + str(exception)) def update(new_infos, old_infos=False): remove_alias = None @@ -787,11 +812,21 @@ def user_import(operation_logger, csvfile, update=False, delete=False): remove_groups = [] add_groups = new_infos["groups"] if old_infos: - new_infos['mail'] = None if old_infos['mail'] == new_infos['mail'] else new_infos['mail'] - remove_alias = list(set(old_infos['mail-alias']) - set(new_infos['mail-alias'])) - remove_forward = list(set(old_infos['mail-forward']) - set(new_infos['mail-forward'])) - new_infos['mail-alias'] = list(set(new_infos['mail-alias']) - set(old_infos['mail-alias'])) - new_infos['mail-forward'] = list(set(new_infos['mail-forward']) - set(old_infos['mail-forward'])) + new_infos["mail"] = ( + None if old_infos["mail"] == new_infos["mail"] else new_infos["mail"] + ) + remove_alias = list( + set(old_infos["mail-alias"]) - set(new_infos["mail-alias"]) + ) + remove_forward = list( + set(old_infos["mail-forward"]) - set(new_infos["mail-forward"]) + ) + new_infos["mail-alias"] = list( + set(new_infos["mail-alias"]) - set(old_infos["mail-alias"]) + ) + new_infos["mail-forward"] = list( + set(new_infos["mail-forward"]) - set(old_infos["mail-forward"]) + ) remove_groups = list(set(old_infos["groups"]) - set(new_infos["groups"])) add_groups = list(set(new_infos["groups"]) - set(old_infos["groups"])) @@ -799,69 +834,90 @@ def user_import(operation_logger, csvfile, update=False, delete=False): for group, infos in existing_groups.items(): # Loop only on groups in 'remove_groups' # Ignore 'all_users' and primary group - if group in ["all_users", new_infos['username']] or group not in remove_groups: + if ( + group in ["all_users", new_infos["username"]] + or group not in remove_groups + ): continue # If the user is in this group (and it's not the primary group), # remove the member from the group - if new_infos['username'] in infos["members"]: - user_group_update(group, remove=new_infos['username'], sync_perm=False, from_import=True) + if new_infos["username"] in infos["members"]: + user_group_update( + group, + remove=new_infos["username"], + sync_perm=False, + from_import=True, + ) - user_update(new_infos['username'], - new_infos['firstname'], new_infos['lastname'], - new_infos['mail'], new_infos['password'], - mailbox_quota=new_infos['mailbox-quota'], - mail=new_infos['mail'], add_mailalias=new_infos['mail-alias'], - remove_mailalias=remove_alias, - remove_mailforward=remove_forward, - add_mailforward=new_infos['mail-forward'], from_import=True) + user_update( + new_infos["username"], + new_infos["firstname"], + new_infos["lastname"], + new_infos["mail"], + new_infos["password"], + mailbox_quota=new_infos["mailbox-quota"], + mail=new_infos["mail"], + add_mailalias=new_infos["mail-alias"], + remove_mailalias=remove_alias, + remove_mailforward=remove_forward, + add_mailforward=new_infos["mail-forward"], + from_import=True, + ) for group in add_groups: - if group in ["all_users", new_infos['username']]: + if group in ["all_users", new_infos["username"]]: continue - user_group_update(group, add=new_infos['username'], sync_perm=False, from_import=True) + user_group_update( + group, add=new_infos["username"], sync_perm=False, from_import=True + ) - users = user_list(list(FIELDS_FOR_IMPORT.keys()))['users'] + users = user_list(list(FIELDS_FOR_IMPORT.keys()))["users"] operation_logger.start() # We do delete and update before to avoid mail uniqueness issues - for user in actions['deleted']: + for user in actions["deleted"]: try: user_delete(user, purge=True, from_import=True) - result['deleted'] += 1 + result["deleted"] += 1 except YunohostError as e: on_failure(user, e) progress(f"Deleting {user}") - for user in actions['updated']: + for user in actions["updated"]: try: - update(user, users[user['username']]) - result['updated'] += 1 + update(user, users[user["username"]]) + result["updated"] += 1 except YunohostError as e: - on_failure(user['username'], e) + on_failure(user["username"], e) progress(f"Updating {user['username']}") - for user in actions['created']: + for user in actions["created"]: try: - user_create(user['username'], - user['firstname'], user['lastname'], - user['domain'], user['password'], - user['mailbox-quota'], from_import=True) + user_create( + user["username"], + user["firstname"], + user["lastname"], + user["domain"], + user["password"], + user["mailbox-quota"], + from_import=True, + ) update(user) - result['created'] += 1 + result["created"] += 1 except YunohostError as e: - on_failure(user['username'], e) + on_failure(user["username"], e) progress(f"Creating {user['username']}") permission_sync_to_user() app_ssowatconf() - if result['errors']: - msg = m18n.n('user_import_partial_failed') - if result['created'] + result['updated'] + result['deleted'] == 0: - msg = m18n.n('user_import_failed') + if result["errors"]: + msg = m18n.n("user_import_partial_failed") + if result["created"] + result["updated"] + result["deleted"] == 0: + msg = m18n.n("user_import_failed") logger.error(msg) operation_logger.error(msg) else: - logger.success(m18n.n('user_import_success')) + logger.success(m18n.n("user_import_success")) operation_logger.success() return result @@ -1038,7 +1094,7 @@ def user_group_delete(operation_logger, groupname, force=False, sync_perm=True): logger.debug(m18n.n("group_deleted", group=groupname)) -@is_unit_operation([('groupname', 'group')]) +@is_unit_operation([("groupname", "group")]) def user_group_update( operation_logger, groupname, @@ -1046,7 +1102,7 @@ def user_group_update( remove=None, force=False, sync_perm=True, - from_import=False + from_import=False, ): """ Update user informations From 10fddc427ed9dc8dad1b2bc7c1250e2383fb30bb Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 3 Sep 2021 02:01:16 +0200 Subject: [PATCH 080/101] ci: Add magic script to automagically fix i18n string format in trivial case --- .gitlab/ci/translation.gitlab-ci.yml | 11 ++++--- tests/autofix_locale_format.py | 47 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 tests/autofix_locale_format.py diff --git a/.gitlab/ci/translation.gitlab-ci.yml b/.gitlab/ci/translation.gitlab-ci.yml index d7962436c..5e50cd20e 100644 --- a/.gitlab/ci/translation.gitlab-ci.yml +++ b/.gitlab/ci/translation.gitlab-ci.yml @@ -2,7 +2,7 @@ # TRANSLATION ######################################## -remove-stale-translated-strings: +autofix-translated-strings: stage: translation image: "before-install" needs: [] @@ -14,12 +14,13 @@ remove-stale-translated-strings: script: - cd tests # Maybe move this script location to another folder? # create a local branch that will overwrite distant one - - git checkout -b "ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}" --no-track + - git checkout -b "ci-autofix-translated-strings-${CI_COMMIT_REF_NAME}" --no-track - python3 remove_stale_translated_strings.py + - python3 autofix_locale_format.py - '[ $(git diff -w | wc -l) != 0 ] || exit 0' # stop if there is nothing to commit - - git commit -am "[CI] Remove stale translated strings" || true - - git push -f origin "ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}":"ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}" - - hub pull-request -m "[CI] Remove stale translated strings" -b Yunohost:dev -p || true # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd + - git commit -am "[CI] Autofix translated strings" || true + - git push -f origin "ci-autofix-translated-strings-${CI_COMMIT_REF_NAME}":"ci-autofix-translated-strings-${CI_COMMIT_REF_NAME}" + - hub pull-request -m "[CI] Autofix translated strings" -b Yunohost:dev -p || true # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd only: variables: - $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH diff --git a/tests/autofix_locale_format.py b/tests/autofix_locale_format.py new file mode 100644 index 000000000..f777f06f1 --- /dev/null +++ b/tests/autofix_locale_format.py @@ -0,0 +1,47 @@ +import re +import json +import glob + +# List all locale files (except en.json being the ref) +locale_folder = "locales/" +locale_files = glob.glob(locale_folder + "*.json") +locale_files = [filename.split("/")[-1] for filename in locale_files] +locale_files.remove("en.json") + +reference = json.loads(open(locale_folder + "en.json").read()) + + +def fix_locale(locale_file): + + this_locale = json.loads(open(locale_folder + locale_file).read()) + fixed_stuff = False + + # We iterate over all keys/string in en.json + for key, string in reference.items(): + + # Ignore check if there's no translation yet for this key + if key not in this_locale: + continue + + # Then we check that every "{stuff}" (for python's .format()) + # should also be in the translated string, otherwise the .format + # will trigger an exception! + 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])] + + 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): + this_locale[key] = this_locale[key].replace('{%s}' % subkeys_in_this_locale[i], '{%s}' % subkey) + fixed_stuff = True + + if fixed_stuff: + json.dump( + this_locale, + open(locale_folder + locale_file, "w"), + indent=4, + ensure_ascii=False, + ) + + +for locale_file in locale_files: + fix_locale(locale_file) From fd0c283c536aa3bf7d0dfa91f7e4b34639c0a077 Mon Sep 17 00:00:00 2001 From: Weblate Admin Date: Thu, 2 Sep 2021 11:04:30 +0000 Subject: [PATCH 081/101] Translated using Weblate (French) Currently translated at 100.0% (651 of 651 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index e3a32d639..a7fe39bd9 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -291,7 +291,7 @@ "password_too_simple_3": "Le mot de passe doit comporter au moins 8 caractères et contenir des chiffres, des majuscules, des minuscules et des caractères spéciaux", "password_too_simple_4": "Le mot de passe doit comporter au moins 12 caractères et contenir des chiffres, des majuscules, des minuscules et des caractères spéciaux", "root_password_desynchronized": "Le mot de passe administrateur a été changé, mais YunoHost n’a pas pu le propager au mot de passe root !", - "aborting": "Annulation en cours.", + "aborting": "Annulation en cours (do not merge).", "app_not_upgraded": "L’application {failed_app} n’a pas été mise à jour et par conséquence les applications suivantes n’ont pas été mises à jour : {apps}", "app_start_install": "Installation de {app}...", "app_start_remove": "Suppression de {app}...", From ab388dc167c1c5002890f6f5424963e98a2d51b8 Mon Sep 17 00:00:00 2001 From: Weblate Admin Date: Thu, 2 Sep 2021 11:05:08 +0000 Subject: [PATCH 082/101] Translated using Weblate (French) Currently translated at 100.0% (651 of 651 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index a7fe39bd9..e3a32d639 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -291,7 +291,7 @@ "password_too_simple_3": "Le mot de passe doit comporter au moins 8 caractères et contenir des chiffres, des majuscules, des minuscules et des caractères spéciaux", "password_too_simple_4": "Le mot de passe doit comporter au moins 12 caractères et contenir des chiffres, des majuscules, des minuscules et des caractères spéciaux", "root_password_desynchronized": "Le mot de passe administrateur a été changé, mais YunoHost n’a pas pu le propager au mot de passe root !", - "aborting": "Annulation en cours (do not merge).", + "aborting": "Annulation en cours.", "app_not_upgraded": "L’application {failed_app} n’a pas été mise à jour et par conséquence les applications suivantes n’ont pas été mises à jour : {apps}", "app_start_install": "Installation de {app}...", "app_start_remove": "Suppression de {app}...", From 6e1018fd4e6342f18cccce2a18d47ccfd5c812f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Gaspar?= Date: Thu, 2 Sep 2021 14:14:24 +0000 Subject: [PATCH 083/101] Translated using Weblate (French) Currently translated at 100.0% (659 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index e3a32d639..a20a62db8 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -142,7 +142,7 @@ "user_creation_failed": "Impossible de créer l’utilisateur {user} : {error}", "user_deleted": "L’utilisateur a été supprimé", "user_deletion_failed": "Impossible de supprimer l’utilisateur {user} : {error}", - "user_home_creation_failed": "Impossible de créer le dossier personnel de l’utilisateur", + "user_home_creation_failed": "Impossible de créer le dossier personnel '{home}' de l’utilisateur", "user_unknown": "L’utilisateur {user} est inconnu", "user_update_failed": "Impossible de mettre à jour l’utilisateur {user} : {error}", "user_updated": "L’utilisateur a été modifié", @@ -170,7 +170,7 @@ "mailbox_used_space_dovecot_down": "Le service de courriel Dovecot doit être démarré si vous souhaitez voir l’espace disque occupé par la messagerie", "domains_available": "Domaines disponibles :", "backup_archive_broken_link": "Impossible d’accéder à l’archive de sauvegarde (lien invalide vers {path})", - "certmanager_acme_not_configured_for_domain": "Le challenge ACME n'a pas pu être validé pour le domaine {domain} pour le moment car le code de la configuration NGINX est manquant... Merci de vérifier que votre configuration NGINX est à jour avec la commande: `yunohost tools regen-conf nginx --dry-run --with-diff`.", + "certmanager_acme_not_configured_for_domain": "Le challenge ACME n'a pas pu être validé pour le domaine {domain} pour le moment car le code de la configuration NGINX est manquant... Merci de vérifier que votre configuration NGINX est à jour avec la commande : `yunohost tools regen-conf nginx --dry-run --with-diff`.", "domain_hostname_failed": "Échec de l’utilisation d’un nouveau nom d’hôte. Cela pourrait causer des soucis plus tard (cela n’en causera peut-être pas).", "app_already_installed_cant_change_url": "Cette application est déjà installée. L’URL ne peut pas être changé simplement par cette fonction. Vérifiez si cela est disponible avec `app changeurl`.", "app_change_url_failed_nginx_reload": "Le redémarrage de NGINX a échoué. Voici la sortie de 'nginx -t' :\n{nginx_errors}", @@ -649,5 +649,13 @@ "diagnosis_apps_not_in_app_catalog": "Cette application est absente ou ne figure plus dans le catalogue d'applications de YunoHost. Vous devriez envisager de la désinstaller car elle ne recevra pas de mise à jour et pourrait compromettre l'intégrité et la sécurité de votre système.", "diagnosis_apps_issue": "Un problème a été détecté pour l'application {app}", "diagnosis_apps_allgood": "Toutes les applications installées respectent les pratiques de packaging de base", - "diagnosis_description_apps": "Applications" + "diagnosis_description_apps": "Applications", + "user_import_success": "Utilisateurs importés avec succès", + "user_import_nothing_to_do": "Aucun utilisateur n'a besoin d'être importé", + "user_import_failed": "L'opération d'importation des utilisateurs a totalement échoué", + "user_import_partial_failed": "L'opération d'importation des utilisateurs a partiellement échoué", + "user_import_missing_columns": "Les colonnes suivantes sont manquantes : {columns}", + "user_import_bad_file": "Votre fichier CSV n'est pas correctement formaté, il sera ignoré afin d'éviter une potentielle perte de données", + "user_import_bad_line": "Ligne incorrecte {line} : {details}", + "log_user_import": "Importer des utilisateurs" } From bf7b51de18b6af3980ccd37a3d54237d518532c5 Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Thu, 2 Sep 2021 21:52:46 +0000 Subject: [PATCH 084/101] Translated using Weblate (Ukrainian) Currently translated at 30.3% (200 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 222 ++++++++++++++++++++++++------------------------ 1 file changed, 111 insertions(+), 111 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index a9b807981..47c5991b0 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -55,7 +55,7 @@ "service_description_postfix": "Використовується для відправки та отримання електронної пошти", "service_description_php7.3-fpm": "Запускає програми, написані на мові програмування PHP, за допомогою NGINX", "service_description_nginx": "Обслуговує або надає доступ до всіх веб-сайтів, розміщених на вашому сервері", - "service_description_mysql": "Зберігає дані додатків (база даних SQL)", + "service_description_mysql": "Зберігає дані застосунків (база даних SQL)", "service_description_metronome": "Служба захисту миттєвого обміну повідомленнями XMPP", "service_description_fail2ban": "Захист від перебору та інших видів атак з Інтернету", "service_description_dovecot": "Дозволяє поштовим клієнтам отримувати доступ до електронної пошти (через IMAP і POP3)", @@ -87,7 +87,7 @@ "restore_cleaning_failed": "Не вдалося очистити тимчасовий каталог відновлення", "restore_backup_too_old": "Цей архів резервних копій не може бути відновлений, бо він отриманий з дуже старою версією YunoHost.", "restore_already_installed_apps": "Наступні програми не можуть бути відновлені, тому що вони вже встановлені: {apps}", - "restore_already_installed_app": "Додаток з ідентифікатором \"{app} 'вже встановлено", + "restore_already_installed_app": "Застосунок з ідентифікатором \"{app} 'вже встановлено", "regex_with_only_domain": "Ви не можете використовувати regex для домену, тільки для шляху.", "regex_incompatible_with_tile": "/! \\ Packagers! Дозвіл '{permission}' має значення show_tile 'true', тому ви не можете визначити regex URL в якості основного URL.", "regenconf_need_to_explicitly_specify_ssh": "Конфігурація ssh була змінена вручну, але вам потрібно явно вказати категорію 'ssh' з --force, щоб застосувати зміни.", @@ -117,7 +117,7 @@ "permission_deletion_failed": "Не вдалося видалити дозвіл '{permission}': {error}", "permission_deleted": "Дозвіл '{permission}' видалено", "permission_cant_add_to_all_users": "Дозвіл {permission} не може бути додано всім користувачам.", - "permission_currently_allowed_for_all_users": "В даний час цей дозвіл надається всім користувачам на додаток до інших груп. Ймовірно, вам потрібно або видалити дозвіл 'all_users', або видалити інші групи, яким воно зараз надано.", + "permission_currently_allowed_for_all_users": "Наразі цей дозвіл надається всім користувачам на додачу до інших груп. Імовірно, вам потрібно або видалити дозвіл 'all_users', або видалити інші групи, яким його зараз надано.", "permission_creation_failed": "Не вдалося створити дозвіл '{permission}': {error}", "permission_created": "Дозвіл '{permission}' створено", "permission_cannot_remove_main": "Видалення основного дозволу заборонено", @@ -175,8 +175,8 @@ "migration_0015_cleaning_up": "Очищення кеш-пам'яті і пакетів, які більше не потрібні...", "migration_0015_specific_upgrade": "Початок поновлення системних пакетів, які повинні бути оновлені незалежно...", "migration_0015_modified_files": "Зверніть увагу, що такі файли були змінені вручну і можуть бути перезаписані після поновлення: {manually_modified_files}.", - "migration_0015_problematic_apps_warning": "Зверніть увагу, що були виявлені наступні, можливо, проблемні встановлені додатки. Схоже, що вони не були встановлені з каталогу додатків YunoHost або не зазначені як \"робочі\". Отже, не можна гарантувати, що вони будуть працювати після оновлення: {problematic_apps}.", - "migration_0015_general_warning": "Будь ласка, зверніть увагу, що ця міграція є делікатною операцією. Команда YunoHost зробила все можливе, щоб перевірити і протестувати її, але міграція все ще може порушити частина системи або її додатків. Тому рекомендується: - Виконати резервне копіювання всіх важливих даних або додатків. Більш детальна інформація на сайті https://yunohost.org/backup; - Наберіться терпіння після запуску міграції: В залежності від вашого підключення до Інтернету і апаратного забезпечення, оновлення може зайняти до декількох годин.", + "migration_0015_problematic_apps_warning": "Зверніть увагу, що були виявлені наступні, можливо, проблемні встановлені додатки. Схоже, що вони не були встановлені з каталогу застосунків YunoHost або не зазначені як \"робочі\". Отже, не можна гарантувати, що вони будуть працювати після оновлення: {problematic_apps}.", + "migration_0015_general_warning": "Будь ласка, зверніть увагу, що ця міграція є делікатною операцією. Команда YunoHost зробила все можливе, щоб перевірити і протестувати її, але міграція все ще може порушити частина системи або її застосунків. Тому рекомендується: - Виконати резервне копіювання всіх важливих даних або застосунків. Більш детальна інформація на сайті https://yunohost.org/backup; - Наберіться терпіння після запуску міграції: В залежності від вашого підключення до Інтернету і апаратного забезпечення, оновлення може зайняти до декількох годин.", "migration_0015_system_not_fully_up_to_date": "Ваша система не повністю оновлена. Будь ласка, виконайте регулярне оновлення перед запуском міграції на Buster.", "migration_0015_not_enough_free_space": "Вільного місця в/var/досить мало! У вас повинно бути не менше 1 ГБ вільного місця, щоб запустити цю міграцію.", "migration_0015_not_stretch": "Поточний дистрибутив Debian не є Stretch!", @@ -189,9 +189,9 @@ "migration_ldap_rollback_success": "Система відкотилася.", "migration_ldap_migration_failed_trying_to_rollback": "Не вдалося виконати міграцію... спроба відкату системи.", "migration_ldap_can_not_backup_before_migration": "Не вдалося завершити резервне копіювання системи перед невдалої міграцією. Помилка: {error}", - "migration_ldap_backup_before_migration": "Створення резервної копії бази даних LDAP і установки додатків перед фактичної міграцією.", + "migration_ldap_backup_before_migration": "Створення резервної копії бази даних LDAP і установки застосунків перед фактичної міграцією.", "migration_description_0020_ssh_sftp_permissions": "Додайте підтримку дозволів SSH і SFTP", - "migration_description_0019_extend_permissions_features": "Розширення/переробка системи управління дозволами додатків", + "migration_description_0019_extend_permissions_features": "Розширення/переробка системи управління дозволами застосунків", "migration_description_0018_xtable_to_nftable": "Перенесення старих правил мережевого трафіку в нову систему nftable", "migration_description_0017_postgresql_9p6_to_11": "Перенесення баз даних з PostgreSQL 9.6 на 11", "migration_description_0016_php70_to_php73_pools": "Перенесіть php7.0-fpm 'pool' conf файли на php7.3", @@ -240,9 +240,9 @@ "log_app_config_show_panel": "Показати панель конфігурації програми \"{} '", "log_app_action_run": "Активації дії додатка \"{} '", "log_app_makedefault": "Зробити '{}' додатком за замовчуванням", - "log_app_upgrade": "Оновити додаток '{}'", + "log_app_upgrade": "Оновити застосунок '{}'", "log_app_remove": "Для видалення програми '{}'", - "log_app_install": "Встановіть додаток '{}'", + "log_app_install": "Встановіть застосунок '{}'", "log_app_change_url": "Змініть URL-адресу додатка \"{} '", "log_operation_unit_unclosed_properly": "Блок операцій не був закритий належним чином", "log_does_exists": "Немає журналу операцій з ім'ям '{log}', використовуйте 'yunohost log list', щоб подивитися всі публічні журнали операцій", @@ -331,7 +331,7 @@ "domain_unknown": "невідомий домен", "domain_name_unknown": "Домен '{domain}' невідомий", "domain_uninstall_app_first": "Ці додатки все ще встановлені на вашому домені: {apps} ласка, видаліть їх за допомогою 'yunohost app remove the_app_id' або перемістити їх на інший домен за допомогою 'yunohost app change-url the_app_id', перш ніж приступити до видалення домену.", - "domain_remove_confirm_apps_removal": "Видалення цього домену призведе до видалення цих додатків: {apps} Ви впевнені, що хочете це зробити? [{answers}].", + "domain_remove_confirm_apps_removal": "Видалення цього домену призведе до видалення цих застосунків: {apps} Ви впевнені, що хочете це зробити? [{answers}].", "domain_hostname_failed": "Неможливо встановити нове ім'я хоста. Це може викликати проблеми в подальшому (можливо, все буде в порядку).", "domain_exists": "Домен вже існує", "domain_dyndns_root_unknown": "Невідомий кореневої домен DynDNS", @@ -485,157 +485,157 @@ "diagnosis_domain_expiration_warning": "Термін дії деяких доменів закінчиться найближчим часом!", "diagnosis_domain_expiration_success": "Ваші домени зареєстровані і не збираються спливати найближчим часом.", "diagnosis_domain_expiration_not_found_details": "Інформація WHOIS для домену {domain} не містить інформації про термін дії?", - "diagnosis_domain_not_found_details": "Домен {domain} не існує в базі даних WHOIS або термін його дії закінчився!", - "diagnosis_domain_expiration_not_found": "Неможливо перевірити термін дії деяких доменів", + "diagnosis_domain_not_found_details": "Домен {domain} не існує в базі даних WHOIS або строк його дії сплив!", + "diagnosis_domain_expiration_not_found": "Неможливо перевірити строк дії деяких доменів", "diagnosis_dns_specialusedomain": "Домен {domain} заснований на домені верхнього рівня спеціального призначення (TLD) і тому не очікується, що у нього будуть актуальні записи DNS.", - "diagnosis_dns_try_dyndns_update_force": "Конфігурація DNS цього домену повинна автоматично управлятися YunoHost. Якщо це не так, ви можете спробувати примусово оновити її за допомогою команди yunohost dyndns update --force .", - "diagnosis_dns_point_to_doc": "Якщо вам потрібна допомога з налаштування DNS-записів, зверніться до документації на сайті https://yunohost.org/dns_config .", - "diagnosis_dns_discrepancy": "Наступний запис DNS, схоже, не відповідає рекомендованої конфігурації:
Type: {type}
Name: {name}
Поточне значення: {current}
Очікуване значення: {value} ", - "diagnosis_dns_missing_record": "Згідно рекомендованої конфігурації DNS, ви повинні додати запис DNS з наступною інформацією.
Тип: {type}
Name: {name}
Value: < code> {value} .", - "diagnosis_dns_bad_conf": "Деякі DNS-записи відсутні або невірні для домену {domain} (категорія {category})", + "diagnosis_dns_try_dyndns_update_force": "Конфігурація DNS цього домену повинна автоматично управлятися YunoHost. Якщо це не так, ви можете спробувати примусово оновити її за допомогою команди yunohost dyndns update --force.", + "diagnosis_dns_point_to_doc": "Якщо вам потрібна допомога з налаштування DNS-записів, зверніться до документації на сайті https://yunohost.org/dns_config.", + "diagnosis_dns_discrepancy": "Наступний запис DNS, схоже, не відповідає рекомендованій конфігурації:
Тип: {type}
Назва: {name}
Поточне значення: {current}
Очікуване значення: {value}", + "diagnosis_dns_missing_record": "Згідно рекомендованої конфігурації DNS, ви повинні додати запис DNS з наступними відомостями.\n
Тип: {type}\n
Назва: {name}\n
Значення: {value}", + "diagnosis_dns_bad_conf": "Деякі DNS-записи відсутні або неправильні для домену {domain} (категорія {category})", "diagnosis_dns_good_conf": "DNS-записи правильно налаштовані для домену {domain} (категорія {category})", - "diagnosis_ip_weird_resolvconf_details": "Файл /etc/resolv.conf повинен бути симлінк на /etc/resolvconf/run/resolv.conf , що вказує на 127.0.0.1 (dnsmasq ). Якщо ви хочете вручну налаштувати DNS Резолвер, відредагуйте /etc/resolv.dnsmasq.conf .", - "diagnosis_ip_weird_resolvconf": "Дозвіл DNS, схоже, працює, але схоже, що ви використовуєте для користувача /etc/resolv.conf .", - "diagnosis_ip_broken_resolvconf": "Схоже, що дозвіл доменних імен на вашому сервері порушено, що пов'язано з тим, що /etc/resolv.conf не вказує на 127.0.0.1 .", - "diagnosis_ip_broken_dnsresolution": "Дозвіл доменних імен, схоже, з якоїсь причини не працює... Брандмауер блокує DNS-запити?", - "diagnosis_ip_dnsresolution_working": "Дозвіл доменних імен працює!", - "diagnosis_ip_not_connected_at_all": "Здається, що сервер взагалі не підключений до Інтернету !?", - "diagnosis_ip_local": "Локальний IP: {local} .", - "diagnosis_ip_global": "Глобальний IP: {global} ", - "diagnosis_ip_no_ipv6_tip": "Наявність працюючого IPv6 не є обов'язковим для роботи вашого сервера, але це краще для здоров'я Інтернету в цілому. IPv6 зазвичай автоматично налаштовується системою або вашим провайдером, якщо він доступний. В іншому випадку вам, можливо, доведеться налаштувати деякі речі вручну, як пояснюється в документації тут: https://yunohost.org/#/ipv6. Якщо ви не можете включити IPv6 або якщо це здається вам занадто технічним, ви також можете сміливо ігнорувати це попередження.", - "diagnosis_ip_no_ipv6": "Сервер не має працюючого IPv6.", - "diagnosis_ip_connected_ipv6": "Сервер підключений до Інтернету через IPv6!", - "diagnosis_ip_no_ipv4": "Сервер не має працюючого IPv4.", - "diagnosis_ip_connected_ipv4": "Сервер підключений до Інтернету через IPv4!", - "diagnosis_no_cache": "Для категорії \"{category} 'ще немає кеша діагнозів.", - "diagnosis_failed": "Не вдалося результат діагностики для категорії '{category}': {error}", - "diagnosis_everything_ok": "Все виглядає добре для {category}!", + "diagnosis_ip_weird_resolvconf_details": "Файл /etc/resolv.conf повинен бути символічним посиланням на /etc/resolvconf/run/resolv.conf, що вказує на 127.0.0.1(dnsmasq). Якщо ви хочете вручну налаштувати DNS вирішувачі (resolvers), відредагуйте /etc/resolv.dnsmasq.conf.", + "diagnosis_ip_weird_resolvconf": "Роздільність DNS, схоже, працює, але схоже, що ви використовуєте користувацьку /etc/resolv.conf.", + "diagnosis_ip_broken_resolvconf": "Схоже, що роздільність доменних імен на вашому сервері порушено, що пов'язано з тим, що /etc/resolv.conf не вказує на 127.0.0.1.", + "diagnosis_ip_broken_dnsresolution": "Роздільність доменних імен, схоже, з якоїсь причини не працює... Фаєрвол блокує DNS-запити?", + "diagnosis_ip_dnsresolution_working": "Роздільність доменних імен працює!", + "diagnosis_ip_not_connected_at_all": "Здається, сервер взагалі не під'єднаний до Інтернету!?", + "diagnosis_ip_local": "Локальний IP: {local}.", + "diagnosis_ip_global": "Глобальний IP: {global}", + "diagnosis_ip_no_ipv6_tip": "Наявність робочого IPv6 не є обов'язковим для роботи вашого сервера, але це краще для здоров'я Інтернету в цілому. IPv6 зазвичай автоматично налаштовується системою або вашим провайдером, якщо він доступний. В іншому випадку вам, можливо, доведеться налаштувати деякі речі вручну, як пояснюється в документації тут: https://yunohost.org/#/ipv6. Якщо ви не можете увімкнути IPv6 або якщо це здається вам занадто технічним, ви також можете сміливо нехтувати цим попередженням.", + "diagnosis_ip_no_ipv6": "Сервер не має робочого IPv6.", + "diagnosis_ip_connected_ipv6": "Сервер під'єднаний до Інтернету через IPv6!", + "diagnosis_ip_no_ipv4": "Сервер не має робочого IPv4.", + "diagnosis_ip_connected_ipv4": "Сервер під'єднаний до Інтернету через IPv4!", + "diagnosis_no_cache": "Для категорії \"{category} 'ще немає кеша діагностики.", + "diagnosis_failed": "Не вдалося отримати результат діагностики для категорії '{category}': {error}", + "diagnosis_everything_ok": "Усе виглядає добре для {category}!", "diagnosis_found_warnings": "Знайдено {warnings} пунктів, які можна поліпшити для {category}.", "diagnosis_found_errors_and_warnings": "Знайдено {errors} істотний (і) питання (и) (і {warnings} попередження (я)), що відносяться до {category}!", "diagnosis_found_errors": "Знайдена {errors} важлива проблема (і), пов'язана з {category}!", - "diagnosis_ignored_issues": "(+ {nb_ignored} проігнорована проблема (проблеми))", + "diagnosis_ignored_issues": "(+ {nb_ignored} знехтувана проблема (проблеми))", "diagnosis_cant_run_because_of_dep": "Неможливо запустити діагностику для {category}, поки є важливі проблеми, пов'язані з {dep}.", "diagnosis_cache_still_valid": "(Кеш все ще дійсний для діагностики {category}. Повторна діагностика поки не проводиться!)", "diagnosis_failed_for_category": "Не вдалося провести діагностику для категорії '{category}': {error}", - "diagnosis_display_tip": "Щоб побачити знайдені проблеми, ви можете перейти в розділ Diagnosis в веб-адміном або виконати команду 'yunohost diagnosis show --issues --human-readable' з командного рядка.", - "diagnosis_package_installed_from_sury_details": "Деякі пакети були ненавмисно встановлені з стороннього сховища під назвою Sury. Команда YunoHost поліпшила стратегію роботи з цими пакетами, але очікується, що в деяких системах, які встановили додатки PHP7.3 ще на Stretch, залишаться деякі невідповідності. Щоб виправити цю ситуацію, спробуйте виконати наступну команду: {cmd_to_fix} .", - "diagnosis_package_installed_from_sury": "Деякі системні пакети повинні бути знижені в статусі", - "diagnosis_backports_in_sources_list": "Схоже, що apt (менеджер пакетів) налаштований на використання сховища backports. Якщо ви не знаєте, що робите, ми настійно не рекомендуємо встановлювати пакети з backports, тому що це може привести до нестабільності або конфліктів у вашій системі.", - "diagnosis_basesystem_ynh_inconsistent_versions": "Ви використовуєте несумісні версії пакетів YunoHost... швидше за все, через невдалий або часткового оновлення.", + "diagnosis_display_tip": "Щоб побачити знайдені проблеми, ви можете перейти в розділ Діагностика в вебадміністраторі або виконати команду 'yunohost diagnosis show --issues --human-readable' з командного рядка.", + "diagnosis_package_installed_from_sury_details": "Деякі пакети були ненавмисно встановлені зі стороннього репозиторію під назвою Sury. Команда YunoHost поліпшила стратегію роботи з цими пакетами, але очікується, що в деяких системах, які встановили застосунки PHP7.3 ще на Stretch, залишаться деякі невідповідності. Щоб виправити це становище, спробуйте виконати наступну команду: {cmd_to_fix}.", + "diagnosis_package_installed_from_sury": "Деякі системні пакети мають бути зістарені у версії", + "diagnosis_backports_in_sources_list": "Схоже, що apt (менеджер пакетів) налаштований на використання репозиторія backports. Якщо ви не знаєте, що робите, ми наполегливо не радимо встановлювати пакети з backports, тому що це може привести до нестабільності або конфліктів у вашій системі.", + "diagnosis_basesystem_ynh_inconsistent_versions": "Ви використовуєте несумісні версії пакетів YunoHost... швидше за все, через невдале або часткове оновлення.", "diagnosis_basesystem_ynh_main_version": "Сервер працює під управлінням YunoHost {main_version} ({repo})", "diagnosis_basesystem_ynh_single_version": "{package} версія: {version} ({repo})", "diagnosis_basesystem_kernel": "Сервер працює під управлінням ядра Linux {kernel_version}", "diagnosis_basesystem_host": "Сервер працює під управлінням Debian {debian_version}", "diagnosis_basesystem_hardware_model": "Модель сервера - {model}", "diagnosis_basesystem_hardware": "Архітектура апаратного забезпечення сервера - {virt} {arch}", - "custom_app_url_required": "Ви повинні надати URL для оновлення вашого призначеного для користувача додатки {app}.", - "confirm_app_install_thirdparty": "НЕБЕЗПЕЧНО! Ця програма не входить в каталог додатків YunoHost. Установлення сторонніх додатків може порушити цілісність і безпеку вашої системи. Вам не слід встановлювати його, якщо ви не знаєте, що робите. НІЯКОЇ ПІДТРИМКИ НЕ БУДЕ, якщо цей додаток не буде працювати або зламає вашу систему... Якщо ви все одно готові піти на такий ризик, введіть '{answers}'.", - "confirm_app_install_danger": "НЕБЕЗПЕЧНО! Відомо, що це додаток все ще експериментальне (якщо не сказати, що воно явно не працює)! Вам не слід встановлювати його, якщо ви не знаєте, що робите. Ніякої підтримки не буде надано, якщо цей додаток не буде працювати або зламає вашу систему... Якщо ви все одно готові ризикнути, введіть '{answers}'.", - "confirm_app_install_warning": "Попередження: Ця програма може працювати, але не дуже добре інтегровано в YunoHost. Деякі функції, такі як єдина реєстрація та резервне копіювання/відновлення, можуть бути недоступні. Все одно встановити? [{answers}]. ", - "certmanager_unable_to_parse_self_CA_name": "Не вдалося розібрати ім'я самоподпісивающегося центру (файл: {file})", - "certmanager_self_ca_conf_file_not_found": "Не вдалося знайти файл конфігурації для самоподпісивающегося центру (файл: {file})", + "custom_app_url_required": "Ви повинні надати URL-адресу для оновлення вашого користувацького застосунку {app}.", + "confirm_app_install_thirdparty": "НЕБЕЗПЕЧНО! Цей застосунок не входить в каталог застосунків YunoHost. Установлення сторонніх застосунків може порушити цілісність і безпеку вашої системи. Вам не слід встановлювати його, якщо ви не знаєте, що робите. НІЯКОЇ ПІДТРИМКИ НЕ БУДЕ, якщо цей застосунок не буде працювати або зламає вашу систему... Якщо ви все одно готові піти на такий ризик, введіть '{answers}'.", + "confirm_app_install_danger": "НЕБЕЗПЕЧНО! Відомо, що цей застосунок все ще експериментальний (якщо не сказати, що він явно не працює)! Вам не слід встановлювати його, якщо ви не знаєте, що робите. Ніякої підтримки не буде надано, якщо цей застосунок не буде працювати або зламає вашу систему... Якщо ви все одно готові ризикнути, введіть '{answers}'.", + "confirm_app_install_warning": "Попередження: Цей застосунок може працювати, але він не дуже добре інтегрований в YunoHost. Деякі функції, такі як єдина реєстрація та резервне копіювання/відновлення, можуть бути недоступні. Все одно встановити? [{answers}]. ", + "certmanager_unable_to_parse_self_CA_name": "Не вдалося розібрати назву самопідписного центру (файл: {file})", + "certmanager_self_ca_conf_file_not_found": "Не вдалося знайти файл конфігурації для самопідписного центру (файл: {file})", "certmanager_no_cert_file": "Не вдалося розпізнати файл сертифіката для домену {domain} (файл: {file})", - "certmanager_hit_rate_limit": "Для цього набору доменів {domain} недавно було випущено дуже багато сертифікатів. Будь ласка, спробуйте ще раз пізніше. Див. Https://letsencrypt.org/docs/rate-limits/ для отримання більш докладної інформації.", - "certmanager_warning_subdomain_dns_record": "Піддомен '{subdomain} \"не дозволяється на той же IP-адресу, що і' {domain} '. Деякі функції будуть недоступні, поки ви не виправите це і не перегенеріруете сертифікат.", - "certmanager_domain_http_not_working": "Домен {domain}, схоже, не доступний через HTTP. Будь ласка, перевірте категорію 'Web' в діагностиці для отримання додаткової інформації. (Якщо ви знаєте, що робите, використовуйте '--no-checks', щоб відключити ці перевірки).", - "certmanager_domain_dns_ip_differs_from_public_ip": "DNS-записи для домену '{domain}' відрізняються від IP цього сервера. Будь ласка, перевірте категорію 'DNS-записи' (основні) в діагностиці для отримання додаткової інформації. Якщо ви недавно змінили запис A, будь ласка, зачекайте, поки вона пошириться (деякі програми перевірки поширення DNS доступні в Інтернеті). (Якщо ви знаєте, що робите, використовуйте '--no-checks', щоб відключити ці перевірки).", - "certmanager_domain_cert_not_selfsigned": "Сертифікат для домену {domain} не є самоподпісанного. Ви впевнені, що хочете замінити його? (Для цього використовуйте '--force').", - "certmanager_domain_not_diagnosed_yet": "Поки немає результатів діагностики для домену {domain}. Будь ласка, повторно проведіть діагностику для категорій 'DNS-записи' і 'Web' в розділі діагностики, щоб перевірити, чи готовий домен до Let's Encrypt. (Або, якщо ви знаєте, що робите, використовуйте '--no-checks', щоб відключити ці перевірки).", + "certmanager_hit_rate_limit": "Для цього набору доменів {domain} недавно було випущено дуже багато сертифікатів. Будь ласка, спробуйте ще раз пізніше. Див. https://letsencrypt.org/docs/rate-limits/ для отримання подробиць.", + "certmanager_warning_subdomain_dns_record": "Піддомен '{subdomain}' не дозволяється на тій же IP-адресі, що і '{domain}'. Деякі функції будуть недоступні, поки ви не виправите це і не перестворите сертифікат.", + "certmanager_domain_http_not_working": "Домен {domain}, схоже, не доступний через HTTP. Будь ласка, перевірте категорію 'Мережа' в діагностиці для отримання додаткових даних. (Якщо ви знаєте, що робите, використовуйте '--no-checks', щоб вимкнути ці перевірки).", + "certmanager_domain_dns_ip_differs_from_public_ip": "DNS-записи для домену '{domain}' відрізняються від IP цього сервера. Будь ласка, перевірте категорію 'DNS-записи' (основні) в діагностиці для отримання додаткових даних. Якщо ви недавно змінили запис A, будь ласка, зачекайте, поки він пошириться (деякі програми перевірки поширення DNS доступні в Інтернеті). (Якщо ви знаєте, що робите, використовуйте '--no-checks', щоб вимкнути ці перевірки).", + "certmanager_domain_cert_not_selfsigned": "Сертифікат для домену {domain} не є самопідписаним. Ви впевнені, що хочете замінити його? (Для цього використовуйте '--force').", + "certmanager_domain_not_diagnosed_yet": "Поки немає результатів діагностики для домену {domain}. Будь ласка, повторно проведіть діагностику для категорій 'DNS-записи' і 'Мережа' в розділі діагностики, щоб перевірити, чи готовий домен до Let's Encrypt. (Або, якщо ви знаєте, що робите, використовуйте '--no-checks', щоб вимкнути ці перевірки).", "certmanager_certificate_fetching_or_enabling_failed": "Спроба використовувати новий сертифікат для {domain} не спрацювала...", "certmanager_cert_signing_failed": "Не вдалося підписати новий сертифікат", "certmanager_cert_renew_success": "Сертифікат Let's Encrypt оновлений для домену '{domain}'", - "certmanager_cert_install_success_selfsigned": "Самоподпісанний сертифікат тепер встановлений для домену '{domain}'", - "certmanager_cert_install_success": "Сертифікат Let's Encrypt тепер встановлений для домену '{domain}'", - "certmanager_cannot_read_cert": "Щось не так сталося при спробі відкрити поточний сертифікат для домену {domain} (файл: {file}), причина: {reason}", - "certmanager_attempt_to_replace_valid_cert": "Ви намагаєтеся перезаписати хороший і дійсний сертифікат для домену {domain}! (Використовуйте --force для обходу)", - "certmanager_attempt_to_renew_valid_cert": "Термін дії сертифіката для домену '{domain} \"не закінчується! (Ви можете використовувати --force, якщо знаєте, що робите)", + "certmanager_cert_install_success_selfsigned": "Самопідписаний сертифікат тепер встановлений для домену '{domain}'", + "certmanager_cert_install_success": "Сертифікат Let's Encrypt тепер встановлений для домена '{domain}'", + "certmanager_cannot_read_cert": "Щось не так сталося при спробі відкрити поточний сертифікат для домена {domain} (файл: {file}), причина: {reason}", + "certmanager_attempt_to_replace_valid_cert": "Ви намагаєтеся перезаписати хороший дійсний сертифікат для домену {domain}! (Використовуйте --force для обходу)", + "certmanager_attempt_to_renew_valid_cert": "Строк дії сертифіката для домена '{domain}' не закінчується! (Ви можете використовувати --force, якщо знаєте, що робите)", "certmanager_attempt_to_renew_nonLE_cert": "Сертифікат для домену '{domain}' не випущено Let's Encrypt. Неможливо продовжити його автоматично!", - "certmanager_acme_not_configured_for_domain": "Завдання ACME не може бути запущена для {domain} прямо зараз, тому що в його nginx conf відсутній відповідний фрагмент коду... Будь ласка, переконайтеся, що конфігурація nginx оновлена за допомогою `yunohost tools regen-conf nginx --dry-run - with-diff`.", - "backup_with_no_restore_script_for_app": "{app} не має скрипта відновлення, ви не зможете автоматично відновити резервну копію цього додатка.", - "backup_with_no_backup_script_for_app": "Додаток '{app}' не має скрипта резервного копіювання. Ігнорування.", - "backup_unable_to_organize_files": "Неможливо використовувати швидкий метод для організації файлів в архіві", + "certmanager_acme_not_configured_for_domain": "Завдання ACME не може бути запущене для {domain} прямо зараз, тому що в його nginx-конфігурації відсутній відповідний фрагмент коду... Будь ласка, переконайтеся, що конфігурація nginx оновлена за допомогою `yunohost tools regen-conf nginx --dry-run --with-diff`.", + "backup_with_no_restore_script_for_app": "{app} не має скрипта відновлення, ви не зможете автоматично відновити резервну копію цього застосунку.", + "backup_with_no_backup_script_for_app": "Застосунок '{app}' не має скрипта резервного копіювання. Нехтую ним.", + "backup_unable_to_organize_files": "Неможливо використовувати швидкий спосіб для організації файлів в архіві", "backup_system_part_failed": "Не вдалося створити резервну копію системної частини '{part}'.", - "backup_running_hooks": "Запуск гачків резервного копіювання...", + "backup_running_hooks": "Запуск гачків (hook) резервного копіювання...", "backup_permission": "Дозвіл на резервне копіювання для {app}", - "backup_output_symlink_dir_broken": "Ваш архівний каталог '{path}' є непрацюючою симлінк. Можливо, ви забули перемонтувати або підключити носій, на який вона вказує.", + "backup_output_symlink_dir_broken": "Ваш архівний каталог '{path}' є неробочим символічним посиланням. Можливо, ви забули перемонтувати або підключити носій, на який вона вказує.", "backup_output_directory_required": "Ви повинні вказати вихідний каталог для резервного копіювання", "backup_output_directory_not_empty": "Ви повинні вибрати порожній вихідний каталог", - "backup_output_directory_forbidden": "Виберіть інший вихідний каталог. Резервні копії не можуть бути створені в підкаталогах/bin,/boot,/dev,/etc,/lib,/root,/run,/sbin,/sys,/usr,/var або /home/yunohost.backup/archives.", - "backup_nothings_done": "нічого зберігати", + "backup_output_directory_forbidden": "Виберіть інший вихідний каталог. Резервні копії не можуть бути створені в підкаталогах /bin,/boot,/dev,/etc,/lib,/root,/run,/sbin,/sys,/usr,/var або /home/yunohost.backup/archives.", + "backup_nothings_done": "Нема що зберігати", "backup_no_uncompress_archive_dir": "Немає такого каталогу нестислого архіву", - "backup_mount_archive_for_restore": "Підготовка архіву для відновлення...", + "backup_mount_archive_for_restore": "Підготовлення архіву для відновлення...", "backup_method_tar_finished": "Створено архів резервного копіювання TAR", - "backup_method_custom_finished": "Призначений для користувача метод резервного копіювання '{method}' завершено", + "backup_method_custom_finished": "Користувацький спосіб резервного копіювання '{method}' завершено", "backup_method_copy_finished": "Резервне копіювання завершено", - "backup_hook_unknown": "Гачок резервного копіювання '{hook}' невідомий", + "backup_hook_unknown": "Гачок (hook) резервного копіювання '{hook}' невідомий", "backup_deleted": "Резервна копія видалена", "backup_delete_error": "Не вдалося видалити '{path}'", - "backup_custom_mount_error": "Призначений для користувача метод резервного копіювання не зміг пройти етап 'монтування'", - "backup_custom_backup_error": "Призначений для користувача метод резервного копіювання не зміг пройти етап 'резервне копіювання'", + "backup_custom_mount_error": "Користувацький спосіб резервного копіювання не зміг пройти етап 'монтування'", + "backup_custom_backup_error": "Користувацький спосіб резервного копіювання не зміг пройти етап 'резервне копіювання'", "backup_csv_creation_failed": "Не вдалося створити CSV-файл, необхідний для відновлення", "backup_csv_addition_failed": "Не вдалося додати файли для резервного копіювання в CSV-файл", "backup_creation_failed": "Не вдалося створити архів резервного копіювання", "backup_create_size_estimation": "Архів буде містити близько {size} даних.", "backup_created": "Резервна копія створена", "backup_couldnt_bind": "Не вдалося зв'язати {src} з {dest}.", - "backup_copying_to_organize_the_archive": "Копіювання {size} MB для організації архіву", - "backup_cleaning_failed": "Не вдалося очистити тимчасову папку резервного копіювання", + "backup_copying_to_organize_the_archive": "Копіювання {size} МБ для організації архіву", + "backup_cleaning_failed": "Не вдалося очистити тимчасовий каталог резервного копіювання", "backup_cant_mount_uncompress_archive": "Не вдалося змонтувати нестислий архів як захищений від запису", - "backup_ask_for_copying_if_needed": "Чи хочете ви тимчасово виконати резервне копіювання з використанням {size} MB? (Цей спосіб використовується, оскільки деякі файли не можуть бути підготовлені більш ефективним методом).", + "backup_ask_for_copying_if_needed": "Ви бажаєте тимчасово виконати резервне копіювання з використанням {size} МБ? (Цей спосіб використовується, оскільки деякі файли не можуть бути підготовлені дієвіше).", "backup_archive_writing_error": "Не вдалося додати файли '{source}' (названі в архіві '{dest}') для резервного копіювання в стислий архів '{archive}'.", - "backup_archive_system_part_not_available": "Системна частина '{part}' недоступна в цій резервної копії", - "backup_archive_corrupted": "Схоже, що архів резервної копії \"{archive} 'пошкоджений: {error}", - "backup_archive_cant_retrieve_info_json": "Не вдалося завантажити інформацію для архіву '{archive}'... info.json не може бути отриманий (або не є коректним json).", - "backup_archive_open_failed": "Не вдалося відкрити архів резервних копій", - "backup_archive_name_unknown": "Невідомий локальний архів резервного копіювання з ім'ям '{name}'", - "backup_archive_name_exists": "Архів резервного копіювання з таким ім'ям вже існує.", - "backup_archive_broken_link": "Не вдалося отримати доступ до архіву резервного копіювання (непрацююча посилання на {path})", + "backup_archive_system_part_not_available": "Системна частина '{part}' недоступна в цій резервній копії", + "backup_archive_corrupted": "Схоже, що архів резервної копії '{archive}' пошкоджений: {error}", + "backup_archive_cant_retrieve_info_json": "Не вдалося завантажити відомості для архіву '{archive}'... info.json не може бути отриманий(або не є правильним json).", + "backup_archive_open_failed": "Не вдалося відкрити архів резервної копії", + "backup_archive_name_unknown": "Невідомий локальний архів резервного копіювання з назвою '{name}'", + "backup_archive_name_exists": "Архів резервного копіювання з такою назвою вже існує.", + "backup_archive_broken_link": "Не вдалося отримати доступ до архіву резервного копіювання (неробоче посилання на {path})", "backup_archive_app_not_found": "Не вдалося знайти {app} в архіві резервного копіювання", "backup_applying_method_tar": "Створення резервного TAR-архіву...", - "backup_applying_method_custom": "Виклик для користувача методу резервного копіювання '{method}'...", - "backup_applying_method_copy": "Копіювання всіх файлів в резервну копію...", + "backup_applying_method_custom": "Виклик користувацького способу резервного копіювання '{method}'...", + "backup_applying_method_copy": "Копіювання всіх файлів у резервну копію...", "backup_app_failed": "Не вдалося створити резервну копію {app}", "backup_actually_backuping": "Створення резервного архіву з зібраних файлів...", - "backup_abstract_method": "Цей метод резервного копіювання ще не реалізований", - "ask_password": "пароль", + "backup_abstract_method": "Цей спосіб резервного копіювання ще не реалізований", + "ask_password": "Пароль", "ask_new_path": "Новий шлях", - "ask_new_domain": "новий домен", - "ask_new_admin_password": "Новий адміністративний пароль", - "ask_main_domain": "основний домен", + "ask_new_domain": "Новий домен", + "ask_new_admin_password": "Новий пароль адміністратора", + "ask_main_domain": "Основний домен", "ask_lastname": "Прізвище", - "ask_firstname": "ім'я", - "ask_user_domain": "Домен для адреси електронної пошти користувача і облікового запису XMPP", - "apps_catalog_update_success": "Каталог додатків був оновлений!", - "apps_catalog_obsolete_cache": "Кеш каталогу додатків порожній або застарів.", - "apps_catalog_failed_to_download": "Неможливо завантажити каталог додатків {apps_catalog}: {error}", - "apps_catalog_updating": "Оновлення каталогу додатків…", - "apps_catalog_init_success": "Система каталогу додатків инициализирована!", - "apps_already_up_to_date": "Всі додатки вже оновлені", - "app_packaging_format_not_supported": "Ця програма не може бути встановлено, тому що формат його упаковки не підтримується вашою версією YunoHost. Можливо, вам слід оновити вашу систему.", + "ask_firstname": "Ім'я", + "ask_user_domain": "Домен для адреси е-пошти користувача і облікового запису XMPP", + "apps_catalog_update_success": "Каталог застосунків був оновлений!", + "apps_catalog_obsolete_cache": "Кеш каталогу застосунків порожній або застарів.", + "apps_catalog_failed_to_download": "Неможливо завантажити каталог застосунків {apps_catalog}: {error}", + "apps_catalog_updating": "Оновлення каталогу застосунків…", + "apps_catalog_init_success": "Систему каталогу застосунків ініціалізовано!", + "apps_already_up_to_date": "Усі застосунки вже оновлено", + "app_packaging_format_not_supported": "Цей застосунок не може бути встановлено, тому що формат його упакування не підтримується вашою версією YunoHost. Можливо, вам слід оновити систему.", "app_upgraded": "{app} оновлено", - "app_upgrade_some_app_failed": "Деякі програми не можуть бути оновлені", - "app_upgrade_script_failed": "Сталася помилка в сценарії оновлення програми", + "app_upgrade_some_app_failed": "Деякі застосунки не можуть бути оновлені", + "app_upgrade_script_failed": "Сталася помилка в скрипті оновлення застосунку", "app_upgrade_failed": "Не вдалося оновити {app}: {error}", "app_upgrade_app_name": "Зараз оновлюємо {app}...", - "app_upgrade_several_apps": "Наступні додатки будуть оновлені: {apps}", - "app_unsupported_remote_type": "Для додатка використовується непідтримуваний віддалений тип.", - "app_unknown": "невідоме додаток", + "app_upgrade_several_apps": "Наступні застосунки буде оновлено: {apps}", + "app_unsupported_remote_type": "Для застосунку використовується непідтримуваний віддалений тип.", + "app_unknown": "Невідомий застосунок", "app_start_restore": "Відновлення {app}...", - "app_start_backup": "Збір файлів для резервного копіювання {app}...", - "app_start_remove": "Видалення {app}...", + "app_start_backup": "Збирання файлів для резервного копіювання {app}...", + "app_start_remove": "Вилучення {app}...", "app_start_install": "Установлення {app}...", - "app_sources_fetch_failed": "Не вдалося вихідні файли, URL коректний?", - "app_restore_script_failed": "Сталася помилка всередині скрипта відновити оригінальну програму", + "app_sources_fetch_failed": "Не вдалося отримати джерельні файли, URL-адреса правильна?", + "app_restore_script_failed": "Сталася помилка всередині скрипта відновлення застосунку", "app_restore_failed": "Не вдалося відновити {app}: {error}", - "app_remove_after_failed_install": "Видалення програми після збою установки...", + "app_remove_after_failed_install": "Вилучення застосунку після збою встановлення...", "app_requirements_unmeet": "Вимоги не виконані для {app}, пакет {pkgname} ({version}) повинен бути {spec}.", - "app_requirements_checking": "Перевірка необхідних пакетів для {app}...", + "app_requirements_checking": "Перевіряння необхідних пакетів для {app}...", "app_removed": "{app} видалено", "app_not_properly_removed": "{app} не було видалено належним чином", - "app_not_installed": "Не вдалося знайти {app} в списку встановлених додатків: {all_apps}", + "app_not_installed": "Не вдалося знайти {app} в списку встановлених застосунків: {all_apps}", "app_not_correctly_installed": "{app}, схоже, неправильно встановлено", - "app_not_upgraded": "Додаток '{failed_app}' не вдалося оновити, і, як наслідок, оновлення таких програмах було скасовано: {apps}", - "app_manifest_install_ask_is_public": "Чи повинно це додаток бути відкрито для анонімних відвідувачів?", - "app_manifest_install_ask_admin": "Виберіть користувача-адміністратора для цього додатка", - "app_manifest_install_ask_password": "Виберіть пароль адміністратора для цього додатка" + "app_not_upgraded": "Застосунок '{failed_app}' не вдалося оновити, і, як наслідок, оновлення таких застосунків було скасовано: {apps}", + "app_manifest_install_ask_is_public": "Чи має цей застосунок бути відкритим для анонімних відвідувачів?", + "app_manifest_install_ask_admin": "Виберіть користувача-адміністратора для цього застосунку", + "app_manifest_install_ask_password": "Виберіть пароль адміністратора для цього застосунку" } From 29ff4faf307d0c296b6f7da668d32eb22ce37d1a Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 4 Sep 2021 19:05:02 +0200 Subject: [PATCH 085/101] i18n: Add add_missing_keys script --- tests/add_missing_keys.py | 193 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 tests/add_missing_keys.py diff --git a/tests/add_missing_keys.py b/tests/add_missing_keys.py new file mode 100644 index 000000000..30c6c6640 --- /dev/null +++ b/tests/add_missing_keys.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- + +import os +import re +import glob +import json +import yaml +import subprocess + +############################################################################### +# Find used keys in python code # +############################################################################### + + +def find_expected_string_keys(): + + # Try to find : + # m18n.n( "foo" + # YunohostError("foo" + # YunohostValidationError("foo" + # # i18n: foo + p1 = re.compile(r"m18n\.n\(\n*\s*[\"\'](\w+)[\"\']") + p2 = re.compile(r"YunohostError\(\n*\s*[\'\"](\w+)[\'\"]") + p3 = re.compile(r"YunohostValidationError\(\n*\s*[\'\"](\w+)[\'\"]") + p4 = re.compile(r"# i18n: [\'\"]?(\w+)[\'\"]?") + + python_files = glob.glob("src/yunohost/*.py") + python_files.extend(glob.glob("src/yunohost/utils/*.py")) + python_files.extend(glob.glob("src/yunohost/data_migrations/*.py")) + python_files.extend(glob.glob("src/yunohost/authenticators/*.py")) + python_files.extend(glob.glob("data/hooks/diagnosis/*.py")) + python_files.append("bin/yunohost") + + for python_file in python_files: + content = open(python_file).read() + for m in p1.findall(content): + if m.endswith("_"): + continue + yield m + for m in p2.findall(content): + if m.endswith("_"): + continue + yield m + for m in p3.findall(content): + if m.endswith("_"): + continue + yield m + for m in p4.findall(content): + yield m + + # For each diagnosis, try to find strings like "diagnosis_stuff_foo" (c.f. diagnosis summaries) + # Also we expect to have "diagnosis_description_" for each diagnosis + p3 = re.compile(r"[\"\'](diagnosis_[a-z]+_\w+)[\"\']") + for python_file in glob.glob("data/hooks/diagnosis/*.py"): + content = open(python_file).read() + for m in p3.findall(content): + if m.endswith("_"): + # Ignore some name fragments which are actually concatenated with other stuff.. + continue + yield m + yield "diagnosis_description_" + os.path.basename(python_file)[:-3].split("-")[ + -1 + ] + + # For each migration, expect to find "migration_description_" + for path in glob.glob("src/yunohost/data_migrations/*.py"): + if "__init__" in path: + continue + yield "migration_description_" + os.path.basename(path)[:-3] + + # For each default service, expect to find "service_description_" + for service, info in yaml.safe_load( + open("data/templates/yunohost/services.yml") + ).items(): + if info is None: + continue + yield "service_description_" + service + + # For all unit operations, expect to find "log_" + # A unit operation is created either using the @is_unit_operation decorator + # or using OperationLogger( + cmd = "grep -hr '@is_unit_operation' src/yunohost/ -A3 2>/dev/null | grep '^def' | sed -E 's@^def (\\w+)\\(.*@\\1@g'" + for funcname in ( + subprocess.check_output(cmd, shell=True).decode("utf-8").strip().split("\n") + ): + yield "log_" + funcname + + p4 = re.compile(r"OperationLogger\(\n*\s*[\"\'](\w+)[\"\']") + for python_file in python_files: + content = open(python_file).read() + for m in ("log_" + match for match in p4.findall(content)): + yield m + + # Global settings descriptions + # Will be on a line like : ("service.ssh.allow_deprecated_dsa_hostkey", {"type": "bool", ... + p5 = re.compile(r" \(\n*\s*[\"\'](\w[\w\.]+)[\"\'],") + content = open("src/yunohost/settings.py").read() + for m in ( + "global_settings_setting_" + s.replace(".", "_") for s in p5.findall(content) + ): + yield m + + # Keys for the actionmap ... + for category in yaml.safe_load(open("data/actionsmap/yunohost.yml")).values(): + if "actions" not in category.keys(): + continue + for action in category["actions"].values(): + if "arguments" not in action.keys(): + continue + for argument in action["arguments"].values(): + extra = argument.get("extra") + if not extra: + continue + if "password" in extra: + yield extra["password"] + if "ask" in extra: + yield extra["ask"] + if "comment" in extra: + yield extra["comment"] + if "pattern" in extra: + yield extra["pattern"][1] + if "help" in extra: + yield extra["help"] + + # Hardcoded expected keys ... + yield "admin_password" # Not sure that's actually used nowadays... + + for method in ["tar", "copy", "custom"]: + yield "backup_applying_method_%s" % method + yield "backup_method_%s_finished" % method + + for level in ["danger", "thirdparty", "warning"]: + yield "confirm_app_install_%s" % level + + for errortype in ["not_found", "error", "warning", "success", "not_found_details"]: + yield "diagnosis_domain_expiration_%s" % errortype + yield "diagnosis_domain_not_found_details" + + for errortype in ["bad_status_code", "connection_error", "timeout"]: + yield "diagnosis_http_%s" % errortype + + yield "password_listed" + for i in [1, 2, 3, 4]: + yield "password_too_simple_%s" % i + + checks = [ + "outgoing_port_25_ok", + "ehlo_ok", + "fcrdns_ok", + "blacklist_ok", + "queue_ok", + "ehlo_bad_answer", + "ehlo_unreachable", + "ehlo_bad_answer_details", + "ehlo_unreachable_details", + ] + for check in checks: + yield "diagnosis_mail_%s" % check + + +############################################################################### +# Load en locale json keys # +############################################################################### + + +def keys_defined_for_en(): + return json.loads(open("locales/en.json").read()).keys() + + +############################################################################### +# Compare keys used and keys defined # +############################################################################### + + +expected_string_keys = set(find_expected_string_keys()) +keys_defined = set(keys_defined_for_en()) + + +undefined_keys = expected_string_keys.difference(keys_defined) +undefined_keys = sorted(undefined_keys) + + +j = json.loads(open("locales/en.json").read()) +for key in undefined_keys: + j[key] = "FIXME" + +json.dump( + j, + open("locales/en.json", "w"), + indent=4, + ensure_ascii=False, + sort_keys=True, +) From 5ac79d8f0521667d6aef59a98a12c169d010e3e2 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 4 Sep 2021 19:06:16 +0200 Subject: [PATCH 086/101] i18n: Apply add_missing_key script ('just' to reorder keys) --- locales/en.json | 466 ++++++++++++++++++++++++------------------------ 1 file changed, 233 insertions(+), 233 deletions(-) diff --git a/locales/en.json b/locales/en.json index 8a95caaf2..7e98ad2fc 100644 --- a/locales/en.json +++ b/locales/en.json @@ -8,8 +8,8 @@ "admin_password_changed": "The administration password was changed", "admin_password_too_long": "Please choose a password shorter than 127 characters", "already_up_to_date": "Nothing to do. Everything is already up-to-date.", - "app_action_cannot_be_ran_because_required_services_down": "These required services should be running to run this action: {services}. Try restarting them to continue (and possibly investigate why they are down).", "app_action_broke_system": "This action seems to have broken these important services: {services}", + "app_action_cannot_be_ran_because_required_services_down": "These required services should be running to run this action: {services}. Try restarting them to continue (and possibly investigate why they are down).", "app_already_installed": "{app} is already installed", "app_already_installed_cant_change_url": "This app is already installed. The URL cannot be changed just by this function. Check in `app changeurl` if it's available.", "app_already_up_to_date": "{app} is already up-to-date", @@ -24,49 +24,48 @@ "app_extraction_failed": "Could not extract the installation files", "app_full_domain_unavailable": "Sorry, this app must be installed on a domain of its own, but other apps are already installed on the domain '{domain}'. You could use a subdomain dedicated to this app instead.", "app_id_invalid": "Invalid app ID", - "app_install_files_invalid": "These files cannot be installed", "app_install_failed": "Unable to install {app}: {error}", + "app_install_files_invalid": "These files cannot be installed", "app_install_script_failed": "An error occurred inside the app installation script", - "app_make_default_location_already_used": "Unable to make '{app}' the default app on the domain, '{domain}' is already in use by '{other_app}'", "app_label_deprecated": "This command is deprecated! Please use the new command 'yunohost user permission update' to manage the app label.", "app_location_unavailable": "This URL is either unavailable, or conflicts with the already installed app(s):\n{apps}", - "app_manifest_invalid": "Something is wrong with the app manifest: {error}", - "app_manifest_install_ask_domain": "Choose the domain where this app should be installed", - "app_manifest_install_ask_path": "Choose the URL path (after the domain) where this app should be installed", - "app_manifest_install_ask_password": "Choose an administration password for this app", + "app_make_default_location_already_used": "Unable to make '{app}' the default app on the domain, '{domain}' is already in use by '{other_app}'", "app_manifest_install_ask_admin": "Choose an administrator user for this app", + "app_manifest_install_ask_domain": "Choose the domain where this app should be installed", "app_manifest_install_ask_is_public": "Should this app be exposed to anonymous visitors?", - "app_not_upgraded": "The app '{failed_app}' failed to upgrade, and as a consequence the following apps' upgrades have been cancelled: {apps}", + "app_manifest_install_ask_password": "Choose an administration password for this app", + "app_manifest_install_ask_path": "Choose the URL path (after the domain) where this app should be installed", + "app_manifest_invalid": "Something is wrong with the app manifest: {error}", "app_not_correctly_installed": "{app} seems to be incorrectly installed", "app_not_installed": "Could not find {app} in the list of installed apps: {all_apps}", "app_not_properly_removed": "{app} has not been properly removed", + "app_not_upgraded": "The app '{failed_app}' failed to upgrade, and as a consequence the following apps' upgrades have been cancelled: {apps}", + "app_packaging_format_not_supported": "This app cannot be installed because its packaging format is not supported by your YunoHost version. You should probably consider upgrading your system.", + "app_remove_after_failed_install": "Removing the app following the installation failure...", "app_removed": "{app} uninstalled", "app_requirements_checking": "Checking required packages for {app}...", "app_requirements_unmeet": "Requirements are not met for {app}, the package {pkgname} ({version}) must be {spec}", - "app_remove_after_failed_install": "Removing the app following the installation failure...", "app_restore_failed": "Could not restore {app}: {error}", "app_restore_script_failed": "An error occured inside the app restore script", "app_sources_fetch_failed": "Could not fetch sources files, is the URL correct?", + "app_start_backup": "Collecting files to be backed up for {app}...", "app_start_install": "Installing {app}...", "app_start_remove": "Removing {app}...", - "app_start_backup": "Collecting files to be backed up for {app}...", "app_start_restore": "Restoring {app}...", "app_unknown": "Unknown app", "app_unsupported_remote_type": "Unsupported remote type used for the app", - "app_upgrade_several_apps": "The following apps will be upgraded: {apps}", "app_upgrade_app_name": "Now upgrading {app}...", "app_upgrade_failed": "Could not upgrade {app}: {error}", "app_upgrade_script_failed": "An error occurred inside the app upgrade script", + "app_upgrade_several_apps": "The following apps will be upgraded: {apps}", "app_upgrade_some_app_failed": "Some apps could not be upgraded", "app_upgraded": "{app} upgraded", - "app_packaging_format_not_supported": "This app cannot be installed because its packaging format is not supported by your YunoHost version. You should probably consider upgrading your system.", "apps_already_up_to_date": "All apps are already up-to-date", - "apps_catalog_init_success": "App catalog system initialized!", - "apps_catalog_updating": "Updating application catalog...", "apps_catalog_failed_to_download": "Unable to download the {apps_catalog} app catalog: {error}", + "apps_catalog_init_success": "App catalog system initialized!", "apps_catalog_obsolete_cache": "The app catalog cache is empty or obsolete.", "apps_catalog_update_success": "The application catalog has been updated!", - "ask_user_domain": "Domain to use for the user's email address and XMPP account", + "apps_catalog_updating": "Updating application catalog...", "ask_firstname": "First name", "ask_lastname": "Last name", "ask_main_domain": "Main domain", @@ -74,6 +73,7 @@ "ask_new_domain": "New domain", "ask_new_path": "New path", "ask_password": "Password", + "ask_user_domain": "Domain to use for the user's email address and XMPP account", "backup_abstract_method": "This backup method has yet to be implemented", "backup_actually_backuping": "Creating a backup archive from the collected files...", "backup_app_failed": "Could not back up {app}", @@ -82,11 +82,11 @@ "backup_applying_method_tar": "Creating the backup TAR archive...", "backup_archive_app_not_found": "Could not find {app} in the backup archive", "backup_archive_broken_link": "Could not access the backup archive (broken link to {path})", + "backup_archive_cant_retrieve_info_json": "Could not load infos for archive '{archive}'... The info.json cannot be retrieved (or is not a valid json).", + "backup_archive_corrupted": "It looks like the backup archive '{archive}' is corrupted : {error}", "backup_archive_name_exists": "A backup archive with this name already exists.", "backup_archive_name_unknown": "Unknown local backup archive named '{name}'", "backup_archive_open_failed": "Could not open the backup archive", - "backup_archive_cant_retrieve_info_json": "Could not load infos for archive '{archive}'... The info.json cannot be retrieved (or is not a valid json).", - "backup_archive_corrupted": "It looks like the backup archive '{archive}' is corrupted : {error}", "backup_archive_system_part_not_available": "System part '{part}' unavailable in this backup", "backup_archive_writing_error": "Could not add the files '{source}' (named in the archive '{dest}') to be backed up into the compressed archive '{archive}'", "backup_ask_for_copying_if_needed": "Do you want to perform the backup using {size}MB temporarily? (This way is used since some files could not be prepared using a more efficient method.)", @@ -94,8 +94,8 @@ "backup_cleaning_failed": "Could not clean up the temporary backup folder", "backup_copying_to_organize_the_archive": "Copying {size}MB to organize the archive", "backup_couldnt_bind": "Could not bind {src} to {dest}.", - "backup_created": "Backup created", "backup_create_size_estimation": "The archive will contain about {size} of data.", + "backup_created": "Backup created", "backup_creation_failed": "Could not create the backup archive", "backup_csv_addition_failed": "Could not add files to backup into the CSV file", "backup_csv_creation_failed": "Could not create the CSV file needed for restoration", @@ -130,163 +130,163 @@ "certmanager_cert_renew_success": "Let's Encrypt certificate renewed for the domain '{domain}'", "certmanager_cert_signing_failed": "Could not sign the new certificate", "certmanager_certificate_fetching_or_enabling_failed": "Trying to use the new certificate for {domain} did not work...", - "certmanager_domain_not_diagnosed_yet": "There is no diagnosis result for domain {domain} yet. Please re-run a diagnosis for categories 'DNS records' and 'Web' in the diagnosis section to check if the domain is ready for Let's Encrypt. (Or if you know what you are doing, use '--no-checks' to turn off those checks.)", "certmanager_domain_cert_not_selfsigned": "The certificate for domain {domain} is not self-signed. Are you sure you want to replace it? (Use '--force' to do so.)", "certmanager_domain_dns_ip_differs_from_public_ip": "The DNS records for domain '{domain}' is different from this server's IP. Please check the 'DNS records' (basic) category in the diagnosis for more info. If you recently modified your A record, please wait for it to propagate (some DNS propagation checkers are available online). (If you know what you are doing, use '--no-checks' to turn off those checks.)", "certmanager_domain_http_not_working": "Domain {domain} does not seem to be accessible through HTTP. Please check the 'Web' category in the diagnosis for more info. (If you know what you are doing, use '--no-checks' to turn off those checks.)", - "certmanager_warning_subdomain_dns_record": "Subdomain '{subdomain}' does not resolve to the same IP address as '{domain}'. Some features will not be available until you fix this and regenerate the certificate.", + "certmanager_domain_not_diagnosed_yet": "There is no diagnosis result for domain {domain} yet. Please re-run a diagnosis for categories 'DNS records' and 'Web' in the diagnosis section to check if the domain is ready for Let's Encrypt. (Or if you know what you are doing, use '--no-checks' to turn off those checks.)", "certmanager_hit_rate_limit": "Too many certificates already issued for this exact set of domains {domain} recently. Please try again later. See https://letsencrypt.org/docs/rate-limits/ for more details", "certmanager_no_cert_file": "Could not read the certificate file for the domain {domain} (file: {file})", "certmanager_self_ca_conf_file_not_found": "Could not find configuration file for self-signing authority (file: {file})", "certmanager_unable_to_parse_self_CA_name": "Could not parse name of self-signing authority (file: {file})", - "confirm_app_install_warning": "Warning: This app may work, but is not well-integrated in YunoHost. Some features such as single sign-on and backup/restore might not be available. Install anyway? [{answers}] ", + "certmanager_warning_subdomain_dns_record": "Subdomain '{subdomain}' does not resolve to the same IP address as '{domain}'. Some features will not be available until you fix this and regenerate the certificate.", "confirm_app_install_danger": "DANGER! This app is known to be still experimental (if not explicitly not working)! You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system... If you are willing to take that risk anyway, type '{answers}'", "confirm_app_install_thirdparty": "DANGER! This app is not part of YunoHost's app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system... If you are willing to take that risk anyway, type '{answers}'", + "confirm_app_install_warning": "Warning: This app may work, but is not well-integrated in YunoHost. Some features such as single sign-on and backup/restore might not be available. Install anyway? [{answers}] ", "custom_app_url_required": "You must provide a URL to upgrade your custom app {app}", + "diagnosis_apps_allgood": "All installed apps respect basic packaging practices", + "diagnosis_apps_bad_quality": "This application is currently flagged as broken on YunoHost's application catalog. This may be a temporary issue while the maintainers attempt to fix the issue. In the meantime, upgrading this app is disabled.", + "diagnosis_apps_broken": "This application is currently flagged as broken on YunoHost's application catalog. This may be a temporary issue while the maintainers attempt to fix the issue. In the meantime, upgrading this app is disabled.", + "diagnosis_apps_deprecated_practices": "This app's installed version still uses some super-old deprecated packaging practices. You should really consider upgrading it.", + "diagnosis_apps_issue": "An issue was found for app {app}", + "diagnosis_apps_not_in_app_catalog": "This application is not in YunoHost's application catalog. If it was in the past and got removed, you should consider uninstalling this app as it won't receive upgrade, and may compromise the integrity and security of your system.", + "diagnosis_apps_outdated_ynh_requirement": "This app's installed version only requires yunohost >= 2.x, which tends to indicate that it's not up to date with recommended packaging practices and helpers. You should really consider upgrading it.", + "diagnosis_backports_in_sources_list": "It looks like apt (the package manager) is configured to use the backports repository. Unless you really know what you are doing, we strongly discourage from installing packages from backports, because it's likely to create unstabilities or conflicts on your system.", "diagnosis_basesystem_hardware": "Server hardware architecture is {virt} {arch}", "diagnosis_basesystem_hardware_model": "Server model is {model}", "diagnosis_basesystem_host": "Server is running Debian {debian_version}", "diagnosis_basesystem_kernel": "Server is running Linux kernel {kernel_version}", - "diagnosis_basesystem_ynh_single_version": "{package} version: {version} ({repo})", - "diagnosis_basesystem_ynh_main_version": "Server is running YunoHost {main_version} ({repo})", "diagnosis_basesystem_ynh_inconsistent_versions": "You are running inconsistent versions of the YunoHost packages... most probably because of a failed or partial upgrade.", - "diagnosis_backports_in_sources_list": "It looks like apt (the package manager) is configured to use the backports repository. Unless you really know what you are doing, we strongly discourage from installing packages from backports, because it's likely to create unstabilities or conflicts on your system.", - "diagnosis_package_installed_from_sury": "Some system packages should be downgraded", - "diagnosis_package_installed_from_sury_details": "Some packages were inadvertendly installed from a third-party repository called Sury. The YunoHost team improved the strategy that handle these packages, but it's expected that some setups that installed PHP7.3 apps while still on Stretch have some remaining inconsistencies. To fix this situation, you should try running the following command: {cmd_to_fix}", - "diagnosis_display_tip": "To see the issues found, you can go to the Diagnosis section of the webadmin, or run 'yunohost diagnosis show --issues --human-readable' from the command-line.", - "diagnosis_failed_for_category": "Diagnosis failed for category '{category}': {error}", + "diagnosis_basesystem_ynh_main_version": "Server is running YunoHost {main_version} ({repo})", + "diagnosis_basesystem_ynh_single_version": "{package} version: {version} ({repo})", "diagnosis_cache_still_valid": "(Cache still valid for {category} diagnosis. Won't re-diagnose it yet!)", "diagnosis_cant_run_because_of_dep": "Can't run diagnosis for {category} while there are important issues related to {dep}.", - "diagnosis_ignored_issues": "(+ {nb_ignored} ignored issue(s))", - "diagnosis_found_errors": "Found {errors} significant issue(s) related to {category}!", - "diagnosis_found_errors_and_warnings": "Found {errors} significant issue(s) (and {warnings} warning(s)) related to {category}!", - "diagnosis_found_warnings": "Found {warnings} item(s) that could be improved for {category}.", - "diagnosis_everything_ok": "Everything looks good for {category}!", - "diagnosis_failed": "Failed to fetch diagnosis result for category '{category}': {error}", - "diagnosis_no_cache": "No diagnosis cache yet for category '{category}'", - "diagnosis_ip_connected_ipv4": "The server is connected to the Internet through IPv4!", - "diagnosis_ip_no_ipv4": "The server does not have working IPv4.", - "diagnosis_ip_connected_ipv6": "The server is connected to the Internet through IPv6!", - "diagnosis_ip_no_ipv6": "The server does not have working IPv6.", - "diagnosis_ip_no_ipv6_tip": "Having a working IPv6 is not mandatory for your server to work, but it is better for the health of the Internet as a whole. IPv6 should usually be automatically configured by the system or your provider if it's available. Otherwise, you might need to configure a few things manually as explained in the documentation here: https://yunohost.org/#/ipv6. If you cannot enable IPv6 or if it seems too technical for you, you can also safely ignore this warning.", - "diagnosis_ip_global": "Global IP: {global}", - "diagnosis_ip_local": "Local IP: {local}", - "diagnosis_ip_not_connected_at_all": "The server does not seem to be connected to the Internet at all!?", - "diagnosis_ip_dnsresolution_working": "Domain name resolution is working!", - "diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason... Is a firewall blocking DNS requests ?", - "diagnosis_ip_broken_resolvconf": "Domain name resolution seems to be broken on your server, which seems related to /etc/resolv.conf not pointing to 127.0.0.1.", - "diagnosis_ip_weird_resolvconf": "DNS resolution seems to be working, but it looks like you're using a custom /etc/resolv.conf.", - "diagnosis_ip_weird_resolvconf_details": "The file /etc/resolv.conf should be a symlink to /etc/resolvconf/run/resolv.conf itself pointing to 127.0.0.1 (dnsmasq). If you want to manually configure DNS resolvers, please edit /etc/resolv.dnsmasq.conf.", - "diagnosis_dns_good_conf": "DNS records are correctly configured for domain {domain} (category {category})", + "diagnosis_description_apps": "Applications", + "diagnosis_description_basesystem": "Base system", + "diagnosis_description_dnsrecords": "DNS records", + "diagnosis_description_ip": "Internet connectivity", + "diagnosis_description_mail": "Email", + "diagnosis_description_ports": "Ports exposure", + "diagnosis_description_regenconf": "System configurations", + "diagnosis_description_services": "Services status check", + "diagnosis_description_systemresources": "System resources", + "diagnosis_description_web": "Web", + "diagnosis_diskusage_low": "Storage {mountpoint} (on device {device}) has only {free} ({free_percent}%) space remaining (out of {total}). Be careful.", + "diagnosis_diskusage_ok": "Storage {mountpoint} (on device {device}) still has {free} ({free_percent}%) space left (out of {total})!", + "diagnosis_diskusage_verylow": "Storage {mountpoint} (on device {device}) has only {free} ({free_percent}%) space remaining (out of {total}). You should really consider cleaning up some space!", + "diagnosis_display_tip": "To see the issues found, you can go to the Diagnosis section of the webadmin, or run 'yunohost diagnosis show --issues --human-readable' from the command-line.", "diagnosis_dns_bad_conf": "Some DNS records are missing or incorrect for domain {domain} (category {category})", - "diagnosis_dns_missing_record": "According to the recommended DNS configuration, you should add a DNS record with the following info.
Type: {type}
Name: {name}
Value: {value}", "diagnosis_dns_discrepancy": "The following DNS record does not seem to follow the recommended configuration:
Type: {type}
Name: {name}
Current value: {current}
Expected value: {value}", + "diagnosis_dns_good_conf": "DNS records are correctly configured for domain {domain} (category {category})", + "diagnosis_dns_missing_record": "According to the recommended DNS configuration, you should add a DNS record with the following info.
Type: {type}
Name: {name}
Value: {value}", "diagnosis_dns_point_to_doc": "Please check the documentation at https://yunohost.org/dns_config if you need help about configuring DNS records.", - "diagnosis_dns_try_dyndns_update_force": "This domain's DNS configuration should automatically be managed by YunoHost. If that's not the case, you can try to force an update using yunohost dyndns update --force.", "diagnosis_dns_specialusedomain": "Domain {domain} is based on a special-use top-level domain (TLD) and is therefore not expected to have actual DNS records.", + "diagnosis_dns_try_dyndns_update_force": "This domain's DNS configuration should automatically be managed by YunoHost. If that's not the case, you can try to force an update using yunohost dyndns update --force.", + "diagnosis_domain_expiration_error": "Some domains will expire VERY SOON!", "diagnosis_domain_expiration_not_found": "Unable to check the expiration date for some domains", - "diagnosis_domain_not_found_details": "The domain {domain} doesn't exist in WHOIS database or is expired!", "diagnosis_domain_expiration_not_found_details": "The WHOIS information for domain {domain} doesn't seem to contain the information about the expiration date?", "diagnosis_domain_expiration_success": "Your domains are registered and not going to expire anytime soon.", "diagnosis_domain_expiration_warning": "Some domains will expire soon!", - "diagnosis_domain_expiration_error": "Some domains will expire VERY SOON!", "diagnosis_domain_expires_in": "{domain} expires in {days} days.", - "diagnosis_services_running": "Service {service} is running!", - "diagnosis_services_conf_broken": "Configuration is broken for service {service}!", - "diagnosis_services_bad_status": "Service {service} is {status} :(", - "diagnosis_services_bad_status_tip": "You can try to restart the service, and if it doesn't work, have a look at the service logs in the webadmin (from the command line, you can do this with yunohost service restart {service} and yunohost service log {service}).", - "diagnosis_diskusage_verylow": "Storage {mountpoint} (on device {device}) has only {free} ({free_percent}%) space remaining (out of {total}). You should really consider cleaning up some space!", - "diagnosis_diskusage_low": "Storage {mountpoint} (on device {device}) has only {free} ({free_percent}%) space remaining (out of {total}). Be careful.", - "diagnosis_diskusage_ok": "Storage {mountpoint} (on device {device}) still has {free} ({free_percent}%) space left (out of {total})!", - "diagnosis_ram_verylow": "The system has only {available} ({available_percent}%) RAM available! (out of {total})", + "diagnosis_domain_not_found_details": "The domain {domain} doesn't exist in WHOIS database or is expired!", + "diagnosis_everything_ok": "Everything looks good for {category}!", + "diagnosis_failed": "Failed to fetch diagnosis result for category '{category}': {error}", + "diagnosis_failed_for_category": "Diagnosis failed for category '{category}': {error}", + "diagnosis_found_errors": "Found {errors} significant issue(s) related to {category}!", + "diagnosis_found_errors_and_warnings": "Found {errors} significant issue(s) (and {warnings} warning(s)) related to {category}!", + "diagnosis_found_warnings": "Found {warnings} item(s) that could be improved for {category}.", + "diagnosis_http_bad_status_code": "It looks like another machine (maybe your internet router) answered instead of your server.
1. The most common cause for this issue is that port 80 (and 443) are not correctly forwarded to your server.
2. On more complex setups: make sure that no firewall or reverse-proxy is interfering.", + "diagnosis_http_connection_error": "Connection error: could not connect to the requested domain, it's very likely unreachable.", + "diagnosis_http_could_not_diagnose": "Could not diagnose if domains are reachable from outside in IPv{ipversion}.", + "diagnosis_http_could_not_diagnose_details": "Error: {error}", + "diagnosis_http_hairpinning_issue": "Your local network does not seem to have hairpinning enabled.", + "diagnosis_http_hairpinning_issue_details": "This is probably because of your ISP box / router. As a result, people from outside your local network will be able to access your server as expected, but not people from inside the local network (like you, probably?) when using the domain name or global IP. You may be able to improve the situation by having a look at https://yunohost.org/dns_local_network", + "diagnosis_http_localdomain": "Domain {domain}, with a .local TLD, is not expected to be exposed outside the local network.", + "diagnosis_http_nginx_conf_not_up_to_date": "This domain's nginx configuration appears to have been modified manually, and prevents YunoHost from diagnosing if it's reachable on HTTP.", + "diagnosis_http_nginx_conf_not_up_to_date_details": "To fix the situation, inspect the difference with the command line using yunohost tools regen-conf nginx --dry-run --with-diff and if you're ok, apply the changes with yunohost tools regen-conf nginx --force.", + "diagnosis_http_ok": "Domain {domain} is reachable through HTTP from outside the local network.", + "diagnosis_http_partially_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network in IPv{failed}, though it works in IPv{passed}.", + "diagnosis_http_timeout": "Timed-out while trying to contact your server from outside. It appears to be unreachable.
1. The most common cause for this issue is that port 80 (and 443) are not correctly forwarded to your server.
2. You should also make sure that the service nginx is running
3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.", + "diagnosis_http_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network.", + "diagnosis_ignored_issues": "(+ {nb_ignored} ignored issue(s))", + "diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason... Is a firewall blocking DNS requests ?", + "diagnosis_ip_broken_resolvconf": "Domain name resolution seems to be broken on your server, which seems related to /etc/resolv.conf not pointing to 127.0.0.1.", + "diagnosis_ip_connected_ipv4": "The server is connected to the Internet through IPv4!", + "diagnosis_ip_connected_ipv6": "The server is connected to the Internet through IPv6!", + "diagnosis_ip_dnsresolution_working": "Domain name resolution is working!", + "diagnosis_ip_global": "Global IP: {global}", + "diagnosis_ip_local": "Local IP: {local}", + "diagnosis_ip_no_ipv4": "The server does not have working IPv4.", + "diagnosis_ip_no_ipv6": "The server does not have working IPv6.", + "diagnosis_ip_no_ipv6_tip": "Having a working IPv6 is not mandatory for your server to work, but it is better for the health of the Internet as a whole. IPv6 should usually be automatically configured by the system or your provider if it's available. Otherwise, you might need to configure a few things manually as explained in the documentation here: https://yunohost.org/#/ipv6. If you cannot enable IPv6 or if it seems too technical for you, you can also safely ignore this warning.", + "diagnosis_ip_not_connected_at_all": "The server does not seem to be connected to the Internet at all!?", + "diagnosis_ip_weird_resolvconf": "DNS resolution seems to be working, but it looks like you're using a custom /etc/resolv.conf.", + "diagnosis_ip_weird_resolvconf_details": "The file /etc/resolv.conf should be a symlink to /etc/resolvconf/run/resolv.conf itself pointing to 127.0.0.1 (dnsmasq). If you want to manually configure DNS resolvers, please edit /etc/resolv.dnsmasq.conf.", + "diagnosis_mail_blacklist_listed_by": "Your IP or domain {item} is blacklisted on {blacklist_name}", + "diagnosis_mail_blacklist_ok": "The IPs and domains used by this server do not appear to be blacklisted", + "diagnosis_mail_blacklist_reason": "The blacklist reason is: {reason}", + "diagnosis_mail_blacklist_website": "After identifying why you are listed and fixed it, feel free to ask for your IP or domaine to be removed on {blacklist_website}", + "diagnosis_mail_ehlo_bad_answer": "A non-SMTP service answered on port 25 on IPv{ipversion}", + "diagnosis_mail_ehlo_bad_answer_details": "It could be due to an other machine answering instead of your server.", + "diagnosis_mail_ehlo_could_not_diagnose": "Could not diagnose if postfix mail server is reachable from outside in IPv{ipversion}.", + "diagnosis_mail_ehlo_could_not_diagnose_details": "Error: {error}", + "diagnosis_mail_ehlo_ok": "The SMTP mail server is reachable from the outside and therefore is able to receive emails!", + "diagnosis_mail_ehlo_unreachable": "The SMTP mail server is unreachable from the outside on IPv{ipversion}. It won't be able to receive emails.", + "diagnosis_mail_ehlo_unreachable_details": "Could not open a connection on port 25 to your server in IPv{ipversion}. It appears to be unreachable.
1. The most common cause for this issue is that port 25 is not correctly forwarded to your server.
2. You should also make sure that service postfix is running.
3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.", + "diagnosis_mail_ehlo_wrong": "A different SMTP mail server answers on IPv{ipversion}. Your server will probably not be able to receive emails.", + "diagnosis_mail_ehlo_wrong_details": "The EHLO received by the remote diagnoser in IPv{ipversion} is different from your server's domain.
Received EHLO: {wrong_ehlo}
Expected: {right_ehlo}
The most common cause for this issue is that port 25 is not correctly forwarded to your server. Alternatively, make sure that no firewall or reverse-proxy is interfering.", + "diagnosis_mail_fcrdns_different_from_ehlo_domain": "The reverse DNS is not correctly configured in IPv{ipversion}. Some emails may fail to get delivered or may get flagged as spam.", + "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Current reverse DNS: {rdns_domain}
Expected value: {ehlo_domain}", + "diagnosis_mail_fcrdns_dns_missing": "No reverse DNS is defined in IPv{ipversion}. Some emails may fail to get delivered or may get flagged as spam.", + "diagnosis_mail_fcrdns_nok_alternatives_4": "Some providers won't let you configure your reverse DNS (or their feature might be broken...). If you are experiencing issues because of this, consider the following solutions:
- Some ISP provide the alternative of using a mail server relay though it implies that the relay will be able to spy on your email traffic.
- A privacy-friendly alternative is to use a VPN *with a dedicated public IP* to bypass this kind of limits. See https://yunohost.org/#/vpn_advantage
- Or it's possible to switch to a different provider", + "diagnosis_mail_fcrdns_nok_alternatives_6": "Some providers won't let you configure your reverse DNS (or their feature might be broken...). If your reverse DNS is correctly configured for IPv4, you can try disabling the use of IPv6 when sending emails by running yunohost settings set smtp.allow_ipv6 -v off. Note: this last solution means that you won't be able to send or receive emails from the few IPv6-only servers out there.", + "diagnosis_mail_fcrdns_nok_details": "You should first try to configure the reverse DNS with {ehlo_domain} in your internet router interface or your hosting provider interface. (Some hosting provider may require you to send them a support ticket for this).", + "diagnosis_mail_fcrdns_ok": "Your reverse DNS is correctly configured!", + "diagnosis_mail_outgoing_port_25_blocked": "The SMTP mail server cannot send emails to other servers because outgoing port 25 is blocked in IPv{ipversion}.", + "diagnosis_mail_outgoing_port_25_blocked_details": "You should first try to unblock outgoing port 25 in your internet router interface or your hosting provider interface. (Some hosting provider may require you to send them a support ticket for this).", + "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Some providers won't let you unblock outgoing port 25 because they don't care about Net Neutrality.
- Some of them provide the alternative of using a mail server relay though it implies that the relay will be able to spy on your email traffic.
- A privacy-friendly alternative is to use a VPN *with a dedicated public IP* to bypass this kind of limits. See https://yunohost.org/#/vpn_advantage
- You can also consider switching to a more net neutrality-friendly provider", + "diagnosis_mail_outgoing_port_25_ok": "The SMTP mail server is able to send emails (outgoing port 25 is not blocked).", + "diagnosis_mail_queue_ok": "{nb_pending} pending emails in the mail queues", + "diagnosis_mail_queue_too_big": "Too many pending emails in mail queue ({nb_pending} emails)", + "diagnosis_mail_queue_unavailable": "Can not consult number of pending emails in queue", + "diagnosis_mail_queue_unavailable_details": "Error: {error}", + "diagnosis_never_ran_yet": "It looks like this server was setup recently and there's no diagnosis report to show yet. You should start by running a full diagnosis, either from the webadmin or using 'yunohost diagnosis run' from the command line.", + "diagnosis_no_cache": "No diagnosis cache yet for category '{category}'", + "diagnosis_package_installed_from_sury": "Some system packages should be downgraded", + "diagnosis_package_installed_from_sury_details": "Some packages were inadvertendly installed from a third-party repository called Sury. The YunoHost team improved the strategy that handle these packages, but it's expected that some setups that installed PHP7.3 apps while still on Stretch have some remaining inconsistencies. To fix this situation, you should try running the following command: {cmd_to_fix}", + "diagnosis_ports_could_not_diagnose": "Could not diagnose if ports are reachable from outside in IPv{ipversion}.", + "diagnosis_ports_could_not_diagnose_details": "Error: {error}", + "diagnosis_ports_forwarding_tip": "To fix this issue, you most probably need to configure port forwarding on your internet router as described in https://yunohost.org/isp_box_config", + "diagnosis_ports_needed_by": "Exposing this port is needed for {category} features (service {service})", + "diagnosis_ports_ok": "Port {port} is reachable from outside.", + "diagnosis_ports_partially_unreachable": "Port {port} is not reachable from outside in IPv{failed}.", + "diagnosis_ports_unreachable": "Port {port} is not reachable from outside.", + "diagnosis_processes_killed_by_oom_reaper": "Some processes were recently killed by the system because it ran out of memory. This is typically symptomatic of a lack of memory on the system or of a process that ate up to much memory. Summary of the processes killed:\n{kills_summary}", "diagnosis_ram_low": "The system has {available} ({available_percent}%) RAM available (out of {total}). Be careful.", "diagnosis_ram_ok": "The system still has {available} ({available_percent}%) RAM available out of {total}.", + "diagnosis_ram_verylow": "The system has only {available} ({available_percent}%) RAM available! (out of {total})", + "diagnosis_regenconf_allgood": "All configurations files are in line with the recommended configuration!", + "diagnosis_regenconf_manually_modified": "Configuration file {file} appears to have been manually modified.", + "diagnosis_regenconf_manually_modified_details": "This is probably OK if you know what you're doing! YunoHost will stop updating this file automatically... But beware that YunoHost upgrades could contain important recommended changes. If you want to, you can inspect the differences with yunohost tools regen-conf {category} --dry-run --with-diff and force the reset to the recommended configuration with yunohost tools regen-conf {category} --force", + "diagnosis_rootfstotalspace_critical": "The root filesystem only has a total of {space} which is quite worrisome! You will likely run out of disk space very quickly! It's recommended to have at least 16 GB for the root filesystem.", + "diagnosis_rootfstotalspace_warning": "The root filesystem only has a total of {space}. This may be okay, but be careful because ultimately you may run out of disk space quickly... It's recommended to have at least 16 GB for the root filesystem.", + "diagnosis_security_vulnerable_to_meltdown": "You appear vulnerable to the Meltdown criticial security vulnerability", + "diagnosis_security_vulnerable_to_meltdown_details": "To fix this, you should upgrade your system and reboot to load the new linux kernel (or contact your server provider if this doesn't work). See https://meltdownattack.com/ for more infos.", + "diagnosis_services_bad_status": "Service {service} is {status} :(", + "diagnosis_services_bad_status_tip": "You can try to restart the service, and if it doesn't work, have a look at the service logs in the webadmin (from the command line, you can do this with yunohost service restart {service} and yunohost service log {service}).", + "diagnosis_services_conf_broken": "Configuration is broken for service {service}!", + "diagnosis_services_running": "Service {service} is running!", + "diagnosis_sshd_config_inconsistent": "It looks like the SSH port was manually modified in /etc/ssh/sshd_config. Since YunoHost 4.2, a new global setting 'security.ssh.port' is available to avoid manually editing the configuration.", + "diagnosis_sshd_config_inconsistent_details": "Please run yunohost settings set security.ssh.port -v YOUR_SSH_PORT to define the SSH port, and check yunohost tools regen-conf ssh --dry-run --with-diff and yunohost tools regen-conf ssh --force to reset your conf to the YunoHost recommendation.", + "diagnosis_sshd_config_insecure": "The SSH configuration appears to have been manually modified, and is insecure because it contains no 'AllowGroups' or 'AllowUsers' directive to limit access to authorized users.", "diagnosis_swap_none": "The system has no swap at all. You should consider adding at least {recommended} of swap to avoid situations where the system runs out of memory.", "diagnosis_swap_notsomuch": "The system has only {total} swap. You should consider having at least {recommended} to avoid situations where the system runs out of memory.", "diagnosis_swap_ok": "The system has {total} of swap!", "diagnosis_swap_tip": "Please be careful and aware that if the server is hosting swap on an SD card or SSD storage, it may drastically reduce the life expectancy of the device`.", - "diagnosis_mail_outgoing_port_25_ok": "The SMTP mail server is able to send emails (outgoing port 25 is not blocked).", - "diagnosis_mail_outgoing_port_25_blocked": "The SMTP mail server cannot send emails to other servers because outgoing port 25 is blocked in IPv{ipversion}.", - "diagnosis_mail_outgoing_port_25_blocked_details": "You should first try to unblock outgoing port 25 in your internet router interface or your hosting provider interface. (Some hosting provider may require you to send them a support ticket for this).", - "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Some providers won't let you unblock outgoing port 25 because they don't care about Net Neutrality.
- Some of them provide the alternative of using a mail server relay though it implies that the relay will be able to spy on your email traffic.
- A privacy-friendly alternative is to use a VPN *with a dedicated public IP* to bypass this kind of limits. See https://yunohost.org/#/vpn_advantage
- You can also consider switching to a more net neutrality-friendly provider", - "diagnosis_mail_ehlo_ok": "The SMTP mail server is reachable from the outside and therefore is able to receive emails!", - "diagnosis_mail_ehlo_unreachable": "The SMTP mail server is unreachable from the outside on IPv{ipversion}. It won't be able to receive emails.", - "diagnosis_mail_ehlo_unreachable_details": "Could not open a connection on port 25 to your server in IPv{ipversion}. It appears to be unreachable.
1. The most common cause for this issue is that port 25 is not correctly forwarded to your server.
2. You should also make sure that service postfix is running.
3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.", - "diagnosis_mail_ehlo_bad_answer": "A non-SMTP service answered on port 25 on IPv{ipversion}", - "diagnosis_mail_ehlo_bad_answer_details": "It could be due to an other machine answering instead of your server.", - "diagnosis_mail_ehlo_wrong": "A different SMTP mail server answers on IPv{ipversion}. Your server will probably not be able to receive emails.", - "diagnosis_mail_ehlo_wrong_details": "The EHLO received by the remote diagnoser in IPv{ipversion} is different from your server's domain.
Received EHLO: {wrong_ehlo}
Expected: {right_ehlo}
The most common cause for this issue is that port 25 is not correctly forwarded to your server. Alternatively, make sure that no firewall or reverse-proxy is interfering.", - "diagnosis_mail_ehlo_could_not_diagnose": "Could not diagnose if postfix mail server is reachable from outside in IPv{ipversion}.", - "diagnosis_mail_ehlo_could_not_diagnose_details": "Error: {error}", - "diagnosis_mail_fcrdns_ok": "Your reverse DNS is correctly configured!", - "diagnosis_mail_fcrdns_dns_missing": "No reverse DNS is defined in IPv{ipversion}. Some emails may fail to get delivered or may get flagged as spam.", - "diagnosis_mail_fcrdns_nok_details": "You should first try to configure the reverse DNS with {ehlo_domain} in your internet router interface or your hosting provider interface. (Some hosting provider may require you to send them a support ticket for this).", - "diagnosis_mail_fcrdns_nok_alternatives_4": "Some providers won't let you configure your reverse DNS (or their feature might be broken...). If you are experiencing issues because of this, consider the following solutions:
- Some ISP provide the alternative of using a mail server relay though it implies that the relay will be able to spy on your email traffic.
- A privacy-friendly alternative is to use a VPN *with a dedicated public IP* to bypass this kind of limits. See https://yunohost.org/#/vpn_advantage
- Or it's possible to switch to a different provider", - "diagnosis_mail_fcrdns_nok_alternatives_6": "Some providers won't let you configure your reverse DNS (or their feature might be broken...). If your reverse DNS is correctly configured for IPv4, you can try disabling the use of IPv6 when sending emails by running yunohost settings set smtp.allow_ipv6 -v off. Note: this last solution means that you won't be able to send or receive emails from the few IPv6-only servers out there.", - "diagnosis_mail_fcrdns_different_from_ehlo_domain": "The reverse DNS is not correctly configured in IPv{ipversion}. Some emails may fail to get delivered or may get flagged as spam.", - "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Current reverse DNS: {rdns_domain}
Expected value: {ehlo_domain}", - "diagnosis_mail_blacklist_ok": "The IPs and domains used by this server do not appear to be blacklisted", - "diagnosis_mail_blacklist_listed_by": "Your IP or domain {item} is blacklisted on {blacklist_name}", - "diagnosis_mail_blacklist_reason": "The blacklist reason is: {reason}", - "diagnosis_mail_blacklist_website": "After identifying why you are listed and fixed it, feel free to ask for your IP or domaine to be removed on {blacklist_website}", - "diagnosis_mail_queue_ok": "{nb_pending} pending emails in the mail queues", - "diagnosis_mail_queue_unavailable": "Can not consult number of pending emails in queue", - "diagnosis_mail_queue_unavailable_details": "Error: {error}", - "diagnosis_mail_queue_too_big": "Too many pending emails in mail queue ({nb_pending} emails)", - "diagnosis_regenconf_allgood": "All configurations files are in line with the recommended configuration!", - "diagnosis_regenconf_manually_modified": "Configuration file {file} appears to have been manually modified.", - "diagnosis_regenconf_manually_modified_details": "This is probably OK if you know what you're doing! YunoHost will stop updating this file automatically... But beware that YunoHost upgrades could contain important recommended changes. If you want to, you can inspect the differences with yunohost tools regen-conf {category} --dry-run --with-diff and force the reset to the recommended configuration with yunohost tools regen-conf {category} --force", - "diagnosis_rootfstotalspace_warning": "The root filesystem only has a total of {space}. This may be okay, but be careful because ultimately you may run out of disk space quickly... It's recommended to have at least 16 GB for the root filesystem.", - "diagnosis_rootfstotalspace_critical": "The root filesystem only has a total of {space} which is quite worrisome! You will likely run out of disk space very quickly! It's recommended to have at least 16 GB for the root filesystem.", - "diagnosis_security_vulnerable_to_meltdown": "You appear vulnerable to the Meltdown criticial security vulnerability", - "diagnosis_security_vulnerable_to_meltdown_details": "To fix this, you should upgrade your system and reboot to load the new linux kernel (or contact your server provider if this doesn't work). See https://meltdownattack.com/ for more infos.", - "diagnosis_description_basesystem": "Base system", - "diagnosis_description_ip": "Internet connectivity", - "diagnosis_description_dnsrecords": "DNS records", - "diagnosis_description_services": "Services status check", - "diagnosis_description_systemresources": "System resources", - "diagnosis_description_ports": "Ports exposure", - "diagnosis_description_web": "Web", - "diagnosis_description_mail": "Email", - "diagnosis_description_regenconf": "System configurations", - "diagnosis_description_apps": "Applications", - "diagnosis_apps_allgood": "All installed apps respect basic packaging practices", - "diagnosis_apps_issue": "An issue was found for app {app}", - "diagnosis_apps_not_in_app_catalog": "This application is not in YunoHost's application catalog. If it was in the past and got removed, you should consider uninstalling this app as it won't receive upgrade, and may compromise the integrity and security of your system.", - "diagnosis_apps_broken": "This application is currently flagged as broken on YunoHost's application catalog. This may be a temporary issue while the maintainers attempt to fix the issue. In the meantime, upgrading this app is disabled.", - "diagnosis_apps_bad_quality": "This application is currently flagged as broken on YunoHost's application catalog. This may be a temporary issue while the maintainers attempt to fix the issue. In the meantime, upgrading this app is disabled.", - "diagnosis_apps_outdated_ynh_requirement": "This app's installed version only requires yunohost >= 2.x, which tends to indicate that it's not up to date with recommended packaging practices and helpers. You should really consider upgrading it.", - "diagnosis_apps_deprecated_practices": "This app's installed version still uses some super-old deprecated packaging practices. You should really consider upgrading it.", - "diagnosis_ports_could_not_diagnose": "Could not diagnose if ports are reachable from outside in IPv{ipversion}.", - "diagnosis_ports_could_not_diagnose_details": "Error: {error}", - "diagnosis_ports_unreachable": "Port {port} is not reachable from outside.", - "diagnosis_ports_partially_unreachable": "Port {port} is not reachable from outside in IPv{failed}.", - "diagnosis_ports_ok": "Port {port} is reachable from outside.", - "diagnosis_ports_needed_by": "Exposing this port is needed for {category} features (service {service})", - "diagnosis_ports_forwarding_tip": "To fix this issue, you most probably need to configure port forwarding on your internet router as described in https://yunohost.org/isp_box_config", - "diagnosis_http_hairpinning_issue": "Your local network does not seem to have hairpinning enabled.", - "diagnosis_http_hairpinning_issue_details": "This is probably because of your ISP box / router. As a result, people from outside your local network will be able to access your server as expected, but not people from inside the local network (like you, probably?) when using the domain name or global IP. You may be able to improve the situation by having a look at https://yunohost.org/dns_local_network", - "diagnosis_http_could_not_diagnose": "Could not diagnose if domains are reachable from outside in IPv{ipversion}.", - "diagnosis_http_could_not_diagnose_details": "Error: {error}", - "diagnosis_http_localdomain": "Domain {domain}, with a .local TLD, is not expected to be exposed outside the local network.", - "diagnosis_http_ok": "Domain {domain} is reachable through HTTP from outside the local network.", - "diagnosis_http_timeout": "Timed-out while trying to contact your server from outside. It appears to be unreachable.
1. The most common cause for this issue is that port 80 (and 443) are not correctly forwarded to your server.
2. You should also make sure that the service nginx is running
3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.", - "diagnosis_http_connection_error": "Connection error: could not connect to the requested domain, it's very likely unreachable.", - "diagnosis_http_bad_status_code": "It looks like another machine (maybe your internet router) answered instead of your server.
1. The most common cause for this issue is that port 80 (and 443) are not correctly forwarded to your server.
2. On more complex setups: make sure that no firewall or reverse-proxy is interfering.", - "diagnosis_http_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network.", - "diagnosis_http_partially_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network in IPv{failed}, though it works in IPv{passed}.", - "diagnosis_http_nginx_conf_not_up_to_date": "This domain's nginx configuration appears to have been modified manually, and prevents YunoHost from diagnosing if it's reachable on HTTP.", - "diagnosis_http_nginx_conf_not_up_to_date_details": "To fix the situation, inspect the difference with the command line using yunohost tools regen-conf nginx --dry-run --with-diff and if you're ok, apply the changes with yunohost tools regen-conf nginx --force.", "diagnosis_unknown_categories": "The following categories are unknown: {categories}", - "diagnosis_never_ran_yet": "It looks like this server was setup recently and there's no diagnosis report to show yet. You should start by running a full diagnosis, either from the webadmin or using 'yunohost diagnosis run' from the command line.", - "diagnosis_processes_killed_by_oom_reaper": "Some processes were recently killed by the system because it ran out of memory. This is typically symptomatic of a lack of memory on the system or of a process that ate up to much memory. Summary of the processes killed:\n{kills_summary}", - "diagnosis_sshd_config_insecure": "The SSH configuration appears to have been manually modified, and is insecure because it contains no 'AllowGroups' or 'AllowUsers' directive to limit access to authorized users.", - "diagnosis_sshd_config_inconsistent": "It looks like the SSH port was manually modified in /etc/ssh/sshd_config. Since YunoHost 4.2, a new global setting 'security.ssh.port' is available to avoid manually editing the configuration.", - "diagnosis_sshd_config_inconsistent_details": "Please run yunohost settings set security.ssh.port -v YOUR_SSH_PORT to define the SSH port, and check yunohost tools regen-conf ssh --dry-run --with-diff and yunohost tools regen-conf ssh --force to reset your conf to the YunoHost recommendation.", "disk_space_not_sufficient_install": "There is not enough disk space left to install this application", "disk_space_not_sufficient_update": "There is not enough disk space left to update this application", - "domain_cannot_remove_main": "You cannot remove '{domain}' since it's the main domain, you first need to set another domain as the main domain using 'yunohost domain main-domain -n '; here is the list of candidate domains: {other_domains}", "domain_cannot_add_xmpp_upload": "You cannot add domains starting with 'xmpp-upload.'. This kind of name is reserved for the XMPP upload feature integrated in YunoHost.", + "domain_cannot_remove_main": "You cannot remove '{domain}' since it's the main domain, you first need to set another domain as the main domain using 'yunohost domain main-domain -n '; here is the list of candidate domains: {other_domains}", "domain_cannot_remove_main_add_new_one": "You cannot remove '{domain}' since it's the main domain and your only domain, you need to first add another domain using 'yunohost domain add ', then set is as the main domain using 'yunohost domain main-domain -n ' and then you can remove the domain '{domain}' using 'yunohost domain remove {domain}'.'", "domain_cert_gen_failed": "Could not generate certificate", "domain_created": "Domain created", @@ -298,17 +298,18 @@ "domain_dyndns_root_unknown": "Unknown DynDNS root domain", "domain_exists": "The domain already exists", "domain_hostname_failed": "Unable to set new hostname. This might cause an issue later (it might be fine).", + "domain_name_unknown": "Domain '{domain}' unknown", "domain_remove_confirm_apps_removal": "Removing this domain will remove those applications:\n{apps}\n\nAre you sure you want to do that? [{answers}]", "domain_uninstall_app_first": "Those applications are still installed on your domain:\n{apps}\n\nPlease uninstall them using 'yunohost app remove the_app_id' or move them to another domain using 'yunohost app change-url the_app_id' before proceeding to domain removal", - "domain_name_unknown": "Domain '{domain}' unknown", "domain_unknown": "Unknown domain", "domains_available": "Available domains:", "done": "Done", "downloading": "Downloading...", "dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state... You can try to solve this issue by connecting through SSH and running `sudo apt install --fix-broken` and/or `sudo dpkg --configure -a`.", "dpkg_lock_not_available": "This command can't be run right now because another program seems to be using the lock of dpkg (the system package manager)", - "dyndns_could_not_check_provide": "Could not check if {provider} can provide {domain}.", "dyndns_could_not_check_available": "Could not check if {domain} is available on {provider}.", + "dyndns_could_not_check_provide": "Could not check if {provider} can provide {domain}.", + "dyndns_domain_not_provided": "DynDNS provider {provider} cannot provide domain {domain}.", "dyndns_ip_update_failed": "Could not update IP address to DynDNS", "dyndns_ip_updated": "Updated your IP on DynDNS", "dyndns_key_generating": "Generating DNS key... It may take a while.", @@ -317,10 +318,9 @@ "dyndns_provider_unreachable": "Unable to reach DynDNS provider {provider}: either your YunoHost is not correctly connected to the internet or the dynette server is down.", "dyndns_registered": "DynDNS domain registered", "dyndns_registration_failed": "Could not register DynDNS domain: {error}", - "dyndns_domain_not_provided": "DynDNS provider {provider} cannot provide domain {domain}.", "dyndns_unavailable": "The domain '{domain}' is unavailable.", - "extracting": "Extracting...", "experimental_feature": "Warning: This feature is experimental and not considered stable, you should not use it unless you know what you are doing.", + "extracting": "Extracting...", "field_invalid": "Invalid field '{}'", "file_does_not_exist": "The file {path} does not exist.", "firewall_reload_failed": "Could not reload the firewall", @@ -333,42 +333,42 @@ "global_settings_cant_write_settings": "Could not save settings file, reason: {reason}", "global_settings_key_doesnt_exists": "The key '{settings_key}' does not exist in the global settings, you can see all the available keys by running 'yunohost settings list'", "global_settings_reset_success": "Previous settings now backed up to {path}", + "global_settings_setting_backup_compress_tar_archives": "When creating new backups, compress the archives (.tar.gz) instead of uncompressed archives (.tar). N.B. : enabling this option means create lighter backup archives, but the initial backup procedure will be significantly longer and heavy on CPU.", "global_settings_setting_pop3_enabled": "Enable the POP3 protocol for the mail server", + "global_settings_setting_security_experimental_enabled": "Enable experimental security features (don't enable this if you don't know what you're doing!)", "global_settings_setting_security_nginx_compatibility": "Compatibility vs. security tradeoff for the web server NGINX. Affects the ciphers (and other security-related aspects)", "global_settings_setting_security_password_admin_strength": "Admin password strength", "global_settings_setting_security_password_user_strength": "User password strength", - "global_settings_setting_security_ssh_compatibility": "Compatibility vs. security tradeoff for the SSH server. Affects the ciphers (and other security-related aspects)", "global_settings_setting_security_postfix_compatibility": "Compatibility vs. security tradeoff for the Postfix server. Affects the ciphers (and other security-related aspects)", + "global_settings_setting_security_ssh_compatibility": "Compatibility vs. security tradeoff for the SSH server. Affects the ciphers (and other security-related aspects)", "global_settings_setting_security_ssh_port": "SSH port", - "global_settings_unknown_setting_from_settings_file": "Unknown key in settings: '{setting_key}', discard it and save it in /etc/yunohost/settings-unknown.json", + "global_settings_setting_security_webadmin_allowlist": "IP adresses allowed to access the webadmin. Comma-separated.", + "global_settings_setting_security_webadmin_allowlist_enabled": "Allow only some IPs to access the webadmin.", "global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Allow the use of (deprecated) DSA hostkey for the SSH daemon configuration", - "global_settings_setting_ssowat_panel_overlay_enabled": "Enable SSOwat panel overlay", "global_settings_setting_smtp_allow_ipv6": "Allow the use of IPv6 to receive and send mail", "global_settings_setting_smtp_relay_host": "SMTP relay host to use in order to send mail instead of this yunohost instance. Useful if you are in one of this situation: your 25 port is blocked by your ISP or VPS provider, you have a residential IP listed on DUHL, you are not able to configure reverse DNS or this server is not directly exposed on the internet and you want use an other one to send mails.", + "global_settings_setting_smtp_relay_password": "SMTP relay host password", "global_settings_setting_smtp_relay_port": "SMTP relay port", "global_settings_setting_smtp_relay_user": "SMTP relay user account", - "global_settings_setting_smtp_relay_password": "SMTP relay host password", - "global_settings_setting_security_webadmin_allowlist_enabled": "Allow only some IPs to access the webadmin.", - "global_settings_setting_security_webadmin_allowlist": "IP adresses allowed to access the webadmin. Comma-separated.", - "global_settings_setting_security_experimental_enabled": "Enable experimental security features (don't enable this if you don't know what you're doing!)", - "global_settings_setting_backup_compress_tar_archives": "When creating new backups, compress the archives (.tar.gz) instead of uncompressed archives (.tar). N.B. : enabling this option means create lighter backup archives, but the initial backup procedure will be significantly longer and heavy on CPU.", + "global_settings_setting_ssowat_panel_overlay_enabled": "Enable SSOwat panel overlay", + "global_settings_unknown_setting_from_settings_file": "Unknown key in settings: '{setting_key}', discard it and save it in /etc/yunohost/settings-unknown.json", "global_settings_unknown_type": "Unexpected situation, the setting {setting} appears to have the type {unknown_type} but it is not a type supported by the system.", "good_practices_about_admin_password": "You are now about to define a new administration password. The password should be at least 8 characters long—though it is good practice to use a longer password (i.e. a passphrase) and/or to use a variation of characters (uppercase, lowercase, digits and special characters).", "good_practices_about_user_password": "You are now about to define a new user password. The password should be at least 8 characters long—though it is good practice to use a longer password (i.e. a passphrase) and/or to a variation of characters (uppercase, lowercase, digits and special characters).", "group_already_exist": "Group {group} already exists", "group_already_exist_on_system": "Group {group} already exists in the system groups", "group_already_exist_on_system_but_removing_it": "Group {group} already exists in the system groups, but YunoHost will remove it...", + "group_cannot_be_deleted": "The group {group} cannot be deleted manually.", + "group_cannot_edit_all_users": "The group 'all_users' cannot be edited manually. It is a special group meant to contain all users registered in YunoHost", + "group_cannot_edit_primary_group": "The group '{group}' cannot be edited manually. It is the primary group meant to contain only one specific user.", + "group_cannot_edit_visitors": "The group 'visitors' cannot be edited manually. It is a special group representing anonymous visitors", "group_created": "Group '{group}' created", "group_creation_failed": "Could not create the group '{group}': {error}", - "group_cannot_edit_all_users": "The group 'all_users' cannot be edited manually. It is a special group meant to contain all users registered in YunoHost", - "group_cannot_edit_visitors": "The group 'visitors' cannot be edited manually. It is a special group representing anonymous visitors", - "group_cannot_edit_primary_group": "The group '{group}' cannot be edited manually. It is the primary group meant to contain only one specific user.", - "group_cannot_be_deleted": "The group {group} cannot be deleted manually.", "group_deleted": "Group '{group}' deleted", "group_deletion_failed": "Could not delete the group '{group}': {error}", "group_unknown": "The group '{group}' is unknown", - "group_updated": "Group '{group}' updated", "group_update_failed": "Could not update the group '{group}': {error}", + "group_updated": "Group '{group}' updated", "group_user_already_in_group": "User {user} is already in group {group}", "group_user_not_in_group": "User {user} is not in group {group}", "hook_exec_failed": "Could not run script: {path}", @@ -377,67 +377,90 @@ "hook_list_by_invalid": "This property can not be used to list hooks", "hook_name_unknown": "Unknown hook name '{name}'", "installation_complete": "Installation completed", + "invalid_number": "Must be a number", + "invalid_password": "Invalid password", "invalid_regex": "Invalid regex:'{regex}'", "ip6tables_unavailable": "You cannot play with ip6tables here. You are either in a container or your kernel does not support it", "iptables_unavailable": "You cannot play with iptables here. You are either in a container or your kernel does not support it", "ldap_server_down": "Unable to reach LDAP server", "ldap_server_is_down_restart_it": "The LDAP service is down, attempt to restart it...", - "log_corrupted_md_file": "The YAML metadata file associated with logs is damaged: '{md_file}\nError: {error}'", - "log_link_to_log": "Full log of this operation: '{desc}'", - "log_help_to_get_log": "To view the log of the operation '{desc}', use the command 'yunohost log show {name}{name}'", - "log_link_to_failed_log": "Could not complete the operation '{desc}'. Please provide the full log of this operation by clicking here to get help", - "log_help_to_get_failed_log": "The operation '{desc}' could not be completed. Please share the full log of this operation using the command 'yunohost log share {name}' to get help", - "log_does_exists": "There is no operation log with the name '{log}', use 'yunohost log list' to see all available operation logs", - "log_operation_unit_unclosed_properly": "Operation unit has not been closed properly", + "log_app_action_run": "Run action of the '{}' app", "log_app_change_url": "Change the URL of the '{}' app", + "log_app_config_apply": "Apply config to the '{}' app", + "log_app_config_show_panel": "Show the config panel of the '{}' app", "log_app_install": "Install the '{}' app", + "log_app_makedefault": "Make '{}' the default app", "log_app_remove": "Remove the '{}' app", "log_app_upgrade": "Upgrade the '{}' app", - "log_app_makedefault": "Make '{}' the default app", - "log_app_action_run": "Run action of the '{}' app", - "log_app_config_show_panel": "Show the config panel of the '{}' app", - "log_app_config_apply": "Apply config to the '{}' app", "log_available_on_yunopaste": "This log is now available via {url}", "log_backup_create": "Create a backup archive", - "log_backup_restore_system": "Restore system from a backup archive", "log_backup_restore_app": "Restore '{}' from a backup archive", - "log_remove_on_failed_restore": "Remove '{}' after a failed restore from a backup archive", - "log_remove_on_failed_install": "Remove '{}' after a failed installation", + "log_backup_restore_system": "Restore system from a backup archive", + "log_corrupted_md_file": "The YAML metadata file associated with logs is damaged: '{md_file}\nError: {error}'", + "log_does_exists": "There is no operation log with the name '{log}', use 'yunohost log list' to see all available operation logs", "log_domain_add": "Add '{}' domain into system configuration", + "log_domain_main_domain": "Make '{}' the main domain", "log_domain_remove": "Remove '{}' domain from system configuration", "log_dyndns_subscribe": "Subscribe to a YunoHost subdomain '{}'", "log_dyndns_update": "Update the IP associated with your YunoHost subdomain '{}'", + "log_help_to_get_failed_log": "The operation '{desc}' could not be completed. Please share the full log of this operation using the command 'yunohost log share {name}' to get help", + "log_help_to_get_log": "To view the log of the operation '{desc}', use the command 'yunohost log show {name}{name}'", "log_letsencrypt_cert_install": "Install a Let's Encrypt certificate on '{}' domain", + "log_letsencrypt_cert_renew": "Renew '{}' Let's Encrypt certificate", + "log_link_to_failed_log": "Could not complete the operation '{desc}'. Please provide the full log of this operation by clicking here to get help", + "log_link_to_log": "Full log of this operation: '{desc}'", + "log_operation_unit_unclosed_properly": "Operation unit has not been closed properly", "log_permission_create": "Create permission '{}'", "log_permission_delete": "Delete permission '{}'", "log_permission_url": "Update URL related to permission '{}'", - "log_selfsigned_cert_install": "Install self-signed certificate on '{}' domain", - "log_letsencrypt_cert_renew": "Renew '{}' Let's Encrypt certificate", "log_regen_conf": "Regenerate system configurations '{}'", + "log_remove_on_failed_install": "Remove '{}' after a failed installation", + "log_remove_on_failed_restore": "Remove '{}' after a failed restore from a backup archive", + "log_selfsigned_cert_install": "Install self-signed certificate on '{}' domain", + "log_tools_migrations_migrate_forward": "Run migrations", + "log_tools_postinstall": "Postinstall your YunoHost server", + "log_tools_reboot": "Reboot your server", + "log_tools_shutdown": "Shutdown your server", + "log_tools_upgrade": "Upgrade system packages", "log_user_create": "Add '{}' user", "log_user_delete": "Delete '{}' user", - "log_user_import": "Import users", "log_user_group_create": "Create '{}' group", "log_user_group_delete": "Delete '{}' group", "log_user_group_update": "Update '{}' group", - "log_user_update": "Update info for user '{}'", - "log_user_permission_update": "Update accesses for permission '{}'", + "log_user_import": "Import users", "log_user_permission_reset": "Reset permission '{}'", - "log_domain_main_domain": "Make '{}' the main domain", - "log_tools_migrations_migrate_forward": "Run migrations", - "log_tools_postinstall": "Postinstall your YunoHost server", - "log_tools_upgrade": "Upgrade system packages", - "log_tools_shutdown": "Shutdown your server", - "log_tools_reboot": "Reboot your server", + "log_user_permission_update": "Update accesses for permission '{}'", + "log_user_update": "Update info for user '{}'", "mail_alias_remove_failed": "Could not remove e-mail alias '{mail}'", "mail_domain_unknown": "Invalid e-mail address for domain '{domain}'. Please, use a domain administrated by this server.", "mail_forward_remove_failed": "Could not remove e-mail forwarding '{mail}'", + "mail_unavailable": "This e-mail address is reserved and shall be automatically allocated to the very first user", "mailbox_disabled": "E-mail turned off for user {user}", "mailbox_used_space_dovecot_down": "The Dovecot mailbox service needs to be up if you want to fetch used mailbox space", - "mail_unavailable": "This e-mail address is reserved and shall be automatically allocated to the very first user", "main_domain_change_failed": "Unable to change the main domain", "main_domain_changed": "The main domain has been changed", "migrating_legacy_permission_settings": "Migrating legacy permission settings...", + "migration_0015_cleaning_up": "Cleaning up cache and packages not useful anymore...", + "migration_0015_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade.", + "migration_0015_main_upgrade": "Starting main upgrade...", + "migration_0015_modified_files": "Please note that the following files were found to be manually modified and might be overwritten following the upgrade: {manually_modified_files}", + "migration_0015_not_enough_free_space": "Free space is pretty low in /var/! You should have at least 1GB free to run this migration.", + "migration_0015_not_stretch": "The current Debian distribution is not Stretch!", + "migration_0015_patching_sources_list": "Patching the sources.lists...", + "migration_0015_problematic_apps_warning": "Please note that the following possibly problematic installed apps were detected. It looks like those were not installed from the YunoHost app catalog, or are not flagged as 'working'. Consequently, it cannot be guaranteed that they will still work after the upgrade: {problematic_apps}", + "migration_0015_specific_upgrade": "Starting upgrade of system packages that needs to be upgrade independently...", + "migration_0015_start": "Starting migration to Buster", + "migration_0015_still_on_stretch_after_main_upgrade": "Something went wrong during the main upgrade, the system appears to still be on Debian Stretch", + "migration_0015_system_not_fully_up_to_date": "Your system is not fully up-to-date. Please perform a regular upgrade before running the migration to Buster.", + "migration_0015_weak_certs": "The following certificates were found to still use weak signature algorithms and have to be upgraded to be compatible with the next version of nginx: {certs}", + "migration_0015_yunohost_upgrade": "Starting YunoHost core upgrade...", + "migration_0017_not_enough_space": "Make sufficient space available in {path} to run the migration.", + "migration_0017_postgresql_11_not_installed": "PostgreSQL 9.6 is installed, but not postgresql 11‽ Something weird might have happened on your system :(...", + "migration_0017_postgresql_96_not_installed": "PostgreSQL was not installed on your system. Nothing to do.", + "migration_0018_failed_to_migrate_iptables_rules": "Failed to migrate legacy iptables rules to nftables: {error}", + "migration_0018_failed_to_reset_legacy_rules": "Failed to reset legacy iptables rules: {error}", + "migration_0019_add_new_attributes_in_ldap": "Add new attributes for permissions in LDAP database", + "migration_0019_slapd_config_will_be_overwritten": "It looks like you manually edited the slapd configuration. For this critical migration, YunoHost needs to force the update of the slapd configuration. The original files will be backuped in {conf_backup_folder}.", "migration_description_0015_migrate_to_buster": "Upgrade the system to Debian Buster and YunoHost 4.x", "migration_description_0016_php70_to_php73_pools": "Migrate php7.0-fpm 'pool' conf files to php7.3", "migration_description_0017_postgresql_9p6_to_11": "Migrate databases from PostgreSQL 9.6 to 11", @@ -449,32 +472,11 @@ "migration_ldap_migration_failed_trying_to_rollback": "Could not migrate... trying to roll back the system.", "migration_ldap_rollback_success": "System rolled back.", "migration_update_LDAP_schema": "Updating LDAP schema...", - "migration_0015_start" : "Starting migration to Buster", - "migration_0015_patching_sources_list": "Patching the sources.lists...", - "migration_0015_main_upgrade": "Starting main upgrade...", - "migration_0015_still_on_stretch_after_main_upgrade": "Something went wrong during the main upgrade, the system appears to still be on Debian Stretch", - "migration_0015_yunohost_upgrade" : "Starting YunoHost core upgrade...", - "migration_0015_not_stretch" : "The current Debian distribution is not Stretch!", - "migration_0015_not_enough_free_space" : "Free space is pretty low in /var/! You should have at least 1GB free to run this migration.", - "migration_0015_system_not_fully_up_to_date": "Your system is not fully up-to-date. Please perform a regular upgrade before running the migration to Buster.", - "migration_0015_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade.", - "migration_0015_problematic_apps_warning": "Please note that the following possibly problematic installed apps were detected. It looks like those were not installed from the YunoHost app catalog, or are not flagged as 'working'. Consequently, it cannot be guaranteed that they will still work after the upgrade: {problematic_apps}", - "migration_0015_modified_files": "Please note that the following files were found to be manually modified and might be overwritten following the upgrade: {manually_modified_files}", - "migration_0015_specific_upgrade": "Starting upgrade of system packages that needs to be upgrade independently...", - "migration_0015_cleaning_up": "Cleaning up cache and packages not useful anymore...", - "migration_0015_weak_certs": "The following certificates were found to still use weak signature algorithms and have to be upgraded to be compatible with the next version of nginx: {certs}", - "migration_0017_postgresql_96_not_installed": "PostgreSQL was not installed on your system. Nothing to do.", - "migration_0017_postgresql_11_not_installed": "PostgreSQL 9.6 is installed, but not postgresql 11‽ Something weird might have happened on your system :(...", - "migration_0017_not_enough_space": "Make sufficient space available in {path} to run the migration.", - "migration_0018_failed_to_migrate_iptables_rules": "Failed to migrate legacy iptables rules to nftables: {error}", - "migration_0018_failed_to_reset_legacy_rules": "Failed to reset legacy iptables rules: {error}", - "migration_0019_add_new_attributes_in_ldap": "Add new attributes for permissions in LDAP database", - "migration_0019_slapd_config_will_be_overwritten": "It looks like you manually edited the slapd configuration. For this critical migration, YunoHost needs to force the update of the slapd configuration. The original files will be backuped in {conf_backup_folder}.", "migrations_already_ran": "Those migrations are already done: {ids}", "migrations_cant_reach_migration_file": "Could not access migrations files at the path '%s'", "migrations_dependencies_not_satisfied": "Run these migrations: '{dependencies_id}', before migration {id}.", - "migrations_failed_to_load_migration": "Could not load migration {id}: {error}", "migrations_exclusive_options": "'--auto', '--skip', and '--force-rerun' are mutually exclusive options.", + "migrations_failed_to_load_migration": "Could not load migration {id}: {error}", "migrations_list_conflict_pending_done": "You cannot use both '--previous' and '--done' at the same time.", "migrations_loading_migration": "Loading migration {id}...", "migrations_migration_has_failed": "Migration {id} did not complete, aborting. Error: {exception}", @@ -487,10 +489,8 @@ "migrations_running_forward": "Running migration {id}...", "migrations_skip_migration": "Skipping migration {id}...", "migrations_success_forward": "Migration {id} completed", - "migrations_to_be_ran_manually": "Migration {id} has to be run manually. Please go to Tools → Migrations on the webadmin page, or run `yunohost tools migrations run`.", + "migrations_to_be_ran_manually": "Migration {id} has to be run manually. Please go to Tools → Migrations on the webadmin page, or run `yunohost tools migrations run`.", "not_enough_disk_space": "Not enough free space on '{path}'", - "invalid_number": "Must be a number", - "invalid_password": "Invalid password", "operation_interrupted": "The operation was manually interrupted?", "packages_upgrade_failed": "Could not upgrade all the packages", "password_listed": "This password is among the most used passwords in the world. Please choose something more unique.", @@ -500,35 +500,37 @@ "password_too_simple_4": "The password needs to be at least 12 characters long and contain a digit, upper, lower and special characters", "pattern_backup_archive_name": "Must be a valid filename with max 30 characters, alphanumeric and -_. characters only", "pattern_domain": "Must be a valid domain name (e.g. my-domain.org)", - "pattern_email_forward": "Must be a valid e-mail address, '+' symbol accepted (e.g. someone+tag@example.com)", "pattern_email": "Must be a valid e-mail address, without '+' symbol (e.g. someone@example.com)", + "pattern_email_forward": "Must be a valid e-mail address, '+' symbol accepted (e.g. someone+tag@example.com)", "pattern_firstname": "Must be a valid first name", "pattern_lastname": "Must be a valid last name", "pattern_mailbox_quota": "Must be a size with b/k/M/G/T suffix or 0 to not have a quota", "pattern_password": "Must be at least 3 characters long", + "pattern_password_app": "Sorry, passwords can not contain the following characters: {forbidden_chars}", "pattern_port_or_range": "Must be a valid port number (i.e. 0-65535) or range of ports (e.g. 100:200)", "pattern_positive_number": "Must be a positive number", "pattern_username": "Must be lower-case alphanumeric and underscore characters only", - "pattern_password_app": "Sorry, passwords can not contain the following characters: {forbidden_chars}", "permission_already_allowed": "Group '{group}' already has permission '{permission}' enabled", "permission_already_disallowed": "Group '{group}' already has permission '{permission}' disabled", "permission_already_exist": "Permission '{permission}' already exists", "permission_already_up_to_date": "The permission was not updated because the addition/removal requests already match the current state.", "permission_cannot_remove_main": "Removing a main permission is not allowed", + "permission_cant_add_to_all_users": "The permission {permission} can not be added to all users.", "permission_created": "Permission '{permission}' created", "permission_creation_failed": "Could not create permission '{permission}': {error}", "permission_currently_allowed_for_all_users": "This permission is currently granted to all users in addition to other groups. You probably want to either remove the 'all_users' permission or remove the other groups it is currently granted to.", - "permission_cant_add_to_all_users": "The permission {permission} can not be added to all users.", "permission_deleted": "Permission '{permission}' deleted", "permission_deletion_failed": "Could not delete permission '{permission}': {error}", "permission_not_found": "Permission '{permission}' not found", - "permission_update_failed": "Could not update permission '{permission}': {error}", - "permission_updated": "Permission '{permission}' updated", "permission_protected": "Permission {permission} is protected. You cannot add or remove the visitors group to/from this permission.", "permission_require_account": "Permission {permission} only makes sense for users having an account, and therefore cannot be enabled for visitors.", + "permission_update_failed": "Could not update permission '{permission}': {error}", + "permission_updated": "Permission '{permission}' updated", "port_already_closed": "Port {port} is already closed for {ip_version} connections", "port_already_opened": "Port {port} is already opened for {ip_version} connections", "postinstall_low_rootfsspace": "The root filesystem has a total space less than 10 GB, which is quite worrisome! You will likely run out of disk space very quickly! It's recommended to have at least 16GB for the root filesystem. If you want to install YunoHost despite this warning, re-run the postinstall with --force-diskspace", + "regenconf_dry_pending_applying": "Checking pending configuration which would have been applied for category '{category}'...", + "regenconf_failed": "Could not regenerate the configuration for category(s): {categories}", "regenconf_file_backed_up": "Configuration file '{conf}' backed up to '{backup}'", "regenconf_file_copy_failed": "Could not copy the new configuration file '{new}' to '{conf}'", "regenconf_file_kept_back": "The configuration file '{conf}' is expected to be deleted by regen-conf (category {category}) but was kept back.", @@ -537,14 +539,12 @@ "regenconf_file_remove_failed": "Could not remove the configuration file '{conf}'", "regenconf_file_removed": "Configuration file '{conf}' removed", "regenconf_file_updated": "Configuration file '{conf}' updated", + "regenconf_need_to_explicitly_specify_ssh": "The ssh configuration has been manually modified, but you need to explicitly specify category 'ssh' with --force to actually apply the changes.", "regenconf_now_managed_by_yunohost": "The configuration file '{conf}' is now managed by YunoHost (category {category}).", + "regenconf_pending_applying": "Applying pending configuration for category '{category}'...", "regenconf_up_to_date": "The configuration is already up-to-date for category '{category}'", "regenconf_updated": "Configuration updated for '{category}'", "regenconf_would_be_updated": "The configuration would have been updated for category '{category}'", - "regenconf_dry_pending_applying": "Checking pending configuration which would have been applied for category '{category}'...", - "regenconf_failed": "Could not regenerate the configuration for category(s): {categories}", - "regenconf_pending_applying": "Applying pending configuration for category '{category}'...", - "regenconf_need_to_explicitly_specify_ssh": "The ssh configuration has been manually modified, but you need to explicitly specify category 'ssh' with --force to actually apply the changes.", "regex_incompatible_with_tile": "/!\\ Packagers! Permission '{permission}' has show_tile set to 'true' and you therefore cannot define a regex URL as the main URL", "regex_with_only_domain": "You can't use a regex for domain, only for path", "restore_already_installed_app": "An app with the ID '{app}' is already installed", @@ -565,16 +565,15 @@ "restore_system_part_failed": "Could not restore the '{part}' system part", "root_password_desynchronized": "The admin password was changed, but YunoHost could not propagate this to the root password!", "root_password_replaced_by_admin_password": "Your root password have been replaced by your admin password.", - "server_shutdown": "The server will shut down", - "server_shutdown_confirm": "The server will shutdown immediatly, are you sure? [{answers}]", "server_reboot": "The server will reboot", "server_reboot_confirm": "The server will reboot immediatly, are you sure? [{answers}]", + "server_shutdown": "The server will shut down", + "server_shutdown_confirm": "The server will shutdown immediatly, are you sure? [{answers}]", "service_add_failed": "Could not add the service '{service}'", "service_added": "The service '{service}' was added", "service_already_started": "The service '{service}' is running already", "service_already_stopped": "The service '{service}' has already been stopped", "service_cmd_exec_failed": "Could not execute the command '{command}'", - "service_description_yunomdns": "Allows you to reach your server using 'yunohost.local' in your local network", "service_description_dnsmasq": "Handles domain name resolution (DNS)", "service_description_dovecot": "Allows e-mail clients to access/fetch email (via IMAP and POP3)", "service_description_fail2ban": "Protects against brute-force and other kinds of attacks from the Internet", @@ -589,26 +588,27 @@ "service_description_ssh": "Allows you to connect remotely to your server via a terminal (SSH protocol)", "service_description_yunohost-api": "Manages interactions between the YunoHost web interface and the system", "service_description_yunohost-firewall": "Manages open and close connection ports to services", + "service_description_yunomdns": "Allows you to reach your server using 'yunohost.local' in your local network", "service_disable_failed": "Could not make the service '{service}' not start at boot.\n\nRecent service logs:{logs}", "service_disabled": "The service '{service}' will not be started anymore when system boots.", "service_enable_failed": "Could not make the service '{service}' automatically start at boot.\n\nRecent service logs:{logs}", "service_enabled": "The service '{service}' will now be automatically started during system boots.", "service_regen_conf_is_deprecated": "'yunohost service regen-conf' is deprecated! Please use 'yunohost tools regen-conf' instead.", + "service_reload_failed": "Could not reload the service '{service}'\n\nRecent service logs:{logs}", + "service_reload_or_restart_failed": "Could not reload or restart the service '{service}'\n\nRecent service logs:{logs}", + "service_reloaded": "Service '{service}' reloaded", + "service_reloaded_or_restarted": "The service '{service}' was reloaded or restarted", "service_remove_failed": "Could not remove the service '{service}'", "service_removed": "Service '{service}' removed", - "service_reload_failed": "Could not reload the service '{service}'\n\nRecent service logs:{logs}", - "service_reloaded": "Service '{service}' reloaded", "service_restart_failed": "Could not restart the service '{service}'\n\nRecent service logs:{logs}", "service_restarted": "Service '{service}' restarted", - "service_reload_or_restart_failed": "Could not reload or restart the service '{service}'\n\nRecent service logs:{logs}", - "service_reloaded_or_restarted": "The service '{service}' was reloaded or restarted", "service_start_failed": "Could not start the service '{service}'\n\nRecent service logs:{logs}", "service_started": "Service '{service}' started", "service_stop_failed": "Unable to stop the service '{service}'\n\nRecent service logs:{logs}", "service_stopped": "Service '{service}' stopped", "service_unknown": "Unknown service '{service}'", - "show_tile_cant_be_enabled_for_url_not_defined": "You cannot enable 'show_tile' right now, because you must first define an URL for the permission '{permission}'", "show_tile_cant_be_enabled_for_regex": "You cannot enable 'show_tile' right no, because the URL for the permission '{permission}' is a regex", + "show_tile_cant_be_enabled_for_url_not_defined": "You cannot enable 'show_tile' right now, because you must first define an URL for the permission '{permission}'", "ssowat_conf_generated": "SSOwat configuration regenerated", "ssowat_conf_updated": "SSOwat configuration updated", "system_upgraded": "System upgraded", @@ -621,8 +621,8 @@ "tools_upgrade_regular_packages": "Now upgrading 'regular' (non-yunohost-related) packages...", "tools_upgrade_regular_packages_failed": "Could not upgrade packages: {packages_list}", "tools_upgrade_special_packages": "Now upgrading 'special' (yunohost-related) packages...", - "tools_upgrade_special_packages_explanation": "The special upgrade will continue in the background. Please don't start any other actions on your server for the next ~10 minutes (depending on hardware speed). After this, you may have to re-log in to the webadmin. The upgrade log will be available in Tools → Log (in the webadmin) or using 'yunohost log list' (from the command-line).", "tools_upgrade_special_packages_completed": "YunoHost package upgrade completed.\nPress [Enter] to get the command line back", + "tools_upgrade_special_packages_explanation": "The special upgrade will continue in the background. Please don't start any other actions on your server for the next ~10 minutes (depending on hardware speed). After this, you may have to re-log in to the webadmin. The upgrade log will be available in Tools → Log (in the webadmin) or using 'yunohost log list' (from the command-line).", "unbackup_app": "{app} will not be saved", "unexpected_error": "Something unexpected went wrong: {error}", "unknown_main_domain_path": "Unknown domain or path for '{app}'. You need to specify a domain and a path to be able to specify a URL for permission.", @@ -643,19 +643,19 @@ "user_deleted": "User deleted", "user_deletion_failed": "Could not delete user {user}: {error}", "user_home_creation_failed": "Could not create home folder '{home}' for user", + "user_import_bad_file": "Your CSV file is not correctly formatted it will be ignored to avoid potential data loss", + "user_import_bad_line": "Incorrect line {line}: {details}", + "user_import_failed": "The users import operation completely failed", + "user_import_missing_columns": "The following columns are missing: {columns}", + "user_import_nothing_to_do": "No user needs to be imported", + "user_import_partial_failed": "The users import operation partially failed", + "user_import_success": "Users successfully imported", "user_unknown": "Unknown user: {user}", "user_update_failed": "Could not update user {user}: {error}", "user_updated": "User info changed", - "user_import_bad_line": "Incorrect line {line}: {details}", - "user_import_bad_file": "Your CSV file is not correctly formatted it will be ignored to avoid potential data loss", - "user_import_missing_columns": "The following columns are missing: {columns}", - "user_import_partial_failed": "The users import operation partially failed", - "user_import_failed": "The users import operation completely failed", - "user_import_nothing_to_do": "No user needs to be imported", - "user_import_success": "Users successfully imported", "yunohost_already_installed": "YunoHost is already installed", "yunohost_configured": "YunoHost is now configured", "yunohost_installing": "Installing YunoHost...", "yunohost_not_installed": "YunoHost is not correctly installed. Please run 'yunohost tools postinstall'", "yunohost_postinstall_end_tip": "The post-install completed! To finalize your setup, please consider:\n - adding a first user through the 'Users' section of the webadmin (or 'yunohost user create ' in command-line);\n - diagnose potential issues through the 'Diagnosis' section of the webadmin (or 'yunohost diagnosis run' in command-line);\n - reading the 'Finalizing your setup' and 'Getting to know YunoHost' parts in the admin documentation: https://yunohost.org/admindoc." -} +} \ No newline at end of file From 377771cc1170d8e3797fce5a9f1dade178142cb9 Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 3 Sep 2021 13:25:00 +0000 Subject: [PATCH 087/101] Translated using Weblate (Ukrainian) Currently translated at 34.2% (226 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 82 ++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index 47c5991b0..52a5b0a70 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -357,22 +357,22 @@ "diagnosis_http_nginx_conf_not_up_to_date": "Схоже, що конфігурація nginx цього домену була змінена вручну, що не дозволяє YunoHost визначити, чи доступний він по HTTP.", "diagnosis_http_partially_unreachable": "Домен {domain} здається недоступним по HTTP ззовні локальної мережі в IPv {failed}, хоча він працює в IPv {passed}.", "diagnosis_http_unreachable": "Домен {domain} здається недоступним через HTTP ззовні локальної мережі.", - "diagnosis_http_bad_status_code": "Схоже, що замість вашого сервера відповіла інша машина (можливо, ваш маршрутизатор).
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", + "diagnosis_http_bad_status_code": "Схоже, що замість вашого сервера відповіла інша машина (можливо, ваш маршрутизатор).
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", "diagnosis_http_connection_error": "Помилка підключення: не вдалося підключитися до запитуваного домену, швидше за все, він недоступний.", - "diagnosis_http_timeout": "При спробі зв'язатися з вашим сервером ззовні стався тайм-аут. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. Ви також повинні переконатися, що служба nginx запущена
3. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", + "diagnosis_http_timeout": "При спробі зв'язатися з вашим сервером ззовні стався тайм-аут. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. Ви також повинні переконатися, що служба nginx запущена
3. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", "diagnosis_http_ok": "Домен {domain} доступний по HTTP ззовні локальної мережі.", "diagnosis_http_localdomain": "Домен {domain} з доменом .local TLD не може бути доступний ззовні локальної мережі.", "diagnosis_http_could_not_diagnose_details": "Помилка: {error}", - "diagnosis_http_could_not_diagnose": "Не вдалося діагностувати досяжність доменів ззовні в IPv {ipversion}.", - "diagnosis_http_hairpinning_issue_details": "Можливо, це пов'язано з блоком/маршрутизатором вашого інтернет-провайдера. В результаті, люди ззовні вашої локальної мережі зможуть отримати доступ до вашого сервера, як і очікувалося, але не люди зсередини локальної мережі (як ви, ймовірно?) При використанні доменного імені або глобального IP. Можливо, ви зможете поліпшити ситуацію, глянувши на https://yunohost.org/dns_local_network .", + "diagnosis_http_could_not_diagnose": "Не вдалося діагностувати досяжність доменів ззовні в IPv{ipversion}.", + "diagnosis_http_hairpinning_issue_details": "Можливо, це пов'язано з блоком/маршрутизатором вашого інтернет-провайдера. В результаті, люди ззовні вашої локальної мережі зможуть отримати доступ до вашого сервера, як і очікувалося, але не люди зсередини локальної мережі (як ви, ймовірно?) При використанні доменного імені або глобального IP. Можливо, ви зможете поліпшити ситуацію, глянувши на https://yunohost.org/dns_local_network .", "diagnosis_http_hairpinning_issue": "Схоже, що у вашій локальній мережі не включена проброска.", - "diagnosis_ports_forwarding_tip": "Щоб вирішити цю проблему, вам, швидше за все, потрібно налаштувати кидок портів на вашому інтернет-маршрутизатор, як описано в https://yunohost.org/isp_box_config.", + "diagnosis_ports_forwarding_tip": "Щоб вирішити цю проблему, вам, швидше за все, потрібно налаштувати кидок портів на вашому інтернет-маршрутизатор, як описано в https://yunohost.org/isp_box_config.", "diagnosis_ports_needed_by": "Відкриття цього порту необхідно для функцій {category} (служба {service}).", "diagnosis_ports_ok": "Порт {port} доступний ззовні.", "diagnosis_ports_partially_unreachable": "Порт {port} не доступний ззовні в IPv {failed}.", "diagnosis_ports_unreachable": "Порт {port} недоступний ззовні.", "diagnosis_ports_could_not_diagnose_details": "Помилка: {error}", - "diagnosis_ports_could_not_diagnose": "Не вдалося діагностувати досяжність портів ззовні в IPv {ipversion}.", + "diagnosis_ports_could_not_diagnose": "Не вдалося діагностувати досяжність портів ззовні в IPv{ipversion}.", "diagnosis_description_regenconf": "Конфігурації системи", "diagnosis_description_mail": "Електронна пошта", "diagnosis_description_ports": "виявлення портів", @@ -386,7 +386,7 @@ "diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {space}, що вельми тривожно! Швидше за все, дисковий простір закінчиться дуже швидко! Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", "diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {space}. Це може бути нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", "diagnosis_regenconf_manually_modified_details": "Це можливо нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що поновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою yunohost tools regen- conf {category} --force .", - "diagnosis_regenconf_manually_modified": "Конфігураційний файл {file} , схоже, був змінений вручну.", + "diagnosis_regenconf_manually_modified": "Конфігураційний файл {file}, схоже, був змінений вручну.", "diagnosis_regenconf_allgood": "Всі конфігураційні файли відповідають рекомендованої конфігурації!", "diagnosis_mail_queue_too_big": "Занадто багато відкладених листів в поштовій черзі ({nb_pending} emails)", "diagnosis_mail_queue_unavailable_details": "Помилка: {error}", @@ -394,27 +394,27 @@ "diagnosis_mail_queue_ok": "{nb_pending} відкладені листи в поштових чергах", "diagnosis_mail_blacklist_website": "Після визначення причини, по якій ви потрапили в чорний список, і її усунення, ви можете попросити видалити ваш IP або домен на {blacklist_website}.", "diagnosis_mail_blacklist_reason": "Причина внесення в чорний список: {reason}", - "diagnosis_mail_blacklist_listed_by": "Ваш IP або домен {item} знаходиться в чорному списку {blacklist_name}.", + "diagnosis_mail_blacklist_listed_by": "Ваш IP або домен {item} знаходиться в чорному списку {blacklist_name}.", "diagnosis_mail_blacklist_ok": "IP-адреси і домени, які використовуються цим сервером, не внесені в чорний список", - "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Поточний зворотний DNS: {rdns_domain}
Очікуване значення: {ehlo_domain} .", - "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Зворотний DNS неправильно налаштований в IPv {ipversion}. Деякі електронні листи можуть бути не доставлені або можуть бути відзначені як спам.", + "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Поточний зворотний DNS: {rdns_domain}
Очікуване значення: {ehlo_domain}.", + "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Зворотний DNS неправильно налаштований в IPv{ipversion}. Деякі електронні листи можуть бути не доставлені або можуть бути відзначені як спам.", "diagnosis_mail_fcrdns_nok_alternatives_6": "Деякі провайдери не дозволяють вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ваш зворотний DNS правильно налаштований для IPv4, ви можете спробувати відключити використання IPv6 при відправці листів, виконавши команду yunohost settings set smtp.allow_ipv6 -v off . Примітка: останнє рішення означає, що ви не зможете відправляти або отримувати електронну пошту з нечисленних серверів, що використовують тільки IPv6.", - "diagnosis_mail_fcrdns_nok_alternatives_4": "Деякі провайдери не дозволять вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ви відчуваєте проблеми з-за цього, розгляньте наступні рішення:
- Деякі провайдери надають альтернативу
використання ретранслятора поштового сервера , хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN * з виділеним публічним IP * для обходу подібних обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Або можна переключитися на іншого провайдера .", - "diagnosis_mail_fcrdns_nok_details": "Спочатку спробуйте налаштувати зворотний DNS з {ehlo_domain} в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм тікет підтримки для цього).", - "diagnosis_mail_fcrdns_dns_missing": "У IPv {ipversion} не визначений зворотний DNS. Деякі листи можуть не доставлятися або позначатися як спам.", + "diagnosis_mail_fcrdns_nok_alternatives_4": "Деякі провайдери не дозволять вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ви відчуваєте проблеми через це, розгляньте наступні рішення:
- Деякі провайдери надають альтернативу використання ретранслятора поштового сервера, хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN *з виділеним загальнодоступним IP* для обходу подібних обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Або можна переключитися на іншого провайдера .", + "diagnosis_mail_fcrdns_nok_details": "Спочатку спробуйте налаштувати зворотний DNS з {ehlo_domain} в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм тікет підтримки для цього).", + "diagnosis_mail_fcrdns_dns_missing": "У IPv{ipversion} не визначений зворотний DNS. Деякі листи можуть не доставлятися або позначатися як спам.", "diagnosis_mail_fcrdns_ok": "Ваш зворотний DNS налаштований правильно!", "diagnosis_mail_ehlo_could_not_diagnose_details": "Помилка: {error}", - "diagnosis_mail_ehlo_could_not_diagnose": "Не вдалося діагностувати наявність певної поштовий сервер postfix ззовні в IPv {ipversion}.", - "diagnosis_mail_ehlo_wrong_details": "EHLO, отриманий віддаленим діагностичним центром в IPv {ipversion}, відрізняється від домену вашого сервера.
Отриманий EHLO: {wrong_ehlo}
Очікуваний: {right_ehlo} < br> найпоширенішою причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер . Крім того, переконайтеся, що в роботу сервера не втручається брандмауер або зворотний проксі-сервер.", - "diagnosis_mail_ehlo_wrong": "Інший поштовий SMTP-сервер відповідає на IPv {ipversion}. Ваш сервер, ймовірно, не зможе отримувати електронну пошту.", + "diagnosis_mail_ehlo_could_not_diagnose": "Не вдалося діагностувати наявність певної поштовий сервер postfix ззовні в IPv{ipversion}.", + "diagnosis_mail_ehlo_wrong_details": "EHLO, отриманий віддаленим діагностичним центром в IPv{ipversion}, відрізняється від домену вашого сервера.
Отриманий EHLO: {wrong_ehlo}
Очікуваний: {right_ehlo} < br> найпоширенішою причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер . Крім того, переконайтеся, що в роботу сервера не втручається брандмауер або зворотний проксі-сервер.", + "diagnosis_mail_ehlo_wrong": "Інший поштовий SMTP-сервер відповідає на IPv{ipversion}. Ваш сервер, ймовірно, не зможе отримувати електронну пошту.", "diagnosis_mail_ehlo_bad_answer_details": "Це може бути викликано тим, що замість вашого сервера відповідає інша машина.", - "diagnosis_mail_ehlo_bad_answer": "Ні-SMTP служба відповідає на порту 25 на IPv {ipversion}.", - "diagnosis_mail_ehlo_unreachable_details": "Не вдалося відкрити з'єднання по порту 25 з вашим сервером на IPv {ipversion}. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер .
2. Ви також повинні переконатися, що служба postfix запущена.
3. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", - "diagnosis_mail_ehlo_unreachable": "Поштовий сервер SMTP недоступний ззовні по IPv {ipversion}. Він не зможе отримувати повідомлення електронної пошти.", - "diagnosis_mail_ehlo_ok": "Поштовий сервер SMTP доступний ззовні і тому може отримувати електронну пошту!", - "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Деякі провайдери не дозволять вам розблокувати вихідний порт 25, тому що вони не піклуються про Net Neutrality.
- Деякі з них пропонують альтернативу використання ретранслятора поштового сервера , хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN * з виділеним публічним IP * для обходу такого роду обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Ви також можете розглянути можливість переходу на более дружнього до мережевого нейтралітету провайдера .", + "diagnosis_mail_ehlo_bad_answer": "Ні-SMTP служба відповідає на порту 25 на IPv{ipversion}.", + "diagnosis_mail_ehlo_unreachable_details": "Не вдалося відкрити з'єднання по порту 25 з вашим сервером на IPv{ipversion}. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер .
2. Ви також повинні переконатися, що служба postfix запущена.
3. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", + "diagnosis_mail_ehlo_unreachable": "Поштовий сервер SMTP недоступний ззовні по IPv{ipversion}. Він не зможе отримувати листи електронної пошти.", + "diagnosis_mail_ehlo_ok": "Поштовий сервер SMTP доступний ззовні і тому може отримувати електронні листи!", + "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Деякі провайдери не дозволять вам розблокувати вихідний порт 25, тому що вони не піклуються про мережевий нейтралітет (Net Neutrality).
- Деякі з них пропонують альтернативу використання ретранслятора поштового сервера, хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN *з виділеним загальнодоступним IP* для обходу такого роду обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Ви також можете розглянути можливість переходу на більш дружнього до мережевого нейтралітету провайдера.", "diagnosis_mail_outgoing_port_25_blocked_details": "Спочатку спробуйте розблокувати вихідний порт 25 в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм заявку в службу підтримки).", - "diagnosis_mail_outgoing_port_25_blocked": "Поштовий сервер SMTP не може відправляти електронні листи на інші сервери, оскільки вихідний порт 25 заблокований в IPv {ipversion}.", + "diagnosis_mail_outgoing_port_25_blocked": "Поштовий сервер SMTP не може відправляти електронні листи на інші сервери, оскільки вихідний порт 25 заблоковано в IPv{ipversion}.", "app_manifest_install_ask_path": "Оберіть шлях URL (після домену), за яким має бути встановлено цей застосунок", "yunohost_postinstall_end_tip": "Постінсталляція завершена! Щоб завершити установку, будь ласка, розгляньте наступні варіанти: - додавання першого користувача через розділ 'Користувачі' веб-адміністратора (або 'yunohost user create ' в командному рядку); - діагностику можливих проблем через розділ 'Діагностика' веб-адміністратора (або 'yunohost diagnosis run' в командному рядку); - читання розділів 'Завершення установки' і 'Знайомство з YunoHost' в документації адміністратора: https://yunohost.org/admindoc.", "yunohost_not_installed": "YunoHost встановлений неправильно. Будь ласка, запустіть 'yunohost tools postinstall'.", @@ -465,26 +465,26 @@ "service_stop_failed": "Неможливо зупинити службу '{service}' Недавні журнали служб: {logs}", "service_started": "Служба '{service}' запущена", "service_start_failed": "Не вдалося запустити службу '{service}' Recent service logs: {logs}", - "diagnosis_mail_outgoing_port_25_ok": "Поштовий сервер SMTP може відправляти електронні листи (вихідний порт 25 не заблокований).", - "diagnosis_swap_tip": "Будь ласка, будьте обережні і знайте, що якщо сервер розміщує своп на SD-карті або SSD-накопичувачі, це може різко скоротити термін служби устройства`.", - "diagnosis_swap_ok": "Система має {total} свопу!", - "diagnosis_swap_notsomuch": "Система має тільки {total} свопу. Щоб уникнути ситуацій, коли в системі закінчується пам'ять, слід передбачити наявність не менше {recommended} обсягу підкачки.", - "diagnosis_swap_none": "В системі повністю відсутній своп. Ви повинні розглянути можливість додавання принаймні {recommended} обсягу підкачки, щоб уникнути ситуацій, коли системі не вистачає пам'яті.", + "diagnosis_mail_outgoing_port_25_ok": "Поштовий сервер SMTP може відправляти електронні листи (вихідний порт 25 не заблоковано).", + "diagnosis_swap_tip": "Будь ласка, будьте обережні і знайте, що якщо сервер розміщує обсяг підкачки на SD-карті або SSD-накопичувачі, це може різко скоротити строк служби пристрою`.", + "diagnosis_swap_ok": "Система має {total} обсягу підкачки!", + "diagnosis_swap_notsomuch": "Система має тільки {total} обсягу підкачки. Щоб уникнути станоаищ, коли в системі закінчується пам'ять, слід передбачити наявність не менше {recommended} обсягу підкачки.", + "diagnosis_swap_none": "В системі повністю відсутня підкачка. Ви повинні розглянути можливість додавання принаймні {recommended} обсягу підкачки, щоб уникнути ситуацій, коли системі не вистачає пам'яті.", "diagnosis_ram_ok": "Система все ще має {available} ({available_percent}%) оперативної пам'яті з {total}.", - "diagnosis_ram_low": "У системі є {available} ({available_percent}%) оперативної пам'яті (з {total}). Будьте уважні.", - "diagnosis_ram_verylow": "Система має тільки {available} ({available_percent}%) оперативної пам'яті! (З {total})", - "diagnosis_diskusage_ok": "У сховищі {mountpoint} (на пристрої {device} ) залишилося {free} ({free_percent}%) вільного місця (з {total})!", - "diagnosis_diskusage_low": "Сховище {mountpoint} (на пристрої {device} ) має тільки {free} ({free_percent}%) вільного місця (з {total}). Будьте уважні.", - "diagnosis_diskusage_verylow": "Сховище {mountpoint} (на пристрої {device} ) має тільки {free} ({free_percent}%) вільного місця (з {total}). Вам дійсно варто подумати про очищення простору!", - "diagnosis_services_bad_status_tip": "Ви можете спробувати перезапустити службу , а якщо це не допоможе, подивіться журнали служби в webadmin (з командного рядка це можна зробити за допомогою yunohost service restart {service} yunohost service log {service} ).", - "diagnosis_services_bad_status": "Сервіс {service} знаходиться в {status} :(", - "diagnosis_services_conf_broken": "Конфігурація порушена для служби {service}!", - "diagnosis_services_running": "Служба {service} запущена!", - "diagnosis_domain_expires_in": "Термін дії {domain} закінчується через {days} днів.", - "diagnosis_domain_expiration_error": "Термін дії деяких доменів закінчується ДУЖЕ СКОРО!", - "diagnosis_domain_expiration_warning": "Термін дії деяких доменів закінчиться найближчим часом!", + "diagnosis_ram_low": "У системі наявно {available} ({available_percent}%) оперативної пам'яті (з {total}). Будьте уважні.", + "diagnosis_ram_verylow": "Система має тільки {available} ({available_percent}%) оперативної пам'яті! (з {total})", + "diagnosis_diskusage_ok": "У сховищі {mountpoint} (на пристрої {device}) залишилося {free} ({free_percent}%) вільного місця (з {total})!", + "diagnosis_diskusage_low": "Сховище {mountpoint} (на пристрої {device}) має тільки {free} ({free_percent}%) вільного місця (з {total}). Будьте уважні.", + "diagnosis_diskusage_verylow": "Сховище {mountpoint} (на пристрої {device}) має тільки {free} ({free_percent}%) вільного місця (з {total}). Вам дійсно варто подумати про очищення простору!", + "diagnosis_services_bad_status_tip": "Ви можете спробувати перезапустити службу, а якщо це не допоможе, подивіться журнали служби в вебадміністраторі (з командного рядка це можна зробити за допомогою yunohost service restart {service} і yunohost service log {service}).", + "diagnosis_services_bad_status": "Служба {service} у стані {status} :(", + "diagnosis_services_conf_broken": "Для служби {service} порушена конфігурація!", + "diagnosis_services_running": "Службу {service} запущено!", + "diagnosis_domain_expires_in": "Строк дії {domain} спливе через {days} днів.", + "diagnosis_domain_expiration_error": "Строк дії деяких доменів НЕЗАБАРОМ спливе!", + "diagnosis_domain_expiration_warning": "Строк дії деяких доменів спливе найближчим часом!", "diagnosis_domain_expiration_success": "Ваші домени зареєстровані і не збираються спливати найближчим часом.", - "diagnosis_domain_expiration_not_found_details": "Інформація WHOIS для домену {domain} не містить інформації про термін дії?", + "diagnosis_domain_expiration_not_found_details": "Відомості WHOIS для домену {domain} не містять даних про строк дії?", "diagnosis_domain_not_found_details": "Домен {domain} не існує в базі даних WHOIS або строк його дії сплив!", "diagnosis_domain_expiration_not_found": "Неможливо перевірити строк дії деяких доменів", "diagnosis_dns_specialusedomain": "Домен {domain} заснований на домені верхнього рівня спеціального призначення (TLD) і тому не очікується, що у нього будуть актуальні записи DNS.", @@ -502,7 +502,7 @@ "diagnosis_ip_not_connected_at_all": "Здається, сервер взагалі не під'єднаний до Інтернету!?", "diagnosis_ip_local": "Локальний IP: {local}.", "diagnosis_ip_global": "Глобальний IP: {global}", - "diagnosis_ip_no_ipv6_tip": "Наявність робочого IPv6 не є обов'язковим для роботи вашого сервера, але це краще для здоров'я Інтернету в цілому. IPv6 зазвичай автоматично налаштовується системою або вашим провайдером, якщо він доступний. В іншому випадку вам, можливо, доведеться налаштувати деякі речі вручну, як пояснюється в документації тут: https://yunohost.org/#/ipv6. Якщо ви не можете увімкнути IPv6 або якщо це здається вам занадто технічним, ви також можете сміливо нехтувати цим попередженням.", + "diagnosis_ip_no_ipv6_tip": "Наявність робочого IPv6 не є обов'язковим для роботи вашого сервера, але це краще для здоров'я Інтернету в цілому. IPv6 зазвичай автоматично налаштовується системою або вашим провайдером, якщо він доступний. В іншому випадку вам, можливо, доведеться налаштувати деякі речі вручну, як пояснюється в документації тут: https://yunohost.org/#/ipv6. Якщо ви не можете увімкнути IPv6 або якщо це здається вам занадто технічним, ви також можете сміливо нехтувати цим попередженням.", "diagnosis_ip_no_ipv6": "Сервер не має робочого IPv6.", "diagnosis_ip_connected_ipv6": "Сервер під'єднаний до Інтернету через IPv6!", "diagnosis_ip_no_ipv4": "Сервер не має робочого IPv4.", From d36de3589b5253ae6e5e77fc1a45d612f22265bf Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 3 Sep 2021 14:43:40 +0000 Subject: [PATCH 088/101] Translated using Weblate (Ukrainian) Currently translated at 34.4% (227 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index 52a5b0a70..41efdabe8 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -406,10 +406,10 @@ "diagnosis_mail_ehlo_could_not_diagnose_details": "Помилка: {error}", "diagnosis_mail_ehlo_could_not_diagnose": "Не вдалося діагностувати наявність певної поштовий сервер postfix ззовні в IPv{ipversion}.", "diagnosis_mail_ehlo_wrong_details": "EHLO, отриманий віддаленим діагностичним центром в IPv{ipversion}, відрізняється від домену вашого сервера.
Отриманий EHLO: {wrong_ehlo}
Очікуваний: {right_ehlo} < br> найпоширенішою причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер . Крім того, переконайтеся, що в роботу сервера не втручається брандмауер або зворотний проксі-сервер.", - "diagnosis_mail_ehlo_wrong": "Інший поштовий SMTP-сервер відповідає на IPv{ipversion}. Ваш сервер, ймовірно, не зможе отримувати електронну пошту.", + "diagnosis_mail_ehlo_wrong": "Інший поштовий SMTP-сервер відповідає на IPv{ipversion}. Ваш сервер, ймовірно, не зможе отримувати електронні листи.", "diagnosis_mail_ehlo_bad_answer_details": "Це може бути викликано тим, що замість вашого сервера відповідає інша машина.", - "diagnosis_mail_ehlo_bad_answer": "Ні-SMTP служба відповідає на порту 25 на IPv{ipversion}.", - "diagnosis_mail_ehlo_unreachable_details": "Не вдалося відкрити з'єднання по порту 25 з вашим сервером на IPv{ipversion}. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер .
2. Ви також повинні переконатися, що служба postfix запущена.
3. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", + "diagnosis_mail_ehlo_bad_answer": "Не-SMTP служба відповіла на порту 25 на IPv{ipversion}.", + "diagnosis_mail_ehlo_unreachable_details": "Не вдалося відкрити з'єднання за портом 25 з вашим сервером на IPv{ipversion}. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер.
2. Ви також повинні переконатися, що служба postfix запущена.
3. На більш складних установках: переконайтеся, що немає фаєрвола або зворотного проксі.", "diagnosis_mail_ehlo_unreachable": "Поштовий сервер SMTP недоступний ззовні по IPv{ipversion}. Він не зможе отримувати листи електронної пошти.", "diagnosis_mail_ehlo_ok": "Поштовий сервер SMTP доступний ззовні і тому може отримувати електронні листи!", "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Деякі провайдери не дозволять вам розблокувати вихідний порт 25, тому що вони не піклуються про мережевий нейтралітет (Net Neutrality).
- Деякі з них пропонують альтернативу використання ретранслятора поштового сервера, хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN *з виділеним загальнодоступним IP* для обходу такого роду обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Ви також можете розглянути можливість переходу на більш дружнього до мережевого нейтралітету провайдера.", From 2b5fc01d054eb1327ccff7353918523d4a9ea5fd Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 3 Sep 2021 14:46:59 +0000 Subject: [PATCH 089/101] Translated using Weblate (Ukrainian) Currently translated at 34.5% (228 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/uk.json b/locales/uk.json index 41efdabe8..0b0ddc191 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -405,7 +405,7 @@ "diagnosis_mail_fcrdns_ok": "Ваш зворотний DNS налаштований правильно!", "diagnosis_mail_ehlo_could_not_diagnose_details": "Помилка: {error}", "diagnosis_mail_ehlo_could_not_diagnose": "Не вдалося діагностувати наявність певної поштовий сервер postfix ззовні в IPv{ipversion}.", - "diagnosis_mail_ehlo_wrong_details": "EHLO, отриманий віддаленим діагностичним центром в IPv{ipversion}, відрізняється від домену вашого сервера.
Отриманий EHLO: {wrong_ehlo}
Очікуваний: {right_ehlo} < br> найпоширенішою причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер . Крім того, переконайтеся, що в роботу сервера не втручається брандмауер або зворотний проксі-сервер.", + "diagnosis_mail_ehlo_wrong_details": "EHLO, отриманий віддаленим діагностичним центром в IPv{ipversion}, відрізняється від домену вашого сервера.
Отриманий EHLO: {wrong_ehlo}
Очікуваний: {right_ehlo}< br>Найпоширенішою причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер. Крім того, переконайтеся, що в роботу сервера не втручається фаєрвол або зворотний проксі-сервер.", "diagnosis_mail_ehlo_wrong": "Інший поштовий SMTP-сервер відповідає на IPv{ipversion}. Ваш сервер, ймовірно, не зможе отримувати електронні листи.", "diagnosis_mail_ehlo_bad_answer_details": "Це може бути викликано тим, що замість вашого сервера відповідає інша машина.", "diagnosis_mail_ehlo_bad_answer": "Не-SMTP служба відповіла на порту 25 на IPv{ipversion}.", From 0093d126309cb47eba721e39ecb276ede45dfc06 Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 3 Sep 2021 14:51:29 +0000 Subject: [PATCH 090/101] Translated using Weblate (Ukrainian) Currently translated at 35.8% (236 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index 0b0ddc191..77bc1f416 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -396,15 +396,15 @@ "diagnosis_mail_blacklist_reason": "Причина внесення в чорний список: {reason}", "diagnosis_mail_blacklist_listed_by": "Ваш IP або домен {item} знаходиться в чорному списку {blacklist_name}.", "diagnosis_mail_blacklist_ok": "IP-адреси і домени, які використовуються цим сервером, не внесені в чорний список", - "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Поточний зворотний DNS: {rdns_domain}
Очікуване значення: {ehlo_domain}.", + "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Поточний зворотний DNS:{rdns_domain}
Очікуване значення: {ehlo_domain}.", "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Зворотний DNS неправильно налаштований в IPv{ipversion}. Деякі електронні листи можуть бути не доставлені або можуть бути відзначені як спам.", - "diagnosis_mail_fcrdns_nok_alternatives_6": "Деякі провайдери не дозволяють вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ваш зворотний DNS правильно налаштований для IPv4, ви можете спробувати відключити використання IPv6 при відправці листів, виконавши команду yunohost settings set smtp.allow_ipv6 -v off . Примітка: останнє рішення означає, що ви не зможете відправляти або отримувати електронну пошту з нечисленних серверів, що використовують тільки IPv6.", + "diagnosis_mail_fcrdns_nok_alternatives_6": "Деякі провайдери не дозволять вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ваш зворотний DNS правильно налаштований для IPv4, ви можете спробувати вимкнути використання IPv6 при надсиланні листів, виконавши команду yunohost settings set smtp.allow_ipv6 -v off. Примітка: останнє рішення означає, що ви не зможете надсилати або отримувати електронні листи з нечисленних серверів, що використовують тільки IPv6.", "diagnosis_mail_fcrdns_nok_alternatives_4": "Деякі провайдери не дозволять вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ви відчуваєте проблеми через це, розгляньте наступні рішення:
- Деякі провайдери надають альтернативу використання ретранслятора поштового сервера, хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN *з виділеним загальнодоступним IP* для обходу подібних обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Або можна переключитися на іншого провайдера .", - "diagnosis_mail_fcrdns_nok_details": "Спочатку спробуйте налаштувати зворотний DNS з {ehlo_domain} в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм тікет підтримки для цього).", + "diagnosis_mail_fcrdns_nok_details": "Спочатку спробуйте налаштувати зворотний DNS з {ehlo_domain} в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм запит у підтримку для цього).", "diagnosis_mail_fcrdns_dns_missing": "У IPv{ipversion} не визначений зворотний DNS. Деякі листи можуть не доставлятися або позначатися як спам.", - "diagnosis_mail_fcrdns_ok": "Ваш зворотний DNS налаштований правильно!", + "diagnosis_mail_fcrdns_ok": "Ваш зворотний DNS налаштовано правильно!", "diagnosis_mail_ehlo_could_not_diagnose_details": "Помилка: {error}", - "diagnosis_mail_ehlo_could_not_diagnose": "Не вдалося діагностувати наявність певної поштовий сервер postfix ззовні в IPv{ipversion}.", + "diagnosis_mail_ehlo_could_not_diagnose": "Не вдалося діагностувати, чи доступний поштовий сервер postfix ззовні в IPv{ipversion}.", "diagnosis_mail_ehlo_wrong_details": "EHLO, отриманий віддаленим діагностичним центром в IPv{ipversion}, відрізняється від домену вашого сервера.
Отриманий EHLO: {wrong_ehlo}
Очікуваний: {right_ehlo}< br>Найпоширенішою причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер. Крім того, переконайтеся, що в роботу сервера не втручається фаєрвол або зворотний проксі-сервер.", "diagnosis_mail_ehlo_wrong": "Інший поштовий SMTP-сервер відповідає на IPv{ipversion}. Ваш сервер, ймовірно, не зможе отримувати електронні листи.", "diagnosis_mail_ehlo_bad_answer_details": "Це може бути викликано тим, що замість вашого сервера відповідає інша машина.", From 23a8830af405119ede3fcaafebf2958c4aab92c9 Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 3 Sep 2021 14:53:25 +0000 Subject: [PATCH 091/101] Translated using Weblate (Ukrainian) Currently translated at 36.4% (240 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index 77bc1f416..3a4fe8910 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -391,8 +391,8 @@ "diagnosis_mail_queue_too_big": "Занадто багато відкладених листів в поштовій черзі ({nb_pending} emails)", "diagnosis_mail_queue_unavailable_details": "Помилка: {error}", "diagnosis_mail_queue_unavailable": "Неможливо дізнатися кількість очікують листів в черзі", - "diagnosis_mail_queue_ok": "{nb_pending} відкладені листи в поштових чергах", - "diagnosis_mail_blacklist_website": "Після визначення причини, по якій ви потрапили в чорний список, і її усунення, ви можете попросити видалити ваш IP або домен на {blacklist_website}.", + "diagnosis_mail_queue_ok": "Відкладених електронних листів у поштових чергах: {nb_pending}", + "diagnosis_mail_blacklist_website": "Після визначення причини, з якої ви потрапили в чорний список, і її усунення, ви можете попросити видалити ваш IP або домен на {blacklist_website}.", "diagnosis_mail_blacklist_reason": "Причина внесення в чорний список: {reason}", "diagnosis_mail_blacklist_listed_by": "Ваш IP або домен {item} знаходиться в чорному списку {blacklist_name}.", "diagnosis_mail_blacklist_ok": "IP-адреси і домени, які використовуються цим сервером, не внесені в чорний список", From a2e68fe75345975bc26799fbbc9aa2aad2aa819f Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 3 Sep 2021 14:54:54 +0000 Subject: [PATCH 092/101] Translated using Weblate (Ukrainian) Currently translated at 37.1% (245 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index 3a4fe8910..4e323bfd6 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -386,11 +386,11 @@ "diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {space}, що вельми тривожно! Швидше за все, дисковий простір закінчиться дуже швидко! Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", "diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {space}. Це може бути нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", "diagnosis_regenconf_manually_modified_details": "Це можливо нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що поновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою yunohost tools regen- conf {category} --force .", - "diagnosis_regenconf_manually_modified": "Конфігураційний файл {file}, схоже, був змінений вручну.", - "diagnosis_regenconf_allgood": "Всі конфігураційні файли відповідають рекомендованої конфігурації!", - "diagnosis_mail_queue_too_big": "Занадто багато відкладених листів в поштовій черзі ({nb_pending} emails)", + "diagnosis_regenconf_manually_modified": "Конфігураційний файл {file}, схоже, було змінено вручну.", + "diagnosis_regenconf_allgood": "Усі конфігураційні файли відповідають рекомендованій конфігурації!", + "diagnosis_mail_queue_too_big": "Занадто багато відкладених листів у поштовій черзі (листів: {nb_pending})", "diagnosis_mail_queue_unavailable_details": "Помилка: {error}", - "diagnosis_mail_queue_unavailable": "Неможливо дізнатися кількість очікують листів в черзі", + "diagnosis_mail_queue_unavailable": "Неможливо дізнатися кількість очікувальних листів у черзі", "diagnosis_mail_queue_ok": "Відкладених електронних листів у поштових чергах: {nb_pending}", "diagnosis_mail_blacklist_website": "Після визначення причини, з якої ви потрапили в чорний список, і її усунення, ви можете попросити видалити ваш IP або домен на {blacklist_website}.", "diagnosis_mail_blacklist_reason": "Причина внесення в чорний список: {reason}", From 09e55ef9b1876a4781a9061d3499fe24cdd0cdf5 Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 3 Sep 2021 15:15:04 +0000 Subject: [PATCH 093/101] Translated using Weblate (Ukrainian) Currently translated at 41.7% (275 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index 4e323bfd6..45c5e6bb8 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -359,33 +359,33 @@ "diagnosis_http_unreachable": "Домен {domain} здається недоступним через HTTP ззовні локальної мережі.", "diagnosis_http_bad_status_code": "Схоже, що замість вашого сервера відповіла інша машина (можливо, ваш маршрутизатор).
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", "diagnosis_http_connection_error": "Помилка підключення: не вдалося підключитися до запитуваного домену, швидше за все, він недоступний.", - "diagnosis_http_timeout": "При спробі зв'язатися з вашим сервером ззовні стався тайм-аут. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. Ви також повинні переконатися, що служба nginx запущена
3. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", - "diagnosis_http_ok": "Домен {domain} доступний по HTTP ззовні локальної мережі.", - "diagnosis_http_localdomain": "Домен {domain} з доменом .local TLD не може бути доступний ззовні локальної мережі.", + "diagnosis_http_timeout": "При спробі зв'язатися з вашим сервером ззовні стався тайм-аут. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлено на ваш сервер .
2. Ви також повинні переконатися, що служба nginx запущена
3.На більш складних установках: переконайтеся, що немає фаєрвола або зворотного проксі.", + "diagnosis_http_ok": "Домен {domain} доступний по HTTP поза локальною мережею.", + "diagnosis_http_localdomain": "Домен {domain} з .local TLD не може бути доступний ззовні локальної мережі.", "diagnosis_http_could_not_diagnose_details": "Помилка: {error}", "diagnosis_http_could_not_diagnose": "Не вдалося діагностувати досяжність доменів ззовні в IPv{ipversion}.", - "diagnosis_http_hairpinning_issue_details": "Можливо, це пов'язано з блоком/маршрутизатором вашого інтернет-провайдера. В результаті, люди ззовні вашої локальної мережі зможуть отримати доступ до вашого сервера, як і очікувалося, але не люди зсередини локальної мережі (як ви, ймовірно?) При використанні доменного імені або глобального IP. Можливо, ви зможете поліпшити ситуацію, глянувши на https://yunohost.org/dns_local_network .", - "diagnosis_http_hairpinning_issue": "Схоже, що у вашій локальній мережі не включена проброска.", - "diagnosis_ports_forwarding_tip": "Щоб вирішити цю проблему, вам, швидше за все, потрібно налаштувати кидок портів на вашому інтернет-маршрутизатор, як описано в https://yunohost.org/isp_box_config.", - "diagnosis_ports_needed_by": "Відкриття цього порту необхідно для функцій {category} (служба {service}).", + "diagnosis_http_hairpinning_issue_details": "Можливо, це пов'язано з коробкою/маршрутизатором вашого інтернет-провайдера. В результаті, люди ззовні вашої локальної мережі зможуть отримати доступ до вашого сервера, як і очікувалося, але не люди зсередини локальної мережі (як ви, ймовірно?) При використанні доменного імені або глобального IP. Можливо, ви зможете поліпшити ситуацію, глянувши https://yunohost.org/dns_local_network .", + "diagnosis_http_hairpinning_issue": "Схоже, що у вашій локальній мережі не увімкнено шпилькування (hairpinning).", + "diagnosis_ports_forwarding_tip": "Щоб вирішити цю проблему, вам, швидше за все, потрібно налаштувати пересилання портів на вашому інтернет-маршрутизаторі, як описано в https://yunohost.org/isp_box_config.", + "diagnosis_ports_needed_by": "Відкриття цього порту необхідне для функцій {category} (служба {service}).", "diagnosis_ports_ok": "Порт {port} доступний ззовні.", - "diagnosis_ports_partially_unreachable": "Порт {port} не доступний ззовні в IPv {failed}.", + "diagnosis_ports_partially_unreachable": "Порт {port} не доступний ззовні в IPv{failed}.", "diagnosis_ports_unreachable": "Порт {port} недоступний ззовні.", "diagnosis_ports_could_not_diagnose_details": "Помилка: {error}", "diagnosis_ports_could_not_diagnose": "Не вдалося діагностувати досяжність портів ззовні в IPv{ipversion}.", "diagnosis_description_regenconf": "Конфігурації системи", - "diagnosis_description_mail": "Електронна пошта", - "diagnosis_description_ports": "виявлення портів", + "diagnosis_description_mail": "Е-пошта", + "diagnosis_description_ports": "Виявлення портів", "diagnosis_description_systemresources": "Системні ресурси", "diagnosis_description_services": "Перевірка стану служб", - "diagnosis_description_dnsrecords": "записи DNS", + "diagnosis_description_dnsrecords": "DNS-записи", "diagnosis_description_ip": "Інтернет-з'єднання", - "diagnosis_description_basesystem": "Базова система", - "diagnosis_security_vulnerable_to_meltdown_details": "Щоб виправити це, вам слід оновити систему і перезавантажитися, щоб завантажити нове ядро linux (або звернутися до вашого серверного провайдеру, якщо це не спрацює). Додаткову інформацію див. На сайті https://meltdownattack.com/.", - "diagnosis_security_vulnerable_to_meltdown": "Схоже, що ви уразливі до критичної уразливості безпеки Meltdown.", - "diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {space}, що вельми тривожно! Швидше за все, дисковий простір закінчиться дуже швидко! Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", - "diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {space}. Це може бути нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендується мати не менше 16 ГБ для кореневої файлової системи.", - "diagnosis_regenconf_manually_modified_details": "Це можливо нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що поновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою yunohost tools regen- conf {category} --force .", + "diagnosis_description_basesystem": "Основна система", + "diagnosis_security_vulnerable_to_meltdown_details": "Щоб виправити це, вам слід оновити систему і перезавантажитися, щоб завантажити нове ядро Linux (або звернутися до вашого серверного провайдера, якщо це не спрацює). Докладніше див. на сайті https://meltdownattack.com/.", + "diagnosis_security_vulnerable_to_meltdown": "Схоже, що ви вразливі до критичної вразливості безпеки Meltdown.", + "diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {space}, що дуже тривожно! Скоріше за все, дисковий простір закінчиться дуже скоро! Рекомендовано мати не менше 16 ГБ для кореневої файлової системи.", + "diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {space}. Можливо це нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендовано мати не менше 16 ГБ для кореневої файлової системи.", + "diagnosis_regenconf_manually_modified_details": "Можливо це нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що оновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою команди yunohost tools regen-conf {category} --force.", "diagnosis_regenconf_manually_modified": "Конфігураційний файл {file}, схоже, було змінено вручну.", "diagnosis_regenconf_allgood": "Усі конфігураційні файли відповідають рекомендованій конфігурації!", "diagnosis_mail_queue_too_big": "Занадто багато відкладених листів у поштовій черзі (листів: {nb_pending})", @@ -529,7 +529,7 @@ "diagnosis_basesystem_hardware_model": "Модель сервера - {model}", "diagnosis_basesystem_hardware": "Архітектура апаратного забезпечення сервера - {virt} {arch}", "custom_app_url_required": "Ви повинні надати URL-адресу для оновлення вашого користувацького застосунку {app}.", - "confirm_app_install_thirdparty": "НЕБЕЗПЕЧНО! Цей застосунок не входить в каталог застосунків YunoHost. Установлення сторонніх застосунків може порушити цілісність і безпеку вашої системи. Вам не слід встановлювати його, якщо ви не знаєте, що робите. НІЯКОЇ ПІДТРИМКИ НЕ БУДЕ, якщо цей застосунок не буде працювати або зламає вашу систему... Якщо ви все одно готові піти на такий ризик, введіть '{answers}'.", + "confirm_app_install_thirdparty": "НЕБЕЗПЕЧНО! Цей застосунок не входить у каталог застосунків YunoHost. Установлення сторонніх застосунків може порушити цілісність і безпеку вашої системи. Вам не слід встановлювати його, якщо ви не знаєте, що робите. НІЯКОЇ ПІДТРИМКИ НЕ БУДЕ, якщо цей застосунок не буде працювати або зламає вашу систему... Якщо ви все одно готові піти на такий ризик, введіть '{answers}'.", "confirm_app_install_danger": "НЕБЕЗПЕЧНО! Відомо, що цей застосунок все ще експериментальний (якщо не сказати, що він явно не працює)! Вам не слід встановлювати його, якщо ви не знаєте, що робите. Ніякої підтримки не буде надано, якщо цей застосунок не буде працювати або зламає вашу систему... Якщо ви все одно готові ризикнути, введіть '{answers}'.", "confirm_app_install_warning": "Попередження: Цей застосунок може працювати, але він не дуже добре інтегрований в YunoHost. Деякі функції, такі як єдина реєстрація та резервне копіювання/відновлення, можуть бути недоступні. Все одно встановити? [{answers}]. ", "certmanager_unable_to_parse_self_CA_name": "Не вдалося розібрати назву самопідписного центру (файл: {file})", @@ -637,5 +637,6 @@ "app_not_upgraded": "Застосунок '{failed_app}' не вдалося оновити, і, як наслідок, оновлення таких застосунків було скасовано: {apps}", "app_manifest_install_ask_is_public": "Чи має цей застосунок бути відкритим для анонімних відвідувачів?", "app_manifest_install_ask_admin": "Виберіть користувача-адміністратора для цього застосунку", - "app_manifest_install_ask_password": "Виберіть пароль адміністратора для цього застосунку" + "app_manifest_install_ask_password": "Виберіть пароль адміністратора для цього застосунку", + "diagnosis_description_apps": "Застосунки" } From 25d9ff8a7982e93ce63e8a4c662589dbb1878fce Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 3 Sep 2021 18:40:38 +0000 Subject: [PATCH 094/101] Translated using Weblate (Ukrainian) Currently translated at 100.0% (659 of 659 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 595 +++++++++++++++++++++++++----------------------- 1 file changed, 307 insertions(+), 288 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index 45c5e6bb8..bdbe8b0cd 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -33,63 +33,63 @@ "action_invalid": "Неприпустима дія '{action}'", "aborting": "Переривання.", "diagnosis_description_web": "Мережа", - "service_reloaded_or_restarted": "Служба '{service}' була перезавантажена або перезапущено", - "service_reload_or_restart_failed": "Не вдалося перезавантажити або перезапустити службу '{service}' Recent service logs: {logs}", - "service_restarted": "Служба '{service}' перезапущено", - "service_restart_failed": "Не вдалося запустити службу '{service}' Недавні журнали служб: {logs}", + "service_reloaded_or_restarted": "Службу '{service}' була перезавантажено або перезапущено", + "service_reload_or_restart_failed": "Не вдалося перезавантажити або перезапустити службу '{service}' \n\nНедавні журнали служби: {logs}", + "service_restarted": "Службу '{service}' перезапущено", + "service_restart_failed": "Не вдалося запустити службу '{service}' \n\nНедавні журнали служб: {logs}", "service_reloaded": "Служба '{service}' перезавантажена", - "service_reload_failed": "Не вдалося перезавантажити службу '{service}' Останні журнали служби: {logs}", + "service_reload_failed": "Не вдалося перезавантажити службу '{service}'\n\nОстанні журнали служби: {logs}", "service_removed": "Служба '{service}' вилучена", "service_remove_failed": "Не вдалося видалити службу '{service}'", - "service_regen_conf_is_deprecated": "'Yunohost service regen-conf' застарів! Будь ласка, використовуйте 'yunohost tools regen-conf' замість цього.", - "service_enabled": "Служба '{service}' тепер буде автоматично запускатися при завантаженні системи.", - "service_enable_failed": "Неможливо змусити службу '{service}' автоматично запускатися при завантаженні. Недавні журнали служб: {logs}", - "service_disabled": "Служба '{service}' більше не буде запускатися при завантаженні системи.", - "service_disable_failed": "Неможливо змусити службу '{service} \"не запускатися при завантаженні. Останні журнали служби: {logs}", - "service_description_yunohost-firewall": "Управляє відкритими і закритими портами підключення до сервісів", - "service_description_yunohost-api": "Управляє взаємодією між веб-інтерфейсом YunoHost і системою", - "service_description_ssh": "Дозволяє віддалено підключатися до сервера через термінал (протокол SSH)", - "service_description_slapd": "Зберігає користувачів, домени і пов'язану з ними інформацію", - "service_description_rspamd": "Фільтрує спам і інші функції, пов'язані з електронною поштою", + "service_regen_conf_is_deprecated": "'yunohost service regen-conf' застарів! Будь ласка, використовуйте 'yunohost tools regen-conf' замість цього.", + "service_enabled": "Служба '{service}' тепер буде автоматично запускатися під час завантаження системи.", + "service_enable_failed": "Неможливо змусити службу '{service}' автоматично запускатися під час завантаження.\n\nНедавні журнали служби: {logs}", + "service_disabled": "Служба '{service}' більше не буде запускатися під час завантаження системи.", + "service_disable_failed": "Неможливо змусити службу '{service}' не запускатися під час завантаження.\n\nОстанні журнали служби: {logs}", + "service_description_yunohost-firewall": "Управляє відкритими і закритими портами з'єднання зі службами", + "service_description_yunohost-api": "Управляє взаємодією між вебінтерфейсом YunoHost і системою", + "service_description_ssh": "Дозволяє віддалено під'єднуватися до сервера через термінал (протокол SSH)", + "service_description_slapd": "Зберігає користувачів, домени і пов'язані з ними дані", + "service_description_rspamd": "Фільтри спаму і інші функції, пов'язані з е-поштою", "service_description_redis-server": "Спеціалізована база даних, яка використовується для швидкого доступу до даних, черги завдань і зв'язку між програмами", - "service_description_postfix": "Використовується для відправки та отримання електронної пошти", - "service_description_php7.3-fpm": "Запускає програми, написані на мові програмування PHP, за допомогою NGINX", - "service_description_nginx": "Обслуговує або надає доступ до всіх веб-сайтів, розміщених на вашому сервері", + "service_description_postfix": "Використовується для надсилання та отримання е-пошти", + "service_description_php7.3-fpm": "Запускає застосунки, написані мовою програмування PHP за допомогою NGINX", + "service_description_nginx": "Обслуговує або надає доступ до всіх вебсайтів, розміщених на вашому сервері", "service_description_mysql": "Зберігає дані застосунків (база даних SQL)", - "service_description_metronome": "Служба захисту миттєвого обміну повідомленнями XMPP", - "service_description_fail2ban": "Захист від перебору та інших видів атак з Інтернету", + "service_description_metronome": "Управління обліковими записами миттєвих повідомлень XMPP", + "service_description_fail2ban": "Захист від перебирання (брутфорсу) та інших видів атак з Інтернету", "service_description_dovecot": "Дозволяє поштовим клієнтам отримувати доступ до електронної пошти (через IMAP і POP3)", - "service_description_dnsmasq": "Обробляє дозвіл доменних імен (DNS)", + "service_description_dnsmasq": "Обробляє роздільність доменних імен (DNS)", "service_description_yunomdns": "Дозволяє вам отримати доступ до вашого сервера, використовуючи 'yunohost.local' у вашій локальній мережі", "service_cmd_exec_failed": "Не вдалося виконати команду '{command}'", - "service_already_stopped": "Служба '{service}' вже зупинена", - "service_already_started": "Служба '{service}' вже запущена", - "service_added": "Служба '{service}' була додана", + "service_already_stopped": "Службу '{service}' вже зупинено", + "service_already_started": "Службу '{service}' вже запущено", + "service_added": "Службу '{service}' було додано", "service_add_failed": "Не вдалося додати службу '{service}'", - "server_reboot_confirm": "Сервер негайно перезавантажиться, ви впевнені? [{answers}]", - "server_reboot": "сервер перезавантажиться", - "server_shutdown_confirm": "Сервер буде негайно виключений, ви впевнені? [{answers}].", - "server_shutdown": "сервер вимкнеться", - "root_password_replaced_by_admin_password": "Ваш кореневої пароль був замінений на пароль адміністратора.", - "root_password_desynchronized": "Пароль адміністратора був змінений, але YunoHost не зміг поширити це на пароль root!", - "restore_system_part_failed": "Не вдалося відновити системну частину '{part}'.", - "restore_running_hooks": "Запуск хуков відновлення…", - "restore_running_app_script": "Відновлення програми \"{app} '…", + "server_reboot_confirm": "Сервер буде негайно перезавантажено, ви впевнені? [{answers}]", + "server_reboot": "Сервер буде перезавантажено", + "server_shutdown_confirm": "Сервер буде негайно вимкнено, ви впевнені? [{answers}]", + "server_shutdown": "Сервер буде вимкнено", + "root_password_replaced_by_admin_password": "Ваш кореневий (root) пароль було замінено на пароль адміністратора.", + "root_password_desynchronized": "Пароль адміністратора було змінено, але YunoHost не зміг поширити це на кореневий (root) пароль!", + "restore_system_part_failed": "Не вдалося відновити системний розділ '{part}'", + "restore_running_hooks": "Запуск хуків відновлення…", + "restore_running_app_script": "Відновлення застосунку '{app}'…", "restore_removing_tmp_dir_failed": "Неможливо видалити старий тимчасовий каталог", "restore_nothings_done": "Нічого не було відновлено", - "restore_not_enough_disk_space": "Недостатньо місця (простір: {free_space: d} B, необхідний простір: {needed_space: d} B, маржа безпеки: {margin: d} B)", - "restore_may_be_not_enough_disk_space": "Схоже, у вашій системі недостатньо місця (вільного: {free_space: d} B, необхідний простір: {needed_space: d} B, запас міцності: {margin: d} B)", - "restore_hook_unavailable": "Сценарій відновлення для '{part}' недоступним у вашій системі і в архіві його теж немає", + "restore_not_enough_disk_space": "Недостатньо місця (простір: {free_space} Б, необхідний простір: {needed_space} Б, межа безпеки: {margin: d} Б)", + "restore_may_be_not_enough_disk_space": "Схоже, у вашій системі недостатньо місця (вільно: {free_space} Б, необхідний простір: {needed_space} Б, межа безпеки: {margin: d} Б)", + "restore_hook_unavailable": "Скрипт відновлення для '{part}' недоступний у вашій системі і в архіві його теж немає", "restore_failed": "Не вдалося відновити систему", - "restore_extracting": "Витяг необхідних файлів з архіву…", - "restore_confirm_yunohost_installed": "Ви дійсно хочете відновити вже встановлену систему? [{answers}].", - "restore_complete": "відновлення завершено", + "restore_extracting": "Витягнення необхідних файлів з архіву…", + "restore_confirm_yunohost_installed": "Ви дійсно хочете відновити вже встановлену систему? [{answers}]", + "restore_complete": "Відновлення завершено", "restore_cleaning_failed": "Не вдалося очистити тимчасовий каталог відновлення", - "restore_backup_too_old": "Цей архів резервних копій не може бути відновлений, бо він отриманий з дуже старою версією YunoHost.", + "restore_backup_too_old": "Цей архів резервних копій не може бути відновлений, бо він отриманий з дуже старої версії YunoHost.", "restore_already_installed_apps": "Наступні програми не можуть бути відновлені, тому що вони вже встановлені: {apps}", - "restore_already_installed_app": "Застосунок з ідентифікатором \"{app} 'вже встановлено", - "regex_with_only_domain": "Ви не можете використовувати regex для домену, тільки для шляху.", - "regex_incompatible_with_tile": "/! \\ Packagers! Дозвіл '{permission}' має значення show_tile 'true', тому ви не можете визначити regex URL в якості основного URL.", + "restore_already_installed_app": "Застосунок з ID \"{app} 'вже встановлено", + "regex_with_only_domain": "Ви не можете використовувати regex для домену, тільки для шляху", + "regex_incompatible_with_tile": "/! \\ Packagers! Дозвіл '{permission}' має значення show_tile 'true', тому ви не можете визначити regex URL в якості основної URL", "regenconf_need_to_explicitly_specify_ssh": "Конфігурація ssh була змінена вручну, але вам потрібно явно вказати категорію 'ssh' з --force, щоб застосувати зміни.", "regenconf_pending_applying": "Застосування очікує конфігурації для категорії '{category}'...", "regenconf_failed": "Не вдалося відновити конфігурацію для категорії (категорій): {categories}", @@ -98,276 +98,276 @@ "regenconf_updated": "Конфігурація оновлена для категорії '{category}'", "regenconf_up_to_date": "Конфігурація вже оновлена для категорії '{category}'", "regenconf_now_managed_by_yunohost": "Конфігураційний файл '{conf}' тепер управляється YunoHost (категорія {category}).", - "regenconf_file_updated": "Конфігураційний файл '{conf}' оновлений", - "regenconf_file_removed": "Конфігураційний файл '{conf}' видалений", + "regenconf_file_updated": "Конфігураційний файл '{conf}' оновлено", + "regenconf_file_removed": "Конфігураційний файл '{conf}' видалено", "regenconf_file_remove_failed": "Неможливо видалити файл конфігурації '{conf}'", - "regenconf_file_manually_removed": "Конфігураційний файл '{conf}' був видалений вручну і не буде створено", - "regenconf_file_manually_modified": "Конфігураційний файл '{conf}' був змінений вручну і не буде оновлено", - "regenconf_file_kept_back": "Конфігураційний файл '{conf}' повинен був бути вилучений regen-conf (категорія {category}), але був збережений.", + "regenconf_file_manually_removed": "Конфігураційний файл '{conf}' було видалено вручну і не буде створено", + "regenconf_file_manually_modified": "Конфігураційний файл '{conf}' було змінено вручну і не буде оновлено", + "regenconf_file_kept_back": "Очікувалося видалення конфігураційного файлу '{conf}' за допомогою regen-conf (категорія {category}), але його було збережено.", "regenconf_file_copy_failed": "Не вдалося скопіювати новий файл конфігурації '{new}' в '{conf}'", - "regenconf_file_backed_up": "Конфігураційний файл '{conf}' збережений в '{backup}'", - "postinstall_low_rootfsspace": "Загальна площа кореневої файлової системи становить менше 10 ГБ, що викликає занепокоєння! Швидше за все, дисковий простір закінчиться дуже швидко! Рекомендується мати не менше 16 ГБ для кореневої файлової системи. Якщо ви хочете встановити YunoHost, незважаючи на це попередження, повторно запустіть постінсталляцію з параметром --force-diskspace", - "port_already_opened": "Порт {port: d} вже відкритий для з'єднань {ip_version}.", - "port_already_closed": "Порт {port: d} вже закритий для з'єднань {ip_version}.", - "permission_require_account": "Дозвіл {permission} має сенс тільки для користувачів, що мають обліковий запис, і тому не може бути включено для відвідувачів.", - "permission_protected": "Дозвіл {permission} захищено. Ви не можете додавати або видаляти групу відвідувачів в/з цього дозволу.", + "regenconf_file_backed_up": "Конфігураційний файл '{conf}' збережено в '{backup}'", + "postinstall_low_rootfsspace": "Загальне місце кореневої файлової системи становить менше 10 ГБ, що викликає занепокоєння! Швидше за все, дисковий простір закінчиться дуже скоро! Рекомендовано мати не менше 16 ГБ для кореневої файлової системи. Якщо ви хочете встановити YunoHost попри це попередження, повторно запустіть післявстановлення з параметром --force-diskspace", + "port_already_opened": "Порт {port} вже відкрито для з'єднань {ip_version}", + "port_already_closed": "Порт {port} вже закрито для з'єднань {ip_version}", + "permission_require_account": "Дозвіл {permission} має зміст тільки для користувачів, що мають обліковий запис, і тому не може бути увімкненим для відвідувачів.", + "permission_protected": "Дозвіл {permission} захищено. Ви не можете додавати або вилучати групу відвідувачів до/з цього дозволу.", "permission_updated": "Дозвіл '{permission}' оновлено", "permission_update_failed": "Не вдалося оновити дозвіл '{permission}': {error}", - "permission_not_found": "Дозвіл '{permission}', не знайдено", + "permission_not_found": "Дозвіл '{permission}' не знайдено", "permission_deletion_failed": "Не вдалося видалити дозвіл '{permission}': {error}", "permission_deleted": "Дозвіл '{permission}' видалено", "permission_cant_add_to_all_users": "Дозвіл {permission} не може бути додано всім користувачам.", "permission_currently_allowed_for_all_users": "Наразі цей дозвіл надається всім користувачам на додачу до інших груп. Імовірно, вам потрібно або видалити дозвіл 'all_users', або видалити інші групи, яким його зараз надано.", "permission_creation_failed": "Не вдалося створити дозвіл '{permission}': {error}", "permission_created": "Дозвіл '{permission}' створено", - "permission_cannot_remove_main": "Видалення основного дозволу заборонено", - "permission_already_up_to_date": "Дозвіл не було оновлено, тому що запити на додавання/видалення вже відповідають поточному стану.", + "permission_cannot_remove_main": "Вилучення основного дозволу заборонене", + "permission_already_up_to_date": "Дозвіл не було оновлено, тому що запити на додавання/вилучення вже відповідають поточному стану.", "permission_already_exist": "Дозвіл '{permission}' вже існує", - "permission_already_disallowed": "Група '{group}' вже має дозвіл \"{permission} 'відключено", - "permission_already_allowed": "Для гурту \"{group} 'вже включено дозвіл' {permission} '", + "permission_already_disallowed": "Група '{group}' вже має вимкнений дозвіл '{permission}'", + "permission_already_allowed": "Група '{group}' вже має увімкнений дозвіл '{permission}'", "pattern_password_app": "На жаль, паролі не можуть містити такі символи: {forbidden_chars}", - "pattern_username": "Повинен складатися тільки з букв і цифр в нижньому регістрі і символів підкреслення.", - "pattern_positive_number": "Повинно бути позитивним числом", - "pattern_port_or_range": "Повинен бути дійсний номер порту (наприклад, 0-65535) або діапазон портів (наприклад, 100: 200).", - "pattern_password": "Повинен бути довжиною не менше 3 символів", - "pattern_mailbox_quota": "Повинен бути розмір з суфіксом b/k/M/G/T або 0, щоб не мати квоти.", - "pattern_lastname": "Повинна бути дійсне прізвище", - "pattern_firstname": "Повинно бути дійсне ім'я", - "pattern_email": "Повинен бути дійсною адресою електронної пошти, без символу '+' (наприклад, someone@example.com ).", - "pattern_email_forward": "Повинен бути дійсну адресу електронної пошти, символ '+' приймається (наприклад, someone+tag@example.com )", - "pattern_domain": "Повинно бути дійсне доменне ім'я (наприклад, my-domain.org)", - "pattern_backup_archive_name": "Повинно бути правильне ім'я файлу, що містить не більше 30 символів, тільки букви і цифри символи і символ -_.", - "password_too_simple_4": "Пароль повинен бути довжиною не менше 12 символів і містити цифру, верхні, нижні і спеціальні символи.", - "password_too_simple_3": "Пароль повинен бути довжиною не менше 8 символів і містити цифру, верхні, нижні і спеціальні символи", - "password_too_simple_2": "Пароль повинен складатися не менше ніж з 8 символів і містити цифру, верхній і нижній символи", - "password_too_simple_1": "Пароль повинен складатися не менше ніж з 8 символів", - "password_listed": "Цей пароль входить в число найбільш часто використовуваних паролів в світі. Будь ласка, виберіть щось більш унікальне.", + "pattern_username": "Має складатися тільки з букв і цифр в нижньому регістрі і символів підкреслення", + "pattern_positive_number": "Має бути додатним числом", + "pattern_port_or_range": "Має бути припустимий номер порту (наприклад, 0-65535) або діапазон портів (наприклад, 100:200)", + "pattern_password": "Має бути довжиною не менше 3 символів", + "pattern_mailbox_quota": "Має бути розмір з суфіксом b/k/M/G/T або 0, щоб не мати квоти", + "pattern_lastname": "Має бути припустиме прізвище", + "pattern_firstname": "Має бути припустиме ім'я", + "pattern_email": "Має бути припустима адреса е-пошти, без символу '+' (наприклад, someone@example.com)", + "pattern_email_forward": "Має бути припустима адреса е-пошти, символ '+' приймається (наприклад, someone+tag@example.com)", + "pattern_domain": "Має бути припустиме доменне ім'я (наприклад, my-domain.org)", + "pattern_backup_archive_name": "Має бути правильна назва файлу, що містить не більше 30 символів, тільки букви і цифри і символи -_", + "password_too_simple_4": "Пароль має складатися не менше ніж з 12 символів і містити цифри, великі та малі символи і спеціальні символи", + "password_too_simple_3": "Пароль має складатися не менше ніж з 8 символів і містити цифри, великі та малі символи і спеціальні символи", + "password_too_simple_2": "Пароль має складатися не менше ніж з 8 символів і містити цифри, великі та малі символи", + "password_too_simple_1": "Пароль має складатися не менше ніж з 8 символів", + "password_listed": "Цей пароль входить в число найбільш часто використовуваних паролів у світі. Будь ласка, виберіть щось неповторюваніше.", "packages_upgrade_failed": "Не вдалося оновити всі пакети", - "operation_interrupted": "Операція була перервана вручну?", - "invalid_number": "Повинно бути число", - "not_enough_disk_space": "Недостатньо вільного місця на \"{path} '.", - "migrations_to_be_ran_manually": "Міграція {id} повинна бути запущена вручну. Будь ласка, перейдіть в розділ Інструменти → Міграції на сторінці веб-адміністратора або виконайте команду `yunohost tools migrations run`.", - "migrations_success_forward": "Міграція {id} завершена", - "migrations_skip_migration": "Пропуск міграції {id}...", + "operation_interrupted": "Операція була вручну перервана?", + "invalid_number": "Має бути числом", + "not_enough_disk_space": "Недостатньо вільного місця на '{path}'", + "migrations_to_be_ran_manually": "Міграція {id} повинна бути запущена вручну. Будь ласка, перейдіть в розділ Засоби → Міграції на сторінці вебадміністратора або виконайте команду `yunohost tools migrations run`.", + "migrations_success_forward": "Міграцію {id} завершено", + "migrations_skip_migration": "Пропускання міграції {id}...", "migrations_running_forward": "Виконання міграції {id}...", - "migrations_pending_cant_rerun": "Ці міграції ще не завершені, тому не можуть бути запущені знову: {ids}", - "migrations_not_pending_cant_skip": "Ці міграції не очікують виконання, тому не можуть бути пропущені: {ids}", - "migrations_no_such_migration": "Не існує міграції під назвою '{id}'.", + "migrations_pending_cant_rerun": "Наступні міграції ще не завершені, тому не можуть бути запущені знову: {ids}", + "migrations_not_pending_cant_skip": "Наступні міграції не очікують виконання, тому не можуть бути пропущені: {ids}", + "migrations_no_such_migration": "Не існує міграції під назвою '{id}'", "migrations_no_migrations_to_run": "Немає міграцій для запуску", - "migrations_need_to_accept_disclaimer": "Щоб запустити міграцію {id}, ви повинні прийняти наступний відмова від відповідальності: --- {disclaimer} --- Якщо ви згодні запустити міграцію, будь ласка, повторіть команду з опцією '--accept-disclaimer'.", - "migrations_must_provide_explicit_targets": "Ви повинні вказати явні цілі при використанні '--skip' або '--force-rerun'.", - "migrations_migration_has_failed": "Міграція {id} не завершена, переривається. Помилка: {exception}.", + "migrations_need_to_accept_disclaimer": "Щоб запустити міграцію {id}, ви повинні прийняти наступну відмову від відповідальності:\n---\n{disclaimer}\n---\nЯкщо ви згодні запустити міграцію, будь ласка, повторіть команду з опцією '--accept-disclaimer'.", + "migrations_must_provide_explicit_targets": "Ви повинні вказати явні цілі при використанні '--skip' або '--force-rerun'", + "migrations_migration_has_failed": "Міграція {id} не завершена, перериваємо. Помилка: {exception}", "migrations_loading_migration": "Завантаження міграції {id}...", "migrations_list_conflict_pending_done": "Ви не можете одночасно використовувати '--previous' і '--done'.", - "migrations_exclusive_options": "'--Auto', '--skip' і '--force-rerun' є взаємовиключними опціями.", + "migrations_exclusive_options": "'--auto', '--skip', і '--force-rerun' є взаємовиключними опціями.", "migrations_failed_to_load_migration": "Не вдалося завантажити міграцію {id}: {error}", "migrations_dependencies_not_satisfied": "Запустіть ці міграції: '{dependencies_id}', перед міграцією {id}.", - "migrations_cant_reach_migration_file": "Не вдалося отримати доступ до файлів міграцій по шляху '% s'.", - "migrations_already_ran": "Ці міграції вже виконані: {ids}", + "migrations_cant_reach_migration_file": "Не вдалося отримати доступ до файлів міграцій за шляхом '%s'", + "migrations_already_ran": "Наступні міграції вже виконано: {ids}", "migration_0019_slapd_config_will_be_overwritten": "Схоже, що ви вручну відредагували конфігурацію slapd. Для цього критичного переходу YunoHost повинен примусово оновити конфігурацію slapd. Оригінальні файли будуть збережені в {conf_backup_folder}.", - "migration_0019_add_new_attributes_in_ldap": "Додавання нових атрибутів для дозволів в базі даних LDAP", - "migration_0018_failed_to_reset_legacy_rules": "Не вдалося скинути застарілі правила iptables: {error}", - "migration_0018_failed_to_migrate_iptables_rules": "Не вдалося перенести застарілі правила iptables в nftables: {error}", + "migration_0019_add_new_attributes_in_ldap": "Додавання нових атрибутів для дозволів у базі даних LDAP", + "migration_0018_failed_to_reset_legacy_rules": "Не вдалося скинути спадкові правила iptables: {error}", + "migration_0018_failed_to_migrate_iptables_rules": "Не вдалося перенести спадкові правила iptables в nftables: {error}", "migration_0017_not_enough_space": "Звільніть достатньо місця в {path} для запуску міграції.", - "migration_0017_postgresql_11_not_installed": "PostgreSQL 9.6 встановлений, але не postgresql 11‽ Можливо, у вашій системі відбулося щось дивне: (...", - "migration_0017_postgresql_96_not_installed": "PostgreSQL ні встановлено у вашій системі. Нічого не потрібно робити.", + "migration_0017_postgresql_11_not_installed": "PostgreSQL 9.6 встановлено, але не PostgreSQL 11‽ Можливо, у вашій системі відбулося щось дивне :(...", + "migration_0017_postgresql_96_not_installed": "PostgreSQL не встановлено у вашій системі. Нічого не потрібно робити.", "migration_0015_weak_certs": "Було виявлено, що такі сертифікати все ще використовують слабкі алгоритми підпису і повинні бути оновлені для сумісності з наступною версією nginx: {certs}", "migration_0015_cleaning_up": "Очищення кеш-пам'яті і пакетів, які більше не потрібні...", - "migration_0015_specific_upgrade": "Початок поновлення системних пакетів, які повинні бути оновлені незалежно...", - "migration_0015_modified_files": "Зверніть увагу, що такі файли були змінені вручну і можуть бути перезаписані після поновлення: {manually_modified_files}.", - "migration_0015_problematic_apps_warning": "Зверніть увагу, що були виявлені наступні, можливо, проблемні встановлені додатки. Схоже, що вони не були встановлені з каталогу застосунків YunoHost або не зазначені як \"робочі\". Отже, не можна гарантувати, що вони будуть працювати після оновлення: {problematic_apps}.", - "migration_0015_general_warning": "Будь ласка, зверніть увагу, що ця міграція є делікатною операцією. Команда YunoHost зробила все можливе, щоб перевірити і протестувати її, але міграція все ще може порушити частина системи або її застосунків. Тому рекомендується: - Виконати резервне копіювання всіх важливих даних або застосунків. Більш детальна інформація на сайті https://yunohost.org/backup; - Наберіться терпіння після запуску міграції: В залежності від вашого підключення до Інтернету і апаратного забезпечення, оновлення може зайняти до декількох годин.", + "migration_0015_specific_upgrade": "Початок оновлення системних пакетів, які повинні бути оновлені незалежно...", + "migration_0015_modified_files": "Зверніть увагу, що такі файли були змінені вручну і можуть бути перезаписані після оновлення: {manually_modified_files}", + "migration_0015_problematic_apps_warning": "Зверніть увагу, що були виявлені наступні, можливо, проблемні встановлені застосунки. Схоже, що вони не були встановлені з каталогу застосунків YunoHost або не зазначені як \"робочі\". Отже, не можна гарантувати, що вони будуть працювати після оновлення: {problematic_apps}", + "migration_0015_general_warning": "Будь ласка, зверніть увагу, що ця міграція є делікатною операцією. Команда YunoHost зробила все можливе, щоб перевірити і протестувати її, але міграція все ще може порушити частина системи або її застосунків.\n\nТому рекомендовано:\n - Виконати резервне копіювання всіх важливих даних або застосунків. Подробиці на сайті https://yunohost.org/backup; \n - Наберіться терпіння після запуску міграції: В залежності від вашого з'єднання з Інтернетом і апаратного забезпечення, оновлення може зайняти до декількох годин.", "migration_0015_system_not_fully_up_to_date": "Ваша система не повністю оновлена. Будь ласка, виконайте регулярне оновлення перед запуском міграції на Buster.", - "migration_0015_not_enough_free_space": "Вільного місця в/var/досить мало! У вас повинно бути не менше 1 ГБ вільного місця, щоб запустити цю міграцію.", + "migration_0015_not_enough_free_space": "Вільного місця в /var/ досить мало! У вас повинно бути не менше 1 ГБ вільного місця, щоб запустити цю міграцію.", "migration_0015_not_stretch": "Поточний дистрибутив Debian не є Stretch!", - "migration_0015_yunohost_upgrade": "Починаємо оновлення ядра YunoHost...", - "migration_0015_still_on_stretch_after_main_upgrade": "Щось пішло не так під час основного поновлення, система, схоже, все ще знаходиться на Debian Stretch", - "migration_0015_main_upgrade": "Початок основного поновлення...", + "migration_0015_yunohost_upgrade": "Початок оновлення ядра YunoHost...", + "migration_0015_still_on_stretch_after_main_upgrade": "Щось пішло не так під час основного оновлення, система, схоже, все ще знаходиться на Debian Stretch", + "migration_0015_main_upgrade": "Початок основного оновлення...", "migration_0015_patching_sources_list": "Виправлення sources.lists...", "migration_0015_start": "Початок міграції на Buster", "migration_update_LDAP_schema": "Оновлення схеми LDAP...", "migration_ldap_rollback_success": "Система відкотилася.", - "migration_ldap_migration_failed_trying_to_rollback": "Не вдалося виконати міграцію... спроба відкату системи.", - "migration_ldap_can_not_backup_before_migration": "Не вдалося завершити резервне копіювання системи перед невдалої міграцією. Помилка: {error}", - "migration_ldap_backup_before_migration": "Створення резервної копії бази даних LDAP і установки застосунків перед фактичної міграцією.", - "migration_description_0020_ssh_sftp_permissions": "Додайте підтримку дозволів SSH і SFTP", + "migration_ldap_migration_failed_trying_to_rollback": "Не вдалося виконати міграцію... Пробуємо відкотити систему.", + "migration_ldap_can_not_backup_before_migration": "Не вдалося завершити резервне копіювання системи перед невдалою міграцією. Помилка: {error}", + "migration_ldap_backup_before_migration": "Створення резервної копії бази даних LDAP і налаштування застосунків перед фактичною міграцією.", + "migration_description_0020_ssh_sftp_permissions": "Додавання підтримки дозволів SSH і SFTP", "migration_description_0019_extend_permissions_features": "Розширення/переробка системи управління дозволами застосунків", "migration_description_0018_xtable_to_nftable": "Перенесення старих правил мережевого трафіку в нову систему nftable", "migration_description_0017_postgresql_9p6_to_11": "Перенесення баз даних з PostgreSQL 9.6 на 11", - "migration_description_0016_php70_to_php73_pools": "Перенесіть php7.0-fpm 'pool' conf файли на php7.3", + "migration_description_0016_php70_to_php73_pools": "Перенесення php7.0-fpm 'pool' conf файлів на php7.3", "migration_description_0015_migrate_to_buster": "Оновлення системи до Debian Buster і YunoHost 4.x", - "migrating_legacy_permission_settings": "Перенесення застарілих налаштувань дозволів...", - "main_domain_changed": "Основний домен був змінений", + "migrating_legacy_permission_settings": "Перенесення спадкових налаштувань дозволів...", + "main_domain_changed": "Основний домен було змінено", "main_domain_change_failed": "Неможливо змінити основний домен", - "mail_unavailable": "Ця електронна адреса зарезервований і буде автоматично виділено найпершого користувачеві", - "mailbox_used_space_dovecot_down": "Поштова служба Dovecot повинна бути запущена, якщо ви хочете отримати використане місце в поштовій скриньці.", - "mailbox_disabled": "Електронна пошта відключена для користувача {user}", + "mail_unavailable": "Ця е-пошта зарезервована і буде автоматично виділена найпершому користувачеві", + "mailbox_used_space_dovecot_down": "Поштова служба Dovecot повинна бути запущена, якщо ви хочете отримати використане місце в поштовій скриньці", + "mailbox_disabled": "Е-пошта вимкнена для користувача {user}", "mail_forward_remove_failed": "Не вдалося видалити переадресацію електронної пошти '{mail}'", - "mail_domain_unknown": "Неправильну адресу електронної пошти для домену '{domain}'. Будь ласка, використовуйте домен, адмініструється цим сервером.", - "mail_alias_remove_failed": "Не вдалося видалити псевдонім електронної пошти '{mail}'", - "log_tools_reboot": "перезавантажити сервер", - "log_tools_shutdown": "Вимкнути ваш сервер", + "mail_domain_unknown": "Неправильна адреса е-пошти для домену '{domain}'. Будь ласка, використовуйте домен, що адмініструється цим сервером.", + "mail_alias_remove_failed": "Не вдалося видалити аліас електронної пошти '{mail}'", + "log_tools_reboot": "Перезавантаження сервера", + "log_tools_shutdown": "Вимикання сервера", "log_tools_upgrade": "Оновлення системних пакетів", - "log_tools_postinstall": "Постінсталляція вашого сервера YunoHost", - "log_tools_migrations_migrate_forward": "запустіть міграції", - "log_domain_main_domain": "Зробити '{}' основним доменом", - "log_user_permission_reset": "Скинути дозвіл \"{} '", - "log_user_permission_update": "Оновити доступи для дозволу '{}'", - "log_user_update": "Оновити інформацію для користувача '{}'", - "log_user_group_update": "Оновити групу '{}'", - "log_user_group_delete": "Видалити групу \"{} '", - "log_user_group_create": "Створити групу '{}'", - "log_user_delete": "Видалити користувача '{}'", - "log_user_create": "Додати користувача '{}'", - "log_regen_conf": "Регенерувати системні конфігурації '{}'", - "log_letsencrypt_cert_renew": "Оновити сертифікат Let's Encrypt на домені '{}'", - "log_selfsigned_cert_install": "Встановити самоподпісанний сертифікат на домені '{}'", - "log_permission_url": "Оновити URL, пов'язаний з дозволом '{}'", - "log_permission_delete": "Видалити дозвіл \"{} '", - "log_permission_create": "Створити дозвіл \"{} '", - "log_letsencrypt_cert_install": "Встановіть сертифікат Let's Encrypt на домен '{}'", - "log_dyndns_update": "Оновити IP, пов'язаний з вашим піддоменом YunoHost '{}'", + "log_tools_postinstall": "Післявстановлення сервера YunoHost", + "log_tools_migrations_migrate_forward": "Запущено міграції", + "log_domain_main_domain": "Зроблено '{}' основним доменом", + "log_user_permission_reset": "Скинуто дозвіл \"{} '", + "log_user_permission_update": "Оновлено доступи для дозволу '{}'", + "log_user_update": "Оновлено відомості для користувача '{}'", + "log_user_group_update": "Оновлено групу '{}'", + "log_user_group_delete": "Видалено групу \"{} '", + "log_user_group_create": "Створено групу '{}'", + "log_user_delete": "Видалення користувача '{}'", + "log_user_create": "Додавання користувача '{}'", + "log_regen_conf": "Перестворення системних конфігурацій '{}'", + "log_letsencrypt_cert_renew": "Оновлення сертифікату Let's Encrypt на домені '{}'", + "log_selfsigned_cert_install": "Установлення самопідписаного сертифікату на домені '{}'", + "log_permission_url": "Оновлення URL, пов'язаногл з дозволом '{}'", + "log_permission_delete": "Видалення дозволу '{}'", + "log_permission_create": "Створення дозволу '{}'", + "log_letsencrypt_cert_install": "Установлення сертифікату Let's Encrypt на домен '{}'", + "log_dyndns_update": "Оновлення IP, пов'язаного з вашим піддоменом YunoHost '{}'", "log_dyndns_subscribe": "Підписка на піддомен YunoHost '{}'", - "log_domain_remove": "Видалити домен '{}' з конфігурації системи", - "log_domain_add": "Додати домен '{}' в конфігурацію системи", - "log_remove_on_failed_install": "Видалити '{}' після невдалої установки", - "log_remove_on_failed_restore": "Видалити '{}' після невдалого відновлення з резервного архіву", + "log_domain_remove": "Вилучення домену '{}' з конфігурації системи", + "log_domain_add": "Додавання домену '{}' в конфігурацію системи", + "log_remove_on_failed_install": "Вилучення '{}' після невдалого встановлення", + "log_remove_on_failed_restore": "Вилучення '{}' після невдалого відновлення з резервного архіву", "log_backup_restore_app": "Відновлення '{}' з архіву резервних копій", "log_backup_restore_system": "Відновлення системи з резервного архіву", "log_backup_create": "Створення резервного архіву", "log_available_on_yunopaste": "Цей журнал тепер доступний за посиланням {url}", - "log_app_config_apply": "Застосувати конфігурацію до додатка \"{} '", - "log_app_config_show_panel": "Показати панель конфігурації програми \"{} '", - "log_app_action_run": "Активації дії додатка \"{} '", - "log_app_makedefault": "Зробити '{}' додатком за замовчуванням", - "log_app_upgrade": "Оновити застосунок '{}'", - "log_app_remove": "Для видалення програми '{}'", - "log_app_install": "Встановіть застосунок '{}'", - "log_app_change_url": "Змініть URL-адресу додатка \"{} '", + "log_app_config_apply": "Застосування конфігурації до застосунку '{}'", + "log_app_config_show_panel": "Показ панелі конфігурації застосунку '{}'", + "log_app_action_run": "Запуск дії застосунку \"{} '", + "log_app_makedefault": "Застосунок '{}' зроблено типовим", + "log_app_upgrade": "Оновлення застосунку '{}'", + "log_app_remove": "Вилучення застосунку '{}'", + "log_app_install": "Установлення застосунку '{}'", + "log_app_change_url": "Змінення URL-адреси застосунку \"{} '", "log_operation_unit_unclosed_properly": "Блок операцій не був закритий належним чином", - "log_does_exists": "Немає журналу операцій з ім'ям '{log}', використовуйте 'yunohost log list', щоб подивитися всі публічні журнали операцій", - "log_help_to_get_failed_log": "Операція '{desc}' не може бути завершена. Будь ласка, поділіться повним журналом цієї операції, використовуючи команду 'yunohost log share {name}', щоб отримати допомогу.", - "log_link_to_failed_log": "Не вдалося завершити операцію '{desc}'. Будь ласка, надайте повний журнал цієї операції, натиснувши тут , щоб отримати допомогу.", - "log_help_to_get_log": "Щоб переглянути журнал операції '{desc}', використовуйте команду 'yunohost log show {name} {name}'.", - "log_link_to_log": "Повний журнал цієї операції: ' {desc} '", - "log_corrupted_md_file": "Файл метаданих YAML, пов'язаний з журналами, пошкоджений: '{md_file} Помилка: {error}'", - "iptables_unavailable": "Ви не можете грати з iptables тут. Ви перебуваєте або в контейнері, або ваше ядро не підтримує його.", - "ip6tables_unavailable": "Ви не можете грати з ip6tables тут. Ви перебуваєте або в контейнері, або ваше ядро не підтримує його.", - "invalid_regex": "Невірний regex: '{regex}'", - "installation_complete": "установка завершена", - "hook_name_unknown": "Невідоме ім'я хука '{name}'", - "hook_list_by_invalid": "Це властивість не може бути використано для перерахування хуков", + "log_does_exists": "Немає журналу операцій з назвою '{log}', використовуйте 'yunohost log list', щоб подивитися всі доступні журнали операцій", + "log_help_to_get_failed_log": "Операція '{desc}' не може бути завершена. Будь ласка, поділіться повним журналом цієї операції, використовуючи команду 'yunohost log share {name}', щоб отримати допомогу", + "log_link_to_failed_log": "Не вдалося завершити операцію '{desc}'. Будь ласка, надайте повний журнал цієї операції, натиснувши тут, щоб отримати допомогу", + "log_help_to_get_log": "Щоб переглянути журнал операції '{desc}', використовуйте команду 'yunohost log show {name}{name}'", + "log_link_to_log": "Повний журнал цієї операції: '{desc}'", + "log_corrupted_md_file": "Файл метаданих YAML, пов'язаний з журналами, пошкоджено: '{md_file}\nПомилка: {error}'", + "iptables_unavailable": "Ви не можете грати з iptables тут. Ви перебуваєте або в контейнері, або ваше ядро не підтримує його", + "ip6tables_unavailable": "Ви не можете грати з ip6tables тут. Ви перебуваєте або в контейнері, або ваше ядро не підтримує його", + "invalid_regex": "Неприпустимий regex: '{regex}'", + "installation_complete": "Установлення завершено", + "hook_name_unknown": "Невідома назва хука '{name}'", + "hook_list_by_invalid": "Цю властивість не може бути використано для перерахування хуків (гачків)", "hook_json_return_error": "Не вдалося розпізнати повернення з хука {path}. Помилка: {msg}. Необроблений контент: {raw_content}", "hook_exec_not_terminated": "Скрипт не завершився належним чином: {path}", "hook_exec_failed": "Не вдалося запустити скрипт: {path}", "group_user_not_in_group": "Користувач {user} не входить в групу {group}", "group_user_already_in_group": "Користувач {user} вже в групі {group}", "group_update_failed": "Не вдалося оновити групу '{group}': {error}", - "group_updated": "Група '{group}' оновлена", - "group_unknown": "Група '{group}' невідома.", + "group_updated": "Групу '{group}' оновлено", + "group_unknown": "Група '{group}' невідома", "group_deletion_failed": "Не вдалося видалити групу '{group}': {error}", - "group_deleted": "Група '{group}' вилучена", + "group_deleted": "Групу '{group}' видалено", "group_cannot_be_deleted": "Група {group} не може бути видалена вручну.", - "group_cannot_edit_primary_group": "Група '{group}' не може бути відредаговано вручну. Це основна група, призначена тільки для одного конкретного користувача.", - "group_cannot_edit_visitors": "Група 'visitors' не може бути відредаговано вручну. Це спеціальна група, що представляє анонімних відвідувачів.", - "group_cannot_edit_all_users": "Група 'all_users' не може бути відредаговано вручну. Це спеціальна група, призначена для всіх користувачів, зареєстрованих в YunoHost.", - "group_creation_failed": "Не вдалося створити групу \"{group} ': {error}", - "group_created": "Група '{group}' створена", - "group_already_exist_on_system_but_removing_it": "Група {group} вже існує в групах системи, але YunoHost видалить її...", + "group_cannot_edit_primary_group": "Група '{group}' не може бути відредагована вручну. Це основна група, призначена тільки для одного конкретного користувача.", + "group_cannot_edit_visitors": "Група 'visitors' не може бути відредагована вручну. Це спеціальна група, що представляє анонімних відвідувачів", + "group_cannot_edit_all_users": "Група 'all_users' не може бути відредагована вручну. Це спеціальна група, призначена для всіх користувачів, зареєстрованих в YunoHost", + "group_creation_failed": "Не вдалося створити групу '{group}': {error}", + "group_created": "Групу '{group}' створено", + "group_already_exist_on_system_but_removing_it": "Група {group} вже існує в групах системи, але YunoHost вилучить її...", "group_already_exist_on_system": "Група {group} вже існує в групах системи", "group_already_exist": "Група {group} вже існує", - "good_practices_about_user_password": "Зараз ви маєте визначити новий пароль користувача. Пароль повинен складатися не менше ніж з 8 символів, але хорошою практикою є використання більш довгого пароля (тобто парольної фрази) і/або використання різних символів (заголовних, малих, цифр і спеціальних символів).", - "good_practices_about_admin_password": "Зараз ви збираєтеся поставити новий пароль адміністратора. Пароль повинен складатися не менше ніж з 8 символів, але хорошою практикою є використання більш довгого пароля (тобто парольної фрази) і/або використання різних символів (прописних, малих, цифр і спеціальних символів).", - "global_settings_unknown_type": "Несподівана ситуація, параметр {setting} має тип {unknown_type}, але це не тип, підтримуваний системою.", - "global_settings_setting_backup_compress_tar_archives": "При створенні нових резервних копій стискати архіви (.tar.gz) замість незжатих архівів (.tar). NB: включення цієї опції означає створення більш легких архівів резервних копій, але початкова процедура резервного копіювання буде значно довше і важче для CPU.", - "global_settings_setting_security_webadmin_allowlist": "IP-адреси, яким дозволений доступ до веб-адміну. Через кому.", - "global_settings_setting_security_webadmin_allowlist_enabled": "Дозволити доступ до веб-адміну тільки деяким IP-адресами.", + "good_practices_about_user_password": "Зараз ви збираєтеся поставити новий пароль користувача. Пароль повинен складатися не менше ніж з 8 символів, але хорошою практикою є використання більш довгого пароля (тобто гасла) і/або використання різних символів (великих, малих, цифр і спеціальних символів).", + "good_practices_about_admin_password": "Зараз ви збираєтеся поставити новий пароль адміністратора. Пароль повинен складатися не менше ніж з 8 символів, але хорошою практикою є використання більш довгого пароля (тобто парольного гасла) і/або використання різних символів (великих, малих, цифр і спеціальних символів).", + "global_settings_unknown_type": "Несподівана ситуація, налаштування {setting} має тип {unknown_type}, але це не тип, підтримуваний системою.", + "global_settings_setting_backup_compress_tar_archives": "При створенні нових резервних копій стискати архіви (.tar.gz) замість нестислих архівів (.tar). NB: вмикання цієї опції означає створення легших архівів резервних копій, але початкова процедура резервного копіювання буде значно довшою і важчою для CPU.", + "global_settings_setting_security_webadmin_allowlist": "IP-адреси, яким дозволений доступ до вебадміністратора. Через кому.", + "global_settings_setting_security_webadmin_allowlist_enabled": "Дозволити доступ до вебадміністратора тільки деяким IP-адресам.", "global_settings_setting_smtp_relay_password": "Пароль хоста SMTP-ретрансляції", - "global_settings_setting_smtp_relay_user": "Обліковий запис користувача SMTP-реле", - "global_settings_setting_smtp_relay_port": "Порт SMTP-реле", - "global_settings_setting_smtp_relay_host": "SMTP релейний хост, який буде використовуватися для відправки пошти замість цього примірника yunohost. Корисно, якщо ви знаходитеся в одній із цих ситуацій: ваш 25 порт заблокований вашим провайдером або VPS провайдером, у вас є житловий IP в списку DUHL, ви не можете налаштувати зворотний DNS або цей сервер не доступний безпосередньо в інтернеті і ви хочете використовувати інший сервер для відправки пошти.", - "global_settings_setting_smtp_allow_ipv6": "Дозволити використання IPv6 для отримання і відправки пошти", - "global_settings_setting_ssowat_panel_overlay_enabled": "Включити накладення панелі SSOwat", + "global_settings_setting_smtp_relay_user": "Обліковий запис користувача SMTP-ретрансляції", + "global_settings_setting_smtp_relay_port": "Порт SMTP-ретрансляції", + "global_settings_setting_smtp_relay_host": "Хост SMTP-ретрансляції, який буде використовуватися для надсилання е-пошти замість цього зразка Yunohost. Корисно, якщо ви знаходитеся в одній із цих ситуацій: ваш 25 порт заблокований вашим провайдером або VPS провайдером, у вас є житловий IP в списку DUHL, ви не можете налаштувати зворотний DNS або цей сервер не доступний безпосередньо в Інтернеті і ви хочете використовувати інший сервер для відправки електронних листів.", + "global_settings_setting_smtp_allow_ipv6": "Дозволити використання IPv6 для отримання і надсилання листів е-пошти", + "global_settings_setting_ssowat_panel_overlay_enabled": "Увімкнути накладення панелі SSOwat", "global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Дозволити використання (застарілого) ключа DSA для конфігурації демона SSH", - "global_settings_unknown_setting_from_settings_file": "Невідомий ключ в настройках: '{setting_key}', відкиньте його і збережіть в /etc/yunohost/settings-unknown.json", + "global_settings_unknown_setting_from_settings_file": "Невідомий ключ в налаштуваннях: '{setting_key}', відхиліть його і збережіть у /etc/yunohost/settings-unknown.json", "global_settings_setting_security_ssh_port": "SSH-порт", "global_settings_setting_security_postfix_compatibility": "Компроміс між сумісністю і безпекою для сервера Postfix. Впливає на шифри (і інші аспекти, пов'язані з безпекою)", - "global_settings_setting_security_ssh_compatibility": "Сумісність і співвідношення безпеки для SSH-сервера. Впливає на шифри (і інші аспекти, пов'язані з безпекою)", + "global_settings_setting_security_ssh_compatibility": "Компроміс між сумісністю і безпекою для SSH-сервера. Впливає на шифри (і інші аспекти, пов'язані з безпекою)", "global_settings_setting_security_password_user_strength": "Надійність пароля користувача", "global_settings_setting_security_password_admin_strength": "Надійність пароля адміністратора", - "global_settings_setting_security_nginx_compatibility": "Компроміс між сумісністю і безпекою для веб-сервера NGINX. Впливає на шифри (і інші аспекти, пов'язані з безпекою)", - "global_settings_setting_pop3_enabled": "Включити протокол POP3 для поштового сервера.", - "global_settings_reset_success": "Попередні настройки тепер збережені в {path}.", - "global_settings_key_doesnt_exists": "Ключ '{settings_key}' не існує в глобальних налаштуваннях, ви можете побачити всі доступні ключі, виконавши команду 'yunohost settings list'.", - "global_settings_cant_write_settings": "Неможливо зберегти файл настройок, причина: {reason}", - "global_settings_cant_serialize_settings": "Не вдалося серіалізовать дані налаштувань, причина: {reason}", - "global_settings_cant_open_settings": "Не вдалося відкрити файл настройок, причина: {reason}", - "global_settings_bad_type_for_setting": "Поганий тип для настройки {setting}, отриманий {received_type}, очікується {expected_type}", - "global_settings_bad_choice_for_enum": "Поганий вибір для настройки {setting}, отримано '{choice}', але доступні наступні варіанти: {available_choices}.", - "firewall_rules_cmd_failed": "Деякі команди правил брандмауера не спрацювали. Більш детальна інформація в журналі.", - "firewall_reloaded": "брандмауер перезавантажений", - "firewall_reload_failed": "Не вдалося перезавантажити брандмауер", + "global_settings_setting_security_nginx_compatibility": "Компроміс між сумісністю і безпекою для вебсервера NGINX. Впливає на шифри (і інші аспекти, пов'язані з безпекою)", + "global_settings_setting_pop3_enabled": "Увімкніть протокол POP3 для поштового сервера", + "global_settings_reset_success": "Попередні налаштування тепер збережені в {path}", + "global_settings_key_doesnt_exists": "Ключ '{settings_key}' не існує в глобальних налаштуваннях, ви можете побачити всі доступні ключі, виконавши команду 'yunohost settings list'", + "global_settings_cant_write_settings": "Неможливо зберегти файл налаштувань, причина: {reason}", + "global_settings_cant_serialize_settings": "Не вдалося серіалізувати дані налаштувань, причина: {reason}", + "global_settings_cant_open_settings": "Не вдалося відкрити файл налаштувань, причина: {reason}", + "global_settings_bad_type_for_setting": "Поганий тип для налаштування {setting}, отримано {received_type}, а очікується {expected_type}", + "global_settings_bad_choice_for_enum": "Поганий вибір для налаштування {setting}, отримано '{choice}', але доступні наступні варіанти: {available_choices}", + "firewall_rules_cmd_failed": "Деякі команди правил фаєрвола не спрацювали. Подробиці в журналі.", + "firewall_reloaded": "Фаєрвол перезавантажено", + "firewall_reload_failed": "Не вдалося перезавантажити фаєрвол", "file_does_not_exist": "Файл {path} не існує.", "field_invalid": "Неприпустиме поле '{}'", "experimental_feature": "Попередження: Ця функція є експериментальною і не вважається стабільною, ви не повинні використовувати її, якщо не знаєте, що робите.", - "extracting": "Витяг...", + "extracting": "Витягнення...", "dyndns_unavailable": "Домен '{domain}' недоступний.", "dyndns_domain_not_provided": "DynDNS провайдер {provider} не може надати домен {domain}.", - "dyndns_registration_failed": "Не вдалося зареєструвати домен DynDNS: {error}.", - "dyndns_registered": "Домен DynDNS зареєстрований", - "dyndns_provider_unreachable": "Неможливо зв'язатися з провайдером DynDNS {provider}: або ваш YunoHost неправильно підключений до інтернету, або сервер dynette не працює.", - "dyndns_no_domain_registered": "Домен не зареєстрований в DynDNS", - "dyndns_key_not_found": "DNS-ключ не знайдений для домену", - "dyndns_key_generating": "Генерація DNS-ключа... Це може зайняти деякий час.", - "dyndns_ip_updated": "Оновлення свій IP-адресу в DynDNS", - "dyndns_ip_update_failed": "Не вдалося оновити IP-адреса в DynDNS", - "dyndns_could_not_check_available": "Не вдалося перевірити наявність певної {domain} на {provider}.", + "dyndns_registration_failed": "Не вдалося зареєструвати домен DynDNS: {error}", + "dyndns_registered": "Домен DynDNS зареєстровано", + "dyndns_provider_unreachable": "Неможливо зв'язатися з провайдером DynDNS {provider}: або ваш YunoHost неправильно під'єднано до Інтернету, або сервер dynette не працює.", + "dyndns_no_domain_registered": "Домен не зареєстровано в DynDNS", + "dyndns_key_not_found": "DNS-ключ для домену не знайдено", + "dyndns_key_generating": "Утворення DNS-ключа... Це може зайняти деякий час.", + "dyndns_ip_updated": "Вашу IP-адресу в DynDNS оновлено", + "dyndns_ip_update_failed": "Не вдалося оновити IP-адресу в DynDNS", + "dyndns_could_not_check_available": "Не вдалося перевірити, чи {domain} доступний у {provider}.", "dyndns_could_not_check_provide": "Не вдалося перевірити, чи може {provider} надати {domain}.", - "dpkg_lock_not_available": "Ця команда не може бути виконана прямо зараз, тому що інша програма, схоже, використовує блокування dpkg (системного менеджера пакетів).", - "dpkg_is_broken": "Ви не можете зробити це прямо зараз, тому що dpkg/APT (системні менеджери пакетів), схоже, знаходяться в зламаному стані... Ви можете спробувати вирішити цю проблему, підключившись через SSH і виконавши `sudo apt install --fix-broken` і/або `sudo dpkg --configure -a`.", + "dpkg_lock_not_available": "Ця команда не може бути виконана прямо зараз, тому що інша програма, схоже, використовує блокування dpkg (системного менеджера пакетів)", + "dpkg_is_broken": "Ви не можете зробити це прямо зараз, тому що dpkg/APT (системні менеджери пакетів), схоже, знаходяться в зламаному стані... Ви можете спробувати вирішити цю проблему, під'єднавшись через SSH і виконавши `sudo apt install --fix-broken` та/або `sudo dpkg --configure -a`.", "downloading": "Завантаження…", "done": "Готово", "domains_available": "Доступні домени:", - "domain_unknown": "невідомий домен", + "domain_unknown": "Невідомий домен", "domain_name_unknown": "Домен '{domain}' невідомий", - "domain_uninstall_app_first": "Ці додатки все ще встановлені на вашому домені: {apps} ласка, видаліть їх за допомогою 'yunohost app remove the_app_id' або перемістити їх на інший домен за допомогою 'yunohost app change-url the_app_id', перш ніж приступити до видалення домену.", - "domain_remove_confirm_apps_removal": "Видалення цього домену призведе до видалення цих застосунків: {apps} Ви впевнені, що хочете це зробити? [{answers}].", - "domain_hostname_failed": "Неможливо встановити нове ім'я хоста. Це може викликати проблеми в подальшому (можливо, все буде в порядку).", - "domain_exists": "Домен вже існує", - "domain_dyndns_root_unknown": "Невідомий кореневої домен DynDNS", + "domain_uninstall_app_first": "Ці застосунки все ще встановлені на вашому домені:\n{apps}\n\nВидаліть їх за допомогою 'yunohost app remove the_app_id' або перемістіть їх на інший домен за допомогою 'yunohost app change-url the_app_id', перш ніж приступити до вилучення домену", + "domain_remove_confirm_apps_removal": "Вилучення цього домену призведе до вилучення таких застосунків:\n{apps}\n\nВи впевнені, що хочете це зробити? [{answers}]", + "domain_hostname_failed": "Неможливо встановити нову назву хоста. Це може викликати проблеми в подальшому (можливо, все буде в порядку).", + "domain_exists": "Цей домен уже існує", + "domain_dyndns_root_unknown": "Невідомий кореневий домен DynDNS", "domain_dyndns_already_subscribed": "Ви вже підписалися на домен DynDNS", - "domain_dns_conf_is_just_a_recommendation": "Ця команда показує * рекомендовану * конфігурацію. Насправді вона не встановлює конфігурацію DNS для вас. Ви самі повинні налаштувати свою зону DNS у реєстратора відповідно до цих рекомендацій.", + "domain_dns_conf_is_just_a_recommendation": "Ця команда показує *рекомендовану* конфігурацію. Насправді вона не встановлює конфігурацію DNS для вас. Ви самі повинні налаштувати свою зону DNS у реєстратора відповідно до цих рекомендацій.", "domain_deletion_failed": "Неможливо видалити домен {domain}: {error}", - "domain_deleted": "домен видалений", + "domain_deleted": "Домен видалено", "domain_creation_failed": "Неможливо створити домен {domain}: {error}", - "domain_created": "домен створений", - "domain_cert_gen_failed": "Не вдалося згенерувати сертифікат", - "domain_cannot_remove_main_add_new_one": "Ви не можете видалити '{domain}', так як це основний домен і ваш єдиний домен, вам потрібно спочатку додати інший домен за допомогою 'yunohost domain add ', потім встановити його як основний домен за допомогою ' yunohost domain main-domain -n 'і потім ви можете видалити домен' {domain} 'за допомогою' yunohost domain remove {domain} ''.", - "domain_cannot_add_xmpp_upload": "Ви не можете додавати домени, що починаються з 'xmpp-upload.'. Таке ім'я зарезервовано для функції XMPP upload, вбудованої в YunoHost.", - "domain_cannot_remove_main": "Ви не можете видалити '{domain}', так як це основний домен, спочатку вам потрібно встановити інший домен в якості основного за допомогою 'yunohost domain main-domain -n '; ось список доменів-кандидатів: {other_domains}", - "disk_space_not_sufficient_update": "Недостатньо місця на диску для поновлення цього додатка", - "disk_space_not_sufficient_install": "Бракує місця на диску для установки цього додатка", - "diagnosis_sshd_config_inconsistent_details": "Будь ласка, виконайте yunohost settings set security.ssh.port -v YOUR_SSH_PORT , щоб визначити порт SSH, і перевірте yunohost tools regen-conf ssh --dry-run --with-diff yunohost tools regen-conf ssh --force , щоб скинути ваш conf на рекомендований YunoHost.", - "diagnosis_sshd_config_inconsistent": "Схоже, що порт SSH був вручну змінений в/etc/ssh/sshd_config. Починаючи з версії YunoHost 4.2, доступний новий глобальний параметр 'security.ssh.port', що дозволяє уникнути ручного редагування конфігурації.", + "domain_created": "Домен створено", + "domain_cert_gen_failed": "Не вдалося утворити сертифікат", + "domain_cannot_remove_main_add_new_one": "Ви не можете видалити '{domain}', так як це основний домен і ваш єдиний домен, вам потрібно спочатку додати інший домен за допомогою 'yunohost domain add ', потім встановити його як основний домен за допомогою 'yunohost domain main-domain -n ' і потім ви можете вилучити домен '{domain}' за допомогою 'yunohost domain remove {domain}'.'", + "domain_cannot_add_xmpp_upload": "Ви не можете додавати домени, що починаються з 'xmpp-upload.'. Таку назву зарезервовано для функції XMPP upload, вбудованої в YunoHost.", + "domain_cannot_remove_main": "Ви не можете вилучити '{domain}', бо це основний домен, спочатку вам потрібно встановити інший домен в якості основного за допомогою 'yunohost domain main-domain -n '; ось список доменів-кандидатів: {other_domains}", + "disk_space_not_sufficient_update": "Недостатньо місця на диску для оновлення цього застосунку", + "disk_space_not_sufficient_install": "Недостатньо місця на диску для встановлення цього застосунку", + "diagnosis_sshd_config_inconsistent_details": "Будь ласка, виконайте команду yunohost settings set security.ssh.port -v YOUR_SSH_PORT, щоб визначити порт SSH, і перевіртеyunohost tools regen-conf ssh --dry-run --with-diff і yunohost tools regen-conf ssh --force, щоб скинути ваш конфіг на рекомендований YunoHost.", + "diagnosis_sshd_config_inconsistent": "Схоже, що порт SSH був уручну змінений в /etc/ssh/sshd_config. Починаючи з версії YunoHost 4.2, доступний новий глобальний параметр 'security.ssh.port', що дозволяє уникнути ручного редагування конфігурації.", "diagnosis_sshd_config_insecure": "Схоже, що конфігурація SSH була змінена вручну і є небезпечною, оскільки не містить директив 'AllowGroups' або 'AllowUsers' для обмеження доступу авторизованих користувачів.", - "diagnosis_processes_killed_by_oom_reaper": "Деякі процеси були недавно вбито системою через брак пам'яті. Зазвичай це є симптомом нестачі пам'яті в системі або процесу, який з'їв дуже багато пам'яті. Зведення убитих процесів: {kills_summary}", - "diagnosis_never_ran_yet": "Схоже, що цей сервер був налаштований недавно, і поки немає звіту про діагностику. Вам слід почати з повної діагностики, або з веб-адміністратора, або використовуючи 'yunohost diagnosis run' з командного рядка.", + "diagnosis_processes_killed_by_oom_reaper": "Деякі процеси було недавно вбито системою через брак пам'яті. Зазвичай це є симптомом нестачі пам'яті в системі або процесу, який з'їв дуже багато пам'яті. Зведення убитих процесів:\n{kills_summary}", + "diagnosis_never_ran_yet": "Схоже, що цей сервер був налаштований недавно, і поки немає звіту про діагностику. Вам слід почати з повної діагностики, або з вебадміністратора, або використовуючи 'yunohost diagnosis run' з командного рядка.", "diagnosis_unknown_categories": "Наступні категорії невідомі: {categories}", - "diagnosis_http_nginx_conf_not_up_to_date_details": "Щоб виправити ситуацію, перевірте різницю за допомогою командного рядка, використовуючи yunohost tools regen-conf nginx --dry-run --with-diff , і якщо все в порядку, застосуйте зміни за допомогою yunohost tools regen-conf nginx --force .", + "diagnosis_http_nginx_conf_not_up_to_date_details": "Щоб виправити становище, перевірте різницю за допомогою командного рядка, використовуючи yunohost tools regen-conf nginx --dry-run --with-diff, і якщо все в порядку, застосуйте зміни за допомогою команди yunohost tools regen-conf nginx --force.", "diagnosis_http_nginx_conf_not_up_to_date": "Схоже, що конфігурація nginx цього домену була змінена вручну, що не дозволяє YunoHost визначити, чи доступний він по HTTP.", - "diagnosis_http_partially_unreachable": "Домен {domain} здається недоступним по HTTP ззовні локальної мережі в IPv {failed}, хоча він працює в IPv {passed}.", - "diagnosis_http_unreachable": "Домен {domain} здається недоступним через HTTP ззовні локальної мережі.", - "diagnosis_http_bad_status_code": "Схоже, що замість вашого сервера відповіла інша машина (можливо, ваш маршрутизатор).
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлений на ваш сервер .
2. На більш складних установках: переконайтеся, що немає брандмауера або зворотного проксі.", - "diagnosis_http_connection_error": "Помилка підключення: не вдалося підключитися до запитуваного домену, швидше за все, він недоступний.", + "diagnosis_http_partially_unreachable": "Домен {domain} здається недоступним по HTTP поза локальною мережею в IPv{failed}, хоча він працює в IPv{passed}.", + "diagnosis_http_unreachable": "Домен {domain} здається недоступним через HTTP поза локальною мережею.", + "diagnosis_http_bad_status_code": "Схоже, що замість вашого сервера відповіла інша машина (можливо, ваш маршрутизатор).
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлено на ваш сервер .
2. На більш складних установках: переконайтеся, що немає фаєрвола або зворотного проксі.", + "diagnosis_http_connection_error": "Помилка з'єднання: не вдалося з'єднатися із запитуваним доменом, швидше за все, він недоступний.", "diagnosis_http_timeout": "При спробі зв'язатися з вашим сервером ззовні стався тайм-аут. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 80 (і 443) неправильно перенаправлено на ваш сервер .
2. Ви також повинні переконатися, що служба nginx запущена
3.На більш складних установках: переконайтеся, що немає фаєрвола або зворотного проксі.", "diagnosis_http_ok": "Домен {domain} доступний по HTTP поза локальною мережею.", "diagnosis_http_localdomain": "Домен {domain} з .local TLD не може бути доступний ззовні локальної мережі.", "diagnosis_http_could_not_diagnose_details": "Помилка: {error}", "diagnosis_http_could_not_diagnose": "Не вдалося діагностувати досяжність доменів ззовні в IPv{ipversion}.", - "diagnosis_http_hairpinning_issue_details": "Можливо, це пов'язано з коробкою/маршрутизатором вашого інтернет-провайдера. В результаті, люди ззовні вашої локальної мережі зможуть отримати доступ до вашого сервера, як і очікувалося, але не люди зсередини локальної мережі (як ви, ймовірно?) При використанні доменного імені або глобального IP. Можливо, ви зможете поліпшити ситуацію, глянувши https://yunohost.org/dns_local_network .", + "diagnosis_http_hairpinning_issue_details": "Можливо, це пов'язано з коробкою/маршрутизатором вашого інтернет-провайдера. В результаті, люди ззовні вашої локальної мережі зможуть отримати доступ до вашого сервера, як і очікувалося, але не люди зсередини локальної мережі (як ви, ймовірно?) При використанні доменного імені або глобального IP. Можливо, ви зможете поліпшити ситуацію, глянувши https://yunohost.org/dns_local_network ", "diagnosis_http_hairpinning_issue": "Схоже, що у вашій локальній мережі не увімкнено шпилькування (hairpinning).", - "diagnosis_ports_forwarding_tip": "Щоб вирішити цю проблему, вам, швидше за все, потрібно налаштувати пересилання портів на вашому інтернет-маршрутизаторі, як описано в https://yunohost.org/isp_box_config.", - "diagnosis_ports_needed_by": "Відкриття цього порту необхідне для функцій {category} (служба {service}).", + "diagnosis_ports_forwarding_tip": "Щоб вирішити цю проблему, вам, швидше за все, потрібно налаштувати пересилання портів на вашому інтернет-маршрутизаторі, як описано в https://yunohost.org/isp_box_config", + "diagnosis_ports_needed_by": "Відкриття цього порту необхідне для функцій {category} (служба {service})", "diagnosis_ports_ok": "Порт {port} доступний ззовні.", "diagnosis_ports_partially_unreachable": "Порт {port} не доступний ззовні в IPv{failed}.", "diagnosis_ports_unreachable": "Порт {port} недоступний ззовні.", @@ -382,24 +382,24 @@ "diagnosis_description_ip": "Інтернет-з'єднання", "diagnosis_description_basesystem": "Основна система", "diagnosis_security_vulnerable_to_meltdown_details": "Щоб виправити це, вам слід оновити систему і перезавантажитися, щоб завантажити нове ядро Linux (або звернутися до вашого серверного провайдера, якщо це не спрацює). Докладніше див. на сайті https://meltdownattack.com/.", - "diagnosis_security_vulnerable_to_meltdown": "Схоже, що ви вразливі до критичної вразливості безпеки Meltdown.", + "diagnosis_security_vulnerable_to_meltdown": "Схоже, що ви вразливі до критичної вразливості безпеки Meltdown", "diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {space}, що дуже тривожно! Скоріше за все, дисковий простір закінчиться дуже скоро! Рекомендовано мати не менше 16 ГБ для кореневої файлової системи.", "diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {space}. Можливо це нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендовано мати не менше 16 ГБ для кореневої файлової системи.", - "diagnosis_regenconf_manually_modified_details": "Можливо це нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що оновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою команди yunohost tools regen-conf {category} --force.", + "diagnosis_regenconf_manually_modified_details": "Можливо це нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що оновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою команди yunohost tools regen-conf {category} --force", "diagnosis_regenconf_manually_modified": "Конфігураційний файл {file}, схоже, було змінено вручну.", "diagnosis_regenconf_allgood": "Усі конфігураційні файли відповідають рекомендованій конфігурації!", "diagnosis_mail_queue_too_big": "Занадто багато відкладених листів у поштовій черзі (листів: {nb_pending})", "diagnosis_mail_queue_unavailable_details": "Помилка: {error}", "diagnosis_mail_queue_unavailable": "Неможливо дізнатися кількість очікувальних листів у черзі", "diagnosis_mail_queue_ok": "Відкладених електронних листів у поштових чергах: {nb_pending}", - "diagnosis_mail_blacklist_website": "Після визначення причини, з якої ви потрапили в чорний список, і її усунення, ви можете попросити видалити ваш IP або домен на {blacklist_website}.", + "diagnosis_mail_blacklist_website": "Після визначення причини, з якої ви потрапили в чорний список, і її усунення, ви можете попросити видалити ваш IP або домен на {blacklist_website}", "diagnosis_mail_blacklist_reason": "Причина внесення в чорний список: {reason}", - "diagnosis_mail_blacklist_listed_by": "Ваш IP або домен {item} знаходиться в чорному списку {blacklist_name}.", + "diagnosis_mail_blacklist_listed_by": "Ваш IP або домен {item} знаходиться в чорному списку {blacklist_name}", "diagnosis_mail_blacklist_ok": "IP-адреси і домени, які використовуються цим сервером, не внесені в чорний список", - "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Поточний зворотний DNS:{rdns_domain}
Очікуване значення: {ehlo_domain}.", + "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Поточний зворотний DNS:{rdns_domain}
Очікуване значення: {ehlo_domain}", "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Зворотний DNS неправильно налаштований в IPv{ipversion}. Деякі електронні листи можуть бути не доставлені або можуть бути відзначені як спам.", "diagnosis_mail_fcrdns_nok_alternatives_6": "Деякі провайдери не дозволять вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ваш зворотний DNS правильно налаштований для IPv4, ви можете спробувати вимкнути використання IPv6 при надсиланні листів, виконавши команду yunohost settings set smtp.allow_ipv6 -v off. Примітка: останнє рішення означає, що ви не зможете надсилати або отримувати електронні листи з нечисленних серверів, що використовують тільки IPv6.", - "diagnosis_mail_fcrdns_nok_alternatives_4": "Деякі провайдери не дозволять вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ви відчуваєте проблеми через це, розгляньте наступні рішення:
- Деякі провайдери надають альтернативу використання ретранслятора поштового сервера, хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN *з виділеним загальнодоступним IP* для обходу подібних обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Або можна переключитися на іншого провайдера .", + "diagnosis_mail_fcrdns_nok_alternatives_4": "Деякі провайдери не дозволять вам налаштувати зворотний DNS (або їх функція може бути зламана...). Якщо ви відчуваєте проблеми через це, розгляньте наступні рішення:
- Деякі провайдери надають альтернативу використання ретранслятора поштового сервера, хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN *з виділеним загальнодоступним IP* для обходу подібних обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Або можна переключитися на іншого провайдера", "diagnosis_mail_fcrdns_nok_details": "Спочатку спробуйте налаштувати зворотний DNS з {ehlo_domain} в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм запит у підтримку для цього).", "diagnosis_mail_fcrdns_dns_missing": "У IPv{ipversion} не визначений зворотний DNS. Деякі листи можуть не доставлятися або позначатися як спам.", "diagnosis_mail_fcrdns_ok": "Ваш зворотний DNS налаштовано правильно!", @@ -408,63 +408,63 @@ "diagnosis_mail_ehlo_wrong_details": "EHLO, отриманий віддаленим діагностичним центром в IPv{ipversion}, відрізняється від домену вашого сервера.
Отриманий EHLO: {wrong_ehlo}
Очікуваний: {right_ehlo}< br>Найпоширенішою причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер. Крім того, переконайтеся, що в роботу сервера не втручається фаєрвол або зворотний проксі-сервер.", "diagnosis_mail_ehlo_wrong": "Інший поштовий SMTP-сервер відповідає на IPv{ipversion}. Ваш сервер, ймовірно, не зможе отримувати електронні листи.", "diagnosis_mail_ehlo_bad_answer_details": "Це може бути викликано тим, що замість вашого сервера відповідає інша машина.", - "diagnosis_mail_ehlo_bad_answer": "Не-SMTP служба відповіла на порту 25 на IPv{ipversion}.", + "diagnosis_mail_ehlo_bad_answer": "Не-SMTP служба відповіла на порту 25 на IPv{ipversion}", "diagnosis_mail_ehlo_unreachable_details": "Не вдалося відкрити з'єднання за портом 25 з вашим сервером на IPv{ipversion}. Він здається недоступним.
1. Найбільш поширеною причиною цієї проблеми є те, що порт 25 неправильно перенаправлений на ваш сервер.
2. Ви також повинні переконатися, що служба postfix запущена.
3. На більш складних установках: переконайтеся, що немає фаєрвола або зворотного проксі.", "diagnosis_mail_ehlo_unreachable": "Поштовий сервер SMTP недоступний ззовні по IPv{ipversion}. Він не зможе отримувати листи електронної пошти.", "diagnosis_mail_ehlo_ok": "Поштовий сервер SMTP доступний ззовні і тому може отримувати електронні листи!", - "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Деякі провайдери не дозволять вам розблокувати вихідний порт 25, тому що вони не піклуються про мережевий нейтралітет (Net Neutrality).
- Деякі з них пропонують альтернативу використання ретранслятора поштового сервера, хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN *з виділеним загальнодоступним IP* для обходу такого роду обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Ви також можете розглянути можливість переходу на більш дружнього до мережевого нейтралітету провайдера.", + "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Деякі провайдери не дозволять вам розблокувати вихідний порт 25, тому що вони не піклуються про мережевий нейтралітет (Net Neutrality).
- Деякі з них пропонують альтернативу використання ретранслятора поштового сервера, хоча це має на увазі, що ретранслятор зможе шпигувати за вашим поштовим трафіком.
- Альтернативою для захисту конфіденційності є використання VPN *з виділеним загальнодоступним IP* для обходу такого роду обмежень. Дивіться https://yunohost.org/#/vpn_advantage
- Ви також можете розглянути можливість переходу на більш дружнього до мережевого нейтралітету провайдера", "diagnosis_mail_outgoing_port_25_blocked_details": "Спочатку спробуйте розблокувати вихідний порт 25 в інтерфейсі вашого інтернет-маршрутизатора або в інтерфейсі вашого хостинг-провайдера. (Деякі хостинг-провайдери можуть вимагати, щоб ви відправили їм заявку в службу підтримки).", "diagnosis_mail_outgoing_port_25_blocked": "Поштовий сервер SMTP не може відправляти електронні листи на інші сервери, оскільки вихідний порт 25 заблоковано в IPv{ipversion}.", "app_manifest_install_ask_path": "Оберіть шлях URL (після домену), за яким має бути встановлено цей застосунок", - "yunohost_postinstall_end_tip": "Постінсталляція завершена! Щоб завершити установку, будь ласка, розгляньте наступні варіанти: - додавання першого користувача через розділ 'Користувачі' веб-адміністратора (або 'yunohost user create ' в командному рядку); - діагностику можливих проблем через розділ 'Діагностика' веб-адміністратора (або 'yunohost diagnosis run' в командному рядку); - читання розділів 'Завершення установки' і 'Знайомство з YunoHost' в документації адміністратора: https://yunohost.org/admindoc.", - "yunohost_not_installed": "YunoHost встановлений неправильно. Будь ласка, запустіть 'yunohost tools postinstall'.", + "yunohost_postinstall_end_tip": "Післявстановлення завершено! Щоб завершити доналаштування, будь ласка, розгляньте наступні варіанти:\n - додавання першого користувача через розділ 'Користувачі' вебадміністратора (або 'yunohost user create ' в командному рядку);\n - діагностика можливих проблем через розділ 'Діагностика' вебадміністратора (або 'yunohost diagnosis run' в командному рядку);\n - прочитання розділів 'Завершення встановлення' і 'Знайомство з YunoHost' у документації адміністратора: https://yunohost.org/admindoc.", + "yunohost_not_installed": "YunoHost установлений неправильно. Будь ласка, запустіть 'yunohost tools postinstall'", "yunohost_installing": "Установлення YunoHost...", - "yunohost_configured": "YunoHost вже налаштований", + "yunohost_configured": "YunoHost вже налаштовано", "yunohost_already_installed": "YunoHost вже встановлено", - "user_updated": "Інформація про користувача змінена", + "user_updated": "Відомості про користувача змінено", "user_update_failed": "Не вдалося оновити користувача {user}: {error}", "user_unknown": "Невідомий користувач: {user}", - "user_home_creation_failed": "Не вдалося створити домашню папку для користувача", + "user_home_creation_failed": "Не вдалося створити каталог домівки для користувача", "user_deletion_failed": "Не вдалося видалити користувача {user}: {error}", - "user_deleted": "користувача видалено", + "user_deleted": "Користувача видалено", "user_creation_failed": "Не вдалося створити користувача {user}: {error}", - "user_created": "Аккаунт було створено", + "user_created": "Користувача створено", "user_already_exists": "Користувач '{user}' вже існує", "upnp_port_open_failed": "Не вдалося відкрити порт через UPnP", - "upnp_enabled": "UPnP включено", + "upnp_enabled": "UPnP увімкнено", "upnp_disabled": "UPnP вимкнено", - "upnp_dev_not_found": "UPnP-пристрій, не знайдено", + "upnp_dev_not_found": "UPnP-пристрій не знайдено", "upgrading_packages": "Оновлення пакетів...", - "upgrade_complete": "оновлення завершено", - "updating_apt_cache": "Вибірка доступних оновлень для системних пакетів...", - "update_apt_cache_warning": "Щось пішло не так при оновленні кеша APT (менеджера пакунків Debian). Ось дамп рядків sources.list, який може допомогти визначити проблемні рядки: {sourceslist}", - "update_apt_cache_failed": "Неможливо оновити кеш APT (менеджер пакетів Debian). Ось дамп рядків sources.list, який може допомогти визначити проблемні рядки: {sourceslist}", - "unrestore_app": "{app} не буде поновлено", - "unlimit": "немає квоти", + "upgrade_complete": "Оновлення завершено", + "updating_apt_cache": "Завантаження доступних оновлень для системних пакетів...", + "update_apt_cache_warning": "Щось пішло не так при оновленні кеша APT (менеджера пакунків Debian). Ось дамп рядків sources.list, який може допомогти визначити проблемні рядки:\n{sourceslist}", + "update_apt_cache_failed": "Неможливо оновити кеш APT (менеджер пакетів Debian). Ось дамп рядків sources.list, який може допомогти визначити проблемні рядки:\n{sourceslist}", + "unrestore_app": "{app} не буде оновлено", + "unlimit": "Квоти немає", "unknown_main_domain_path": "Невідомий домен або шлях для '{app}'. Вам необхідно вказати домен і шлях, щоб мати можливість вказати URL для дозволу.", "unexpected_error": "Щось пішло не так: {error}", - "unbackup_app": "{app} НЕ буде збережений", - "tools_upgrade_special_packages_completed": "Оновлення пакета YunoHost завершено. Натисніть [Enter] для повернення командного рядка", - "tools_upgrade_special_packages_explanation": "Спеціальне оновлення триватиме у фоновому режимі. Будь ласка, не запускайте ніяких інших дій на вашому сервері протягом наступних ~ 10 хвилин (в залежності від швидкості обладнання). Після цього вам, можливо, доведеться заново увійти в веб-адмін. Журнал поновлення буде доступний в Інструменти → Журнал (в веб-адміном) або за допомогою 'yunohost log list' (з командного рядка).", - "tools_upgrade_special_packages": "Тепер оновлюємо \"спеціальні\" (пов'язані з yunohost) пакети…", + "unbackup_app": "{app} НЕ буде збережено", + "tools_upgrade_special_packages_completed": "Оновлення пакета YunoHost завершено.\nНатисніть [Enter] для повернення до командного рядка", + "tools_upgrade_special_packages_explanation": "Спеціальне оновлення триватиме у тлі. Будь ласка, не запускайте ніяких інших дій на вашому сервері протягом наступних ~ 10 хвилин (в залежності від швидкості обладнання). Після цього вам, можливо, доведеться заново увійти в вебадміністратора. Журнал оновлення буде доступний в Засоби → Журнал (в веб-адміністраторі) або за допомогою 'yunohost log list' (з командного рядка).", + "tools_upgrade_special_packages": "Тепер оновлюємо 'спеціальні' (пов'язані з yunohost) пакети…", "tools_upgrade_regular_packages_failed": "Не вдалося оновити пакети: {packages_list}", - "tools_upgrade_regular_packages": "Тепер оновлюємо \"звичайні\" (не пов'язані з yunohost) пакети…", - "tools_upgrade_cant_unhold_critical_packages": "Не вдалося утримати критичні пакети…", + "tools_upgrade_regular_packages": "Тепер оновлюємо 'звичайні' (не пов'язані з yunohost) пакети…", + "tools_upgrade_cant_unhold_critical_packages": "Не вдалося розтримати критичні пакети…", "tools_upgrade_cant_hold_critical_packages": "Не вдалося утримати критичні пакети…", - "tools_upgrade_cant_both": "Неможливо оновити систему і програми одночасно", - "tools_upgrade_at_least_one": "Будь ласка, вкажіть 'apps', або 'system'.", - "this_action_broke_dpkg": "Ця дія порушило dpkg/APT (системні менеджери пакетів)... Ви можете спробувати вирішити цю проблему, підключившись по SSH і запустивши `sudo apt install --fix-broken` і/або` sudo dpkg --configure -a`.", + "tools_upgrade_cant_both": "Неможливо оновити систему і застосунки одночасно", + "tools_upgrade_at_least_one": "Будь ласка, вкажіть 'apps', або 'system'", + "this_action_broke_dpkg": "Ця дія порушила dpkg/APT (системні менеджери пакетів)... Ви можете спробувати вирішити цю проблему, під'єднавшись по SSH і запустивши `sudo apt install --fix-broken` та/або `sudo dpkg --configure -a`.", "system_username_exists": "Ім'я користувача вже існує в списку користувачів системи", - "system_upgraded": "система оновлена", - "ssowat_conf_updated": "Конфігурація SSOwat оновлена", - "ssowat_conf_generated": "Регенерувати конфігурація SSOwat", - "show_tile_cant_be_enabled_for_regex": "Ви не можете включити 'show_tile' прямо зараз, тому що URL для дозволу '{permission}' являє собою регекс", - "show_tile_cant_be_enabled_for_url_not_defined": "Ви не можете включити 'show_tile' прямо зараз, тому що спочатку ви повинні визначити URL для дозволу '{permission}'", + "system_upgraded": "Систему оновлено", + "ssowat_conf_updated": "Конфігурацію SSOwat оновлено", + "ssowat_conf_generated": "Конфігурацію SSOwat перестворено", + "show_tile_cant_be_enabled_for_regex": "Ви не можете увімкнути 'show_tile' прямо зараз, тому що URL для дозволу '{permission}' являє собою регулярний вираз", + "show_tile_cant_be_enabled_for_url_not_defined": "Ви не можете увімкнути 'show_tile' прямо зараз, тому що спочатку ви повинні визначити URL для дозволу '{permission}'", "service_unknown": "Невідома служба '{service}'", - "service_stopped": "Служба '{service}' зупинена", - "service_stop_failed": "Неможливо зупинити службу '{service}' Недавні журнали служб: {logs}", - "service_started": "Служба '{service}' запущена", - "service_start_failed": "Не вдалося запустити службу '{service}' Recent service logs: {logs}", + "service_stopped": "Службу '{service}' зупинено", + "service_stop_failed": "Неможливо зупинити службу '{service}' \n\nНедавні журнали служби: {logs}", + "service_started": "Службу '{service}' запущено", + "service_start_failed": "Не вдалося запустити службу '{service}' \n\nНедавні журнали служби: {logs}", "diagnosis_mail_outgoing_port_25_ok": "Поштовий сервер SMTP може відправляти електронні листи (вихідний порт 25 не заблоковано).", "diagnosis_swap_tip": "Будь ласка, будьте обережні і знайте, що якщо сервер розміщує обсяг підкачки на SD-карті або SSD-накопичувачі, це може різко скоротити строк служби пристрою`.", "diagnosis_swap_ok": "Система має {total} обсягу підкачки!", @@ -491,7 +491,7 @@ "diagnosis_dns_try_dyndns_update_force": "Конфігурація DNS цього домену повинна автоматично управлятися YunoHost. Якщо це не так, ви можете спробувати примусово оновити її за допомогою команди yunohost dyndns update --force.", "diagnosis_dns_point_to_doc": "Якщо вам потрібна допомога з налаштування DNS-записів, зверніться до документації на сайті https://yunohost.org/dns_config.", "diagnosis_dns_discrepancy": "Наступний запис DNS, схоже, не відповідає рекомендованій конфігурації:
Тип: {type}
Назва: {name}
Поточне значення: {current}
Очікуване значення: {value}", - "diagnosis_dns_missing_record": "Згідно рекомендованої конфігурації DNS, ви повинні додати запис DNS з наступними відомостями.\n
Тип: {type}\n
Назва: {name}\n
Значення: {value}", + "diagnosis_dns_missing_record": "Згідно рекомендованої конфігурації DNS, ви повинні додати запис DNS з наступними відомостями.
Тип: {type}
Назва: {name}
Значення: {value}", "diagnosis_dns_bad_conf": "Деякі DNS-записи відсутні або неправильні для домену {domain} (категорія {category})", "diagnosis_dns_good_conf": "DNS-записи правильно налаштовані для домену {domain} (категорія {category})", "diagnosis_ip_weird_resolvconf_details": "Файл /etc/resolv.conf повинен бути символічним посиланням на /etc/resolvconf/run/resolv.conf, що вказує на 127.0.0.1(dnsmasq). Якщо ви хочете вручну налаштувати DNS вирішувачі (resolvers), відредагуйте /etc/resolv.dnsmasq.conf.", @@ -500,14 +500,14 @@ "diagnosis_ip_broken_dnsresolution": "Роздільність доменних імен, схоже, з якоїсь причини не працює... Фаєрвол блокує DNS-запити?", "diagnosis_ip_dnsresolution_working": "Роздільність доменних імен працює!", "diagnosis_ip_not_connected_at_all": "Здається, сервер взагалі не під'єднаний до Інтернету!?", - "diagnosis_ip_local": "Локальний IP: {local}.", + "diagnosis_ip_local": "Локальний IP: {local}", "diagnosis_ip_global": "Глобальний IP: {global}", "diagnosis_ip_no_ipv6_tip": "Наявність робочого IPv6 не є обов'язковим для роботи вашого сервера, але це краще для здоров'я Інтернету в цілому. IPv6 зазвичай автоматично налаштовується системою або вашим провайдером, якщо він доступний. В іншому випадку вам, можливо, доведеться налаштувати деякі речі вручну, як пояснюється в документації тут: https://yunohost.org/#/ipv6. Якщо ви не можете увімкнути IPv6 або якщо це здається вам занадто технічним, ви також можете сміливо нехтувати цим попередженням.", "diagnosis_ip_no_ipv6": "Сервер не має робочого IPv6.", "diagnosis_ip_connected_ipv6": "Сервер під'єднаний до Інтернету через IPv6!", "diagnosis_ip_no_ipv4": "Сервер не має робочого IPv4.", "diagnosis_ip_connected_ipv4": "Сервер під'єднаний до Інтернету через IPv4!", - "diagnosis_no_cache": "Для категорії \"{category} 'ще немає кеша діагностики.", + "diagnosis_no_cache": "Для категорії \"{category} 'ще немає кеша діагностики", "diagnosis_failed": "Не вдалося отримати результат діагностики для категорії '{category}': {error}", "diagnosis_everything_ok": "Усе виглядає добре для {category}!", "diagnosis_found_warnings": "Знайдено {warnings} пунктів, які можна поліпшити для {category}.", @@ -518,7 +518,7 @@ "diagnosis_cache_still_valid": "(Кеш все ще дійсний для діагностики {category}. Повторна діагностика поки не проводиться!)", "diagnosis_failed_for_category": "Не вдалося провести діагностику для категорії '{category}': {error}", "diagnosis_display_tip": "Щоб побачити знайдені проблеми, ви можете перейти в розділ Діагностика в вебадміністраторі або виконати команду 'yunohost diagnosis show --issues --human-readable' з командного рядка.", - "diagnosis_package_installed_from_sury_details": "Деякі пакети були ненавмисно встановлені зі стороннього репозиторію під назвою Sury. Команда YunoHost поліпшила стратегію роботи з цими пакетами, але очікується, що в деяких системах, які встановили застосунки PHP7.3 ще на Stretch, залишаться деякі невідповідності. Щоб виправити це становище, спробуйте виконати наступну команду: {cmd_to_fix}.", + "diagnosis_package_installed_from_sury_details": "Деякі пакети були ненавмисно встановлені зі стороннього репозиторію під назвою Sury. Команда YunoHost поліпшила стратегію роботи з цими пакетами, але очікується, що в деяких системах, які встановили застосунки PHP7.3 ще на Stretch, залишаться деякі невідповідності. Щоб виправити це становище, спробуйте виконати наступну команду: {cmd_to_fix}", "diagnosis_package_installed_from_sury": "Деякі системні пакети мають бути зістарені у версії", "diagnosis_backports_in_sources_list": "Схоже, що apt (менеджер пакетів) налаштований на використання репозиторія backports. Якщо ви не знаєте, що робите, ми наполегливо не радимо встановлювати пакети з backports, тому що це може привести до нестабільності або конфліктів у вашій системі.", "diagnosis_basesystem_ynh_inconsistent_versions": "Ви використовуєте несумісні версії пакетів YunoHost... швидше за все, через невдале або часткове оновлення.", @@ -528,14 +528,14 @@ "diagnosis_basesystem_host": "Сервер працює під управлінням Debian {debian_version}", "diagnosis_basesystem_hardware_model": "Модель сервера - {model}", "diagnosis_basesystem_hardware": "Архітектура апаратного забезпечення сервера - {virt} {arch}", - "custom_app_url_required": "Ви повинні надати URL-адресу для оновлення вашого користувацького застосунку {app}.", - "confirm_app_install_thirdparty": "НЕБЕЗПЕЧНО! Цей застосунок не входить у каталог застосунків YunoHost. Установлення сторонніх застосунків може порушити цілісність і безпеку вашої системи. Вам не слід встановлювати його, якщо ви не знаєте, що робите. НІЯКОЇ ПІДТРИМКИ НЕ БУДЕ, якщо цей застосунок не буде працювати або зламає вашу систему... Якщо ви все одно готові піти на такий ризик, введіть '{answers}'.", - "confirm_app_install_danger": "НЕБЕЗПЕЧНО! Відомо, що цей застосунок все ще експериментальний (якщо не сказати, що він явно не працює)! Вам не слід встановлювати його, якщо ви не знаєте, що робите. Ніякої підтримки не буде надано, якщо цей застосунок не буде працювати або зламає вашу систему... Якщо ви все одно готові ризикнути, введіть '{answers}'.", + "custom_app_url_required": "Ви повинні надати URL-адресу для оновлення вашого користувацького застосунку {app}", + "confirm_app_install_thirdparty": "НЕБЕЗПЕЧНО! Цей застосунок не входить у каталог застосунків YunoHost. Установлення сторонніх застосунків може порушити цілісність і безпеку вашої системи. Вам не слід встановлювати його, якщо ви не знаєте, що робите. НІЯКОЇ ПІДТРИМКИ НЕ БУДЕ, якщо цей застосунок не буде працювати або зламає вашу систему... Якщо ви все одно готові піти на такий ризик, введіть '{answers}'", + "confirm_app_install_danger": "НЕБЕЗПЕЧНО! Відомо, що цей застосунок все ще експериментальний (якщо не сказати, що він явно не працює)! Вам не слід встановлювати його, якщо ви не знаєте, що робите. Ніякої підтримки не буде надано, якщо цей застосунок не буде працювати або зламає вашу систему... Якщо ви все одно готові ризикнути, введіть '{answers}'", "confirm_app_install_warning": "Попередження: Цей застосунок може працювати, але він не дуже добре інтегрований в YunoHost. Деякі функції, такі як єдина реєстрація та резервне копіювання/відновлення, можуть бути недоступні. Все одно встановити? [{answers}]. ", "certmanager_unable_to_parse_self_CA_name": "Не вдалося розібрати назву самопідписного центру (файл: {file})", "certmanager_self_ca_conf_file_not_found": "Не вдалося знайти файл конфігурації для самопідписного центру (файл: {file})", "certmanager_no_cert_file": "Не вдалося розпізнати файл сертифіката для домену {domain} (файл: {file})", - "certmanager_hit_rate_limit": "Для цього набору доменів {domain} недавно було випущено дуже багато сертифікатів. Будь ласка, спробуйте ще раз пізніше. Див. https://letsencrypt.org/docs/rate-limits/ для отримання подробиць.", + "certmanager_hit_rate_limit": "Для цього набору доменів {domain} недавно було випущено дуже багато сертифікатів. Будь ласка, спробуйте ще раз пізніше. Див. https://letsencrypt.org/docs/rate-limits/ для отримання подробиць", "certmanager_warning_subdomain_dns_record": "Піддомен '{subdomain}' не дозволяється на тій же IP-адресі, що і '{domain}'. Деякі функції будуть недоступні, поки ви не виправите це і не перестворите сертифікат.", "certmanager_domain_http_not_working": "Домен {domain}, схоже, не доступний через HTTP. Будь ласка, перевірте категорію 'Мережа' в діагностиці для отримання додаткових даних. (Якщо ви знаєте, що робите, використовуйте '--no-checks', щоб вимкнути ці перевірки).", "certmanager_domain_dns_ip_differs_from_public_ip": "DNS-записи для домену '{domain}' відрізняються від IP цього сервера. Будь ласка, перевірте категорію 'DNS-записи' (основні) в діагностиці для отримання додаткових даних. Якщо ви недавно змінили запис A, будь ласка, зачекайте, поки він пошириться (деякі програми перевірки поширення DNS доступні в Інтернеті). (Якщо ви знаєте, що робите, використовуйте '--no-checks', щоб вимкнути ці перевірки).", @@ -554,13 +554,13 @@ "backup_with_no_restore_script_for_app": "{app} не має скрипта відновлення, ви не зможете автоматично відновити резервну копію цього застосунку.", "backup_with_no_backup_script_for_app": "Застосунок '{app}' не має скрипта резервного копіювання. Нехтую ним.", "backup_unable_to_organize_files": "Неможливо використовувати швидкий спосіб для організації файлів в архіві", - "backup_system_part_failed": "Не вдалося створити резервну копію системної частини '{part}'.", + "backup_system_part_failed": "Не вдалося створити резервну копію системної частини '{part}'", "backup_running_hooks": "Запуск гачків (hook) резервного копіювання...", "backup_permission": "Дозвіл на резервне копіювання для {app}", "backup_output_symlink_dir_broken": "Ваш архівний каталог '{path}' є неробочим символічним посиланням. Можливо, ви забули перемонтувати або підключити носій, на який вона вказує.", "backup_output_directory_required": "Ви повинні вказати вихідний каталог для резервного копіювання", "backup_output_directory_not_empty": "Ви повинні вибрати порожній вихідний каталог", - "backup_output_directory_forbidden": "Виберіть інший вихідний каталог. Резервні копії не можуть бути створені в підкаталогах /bin,/boot,/dev,/etc,/lib,/root,/run,/sbin,/sys,/usr,/var або /home/yunohost.backup/archives.", + "backup_output_directory_forbidden": "Виберіть інший вихідний каталог. Резервні копії не можуть бути створені в підкаталогах /bin,/boot,/dev,/etc,/lib,/root,/run,/sbin,/sys,/usr,/var або /home/yunohost.backup/archives", "backup_nothings_done": "Нема що зберігати", "backup_no_uncompress_archive_dir": "Немає такого каталогу нестислого архіву", "backup_mount_archive_for_restore": "Підготовлення архіву для відновлення...", @@ -582,7 +582,7 @@ "backup_cleaning_failed": "Не вдалося очистити тимчасовий каталог резервного копіювання", "backup_cant_mount_uncompress_archive": "Не вдалося змонтувати нестислий архів як захищений від запису", "backup_ask_for_copying_if_needed": "Ви бажаєте тимчасово виконати резервне копіювання з використанням {size} МБ? (Цей спосіб використовується, оскільки деякі файли не можуть бути підготовлені дієвіше).", - "backup_archive_writing_error": "Не вдалося додати файли '{source}' (названі в архіві '{dest}') для резервного копіювання в стислий архів '{archive}'.", + "backup_archive_writing_error": "Не вдалося додати файли '{source}' (названі в архіві '{dest}') для резервного копіювання в стислий архів '{archive}'", "backup_archive_system_part_not_available": "Системна частина '{part}' недоступна в цій резервній копії", "backup_archive_corrupted": "Схоже, що архів резервної копії '{archive}' пошкоджений: {error}", "backup_archive_cant_retrieve_info_json": "Не вдалося завантажити відомості для архіву '{archive}'... info.json не може бути отриманий(або не є правильним json).", @@ -618,7 +618,7 @@ "app_upgrade_failed": "Не вдалося оновити {app}: {error}", "app_upgrade_app_name": "Зараз оновлюємо {app}...", "app_upgrade_several_apps": "Наступні застосунки буде оновлено: {apps}", - "app_unsupported_remote_type": "Для застосунку використовується непідтримуваний віддалений тип.", + "app_unsupported_remote_type": "Для застосунку використовується непідтримуваний віддалений тип", "app_unknown": "Невідомий застосунок", "app_start_restore": "Відновлення {app}...", "app_start_backup": "Збирання файлів для резервного копіювання {app}...", @@ -628,7 +628,7 @@ "app_restore_script_failed": "Сталася помилка всередині скрипта відновлення застосунку", "app_restore_failed": "Не вдалося відновити {app}: {error}", "app_remove_after_failed_install": "Вилучення застосунку після збою встановлення...", - "app_requirements_unmeet": "Вимоги не виконані для {app}, пакет {pkgname} ({version}) повинен бути {spec}.", + "app_requirements_unmeet": "Вимоги не виконані для {app}, пакет {pkgname} ({version}) повинен бути {spec}", "app_requirements_checking": "Перевіряння необхідних пакетів для {app}...", "app_removed": "{app} видалено", "app_not_properly_removed": "{app} не було видалено належним чином", @@ -638,5 +638,24 @@ "app_manifest_install_ask_is_public": "Чи має цей застосунок бути відкритим для анонімних відвідувачів?", "app_manifest_install_ask_admin": "Виберіть користувача-адміністратора для цього застосунку", "app_manifest_install_ask_password": "Виберіть пароль адміністратора для цього застосунку", - "diagnosis_description_apps": "Застосунки" + "diagnosis_description_apps": "Застосунки", + "user_import_success": "Користувачів успішно імпортовано", + "user_import_nothing_to_do": "Не потрібно імпортувати жодного користувача", + "user_import_failed": "Операція імпорту користувачів цілковито не вдалася", + "user_import_partial_failed": "Операція імпорту користувачів частково не вдалася", + "user_import_missing_columns": "Відсутні такі стовпці: {columns}", + "user_import_bad_file": "Ваш файл CSV неправильно відформатовано, він буде знехтуваний, щоб уникнути потенційної втрати даних", + "user_import_bad_line": "Неправильний рядок {line}: {details}", + "invalid_password": "Недійсний пароль", + "log_user_import": "Імпорт користувачів", + "ldap_server_is_down_restart_it": "Службу LDAP вимкнено, спробуйте перезапустити її...", + "ldap_server_down": "Не вдається під'єднатися до сервера LDAP", + "global_settings_setting_security_experimental_enabled": "Увімкнути експериментальні функції безпеки (не вмикайте це, якщо ви не знаєте, що робите!)", + "diagnosis_apps_deprecated_practices": "Установлена версія цього застосунку все ще використовує деякі надзастарілі практики упакування. Вам дійсно варто подумати про його оновлення.", + "diagnosis_apps_outdated_ynh_requirement": "Установлена версія цього застосунку вимагає лише Yunohost >= 2.x, що, як правило, вказує на те, що воно не відповідає сучасним рекомендаційним практикам упакування та порадникам. Вам дійсно варто подумати про його оновлення.", + "diagnosis_apps_bad_quality": "Цей застосунок наразі позначено як зламаний у каталозі застосунків YunoHost. Це може бути тимчасовою проблемою, поки організатори намагаються вирішити цю проблему. Тим часом оновлення цього застосунку вимкнено.", + "diagnosis_apps_broken": "Цей застосунок наразі позначено як зламаний у каталозі застосунків YunoHost. Це може бути тимчасовою проблемою, поки організатори намагаються вирішити цю проблему. Тим часом оновлення цього застосунку вимкнено.", + "diagnosis_apps_not_in_app_catalog": "Цей застосунок не міститься у каталозі застосунків YunoHost. Якщо він був у минулому і був видалений, вам слід подумати про видалення цього застосунку, оскільки він не отримає оновлення, і це може поставити під загрозу цілісність та безпеку вашої системи.", + "diagnosis_apps_issue": "Виявлено проблему із застосунком {app}", + "diagnosis_apps_allgood": "Усі встановлені застосунки дотримуються основних способів упакування" } From c8791a98340acd28566a818244bba4c886fdd68e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 4 Sep 2021 20:21:30 +0200 Subject: [PATCH 095/101] Add config check during service_reload_or_restart --- src/yunohost/app.py | 14 ++++---------- src/yunohost/service.py | 25 ++++++++++++++++++++++++- src/yunohost/tests/test_service.py | 22 ++++++++++++++++++++++ src/yunohost/utils/config.py | 14 +++----------- 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 83ff27cdf..23f3b011b 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -52,7 +52,6 @@ from moulinette.utils.filesystem import ( mkdir, ) -from yunohost.service import service_status, _run_service_command from yunohost.utils import packages from yunohost.utils.config import ( ConfigPanel, @@ -424,6 +423,7 @@ def app_change_url(operation_logger, app, domain, path): """ from yunohost.hook import hook_exec, hook_callback + from yunohost.service import service_reload_or_restart installed = _is_installed(app) if not installed: @@ -492,15 +492,7 @@ def app_change_url(operation_logger, app, domain, path): app_ssowatconf() - # avoid common mistakes - if _run_service_command("reload", "nginx") is False: - # grab nginx errors - # the "exit 0" is here to avoid check_output to fail because 'nginx -t' - # will return != 0 since we are in a failed state - nginx_errors = check_output("nginx -t; exit 0") - raise YunohostError( - "app_change_url_failed_nginx_reload", nginx_errors=nginx_errors - ) + service_reload_or_restart("nginx") logger.success(m18n.n("app_change_url_success", app=app, domain=domain, path=path)) @@ -2883,6 +2875,8 @@ def unstable_apps(): def _assert_system_is_sane_for_app(manifest, when): + from yunohost.service import service_status + logger.debug("Checking that required services are up and running...") services = manifest.get("services", []) diff --git a/src/yunohost/service.py b/src/yunohost/service.py index fb12e9053..da3bded3c 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -256,7 +256,7 @@ def service_restart(names): ) -def service_reload_or_restart(names): +def service_reload_or_restart(names, test_conf=True): """ Reload one or more services if they support it. If not, restart them instead. If the services are not running yet, they will be started. @@ -266,7 +266,30 @@ def service_reload_or_restart(names): """ if isinstance(names, str): names = [names] + + services = _get_services() + for name in names: + + logger.debug(f"Reloading service {name}") + + test_conf_cmd = services.get(service, {}).get("test_conf") + if test_conf and test_conf_cmd: + + p = subprocess.Popen( + test_conf_cmd, + shell=True, + executable="/bin/bash", + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + + out, _ = p.communicate() + if p.returncode != 0: + errors = out.strip().split("\n") + logger.error(m18n.("service_not_reloading_because_conf_broken", errors=errors)) + continue + if _run_service_command("reload-or-restart", name): logger.success(m18n.n("service_reloaded_or_restarted", service=name)) else: diff --git a/src/yunohost/tests/test_service.py b/src/yunohost/tests/test_service.py index 1f82dc8fd..1007419a1 100644 --- a/src/yunohost/tests/test_service.py +++ b/src/yunohost/tests/test_service.py @@ -9,6 +9,7 @@ from yunohost.service import ( service_add, service_remove, service_log, + service_reload_or_restart, ) @@ -38,6 +39,10 @@ def clean(): _save_services(services) + if os.path.exists("/etc/nginx/conf.d/broken.conf"): + os.remove("/etc/nginx/conf.d/broken.conf") + os.system("systemctl reload-or-restart nginx") + def test_service_status_all(): @@ -118,3 +123,20 @@ def test_service_update_to_remove_properties(): assert _get_services()["dummyservice"].get("test_status") == "false" service_add("dummyservice", description="dummy", test_status="") assert not _get_services()["dummyservice"].get("test_status") + + +def test_service_conf_broken(): + + os.system("echo pwet > /etc/nginx/conf.d/broken.conf") + + status = service_status("nginx") + assert status["status"] == "running" + assert status["configuration"] == "broken" + assert "broken.conf" in status["configuration-details"] + + # Service reload-or-restart should check that the conf ain't valid + # before reload-or-restart, hence the service should still be running + service_reload_or_restart("nginx") + assert status["status"] == "running" + + os.remove("/etc/nginx/conf.d/broken.conf") diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index 8fcf493ed..9cdb30119 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -289,7 +289,7 @@ class ConfigPanel: def _reload_services(self): - from yunohost.service import _run_service_command, _get_services + from yunohost.service import service_reload_or_restart logger.info("Reloading services...") services_to_reload = set() @@ -299,16 +299,8 @@ class ConfigPanel: services_to_reload = list(services_to_reload) services_to_reload.sort(key="nginx".__eq__) for service in services_to_reload: - if "__APP__": - service = service.replace("__APP__", self.app) - logger.debug(f"Reloading {service}") - if not _run_service_command("reload-or-restart", service): - services = _get_services() - test_conf = services[service].get("test_conf", "true") - errors = check_output(f"{test_conf}; exit 0") if test_conf else "" - raise YunohostError( - "config_failed_service_reload", service=service, errors=errors - ) + service = service.replace("__APP__", self.app) + service_reload_or_restart(service) def _iterate(self, trigger=["option"]): for panel in self.config.get("panels", []): From 778c67540cbd6abe25c2735ef3a80494aa80e10e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 4 Sep 2021 20:22:28 +0200 Subject: [PATCH 096/101] Misc fixes, try to implement locale strings --- locales/en.json | 6 +++++- src/yunohost/app.py | 4 ++-- src/yunohost/utils/config.py | 37 ++++++++++++++++++++---------------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/locales/en.json b/locales/en.json index a5652f378..667a8d4b3 100644 --- a/locales/en.json +++ b/locales/en.json @@ -21,6 +21,8 @@ "app_change_url_identical_domains": "The old and new domain/url_path are identical ('{domain}{path}'), nothing to do.", "app_change_url_no_script": "The app '{app_name}' doesn't support URL modification yet. Maybe you should upgrade it.", "app_change_url_success": "{app} URL is now {domain}{path}", + "app_config_unable_to_apply": "Failed to apply config panel values.", + "app_config_unable_to_read": "Failed to read config panel values.", "app_extraction_failed": "Could not extract the installation files", "app_full_domain_unavailable": "Sorry, this app must be installed on a domain of its own, but other apps are already installed on the domain '{domain}'. You could use a subdomain dedicated to this app instead.", "app_id_invalid": "Invalid app ID", @@ -139,6 +141,7 @@ "certmanager_self_ca_conf_file_not_found": "Could not find configuration file for self-signing authority (file: {file})", "certmanager_unable_to_parse_self_CA_name": "Could not parse name of self-signing authority (file: {file})", "certmanager_warning_subdomain_dns_record": "Subdomain '{subdomain}' does not resolve to the same IP address as '{domain}'. Some features will not be available until you fix this and regenerate the certificate.", + "config_apply_failed": "Applying the new configuration failed: {error}", "confirm_app_install_danger": "DANGER! This app is known to be still experimental (if not explicitly not working)! You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system... If you are willing to take that risk anyway, type '{answers}'", "confirm_app_install_thirdparty": "DANGER! This app is not part of YunoHost's app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system... If you are willing to take that risk anyway, type '{answers}'", "confirm_app_install_warning": "Warning: This app may work, but is not well-integrated in YunoHost. Some features such as single sign-on and backup/restore might not be available. Install anyway? [{answers}] ", @@ -389,8 +392,8 @@ "log_app_change_url": "Change the URL of the '{}' app", "log_app_config_apply": "Apply config to the '{}' app", "log_app_config_get": "Get a specific setting from config panel of the '{}' app", - "log_app_config_show": "Show the config panel of the '{}' app", "log_app_config_set": "Apply config to the '{}' app", + "log_app_config_show": "Show the config panel of the '{}' app", "log_app_install": "Install the '{}' app", "log_app_makedefault": "Make '{}' the default app", "log_app_remove": "Remove the '{}' app", @@ -596,6 +599,7 @@ "service_disabled": "The service '{service}' will not be started anymore when system boots.", "service_enable_failed": "Could not make the service '{service}' automatically start at boot.\n\nRecent service logs:{logs}", "service_enabled": "The service '{service}' will now be automatically started during system boots.", + "service_not_reloading_because_conf_broken": "Not reloading/restarting service '{name}' because it configuration is broken: {errors}", "service_regen_conf_is_deprecated": "'yunohost service regen-conf' is deprecated! Please use 'yunohost tools regen-conf' instead.", "service_reload_failed": "Could not reload the service '{service}'\n\nRecent service logs:{logs}", "service_reload_or_restart_failed": "Could not reload or restart the service '{service}'\n\nRecent service logs:{logs}", diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 23f3b011b..e24af1654 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1823,9 +1823,9 @@ ynh_app_config_run $1 ret, values = hook_exec(config_script, args=[action], env=env) if ret != 0: if action == "show": - raise YunohostError("app_config_unable_to_read_values") + raise YunohostError("app_config_unable_to_read") else: - raise YunohostError("app_config_unable_to_apply_values_correctly") + raise YunohostError("app_config_unable_to_apply") return values diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index 9cdb30119..8c1b2948a 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -31,6 +31,7 @@ from moulinette import Moulinette, m18n from moulinette.utils.log import getActionLogger from moulinette.utils.process import check_output from moulinette.utils.filesystem import ( + write_to_file, read_toml, read_yaml, write_to_yaml, @@ -127,14 +128,14 @@ class ConfigPanel: # N.B. : KeyboardInterrupt does not inherit from Exception except (KeyboardInterrupt, EOFError): error = m18n.n("operation_interrupted") - logger.error(m18n.n("config_failed", error=error)) + logger.error(m18n.n("config_apply_failed", error=error)) raise # Something wrong happened in Yunohost's code (most probably hook_exec) except Exception: import traceback error = m18n.n("unexpected_error", error="\n" + traceback.format_exc()) - logger.error(m18n.n("config_failed", error=error)) + logger.error(m18n.n("config_apply_failed", error=error)) raise finally: # Delete files uploaded from API @@ -154,10 +155,11 @@ class ConfigPanel: return read_toml(self.config_path) def _get_config_panel(self): + # Split filter_key - filter_key = dict(enumerate(self.filter_key.split("."))) + filter_key = self.filter_key.split(".") if len(filter_key) > 3: - raise YunohostError("config_too_much_sub_keys") + raise YunohostError("config_too_many_sub_keys", key=self.filter_key) if not os.path.exists(self.config_path): return None @@ -166,7 +168,7 @@ class ConfigPanel: # Check TOML config panel is in a supported version if float(toml_config_panel["version"]) < CONFIG_PANEL_VERSION_SUPPORTED: raise YunohostError( - "config_too_old_version", version=toml_config_panel["version"] + "config_version_not_supported", version=toml_config_panel["version"] ) # Transform toml format into internal format @@ -187,6 +189,13 @@ class ConfigPanel: # optional choices pattern limit min max step accept redact } + # + # FIXME : this is hella confusing ... + # from what I understand, the purpose is to have some sort of "deep_update" + # to apply the defaults onto the loaded toml ... + # in that case we probably want to get inspiration from + # https://stackoverflow.com/questions/3232943/update-value-of-a-nested-dictionary-of-varying-depth + # def convert(toml_node, node_type): """Convert TOML in internal format ('full' mode used by webadmin) Here are some properties of 1.0 config panel in toml: @@ -456,7 +465,7 @@ class YunoHostArgumentFormatParser(object): if self.operation_logger: self.operation_logger.data_to_redact.extend(data_to_redact) elif data_to_redact: - raise YunohostError("app_argument_cant_redact", arg=question.name) + raise YunohostError(f"Can't redact {question.name} because no operation logger available in the context", raw_msg=True) return question.value @@ -729,7 +738,7 @@ class FileArgumentParser(YunoHostArgumentFormatParser): raise YunohostValidationError( "app_argument_invalid", field=question.name, - error=m18n.n("invalid_number1"), + error=m18n.n("file_does_not_exists"), ) if question.value in [None, ""] or not question.accept: return @@ -743,7 +752,7 @@ class FileArgumentParser(YunoHostArgumentFormatParser): raise YunohostValidationError( "app_argument_invalid", field=question.name, - error=m18n.n("invalid_number2"), + error=m18n.n("file_extension_not_accepted"), ) def _post_parse_value(self, question): @@ -768,19 +777,15 @@ class FileArgumentParser(YunoHostArgumentFormatParser): # i.e. os.path.join("/foo", "/etc/passwd") == "/etc/passwd" file_path = os.path.normpath(upload_dir + "/" + filename) if not file_path.startswith(upload_dir + "/"): - raise YunohostError("relative_parent_path_in_filename_forbidden") + raise YunohostError("file_relative_parent_path_in_filename_forbidden") i = 2 while os.path.exists(file_path): file_path = os.path.normpath(upload_dir + "/" + filename + (".%d" % i)) i += 1 content = question.value["content"] - try: - with open(file_path, "wb") as f: - f.write(b64decode(content)) - except IOError as e: - raise YunohostError("cannot_write_file", file=file_path, error=str(e)) - except Exception as e: - raise YunohostError("error_writing_file", file=file_path, error=str(e)) + + write_to_file(file_path, b64decode(content), file_mode="wb") + question.value = file_path return question.value From a062254402ba5463c5c12a4885fd45f91052d457 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 4 Sep 2021 20:34:56 +0200 Subject: [PATCH 097/101] Moar localization --- locales/en.json | 1 + src/yunohost/utils/config.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/locales/en.json b/locales/en.json index 667a8d4b3..faef3efc5 100644 --- a/locales/en.json +++ b/locales/en.json @@ -327,6 +327,7 @@ "extracting": "Extracting...", "field_invalid": "Invalid field '{}'", "file_does_not_exist": "The file {path} does not exist.", + "file_extension_not_accepted": "Refusing file '{path}' because its extension is not among the accepted extensions: {accept}", "firewall_reload_failed": "Could not reload the firewall", "firewall_reloaded": "Firewall reloaded", "firewall_rules_cmd_failed": "Some firewall rule commands have failed. More info in log.", diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index cb493be03..23a95b565 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -797,7 +797,7 @@ class FileQuestion(Question): raise YunohostValidationError( "app_argument_invalid", field=self.name, - error=m18n.n("file_does_not_exists"), + error=m18n.n("file_does_not_exist", path=self.value), ) if self.value in [None, ""] or not self.accept: return @@ -807,7 +807,7 @@ class FileQuestion(Question): raise YunohostValidationError( "app_argument_invalid", field=self.name, - error=m18n.n("file_extension_not_accepted"), + error=m18n.n("file_extension_not_accepted", file=filename, accept=self.accept), ) @@ -833,7 +833,7 @@ class FileQuestion(Question): # i.e. os.path.join("/foo", "/etc/passwd") == "/etc/passwd" file_path = os.path.normpath(upload_dir + "/" + filename) if not file_path.startswith(upload_dir + "/"): - raise YunohostError("file_relative_parent_path_in_filename_forbidden") + raise YunohostError(f"Filename '{filename}' received from the API got a relative parent path, which is forbidden", raw_msg=True) i = 2 while os.path.exists(file_path): file_path = os.path.normpath(upload_dir + "/" + filename + (".%d" % i)) From 1bf0196ff8fa33712894bd8e4dde7ca8df62f4c2 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 5 Sep 2021 00:20:12 +0200 Subject: [PATCH 098/101] Black + fix some invalid code issues --- src/yunohost/service.py | 4 +- src/yunohost/utils/config.py | 119 ++++++++++++++++++--------------- tests/autofix_locale_format.py | 12 +++- tests/reformat_locales.py | 54 ++++++++++----- 4 files changed, 116 insertions(+), 73 deletions(-) diff --git a/src/yunohost/service.py b/src/yunohost/service.py index da3bded3c..2ef94878d 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -287,7 +287,9 @@ def service_reload_or_restart(names, test_conf=True): out, _ = p.communicate() if p.returncode != 0: 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 if _run_service_command("reload-or-restart", name): diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index 23a95b565..5c81f5007 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -29,7 +29,6 @@ from collections import OrderedDict from moulinette.interfaces.cli import colorize from moulinette import Moulinette, m18n from moulinette.utils.log import getActionLogger -from moulinette.utils.process import check_output from moulinette.utils.filesystem import ( write_to_file, read_toml, @@ -80,16 +79,22 @@ class ConfigPanel: result = {} for panel, section, option in self._iterate(): key = f"{panel['id']}.{section['id']}.{option['id']}" - if mode == 'export': - result[option['id']] = option.get('current_value') + if mode == "export": + result[option["id"]] = option.get("current_value") else: - if 'ask' in option: - result[key] = {'ask': _value_for_locale(option['ask'])} - elif 'i18n' in self.config: - result[key] = {'ask': m18n.n(self.config['i18n'] + '_' + option['id'])} - if 'current_value' in option: - question_class = ARGUMENTS_TYPE_PARSERS[option.get("type", "string")] - result[key]['value'] = question_class.humanize(option['current_value'], option) + if "ask" in option: + result[key] = {"ask": _value_for_locale(option["ask"])} + elif "i18n" in self.config: + result[key] = { + "ask": m18n.n(self.config["i18n"] + "_" + option["id"]) + } + 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 @@ -294,8 +299,11 @@ class ConfigPanel: self.errors = None def _get_default_values(self): - return { option['id']: option['default'] - for _, _, option in self._iterate() if 'default' in option } + return { + option["id"]: option["default"] + for _, _, option in self._iterate() + if "default" in option + } def _load_current_values(self): """ @@ -319,9 +327,11 @@ class ConfigPanel: mkdir(dir_path, mode=0o700) values_to_save = {**self.values, **self.new_values} - if self.save_mode == 'diff': + if self.save_mode == "diff": 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 write_to_yaml(self.save_path, self.new_values) @@ -360,17 +370,17 @@ class Question(object): def __init__(self, question, user_answers): self.name = question["name"] - self.type = question.get("type", 'string') + self.type = question.get("type", "string") self.default = question.get("default", None) self.current_value = question.get("current_value") self.optional = question.get("optional", False) self.choices = question.get("choices", []) 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.helpLink = question.get("helpLink") 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 if self.default == "": @@ -384,11 +394,10 @@ class Question(object): def normalize(value, option={}): return value - def ask_if_needed(self): while True: # 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() if getattr(self, "readonly", False): Moulinette.display(text_for_user_input_in_cli) @@ -433,7 +442,6 @@ class Question(object): return (self.value, self.argument_type) - def _prevalidate(self): if self.value in [None, ""] and not self.optional: raise YunohostValidationError("app_argument_required", name=self.name) @@ -442,9 +450,9 @@ class Question(object): if self.value is not None: if self.choices and self.value not in self.choices: 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( - self.pattern['error'], + self.pattern["error"], name=self.name, value=self.value, ) @@ -494,7 +502,10 @@ class Question(object): if self.operation_logger: self.operation_logger.data_to_redact.extend(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 @@ -510,7 +521,7 @@ class TagsQuestion(Question): @staticmethod def humanize(value, option={}): if isinstance(value, list): - return ','.join(value) + return ",".join(value) return value def _prevalidate(self): @@ -540,7 +551,7 @@ class PasswordQuestion(Question): @staticmethod def humanize(value, option={}): if value: - return '***' # Avoid to display the password on screen + return "********" # Avoid to display the password on screen return "" def _prevalidate(self): @@ -571,32 +582,32 @@ class BooleanQuestion(Question): @staticmethod def humanize(value, option={}): - yes = option.get('yes', 1) - no = option.get('no', 0) + yes = option.get("yes", 1) + no = option.get("no", 0) value = str(value).lower() if value == str(yes).lower(): - return 'yes' + return "yes" if value == str(no).lower(): - return 'no' + return "no" if value in BooleanQuestion.yes_answers: - return 'yes' + return "yes" if value in BooleanQuestion.no_answers: - return 'no' + return "no" - if value in ['none', ""]: - return '' + if value in ["none", ""]: + return "" raise YunohostValidationError( "app_argument_choice_invalid", - name=self.name, - value=self.value, + name=self.name, # FIXME ... + value=value, choices="yes, no, y, n, 1, 0", ) @staticmethod def normalize(value, option={}): - yes = option.get('yes', 1) - no = option.get('no', 0) + yes = option.get("yes", 1) + no = option.get("no", 0) if str(value).lower() in BooleanQuestion.yes_answers: return yes @@ -608,19 +619,18 @@ class BooleanQuestion(Question): return None raise YunohostValidationError( "app_argument_choice_invalid", - name=self.name, - value=self.value, + name=self.name, # FIXME.... + value=value, choices="yes, no, y, n, 1, 0", ) def __init__(self, question, user_answers): super().__init__(question, user_answers) - self.yes = question.get('yes', 1) - self.no = question.get('no', 0) + self.yes = question.get("yes", 1) + self.no = question.get("no", 0) if self.default is None: self.default = False - def _format_text_for_user_input_in_cli(self): text_for_user_input_in_cli = _value_for_locale(self.ask) @@ -652,7 +662,6 @@ class DomainQuestion(Question): self.choices = domain_list()["domains"] - def _raise_invalid_answer(self): raise YunohostValidationError( "app_argument_invalid", field=self.name, error=m18n.n("domain_unknown") @@ -675,7 +684,6 @@ class UserQuestion(Question): self.default = user break - def _raise_invalid_answer(self): raise YunohostValidationError( "app_argument_invalid", @@ -698,7 +706,6 @@ class NumberQuestion(Question): self.max = question.get("max", None) self.step = question.get("step", None) - def _prevalidate(self): super()._prevalidate() if not isinstance(self.value, int) and not ( @@ -744,8 +751,7 @@ class DisplayTextQuestion(Question): super().__init__(question, user_answers) self.optional = True - self.style = question.get("style", "info") - + self.style = question.get("style", "info") def _format_text_for_user_input_in_cli(self): text = self.ask["en"] @@ -780,7 +786,7 @@ class FileQuestion(Question): self.accept = question.get("accept").replace(" ", "").split(",") else: self.accept = [] - if Moulinette.interface.type== "api": + if Moulinette.interface.type == "api": if user_answers.get(f"{self.name}[name]"): self.value = { "content": self.value, @@ -790,10 +796,13 @@ class FileQuestion(Question): if self.value and str(self.value) == self.current_value: self.value = None - def _prevalidate(self): 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( "app_argument_invalid", field=self.name, @@ -807,10 +816,11 @@ class FileQuestion(Question): raise YunohostValidationError( "app_argument_invalid", 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): from base64 import b64decode @@ -833,7 +843,10 @@ class FileQuestion(Question): # i.e. os.path.join("/foo", "/etc/passwd") == "/etc/passwd" file_path = os.path.normpath(upload_dir + "/" + filename) 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 while os.path.exists(file_path): file_path = os.path.normpath(upload_dir + "/" + filename + (".%d" % i)) diff --git a/tests/autofix_locale_format.py b/tests/autofix_locale_format.py index f777f06f1..dd7812635 100644 --- a/tests/autofix_locale_format.py +++ b/tests/autofix_locale_format.py @@ -27,11 +27,17 @@ def fix_locale(locale_file): # should also be in the translated string, otherwise the .format # will trigger an exception! 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): - 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 if fixed_stuff: diff --git a/tests/reformat_locales.py b/tests/reformat_locales.py index 90251d040..9119c7288 100644 --- a/tests/reformat_locales.py +++ b/tests/reformat_locales.py @@ -1,5 +1,6 @@ import re + def reformat(lang, transformations): locale = open(f"locales/{lang}.json").read() @@ -8,31 +9,52 @@ def reformat(lang, transformations): 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.update({ - "…": "...", -}) +transformations.update( + { + "…": "...", + } +) reformat("en", transformations) ###################################################### -transformations.update({ - "courriel": "email", - "e-mail": "email", - "Courriel": "Email", - "E-mail": "Email", - "« ": "'", - "«": "'", - " »": "'", - "»": "'", - "’": "'", - #r"$(\w{1,2})'|( \w{1,2})'": r"\1\2’", -}) +transformations.update( + { + "courriel": "email", + "e-mail": "email", + "Courriel": "Email", + "E-mail": "Email", + "« ": "'", + "«": "'", + " »": "'", + "»": "'", + "’": "'", + # r"$(\w{1,2})'|( \w{1,2})'": r"\1\2’", + } +) reformat("fr", transformations) From a289f081d911656f460f7acc76e041e892a5083e Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Sat, 4 Sep 2021 22:52:35 +0000 Subject: [PATCH 099/101] [CI] Format code --- data/hooks/diagnosis/00-basesystem.py | 5 ++- tests/autofix_locale_format.py | 12 ++++-- tests/reformat_locales.py | 54 +++++++++++++++++++-------- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/data/hooks/diagnosis/00-basesystem.py b/data/hooks/diagnosis/00-basesystem.py index 5b4b3394c..b472a2d32 100644 --- a/data/hooks/diagnosis/00-basesystem.py +++ b/data/hooks/diagnosis/00-basesystem.py @@ -172,7 +172,10 @@ class BaseSystemDiagnoser(Diagnoser): try: return int(n_failures) except Exception: - self.logger_warning("Failed to parse number of recent auth failures, expected an int, got '%s'" % n_failures) + self.logger_warning( + "Failed to parse number of recent auth failures, expected an int, got '%s'" + % n_failures + ) return -1 def is_vulnerable_to_meltdown(self): diff --git a/tests/autofix_locale_format.py b/tests/autofix_locale_format.py index f777f06f1..dd7812635 100644 --- a/tests/autofix_locale_format.py +++ b/tests/autofix_locale_format.py @@ -27,11 +27,17 @@ def fix_locale(locale_file): # should also be in the translated string, otherwise the .format # will trigger an exception! 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): - 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 if fixed_stuff: diff --git a/tests/reformat_locales.py b/tests/reformat_locales.py index 90251d040..9119c7288 100644 --- a/tests/reformat_locales.py +++ b/tests/reformat_locales.py @@ -1,5 +1,6 @@ import re + def reformat(lang, transformations): locale = open(f"locales/{lang}.json").read() @@ -8,31 +9,52 @@ def reformat(lang, transformations): 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.update({ - "…": "...", -}) +transformations.update( + { + "…": "...", + } +) reformat("en", transformations) ###################################################### -transformations.update({ - "courriel": "email", - "e-mail": "email", - "Courriel": "Email", - "E-mail": "Email", - "« ": "'", - "«": "'", - " »": "'", - "»": "'", - "’": "'", - #r"$(\w{1,2})'|( \w{1,2})'": r"\1\2’", -}) +transformations.update( + { + "courriel": "email", + "e-mail": "email", + "Courriel": "Email", + "E-mail": "Email", + "« ": "'", + "«": "'", + " »": "'", + "»": "'", + "’": "'", + # r"$(\w{1,2})'|( \w{1,2})'": r"\1\2’", + } +) reformat("fr", transformations) From 0122b7a1262cc63f250074d3a2a4930683e9fc94 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 5 Sep 2021 15:37:46 +0200 Subject: [PATCH 100/101] Misc fixes --- .gitlab/ci/test.gitlab-ci.yml | 6 +- src/yunohost/service.py | 2 +- ...ps_arguments_parsing.py => test_config.py} | 250 +++++++++--------- src/yunohost/tests/test_service.py | 2 +- 4 files changed, 130 insertions(+), 130 deletions(-) rename src/yunohost/tests/{test_apps_arguments_parsing.py => test_config.py} (81%) diff --git a/.gitlab/ci/test.gitlab-ci.yml b/.gitlab/ci/test.gitlab-ci.yml index e0e0e001a..78394f253 100644 --- a/.gitlab/ci/test.gitlab-ci.yml +++ b/.gitlab/ci/test.gitlab-ci.yml @@ -112,14 +112,14 @@ test-appurl: changes: - src/yunohost/app.py -test-apps-arguments-parsing: +test-config: extends: .test-stage script: - cd src/yunohost - - python3 -m pytest tests/test_apps_arguments_parsing.py + - python3 -m pytest tests/test_config.py only: changes: - - src/yunohost/app.py + - src/yunohost/utils/config.py test-changeurl: extends: .test-stage diff --git a/src/yunohost/service.py b/src/yunohost/service.py index 2ef94878d..5f9f3e60a 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -273,7 +273,7 @@ def service_reload_or_restart(names, test_conf=True): logger.debug(f"Reloading service {name}") - test_conf_cmd = services.get(service, {}).get("test_conf") + test_conf_cmd = services.get(name, {}).get("test_conf") if test_conf and test_conf_cmd: p = subprocess.Popen( diff --git a/src/yunohost/tests/test_apps_arguments_parsing.py b/src/yunohost/tests/test_config.py similarity index 81% rename from src/yunohost/tests/test_apps_arguments_parsing.py rename to src/yunohost/tests/test_config.py index fe5c5f8cd..2e52c4086 100644 --- a/src/yunohost/tests/test_apps_arguments_parsing.py +++ b/src/yunohost/tests/test_config.py @@ -8,7 +8,7 @@ from collections import OrderedDict from moulinette import Moulinette from yunohost import domain, user -from yunohost.app import _parse_args_in_yunohost_format, PasswordArgumentParser +from yunohost.utils.config import parse_args_in_yunohost_format, PasswordQuestion from yunohost.utils.error import YunohostError @@ -36,7 +36,7 @@ User answers: def test_parse_args_in_yunohost_format_empty(): - assert _parse_args_in_yunohost_format({}, []) == {} + assert parse_args_in_yunohost_format({}, []) == {} def test_parse_args_in_yunohost_format_string(): @@ -48,7 +48,7 @@ def test_parse_args_in_yunohost_format_string(): ] answers = {"some_string": "some_value"} expected_result = OrderedDict({"some_string": ("some_value", "string")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_default_type(): @@ -59,7 +59,7 @@ def test_parse_args_in_yunohost_format_string_default_type(): ] answers = {"some_string": "some_value"} expected_result = OrderedDict({"some_string": ("some_value", "string")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_no_input(): @@ -71,7 +71,7 @@ def test_parse_args_in_yunohost_format_string_no_input(): answers = {} with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_string_input(): @@ -85,7 +85,7 @@ def test_parse_args_in_yunohost_format_string_input(): expected_result = OrderedDict({"some_string": ("some_value", "string")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_input_no_ask(): @@ -98,7 +98,7 @@ def test_parse_args_in_yunohost_format_string_input_no_ask(): expected_result = OrderedDict({"some_string": ("some_value", "string")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_no_input_optional(): @@ -110,7 +110,7 @@ def test_parse_args_in_yunohost_format_string_no_input_optional(): ] answers = {} expected_result = OrderedDict({"some_string": ("", "string")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_optional_with_input(): @@ -125,7 +125,7 @@ def test_parse_args_in_yunohost_format_string_optional_with_input(): expected_result = OrderedDict({"some_string": ("some_value", "string")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_optional_with_empty_input(): @@ -140,7 +140,7 @@ def test_parse_args_in_yunohost_format_string_optional_with_empty_input(): expected_result = OrderedDict({"some_string": ("", "string")}) with patch.object(Moulinette.interface, "prompt", return_value=""): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_optional_with_input_without_ask(): @@ -154,7 +154,7 @@ def test_parse_args_in_yunohost_format_string_optional_with_input_without_ask(): expected_result = OrderedDict({"some_string": ("some_value", "string")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_no_input_default(): @@ -167,7 +167,7 @@ def test_parse_args_in_yunohost_format_string_no_input_default(): ] answers = {} expected_result = OrderedDict({"some_string": ("some_value", "string")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_input_test_ask(): @@ -183,7 +183,7 @@ def test_parse_args_in_yunohost_format_string_input_test_ask(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) prompt.assert_called_with(ask_text, False) @@ -202,7 +202,7 @@ def test_parse_args_in_yunohost_format_string_input_test_ask_with_default(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) prompt.assert_called_with("%s (default: %s)" % (ask_text, default_text), False) @@ -222,7 +222,7 @@ def test_parse_args_in_yunohost_format_string_input_test_ask_with_example(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert ask_text in prompt.call_args[0][0] assert example_text in prompt.call_args[0][0] @@ -243,7 +243,7 @@ def test_parse_args_in_yunohost_format_string_input_test_ask_with_help(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert ask_text in prompt.call_args[0][0] assert help_text in prompt.call_args[0][0] @@ -252,7 +252,7 @@ def test_parse_args_in_yunohost_format_string_with_choice(): questions = [{"name": "some_string", "type": "string", "choices": ["fr", "en"]}] answers = {"some_string": "fr"} expected_result = OrderedDict({"some_string": ("fr", "string")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_with_choice_prompt(): @@ -260,7 +260,7 @@ def test_parse_args_in_yunohost_format_string_with_choice_prompt(): answers = {"some_string": "fr"} expected_result = OrderedDict({"some_string": ("fr", "string")}) with patch.object(Moulinette.interface, "prompt", return_value="fr"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_string_with_choice_bad(): @@ -268,7 +268,7 @@ def test_parse_args_in_yunohost_format_string_with_choice_bad(): answers = {"some_string": "bad"} with pytest.raises(YunohostError): - assert _parse_args_in_yunohost_format(answers, questions) + assert parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_string_with_choice_ask(): @@ -284,7 +284,7 @@ def test_parse_args_in_yunohost_format_string_with_choice_ask(): answers = {} with patch.object(Moulinette.interface, "prompt", return_value="ru") as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert ask_text in prompt.call_args[0][0] for choice in choices: @@ -302,7 +302,7 @@ def test_parse_args_in_yunohost_format_string_with_choice_default(): ] answers = {} expected_result = OrderedDict({"some_string": ("en", "string")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_password(): @@ -314,7 +314,7 @@ def test_parse_args_in_yunohost_format_password(): ] answers = {"some_password": "some_value"} expected_result = OrderedDict({"some_password": ("some_value", "password")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_password_no_input(): @@ -327,7 +327,7 @@ def test_parse_args_in_yunohost_format_password_no_input(): answers = {} with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_password_input(): @@ -342,7 +342,7 @@ def test_parse_args_in_yunohost_format_password_input(): expected_result = OrderedDict({"some_password": ("some_value", "password")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_password_input_no_ask(): @@ -356,7 +356,7 @@ def test_parse_args_in_yunohost_format_password_input_no_ask(): expected_result = OrderedDict({"some_password": ("some_value", "password")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_password_no_input_optional(): @@ -370,13 +370,13 @@ def test_parse_args_in_yunohost_format_password_no_input_optional(): answers = {} expected_result = OrderedDict({"some_password": ("", "password")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result questions = [ {"name": "some_password", "type": "password", "optional": True, "default": ""} ] - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_password_optional_with_input(): @@ -392,7 +392,7 @@ def test_parse_args_in_yunohost_format_password_optional_with_input(): expected_result = OrderedDict({"some_password": ("some_value", "password")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_password_optional_with_empty_input(): @@ -408,7 +408,7 @@ def test_parse_args_in_yunohost_format_password_optional_with_empty_input(): expected_result = OrderedDict({"some_password": ("", "password")}) with patch.object(Moulinette.interface, "prompt", return_value=""): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_password_optional_with_input_without_ask(): @@ -423,7 +423,7 @@ def test_parse_args_in_yunohost_format_password_optional_with_input_without_ask( expected_result = OrderedDict({"some_password": ("some_value", "password")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_password_no_input_default(): @@ -439,7 +439,7 @@ def test_parse_args_in_yunohost_format_password_no_input_default(): # no default for password! with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) @pytest.mark.skip # this should raises @@ -456,7 +456,7 @@ def test_parse_args_in_yunohost_format_password_no_input_example(): # no example for password! with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_password_input_test_ask(): @@ -473,7 +473,7 @@ def test_parse_args_in_yunohost_format_password_input_test_ask(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) prompt.assert_called_with(ask_text, True) @@ -494,7 +494,7 @@ def test_parse_args_in_yunohost_format_password_input_test_ask_with_example(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert ask_text in prompt.call_args[0][0] assert example_text in prompt.call_args[0][0] @@ -516,7 +516,7 @@ def test_parse_args_in_yunohost_format_password_input_test_ask_with_help(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert ask_text in prompt.call_args[0][0] assert help_text in prompt.call_args[0][0] @@ -531,9 +531,9 @@ def test_parse_args_in_yunohost_format_password_bad_chars(): } ] - for i in PasswordArgumentParser.forbidden_chars: + for i in PasswordQuestion.forbidden_chars: with pytest.raises(YunohostError): - _parse_args_in_yunohost_format({"some_password": i * 8}, questions) + parse_args_in_yunohost_format({"some_password": i * 8}, questions) def test_parse_args_in_yunohost_format_password_strong_enough(): @@ -548,10 +548,10 @@ def test_parse_args_in_yunohost_format_password_strong_enough(): with pytest.raises(YunohostError): # too short - _parse_args_in_yunohost_format({"some_password": "a"}, questions) + parse_args_in_yunohost_format({"some_password": "a"}, questions) with pytest.raises(YunohostError): - _parse_args_in_yunohost_format({"some_password": "password"}, questions) + parse_args_in_yunohost_format({"some_password": "password"}, questions) def test_parse_args_in_yunohost_format_password_optional_strong_enough(): @@ -566,10 +566,10 @@ def test_parse_args_in_yunohost_format_password_optional_strong_enough(): with pytest.raises(YunohostError): # too short - _parse_args_in_yunohost_format({"some_password": "a"}, questions) + parse_args_in_yunohost_format({"some_password": "a"}, questions) with pytest.raises(YunohostError): - _parse_args_in_yunohost_format({"some_password": "password"}, questions) + parse_args_in_yunohost_format({"some_password": "password"}, questions) def test_parse_args_in_yunohost_format_path(): @@ -581,7 +581,7 @@ def test_parse_args_in_yunohost_format_path(): ] answers = {"some_path": "some_value"} expected_result = OrderedDict({"some_path": ("some_value", "path")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_path_no_input(): @@ -594,7 +594,7 @@ def test_parse_args_in_yunohost_format_path_no_input(): answers = {} with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_path_input(): @@ -609,7 +609,7 @@ def test_parse_args_in_yunohost_format_path_input(): expected_result = OrderedDict({"some_path": ("some_value", "path")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_path_input_no_ask(): @@ -623,7 +623,7 @@ def test_parse_args_in_yunohost_format_path_input_no_ask(): expected_result = OrderedDict({"some_path": ("some_value", "path")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_path_no_input_optional(): @@ -636,7 +636,7 @@ def test_parse_args_in_yunohost_format_path_no_input_optional(): ] answers = {} expected_result = OrderedDict({"some_path": ("", "path")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_path_optional_with_input(): @@ -652,7 +652,7 @@ def test_parse_args_in_yunohost_format_path_optional_with_input(): expected_result = OrderedDict({"some_path": ("some_value", "path")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_path_optional_with_empty_input(): @@ -668,7 +668,7 @@ def test_parse_args_in_yunohost_format_path_optional_with_empty_input(): expected_result = OrderedDict({"some_path": ("", "path")}) with patch.object(Moulinette.interface, "prompt", return_value=""): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_path_optional_with_input_without_ask(): @@ -683,7 +683,7 @@ def test_parse_args_in_yunohost_format_path_optional_with_input_without_ask(): expected_result = OrderedDict({"some_path": ("some_value", "path")}) with patch.object(Moulinette.interface, "prompt", return_value="some_value"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_path_no_input_default(): @@ -697,7 +697,7 @@ def test_parse_args_in_yunohost_format_path_no_input_default(): ] answers = {} expected_result = OrderedDict({"some_path": ("some_value", "path")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_path_input_test_ask(): @@ -714,7 +714,7 @@ def test_parse_args_in_yunohost_format_path_input_test_ask(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) prompt.assert_called_with(ask_text, False) @@ -734,7 +734,7 @@ def test_parse_args_in_yunohost_format_path_input_test_ask_with_default(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) prompt.assert_called_with("%s (default: %s)" % (ask_text, default_text), False) @@ -755,7 +755,7 @@ def test_parse_args_in_yunohost_format_path_input_test_ask_with_example(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert ask_text in prompt.call_args[0][0] assert example_text in prompt.call_args[0][0] @@ -777,7 +777,7 @@ def test_parse_args_in_yunohost_format_path_input_test_ask_with_help(): with patch.object( Moulinette.interface, "prompt", return_value="some_value" ) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert ask_text in prompt.call_args[0][0] assert help_text in prompt.call_args[0][0] @@ -791,7 +791,7 @@ def test_parse_args_in_yunohost_format_boolean(): ] answers = {"some_boolean": "y"} expected_result = OrderedDict({"some_boolean": (1, "boolean")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_boolean_all_yes(): @@ -803,47 +803,47 @@ def test_parse_args_in_yunohost_format_boolean_all_yes(): ] expected_result = OrderedDict({"some_boolean": (1, "boolean")}) assert ( - _parse_args_in_yunohost_format({"some_boolean": "y"}, questions) + parse_args_in_yunohost_format({"some_boolean": "y"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "Y"}, questions) + parse_args_in_yunohost_format({"some_boolean": "Y"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "yes"}, questions) + parse_args_in_yunohost_format({"some_boolean": "yes"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "Yes"}, questions) + parse_args_in_yunohost_format({"some_boolean": "Yes"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "YES"}, questions) + parse_args_in_yunohost_format({"some_boolean": "YES"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "1"}, questions) + parse_args_in_yunohost_format({"some_boolean": "1"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": 1}, questions) + parse_args_in_yunohost_format({"some_boolean": 1}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": True}, questions) + parse_args_in_yunohost_format({"some_boolean": True}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "True"}, questions) + parse_args_in_yunohost_format({"some_boolean": "True"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "TRUE"}, questions) + parse_args_in_yunohost_format({"some_boolean": "TRUE"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "true"}, questions) + parse_args_in_yunohost_format({"some_boolean": "true"}, questions) == expected_result ) @@ -857,47 +857,47 @@ def test_parse_args_in_yunohost_format_boolean_all_no(): ] expected_result = OrderedDict({"some_boolean": (0, "boolean")}) assert ( - _parse_args_in_yunohost_format({"some_boolean": "n"}, questions) + parse_args_in_yunohost_format({"some_boolean": "n"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "N"}, questions) + parse_args_in_yunohost_format({"some_boolean": "N"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "no"}, questions) + parse_args_in_yunohost_format({"some_boolean": "no"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "No"}, questions) + parse_args_in_yunohost_format({"some_boolean": "No"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "No"}, questions) + parse_args_in_yunohost_format({"some_boolean": "No"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "0"}, questions) + parse_args_in_yunohost_format({"some_boolean": "0"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": 0}, questions) + parse_args_in_yunohost_format({"some_boolean": 0}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": False}, questions) + parse_args_in_yunohost_format({"some_boolean": False}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "False"}, questions) + parse_args_in_yunohost_format({"some_boolean": "False"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "FALSE"}, questions) + parse_args_in_yunohost_format({"some_boolean": "FALSE"}, questions) == expected_result ) assert ( - _parse_args_in_yunohost_format({"some_boolean": "false"}, questions) + parse_args_in_yunohost_format({"some_boolean": "false"}, questions) == expected_result ) @@ -913,7 +913,7 @@ def test_parse_args_in_yunohost_format_boolean_no_input(): answers = {} expected_result = OrderedDict({"some_boolean": (0, "boolean")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_boolean_bad_input(): @@ -926,7 +926,7 @@ def test_parse_args_in_yunohost_format_boolean_bad_input(): answers = {"some_boolean": "stuff"} with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_boolean_input(): @@ -941,11 +941,11 @@ def test_parse_args_in_yunohost_format_boolean_input(): expected_result = OrderedDict({"some_boolean": (1, "boolean")}) with patch.object(Moulinette.interface, "prompt", return_value="y"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result expected_result = OrderedDict({"some_boolean": (0, "boolean")}) with patch.object(Moulinette.interface, "prompt", return_value="n"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_boolean_input_no_ask(): @@ -959,7 +959,7 @@ def test_parse_args_in_yunohost_format_boolean_input_no_ask(): expected_result = OrderedDict({"some_boolean": (1, "boolean")}) with patch.object(Moulinette.interface, "prompt", return_value="y"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_boolean_no_input_optional(): @@ -972,7 +972,7 @@ def test_parse_args_in_yunohost_format_boolean_no_input_optional(): ] answers = {} expected_result = OrderedDict({"some_boolean": (0, "boolean")}) # default to false - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_boolean_optional_with_input(): @@ -988,7 +988,7 @@ def test_parse_args_in_yunohost_format_boolean_optional_with_input(): expected_result = OrderedDict({"some_boolean": (1, "boolean")}) with patch.object(Moulinette.interface, "prompt", return_value="y"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_boolean_optional_with_empty_input(): @@ -1004,7 +1004,7 @@ def test_parse_args_in_yunohost_format_boolean_optional_with_empty_input(): expected_result = OrderedDict({"some_boolean": (0, "boolean")}) # default to false with patch.object(Moulinette.interface, "prompt", return_value=""): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_boolean_optional_with_input_without_ask(): @@ -1019,7 +1019,7 @@ def test_parse_args_in_yunohost_format_boolean_optional_with_input_without_ask() expected_result = OrderedDict({"some_boolean": (0, "boolean")}) with patch.object(Moulinette.interface, "prompt", return_value="n"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_boolean_no_input_default(): @@ -1033,7 +1033,7 @@ def test_parse_args_in_yunohost_format_boolean_no_input_default(): ] answers = {} expected_result = OrderedDict({"some_boolean": (0, "boolean")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_boolean_bad_default(): @@ -1047,7 +1047,7 @@ def test_parse_args_in_yunohost_format_boolean_bad_default(): ] answers = {} with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_boolean_input_test_ask(): @@ -1062,7 +1062,7 @@ def test_parse_args_in_yunohost_format_boolean_input_test_ask(): answers = {} with patch.object(Moulinette.interface, "prompt", return_value=0) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) prompt.assert_called_with(ask_text + " [yes | no] (default: no)", False) @@ -1080,7 +1080,7 @@ def test_parse_args_in_yunohost_format_boolean_input_test_ask_with_default(): answers = {} with patch.object(Moulinette.interface, "prompt", return_value=1) as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) prompt.assert_called_with("%s [yes | no] (default: yes)" % ask_text, False) @@ -1098,7 +1098,7 @@ def test_parse_args_in_yunohost_format_domain_empty(): with patch.object( domain, "_get_maindomain", return_value="my_main_domain.com" ), patch.object(domain, "domain_list", return_value={"domains": [main_domain]}): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_domain(): @@ -1117,7 +1117,7 @@ def test_parse_args_in_yunohost_format_domain(): with patch.object( domain, "_get_maindomain", return_value=main_domain ), patch.object(domain, "domain_list", return_value={"domains": domains}): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_domain_two_domains(): @@ -1137,7 +1137,7 @@ def test_parse_args_in_yunohost_format_domain_two_domains(): with patch.object( domain, "_get_maindomain", return_value=main_domain ), patch.object(domain, "domain_list", return_value={"domains": domains}): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result answers = {"some_domain": main_domain} expected_result = OrderedDict({"some_domain": (main_domain, "domain")}) @@ -1145,7 +1145,7 @@ def test_parse_args_in_yunohost_format_domain_two_domains(): with patch.object( domain, "_get_maindomain", return_value=main_domain ), patch.object(domain, "domain_list", return_value={"domains": domains}): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_domain_two_domains_wrong_answer(): @@ -1165,7 +1165,7 @@ def test_parse_args_in_yunohost_format_domain_two_domains_wrong_answer(): domain, "_get_maindomain", return_value=main_domain ), patch.object(domain, "domain_list", return_value={"domains": domains}): with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_domain_two_domains_default_no_ask(): @@ -1185,7 +1185,7 @@ def test_parse_args_in_yunohost_format_domain_two_domains_default_no_ask(): with patch.object( domain, "_get_maindomain", return_value=main_domain ), patch.object(domain, "domain_list", return_value={"domains": domains}): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_domain_two_domains_default(): @@ -1200,7 +1200,7 @@ def test_parse_args_in_yunohost_format_domain_two_domains_default(): with patch.object( domain, "_get_maindomain", return_value=main_domain ), patch.object(domain, "domain_list", return_value={"domains": domains}): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_domain_two_domains_default_input(): @@ -1216,11 +1216,11 @@ def test_parse_args_in_yunohost_format_domain_two_domains_default_input(): ), patch.object(domain, "domain_list", return_value={"domains": domains}): expected_result = OrderedDict({"some_domain": (main_domain, "domain")}) with patch.object(Moulinette.interface, "prompt", return_value=main_domain): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result expected_result = OrderedDict({"some_domain": (other_domain, "domain")}) with patch.object(Moulinette.interface, "prompt", return_value=other_domain): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_user_empty(): @@ -1244,7 +1244,7 @@ def test_parse_args_in_yunohost_format_user_empty(): with patch.object(user, "user_list", return_value={"users": users}): with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_user(): @@ -1271,7 +1271,7 @@ def test_parse_args_in_yunohost_format_user(): with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_info", return_value={}): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_user_two_users(): @@ -1305,14 +1305,14 @@ def test_parse_args_in_yunohost_format_user_two_users(): with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_info", return_value={}): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result answers = {"some_user": username} expected_result = OrderedDict({"some_user": (username, "user")}) with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_info", return_value={}): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_user_two_users_wrong_answer(): @@ -1345,7 +1345,7 @@ def test_parse_args_in_yunohost_format_user_two_users_wrong_answer(): with patch.object(user, "user_list", return_value={"users": users}): with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_user_two_users_no_default(): @@ -1373,7 +1373,7 @@ def test_parse_args_in_yunohost_format_user_two_users_no_default(): with patch.object(user, "user_list", return_value={"users": users}): with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_user_two_users_default_input(): @@ -1404,14 +1404,14 @@ def test_parse_args_in_yunohost_format_user_two_users_default_input(): expected_result = OrderedDict({"some_user": (username, "user")}) with patch.object(Moulinette.interface, "prompt", return_value=username): assert ( - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) == expected_result ) expected_result = OrderedDict({"some_user": (other_user, "user")}) with patch.object(Moulinette.interface, "prompt", return_value=other_user): assert ( - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) == expected_result ) @@ -1425,7 +1425,7 @@ def test_parse_args_in_yunohost_format_number(): ] answers = {"some_number": 1337} expected_result = OrderedDict({"some_number": (1337, "number")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_number_no_input(): @@ -1438,7 +1438,7 @@ def test_parse_args_in_yunohost_format_number_no_input(): answers = {} expected_result = OrderedDict({"some_number": (0, "number")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_number_bad_input(): @@ -1451,11 +1451,11 @@ def test_parse_args_in_yunohost_format_number_bad_input(): answers = {"some_number": "stuff"} with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) answers = {"some_number": 1.5} with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_number_input(): @@ -1470,14 +1470,14 @@ def test_parse_args_in_yunohost_format_number_input(): expected_result = OrderedDict({"some_number": (1337, "number")}) with patch.object(Moulinette.interface, "prompt", return_value="1337"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result with patch.object(Moulinette.interface, "prompt", return_value=1337): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result expected_result = OrderedDict({"some_number": (0, "number")}) with patch.object(Moulinette.interface, "prompt", return_value=""): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_number_input_no_ask(): @@ -1491,7 +1491,7 @@ def test_parse_args_in_yunohost_format_number_input_no_ask(): expected_result = OrderedDict({"some_number": (1337, "number")}) with patch.object(Moulinette.interface, "prompt", return_value="1337"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_number_no_input_optional(): @@ -1504,7 +1504,7 @@ def test_parse_args_in_yunohost_format_number_no_input_optional(): ] answers = {} expected_result = OrderedDict({"some_number": (0, "number")}) # default to 0 - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_number_optional_with_input(): @@ -1520,7 +1520,7 @@ def test_parse_args_in_yunohost_format_number_optional_with_input(): expected_result = OrderedDict({"some_number": (1337, "number")}) with patch.object(Moulinette.interface, "prompt", return_value="1337"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_number_optional_with_input_without_ask(): @@ -1535,7 +1535,7 @@ def test_parse_args_in_yunohost_format_number_optional_with_input_without_ask(): expected_result = OrderedDict({"some_number": (0, "number")}) with patch.object(Moulinette.interface, "prompt", return_value="0"): - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_number_no_input_default(): @@ -1549,7 +1549,7 @@ def test_parse_args_in_yunohost_format_number_no_input_default(): ] answers = {} expected_result = OrderedDict({"some_number": (1337, "number")}) - assert _parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_number_bad_default(): @@ -1563,7 +1563,7 @@ def test_parse_args_in_yunohost_format_number_bad_default(): ] answers = {} with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) def test_parse_args_in_yunohost_format_number_input_test_ask(): @@ -1578,7 +1578,7 @@ def test_parse_args_in_yunohost_format_number_input_test_ask(): answers = {} with patch.object(Moulinette.interface, "prompt", return_value="1111") as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) prompt.assert_called_with("%s (default: 0)" % (ask_text), False) @@ -1596,7 +1596,7 @@ def test_parse_args_in_yunohost_format_number_input_test_ask_with_default(): answers = {} with patch.object(Moulinette.interface, "prompt", return_value="1111") as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) prompt.assert_called_with("%s (default: %s)" % (ask_text, default_value), False) @@ -1615,7 +1615,7 @@ def test_parse_args_in_yunohost_format_number_input_test_ask_with_example(): answers = {} with patch.object(Moulinette.interface, "prompt", return_value="1111") as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert ask_text in prompt.call_args[0][0] assert example_value in prompt.call_args[0][0] @@ -1635,7 +1635,7 @@ def test_parse_args_in_yunohost_format_number_input_test_ask_with_help(): answers = {} with patch.object(Moulinette.interface, "prompt", return_value="1111") as prompt: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert ask_text in prompt.call_args[0][0] assert help_value in prompt.call_args[0][0] @@ -1645,5 +1645,5 @@ def test_parse_args_in_yunohost_format_display_text(): answers = {} with patch.object(sys, "stdout", new_callable=StringIO) as stdout: - _parse_args_in_yunohost_format(answers, questions) + parse_args_in_yunohost_format(answers, questions) assert "foobar" in stdout.getvalue() diff --git a/src/yunohost/tests/test_service.py b/src/yunohost/tests/test_service.py index 1007419a1..88013a3fe 100644 --- a/src/yunohost/tests/test_service.py +++ b/src/yunohost/tests/test_service.py @@ -132,7 +132,7 @@ def test_service_conf_broken(): status = service_status("nginx") assert status["status"] == "running" assert status["configuration"] == "broken" - assert "broken.conf" in status["configuration-details"] + assert "broken.conf" in status["configuration-details"][0] # Service reload-or-restart should check that the conf ain't valid # before reload-or-restart, hence the service should still be running From c37b21ae140116a1b228344afa2e896e9ec07119 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 5 Sep 2021 15:39:43 +0200 Subject: [PATCH 101/101] ci: test-actionmap should only test actionmap ;) --- .gitlab/ci/test.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/ci/test.gitlab-ci.yml b/.gitlab/ci/test.gitlab-ci.yml index e0e0e001a..80d710f71 100644 --- a/.gitlab/ci/test.gitlab-ci.yml +++ b/.gitlab/ci/test.gitlab-ci.yml @@ -71,7 +71,7 @@ test-translation-format-consistency: test-actionmap: extends: .test-stage script: - - python3 -m pytest tests tests/test_actionmap.py + - python3 -m pytest tests/test_actionmap.py only: changes: - data/actionsmap/*.yml