From 1541b743eb902e6530359dfa18da1b75423ed2c5 Mon Sep 17 00:00:00 2001 From: Bram Date: Sun, 25 Aug 2019 16:43:27 +0200 Subject: [PATCH 01/19] [README] add link to dev documentation --- README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c3464927..cd4595da 100644 --- a/README.md +++ b/README.md @@ -37,15 +37,10 @@ operation on an interface for example (see [Authenticators](#authenticators)). -### Actions Map -... - -### Interfaces -... - -### Authenticators -... +Dev Documentation +----------------- +https://moulinette.readthedocs.org Requirements ------------ From ad1eeef550c355a1654b2c71466cef80e2ac0947 Mon Sep 17 00:00:00 2001 From: Luke Murphy Date: Wed, 28 Aug 2019 17:49:13 +0200 Subject: [PATCH 02/19] Add CI and license badge --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index cd4595da..01ee55cc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![Build Status](https://travis-ci.org/YunoHost/moulinette.svg?branch=stretch-unstable)](https://travis-ci.org/YunoHost/moulinette) +[![GitHub license](https://img.shields.io/github/license/YunoHost/moulinette)](https://github.com/YunoHost/moulinette/blob/stretch-unstable/LICENSE) + Moulinette ========== From 2c84ee1541e77c75d295c6b69572c94d1ee21178 Mon Sep 17 00:00:00 2001 From: Luke Murphy Date: Wed, 28 Aug 2019 17:57:16 +0200 Subject: [PATCH 03/19] Add tests for text/serialize modules Also take a pass on the docstrings. --- moulinette/utils/serialize.py | 5 +++-- moulinette/utils/text.py | 2 +- test/test_serialize.py | 14 ++++++++++++++ test/test_text.py | 21 +++++++++++++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 test/test_serialize.py create mode 100644 test/test_text.py diff --git a/moulinette/utils/serialize.py b/moulinette/utils/serialize.py index 06981d6e..a4492cba 100644 --- a/moulinette/utils/serialize.py +++ b/moulinette/utils/serialize.py @@ -12,9 +12,10 @@ class JSONExtendedEncoder(JSONEncoder): """Extended JSON encoder - Extend default JSON encoder to recognize more types and classes. It - will never raise if the object can't be encoded and return its repr + Extend default JSON encoder to recognize more types and classes. It will + never raise an exception if the object can't be encoded and return its repr instead. + The following objects and types are supported: - set: converted into list diff --git a/moulinette/utils/text.py b/moulinette/utils/text.py index 4c39e0f3..984e2e89 100644 --- a/moulinette/utils/text.py +++ b/moulinette/utils/text.py @@ -10,7 +10,7 @@ def search(pattern, text, count=0, flags=0): """Search for pattern in a text Scan through text looking for all locations where the regular - expresion pattern matches, and return them as a list of strings. + expression pattern matches, and return them as a list of strings. The optional argument count is the maximum number of pattern occurences to return; count must be an integer. If omitted or zero, diff --git a/test/test_serialize.py b/test/test_serialize.py new file mode 100644 index 00000000..0e761064 --- /dev/null +++ b/test/test_serialize.py @@ -0,0 +1,14 @@ +from datetime import datetime as dt +from moulinette.utils.serialize import JSONExtendedEncoder + + +def test_json_extended_encoder(caplog): + encoder = JSONExtendedEncoder() + + assert encoder.default(set([1, 2, 3])) == [1, 2, 3] + + assert encoder.default(dt(1917, 3, 8)) == '1917-03-08T00:00:00+00:00' + + assert encoder.default(None) == 'None' + for message in caplog.messages: + assert 'cannot properly encode in JSON' in message diff --git a/test/test_text.py b/test/test_text.py new file mode 100644 index 00000000..7ccc901f --- /dev/null +++ b/test/test_text.py @@ -0,0 +1,21 @@ +from moulinette.utils.text import search, searchf, prependlines, random_ascii + + +def test_search(): + assert search('a', 'a a a') == ['a', 'a', 'a'] + assert search('a', 'a a a', count=2) == ['a', 'a'] + assert not search('a', 'c c d') + + +def test_searchf(test_file): + assert searchf('bar', str(test_file)) == ['bar'] + assert not searchf('baz', str(test_file)) + + +def test_prependlines(): + assert prependlines('abc\nedf\nghi', 'XXX') == 'XXXabc\nXXXedf\nXXXghi' + assert prependlines('', 'XXX') == 'XXX' + + +def test_random_ascii(): + assert isinstance(random_ascii(length=2), unicode) From cef72f7de97165b7ed3183978e6d13cbeef694ed Mon Sep 17 00:00:00 2001 From: Luke Murphy Date: Wed, 11 Sep 2019 00:47:10 +0100 Subject: [PATCH 04/19] Add some unit tests for the actionsmap module --- moulinette/actionsmap.py | 6 +-- test/test_actionsmap.py | 87 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 test/test_actionsmap.py diff --git a/moulinette/actionsmap.py b/moulinette/actionsmap.py index 63483701..fd88ec72 100644 --- a/moulinette/actionsmap.py +++ b/moulinette/actionsmap.py @@ -95,7 +95,7 @@ class CommentParameter(_ExtraParameter): def validate(klass, value, arg_name): # Deprecated boolean or empty string if isinstance(value, bool) or (isinstance(value, str) and not value): - logger.warning("expecting a string for extra parameter '%s' of " + logger.warning("expecting a non-empty string for extra parameter '%s' of " "argument '%s'", klass.name, arg_name) value = arg_name elif not isinstance(value, str): @@ -130,7 +130,7 @@ class AskParameter(_ExtraParameter): def validate(klass, value, arg_name): # Deprecated boolean or empty string if isinstance(value, bool) or (isinstance(value, str) and not value): - logger.warning("expecting a string for extra parameter '%s' of " + logger.warning("expecting a non-empty string for extra parameter '%s' of " "argument '%s'", klass.name, arg_name) value = arg_name elif not isinstance(value, str): @@ -198,7 +198,7 @@ class PatternParameter(_ExtraParameter): def validate(value, arg_name): # Deprecated string type if isinstance(value, str): - logger.warning("expecting a list for extra parameter 'pattern' of " + logger.warning("expecting a list as extra parameter 'pattern' of " "argument '%s'", arg_name) value = [value, 'pattern_not_match'] elif not isinstance(value, list) or len(value) != 2: diff --git a/test/test_actionsmap.py b/test/test_actionsmap.py new file mode 100644 index 00000000..82f153a8 --- /dev/null +++ b/test/test_actionsmap.py @@ -0,0 +1,87 @@ +import pytest + +from moulinette.actionsmap import ( + CommentParameter, + AskParameter, + PatternParameter, + RequiredParameter, + ActionsMap +) +from moulinette.interfaces import BaseActionsMapParser +from moulinette.core import MoulinetteError + + +@pytest.fixture +def iface(): + return 'iface' + + +def test_comment_parameter_bad_bool_value(iface, caplog): + comment = CommentParameter(iface) + assert comment.validate(True, 'a') == 'a' + assert any('expecting a non-empty string' in message for message in caplog.messages) + + +def test_comment_parameter_bad_empty_string(iface, caplog): + comment = CommentParameter(iface) + assert comment.validate('', 'a') == 'a' + assert any('expecting a non-empty string' in message for message in caplog.messages) + + +def test_comment_parameter_bad_type(iface): + comment = CommentParameter(iface) + with pytest.raises(TypeError): + comment.validate({}, 'b') + + +def test_ask_parameter_bad_bool_value(iface, caplog): + ask = AskParameter(iface) + assert ask.validate(True, 'a') == 'a' + assert any('expecting a non-empty string' in message for message in caplog.messages) + + +def test_ask_parameter_bad_empty_string(iface, caplog): + ask = AskParameter(iface) + assert ask.validate('', 'a') == 'a' + assert any('expecting a non-empty string' in message for message in caplog.messages) + + +def test_ask_parameter_bad_type(iface): + ask = AskParameter(iface) + with pytest.raises(TypeError): + ask.validate({}, 'b') + + +def test_pattern_parameter_bad_str_value(iface, caplog): + pattern = PatternParameter(iface) + assert pattern.validate('', 'a') == ['', 'pattern_not_match'] + assert any('expecting a list' in message for message in caplog.messages) + + +@pytest.mark.parametrize('iface', [ + [], + ['pattern_alone'], + ['pattern', 'message', 'extra stuff'] +]) +def test_pattern_parameter_bad_list_len(iface): + pattern = PatternParameter(iface) + with pytest.raises(TypeError): + pattern.validate(iface, 'a') + + +def test_required_paremeter_missing_value(iface): + required = RequiredParameter(iface) + with pytest.raises(MoulinetteError) as exception: + required(True, 'a', '') + assert 'is required' in str(exception) + + +def test_actions_map_unknown_authenticator(monkeypatch, tmp_path): + monkeypatch.setenv('MOULINETTE_DATA_DIR', str(tmp_path)) + actionsmap_dir = actionsmap_dir = tmp_path / 'actionsmap' + actionsmap_dir.mkdir() + + amap = ActionsMap(BaseActionsMapParser) + with pytest.raises(ValueError) as exception: + amap.get_authenticator(profile='unknown') + assert 'Unknown authenticator' in str(exception) From c2b68c2e767eee3dfd45f9e7aefab72f110d411d Mon Sep 17 00:00:00 2001 From: xaloc33 Date: Wed, 21 Aug 2019 08:36:23 +0000 Subject: [PATCH 05/19] Translated using Weblate (Catalan) Currently translated at 100.0% (56 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/ca/ --- locales/ca.json | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/locales/ca.json b/locales/ca.json index 374f7a64..50417dcb 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -31,7 +31,7 @@ "server_already_running": "Ja s'està executant un servidor en aquest port", "success": "Èxit!", "unable_authenticate": "No s'ha pogut autenticar", - "unable_retrieve_session": "No s'ha pogut recuperar la sessió", + "unable_retrieve_session": "No s'ha pogut recuperar la sessió a causa de «{exception}»", "unknown_group": "Grup '{group}' desconegut", "unknown_user": "Usuari '{user}' desconegut", "values_mismatch": "Els valors no coincideixen", @@ -39,7 +39,7 @@ "websocket_request_expected": "S'esperava una petició WebSocket", "cannot_open_file": "No s'ha pogut obrir el fitxer {file:s} (motiu: {error:s})", "cannot_write_file": "No s'ha pogut escriure el fitxer {file:s} (motiu: {error:s})", - "unknown_error_reading_file": "Error desconegut al intentar llegir el fitxer {file:s}", + "unknown_error_reading_file": "Error desconegut al intentar llegir el fitxer {file:s} (motiu: {error:s})", "corrupted_json": "Json corrupte llegit des de {ressource:s} (motiu: {error:s})", "corrupted_yaml": "Yaml corrupte llegit des de {ressource:s} (motiu: {error:s})", "error_writing_file": "Error al escriure el fitxer {file:s}: {error:s}", @@ -51,5 +51,9 @@ "download_unknown_error": "Error al baixar dades des de {url:s}: {error:s}", "download_bad_status_code": "{url:s} ha retornat el codi d'estat {code:s}", "command_unknown": "Ordre '{command:s}' desconegut ?", - "info": "Info:" + "info": "Info:", + "corrupted_toml": "El fitxer TOML ha estat corromput en la lectura des de {ressource:s} (motiu: {error:s})", + "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_that_lock_is_acquired": "l'altra ordre tot just ha acabat, ara s'executarà aquesta ordre" } From 6da692617a82241477a4ddb3d8f23106ce52faaf Mon Sep 17 00:00:00 2001 From: htsr Date: Fri, 16 Aug 2019 07:56:14 +0000 Subject: [PATCH 06/19] Translated using Weblate (French) Currently translated at 100.0% (56 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/fr/ --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index 65366253..d1df5f3e 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -52,7 +52,7 @@ "command_unknown": "Commande '{command:s}' inconnue ?", "corrupted_yaml": "Fichier YAML corrompu en lecture depuis {ressource:s} (raison : {error:s})", "info": "Info :", - "corrupted_toml": "Fichier toml corrompu lu depuis {ressources:s}(cause: {error:s})", + "corrupted_toml": "Fichier TOML corrompu en lecture depuis {ressource:s} (cause : {error:s})", "warn_the_user_about_waiting_lock": "Une autre commande Yunohost est en cours, nous attendons qu'elle se termine avant de lancer celle là", "warn_the_user_about_waiting_lock_again": "Toujours en attente...", "warn_the_user_that_lock_is_acquired": "l'autre commande vient de se terminer, lancement de cette commande" From 873541b9d6b1ac9ccefb0d66f3f1036f15db8dac Mon Sep 17 00:00:00 2001 From: ppr Date: Mon, 19 Aug 2019 17:56:40 +0000 Subject: [PATCH 07/19] Translated using Weblate (French) Currently translated at 100.0% (56 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/fr/ --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index d1df5f3e..8ea6537e 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -53,7 +53,7 @@ "corrupted_yaml": "Fichier YAML corrompu en lecture depuis {ressource:s} (raison : {error:s})", "info": "Info :", "corrupted_toml": "Fichier TOML corrompu en lecture depuis {ressource:s} (cause : {error:s})", - "warn_the_user_about_waiting_lock": "Une autre commande Yunohost est en cours, nous attendons qu'elle se termine avant de lancer 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_that_lock_is_acquired": "l'autre commande vient de se terminer, lancement de cette commande" } From 704f2074e20a9ed09482fa9932739bc657218778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quent=C3=AD?= Date: Mon, 19 Aug 2019 20:02:28 +0000 Subject: [PATCH 08/19] Translated using Weblate (Occitan) Currently translated at 100.0% (56 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/oc/ --- locales/oc.json | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/locales/oc.json b/locales/oc.json index 64ebbf67..c7068e82 100644 --- a/locales/oc.json +++ b/locales/oc.json @@ -24,7 +24,7 @@ "pattern_not_match": "Correspond pas al patron", "permission_denied": "Permission refusada", "root_required": "Cal èsser root per realizar aquesta accion", - "unable_retrieve_session": "Impossible de recuperar la session", + "unable_retrieve_session": "Recuperacion impossibla de la session a causa de « {exception} »", "unknown_group": "Grop « {group} » desconegut", "unknown_user": "Utilizaire « {user} » desconegut", "values_mismatch": "Las valors correspondon pas", @@ -39,7 +39,7 @@ "websocket_request_expected": "Una requèsta WebSocket èra esperada", "cannot_open_file": "Impossible de dobrir lo fichièr {file:s} (rason : {error:s})", "cannot_write_file": "Escritura impossibla del fichièr {file:s} (rason : {error:s})", - "unknown_error_reading_file": "Error desconeguda en ensajar de legir lo fichièr {file:s}", + "unknown_error_reading_file": "Error desconeguda en ensajar de legir lo fichièr {file:s} (rason : {error:s})", "error_writing_file": "Error en escriure lo fichièr {file:s} : {error:s}", "error_removing": "Error en suprimir {path:s} : {error:s}", "error_changing_file_permissions": "Error en modificar las permissions per {path:s} : {error:s}", @@ -48,8 +48,12 @@ "download_timeout": "{url:s} a trigat per respondre, avèm quitat d’esperar.", "download_unknown_error": "Error en telecargar de donadas de {url:s} : {error:s}", "download_bad_status_code": "{url:s} tòrna lo còdi d’estat {code:s}", - "command_unknown": "Comanda {command:s} desconeguda ?", + "command_unknown": "Comanda « {command:s} » desconeguda ?", "corrupted_json": "Fichièr Json corromput legit de {ressource:s} (rason : {error:s})", "corrupted_yaml": "Fichièr YAML corromput legit de {ressource:s} (rason : {error:s})", - "info": "Info :" + "info": "Info :", + "corrupted_toml": "Fichièr TOML corromput en lectura de {ressource:s} estant (rason : {error:s})", + "warn_the_user_about_waiting_lock": "Una autra comanda YunoHost es en execucion, sèm a esperar qu’acabe abans d’aviar aquesta d’aquí", + "warn_the_user_about_waiting_lock_again": "Encara en espèra…", + "warn_the_user_that_lock_is_acquired": "l’autra comanda ven d’acabar, lançament d’aquesta comanda" } From ad101758ec1a10660a177d41132839e32a433226 Mon Sep 17 00:00:00 2001 From: chema ortega ruiz Date: Tue, 13 Aug 2019 19:02:47 +0000 Subject: [PATCH 09/19] Translated using Weblate (Spanish) Currently translated at 91.1% (51 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/es/ --- locales/es.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/es.json b/locales/es.json index 29758542..324b028a 100644 --- a/locales/es.json +++ b/locales/es.json @@ -31,7 +31,7 @@ "server_already_running": "Ya se está ejecutando un servidor en ese puerto", "success": "¡Éxito!", "unable_authenticate": "No se puede autenticar", - "unable_retrieve_session": "No se puede recuperar la sesión", + "unable_retrieve_session": "No se puede recuperar la sesión por '{exception}'", "unknown_group": "Grupo '{group}' desconocido", "unknown_user": "Usuario '{user}' desconocido", "values_mismatch": "Los valores no coinciden", @@ -39,7 +39,7 @@ "websocket_request_expected": "Se esperaba una petición WebSocket", "cannot_open_file": "No se pudo abrir el fichero{file:s} (motivo:{error:s})", "cannot_write_file": "No se pudo escribir el fichero {file:s} (motivo: {error:s})", - "unknown_error_reading_file": "Error desconocido al intentar leer el fichero {file:s}", + "unknown_error_reading_file": "Error desconocido al intentar leer el fichero {file:s} (motivo: {error:s})", "corrupted_json": "Json corrupto leido desde {ressource:s} (motivo: {error:s})", "error_writing_file": "Error al escribir el fichero {file:s}: {error:s}", "error_removing": "Error al eliminar {path:s}: {error:s}", From 1ee783da1d079481b05e64f3bbc96151393e998a Mon Sep 17 00:00:00 2001 From: ButterflyOfFire Date: Mon, 9 Sep 2019 20:37:26 +0000 Subject: [PATCH 10/19] Translated using Weblate (Arabic) Currently translated at 94.6% (53 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/ar/ --- locales/ar.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/locales/ar.json b/locales/ar.json index 8102b572..b5746321 100644 --- a/locales/ar.json +++ b/locales/ar.json @@ -31,7 +31,7 @@ "server_already_running": "هناك خادم يشتغل على ذاك المنفذ", "success": "تم بنجاح !", "unable_authenticate": "تعذرت المصادقة", - "unable_retrieve_session": "تعذرت مواصلة الجلسة", + "unable_retrieve_session": "تعذرت مواصلة الجلسة بسبب '{exception}'", "unknown_group": "الفريق '{group}' مجهول", "unknown_user": "المستخدم '{user}' مجهول", "values_mismatch": "القيمتين غير متطابقتين", @@ -39,7 +39,7 @@ "websocket_request_expected": "كان ينتظر طلبًا عبر الويب سوكت WebSocket", "cannot_open_file": "ليس بالإمكان فتح الملف {file:s} (السبب : {error:s})", "cannot_write_file": "لا يمكن الكتابة في الملف {file:s} (السبب : {error:s})", - "unknown_error_reading_file": "طرأ هناك خطأ ما أثناء عملية قراءة الملف {file:s}", + "unknown_error_reading_file": "طرأ هناك خطأ ما أثناء عملية قراءة الملف {file:s} (السبب: {error:s})", "corrupted_json": "قراءة json مُشوّهة مِن {ressource:s} (السبب : {error:s})", "error_writing_file": "طرأ هناك خطأ أثناء الكتابة في الملف {file:s}: {error:s}", "error_removing": "خطأ أثناء عملية حذف {path:s}: {error:s}", @@ -49,7 +49,8 @@ "download_timeout": "{url:s} استغرق مدة طويلة جدا للإستجابة، فتوقّف.", "download_unknown_error": "خطأ أثناء عملية تنزيل البيانات مِن {url:s} : {error:s}", "download_bad_status_code": "{url:s} أعاد رمز الحالة {code:s}", - "command_unknown": "الأمر '{command:s}' غير معروف ؟", + "command_unknown": "الأمر '{command:s}' مجهول؟", "corrupted_yaml": "قراءة مُشوّهة لنسق yaml مِن {ressource:s} (السبب : {error:s})", - "info": "معلومة:" + "info": "معلومة:", + "warn_the_user_about_waiting_lock_again": "جارٍ الانتظار…" } From d895ae32068bb98a1531020f2c9501b4a2b433ff Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Mon, 16 Sep 2019 02:54:01 +0200 Subject: [PATCH 11/19] [ux] make timeout message more explicit --- locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.json b/locales/en.json index 78ef4edc..906694eb 100644 --- a/locales/en.json +++ b/locales/en.json @@ -14,7 +14,7 @@ "folder_exists": "Folder already exists: '{path}'", "folder_not_exist": "Folder does not exist", "info": "Info:", - "instance_already_running": "An instance is already running", + "instance_already_running": "There is already a YunoHost command running, please wait for it to finish before doing this one", "invalid_argument": "Invalid argument '{argument}': {error}", "invalid_password": "Invalid password", "invalid_usage": "Invalid usage, pass --help to see help", From bdf0a1cb7a0e11501883c1395849aa056e7139db Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 19 Sep 2019 13:40:08 +0200 Subject: [PATCH 12/19] Small message tweak improvement considering from the webadmin you don't run commands strictly speaking but just click buttons --- locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.json b/locales/en.json index 906694eb..36d93a8f 100644 --- a/locales/en.json +++ b/locales/en.json @@ -14,7 +14,7 @@ "folder_exists": "Folder already exists: '{path}'", "folder_not_exist": "Folder does not exist", "info": "Info:", - "instance_already_running": "There is already a YunoHost command running, please wait for it to finish before doing this one", + "instance_already_running": "There is already a YunoHost operation running. Please wait for it to finish before running another one.", "invalid_argument": "Invalid argument '{argument}': {error}", "invalid_password": "Invalid password", "invalid_usage": "Invalid usage, pass --help to see help", From 808f6203fdc2468bb43e410ce89396904e8912b3 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 27 Sep 2019 17:40:44 +0200 Subject: [PATCH 13/19] Allow to customize color for CLI prompts --- moulinette/core.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/moulinette/core.py b/moulinette/core.py index c902d4c5..e1c9edeb 100644 --- a/moulinette/core.py +++ b/moulinette/core.py @@ -307,7 +307,7 @@ class MoulinetteSignals(object): return authenticator return self._authenticate(authenticator, help) - def prompt(self, message, is_password=False, confirm=False): + def prompt(self, message, is_password=False, confirm=False, color='blue'): """Prompt for a value Prompt the interface for a parameter value which is a password @@ -320,12 +320,13 @@ class MoulinetteSignals(object): - message -- The message to display - is_password -- True if the parameter is a password - confirm -- True if the value must be confirmed + - color -- Color to use for the prompt ... Returns: The collected value """ - return self._prompt(message, is_password, confirm) + return self._prompt(message, is_password, confirm, color=color) def display(self, message, style='info'): """Display a message From 71c01d01314913041d89fd62863d78a9e884db0b Mon Sep 17 00:00:00 2001 From: advocatux Date: Sun, 15 Sep 2019 10:06:09 +0000 Subject: [PATCH 14/19] Translated using Weblate (Spanish) Currently translated at 100.0% (56 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/es/ --- locales/es.json | 54 ++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/locales/es.json b/locales/es.json index 324b028a..b6310882 100644 --- a/locales/es.json +++ b/locales/es.json @@ -1,23 +1,23 @@ { - "argument_required": "Se requiere el argumento '{argument}'", - "authentication_profile_required": "Autenticación requerida para el perfil '{profile}'", + "argument_required": "Se requiere el argumento «{argument}»", + "authentication_profile_required": "Autentificación requerida para el perfil «{profile}»", "authentication_required": "Se requiere autentificación", - "authentication_required_long": "Debe autenticarse para realizar esta acción", + "authentication_required_long": "Debe autentificarse para realizar esta acción", "colon": "{}: ", "confirm": "Confirmar {prompt}", - "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": "«{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", "error": "Error:", "error_see_log": "Ha ocurrido un error. Consulte el registro para obtener más información, localizado en /var/log/yunohost/.", - "file_exists": "El archivo ya existe: '{path}'", - "file_not_exist": "El archivo no existe: '{path}'", - "folder_exists": "El directorio ya existe: '{path}'", - "folder_not_exist": "El directorio no existe", + "file_exists": "El archivo ya existe: «{path}»", + "file_not_exist": "El archivo no existe: «{path}»", + "folder_exists": "El directorio ya existe: «{path}»", + "folder_not_exist": "La carpeta no existe", "instance_already_running": "Una instancia ya se está ejecutando", - "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", - "ldap_attribute_already_exists": "El atributo '{attribute}' ya existe con el valor '{value}'", + "ldap_attribute_already_exists": "El atributo «{attribute}» ya existe con el valor «{value}»", "ldap_operation_error": "Ha ocurrido un error durante la operación de LDAP", "ldap_server_down": "No se pudo conectar con el servidor LDAP", "logged_in": "Sesión iniciada", @@ -30,26 +30,30 @@ "root_required": "Solo root puede realizar esta acción", "server_already_running": "Ya se está ejecutando un servidor en ese puerto", "success": "¡Éxito!", - "unable_authenticate": "No se puede autenticar", - "unable_retrieve_session": "No se puede recuperar la sesión por '{exception}'", - "unknown_group": "Grupo '{group}' desconocido", - "unknown_user": "Usuario '{user}' desconocido", + "unable_authenticate": "No se puede autentificar", + "unable_retrieve_session": "No se puede recuperar la sesión por «{exception}»", + "unknown_group": "Grupo «{group}» desconocido", + "unknown_user": "Usuario «{user}» desconocido", "values_mismatch": "Los valores no coinciden", "warning": "Advertencia:", "websocket_request_expected": "Se esperaba una petición WebSocket", - "cannot_open_file": "No se pudo abrir el fichero{file:s} (motivo:{error:s})", - "cannot_write_file": "No se pudo escribir el fichero {file:s} (motivo: {error:s})", - "unknown_error_reading_file": "Error desconocido al intentar leer el fichero {file:s} (motivo: {error:s})", - "corrupted_json": "Json corrupto leido desde {ressource:s} (motivo: {error:s})", - "error_writing_file": "Error al escribir el fichero {file:s}: {error:s}", + "cannot_open_file": "No se pudo abrir el archivo {file:s} (motivo: {error:s})", + "cannot_write_file": "No se pudo escribir el archivo {file:s} (motivo: {error:s})", + "unknown_error_reading_file": "Error desconocido al intentar leer el archivo {file:s} (motivo: {error:s})", + "corrupted_json": "Lectura corrupta de Json desde {ressource:s} (motivo: {error:s})", + "error_writing_file": "Error al escribir el archivo {file:s}: {error:s}", "error_removing": "Error al eliminar {path:s}: {error:s}", "error_changing_file_permissions": "Error al cambiar los permisos para {path:s}: {error:s}", - "invalid_url": "Url no válida {url:s} (¿existe este sitio web?)", + "invalid_url": "Url no válida {url:s} (¿Existe este sitio?)", "download_ssl_error": "Error SSL al conectar con {url:s}", - "download_timeout": "{url:s} tardó demasiado en responder, me rindo.", + "download_timeout": "{url:s} tardó demasiado en responder, abandono.", "download_unknown_error": "Error al descargar datos desde {url:s} : {error:s}", "download_bad_status_code": "{url:s} devolvió el código de estado {code:s}", - "command_unknown": "Comando '{command:s}' desconocido ?", - "corrupted_yaml": "yaml corrupto leido desde {ressource:s} (motivo: {error:s})", - "info": "Información:" + "command_unknown": "¿Orden «{command:s}» desconocida?", + "corrupted_yaml": "Lectura corrupta de yaml desde {ressource:s} (motivo: {error:s})", + "info": "Información:", + "corrupted_toml": "Lectura corrupta de TOML desde {ressource:s} (motivo: {error:s})", + "warn_the_user_that_lock_is_acquired": "la otra orden ha terminado, iniciando esta orden ahora", + "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" } From b5ef442a4466622fe64667f6b1ef3b279c73fdb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20D=C3=B6ring?= Date: Sun, 22 Sep 2019 09:35:41 +0000 Subject: [PATCH 15/19] Translated using Weblate (German) Currently translated at 67.9% (38 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/de/ --- locales/de.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/locales/de.json b/locales/de.json index 70b6dab9..455eb05d 100644 --- a/locales/de.json +++ b/locales/de.json @@ -11,7 +11,7 @@ "file_not_exist": "Datei ist nicht vorhanden: '{path}'", "folder_exists": "Ordner existiert bereits: '{path}'", "folder_not_exist": "Ordner existiert nicht", - "instance_already_running": "Eine Instanz läuft bereits", + "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_password": "Passwort falsch", "invalid_usage": "Falscher Aufruf, verwende --help für den Hilfstext", @@ -29,12 +29,13 @@ "server_already_running": "Einen anderer Dienst arbeitet bereits auf diesem Port", "success": "Erfolg!", "unable_authenticate": "Anmelden fehlgeschlagen", - "unable_retrieve_session": "Sitzung konnte nicht abgerufen werden", + "unable_retrieve_session": "Sitzung konnte nicht abgerufen werden. Grund: '{exception}'", "values_mismatch": "Die Werte passen nicht", "warning": "Warnung:", "websocket_request_expected": "Eine WebSocket Anfrage wurde erwartet", "deprecated_command": "'{prog} {command}' ist veraltet und wird bald entfernt werden", "deprecated_command_alias": "'{prog} {old}' ist veraltet und wird bald entfernt werden, benutze '{prog} {new}' stattdessen", "unknown_group": "Gruppe '{group}' ist unbekannt", - "unknown_user": "Benutzer '{user}' ist unbekannt" + "unknown_user": "Benutzer '{user}' ist unbekannt", + "info": "Info:" } From cdda60a18b0886bac01eec132708a1210f2f27ae Mon Sep 17 00:00:00 2001 From: advocatux Date: Fri, 20 Sep 2019 21:02:17 +0000 Subject: [PATCH 16/19] Translated using Weblate (Spanish) Currently translated at 100.0% (56 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/es/ --- locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index b6310882..947555bc 100644 --- a/locales/es.json +++ b/locales/es.json @@ -13,7 +13,7 @@ "file_not_exist": "El archivo no existe: «{path}»", "folder_exists": "El directorio ya existe: «{path}»", "folder_not_exist": "La carpeta no existe", - "instance_already_running": "Una instancia ya se está ejecutando", + "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_password": "Contraseña no válida", "invalid_usage": "Uso no válido, utilice --help para ver la ayuda", From bd5eeb4ca351e813dbc92a0cad4b59002e7838f8 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Wed, 25 Sep 2019 07:01:05 +0000 Subject: [PATCH 17/19] Translated using Weblate (French) Currently translated at 100.0% (56 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/fr/ --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index 8ea6537e..732eaa0e 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -13,7 +13,7 @@ "file_not_exist": "Le fichier '{path}' n’existe pas", "folder_exists": "Le dossier existe déjà : '{path}'", "folder_not_exist": "Le dossier n’existe pas", - "instance_already_running": "Une instance est déjà en cours d’exécution", + "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_password": "Mot de passe incorrect", "invalid_usage": "Utilisation erronée, utilisez --help pour accéder à l’aide", From b9370c683924009da9b0c2f1759ffa5119a17fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Thu, 26 Sep 2019 06:53:30 +0000 Subject: [PATCH 18/19] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 32.1% (18 of 56 strings) Translation: YunoHost/moulinette Translate-URL: https://translate.yunohost.org/projects/yunohost/moulinette/nb_NO/ --- locales/nb_NO.json | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/locales/nb_NO.json b/locales/nb_NO.json index 0967ef42..a6260cac 100644 --- a/locales/nb_NO.json +++ b/locales/nb_NO.json @@ -1 +1,22 @@ -{} +{ + "argument_required": "Argumentet '{argument}' er påkrevd", + "warn_the_user_about_waiting_lock_again": "Venter fremdeles…", + "websocket_request_expected": "Forventet en WebSocket-forespørsel", + "warning": "Advarsel:", + "values_mismatch": "Verdiene samsvarer ikke", + "unknown_user": "Ukjent '{group}' bruker", + "unknown_group": "Ukjent '{group}' gruppe", + "unable_authenticate": "Kunne ikke identitetsbekrefte", + "success": "Vellykket.", + "operation_interrupted": "Operasjon forstyrret", + "not_logged_in": "Du er ikke innlogget", + "logged_in": "Innlogget", + "invalid_password": "Ugyldig passord", + "info": "Info:", + "file_exists": "Filen finnes allerede: '{path}'", + "error": "Feil:", + "confirm": "Bekreft {prompt}", + "colon": "{}: ", + "logged_out": "Utlogget", + "password": "Passord" +} From d36fd27d5d44b1083697acf5645f2974fdabb739 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 31 Oct 2019 18:59:24 +0100 Subject: [PATCH 19/19] Update changelog for 3.7.0 testing --- debian/changelog | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/debian/changelog b/debian/changelog index 247b6012..75ad5137 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,27 @@ +moulinette (3.7.0) testing; urgency=low + + # ~ Major stuff + + - [enh] Add group and permission mechanism ([Moulinette#189](https://github.com/YunoHost/moulinette/pull/189) + - [mod] Be able to customize prompt colors ([Moulinette/808f620](https://github.com/YunoHost/Moulinette/commit/808f620)) + - [enh] Support app manifests in toml ([Moulinette#204](https://github.com/YunoHost/moulinette/pull/204), [Moulinette/55515cb](https://github.com/YunoHost/Moulinette/commit/55515cb)) + - [enh] Quite a lot of messages improvements, string cleaning, language rework... ([Moulinette/599bec3](https://github.com/YunoHost/Moulinette/commit/599bec3), [Moulinette#208](https://github.com/YunoHost/moulinette/pull/208), [Moulinette#213](https://github.com/YunoHost/moulinette/pull/213), [Moulinette/b7d415d](https://github.com/YunoHost/Moulinette/commit/b7d415d), [Moulinette/a8966b8](https://github.com/YunoHost/Moulinette/commit/a8966b8), [Moulinette/fdf9a71](https://github.com/YunoHost/Moulinette/commit/fdf9a71), [Moulinette/d895ae3](https://github.com/YunoHost/Moulinette/commit/d895ae3), [Moulinette/bdf0a1c](https://github.com/YunoHost/Moulinette/commit/bdf0a1c)) + - [i18n] Improved translations for Catalan, Occitan, French, Arabic, Spanish, German, Norwegian Bokmål + + # Smaller or pretty technical fix/enh + + - [enh] Preparations for moulinette Python3 migration (Tox, Pytest and unit tests) ([Moulinette#203](https://github.com/YunoHost/moulinette/pull/203), [Moulinette#206](https://github.com/YunoHost/moulinette/pull/206), [Moulinette#207](https://github.com/YunoHost/moulinette/pull/207), [Moulinette#210](https://github.com/YunoHost/moulinette/pull/210), [Moulinette#211](https://github.com/YunoHost/moulinette/pull/211) [Moulinette#212](https://github.com/YunoHost/moulinette/pull/212), [Moulinette/2403ee1](https://github.com/YunoHost/Moulinette/commit/2403ee1), [Moulinette/69b0d49](https://github.com/YunoHost/Moulinette/commit/69b0d49), [Moulinette/49c749c](https://github.com/YunoHost/Moulinette/commit/49c749c), [Moulinette/2c84ee1](https://github.com/YunoHost/Moulinette/commit/2c84ee1), [Moulinette/cef72f7](https://github.com/YunoHost/Moulinette/commit/cef72f7)) + - [enh] Add a write_to_yaml utility similar to write_to_json ([Moulinette/2e2e627](https://github.com/YunoHost/Moulinette/commit/2e2e627)) + - [enh] Warn the user about long locks ([Moulinette#205](https://github.com/YunoHost/moulinette/pull/205)) + - [mod] Tweak stuff about setuptools and moulinette deps? ([Moulinette/b739f27](https://github.com/YunoHost/Moulinette/commit/b739f27), [Moulinette/da00fc9](https://github.com/YunoHost/Moulinette/commit/da00fc9), [Moulinette/d8cbbb0](https://github.com/YunoHost/Moulinette/commit/d8cbbb0)) + - [fix] Misc micro bugfixes or improvements ([Moulinette/83d9e77](https://github.com/YunoHost/Moulinette/commit/83d9e77)) + - [doc] Fix doc building + add doc build tests with Tox ([Moulinette/f1ac5b8](https://github.com/YunoHost/Moulinette/commit/f1ac5b8), [Moulinette/df7d478](https://github.com/YunoHost/Moulinette/commit/df7d478), [Moulinette/74c8f79](https://github.com/YunoHost/Moulinette/commit/74c8f79), [Moulinette/bcf92c7](https://github.com/YunoHost/Moulinette/commit/bcf92c7), [Moulinette/af2c80c](https://github.com/YunoHost/Moulinette/commit/af2c80c), [Moulinette/d52a574](https://github.com/YunoHost/Moulinette/commit/d52a574), [Moulinette/307f660](https://github.com/YunoHost/Moulinette/commit/307f660), [Moulinette/dced104](https://github.com/YunoHost/Moulinette/commit/dced104), [Moulinette/ed3823b](https://github.com/YunoHost/Moulinette/commit/ed3823b)) + - [enh] READMEs improvements ([Moulinette/1541b74](https://github.com/YunoHost/Moulinette/commit/1541b74), [Moulinette/ad1eeef](https://github.com/YunoHost/Moulinette/commit/ad1eeef)) + + Thanks to all contributors <3 ! (accross all repo: Yunohost, Moulinette, SSOwat, Yunohost-admin) : advocatux, Aksel K., Aleks, Allan N., amirale qt, Armin P., Bram, ButterflyOfFire, Carles S. A., chema o. r., decentral1se, Emmanuel V., Etienne M., Filip B., Geoff M., htsr, Jibec, Josué, Julien J., Kayou, liberodark, ljf, lucaskev, Lukas D., madtibo, Martin D., Mélanie C., nr 458 h, pitfd, ppr, Quentí, sidddy, troll, tufek yamero, xaloc33, yalh76 + + -- Alexandre Aubin Thu, 31 Oct 2019 18:40:00 +0000 + moulinette (3.6.4.1) stable; urgency=low - [fix] Catch all exceptions in read_yaml helper