From 7b83c27c27b1d42c4b5bf0571b9cd21e40b73696 Mon Sep 17 00:00:00 2001 From: Dummerle Date: Tue, 13 Apr 2021 16:56:44 +0200 Subject: [PATCH] Add Desktop links for Linux --- .github/workflows/release.yml | 14 +++----- rare/__main__.py | 5 +++ rare/app.py | 2 +- rare/components/main_window.py | 22 ++++++++---- .../tabs/games/game_info/__init__.py | 33 ++++++++++++++--- .../game_widgets/base_installed_widget.py | 36 +++++++++++++++++-- .../game_widgets/installed_list_widget.py | 7 ---- rare/utils/utils.py | 33 ++++++++++++++--- 8 files changed, 117 insertions(+), 35 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6a683a50..067e06c9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -82,16 +82,10 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install Deps - run: sudo apt install - python3-all - python3-stdeb - dh-python - python3-requests - python3-pyqt5 - python3-pil - python3-qtawesome - python3-setuptools - python3-wheel + run: | + sudo apt install python3-all python3-stdeb dh-python python3-setuptools python3-wheel + sudo pip install -r requirements.txt + - name: run python setup run: | diff --git a/rare/__main__.py b/rare/__main__.py index 3ebb2560..4fb7217e 100644 --- a/rare/__main__.py +++ b/rare/__main__.py @@ -7,8 +7,13 @@ def main(): parser = ArgumentParser() parser.add_argument("-V", "--version", action="store_true") parser.add_argument("-S", "--silent", action="store_true") + subparsers = parser.add_subparsers(title="Commands", dest="subparser") + + launch_parser = subparsers.add_parser("launch") + launch_parser.add_argument('app_name', help='Name of the app', metavar='') args = parser.parse_args() + if args.version: print(__version__) exit(0) diff --git a/rare/app.py b/rare/app.py index e82e2509..dbf68fb0 100644 --- a/rare/app.py +++ b/rare/app.py @@ -77,7 +77,7 @@ class App(QApplication): self.launch_dialog.show() def start_app(self): - self.mainwindow = MainWindow(self.core) + self.mainwindow = MainWindow(self.core, self.args) self.tray_icon = TrayIcon(self) self.tray_icon.exit_action.triggered.connect(lambda: exit(0)) self.tray_icon.start_rare.triggered.connect(self.mainwindow.show) diff --git a/rare/components/main_window.py b/rare/components/main_window.py index 79375088..fd525381 100644 --- a/rare/components/main_window.py +++ b/rare/components/main_window.py @@ -1,5 +1,5 @@ -import platform -import time +from logging import getLogger + from PyQt5.QtCore import QSettings from PyQt5.QtGui import QCloseEvent from PyQt5.QtWidgets import QMainWindow, QMessageBox @@ -8,10 +8,12 @@ from custom_legendary.core import LegendaryCore from rare.components.tab_widget import TabWidget from rare.utils.rpc import DiscordRPC +logger = getLogger("Window") + class MainWindow(QMainWindow): - def __init__(self, core: LegendaryCore): + def __init__(self, core: LegendaryCore, args): super(MainWindow, self).__init__() self.settings = QSettings() self.core = core @@ -31,13 +33,20 @@ class MainWindow(QMainWindow): # Remove RPC self.tab_widget.delete_presence.connect(self.rpc.set_discord_rpc) # Show RPC on changed rare_settings - self.tab_widget.settings.rare_settings.rpc.update_settings.connect(lambda: self.rpc.changed_settings(self.tab_widget.games_tab.default_widget.game_list.running_games)) + self.tab_widget.settings.rare_settings.rpc.update_settings.connect( + lambda: self.rpc.changed_settings(self.tab_widget.games_tab.default_widget.game_list.running_games)) game = self.tab_widget.games_tab.default_widget.game_list.active_game if game != ("", 0): self.set_discord_rpc(game[0]) # Appname self.show() + if args.subparser == "launch": + logger.info("Launching " + self.core.get_installed_game(args.app_name).title) + if args.app_name in self.tab_widget.games_tab.default_widget.game_list.widgets.keys(): + self.tab_widget.games_tab.default_widget.game_list.widgets[args.app_name][1].launch() + else: + logger.info(f"Could not find {args.app_name} in Games") def closeEvent(self, e: QCloseEvent): if self.settings.value("sys_tray", True, bool): @@ -45,11 +54,12 @@ class MainWindow(QMainWindow): e.ignore() return elif self.tab_widget.downloadTab.active_game is not None: - if not QMessageBox.question(self, "Close", self.tr("There is a download active. Do you really want to exit app?"), QMessageBox.Yes, QMessageBox.No) == QMessageBox.Yes: + if not QMessageBox.question(self, "Close", + self.tr("There is a download active. Do you really want to exit app?"), + QMessageBox.Yes, QMessageBox.No) == QMessageBox.Yes: e.ignore() return if self.settings.value("save_size", False, bool): size = self.size().width(), self.size().height() self.settings.setValue("window_size", size) e.accept() - diff --git a/rare/components/tabs/games/game_info/__init__.py b/rare/components/tabs/games/game_info/__init__.py index 459066ba..85270c57 100644 --- a/rare/components/tabs/games/game_info/__init__.py +++ b/rare/components/tabs/games/game_info/__init__.py @@ -6,12 +6,11 @@ from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout, QLabel, QHBoxLayo QProgressBar, QStackedWidget, QGroupBox, QScrollArea from qtawesome import icon -from rare.components.dialogs.uninstall_dialog import UninstallDialog +from rare import utils from rare.components.tabs.games.game_info.game_settings import GameSettings -from rare.utils import legendary_utils from rare.utils.legendary_utils import VerifyThread from rare.utils.extra_widgets import SideTabBar -from rare.utils.utils import IMAGE_DIR, get_size +from rare.utils.utils import IMAGE_DIR, get_size, create_desktop_link from custom_legendary.core import LegendaryCore from custom_legendary.models.game import InstalledGame, Game @@ -49,6 +48,7 @@ class GameInfo(QScrollArea): verify_game = pyqtSignal(str) verify_threads = {} action = pyqtSignal(str) + desktop_exists = False def __init__(self, core: LegendaryCore): super(GameInfo, self).__init__() @@ -87,6 +87,10 @@ class GameInfo(QScrollArea): self.install_path.setTextInteractionFlags(Qt.TextSelectableByMouse) right_layout.addWidget(self.install_path) + self.create_desktop_link_button = QPushButton(self.tr("Create Desktop link")) + right_layout.addWidget(self.create_desktop_link_button) + self.create_desktop_link_button.clicked.connect(self.create_desktop_link) + top_layout.addLayout(right_layout) top_layout.addStretch() self.game_actions = GameActions() @@ -101,6 +105,19 @@ class GameInfo(QScrollArea): self.widget.setLayout(self.layout) self.setWidget(self.widget) + def create_desktop_link(self): + if not self.desktop_exists: + create_desktop_link(self.igame.app_name, self.core) + self.create_desktop_link_button.setText(self.tr("Remove Desktop link")) + self.desktop_exists = True + else: + if os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.desktop")): + os.remove(os.path.expanduser(f"~/Desktop/{self.igame.title}.desktop")) + elif os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.lnk")): + os.remove(os.path.expanduser(f"~/Desktop/{self.igame.title}.lnk")) + self.desktop_exists = False + self.create_desktop_link_button.setText(self.tr("Create Desktop link")) + def repair(self): repair_file = os.path.join(self.core.lgd.get_tmp_path(), f'{self.game.app_name}.repair') if not os.path.exists(repair_file): @@ -169,6 +186,13 @@ class GameInfo(QScrollArea): self.game_actions.verify_widget.setCurrentIndex(1) self.game_actions.verify_progress_bar.setValue( self.verify_threads[app_name].num / self.verify_threads[app_name].total * 100) + if os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.desktop")) \ + or os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.lnk")): + self.create_desktop_link_button.setText(self.tr("Remove Desktop link")) + self.desktop_exists = True + else: + self.create_desktop_link_button.setText(self.tr("Create Desktop link")) + self.desktop_exists = False class GameActions(QGroupBox): @@ -177,8 +201,7 @@ class GameActions(QGroupBox): self.setTitle(f"{self.tr('Game actions')}") self.setStyleSheet("QGroupBox{font-size: 20px}") self.layout = QVBoxLayout() - self.game_actions = QLabel("

Game actions

") - # self.layout.addWidget(self.game_actions) + uninstall_layout = QHBoxLayout() self.uninstall_game = QLabel(self.tr("Uninstall game")) uninstall_layout.addWidget(self.uninstall_game) diff --git a/rare/components/tabs/games/game_widgets/base_installed_widget.py b/rare/components/tabs/games/game_widgets/base_installed_widget.py index 2bf4d635..9c2b531a 100644 --- a/rare/components/tabs/games/game_widgets/base_installed_widget.py +++ b/rare/components/tabs/games/game_widgets/base_installed_widget.py @@ -1,12 +1,14 @@ +import os from logging import getLogger -from PyQt5.QtCore import pyqtSignal, QProcess, QSettings -from PyQt5.QtWidgets import QGroupBox, QMessageBox +from PyQt5.QtCore import pyqtSignal, QProcess, QSettings, Qt +from PyQt5.QtWidgets import QGroupBox, QMessageBox, QAction from custom_legendary.core import LegendaryCore from custom_legendary.models.game import InstalledGame from rare.components.dialogs.uninstall_dialog import UninstallDialog from rare.utils import legendary_utils +from rare.utils.utils import create_desktop_link logger = getLogger("Game") @@ -29,6 +31,36 @@ class BaseInstalledWidget(QGroupBox): self.setContentsMargins(0, 0, 0, 0) + self.setContextMenuPolicy(Qt.ActionsContextMenu) + launch = QAction(self.tr("Launch"), self) + launch.triggered.connect(self.launch) + self.addAction(launch) + + if os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.desktop"))\ + or os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.lnk")): + self.create_desktop = QAction(self.tr("Remove Desktop link")) + else: + self.create_desktop = QAction(self.tr("Create Desktop link")) + + self.create_desktop.triggered.connect(self.create_desktop_link) + self.addAction(self.create_desktop) + + uninstall = QAction(self.tr("Uninstall"), self) + uninstall.triggered.connect(self.uninstall) + self.addAction(uninstall) + + def create_desktop_link(self): + if not (os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.desktop"))\ + or os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.lnk"))): + create_desktop_link(self.igame.app_name, self.core) + self.create_desktop.setText(self.tr("Remove Desktop link")) + else: + if os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.desktop")): + os.remove(os.path.expanduser(f"~/Desktop/{self.igame.title}.desktop")) + elif os.path.exists(os.path.expanduser(f"~/Desktop/{self.igame.title}.lnk")): + os.remove(os.path.expanduser(f"~/Desktop/{self.igame.title}.lnk")) + self.create_desktop.setText(self.tr("Create Desktop link")) + def launch(self, offline=False, skip_version_check=False): if QSettings().value("confirm_start", False, bool): if not QMessageBox.question(self, "Launch", self.tr("Do you want to launch {}").format(self.game.app_title), diff --git a/rare/components/tabs/games/game_widgets/installed_list_widget.py b/rare/components/tabs/games/game_widgets/installed_list_widget.py index bbd715cf..96218db9 100644 --- a/rare/components/tabs/games/game_widgets/installed_list_widget.py +++ b/rare/components/tabs/games/game_widgets/installed_list_widget.py @@ -22,15 +22,8 @@ class InstalledListWidget(BaseInstalledWidget): self.dev = core.get_game(self.igame.app_name).metadata["developer"] self.size = game.install_size self.launch_params = game.launch_parameters - self.setContextMenuPolicy(Qt.ActionsContextMenu) - launch = QAction(self.tr("Launch"), self) - launch.triggered.connect(self.launch) - self.addAction(launch) - uninstall = QAction(self.tr("Uninstall"), self) - uninstall.triggered.connect(self.uninstall) - self.addAction(uninstall) self.layout = QHBoxLayout() diff --git a/rare/utils/utils.py b/rare/utils/utils.py index f29bc333..c650e708 100644 --- a/rare/utils/utils.py +++ b/rare/utils/utils.py @@ -1,13 +1,14 @@ import json import os import shutil +import sys from logging import getLogger import requests from PIL import Image, UnidentifiedImageError from PyQt5.QtCore import pyqtSignal, QLocale, QSettings -from rare import lang_path, __version__ +from rare import lang_path, __version__, style_path from custom_legendary.core import LegendaryCore logger = getLogger("Utils") @@ -40,13 +41,14 @@ def download_image(game, force=False): # to git picture updates if not os.path.isfile(f"{IMAGE_DIR}/{game.app_name}/image.json"): - json_data = {"DieselGameBoxTall": None, "DieselGameBoxLogo": None} + json_data = {"DieselGameBoxTall": None, "DieselGameBoxLogo": None, "Thumbnail": None} else: json_data = json.load(open(f"{IMAGE_DIR}/{game.app_name}/image.json", "r")) # Download for image in game.metadata["keyImages"]: - if image["type"] == "DieselGameBoxTall" or image["type"] == "DieselGameBoxLogo": - + if image["type"] == "DieselGameBoxTall" or image["type"] == "DieselGameBoxLogo" or image["type"] == "Thumbnail": + if image["type"] not in json_data.keys(): + json_data[image["type"]] = None if json_data[image["type"]] != image["md5"] or not os.path.isfile( f"{IMAGE_DIR}/{game.app_name}/{image['type']}.png"): # Download @@ -131,3 +133,26 @@ def get_size(b: int) -> str: if b < 1024: return f"{b:.2f}{i}B" b /= 1024 + + +def create_desktop_link(app_name, core: LegendaryCore): + igame = core.get_installed_game(app_name) + + # Linux + if os.name == "posix": + if os.path.exists(os.path.join(QSettings('Rare', 'Rare').value('img_dir', os.path.expanduser('~/.cache/rare/images'), str), igame.app_name, 'Thumbnail.png')): + icon = os.path.join(QSettings('Rare', 'Rare').value('img_dir', os.path.expanduser('~/.cache/rare/images'), str), igame.app_name, 'Thumbnail.png') + else: + icon = os.path.join(QSettings('Rare', 'Rare').value('img_dir', os.path.expanduser('~/.cache/rare/images'), str), igame.app_name, 'DieselGameBoxTall.png') + with open(os.path.expanduser(f"~/Desktop/{igame.title}.desktop"), "w") as desktop_file: + desktop_file.write("[Desktop Entry]\n" + f"Name={igame.title}\n" + f"Type=Application\n" + f"Icon={icon}\n" + f"Exec=rare launch {app_name}\n" + "Terminal=false\n" + "StartupWMClass=rare-game\n" + ) + os.chmod(os.path.expanduser(f"~/Desktop/{igame.title}.desktop"), 0o755) + elif os.name == "nt": + logger.info("Create a shortcut is currently not supported on windows")