Optimize search requests and option to cache images
This commit is contained in:
parent
254a8a48e7
commit
0d0b858a8f
|
@ -34,7 +34,8 @@ class RareSettings(QWidget, Ui_RareSettings):
|
|||
(self.confirm_start, "confirm_start", False),
|
||||
(self.auto_sync_cloud, "auto_sync_cloud", 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()
|
||||
|
@ -99,6 +100,9 @@ class RareSettings(QWidget, Ui_RareSettings):
|
|||
self.save_size.stateChanged.connect(
|
||||
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":
|
||||
self.desktop_file = os.path.expanduser("~/Desktop/Rare.desktop")
|
||||
|
|
|
@ -44,8 +44,6 @@ class ShopGame:
|
|||
|
||||
@classmethod
|
||||
def from_json(cls, api_data: dict, search_data: dict):
|
||||
print(api_data)
|
||||
print(search_data)
|
||||
if isinstance(api_data, list):
|
||||
for product in api_data:
|
||||
if product["_title"] == "home":
|
||||
|
|
|
@ -4,10 +4,9 @@ import logging
|
|||
import os
|
||||
from json import JSONDecodeError
|
||||
|
||||
import requests
|
||||
from PyQt5 import QtGui
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, QUrl, QJsonDocument, QJsonParseError, \
|
||||
QStringListModel
|
||||
QStringListModel, QSettings
|
||||
from PyQt5.QtGui import QPixmap
|
||||
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
||||
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.utils import get_lang
|
||||
|
||||
logger = logging.getLogger("Shop")
|
||||
|
||||
|
||||
# noinspection PyAttributeOutsideInit,PyBroadException
|
||||
class ShopWidget(QScrollArea, Ui_ShopWidget):
|
||||
show_info = pyqtSignal(list)
|
||||
show_game = pyqtSignal(dict)
|
||||
free_game_widgets = []
|
||||
active_search_request = False
|
||||
next_search = ""
|
||||
|
||||
def __init__(self):
|
||||
super(ShopWidget, self).__init__()
|
||||
|
@ -137,19 +140,24 @@ class ShopWidget(QScrollArea, Ui_ShopWidget):
|
|||
self.free_game_request.deleteLater()
|
||||
|
||||
def search_games(self, text, show_direct=False):
|
||||
if text != "":
|
||||
locale = get_lang()
|
||||
payload = json.dumps({
|
||||
"query": query,
|
||||
"variables": {"category": "games/edition/base|bundles/games|editors|software/edition/base", "count": 20,
|
||||
"country": "DE", "keywords": text, "locale": locale, "sortDir": "DESC",
|
||||
"allowCountries": locale.upper(),
|
||||
"start": 0, "tag": "", "withMapping": False, "withPrice": True}
|
||||
}).encode()
|
||||
request = QNetworkRequest(QUrl("https://www.epicgames.com/graphql"))
|
||||
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))
|
||||
if not self.active_search_request:
|
||||
if text != "":
|
||||
locale = get_lang()
|
||||
payload = json.dumps({
|
||||
"query": query,
|
||||
"variables": {"category": "games/edition/base|bundles/games|editors|software/edition/base",
|
||||
"count": 20,
|
||||
"country": locale.upper(), "keywords": text, "locale": locale, "sortDir": "DESC",
|
||||
"allowCountries": locale.upper(),
|
||||
"start": 0, "tag": "", "withMapping": False, "withPrice": True}
|
||||
}).encode()
|
||||
request = QNetworkRequest(QUrl("https://www.epicgames.com/graphql"))
|
||||
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):
|
||||
if self.search_request:
|
||||
|
@ -158,27 +166,24 @@ class ShopWidget(QScrollArea, Ui_ShopWidget):
|
|||
json_data = QJsonDocument.fromJson(self.search_request.readAll().data(), error)
|
||||
if QJsonParseError.NoError == error.error:
|
||||
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:
|
||||
logging.error(error.errorString())
|
||||
return
|
||||
# response = .decode(encoding="utf-8")
|
||||
# print(response)
|
||||
# results = json.loads(response)
|
||||
else:
|
||||
return
|
||||
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()
|
||||
|
||||
self.search_games(self.next_search)
|
||||
|
||||
def show_search_result(self, show_direct=False):
|
||||
if not show_direct:
|
||||
|
@ -198,6 +203,7 @@ class GameWidget(QWidget):
|
|||
|
||||
def __init__(self, path, json_info=None):
|
||||
super(GameWidget, self).__init__()
|
||||
self.manager = QNetworkAccessManager()
|
||||
if json_info:
|
||||
self.init_ui(json_info, path)
|
||||
self.path = path
|
||||
|
@ -207,35 +213,34 @@ class GameWidget(QWidget):
|
|||
self.layout = QVBoxLayout()
|
||||
self.image = ImageLabel()
|
||||
self.json_info = json_info
|
||||
self.slug = json_info["productSlug"]
|
||||
self.width = 300
|
||||
self.title = json_info["title"]
|
||||
for img in json_info["keyImages"]:
|
||||
if img["type"] in ["DieselStoreFrontWide", "VaultClosed"]:
|
||||
width = 300
|
||||
self.image.update_image(img["url"], json_info["title"], (width, int(width * 9 / 16)))
|
||||
if img["type"] == "VaultClosed" and self.title != "Mystery Game":
|
||||
continue
|
||||
self.image.update_image(img["url"], json_info["title"], (self.width, int(self.width * 9 / 16)))
|
||||
break
|
||||
else:
|
||||
print("No image found")
|
||||
|
||||
self.slug = json_info["productSlug"]
|
||||
self.title = json_info["title"]
|
||||
if not os.path.exists(p := os.path.join(self.path, f"{json_info['title']}.png")):
|
||||
save = QSettings().value("cache_images", True, bool)
|
||||
if os.path.exists(p := os.path.join(self.path, f"{json_info['title']}_wide.png")) and save:
|
||||
self.image.setPixmap(QPixmap(p)
|
||||
.scaled(self.width, int(self.width * 9 / 16), transformMode=Qt.SmoothTransformation))
|
||||
else:
|
||||
for img in json_info["keyImages"]:
|
||||
if json_info["title"] != "Mystery Game":
|
||||
if img["type"] == "DieselStoreFrontWide":
|
||||
with open(p, "wb") as img_file:
|
||||
content = requests.get(img["url"]).content
|
||||
img_file.write(content)
|
||||
break
|
||||
else:
|
||||
if img["type"] == "VaultClosed":
|
||||
with open(p, "wb") as img_file:
|
||||
content = requests.get(img["url"]).content
|
||||
img_file.write(content)
|
||||
break
|
||||
if img["type"] in ["DieselStoreFrontWide", "VaultClosed"]:
|
||||
if img["type"] == "VaultClosed" and self.title != "Mystery Game":
|
||||
continue
|
||||
self.image_request = self.manager.get(QNetworkRequest(QUrl(img["url"])))
|
||||
self.image_request.finished.connect(lambda: self.image_ready(save))
|
||||
break
|
||||
else:
|
||||
print("No image found")
|
||||
width = 300
|
||||
self.image.setPixmap(QPixmap(os.path.join(self.path, f"{json_info['title']}.png"))
|
||||
.scaled(width, int(width * 9 / 16), transformMode=Qt.SmoothTransformation))
|
||||
# No image found
|
||||
logger.error(f"No image found for {self.title}")
|
||||
|
||||
self.layout.addWidget(self.image)
|
||||
|
||||
self.title_label = QLabel(json_info["title"])
|
||||
|
@ -243,6 +248,19 @@ class GameWidget(QWidget):
|
|||
self.layout.addWidget(self.title_label)
|
||||
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:
|
||||
self.show_info.emit(self.json_info)
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|||
class Ui_RareSettings(object):
|
||||
def setupUi(self, RareSettings):
|
||||
RareSettings.setObjectName("RareSettings")
|
||||
RareSettings.resize(544, 532)
|
||||
self.rare_layout = QtWidgets.QGridLayout(RareSettings)
|
||||
self.rare_layout.setObjectName("rare_layout")
|
||||
self.rpc_layout = QtWidgets.QVBoxLayout()
|
||||
|
@ -34,26 +35,29 @@ class Ui_RareSettings(object):
|
|||
self.settings_group.setObjectName("settings_group")
|
||||
self.behavior_layout = QtWidgets.QGridLayout(self.settings_group)
|
||||
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)
|
||||
self.behavior_layout.addItem(spacerItem, 2, 1, 2, 1)
|
||||
self.save_size = QtWidgets.QCheckBox(self.settings_group)
|
||||
self.save_size.setObjectName("save_size")
|
||||
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.setObjectName("auto_sync_cloud")
|
||||
self.behavior_layout.addWidget(self.auto_sync_cloud, 3, 0, 1, 1)
|
||||
self.confirm_start = QtWidgets.QCheckBox(self.settings_group)
|
||||
self.confirm_start.setObjectName("confirm_start")
|
||||
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.setObjectName("sys_tray")
|
||||
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.log_dir_group = QtWidgets.QGroupBox(RareSettings)
|
||||
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.startmenu_link.setText(_translate("RareSettings", "Create start menu link"))
|
||||
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.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.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.image_cache.setText(_translate("RareSettings", "Cache images in store"))
|
||||
self.log_dir_group.setTitle(_translate("RareSettings", "Logs"))
|
||||
self.log_dir_open_button.setText(_translate("RareSettings", "Open Log directory"))
|
||||
self.log_dir_clean_button.setText(_translate("RareSettings", "Clean Log directory"))
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
<ui version="4.0">
|
||||
<class>RareSettings</class>
|
||||
<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">
|
||||
<string>RareSettings</string>
|
||||
</property>
|
||||
|
@ -38,6 +46,20 @@
|
|||
<string>Behavior</string>
|
||||
</property>
|
||||
<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">
|
||||
<spacer name="settings_hspacer">
|
||||
<property name="orientation">
|
||||
|
@ -58,13 +80,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</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">
|
||||
<widget class="QCheckBox" name="auto_sync_cloud">
|
||||
<property name="text">
|
||||
|
@ -79,13 +94,6 @@
|
|||
</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="0" column="0">
|
||||
<widget class="QCheckBox" name="sys_tray">
|
||||
<property name="text">
|
||||
|
@ -93,6 +101,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
Loading…
Reference in a new issue