1
0
Fork 0
mirror of https://github.com/YunoHost/apps.git synced 2024-09-03 20:06:07 +02:00

appgenerator: rework css using tailwind + misc cleanup, wording (#2259)

* appgenerator: rework css using tailwind + misc cleanup, wording

* appgenerator: tweak gettext + update translations (at least fr)

* appgenerator: bump version idk
This commit is contained in:
Alexandre Aubin 2024-04-30 22:54:07 +02:00 committed by GitHub
parent 70d851dc76
commit 826639058e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1432 additions and 832 deletions

View file

@ -16,7 +16,6 @@ from markupsafe import Markup # No longer imported from Flask
# Form libraries
from flask_wtf import FlaskForm
from flask_bootstrap import Bootstrap
from wtforms import (
StringField,
RadioField,
@ -37,7 +36,7 @@ from wtforms.validators import (
# Translations
from flask_babel import Babel
from flask_babel import gettext, lazy_gettext
from flask_babel import lazy_gettext as _
from flask import redirect, request, make_response # Language swap by redirecting
@ -51,12 +50,11 @@ from urllib import parse
from secrets import token_urlsafe
#### GLOBAL VARIABLES
YOLOGEN_VERSION = "0.9.2.1"
YOLOGEN_VERSION = "0.10"
GENERATOR_DICT = {"GENERATOR_VERSION": YOLOGEN_VERSION}
#### Create FLASK and Jinja Environments
app = Flask(__name__)
Bootstrap(app)
app.config["SECRET_KEY"] = token_urlsafe(16) # Necessary for the form CORS
cors = CORS(app)
@ -67,7 +65,7 @@ BABEL_TRANSLATION_DIRECTORIES = "translations"
babel = Babel()
LANGUAGES = {"en": gettext("English"), "fr": gettext("French")}
LANGUAGES = {"en": _("English"), "fr": _("French")}
@app.context_processor
@ -126,7 +124,7 @@ def markdown_file_to_html_string(file):
# Use it in the HTML with {{ form_field(main_form.generator_language) }}
class Translations(FlaskForm):
generator_language = SelectField(
gettext("Select language"),
_("Select language"),
choices=[("none", "")] + [language for language in LANGUAGES.items()],
default=["en"],
id="selectLanguage",
@ -136,8 +134,8 @@ class Translations(FlaskForm):
class GeneralInfos(FlaskForm):
app_id = StringField(
Markup(lazy_gettext("Application identifier (id)")),
description=lazy_gettext("Small caps and without spaces"),
Markup(_("Application identifier (id)")),
description=_("Small caps and without spaces"),
validators=[DataRequired(), Regexp("[a-z_1-9]+.*(?<!_ynh)$")],
render_kw={
"placeholder": "my_super_app",
@ -145,8 +143,8 @@ class GeneralInfos(FlaskForm):
)
app_name = StringField(
lazy_gettext("App name"),
description=lazy_gettext(
_("App name"),
description=_(
"It's the application name, displayed in the user interface"
),
validators=[DataRequired()],
@ -156,15 +154,15 @@ class GeneralInfos(FlaskForm):
)
description_en = StringField(
lazy_gettext("Short description (en)"),
description=lazy_gettext(
_("Short description (en)"),
description=_(
"Explain in a few words (10-15) why this app is useful or what it does (the goal is to give a broad idea for the user browsing an hundred apps long catalog"
),
validators=[DataRequired()],
)
description_fr = StringField(
lazy_gettext("Description courte (fr)"),
description=lazy_gettext(
_("Short description (fr)"),
description=_(
"Explain in a few words (10-15) why this app is useful or what it does (the goal is to give a broad idea for the user browsing an hundred apps long catalog"
),
validators=[DataRequired()],
@ -175,21 +173,21 @@ class IntegrationInfos(FlaskForm):
# TODO : people shouldnt have to put the ~ynh1 ? This should be added automatically when rendering the app files ?
version = StringField(
lazy_gettext("Version"),
_("Version"),
validators=[Regexp("\d{1,4}.\d{1,4}(.\d{1,4})?(.\d{1,4})?~ynh\d+")],
render_kw={"placeholder": "1.0~ynh1"},
)
maintainers = StringField(
lazy_gettext("Maintener of the generated app"),
description=lazy_gettext(
"Commonly you put your name here... If you agree with it ;)"
_("Maintainer of the generated app"),
description=_(
"Usually you put your name here... If you're okay with it ;)"
),
)
yunohost_required_version = StringField(
lazy_gettext("Minimal YunoHost version"),
description=lazy_gettext(
_("Minimal YunoHost version"),
description=_(
"Minimal YunoHost version for the application to work"
),
render_kw={
@ -198,9 +196,9 @@ class IntegrationInfos(FlaskForm):
)
architectures = SelectMultipleField(
lazy_gettext("Supported architectures"),
_("Supported architectures"),
choices=[
("all", lazy_gettext("All architectures")),
("all", _("All architectures")),
("amd64", "amd64"),
("i386", "i386"),
("armhf", "armhf"),
@ -211,34 +209,34 @@ class IntegrationInfos(FlaskForm):
)
multi_instance = BooleanField(
lazy_gettext(
_(
"The app can be installed multiple times at the same time on the same server"
),
default=True,
)
ldap = SelectField(
lazy_gettext("The app will be integrating LDAP"),
description=lazy_gettext(
"Which means it's possible to use Yunohost credential to connect. 'LDAP' corresponds to the technology used by Yunohost to handle a centralised user base. Bridging the APP and Yunohost LDAP often requires to fill some parameters in the app configuration"
_("The app will be integrating LDAP"),
description=_(
"Which means it's possible to use Yunohost credentials to log into this app. 'LDAP' corresponds to the technology used by Yunohost to handle a centralised user base. Bridging the app and Yunohost's LDAP often requires to add the proper technical details in the app's configuration file"
),
choices=[
("false", lazy_gettext("No")),
("true", lazy_gettext("Yes")),
("not_relevant", lazy_gettext("Not relevant")),
("false", _("No")),
("true", _("Yes")),
("not_relevant", _("Not relevant")),
],
default="not_relevant",
validators=[DataRequired()],
)
sso = SelectField(
lazy_gettext("The app will be integrated in Yunohost SSO (Single Sign On)"),
description=lazy_gettext(
"Which means that one connexion to Yunohost unlock the connexion to the software, without having to sign on specificaly into it. One only has to connect once (Single Sign On)"
_("The app will be integrated in Yunohost SSO (Single Sign On)"),
description=_(
"Which means that people will be logged in the app after logging in YunoHost's portal, without having to sign on specifically into this app."
),
choices=[
("false", lazy_gettext("Yes")),
("true", lazy_gettext("No")),
("not_relevant", lazy_gettext("Not relevant")),
("false", _("Yes")),
("true", _("No")),
("not_relevant", _("Not relevant")),
],
default="not_relevant",
validators=[DataRequired()],
@ -248,47 +246,47 @@ class IntegrationInfos(FlaskForm):
class UpstreamInfos(FlaskForm):
license = StringField(
lazy_gettext("Licence"),
description=lazy_gettext(
_("Licence"),
description=_(
"You should check this on the upstream repository. The expected format is a SPDX id listed in https://spdx.org/licenses/"
),
validators=[DataRequired()],
)
website = StringField(
lazy_gettext("Official website"),
description=lazy_gettext("Leave empty if there is no official website"),
_("Official website"),
description=_("Leave empty if there is no official website"),
validators=[URL(), Optional()],
render_kw={
"placeholder": "https://awesome-app-website.com",
},
)
demo = StringField(
lazy_gettext("Official app demo"),
description=lazy_gettext("Leave empty if there is no official demo"),
_("Official app demo"),
description=_("Leave empty if there is no official demo"),
validators=[URL(), Optional()],
render_kw={
"placeholder": "https://awesome-app-website.com/demo",
},
)
admindoc = StringField(
lazy_gettext("Admin documentation"),
description=lazy_gettext("Leave empty if there is no official admin doc"),
_("Admin documentation"),
description=_("Leave empty if there is no official admin doc"),
validators=[URL(), Optional()],
render_kw={
"placeholder": "https://awesome-app-website.com/doc/admin",
},
)
userdoc = StringField(
lazy_gettext("Usage documentation"),
description=lazy_gettext("Leave empty if there is no official user doc"),
_("Usage documentation"),
description=_("Leave empty if there is no official user doc"),
validators=[URL(), Optional()],
render_kw={
"placeholder": "https://awesome-app-website.com/doc/user",
},
)
code = StringField(
lazy_gettext("Code repository"),
_("Code repository"),
validators=[URL(), DataRequired()],
render_kw={
"placeholder": "https://some.git.forge/org/app",
@ -299,51 +297,51 @@ class UpstreamInfos(FlaskForm):
class InstallQuestions(FlaskForm):
domain_and_path = SelectField(
lazy_gettext(
_(
"Ask the URL where the app will be installed ('domain' and 'path' variables)"
),
default="true",
choices=[
("true", lazy_gettext("Ask domain+path")),
("true", _("Ask domain+path")),
(
"full_domain",
lazy_gettext(
_(
"Ask only the domain (the app requires to be installed at the root of a dedicated domain)"
),
),
("false", lazy_gettext("Do not ask (it isn't a webapp)")),
("false", _("Do not ask (it isn't a webapp)")),
],
)
init_main_permission = BooleanField(
lazy_gettext("Ask who can access to the app"),
description=lazy_gettext(
_("Ask who can access to the app"),
description=_(
"In the users groups : by default at least 'visitors', 'all_users' et 'admins' exists. (It was previously the private/public app concept)"
),
default=True,
)
init_admin_permission = BooleanField(
lazy_gettext("Ask who can access to the admin interface"),
description=lazy_gettext("In the case where the app has an admin interface"),
_("Ask who can access to the admin interface"),
description=_("In the case where the app has an admin interface"),
default=False,
)
language = SelectMultipleField(
lazy_gettext("Supported languages"),
_("Supported languages"),
choices=[
("_", lazy_gettext("None / not relevant")),
("en", lazy_gettext("English")),
("fr", lazy_gettext("Français")),
("en", lazy_gettext("Spanish")),
("it", lazy_gettext("Italian")),
("de", lazy_gettext("German")),
("zh", lazy_gettext("Chinese")),
("jp", lazy_gettext("Japanese")),
("da", lazy_gettext("Danish")),
("pt", lazy_gettext("Portugese")),
("nl", lazy_gettext("Dutch")),
("ru", lazy_gettext("Russian")),
("_", _("None / not relevant")),
("en", _("English")),
("fr", _("French")),
("en", _("Spanish")),
("it", _("Italian")),
("de", _("German")),
("zh", _("Chinese")),
("jp", _("Japanese")),
("da", _("Danish")),
("pt", _("Portugese")),
("nl", _("Dutch")),
("ru", _("Russian")),
],
default=["_"],
validators=[DataRequired()],
@ -355,14 +353,14 @@ class Ressources(FlaskForm):
# Sources
source_url = StringField(
lazy_gettext("Application source code or executable"),
_("Application source code or executable"),
validators=[DataRequired(), URL()],
render_kw={
"placeholder": "https://github.com/foo/bar/archive/refs/tags/v1.2.3.tar.gz",
},
)
sha256sum = StringField(
lazy_gettext("Sources sha256 checksum"),
_("Sources sha256 checksum"),
validators=[DataRequired(), Length(min=64, max=64)],
render_kw={
"placeholder": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
@ -370,9 +368,9 @@ class Ressources(FlaskForm):
)
auto_update = SelectField(
lazy_gettext("Activate the automated source update bot"),
description=lazy_gettext(
"If the software is available in one of the handled sources and publish releases or tags for its new updates, or for each new commit, a bot will provide an update with updated URL and checksum"
_("Enable automatic update of sources (using a bot running every night)"),
description=_(
"If the upstream software is hosted in one of the handled sources and publishes proper releases or tags, the bot will create a pull request to update the sources URL and checksum"
),
default="none",
choices=[
@ -393,8 +391,8 @@ class Ressources(FlaskForm):
)
apt_dependencies = StringField(
lazy_gettext(
"Dependances to be installed via apt (separated by a quote and/or spaces)"
_(
"Dependencies to be installed via apt (separated by comma and/or spaces)"
),
render_kw={
"placeholder": "foo, bar2.1-ext, libwat",
@ -402,7 +400,7 @@ class Ressources(FlaskForm):
)
database = SelectField(
lazy_gettext("Initialise a SQL database"),
_("Initialize an SQL database"),
choices=[
("false", "Non"),
("mysql", "MySQL/MariaDB"),
@ -412,19 +410,19 @@ class Ressources(FlaskForm):
)
system_user = BooleanField(
lazy_gettext("Initialise a system user for this app"),
_("Initialize a system user for this app"),
default=True,
)
install_dir = BooleanField(
lazy_gettext("Initialise an installation folder for this app"),
description=lazy_gettext("By default it's /var/www/$app"),
_("Initialize an installation folder for this app"),
description=_("By default it's /var/www/$app"),
default=True,
)
data_dir = BooleanField(
lazy_gettext("Initialise a folder to store the app data"),
description=lazy_gettext("By default it's /var/yunohost.app/$app"),
_("Initialize a folder to store the app data"),
description=_("By default it's /var/yunohost.app/$app"),
default=False,
)
@ -432,22 +430,22 @@ class Ressources(FlaskForm):
class SpecificTechnology(FlaskForm):
main_technology = SelectField(
lazy_gettext("App main technology"),
_("App main technology"),
choices=[
("none", lazy_gettext("None / Static application")),
("none", _("None / Static application")),
("php", "PHP"),
("nodejs", "NodeJS"),
("python", "Python"),
("ruby", "Ruby"),
("other", lazy_gettext("Other")),
("other", _("Other")),
],
default="none",
validators=[DataRequired()],
)
install_snippet = TextAreaField(
lazy_gettext("Installation specific commands"),
description=lazy_gettext(
_("Installation specific commands"),
description=_(
"These commands are executed from the app installation folder (by default, /var/www/$app) after the sources have been deployed. This field uses by default a classic example based on the selected technology. You should probably compare and adapt it according to the app installation documentation"
),
validators=[Optional()],
@ -459,8 +457,8 @@ class SpecificTechnology(FlaskForm):
#
use_composer = BooleanField(
lazy_gettext("Use composer"),
description=lazy_gettext(
_("Use composer"),
description=_(
"Composer is a PHP dependencies manager used by some apps"
),
default=False,
@ -471,23 +469,23 @@ class SpecificTechnology(FlaskForm):
#
nodejs_version = StringField(
lazy_gettext("NodeJS version"),
description=lazy_gettext("For example: 16.4, 18, 18.2, 20, 20.1, ..."),
_("NodeJS version"),
description=_("For example: 16.4, 18, 18.2, 20, 20.1, ..."),
render_kw={
"placeholder": "20",
},
)
use_yarn = BooleanField(
lazy_gettext("Install and use Yarn"),
_("Install and use Yarn"),
default=False,
)
# NodeJS / Python / Ruby / ...
systemd_execstart = StringField(
lazy_gettext("Command to start the app daemon (from systemd service)"),
description=lazy_gettext(
_("Command to start the app daemon (from systemd service)"),
description=_(
"Corresponds to 'ExecStart' statement in systemd. You can use '__INSTALL_DIR__' to refer to the install directory, or '__APP__' to refer to the app id"
),
render_kw={
@ -499,15 +497,15 @@ class SpecificTechnology(FlaskForm):
class AppConfig(FlaskForm):
use_custom_config_file = BooleanField(
lazy_gettext("The app uses a specific configuration file"),
description=lazy_gettext(
_("The app uses a specific configuration file"),
description=_(
"Usually : .env, config.json, conf.ini, params.yml, ..."
),
default=False,
)
custom_config_file = StringField(
lazy_gettext("Name or file path to use"),
_("Name or file path to use"),
validators=[Optional()],
render_kw={
"placeholder": "config.json",
@ -515,8 +513,8 @@ class AppConfig(FlaskForm):
)
custom_config_file_content = TextAreaField(
lazy_gettext("App configuration file pattern"),
description=lazy_gettext(
_("App configuration file pattern"),
description=_(
"In this pattern, you can use the syntax __FOO_BAR__ which will automatically replaced by the value of the variable $foo_bar"
),
validators=[Optional()],
@ -528,54 +526,52 @@ class Documentation(FlaskForm):
# TODO : # screenshot
description = TextAreaField(
Markup(
lazy_gettext(
"""Type the content of DESCRIPTION.md file. <br> \
Do not give the software name at the beginning, as it will be integrated an 'Overview' subpart"""
_(
"""doc/DESCRIPTION.md: A comprehensive presentation of the app, possibly listing the main features, possible warnings and specific details on its functioning in Yunohost (e.g. warning about integration issues)."""
)
),
validators=[Optional()],
render_kw={
"class": "form-control",
"spellcheck": "false",
},
)
pre_install = TextAreaField(
lazy_gettext("Type the PRE_INSTALL.md file content"),
_("doc/PRE_INSTALL.md: important info to be shown to the admin before installing the app"),
description=_("Leave empty if not relevant"),
validators=[Optional()],
render_kw={
"class": "form-control",
"spellcheck": "false",
},
)
post_install = TextAreaField(
lazy_gettext("Type the POST_INSTALL.md file content"),
_("doc/POST_INSTALL.md: important info to be shown to the admin after installing the app"),
description=_("Leave empty if not relevant"),
validators=[Optional()],
render_kw={
"class": "form-control",
"spellcheck": "false",
},
)
pre_upgrade = TextAreaField(
lazy_gettext("Type the PRE_UPGRADE.md file content"),
_("doc/PRE_UPGRADE.md: important info to be shown to the admin before upgrading the app"),
description=_("Leave empty if not relevant"),
validators=[Optional()],
render_kw={
"class": "form-control",
"spellcheck": "false",
},
)
post_upgrade = TextAreaField(
lazy_gettext("Type the POST_UPGRADE.md file content"),
_("doc/POST_UPGRADE.md: important info to be shown to the admin after upgrading the app"),
description=_("Leave empty if not relevant"),
validators=[Optional()],
render_kw={
"class": "form-control",
"spellcheck": "false",
},
)
admin = TextAreaField(
lazy_gettext("Type the ADMIN.md file content"),
_("doc/ADMIN.md: general tips on how to administrate this app"),
description=_("Leave empty if not relevant"),
validators=[Optional()],
render_kw={
"class": "form-control",
"spellcheck": "false",
},
)
@ -584,20 +580,20 @@ Do not give the software name at the beginning, as it will be integrated an 'Ove
class MoreAdvanced(FlaskForm):
enable_change_url = BooleanField(
lazy_gettext("Handle app install URL change (change_url script)"),
_("Handle app install URL change (change_url script)"),
default=True,
render_kw={
"title": lazy_gettext(
"title": _(
"Should changing the app URL be allowed ? (change_url change)"
)
},
)
use_logrotate = BooleanField(
lazy_gettext("Use logrotate for the app logs"),
_("Use logrotate for the app logs"),
default=True,
render_kw={
"title": lazy_gettext(
"title": _(
"If the app generates logs, this option permit to handle their archival. Recommended."
)
},
@ -605,23 +601,23 @@ class MoreAdvanced(FlaskForm):
# TODO : specify custom log file
# custom_log_file = "/var/log/$app/$app.log" "/var/log/nginx/${domain}-error.log"
use_fail2ban = BooleanField(
lazy_gettext(
_(
"Protect the application against brute force attacks (via fail2ban)"
),
default=False,
render_kw={
"title": lazy_gettext(
"title": _(
"If the app generates failed connexions logs, this option allows to automatically banish the related IP after a certain number of failed password tries. Recommended."
)
},
)
use_cron = BooleanField(
lazy_gettext("Add a CRON task for this application"),
description=lazy_gettext("Corresponds to some app periodic operations"),
_("Add a CRON task for this application"),
description=_("Corresponds to some app periodic operations"),
default=False,
)
cron_config_file = TextAreaField(
lazy_gettext("Type the CRON file content"),
_("Type the CRON file content"),
validators=[Optional()],
render_kw={
"class": "form-control",
@ -630,13 +626,13 @@ class MoreAdvanced(FlaskForm):
)
fail2ban_regex = StringField(
lazy_gettext("Regular expression for fail2ban"),
_("Regular expression for fail2ban"),
# Regex to match into the log for a failed login
validators=[Optional()],
render_kw={
"placeholder": lazy_gettext("A regular expression"),
"placeholder": _("A regular expression"),
"class": "form-control",
"title": lazy_gettext(
"title": _(
"Regular expression to check in the log file to activate failban (search for a line that indicates a credentials error)."
),
},
@ -660,25 +656,25 @@ class GeneratorForm(
csrf = False
generator_mode = SelectField(
lazy_gettext("Generator mode"),
description=lazy_gettext(
_("Generator mode"),
description=_(
"In tutorial version, the generated app will contain additionnal comments to ease the understanding. In steamlined version, the generated app will only contain the necessary minimum."
),
choices=[
("simple", lazy_gettext("Streamlined version")),
("tutorial", lazy_gettext("Tutorial version")),
("simple", _("Streamlined version")),
("tutorial", _("Tutorial version")),
],
default="true",
validators=[DataRequired()],
)
submit_preview = SubmitField(lazy_gettext("Previsualise"))
submit_download = SubmitField(lazy_gettext("Download the .zip"))
submit_preview = SubmitField(_("Previsualise"))
submit_download = SubmitField(_("Download the .zip"))
submit_demo = SubmitField(
lazy_gettext("Fill with demo values"),
_("Fill with demo values"),
render_kw={
"onclick": "fillFormWithDefaultValues()",
"title": lazy_gettext(
"title": _(
"Generate a complete and functionnal minimalistic app that you can iterate from"
),
},

View file

@ -4,7 +4,6 @@ click==8.1.7
dominate==2.8.0
Flask==3.0.0
flask_babel~=4.0.0
Flask-Bootstrap==3.3.7.1
Flask-Cors==4.0.0
Flask-Misaka==1.0.0
Flask-WTF==1.2.1

View file

@ -0,0 +1,6 @@
# Download standalone tailwind to compile what we need
wget https://github.com/tailwindlabs/tailwindcss/releases/download/v3.3.3/tailwindcss-linux-x64
chmod +x tailwindcss-linux-x64
./tailwindcss-linux-x64 --input tailwind-local.css --output tailwind.css --minify

View file

@ -1,45 +0,0 @@
.form-horizontal .form-group {
margin-left: 0;
margin-right: 0;
}
h2 {
font-weight: bold;
font-size: 1.3em !important;
}
.checkbox {
margin-bottom: 15px !important;
}
.checkbox label {
font-weight: bold;
}
.active, .collapse-button:hover {
background-color: #318ddc;
}
.collapse-title:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}
.expanded .collapse-title::after {
content: "\2212";
}
.collapsed {
padding: 0px 15px 0px 15px;
}
.collapsible {
max-height: 0px;
overflow: hidden;
transition: max-height 0.2s ease-out;
}

View file

@ -0,0 +1,105 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer utilities {
body {
@apply text-gray-800;
}
h1 {
@apply text-2xl font-bold;
}
h2 {
@apply text-xl font-bold;
}
h3 {
@apply text-lg font-bold;
}
.hide {
display: none;
}
.btn {
@apply text-sm font-medium rounded-md px-4 py-2 transition bg-gray-200 m-1;
}
.btn-sm {
@apply text-xs font-medium rounded-md px-2 py-2 transition;
}
.btn-success {
@apply text-white bg-green-500 hover:bg-green-700;
}
.btn-primary {
@apply text-white bg-blue-500 hover:bg-blue-700;
}
.btn-link {
@apply bg-gray-400 hover:bg-gray-200;
}
.panel {
@apply block rounded-lg border border-gray-400 mb-2;
}
.panel-heading {
@apply text-white bg-blue-500 hover:bg-blue-700 p-2 font-bold;
}
.panel-body {
@apply p-2;
}
.alert-info {
@apply text-blue-900 border-blue-900 bg-blue-200 rounded-lg p-4;
}
.active, .collapse-button:hover {
background-color: #318ddc;
}
.collapse-title:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}
.expanded .collapse-title::after {
content: "\2212";
}
.collapsed {
padding: 0px 15px 0px 15px;
}
.collapsible {
max-height: 0px;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
label {
@apply font-bold;
}
input {
@apply rounded-lg;
}
.form-group, .checkbox {
@apply px-2 py-4;
}
.form-control {
@apply block w-full rounded-md border-gray-300;
}
.help-block {
@apply text-gray-500 text-sm;
}
.tip {
@apply italic p-2;
}
}

View file

@ -0,0 +1,17 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['../templates/*.html'],
theme: {
extend: {},
},
plugins: [
require('@tailwindcss/forms'),
],
safelist: [
'safelisted',
{
pattern: /^(text-[a-z]+-600|border-[a-z]+-400)$/,
},
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ gettext("YunoHost app generator") }}</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{ url_for('static', filename='fork-awesome.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='tailwind.css') }}">
</head>
<body>
<main class="my-2 mx-auto max-w-screen-md">
{% block main -%}
{%- endblock main %}
</main>
</body>
</html>

View file

@ -1,4 +1,4 @@
{% import "bootstrap/wtf.html" as wtf %}
{% import "wtf.html" as wtf %}
{% macro form_field(field,
form_type="basic",
@ -19,64 +19,38 @@
{% endmacro %}
{% extends "bootstrap/base.html" %}
{% extends "base.html" %}
{% block title %}
YunoHost app generator
{% endblock %}
{% block styles %}
{{super()}}
<link rel="stylesheet" href="{{url_for('.static', filename='stylesheet.css')}}">
{% endblock %}
{% block content %}
<div class="container" style="max-width: 800px;">
<h1 class="message text-center">{{ gettext("Yunohost application generation form") }}</h1>
<p style="text-align: center">Version: {{ generator_info['GENERATOR_VERSION'] }}</p>
<!--
<script>/*
document.addEventListener('DOMContentLoaded', function() {
var selectField = document.getElementById('selectLanguage');
selectField.addEventListener('change', function() {
var lang = this.value;
// alert("Switching to language: "+ this.value);
if (lang != 'none') {
var url = window.location.href; // Get current URL
var newURL = url + '/language/' + lang
window.location.href = newURL
}
});
});
</script> -->
<script>
function changeLanguage(lang) {
var url = "{{ url_for('set_language', language=lang) }}" + lang;
window.location.href = url;
}
</script>
<div style="text-align:center">
{% for lang in AVAILABLE_LANGUAGES.items() %}
<button type="button" onclick="changeLanguage('{{ lang[0] }}')">{{ lang[1] }}</button>
{% endfor %}
{% block main %}
<div class="mx-auto w-full text-center p-8">
<img alt="YunoHost application logo" src="{{ url_for('static', filename='yunohost-package.png') }}" class="w-32 mx-auto">
<h1 class="text-2xl font-bold">
{{ _("Yunohost application generation form") }}
</h1>
<p>Version: {{ generator_info['GENERATOR_VERSION'] }}</p>
<script>
function changeLanguage(lang) {
var url = "{{ url_for('set_language', language=lang) }}" + lang;
window.location.href = url;
}
</script>
<div>
{% for lang in AVAILABLE_LANGUAGES.items() %}
<button class="btn btn-sm bg-gray-200" type="button" onclick="changeLanguage('{{ lang[0] }}')">{{ lang[1] }}</button>
{% endfor %}
</div>
</div>
<form method="POST" role="form">
<form id="main-form" class="form form-horizontal" method="POST" role="form">
{{ main_form.hidden_tag() }}
<div style="color: red;">
<div class="text-red-800">
{{ wtf.form_errors(main_form, hiddens="only") }}
</div>
{{ form_field(main_form.generator_mode) }}
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h2 class="panel-title collapse-title">{{ gettext("1/9 - General information") }}</h2>
</div>
@ -91,12 +65,12 @@ function changeLanguage(lang) {
</div>
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h2 class="panel-title collapse-title">{{ gettext("2/9 - Informations about the application") }}</h2>
<h2 class="panel-title collapse-title">{{ gettext("2/9 - Upstream information") }}</h2>
</div>
<div class="panel-body collapsible collapsed">
<p><i>{{ gettext("The word upstream refers to the original project that maintains the app") }}</i></p>
<p class="tip">{{ gettext("The word 'upstream' refers to the original project that develops and maintains the app") }}</p>
<div>
{{ form_field(main_form.license) }}
{{ form_field(main_form.website) }}
@ -109,7 +83,7 @@ function changeLanguage(lang) {
</div>
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h2 class="panel-title collapse-title">{{ gettext("3/9 - Integration in YunoHost") }}</h2>
</div>
@ -125,15 +99,15 @@ function changeLanguage(lang) {
</div>
</div>
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h2 class="panel-title collapse-title">{{ gettext("4/9 - Questions to ask during installation") }}</h2>
</div>
<div class="panel-body collapsible collapsed">
<p>
<em>{{ gettext("This part is meant to indicate the questions that will be asked.") }}</em>
<p class="tip">
{{ gettext("This part is meant to indicate the questions that will be asked.") }}
<br/>
<em>{{ gettext("NB: only standard questions are asked here, it might be required to complete it by hand using other questions as a guide.") }}</em>
{{ gettext("NB: only standard questions are asked here, it might be required to complete it by hand using other questions as a guide.") }}
</p>
<div>
@ -145,17 +119,17 @@ function changeLanguage(lang) {
</div>
</div>
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h2 class="panel-title collapse-title">{{ gettext("5/9 - Ressources to initialise") }}</h2>
<h2 class="panel-title collapse-title">{{ gettext("5/9 - Resources to initialize") }}</h2>
</div>
<div class="panel-body collapsible collapsed">
<p>
<em>{{ gettext("Technical elements configured before launching the 'real' app install script. Usually : creating a system user, downloading app sources, initialiser le dossier d'install et de données, install apt dependencies, create a database, ...") }}</em>
<p class="tip">
{{ gettext("Technical elements configured before launching the 'real' app install script. Usually : creating a system user, downloading app sources, initialiser le dossier d'install et de données, install apt dependencies, create a database, ...") }}
</p>
<h3>Sources du logiciel</h3>
<div style="margin-left: 2em;">
<div class="pl-2">
{{ form_field(main_form.source_url) }}
{{ form_field(main_form.sha256sum) }}
{{ form_field(main_form.auto_update) }}
@ -172,7 +146,7 @@ function changeLanguage(lang) {
</div>
</div>
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h2 class="panel-title collapse-title">{{ gettext("6/9 - Specific technology") }}</h2>
</div>
@ -197,8 +171,14 @@ function changeLanguage(lang) {
</div>
</div>
<script>
let main_technology = document.getElementById("main_technology");
let install_snippet = document.getElementById("install_snippet");
let systemd_execstart = document.getElementById("systemd_execstart");
install_snippet.classList.add("font-mono");
systemd_execstart.classList.add("font-mono");
function update_main_technology()
{
document.getElementById("php_options").classList.add("hide");
@ -252,7 +232,7 @@ function changeLanguage(lang) {
</script>
</div>
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h2 class="panel-title collapse-title">{{ gettext("7/9 - App configuration") }}</h2>
</div>
@ -276,26 +256,21 @@ function changeLanguage(lang) {
</script>
</div>
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h2 class="panel-title collapse-title">{{ gettext("8/9 - General and advanced documentation") }}</h2>
</div>
<div class="panel-body collapsible collapsed">
<p><i>{{ gettext("A more complete presentation that the summary completed above, explaining to what correspond the software, the eventual warnings and specific details on its functioning in Yunohost (it's the place where one can warn about integration issues).") }}</i></p>
{{ form_field(main_form.description) }}
<p><i>{{ gettext("Indications to show at key steps to manage the package : installation, update, message to the admin account. You usually don't have to fill them.") }}</i></p>
{{ form_field(main_form.pre_install) }}
{{ form_field(main_form.post_install) }}
{{ form_field(main_form.pre_upgrade) }}
{{ form_field(main_form.post_upgrade) }}
{{ form_field(main_form.admin) }}
</div>
</div>
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h2 class="panel-title collapse-title">{{ gettext("9/9 - Advanced options") }}</h2>
</div>
@ -313,6 +288,8 @@ function changeLanguage(lang) {
<p class="text-center">
{{ main_form.submit_preview(class="btn btn-primary") }}
{{ main_form.submit_download(class="btn btn-primary") }}
<br/>
{{ main_form.submit_demo(class="btn") }}
</p>
<!-- Submit button for demo values-->
@ -332,32 +309,27 @@ function changeLanguage(lang) {
document.getElementById('source_url').value = "https://github.com/YunoHost/example_ynh/archive/1235ae57a3a285a4024d028d860f56980fa5ed19.tar.gz"
document.getElementById('sha256sum').value = "471ff03ae251812d3d042fb7e9206c812de5bf07bd4ac4c95763278702eff30a" }
</script>
<p class="text-center">
{{ main_form.submit_demo(class="btn btn-primary") }}
</p>
</form>
</div>
</form>
<hr>
<hr class="my-2" />
{% if generated_files %}
<h2>Code généré</h1>
<div>
<h2 class="text-center">Code généré</h2>
{% for file in generated_files %}
<div class="panel panel-primary">
<div class="panel">
<div class="panel-heading collapse-button">
<h3 class="panel-title collapse-title">{{ file.destination_path }}</h3>
</div>
<div class="panel-body collapsible collapsed" style="padding: 0;">
<pre style="margin:0;">{{ file.content }}</pre>
<div class="panel-body collapsible collapsed p-0">
<pre class="m-0">{{ file.content }}</pre>
</div>
</div>
{% endfor %}
{% endif %}
</div>
{% endif %}
<script>
var coll = document.getElementsByClassName("collapse-button");

View file

@ -0,0 +1,213 @@
{% macro form_errors(form, hiddens=True) %}
{%- if form.errors %}
{%- for fieldname, errors in form.errors.items() %}
{%- if bootstrap_is_hidden_field(form[fieldname]) and hiddens or
not bootstrap_is_hidden_field(form[fieldname]) and hiddens != 'only' %}
{%- for error in errors %}
<p class="error">{{error}}</p>
{%- endfor %}
{%- endif %}
{%- endfor %}
{%- endif %}
{%- endmacro %}
{% macro _hz_form_wrap(horizontal_columns, form_type, add_group=False, required=False) %}
{% if form_type == "horizontal" %}
{% if add_group %}<div class="form-group{% if required %} required{% endif %}">{% endif %}
<div class="col-{{horizontal_columns[0]}}-offset-{{horizontal_columns[1]}}
col-{{horizontal_columns[0]}}-{{horizontal_columns[2]}}
">
{% endif %}
{{caller()}}
{% if form_type == "horizontal" %}
{% if add_group %}</div>{% endif %}
</div>
{% endif %}
{% endmacro %}
{% macro form_field(field,
form_type="basic",
horizontal_columns=('lg', 2, 10),
button_map={}) %}
{# this is a workaround hack for the more straightforward-code of just passing required=required parameter. older versions of wtforms do not have
the necessary fix for required=False attributes, but will also not set the required flag in the first place. we skirt the issue using the code below #}
{% if field.flags.required and not required in kwargs %}
{% set kwargs = dict(required=True, **kwargs) %}
{% endif %}
{% if field.widget.input_type == 'checkbox' %}
{% call _hz_form_wrap(horizontal_columns, form_type, True, required=required) %}
<div class="checkbox">
<label>
{{field()|safe}} {{field.label.text|safe}}
</label>
</div>
{% endcall %}
{%- elif field.type == 'RadioField' -%}
{# note: A cleaner solution would be rendering depending on the widget,
this is just a hack for now, until I can think of something better #}
{% call _hz_form_wrap(horizontal_columns, form_type, True, required=required) %}
{% for item in field -%}
<div class="radio">
<label>
{{item|safe}} {{item.label.text|safe}}
</label>
</div>
{% endfor %}
{% endcall %}
{%- elif field.type == 'SubmitField' -%}
{# deal with jinja scoping issues? #}
{% set field_kwargs = kwargs %}
{# note: same issue as above - should check widget, not field type #}
{% call _hz_form_wrap(horizontal_columns, form_type, True, required=required) %}
{{field(class='btn btn-%s' % button_map.get(field.name, 'default'),
**field_kwargs)}}
{% endcall %}
{%- elif field.type == 'FormField' -%}
{# note: FormFields are tricky to get right and complex setups requiring
these are probably beyond the scope of what this macro tries to do.
the code below ensures that things don't break horribly if we run into
one, but does not try too hard to get things pretty. #}
<fieldset>
<legend>{{field.label}}</legend>
{%- for subfield in field %}
{% if not bootstrap_is_hidden_field(subfield) -%}
{{ form_field(subfield,
form_type=form_type,
horizontal_columns=horizontal_columns,
button_map=button_map) }}
{%- endif %}
{%- endfor %}
</fieldset>
{% else -%}
<div class="form-group {% if field.errors %} has-error{% endif -%}
{%- if field.flags.required %} required{% endif -%}
">
{%- if form_type == "inline" %}
{{field.label(class="sr-only")|safe}}
{% if field.type == 'FileField' %}
{{field(**kwargs)|safe}}
{% else %}
{{field(class="form-control", **kwargs)|safe}}
{% endif %}
{% elif form_type == "horizontal" %}
{{field.label(class="control-label " + (
" col-%s-%s" % horizontal_columns[0:2]
))|safe}}
<div class=" col-{{horizontal_columns[0]}}-{{horizontal_columns[2]}}">
{% if field.type == 'FileField' %}
{{field(**kwargs)|safe}}
{% else %}
{{field(class="form-control", **kwargs)|safe}}
{% endif %}
</div>
{%- if field.errors %}
{%- for error in field.errors %}
{% call _hz_form_wrap(horizontal_columns, form_type, required=required) %}
<p class="help-block">{{error}}</p>
{% endcall %}
{%- endfor %}
{%- elif field.description -%}
{% call _hz_form_wrap(horizontal_columns, form_type, required=required) %}
<p class="help-block">{{field.description|safe}}</p>
{% endcall %}
{%- endif %}
{%- else -%}
{{field.label(class="control-label")|safe}}
{% if field.type == 'FileField' %}
{{field(**kwargs)|safe}}
{% else %}
{{field(class="form-control", **kwargs)|safe}}
{% endif %}
{%- if field.errors %}
{%- for error in field.errors %}
<p class="help-block">{{error}}</p>
{%- endfor %}
{%- elif field.description -%}
<p class="help-block">{{field.description|safe}}</p>
{%- endif %}
{%- endif %}
</div>
{% endif %}
{% endmacro %}
{# valid form types are "basic", "inline" and "horizontal" #}
{% macro quick_form(form,
action="",
method="post",
extra_classes=None,
role="form",
form_type="basic",
horizontal_columns=('lg', 2, 10),
enctype=None,
button_map={},
id="",
novalidate=False) %}
{#-
action="" is what we want, from http://www.ietf.org/rfc/rfc2396.txt:
4.2. Same-document References
A URI reference that does not contain a URI is a reference to the
current document. In other words, an empty URI reference within a
document is interpreted as a reference to the start of that document,
and a reference containing only a fragment identifier is a reference
to the identified fragment of that document. Traversal of such a
reference should not result in an additional retrieval action.
However, if the URI reference occurs in a context that is always
intended to result in a new request, as in the case of HTML's FORM
element, then an empty URI reference represents the base URI of the
current document and should be replaced by that URI when transformed
into a request.
-#}
{#- if any file fields are inside the form and enctype is automatic, adjust
if file fields are found. could really use the equalto test of jinja2
here, but latter is not available until 2.8
warning: the code below is guaranteed to make you cry =(
#}
{%- set _enctype = [] %}
{%- if enctype is none -%}
{%- for field in form %}
{%- if field.type == 'FileField' %}
{#- for loops come with a fairly watertight scope, so this list-hack is
used to be able to set values outside of it #}
{%- set _ = _enctype.append('multipart/form-data') -%}
{%- endif %}
{%- endfor %}
{%- else %}
{% set _ = _enctype.append(enctype) %}
{%- endif %}
<form
{%- if action != None %} action="{{action}}"{% endif -%}
{%- if id %} id="{{id}}"{% endif -%}
{%- if method %} method="{{method}}"{% endif %}
class="form
{%- if extra_classes %} {{extra_classes}}{% endif -%}
{%- if form_type == "horizontal" %} form-horizontal
{%- elif form_type == "inline" %} form-inline
{%- endif -%}
"
{%- if _enctype[0] %} enctype="{{_enctype[0]}}"{% endif -%}
{%- if role %} role="{{role}}"{% endif -%}
{%- if novalidate %} novalidate{% endif -%}
>
{{ form.hidden_tag() }}
{{ form_errors(form, hiddens='only') }}
{%- for field in form %}
{% if not bootstrap_is_hidden_field(field) -%}
{{ form_field(field,
form_type=form_type,
horizontal_columns=horizontal_columns,
button_map=button_map) }}
{%- endif %}
{%- endfor %}
</form>
{%- endmacro %}

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-03-31 22:46+0200\n"
"POT-Creation-Date: 2024-04-26 15:39+0200\n"
"PO-Revision-Date: 2024-03-31 20:23+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
@ -16,304 +16,312 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.10.3\n"
"Generated-By: Babel 2.14.0\n"
#: YunohostAppGenerator.py:119
#: app.py:68 app.py:334
msgid "English"
msgstr ""
#: app.py:68 app.py:335
msgid "French"
msgstr ""
#: app.py:127
msgid "Select language"
msgstr ""
#: app.py:137
msgid "Application identifier (id)"
msgstr ""
#: YunohostAppGenerator.py:121
#: app.py:138
msgid "Small caps and without spaces"
msgstr ""
#: YunohostAppGenerator.py:129
#: app.py:146
msgid "App name"
msgstr ""
#: YunohostAppGenerator.py:130
#: app.py:147
msgid "It's the application name, displayed in the user interface"
msgstr ""
#: YunohostAppGenerator.py:138
#: app.py:157
msgid "Short description (en)"
msgstr ""
#: YunohostAppGenerator.py:139
#: app.py:158 app.py:165
msgid ""
"Explain in a few words (10-15) why this app is useful or what it does "
"(the goal is to give a broad idea for the user browsing an hundred apps "
"long catalog"
msgstr ""
#: YunohostAppGenerator.py:143
msgid "Description courte (fr)"
#: app.py:164
msgid "Short description (fr)"
msgstr ""
#: YunohostAppGenerator.py:159
msgid "Maintener of the generated app"
#: app.py:176
msgid "Version"
msgstr ""
#: YunohostAppGenerator.py:160
msgid "Commonly you put your name here... If you agree with it ;)"
#: app.py:182
msgid "Maintainer of the generated app"
msgstr ""
#: YunohostAppGenerator.py:164
#: app.py:183
msgid "Usually you put your name here... If you're okay with it ;)"
msgstr ""
#: app.py:189
msgid "Minimal YunoHost version"
msgstr ""
#: YunohostAppGenerator.py:165
#: app.py:190
msgid "Minimal YunoHost version for the application to work"
msgstr ""
#: YunohostAppGenerator.py:172
#: app.py:199
msgid "Supported architectures"
msgstr ""
#: YunohostAppGenerator.py:174
#: app.py:201
msgid "All architectures"
msgstr ""
#: YunohostAppGenerator.py:185
#: app.py:212
msgid ""
"The app can be installed multiple times at the same time on the same "
"server"
msgstr ""
#: YunohostAppGenerator.py:190
#: app.py:219
msgid "The app will be integrating LDAP"
msgstr ""
#: YunohostAppGenerator.py:191
#: app.py:220
msgid ""
"Which means it's possible to use Yunohost credential to connect. 'LDAP' "
"corresponds to the technology used by Yunohost to handle a centralised "
"user base. Bridging the APP and Yunohost LDAP often requires to fill some"
" parameters in the app configuration"
"Which means it's possible to use Yunohost credentials to log into this "
"app. 'LDAP' corresponds to the technology used by Yunohost to handle a "
"centralised user base. Bridging the app and Yunohost's LDAP often "
"requires to add the proper technical details in the app's configuration "
"file"
msgstr ""
#: YunohostAppGenerator.py:193 YunohostAppGenerator.py:205
#: app.py:224 app.py:238
msgid "No"
msgstr ""
#: YunohostAppGenerator.py:194 YunohostAppGenerator.py:204
#: app.py:225 app.py:237
msgid "Yes"
msgstr ""
#: YunohostAppGenerator.py:195 YunohostAppGenerator.py:206
#: app.py:226 app.py:239
msgid "Not relevant"
msgstr ""
#: YunohostAppGenerator.py:201
#: app.py:232
msgid "The app will be integrated in Yunohost SSO (Single Sign On)"
msgstr ""
#: YunohostAppGenerator.py:202
#: app.py:233
msgid ""
"Which means that one connexion to Yunohost unlock the connexion to the "
"software, without having to sign on specificaly into it. One only has to "
"connect once (Single Sign On)"
"Which means that people will be logged in the app after logging in "
"YunoHost's portal, without having to sign on specifically into this app."
msgstr ""
#: YunohostAppGenerator.py:216
#: app.py:249
msgid "Licence"
msgstr ""
#: YunohostAppGenerator.py:217
#: app.py:250
msgid ""
"You should check this on the upstream repository. The expected format is "
"a SPDX id listed in https://spdx.org/licenses/"
msgstr ""
#: YunohostAppGenerator.py:222
#: app.py:257
msgid "Official website"
msgstr ""
#: YunohostAppGenerator.py:223
#: app.py:258
msgid "Leave empty if there is no official website"
msgstr ""
#: YunohostAppGenerator.py:230
#: app.py:265
msgid "Official app demo"
msgstr ""
#: YunohostAppGenerator.py:231
#: app.py:266
msgid "Leave empty if there is no official demo"
msgstr ""
#: YunohostAppGenerator.py:238
#: app.py:273
msgid "Admin documentation"
msgstr ""
#: YunohostAppGenerator.py:239
#: app.py:274
msgid "Leave empty if there is no official admin doc"
msgstr ""
#: YunohostAppGenerator.py:246
#: app.py:281
msgid "Usage documentation"
msgstr ""
#: YunohostAppGenerator.py:247
#: app.py:282
msgid "Leave empty if there is no official user doc"
msgstr ""
#: YunohostAppGenerator.py:254
#: app.py:289
msgid "Code repository"
msgstr ""
#: YunohostAppGenerator.py:264
#: app.py:300
msgid ""
"Ask the URL where the app will be installed ('domain' and 'path' "
"variables)"
msgstr ""
#: YunohostAppGenerator.py:267
#: app.py:305
msgid "Ask domain+path"
msgstr ""
#: YunohostAppGenerator.py:268
#: app.py:308
msgid ""
"Ask only the domain (the app requires to be installed at the root of a "
"dedicated domain)"
msgstr ""
#: YunohostAppGenerator.py:269
#: app.py:312
msgid "Do not ask (it isn't a webapp)"
msgstr ""
#: YunohostAppGenerator.py:274
#: app.py:317
msgid "Ask who can access to the app"
msgstr ""
#: YunohostAppGenerator.py:275
#: app.py:318
msgid ""
"In the users groups : by default at least 'visitors', 'all_users' et "
"'admins' exists. (It was previously the private/public app concept)"
msgstr ""
#: YunohostAppGenerator.py:280
#: app.py:325
msgid "Ask who can access to the admin interface"
msgstr ""
#: YunohostAppGenerator.py:281
#: app.py:326
msgid "In the case where the app has an admin interface"
msgstr ""
#: YunohostAppGenerator.py:286
#: app.py:331
msgid "Supported languages"
msgstr ""
#: YunohostAppGenerator.py:288
#: app.py:333
msgid "None / not relevant"
msgstr ""
#: YunohostAppGenerator.py:289
msgid "English"
msgstr ""
#: YunohostAppGenerator.py:290
msgid "Français"
msgstr ""
#: YunohostAppGenerator.py:291
#: app.py:336
msgid "Spanish"
msgstr ""
#: YunohostAppGenerator.py:292
#: app.py:337
msgid "Italian"
msgstr ""
#: YunohostAppGenerator.py:293
#: app.py:338
msgid "German"
msgstr ""
#: YunohostAppGenerator.py:294
#: app.py:339
msgid "Chinese"
msgstr ""
#: YunohostAppGenerator.py:295
#: app.py:340
msgid "Japanese"
msgstr ""
#: YunohostAppGenerator.py:296
#: app.py:341
msgid "Danish"
msgstr ""
#: YunohostAppGenerator.py:297
#: app.py:342
msgid "Portugese"
msgstr ""
#: YunohostAppGenerator.py:298
#: app.py:343
msgid "Dutch"
msgstr ""
#: YunohostAppGenerator.py:299
#: app.py:344
msgid "Russian"
msgstr ""
#: YunohostAppGenerator.py:313
#: app.py:356
msgid "Application source code or executable"
msgstr ""
#: YunohostAppGenerator.py:320
#: app.py:363
msgid "Sources sha256 checksum"
msgstr ""
#: YunohostAppGenerator.py:328
msgid "Activate the automated source update bot"
#: app.py:371
msgid "Enable automatic update of sources (using a bot running every night)"
msgstr ""
#: YunohostAppGenerator.py:329
#: app.py:372
msgid ""
"If the software is available in one of the handled sources and publish "
"releases or tags for its new updates, or for each new commit, a bot will "
"provide an update with updated URL and checksum"
"If the upstream software is hosted in one of the handled sources and "
"publishes proper releases or tags, the bot will create a pull request to "
"update the sources URL and checksum"
msgstr ""
#: YunohostAppGenerator.py:349
msgid "Dependances to be installed via apt (separated by a quote and/or spaces)"
#: app.py:394
msgid "Dependencies to be installed via apt (separated by comma and/or spaces)"
msgstr ""
#: YunohostAppGenerator.py:356
msgid "Initialise a SQL database"
#: app.py:403
msgid "Initialize an SQL database"
msgstr ""
#: YunohostAppGenerator.py:366
msgid "Initialise a system user for this app"
#: app.py:413
msgid "Initialize a system user for this app"
msgstr ""
#: YunohostAppGenerator.py:371
msgid "Initialise an installation folder for this app"
#: app.py:418
msgid "Initialize an installation folder for this app"
msgstr ""
#: YunohostAppGenerator.py:372
#: app.py:419
msgid "By default it's /var/www/$app"
msgstr ""
#: YunohostAppGenerator.py:377
msgid "Initialise a folder to store the app data"
#: app.py:424
msgid "Initialize a folder to store the app data"
msgstr ""
#: YunohostAppGenerator.py:378
#: app.py:425
msgid "By default it's /var/yunohost.app/$app"
msgstr ""
#: YunohostAppGenerator.py:386
#: app.py:433
msgid "App main technology"
msgstr ""
#: YunohostAppGenerator.py:388
#: app.py:435
msgid "None / Static application"
msgstr ""
#: YunohostAppGenerator.py:393
#: app.py:440
msgid "Other"
msgstr ""
#: YunohostAppGenerator.py:400
#: app.py:447
msgid "Installation specific commands"
msgstr ""
#: YunohostAppGenerator.py:401
#: app.py:448
msgid ""
"These commands are executed from the app installation folder (by default,"
" /var/www/$app) after the sources have been deployed. This field uses by "
@ -322,222 +330,235 @@ msgid ""
"documentation"
msgstr ""
#: YunohostAppGenerator.py:413
#: app.py:460
msgid "Use composer"
msgstr ""
#: YunohostAppGenerator.py:414
#: app.py:461
msgid "Composer is a PHP dependencies manager used by some apps"
msgstr ""
#: YunohostAppGenerator.py:423
#: app.py:472
msgid "NodeJS version"
msgstr ""
#: YunohostAppGenerator.py:424
#: app.py:473
msgid "For example: 16.4, 18, 18.2, 20, 20.1, ..."
msgstr ""
#: YunohostAppGenerator.py:431
#: app.py:480
msgid "Install and use Yarn"
msgstr ""
#: YunohostAppGenerator.py:438
#: app.py:487
msgid "Command to start the app daemon (from systemd service)"
msgstr ""
#: YunohostAppGenerator.py:439
#: app.py:488
msgid ""
"Corresponds to 'ExecStart' statement in systemd. You can use "
"'__INSTALL_DIR__' to refer to the install directory, or '__APP__' to "
"refer to the app id"
msgstr ""
#: YunohostAppGenerator.py:449
#: app.py:500
msgid "The app uses a specific configuration file"
msgstr ""
#: YunohostAppGenerator.py:450
#: app.py:501
msgid "Usually : .env, config.json, conf.ini, params.yml, ..."
msgstr ""
#: YunohostAppGenerator.py:455
#: app.py:508
msgid "Name or file path to use"
msgstr ""
#: YunohostAppGenerator.py:463
#: app.py:516
msgid "App configuration file pattern"
msgstr ""
#: YunohostAppGenerator.py:464
#: app.py:517
msgid ""
"In this pattern, you can use the syntax __FOO_BAR__ which will "
"automatically replaced by the value of the variable $foo_bar"
msgstr ""
#: YunohostAppGenerator.py:474
#: app.py:529
msgid ""
"Type the content of DESCRIPTION.md file. <br> Do not give the software "
"name at the beginning, as it will be integrated an 'Overview' subpart"
"doc/DESCRIPTION.md: A comprehensive presentation of the app, possibly "
"listing the main features, possible warnings and specific details on its "
"functioning in Yunohost (e.g. warning about integration issues)."
msgstr ""
#: YunohostAppGenerator.py:483
#: app.py:539
msgid ""
"Type the DISCLAIMER.md file content, which list warnings and attention "
"points."
"doc/PRE_INSTALL.md: important info to be shown to the admin before "
"installing the app"
msgstr ""
#: YunohostAppGenerator.py:491
msgid "Type the PRE_INSTALL.md file content"
#: app.py:540 app.py:548 app.py:556 app.py:564 app.py:572
msgid "Leave empty if not relevant"
msgstr ""
#: YunohostAppGenerator.py:499
msgid "Type the POST_INSTALL.md file content"
#: app.py:547
msgid ""
"doc/POST_INSTALL.md: important info to be shown to the admin after "
"installing the app"
msgstr ""
#: YunohostAppGenerator.py:507
msgid "Type the PRE_UPGRADE.md file content"
#: app.py:555
msgid ""
"doc/PRE_UPGRADE.md: important info to be shown to the admin before "
"upgrading the app"
msgstr ""
#: YunohostAppGenerator.py:515
msgid "Type the POST_UPGRADE.md file content"
#: app.py:563
msgid ""
"doc/POST_UPGRADE.md: important info to be shown to the admin after "
"upgrading the app"
msgstr ""
#: YunohostAppGenerator.py:523
msgid "Type the ADMIN.md file content"
#: app.py:571
msgid "doc/ADMIN.md: general tips on how to administrate this app"
msgstr ""
#: YunohostAppGenerator.py:534
#: app.py:583
msgid "Handle app install URL change (change_url script)"
msgstr ""
#: YunohostAppGenerator.py:537
#: app.py:586
msgid "Should changing the app URL be allowed ? (change_url change)"
msgstr ""
#: YunohostAppGenerator.py:542
#: app.py:593
msgid "Use logrotate for the app logs"
msgstr ""
#: YunohostAppGenerator.py:545
#: app.py:596
msgid ""
"If the app generates logs, this option permit to handle their archival. "
"Recommended."
msgstr ""
#: YunohostAppGenerator.py:551
#: app.py:604
msgid "Protect the application against brute force attacks (via fail2ban)"
msgstr ""
#: YunohostAppGenerator.py:554
#: app.py:609
msgid ""
"If the app generates failed connexions logs, this option allows to "
"automatically banish the related IP after a certain number of failed "
"password tries. Recommended."
msgstr ""
#: YunohostAppGenerator.py:558
#: app.py:615
msgid "Add a CRON task for this application"
msgstr ""
#: YunohostAppGenerator.py:559
#: app.py:616
msgid "Corresponds to some app periodic operations"
msgstr ""
#: YunohostAppGenerator.py:563
#: app.py:620
msgid "Type the CRON file content"
msgstr ""
#: YunohostAppGenerator.py:572
#: app.py:629
msgid "Regular expression for fail2ban"
msgstr ""
#: YunohostAppGenerator.py:576
#: app.py:633
msgid "A regular expression"
msgstr ""
#: YunohostAppGenerator.py:578
#: app.py:635
msgid ""
"Regular expression to check in the log file to activate failban (search "
"for a line that indicates a credentials error)."
msgstr ""
#: YunohostAppGenerator.py:592
#: app.py:659
msgid "Generator mode"
msgstr ""
#: YunohostAppGenerator.py:593
#: app.py:660
msgid ""
"In tutorial version, the generated app will contain additionnal comments "
"to ease the understanding. In steamlined version, the generated app will "
"only contain the necessary minimum."
msgstr ""
#: YunohostAppGenerator.py:594
#: app.py:664
msgid "Streamlined version"
msgstr ""
#: YunohostAppGenerator.py:594
#: app.py:665
msgid "Tutorial version"
msgstr ""
#: YunohostAppGenerator.py:599
#: app.py:671
msgid "Previsualise"
msgstr ""
#: YunohostAppGenerator.py:600
#: app.py:672
msgid "Download the .zip"
msgstr ""
#: YunohostAppGenerator.py:601
#: app.py:674
msgid "Fill with demo values"
msgstr ""
#: YunohostAppGenerator.py:602
#: app.py:677
msgid ""
"Generate a complete and functionnal minimalistic app that you can iterate"
" from"
msgstr ""
#: templates/index.html:36
#: templates/base.html:5
msgid "YunoHost app generator"
msgstr ""
#: templates/index.html:28
msgid "Yunohost application generation form"
msgstr ""
#: templates/index.html:50
#: templates/index.html:55
msgid "1/9 - General information"
msgstr ""
#: templates/index.html:65
msgid "2/9 - Informations about the application"
#: templates/index.html:70
msgid "2/9 - Upstream information"
msgstr ""
#: templates/index.html:68
msgid "The word upstream refers to the original project that maintains the app"
#: templates/index.html:73
msgid ""
"The word 'upstream' refers to the original project that develops and "
"maintains the app"
msgstr ""
#: templates/index.html:83
#: templates/index.html:88
msgid "3/9 - Integration in YunoHost"
msgstr ""
#: templates/index.html:99
#: templates/index.html:104
msgid "4/9 - Questions to ask during installation"
msgstr ""
#: templates/index.html:103
#: templates/index.html:108
msgid "This part is meant to indicate the questions that will be asked."
msgstr ""
#: templates/index.html:105
#: templates/index.html:110
msgid ""
"NB: only standard questions are asked here, it might be required to "
"complete it by hand using other questions as a guide."
msgstr ""
#: templates/index.html:119
msgid "5/9 - Ressources to initialise"
#: templates/index.html:124
msgid "5/9 - Resources to initialize"
msgstr ""
#: templates/index.html:123
#: templates/index.html:128
msgid ""
"Technical elements configured before launching the 'real' app install "
"script. Usually : creating a system user, downloading app sources, "
@ -545,60 +566,195 @@ msgid ""
" create a database, ..."
msgstr ""
#: templates/index.html:146
#: templates/index.html:151
msgid "6/9 - Specific technology"
msgstr ""
#: templates/index.html:151
#: templates/index.html:156
msgid ""
"You probably want to make sure to have 'phpX.Y-fpm' and others "
"'phpX.Y-foobar' libraries listed the apt dependencies earlier (with X.Y "
"being the php version you want to use)"
msgstr ""
#: templates/index.html:152
#: templates/index.html:157
msgid ""
"The generated application draft will include an nginx configuration "
"snippet that interfaces with PHP-FPM"
msgstr ""
#: templates/index.html:160
#: templates/index.html:165
msgid ""
"You probably want to make sure to have 'python3' and 'python3-venv' "
"listed in the apt dependencies earlier. Other dependencies should be "
"installed inside a venv (cf the proposed install snippet)"
msgstr ""
#: templates/index.html:164
#: templates/index.html:169
msgid ""
"The generated application draft will include an nginx configuration "
"snippet that reverse-proxies to a systemd service using an internal port"
msgstr ""
#: templates/index.html:226
#: templates/index.html:237
msgid "7/9 - App configuration"
msgstr ""
#: templates/index.html:250
#: templates/index.html:261
msgid "8/9 - General and advanced documentation"
msgstr ""
#: templates/index.html:253
msgid ""
"A more complete presentation that the summary completed above, explaining"
" to what correspond the software, the eventual warnings and specific "
"details on its functioning in Yunohost (it's the place where one can warn"
" about integration issues)."
msgstr ""
#: templates/index.html:257
msgid ""
"Indications to show at key steps to manage the package : installation, "
"update, message to the admin account. You usually don't have to fill "
"them."
msgstr ""
#: templates/index.html:270
#: templates/index.html:275
msgid "9/9 - Advanced options"
msgstr ""
#~ msgid "Maintener of the generated app"
#~ msgstr ""
#~ msgid "Commonly you put your name here... If you agree with it ;)"
#~ msgstr ""
#~ msgid ""
#~ "Which means it's possible to use "
#~ "Yunohost credential to connect. 'LDAP' "
#~ "corresponds to the technology used by"
#~ " Yunohost to handle a centralised "
#~ "user base. Bridging the APP and "
#~ "Yunohost LDAP often requires to fill "
#~ "some parameters in the app configuration"
#~ msgstr ""
#~ msgid ""
#~ "Which means that one connexion to "
#~ "Yunohost unlock the connexion to the "
#~ "software, without having to sign on "
#~ "specificaly into it. One only has "
#~ "to connect once (Single Sign On)"
#~ msgstr ""
#~ msgid "Activate the automated source update bot"
#~ msgstr ""
#~ msgid ""
#~ "If the software is available in "
#~ "one of the handled sources and "
#~ "publish releases or tags for its "
#~ "new updates, or for each new "
#~ "commit, a bot will provide an "
#~ "update with updated URL and checksum"
#~ msgstr ""
#~ msgid ""
#~ "Dependances to be installed via apt "
#~ "(separated by a quote and/or spaces)"
#~ msgstr ""
#~ msgid "Initialise a SQL database"
#~ msgstr ""
#~ msgid "Initialise a system user for this app"
#~ msgstr ""
#~ msgid "Initialise an installation folder for this app"
#~ msgstr ""
#~ msgid "Initialise a folder to store the app data"
#~ msgstr ""
#~ msgid ""
#~ "Type the content of DESCRIPTION.md file."
#~ " <br> Do not give the software "
#~ "name at the beginning, as it will"
#~ " be integrated an 'Overview' subpart"
#~ msgstr ""
#~ msgid ""
#~ "Type the DISCLAIMER.md file content, "
#~ "which list warnings and attention "
#~ "points."
#~ msgstr ""
#~ msgid "Type the PRE_INSTALL.md file content"
#~ msgstr ""
#~ msgid "Type the POST_INSTALL.md file content"
#~ msgstr ""
#~ msgid "Type the PRE_UPGRADE.md file content"
#~ msgstr ""
#~ msgid "Type the POST_UPGRADE.md file content"
#~ msgstr ""
#~ msgid "Type the ADMIN.md file content"
#~ msgstr ""
#~ msgid "2/9 - Informations about the application"
#~ msgstr ""
#~ msgid "The word upstream refers to the original project that maintains the app"
#~ msgstr ""
#~ msgid "5/9 - Ressources to initialise"
#~ msgstr ""
#~ msgid ""
#~ "A more complete presentation that the"
#~ " summary completed above, explaining to "
#~ "what correspond the software, the "
#~ "eventual warnings and specific details "
#~ "on its functioning in Yunohost (it's "
#~ "the place where one can warn about"
#~ " integration issues)."
#~ msgstr ""
#~ msgid ""
#~ "Indications to show at key steps "
#~ "to manage the package : installation,"
#~ " update, message to the admin "
#~ "account. You usually don't have to "
#~ "fill them."
#~ msgstr ""
#~ msgid "Description courte (fr)"
#~ msgstr ""
#~ msgid "Français"
#~ msgstr ""
#~ msgid ""
#~ "doc/DESCRIPTION.md : A comprehensive "
#~ "presentation of the app, possibly "
#~ "listing the main features, possible "
#~ "warnings and specific details on its "
#~ "functioning in Yunohost (e.g. warning "
#~ "about integration issues)."
#~ msgstr ""
#~ msgid ""
#~ "doc/PRE_INSTALL.md : important info to "
#~ "be shown to the admin before "
#~ "installing the app"
#~ msgstr ""
#~ msgid ""
#~ "doc/POST_INSTALL.md : important info to "
#~ "be shown to the admin after "
#~ "installing the app"
#~ msgstr ""
#~ msgid ""
#~ "doc/PRE_UPGRADE.md : important info to "
#~ "be shown to the admin before "
#~ "upgrading the app"
#~ msgstr ""
#~ msgid ""
#~ "doc/POST_UPGRADE.md : important info to "
#~ "be shown to the admin after "
#~ "upgrading the app"
#~ msgstr ""
#~ msgid "doc/ADMIN.md : general tips on how to administrate this app"
#~ msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-03-31 22:46+0200\n"
"POT-Creation-Date: 2024-04-26 15:39+0200\n"
"PO-Revision-Date: 2024-03-31 20:02+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: es\n"
@ -16,304 +16,312 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.10.3\n"
"Generated-By: Babel 2.14.0\n"
#: YunohostAppGenerator.py:119
#: app.py:68 app.py:334
msgid "English"
msgstr ""
#: app.py:68 app.py:335
msgid "French"
msgstr ""
#: app.py:127
msgid "Select language"
msgstr ""
#: app.py:137
msgid "Application identifier (id)"
msgstr ""
#: YunohostAppGenerator.py:121
#: app.py:138
msgid "Small caps and without spaces"
msgstr ""
#: YunohostAppGenerator.py:129
#: app.py:146
msgid "App name"
msgstr ""
#: YunohostAppGenerator.py:130
#: app.py:147
msgid "It's the application name, displayed in the user interface"
msgstr ""
#: YunohostAppGenerator.py:138
#: app.py:157
msgid "Short description (en)"
msgstr ""
#: YunohostAppGenerator.py:139
#: app.py:158 app.py:165
msgid ""
"Explain in a few words (10-15) why this app is useful or what it does "
"(the goal is to give a broad idea for the user browsing an hundred apps "
"long catalog"
msgstr ""
#: YunohostAppGenerator.py:143
msgid "Description courte (fr)"
#: app.py:164
msgid "Short description (fr)"
msgstr ""
#: YunohostAppGenerator.py:159
msgid "Maintener of the generated app"
#: app.py:176
msgid "Version"
msgstr ""
#: YunohostAppGenerator.py:160
msgid "Commonly you put your name here... If you agree with it ;)"
#: app.py:182
msgid "Maintainer of the generated app"
msgstr ""
#: YunohostAppGenerator.py:164
#: app.py:183
msgid "Usually you put your name here... If you're okay with it ;)"
msgstr ""
#: app.py:189
msgid "Minimal YunoHost version"
msgstr ""
#: YunohostAppGenerator.py:165
#: app.py:190
msgid "Minimal YunoHost version for the application to work"
msgstr ""
#: YunohostAppGenerator.py:172
#: app.py:199
msgid "Supported architectures"
msgstr ""
#: YunohostAppGenerator.py:174
#: app.py:201
msgid "All architectures"
msgstr ""
#: YunohostAppGenerator.py:185
#: app.py:212
msgid ""
"The app can be installed multiple times at the same time on the same "
"server"
msgstr ""
#: YunohostAppGenerator.py:190
#: app.py:219
msgid "The app will be integrating LDAP"
msgstr ""
#: YunohostAppGenerator.py:191
#: app.py:220
msgid ""
"Which means it's possible to use Yunohost credential to connect. 'LDAP' "
"corresponds to the technology used by Yunohost to handle a centralised "
"user base. Bridging the APP and Yunohost LDAP often requires to fill some"
" parameters in the app configuration"
"Which means it's possible to use Yunohost credentials to log into this "
"app. 'LDAP' corresponds to the technology used by Yunohost to handle a "
"centralised user base. Bridging the app and Yunohost's LDAP often "
"requires to add the proper technical details in the app's configuration "
"file"
msgstr ""
#: YunohostAppGenerator.py:193 YunohostAppGenerator.py:205
#: app.py:224 app.py:238
msgid "No"
msgstr ""
#: YunohostAppGenerator.py:194 YunohostAppGenerator.py:204
#: app.py:225 app.py:237
msgid "Yes"
msgstr ""
#: YunohostAppGenerator.py:195 YunohostAppGenerator.py:206
#: app.py:226 app.py:239
msgid "Not relevant"
msgstr ""
#: YunohostAppGenerator.py:201
#: app.py:232
msgid "The app will be integrated in Yunohost SSO (Single Sign On)"
msgstr ""
#: YunohostAppGenerator.py:202
#: app.py:233
msgid ""
"Which means that one connexion to Yunohost unlock the connexion to the "
"software, without having to sign on specificaly into it. One only has to "
"connect once (Single Sign On)"
"Which means that people will be logged in the app after logging in "
"YunoHost's portal, without having to sign on specifically into this app."
msgstr ""
#: YunohostAppGenerator.py:216
#: app.py:249
msgid "Licence"
msgstr ""
#: YunohostAppGenerator.py:217
#: app.py:250
msgid ""
"You should check this on the upstream repository. The expected format is "
"a SPDX id listed in https://spdx.org/licenses/"
msgstr ""
#: YunohostAppGenerator.py:222
#: app.py:257
msgid "Official website"
msgstr ""
#: YunohostAppGenerator.py:223
#: app.py:258
msgid "Leave empty if there is no official website"
msgstr ""
#: YunohostAppGenerator.py:230
#: app.py:265
msgid "Official app demo"
msgstr ""
#: YunohostAppGenerator.py:231
#: app.py:266
msgid "Leave empty if there is no official demo"
msgstr ""
#: YunohostAppGenerator.py:238
#: app.py:273
msgid "Admin documentation"
msgstr ""
#: YunohostAppGenerator.py:239
#: app.py:274
msgid "Leave empty if there is no official admin doc"
msgstr ""
#: YunohostAppGenerator.py:246
#: app.py:281
msgid "Usage documentation"
msgstr ""
#: YunohostAppGenerator.py:247
#: app.py:282
msgid "Leave empty if there is no official user doc"
msgstr ""
#: YunohostAppGenerator.py:254
#: app.py:289
msgid "Code repository"
msgstr ""
#: YunohostAppGenerator.py:264
#: app.py:300
msgid ""
"Ask the URL where the app will be installed ('domain' and 'path' "
"variables)"
msgstr ""
#: YunohostAppGenerator.py:267
#: app.py:305
msgid "Ask domain+path"
msgstr ""
#: YunohostAppGenerator.py:268
#: app.py:308
msgid ""
"Ask only the domain (the app requires to be installed at the root of a "
"dedicated domain)"
msgstr ""
#: YunohostAppGenerator.py:269
#: app.py:312
msgid "Do not ask (it isn't a webapp)"
msgstr ""
#: YunohostAppGenerator.py:274
#: app.py:317
msgid "Ask who can access to the app"
msgstr ""
#: YunohostAppGenerator.py:275
#: app.py:318
msgid ""
"In the users groups : by default at least 'visitors', 'all_users' et "
"'admins' exists. (It was previously the private/public app concept)"
msgstr ""
#: YunohostAppGenerator.py:280
#: app.py:325
msgid "Ask who can access to the admin interface"
msgstr ""
#: YunohostAppGenerator.py:281
#: app.py:326
msgid "In the case where the app has an admin interface"
msgstr ""
#: YunohostAppGenerator.py:286
#: app.py:331
msgid "Supported languages"
msgstr ""
#: YunohostAppGenerator.py:288
#: app.py:333
msgid "None / not relevant"
msgstr ""
#: YunohostAppGenerator.py:289
msgid "English"
msgstr ""
#: YunohostAppGenerator.py:290
msgid "Français"
msgstr ""
#: YunohostAppGenerator.py:291
#: app.py:336
msgid "Spanish"
msgstr ""
#: YunohostAppGenerator.py:292
#: app.py:337
msgid "Italian"
msgstr ""
#: YunohostAppGenerator.py:293
#: app.py:338
msgid "German"
msgstr ""
#: YunohostAppGenerator.py:294
#: app.py:339
msgid "Chinese"
msgstr ""
#: YunohostAppGenerator.py:295
#: app.py:340
msgid "Japanese"
msgstr ""
#: YunohostAppGenerator.py:296
#: app.py:341
msgid "Danish"
msgstr ""
#: YunohostAppGenerator.py:297
#: app.py:342
msgid "Portugese"
msgstr ""
#: YunohostAppGenerator.py:298
#: app.py:343
msgid "Dutch"
msgstr ""
#: YunohostAppGenerator.py:299
#: app.py:344
msgid "Russian"
msgstr ""
#: YunohostAppGenerator.py:313
#: app.py:356
msgid "Application source code or executable"
msgstr ""
#: YunohostAppGenerator.py:320
#: app.py:363
msgid "Sources sha256 checksum"
msgstr ""
#: YunohostAppGenerator.py:328
msgid "Activate the automated source update bot"
#: app.py:371
msgid "Enable automatic update of sources (using a bot running every night)"
msgstr ""
#: YunohostAppGenerator.py:329
#: app.py:372
msgid ""
"If the software is available in one of the handled sources and publish "
"releases or tags for its new updates, or for each new commit, a bot will "
"provide an update with updated URL and checksum"
"If the upstream software is hosted in one of the handled sources and "
"publishes proper releases or tags, the bot will create a pull request to "
"update the sources URL and checksum"
msgstr ""
#: YunohostAppGenerator.py:349
msgid "Dependances to be installed via apt (separated by a quote and/or spaces)"
#: app.py:394
msgid "Dependencies to be installed via apt (separated by comma and/or spaces)"
msgstr ""
#: YunohostAppGenerator.py:356
msgid "Initialise a SQL database"
#: app.py:403
msgid "Initialize an SQL database"
msgstr ""
#: YunohostAppGenerator.py:366
msgid "Initialise a system user for this app"
#: app.py:413
msgid "Initialize a system user for this app"
msgstr ""
#: YunohostAppGenerator.py:371
msgid "Initialise an installation folder for this app"
#: app.py:418
msgid "Initialize an installation folder for this app"
msgstr ""
#: YunohostAppGenerator.py:372
#: app.py:419
msgid "By default it's /var/www/$app"
msgstr ""
#: YunohostAppGenerator.py:377
msgid "Initialise a folder to store the app data"
#: app.py:424
msgid "Initialize a folder to store the app data"
msgstr ""
#: YunohostAppGenerator.py:378
#: app.py:425
msgid "By default it's /var/yunohost.app/$app"
msgstr ""
#: YunohostAppGenerator.py:386
#: app.py:433
msgid "App main technology"
msgstr ""
#: YunohostAppGenerator.py:388
#: app.py:435
msgid "None / Static application"
msgstr ""
#: YunohostAppGenerator.py:393
#: app.py:440
msgid "Other"
msgstr ""
#: YunohostAppGenerator.py:400
#: app.py:447
msgid "Installation specific commands"
msgstr ""
#: YunohostAppGenerator.py:401
#: app.py:448
msgid ""
"These commands are executed from the app installation folder (by default,"
" /var/www/$app) after the sources have been deployed. This field uses by "
@ -322,222 +330,235 @@ msgid ""
"documentation"
msgstr ""
#: YunohostAppGenerator.py:413
#: app.py:460
msgid "Use composer"
msgstr ""
#: YunohostAppGenerator.py:414
#: app.py:461
msgid "Composer is a PHP dependencies manager used by some apps"
msgstr ""
#: YunohostAppGenerator.py:423
#: app.py:472
msgid "NodeJS version"
msgstr ""
#: YunohostAppGenerator.py:424
#: app.py:473
msgid "For example: 16.4, 18, 18.2, 20, 20.1, ..."
msgstr ""
#: YunohostAppGenerator.py:431
#: app.py:480
msgid "Install and use Yarn"
msgstr ""
#: YunohostAppGenerator.py:438
#: app.py:487
msgid "Command to start the app daemon (from systemd service)"
msgstr ""
#: YunohostAppGenerator.py:439
#: app.py:488
msgid ""
"Corresponds to 'ExecStart' statement in systemd. You can use "
"'__INSTALL_DIR__' to refer to the install directory, or '__APP__' to "
"refer to the app id"
msgstr ""
#: YunohostAppGenerator.py:449
#: app.py:500
msgid "The app uses a specific configuration file"
msgstr ""
#: YunohostAppGenerator.py:450
#: app.py:501
msgid "Usually : .env, config.json, conf.ini, params.yml, ..."
msgstr ""
#: YunohostAppGenerator.py:455
#: app.py:508
msgid "Name or file path to use"
msgstr ""
#: YunohostAppGenerator.py:463
#: app.py:516
msgid "App configuration file pattern"
msgstr ""
#: YunohostAppGenerator.py:464
#: app.py:517
msgid ""
"In this pattern, you can use the syntax __FOO_BAR__ which will "
"automatically replaced by the value of the variable $foo_bar"
msgstr ""
#: YunohostAppGenerator.py:474
#: app.py:529
msgid ""
"Type the content of DESCRIPTION.md file. <br> Do not give the software "
"name at the beginning, as it will be integrated an 'Overview' subpart"
"doc/DESCRIPTION.md: A comprehensive presentation of the app, possibly "
"listing the main features, possible warnings and specific details on its "
"functioning in Yunohost (e.g. warning about integration issues)."
msgstr ""
#: YunohostAppGenerator.py:483
#: app.py:539
msgid ""
"Type the DISCLAIMER.md file content, which list warnings and attention "
"points."
"doc/PRE_INSTALL.md: important info to be shown to the admin before "
"installing the app"
msgstr ""
#: YunohostAppGenerator.py:491
msgid "Type the PRE_INSTALL.md file content"
#: app.py:540 app.py:548 app.py:556 app.py:564 app.py:572
msgid "Leave empty if not relevant"
msgstr ""
#: YunohostAppGenerator.py:499
msgid "Type the POST_INSTALL.md file content"
#: app.py:547
msgid ""
"doc/POST_INSTALL.md: important info to be shown to the admin after "
"installing the app"
msgstr ""
#: YunohostAppGenerator.py:507
msgid "Type the PRE_UPGRADE.md file content"
#: app.py:555
msgid ""
"doc/PRE_UPGRADE.md: important info to be shown to the admin before "
"upgrading the app"
msgstr ""
#: YunohostAppGenerator.py:515
msgid "Type the POST_UPGRADE.md file content"
#: app.py:563
msgid ""
"doc/POST_UPGRADE.md: important info to be shown to the admin after "
"upgrading the app"
msgstr ""
#: YunohostAppGenerator.py:523
msgid "Type the ADMIN.md file content"
#: app.py:571
msgid "doc/ADMIN.md: general tips on how to administrate this app"
msgstr ""
#: YunohostAppGenerator.py:534
#: app.py:583
msgid "Handle app install URL change (change_url script)"
msgstr ""
#: YunohostAppGenerator.py:537
#: app.py:586
msgid "Should changing the app URL be allowed ? (change_url change)"
msgstr ""
#: YunohostAppGenerator.py:542
#: app.py:593
msgid "Use logrotate for the app logs"
msgstr ""
#: YunohostAppGenerator.py:545
#: app.py:596
msgid ""
"If the app generates logs, this option permit to handle their archival. "
"Recommended."
msgstr ""
#: YunohostAppGenerator.py:551
#: app.py:604
msgid "Protect the application against brute force attacks (via fail2ban)"
msgstr ""
#: YunohostAppGenerator.py:554
#: app.py:609
msgid ""
"If the app generates failed connexions logs, this option allows to "
"automatically banish the related IP after a certain number of failed "
"password tries. Recommended."
msgstr ""
#: YunohostAppGenerator.py:558
#: app.py:615
msgid "Add a CRON task for this application"
msgstr ""
#: YunohostAppGenerator.py:559
#: app.py:616
msgid "Corresponds to some app periodic operations"
msgstr ""
#: YunohostAppGenerator.py:563
#: app.py:620
msgid "Type the CRON file content"
msgstr ""
#: YunohostAppGenerator.py:572
#: app.py:629
msgid "Regular expression for fail2ban"
msgstr ""
#: YunohostAppGenerator.py:576
#: app.py:633
msgid "A regular expression"
msgstr ""
#: YunohostAppGenerator.py:578
#: app.py:635
msgid ""
"Regular expression to check in the log file to activate failban (search "
"for a line that indicates a credentials error)."
msgstr ""
#: YunohostAppGenerator.py:592
#: app.py:659
msgid "Generator mode"
msgstr ""
#: YunohostAppGenerator.py:593
#: app.py:660
msgid ""
"In tutorial version, the generated app will contain additionnal comments "
"to ease the understanding. In steamlined version, the generated app will "
"only contain the necessary minimum."
msgstr ""
#: YunohostAppGenerator.py:594
#: app.py:664
msgid "Streamlined version"
msgstr ""
#: YunohostAppGenerator.py:594
#: app.py:665
msgid "Tutorial version"
msgstr ""
#: YunohostAppGenerator.py:599
#: app.py:671
msgid "Previsualise"
msgstr ""
#: YunohostAppGenerator.py:600
#: app.py:672
msgid "Download the .zip"
msgstr ""
#: YunohostAppGenerator.py:601
#: app.py:674
msgid "Fill with demo values"
msgstr ""
#: YunohostAppGenerator.py:602
#: app.py:677
msgid ""
"Generate a complete and functionnal minimalistic app that you can iterate"
" from"
msgstr ""
#: templates/index.html:36
#: templates/base.html:5
msgid "YunoHost app generator"
msgstr ""
#: templates/index.html:28
msgid "Yunohost application generation form"
msgstr ""
#: templates/index.html:50
#: templates/index.html:55
msgid "1/9 - General information"
msgstr ""
#: templates/index.html:65
msgid "2/9 - Informations about the application"
#: templates/index.html:70
msgid "2/9 - Upstream information"
msgstr ""
#: templates/index.html:68
msgid "The word upstream refers to the original project that maintains the app"
#: templates/index.html:73
msgid ""
"The word 'upstream' refers to the original project that develops and "
"maintains the app"
msgstr ""
#: templates/index.html:83
#: templates/index.html:88
msgid "3/9 - Integration in YunoHost"
msgstr ""
#: templates/index.html:99
#: templates/index.html:104
msgid "4/9 - Questions to ask during installation"
msgstr ""
#: templates/index.html:103
#: templates/index.html:108
msgid "This part is meant to indicate the questions that will be asked."
msgstr ""
#: templates/index.html:105
#: templates/index.html:110
msgid ""
"NB: only standard questions are asked here, it might be required to "
"complete it by hand using other questions as a guide."
msgstr ""
#: templates/index.html:119
msgid "5/9 - Ressources to initialise"
#: templates/index.html:124
msgid "5/9 - Resources to initialize"
msgstr ""
#: templates/index.html:123
#: templates/index.html:128
msgid ""
"Technical elements configured before launching the 'real' app install "
"script. Usually : creating a system user, downloading app sources, "
@ -545,60 +566,195 @@ msgid ""
" create a database, ..."
msgstr ""
#: templates/index.html:146
#: templates/index.html:151
msgid "6/9 - Specific technology"
msgstr ""
#: templates/index.html:151
#: templates/index.html:156
msgid ""
"You probably want to make sure to have 'phpX.Y-fpm' and others "
"'phpX.Y-foobar' libraries listed the apt dependencies earlier (with X.Y "
"being the php version you want to use)"
msgstr ""
#: templates/index.html:152
#: templates/index.html:157
msgid ""
"The generated application draft will include an nginx configuration "
"snippet that interfaces with PHP-FPM"
msgstr ""
#: templates/index.html:160
#: templates/index.html:165
msgid ""
"You probably want to make sure to have 'python3' and 'python3-venv' "
"listed in the apt dependencies earlier. Other dependencies should be "
"installed inside a venv (cf the proposed install snippet)"
msgstr ""
#: templates/index.html:164
#: templates/index.html:169
msgid ""
"The generated application draft will include an nginx configuration "
"snippet that reverse-proxies to a systemd service using an internal port"
msgstr ""
#: templates/index.html:226
#: templates/index.html:237
msgid "7/9 - App configuration"
msgstr ""
#: templates/index.html:250
#: templates/index.html:261
msgid "8/9 - General and advanced documentation"
msgstr ""
#: templates/index.html:253
msgid ""
"A more complete presentation that the summary completed above, explaining"
" to what correspond the software, the eventual warnings and specific "
"details on its functioning in Yunohost (it's the place where one can warn"
" about integration issues)."
msgstr ""
#: templates/index.html:257
msgid ""
"Indications to show at key steps to manage the package : installation, "
"update, message to the admin account. You usually don't have to fill "
"them."
msgstr ""
#: templates/index.html:270
#: templates/index.html:275
msgid "9/9 - Advanced options"
msgstr ""
#~ msgid "Maintener of the generated app"
#~ msgstr ""
#~ msgid "Commonly you put your name here... If you agree with it ;)"
#~ msgstr ""
#~ msgid ""
#~ "Which means it's possible to use "
#~ "Yunohost credential to connect. 'LDAP' "
#~ "corresponds to the technology used by"
#~ " Yunohost to handle a centralised "
#~ "user base. Bridging the APP and "
#~ "Yunohost LDAP often requires to fill "
#~ "some parameters in the app configuration"
#~ msgstr ""
#~ msgid ""
#~ "Which means that one connexion to "
#~ "Yunohost unlock the connexion to the "
#~ "software, without having to sign on "
#~ "specificaly into it. One only has "
#~ "to connect once (Single Sign On)"
#~ msgstr ""
#~ msgid "Activate the automated source update bot"
#~ msgstr ""
#~ msgid ""
#~ "If the software is available in "
#~ "one of the handled sources and "
#~ "publish releases or tags for its "
#~ "new updates, or for each new "
#~ "commit, a bot will provide an "
#~ "update with updated URL and checksum"
#~ msgstr ""
#~ msgid ""
#~ "Dependances to be installed via apt "
#~ "(separated by a quote and/or spaces)"
#~ msgstr ""
#~ msgid "Initialise a SQL database"
#~ msgstr ""
#~ msgid "Initialise a system user for this app"
#~ msgstr ""
#~ msgid "Initialise an installation folder for this app"
#~ msgstr ""
#~ msgid "Initialise a folder to store the app data"
#~ msgstr ""
#~ msgid ""
#~ "Type the content of DESCRIPTION.md file."
#~ " <br> Do not give the software "
#~ "name at the beginning, as it will"
#~ " be integrated an 'Overview' subpart"
#~ msgstr ""
#~ msgid ""
#~ "Type the DISCLAIMER.md file content, "
#~ "which list warnings and attention "
#~ "points."
#~ msgstr ""
#~ msgid "Type the PRE_INSTALL.md file content"
#~ msgstr ""
#~ msgid "Type the POST_INSTALL.md file content"
#~ msgstr ""
#~ msgid "Type the PRE_UPGRADE.md file content"
#~ msgstr ""
#~ msgid "Type the POST_UPGRADE.md file content"
#~ msgstr ""
#~ msgid "Type the ADMIN.md file content"
#~ msgstr ""
#~ msgid "2/9 - Informations about the application"
#~ msgstr ""
#~ msgid "The word upstream refers to the original project that maintains the app"
#~ msgstr ""
#~ msgid "5/9 - Ressources to initialise"
#~ msgstr ""
#~ msgid ""
#~ "A more complete presentation that the"
#~ " summary completed above, explaining to "
#~ "what correspond the software, the "
#~ "eventual warnings and specific details "
#~ "on its functioning in Yunohost (it's "
#~ "the place where one can warn about"
#~ " integration issues)."
#~ msgstr ""
#~ msgid ""
#~ "Indications to show at key steps "
#~ "to manage the package : installation,"
#~ " update, message to the admin "
#~ "account. You usually don't have to "
#~ "fill them."
#~ msgstr ""
#~ msgid "Description courte (fr)"
#~ msgstr ""
#~ msgid "Français"
#~ msgstr ""
#~ msgid ""
#~ "doc/DESCRIPTION.md : A comprehensive "
#~ "presentation of the app, possibly "
#~ "listing the main features, possible "
#~ "warnings and specific details on its "
#~ "functioning in Yunohost (e.g. warning "
#~ "about integration issues)."
#~ msgstr ""
#~ msgid ""
#~ "doc/PRE_INSTALL.md : important info to "
#~ "be shown to the admin before "
#~ "installing the app"
#~ msgstr ""
#~ msgid ""
#~ "doc/POST_INSTALL.md : important info to "
#~ "be shown to the admin after "
#~ "installing the app"
#~ msgstr ""
#~ msgid ""
#~ "doc/PRE_UPGRADE.md : important info to "
#~ "be shown to the admin before "
#~ "upgrading the app"
#~ msgstr ""
#~ msgid ""
#~ "doc/POST_UPGRADE.md : important info to "
#~ "be shown to the admin after "
#~ "upgrading the app"
#~ msgstr ""
#~ msgid "doc/ADMIN.md : general tips on how to administrate this app"
#~ msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-03-31 22:46+0200\n"
"POT-Creation-Date: 2024-04-26 15:39+0200\n"
"PO-Revision-Date: 2024-03-31 20:23+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: fr\n"
@ -16,31 +16,43 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.10.3\n"
"Generated-By: Babel 2.14.0\n"
#: app_generator.py:119
#: app.py:68 app.py:334
msgid "English"
msgstr "Anglais"
#: app.py:68 app.py:335
msgid "French"
msgstr "Français"
#: app.py:127
msgid "Select language"
msgstr "Langues supportées"
#: app.py:137
msgid "Application identifier (id)"
msgstr "Identifiant (id) de l'application"
#: app_generator.py:121
#: app.py:138
msgid "Small caps and without spaces"
msgstr "En minuscule et sans espace"
#: app_generator.py:129
#: app.py:146
msgid "App name"
msgstr "Nom de l'application"
#: app_generator.py:130
#: app.py:147
msgid "It's the application name, displayed in the user interface"
msgstr ""
"Il s'agit du nom l'application, affiché dans les interfaces "
"utilisateur·ice·s"
#: app_generator.py:138
#: app.py:157
msgid "Short description (en)"
msgstr "Description courte (en)"
#: app_generator.py:139
#: app.py:158 app.py:165
msgid ""
"Explain in a few words (10-15) why this app is useful or what it does "
"(the goal is to give a broad idea for the user browsing an hundred apps "
@ -50,36 +62,39 @@ msgstr ""
"fait (l'objectif est de donner une idée grossière pour des utilisateurs "
"qui naviguent dans un catalogue de 100+ apps)"
#: app_generator.py:143
#, fuzzy
msgid "Description courte (fr)"
#: app.py:164
msgid "Short description (fr)"
msgstr "Description courte (fr)"
#: app_generator.py:159
msgid "Maintener of the generated app"
#: app.py:176
msgid "Version"
msgstr "Version"
#: app.py:182
msgid "Maintainer of the generated app"
msgstr "Mainteneur·euse de l'app YunoHost créée"
#: app_generator.py:160
msgid "Commonly you put your name here... If you agree with it ;)"
#: app.py:183
msgid "Usually you put your name here... If you're okay with it ;)"
msgstr "Généralement vous mettez votre nom ici… Si vous êtes d'accord ;)"
#: app_generator.py:164
#: app.py:189
msgid "Minimal YunoHost version"
msgstr "Version YunoHost minimale"
#: app_generator.py:165
#: app.py:190
msgid "Minimal YunoHost version for the application to work"
msgstr "Version minimale de Yunohost pour que l'application fonctionne."
#: app_generator.py:172
#: app.py:199
msgid "Supported architectures"
msgstr "Architectures supportées"
#: app_generator.py:174
#: app.py:201
msgid "All architectures"
msgstr "Toutes les architectures"
#: app_generator.py:185
#: app.py:212
msgid ""
"The app can be installed multiple times at the same time on the same "
"server"
@ -87,55 +102,54 @@ msgstr ""
"L'app pourra être installée simultanément plusieurs fois sur la même "
"machine"
#: app_generator.py:190
#: app.py:219
msgid "The app will be integrating LDAP"
msgstr "L'app s'intègrera avec le LDAP"
#: app_generator.py:191
#: app.py:220
msgid ""
"Which means it's possible to use Yunohost credential to connect. 'LDAP' "
"corresponds to the technology used by Yunohost to handle a centralised "
"user base. Bridging the APP and Yunohost LDAP often requires to fill some"
" parameters in the app configuration"
"Which means it's possible to use Yunohost credentials to log into this "
"app. 'LDAP' corresponds to the technology used by Yunohost to handle a "
"centralised user base. Bridging the app and Yunohost's LDAP often "
"requires to add the proper technical details in the app's configuration "
"file"
msgstr ""
"C'est-à-dire pouvoir se connecter en utilisant ses identifiants YunoHost."
" 'LDAP' corresponds à la technologie utilisée par YunoHost comme base de "
"compte utilisateurs centralisée. L'interface entre l'app et le LDAP de "
"YunoHost nécessite le plus souvent de remplir des paramètres dans la "
"configuration de l'app (voir plus tard)"
"configuration de l'app"
#: app_generator.py:193 app_generator.py:205
#: app.py:224 app.py:238
msgid "No"
msgstr "Non"
#: app_generator.py:194 app_generator.py:204
#: app.py:225 app.py:237
msgid "Yes"
msgstr "Oui"
#: app_generator.py:195 app_generator.py:206
#: app.py:226 app.py:239
msgid "Not relevant"
msgstr "Non pertinent"
#: app_generator.py:201
#: app.py:232
msgid "The app will be integrated in Yunohost SSO (Single Sign On)"
msgstr "L'app s'intègrera avec le SSO (Single Sign On) de YunoHost"
#: app_generator.py:202
#: app.py:233
msgid ""
"Which means that one connexion to Yunohost unlock the connexion to the "
"software, without having to sign on specificaly into it. One only has to "
"connect once (Single Sign On)"
"Which means that people will be logged in the app after logging in "
"YunoHost's portal, without having to sign on specifically into this app."
msgstr ""
"C'est-à-dire qu'une connexion à Yunohost déverouille la connexion au "
"logiciel, sans avoir à s'y connecter spécifiquement. On ne se connecte "
"qu'une seule fois (Single Sign On)"
"Ce qui signifie que les personnes seront logguées dans l'app après s'être"
" connectées au portail YunoHost, sans avoir à se connecter spécifiquement"
" dans"
#: app_generator.py:216
#, fuzzy
#: app.py:249
msgid "Licence"
msgstr "Licence"
msgstr "License"
#: app_generator.py:217
#: app.py:250
msgid ""
"You should check this on the upstream repository. The expected format is "
"a SPDX id listed in https://spdx.org/licenses/"
@ -143,43 +157,43 @@ msgstr ""
"Vous devriez chercher cela dans le dépôt du logiciel. Le format attendu "
"est un identifiant SPDX listé dans https://spdx.org/licenses/"
#: app_generator.py:222
#: app.py:257
msgid "Official website"
msgstr "Site web officiel"
#: app_generator.py:223
#: app.py:258
msgid "Leave empty if there is no official website"
msgstr "Laisser vide s'il n'y a pas de site officiel"
#: app_generator.py:230
#: app.py:265
msgid "Official app demo"
msgstr "Démo officielle de l'app"
#: app_generator.py:231
#: app.py:266
msgid "Leave empty if there is no official demo"
msgstr "Laisser vide s'il n'y a pas de démo officielle"
#: app_generator.py:238
#: app.py:273
msgid "Admin documentation"
msgstr "Documentation d'administration"
#: app_generator.py:239
#: app.py:274
msgid "Leave empty if there is no official admin doc"
msgstr "Laisser vide s'il n'y a pas de documentation d'administration officielle"
#: app_generator.py:246
#: app.py:281
msgid "Usage documentation"
msgstr "Documentation d'utilisation"
#: app_generator.py:247
#: app.py:282
msgid "Leave empty if there is no official user doc"
msgstr "Laisser vide s'il n'y a pas de documentation d'utilisation officielle"
#: app_generator.py:254
#: app.py:289
msgid "Code repository"
msgstr "Dépôt de code"
#: app_generator.py:264
#: app.py:300
msgid ""
"Ask the URL where the app will be installed ('domain' and 'path' "
"variables)"
@ -187,11 +201,11 @@ msgstr ""
"Demander l'URL sur laquelle sera installée l'app (variables 'domain' et "
"'path')"
#: app_generator.py:267
#: app.py:305
msgid "Ask domain+path"
msgstr "Demander le domaine+chemin"
#: app_generator.py:268
#: app.py:308
msgid ""
"Ask only the domain (the app requires to be installed at the root of a "
"dedicated domain)"
@ -199,15 +213,15 @@ msgstr ""
"Demander le domaine uniquement (l'app nécessite d'être installée à la "
"racine d'un domaine dédié à cette app)"
#: app_generator.py:269
#: app.py:312
msgid "Do not ask (it isn't a webapp)"
msgstr "Ne pas demander (l'app n'est pas une webapp)"
#: app_generator.py:274
#: app.py:317
msgid "Ask who can access to the app"
msgstr "Demander qui pourra accéder à l'app"
#: app_generator.py:275
#: app.py:318
msgid ""
"In the users groups : by default at least 'visitors', 'all_users' et "
"'admins' exists. (It was previously the private/public app concept)"
@ -216,134 +230,127 @@ msgstr ""
"'all_users' et 'admins' existent. (Corresponds anciennement à la notion "
"d'app privée/publique)"
#: app_generator.py:280
#: app.py:325
msgid "Ask who can access to the admin interface"
msgstr "Demander qui pourra accéder à l'interface d'admin"
#: app_generator.py:281
#: app.py:326
msgid "In the case where the app has an admin interface"
msgstr "Ceci suppose a priori que l'app dispose d'une interface d'admin"
#: app_generator.py:286
#: app.py:331
msgid "Supported languages"
msgstr "Langues supportées"
#: app_generator.py:288
#: app.py:333
msgid "None / not relevant"
msgstr "Aucune / non pertinent"
#: app_generator.py:289
msgid "English"
msgstr "Anglais"
#: app_generator.py:290
msgid "Français"
msgstr "French"
#: app_generator.py:291
#: app.py:336
msgid "Spanish"
msgstr "Espagnol"
#: app_generator.py:292
#: app.py:337
msgid "Italian"
msgstr "Italien"
#: app_generator.py:293
#: app.py:338
msgid "German"
msgstr "Allemand"
#: app_generator.py:294
#: app.py:339
msgid "Chinese"
msgstr "Chinois"
#: app_generator.py:295
#: app.py:340
msgid "Japanese"
msgstr "Japonais"
#: app_generator.py:296
#: app.py:341
msgid "Danish"
msgstr "Danois"
#: app_generator.py:297
#: app.py:342
msgid "Portugese"
msgstr "Portugais"
#: app_generator.py:298
#: app.py:343
msgid "Dutch"
msgstr "Néerlandais"
#: app_generator.py:299
#: app.py:344
msgid "Russian"
msgstr "Russe"
#: app_generator.py:313
#: app.py:356
msgid "Application source code or executable"
msgstr "Code source ou exécutable de l'application"
#: app_generator.py:320
#: app.py:363
msgid "Sources sha256 checksum"
msgstr "Empreinte sha256 des sources"
#: app_generator.py:328
msgid "Activate the automated source update bot"
msgstr "Activer le robot de mise à jour automatique des sources"
#: app.py:371
msgid "Enable automatic update of sources (using a bot running every night)"
msgstr ""
"Activer le robot de mise à jour automatique des sources (via un robot "
"chaque nuit)"
#: app_generator.py:329
#: app.py:372
msgid ""
"If the software is available in one of the handled sources and publish "
"releases or tags for its new updates, or for each new commit, a bot will "
"provide an update with updated URL and checksum"
"If the upstream software is hosted in one of the handled sources and "
"publishes proper releases or tags, the bot will create a pull request to "
"update the sources URL and checksum"
msgstr ""
"Si le logiciel est disponible sur une des sources prises en charge et "
"publie des releases ou des tags pour ses nouvelles versions, ou pour "
"chaque nouveau commit, un robot proposera automatiquement des mises à "
"jour de l'URL et de la checksum."
"publie des releases ou des tags pour ses nouvelles versions, un robot "
"proposera automatiquement des mises à jour de l'URL et de la checksum."
#: app_generator.py:349
msgid "Dependances to be installed via apt (separated by a quote and/or spaces)"
#: app.py:394
msgid "Dependencies to be installed via apt (separated by comma and/or spaces)"
msgstr "Dépendances à installer via apt (séparées par des virgules et/ou espaces)"
#: app_generator.py:356
msgid "Initialise a SQL database"
#: app.py:403
msgid "Initialize an SQL database"
msgstr "Initialiser une base de données SQL"
#: app_generator.py:366
msgid "Initialise a system user for this app"
#: app.py:413
msgid "Initialize a system user for this app"
msgstr "Initialiser un utilisateur système pour cet app"
#: app_generator.py:371
msgid "Initialise an installation folder for this app"
#: app.py:418
msgid "Initialize an installation folder for this app"
msgstr "Initialiser un dossier d'installation de l'app"
#: app_generator.py:372
#: app.py:419
msgid "By default it's /var/www/$app"
msgstr "Par défaut il s'agit de /var/www/$app"
#: app_generator.py:377
msgid "Initialise a folder to store the app data"
#: app.py:424
msgid "Initialize a folder to store the app data"
msgstr "Initialiser un dossier destiné à stocker les données de l'app"
#: app_generator.py:378
#: app.py:425
msgid "By default it's /var/yunohost.app/$app"
msgstr "Par défaut il s'agit de /home/yunohost.app/$app"
#: app_generator.py:386
#: app.py:433
msgid "App main technology"
msgstr "Technologie principale de l'app"
#: app_generator.py:388
#: app.py:435
msgid "None / Static application"
msgstr "Aucune / application statique"
#: app_generator.py:393
#: app.py:440
msgid "Other"
msgstr "Autre"
#: app_generator.py:400
#: app.py:447
msgid "Installation specific commands"
msgstr "Commandes spécifiques d'installation"
#: app_generator.py:401
#: app.py:448
msgid ""
"These commands are executed from the app installation folder (by default,"
" /var/www/$app) after the sources have been deployed. This field uses by "
@ -357,31 +364,31 @@ msgstr ""
"technologie sélectionnée. Vous devriez sans-doute le comparer et "
"l'adapter en fonction de la documentation d'installation de l'app."
#: app_generator.py:413
#: app.py:460
msgid "Use composer"
msgstr "Utiliser composer"
#: app_generator.py:414
#: app.py:461
msgid "Composer is a PHP dependencies manager used by some apps"
msgstr "Composer est un gestionnaire de dépendance PHP utilisé par certaines apps"
#: app_generator.py:423
#: app.py:472
msgid "NodeJS version"
msgstr "Version de NodeJS"
#: app_generator.py:424
#: app.py:473
msgid "For example: 16.4, 18, 18.2, 20, 20.1, ..."
msgstr "Par exemple: 16.4, 18, 18.2, 20, 20.1, ..."
#: app_generator.py:431
#: app.py:480
msgid "Install and use Yarn"
msgstr "Installer et utiliser Yarn"
#: app_generator.py:438
#: app.py:487
msgid "Command to start the app daemon (from systemd service)"
msgstr "Commande pour lancer le daemon de l'app (depuis le service systemd)"
#: app_generator.py:439
#: app.py:488
msgid ""
"Corresponds to 'ExecStart' statement in systemd. You can use "
"'__INSTALL_DIR__' to refer to the install directory, or '__APP__' to "
@ -391,23 +398,23 @@ msgstr ""
"'__INSTALL_DIR__' pour faire référence directory, our '__APP__' pour "
"l'identifiant de l'application"
#: app_generator.py:449
#: app.py:500
msgid "The app uses a specific configuration file"
msgstr "L'app utilise un fichier de configuration spécifique"
#: app_generator.py:450
#: app.py:501
msgid "Usually : .env, config.json, conf.ini, params.yml, ..."
msgstr "Typiquement : .env, config.json, conf.ini, params.yml, ..."
#: app_generator.py:455
#: app.py:508
msgid "Name or file path to use"
msgstr "Nom ou chemin du fichier à utiliser"
#: app_generator.py:463
#: app.py:516
msgid "App configuration file pattern"
msgstr "Modèle de fichier de configuration de l'app"
#: app_generator.py:464
#: app.py:517
msgid ""
"In this pattern, you can use the syntax __FOO_BAR__ which will "
"automatically replaced by the value of the variable $foo_bar"
@ -415,59 +422,72 @@ msgstr ""
"Dans ce modèle, vous pouvez utilisez la syntaxe __FOO_BAR__ qui sera "
"automatiquement remplacé par la valeur de la variable $foo_bar"
#: app_generator.py:474
#: app.py:529
msgid ""
"Type the content of DESCRIPTION.md file. <br> Do not give the software "
"name at the beginning, as it will be integrated an 'Overview' subpart"
"doc/DESCRIPTION.md: A comprehensive presentation of the app, possibly "
"listing the main features, possible warnings and specific details on its "
"functioning in Yunohost (e.g. warning about integration issues)."
msgstr ""
"Saisissez le contenu du fichier DESCRIPTION.md. <br> N'indiquez pas de "
"titre du logiciel au début, car ce sera intégré dans une sous-partie "
"'Overview'"
"doc/DESCRIPTION.md : Une présentation plus complète que le résumé rempli "
"plus haut de ce à quoi correspond le logiciel, et les avertissements et "
"précisions éventuelles sur son fonctionnement dans Yunohost (c'est "
"l'endroit où l'on signale des problèmes d'intégrations)."
#: app_generator.py:483
#: app.py:539
msgid ""
"Type the DISCLAIMER.md file content, which list warnings and attention "
"points."
"doc/PRE_INSTALL.md: important info to be shown to the admin before "
"installing the app"
msgstr ""
"Saisissez le contenu du fichier DISCLAIMER.md, qui liste des "
"avertissements et points d'attention."
"doc/PRE_INSTALL.md : info importantes à montrer aux admins avant "
"l'installation de l'app"
#: app_generator.py:491
msgid "Type the PRE_INSTALL.md file content"
msgstr "Saisissez le contenu du fichier PRE_INSTALL.md"
#: app.py:540 app.py:548 app.py:556 app.py:564 app.py:572
msgid "Leave empty if not relevant"
msgstr "Laisser vide si pas pertinent"
#: app_generator.py:499
msgid "Type the POST_INSTALL.md file content"
msgstr "Saisissez le contenu du fichier POST_INSTALL.md"
#: app.py:547
msgid ""
"doc/POST_INSTALL.md: important info to be shown to the admin after "
"installing the app"
msgstr ""
"doc/POST_INSTALL.md : infos importantes à montrer aux admins après "
"l'installation de l'app"
#: app_generator.py:507
msgid "Type the PRE_UPGRADE.md file content"
msgstr "Saisissez le contenu du fichier PRE_UPGRADE.md"
#: app.py:555
msgid ""
"doc/PRE_UPGRADE.md: important info to be shown to the admin before "
"upgrading the app"
msgstr ""
"doc/PRE_UPGRADE.md : infos importantes à montrer aux admins avant la mise"
" à jour de l'app"
#: app_generator.py:515
msgid "Type the POST_UPGRADE.md file content"
msgstr "Saisissez le contenu du fichier POST_UPGRADE.md"
#: app.py:563
msgid ""
"doc/POST_UPGRADE.md: important info to be shown to the admin after "
"upgrading the app"
msgstr ""
"doc/POST_UPGRADE.md : infos importantes à montrer aux admins après la "
"mise à jour de l'app"
#: app_generator.py:523
msgid "Type the ADMIN.md file content"
msgstr "Saisissez le contenu du fichier ADMIN.md"
#: app.py:571
msgid "doc/ADMIN.md: general tips on how to administrate this app"
msgstr "doc/ADMIN.md : indications générales pour administrer l'app"
#: app_generator.py:534
#: app.py:583
msgid "Handle app install URL change (change_url script)"
msgstr "Gérer le changement d'URL d'installation (script change_url)"
#: app_generator.py:537
#: app.py:586
msgid "Should changing the app URL be allowed ? (change_url change)"
msgstr ""
"Faut-il permettre le changement d'URL pour l'application ? (fichier "
"change_url)"
#: app_generator.py:542
#: app.py:593
msgid "Use logrotate for the app logs"
msgstr "Utiliser logrotate pour les journaux de l'app"
#: app_generator.py:545
#, fuzzy
#: app.py:596
msgid ""
"If the app generates logs, this option permit to handle their archival. "
"Recommended."
@ -475,11 +495,11 @@ msgstr ""
"Si l'application genère des journaux (log), cette option permet d'en "
"gérer l'archivage. Recommandé."
#: app_generator.py:551
#: app.py:604
msgid "Protect the application against brute force attacks (via fail2ban)"
msgstr "Protéger l'application des attaques par force brute (via fail2ban)"
#: app_generator.py:554
#: app.py:609
msgid ""
"If the app generates failed connexions logs, this option allows to "
"automatically banish the related IP after a certain number of failed "
@ -489,27 +509,27 @@ msgstr ""
"option permet de bannir automatiquement les IP au bout d'un certain "
"nombre d'essais de mot de passe. Recommandé."
#: app_generator.py:558
#: app.py:615
msgid "Add a CRON task for this application"
msgstr "Ajouter une tâche CRON pour cette application"
#: app_generator.py:559
#: app.py:616
msgid "Corresponds to some app periodic operations"
msgstr "Corresponds à des opérations périodiques de l'application"
#: app_generator.py:563
#: app.py:620
msgid "Type the CRON file content"
msgstr "Saisissez le contenu du fichier CRON"
#: app_generator.py:572
#: app.py:629
msgid "Regular expression for fail2ban"
msgstr "Expression régulière pour fail2ban"
#: app_generator.py:576
#: app.py:633
msgid "A regular expression"
msgstr "Une expression régulière"
#: app_generator.py:578
#: app.py:635
msgid ""
"Regular expression to check in the log file to activate failban (search "
"for a line that indicates a credentials error)."
@ -518,11 +538,11 @@ msgstr ""
"s'active (cherchez une ligne qui indique une erreur d'identifiants de "
"connexion)."
#: app_generator.py:592
#: app.py:659
msgid "Generator mode"
msgstr "Mode du générateur"
#: app_generator.py:593
#: app.py:660
msgid ""
"In tutorial version, the generated app will contain additionnal comments "
"to ease the understanding. In steamlined version, the generated app will "
@ -532,27 +552,27 @@ msgstr ""
"additionnels pour faciliter la compréhension. En version épurée, "
"l'application générée ne contiendra que le minimum nécessaire."
#: app_generator.py:594
#: app.py:664
msgid "Streamlined version"
msgstr "Version épurée"
#: app_generator.py:594
#: app.py:665
msgid "Tutorial version"
msgstr "Version tutoriel"
#: app_generator.py:599
#: app.py:671
msgid "Previsualise"
msgstr "Prévisualiser"
#: app_generator.py:600
#: app.py:672
msgid "Download the .zip"
msgstr "Télécharger le .zip"
#: app_generator.py:601
#: app.py:674
msgid "Fill with demo values"
msgstr "Remplir avec des valeurs de démonstration"
#: app_generator.py:602
#: app.py:677
msgid ""
"Generate a complete and functionnal minimalistic app that you can iterate"
" from"
@ -560,35 +580,43 @@ msgstr ""
"Générer une application minimaliste complète et fonctionnelle à partir de"
" laquelle itérer"
#: templates/index.html:36
#: templates/base.html:5
msgid "YunoHost app generator"
msgstr "Générateur d'app YunoHost"
#: templates/index.html:28
msgid "Yunohost application generation form"
msgstr "Formulaire de génération d'une application Yunohost"
#: templates/index.html:50
#: templates/index.html:55
msgid "1/9 - General information"
msgstr "1/9 - Informations générales"
#: templates/index.html:65
msgid "2/9 - Informations about the application"
msgstr "2/9 - Informations sur le projet upstream de l'application"
#: templates/index.html:70
msgid "2/9 - Upstream information"
msgstr "2/9 - Informations sur l'upstream"
#: templates/index.html:68
msgid "The word upstream refers to the original project that maintains the app"
msgstr "Le terme upstream désigne le projet original qui maintient l'app"
#: templates/index.html:73
msgid ""
"The word 'upstream' refers to the original project that develops and "
"maintains the app"
msgstr ""
"Le terme 'upstream' désigne le projet original qui développe et maintient"
" l'app"
#: templates/index.html:83
#: templates/index.html:88
msgid "3/9 - Integration in YunoHost"
msgstr "3/9 - Intégration dans YunoHost"
#: templates/index.html:99
#: templates/index.html:104
msgid "4/9 - Questions to ask during installation"
msgstr "4/9 - Questions à poser pendant l'installation"
#: templates/index.html:103
#: templates/index.html:108
msgid "This part is meant to indicate the questions that will be asked."
msgstr "Cette partie sert à indiquer les questions qui devront être posées."
#: templates/index.html:105
#: templates/index.html:110
msgid ""
"NB: only standard questions are asked here, it might be required to "
"complete it by hand using other questions as a guide."
@ -597,11 +625,11 @@ msgstr ""
"éventuellement compléter à la main en suivant le modèle des autres "
"questions."
#: templates/index.html:119
msgid "5/9 - Ressources to initialise"
#: templates/index.html:124
msgid "5/9 - Resources to initialize"
msgstr "5/9 - Ressources à initialiser"
#: templates/index.html:123
#: templates/index.html:128
msgid ""
"Technical elements configured before launching the 'real' app install "
"script. Usually : creating a system user, downloading app sources, "
@ -614,11 +642,11 @@ msgstr ""
"données, installer des dépendances avec apt, créer une base de données, "
"..."
#: templates/index.html:146
#: templates/index.html:151
msgid "6/9 - Specific technology"
msgstr "6/9 - Technologie spécifique"
#: templates/index.html:151
#: templates/index.html:156
msgid ""
"You probably want to make sure to have 'phpX.Y-fpm' and others "
"'phpX.Y-foobar' libraries listed the apt dependencies earlier (with X.Y "
@ -628,7 +656,7 @@ msgstr ""
"librairies 'phpX.Y-foobar' listées dans les dépendances apt (X.Y étant la"
" version de PHP que vous voulez utiliser)"
#: templates/index.html:152
#: templates/index.html:157
msgid ""
"The generated application draft will include an nginx configuration "
"snippet that interfaces with PHP-FPM"
@ -636,7 +664,7 @@ msgstr ""
"Le brouillon de l'application inclura une configuration nginx qui "
"s'interface avec PHP-FPM"
#: templates/index.html:160
#: templates/index.html:165
msgid ""
"You probably want to make sure to have 'python3' and 'python3-venv' "
"listed in the apt dependencies earlier. Other dependencies should be "
@ -646,7 +674,7 @@ msgstr ""
" listés dans les dépendances apt. Les autres dépendences devront être "
"installées dans un venv"
#: templates/index.html:164
#: templates/index.html:169
msgid ""
"The generated application draft will include an nginx configuration "
"snippet that reverse-proxies to a systemd service using an internal port"
@ -654,38 +682,18 @@ msgstr ""
"Le brouillon de l'application inclura une configuration nginx qui "
"redirige vers le service systemd en utilisant un port interne"
#: templates/index.html:226
#: templates/index.html:237
msgid "7/9 - App configuration"
msgstr "7/9 - Configuration de l'app"
#: templates/index.html:250
#: templates/index.html:261
msgid "8/9 - General and advanced documentation"
msgstr "8/9 - Documentation générale et avancée"
#: templates/index.html:253
msgid ""
"A more complete presentation that the summary completed above, explaining"
" to what correspond the software, the eventual warnings and specific "
"details on its functioning in Yunohost (it's the place where one can warn"
" about integration issues)."
msgstr ""
"Une présentation plus complète que le résumé rempli plus haut de ce à "
"quoi correspond le logiciel, et les avertissements et précisions "
"éventuelles sur son fonctionnement dans Yunohost (c'est l'endroit où l'on"
" signale des problèmes d'intégrations)."
#: templates/index.html:257
msgid ""
"Indications to show at key steps to manage the package : installation, "
"update, message to the admin account. You usually don't have to fill "
"them."
msgstr ""
"Des indications à afficher à des étapes clés de gestion du paquet: "
"installation, mise à jour, message au compte admin. Vous n'avez "
"généralement pas besoin de les remplir."
#: templates/index.html:270
#: templates/index.html:275
msgid "9/9 - Advanced options"
msgstr "9/9 - Options avancées"
#~ msgid "Français"
#~ msgstr "French"