Merge branch 'stretch-unstable' into simplify-auth-mechanism

This commit is contained in:
Alexandre Aubin 2019-11-19 16:55:06 +01:00
commit 9fda7f4716
17 changed files with 242 additions and 61 deletions

View file

@ -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 Moulinette
========== ==========
@ -37,15 +40,10 @@ operation on an interface for example (see
[Authenticators](#authenticators)). [Authenticators](#authenticators)).
### Actions Map Dev Documentation
... -----------------
### Interfaces
...
### Authenticators
...
https://moulinette.readthedocs.org
Requirements Requirements
------------ ------------

24
debian/changelog vendored
View file

@ -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 <alex.aubin@mailoo.org> Thu, 31 Oct 2019 18:40:00 +0000
moulinette (3.6.4.1) stable; urgency=low moulinette (3.6.4.1) stable; urgency=low
- [fix] Catch all exceptions in read_yaml helper - [fix] Catch all exceptions in read_yaml helper

View file

@ -31,7 +31,7 @@
"server_already_running": "هناك خادم يشتغل على ذاك المنفذ", "server_already_running": "هناك خادم يشتغل على ذاك المنفذ",
"success": "تم بنجاح !", "success": "تم بنجاح !",
"unable_authenticate": "تعذرت المصادقة", "unable_authenticate": "تعذرت المصادقة",
"unable_retrieve_session": "تعذرت مواصلة الجلسة", "unable_retrieve_session": "تعذرت مواصلة الجلسة بسبب '{exception}'",
"unknown_group": "الفريق '{group}' مجهول", "unknown_group": "الفريق '{group}' مجهول",
"unknown_user": "المستخدم '{user}' مجهول", "unknown_user": "المستخدم '{user}' مجهول",
"values_mismatch": "القيمتين غير متطابقتين", "values_mismatch": "القيمتين غير متطابقتين",
@ -39,7 +39,7 @@
"websocket_request_expected": "كان ينتظر طلبًا عبر الويب سوكت WebSocket", "websocket_request_expected": "كان ينتظر طلبًا عبر الويب سوكت WebSocket",
"cannot_open_file": "ليس بالإمكان فتح الملف {file:s} (السبب : {error:s})", "cannot_open_file": "ليس بالإمكان فتح الملف {file:s} (السبب : {error:s})",
"cannot_write_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})", "corrupted_json": "قراءة json مُشوّهة مِن {ressource:s} (السبب : {error:s})",
"error_writing_file": "طرأ هناك خطأ أثناء الكتابة في الملف {file:s}: {error:s}", "error_writing_file": "طرأ هناك خطأ أثناء الكتابة في الملف {file:s}: {error:s}",
"error_removing": "خطأ أثناء عملية حذف {path:s}: {error:s}", "error_removing": "خطأ أثناء عملية حذف {path:s}: {error:s}",
@ -49,7 +49,8 @@
"download_timeout": "{url:s} استغرق مدة طويلة جدا للإستجابة، فتوقّف.", "download_timeout": "{url:s} استغرق مدة طويلة جدا للإستجابة، فتوقّف.",
"download_unknown_error": "خطأ أثناء عملية تنزيل البيانات مِن {url:s} : {error:s}", "download_unknown_error": "خطأ أثناء عملية تنزيل البيانات مِن {url:s} : {error:s}",
"download_bad_status_code": "{url:s} أعاد رمز الحالة {code:s}", "download_bad_status_code": "{url:s} أعاد رمز الحالة {code:s}",
"command_unknown": "الأمر '{command:s}' غير معروف ؟", "command_unknown": "الأمر '{command:s}' مجهول؟",
"corrupted_yaml": "قراءة مُشوّهة لنسق yaml مِن {ressource:s} (السبب : {error:s})", "corrupted_yaml": "قراءة مُشوّهة لنسق yaml مِن {ressource:s} (السبب : {error:s})",
"info": "معلومة:" "info": "معلومة:",
"warn_the_user_about_waiting_lock_again": "جارٍ الانتظار…"
} }

View file

@ -31,7 +31,7 @@
"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ó", "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",
@ -39,7 +39,7 @@
"websocket_request_expected": "S'esperava una petició WebSocket", "websocket_request_expected": "S'esperava una petició WebSocket",
"cannot_open_file": "No s'ha pogut obrir el fitxer {file:s} (motiu: {error:s})", "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})", "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_json": "Json corrupte llegit des de {ressource:s} (motiu: {error:s})",
"corrupted_yaml": "Yaml 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}", "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_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}", "download_bad_status_code": "{url:s} ha retornat el codi d'estat {code:s}",
"command_unknown": "Ordre '{command:s}' desconegut ?", "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"
} }

View file

@ -11,7 +11,7 @@
"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}'",
"folder_not_exist": "Ordner existiert nicht", "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_argument": "Argument ungültig '{argument}': {error}",
"invalid_password": "Passwort falsch", "invalid_password": "Passwort falsch",
"invalid_usage": "Falscher Aufruf, verwende --help für den Hilfstext", "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", "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", "unable_retrieve_session": "Sitzung konnte nicht abgerufen werden. Grund: '{exception}'",
"values_mismatch": "Die Werte passen nicht", "values_mismatch": "Die Werte passen nicht",
"warning": "Warnung:", "warning": "Warnung:",
"websocket_request_expected": "Eine WebSocket Anfrage wurde erwartet", "websocket_request_expected": "Eine WebSocket Anfrage wurde erwartet",
"deprecated_command": "'{prog} {command}' ist veraltet und wird bald entfernt werden", "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", "deprecated_command_alias": "'{prog} {old}' ist veraltet und wird bald entfernt werden, benutze '{prog} {new}' stattdessen",
"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:"
} }

View file

@ -13,7 +13,7 @@
"folder_exists": "Folder already exists: '{path}'", "folder_exists": "Folder already exists: '{path}'",
"folder_not_exist": "Folder does not exist", "folder_not_exist": "Folder does not exist",
"info": "Info:", "info": "Info:",
"instance_already_running": "An instance is already running", "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_argument": "Invalid argument '{argument}': {error}",
"invalid_password": "Invalid password", "invalid_password": "Invalid password",
"invalid_token": "Invalid token - please authenticate", "invalid_token": "Invalid token - please authenticate",

View file

@ -1,23 +1,23 @@
{ {
"argument_required": "Se requiere el argumento '{argument}'", "argument_required": "Se requiere el argumento «{argument}»",
"authentication_profile_required": "Autenticación requerida para el perfil '{profile}'", "authentication_profile_required": "Autentificación requerida para el perfil «{profile}»",
"authentication_required": "Se requiere autentificación", "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": "{}: ", "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",
"error": "Error:", "error": "Error:",
"error_see_log": "Ha ocurrido un error. Consulte el registro para obtener más información, localizado en /var/log/yunohost/.", "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_exists": "El archivo ya existe: «{path}»",
"file_not_exist": "El archivo no existe: '{path}'", "file_not_exist": "El archivo no existe: «{path}»",
"folder_exists": "El directorio ya existe: '{path}'", "folder_exists": "El directorio ya existe: «{path}»",
"folder_not_exist": "El directorio no existe", "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_argument": "Argumento no válido «{argument}»: {error}",
"invalid_password": "Contraseña no válida", "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_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_operation_error": "Ha ocurrido un error durante la operación de LDAP",
"ldap_server_down": "No se pudo conectar con el servidor LDAP", "ldap_server_down": "No se pudo conectar con el servidor LDAP",
"logged_in": "Sesión iniciada", "logged_in": "Sesión iniciada",
@ -30,26 +30,30 @@
"root_required": "Solo root puede realizar esta acción", "root_required": "Solo root puede realizar esta acción",
"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 autenticar", "unable_authenticate": "No se puede autentificar",
"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_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",
"warning": "Advertencia:", "warning": "Advertencia:",
"websocket_request_expected": "Se esperaba una petición WebSocket", "websocket_request_expected": "Se esperaba una petición WebSocket",
"cannot_open_file": "No se pudo abrir el fichero{file:s} (motivo:{error:s})", "cannot_open_file": "No se pudo abrir el archivo {file:s} (motivo: {error:s})",
"cannot_write_file": "No se pudo escribir el fichero {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 fichero {file:s}", "unknown_error_reading_file": "Error desconocido al intentar leer el archivo {file:s} (motivo: {error:s})",
"corrupted_json": "Json corrupto leido desde {ressource:s} (motivo: {error:s})", "corrupted_json": "Lectura corrupta de Json desde {ressource:s} (motivo: {error:s})",
"error_writing_file": "Error al escribir el fichero {file:s}: {error:s}", "error_writing_file": "Error al escribir el archivo {file:s}: {error:s}",
"error_removing": "Error al eliminar {path: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}", "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_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_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}", "download_bad_status_code": "{url:s} devolvió el código de estado {code:s}",
"command_unknown": "Comando '{command:s}' desconocido ?", "command_unknown": "¿Orden «{command:s}» desconocida?",
"corrupted_yaml": "yaml corrupto leido desde {ressource:s} (motivo: {error:s})", "corrupted_yaml": "Lectura corrupta de yaml desde {ressource:s} (motivo: {error:s})",
"info": "Información:" "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"
} }

View file

@ -13,7 +13,7 @@
"file_not_exist": "Le fichier '{path}' nexiste pas", "file_not_exist": "Le fichier '{path}' nexiste pas",
"folder_exists": "Le dossier existe déjà : '{path}'", "folder_exists": "Le dossier existe déjà : '{path}'",
"folder_not_exist": "Le dossier nexiste pas", "folder_not_exist": "Le dossier nexiste pas",
"instance_already_running": "Une instance est déjà en cours dexécution", "instance_already_running": "Une instance est déjà en cours dexé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_password": "Mot de passe incorrect",
"invalid_usage": "Utilisation erronée, utilisez --help pour accéder à laide", "invalid_usage": "Utilisation erronée, utilisez --help pour accéder à laide",
@ -52,8 +52,8 @@
"command_unknown": "Commande '{command:s}' inconnue ?", "command_unknown": "Commande '{command:s}' inconnue ?",
"corrupted_yaml": "Fichier YAML corrompu en lecture depuis {ressource:s} (raison : {error:s})", "corrupted_yaml": "Fichier YAML corrompu en lecture depuis {ressource:s} (raison : {error:s})",
"info": "Info :", "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": "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": "l'autre commande vient de se terminer, lancement de cette commande" "warn_the_user_that_lock_is_acquired": "l'autre commande vient de se terminer, lancement de cette commande"
} }

View file

@ -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"
}

View file

@ -24,7 +24,7 @@
"pattern_not_match": "Correspond pas al patron", "pattern_not_match": "Correspond pas al patron",
"permission_denied": "Permission refusada", "permission_denied": "Permission refusada",
"root_required": "Cal èsser root per realizar aquesta accion", "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_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",
@ -39,7 +39,7 @@
"websocket_request_expected": "Una requèsta WebSocket èra esperada", "websocket_request_expected": "Una requèsta WebSocket èra esperada",
"cannot_open_file": "Impossible de dobrir lo fichièr {file:s} (rason: {error:s})", "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})", "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_writing_file": "Error en escriure lo fichièr {file:s}: {error:s}",
"error_removing": "Error en suprimir {path: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}", "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 desperar.", "download_timeout": "{url:s} a trigat per respondre, avèm quitat desperar.",
"download_unknown_error": "Error en telecargar de donadas de {url:s}: {error:s}", "download_unknown_error": "Error en telecargar de donadas de {url:s}: {error:s}",
"download_bad_status_code": "{url:s} tòrna lo còdi destat {code:s}", "download_bad_status_code": "{url:s} tòrna lo còdi destat {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_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})", "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 quacabe abans daviar aquesta daquí",
"warn_the_user_about_waiting_lock_again": "Encara en espèra…",
"warn_the_user_that_lock_is_acquired": "lautra comanda ven dacabar, lançament daquesta comanda"
} }

View file

@ -96,7 +96,7 @@ class CommentParameter(_ExtraParameter):
def validate(klass, value, arg_name): def validate(klass, value, arg_name):
# Deprecated boolean or empty string # Deprecated boolean or empty string
if isinstance(value, bool) or (isinstance(value, str) and not value): 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) "argument '%s'", klass.name, arg_name)
value = arg_name value = arg_name
elif not isinstance(value, str): elif not isinstance(value, str):
@ -131,7 +131,7 @@ class AskParameter(_ExtraParameter):
def validate(klass, value, arg_name): def validate(klass, value, arg_name):
# Deprecated boolean or empty string # Deprecated boolean or empty string
if isinstance(value, bool) or (isinstance(value, str) and not value): 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) "argument '%s'", klass.name, arg_name)
value = arg_name value = arg_name
elif not isinstance(value, str): elif not isinstance(value, str):
@ -199,7 +199,7 @@ class PatternParameter(_ExtraParameter):
def validate(value, arg_name): def validate(value, arg_name):
# Deprecated string type # Deprecated string type
if isinstance(value, str): 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) "argument '%s'", arg_name)
value = [value, 'pattern_not_match'] value = [value, 'pattern_not_match']
elif not isinstance(value, list) or len(value) != 2: elif not isinstance(value, list) or len(value) != 2:

View file

@ -305,7 +305,7 @@ class MoulinetteSignals(object):
return authenticator return authenticator
return self._authenticate(authenticator) return self._authenticate(authenticator)
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 for a value
Prompt the interface for a parameter value which is a password Prompt the interface for a parameter value which is a password
@ -318,12 +318,13 @@ class MoulinetteSignals(object):
- message -- The message to display - message -- The message to display
- is_password -- True if the parameter is a password - is_password -- True if the parameter is a password
- confirm -- True if the value must be confirmed - confirm -- True if the value must be confirmed
- color -- Color to use for the prompt ...
Returns: Returns:
The collected value 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'): def display(self, message, style='info'):
"""Display a message """Display a message

View file

@ -12,9 +12,10 @@ class JSONExtendedEncoder(JSONEncoder):
"""Extended JSON encoder """Extended JSON encoder
Extend default JSON encoder to recognize more types and classes. It Extend default JSON encoder to recognize more types and classes. It will
will never raise if the object can't be encoded and return its repr never raise an exception if the object can't be encoded and return its repr
instead. instead.
The following objects and types are supported: The following objects and types are supported:
- set: converted into list - set: converted into list

View file

@ -10,7 +10,7 @@ def search(pattern, text, count=0, flags=0):
"""Search for pattern in a text """Search for pattern in a text
Scan through text looking for all locations where the regular 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 The optional argument count is the maximum number of pattern
occurences to return; count must be an integer. If omitted or zero, occurences to return; count must be an integer. If omitted or zero,

87
test/test_actionsmap.py Normal file
View file

@ -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)

14
test/test_serialize.py Normal file
View file

@ -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

21
test/test_text.py Normal file
View file

@ -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)