From 0ad6cd5d2a159e30b9c82f8603144de67afad53a Mon Sep 17 00:00:00 2001 From: lapineige Date: Sat, 13 Apr 2024 11:58:49 +0200 Subject: [PATCH] fix babel translations not loaded (v0.9.2.1) --- tools/app_generator/app_generator.py | 511 ++++++++++++--------------- 1 file changed, 226 insertions(+), 285 deletions(-) diff --git a/tools/app_generator/app_generator.py b/tools/app_generator/app_generator.py index 384f1402e..95aa40418 100644 --- a/tools/app_generator/app_generator.py +++ b/tools/app_generator/app_generator.py @@ -37,9 +37,9 @@ # 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 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 @@ 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 __init__(self, id_, destination_path=None): 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 __init__(self, id_, destination_path=None): # 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 __init__(self, id_, destination_path=None): 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 __init__(self, id_, destination_path=None): 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)