Merge pull request #239 from loathingKernel/fixups
Fix logging, application paths and shortcuts
This commit is contained in:
commit
0c45bd918c
7
.github/workflows/tests.yml
vendored
7
.github/workflows/tests.yml
vendored
|
@ -14,12 +14,13 @@ jobs:
|
|||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.10
|
||||
python-version: '3.10'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pylint
|
||||
pip install -r requirements.txt
|
||||
pip install pypresence
|
||||
- name: Analysing the code with pylint
|
||||
run: |
|
||||
pylint -E rare --disable=E0611,E1123,E1120 --ignore=ui,singleton.py --extension-pkg-whitelist=PyQt5
|
||||
|
@ -76,7 +77,6 @@ jobs:
|
|||
name: Rare.AppImage
|
||||
path: Rare.AppImage
|
||||
|
||||
|
||||
cx_freeze:
|
||||
runs-on: "windows-latest"
|
||||
steps:
|
||||
|
@ -90,6 +90,8 @@ jobs:
|
|||
run: pip3 install -r requirements.txt
|
||||
- name: cx_freeze
|
||||
run: pip3 install --upgrade cx_freeze wheel
|
||||
- name: pypresence
|
||||
run: pip3 install pypresence
|
||||
- name: Build
|
||||
run: python freeze.py bdist_msi
|
||||
|
||||
|
@ -97,6 +99,7 @@ jobs:
|
|||
with:
|
||||
name: Rare-Windows.msi
|
||||
path: dist/*.msi
|
||||
|
||||
mac_os:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import multiprocessing
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
|
@ -6,8 +7,6 @@ from argparse import ArgumentParser
|
|||
|
||||
def main():
|
||||
# fix cx_freeze
|
||||
import multiprocessing
|
||||
|
||||
multiprocessing.freeze_support()
|
||||
|
||||
# insert legendary for installed via pip/setup.py submodule to path
|
||||
|
@ -95,9 +94,9 @@ def main():
|
|||
me = singleton.SingleInstance()
|
||||
except singleton.SingleInstanceException:
|
||||
print("Rare is already running")
|
||||
from rare.utils.paths import data_dir
|
||||
from rare.utils.paths import lock_file
|
||||
|
||||
with open(os.path.join(data_dir, "lockfile"), "w") as file:
|
||||
with open(lock_file(), "w") as file:
|
||||
file.write("show")
|
||||
file.close()
|
||||
return
|
||||
|
|
83
rare/app.py
83
rare/app.py
|
@ -24,14 +24,9 @@ from rare.shared import (
|
|||
ArgumentsSingleton,
|
||||
)
|
||||
from rare.shared.rare_core import RareCore
|
||||
from rare.utils import legendary_utils, config_helper
|
||||
from rare.utils.paths import cache_dir, tmp_dir
|
||||
from rare.utils import legendary_utils, config_helper, paths
|
||||
from rare.widgets.rare_app import RareApp
|
||||
|
||||
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))
|
||||
|
||||
logger = logging.getLogger("Rare")
|
||||
|
||||
|
@ -57,7 +52,49 @@ def excepthook(exc_type, exc_value, exc_tb):
|
|||
|
||||
class App(RareApp):
|
||||
def __init__(self, args: Namespace):
|
||||
super(App, self).__init__()
|
||||
super(App, self).__init__(args)
|
||||
|
||||
start_time = time.strftime("%y-%m-%d--%H-%M") # year-month-day-hour-minute
|
||||
file_name = os.path.join(paths.log_dir(), f"Rare_{start_time}.log")
|
||||
|
||||
for handler in logging.root.handlers[:]:
|
||||
logging.root.removeHandler(handler)
|
||||
|
||||
file_handler = logging.FileHandler(filename=file_name, encoding="utf-8")
|
||||
file_handler.setFormatter(fmt=logging.Formatter("[%(name)s] %(levelname)s: %(message)s"))
|
||||
|
||||
# configure logging
|
||||
if args.debug:
|
||||
logging.basicConfig(
|
||||
format="[%(name)s] %(levelname)s: %(message)s",
|
||||
level=logging.DEBUG,
|
||||
stream=sys.stderr,
|
||||
)
|
||||
file_handler.setLevel(logging.DEBUG)
|
||||
logging.root.addHandler(file_handler)
|
||||
logging.getLogger().setLevel(level=logging.DEBUG)
|
||||
# keep requests, asyncio and pillow quiet
|
||||
logging.getLogger("requests").setLevel(logging.WARNING)
|
||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
||||
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)}\n"
|
||||
f" - Qt version: {QT_VERSION_STR}, PyQt version: {PYQT_VERSION_STR}"
|
||||
)
|
||||
else:
|
||||
logging.basicConfig(
|
||||
format="[%(name)s] %(levelname)s: %(message)s",
|
||||
level=logging.INFO,
|
||||
stream=sys.stderr,
|
||||
)
|
||||
file_handler.setLevel(logging.INFO)
|
||||
logging.root.addHandler(file_handler)
|
||||
logger.info(f"Launching Rare version {rare.__version__}")
|
||||
logger.info(f"Operating System: {platform.system()}")
|
||||
|
||||
self.rare_core = RareCore(args=args)
|
||||
self.args = ArgumentsSingleton()
|
||||
self.signals = GlobalSignalsSingleton()
|
||||
|
@ -71,6 +108,7 @@ class App(RareApp):
|
|||
# set Application name for settings
|
||||
self.mainwindow: Optional[MainWindow] = None
|
||||
self.launch_dialog: Optional[LaunchDialog] = None
|
||||
self.timer = QTimer()
|
||||
|
||||
# launch app
|
||||
self.launch_dialog = LaunchDialog(parent=None)
|
||||
|
@ -84,7 +122,6 @@ class App(RareApp):
|
|||
dt_exp = datetime.fromisoformat(self.core.lgd.userdata['expires_at'][:-1])
|
||||
dt_now = datetime.utcnow()
|
||||
td = abs(dt_exp - dt_now)
|
||||
self.timer = QTimer()
|
||||
self.timer.timeout.connect(self.re_login)
|
||||
self.timer.start(int(td.total_seconds() - 60) * 1000)
|
||||
|
||||
|
@ -142,8 +179,8 @@ class App(RareApp):
|
|||
self.rare_core.deleteLater()
|
||||
del self.rare_core
|
||||
self.processEvents()
|
||||
shutil.rmtree(tmp_dir)
|
||||
os.makedirs(tmp_dir)
|
||||
shutil.rmtree(paths.tmp_dir())
|
||||
os.makedirs(paths.tmp_dir())
|
||||
|
||||
self.exit(exit_code)
|
||||
|
||||
|
@ -152,32 +189,6 @@ def start(args):
|
|||
# set excepthook to show dialog with exception
|
||||
sys.excepthook = excepthook
|
||||
|
||||
# configure logging
|
||||
if args.debug:
|
||||
logging.basicConfig(
|
||||
format="[%(name)s] %(levelname)s: %(message)s", level=logging.DEBUG
|
||||
)
|
||||
logging.getLogger().setLevel(level=logging.DEBUG)
|
||||
# keep requests, asyncio and pillow quiet
|
||||
logging.getLogger("requests").setLevel(logging.WARNING)
|
||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
||||
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)}\n"
|
||||
f" - Qt version: {QT_VERSION_STR}, PyQt version: {PYQT_VERSION_STR}"
|
||||
)
|
||||
else:
|
||||
logging.basicConfig(
|
||||
format="[%(name)s] %(levelname)s: %(message)s",
|
||||
level=logging.INFO,
|
||||
filename=file_name,
|
||||
)
|
||||
logger.info(f"Launching Rare version {rare.__version__}")
|
||||
logger.info(f"Operating System: {platform.system()}")
|
||||
|
||||
while True:
|
||||
app = App(args)
|
||||
exit_code = app.exec_()
|
||||
|
|
|
@ -309,6 +309,9 @@ class InstallDialog(QDialog):
|
|||
self.show()
|
||||
|
||||
def error_box(self, label: str = "", message: str = ""):
|
||||
if message.startswith("403 Client Error: Forbidden for url:"):
|
||||
message = self.tr("403 Client Error: Wait a few seconds and try <b>Verify</b> again")
|
||||
self.options_changed = True
|
||||
self.ui.warn_label.setVisible(bool(label))
|
||||
self.ui.warn_label.setText(label)
|
||||
self.ui.warn_message.setVisible(bool(message))
|
||||
|
|
|
@ -11,7 +11,7 @@ from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton, ApiResultsSi
|
|||
from rare.ui.components.dialogs.launch_dialog import Ui_LaunchDialog
|
||||
from rare.utils.misc import CloudWorker
|
||||
|
||||
logger = getLogger("LoginDialog")
|
||||
logger = getLogger("LaunchDialog")
|
||||
|
||||
|
||||
class LaunchWorker(QRunnable):
|
||||
|
|
|
@ -12,7 +12,7 @@ from rare.widgets.sliding_stack import SlidingStackedWidget
|
|||
from .browser_login import BrowserLogin
|
||||
from .import_login import ImportLogin
|
||||
|
||||
logger = getLogger("Login")
|
||||
logger = getLogger("LoginDialog")
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
|
@ -8,7 +8,7 @@ from PyQt5.QtWidgets import QMainWindow, QApplication, QStatusBar, QScrollArea,
|
|||
from rare.components.tabs import TabWidget
|
||||
from rare.components.tray_icon import TrayIcon
|
||||
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton
|
||||
from rare.utils.paths import data_dir
|
||||
from rare.utils.paths import lock_file
|
||||
|
||||
logger = getLogger("MainWindow")
|
||||
|
||||
|
@ -125,7 +125,7 @@ class MainWindow(QMainWindow):
|
|||
self.hide()
|
||||
|
||||
def timer_finished(self):
|
||||
file_path = os.path.join(data_dir, "lockfile")
|
||||
file_path = lock_file()
|
||||
if os.path.exists(file_path):
|
||||
file = open(file_path, "r")
|
||||
action = file.read()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import datetime
|
||||
from logging import getLogger
|
||||
from typing import List, Dict, Union
|
||||
from typing import List, Dict, Union, Set
|
||||
|
||||
from PyQt5.QtCore import QThread, pyqtSignal, QSettings, pyqtSlot
|
||||
from PyQt5.QtWidgets import (
|
||||
|
@ -31,7 +31,7 @@ class DownloadsTab(QWidget, Ui_DownloadsTab):
|
|||
dl_queue: List[InstallQueueItemModel] = []
|
||||
dl_status = pyqtSignal(int)
|
||||
|
||||
def __init__(self, updates: list):
|
||||
def __init__(self, updates: Set):
|
||||
super(DownloadsTab, self).__init__()
|
||||
self.setupUi(self)
|
||||
self.core = LegendaryCoreSingleton()
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
from logging import getLogger
|
||||
from typing import Tuple, Dict, Union, List
|
||||
from typing import Tuple, Dict, Union, List, Set
|
||||
|
||||
from PyQt5.QtCore import QSettings, Qt, pyqtSlot
|
||||
from PyQt5.QtWidgets import QStackedWidget, QVBoxLayout, QWidget, QScrollArea, QFrame
|
||||
from legendary.models.game import InstalledGame, Game
|
||||
|
||||
from rare.shared import ImageManagerSingleton
|
||||
from rare.shared import (
|
||||
LegendaryCoreSingleton,
|
||||
GlobalSignalsSingleton,
|
||||
ArgumentsSingleton,
|
||||
ApiResultsSingleton,
|
||||
ImageManagerSingleton,
|
||||
)
|
||||
from rare.widgets.library_layout import LibraryLayout
|
||||
from rare.widgets.sliding_stack import SlidingStackedWidget
|
||||
|
@ -32,10 +32,6 @@ logger = getLogger("GamesTab")
|
|||
|
||||
|
||||
class GamesTab(QStackedWidget):
|
||||
|
||||
updates = set()
|
||||
active_filter = 0
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(GamesTab, self).__init__(parent=parent)
|
||||
self.core = LegendaryCoreSingleton()
|
||||
|
@ -47,6 +43,8 @@ class GamesTab(QStackedWidget):
|
|||
|
||||
self.widgets: Dict[str, Tuple[
|
||||
Union[InstalledIconWidget, UninstalledIconWidget], Union[InstalledListWidget, UninstalledListWidget]]] = {}
|
||||
self.updates: Set = set()
|
||||
self.active_filter: int = 0
|
||||
self.uninstalled_games: List[Game] = []
|
||||
|
||||
self.game_list: List[Game] = self.api_results.game_list
|
||||
|
|
|
@ -10,7 +10,7 @@ from PyQt5.QtWidgets import QWidget, QMessageBox
|
|||
from rare.shared import LegendaryCoreSingleton
|
||||
from rare.components.tabs.settings.widgets.rpc import RPCSettings
|
||||
from rare.ui.components.tabs.settings.rare import Ui_RareSettings
|
||||
from rare.utils.paths import cache_dir
|
||||
from rare.utils.paths import log_dir
|
||||
from rare.utils.misc import (
|
||||
get_translations,
|
||||
get_color_schemes,
|
||||
|
@ -51,7 +51,6 @@ class RareSettings(QWidget, Ui_RareSettings):
|
|||
|
||||
self.settings = QSettings()
|
||||
language = self.settings.value("language", self.core.language_code, type=str)
|
||||
self.logdir = os.path.join(cache_dir, "logs")
|
||||
|
||||
# Select lang
|
||||
self.lang_select.addItems([i[1] for i in languages])
|
||||
|
@ -143,19 +142,18 @@ class RareSettings(QWidget, Ui_RareSettings):
|
|||
self.log_dir_open_button.clicked.connect(self.open_dir)
|
||||
self.log_dir_clean_button.clicked.connect(self.clean_logdir)
|
||||
|
||||
logdir = os.path.join(cache_dir, "logs")
|
||||
# get size of logdir
|
||||
size = 0
|
||||
for i in os.listdir(logdir):
|
||||
size += os.path.getsize(os.path.join(logdir, i))
|
||||
for i in os.listdir(log_dir()):
|
||||
size += os.path.getsize(os.path.join(log_dir(), i))
|
||||
|
||||
self.log_dir_size_label.setText(get_size(size))
|
||||
# self.log_dir_clean_button.setVisible(False)
|
||||
# self.log_dir_size_label.setVisible(False)
|
||||
|
||||
def clean_logdir(self):
|
||||
for i in os.listdir(os.path.join(cache_dir, "logs")):
|
||||
os.remove(os.path.join(cache_dir, f"logs/{i}"))
|
||||
for i in os.listdir(log_dir()):
|
||||
os.remove(os.path.join(log_dir(), f"{i}"))
|
||||
self.log_dir_size_label.setText("0KB")
|
||||
|
||||
def create_start_menu_link(self):
|
||||
|
@ -216,10 +214,10 @@ class RareSettings(QWidget, Ui_RareSettings):
|
|||
|
||||
def open_dir(self):
|
||||
if platform.system() == "Windows":
|
||||
os.startfile(self.logdir) # pylint: disable=E1101
|
||||
os.startfile(log_dir()) # pylint: disable=E1101
|
||||
else:
|
||||
opener = "open" if sys.platform == "darwin" else "xdg-open"
|
||||
subprocess.Popen([opener, self.logdir])
|
||||
subprocess.Popen([opener, log_dir()])
|
||||
|
||||
def save_window_size(self):
|
||||
self.settings.setValue("save_size", self.save_size.isChecked())
|
||||
|
|
|
@ -23,7 +23,7 @@ class Shop(QStackedWidget):
|
|||
self.core.country_code,
|
||||
)
|
||||
|
||||
self.shop = ShopWidget(cache_dir, self.core, self.api_core)
|
||||
self.shop = ShopWidget(cache_dir(), self.core, self.api_core)
|
||||
self.wishlist_widget = Wishlist(self.api_core)
|
||||
|
||||
self.store_tabs = QTabWidget()
|
||||
|
|
|
@ -61,13 +61,13 @@ class GameProcessApp(RareApp):
|
|||
server: QLocalServer
|
||||
socket: Optional[QLocalSocket] = None
|
||||
exit_app = pyqtSignal()
|
||||
console: Console = None
|
||||
console: Optional[Console] = None
|
||||
success: bool = True
|
||||
|
||||
def __init__(self, app_name: str):
|
||||
super(GameProcessApp, self).__init__()
|
||||
def __init__(self, args: Namespace):
|
||||
super(GameProcessApp, self).__init__(args)
|
||||
self.game_process = QProcess()
|
||||
self.app_name = app_name
|
||||
self.app_name = args.app_name
|
||||
self.logger = getLogger(self.app_name)
|
||||
self.core = LegendaryCore()
|
||||
|
||||
|
@ -211,7 +211,7 @@ def start_game(args: Namespace):
|
|||
level=logging.INFO,
|
||||
)
|
||||
|
||||
app = GameProcessApp(args.app_name)
|
||||
app = GameProcessApp(args)
|
||||
app.setQuitOnLastWindowClosed(True)
|
||||
|
||||
def excepthook(exc_type, exc_value, exc_tb):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import platform
|
||||
|
||||
from PyQt5.QtCore import QProcessEnvironment, pyqtSignal
|
||||
from PyQt5.QtGui import QTextCursor, QFont
|
||||
from PyQt5.QtCore import QProcessEnvironment, pyqtSignal, QSize
|
||||
from PyQt5.QtGui import QTextCursor, QFont, QCursor
|
||||
from PyQt5.QtWidgets import (
|
||||
QPlainTextEdit,
|
||||
QDialog,
|
||||
|
@ -10,7 +10,7 @@ from PyQt5.QtWidgets import (
|
|||
QVBoxLayout,
|
||||
QHBoxLayout,
|
||||
QSpacerItem,
|
||||
QSizePolicy, QTableWidgetItem, QHeaderView,
|
||||
QSizePolicy, QTableWidgetItem, QHeaderView, QApplication,
|
||||
)
|
||||
|
||||
from rare.ui.components.extra.console_env import Ui_ConsoleEnv
|
||||
|
@ -24,7 +24,7 @@ class Console(QDialog):
|
|||
def __init__(self, parent=None):
|
||||
super(Console, self).__init__(parent=parent)
|
||||
self.setWindowTitle("Rare - Console")
|
||||
self.setGeometry(0, 0, 600, 400)
|
||||
self.setGeometry(0, 0, 640, 480)
|
||||
layout = QVBoxLayout()
|
||||
|
||||
self.console = ConsoleEdit(self)
|
||||
|
@ -63,6 +63,31 @@ class Console(QDialog):
|
|||
self.env_variables = ConsoleEnv(self)
|
||||
self.env_variables.hide()
|
||||
|
||||
def show(self) -> None:
|
||||
super(Console, self).show()
|
||||
self.center_window()
|
||||
|
||||
def center_window(self):
|
||||
# get the margins of the decorated window
|
||||
margins = self.windowHandle().frameMargins()
|
||||
# get the screen the cursor is on
|
||||
current_screen = QApplication.screenAt(QCursor.pos())
|
||||
if not current_screen:
|
||||
current_screen = QApplication.primaryScreen()
|
||||
# get the available screen geometry (excludes panels/docks)
|
||||
screen_rect = current_screen.availableGeometry()
|
||||
decor_width = margins.left() + margins.right()
|
||||
decor_height = margins.top() + margins.bottom()
|
||||
window_size = QSize(self.width(), self.height()).boundedTo(
|
||||
screen_rect.size() - QSize(decor_width, decor_height)
|
||||
)
|
||||
|
||||
self.resize(window_size)
|
||||
self.move(
|
||||
screen_rect.center()
|
||||
- self.rect().adjusted(0, 0, decor_width, decor_height).center()
|
||||
)
|
||||
|
||||
def save(self):
|
||||
file, ok = QFileDialog.getSaveFileName(
|
||||
self, "Save output", "", "Log Files (*.log);;All Files (*)"
|
||||
|
|
|
@ -30,7 +30,7 @@ class LegendaryCLI(LegendaryCLIReal):
|
|||
# noinspection PyMissingConstructor
|
||||
def __init__(self, core: LegendaryCore):
|
||||
self.core = core
|
||||
self.logger = logging.getLogger('cli')
|
||||
self.logger = logging.getLogger('Api')
|
||||
self.logging_queue = None
|
||||
self.ql = self.setup_threaded_logging()
|
||||
|
||||
|
|
|
@ -38,17 +38,13 @@ logger = getLogger("ImageManager")
|
|||
|
||||
class ImageSize:
|
||||
class Preset:
|
||||
__img_factor = 67
|
||||
__size: QSize
|
||||
__divisor: float = 1.0
|
||||
__pixel_ratio: float = 1.0
|
||||
# lk: for prettier images set this to true
|
||||
__smooth_transform: bool = False
|
||||
|
||||
def __init__(self, divisor: float, pixel_ratio: float):
|
||||
self.__pixel_ratio = pixel_ratio
|
||||
self.__img_factor = 67
|
||||
self.__divisor = divisor
|
||||
self.__pixel_ratio = pixel_ratio
|
||||
self.__size = QSize(self.__img_factor * 3, self.__img_factor * 4) * pixel_ratio / divisor
|
||||
# lk: for prettier images set this to true
|
||||
self.__smooth_transform: bool = False
|
||||
if divisor > 2:
|
||||
self.__smooth_transform = False
|
||||
|
||||
|
@ -107,17 +103,16 @@ class ImageManager(QObject):
|
|||
logger.debug(f" Emitting singal for game {self.game.app_name} - {self.game.app_title}")
|
||||
self.signals.completed.emit(self.game.app_name)
|
||||
|
||||
# lk: the ordering in __img_types matters for the order of fallbacks
|
||||
__img_types: List = ["DieselGameBoxTall", "Thumbnail", "DieselGameBoxLogo"]
|
||||
__dl_retries = 1
|
||||
__worker_app_names: List[str] = list()
|
||||
|
||||
def __init__(self, signals: GlobalSignals, core: LegendaryCore):
|
||||
# lk: the ordering in __img_types matters for the order of fallbacks
|
||||
self.__img_types: Tuple = ("DieselGameBoxTall", "Thumbnail", "DieselGameBoxLogo")
|
||||
self.__dl_retries = 1
|
||||
self.__worker_app_names: List[str] = []
|
||||
super(QObject, self).__init__()
|
||||
self.signals = signals
|
||||
self.core = core
|
||||
|
||||
self.image_dir = Path(image_dir)
|
||||
self.image_dir: Path = image_dir()
|
||||
if not self.image_dir.is_dir():
|
||||
self.image_dir.mkdir()
|
||||
logger.info(f"Created image directory at {self.image_dir}")
|
||||
|
|
|
@ -418,7 +418,7 @@ class ImageLabel(QLabel):
|
|||
|
||||
def __init__(self):
|
||||
super(ImageLabel, self).__init__()
|
||||
self.path = tmp_dir
|
||||
self.path = tmp_dir()
|
||||
self.manager = QtRequestManager("bytes")
|
||||
|
||||
def update_image(self, url, name="", size: tuple = (240, 320)):
|
||||
|
|
|
@ -34,7 +34,7 @@ class RareGameMeta:
|
|||
|
||||
def __init__(self):
|
||||
meta_data = {}
|
||||
if os.path.exists(p := os.path.join(data_dir, "game_meta.json")):
|
||||
if os.path.exists(p := os.path.join(data_dir(), "game_meta.json")):
|
||||
try:
|
||||
meta_data = json.load(open(p))
|
||||
except json.JSONDecodeError:
|
||||
|
@ -59,6 +59,6 @@ class RareGameMeta:
|
|||
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"),
|
||||
open(os.path.join(data_dir(), "game_meta.json"), "w"),
|
||||
indent=4
|
||||
)
|
||||
|
|
|
@ -165,7 +165,7 @@ def get_size(b: Union[int, float]) -> str:
|
|||
|
||||
|
||||
def get_rare_executable() -> List[str]:
|
||||
# lk: detech if nuitka
|
||||
# lk: detect if nuitka
|
||||
if "__compiled__" in globals():
|
||||
executable = [sys.executable]
|
||||
elif platform.system() == "Linux" or platform.system() == "Darwin":
|
||||
|
@ -180,10 +180,12 @@ def get_rare_executable() -> List[str]:
|
|||
elif platform.system() == "Windows":
|
||||
executable = [sys.executable]
|
||||
|
||||
if not sys.executable.endswith("Rare.exe"):
|
||||
if sys.executable != os.path.abspath(sys.argv[0]):
|
||||
executable.append(os.path.abspath(sys.argv[0]))
|
||||
|
||||
if executable[0].endswith("python.exe"):
|
||||
# be sure to start consoleless then
|
||||
executable[0] = executable[0].replace("python.exe", "pythonw.exe")
|
||||
executable.extend(["-m", "rare"])
|
||||
else:
|
||||
executable = [sys.executable]
|
||||
|
||||
|
@ -195,7 +197,7 @@ def create_desktop_link(app_name=None, core: LegendaryCore = None, type_of_link=
|
|||
if not for_rare:
|
||||
igame = core.get_installed_game(app_name)
|
||||
|
||||
icon = os.path.join(os.path.join(image_dir, igame.app_name, "installed.png"))
|
||||
icon = os.path.join(os.path.join(image_dir(), igame.app_name, "installed.png"))
|
||||
icon = icon.replace(".png", "")
|
||||
|
||||
if platform.system() == "Linux":
|
||||
|
@ -208,6 +210,7 @@ def create_desktop_link(app_name=None, core: LegendaryCore = None, type_of_link=
|
|||
if not os.path.exists(path):
|
||||
return False
|
||||
executable = get_rare_executable()
|
||||
executable = shlex.join(executable)
|
||||
|
||||
if for_rare:
|
||||
with open(os.path.join(path, "Rare.desktop"), "w") as desktop_file:
|
||||
|
@ -274,20 +277,14 @@ def create_desktop_link(app_name=None, core: LegendaryCore = None, type_of_link=
|
|||
|
||||
if len(executable) > 1:
|
||||
arguments.extend(executable[1:])
|
||||
executable = executable[0]
|
||||
|
||||
if not sys.executable.endswith("Rare.exe"):
|
||||
# be sure to start consoleless then
|
||||
executable = sys.executable.replace("python.exe", "pythonw.exe")
|
||||
arguments.append(os.path.abspath(sys.argv[0]))
|
||||
executable = executable[0]
|
||||
|
||||
if not for_rare:
|
||||
arguments.extend(["launch", app_name])
|
||||
|
||||
shortcut.Targetpath = executable
|
||||
shortcut.Arguments = shlex.join(arguments)
|
||||
# Maybe there is a better solution, but windows does not accept single quotes (Windows is weird)
|
||||
shortcut.Arguments = shortcut.Arguments.replace("'", '"')
|
||||
shortcut.Arguments = shlex.join(arguments).replace("'", '"')
|
||||
if for_rare:
|
||||
shortcut.WorkingDirectory = QStandardPaths.writableLocation(QStandardPaths.HomeLocation)
|
||||
|
||||
|
|
|
@ -1,13 +1,51 @@
|
|||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5.QtCore import QStandardPaths
|
||||
|
||||
resources_path = Path(__file__).absolute().parent.parent.joinpath("resources")
|
||||
data_dir = Path(QStandardPaths.writableLocation(QStandardPaths.DataLocation), "rare")
|
||||
cache_dir = Path(QStandardPaths.writableLocation(QStandardPaths.CacheLocation), "rare")
|
||||
image_dir = data_dir.joinpath("images")
|
||||
tmp_dir = cache_dir.joinpath("tmp")
|
||||
|
||||
for path in (data_dir, cache_dir, image_dir, tmp_dir):
|
||||
if not path.exists():
|
||||
path.mkdir(parents=True)
|
||||
# lk: delete old Rare directories
|
||||
for old_dir in [
|
||||
Path(QStandardPaths.writableLocation(QStandardPaths.CacheLocation), "rare").joinpath("tmp"),
|
||||
Path(QStandardPaths.writableLocation(QStandardPaths.DataLocation), "rare").joinpath("images"),
|
||||
Path(QStandardPaths.writableLocation(QStandardPaths.CacheLocation), "rare"),
|
||||
Path(QStandardPaths.writableLocation(QStandardPaths.DataLocation), "rare"),
|
||||
]:
|
||||
if old_dir.exists():
|
||||
# lk: case-sensitive matching on Winblows
|
||||
if old_dir.stem in os.listdir(old_dir.parent):
|
||||
shutil.rmtree(old_dir, ignore_errors=True)
|
||||
|
||||
|
||||
# lk: TempLocation doesn't depend on OrganizationName or ApplicationName
|
||||
# lk: so it is fine to use it before initializing the QApplication
|
||||
def lock_file() -> Path:
|
||||
return Path(QStandardPaths.writableLocation(QStandardPaths.TempLocation), "Rare.lock")
|
||||
|
||||
|
||||
def data_dir() -> Path:
|
||||
return Path(QStandardPaths.writableLocation(QStandardPaths.DataLocation))
|
||||
|
||||
|
||||
def cache_dir() -> Path:
|
||||
return Path(QStandardPaths.writableLocation(QStandardPaths.CacheLocation))
|
||||
|
||||
|
||||
def image_dir() -> Path:
|
||||
return data_dir().joinpath("images")
|
||||
|
||||
|
||||
def log_dir() -> Path:
|
||||
return cache_dir().joinpath("logs")
|
||||
|
||||
|
||||
def tmp_dir() -> Path:
|
||||
return cache_dir().joinpath("tmp")
|
||||
|
||||
|
||||
def create_dirs() -> None:
|
||||
for path in (data_dir(), cache_dir(), image_dir(), log_dir(), tmp_dir()):
|
||||
if not path.exists():
|
||||
path.mkdir(parents=True)
|
||||
|
|
|
@ -6,13 +6,11 @@ from datetime import date
|
|||
import requests
|
||||
from PyQt5.QtCore import pyqtSignal, QRunnable, QObject, QCoreApplication
|
||||
|
||||
from legendary.core import LegendaryCore
|
||||
from rare.lgndr.core import LegendaryCore
|
||||
from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton
|
||||
from rare.utils.paths import data_dir, cache_dir
|
||||
|
||||
replace_chars = ",;.:-_ "
|
||||
|
||||
file = os.path.join(cache_dir, "game_list.json")
|
||||
url = "https://api.steampowered.com/ISteamApps/GetAppList/v2/"
|
||||
|
||||
|
||||
|
@ -20,7 +18,7 @@ class SteamWorker(QRunnable):
|
|||
class Signals(QObject):
|
||||
rating_signal = pyqtSignal(str)
|
||||
|
||||
app_name:str = ""
|
||||
app_name: str = ""
|
||||
|
||||
def __init__(self, core: LegendaryCore):
|
||||
super(SteamWorker, self).__init__()
|
||||
|
@ -55,7 +53,7 @@ def get_rating(app_name: str):
|
|||
args = ArgumentsSingleton()
|
||||
global __grades_json
|
||||
if __grades_json is None:
|
||||
if os.path.exists(p := os.path.join(data_dir, "steam_ids.json")):
|
||||
if os.path.exists(p := os.path.join(data_dir(), "steam_ids.json")):
|
||||
grades = json.loads(open(p).read())
|
||||
__grades_json = grades
|
||||
else:
|
||||
|
@ -72,7 +70,7 @@ def get_rating(app_name: str):
|
|||
steam_id = get_steam_id(game.app_title)
|
||||
grade = get_grade(steam_id)
|
||||
grades[app_name] = {"steam_id": steam_id, "grade": grade}
|
||||
with open(os.path.join(data_dir, "steam_ids.json"), "w") as f:
|
||||
with open(os.path.join(data_dir(), "steam_ids.json"), "w") as f:
|
||||
f.write(json.dumps(grades))
|
||||
f.close()
|
||||
return grade
|
||||
|
@ -96,8 +94,8 @@ def get_grade(steam_code):
|
|||
|
||||
|
||||
def load_json() -> dict:
|
||||
file = os.path.join(cache_dir(), "game_list.json")
|
||||
if not os.path.exists(file):
|
||||
|
||||
response = requests.get(url)
|
||||
steam_ids = json.loads(response.text)["applist"]["apps"]
|
||||
ids = {}
|
||||
|
@ -113,6 +111,7 @@ def load_json() -> dict:
|
|||
|
||||
|
||||
def get_steam_id(title: str):
|
||||
file = os.path.join(cache_dir(), "game_list.json")
|
||||
# workarounds for satisfactory
|
||||
title = title.replace("Early Access", "").replace("Experimental", "").strip()
|
||||
global __steam_ids_json
|
||||
|
@ -146,7 +145,7 @@ def get_steam_id(title: str):
|
|||
|
||||
|
||||
def check_time(): # this function check if it's time to update
|
||||
global file
|
||||
file = os.path.join(cache_dir(), "game_list.json")
|
||||
json_table = json.loads(open(file, "r").read())
|
||||
|
||||
today = date.today()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import sys
|
||||
from argparse import Namespace
|
||||
from logging import getLogger
|
||||
|
||||
from PyQt5.QtCore import Qt, QSettings, QTranslator
|
||||
|
@ -10,14 +11,14 @@ from PyQt5.QtWidgets import QApplication
|
|||
from legendary.core import LegendaryCore
|
||||
|
||||
import rare.resources.resources
|
||||
from rare.utils.paths import resources_path
|
||||
from rare.utils import paths
|
||||
from rare.utils.misc import set_color_pallete, set_style_sheet
|
||||
|
||||
|
||||
class RareApp(QApplication):
|
||||
logger = getLogger("RareApp")
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, args: Namespace):
|
||||
super(RareApp, self).__init__(sys.argv)
|
||||
self.setQuitOnLastWindowClosed(False)
|
||||
if hasattr(Qt, "AA_UseHighDpiPixmaps"):
|
||||
|
@ -25,6 +26,7 @@ class RareApp(QApplication):
|
|||
|
||||
self.setApplicationName("Rare")
|
||||
self.setOrganizationName("Rare")
|
||||
paths.create_dirs()
|
||||
self.settings = QSettings()
|
||||
|
||||
# Translator
|
||||
|
@ -51,7 +53,7 @@ class RareApp(QApplication):
|
|||
self.setWindowIcon(QIcon(":/images/Rare.png"))
|
||||
|
||||
def load_translator(self, lang: str):
|
||||
if os.path.isfile(f := os.path.join(resources_path, "languages", f"{lang}.qm")):
|
||||
if os.path.isfile(f := os.path.join(paths.resources_path, "languages", f"{lang}.qm")):
|
||||
self.translator.load(f)
|
||||
self.logger.info(f"Your language is supported: {lang}")
|
||||
elif not lang == "en":
|
||||
|
@ -59,7 +61,7 @@ class RareApp(QApplication):
|
|||
self.installTranslator(self.translator)
|
||||
|
||||
# translator for qt stuff
|
||||
if os.path.isfile(f := os.path.join(resources_path, f"qt_{lang}.qm")):
|
||||
if os.path.isfile(f := os.path.join(paths.resources_path, f"qt_{lang}.qm")):
|
||||
self.qt_translator = QTranslator()
|
||||
self.qt_translator.load(f)
|
||||
self.installTranslator(self.qt_translator)
|
||||
|
|
Loading…
Reference in a new issue