feat: added translate support to custom data

Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
2025-07-06 13:10:37 +05:00
parent 0efc3a8701
commit 731e919884
3 changed files with 52 additions and 29 deletions

View File

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

View File

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