1
0
Fork 0
mirror of synced 2024-06-02 18:54:41 +12:00
Rare/rare/app.py

275 lines
10 KiB
Python
Raw Normal View History

2021-04-05 20:57:11 +12:00
import configparser
2021-03-18 02:16:33 +13:00
import logging
2021-03-19 00:45:59 +13:00
import os
import platform
2021-03-25 05:01:12 +13:00
import sys
import time
import traceback
2021-03-18 02:16:33 +13:00
2021-12-11 08:05:51 +13:00
from PyQt5.QtCore import QThreadPool, QSettings, QTranslator
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMessageBox
2021-10-15 10:05:00 +13:00
from requests import HTTPError
2021-03-18 02:16:33 +13:00
import legendary
2021-12-10 09:59:07 +13:00
# noinspection PyUnresolvedReferences
import rare.resources.resources
2021-10-21 06:19:03 +13:00
import rare.shared as shared
2021-12-11 08:05:51 +13:00
from rare import cache_dir, resources_path
2021-04-08 08:39:23 +12:00
from rare.components.dialogs.launch_dialog import LaunchDialog
from rare.components.main_window import MainWindow
from rare.components.tray_icon import TrayIcon
from rare.utils.utils import set_color_pallete, set_style_sheet
2021-03-18 02:16:33 +13:00
2021-12-24 22:09:50 +13:00
start_time = time.strftime("%y-%m-%d--%H-%M") # year-month-day-hour-minute
file_name = os.path.join(cache_dir, "logs", f"Rare_{start_time}.log")
if not os.path.exists(os.path.dirname(file_name)):
os.makedirs(os.path.dirname(file_name))
2021-03-18 02:16:33 +13:00
logger = logging.getLogger("Rare")
def excepthook(exc_type, exc_value, exc_tb):
tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
print("Error")
2021-10-15 10:05:00 +13:00
if exc_tb == HTTPError:
try:
2021-10-15 10:18:13 +13:00
if shared.core.login():
2021-10-15 10:05:00 +13:00
return
else:
raise ValueError
except Exception as e:
logger.fatal(str(e))
QMessageBox.warning(None, "Error", QApplication.tr("Failed to login"))
QApplication.exit(1)
return
logger.fatal(tb)
QMessageBox.warning(None, "Error", tb)
QApplication.exit(1)
2021-03-25 05:01:12 +13:00
class App(QApplication):
mainwindow: MainWindow = None
tray_icon: QSystemTrayIcon = None
2021-10-08 07:19:24 +13:00
def __init__(self):
2021-03-25 05:01:12 +13:00
super(App, self).__init__(sys.argv)
2021-10-08 07:19:24 +13:00
self.args = shared.args # add some options
self.window_launched = False
self.setQuitOnLastWindowClosed(False)
2021-03-27 06:23:22 +13:00
# init Legendary
2021-04-05 20:57:11 +12:00
try:
2021-10-08 07:19:24 +13:00
self.core = shared.init_legendary()
2021-04-05 20:57:11 +12:00
except configparser.MissingSectionHeaderError as e:
logger.warning(f"Config is corrupt: {e}")
2021-12-24 22:09:50 +13:00
if config_path := os.environ.get("XDG_CONFIG_HOME"):
path = os.path.join(config_path, "legendary")
2021-04-05 20:57:11 +12:00
else:
2021-12-24 22:09:50 +13:00
path = os.path.expanduser("~/.config/legendary")
2021-04-05 20:57:11 +12:00
with open(os.path.join(path, "config.ini"), "w") as config_file:
config_file.write("[Legendary]")
2021-10-21 06:19:03 +13:00
self.core = shared.init_legendary()
2021-04-08 08:39:23 +12:00
if "Legendary" not in self.core.lgd.config.sections():
2021-03-27 06:23:22 +13:00
self.core.lgd.config.add_section("Legendary")
self.core.lgd.save_config()
# workaround if egl sync enabled, but no programdata_path
# programdata_path might be unset if logging in through the browser
if self.core.egl_sync_enabled:
if self.core.egl.programdata_path is None:
self.core.lgd.config.remove_option("Legendary", "egl_sync")
self.core.lgd.save_config()
else:
if not os.path.exists(self.core.egl.programdata_path):
self.core.lgd.config.remove_option("Legendary", "egl_sync")
self.core.lgd.save_config()
2021-05-21 09:00:38 +12:00
2021-04-05 20:57:11 +12:00
# set Application name for settings
self.launch_dialog = None
2021-03-25 05:01:12 +13:00
self.setApplicationName("Rare")
self.setOrganizationName("Rare")
2021-09-30 10:22:47 +13:00
self.settings = QSettings()
2021-10-08 07:19:24 +13:00
self.signals = shared.init_signals()
2021-10-15 10:05:00 +13:00
self.signals.exit_app.connect(self.exit_app)
2021-10-15 10:05:00 +13:00
self.signals.send_notification.connect(
2021-12-24 22:09:50 +13:00
lambda title: self.tray_icon.showMessage(
2021-10-15 10:05:00 +13:00
self.tr("Download finished"),
self.tr("Download finished. {} is playable now").format(title),
2021-12-24 22:09:50 +13:00
QSystemTrayIcon.Information,
4000,
)
if self.settings.value("notification", True, bool)
else None
)
2021-03-25 05:01:12 +13:00
# Translator
self.translator = QTranslator()
2021-09-30 10:22:47 +13:00
lang = self.settings.value("language", self.core.language_code, type=str)
2021-12-10 09:59:07 +13:00
2021-12-11 08:05:51 +13:00
if os.path.isfile(f := os.path.join(resources_path, "languages", f"{lang}.qm")):
self.translator.load(f)
logger.info("Your language is supported: " + lang)
2021-03-25 05:01:12 +13:00
elif not lang == "en":
logger.info("Your language is not supported")
self.installTranslator(self.translator)
# translator for qt stuff
2021-12-11 08:05:51 +13:00
if os.path.isfile(f := os.path.join(resources_path, f"qt_{lang}.qm")):
self.qt_translator = QTranslator()
2021-12-11 08:05:51 +13:00
self.qt_translator.load(f)
self.installTranslator(self.qt_translator)
2021-03-25 05:01:12 +13:00
# Style
# lk: this is a bit silly but serves well until we have a class
# lk: store the default qt style name from the system on startup as a property for later reference
2021-12-24 22:09:50 +13:00
self.setProperty("rareDefaultQtStyle", self.style().objectName())
2021-12-24 22:09:50 +13:00
if (
self.settings.value("color_scheme", None) is None
and self.settings.value("style_sheet", None) is None
):
2021-09-30 10:22:47 +13:00
self.settings.setValue("color_scheme", "")
self.settings.setValue("style_sheet", "RareStyle")
2021-10-21 06:19:03 +13:00
if color_scheme := self.settings.value("color_scheme", False):
2021-09-30 10:22:47 +13:00
self.settings.setValue("style_sheet", "")
set_color_pallete(color_scheme)
elif style_sheet := self.settings.value("style_sheet", False):
2021-09-30 10:22:47 +13:00
self.settings.setValue("color_scheme", "")
set_style_sheet(style_sheet)
2021-12-10 09:59:07 +13:00
self.setWindowIcon(QIcon(":/images/Rare.png"))
2021-03-25 05:01:12 +13:00
2021-04-05 20:57:11 +12:00
# launch app
2021-10-08 07:19:24 +13:00
self.launch_dialog = LaunchDialog()
self.launch_dialog.quit_app.connect(self.launch_dialog.close)
self.launch_dialog.quit_app.connect(lambda ec: exit(ec))
2021-03-25 05:01:12 +13:00
self.launch_dialog.start_app.connect(self.start_app)
self.launch_dialog.start_app.connect(self.launch_dialog.close)
2021-04-20 01:44:28 +12:00
self.launch_dialog.login()
2021-03-25 05:01:12 +13:00
def show_mainwindow(self):
if self.window_launched:
self.mainwindow.show()
else:
self.mainwindow.show_window_centralized()
2021-10-08 07:19:24 +13:00
def start_app(self):
self.mainwindow = MainWindow()
2021-10-04 08:29:33 +13:00
self.launch_dialog.close()
2021-04-08 00:46:27 +12:00
self.tray_icon = TrayIcon(self)
self.tray_icon.exit_action.triggered.connect(self.exit_app)
self.tray_icon.start_rare.triggered.connect(self.show_mainwindow)
2021-12-24 22:09:50 +13:00
self.tray_icon.activated.connect(
lambda r: self.show_mainwindow()
if r == QSystemTrayIcon.DoubleClick
else None
)
2021-03-18 02:16:33 +13:00
if not self.args.silent:
self.mainwindow.show_window_centralized()
self.window_launched = True
if shared.args.subparser == "launch":
2021-12-24 22:09:50 +13:00
if shared.args.app_name in [
i.app_name for i in self.core.get_installed_list()
]:
logger.info(
"Launching "
+ self.core.get_installed_game(shared.args.app_name).title
)
self.mainwindow.tab_widget.games_tab.game_utils.prepare_launch(
shared.args.app_name
)
else:
logger.error(
2021-12-24 22:09:50 +13:00
f"Could not find {shared.args.app_name} in Games or it is not installed"
)
QMessageBox.warning(
self.mainwindow,
"Warning",
self.tr(
"Could not find {} in installed games. Did you modify the shortcut? "
).format(shared.args.app_name),
)
if shared.args.test_start:
self.exit_app(0)
2021-04-08 00:46:27 +12:00
def tray(self, reason):
if reason == QSystemTrayIcon.DoubleClick:
self.mainwindow.show()
logger.info("Show App")
def exit_app(self, exit_code=0):
2021-11-23 10:35:37 +13:00
# FIXME: Fix this with the downlaod tab redesign
if self.mainwindow is not None:
if not shared.args.offline and self.mainwindow.tab_widget.downloadTab.is_download_active:
2021-11-23 10:35:37 +13:00
question = QMessageBox.question(
self.mainwindow,
self.tr("Close"),
2021-12-24 22:09:50 +13:00
self.tr(
"There is a download active. Do you really want to exit app?"
),
QMessageBox.Yes,
QMessageBox.No,
)
2021-11-23 10:35:37 +13:00
if question == QMessageBox.No:
return
else:
# clear queue
self.mainwindow.tab_widget.downloadTab.queue_widget.update_queue([])
2021-11-23 10:35:37 +13:00
self.mainwindow.tab_widget.downloadTab.stop_download()
# FIXME: End of FIXME
self.mainwindow.timer.stop()
2021-10-21 06:19:03 +13:00
self.mainwindow.hide()
threadpool = QThreadPool.globalInstance()
threadpool.waitForDone()
if self.mainwindow is not None:
self.mainwindow.close()
2021-10-21 06:19:03 +13:00
if self.tray_icon is not None:
self.tray_icon.deleteLater()
self.processEvents()
self.exit(exit_code)
2021-03-25 05:01:12 +13:00
def start(args):
# set excepthook to show dialog with exception
sys.excepthook = excepthook
2021-10-08 07:19:24 +13:00
shared.init_args(args)
# configure logging
if args.debug:
2021-12-24 22:09:50 +13:00
logging.basicConfig(
format="[%(name)s] %(levelname)s: %(message)s", level=logging.DEBUG
)
logging.getLogger().setLevel(level=logging.DEBUG)
2021-09-13 07:19:51 +12:00
# keep requests, asyncio and pillow quiet
2021-12-24 22:09:50 +13:00
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
2021-09-13 07:19:51 +12:00
logging.getLogger("asyncio").setLevel(logging.WARNING)
2021-12-24 22:09:50 +13:00
logger.info(
f"Launching Rare version {rare.__version__} Codename: {rare.code_name}\n"
f"Using Legendary {legendary.__version__} Codename: {legendary.__codename__} as backend\n"
f"Operating System: {platform.system()}, Python version: {platform.python_version()}\n"
f"Running {sys.executable} {' '.join(sys.argv)}"
)
else:
logging.basicConfig(
2021-12-24 22:09:50 +13:00
format="[%(name)s] %(levelname)s: %(message)s",
level=logging.INFO,
filename=file_name,
)
while True:
2021-10-08 07:19:24 +13:00
app = App()
exit_code = app.exec_()
# if not restart
# restart app
del app
if exit_code != -133742:
break