1
0
Fork 0
mirror of synced 2024-06-26 10:11:19 +12:00

Optimize search requests and option to cache images

This commit is contained in:
Dummerle 2021-06-13 14:33:17 +02:00
parent 254a8a48e7
commit 0d0b858a8f
5 changed files with 117 additions and 77 deletions

View file

@ -34,7 +34,8 @@ class RareSettings(QWidget, Ui_RareSettings):
(self.confirm_start, "confirm_start", False), (self.confirm_start, "confirm_start", False),
(self.auto_sync_cloud, "auto_sync_cloud", True), (self.auto_sync_cloud, "auto_sync_cloud", True),
(self.notification, "notification", True), (self.notification, "notification", True),
(self.save_size, "save_size", False) (self.save_size, "save_size", False),
(self.image_cache, "cache_images", True)
] ]
self.settings = QSettings() self.settings = QSettings()
@ -99,6 +100,9 @@ class RareSettings(QWidget, Ui_RareSettings):
self.save_size.stateChanged.connect( self.save_size.stateChanged.connect(
lambda: self.settings.setValue("save_size", self.save_size.isChecked()) lambda: self.settings.setValue("save_size", self.save_size.isChecked())
) )
self.image_cache.stateChanged.connect(
lambda: self.settings.setValue("cache_images", self.image_cache.isChecked())
)
if os.name == "posix": if os.name == "posix":
self.desktop_file = os.path.expanduser("~/Desktop/Rare.desktop") self.desktop_file = os.path.expanduser("~/Desktop/Rare.desktop")

View file

@ -44,8 +44,6 @@ class ShopGame:
@classmethod @classmethod
def from_json(cls, api_data: dict, search_data: dict): def from_json(cls, api_data: dict, search_data: dict):
print(api_data)
print(search_data)
if isinstance(api_data, list): if isinstance(api_data, list):
for product in api_data: for product in api_data:
if product["_title"] == "home": if product["_title"] == "home":

View file

@ -4,10 +4,9 @@ import logging
import os import os
from json import JSONDecodeError from json import JSONDecodeError
import requests
from PyQt5 import QtGui from PyQt5 import QtGui
from PyQt5.QtCore import Qt, pyqtSignal, QUrl, QJsonDocument, QJsonParseError, \ from PyQt5.QtCore import Qt, pyqtSignal, QUrl, QJsonDocument, QJsonParseError, \
QStringListModel QStringListModel, QSettings
from PyQt5.QtGui import QPixmap from PyQt5.QtGui import QPixmap
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QCompleter, QGroupBox, QHBoxLayout, QScrollArea from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QCompleter, QGroupBox, QHBoxLayout, QScrollArea
@ -16,12 +15,16 @@ from rare.ui.components.tabs.store.store import Ui_ShopWidget
from rare.utils.extra_widgets import WaitingSpinner, ImageLabel, FlowLayout from rare.utils.extra_widgets import WaitingSpinner, ImageLabel, FlowLayout
from rare.utils.utils import get_lang from rare.utils.utils import get_lang
logger = logging.getLogger("Shop")
# noinspection PyAttributeOutsideInit,PyBroadException # noinspection PyAttributeOutsideInit,PyBroadException
class ShopWidget(QScrollArea, Ui_ShopWidget): class ShopWidget(QScrollArea, Ui_ShopWidget):
show_info = pyqtSignal(list) show_info = pyqtSignal(list)
show_game = pyqtSignal(dict) show_game = pyqtSignal(dict)
free_game_widgets = [] free_game_widgets = []
active_search_request = False
next_search = ""
def __init__(self): def __init__(self):
super(ShopWidget, self).__init__() super(ShopWidget, self).__init__()
@ -137,19 +140,24 @@ class ShopWidget(QScrollArea, Ui_ShopWidget):
self.free_game_request.deleteLater() self.free_game_request.deleteLater()
def search_games(self, text, show_direct=False): def search_games(self, text, show_direct=False):
if text != "": if not self.active_search_request:
locale = get_lang() if text != "":
payload = json.dumps({ locale = get_lang()
"query": query, payload = json.dumps({
"variables": {"category": "games/edition/base|bundles/games|editors|software/edition/base", "count": 20, "query": query,
"country": "DE", "keywords": text, "locale": locale, "sortDir": "DESC", "variables": {"category": "games/edition/base|bundles/games|editors|software/edition/base",
"allowCountries": locale.upper(), "count": 20,
"start": 0, "tag": "", "withMapping": False, "withPrice": True} "country": locale.upper(), "keywords": text, "locale": locale, "sortDir": "DESC",
}).encode() "allowCountries": locale.upper(),
request = QNetworkRequest(QUrl("https://www.epicgames.com/graphql")) "start": 0, "tag": "", "withMapping": False, "withPrice": True}
request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") }).encode()
self.search_request = self.manager.post(request, payload) request = QNetworkRequest(QUrl("https://www.epicgames.com/graphql"))
self.search_request.finished.connect(lambda: self.show_search_results(show_direct)) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json")
self.search_request = self.manager.post(request, payload)
self.search_request.finished.connect(lambda: self.show_search_results(show_direct))
else:
self.next_search = text
def show_search_results(self, show_direct=False): def show_search_results(self, show_direct=False):
if self.search_request: if self.search_request:
@ -158,27 +166,24 @@ class ShopWidget(QScrollArea, Ui_ShopWidget):
json_data = QJsonDocument.fromJson(self.search_request.readAll().data(), error) json_data = QJsonDocument.fromJson(self.search_request.readAll().data(), error)
if QJsonParseError.NoError == error.error: if QJsonParseError.NoError == error.error:
data = json.loads(json_data.toJson().data().decode())["data"]["Catalog"]["searchStore"]["elements"] data = json.loads(json_data.toJson().data().decode())["data"]["Catalog"]["searchStore"]["elements"]
self.data = data
if show_direct:
self.show_search_result(True)
return
titles = [i.get("title") for i in data]
model = QStringListModel()
model.setStringList(titles)
self.completer.setModel(model)
# self.completer.popup()
if self.search_request:
self.search_request.deleteLater()
else: else:
logging.error(error.errorString()) logging.error(error.errorString())
return
# response = .decode(encoding="utf-8") # response = .decode(encoding="utf-8")
# print(response) # print(response)
# results = json.loads(response) # results = json.loads(response)
else:
return self.search_games(self.next_search)
else:
return
self.data = data
if show_direct:
self.show_search_result(True)
return
titles = [i.get("title") for i in data]
model = QStringListModel()
model.setStringList(titles)
self.completer.setModel(model)
# self.completer.popup()
if self.search_request:
self.search_request.deleteLater()
def show_search_result(self, show_direct=False): def show_search_result(self, show_direct=False):
if not show_direct: if not show_direct:
@ -198,6 +203,7 @@ class GameWidget(QWidget):
def __init__(self, path, json_info=None): def __init__(self, path, json_info=None):
super(GameWidget, self).__init__() super(GameWidget, self).__init__()
self.manager = QNetworkAccessManager()
if json_info: if json_info:
self.init_ui(json_info, path) self.init_ui(json_info, path)
self.path = path self.path = path
@ -207,35 +213,34 @@ class GameWidget(QWidget):
self.layout = QVBoxLayout() self.layout = QVBoxLayout()
self.image = ImageLabel() self.image = ImageLabel()
self.json_info = json_info self.json_info = json_info
self.slug = json_info["productSlug"]
self.width = 300
self.title = json_info["title"]
for img in json_info["keyImages"]: for img in json_info["keyImages"]:
if img["type"] in ["DieselStoreFrontWide", "VaultClosed"]: if img["type"] in ["DieselStoreFrontWide", "VaultClosed"]:
width = 300 if img["type"] == "VaultClosed" and self.title != "Mystery Game":
self.image.update_image(img["url"], json_info["title"], (width, int(width * 9 / 16))) continue
self.image.update_image(img["url"], json_info["title"], (self.width, int(self.width * 9 / 16)))
break break
else: else:
print("No image found") print("No image found")
self.slug = json_info["productSlug"] save = QSettings().value("cache_images", True, bool)
self.title = json_info["title"] if os.path.exists(p := os.path.join(self.path, f"{json_info['title']}_wide.png")) and save:
if not os.path.exists(p := os.path.join(self.path, f"{json_info['title']}.png")): self.image.setPixmap(QPixmap(p)
.scaled(self.width, int(self.width * 9 / 16), transformMode=Qt.SmoothTransformation))
else:
for img in json_info["keyImages"]: for img in json_info["keyImages"]:
if json_info["title"] != "Mystery Game": if img["type"] in ["DieselStoreFrontWide", "VaultClosed"]:
if img["type"] == "DieselStoreFrontWide": if img["type"] == "VaultClosed" and self.title != "Mystery Game":
with open(p, "wb") as img_file: continue
content = requests.get(img["url"]).content self.image_request = self.manager.get(QNetworkRequest(QUrl(img["url"])))
img_file.write(content) self.image_request.finished.connect(lambda: self.image_ready(save))
break break
else:
if img["type"] == "VaultClosed":
with open(p, "wb") as img_file:
content = requests.get(img["url"]).content
img_file.write(content)
break
else: else:
print("No image found") # No image found
width = 300 logger.error(f"No image found for {self.title}")
self.image.setPixmap(QPixmap(os.path.join(self.path, f"{json_info['title']}.png"))
.scaled(width, int(width * 9 / 16), transformMode=Qt.SmoothTransformation))
self.layout.addWidget(self.image) self.layout.addWidget(self.image)
self.title_label = QLabel(json_info["title"]) self.title_label = QLabel(json_info["title"])
@ -243,6 +248,19 @@ class GameWidget(QWidget):
self.layout.addWidget(self.title_label) self.layout.addWidget(self.title_label)
self.setLayout(self.layout) self.setLayout(self.layout)
def image_ready(self, save: bool):
if self.image_request:
if self.image_request.error() == QNetworkReply.NoError:
data = self.image_request.readAll().data()
if save:
with open(os.path.join(self.path, f"{self.title}_wide.png"), "wb") as file:
file.write(data)
file.close()
pixmap = QPixmap()
pixmap.loadFromData(data)
self.image.setPixmap(pixmap.scaled(self.width, int(self.width * 9 / 16),
transformMode=Qt.SmoothTransformation))
def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None: def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
self.show_info.emit(self.json_info) self.show_info.emit(self.json_info)

View file

@ -14,6 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_RareSettings(object): class Ui_RareSettings(object):
def setupUi(self, RareSettings): def setupUi(self, RareSettings):
RareSettings.setObjectName("RareSettings") RareSettings.setObjectName("RareSettings")
RareSettings.resize(544, 532)
self.rare_layout = QtWidgets.QGridLayout(RareSettings) self.rare_layout = QtWidgets.QGridLayout(RareSettings)
self.rare_layout.setObjectName("rare_layout") self.rare_layout.setObjectName("rare_layout")
self.rpc_layout = QtWidgets.QVBoxLayout() self.rpc_layout = QtWidgets.QVBoxLayout()
@ -34,26 +35,29 @@ class Ui_RareSettings(object):
self.settings_group.setObjectName("settings_group") self.settings_group.setObjectName("settings_group")
self.behavior_layout = QtWidgets.QGridLayout(self.settings_group) self.behavior_layout = QtWidgets.QGridLayout(self.settings_group)
self.behavior_layout.setObjectName("behavior_layout") self.behavior_layout.setObjectName("behavior_layout")
self.notification = QtWidgets.QCheckBox(self.settings_group)
self.notification.setObjectName("notification")
self.behavior_layout.addWidget(self.notification, 4, 0, 1, 1)
self.auto_update = QtWidgets.QCheckBox(self.settings_group)
self.auto_update.setObjectName("auto_update")
self.behavior_layout.addWidget(self.auto_update, 1, 0, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.behavior_layout.addItem(spacerItem, 2, 1, 2, 1) self.behavior_layout.addItem(spacerItem, 2, 1, 2, 1)
self.save_size = QtWidgets.QCheckBox(self.settings_group) self.save_size = QtWidgets.QCheckBox(self.settings_group)
self.save_size.setObjectName("save_size") self.save_size.setObjectName("save_size")
self.behavior_layout.addWidget(self.save_size, 5, 0, 1, 1) self.behavior_layout.addWidget(self.save_size, 5, 0, 1, 1)
self.notification = QtWidgets.QCheckBox(self.settings_group)
self.notification.setObjectName("notification")
self.behavior_layout.addWidget(self.notification, 4, 0, 1, 1)
self.auto_sync_cloud = QtWidgets.QCheckBox(self.settings_group) self.auto_sync_cloud = QtWidgets.QCheckBox(self.settings_group)
self.auto_sync_cloud.setObjectName("auto_sync_cloud") self.auto_sync_cloud.setObjectName("auto_sync_cloud")
self.behavior_layout.addWidget(self.auto_sync_cloud, 3, 0, 1, 1) self.behavior_layout.addWidget(self.auto_sync_cloud, 3, 0, 1, 1)
self.confirm_start = QtWidgets.QCheckBox(self.settings_group) self.confirm_start = QtWidgets.QCheckBox(self.settings_group)
self.confirm_start.setObjectName("confirm_start") self.confirm_start.setObjectName("confirm_start")
self.behavior_layout.addWidget(self.confirm_start, 2, 0, 1, 1) self.behavior_layout.addWidget(self.confirm_start, 2, 0, 1, 1)
self.auto_update = QtWidgets.QCheckBox(self.settings_group)
self.auto_update.setObjectName("auto_update")
self.behavior_layout.addWidget(self.auto_update, 1, 0, 1, 1)
self.sys_tray = QtWidgets.QCheckBox(self.settings_group) self.sys_tray = QtWidgets.QCheckBox(self.settings_group)
self.sys_tray.setObjectName("sys_tray") self.sys_tray.setObjectName("sys_tray")
self.behavior_layout.addWidget(self.sys_tray, 0, 0, 1, 1) self.behavior_layout.addWidget(self.sys_tray, 0, 0, 1, 1)
self.image_cache = QtWidgets.QCheckBox(self.settings_group)
self.image_cache.setObjectName("image_cache")
self.behavior_layout.addWidget(self.image_cache, 6, 0, 1, 1)
self.rare_layout.addWidget(self.settings_group, 2, 0, 1, 1, QtCore.Qt.AlignTop) self.rare_layout.addWidget(self.settings_group, 2, 0, 1, 1, QtCore.Qt.AlignTop)
self.log_dir_group = QtWidgets.QGroupBox(RareSettings) self.log_dir_group = QtWidgets.QGroupBox(RareSettings)
self.log_dir_group.setObjectName("log_dir_group") self.log_dir_group.setObjectName("log_dir_group")
@ -128,12 +132,13 @@ class Ui_RareSettings(object):
self.desktop_link.setText(_translate("RareSettings", "Create Desktop link")) self.desktop_link.setText(_translate("RareSettings", "Create Desktop link"))
self.startmenu_link.setText(_translate("RareSettings", "Create start menu link")) self.startmenu_link.setText(_translate("RareSettings", "Create start menu link"))
self.settings_group.setTitle(_translate("RareSettings", "Behavior")) self.settings_group.setTitle(_translate("RareSettings", "Behavior"))
self.save_size.setText(_translate("RareSettings", "Restore window size on application startup"))
self.notification.setText(_translate("RareSettings", "Show notification on download completion")) self.notification.setText(_translate("RareSettings", "Show notification on download completion"))
self.auto_update.setText(_translate("RareSettings", "Update games on application startup"))
self.save_size.setText(_translate("RareSettings", "Restore window size on application startup"))
self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically sync with cloud")) self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically sync with cloud"))
self.confirm_start.setText(_translate("RareSettings", "Confirm game launch")) self.confirm_start.setText(_translate("RareSettings", "Confirm game launch"))
self.auto_update.setText(_translate("RareSettings", "Update games on application startup"))
self.sys_tray.setText(_translate("RareSettings", "Exit to System tray")) self.sys_tray.setText(_translate("RareSettings", "Exit to System tray"))
self.image_cache.setText(_translate("RareSettings", "Cache images in store"))
self.log_dir_group.setTitle(_translate("RareSettings", "Logs")) self.log_dir_group.setTitle(_translate("RareSettings", "Logs"))
self.log_dir_open_button.setText(_translate("RareSettings", "Open Log directory")) self.log_dir_open_button.setText(_translate("RareSettings", "Open Log directory"))
self.log_dir_clean_button.setText(_translate("RareSettings", "Clean Log directory")) self.log_dir_clean_button.setText(_translate("RareSettings", "Clean Log directory"))

View file

@ -2,6 +2,14 @@
<ui version="4.0"> <ui version="4.0">
<class>RareSettings</class> <class>RareSettings</class>
<widget class="QWidget" name="RareSettings"> <widget class="QWidget" name="RareSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>544</width>
<height>532</height>
</rect>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>RareSettings</string> <string>RareSettings</string>
</property> </property>
@ -38,6 +46,20 @@
<string>Behavior</string> <string>Behavior</string>
</property> </property>
<layout class="QGridLayout" name="behavior_layout"> <layout class="QGridLayout" name="behavior_layout">
<item row="4" column="0">
<widget class="QCheckBox" name="notification">
<property name="text">
<string>Show notification on download completion</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="auto_update">
<property name="text">
<string>Update games on application startup</string>
</property>
</widget>
</item>
<item row="2" column="1" rowspan="2"> <item row="2" column="1" rowspan="2">
<spacer name="settings_hspacer"> <spacer name="settings_hspacer">
<property name="orientation"> <property name="orientation">
@ -58,13 +80,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0">
<widget class="QCheckBox" name="notification">
<property name="text">
<string>Show notification on download completion</string>
</property>
</widget>
</item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QCheckBox" name="auto_sync_cloud"> <widget class="QCheckBox" name="auto_sync_cloud">
<property name="text"> <property name="text">
@ -79,13 +94,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QCheckBox" name="auto_update">
<property name="text">
<string>Update games on application startup</string>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QCheckBox" name="sys_tray"> <widget class="QCheckBox" name="sys_tray">
<property name="text"> <property name="text">
@ -93,6 +101,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0">
<widget class="QCheckBox" name="image_cache">
<property name="text">
<string>Cache images in store</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>