mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
Merge branch 'stretch-unstable' into simplify-auth-mechanism
This commit is contained in:
commit
9fda7f4716
17 changed files with 242 additions and 61 deletions
14
README.md
14
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
|
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
24
debian/changelog
vendored
|
@ -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
|
||||||
|
|
|
@ -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": "جارٍ الانتظار…"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
"file_not_exist": "Le fichier '{path}' n’existe 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}'",
|
||||||
"folder_not_exist": "Le dossier n’existe pas",
|
"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_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 à l’aide",
|
"invalid_usage": "Utilisation erronée, utilisez --help pour accéder à l’aide",
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
|
|
@ -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 d’esperar.",
|
"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_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}",
|
"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_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 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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
87
test/test_actionsmap.py
Normal 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
14
test/test_serialize.py
Normal 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
21
test/test_text.py
Normal 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)
|
Loading…
Reference in a new issue