chore: update program name to PortProtonQt

Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
2025-06-09 09:56:25 +05:00
parent 6fa145ee13
commit 61680ed97f
21 changed files with 45 additions and 46 deletions

View File

@ -60,7 +60,7 @@
- [X] Исправить частичное применение тем на лету - [X] Исправить частичное применение тем на лету
- [X] Исправить наложение подписей скриншотов при первом перелистывании в полноэкранном режиме - [X] Исправить наложение подписей скриншотов при первом перелистывании в полноэкранном режиме
- [ ] Добавить поддержку GOG (?) - [ ] Добавить поддержку GOG (?)
- [ ] Определиться с названием (PortProtonQt или PortProtonQT или вообще третий вариант) - [X] Определиться с названием (PortProtonQt или PortProtonQT или вообще третий вариант)
- [ ] Добавить данные с HowLongToBeat на страницу с деталями игры (?) - [ ] Добавить данные с HowLongToBeat на страницу с деталями игры (?)
- [ ] Добавить виброотдачу на геймпаде при запуске игры (?) - [ ] Добавить виброотдачу на геймпаде при запуске игры (?)

View File

@ -106,7 +106,7 @@ def compile_locales() -> None:
def extract_strings() -> None: def extract_strings() -> None:
input_dir = (Path(__file__).parent.parent / "portprotonqt").resolve() input_dir = (Path(__file__).parent.parent / "portprotonqt").resolve()
CommandLineInterface().run([ CommandLineInterface().run([
"pybabel", "extract", "--project=PortProtonQT", "pybabel", "extract", "--project=PortProtonQt",
f"--version={_get_version()}", f"--version={_get_version()}",
"--strip-comment-tag", "--strip-comment-tag",
"--no-location", "--no-location",
@ -231,7 +231,7 @@ def main(args) -> int:
return 0 return 0
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser(prog="l10n", description="Localization utility for PortProtonQT.") parser = argparse.ArgumentParser(prog="l10n", description="Localization utility for PortProtonQt.")
parser.add_argument("--create-new", nargs='+', type=str, default=False, help="Create .po for new locales") parser.add_argument("--create-new", nargs='+', type=str, default=False, help="Create .po for new locales")
parser.add_argument("--update-all", action='store_true', help="Extract/update locales and update README coverage") parser.add_argument("--update-all", action='store_true', help="Extract/update locales and update README coverage")
parser.add_argument("--spellcheck", action='store_true', help="Run spellcheck on POT and PO files") parser.add_argument("--spellcheck", action='store_true', help="Run spellcheck on POT and PO files")

View File

@ -7,7 +7,7 @@ def parse_args():
""" """
Парсит аргументы командной строки. Парсит аргументы командной строки.
""" """
parser = argparse.ArgumentParser(description="PortProtonQT CLI") parser = argparse.ArgumentParser(description="PortProtonQt CLI")
parser.add_argument( parser.add_argument(
"--fullscreen", "--fullscreen",
action="store_true", action="store_true",

View File

@ -10,7 +10,7 @@ _portproton_location = None
# Пути к конфигурационным файлам # Пути к конфигурационным файлам
CONFIG_FILE = os.path.join( CONFIG_FILE = os.path.join(
os.getenv("XDG_CONFIG_HOME", os.path.join(os.path.expanduser("~"), ".config")), os.getenv("XDG_CONFIG_HOME", os.path.join(os.path.expanduser("~"), ".config")),
"PortProtonQT.conf" "PortProtonQt.conf"
) )
PORTPROTON_CONFIG_FILE = os.path.join( PORTPROTON_CONFIG_FILE = os.path.join(
@ -21,7 +21,7 @@ PORTPROTON_CONFIG_FILE = os.path.join(
# Пути к папкам с темами # Пути к папкам с темами
xdg_data_home = os.getenv("XDG_DATA_HOME", os.path.join(os.path.expanduser("~"), ".local", "share")) xdg_data_home = os.getenv("XDG_DATA_HOME", os.path.join(os.path.expanduser("~"), ".local", "share"))
THEMES_DIRS = [ THEMES_DIRS = [
os.path.join(xdg_data_home, "PortProtonQT", "themes"), os.path.join(xdg_data_home, "PortProtonQt", "themes"),
os.path.join(os.path.dirname(os.path.abspath(__file__)), "themes") os.path.join(os.path.dirname(os.path.abspath(__file__)), "themes")
] ]
@ -472,14 +472,14 @@ def reset_config():
def clear_cache(): def clear_cache():
""" """
Очищает кэш PortProtonQT, удаляя папку кэша. Очищает кэш PortProtonQt, удаляя папку кэша.
""" """
xdg_cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")) xdg_cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache"))
cache_dir = os.path.join(xdg_cache_home, "PortProtonQT") cache_dir = os.path.join(xdg_cache_home, "PortProtonQt")
if os.path.exists(cache_dir): if os.path.exists(cache_dir):
try: try:
shutil.rmtree(cache_dir) shutil.rmtree(cache_dir)
logger.info("Кэш PortProtonQT удалён: %s", cache_dir) logger.info("Кэш PortProtonQt удалён: %s", cache_dir)
except Exception as e: except Exception as e:
logger.error("Ошибка при удалении кэша: %s", e) logger.error("Ошибка при удалении кэша: %s", e)

View File

@ -12,7 +12,7 @@ from portprotonqt.steam_api import is_game_in_steam, add_to_steam, remove_from_s
from portprotonqt.dialogs import AddGameDialog from portprotonqt.dialogs import AddGameDialog
class ContextMenuManager: class ContextMenuManager:
"""Manages context menu actions for game management in PortProtonQT.""" """Manages context menu actions for game management in PortProtonQt."""
def __init__(self, parent, portproton_location, theme, load_games_callback, update_game_grid_callback): def __init__(self, parent, portproton_location, theme, load_games_callback, update_game_grid_callback):
""" """
@ -258,7 +258,7 @@ class ContextMenuManager:
"XDG_DATA_HOME", "XDG_DATA_HOME",
os.path.join(os.path.expanduser("~"), ".local", "share") os.path.join(os.path.expanduser("~"), ".local", "share")
) )
custom_folder = os.path.join(xdg_data_home, "PortProtonQT", "custom_data", exe_name) custom_folder = os.path.join(xdg_data_home, "PortProtonQt", "custom_data", exe_name)
if os.path.exists(custom_folder): if os.path.exists(custom_folder):
try: try:
shutil.rmtree(custom_folder) shutil.rmtree(custom_folder)
@ -417,7 +417,7 @@ class ContextMenuManager:
"XDG_DATA_HOME", "XDG_DATA_HOME",
os.path.join(os.path.expanduser("~"), ".local", "share") os.path.join(os.path.expanduser("~"), ".local", "share")
) )
custom_folder = os.path.join(xdg_data_home, "PortProtonQT", "custom_data", exe_name) custom_folder = os.path.join(xdg_data_home, "PortProtonQt", "custom_data", exe_name)
os.makedirs(custom_folder, exist_ok=True) os.makedirs(custom_folder, exist_ok=True)
ext = os.path.splitext(new_cover_path)[1].lower() ext = os.path.splitext(new_cover_path)[1].lower()

View File

@ -303,7 +303,7 @@ class Downloader(QObject):
local_path = os.path.join( local_path = os.path.join(
os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")), os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")),
"PortProtonQT", "legendary_cache", "legendary" "PortProtonQt", "legendary_cache", "legendary"
) )
logger.info(f"Downloading legendary binary version {version} from {binary_url} to {local_path}") logger.info(f"Downloading legendary binary version {version} from {binary_url} to {local_path}")

View File

@ -22,7 +22,7 @@ def get_cache_dir() -> Path:
"XDG_CACHE_HOME", "XDG_CACHE_HOME",
os.path.join(os.path.expanduser("~"), ".cache") os.path.join(os.path.expanduser("~"), ".cache")
) )
cache_dir = Path(xdg_cache_home) / "PortProtonQT" cache_dir = Path(xdg_cache_home) / "PortProtonQt"
cache_dir.mkdir(parents=True, exist_ok=True) cache_dir.mkdir(parents=True, exist_ok=True)
return cache_dir return cache_dir
@ -36,7 +36,7 @@ def get_egs_game_description_async(
Asynchronously fetches the game description from the Epic Games Store API. Asynchronously fetches the game description from the Epic Games Store API.
Prioritizes GraphQL API with namespace for slug and description. Prioritizes GraphQL API with namespace for slug and description.
Falls back to legacy API if GraphQL provides a slug but no description. Falls back to legacy API if GraphQL provides a slug but no description.
Caches results in ~/.cache/PortProtonQT/egs_app_{app_name}.json. Caches results in ~/.cache/PortProtonQt/egs_app_{app_name}.json.
Handles DNS resolution failures gracefully. Handles DNS resolution failures gracefully.
""" """
cache_dir = get_cache_dir() cache_dir = get_cache_dir()
@ -423,7 +423,7 @@ def _continue_loading_egs_games(legendary_path: str, callback: Callable[[list[tu
except Exception as e: except Exception as e:
logger.warning("Error processing metadata for %s: %s", app_name, str(e)) logger.warning("Error processing metadata for %s: %s", app_name, str(e))
image_folder = os.path.join(os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")), "PortProtonQT", "images") image_folder = os.path.join(os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")), "PortProtonQt", "images")
local_path = os.path.join(image_folder, f"{app_name}.jpg") if cover_url else "" local_path = os.path.join(image_folder, f"{app_name}.jpg") if cover_url else ""
def on_description_fetched(api_description: str): def on_description_fetched(api_description: str):

View File

@ -35,10 +35,9 @@ def load_pixmap_async(cover: str, width: int, height: int, callback: Callable[[Q
y = (scaled.height() - height) // 2 y = (scaled.height() - height) // 2
cropped = scaled.copy(x, y, width, height) cropped = scaled.copy(x, y, width, height)
callback(cropped) callback(cropped)
# Removed: pixmap = None (unnecessary, causes type error)
xdg_cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")) xdg_cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache"))
image_folder = os.path.join(xdg_cache_home, "PortProtonQT", "images") image_folder = os.path.join(xdg_cache_home, "PortProtonQt", "images")
os.makedirs(image_folder, exist_ok=True) os.makedirs(image_folder, exist_ok=True)
if cover and cover.startswith("https://steamcdn-a.akamaihd.net/steam/apps/"): if cover and cover.startswith("https://steamcdn-a.akamaihd.net/steam/apps/"):

View File

@ -1,6 +1,6 @@
# German (Germany) translations for PortProtonQT. # German (Germany) translations for PortProtonQt.
# Copyright (C) 2025 boria138 # Copyright (C) 2025 boria138
# This file is distributed under the same license as the PortProtonQT # This file is distributed under the same license as the PortProtonQt
# project. # project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025. # FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
# #
@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-08 22:55+0500\n" "POT-Creation-Date: 2025-06-09 09:53+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de_DE\n" "Language: de_DE\n"

View File

@ -1,6 +1,6 @@
# Spanish (Spain) translations for PortProtonQT. # Spanish (Spain) translations for PortProtonQt.
# Copyright (C) 2025 boria138 # Copyright (C) 2025 boria138
# This file is distributed under the same license as the PortProtonQT # This file is distributed under the same license as the PortProtonQt
# project. # project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025. # FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
# #
@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-08 22:55+0500\n" "POT-Creation-Date: 2025-06-09 09:53+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: es_ES\n" "Language: es_ES\n"

View File

@ -1,15 +1,15 @@
# Translations template for PortProtonQT. # Translations template for PortProtonQt.
# Copyright (C) 2025 boria138 # Copyright (C) 2025 boria138
# This file is distributed under the same license as the PortProtonQT # This file is distributed under the same license as the PortProtonQt
# project. # project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025. # FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
# #
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PortProtonQT 0.1.1\n" "Project-Id-Version: PortProtonQt 0.1.1\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-08 22:55+0500\n" "POT-Creation-Date: 2025-06-09 09:53+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"

View File

@ -1,6 +1,6 @@
# Russian (Russia) translations for PortProtonQT. # Russian (Russia) translations for PortProtonQt.
# Copyright (C) 2025 boria138 # Copyright (C) 2025 boria138
# This file is distributed under the same license as the PortProtonQT # This file is distributed under the same license as the PortProtonQt
# project. # project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025. # FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
# #
@ -9,9 +9,9 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-08 22:55+0500\n" "POT-Creation-Date: 2025-06-09 09:53+0500\n"
"PO-Revision-Date: 2025-06-08 22:55+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: \n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: ru_RU\n" "Language: ru_RU\n"
"Language-Team: ru_RU <LL@li.org>\n" "Language-Team: ru_RU <LL@li.org>\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "

View File

@ -44,7 +44,7 @@ from datetime import datetime
logger = get_logger(__name__) logger = get_logger(__name__)
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
"""Main window of PortProtonQT.""" """Main window of PortProtonQt."""
settings_saved = Signal() settings_saved = Signal()
games_loaded = Signal(list) games_loaded = Signal(list)
update_progress = Signal(int) # Signal to update progress bar update_progress = Signal(int) # Signal to update progress bar
@ -73,10 +73,10 @@ class MainWindow(QMainWindow):
self.settingsDebounceTimer.timeout.connect(self.applySettingsDelayed) self.settingsDebounceTimer.timeout.connect(self.applySettingsDelayed)
read_time_config() read_time_config()
# Set LEGENDARY_CONFIG_PATH to ~/.cache/PortProtonQT/legendary # Set LEGENDARY_CONFIG_PATH to ~/.cache/PortProtonQt/legendary_cache
self.legendary_config_path = os.path.join( self.legendary_config_path = os.path.join(
os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")), os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")),
"PortProtonQT", "legendary_cache" "PortProtonQt", "legendary_cache"
) )
os.makedirs(self.legendary_config_path, exist_ok=True) os.makedirs(self.legendary_config_path, exist_ok=True)
os.environ["LEGENDARY_CONFIG_PATH"] = self.legendary_config_path os.environ["LEGENDARY_CONFIG_PATH"] = self.legendary_config_path
@ -98,7 +98,7 @@ class MainWindow(QMainWindow):
if not self.theme: if not self.theme:
self.theme = default_styles self.theme = default_styles
self.card_width = read_card_size() self.card_width = read_card_size()
self.setWindowTitle("PortProtonQT") self.setWindowTitle("PortProtonQt")
self.setMinimumSize(800, 600) self.setMinimumSize(800, 600)
self.games = [] self.games = []
@ -384,7 +384,7 @@ class MainWindow(QMainWindow):
builtin_custom_folder = os.path.join(repo_root, "portprotonqt", "custom_data") builtin_custom_folder = os.path.join(repo_root, "portprotonqt", "custom_data")
xdg_data_home = os.getenv("XDG_DATA_HOME", xdg_data_home = os.getenv("XDG_DATA_HOME",
os.path.join(os.path.expanduser("~"), ".local", "share")) os.path.join(os.path.expanduser("~"), ".local", "share"))
user_custom_folder = os.path.join(xdg_data_home, "PortProtonQT", "custom_data") user_custom_folder = os.path.join(xdg_data_home, "PortProtonQt", "custom_data")
os.makedirs(user_custom_folder, exist_ok=True) os.makedirs(user_custom_folder, exist_ok=True)
builtin_cover = "" builtin_cover = ""
@ -780,7 +780,7 @@ class MainWindow(QMainWindow):
os.path.join(os.path.expanduser("~"), ".local", "share")) os.path.join(os.path.expanduser("~"), ".local", "share"))
custom_folder = os.path.join( custom_folder = os.path.join(
xdg_data_home, xdg_data_home,
"PortProtonQT", "PortProtonQt",
"custom_data", "custom_data",
exe_name exe_name
) )
@ -1228,7 +1228,7 @@ class MainWindow(QMainWindow):
self.statusBar().showMessage(_("Theme '{0}' applied successfully").format(selected_theme), 3000) self.statusBar().showMessage(_("Theme '{0}' applied successfully").format(selected_theme), 3000)
xdg_data_home = os.getenv("XDG_DATA_HOME", xdg_data_home = os.getenv("XDG_DATA_HOME",
os.path.join(os.path.expanduser("~"), ".local", "share")) os.path.join(os.path.expanduser("~"), ".local", "share"))
state_file = os.path.join(xdg_data_home, "PortProtonQT", "state.txt") state_file = os.path.join(xdg_data_home, "PortProtonQt", "state.txt")
os.makedirs(os.path.dirname(state_file), exist_ok=True) os.makedirs(os.path.dirname(state_file), exist_ok=True)
with open(state_file, "w", encoding="utf-8") as f: with open(state_file, "w", encoding="utf-8") as f:
f.write("theme_tab\n") f.write("theme_tab\n")
@ -1251,7 +1251,7 @@ class MainWindow(QMainWindow):
def restore_state(self): def restore_state(self):
"""Восстанавливает состояние приложения после перезапуска.""" """Восстанавливает состояние приложения после перезапуска."""
xdg_cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")) xdg_cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache"))
state_file = os.path.join(xdg_cache_home, "PortProtonQT", "state.txt") state_file = os.path.join(xdg_cache_home, "PortProtonQt", "state.txt")
if os.path.exists(state_file): if os.path.exists(state_file):
with open(state_file, encoding="utf-8") as f: with open(state_file, encoding="utf-8") as f:
state = f.read().strip() state = f.read().strip()

View File

@ -49,7 +49,7 @@ def decode_text(text: str) -> str:
def get_cache_dir(): def get_cache_dir():
"""Возвращает путь к каталогу кэша, создаёт его при необходимости.""" """Возвращает путь к каталогу кэша, создаёт его при необходимости."""
xdg_cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")) xdg_cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache"))
cache_dir = os.path.join(xdg_cache_home, "PortProtonQT") cache_dir = os.path.join(xdg_cache_home, "PortProtonQt")
os.makedirs(cache_dir, exist_ok=True) os.makedirs(cache_dir, exist_ok=True)
return cache_dir return cache_dir

View File

@ -11,7 +11,7 @@ logger = get_logger(__name__)
# Папка, где располагаются все дополнительные темы # Папка, где располагаются все дополнительные темы
xdg_data_home = os.getenv("XDG_DATA_HOME", os.path.join(os.path.expanduser("~"), ".local", "share")) xdg_data_home = os.getenv("XDG_DATA_HOME", os.path.join(os.path.expanduser("~"), ".local", "share"))
THEMES_DIRS = [ THEMES_DIRS = [
os.path.join(xdg_data_home, "PortProtonQT", "themes"), os.path.join(xdg_data_home, "PortProtonQt", "themes"),
os.path.join(os.path.dirname(os.path.abspath(__file__)), "themes") os.path.join(os.path.dirname(os.path.abspath(__file__)), "themes")
] ]

View File

@ -1,5 +1,5 @@
[Metainfo] [Metainfo]
author = BlackSnaker author = BlackSnaker
author_link = author_link =
description = Стандартная тема PortProtonQT (светлый вариант) description = Стандартная тема PortProtonQt (светлый вариант)
name = Light name = Light

View File

@ -1,5 +1,5 @@
[Metainfo] [Metainfo]
author = Dervart author = Dervart
author_link = author_link =
description = Стандартная тема PortProtonQT (тёмный вариант) description = Стандартная тема PortProtonQt (тёмный вариант)
name = Clean Dark name = Clean Dark

View File

@ -10,7 +10,7 @@ logger = get_logger(__name__)
def get_cache_file_path(): def get_cache_file_path():
"""Возвращает путь к файлу кеша portproton_last_launch.""" """Возвращает путь к файлу кеша portproton_last_launch."""
cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")) cache_home = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache"))
return os.path.join(cache_home, "PortProtonQT", "last_launch") return os.path.join(cache_home, "PortProtonQt", "last_launch")
def save_last_launch(exe_name, launch_time): def save_last_launch(exe_name, launch_time):
""" """