diff --git a/tools/app_generator/app_generator.py b/tools/app_generator/app_generator.py
index 384f1402..95aa4041 100644
--- a/tools/app_generator/app_generator.py
+++ b/tools/app_generator/app_generator.py
@@ -37,9 +37,9 @@ from wtforms.validators import (
# Translations
from flask_babel import Babel
-from flask_babel import gettext
+from flask_babel import gettext, lazy_gettext
-from flask import redirect, request, make_response # Language swap by redirecting
+from flask import redirect, request, make_response # Language swap by redirecting
# Markdown to HTML - for debugging purposes
from misaka import Markdown, HtmlRenderer
@@ -51,7 +51,7 @@ from urllib import parse
from secrets import token_urlsafe
#### GLOBAL VARIABLES
-YOLOGEN_VERSION = "0.9.1"
+YOLOGEN_VERSION = "0.9.2.1"
GENERATOR_DICT = {"GENERATOR_VERSION": YOLOGEN_VERSION}
#### Create FLASK and Jinja Environments
@@ -63,26 +63,32 @@ cors = CORS(app)
environment = j2.Environment(loader=j2.FileSystemLoader("templates/"))
# Handle translations
-BABEL_TRANSLATION_DIRECTORIES = "translations"
+BABEL_TRANSLATION_DIRECTORIES='translations'
babel = Babel()
-LANGUAGES = {"en": "English", "fr": "French"}
+LANGUAGES = {
+ 'en': gettext('English'),
+ 'fr': gettext('French')
+}
+@app.context_processor
+def inject_conf_var():
+ return dict(AVAILABLE_LANGUAGES=LANGUAGES)
def configure(app):
babel.init_app(app, locale_selector=get_locale)
- app.config["LANGUAGES"] = LANGUAGES
-
-
+ app.config['LANGUAGES'] = LANGUAGES
def get_locale():
- print(request.accept_languages.best_match(app.config["LANGUAGES"].keys()))
- print(request.cookies.get("lang", "en"))
- # return 'en' # to test
- # return 'fr'
- return request.cookies.get("lang", "en")
- # return request.accept_languages.best_match(app.config['LANGUAGES'].keys()) # The result is based on the Accept-Language header. For testing purposes, you can directly return a language code, for example: return ‘de’
-
+ print(request.accept_languages.best_match(app.config['LANGUAGES'].keys()))
+ print(request.cookies.get('lang', 'en'))
+ #return 'en' # to test
+ #return 'fr'
+ if request.args.get('language'):
+ print(request.args.get('language'))
+ session['language'] = request.args.get('language')
+ return request.cookies.get('lang', 'en')
+ #return request.accept_languages.best_match(app.config['LANGUAGES'].keys()) # The result is based on the Accept-Language header. For testing purposes, you can directly return a language code, for example: return ‘de’
configure(app)
@@ -113,12 +119,23 @@ def markdown_file_to_html_string(file):
### Forms
+# Language selector. Not used (in GeneratorForm) until it's fixed or superseeded.
+# Use it in the HTML with {{ form_field(main_form.generator_language) }}
+class Translations(FlaskForm):
+ generator_language = SelectField(
+ gettext("Select language"),
+ choices=[('none', "")]+[language for language in LANGUAGES.items()],
+ default=['en'],
+ id = 'selectLanguage'
+ )
class GeneralInfos(FlaskForm):
app_id = StringField(
- Markup(gettext("Application identifier (id)")),
- description=gettext("Small caps and without spaces"),
+ Markup(
+ lazy_gettext("Application identifier (id)")
+ ),
+ description=lazy_gettext("Small caps and without spaces"),
validators=[DataRequired(), Regexp("[a-z_1-9]+.*(? \
-Do not give the software name at the beginning, as it will be integrated an 'Overview' subpart"""
- )
- ),
- validators=[Optional()],
- render_kw={
- "class": "form-control",
- "spellcheck": "false",
- },
+ Markup(lazy_gettext('''Type the content of DESCRIPTION.md file.
\
+Do not give the software name at the beginning, as it will be integrated an 'Overview' subpart''')),
+ validators=[Optional()],
+ render_kw={
+ "class": "form-control",
+ "spellcheck": "false",
+ },
)
disclaimer = TextAreaField(
- gettext(
- "Type the DISCLAIMER.md file content, which list warnings and attention points."
- ),
- validators=[Optional()],
- render_kw={
- "class": "form-control",
- "spellcheck": "false",
- },
+ lazy_gettext("Type the DISCLAIMER.md file content, which list warnings and attention points."),
+ validators=[Optional()],
+ render_kw={
+ "class": "form-control",
+ "spellcheck": "false",
+ },
)
pre_install = TextAreaField(
- gettext("Type the PRE_INSTALL.md file content"),
- validators=[Optional()],
- render_kw={
- "class": "form-control",
- "spellcheck": "false",
- },
+ lazy_gettext("Type the PRE_INSTALL.md file content"),
+ validators=[Optional()],
+ render_kw={
+ "class": "form-control",
+ "spellcheck": "false",
+ },
)
post_install = TextAreaField(
- gettext("Type the POST_INSTALL.md file content"),
- validators=[Optional()],
- render_kw={
- "class": "form-control",
- "spellcheck": "false",
- },
+ lazy_gettext("Type the POST_INSTALL.md file content"),
+ validators=[Optional()],
+ render_kw={
+ "class": "form-control",
+ "spellcheck": "false",
+ },
)
pre_upgrade = TextAreaField(
- gettext("Type the PRE_UPGRADE.md file content"),
- validators=[Optional()],
- render_kw={
- "class": "form-control",
- "spellcheck": "false",
- },
+ lazy_gettext("Type the PRE_UPGRADE.md file content"),
+ validators=[Optional()],
+ render_kw={
+ "class": "form-control",
+ "spellcheck": "false",
+ },
)
post_upgrade = TextAreaField(
- gettext("Type the POST_UPGRADE.md file content"),
- validators=[Optional()],
- render_kw={
- "class": "form-control",
- "spellcheck": "false",
- },
+ lazy_gettext("Type the POST_UPGRADE.md file content"),
+ validators=[Optional()],
+ render_kw={
+ "class": "form-control",
+ "spellcheck": "false",
+ },
)
admin = TextAreaField(
- gettext("Type the ADMIN.md file content"),
- validators=[Optional()],
- render_kw={
- "class": "form-control",
- "spellcheck": "false",
- },
+ lazy_gettext("Type the ADMIN.md file content"),
+ validators=[Optional()],
+ render_kw={
+ "class": "form-control",
+ "spellcheck": "false",
+ },
)
-
class MoreAdvanced(FlaskForm):
enable_change_url = BooleanField(
- gettext("Handle app install URL change (change_url script)"),
+ lazy_gettext("Handle app install URL change (change_url script)"),
default=True,
render_kw={
- "title": gettext(
- "Should changing the app URL be allowed ? (change_url change)"
- )
+ "title": lazy_gettext("Should changing the app URL be allowed ? (change_url change)")
},
)
use_logrotate = BooleanField(
- gettext("Use logrotate for the app logs"),
+ lazy_gettext("Use logrotate for the app logs"),
default=True,
render_kw={
- "title": gettext(
- "If the app generates logs, this option permit to handle their archival. Recommended."
- )
+ "title": lazy_gettext("If the app generates logs, this option permit to handle their archival. Recommended.")
},
)
# TODO : specify custom log file
# custom_log_file = "/var/log/$app/$app.log" "/var/log/nginx/${domain}-error.log"
use_fail2ban = BooleanField(
- gettext("Protect the application against brute force attacks (via fail2ban)"),
+ lazy_gettext("Protect the application against brute force attacks (via fail2ban)"),
default=False,
render_kw={
- "title": gettext(
- "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."
- )
+ "title": lazy_gettext("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(
- gettext("Add a CRON task for this application"),
- description=gettext("Corresponds to some app periodic operations"),
+ lazy_gettext("Add a CRON task for this application"),
+ description=lazy_gettext("Corresponds to some app periodic operations"),
default=False,
)
cron_config_file = TextAreaField(
- gettext("Type the CRON file content"),
+ lazy_gettext("Type the CRON file content"),
validators=[Optional()],
render_kw={
"class": "form-control",
@@ -611,59 +586,38 @@ class MoreAdvanced(FlaskForm):
)
fail2ban_regex = StringField(
- gettext("Regular expression for fail2ban"),
+ lazy_gettext("Regular expression for fail2ban"),
# Regex to match into the log for a failed login
validators=[Optional()],
render_kw={
- "placeholder": gettext("A regular expression"),
+ "placeholder": lazy_gettext("A regular expression"),
"class": "form-control",
- "title": gettext(
- "Regular expression to check in the log file to activate failban (search for a line that indicates a credentials error)."
- ),
+ "title": lazy_gettext("Regular expression to check in the log file to activate failban (search for a line that indicates a credentials error)."),
},
)
## Main form
class GeneratorForm(
- GeneralInfos,
- IntegrationInfos,
- UpstreamInfos,
- InstallQuestions,
- Resources,
- SpecificTechnology,
- AppConfig,
- Documentation,
- MoreAdvanced,
+ GeneralInfos, IntegrationInfos, UpstreamInfos, InstallQuestions, Ressources, SpecificTechnology, AppConfig, Documentation, MoreAdvanced
):
class Meta:
csrf = False
generator_mode = SelectField(
- gettext("Generator mode"),
- description=gettext(
- "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", gettext("Streamlined version")),
- ("tutorial", gettext("Tutorial version")),
- ],
+ lazy_gettext("Generator mode"),
+ description=lazy_gettext("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"))],
default="true",
validators=[DataRequired()],
)
- submit_preview = SubmitField(gettext("Previsualise"))
- submit_download = SubmitField(gettext("Download the .zip"))
- submit_demo = SubmitField(
- gettext("Fill with demo values"),
- render_kw={
- "onclick": "fillFormWithDefaultValues()",
- "title": gettext(
- "Generate a complete and functionnal minimalistic app that you can iterate from"
- ),
- },
- )
+ submit_preview = SubmitField(lazy_gettext("Previsualise"))
+ submit_download = SubmitField(lazy_gettext("Download the .zip"))
+ submit_demo = SubmitField(lazy_gettext('Fill with demo values'), render_kw={"onclick": "fillFormWithDefaultValues()",
+ "title": lazy_gettext("Generate a complete and functionnal minimalistic app that you can iterate from")
+ })
#### Web pages
@@ -673,6 +627,7 @@ def main_form_route():
main_form = GeneratorForm()
app_files = []
+
if request.method == "POST":
if not main_form.validate_on_submit():
@@ -680,16 +635,13 @@ def main_form_route():
print(main_form.errors)
return render_template(
- "index.html",
- main_form=main_form,
- generator_info=GENERATOR_DICT,
- generated_files={},
+ "index.html", main_form=main_form, generator_info=GENERATOR_DICT, generated_files={}
)
if main_form.submit_preview.data:
submit_mode = "preview"
elif main_form.submit_demo.data:
- submit_mode = "demo" # TODO : for now this always trigger a preview. Not sure if that's an issue
+ submit_mode = "demo" # TODO : for now this always trigger a preview. Not sure if that's an issue
else:
submit_mode = "download"
@@ -700,15 +652,15 @@ def main_form_route():
self.content = None
app_files = [
- AppFile("manifest", "manifest.toml"),
- AppFile("tests", "tests.toml"), # TODO test this
+ AppFile("manifest", "manifest.toml"),
+ AppFile("tests", "tests.toml"), # TODO test this
AppFile("_common.sh", "scripts/_common.sh"),
- AppFile("install", "scripts/install"),
- AppFile("remove", "scripts/remove"),
- AppFile("backup", "scripts/backup"),
- AppFile("restore", "scripts/restore"),
- AppFile("upgrade", "scripts/upgrade"),
- AppFile("nginx", "conf/nginx.conf"),
+ AppFile("install", "scripts/install"),
+ AppFile("remove", "scripts/remove"),
+ AppFile("backup", "scripts/backup"),
+ AppFile("restore", "scripts/restore"),
+ AppFile("upgrade", "scripts/upgrade"),
+ AppFile("nginx", "conf/nginx.conf"),
]
if main_form.enable_change_url.data:
@@ -719,7 +671,7 @@ def main_form_route():
# TODO : buggy, tries to open php.j2
# if main_form.main_technology.data == "php":
- # app_files.append(AppFile("php", "conf/extra_php-fpm.conf"))
+ # app_files.append(AppFile("php", "conf/extra_php-fpm.conf"))
if main_form.description.data:
app_files.append(AppFile("DESCRIPTION", "docs/DESCRIPTION.md"))
@@ -745,17 +697,13 @@ def main_form_route():
template_dir = os.path.dirname(__file__) + "/templates/"
for app_file in app_files:
template = open(template_dir + app_file.id + ".j2").read()
- app_file.content = render_template_string(
- template, data=dict(request.form | GENERATOR_DICT)
- )
- app_file.content = re.sub(r"\n\s+$", "\n", app_file.content, flags=re.M)
- app_file.content = re.sub(r"\n{3,}", "\n\n", app_file.content, flags=re.M)
+ app_file.content = render_template_string(template, data=dict(request.form | GENERATOR_DICT))
+ app_file.content = re.sub(r'\n\s+$', '\n', app_file.content, flags=re.M)
+ app_file.content = re.sub(r'\n{3,}', '\n\n', app_file.content, flags=re.M)
print(main_form.use_custom_config_file.data)
if main_form.use_custom_config_file.data:
- app_files.append(
- AppFile("appconf", "conf/" + main_form.custom_config_file.data)
- )
+ app_files.append(AppFile("appconf", "conf/" + main_form.custom_config_file.data))
app_files[-1].content = main_form.custom_config_file_content.data
print(main_form.custom_config_file.data)
print(main_form.custom_config_file_content.data)
@@ -771,26 +719,19 @@ def main_form_route():
zf.writestr(app_file.destination_path, app_file.content)
f.seek(0)
# Send the zip file to the user
- return send_file(
- f, as_attachment=True, download_name=request.form["app_id"] + ".zip"
- )
+ return send_file(f, as_attachment=True, download_name=request.form["app_id"] + ".zip")
return render_template(
- "index.html",
- main_form=main_form,
- generator_info=GENERATOR_DICT,
- generated_files=app_files,
+ "index.html", main_form=main_form, generator_info=GENERATOR_DICT, generated_files=app_files,
)
-
# Localisation
-@app.route("/language/")
+@app.route('/language/')
def set_language(language=None):
- response = make_response(redirect(request.referrer or "/"))
- response.set_cookie("lang", language)
+ response = make_response(redirect(request.referrer or '/'))
+ response.set_cookie('lang', language)
return response
-
#### Running the web server
if __name__ == "__main__":
app.run(debug=True)