支持自动检测语言
This commit is contained in:
13
web/app.py
13
web/app.py
@@ -13,7 +13,7 @@ import streamlit as st
|
||||
from loguru import logger
|
||||
|
||||
# Import i18n and config manager
|
||||
from web.i18n import load_locales, set_language, tr, get_available_languages
|
||||
from web.i18n import load_locales, set_language, tr, get_available_languages, get_language
|
||||
from reelforge.config import config_manager
|
||||
from reelforge.models.progress import ProgressEvent
|
||||
|
||||
@@ -52,12 +52,10 @@ def safe_rerun():
|
||||
|
||||
def init_i18n():
|
||||
"""Initialize internationalization"""
|
||||
# Load locales if not already loaded
|
||||
load_locales()
|
||||
|
||||
# Get language from session state or default to Chinese
|
||||
# Locales are already loaded and system language detected on import
|
||||
# Get language from session state or use auto-detected system language
|
||||
if "language" not in st.session_state:
|
||||
st.session_state.language = "zh_CN"
|
||||
st.session_state.language = get_language() # Use auto-detected language
|
||||
|
||||
# Set current language
|
||||
set_language(st.session_state.language)
|
||||
@@ -86,7 +84,8 @@ def get_reelforge():
|
||||
def init_session_state():
|
||||
"""Initialize session state variables"""
|
||||
if "language" not in st.session_state:
|
||||
st.session_state.language = "zh_CN"
|
||||
# Use auto-detected system language
|
||||
st.session_state.language = get_language()
|
||||
|
||||
|
||||
# ============================================================================
|
||||
|
||||
@@ -3,13 +3,14 @@ International language support for ReelForge Web UI
|
||||
"""
|
||||
|
||||
import json
|
||||
import locale
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional
|
||||
|
||||
from loguru import logger
|
||||
|
||||
_locales: Dict[str, dict] = {}
|
||||
_current_language: str = "zh_CN"
|
||||
_current_language: str = "en_US" # Default fallback to English
|
||||
|
||||
|
||||
def load_locales() -> Dict[str, dict]:
|
||||
@@ -112,6 +113,125 @@ def get_available_languages() -> Dict[str, str]:
|
||||
}
|
||||
|
||||
|
||||
def detect_system_language() -> str:
|
||||
"""
|
||||
Detect system/OS language and return the best matching locale code.
|
||||
Falls back to English if no match found.
|
||||
|
||||
This is designed for self-hosted scenarios where the server and browser
|
||||
are typically on the same machine.
|
||||
|
||||
Returns:
|
||||
Language code (e.g., "zh_CN", "en_US")
|
||||
"""
|
||||
try:
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
|
||||
system_locale = None
|
||||
|
||||
# Method 1: macOS-specific detection (most reliable for macOS)
|
||||
if platform.system() == "Darwin": # macOS
|
||||
try:
|
||||
# Get AppleLocale which reflects system language preference
|
||||
result = subprocess.run(
|
||||
["defaults", "read", "-g", "AppleLocale"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=2
|
||||
)
|
||||
if result.returncode == 0:
|
||||
system_locale = result.stdout.strip()
|
||||
logger.debug(f"System locale from macOS AppleLocale: {system_locale}")
|
||||
except Exception as e:
|
||||
logger.debug(f"macOS AppleLocale detection failed: {e}")
|
||||
|
||||
# Fallback: try AppleLanguages
|
||||
if not system_locale:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["defaults", "read", "-g", "AppleLanguages"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=2
|
||||
)
|
||||
if result.returncode == 0:
|
||||
# Parse array output like: ( "zh-Hans-CN", "en-CN" )
|
||||
output = result.stdout.strip()
|
||||
# Extract first language
|
||||
import re
|
||||
match = re.search(r'"([^"]+)"', output)
|
||||
if match:
|
||||
lang = match.group(1)
|
||||
# Convert zh-Hans-CN to zh_CN
|
||||
if lang.startswith("zh-Hans"):
|
||||
system_locale = "zh_CN"
|
||||
elif lang.startswith("zh-Hant"):
|
||||
system_locale = "zh_TW"
|
||||
else:
|
||||
system_locale = lang.replace("-", "_")
|
||||
logger.debug(f"System locale from macOS AppleLanguages: {system_locale}")
|
||||
except Exception as e:
|
||||
logger.debug(f"macOS AppleLanguages detection failed: {e}")
|
||||
|
||||
# Method 2: Get from environment locale (cross-platform)
|
||||
if not system_locale:
|
||||
try:
|
||||
system_locale = locale.getdefaultlocale()[0]
|
||||
logger.debug(f"System locale from getdefaultlocale(): {system_locale}")
|
||||
except Exception as e:
|
||||
logger.debug(f"getdefaultlocale() failed: {e}")
|
||||
|
||||
# Method 3: Get from current locale
|
||||
if not system_locale:
|
||||
try:
|
||||
system_locale = locale.getlocale()[0]
|
||||
logger.debug(f"System locale from getlocale(): {system_locale}")
|
||||
except Exception as e:
|
||||
logger.debug(f"getlocale() failed: {e}")
|
||||
|
||||
# Method 4: Try to get from environment variables
|
||||
if not system_locale:
|
||||
for env_var in ['LC_ALL', 'LC_MESSAGES', 'LANG', 'LANGUAGE']:
|
||||
env_value = os.environ.get(env_var)
|
||||
if env_value:
|
||||
# Extract language code from formats like "zh_CN.UTF-8"
|
||||
system_locale = env_value.split('.')[0]
|
||||
logger.debug(f"System locale from {env_var}: {system_locale}")
|
||||
break
|
||||
|
||||
if system_locale:
|
||||
# Normalize the locale string
|
||||
# Handle formats: zh_CN, zh-CN, zh_CN.UTF-8, etc.
|
||||
system_locale = system_locale.replace('-', '_').split('.')[0]
|
||||
|
||||
# Direct match (e.g., "zh_CN")
|
||||
for locale_code in _locales.keys():
|
||||
if locale_code.lower() == system_locale.lower():
|
||||
logger.info(f"System language matched: {locale_code}")
|
||||
return locale_code
|
||||
|
||||
# Partial match (e.g., "zh" matches "zh_CN")
|
||||
lang_prefix = system_locale.split('_')[0].lower()
|
||||
for locale_code in _locales.keys():
|
||||
if locale_code.lower().startswith(lang_prefix):
|
||||
logger.info(f"System language partially matched: {locale_code} (from {system_locale})")
|
||||
return locale_code
|
||||
|
||||
logger.info("No system language detected, using fallback")
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to detect system language: {e}")
|
||||
|
||||
# Fallback to English
|
||||
return "en_US"
|
||||
|
||||
|
||||
# Auto-load locales on import
|
||||
load_locales()
|
||||
|
||||
# Auto-detect and set system language
|
||||
_detected_language = detect_system_language()
|
||||
_current_language = _detected_language
|
||||
logger.info(f"Default language initialized to: {_current_language}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user