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

Format Python code with Black (#2252)

Co-authored-by: tituspijean <8769166+tituspijean@users.noreply.github.com>
This commit is contained in:
github-actions[bot] 2024-04-23 20:05:53 +02:00 committed by GitHub
parent 957db5114b
commit c52b2aaf77
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -63,32 +63,34 @@ cors = CORS(app)
environment = j2.Environment(loader=j2.FileSystemLoader("templates/"))
# Handle translations
BABEL_TRANSLATION_DIRECTORIES='translations'
BABEL_TRANSLATION_DIRECTORIES = "translations"
babel = Babel()
LANGUAGES = {
'en': gettext('English'),
'fr': gettext('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'
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
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)
@ -119,22 +121,22 @@ 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'
choices=[("none", "")] + [language for language in LANGUAGES.items()],
default=["en"],
id="selectLanguage",
)
class GeneralInfos(FlaskForm):
app_id = StringField(
Markup(
lazy_gettext("Application identifier (id)")
),
Markup(lazy_gettext("Application identifier (id)")),
description=lazy_gettext("Small caps and without spaces"),
validators=[DataRequired(), Regexp("[a-z_1-9]+.*(?<!_ynh)$")],
render_kw={
@ -144,7 +146,9 @@ class GeneralInfos(FlaskForm):
app_name = StringField(
lazy_gettext("App name"),
description=lazy_gettext("It's the application name, displayed in the user interface"),
description=lazy_gettext(
"It's the application name, displayed in the user interface"
),
validators=[DataRequired()],
render_kw={
"placeholder": "My super App",
@ -153,12 +157,16 @@ class GeneralInfos(FlaskForm):
description_en = StringField(
lazy_gettext("Short description (en)"),
description=lazy_gettext("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"),
description=lazy_gettext(
"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("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"),
description=lazy_gettext(
"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()],
)
@ -174,12 +182,16 @@ class IntegrationInfos(FlaskForm):
maintainers = StringField(
lazy_gettext("Maintener of the generated app"),
description=lazy_gettext("Commonly you put your name here... If you agree with it ;)")
description=lazy_gettext(
"Commonly you put your name here... If you agree with it ;)"
),
)
yunohost_required_version = StringField(
lazy_gettext("Minimal YunoHost version"),
description=lazy_gettext("Minimal YunoHost version for the application to work"),
description=lazy_gettext(
"Minimal YunoHost version for the application to work"
),
render_kw={
"placeholder": "11.1.21",
},
@ -199,13 +211,17 @@ class IntegrationInfos(FlaskForm):
)
multi_instance = BooleanField(
lazy_gettext("The app can be installed multiple times at the same time on the same server"),
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"),
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"
),
choices=[
("false", lazy_gettext("No")),
("true", lazy_gettext("Yes")),
@ -216,7 +232,9 @@ class IntegrationInfos(FlaskForm):
)
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)"),
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)"
),
choices=[
("false", lazy_gettext("Yes")),
("true", lazy_gettext("No")),
@ -231,7 +249,9 @@ class UpstreamInfos(FlaskForm):
license = StringField(
lazy_gettext("Licence"),
description=lazy_gettext("You should check this on the upstream repository. The expected format is a SPDX id listed in https://spdx.org/licenses/"),
description=lazy_gettext(
"You should check this on the upstream repository. The expected format is a SPDX id listed in https://spdx.org/licenses/"
),
validators=[DataRequired()],
)
@ -275,21 +295,31 @@ 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)"),
lazy_gettext(
"Ask the URL where the app will be installed ('domain' and 'path' variables)"
),
default="true",
choices=[
("true", lazy_gettext("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)"))
(
"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)")),
],
)
init_main_permission = BooleanField(
lazy_gettext("Ask who can access to the app"),
description=lazy_gettext("In the users groups : by default at least 'visitors', 'all_users' et 'admins' exists. (It was previously the private/public app concept)"),
description=lazy_gettext(
"In the users groups : by default at least 'visitors', 'all_users' et 'admins' exists. (It was previously the private/public app concept)"
),
default=True,
)
@ -320,11 +350,9 @@ class InstallQuestions(FlaskForm):
)
# manifest
class Ressources(FlaskForm):
# Sources
source_url = StringField(
lazy_gettext("Application source code or executable"),
@ -343,7 +371,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"),
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"
),
default="none",
choices=[
("none", "Non"),
@ -363,7 +393,9 @@ class Ressources(FlaskForm):
)
apt_dependencies = StringField(
lazy_gettext("Dependances to be installed via apt (separated by a quote and/or spaces)"),
lazy_gettext(
"Dependances to be installed via apt (separated by a quote and/or spaces)"
),
render_kw={
"placeholder": "foo, bar2.1-ext, libwat",
},
@ -415,11 +447,11 @@ class SpecificTechnology(FlaskForm):
install_snippet = TextAreaField(
lazy_gettext("Installation specific commands"),
description=lazy_gettext("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"),
description=lazy_gettext(
"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()],
render_kw={
"spellcheck": "false"
}
render_kw={"spellcheck": "false"},
)
#
@ -428,7 +460,9 @@ class SpecificTechnology(FlaskForm):
use_composer = BooleanField(
lazy_gettext("Use composer"),
description=lazy_gettext("Composer is a PHP dependencies manager used by some apps"),
description=lazy_gettext(
"Composer is a PHP dependencies manager used by some apps"
),
default=False,
)
@ -453,7 +487,9 @@ class SpecificTechnology(FlaskForm):
systemd_execstart = StringField(
lazy_gettext("Command to start the app daemon (from systemd service)"),
description=lazy_gettext("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"),
description=lazy_gettext(
"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={
"placeholder": "__INSTALL_DIR__/bin/app --some-option",
},
@ -464,7 +500,9 @@ class AppConfig(FlaskForm):
use_custom_config_file = BooleanField(
lazy_gettext("The app uses a specific configuration file"),
description=lazy_gettext("Usually : .env, config.json, conf.ini, params.yml, ..."),
description=lazy_gettext(
"Usually : .env, config.json, conf.ini, params.yml, ..."
),
default=False,
)
@ -478,18 +516,23 @@ class AppConfig(FlaskForm):
custom_config_file_content = TextAreaField(
lazy_gettext("App configuration file pattern"),
description=lazy_gettext("In this pattern, you can use the syntax __FOO_BAR__ which will automatically replaced by the value of the variable $foo_bar"),
description=lazy_gettext(
"In this pattern, you can use the syntax __FOO_BAR__ which will automatically replaced by the value of the variable $foo_bar"
),
validators=[Optional()],
render_kw={
"spellcheck": "false"
}
render_kw={"spellcheck": "false"},
)
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''')),
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"""
)
),
validators=[Optional()],
render_kw={
"class": "form-control",
@ -497,7 +540,9 @@ Do not give the software name at the beginning, as it will be integrated an 'Ove
},
)
disclaimer = TextAreaField(
lazy_gettext("Type the DISCLAIMER.md file content, which list warnings and attention points."),
lazy_gettext(
"Type the DISCLAIMER.md file content, which list warnings and attention points."
),
validators=[Optional()],
render_kw={
"class": "form-control",
@ -545,13 +590,16 @@ 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)"),
default=True,
render_kw={
"title": lazy_gettext("Should changing the app URL be allowed ? (change_url change)")
"title": lazy_gettext(
"Should changing the app URL be allowed ? (change_url change)"
)
},
)
@ -559,16 +607,22 @@ class MoreAdvanced(FlaskForm):
lazy_gettext("Use logrotate for the app logs"),
default=True,
render_kw={
"title": lazy_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(
lazy_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": 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.")
"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(
@ -592,14 +646,24 @@ class MoreAdvanced(FlaskForm):
render_kw={
"placeholder": lazy_gettext("A regular expression"),
"class": "form-control",
"title": lazy_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, Ressources, SpecificTechnology, AppConfig, Documentation, MoreAdvanced
GeneralInfos,
IntegrationInfos,
UpstreamInfos,
InstallQuestions,
Ressources,
SpecificTechnology,
AppConfig,
Documentation,
MoreAdvanced,
):
class Meta:
@ -607,17 +671,28 @@ class GeneratorForm(
generator_mode = SelectField(
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"))],
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(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")
})
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
@ -627,7 +702,6 @@ def main_form_route():
main_form = GeneratorForm()
app_files = []
if request.method == "POST":
if not main_form.validate_on_submit():
@ -635,7 +709,10 @@ 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:
@ -697,13 +774,17 @@ 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)
@ -719,19 +800,26 @@ 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 render_template(
"index.html", main_form=main_form, generator_info=GENERATOR_DICT, generated_files=app_files,
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,
)
# Localisation
@app.route('/language/<language>')
@app.route("/language/<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)