feat: added translate support to custom data
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
import gettext
|
import gettext
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import locale
|
import locale
|
||||||
|
import os
|
||||||
from babel import Locale
|
from babel import Locale
|
||||||
|
|
||||||
LOCALE_MAP = {
|
LOCALE_MAP = {
|
||||||
@ -72,3 +73,32 @@ def get_egs_language():
|
|||||||
|
|
||||||
# Если что-то пошло не так — используем английский по умолчанию
|
# Если что-то пошло не так — используем английский по умолчанию
|
||||||
return 'en'
|
return 'en'
|
||||||
|
|
||||||
|
def read_metadata_translations(metadata_file, language_code):
|
||||||
|
"""
|
||||||
|
Читает переводы из metadata.txt для указанного языка.
|
||||||
|
Возвращает словарь с полями name и description.
|
||||||
|
Для name: использует name_<language_code>, затем name_en, затем name, и наконец _('Unknown Game').
|
||||||
|
Для description: использует description_<language_code>, затем description_en, затем description.
|
||||||
|
"""
|
||||||
|
translations = {'name': _('Unknown Game'), 'description': ''}
|
||||||
|
if not os.path.exists(metadata_file):
|
||||||
|
return translations
|
||||||
|
|
||||||
|
with open(metadata_file, encoding='utf-8') as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith(f'name_{language_code}='):
|
||||||
|
translations['name'] = line[len(f'name_{language_code}='):].strip()
|
||||||
|
elif line.startswith('name_en=') and translations['name'] == _('Unknown Game'):
|
||||||
|
translations['name'] = line[len('name_en='):].strip()
|
||||||
|
elif line.startswith('name=') and translations['name'] == _('Unknown Game'):
|
||||||
|
translations['name'] = line[len('name='):].strip()
|
||||||
|
elif line.startswith(f'description_{language_code}='):
|
||||||
|
translations['description'] = line[len(f'description_{language_code}='):].strip()
|
||||||
|
elif line.startswith('description_en=') and not translations['description']:
|
||||||
|
translations['description'] = line[len('description_en='):].strip()
|
||||||
|
elif line.startswith('description=') and not translations['description']:
|
||||||
|
translations['description'] = line[len('description='):].strip()
|
||||||
|
|
||||||
|
return translations
|
||||||
|
@ -28,7 +28,7 @@ from portprotonqt.config_utils import (
|
|||||||
save_fullscreen_config, read_window_geometry, save_window_geometry, reset_config,
|
save_fullscreen_config, read_window_geometry, save_window_geometry, reset_config,
|
||||||
clear_cache, read_auto_fullscreen_gamepad, save_auto_fullscreen_gamepad, read_rumble_config, save_rumble_config
|
clear_cache, read_auto_fullscreen_gamepad, save_auto_fullscreen_gamepad, read_rumble_config, save_rumble_config
|
||||||
)
|
)
|
||||||
from portprotonqt.localization import _
|
from portprotonqt.localization import _, get_egs_language, read_metadata_translations
|
||||||
from portprotonqt.logger import get_logger
|
from portprotonqt.logger import get_logger
|
||||||
from portprotonqt.downloader import Downloader
|
from portprotonqt.downloader import Downloader
|
||||||
|
|
||||||
@ -465,11 +465,9 @@ class MainWindow(QMainWindow):
|
|||||||
os.makedirs(user_custom_folder, exist_ok=True)
|
os.makedirs(user_custom_folder, exist_ok=True)
|
||||||
|
|
||||||
builtin_cover = ""
|
builtin_cover = ""
|
||||||
builtin_name = None
|
|
||||||
builtin_desc = None
|
|
||||||
user_cover = ""
|
user_cover = ""
|
||||||
user_name = None
|
user_game_folder=""
|
||||||
user_desc = None
|
builtin_game_folder=""
|
||||||
|
|
||||||
if game_exe:
|
if game_exe:
|
||||||
exe_name = os.path.splitext(os.path.basename(game_exe))[0]
|
exe_name = os.path.splitext(os.path.basename(game_exe))[0]
|
||||||
@ -477,6 +475,7 @@ class MainWindow(QMainWindow):
|
|||||||
user_game_folder = os.path.join(user_custom_folder, exe_name)
|
user_game_folder = os.path.join(user_custom_folder, exe_name)
|
||||||
os.makedirs(user_game_folder, exist_ok=True)
|
os.makedirs(user_game_folder, exist_ok=True)
|
||||||
|
|
||||||
|
# Чтение обложки
|
||||||
builtin_files = set(os.listdir(builtin_game_folder)) if os.path.exists(builtin_game_folder) else set()
|
builtin_files = set(os.listdir(builtin_game_folder)) if os.path.exists(builtin_game_folder) else set()
|
||||||
for ext in [".jpg", ".png", ".jpeg", ".bmp"]:
|
for ext in [".jpg", ".png", ".jpeg", ".bmp"]:
|
||||||
candidate = f"cover{ext}"
|
candidate = f"cover{ext}"
|
||||||
@ -484,16 +483,6 @@ class MainWindow(QMainWindow):
|
|||||||
builtin_cover = os.path.join(builtin_game_folder, candidate)
|
builtin_cover = os.path.join(builtin_game_folder, candidate)
|
||||||
break
|
break
|
||||||
|
|
||||||
builtin_metadata_file = os.path.join(builtin_game_folder, "metadata.txt")
|
|
||||||
if os.path.exists(builtin_metadata_file):
|
|
||||||
with open(builtin_metadata_file, encoding="utf-8") as f:
|
|
||||||
for line in f:
|
|
||||||
line = line.strip()
|
|
||||||
if line.startswith("name="):
|
|
||||||
builtin_name = line[len("name="):].strip()
|
|
||||||
elif line.startswith("description="):
|
|
||||||
builtin_desc = line[len("description="):].strip()
|
|
||||||
|
|
||||||
user_files = set(os.listdir(user_game_folder)) if os.path.exists(user_game_folder) else set()
|
user_files = set(os.listdir(user_game_folder)) if os.path.exists(user_game_folder) else set()
|
||||||
for ext in [".jpg", ".png", ".jpeg", ".bmp"]:
|
for ext in [".jpg", ".png", ".jpeg", ".bmp"]:
|
||||||
candidate = f"cover{ext}"
|
candidate = f"cover{ext}"
|
||||||
@ -501,16 +490,7 @@ class MainWindow(QMainWindow):
|
|||||||
user_cover = os.path.join(user_game_folder, candidate)
|
user_cover = os.path.join(user_game_folder, candidate)
|
||||||
break
|
break
|
||||||
|
|
||||||
user_metadata_file = os.path.join(user_game_folder, "metadata.txt")
|
# Чтение статистики
|
||||||
if os.path.exists(user_metadata_file):
|
|
||||||
with open(user_metadata_file, encoding="utf-8") as f:
|
|
||||||
for line in f:
|
|
||||||
line = line.strip()
|
|
||||||
if line.startswith("name="):
|
|
||||||
user_name = line[len("name="):].strip()
|
|
||||||
elif line.startswith("description="):
|
|
||||||
user_desc = line[len("description="):].strip()
|
|
||||||
|
|
||||||
if self.portproton_location:
|
if self.portproton_location:
|
||||||
statistics_file = os.path.join(self.portproton_location, "data", "tmp", "statistics")
|
statistics_file = os.path.join(self.portproton_location, "data", "tmp", "statistics")
|
||||||
try:
|
try:
|
||||||
@ -526,13 +506,26 @@ class MainWindow(QMainWindow):
|
|||||||
print(f"Failed to parse playtime data: {e}")
|
print(f"Failed to parse playtime data: {e}")
|
||||||
|
|
||||||
def on_steam_info(steam_info: dict):
|
def on_steam_info(steam_info: dict):
|
||||||
final_name = user_name or builtin_name or desktop_name
|
# Определяем текущий язык
|
||||||
final_desc = (user_desc if user_desc is not None else
|
language_code = get_egs_language()
|
||||||
builtin_desc if builtin_desc is not None else
|
|
||||||
steam_info.get("description", ""))
|
# Чтение переводов из metadata.txt
|
||||||
|
user_metadata_file = os.path.join(user_game_folder, "metadata.txt")
|
||||||
|
builtin_metadata_file = os.path.join(builtin_game_folder, "metadata.txt")
|
||||||
|
|
||||||
|
# Сначала пытаемся загрузить пользовательские переводы
|
||||||
|
translations = {'name': desktop_name, 'description': ''}
|
||||||
|
if os.path.exists(user_metadata_file):
|
||||||
|
translations = read_metadata_translations(user_metadata_file, language_code)
|
||||||
|
elif os.path.exists(builtin_metadata_file):
|
||||||
|
translations = read_metadata_translations(builtin_metadata_file, language_code)
|
||||||
|
|
||||||
|
final_name = translations['name']
|
||||||
|
final_desc = translations['description'] or steam_info.get("description", "")
|
||||||
final_cover = (user_cover if user_cover else
|
final_cover = (user_cover if user_cover else
|
||||||
builtin_cover if builtin_cover else
|
builtin_cover if builtin_cover else
|
||||||
steam_info.get("cover", "") or entry.get("Icon", ""))
|
steam_info.get("cover", "") or entry.get("Icon", ""))
|
||||||
|
|
||||||
callback((
|
callback((
|
||||||
final_name,
|
final_name,
|
||||||
final_desc,
|
final_desc,
|
||||||
|
Reference in New Issue
Block a user