diff options
author | Wojtek Kosior <koszko@koszko.org> | 2022-10-31 22:19:18 +0100 |
---|---|---|
committer | Wojtek Kosior <koszko@koszko.org> | 2022-10-31 22:19:18 +0100 |
commit | 9b01180ec981d6d0ffd7b0e84a3ddbb0a2cf1ecc (patch) | |
tree | 66ec7089fca89fcaa4f769cc74cf12e783968ea9 /src/hydrilla/proxy | |
parent | f1638c63de7c27c2fdccb55f4b540c8fb79d3762 (diff) | |
download | haketilo-hydrilla-9b01180ec981d6d0ffd7b0e84a3ddbb0a2cf1ecc.tar.gz haketilo-hydrilla-9b01180ec981d6d0ffd7b0e84a3ddbb0a2cf1ecc.zip |
[builder][server][proxy] complete internationalization and add polish translation
Diffstat (limited to 'src/hydrilla/proxy')
-rw-r--r-- | src/hydrilla/proxy/policies/base.py | 25 | ||||
-rw-r--r-- | src/hydrilla/proxy/policies/misc.py | 10 | ||||
-rw-r--r-- | src/hydrilla/proxy/policies/payload.py | 2 | ||||
-rw-r--r-- | src/hydrilla/proxy/policies/rule.py | 6 | ||||
-rw-r--r-- | src/hydrilla/proxy/state.py | 2 | ||||
-rw-r--r-- | src/hydrilla/proxy/state_impl/concrete_state.py | 26 | ||||
-rw-r--r-- | src/hydrilla/proxy/web_ui/root.py | 40 | ||||
-rw-r--r-- | src/hydrilla/proxy/web_ui/templates/index.html.jinja | 19 |
8 files changed, 108 insertions, 22 deletions
diff --git a/src/hydrilla/proxy/policies/base.py b/src/hydrilla/proxy/policies/base.py index 95021cd..967e2c4 100644 --- a/src/hydrilla/proxy/policies/base.py +++ b/src/hydrilla/proxy/policies/base.py @@ -43,7 +43,7 @@ import jinja2 from immutables import Map -from ...translations import translation as make_translation +from ... import translations from ... import url_patterns from ... import common_jinja_templates from .. import state @@ -62,14 +62,9 @@ _jinja_info_env = jinja2.Environment( lstrip_blocks = True, extensions = ['jinja2.ext.i18n', 'jinja2.ext.do'] ) -_jinja_info_env.install_gettext_translations(make_translation()) # type: ignore _jinja_info_env.globals['url_patterns'] = url_patterns _jinja_info_lock = threading.Lock() -def get_info_template(template_file_name: str) -> jinja2.Template: - with _jinja_info_lock: - return _jinja_info_env.get_template(template_file_name) - _jinja_script_loader = jinja2.PackageLoader( __package__, @@ -164,6 +159,20 @@ class Policy(ABC): return (self.current_popup_settings.popup_enabled and http_messages.is_likely_a_page(request_info, response_info)) + def _get_info_template(self, template_file_name: str) -> jinja2.Template: + with _jinja_info_lock: + chosen_locale = self.haketilo_settings.locale + if chosen_locale not in translations.supported_locales: + chosen_locale = None + + if chosen_locale is None: + chosen_locale = translations.default_locale + + trans = translations.translation(chosen_locale) + _jinja_info_env.install_gettext_translations(trans) # type: ignore + return _jinja_info_env.get_template(template_file_name) + + def _csp_to_clear(self, http_info: http_messages.FullHTTPInfo) \ -> t.Union[t.Sequence[str], t.Literal['all']]: return () @@ -215,7 +224,9 @@ class Policy(ABC): popup_page = self.make_info_page(http_info) if popup_page is None: - template = get_info_template('special_page_info.html.jinja') + template = self._get_info_template( + 'special_page_info.html.jinja' + ) popup_page = template.render( url = http_info.request_info.url.orig_url ) diff --git a/src/hydrilla/proxy/policies/misc.py b/src/hydrilla/proxy/policies/misc.py index 0ff4596..e789b29 100644 --- a/src/hydrilla/proxy/policies/misc.py +++ b/src/hydrilla/proxy/policies/misc.py @@ -47,7 +47,9 @@ class FallbackAllowPolicy(AllowPolicy): def make_info_page(self, http_info: http_messages.FullHTTPInfo) \ -> t.Optional[str]: - template = base.get_info_template('js_fallback_allowed_info.html.jinja') + template = self._get_info_template( + 'js_fallback_allowed_info.html.jinja' + ) return template.render(url=http_info.request_info.url.orig_url) @@ -56,7 +58,9 @@ class FallbackBlockPolicy(BlockPolicy): def make_info_page(self, http_info: http_messages.FullHTTPInfo) \ -> t.Optional[str]: - template = base.get_info_template('js_fallback_blocked_info.html.jinja') + template = self._get_info_template( + 'js_fallback_blocked_info.html.jinja' + ) return template.render(url=http_info.request_info.url.orig_url) @@ -71,7 +75,7 @@ class ErrorBlockPolicy(BlockPolicy): def make_info_page(self, http_info: http_messages.FullHTTPInfo) \ -> t.Optional[str]: - template = base.get_info_template('js_error_blocked_info.html.jinja') + template = self._get_info_template('js_error_blocked_info.html.jinja') return template.render( url = http_info.request_info.url.orig_url, settings = self.haketilo_settings, diff --git a/src/hydrilla/proxy/policies/payload.py b/src/hydrilla/proxy/policies/payload.py index 55851cc..3660eac 100644 --- a/src/hydrilla/proxy/policies/payload.py +++ b/src/hydrilla/proxy/policies/payload.py @@ -175,7 +175,7 @@ class PayloadInjectPolicy(PayloadAwarePolicy): def make_info_page(self, http_info: http_messages.FullHTTPInfo) \ -> t.Optional[str]: - return base.get_info_template('payload_info.html.jinja').render( + return self._get_info_template('payload_info.html.jinja').render( url = http_info.request_info.url.orig_url, payload_data = self.payload_data ) diff --git a/src/hydrilla/proxy/policies/rule.py b/src/hydrilla/proxy/policies/rule.py index 1f39295..e318a7f 100644 --- a/src/hydrilla/proxy/policies/rule.py +++ b/src/hydrilla/proxy/policies/rule.py @@ -69,7 +69,8 @@ class RuleAllowPolicy(AllowPolicy): def make_info_page(self, http_info: http_messages.FullHTTPInfo) \ -> t.Optional[str]: - return base.get_info_template('js_rule_allowed_info.html.jinja').render( + template = self._get_info_template('js_rule_allowed_info.html.jinja') + return template.render( url = http_info.request_info.url.orig_url, pattern = self.pattern.orig_url ) @@ -81,7 +82,8 @@ class RuleBlockPolicy(BlockPolicy): def make_info_page(self, http_info: http_messages.FullHTTPInfo) \ -> t.Optional[str]: - return base.get_info_template('js_rule_blocked_info.html.jinja').render( + template = self._get_info_template('js_rule_blocked_info.html.jinja') + return template.render( url = http_info.request_info.url.orig_url, pattern = self.pattern.orig_url ) diff --git a/src/hydrilla/proxy/state.py b/src/hydrilla/proxy/state.py index 72eaaa0..1a2d344 100644 --- a/src/hydrilla/proxy/state.py +++ b/src/hydrilla/proxy/state.py @@ -544,6 +544,7 @@ class HaketiloGlobalSettings: default_allow_scripts: bool advanced_user: bool repo_refresh_seconds: int + locale: t.Optional[str] default_popup_jsallowed: PopupSettings default_popup_jsblocked: PopupSettings @@ -627,6 +628,7 @@ class HaketiloState(ABC): default_allow_scripts: t.Optional[bool] = None, advanced_user: t.Optional[bool] = None, repo_refresh_seconds: t.Optional[int] = None, + locale: t.Optional[str] = None, default_popup_settings: t.Mapping[str, PopupSettings] = {} ) -> None: ... diff --git a/src/hydrilla/proxy/state_impl/concrete_state.py b/src/hydrilla/proxy/state_impl/concrete_state.py index a5c547f..e97514a 100644 --- a/src/hydrilla/proxy/state_impl/concrete_state.py +++ b/src/hydrilla/proxy/state_impl/concrete_state.py @@ -71,6 +71,14 @@ def _add_popup_settings_columns(cursor: sqlite3.Cursor) -> None: ''' ) +def _add_locale_column(cursor: sqlite3.Cursor) -> None: + cursor.execute( + ''' + ALTER TABLE general ADD COLUMN + locale VARCHAR NOT NULL DEFAULT 'unknown'; + ''' + ) + def _prepare_database(connection: sqlite3.Connection) -> None: cursor = connection.cursor() @@ -111,6 +119,7 @@ def _prepare_database(connection: sqlite3.Connection) -> None: raise HaketiloException(_('err.proxy.unknown_db_schema')) popup_settings_columns_present = False + locale_column_present = False cursor.execute("PRAGMA TABLE_INFO('general')") for __cid, name, __type, __notnull, __dflt_value, __pk \ @@ -118,16 +127,20 @@ def _prepare_database(connection: sqlite3.Connection) -> None: if name == 'default_popup_jsallowed_onkeyboard': popup_settings_columns_present = True + if name == 'locale': + locale_column_present = True + if not popup_settings_columns_present: _add_popup_settings_columns(cursor) + if not locale_column_present: + _add_locale_column(cursor) + cursor.execute('COMMIT TRANSACTION;') except: cursor.execute('ROLLBACK TRANSACTION;') raise - - cursor.execute('PRAGMA FOREIGN_KEYS;') if cursor.fetchall() == []: raise HaketiloException(_('err.proxy.no_sqlite_foreign_keys')) @@ -144,14 +157,15 @@ def load_settings(cursor: sqlite3.Cursor) -> st.HaketiloGlobalSettings: default_allow_scripts, advanced_user, repo_refresh_seconds, - mapping_use_mode + mapping_use_mode, + locale FROM general; ''' ) (default_allow_scripts, advanced_user, repo_refresh_seconds, - mapping_use_mode), = cursor.fetchall() + mapping_use_mode, locale), = cursor.fetchall() popup_settings_dict = {} @@ -181,6 +195,7 @@ def load_settings(cursor: sqlite3.Cursor) -> st.HaketiloGlobalSettings: advanced_user = advanced_user, repo_refresh_seconds = repo_refresh_seconds, mapping_use_mode = st.MappingUseMode(mapping_use_mode), + locale = locale, **popup_settings_dict ) @@ -422,6 +437,7 @@ class ConcreteHaketiloState(base.HaketiloStateWithFields): default_allow_scripts: t.Optional[bool] = None, advanced_user: t.Optional[bool] = None, repo_refresh_seconds: t.Optional[int] = None, + locale: t.Optional[str] = None, default_popup_settings: t.Mapping[str, st.PopupSettings] = {} ) -> None: with self.cursor(transaction=True) as cursor: @@ -436,6 +452,8 @@ class ConcreteHaketiloState(base.HaketiloStateWithFields): set_opt('advanced_user', advanced_user) if repo_refresh_seconds is not None: set_opt('repo_refresh_seconds', repo_refresh_seconds) + if locale is not None: + set_opt('locale', locale) for page_type in ('jsallowed', 'jsblocked', 'payloadon'): popup_settings = default_popup_settings.get(page_type) diff --git a/src/hydrilla/proxy/web_ui/root.py b/src/hydrilla/proxy/web_ui/root.py index 4915e51..6f9e349 100644 --- a/src/hydrilla/proxy/web_ui/root.py +++ b/src/hydrilla/proxy/web_ui/root.py @@ -60,6 +60,30 @@ from . import prompts from . import _app +def choose_locale() -> None: + app = t.cast(WebUIAppImpl, flask.current_app) + + user_chosen_locale = get_settings().locale + if user_chosen_locale not in translations.supported_locales: + user_chosen_locale = None + + if user_chosen_locale is None: + best_locale_match = flask.request.accept_languages.best_match( + translations.supported_locales, + default = translations.default_locale + ) + if best_locale_match is None: + app._haketilo_request_locale = translations.default_locale + else: + app._haketilo_request_locale = best_locale_match + else: + app._haketilo_request_locale = user_chosen_locale + + trans = translations.translation(app._haketilo_request_locale) + + app.jinja_env.install_gettext_translations(trans) + + def authenticate_by_referrer() -> t.Optional[werkzeug.Response]: if flask.request.method == 'GET': return None @@ -90,6 +114,8 @@ class WebUIAppImpl(_app.WebUIApp): _haketilo_blueprints: t.ClassVar[t.Sequence[flask.Blueprint]] _haketilo_ui_domain: t.ClassVar[_app.UIDomain] + _haketilo_request_locale: str + def __init__(self): super().__init__(__name__) @@ -122,6 +148,7 @@ class WebUIAppImpl(_app.WebUIApp): self.jinja_env.globals['doc_base_filename'] = 'doc_base.html.jinja' self.before_request(authenticate_by_referrer) + self.before_request(choose_locale) for bp in self._haketilo_blueprints: self.register_blueprint(bp) @@ -150,7 +177,11 @@ def home_post() -> werkzeug.Response: state = _app.get_haketilo_state() - if action == 'use_enabled': + if action == 'set_lang': + new_locale = flask.request.form['locale'] + assert new_locale in translations.supported_locales + state.update_settings(locale=new_locale) + elif action == 'use_enabled': state.update_settings(mapping_use_mode=st.MappingUseMode.WHEN_ENABLED) elif action == 'use_auto': state.update_settings(mapping_use_mode=st.MappingUseMode.AUTO) @@ -188,7 +219,9 @@ def home_doc(page: str) -> str: if page not in self_doc.page_names: flask.abort(404) - locale = translations.select_best_locale(self_doc.available_locales) + locale = t.cast(WebUIAppImpl, flask.current_app)._haketilo_request_locale + if locale not in self_doc.available_locales: + locale = translations.default_locale return flask.render_template( f'{locale}/{page}.html.jinja', @@ -241,9 +274,6 @@ def process_request( with app._haketilo_app_lock: app._haketilo_state = state - best_translations = translations.translation() - app.jinja_env.install_gettext_translations(best_translations) - flask_response = app.test_client().open( path = path, base_url = request_info.url.url_without_path, diff --git a/src/hydrilla/proxy/web_ui/templates/index.html.jinja b/src/hydrilla/proxy/web_ui/templates/index.html.jinja index 1e498a3..fe9c5d5 100644 --- a/src/hydrilla/proxy/web_ui/templates/index.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/index.html.jinja @@ -73,6 +73,25 @@ code in a proprietary work, I am not going to enforce this in court. {{ _('web_ui.home.heading.options') }} </h4> + {{ label(_('web_ui.home.choose_language_label')) }} + + {% call unordered_list() %} + {% + for lang_name, lang_code in [ + ('english', 'en_US'), + ('polski', 'pl_PL') + ] + %} + {% call list_entry() %} + <form method="POST" class="inline"> + <input type="hidden" name="action" value="set_lang"> + <input type="hidden" name="locale" value="{{ lang_code }}"> + <button>{{ lang_name }}</button> + </form> + {% endcall %} + {% endfor %} + {% endcall %} + {% call label(_('web_ui.home.mapping_usage_mode_label')) %} {{ hkt_doc_link('packages') }} {% endcall %} |