diff --git a/app.py b/app.py
index 72e752b..7db269e 100644
--- a/app.py
+++ b/app.py
@@ -1,8 +1,62 @@
from os import system as console
-from flask import Flask, render_template
+from configparser import ConfigParser
+from flask import (
+ Flask,
+ g,
+ request,
+ render_template,
+)
+
+
+translations_cache = {}
+
+def load_translations(lang):
+ if lang not in translations_cache:
+ translations_cache[lang] = {}
+
+ try:
+ config = ConfigParser()
+ config.read(f'locale/{lang}.ini')
+ for section in config.sections():
+ translations_cache[lang][section] = dict(config.items(section))
+ except:
+ pass
+
+ return translations_cache[lang]
+
+
+def get_locale():
+ return request.accept_languages.best_match(('en', 'ru', 'de', 'fr', 'ja'), 'en')
app = Flask(__name__)
+
+@app.before_request
+def before_request():
+ g.locale = get_locale()
+ g.translations = load_translations(g.locale)
+
+
+@app.context_processor
+def inject_translations():
+ def translate(text, **kwargs):
+ if ":" in text:
+ section, key = text.split(":", 1)
+ else:
+ section, key = "common", text
+
+ template = g.translations \
+ .get(section, {}) \
+ .get(key, f"${section}: {key}$")
+
+ try:
+ return template.format(**kwargs)
+ except:
+ return template
+
+ return {'_': translate}
+
+
if app.debug:
console("sass static/style/main.scss static/style/main.css")
diff --git a/locale/de.ini b/locale/de.ini
new file mode 100644
index 0000000..5a49932
--- /dev/null
+++ b/locale/de.ini
@@ -0,0 +1,23 @@
+[common]
+site source = Website-Quellcode
+contact us = Kontakt
+
+about us = Über uns
+about host = Über Server
+
+
+[index]
+bottom_text = Außerdem bieten wir {glitchtip}, {baikal} und {freshrss} für Mitglieder unserer Gruppe an!
+
+[index.descr]
+sharkey = Föderierter Microblogging-Dienst auf Basis des ActivityPub-Protokolls
+gitea = Open-Source, selbst gehosteter Git-Repository-Hoster
+matrix = Föderierter Messenger
+copyparty = Cloud-Dateispeicher
+4get = Proxy-Suchmaschine
+
+
+[host]
+hoster = Hosting-Anbieter
+specifications = Spezifikationen
+hoster_descr = Nicht schlecht, nicht teuer. In der Vergangenheit gab es Netzwerkprobleme.
\ No newline at end of file
diff --git a/locale/en.ini b/locale/en.ini
new file mode 100644
index 0000000..7355687
--- /dev/null
+++ b/locale/en.ini
@@ -0,0 +1,23 @@
+[common]
+site source = Site source
+contact us = Contact us
+
+about us = About us
+about host = About host
+
+
+[index]
+bottom_text = We also have {glitchtip}, {baikal} and {freshrss} for members of our squad!
+
+[index.descr]
+sharkey = ActivityPub-based federated microblogging service
+gitea = Opensource selfhosted Git repository hosting
+matrix = federated instant messenger
+copyparty = cloud file storage
+4get = proxy search engine
+
+
+[host]
+hoster = Hosting Provider
+specifications = Specifications
+hoster_descr = Not bad, not expensive. There were network issues in the past
diff --git a/locale/fr.ini b/locale/fr.ini
new file mode 100644
index 0000000..7d3dc56
--- /dev/null
+++ b/locale/fr.ini
@@ -0,0 +1,23 @@
+[common]
+site source = Code source du site
+contact us = Contacte-nous
+
+about us = À propos de nous
+about host = À propos de serveur
+
+
+[index]
+bottom_text = On a aussi {glitchtip}, {baikal} et {freshrss} pour les membres du groupe !
+
+[index.descr]
+sharkey = Service de microblogging fédéré avec ActivityPub
+gitea = Hébergement de dépôts Git open source en auto-hébergé
+matrix = Messagerie fédérée
+copyparty = Stockage de fichiers en cloud
+4get = Moteur de recherche proxy
+
+
+[host]
+hoster = Hébergeur
+specifications = Spécifications
+hoster_descr = Pas mal, pas cher. Y'a eu des soucis réseau avant.
\ No newline at end of file
diff --git a/locale/ja.ini b/locale/ja.ini
new file mode 100644
index 0000000..ab49619
--- /dev/null
+++ b/locale/ja.ini
@@ -0,0 +1,23 @@
+[common]
+site source = サイトのソースコード
+contact us = 問い合わせ
+
+about us = 私たちについて
+about host = サーバーについて
+
+
+[index]
+bottom_text = メンバーには {glitchtip}、{baikal}、{freshrss} も使えるよ!
+
+[index.descr]
+sharkey = ActivityPubを使った連合型マイクロブログ
+gitea = オープンソースのセルフホスティングGitリポジトリ
+matrix = 連合型メッセンジャー
+copyparty = クラウドファイルストレージ
+4get = プロキシ検索エンジン
+
+
+[host]
+hoster = ホスティングプロバイダー
+specifications = サーバーのスペック
+hoster_descr = 悪くないし安い。前にネットワークの不具合があったんだ。
diff --git a/locale/ru.ini b/locale/ru.ini
new file mode 100644
index 0000000..0d4c9e8
--- /dev/null
+++ b/locale/ru.ini
@@ -0,0 +1,23 @@
+[common]
+site source = Исходники сайта
+contact us = Для связи
+
+about us = О нас
+about host = О хосте
+
+
+[index]
+bottom_text = Ещё у нас есть {glitchtip}, {baikal} и {freshrss} для участников нашей группы!
+
+[index.descr]
+sharkey = Федеративная микроблогинговая система поверх протокола ActivityPub
+gitea = Selfhosted хранилище Git-репозиториев со свободным исходным кодом
+matrix = федеративный мессенджер
+copyparty = облачное хранилище файлов
+4get = прокси-поисковик
+
+
+[host]
+hoster = Хостер
+specifications = Характеристики
+hoster_descr = Неплохой, недорогой. В прошлом были проблемы с сетью
diff --git a/static/font/PixelMPlus/Bold.ttf b/static/font/PixelMPlus/Bold.ttf
new file mode 100644
index 0000000..7c0a1fe
Binary files /dev/null and b/static/font/PixelMPlus/Bold.ttf differ
diff --git a/static/font/PixelMPlus/LICENSE_E b/static/font/PixelMPlus/LICENSE_E
new file mode 100644
index 0000000..3e6f89c
--- /dev/null
+++ b/static/font/PixelMPlus/LICENSE_E
@@ -0,0 +1,16 @@
+M+ FONTS Copyright (C) 2002-2013 M+ FONTS PROJECT
+
+-
+
+LICENSE_E
+
+
+
+
+These fonts are free software.
+Unlimited permission is granted to use, copy, and distribute them, with
+or without modification, either commercially or noncommercially.
+THESE FONTS ARE PROVIDED "AS IS" WITHOUT WARRANTY.
+
+
+http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/
diff --git a/static/font/PixelMPlus/Regular.ttf b/static/font/PixelMPlus/Regular.ttf
new file mode 100644
index 0000000..3a7270b
Binary files /dev/null and b/static/font/PixelMPlus/Regular.ttf differ
diff --git a/static/font/SOURCES b/static/font/SOURCES
index e3705c5..6eaceb2 100644
--- a/static/font/SOURCES
+++ b/static/font/SOURCES
@@ -1,2 +1,3 @@
Monocraft: https://idreesinc.itch.io/monocraft
-Pixeloid: https://ggbot.itch.io/pixeloid-font
\ No newline at end of file
+Pixeloid: https://ggbot.itch.io/pixeloid-font
+PixelM+: https://itouhiro.hatenablog.com/entry/20130602/font
diff --git a/static/style/main.scss b/static/style/main.scss
index b12e2ea..4df3358 100644
--- a/static/style/main.scss
+++ b/static/style/main.scss
@@ -34,7 +34,7 @@ body {
display: flex;
flex-direction: column;
background-color: $base;
- font-family: Pixeloid;
+ font-family: Pixeloid, PixelMPlus;
color: $text;
width: 100%;
height: 100%;
@@ -166,3 +166,13 @@ footer {
url("/static/font/Pixeloid/otf/Sans-Bold.otf") format("opentype");
font-weight: bold;
}
+
+@font-face {
+ font-family: PixelMPlus;
+ src: url("/static/font/PixelMPlus/Regular.ttf");
+}
+@font-face {
+ font-family: PixelMPlus;
+ src: url("/static/font/PixelMPlus/Bold.ttf");
+ font-weight: bold;
+}
diff --git a/templates/footer.tmpl b/templates/footer.tmpl
index 72dae32..f44d890 100644
--- a/templates/footer.tmpl
+++ b/templates/footer.tmpl
@@ -1,5 +1,5 @@
\ No newline at end of file
diff --git a/templates/header.tmpl b/templates/header.tmpl
index 4aec285..4aa02db 100644
--- a/templates/header.tmpl
+++ b/templates/header.tmpl
@@ -1,8 +1,8 @@