update readme due release on codeberg #2

Open
nocci wants to merge 26 commits from dev into main
1 changed files with 57 additions and 35 deletions
Showing only changes of commit 8aba6f5129 - Show all commits

View File

@ -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>