Skip to content

Feature/i18n #174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 64 commits into from
Feb 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
0f8b20c
feat: add i18n support
sMOKIK Jan 22, 2021
3cecc97
fix(i18n): correct flake8 line length errors
sMOKIK Jan 22, 2021
65db418
fix(i18n): attempt to fix build crash at get_translations_dicts() and…
sMOKIK Jan 22, 2021
feba1bb
fix(i18n): simplify check of language file path between live and testing
sMOKIK Jan 22, 2021
72f3a2b
fix(i18n): replace glob with path.glob
sMOKIK Jan 23, 2021
8d85279
fix(i18n): revert attempted code improvement
sMOKIK Jan 23, 2021
d75fd94
fix(i18n): added missing language_id to placeholder user
sMOKIK Jan 23, 2021
86925ad
fix(i18n): added simple test for home
sMOKIK Jan 23, 2021
eaf1107
fix(i18n): code review fixes
sMOKIK Jan 24, 2021
b69042d
fix(i18n): split the html result dict into two sub-dicts, "variables"…
sMOKIK Jan 25, 2021
abc7641
fix(i18n): fixed CR request to not use global state for translations
sMOKIK Jan 25, 2021
6f5728d
fix(i18n): add test to complete code coverage
sMOKIK Jan 25, 2021
e1caaa4
fix(i18n): add missing documentation
sMOKIK Jan 25, 2021
ade7c25
fix(i18n): i18n v2.0
sMOKIK Jan 26, 2021
ae49fce
fix(i18n): temporarily disable F821 errors on built-in _() function
sMOKIK Jan 26, 2021
c6a0c3b
fix(i18n): Change function name
sMOKIK Jan 26, 2021
4bf46ee
fix(i18n): change function name
sMOKIK Jan 26, 2021
c00d714
fix(i18n): add test with no language code and with invalid arguments
sMOKIK Jan 26, 2021
92b585b
fix(i18n): html and documentation fixes
sMOKIK Jan 27, 2021
f4861a8
fix(i18n): add missing documentation fixes from previous commit
sMOKIK Jan 27, 2021
80da4a1
fix(i18n): move 'jinja2.ext.i18n' extension setting to dependencies.py
sMOKIK Jan 27, 2021
0e7d2e7
fix(i18n): code review fixes
sMOKIK Jan 27, 2021
b0a1358
fix(i18n): lint error line length
sMOKIK Jan 27, 2021
5a4e5d3
fix(i18n): hopefully fix code coverage
sMOKIK Jan 27, 2021
46d078e
fix(i18n): small doc fix
sMOKIK Jan 27, 2021
b1d7d30
fix(i18n): testing if this fix works
sMOKIK Jan 27, 2021
a34d3ce
fix(i18n): another fix test
sMOKIK Jan 27, 2021
f96f221
fix(i18n): remove test, didn't work
sMOKIK Jan 27, 2021
5784a09
fix(i18n): try another method of monkeypatch
sMOKIK Jan 27, 2021
1742cb0
Merge branch 'develop' into feature/i18n
Gonzom Feb 1, 2021
4db14e7
fix(i18n): restore requirements.txt to previous version
sMOKIK Feb 1, 2021
fd69b76
fix(i18n): updated strings
sMOKIK Feb 1, 2021
fd8d122
fix(i18n): add language_id to placeholder user objects
sMOKIK Feb 1, 2021
dd4853c
fix(i18n): remove merge artifact
sMOKIK Feb 1, 2021
f13494d
fix(i18n): fix mypy issue
sMOKIK Feb 1, 2021
7228841
fix(i18n): add comments to babel_mapping.ini
sMOKIK Feb 1, 2021
c92329b
fix(i18n): add flake8 configuration file to recognize _()
sMOKIK Feb 1, 2021
a31d952
fix(i18n): add missing requirements
sMOKIK Feb 1, 2021
4f3640a
fix(i18n): add language_id to yet another placeholder user object...
sMOKIK Feb 1, 2021
ce3c06f
fix(i18n): minor fixes
sMOKIK Feb 1, 2021
090d53a
fix(i18n): update test
sMOKIK Feb 1, 2021
62d3c7f
fix(i18n): move tox.ini to correct location
sMOKIK Feb 1, 2021
efa1561
fix(i18n): attempt to get noqa to work
sMOKIK Feb 1, 2021
0798c5a
fix(i18n): attempt to get noqa to work, again
sMOKIK Feb 1, 2021
d42c5da
fix(i18n): test fix
sMOKIK Feb 1, 2021
ea0b078
fix(i18n): fix unrelated bug in invitation.py which fails tests
sMOKIK Feb 1, 2021
b5a2d76
fix(i18n): add missing module
sMOKIK Feb 1, 2021
ec04471
fix(i18n): add missing module
sMOKIK Feb 1, 2021
8339408
fix(i18n): add missing module
sMOKIK Feb 1, 2021
b0a3798
Merge branch 'develop' into feature/i18n
yammesicka Feb 2, 2021
8b314f3
Merge branch 'develop' into feature/i18n
Gonzom Feb 3, 2021
2a787d8
fix(translations-workflow): fixing conflicts, again
Gonzom Feb 3, 2021
67fc754
fix(i18n): fixing conflicts, again
Gonzom Feb 3, 2021
1f2073d
Merge remote-tracking branch 'origin/feature/i18n' into feature/i18n
Gonzom Feb 3, 2021
8abe87e
fix(i18n): small code improvement
Gonzom Feb 3, 2021
e902604
Merge branch 'develop' into feature/i18n
yammesicka Feb 5, 2021
8441cff
Merge branch 'develop' into feature/i18n
Gonzom Feb 5, 2021
c6bbfd7
fix(i18n): resolving conflicts, again
Gonzom Feb 5, 2021
23c7354
Merge branch 'develop' into feature/i18n
Gonzom Feb 7, 2021
9c30760
fix(i18n): update requirements.txt after resolving conflicts
Gonzom Feb 7, 2021
aaff170
Merge branch 'develop' into feature/i18n
Gonzom Feb 7, 2021
b1e0aff
Merge remote-tracking branch 'upstream/develop' into feature/i18n
Gonzom Feb 7, 2021
5d14a23
Merge remote-tracking branch 'origin/feature/i18n' into feature/i18n
Gonzom Feb 7, 2021
4bb7ab9
fix(i18n): resolving conflicts
Gonzom Feb 7, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/babel_mapping.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Extraction from Python source files

[python: **.py]

# Extraction from Jinja2 HTML and text templates

[jinja2: **/templates/**.html]
extensions=jinja2.ext.i18n,jinja2.ext.autoescape,jinja2.ext.with_
4 changes: 4 additions & 0 deletions app/config.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ MEDIA_DIRECTORY = 'media'
PICTURE_EXTENSION = '.png'
AVATAR_SIZE = (120, 120)


# DEFAULT WEBSITE LANGUAGE
WEBSITE_LANGUAGE = "en"

# API-KEYS
# Get a free API KEY for Astronomy feature @ www.weatherapi.com/signup.aspx
ASTRONOMY_API_KEY = os.getenv('ASTRONOMY_API_KEY')
Expand Down
9 changes: 8 additions & 1 deletion app/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class User(Base):
avatar = Column(String, default="profile.png")
telegram_id = Column(String, unique=True)
is_active = Column(Boolean, default=False)

language_id = Column(Integer, ForeignKey("languages.id"))
events = relationship("UserEvent", back_populates="participants")

def __repr__(self):
Expand Down Expand Up @@ -79,6 +79,13 @@ def __repr__(self):
return f'<Event {self.id}>'


class Language(Base):
__tablename__ = "languages"

id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True, nullable=False)


class Category(Base):
__tablename__ = "categories"

Expand Down
2 changes: 1 addition & 1 deletion app/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
from app import config
from app.internal.logger_customizer import LoggerCustomizer


APP_PATH = os.path.dirname(os.path.realpath(__file__))
MEDIA_PATH = os.path.join(APP_PATH, config.MEDIA_DIRECTORY)
STATIC_PATH = os.path.join(APP_PATH, "static")
TEMPLATES_PATH = os.path.join(APP_PATH, "templates")

templates = Jinja2Templates(directory=TEMPLATES_PATH)
templates.env.add_extension('jinja2.ext.i18n')

# Configure logger
logger = LoggerCustomizer.make_logger(config.LOG_PATH,
Expand Down
86 changes: 86 additions & 0 deletions app/internal/languages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import gettext
import os
from pathlib import Path
from typing import Any, Generator

from app import config
from app.dependencies import templates

LANGUAGE_DIR = "app/locales"
LANGUAGE_DIR_TEST = "../app/locales"
TRANSLATION_FILE = "base"


def set_ui_language(language: str = None) -> None:
"""Set the gettext translations to a given language.
If the language requested is not supported, the translations default
to the value of config.WEBSITE_LANGUAGE.

Args:
language (str, optional): a valid language code that follows RFC 1766.
Defaults to None.
See also the Language Code Identifier (LCID) Reference for a list of
valid language codes.

.. _RFC 1766:
https://tools.ietf.org/html/rfc1766.html

.. _Language Code Identifier (LCID) Reference:
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c # noqa: E501
"""

# TODO: Connect when user registration is completed.
# if not language:
# language = _get_display_language(user_id: int)

language_dir = _get_language_directory()

if language not in list(_get_supported_languages(language_dir)):
language = config.WEBSITE_LANGUAGE

translations = gettext.translation(TRANSLATION_FILE,
localedir=language_dir,
languages=[language])
translations.install()
templates.env.install_gettext_translations(translations, newstyle=True)


# TODO: Waiting for user registration. Add doc.
# def _get_display_language(user_id: int) -> str:
# # TODO: handle user language setting:
# # If user is logged in, get language setting.
# # If user is not logged in, get default site setting.
#
# if db_user:
# return db_user.language
# return config.WEBSITE_LANGUAGE


def _get_language_directory() -> str:
"""Get and return the language directory relative path.

Returns:
str: the language directory relative path.
"""
language_dir = LANGUAGE_DIR
if Path(LANGUAGE_DIR_TEST).is_dir():
# If running from test, change dir path.
language_dir = LANGUAGE_DIR_TEST
return language_dir


def _get_supported_languages(language_dir: str = _get_language_directory()) \
-> Generator[str, Any, None]:
"""Get and return a generator of supported translation languages codes.

Args:
language_dir (str, optional): the path of the language directory.
Defaults to the return value of _get_language_directory().

Returns:
Generator[str, Any, None]: a generator expression of supported
translation languages codes.
"""

paths = [Path(f.path) for f in os.scandir(language_dir) if f.is_dir()]
return (language.name for language in paths)
133 changes: 133 additions & 0 deletions app/locales/base.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Translations template for PROJECT.
# Copyright (C) 2021 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-02-01 10:21+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n"

#: app/routers/profile.py:19
msgid "Not found"
msgstr ""

#: app/templates/agenda.html:11
msgid "From"
msgstr ""

#: app/templates/agenda.html:13
msgid "to"
msgstr ""

#: app/templates/agenda.html:15
msgid "Get Agenda"
msgstr ""

#: app/templates/agenda.html:20
msgid "Today"
msgstr ""

#: app/templates/agenda.html:23
msgid "Next week"
msgstr ""

#: app/templates/agenda.html:26
msgid "Next month"
msgstr ""

#: app/templates/agenda.html:33
msgid "Start date is greater than end date"
msgstr ""

#: app/templates/agenda.html:35
msgid "No events found..."
msgstr ""

#: app/templates/base.html:18
msgid "Calendar"
msgstr ""

#: app/templates/base.html:26
msgid "Home"
msgstr ""

#: app/templates/base.html:29
msgid "Profile"
msgstr ""

#: app/templates/base.html:32
msgid "Sign in"
msgstr ""

#: app/templates/base.html:35
msgid "Sign up"
msgstr ""

#: app/templates/base.html:40
msgid "Agenda"
msgstr ""

#: app/templates/profile.html:59
msgid "Update name"
msgstr ""

#: app/templates/profile.html:66 app/templates/profile.html:88
#: app/templates/profile.html:109 app/templates/profile.html:133
msgid "Save changes"
msgstr ""

#: app/templates/profile.html:80
msgid "Update email"
msgstr ""

#: app/templates/profile.html:101
msgid "Update description"
msgstr ""

#: app/templates/profile.html:124
msgid "Update photo"
msgstr ""

#: app/templates/profile.html:176
msgid "Settings"
msgstr ""

#: app/templates/profile.html:207
msgid "Your feature"
msgstr ""

#: app/templates/profile.html:228
msgid "Upcoming event on (date)"
msgstr ""

#: app/templates/profile.html:239
msgid "The Event (event)"
msgstr ""

#: app/templates/profile.html:242
msgid "Last updated (time) ago"
msgstr ""

#: app/templates/profile.html:259
msgid "Explore MeetUps near you"
msgstr ""

#: app/templates/profile.html:268 app/templates/profile.html:277
msgid "Your Card"
msgstr ""

#. i18n: String used in testing. Do not change.
#: tests/test_language.py:32
msgid "test python translation"
msgstr ""

Binary file added app/locales/en/LC_MESSAGES/base.mo
Binary file not shown.
Loading