# SPDX-License-Identifier: AGPL-3.0-or-later # Hydrilla&Haketilo website logic. # # Copyright (C) 2021, 2022 Wojtek Kosior # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. # # # I, Wojtek Kosior, thereby promise not to sue for violation of this # file's license. Although I request that you do not make use of this # code in a proprietary program, I am not going to enforce this in # court. import gettext import dataclasses as dc import typing as t from pathlib import Path import flask import werkzeug import itsdangerous import jinja2 from . import common_jinja_templates here = Path(__file__).resolve().parent supported_locales = {'en_US', 'pl_PL'} default_locale = 'en_US' def choose_locale() -> None: app = t.cast(HydrillaWebsite, flask.current_app) user_chosen_locale = flask.request.cookies.get('chosen-locale') if user_chosen_locale not in supported_locales: user_chosen_locale = None if user_chosen_locale is None: best_locale_match = flask.request.accept_languages.best_match( supported_locales, default = default_locale ) if best_locale_match is None: app._hydrilla_request_locale = default_locale else: app._hydrilla_request_locale = best_locale_match else: app._hydrilla_request_locale = user_chosen_locale translations = gettext.translation( 'messages', localedir = here / 'locales', languages = [app._hydrilla_request_locale] ) app.jinja_env.install_gettext_translations(translations) @dc.dataclass(init=False) class HydrillaWebsite(flask.Flask): _hydrilla_request_locale: str def __init__(self) -> None: super().__init__(__name__) loaders = [jinja2.PackageLoader(__package__)] combined_loader = common_jinja_templates.combine_with_loaders(loaders) self.jinja_options = { **self.jinja_options, 'loader': combined_loader, 'autoescape': jinja2.select_autoescape(['.jinja']), 'lstrip_blocks': True, 'extensions': [ *self.jinja_options.get('extensions', []), 'jinja2.ext.i18n', 'jinja2.ext.do' ] } self.before_request(choose_locale) website_app = HydrillaWebsite() @website_app.route('/', methods=['GET']) def main() -> str: return flask.render_template( 'index.html.jinja', locale_serializer = itsdangerous.Serializer(secret, salt='set_locale') ) @website_app.route('/favicon.ico', methods=['GET']) def favicon() -> str: return flask.send_file('static/haketilo-favicon.ico') @website_app.route('/downloads', methods=['GET']) def downloads() -> str: return flask.render_template('downloads.html.jinja') @website_app.route('/set-lang', methods=['POST']) def set_locale() -> werkzeug.Response: serializer = itsdangerous.Serializer(secret, salt='set_locale') new_locale = serializer.loads(flask.request.form['lang_code']) response = flask.redirect(flask.url_for('main') + '#langs', code=303) response.set_cookie(key='chosen-locale', value=new_locale, path='/') return response secret = 'not-so-secret' def set_secret(new_secret: str) -> None: global secret secret = new_secret