Merge branch 'dev' into bullseye

This commit is contained in:
Alexandre Aubin 2021-10-02 19:59:09 +02:00
commit 8ef882b4f5
47 changed files with 453 additions and 272 deletions

29
.github/workflows/i18n.yml vendored Normal file
View file

@ -0,0 +1,29 @@
name: Autoreformat locale files
on:
push:
branches:
- dev
jobs:
i18n:
name: Autoreformat locale files
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Apply reformating scripts
id: action_reformat
run: |
python3 test/remove_stale_i18n_strings.py
python3 test/autofix_locale_format.py
python3 test/reformat_locales.py
git diff -w --exit-code
- name: Create Pull Request
if: ${{ failure() }}
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
title: "Reformat locale files"
commit-message: ":robot: Reformat locale files"
body: |
Automatic pull request using the scripts in `test/`
base: ${{ github.head_ref }}
branch: actions/i18nreformat

View file

@ -45,3 +45,5 @@ jobs:
pip install tox tox-gh-actions pip install tox tox-gh-actions
- name: Linter - name: Linter
run: tox -e py39-invalidcode run: tox -e py39-invalidcode
- name: Mypy
run: tox -e py39-mypy

View file

@ -2,6 +2,7 @@
<div align="center"> <div align="center">
![Version](https://img.shields.io/github/v/tag/yunohost/moulinette?label=version&sort=semver)
[![Tests status](https://github.com/YunoHost/moulinette/actions/workflows/tox.yml/badge.svg)](https://github.com/YunoHost/moulinette/actions/workflows/tox.yml) [![Tests status](https://github.com/YunoHost/moulinette/actions/workflows/tox.yml/badge.svg)](https://github.com/YunoHost/moulinette/actions/workflows/tox.yml)
[![GitHub license](https://img.shields.io/github/license/YunoHost/moulinette)](https://github.com/YunoHost/moulinette/blob/dev/LICENSE) [![GitHub license](https://img.shields.io/github/license/YunoHost/moulinette)](https://github.com/YunoHost/moulinette/blob/dev/LICENSE)

23
debian/changelog vendored
View file

@ -4,6 +4,29 @@ moulinette (11.0.0~alpha) unstable; urgency=low
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 05 Feb 2021 00:02:38 +0100 -- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 05 Feb 2021 00:02:38 +0100
moulinette (4.3.1) testing; urgency=low
- [mod] Rework cli prompt mecanisc ([#303](https://github.com/YunoHost/moulinette/pull/303))
- [i18n] Translations updated for Indonesian, Russian, Turkish
Thanks to all contributors <3 ! (Éric Gaspar, liimee)
-- Alexandre Aubin <alex.aubin@mailoo.org> Wed, 29 Sep 2021 22:37:28 +0200
moulinette (4.3.0) testing; urgency=low
- [enh] Allow file type in actionmaps ([#258](https://github.com/YunoHost/moulinette/pull/258))
- [refactor] Rework and externalize the authenticator system ([#270](https://github.com/YunoHost/moulinette/pull/270))
- [security] Add httponly to API cookies (8562c05d)
- [enh] Add prefill and multiline in prompt ([#290](https://github.com/YunoHost/moulinette/pull/290), 08f7866f)
- [enh] Support bytes/stream in write_to_file (6e714314)
- [fix] Various technical bugs in utils/process.py (fdc61c91, 4eb60dac, 3741101d)
- [i18n] Translations updated for French, Galician, Persian, Ukrainian
Thanks to all contributors <3 ! (Éric Gaspar, José M, Kay0u, ljf, Parviz Homayun, ppr, Tymofii-Lytvynenko)
-- Alexandre Aubin <alex.aubin@mailoo.org> Sun, 19 Sep 2021 21:19:43 +0200
moulinette (4.2.4) stable; urgency=low moulinette (4.2.4) stable; urgency=low
- [fix] Avoid warning and use safeloader ([#281](https://github.com/YunoHost/moulinette/pull/281)) - [fix] Avoid warning and use safeloader ([#281](https://github.com/YunoHost/moulinette/pull/281))

4
debian/control vendored
View file

@ -14,7 +14,9 @@ Depends: ${misc:Depends}, ${python3:Depends},
python3-gevent-websocket, python3-gevent-websocket,
python3-toml, python3-toml,
python3-psutil, python3-psutil,
python3-tz python3-tz,
python3-prompt-toolkit,
python3-pygments
Breaks: yunohost (<< 4.1) Breaks: yunohost (<< 4.1)
Description: prototype interfaces with ease in Python Description: prototype interfaces with ease in Python
Quickly and easily prototype interfaces for your application. Quickly and easily prototype interfaces for your application.

View file

@ -1,8 +1,6 @@
{ {
"argument_required": "المُعامِل '{argument}' مطلوب", "argument_required": "المُعامِل '{argument}' مطلوب",
"authentication_required": "المصادقة مطلوبة", "authentication_required": "المصادقة مطلوبة",
"authentication_required_long": "المصادقة مطلوبة قبل القيام بهذا الإجراء",
"colon": "{}: ",
"confirm": "تأكيد {prompt}", "confirm": "تأكيد {prompt}",
"deprecated_command": "'{prog} {command}' تم التخلي عنه و سوف تتم إزالته مستقبلا", "deprecated_command": "'{prog} {command}' تم التخلي عنه و سوف تتم إزالته مستقبلا",
"deprecated_command_alias": "'{prog} {old}' تم التخلي عنه و سوف يتم إزالته مستقبلا، إستخدم '{prog} {new}' بدلا من ذلك", "deprecated_command_alias": "'{prog} {old}' تم التخلي عنه و سوف يتم إزالته مستقبلا، إستخدم '{prog} {new}' بدلا من ذلك",
@ -11,10 +9,7 @@
"folder_exists": "إنّ المجلد موجود من قبل : '{path}'", "folder_exists": "إنّ المجلد موجود من قبل : '{path}'",
"instance_already_running": "هناك بالفعل عملية YunoHost جارية. الرجاء الانتظار حتى ينتهي الأمر قبل تشغيل آخر.", "instance_already_running": "هناك بالفعل عملية YunoHost جارية. الرجاء الانتظار حتى ينتهي الأمر قبل تشغيل آخر.",
"invalid_argument": "المُعامِل غير صالح '{argument}': {error}", "invalid_argument": "المُعامِل غير صالح '{argument}': {error}",
"invalid_password": "كلمة السر خاطئة",
"invalid_usage": "إستعمال غير صالح، إستخدم --help لعرض المساعدة", "invalid_usage": "إستعمال غير صالح، إستخدم --help لعرض المساعدة",
"ldap_attribute_already_exists": "الخاصية '{attribute}' موجودة مسبقا و تحمل القيمة '{value}'",
"ldap_server_down": "لا يمكن الإتصال بخادم LDAP",
"logged_in": "مُتّصل", "logged_in": "مُتّصل",
"logged_out": "تم تسجيل خروجك", "logged_out": "تم تسجيل خروجك",
"not_logged_in": "لم تقم بعدُ بتسجيل دخولك", "not_logged_in": "لم تقم بعدُ بتسجيل دخولك",
@ -25,7 +20,6 @@
"server_already_running": "هناك خادم يشتغل على ذاك المنفذ", "server_already_running": "هناك خادم يشتغل على ذاك المنفذ",
"success": "تم بنجاح !", "success": "تم بنجاح !",
"unable_authenticate": "تعذرت المصادقة", "unable_authenticate": "تعذرت المصادقة",
"unable_retrieve_session": "تعذرت مواصلة الجلسة بسبب '{exception}'",
"unknown_group": "الفريق '{group}' مجهول", "unknown_group": "الفريق '{group}' مجهول",
"unknown_user": "المستخدم '{user}' مجهول", "unknown_user": "المستخدم '{user}' مجهول",
"values_mismatch": "القيمتين غير متطابقتين", "values_mismatch": "القيمتين غير متطابقتين",
@ -47,8 +41,5 @@
"info": "معلومة:", "info": "معلومة:",
"warn_the_user_about_waiting_lock_again": "جارٍ الانتظار…", "warn_the_user_about_waiting_lock_again": "جارٍ الانتظار…",
"warn_the_user_that_lock_is_acquired": "لقد انتهى تنفيذ ذاك الأمر للتوّ ، جارٍ تنفيذ هذا الأمر", "warn_the_user_that_lock_is_acquired": "لقد انتهى تنفيذ ذاك الأمر للتوّ ، جارٍ تنفيذ هذا الأمر",
"warn_the_user_about_waiting_lock": "هناك أمر لـ YunoHost قيد التشغيل حاليا. في انتظار انتهاء تنفيذه قبل تشغيل التالي", "warn_the_user_about_waiting_lock": "هناك أمر لـ YunoHost قيد التشغيل حاليا. في انتظار انتهاء تنفيذه قبل تشغيل التالي"
"ldap_server_is_down_restart_it": "إنّ خدمة LDAP غير مشغّلة ، نحن بصدد محاولة إعادة تشغيلها…",
"session_expired": "لقد انتهت مدة صلاحية الجلسة. رجاءً أعد الإستيثاق.",
"invalid_token": "إنّ الرمز المميز غير صالح - يرجى الإستيثاق"
} }

View file

@ -1,8 +1,6 @@
{ {
"argument_required": "Es requereix l'argument {argument}", "argument_required": "Es requereix l'argument {argument}",
"authentication_required": "Es requereix autenticació", "authentication_required": "Es requereix autenticació",
"authentication_required_long": "Es requereix autenticació per realitzar aquesta tasca",
"colon": "{}: ",
"confirm": "Confirmar{prompt}", "confirm": "Confirmar{prompt}",
"deprecated_command": "{prog}{command}és obsolet i es desinstal·larà en el futur", "deprecated_command": "{prog}{command}és obsolet i es desinstal·larà en el futur",
"deprecated_command_alias": "{prog}{old}és obsolet i es desinstal·larà en el futur, utilitzeu {prog}{new}en el seu lloc", "deprecated_command_alias": "{prog}{old}és obsolet i es desinstal·larà en el futur, utilitzeu {prog}{new}en el seu lloc",
@ -11,10 +9,7 @@
"folder_exists": "La carpeta ja existeix: '{path}'", "folder_exists": "La carpeta ja existeix: '{path}'",
"instance_already_running": "Ja hi ha una operació de YunoHost en curs. Espereu a que s'acabi abans d'executar-ne una altra.", "instance_already_running": "Ja hi ha una operació de YunoHost en curs. Espereu a que s'acabi abans d'executar-ne una altra.",
"invalid_argument": "Argument invàlid '{argument}': {error}", "invalid_argument": "Argument invàlid '{argument}': {error}",
"invalid_password": "Contrasenya invàlida",
"invalid_usage": "Utilització invàlida, utilitzeu --help per veure l'ajuda", "invalid_usage": "Utilització invàlida, utilitzeu --help per veure l'ajuda",
"ldap_attribute_already_exists": "L'atribut '{attribute}' ja existeix amb el valor '{value}'",
"ldap_server_down": "No s'ha pogut connectar amb el servidor LDAP",
"logged_in": "Sessió iniciada", "logged_in": "Sessió iniciada",
"logged_out": "Sessió tancada", "logged_out": "Sessió tancada",
"not_logged_in": "No ha iniciat sessió", "not_logged_in": "No ha iniciat sessió",
@ -25,7 +20,6 @@
"server_already_running": "Ja s'està executant un servidor en aquest port", "server_already_running": "Ja s'està executant un servidor en aquest port",
"success": "Èxit!", "success": "Èxit!",
"unable_authenticate": "No s'ha pogut autenticar", "unable_authenticate": "No s'ha pogut autenticar",
"unable_retrieve_session": "No s'ha pogut recuperar la sessió a causa de «{exception}»",
"unknown_group": "Grup '{group}' desconegut", "unknown_group": "Grup '{group}' desconegut",
"unknown_user": "Usuari '{user}' desconegut", "unknown_user": "Usuari '{user}' desconegut",
"values_mismatch": "Els valors no coincideixen", "values_mismatch": "Els valors no coincideixen",
@ -48,8 +42,5 @@
"corrupted_toml": "El fitxer TOML ha estat corromput en la lectura des de {ressource} (motiu: {error})", "corrupted_toml": "El fitxer TOML ha estat corromput en la lectura des de {ressource} (motiu: {error})",
"warn_the_user_about_waiting_lock": "Hi ha una altra ordre de YunoHost en execució, s'executarà aquesta ordre un cop l'anterior hagi acabat", "warn_the_user_about_waiting_lock": "Hi ha una altra ordre de YunoHost en execució, s'executarà aquesta ordre un cop l'anterior hagi acabat",
"warn_the_user_about_waiting_lock_again": "Encara en espera…", "warn_the_user_about_waiting_lock_again": "Encara en espera…",
"warn_the_user_that_lock_is_acquired": "L'altra ordre tot just ha acabat, ara s'executarà aquesta ordre", "warn_the_user_that_lock_is_acquired": "L'altra ordre tot just ha acabat, ara s'executarà aquesta ordre"
"invalid_token": "Testimoni no vàlid - torneu-vos a autenticar",
"ldap_server_is_down_restart_it": "El servei LDAP està caigut, s'està intentant tornar-lo a engegar…",
"session_expired": "La sessió a expirat. Torneu-vos a autenticar."
} }

View file

@ -1,8 +1,6 @@
{ {
"argument_required": "参数“{argument}”是必须的", "argument_required": "参数“{argument}”是必须的",
"authentication_required": "需要验证", "authentication_required": "需要验证",
"authentication_required_long": "此操作需要验证",
"colon": "{} ",
"confirm": "确认 {prompt}", "confirm": "确认 {prompt}",
"deprecated_command": "{prog}{command}已经放弃使用,将来会删除", "deprecated_command": "{prog}{command}已经放弃使用,将来会删除",
"deprecated_command_alias": "{prog}{old}已经放弃使用,将来会删除,请使用{prog}{new}代替", "deprecated_command_alias": "{prog}{old}已经放弃使用,将来会删除,请使用{prog}{new}代替",
@ -12,10 +10,7 @@
"info": "信息:", "info": "信息:",
"instance_already_running": "已经有一个YunoHost操作正在运行。 请等待它完成再运行另一个。", "instance_already_running": "已经有一个YunoHost操作正在运行。 请等待它完成再运行另一个。",
"invalid_argument": "参数错误{argument}{error}", "invalid_argument": "参数错误{argument}{error}",
"invalid_password": "密码错误",
"invalid_usage": "用法错误,输入 --help 查看帮助信息", "invalid_usage": "用法错误,输入 --help 查看帮助信息",
"ldap_attribute_already_exists": "参数{attribute}已赋值{value}",
"ldap_server_down": "无法连接LDAP服务器",
"logged_in": "登录", "logged_in": "登录",
"logged_out": "登出", "logged_out": "登出",
"not_logged_in": "您未登录", "not_logged_in": "您未登录",
@ -26,7 +21,6 @@
"server_already_running": "服务已运行在指定端口", "server_already_running": "服务已运行在指定端口",
"success": "成功!", "success": "成功!",
"unable_authenticate": "认证失败", "unable_authenticate": "认证失败",
"unable_retrieve_session": "由于“ {exception}”,无法检索会话",
"unknown_group": "未知组{group}", "unknown_group": "未知组{group}",
"unknown_user": "未知用户{user}", "unknown_user": "未知用户{user}",
"values_mismatch": "值不匹配", "values_mismatch": "值不匹配",
@ -48,8 +42,5 @@
"warn_the_user_that_lock_is_acquired": "另一个命令刚刚完成,现在启动此命令", "warn_the_user_that_lock_is_acquired": "另一个命令刚刚完成,现在启动此命令",
"warn_the_user_about_waiting_lock_again": "还在等...", "warn_the_user_about_waiting_lock_again": "还在等...",
"warn_the_user_about_waiting_lock": "目前正在运行另一个YunoHost命令我们在运行此命令之前等待它完成", "warn_the_user_about_waiting_lock": "目前正在运行另一个YunoHost命令我们在运行此命令之前等待它完成",
"corrupted_toml": "从{ressources}读取的TOML损坏原因{errors}", "corrupted_toml": "从{ressources}读取的TOML损坏原因{errors}"
"invalid_token": "令牌无效-请进行身份验证",
"ldap_server_is_down_restart_it": "LDAP服务已下线正在尝试重启服务……",
"session_expired": "会话已过期。请重新进行身份验证。"
} }

View file

@ -1,7 +1,6 @@
{ {
"password": "Heslo", "password": "Heslo",
"logged_out": "Jste odhlášen/a", "logged_out": "Jste odhlášen/a",
"ldap_server_is_down_restart_it": "LDAP služba neběží, probíhá pokus o její nastartování...",
"warn_the_user_that_lock_is_acquired": "Předchozí operace dokončena, nyní spouštíme tuto", "warn_the_user_that_lock_is_acquired": "Předchozí operace dokončena, nyní spouštíme tuto",
"warn_the_user_about_waiting_lock_again": "Stále čekáme...", "warn_the_user_about_waiting_lock_again": "Stále čekáme...",
"warn_the_user_about_waiting_lock": "Jiná YunoHost operace právě probíhá, před spuštěním této čekáme na její dokončení", "warn_the_user_about_waiting_lock": "Jiná YunoHost operace právě probíhá, před spuštěním této čekáme na její dokončení",
@ -24,8 +23,6 @@
"values_mismatch": "Hodnoty nesouhlasí", "values_mismatch": "Hodnoty nesouhlasí",
"unknown_user": "Neznámý '{user}' uživatel", "unknown_user": "Neznámý '{user}' uživatel",
"unknown_group": "Neznámá '{group}' skupina", "unknown_group": "Neznámá '{group}' skupina",
"session_expired": "Sezení vypršelo. Přihlašte se znovu, prosím.",
"unable_retrieve_session": "Není možné obdržet sezení neboť '{exception}'",
"unable_authenticate": "Není možné ověřit", "unable_authenticate": "Není možné ověřit",
"success": "Zadařilo se!", "success": "Zadařilo se!",
"server_already_running": "Na tomto portu je server již provozován", "server_already_running": "Na tomto portu je server již provozován",
@ -34,11 +31,7 @@
"operation_interrupted": "Operace přerušena", "operation_interrupted": "Operace přerušena",
"not_logged_in": "Nejste přihlášen", "not_logged_in": "Nejste přihlášen",
"logged_in": "Přihlášení", "logged_in": "Přihlášení",
"ldap_server_down": "Spojení s LDAP serverem se nezdařilo",
"ldap_attribute_already_exists": "Atribut '{attribute}' již obsahuje hodnotu '{value}'",
"invalid_usage": "Nesprávné použití, pass --help pro zobrazení nápovědy", "invalid_usage": "Nesprávné použití, pass --help pro zobrazení nápovědy",
"invalid_token": "Nesprávný token - ověřte se prosím",
"invalid_password": "Nesprávné heslo",
"invalid_argument": "Nesprávný argument '{argument}': {error}", "invalid_argument": "Nesprávný argument '{argument}': {error}",
"instance_already_running": "Právě probíhá jiná YunoHost operace. Před spuštěním další operace vyčkejte na její dokončení.", "instance_already_running": "Právě probíhá jiná YunoHost operace. Před spuštěním další operace vyčkejte na její dokončení.",
"info": "Info:", "info": "Info:",
@ -48,8 +41,6 @@
"deprecated_command_alias": "'{prog} {old}' je zastaralý a bude odebrán v budoucích verzích, použijte '{prog} {new}'", "deprecated_command_alias": "'{prog} {old}' je zastaralý a bude odebrán v budoucích verzích, použijte '{prog} {new}'",
"deprecated_command": "'{prog} {command}' je zastaralý a bude odebrán v budoucích verzích", "deprecated_command": "'{prog} {command}' je zastaralý a bude odebrán v budoucích verzích",
"confirm": "Potvrdit {prompt}", "confirm": "Potvrdit {prompt}",
"colon": "{}: ",
"authentication_required_long": "K provedení této akce je vyžadováno ověření",
"authentication_required": "Vyžadováno ověření", "authentication_required": "Vyžadováno ověření",
"argument_required": "Je vyžadován argument '{argument}'" "argument_required": "Je vyžadován argument '{argument}'"
} }

View file

@ -1,18 +1,13 @@
{ {
"argument_required": "Der Parameter {argument} ist erforderlich", "argument_required": "Der Parameter {argument} ist erforderlich",
"authentication_required": "Anmeldung erforderlich", "authentication_required": "Anmeldung erforderlich",
"authentication_required_long": "Bitte erst anmelden um diese Aktion auszuführen",
"colon": "{}: ",
"confirm": "Bestätige {prompt}", "confirm": "Bestätige {prompt}",
"error": "Fehler:", "error": "Fehler:",
"file_not_exist": "Datei ist nicht vorhanden: '{path}'", "file_not_exist": "Datei ist nicht vorhanden: '{path}'",
"folder_exists": "Ordner existiert bereits: '{path}'", "folder_exists": "Ordner existiert bereits: '{path}'",
"instance_already_running": "Es läuft bereits eine YunoHost-Operation. Bitte warte, bis sie fertig ist, bevor du eine weitere startest.", "instance_already_running": "Es läuft bereits eine YunoHost-Operation. Bitte warte, bis sie fertig ist, bevor du eine weitere startest.",
"invalid_argument": "Argument ungültig '{argument}': {error}", "invalid_argument": "Argument ungültig '{argument}': {error}",
"invalid_password": "Passwort falsch",
"invalid_usage": "Falscher Aufruf, verwende --help für den Hilfstext", "invalid_usage": "Falscher Aufruf, verwende --help für den Hilfstext",
"ldap_attribute_already_exists": "Attribute existieren bereits: '{attribute}={value}'",
"ldap_server_down": "LDAP-Server nicht erreichbar",
"logged_in": "Angemeldet", "logged_in": "Angemeldet",
"logged_out": "Abgemeldet", "logged_out": "Abgemeldet",
"not_logged_in": "Du bist nicht angemeldet", "not_logged_in": "Du bist nicht angemeldet",
@ -23,7 +18,6 @@
"server_already_running": "Einen anderer Dienst arbeitet bereits auf diesem Port", "server_already_running": "Einen anderer Dienst arbeitet bereits auf diesem Port",
"success": "Erfolg!", "success": "Erfolg!",
"unable_authenticate": "Anmelden fehlgeschlagen", "unable_authenticate": "Anmelden fehlgeschlagen",
"unable_retrieve_session": "Sitzung konnte nicht abgerufen werden. Grund: '{exception}'",
"values_mismatch": "Die Werte passen nicht zusammen", "values_mismatch": "Die Werte passen nicht zusammen",
"warning": "Warnung:", "warning": "Warnung:",
"websocket_request_expected": "Eine WebSocket-Anfrage wurde erwartet", "websocket_request_expected": "Eine WebSocket-Anfrage wurde erwartet",
@ -32,7 +26,6 @@
"unknown_group": "Gruppe '{group}' ist unbekannt", "unknown_group": "Gruppe '{group}' ist unbekannt",
"unknown_user": "Benutzer '{user}' ist unbekannt", "unknown_user": "Benutzer '{user}' ist unbekannt",
"info": "Info:", "info": "Info:",
"invalid_token": "Ungültiger Token - bitte authentifizieren",
"corrupted_json": "Beschädigtes JSON gelesen von {ressource} (reason: {error})", "corrupted_json": "Beschädigtes JSON gelesen von {ressource} (reason: {error})",
"unknown_error_reading_file": "Unbekannter Fehler beim Lesen der Datei {file} (reason: {error})", "unknown_error_reading_file": "Unbekannter Fehler beim Lesen der Datei {file} (reason: {error})",
"cannot_write_file": "Kann Datei {file} nicht schreiben (reason: {error})", "cannot_write_file": "Kann Datei {file} nicht schreiben (reason: {error})",
@ -49,7 +42,5 @@
"error_changing_file_permissions": "Fehler beim Ändern der Berechtigungen für {path}: {error}", "error_changing_file_permissions": "Fehler beim Ändern der Berechtigungen für {path}: {error}",
"error_removing": "Fehler beim Entfernen {path}: {error}", "error_removing": "Fehler beim Entfernen {path}: {error}",
"error_writing_file": "Fehler beim Schreiben von Datei {file}: {error}", "error_writing_file": "Fehler beim Schreiben von Datei {file}: {error}",
"corrupted_toml": "Beschädigtes TOML gelesen von {ressource} (reason: {error})", "corrupted_toml": "Beschädigtes TOML gelesen von {ressource} (reason: {error})"
"ldap_server_is_down_restart_it": "Der LDAP-Dienst wurde angehalten. Es wird versucht, ihn erneut zu starten...",
"session_expired": "Die Sitzung ist abgelaufen. Bitte authentifizieren Sie sich neu ."
} }

View file

@ -1,10 +1,10 @@
{ {
"argument_required": "Argument '{argument}' is required", "argument_required": "Argument '{argument}' is required",
"authentication_required": "Authentication required", "authentication_required": "Authentication required",
"colon": "{}: ",
"confirm": "Confirm {prompt}", "confirm": "Confirm {prompt}",
"deprecated_command": "'{prog} {command}' is deprecated and will be removed in the future", "deprecated_command": "'{prog} {command}' is deprecated and will be removed in the future",
"deprecated_command_alias": "'{prog} {old}' is deprecated and will be removed in the future, use '{prog} {new}' instead", "deprecated_command_alias": "'{prog} {old}' is deprecated and will be removed in the future, use '{prog} {new}' instead",
"edit_text_question": "{}. Edit this text ? [yN]: ",
"error": "Error:", "error": "Error:",
"file_not_exist": "File does not exist: '{path}'", "file_not_exist": "File does not exist: '{path}'",
"folder_exists": "Folder already exists: '{path}'", "folder_exists": "Folder already exists: '{path}'",

View file

@ -1,6 +1,5 @@
{ {
"password": "Pasvorto", "password": "Pasvorto",
"colon": "{}: ",
"warn_the_user_that_lock_is_acquired": "La alia komando ĵus kompletigis, nun komencante ĉi tiun komandon", "warn_the_user_that_lock_is_acquired": "La alia komando ĵus kompletigis, nun komencante ĉi tiun komandon",
"warn_the_user_about_waiting_lock_again": "Ankoraŭ atendanta...", "warn_the_user_about_waiting_lock_again": "Ankoraŭ atendanta...",
"warn_the_user_about_waiting_lock": "Alia komando de YunoHost funkcias ĝuste nun, ni atendas, ke ĝi finiĝos antaŭ ol funkcii ĉi tiu", "warn_the_user_about_waiting_lock": "Alia komando de YunoHost funkcias ĝuste nun, ni atendas, ke ĝi finiĝos antaŭ ol funkcii ĉi tiu",
@ -23,7 +22,6 @@
"values_mismatch": "Valoroj ne kongruas", "values_mismatch": "Valoroj ne kongruas",
"unknown_user": "Nekonata uzanto '{user}'", "unknown_user": "Nekonata uzanto '{user}'",
"unknown_group": "Nekonata grupo \"{group}\"", "unknown_group": "Nekonata grupo \"{group}\"",
"unable_retrieve_session": "Ne eblas retrovi la sesion ĉar '{exception}'",
"unable_authenticate": "Ne eblas aŭtentiĝi", "unable_authenticate": "Ne eblas aŭtentiĝi",
"success": "Sukceson!", "success": "Sukceson!",
"server_already_running": "Servilo jam funkcias sur tiu haveno", "server_already_running": "Servilo jam funkcias sur tiu haveno",
@ -32,10 +30,7 @@
"operation_interrupted": "Operacio interrompita", "operation_interrupted": "Operacio interrompita",
"not_logged_in": "Vi ne estas ensalutinta", "not_logged_in": "Vi ne estas ensalutinta",
"logged_in": "Ensalutinta", "logged_in": "Ensalutinta",
"ldap_server_down": "Ne eblas atingi la servilon LDAP",
"ldap_attribute_already_exists": "Atributo '{attribute}' jam ekzistas kun valoro '{value}'",
"invalid_usage": "Nevalida uzado, preterpase '--help' por vidi helpon", "invalid_usage": "Nevalida uzado, preterpase '--help' por vidi helpon",
"invalid_password": "Nevalida pasvorto",
"invalid_argument": "Nevalida argumento '{argument}': {error}", "invalid_argument": "Nevalida argumento '{argument}': {error}",
"instance_already_running": "Jam funkcias YunoHost-operacio. Bonvolu atendi, ke ĝi finiĝos antaŭ ol funkcii alia.", "instance_already_running": "Jam funkcias YunoHost-operacio. Bonvolu atendi, ke ĝi finiĝos antaŭ ol funkcii alia.",
"info": "informoj:", "info": "informoj:",
@ -45,11 +40,7 @@
"deprecated_command_alias": "'{prog} {old}' malakceptas kaj estos forigita estonte, uzu anstataŭe '{prog} {new}'", "deprecated_command_alias": "'{prog} {old}' malakceptas kaj estos forigita estonte, uzu anstataŭe '{prog} {new}'",
"deprecated_command": "'{prog} {command}' malakceptas kaj estos forigita estonte", "deprecated_command": "'{prog} {command}' malakceptas kaj estos forigita estonte",
"confirm": "Konfirmu {prompt}", "confirm": "Konfirmu {prompt}",
"authentication_required_long": "Aŭtentigo necesas por plenumi ĉi tiun agon",
"authentication_required": "Aŭtentigo bezonata", "authentication_required": "Aŭtentigo bezonata",
"argument_required": "Argumento '{argument}' estas bezonata", "argument_required": "Argumento '{argument}' estas bezonata",
"logged_out": "Ensalutinta", "logged_out": "Ensalutinta"
"invalid_token": "Nevalida tokeno - bonvolu autentiki",
"ldap_server_is_down_restart_it": "La LDAP-servo malpliiĝas, provu rekomenci ĝin...",
"session_expired": "La sesio eksvalidiĝis. Bonvolu re-aŭtentikigi."
} }

View file

@ -1,8 +1,6 @@
{ {
"argument_required": "Se requiere el argumento «{argument}»", "argument_required": "Se requiere el argumento «{argument}»",
"authentication_required": "Se requiere autentificación", "authentication_required": "Se requiere autentificación",
"authentication_required_long": "Debe autentificarse para realizar esta acción",
"colon": "{}: ",
"confirm": "Confirmar {prompt}", "confirm": "Confirmar {prompt}",
"deprecated_command": "«{prog} {command}» está obsoleto y será eliminado en el futuro", "deprecated_command": "«{prog} {command}» está obsoleto y será eliminado en el futuro",
"deprecated_command_alias": "«{prog} {old}» está obsoleto y se eliminará en el futuro, use «{prog} {new}» en su lugar", "deprecated_command_alias": "«{prog} {old}» está obsoleto y se eliminará en el futuro, use «{prog} {new}» en su lugar",
@ -11,10 +9,7 @@
"folder_exists": "El directorio ya existe: «{path}»", "folder_exists": "El directorio ya existe: «{path}»",
"instance_already_running": "Ya se está ejecutando una instancia de YunoHost. Espere a que termine antes de ejecutar otra.", "instance_already_running": "Ya se está ejecutando una instancia de YunoHost. Espere a que termine antes de ejecutar otra.",
"invalid_argument": "Argumento no válido «{argument}»: {error}", "invalid_argument": "Argumento no válido «{argument}»: {error}",
"invalid_password": "Contraseña no válida",
"invalid_usage": "Uso no válido, utilice --help para ver la ayuda", "invalid_usage": "Uso no válido, utilice --help para ver la ayuda",
"ldap_attribute_already_exists": "El atributo «{attribute}» ya existe con el valor «{value}»",
"ldap_server_down": "No se pudo conectar con el servidor LDAP",
"logged_in": "Sesión iniciada", "logged_in": "Sesión iniciada",
"logged_out": "Sesión cerrada", "logged_out": "Sesión cerrada",
"not_logged_in": "No ha iniciado sesión", "not_logged_in": "No ha iniciado sesión",
@ -25,7 +20,6 @@
"server_already_running": "Ya se está ejecutando un servidor en ese puerto", "server_already_running": "Ya se está ejecutando un servidor en ese puerto",
"success": "¡Éxito!", "success": "¡Éxito!",
"unable_authenticate": "No se puede autentificar", "unable_authenticate": "No se puede autentificar",
"unable_retrieve_session": "No se puede recuperar la sesión por «{exception}»",
"unknown_group": "Grupo «{group}» desconocido", "unknown_group": "Grupo «{group}» desconocido",
"unknown_user": "Usuario «{user}» desconocido", "unknown_user": "Usuario «{user}» desconocido",
"values_mismatch": "Los valores no coinciden", "values_mismatch": "Los valores no coinciden",
@ -48,8 +42,5 @@
"corrupted_toml": "Lectura corrupta de TOML desde {ressource} (motivo: {error})", "corrupted_toml": "Lectura corrupta de TOML desde {ressource} (motivo: {error})",
"warn_the_user_that_lock_is_acquired": "La otra orden recién terminó, iniciando esta orden ahora", "warn_the_user_that_lock_is_acquired": "La otra orden recién terminó, iniciando esta orden ahora",
"warn_the_user_about_waiting_lock_again": "Aún esperando...", "warn_the_user_about_waiting_lock_again": "Aún esperando...",
"warn_the_user_about_waiting_lock": "Otra orden de YunoHost se está ejecutando ahora, estamos esperando a que termine antes de ejecutar esta", "warn_the_user_about_waiting_lock": "Otra orden de YunoHost se está ejecutando ahora, estamos esperando a que termine antes de ejecutar esta"
"invalid_token": "Token invalido - vuelva a autenticarte",
"ldap_server_is_down_restart_it": "El servicio LDAP está caído, intentando reiniciarlo...",
"session_expired": "La sesión expiró. Por favor autenticarse de nuevo."
} }

View file

@ -1,6 +1,5 @@
{ {
"argument_required": "'{argument}' argumentua beharrezkoa da", "argument_required": "'{argument}' argumentua beharrezkoa da",
"logged_out": "Saioa amaitu", "logged_out": "Saioa amaitu",
"password": "Pasahitza", "password": "Pasahitza"
"colon": "{}: "
} }

View file

@ -6,11 +6,10 @@
"info": "اطلاعات:", "info": "اطلاعات:",
"folder_exists": "پوشه موجود است: '{path}'", "folder_exists": "پوشه موجود است: '{path}'",
"file_not_exist": "فایل وجود ندارد: '{path}'", "file_not_exist": "فایل وجود ندارد: '{path}'",
"error": "خطا:", "error": "ایراد:",
"deprecated_command_alias": "'{prog} {old}' منسوخ شده است و در آینده حذف خواهد شد ، بجای آن از '{prog} {new}' استفاده کنید", "deprecated_command_alias": "'{prog} {old}' منسوخ شده است و در آینده حذف خواهد شد ، بجای آن از '{prog} {new}' استفاده کنید",
"deprecated_command": "'{prog} {command}' منسوخ شده است و در آینده حذف خواهد شد", "deprecated_command": "'{prog} {command}' منسوخ شده است و در آینده حذف خواهد شد",
"confirm": "تأیید {prompt}", "confirm": "تایید کردن {prompt}",
"colon": "{}: ",
"authentication_required": "احراز هویّت الزامی است", "authentication_required": "احراز هویّت الزامی است",
"argument_required": "استدلال '{argument}' ضروری است", "argument_required": "استدلال '{argument}' ضروری است",
"password": "کلمه عبور", "password": "کلمه عبور",
@ -41,7 +40,7 @@
"server_already_running": "در حال حاضر یک سرور روی آن پورت کار می کند", "server_already_running": "در حال حاضر یک سرور روی آن پورت کار می کند",
"root_required": "برای انجام این عمل باید کاربر ریشه باشید", "root_required": "برای انجام این عمل باید کاربر ریشه باشید",
"pattern_not_match": "با الگو مطابقت ندارد", "pattern_not_match": "با الگو مطابقت ندارد",
"operation_interrupted": "عملیات قطع شد", "operation_interrupted": "عملیات قطع شده است",
"not_logged_in": "‌شما وارد نشده اید", "not_logged_in": "‌شما وارد نشده اید",
"logged_out": "خارج شده" "logged_out": "خارج شده"
} }

View file

@ -1,55 +1,47 @@
{ {
"argument_required": "Largument '{argument}' est requis", "argument_required": "L'argument '{argument}' est requis",
"authentication_required": "Authentification requise", "authentication_required": "Authentification requise",
"authentication_required_long": "Lauthentification est requise pour exécuter cette action",
"colon": "{} : ",
"confirm": "Confirmez {prompt}", "confirm": "Confirmez {prompt}",
"deprecated_command": "'{prog} {command}' est déprécié et sera bientôt supprimé", "deprecated_command": "'{prog} {command}' est déprécié et sera bientôt supprimé",
"deprecated_command_alias": "'{prog} {old}' est déprécié et sera bientôt supprimé, utilisez '{prog} {new}' à la place", "deprecated_command_alias": "'{prog} {old}' est déprécié et sera bientôt supprimé, utilisez '{prog} {new}' à la place",
"error": "Erreur :", "error": "Erreur :",
"file_not_exist": "Le fichier '{path}' nexiste pas", "file_not_exist": "Le fichier '{path}' n'existe pas",
"folder_exists": "Le dossier existe déjà : '{path}'", "folder_exists": "Le dossier existe déjà : '{path}'",
"instance_already_running": "Une instance est déjà en cours dexécution, merci d'attendre sa fin avant d'en lancer une autre.", "instance_already_running": "Une instance est déjà en cours d'exécution, merci d'attendre sa fin avant d'en lancer une autre.",
"invalid_argument": "Argument '{argument}' incorrect : {error}", "invalid_argument": "Argument '{argument}' incorrect : {error}",
"invalid_password": "Mot de passe incorrect", "invalid_usage": "Utilisation erronée, utilisez --help pour accéder à l'aide",
"invalid_usage": "Utilisation erronée, utilisez --help pour accéder à laide",
"ldap_attribute_already_exists": "Lattribut '{attribute}' existe déjà avec la valeur suivante : '{value}'",
"ldap_server_down": "Impossible datteindre le serveur LDAP",
"logged_in": "Connecté", "logged_in": "Connecté",
"logged_out": "Déconnecté", "logged_out": "Déconnecté",
"not_logged_in": "Vous nêtes pas connecté", "not_logged_in": "Vous n'êtes pas connecté",
"operation_interrupted": "Opération interrompue", "operation_interrupted": "Opération interrompue",
"password": "Mot de passe", "password": "Mot de passe",
"pattern_not_match": "Ne correspond pas au motif", "pattern_not_match": "Ne correspond pas au motif",
"root_required": "Vous devez être super-utilisateur pour exécuter cette action", "root_required": "Vous devez être super-utilisateur pour exécuter cette action",
"server_already_running": "Un serveur est déjà en cours dexécution sur ce port", "server_already_running": "Un serveur est déjà en cours d'exécution sur ce port",
"success": "Succès !", "success": "Succès !",
"unable_authenticate": "Impossible de vous authentifier", "unable_authenticate": "Impossible de vous authentifier",
"unable_retrieve_session": "Impossible de récupérer la session à cause de '{exception}'", "unknown_group": "Le groupe '{group}' est inconnu",
"unknown_group": "Le groupe « '{group}' » est inconnu", "unknown_user": "L'utilisateur '{user}' est inconnu",
"unknown_user": "L'utilisateur « {user} » est inconnu",
"values_mismatch": "Les valeurs ne correspondent pas", "values_mismatch": "Les valeurs ne correspondent pas",
"warning": "Attention :", "warning": "Attention :",
"websocket_request_expected": "Une requête WebSocket est attendue", "websocket_request_expected": "Une requête WebSocket est attendue",
"cannot_open_file": "Impossible douvrir le fichier {file} (raison : {error})", "cannot_open_file": "Impossible d'ouvrir le fichier {file} (raison : {error})",
"cannot_write_file": "Ne peut pas écrire le fichier {file} (raison : {error})", "cannot_write_file": "Ne peut pas écrire le fichier {file} (raison : {error})",
"unknown_error_reading_file": "Erreur inconnue en essayant de lire le fichier {file} (cause:{error})", "unknown_error_reading_file": "Erreur inconnue en essayant de lire le fichier {file} (raison :{error})",
"corrupted_json": "Fichier JSON corrompu en lecture depuis {ressource} (raison : {error})", "corrupted_json": "Fichier JSON corrompu en lecture depuis {ressource} (raison : {error})",
"error_writing_file": "Erreur en écrivant le fichier {file} : {error}", "error_writing_file": "Erreur en écrivant le fichier {file} : {error}",
"error_removing": "Erreur lors de la suppression {path} : {error}", "error_removing": "Erreur lors de la suppression {path} : {error}",
"error_changing_file_permissions": "Erreur lors de la modification des autorisations pour {path} : {error}", "error_changing_file_permissions": "Erreur lors de la modification des autorisations pour {path} : {error}",
"invalid_url": "Impossible de se connecter à {url} ... peut-être que le service est hors service/indisponible/interrompu, ou que vous n'êtes pas correctement connecté à Internet en IPv4/IPv6.", "invalid_url": "Impossible de se connecter à {url}... peut-être que le service est hors service/indisponible/interrompu, ou que vous n'êtes pas correctement connecté à Internet en IPv4/IPv6.",
"download_ssl_error": "Erreur SSL lors de la connexion à {url}", "download_ssl_error": "Erreur SSL lors de la connexion à {url}",
"download_timeout": "{url} a pris trop de temps pour répondre : abandon.", "download_timeout": "{url} a pris trop de temps pour répondre : abandon.",
"download_unknown_error": "Erreur lors du téléchargement des données à partir de {url} : {error}", "download_unknown_error": "Erreur lors du téléchargement des données à partir de {url} : {error}",
"download_bad_status_code": "{url} renvoie le code d'état {code}", "download_bad_status_code": "{url} renvoie le code d'état {code}",
"corrupted_yaml": "Fichier YAML corrompu en lecture depuis {ressource} (raison : {error})", "corrupted_yaml": "Fichier YAML corrompu en lecture depuis {ressource} (raison : {error})",
"info": "Info :", "info": "Info :",
"corrupted_toml": "Fichier TOML corrompu en lecture depuis {ressource} (cause : {error})", "corrupted_toml": "Fichier TOML corrompu en lecture depuis {ressource} (raison : {error})",
"warn_the_user_about_waiting_lock": "Une autre commande YunoHost est actuellement en cours, nous attendons qu'elle se termine avant de démarrer celle là", "warn_the_user_about_waiting_lock": "Une autre commande YunoHost est actuellement en cours, nous attendons qu'elle se termine avant de démarrer celle là",
"warn_the_user_about_waiting_lock_again": "Toujours en attente...", "warn_the_user_about_waiting_lock_again": "Toujours en attente...",
"warn_the_user_that_lock_is_acquired": "La commande précédente vient de se terminer, lancement de cette nouvelle commande", "warn_the_user_that_lock_is_acquired": "La commande précédente vient de se terminer, lancement de cette nouvelle commande",
"invalid_token": "Jeton non valide - veuillez vous authentifier", "edit_text_question": "{}. Modifier ce texte ? [yN] : "
"ldap_server_is_down_restart_it": "Le service LDAP s'est arrêté, une tentative de redémarrage est en cours...",
"session_expired": "La session a expiré. Merci de vous ré-authentifier."
} }

View file

@ -1,8 +1,5 @@
{ {
"ldap_attribute_already_exists": "O atributo '{attribute}' xa existe e ten o valor '{value}'",
"invalid_usage": "Uso non válido, pass --help para ver a axuda", "invalid_usage": "Uso non válido, pass --help para ver a axuda",
"invalid_token": "Token non válido - por favor autentícate",
"invalid_password": "Contrasinal non válido",
"invalid_argument": "Argumento non válido '{argument}': {error}", "invalid_argument": "Argumento non válido '{argument}': {error}",
"instance_already_running": "Hai unha operación de YunoHost en execución. Por favor agarda a que remate antes de realizar unha nova.", "instance_already_running": "Hai unha operación de YunoHost en execución. Por favor agarda a que remate antes de realizar unha nova.",
"info": "Info:", "info": "Info:",
@ -12,8 +9,6 @@
"deprecated_command_alias": "'{prog} {old}' xa non se utiliza e será eliminado no futuro, usa '{prog} {new}' no seu lugar", "deprecated_command_alias": "'{prog} {old}' xa non se utiliza e será eliminado no futuro, usa '{prog} {new}' no seu lugar",
"deprecated_command": "'{prog} {command}' xa non se utiliza e xa non se usará no futuro", "deprecated_command": "'{prog} {command}' xa non se utiliza e xa non se usará no futuro",
"confirm": "Confirma {prompt}", "confirm": "Confirma {prompt}",
"colon": "{}: ",
"authentication_required_long": "Requírese autenticación para realizar esta acción",
"authentication_required": "Autenticación requerida", "authentication_required": "Autenticación requerida",
"argument_required": "O argumento '{argument}' é requerido", "argument_required": "O argumento '{argument}' é requerido",
"logged_out": "Sesión pechada", "logged_out": "Sesión pechada",
@ -22,8 +17,6 @@
"values_mismatch": "Non concordan os valores", "values_mismatch": "Non concordan os valores",
"unknown_user": "Usuaria '{user}' descoñecida", "unknown_user": "Usuaria '{user}' descoñecida",
"unknown_group": "Grupo '{group}' descoñecido", "unknown_group": "Grupo '{group}' descoñecido",
"session_expired": "A sesión caducou. Volve a conectar por favor.",
"unable_retrieve_session": "Non se puido obter a sesión porque '{exception}'",
"unable_authenticate": "Non se puido autenticar", "unable_authenticate": "Non se puido autenticar",
"success": "Ben feito!", "success": "Ben feito!",
"server_already_running": "Xa hai un servidor a funcionar nese porto", "server_already_running": "Xa hai un servidor a funcionar nese porto",
@ -32,8 +25,6 @@
"operation_interrupted": "Interrumpeuse a operación", "operation_interrupted": "Interrumpeuse a operación",
"not_logged_in": "Non estás conectada", "not_logged_in": "Non estás conectada",
"logged_in": "Conectada", "logged_in": "Conectada",
"ldap_server_down": "Non se puido acadar o servidor LDAP",
"ldap_server_is_down_restart_it": "O servizo LDAP está caído, intentando reinicialo...",
"warn_the_user_that_lock_is_acquired": "O outro comando rematou, agora executarase este", "warn_the_user_that_lock_is_acquired": "O outro comando rematou, agora executarase este",
"warn_the_user_about_waiting_lock_again": "Agardando...", "warn_the_user_about_waiting_lock_again": "Agardando...",
"warn_the_user_about_waiting_lock": "Estase executando outro comando de YunoHost neste intre, estamos agardando a que remate para executar este", "warn_the_user_about_waiting_lock": "Estase executando outro comando de YunoHost neste intre, estamos agardando a que remate para executar este",
@ -51,5 +42,6 @@
"unknown_error_reading_file": "Erro descoñecido ao intentar ler o ficheiro {file} (razón: {error})", "unknown_error_reading_file": "Erro descoñecido ao intentar ler o ficheiro {file} (razón: {error})",
"cannot_write_file": "Non se puido escribir o ficheiro {file} (razón: {error})", "cannot_write_file": "Non se puido escribir o ficheiro {file} (razón: {error})",
"cannot_open_file": "Non se puido abrir o ficheiro {file} (razón: {error})", "cannot_open_file": "Non se puido abrir o ficheiro {file} (razón: {error})",
"websocket_request_expected": "Agardábase unha solicitude WebSocket" "websocket_request_expected": "Agardábase unha solicitude WebSocket",
"edit_text_question": "{}. Editar este texto ? [yN]: "
} }

View file

@ -1,8 +1,6 @@
{ {
"argument_required": "तर्क '{argument}' आवश्यक है", "argument_required": "तर्क '{argument}' आवश्यक है",
"authentication_required": "प्रमाणीकरण आवश्यक", "authentication_required": "प्रमाणीकरण आवश्यक",
"authentication_required_long": "इस कार्य को करने के लिए प्रमाणीकरण आवश्यक है",
"colon": "{}: ",
"confirm": "पुष्टि करें {prompt}", "confirm": "पुष्टि करें {prompt}",
"deprecated_command": "'{prog}' '{command}' का प्रयोग न करे, भविष्य में इसे हटा दिया जाएगा", "deprecated_command": "'{prog}' '{command}' का प्रयोग न करे, भविष्य में इसे हटा दिया जाएगा",
"deprecated_command_alias": "'{prog} {old}' अब पुराना हो गया है और इसे भविष्य में हटा दिया जाएगा, इस की जगह '{prog} {new}' का प्रयोग करें", "deprecated_command_alias": "'{prog} {old}' अब पुराना हो गया है और इसे भविष्य में हटा दिया जाएगा, इस की जगह '{prog} {new}' का प्रयोग करें",
@ -11,10 +9,7 @@
"folder_exists": "फ़ोल्डर में पहले से ही मौजूद है: '{path}'", "folder_exists": "फ़ोल्डर में पहले से ही मौजूद है: '{path}'",
"instance_already_running": "यूनोहोस्ट का एक कार्य पहले से चल रहा है। कृपया इस कार्य के समाप्त होने का इंतज़ार करें।", "instance_already_running": "यूनोहोस्ट का एक कार्य पहले से चल रहा है। कृपया इस कार्य के समाप्त होने का इंतज़ार करें।",
"invalid_argument": "अवैध तर्क '{argument}':'{error}'", "invalid_argument": "अवैध तर्क '{argument}':'{error}'",
"invalid_password": "अवैध पासवर्ड",
"invalid_usage": "अवैध उपयोग, सहायता देखने के लिए --help साथ लिखे।", "invalid_usage": "अवैध उपयोग, सहायता देखने के लिए --help साथ लिखे।",
"ldap_attribute_already_exists": "'{attribute}' तर्क पहले इस वैल्यू '{value}' से मौजूद है।",
"ldap_server_down": "LDAP सर्वर तक पहुंचने में असमर्थ।",
"logged_in": "लोग्ड इन", "logged_in": "लोग्ड इन",
"logged_out": "लॉग आउट", "logged_out": "लॉग आउट",
"not_logged_in": "आप लोग्ड इन नहीं हैं।", "not_logged_in": "आप लोग्ड इन नहीं हैं।",
@ -25,7 +20,6 @@
"server_already_running": "कोई सर्वर पहले से ही इस पोर्ट पर चल रहा है।", "server_already_running": "कोई सर्वर पहले से ही इस पोर्ट पर चल रहा है।",
"success": "सफलता!", "success": "सफलता!",
"unable_authenticate": "प्रमाणित करने में असमर्थ।", "unable_authenticate": "प्रमाणित करने में असमर्थ।",
"unable_retrieve_session": "सेशन को प्राप्त करने में असमर्थ।",
"unknown_group": "अज्ञात ग्रुप: '{group}'", "unknown_group": "अज्ञात ग्रुप: '{group}'",
"unknown_user": "अज्ञात उपयोगकर्ता: '{user}'", "unknown_user": "अज्ञात उपयोगकर्ता: '{user}'",
"values_mismatch": "वैल्यूज मेल नहीं खाती।", "values_mismatch": "वैल्यूज मेल नहीं खाती।",

View file

@ -11,7 +11,6 @@
"success": "Siker!", "success": "Siker!",
"values_mismatch": "Eltérő értékek", "values_mismatch": "Eltérő értékek",
"warning": "Figyelem:", "warning": "Figyelem:",
"invalid_password": "Helytelen jelszó",
"info": "Információ:", "info": "Információ:",
"file_not_exist": "A fájl nem létezik: '{path}'", "file_not_exist": "A fájl nem létezik: '{path}'",
"error": "Hiba:" "error": "Hiba:"

19
locales/id.json Normal file
View file

@ -0,0 +1,19 @@
{
"argument_required": "Argumen '{argument}' dibutuhkan",
"authentication_required": "Otentikasi dibutuhkan",
"deprecated_command": "'{prog} {command}' sudah usang dan akan dihapus nanti",
"logged_out": "Berhasil keluar",
"password": "Kata sandi",
"deprecated_command_alias": "'{prog} {old}' sudah usang dan akan dihapus nanti, gunakan '{prog} {new}' saja",
"info": "Informasi:",
"instance_already_running": "Sudah ada operasi YunoHost yang sedang berjalan. Tunggu itu selesai sebelum menjalankan yang lain.",
"logged_in": "Berhasil masuk",
"warning": "Peringatan:",
"cannot_open_file": "Tidak dapat membuka berkas {file} (alasan: {error})",
"error_removing": "Terjadi kesalahan ketika menghapus {path}: {error}",
"success": "Berhasil!",
"warn_the_user_about_waiting_lock": "Perintah YunoHost lain sedang berjalan saat ini, kami sedang menunggu itu selesai sebelum menjalankan yang ini",
"warn_the_user_about_waiting_lock_again": "Masih menunggu...",
"unable_authenticate": "Tidak dapat mengotentikasi",
"warn_the_user_that_lock_is_acquired": "Perintah yang tadi baru saja selesai, akan memulai perintah ini"
}

View file

@ -3,8 +3,6 @@
"password": "Password", "password": "Password",
"argument_required": "L'argomento '{argument}' è richiesto", "argument_required": "L'argomento '{argument}' è richiesto",
"authentication_required": "Autenticazione richiesta", "authentication_required": "Autenticazione richiesta",
"authentication_required_long": "Autenticazione richiesta per eseguire questa azione",
"colon": "{}: ",
"confirm": "Confermare {prompt}", "confirm": "Confermare {prompt}",
"deprecated_command": "'{prog} {command}' è deprecato e sarà rimosso in futuro", "deprecated_command": "'{prog} {command}' è deprecato e sarà rimosso in futuro",
"deprecated_command_alias": "'{prog} {old}' è deprecato e sarà rimosso in futuro, usa invece '{prog} {new}'", "deprecated_command_alias": "'{prog} {old}' è deprecato e sarà rimosso in futuro, usa invece '{prog} {new}'",
@ -13,10 +11,7 @@
"folder_exists": "La cartella esiste già: '{path}'", "folder_exists": "La cartella esiste già: '{path}'",
"instance_already_running": "Esiste già un'operazione YunoHost in esecuzione. Attendi il completamento prima di eseguirne un altro.", "instance_already_running": "Esiste già un'operazione YunoHost in esecuzione. Attendi il completamento prima di eseguirne un altro.",
"invalid_argument": "Argomento non valido '{argument}': {error}", "invalid_argument": "Argomento non valido '{argument}': {error}",
"invalid_password": "Password non valida",
"invalid_usage": "Utilizzo non valido, usa --help per vedere l'aiuto", "invalid_usage": "Utilizzo non valido, usa --help per vedere l'aiuto",
"ldap_attribute_already_exists": "L'attributo '{attribute}' esiste già con valore '{value}'",
"ldap_server_down": "Impossibile raggiungere il server LDAP",
"logged_in": "Connesso", "logged_in": "Connesso",
"not_logged_in": "Non hai effettuato l'accesso", "not_logged_in": "Non hai effettuato l'accesso",
"operation_interrupted": "Operazione interrotta", "operation_interrupted": "Operazione interrotta",
@ -25,7 +20,6 @@
"server_already_running": "Un server è già in esecuzione su quella porta", "server_already_running": "Un server è già in esecuzione su quella porta",
"success": "Riuscito!", "success": "Riuscito!",
"unable_authenticate": "Autenticazione fallita", "unable_authenticate": "Autenticazione fallita",
"unable_retrieve_session": "Impossibile recuperare la sessione perché \"{exception}\"",
"unknown_group": "Gruppo '{group}' sconosciuto", "unknown_group": "Gruppo '{group}' sconosciuto",
"unknown_user": "Utente '{user}' sconosciuto", "unknown_user": "Utente '{user}' sconosciuto",
"values_mismatch": "I valori non corrispondono", "values_mismatch": "I valori non corrispondono",
@ -48,8 +42,5 @@
"warn_the_user_that_lock_is_acquired": "L'altro comando è appena completato, ora avvio questo comando", "warn_the_user_that_lock_is_acquired": "L'altro comando è appena completato, ora avvio questo comando",
"warn_the_user_about_waiting_lock_again": "Sto ancora aspettando ...", "warn_the_user_about_waiting_lock_again": "Sto ancora aspettando ...",
"warn_the_user_about_waiting_lock": "Un altro comando YunoHost è in esecuzione in questo momento, stiamo aspettando che finisca prima di eseguire questo", "warn_the_user_about_waiting_lock": "Un altro comando YunoHost è in esecuzione in questo momento, stiamo aspettando che finisca prima di eseguire questo",
"corrupted_toml": "TOML corrotto da {ressource} (motivo: {error})", "corrupted_toml": "TOML corrotto da {ressource} (motivo: {error})"
"invalid_token": "Token non valido: autenticare",
"session_expired": "La sessione è terminata. Sei pregato di autenticarti nuovamente.",
"ldap_server_is_down_restart_it": "Il servizio LDAP è terminato, provo a riavviarlo..."
} }

1
locales/mk.json Normal file
View file

@ -0,0 +1 @@
{}

View file

@ -11,11 +11,9 @@
"operation_interrupted": "Operasjon forstyrret", "operation_interrupted": "Operasjon forstyrret",
"not_logged_in": "Du er ikke innlogget", "not_logged_in": "Du er ikke innlogget",
"logged_in": "Innlogget", "logged_in": "Innlogget",
"invalid_password": "Ugyldig passord",
"info": "Info:", "info": "Info:",
"error": "Feil:", "error": "Feil:",
"confirm": "Bekreft {prompt}", "confirm": "Bekreft {prompt}",
"colon": "{}: ",
"logged_out": "Utlogget", "logged_out": "Utlogget",
"password": "Passord" "password": "Passord"
} }

View file

@ -4,8 +4,6 @@
"deprecated_command_alias": "'{prog} {old}' अस्वीकृत गरिएको छ र भविष्यमा हटाइनेछ, यसको सट्टा '{prog} {new}' प्रयोग गर्नुहोस्।", "deprecated_command_alias": "'{prog} {old}' अस्वीकृत गरिएको छ र भविष्यमा हटाइनेछ, यसको सट्टा '{prog} {new}' प्रयोग गर्नुहोस्।",
"deprecated_command": "'{prog} {command}' अस्वीकृत गरिएको छ र भविष्यमा हटाइनेछ", "deprecated_command": "'{prog} {command}' अस्वीकृत गरिएको छ र भविष्यमा हटाइनेछ",
"confirm": "कन्फर्म {prompt}", "confirm": "कन्फर्म {prompt}",
"colon": "{}: ",
"authentication_required_long": "यस कार्य गर्नको लागि प्रमाणीकरण आवाश्यक हुन्छ",
"authentication_required": "प्रमाणीकरण आवाश्यक छ", "authentication_required": "प्रमाणीकरण आवाश्यक छ",
"argument_required": "तर्क '{argument}' आवश्यक छ" "argument_required": "तर्क '{argument}' आवश्यक छ"
} }

View file

@ -1,18 +1,13 @@
{ {
"argument_required": "Argument {argument} is vereist", "argument_required": "Argument {argument} is vereist",
"authentication_required": "Aanmelding vereist", "authentication_required": "Aanmelding vereist",
"authentication_required_long": "Aanmelding is vereist om deze actie uit te voeren",
"colon": "{}: ",
"confirm": "Bevestig {prompt}", "confirm": "Bevestig {prompt}",
"error": "Fout:", "error": "Fout:",
"file_not_exist": "Bestand bestaat niet: '{path}'", "file_not_exist": "Bestand bestaat niet: '{path}'",
"folder_exists": "Deze map bestaat al: '{path}'", "folder_exists": "Deze map bestaat al: '{path}'",
"instance_already_running": "Er is al een instantie actief, bedankt om te wachten tot deze afgesloten is alvorens een andere te starten.", "instance_already_running": "Er is al een instantie actief, bedankt om te wachten tot deze afgesloten is alvorens een andere te starten.",
"invalid_argument": "Ongeldig argument '{argument}': {error}", "invalid_argument": "Ongeldig argument '{argument}': {error}",
"invalid_password": "Ongeldig wachtwoord",
"invalid_usage": "Ongeldig gebruik, doe --help om de hulptekst te lezen", "invalid_usage": "Ongeldig gebruik, doe --help om de hulptekst te lezen",
"ldap_attribute_already_exists": "Attribuut '{attribute}' bestaat al met waarde '{value}'",
"ldap_server_down": "Kan LDAP server niet bereiken",
"logged_in": "Ingelogd", "logged_in": "Ingelogd",
"logged_out": "Uitgelogd", "logged_out": "Uitgelogd",
"not_logged_in": "U bent niet ingelogd", "not_logged_in": "U bent niet ingelogd",
@ -23,7 +18,6 @@
"server_already_running": "Er is al een server actief op die poort", "server_already_running": "Er is al een server actief op die poort",
"success": "Succes!", "success": "Succes!",
"unable_authenticate": "Aanmelding niet mogelijk", "unable_authenticate": "Aanmelding niet mogelijk",
"unable_retrieve_session": "Het is onmogelijk op de sessie op te halen omwille van '{exception}'",
"values_mismatch": "Waarden zijn niet gelijk", "values_mismatch": "Waarden zijn niet gelijk",
"warning": "Waarschuwing:", "warning": "Waarschuwing:",
"websocket_request_expected": "Verwachtte een WebSocket request", "websocket_request_expected": "Verwachtte een WebSocket request",
@ -48,6 +42,5 @@
"warn_the_user_about_waiting_lock": "Een ander YunoHost commando wordt uitgevoerd, we wachten tot het gedaan is alovrens dit te starten", "warn_the_user_about_waiting_lock": "Een ander YunoHost commando wordt uitgevoerd, we wachten tot het gedaan is alovrens dit te starten",
"corrupted_toml": "Ongeldige TOML werd gelezen op {ressource} (reason: {error})", "corrupted_toml": "Ongeldige TOML werd gelezen op {ressource} (reason: {error})",
"corrupted_yaml": "Ongeldig YAML bestand op {ressource} (reason: {error})", "corrupted_yaml": "Ongeldig YAML bestand op {ressource} (reason: {error})",
"invalid_token": "Ongeldig token - gelieve in te loggen",
"info": "Ter info:" "info": "Ter info:"
} }

View file

@ -1,11 +1,9 @@
{ {
"argument_required": "Largument {argument} es requesit", "argument_required": "Largument {argument} es requesit",
"authentication_required": "Autentificacion requesida", "authentication_required": "Autentificacion requesida",
"authentication_required_long": "Una autentificacion es requesida per acomplir aquesta accion",
"logged_in": "Connectat", "logged_in": "Connectat",
"logged_out": "Desconnectat", "logged_out": "Desconnectat",
"password": "Senhal", "password": "Senhal",
"colon": "{}: ",
"confirm": "Confirmatz: {prompt}", "confirm": "Confirmatz: {prompt}",
"deprecated_command": "« {prog} {command} » es despreciat e serà lèu suprimit", "deprecated_command": "« {prog} {command} » es despreciat e serà lèu suprimit",
"deprecated_command_alias": "« {prog} {old} » es despreciat e serà lèu suprimit, utilizatz « {prog} {new} » allòc", "deprecated_command_alias": "« {prog} {old} » es despreciat e serà lèu suprimit, utilizatz « {prog} {new} » allòc",
@ -14,18 +12,14 @@
"folder_exists": "Lo repertòri existís ja: « {path} »", "folder_exists": "Lo repertòri existís ja: « {path} »",
"instance_already_running": "I a ja una operacion de YunoHost en cors. Mercés desperar que sacabe abans de ne lançar una mai.", "instance_already_running": "I a ja una operacion de YunoHost en cors. Mercés desperar que sacabe abans de ne lançar una mai.",
"invalid_argument": "Argument « {argument} » incorrècte: {error}", "invalid_argument": "Argument « {argument} » incorrècte: {error}",
"invalid_password": "Senhal incorrècte",
"ldap_server_down": "Impossible daténher lo servidor LDAP",
"not_logged_in": "Cap de session començada", "not_logged_in": "Cap de session començada",
"pattern_not_match": "Correspond pas al patron", "pattern_not_match": "Correspond pas al patron",
"root_required": "Cal èsser root per realizar aquesta accion", "root_required": "Cal èsser root per realizar aquesta accion",
"unable_retrieve_session": "Recuperacion impossibla de la session a causa de « {exception} »",
"unknown_group": "Grop « {group} » desconegut", "unknown_group": "Grop « {group} » desconegut",
"unknown_user": "Utilizaire « {user} » desconegut", "unknown_user": "Utilizaire « {user} » desconegut",
"values_mismatch": "Las valors correspondon pas", "values_mismatch": "Las valors correspondon pas",
"warning": "Atencion:", "warning": "Atencion:",
"invalid_usage": "Usatge invalid, utilizatz --help per accedir a lajuda", "invalid_usage": "Usatge invalid, utilizatz --help per accedir a lajuda",
"ldap_attribute_already_exists": "Latribut « {attribute} » existís ja amb la valor: {value}",
"operation_interrupted": "Operacion interrompuda", "operation_interrupted": "Operacion interrompuda",
"server_already_running": "Un servidor es ja en execucion sus aqueste pòrt", "server_already_running": "Un servidor es ja en execucion sus aqueste pòrt",
"success": "Capitada!", "success": "Capitada!",
@ -48,8 +42,5 @@
"corrupted_toml": "Fichièr TOML corromput en lectura de {ressource} estant (rason: {error})", "corrupted_toml": "Fichièr TOML corromput en lectura de {ressource} estant (rason: {error})",
"warn_the_user_about_waiting_lock": "Una autra comanda YunoHost es en execucion, sèm a esperar quacabe abans daviar aquesta daquí", "warn_the_user_about_waiting_lock": "Una autra comanda YunoHost es en execucion, sèm a esperar quacabe abans daviar aquesta daquí",
"warn_the_user_about_waiting_lock_again": "Encara en espèra…", "warn_the_user_about_waiting_lock_again": "Encara en espèra…",
"warn_the_user_that_lock_is_acquired": "lautra comanda ven dacabar, ara lançament daquesta comanda", "warn_the_user_that_lock_is_acquired": "lautra comanda ven dacabar, ara lançament daquesta comanda"
"invalid_token": "Geton invalid - volgatz vos autentificar",
"ldap_server_is_down_restart_it": "Lo servici LDAP ses atudat, ensajam de lo reaviar…",
"session_expired": "La session a expirat. Tornatz vos autentificar."
} }

View file

@ -23,7 +23,6 @@
"values_mismatch": "Wartości nie pasują", "values_mismatch": "Wartości nie pasują",
"unknown_user": "Nieznany użytkownik '{user}'", "unknown_user": "Nieznany użytkownik '{user}'",
"unknown_group": "Nieznana grupa '{group}'", "unknown_group": "Nieznana grupa '{group}'",
"unable_retrieve_session": "Nie można pobrać sesji, ponieważ „{exception}”",
"unable_authenticate": "Nie można uwierzytelnić", "unable_authenticate": "Nie można uwierzytelnić",
"success": "Sukces!", "success": "Sukces!",
"server_already_running": "Serwer już działa na tym porcie", "server_already_running": "Serwer już działa na tym porcie",
@ -32,11 +31,7 @@
"operation_interrupted": "Operacja przerwana", "operation_interrupted": "Operacja przerwana",
"not_logged_in": "Nie jesteś zalogowany", "not_logged_in": "Nie jesteś zalogowany",
"logged_in": "Zalogowany", "logged_in": "Zalogowany",
"ldap_server_down": "Nie można połączyć się z serwerem LDAP",
"ldap_attribute_already_exists": "Atrybut „{attribute}” już istnieje z wartością „{value}”",
"invalid_usage": "Nieprawidłowe użycie. Przejdź --help, aby wyświetlić pomoc", "invalid_usage": "Nieprawidłowe użycie. Przejdź --help, aby wyświetlić pomoc",
"invalid_token": "Nieprawidłowy token - proszę uwierzytelnić",
"invalid_password": "Nieprawidłowe hasło",
"invalid_argument": "Nieprawidłowy argument „{argument}”: {error}", "invalid_argument": "Nieprawidłowy argument „{argument}”: {error}",
"instance_already_running": "Trwa już operacja YunoHost. Zaczekaj na zakończenie, zanim uruchomisz kolejny.", "instance_already_running": "Trwa już operacja YunoHost. Zaczekaj na zakończenie, zanim uruchomisz kolejny.",
"info": "Informacje:", "info": "Informacje:",
@ -46,10 +41,6 @@
"deprecated_command_alias": "„{prog} {old}” jest przestarzałe i zostanie usunięte w przyszłości, zamiast tego użyj „{prog} {new}”", "deprecated_command_alias": "„{prog} {old}” jest przestarzałe i zostanie usunięte w przyszłości, zamiast tego użyj „{prog} {new}”",
"deprecated_command": "„{prog} {command}” jest przestarzałe i zostanie usunięte w przyszłości", "deprecated_command": "„{prog} {command}” jest przestarzałe i zostanie usunięte w przyszłości",
"confirm": "Potwierdź {prompt}", "confirm": "Potwierdź {prompt}",
"colon": "{}: ",
"authentication_required_long": "Do wykonania tej czynności wymagane jest uwierzytelnienie",
"authentication_required": "Wymagane uwierzytelnienie", "authentication_required": "Wymagane uwierzytelnienie",
"argument_required": "Argument „{argument}” jest wymagany", "argument_required": "Argument „{argument}” jest wymagany"
"ldap_server_is_down_restart_it": "Usługa LDAP nie działa, próba restartu...",
"session_expired": "Sesja wygasła. Zaloguj się ponownie."
} }

View file

@ -1,18 +1,13 @@
{ {
"argument_required": "O argumento '{argument}' é obrigatório", "argument_required": "O argumento '{argument}' é obrigatório",
"authentication_required": "Autenticação obrigatória", "authentication_required": "Autenticação obrigatória",
"authentication_required_long": "É preciso autenticar-se para realizar esta ação",
"colon": "{}: ",
"confirm": "Confirmar {prompt}", "confirm": "Confirmar {prompt}",
"error": "Erro:", "error": "Erro:",
"file_not_exist": "O ficheiro não existe: '{path}'", "file_not_exist": "O ficheiro não existe: '{path}'",
"folder_exists": "A pasta já existe: '{path}'", "folder_exists": "A pasta já existe: '{path}'",
"instance_already_running": "Já existe uma operação YunoHost em execução. Aguarde o término antes de executar outro.", "instance_already_running": "Já existe uma operação YunoHost em execução. Aguarde o término antes de executar outro.",
"invalid_argument": "Argumento inválido '{argument}': {error}", "invalid_argument": "Argumento inválido '{argument}': {error}",
"invalid_password": "Senha incorreta",
"invalid_usage": "Uso invalido, utilizar --help para ver a ajuda", "invalid_usage": "Uso invalido, utilizar --help para ver a ajuda",
"ldap_attribute_already_exists": "O atributo '{attribute}' já existe com valor '{value}'",
"ldap_server_down": "Não foi possível comunicar com o servidor LDAP",
"logged_in": "Sessão iniciada", "logged_in": "Sessão iniciada",
"logged_out": "Sessão terminada", "logged_out": "Sessão terminada",
"not_logged_in": "Não tem sessão iniciada", "not_logged_in": "Não tem sessão iniciada",
@ -23,7 +18,6 @@
"server_already_running": "Existe um servidor ativo nessa porta", "server_already_running": "Existe um servidor ativo nessa porta",
"success": "Sucesso!", "success": "Sucesso!",
"unable_authenticate": "Não foi possível autenticar", "unable_authenticate": "Não foi possível autenticar",
"unable_retrieve_session": "Não foi possível recuperar a sessão porque '{exception}'",
"values_mismatch": "Os valores não coincidem", "values_mismatch": "Os valores não coincidem",
"warning": "Aviso:", "warning": "Aviso:",
"websocket_request_expected": "Esperado um pedido a WebSocket", "websocket_request_expected": "Esperado um pedido a WebSocket",
@ -48,8 +42,5 @@
"warn_the_user_about_waiting_lock_again": "Ainda esperando...", "warn_the_user_about_waiting_lock_again": "Ainda esperando...",
"warn_the_user_about_waiting_lock": "Outro comando YunoHost está sendo executado agora, estamos aguardando o término antes de executar este", "warn_the_user_about_waiting_lock": "Outro comando YunoHost está sendo executado agora, estamos aguardando o término antes de executar este",
"corrupted_toml": "TOML corrompido lido em {ressource} (motivo: {error})", "corrupted_toml": "TOML corrompido lido em {ressource} (motivo: {error})",
"invalid_token": "Token inválido - autentique", "info": "Informações:"
"info": "Informações:",
"ldap_server_is_down_restart_it": "O serviço LDAP esta caído, tentando reiniciá-lo...",
"session_expired": "A sessão expirou. Se autentique de novo por favor."
} }

View file

@ -1,8 +1,6 @@
{ {
"argument_required": "Требуется'{argument}' аргумент", "argument_required": "Требуется'{argument}' аргумент",
"authentication_required": "Требуется аутентификация", "authentication_required": "Требуется аутентификация",
"authentication_required_long": "Для этого действия требуется аутентификация",
"colon": "{}: ",
"confirm": "Подтвердить {prompt}", "confirm": "Подтвердить {prompt}",
"deprecated_command": "'{prog} {command}' устарела и будет удалена", "deprecated_command": "'{prog} {command}' устарела и будет удалена",
"deprecated_command_alias": "'{prog} {old}' устарела и будет удалена, вместо неё используйте '{prog} {new}'", "deprecated_command_alias": "'{prog} {old}' устарела и будет удалена, вместо неё используйте '{prog} {new}'",
@ -10,8 +8,6 @@
"file_not_exist": "Файл не существует: '{path}'", "file_not_exist": "Файл не существует: '{path}'",
"folder_exists": "Каталог уже существует: '{path}'", "folder_exists": "Каталог уже существует: '{path}'",
"invalid_argument": "Неправильный аргумент '{argument}': {error}", "invalid_argument": "Неправильный аргумент '{argument}': {error}",
"invalid_password": "Неправильный пароль",
"ldap_attribute_already_exists": "Атрибут '{attribute}' уже существует со значением '{value}'",
"logged_in": "Вы вошли", "logged_in": "Вы вошли",
"logged_out": "Вы вышли из системы", "logged_out": "Вы вышли из системы",
"not_logged_in": "Вы не залогинились", "not_logged_in": "Вы не залогинились",
@ -29,7 +25,7 @@
"cannot_open_file": "Не могу открыть файл {file} (причина: {error})", "cannot_open_file": "Не могу открыть файл {file} (причина: {error})",
"cannot_write_file": "Не могу записать файл {file} (причина: {error})", "cannot_write_file": "Не могу записать файл {file} (причина: {error})",
"unknown_error_reading_file": "Неизвестная ошибка при попытке прочитать файл {file} (причина: {error})", "unknown_error_reading_file": "Неизвестная ошибка при попытке прочитать файл {file} (причина: {error})",
"corrupted_yaml": "Повреждённой yaml получен от {ressource} (причина: {error})", "corrupted_yaml": "Повреждённой YAML получен от {ressource} (причина: {error})",
"error_writing_file": "Ошибка при записи файла {file}: {error}", "error_writing_file": "Ошибка при записи файла {file}: {error}",
"error_removing": "Ошибка при удалении {path}: {error}", "error_removing": "Ошибка при удалении {path}: {error}",
"invalid_url": "Неправильный url {url} (этот сайт существует ?)", "invalid_url": "Неправильный url {url} (этот сайт существует ?)",
@ -38,16 +34,13 @@
"download_unknown_error": "Ошибка при загрузке данных с {url} : {error}", "download_unknown_error": "Ошибка при загрузке данных с {url} : {error}",
"instance_already_running": "Операция YunoHost уже запущена. Пожалуйста, подождите, пока он закончится, прежде чем запускать другой.", "instance_already_running": "Операция YunoHost уже запущена. Пожалуйста, подождите, пока он закончится, прежде чем запускать другой.",
"root_required": "Чтобы выполнить это действие, вы должны иметь права root", "root_required": "Чтобы выполнить это действие, вы должны иметь права root",
"corrupted_json": "Повреждённый json получен от {ressource} (причина: {error})", "corrupted_json": "Повреждённый json получен от {ressource} (причина: {error})",
"warn_the_user_that_lock_is_acquired": "другая команда только что завершилась, теперь запускает эту команду", "warn_the_user_that_lock_is_acquired": "другая команда только что завершилась, теперь запускает эту команду",
"warn_the_user_about_waiting_lock_again": "Все еще жду...", "warn_the_user_about_waiting_lock_again": "Все еще жду...",
"warn_the_user_about_waiting_lock": "Сейчас запускается еще одна команда YunoHost, мы ждем ее завершения, прежде чем запустить эту", "warn_the_user_about_waiting_lock": "Сейчас запускается еще одна команда YunoHost, мы ждем ее завершения, прежде чем запустить эту",
"download_bad_status_code": "{url} вернул код состояния {code}", "download_bad_status_code": "{url} вернул код состояния {code}",
"error_changing_file_permissions": "Ошибка при изменении разрешений для {path}: {error}", "error_changing_file_permissions": "Ошибка при изменении разрешений для {path}: {error}",
"corrupted_toml": "Поврежденный том, прочитанный из {ressource} (причина: {error})", "corrupted_toml": "Поврежденный TOML, прочитанный из {ressource} (причина: {error})",
"unable_retrieve_session": "Невозможно получить сеанс, так как '{exception}'",
"ldap_server_down": "Невозможно связаться с сервером LDAP",
"invalid_usage": "Неправильное использование, передайте --help, чтобы увидеть помощь", "invalid_usage": "Неправильное использование, передайте --help, чтобы увидеть помощь",
"invalid_token": "Неверный токен - пожалуйста, авторизуйтесь",
"info": "Информация:" "info": "Информация:"
} }

View file

@ -17,8 +17,6 @@
"operation_interrupted": "Behandling avbruten", "operation_interrupted": "Behandling avbruten",
"not_logged_in": "Du är inte inloggad", "not_logged_in": "Du är inte inloggad",
"logged_in": "Inloggad", "logged_in": "Inloggad",
"ldap_attribute_already_exists": "Attributet '{attribute}' finns redan med värdet '{value}'",
"invalid_password": "Ogiltigt lösenord",
"invalid_argument": "Ogiltig parameter '{argument}': {error}", "invalid_argument": "Ogiltig parameter '{argument}': {error}",
"logged_out": "Utloggad", "logged_out": "Utloggad",
"info": "Info:", "info": "Info:",
@ -28,7 +26,6 @@
"deprecated_command_alias": "'{prog} {old}' rekommenderas inte längre och kommer tas bort i framtiden, använd '{prog} {new}' istället", "deprecated_command_alias": "'{prog} {old}' rekommenderas inte längre och kommer tas bort i framtiden, använd '{prog} {new}' istället",
"deprecated_command": "'{prog} {command}' rekommenderas inte längre och kommer tas bort i framtiden", "deprecated_command": "'{prog} {command}' rekommenderas inte längre och kommer tas bort i framtiden",
"confirm": "Bekräfta {prompt}", "confirm": "Bekräfta {prompt}",
"colon": "{}: ",
"argument_required": "Parametern '{argument}' krävs", "argument_required": "Parametern '{argument}' krävs",
"password": "Lösenord", "password": "Lösenord",
"warn_the_user_that_lock_is_acquired": "det andra kommandot har bara slutförts, nu startar du det här kommandot", "warn_the_user_that_lock_is_acquired": "det andra kommandot har bara slutförts, nu startar du det här kommandot",
@ -42,12 +39,8 @@
"corrupted_yaml": "Skadad yaml läst från {ressource} (anledning: {error})", "corrupted_yaml": "Skadad yaml läst från {ressource} (anledning: {error})",
"corrupted_json": "Skadad json läst från {ressource} (anledning: {error})", "corrupted_json": "Skadad json läst från {ressource} (anledning: {error})",
"unknown_error_reading_file": "Okänt fel vid försök att läsa filen {file} (anledning: {error})", "unknown_error_reading_file": "Okänt fel vid försök att läsa filen {file} (anledning: {error})",
"unable_retrieve_session": "Det gick inte att hämta sessionen eftersom '{exception}'",
"unable_authenticate": "Det går inte att verifiera", "unable_authenticate": "Det går inte att verifiera",
"ldap_server_down": "Det går inte att nå LDAP-servern",
"invalid_usage": "Ogiltig användning, pass --help för att se hjälp", "invalid_usage": "Ogiltig användning, pass --help för att se hjälp",
"invalid_token": "Ogiltigt token - verifiera",
"instance_already_running": "Det finns redan en YunoHost-operation. Vänta tills den är klar innan du kör en annan.", "instance_already_running": "Det finns redan en YunoHost-operation. Vänta tills den är klar innan du kör en annan.",
"authentication_required_long": "Autentisering krävs för att utföra denna åtgärd",
"authentication_required": "Autentisering krävs" "authentication_required": "Autentisering krävs"
} }

View file

@ -1,15 +1,10 @@
{ {
"argument_required": "{argument} argümanı gerekli", "argument_required": "{argument} argümanı gerekli",
"authentication_required": "Yetklendirme gerekli", "authentication_required": "Yetklendirme gerekli",
"authentication_required_long": "Bu işlemi yapmak içi yetkilendirme gerekli",
"colon": "{}: ",
"confirm": "{prompt}'i doğrulayın", "confirm": "{prompt}'i doğrulayın",
"error": "Hata:", "error": "Hata:",
"instance_already_running": "Halihazırda bir YunoHost operasyonu var. Lütfen başka bir tane çalıştırmadan önce bitmesini bekleyin.", "instance_already_running": "Halihazırda bir YunoHost operasyonu var. Lütfen başka bir tane çalıştırmadan önce bitmesini bekleyin.",
"invalid_argument": "Geçersiz argüman '{argument}': {error}", "invalid_argument": "Geçersiz argüman '{argument}': {error}",
"invalid_password": "Geçersiz parola",
"ldap_attribute_already_exists": "'{attribute}={value}' özelliği zaten mevcut",
"ldap_server_down": "LDAP sunucusuna erişilemiyor",
"logged_in": "Giriş yapıldı", "logged_in": "Giriş yapıldı",
"logged_out": ıkış yapıldı", "logged_out": ıkış yapıldı",
"not_logged_in": "Giriş yapmadınız", "not_logged_in": "Giriş yapmadınız",
@ -20,11 +15,10 @@
"server_already_running": "Bu portta zaten çalışan bir sunucu var", "server_already_running": "Bu portta zaten çalışan bir sunucu var",
"success": "İşlem Başarılı!", "success": "İşlem Başarılı!",
"unable_authenticate": "Yetkilendirme başarısız", "unable_authenticate": "Yetkilendirme başarısız",
"unable_retrieve_session": "'{exception}' nedeniyle oturum alınamadı",
"values_mismatch": "Değerler uyuşmuyor", "values_mismatch": "Değerler uyuşmuyor",
"warning": "Uyarı:", "warning": "Uyarı:",
"websocket_request_expected": "WebSocket isteği gerekli", "websocket_request_expected": "WebSocket isteği gerekli",
"warn_the_user_that_lock_is_acquired": "diğer komut şimdi tamamlandı, şimdi bu komutu başlatıyor", "warn_the_user_that_lock_is_acquired": "Diğer komut şimdi tamamlandı, şimdi bu komutu başlatıyor",
"warn_the_user_about_waiting_lock_again": "Hala bekliyor...", "warn_the_user_about_waiting_lock_again": "Hala bekliyor...",
"warn_the_user_about_waiting_lock": "Başka bir YunoHost komutu şu anda çalışıyor, bunu çalıştırmadan önce bitmesini bekliyoruz", "warn_the_user_about_waiting_lock": "Başka bir YunoHost komutu şu anda çalışıyor, bunu çalıştırmadan önce bitmesini bekliyoruz",
"download_bad_status_code": "{url} döndürülen durum kodu {code}", "download_bad_status_code": "{url} döndürülen durum kodu {code}",
@ -35,7 +29,7 @@
"error_changing_file_permissions": "{path} için izinler değiştirilirken hata oluştu: {error}", "error_changing_file_permissions": "{path} için izinler değiştirilirken hata oluştu: {error}",
"error_removing": "{path} kaldırılırken hata oluştu: {error}", "error_removing": "{path} kaldırılırken hata oluştu: {error}",
"error_writing_file": "{file} dosyası yazılırken hata oluştu: {error}", "error_writing_file": "{file} dosyası yazılırken hata oluştu: {error}",
"corrupted_toml": "{ressource} kaynağından okunan bozuk toml (nedeni: {error})", "corrupted_toml": "{ressource} kaynağından okunan bozuk TOML(nedeni: {error})",
"corrupted_yaml": "{ressource} kaynağından bozuk yaml okunuyor (nedeni: {error})", "corrupted_yaml": "{ressource} kaynağından bozuk yaml okunuyor (nedeni: {error})",
"corrupted_json": "{ressource} adresinden okunan bozuk json (nedeni: {error})", "corrupted_json": "{ressource} adresinden okunan bozuk json (nedeni: {error})",
"unknown_error_reading_file": "{file} dosyasını okumaya çalışırken bilinmeyen hata (nedeni: {error})", "unknown_error_reading_file": "{file} dosyasını okumaya çalışırken bilinmeyen hata (nedeni: {error})",
@ -44,7 +38,6 @@
"unknown_user": "Bilinmeyen '{user}' kullanıcı", "unknown_user": "Bilinmeyen '{user}' kullanıcı",
"unknown_group": "Bilinmeyen '{group}' grubu", "unknown_group": "Bilinmeyen '{group}' grubu",
"invalid_usage": "Geçersiz kullanım, yardım görmek için --help iletin", "invalid_usage": "Geçersiz kullanım, yardım görmek için --help iletin",
"invalid_token": "Geçersiz simge - lütfen kimlik doğrulaması yapın",
"info": "Bilgi:", "info": "Bilgi:",
"folder_exists": "Klasör zaten var: '{path}'", "folder_exists": "Klasör zaten var: '{path}'",
"file_not_exist": "Dosya mevcut değil: '{path}'", "file_not_exist": "Dosya mevcut değil: '{path}'",

View file

@ -41,7 +41,7 @@
"deprecated_command_alias": "'{prog} {old}' застаріла і буде видалена, замість неї використовуйте '{prog} {new}'", "deprecated_command_alias": "'{prog} {old}' застаріла і буде видалена, замість неї використовуйте '{prog} {new}'",
"deprecated_command": "'{prog} {command}' застаріла і буде видалена", "deprecated_command": "'{prog} {command}' застаріла і буде видалена",
"confirm": "Підтвердити {prompt}", "confirm": "Підтвердити {prompt}",
"colon": "{}: ",
"authentication_required": "Потрібна автентифікація", "authentication_required": "Потрібна автентифікація",
"argument_required": "Потрібен аргумент '{argument}'" "argument_required": "Потрібен аргумент '{argument}'",
"edit_text_question": "{}. Редагувати цей текст? [yN]: "
} }

View file

@ -6,6 +6,7 @@ import logging
import glob import glob
import pickle as pickle import pickle as pickle
from typing import List, Optional
from time import time from time import time
from collections import OrderedDict from collections import OrderedDict
from importlib import import_module from importlib import import_module
@ -30,7 +31,6 @@ logger = logging.getLogger("moulinette.actionsmap")
class _ExtraParameter(object): class _ExtraParameter(object):
""" """
Argument parser for an extra parameter. Argument parser for an extra parameter.
@ -39,21 +39,14 @@ class _ExtraParameter(object):
""" """
name: Optional[str] = None
"""A list of interface for which the parameter doesn't apply to"""
skipped_iface: List[str] = []
def __init__(self, iface): def __init__(self, iface):
self.iface = iface self.iface = iface
# Required variables
# Each extra parameters classes must overwrite these variables.
"""The extra parameter name"""
name = None
# Optional variables
# Each extra parameters classes can overwrite these variables.
"""A list of interface for which the parameter doesn't apply"""
skipped_iface = []
# Virtual methods # Virtual methods
# Each extra parameters classes can implement these methods. # Each extra parameters classes can implement these methods.
@ -621,7 +614,7 @@ class ActionsMap(object):
# This var is ['*'] by default but could be set for example to # This var is ['*'] by default but could be set for example to
# ['yunohost', 'yml_*'] # ['yunohost', 'yml_*']
NAMESPACE_PATTERNS = env["NAMESPACES"] NAMESPACE_PATTERNS = env["NAMESPACES"].split()
# Look for all files that match the given patterns in the actionsmap dir # Look for all files that match the given patterns in the actionsmap dir
for namespace_pattern in NAMESPACE_PATTERNS: for namespace_pattern in NAMESPACE_PATTERNS:

View file

@ -22,8 +22,6 @@ for key in env.keys():
if value_from_environ: if value_from_environ:
env[key] = value_from_environ env[key] = value_from_environ
env["NAMESPACES"] = env["NAMESPACES"].split()
def during_unittests_run(): def during_unittests_run():
return "TESTS_RUN" in os.environ return "TESTS_RUN" in os.environ
@ -248,7 +246,7 @@ class Moulinette18n(object):
for n in self._namespaces.values(): for n in self._namespaces.values():
n.set_locale(locale) n.set_locale(locale)
def g(self, key, *args, **kwargs): def g(self, key: str, *args, **kwargs) -> str:
"""Retrieve proper translation for a moulinette key """Retrieve proper translation for a moulinette key
Attempt to retrieve value for a key from moulinette translations Attempt to retrieve value for a key from moulinette translations
@ -260,7 +258,7 @@ class Moulinette18n(object):
""" """
return self._global.translate(key, *args, **kwargs) return self._global.translate(key, *args, **kwargs)
def n(self, key, *args, **kwargs): def n(self, key: str, *args, **kwargs) -> str:
"""Retrieve proper translation for a moulinette key """Retrieve proper translation for a moulinette key
Attempt to retrieve value for a key from current loaded namespace Attempt to retrieve value for a key from current loaded namespace
@ -273,7 +271,7 @@ class Moulinette18n(object):
""" """
return self._namespaces[self._current_namespace].translate(key, *args, **kwargs) return self._namespaces[self._current_namespace].translate(key, *args, **kwargs)
def key_exists(self, key): def key_exists(self, key: str) -> bool:
"""Check if a key exists in the translation files """Check if a key exists in the translation files
Keyword arguments: Keyword arguments:
@ -300,7 +298,7 @@ class MoulinetteError(Exception):
super(MoulinetteError, self).__init__(msg) super(MoulinetteError, self).__init__(msg)
self.strerror = msg self.strerror = msg
def content(self): def content(self) -> str:
return self.strerror return self.strerror

View file

@ -7,6 +7,7 @@ import copy
import datetime import datetime
from collections import deque, OrderedDict from collections import deque, OrderedDict
from json.encoder import JSONEncoder from json.encoder import JSONEncoder
from typing import Optional
from moulinette import m18n from moulinette import m18n
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
@ -44,7 +45,7 @@ class BaseActionsMapParser(object):
# Each parser classes must implement these properties. # Each parser classes must implement these properties.
"""The name of the interface for which it is the parser""" """The name of the interface for which it is the parser"""
interface = None interface: Optional[str] = None
# Virtual methods # Virtual methods
# Each parser classes must implement these methods. # Each parser classes must implement these methods.

View file

@ -268,6 +268,7 @@ class Session:
return infos return infos
@staticmethod
def delete_infos(): def delete_infos():
response.set_cookie(f"session.{Session.actionsmap_name}", "", max_age=-1) response.set_cookie(f"session.{Session.actionsmap_name}", "", max_age=-1)

View file

@ -2,12 +2,13 @@
import os import os
import sys import sys
import getpass
import locale import locale
import logging import logging
import argparse import argparse
import tempfile
from collections import OrderedDict from collections import OrderedDict
from datetime import date, datetime from datetime import date, datetime
from subprocess import call
from moulinette import m18n, Moulinette from moulinette import m18n, Moulinette
from moulinette.actionsmap import ActionsMap from moulinette.actionsmap import ActionsMap
@ -522,7 +523,17 @@ class Interface:
credentials = self.prompt(msg, True, False, color="yellow") credentials = self.prompt(msg, True, False, color="yellow")
return authenticator.authenticate_credentials(credentials=credentials) return authenticator.authenticate_credentials(credentials=credentials)
def prompt(self, message, is_password=False, confirm=False, color="blue"): def prompt(
self,
message,
is_password=False,
confirm=False,
color="blue",
prefill="",
is_multiline=False,
autocomplete=[],
help=None,
):
"""Prompt for a value """Prompt for a value
Keyword arguments: Keyword arguments:
@ -534,15 +545,69 @@ class Interface:
"Not a tty, can't do interactive prompts", raw_msg=True "Not a tty, can't do interactive prompts", raw_msg=True
) )
if is_password: def _prompt(message):
prompt = lambda m: getpass.getpass(colorize(m18n.g("colon", m), color))
else: if not is_multiline:
prompt = lambda m: input(colorize(m18n.g("colon", m), color))
value = prompt(message) import prompt_toolkit
from prompt_toolkit.contrib.completers import WordCompleter
from pygments.token import Token
autocomplete_ = WordCompleter(autocomplete)
style = prompt_toolkit.styles.style_from_dict(
{
Token.Message: f"#ansi{color} bold",
}
)
def get_bottom_toolbar_tokens(cli):
if help:
return [(Token, help)]
else:
return []
def get_tokens(cli):
return [
(Token.Message, message),
(Token, ": "),
]
return prompt_toolkit.prompt(
get_prompt_tokens=get_tokens,
get_bottom_toolbar_tokens=get_bottom_toolbar_tokens,
style=style,
default=prefill,
true_color=True,
completer=autocomplete_,
is_password=is_password,
)
else:
while True:
value = input(
colorize(m18n.g("edit_text_question", message), color)
)
value = value.lower().strip()
if value in ["", "n", "no"]:
return prefill
elif value in ["y", "yes"]:
break
initial_message = prefill.encode("utf-8")
with tempfile.NamedTemporaryFile(suffix=".tmp") as tf:
tf.write(initial_message)
tf.flush()
call(["editor", tf.name])
tf.seek(0)
edited_message = tf.read()
return edited_message.decode("utf-8")
value = _prompt(message)
if confirm: if confirm:
m = message[0].lower() + message[1:] m = message[0].lower() + message[1:]
if prompt(m18n.g("confirm", prompt=m)) != value: if _prompt(m18n.g("confirm", prompt=m)) != value:
raise MoulinetteValidationError("values_mismatch") raise MoulinetteValidationError("values_mismatch")
return value return value

View file

@ -15,7 +15,7 @@ from moulinette.core import MoulinetteError
# Files & directories -------------------------------------------------- # Files & directories --------------------------------------------------
def read_file(file_path): def read_file(file_path, file_mode="r"):
""" """
Read a regular text file Read a regular text file
@ -35,7 +35,7 @@ def read_file(file_path):
# Open file and read content # Open file and read content
try: try:
with open(file_path, "r") as f: with open(file_path, file_mode) as f:
file_content = f.read() file_content = f.read()
except IOError as e: except IOError as e:
raise MoulinetteError("cannot_open_file", file=file_path, error=str(e)) raise MoulinetteError("cannot_open_file", file=file_path, error=str(e))
@ -67,16 +67,17 @@ def read_json(file_path):
return loaded_json return loaded_json
def read_yaml(file_path): def read_yaml(file_):
""" """
Safely read a yaml file Safely read a yaml file
Keyword argument: Keyword argument:
file_path -- Path to the yaml file file -- Path or stream to the yaml file
""" """
# Read file # Read file
file_content = read_file(file_path) file_path = file_ if isinstance(file_, str) else file_.name
file_content = read_file(file_) if isinstance(file_, str) else file_
# Try to load yaml to check if it's syntaxically correct # Try to load yaml to check if it's syntaxically correct
try: try:
@ -118,8 +119,8 @@ def write_to_file(file_path, data, file_mode="w"):
file_mode -- Mode used when writing the file. Option meant to be used file_mode -- Mode used when writing the file. Option meant to be used
by append_to_file to avoid duplicating the code of this function. by append_to_file to avoid duplicating the code of this function.
""" """
assert isinstance(data, str) or isinstance( assert (
data, list isinstance(data, str) or isinstance(data, bytes) or isinstance(data, list)
), "Error: data '%s' should be either a string or a list but is of type '%s'" % ( ), "Error: data '%s' should be either a string or a list but is of type '%s'" % (
data, data,
type(data), type(data),
@ -135,7 +136,7 @@ def write_to_file(file_path, data, file_mode="w"):
) )
# If data is a list, check elements are strings and build a single string # If data is a list, check elements are strings and build a single string
if not isinstance(data, str): if isinstance(data, list):
for element in data: for element in data:
assert isinstance( assert isinstance(
element, str element, str
@ -364,3 +365,10 @@ def rm(path, recursive=False, force=False):
except OSError as e: except OSError as e:
if not force: if not force:
raise MoulinetteError("error_removing", path=path, error=str(e)) raise MoulinetteError("error_removing", path=path, error=str(e))
def cp(source, dest, recursive=False, **kwargs):
if recursive and os.path.isdir(source):
return shutil.copytree(source, dest, symlinks=True, **kwargs)
else:
return shutil.copy2(source, dest, follow_symlinks=False, **kwargs)

View file

@ -88,6 +88,13 @@ def call_async_output(args, callback, **kwargs):
break break
callback(message) callback(message)
while True:
try:
callback, message = log_queue.get_nowait()
except queue.Empty:
break
callback(message)
finally: finally:
kwargs["stdout"].close() kwargs["stdout"].close()
kwargs["stderr"].close() kwargs["stderr"].close()
@ -108,7 +115,7 @@ class LogPipe(threading.Thread):
self.log_callback = log_callback self.log_callback = log_callback
self.fdRead, self.fdWrite = os.pipe() self.fdRead, self.fdWrite = os.pipe()
self.pipeReader = os.fdopen(self.fdRead) self.pipeReader = os.fdopen(self.fdRead, "rb")
self.queue = queue self.queue = queue
@ -120,8 +127,8 @@ class LogPipe(threading.Thread):
def run(self): def run(self):
"""Run the thread, logging everything.""" """Run the thread, logging everything."""
for line in iter(self.pipeReader.readline, ""): for line in iter(self.pipeReader.readline, b""):
self.queue.put((self.log_callback, line.strip("\n"))) self.queue.put((self.log_callback, line.decode("utf-8").strip("\n")))
self.pipeReader.close() self.pipeReader.close()

View file

@ -2,9 +2,18 @@
import os import os
import sys import sys
import subprocess
from setuptools import setup, find_packages from setuptools import setup, find_packages
from moulinette import env from moulinette import env
version = (
subprocess.check_output(
"head debian/changelog -n1 | awk '{print $2}' | tr -d '()'", shell=True
)
.decode()
.strip()
)
LOCALES_DIR = env["LOCALES_DIR"] LOCALES_DIR = env["LOCALES_DIR"]
@ -24,6 +33,8 @@ install_deps = [
"toml", "toml",
"gevent-websocket", "gevent-websocket",
"bottle", "bottle",
"prompt-toolkit==1.0.15", # To be bumped to debian version once we're on bullseye (+ need tweaks in cli.py)
"pygments",
] ]
test_deps = [ test_deps = [
@ -31,23 +42,24 @@ test_deps = [
"pytest-cov", "pytest-cov",
"pytest-env", "pytest-env",
"pytest-mock", "pytest-mock",
"mock",
"requests", "requests",
"requests-mock", "requests-mock",
"webtest", "webtest",
] ]
extras = { extras = {
"install": install_deps, "install": install_deps,
"tests": test_deps, "tests": test_deps,
} }
setup( setup(
name="Moulinette", name="Moulinette",
version="2.0.0", version=version,
description="Prototype interfaces quickly and easily", description="Prototype interfaces quickly and easily",
author="Yunohost Team", author="Yunohost Team",
author_email="yunohost@yunohost.org", author_email="yunohost@yunohost.org",
url="http://yunohost.org", url="https://yunohost.org",
license="AGPL", license="AGPL",
packages=find_packages(exclude=["test"]), packages=find_packages(exclude=["test"]),
data_files=[(LOCALES_DIR, locale_files)], data_files=[(LOCALES_DIR, locale_files)],

View file

@ -0,0 +1,53 @@
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)

60
test/reformat_locales.py Normal file
View file

@ -0,0 +1,60 @@
import re
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",
"e-mail": "email",
"Courriel": "Email",
"E-mail": "Email",
"« ": "'",
"«": "'",
" »": "'",
"»": "'",
"": "'",
# r"$(\w{1,2})'|( \w{1,2})'": r"\1\2",
}
)
reformat("fr", transformations)

View file

@ -2,7 +2,7 @@ import json
import glob import glob
from collections import OrderedDict from collections import OrderedDict
locale_folder = "../locales/" locale_folder = "locales/"
locale_files = glob.glob(locale_folder + "*.json") locale_files = glob.glob(locale_folder + "*.json")
locale_files = [filename.split("/")[-1] for filename in locale_files] locale_files = [filename.split("/")[-1] for filename in locale_files]
locale_files.remove("en.json") locale_files.remove("en.json")

View file

@ -188,7 +188,7 @@ class TestAuthAPI:
class TestAuthCLI: class TestAuthCLI:
def test_login(self, moulinette_cli, capsys, mocker): def test_login(self, moulinette_cli, capsys, mocker):
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="dummy") mocker.patch("prompt_toolkit.prompt", return_value="dummy")
moulinette_cli.run(["testauth", "default"], output_as="plain") moulinette_cli.run(["testauth", "default"], output_as="plain")
message = capsys.readouterr() message = capsys.readouterr()
@ -201,25 +201,25 @@ class TestAuthCLI:
def test_login_bad_password(self, moulinette_cli, capsys, mocker): def test_login_bad_password(self, moulinette_cli, capsys, mocker):
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="Bad Password") mocker.patch("prompt_toolkit.prompt", return_value="Bad Password")
with pytest.raises(MoulinetteError): with pytest.raises(MoulinetteError):
moulinette_cli.run(["testauth", "default"], output_as="plain") moulinette_cli.run(["testauth", "default"], output_as="plain")
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="Bad Password") mocker.patch("prompt_toolkit.prompt", return_value="Bad Password")
with pytest.raises(MoulinetteError): with pytest.raises(MoulinetteError):
moulinette_cli.run(["testauth", "default"], output_as="plain") moulinette_cli.run(["testauth", "default"], output_as="plain")
def test_login_wrong_profile(self, moulinette_cli, mocker): def test_login_wrong_profile(self, moulinette_cli, mocker):
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="dummy") mocker.patch("prompt_toolkit.prompt", return_value="dummy")
with pytest.raises(MoulinetteError) as exception: with pytest.raises(MoulinetteError) as exception:
moulinette_cli.run(["testauth", "other-profile"], output_as="none") moulinette_cli.run(["testauth", "other-profile"], output_as="none")
assert "invalid_password" in str(exception) assert "invalid_password" in str(exception)
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="yoloswag") mocker.patch("prompt_toolkit.prompt", return_value="yoloswag")
with pytest.raises(MoulinetteError) as exception: with pytest.raises(MoulinetteError) as exception:
moulinette_cli.run(["testauth", "default"], output_as="none") moulinette_cli.run(["testauth", "default"], output_as="none")
@ -239,7 +239,7 @@ class TestAuthCLI:
def test_request_only_cli(self, capsys, moulinette_cli, mocker): def test_request_only_cli(self, capsys, moulinette_cli, mocker):
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="dummy") mocker.patch("prompt_toolkit.prompt", return_value="dummy")
moulinette_cli.run(["testauth", "only-cli"], output_as="plain") moulinette_cli.run(["testauth", "only-cli"], output_as="plain")
message = capsys.readouterr() message = capsys.readouterr()
@ -248,7 +248,7 @@ class TestAuthCLI:
def test_request_not_logged_only_cli(self, capsys, moulinette_cli, mocker): def test_request_not_logged_only_cli(self, capsys, moulinette_cli, mocker):
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass") mocker.patch("prompt_toolkit.prompt")
with pytest.raises(MoulinetteError) as exception: with pytest.raises(MoulinetteError) as exception:
moulinette_cli.run(["testauth", "only-cli"], output_as="plain") moulinette_cli.run(["testauth", "only-cli"], output_as="plain")
@ -259,7 +259,7 @@ class TestAuthCLI:
def test_request_with_callback(self, moulinette_cli, capsys, mocker): def test_request_with_callback(self, moulinette_cli, capsys, mocker):
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="dummy") mocker.patch("prompt_toolkit.prompt", return_value="dummy")
moulinette_cli.run(["--version"], output_as="plain") moulinette_cli.run(["--version"], output_as="plain")
message = capsys.readouterr() message = capsys.readouterr()
@ -278,7 +278,7 @@ class TestAuthCLI:
def test_request_with_arg(self, moulinette_cli, capsys, mocker): def test_request_with_arg(self, moulinette_cli, capsys, mocker):
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="dummy") mocker.patch("prompt_toolkit.prompt", return_value="dummy")
moulinette_cli.run(["testauth", "with_arg", "yoloswag"], output_as="plain") moulinette_cli.run(["testauth", "with_arg", "yoloswag"], output_as="plain")
message = capsys.readouterr() message = capsys.readouterr()
@ -286,7 +286,7 @@ class TestAuthCLI:
def test_request_arg_with_extra(self, moulinette_cli, capsys, mocker): def test_request_arg_with_extra(self, moulinette_cli, capsys, mocker):
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="dummy") mocker.patch("prompt_toolkit.prompt", return_value="dummy")
moulinette_cli.run( moulinette_cli.run(
["testauth", "with_extra_str_only", "YoLoSwAg"], output_as="plain" ["testauth", "with_extra_str_only", "YoLoSwAg"], output_as="plain"
) )
@ -306,7 +306,7 @@ class TestAuthCLI:
def test_request_arg_with_type(self, moulinette_cli, capsys, mocker): def test_request_arg_with_type(self, moulinette_cli, capsys, mocker):
mocker.patch("os.isatty", return_value=True) mocker.patch("os.isatty", return_value=True)
mocker.patch("getpass.getpass", return_value="dummy") mocker.patch("prompt_toolkit.prompt", return_value="dummy")
moulinette_cli.run(["testauth", "with_type_int", "12345"], output_as="plain") moulinette_cli.run(["testauth", "with_type_int", "12345"], output_as="plain")
message = capsys.readouterr() message = capsys.readouterr()

View file

@ -1,6 +1,7 @@
import os import os
from subprocess import CalledProcessError from subprocess import CalledProcessError
import mock
import pytest import pytest
from moulinette.utils.process import run_commands from moulinette.utils.process import run_commands
@ -65,39 +66,71 @@ def test_run_shell_kwargs():
def test_call_async_output(test_file): def test_call_async_output(test_file):
mock_callback_stdout = mock.Mock()
mock_callback_stderr = mock.Mock()
def stdout_callback(a): def stdout_callback(a):
assert a == "foo" or a == "bar" mock_callback_stdout(a)
def stderr_callback(a): def stderr_callback(a):
assert False # we shouldn't reach this line mock_callback_stderr(a)
callbacks = (lambda l: stdout_callback(l), lambda l: stderr_callback(l)) callbacks = (lambda l: stdout_callback(l), lambda l: stderr_callback(l))
call_async_output(["cat", str(test_file)], callbacks) call_async_output(["cat", str(test_file)], callbacks)
calls = [mock.call("foo"), mock.call("bar")]
mock_callback_stdout.assert_has_calls(calls)
mock_callback_stderr.assert_not_called()
mock_callback_stdout.reset_mock()
mock_callback_stderr.reset_mock()
with pytest.raises(TypeError): with pytest.raises(TypeError):
call_async_output(["cat", str(test_file)], 1) call_async_output(["cat", str(test_file)], 1)
def callbackA(a): mock_callback_stdout.assert_not_called()
assert a == "foo" or a == "bar" mock_callback_stderr.assert_not_called()
def callbackB(a): mock_callback_stdout.reset_mock()
assert "cat: doesntexists" in a mock_callback_stderr.reset_mock()
callback = (callbackA, callbackB) def callback_stdout(a):
mock_callback_stdout(a)
def callback_stderr(a):
mock_callback_stderr(a)
callback = (callback_stdout, callback_stderr)
call_async_output(["cat", str(test_file)], callback) call_async_output(["cat", str(test_file)], callback)
call_async_output(["cat", "doesntexists"], callback) calls = [mock.call("foo"), mock.call("bar")]
mock_callback_stdout.assert_has_calls(calls)
mock_callback_stderr.assert_not_called()
mock_callback_stdout.reset_mock()
mock_callback_stderr.reset_mock()
env_var = {"LANG": "C"}
call_async_output(["cat", "doesntexists"], callback, env=env_var)
calls = [mock.call("cat: doesntexists: No such file or directory")]
mock_callback_stdout.assert_not_called()
mock_callback_stderr.assert_has_calls(calls)
def test_call_async_output_kwargs(test_file, mocker): def test_call_async_output_kwargs(test_file, mocker):
mock_callback_stdout = mock.Mock()
mock_callback_stdinfo = mock.Mock()
mock_callback_stderr = mock.Mock()
def stdinfo_callback(a): def stdinfo_callback(a):
assert False # we shouldn't reach this line mock_callback_stdinfo(a)
def stdout_callback(a): def stdout_callback(a):
assert a == "foo" or a == "bar" mock_callback_stdout(a)
def stderr_callback(a): def stderr_callback(a):
assert False # we shouldn't reach this line mock_callback_stderr(a)
callbacks = ( callbacks = (
lambda l: stdout_callback(l), lambda l: stdout_callback(l),
@ -107,16 +140,43 @@ def test_call_async_output_kwargs(test_file, mocker):
with pytest.raises(ValueError): with pytest.raises(ValueError):
call_async_output(["cat", str(test_file)], callbacks, stdout=None) call_async_output(["cat", str(test_file)], callbacks, stdout=None)
mock_callback_stdout.assert_not_called()
mock_callback_stdinfo.assert_not_called()
mock_callback_stderr.assert_not_called()
mock_callback_stdout.reset_mock()
mock_callback_stdinfo.reset_mock()
mock_callback_stderr.reset_mock()
with pytest.raises(ValueError): with pytest.raises(ValueError):
call_async_output(["cat", str(test_file)], callbacks, stderr=None) call_async_output(["cat", str(test_file)], callbacks, stderr=None)
mock_callback_stdout.assert_not_called()
mock_callback_stdinfo.assert_not_called()
mock_callback_stderr.assert_not_called()
mock_callback_stdout.reset_mock()
mock_callback_stdinfo.reset_mock()
mock_callback_stderr.reset_mock()
with pytest.raises(TypeError): with pytest.raises(TypeError):
call_async_output(["cat", str(test_file)], callbacks, stdinfo=None) call_async_output(["cat", str(test_file)], callbacks, stdinfo=None)
mock_callback_stdout.assert_not_called()
mock_callback_stdinfo.assert_not_called()
mock_callback_stderr.assert_not_called()
mock_callback_stdout.reset_mock()
mock_callback_stdinfo.reset_mock()
mock_callback_stderr.reset_mock()
dirname = os.path.dirname(str(test_file)) dirname = os.path.dirname(str(test_file))
os.mkdir(os.path.join(dirname, "testcwd")) os.mkdir(os.path.join(dirname, "testcwd"))
call_async_output( call_async_output(
["cat", str(test_file)], callbacks, cwd=os.path.join(dirname, "testcwd") ["cat", str(test_file)], callbacks, cwd=os.path.join(dirname, "testcwd")
) )
calls = [mock.call("foo"), mock.call("bar")]
mock_callback_stdout.assert_has_calls(calls)
mock_callback_stdinfo.assert_not_called()
mock_callback_stderr.assert_not_called()
def test_check_output(test_file): def test_check_output(test_file):

10
tox.ini
View file

@ -1,6 +1,6 @@
[tox] [tox]
envlist = envlist =
py{37,39}-{pytest,lint,invalidcode} py{37,39}-{pytest,lint,invalidcode,mypy}
format format
format-check format-check
docs docs
@ -14,10 +14,12 @@ deps =
py{37,39}-pytest: .[tests] py{37,39}-pytest: .[tests]
py{37,39}-lint: flake8 py{37,39}-lint: flake8
py{37,39}-invalidcode: flake8 py{37,39}-invalidcode: flake8
py{37,39}-mypy: mypy >= 0.761
commands = commands =
py{37,39}-pytest: pytest {posargs} -c pytest.ini py{37,39}-pytest: pytest {posargs} -c pytest.ini
py{37,39}-lint: flake8 moulinette test py{37,39}-lint: flake8 moulinette test
py{37,39}-invalidcode: flake8 moulinette test --select F py{37,39}-invalidcode: flake8 moulinette test --select F
py{37,39}-mypy: mypy --ignore-missing-imports --install-types --non-interactive moulinette/
[gh-actions] [gh-actions]
python = python =