had to change folder structure but translations are ok now
This commit is contained in:
parent
8ac8e839c7
commit
8aba6f5129
92
setup.sh
92
setup.sh
|
@ -76,12 +76,11 @@ fi
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
PROJECT_DIR="steam-gift-manager"
|
PROJECT_DIR="steam-gift-manager"
|
||||||
TRANSLATIONS_DIR="$PWD/translations"
|
TRANSLATIONS_DIR="$PWD/$PROJECT_DIR/translations"
|
||||||
DATA_DIR="$PWD/data"
|
DATA_DIR="$PWD/data"
|
||||||
|
|
||||||
# 1. Create folders
|
# 1. Create folders
|
||||||
mkdir -p "$PROJECT_DIR"/{templates,static}
|
mkdir -p "$PROJECT_DIR"/{templates,static,translations}
|
||||||
mkdir -p "$TRANSLATIONS_DIR"
|
|
||||||
mkdir -p "$DATA_DIR"
|
mkdir -p "$DATA_DIR"
|
||||||
|
|
||||||
chmod -R a+rwX "$TRANSLATIONS_DIR" "$DATA_DIR"
|
chmod -R a+rwX "$TRANSLATIONS_DIR" "$DATA_DIR"
|
||||||
|
@ -200,7 +199,7 @@ app = Flask(__name__)
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
|
||||||
TRANSLATION_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'translations'))
|
TRANSLATION_DIR = os.path.join(os.path.dirname(__file__), 'translations')
|
||||||
SUPPORTED_LANGUAGES = ['de', 'en']
|
SUPPORTED_LANGUAGES = ['de', 'en']
|
||||||
TRANSLATIONS = {}
|
TRANSLATIONS = {}
|
||||||
|
|
||||||
|
@ -214,8 +213,16 @@ for lang in SUPPORTED_LANGUAGES:
|
||||||
def translate(key, lang=None, **kwargs):
|
def translate(key, lang=None, **kwargs):
|
||||||
if not lang:
|
if not lang:
|
||||||
lang = session.get('lang', 'en')
|
lang = session.get('lang', 'en')
|
||||||
value = TRANSLATIONS.get(lang, {}).get(key, key)
|
value = TRANSLATIONS.get(lang, {}).get(key)
|
||||||
return value.format(**kwargs) if kwargs else value
|
if value is None and lang != 'en':
|
||||||
|
value = TRANSLATIONS.get('en', {}).get(key, key)
|
||||||
|
else:
|
||||||
|
value = value or key
|
||||||
|
return value.format(**kwargs) if kwargs and isinstance(value, str) else value
|
||||||
|
|
||||||
|
## DEBUG Translations
|
||||||
|
if app.debug:
|
||||||
|
print(f"Loaded translations for 'de': {TRANSLATIONS.get('de', {})}")
|
||||||
|
|
||||||
csrf = CSRFProtect(app)
|
csrf = CSRFProtect(app)
|
||||||
|
|
||||||
|
@ -264,17 +271,19 @@ app.logger.setLevel(logging.INFO)
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def enforce_https():
|
def enforce_https():
|
||||||
if os.getenv('FORCE_HTTPS', 'False').lower() == 'true':
|
if os.getenv('FORCE_HTTPS', 'False').lower() == 'true':
|
||||||
# check if https wanted
|
|
||||||
if request.headers.get('X-Forwarded-Proto', 'http') != 'https' and not request.is_secure:
|
if request.headers.get('X-Forwarded-Proto', 'http') != 'https' and not request.is_secure:
|
||||||
url = request.url.replace('http://', 'https://', 1)
|
url = request.url.replace('http://', 'https://', 1)
|
||||||
|
app.logger.info(f"Redirecting to HTTPS: {url}")
|
||||||
return redirect(url, code=301)
|
return redirect(url, code=301)
|
||||||
|
|
||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_template_vars():
|
def inject_template_vars():
|
||||||
def _(key, **kwargs):
|
def _(key, **kwargs):
|
||||||
lang = session.get('lang', 'en')
|
lang = session.get('lang', 'en')
|
||||||
return translate(key, lang, **kwargs)
|
return translate(key, lang, **kwargs)
|
||||||
return dict(_=_)
|
theme = request.cookies.get('theme', 'light')
|
||||||
|
return dict(_=_, theme=theme)
|
||||||
|
|
||||||
# DB Models
|
# DB Models
|
||||||
class User(db.Model, UserMixin):
|
class User(db.Model, UserMixin):
|
||||||
|
@ -348,7 +357,8 @@ def set_lang(lang):
|
||||||
@app.route('/set-theme/<theme>')
|
@app.route('/set-theme/<theme>')
|
||||||
def set_theme(theme):
|
def set_theme(theme):
|
||||||
resp = make_response('', 204)
|
resp = make_response('', 204)
|
||||||
resp.set_cookie('dark_mode', 'true' if theme == 'dark' else 'false', max_age=60*60*24*365)
|
# Von 'dark_mode' zu 'theme' ändern
|
||||||
|
resp.set_cookie('theme', theme, max_age=60*60*24*365)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@app.route('/login', methods=['GET', 'POST'])
|
@app.route('/login', methods=['GET', 'POST'])
|
||||||
|
@ -864,7 +874,7 @@ services:
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
volumes:
|
volumes:
|
||||||
- ../data:/app/data
|
- ../data:/app/data
|
||||||
- ../translations:/app/translations:rw
|
- ./translations:/app/translations:rw
|
||||||
- ../.env:/app/.env
|
- ../.env:/app/.env
|
||||||
user: "${UID}:${GID}"
|
user: "${UID}:${GID}"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
@ -877,25 +887,12 @@ chmod -R a+rwX ../data ../translations
|
||||||
find ../data ../translations -type d -exec chmod 775 {} \;
|
find ../data ../translations -type d -exec chmod 775 {} \;
|
||||||
find ../data ../translations -type f -exec chmod 664 {} \;
|
find ../data ../translations -type f -exec chmod 664 {} \;
|
||||||
|
|
||||||
# 8. Translation and upgrade scripts
|
|
||||||
cat <<JSON_END > "$TRANSLATIONS_DIR/de.json"
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
JSON_END
|
|
||||||
|
|
||||||
cat <<JSON_END > "$TRANSLATIONS_DIR/en.json"
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
JSON_END
|
|
||||||
|
|
||||||
|
|
||||||
cat <<'SCRIPT_END' > ../translate.sh
|
cat <<'SCRIPT_END' > ../translate.sh
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
TRANSLATION_DIR="./translations"
|
APP_DIR="steam-gift-manager"
|
||||||
|
TRANSLATION_DIR="$APP_DIR/translations"
|
||||||
LANGS=("de" "en")
|
LANGS=("de" "en")
|
||||||
|
|
||||||
# Prüfe jq
|
# Prüfe jq
|
||||||
|
@ -904,7 +901,7 @@ if ! command -v jq &>/dev/null; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 1. Lege JSON-Dateien an, falls sie fehlen
|
# 1. create json files if missing
|
||||||
for lang in "${LANGS[@]}"; do
|
for lang in "${LANGS[@]}"; do
|
||||||
file="$TRANSLATION_DIR/$lang.json"
|
file="$TRANSLATION_DIR/$lang.json"
|
||||||
if [ ! -f "$file" ]; then
|
if [ ! -f "$file" ]; then
|
||||||
|
@ -913,11 +910,12 @@ for lang in "${LANGS[@]}"; do
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# 2. Extrahiere alle zu übersetzenden Strings
|
# 2. Extract the strings
|
||||||
STRINGS=$(grep -rhoP "_\(\s*['\"](.+?)['\"]\s*\)" steam-gift-manager/templates steam-gift-manager/app.py | \
|
STRINGS=$(grep -rhoP "_\(\s*['\"](.+?)['\"]\s*\)" \
|
||||||
sed -E "s/_\(\s*['\"](.+?)['\"]\s*\)/\1/" | sort | uniq)
|
"$APP_DIR/templates" "$APP_DIR/app.py" | \
|
||||||
|
sed -E "s/_\(\s*['\"](.+?)['\"]\s*\)/\1/" | sort | uniq)
|
||||||
|
|
||||||
# 3. Ergänze neue Keys in die JSON-Dateien
|
# 3. add new keys into the json files
|
||||||
for lang in "${LANGS[@]}"; do
|
for lang in "${LANGS[@]}"; do
|
||||||
file="$TRANSLATION_DIR/$lang.json"
|
file="$TRANSLATION_DIR/$lang.json"
|
||||||
tmp="$file.tmp"
|
tmp="$file.tmp"
|
||||||
|
@ -930,10 +928,10 @@ for lang in "${LANGS[@]}"; do
|
||||||
mv "$tmp" "$file"
|
mv "$tmp" "$file"
|
||||||
echo "Updated $file"
|
echo "Updated $file"
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "✅ JSON translation files updated. Please enter your translations!"
|
echo "✅ JSON translation files updated. Please enter your translations!"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SCRIPT_END
|
SCRIPT_END
|
||||||
chmod +x ../translate.sh
|
chmod +x ../translate.sh
|
||||||
|
|
||||||
|
@ -1004,7 +1002,7 @@ MANIFEST_END
|
||||||
|
|
||||||
# Service Worker
|
# Service Worker
|
||||||
cat <<SW_END > static/serviceworker.js
|
cat <<SW_END > static/serviceworker.js
|
||||||
const CACHE_NAME = 'game-key-manager-v1';
|
const CACHE_NAME = 'game-key-manager-v2';
|
||||||
const ASSETS = [
|
const ASSETS = [
|
||||||
'/',
|
'/',
|
||||||
'/static/style.css',
|
'/static/style.css',
|
||||||
|
@ -1069,7 +1067,18 @@ cat <<HTML_END > templates/base.html
|
||||||
type="image/jpeg">
|
type="image/jpeg">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</head>
|
</head>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
var theme = localStorage.getItem('theme');
|
||||||
|
if (!theme) {
|
||||||
|
// Systempräferenz als Fallback
|
||||||
|
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
document.documentElement.setAttribute('data-bs-theme', theme);
|
||||||
|
} catch(e) {}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -1147,12 +1156,25 @@ cat <<HTML_END > templates/base.html
|
||||||
const toggle = document.getElementById('darkModeSwitch');
|
const toggle = document.getElementById('darkModeSwitch');
|
||||||
const html = document.documentElement;
|
const html = document.documentElement;
|
||||||
if (toggle) {
|
if (toggle) {
|
||||||
|
toggle.checked = (html.getAttribute('data-bs-theme') === 'dark')
|
||||||
toggle.addEventListener('change', function() {
|
toggle.addEventListener('change', function() {
|
||||||
const theme = this.checked ? 'dark' : 'light';
|
const theme = this.checked ? 'dark' : 'light';
|
||||||
fetch('/set-theme/' + theme)
|
document.cookie = "theme=" + theme + ";path=/;max-age=31536000";
|
||||||
.then(() => html.setAttribute('data-bs-theme', theme));
|
html.setAttribute('data-bs-theme', theme);
|
||||||
|
fetch('/set-theme/' + theme);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Set theme on page load
|
||||||
|
function getThemeCookie() {
|
||||||
|
const cookies = document.cookie.split(';');
|
||||||
|
for (let cookie of cookies) {
|
||||||
|
const [name, value] = cookie.trim().split('=');
|
||||||
|
if (name === 'theme') return value;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const savedTheme = getThemeCookie() || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
||||||
|
document.documentElement.setAttribute('data-bs-theme', savedTheme);
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue