1
0
Fork 0
mirror of synced 2024-06-09 22:24:40 +12:00

Merge pull request #154 from Dummerle/game_meta

Save last played time and add quick launch for tray icon
This commit is contained in:
Dummerle 2022-01-06 18:27:37 +01:00 committed by GitHub
commit 6f99c22a72
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 24 deletions

View file

@ -1,3 +1,4 @@
import datetime
import os
import platform
import shutil
@ -14,6 +15,7 @@ from rare.components.dialogs.uninstall_dialog import UninstallDialog
from rare.components.extra.console import ConsoleWindow
from rare.components.tabs.games import CloudSaveUtils
from rare.utils import legendary_utils
from rare.utils.meta import RareGameMeta
logger = getLogger("GameUtils")
@ -50,6 +52,7 @@ class GameUtils(QObject):
self.console = ConsoleWindow()
self.cloud_save_utils = CloudSaveUtils()
self.cloud_save_utils.sync_finished.connect(self.sync_finished)
self.game_meta = RareGameMeta()
def uninstall_game(self, app_name) -> bool:
# returns if uninstalled
@ -57,13 +60,13 @@ class GameUtils(QObject):
igame = self.core.get_installed_game(app_name)
if not os.path.exists(igame.install_path):
if QMessageBox.Yes == QMessageBox.question(
None,
"Uninstall",
self.tr(
"Game files of {} do not exist. Remove it from installed games?"
).format(igame.title),
QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes,
None,
"Uninstall",
self.tr(
"Game files of {} do not exist. Remove it from installed games?"
).format(igame.title),
QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes,
):
self.core.lgd.remove_installed_game(app_name)
return True
@ -78,7 +81,7 @@ class GameUtils(QObject):
return True
def prepare_launch(
self, app_name, offline: bool = False, skip_update_check: bool = False
self, app_name, offline: bool = False, skip_update_check: bool = False
):
game = self.core.get_game(app_name)
dont_sync_after_finish = False
@ -102,19 +105,23 @@ class GameUtils(QObject):
)
def launch_game(
self,
app_name: str,
offline: bool = False,
skip_update_check: bool = False,
wine_bin: str = None,
wine_pfx: str = None,
ask_always_sync: bool = False,
self,
app_name: str,
offline: bool = False,
skip_update_check: bool = False,
wine_bin: str = None,
wine_pfx: str = None,
ask_always_sync: bool = False,
):
if shared.args.offline:
offline = True
game = self.core.get_game(app_name)
igame = self.core.get_installed_game(app_name)
meta_data = self.game_meta.get_game(app_name)
meta_data.last_played = datetime.datetime.now()
self.game_meta.set_game(app_name, meta_data)
if not game:
logger.error(f"{app_name} not found")
self.finished.emit(app_name, self.tr("Game not found in available games"))
@ -122,13 +129,13 @@ class GameUtils(QObject):
if QSettings().value("confirm_start", False, bool):
if (
not QMessageBox.question(
None,
"Launch",
self.tr("Do you want to launch {}").format(game.app_title),
QMessageBox.Yes | QMessageBox.No,
)
== QMessageBox.Yes
not QMessageBox.question(
None,
"Launch",
self.tr("Do you want to launch {}").format(game.app_title),
QMessageBox.Yes | QMessageBox.No,
)
== QMessageBox.Yes
):
logger.info("Cancel Startup")
self.finished.emit(app_name, "")

View file

@ -1,6 +1,11 @@
from typing import List
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QSystemTrayIcon, QMenu, QAction
from rare import shared
from rare.utils.meta import GameMeta
class TrayIcon(QSystemTrayIcon):
def __init__(self, parent):
@ -14,8 +19,34 @@ class TrayIcon(QSystemTrayIcon):
self.start_rare = QAction("Rare")
self.menu.addAction(self.start_rare)
self.exit_action = QAction(self.tr("Exit"))
self.menu.addSeparator()
self.menu.addAction(self.exit_action)
self.text_action = QAction("Quick launch")
self.text_action.setEnabled(False)
self.menu.addAction(self.text_action)
if len(installed := shared.core.get_installed_list()) < 5:
last_played = [GameMeta(i.app_name) for i in sorted(installed, key=lambda x: x.title)]
elif games := sorted(
parent.mainwindow.tab_widget.games_tab.game_utils.game_meta.get_games(),
key=lambda x: x.last_played, reverse=True):
last_played: List[GameMeta] = games[0:5]
else:
last_played = [GameMeta(i.app_name) for i in sorted(installed, key=lambda x: x.title)][0:5]
self.game_actions = []
for game in last_played:
a = QAction(shared.core.get_game(game.app_name).app_title)
a.setProperty("app_name", game.app_name)
self.game_actions.append(a)
a.triggered.connect(
lambda: parent.mainwindow.tab_widget.games_tab.game_utils.prepare_launch(
self.sender().property("app_name"))
)
self.menu.addActions(self.game_actions)
self.menu.addSeparator()
self.exit_action = QAction(self.tr("Exit"))
self.menu.addAction(self.exit_action)
self.setContextMenu(self.menu)

64
rare/utils/meta.py Normal file
View file

@ -0,0 +1,64 @@
import json
import os
from dataclasses import dataclass
from datetime import datetime
from logging import getLogger
from typing import Dict
from rare import data_dir
logger = getLogger("GameMeta")
@dataclass
class GameMeta:
app_name: str
last_played: datetime = None
@classmethod
def from_json(cls, data):
return cls(
app_name=data["app_name"],
last_played=datetime.strptime(data.get("last_played", "None"), '%Y-%m-%dT%H:%M:%S.%f')
)
def __dict__(self):
return dict(
app_name=self.app_name,
last_played=self.last_played.strftime("%Y-%m-%dT%H:%M:%S.%f")
)
class RareGameMeta:
_meta: Dict[str, GameMeta] = {}
def __init__(self):
meta_data = {}
if os.path.exists(p := os.path.join(data_dir, "game_meta.json")):
try:
meta_data = json.load(open(p))
except json.JSONDecodeError:
logger.warning("Game meta json file corrupt")
else:
with open(p, "w") as file:
file.write("{}")
for app_name, data in meta_data.items():
self._meta[app_name] = GameMeta.from_json(data)
def get_games(self):
return list(self._meta.values())
def get_game(self, app_name):
return self._meta.get(app_name, GameMeta(app_name))
def set_game(self, app_name: str, game: GameMeta):
self._meta[app_name] = game
self.save_file()
def save_file(self):
json.dump(
{app_name: data.__dict__() for app_name, data in self._meta.items()},
open(os.path.join(data_dir, "game_meta.json"), "w"),
indent=4
)