2 Commits

Author SHA1 Message Date
Sweetbread c981e65c29 Move locale things into module
Docker Build and Push / build-and-push (push) Successful in 35s
2026-01-17 22:35:06 +03:00
Sweetbread e988ef6e10 Put personal pages into subdomains 2026-01-17 22:35:06 +03:00
37 changed files with 157 additions and 85 deletions
+2 -2
View File
@@ -5,5 +5,5 @@ __pycache__/
*$py.class
.python-version
static/style/*.css
static/style/*.css.map
*.css
*.css.map
+3 -3
View File
@@ -2,8 +2,8 @@ FROM node:18-alpine as sass
RUN NODE_OPTIONS=--dns-result-order=ipv4first npm install -g sass
WORKDIR /build
COPY ./static/style ./style
RUN sass ./style:./style \
COPY ./blueprints ./blueprints
RUN sass ./blueprints:./blueprints \
--no-source-map \
--style=compressed
@@ -13,7 +13,7 @@ FROM python:3.11-slim
WORKDIR /app
COPY . .
COPY --from=sass /build/style/ ./static/style/
COPY --from=sass /build/blueprints/ ./blueprints/
RUN pip install --no-cache-dir -r requirements.txt
+19 -71
View File
@@ -1,79 +1,27 @@
from os import system as console
from configparser import ConfigParser
from htmlmin import minify
from flask import (
Flask,
g,
request,
render_template,
)
from modules import locale
from blueprints.root import bp as root_bp
from blueprints.risdeveau import bp as rdv_bp
import blueprints.root.modules.style
import blueprints.risdeveau.modules.style
from flask import Flask
translations_cache = {}
app = Flask(__name__, static_folder=None, subdomain_matching=True)
def load_translations(lang):
if lang not in translations_cache:
translations_cache[lang] = {}
app.before_request(locale.before_request)
app.context_processor(locale.inject_translations)
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}
app.register_blueprint(root_bp)
app.register_blueprint(rdv_bp)
if app.debug:
console("sass static/style/main.scss static/style/main.css")
console("sass static/style/risdeveau.scss static/style/risdeveau.css")
blueprints.root.modules.style.compile_styles()
blueprints.risdeveau.modules.style.compile_styles()
@app.route("/")
def index():
return minify(render_template('index.html'), remove_empty_space=True)
@app.route("/host")
def host():
return minify(render_template('host.html'), remove_empty_space=True)
@app.route("/us")
def us():
return minify(render_template('us.html'), remove_empty_space=True)
@app.route("/risdeveau")
def risdeveau():
return minify(render_template('personal/risdeveau.html'), remove_empty_space=True)
app.config['SERVER_NAME'] = "localhost:5000"
else:
app.config['SERVER_NAME'] = "lair.moe"
+31
View File
@@ -0,0 +1,31 @@
import os
from pathlib import Path
from htmlmin import minify
from flask import Blueprint, render_template, send_from_directory, send_file, abort
bp = Blueprint(
"risdeveau",
__name__,
subdomain="risdeveau",
template_folder="..",
static_folder=None
)
def render_tmpl(filename: str) -> str:
template_path = os.path.join("risdeveau/templates", filename)
return minify(
render_template(template_path),
remove_empty_space=True
)
@bp.route("/static/<path:filename>")
def static(filename: str):
static_folders = ("static", "../root/static")
for dir in static_folders:
if os.path.exists(path := os.path.join("blueprints/risdeveau", dir, filename)):
return send_file(path)
return abort(404)
@bp.route("/")
def index():
return render_tmpl('index.html')
+9
View File
@@ -0,0 +1,9 @@
from os import system as console
from os.path import join
def compile_styles():
dir = "blueprints/risdeveau/static/style"
files = ("risdeveau",)
for file in files:
console(f"sass {join(dir, file+'.scss')} {join(dir, file+'.css')}")

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

@@ -15,7 +15,7 @@
</head>
<body>
<header>
<a href="{{ url_for('index') }}">Lair</a>
<a href="{{ url_for('root.index') }}">Lair</a>
</header>
<main>
@@ -70,17 +70,17 @@
<div class="blocks qr">
<div class="block qr">
<p>POL, BNB</p>
<img src="/static/img/risdeveau/wallets/evm.webp">
<img src="/static/img/wallets/evm.webp">
</div>
<div class="block qr">
<p>TON</p>
<img src="/static/img/risdeveau/wallets/ton.webp">
<img src="/static/img/wallets/ton.webp">
</div>
<div class="block qr">
<p>XMR</p>
<img src="/static/img/risdeveau/wallets/xmr.webp">
<img src="/static/img/wallets/xmr.webp">
</div>
</div>
</main>
+28
View File
@@ -0,0 +1,28 @@
from htmlmin import minify
from flask import Blueprint, render_template, request, jsonify
bp = Blueprint(
"root",
__name__,
template_folder="templates",
static_folder="static"
)
def render_tmpl(filename: str) -> str:
return minify(
render_template(filename),
remove_empty_space=True
)
@bp.route("/")
def index():
return render_tmpl('index.html')
@bp.route("/host")
def host():
return render_tmpl('host.html')
@bp.route("/us")
def us():
return render_tmpl('us.html')
+9
View File
@@ -0,0 +1,9 @@
from os import system as console
from os.path import join
def compile_styles():
dir = "blueprints/root/static/style"
files = ("main",)
for file in files:
console(f"sass {join(dir, file+'.scss')} {join(dir, file+'.css')}")

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

@@ -1,14 +1,14 @@
<header>
{%- if request.path != url_for('index') %}
<a href="{{ url_for('index') }}">Lair</a>
{%- if request.path != url_for('.index') %}
<a href="{{ url_for('.index') }}">Lair</a>
{%- else %}
<div></div>
{%- endif %}
<div class="header-links">
{%- for (l, t) in (
('us', _('about us')),
('host', _('about host'))
('.us', _('about us')),
('.host', _('about host'))
) %}
{%- if url_for(l) == request.path %}
<strong>{{ t }}</strong>
@@ -3,7 +3,7 @@
{% block title %}О нас{% endblock %}
{% block content %}
<a href="{{ url_for('risdeveau') }}" class="block green">
<a href="{{ url_for('risdeveau.index') }}" class="block green">
<div class="header">
<img src="/static/icon/us/risdeveau.webp" class="icon"/>
Sweetbread
+47
View File
@@ -0,0 +1,47 @@
from configparser import ConfigParser
from flask import g, request
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'),
) or 'en'
def before_request():
g.locale = get_locale()
g.translations = load_translations(g.locale)
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}