Merge pull request #154 from Dummerle/game_meta
Save last played time and add quick launch for tray icon
This commit is contained in:
commit
6f99c22a72
|
@ -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, "")
|
||||
|
|
|
@ -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
64
rare/utils/meta.py
Normal 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
|
||||
)
|
Loading…
Reference in a new issue