1
0
Fork 0
mirror of synced 2024-06-03 03:04:42 +12:00

Some optimizations

This commit is contained in:
Dummerle 2021-08-07 23:42:40 +02:00
parent 2233c7f338
commit 983e80a4c6
9 changed files with 248 additions and 298 deletions

View file

@ -41,7 +41,7 @@ class Shop(QStackedWidget):
self.info.back_button.clicked.connect(lambda: self.setCurrentIndex(0))
self.search_results.back_button.clicked.connect(lambda: self.setCurrentIndex(0))
self.shop.show_info.connect(self.show_info)
self.shop.show_info.connect(self.show_search_results)
self.shop.show_game.connect(self.show_game_info)
self.browse_games.show_game.connect(self.show_game_info)
@ -55,6 +55,6 @@ class Shop(QStackedWidget):
self.info.update_game(data)
self.setCurrentIndex(2)
def show_info(self, data):
self.search_results.show_results(data)
def show_search_results(self, text: str):
self.search_results.load_results(text)
self.setCurrentIndex(1)

View file

@ -1,17 +1,15 @@
import datetime
import json
import logging
import random
from PyQt5.QtCore import QUrl, pyqtSignal, QJsonParseError, QJsonDocument
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QCheckBox, QVBoxLayout, QLabel
from rare.components.tabs.shop.constants import game_query, Constants
from rare.components.tabs.shop.game_widgets import GameWidget
from rare.ui.components.tabs.store.browse_games import Ui_browse_games
from rare.utils.extra_widgets import FlowLayout, WaitingSpinner
from rare.utils.utils import get_lang
from rare.utils.utils import get_lang, QtRequestManager
logger = logging.getLogger("BrowseGames")
@ -22,8 +20,6 @@ class BrowseGames(QWidget, Ui_browse_games):
price = ""
tags = []
types = []
request_active = False
next_request = False
def __init__(self, path):
super(BrowseGames, self).__init__()
@ -32,7 +28,8 @@ class BrowseGames(QWidget, Ui_browse_games):
self.games_widget = QWidget()
self.games_widget.setLayout(FlowLayout())
self.games.setWidget(self.games_widget)
self.manager = QNetworkAccessManager()
self.manager = QtRequestManager("json")
self.manager.data_ready.connect(self.show_games)
self.stack.addWidget(WaitingSpinner())
@ -85,10 +82,6 @@ class BrowseGames(QWidget, Ui_browse_games):
if removed_type and removed_type in self.types:
self.types.remove(removed_type)
if self.request_active:
self.next_request = True
return
locale = get_lang()
self.stack.setCurrentIndex(2)
date = f"[,{datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%dT%X')}.{str(random.randint(0, 999)).zfill(3)}Z]"
@ -112,57 +105,26 @@ class BrowseGames(QWidget, Ui_browse_games):
if self.types:
payload["variables"]["category"] = "|".join(self.types)
request = QNetworkRequest(QUrl("https://www.epicgames.com/graphql"))
request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json")
self.request_active = True
self.game_request = self.manager.post(request, json.dumps(payload).encode("utf-8"))
self.game_request.finished.connect(self.show_games)
self.manager.post("https://www.epicgames.com/graphql", payload)
def show_games(self):
if self.game_request:
if self.game_request.error() == QNetworkReply.NoError:
error = QJsonParseError()
json_data = QJsonDocument.fromJson(self.game_request.readAll().data(), error)
def show_games(self, data):
data = data["data"]["Catalog"]["searchStore"]["elements"]
QWidget().setLayout(self.games_widget.layout())
if error.error == error.NoError:
try:
games = json.loads(json_data.toJson().data().decode())["data"]["Catalog"]["searchStore"][
"elements"]
except TypeError as e:
logger.error("Type Error: " + str(e))
self.stack.setCurrentIndex(1)
else:
QWidget().setLayout(self.games_widget.layout())
if games:
self.games_widget.setLayout(FlowLayout())
if data:
self.games_widget.setLayout(FlowLayout())
for game in games:
w = GameWidget(self.path, game, 275)
self.games_widget.layout().addWidget(w)
w.show_info.connect(self.show_game.emit)
for game in data:
w = GameWidget(self.path, game, 275)
self.games_widget.layout().addWidget(w)
w.show_info.connect(self.show_game.emit)
else:
self.games_widget.setLayout(QVBoxLayout())
self.games_widget.layout().addWidget(
QLabel(self.tr("Could not get games matching the filter")))
self.games_widget.layout().addStretch(1)
self.stack.setCurrentIndex(0)
self.request_active = False
if self.next_request:
self.prepare_request()
self.next_request = ()
return
else:
logger.error(error.errorString())
else:
logger.error(self.game_request.errorString())
if self.next_request:
self.prepare_request()
self.next_request = False
else:
self.stack.setCurrentIndex(1)
self.games_widget.setLayout(QVBoxLayout())
self.games_widget.layout().addWidget(
QLabel(self.tr("Could not get games matching the filter")))
self.games_widget.layout().addStretch(1)
self.stack.setCurrentIndex(0)
class CheckBox(QCheckBox):

View file

@ -72,3 +72,34 @@ game_query = "query searchStoreQuery($allowCountries: String, $category: String,
"endDate\n discountSetting {\n discountType\n " \
"discountPercentage\n }\n }\n }\n }\n }\n paging {\n " \
" count\n total\n }\n }\n }\n}\n "
search_query = "query searchStoreQuery($allowCountries: String, $category: String, $count: Int, $country: String!, " \
"$keywords: String, $locale: String, $namespace: String, $withMapping: Boolean = false, $itemNs: String, " \
"$sortBy: String, $sortDir: String, $start: Int, $tag: String, $releaseDate: String, $withPrice: Boolean = " \
"false, $withPromotions: Boolean = false, $priceRange: String, $freeGame: Boolean, $onSale: Boolean, " \
"$effectiveDate: String) {\n Catalog {\n searchStore(\n allowCountries: $allowCountries\n " \
"category: $category\n count: $count\n country: $country\n keywords: $keywords\n locale: " \
"$locale\n namespace: $namespace\n itemNs: $itemNs\n sortBy: $sortBy\n sortDir: " \
"$sortDir\n releaseDate: $releaseDate\n start: $start\n tag: $tag\n priceRange: " \
"$priceRange\n freeGame: $freeGame\n onSale: $onSale\n effectiveDate: $effectiveDate\n ) {" \
"\n elements {\n title\n id\n namespace\n description\n " \
"effectiveDate\n keyImages {\n type\n url\n }\n currentPrice\n " \
"seller {\n id\n name\n }\n productSlug\n urlSlug\n url\n " \
" tags {\n id\n }\n items {\n id\n namespace\n }\n " \
"customAttributes {\n key\n value\n }\n categories {\n path\n " \
"}\n catalogNs @include(if: $withMapping) {\n mappings(pageType: \"productHome\") {\n " \
" pageSlug\n pageType\n }\n }\n offerMappings @include(if: $withMapping) " \
"{\n pageSlug\n pageType\n }\n price(country: $country) @include(if: " \
"$withPrice) {\n totalPrice {\n discountPrice\n originalPrice\n " \
"voucherDiscount\n discount\n currencyCode\n currencyInfo {\n " \
"decimals\n }\n fmtPrice(locale: $locale) {\n originalPrice\n " \
"discountPrice\n intermediatePrice\n }\n }\n lineOffers {\n " \
" appliedRules {\n id\n endDate\n discountSetting {\n " \
"discountType\n }\n }\n }\n }\n promotions(category: " \
"$category) @include(if: $withPromotions) {\n promotionalOffers {\n promotionalOffers {\n " \
" startDate\n endDate\n discountSetting {\n " \
"discountType\n discountPercentage\n }\n }\n }\n " \
"upcomingPromotionalOffers {\n promotionalOffers {\n startDate\n " \
"endDate\n discountSetting {\n discountType\n discountPercentage\n " \
" }\n }\n }\n }\n }\n paging {\n count\n " \
"total\n }\n }\n }\n}\n "

View file

@ -1,13 +1,13 @@
import json
import logging
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSignal, QUrl, QJsonParseError, QJsonDocument
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtNetwork import QNetworkAccessManager
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel
from rare.components.tabs.shop.constants import search_query
from rare.utils.extra_widgets import ImageLabel
from rare.utils.utils import get_lang
from rare.utils.utils import get_lang, QtRequestManager
logger = logging.getLogger("GameWidgets")
@ -19,12 +19,11 @@ class GameWidget(QWidget):
super(GameWidget, self).__init__()
self.manager = QNetworkAccessManager()
self.width = width
self.path = path
if json_info:
self.init_ui(json_info, path)
self.path = path
self.init_ui(json_info)
def init_ui(self, json_info, path):
self.path = path
def init_ui(self, json_info):
self.layout = QVBoxLayout()
self.image = ImageLabel()
self.layout.addWidget(self.image)
@ -58,69 +57,21 @@ class GameWidget(QWidget):
@classmethod
def from_request(cls, name, path):
c = cls(path)
c.manager = QNetworkAccessManager()
c.request = c.manager.get(QNetworkRequest())
c.manager = QtRequestManager("json")
c.manager.data_ready.connect(c.handle_response)
locale = get_lang()
payload = json.dumps({
"query": query,
payload = {
"query": search_query,
"variables": {"category": "games/edition/base|bundles/games|editors|software/edition/base", "count": 1,
"country": "DE", "keywords": name, "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")
c.search_request = c.manager.post(request, payload)
c.search_request.finished.connect(lambda: c.handle_response(path))
}
c.manager.post("https://www.epicgames.com/graphql", payload)
c.search_request.da.connect(lambda: c.handle_response(path))
return c
def handle_response(self, path):
if self.search_request:
if self.search_request.error() == QNetworkReply.NoError:
error = QJsonParseError()
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"][0]
self.init_ui(data, path)
else:
logging.error(error.errorString())
return
def handle_response(self, data):
else:
return
else:
return
query = "query searchStoreQuery($allowCountries: String, $category: String, $count: Int, $country: String!, " \
"$keywords: String, $locale: String, $namespace: String, $withMapping: Boolean = false, $itemNs: String, " \
"$sortBy: String, $sortDir: String, $start: Int, $tag: String, $releaseDate: String, $withPrice: Boolean = " \
"false, $withPromotions: Boolean = false, $priceRange: String, $freeGame: Boolean, $onSale: Boolean, " \
"$effectiveDate: String) {\n Catalog {\n searchStore(\n allowCountries: $allowCountries\n " \
"category: $category\n count: $count\n country: $country\n keywords: $keywords\n locale: " \
"$locale\n namespace: $namespace\n itemNs: $itemNs\n sortBy: $sortBy\n sortDir: " \
"$sortDir\n releaseDate: $releaseDate\n start: $start\n tag: $tag\n priceRange: " \
"$priceRange\n freeGame: $freeGame\n onSale: $onSale\n effectiveDate: $effectiveDate\n ) {" \
"\n elements {\n title\n id\n namespace\n description\n " \
"effectiveDate\n keyImages {\n type\n url\n }\n currentPrice\n " \
"seller {\n id\n name\n }\n productSlug\n urlSlug\n url\n " \
" tags {\n id\n }\n items {\n id\n namespace\n }\n " \
"customAttributes {\n key\n value\n }\n categories {\n path\n " \
"}\n catalogNs @include(if: $withMapping) {\n mappings(pageType: \"productHome\") {\n " \
" pageSlug\n pageType\n }\n }\n offerMappings @include(if: $withMapping) " \
"{\n pageSlug\n pageType\n }\n price(country: $country) @include(if: " \
"$withPrice) {\n totalPrice {\n discountPrice\n originalPrice\n " \
"voucherDiscount\n discount\n currencyCode\n currencyInfo {\n " \
"decimals\n }\n fmtPrice(locale: $locale) {\n originalPrice\n " \
"discountPrice\n intermediatePrice\n }\n }\n lineOffers {\n " \
" appliedRules {\n id\n endDate\n discountSetting {\n " \
"discountType\n }\n }\n }\n }\n promotions(category: " \
"$category) @include(if: $withPromotions) {\n promotionalOffers {\n promotionalOffers {\n " \
" startDate\n endDate\n discountSetting {\n " \
"discountType\n discountPercentage\n }\n }\n }\n " \
"upcomingPromotionalOffers {\n promotionalOffers {\n startDate\n " \
"endDate\n discountSetting {\n discountType\n discountPercentage\n " \
" }\n }\n }\n }\n }\n paging {\n count\n " \
"total\n }\n }\n }\n}\n "
data = data["data"]["Catalog"]["searchStore"]["elements"][0]
self.init_ui(data)

View file

@ -1,16 +1,21 @@
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QScrollArea, QGroupBox, QPushButton
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QScrollArea, QGroupBox, QPushButton, \
QStackedWidget
from rare.utils.extra_widgets import ImageLabel, FlowLayout
from rare.components.tabs.shop.constants import search_query
from rare.utils.extra_widgets import ImageLabel, FlowLayout, WaitingSpinner
from rare.utils.utils import QtRequestManager, get_lang
class SearchResults(QWidget):
class SearchResults(QStackedWidget):
show_info = pyqtSignal(dict)
def __init__(self):
super(SearchResults, self).__init__()
self.search_result_widget = QWidget()
self.addWidget(self.search_result_widget)
self.main_layout = QVBoxLayout()
self.back_button = QPushButton(self.tr("Back"))
self.main_layout.addWidget(self.back_button)
@ -25,9 +30,30 @@ class SearchResults(QWidget):
self.layout = FlowLayout()
self.widget.setLayout(self.layout)
self.setLayout(self.main_layout)
self.search_manager = QtRequestManager("json")
self.search_manager.data_ready.connect(self.show_results)
def show_results(self, results: list):
self.search_result_widget.setLayout(self.main_layout)
self.addWidget(WaitingSpinner())
self.setCurrentIndex(1)
def load_results(self, text: str):
self.setCurrentIndex(1)
if text != "":
locale = get_lang()
payload = {
"query": search_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}
}
self.search_manager.post("https://www.epicgames.com/graphql", payload)
def show_results(self, results: dict):
results = results["data"]["Catalog"]["searchStore"]["elements"]
QVBoxLayout().addWidget(self.widget)
self.widget = QWidget()
self.layout = FlowLayout()
@ -40,6 +66,7 @@ class SearchResults(QWidget):
self.layout.addWidget(w)
self.widget.setLayout(self.layout)
self.result_area.setWidget(self.widget)
self.setCurrentIndex(0)
class _SearchResultItem(QGroupBox):

View file

@ -1,16 +1,13 @@
import json
import logging
import webbrowser
from PyQt5.QtCore import QUrl, QJsonDocument, QJsonParseError
from PyQt5.QtGui import QPixmap, QFont
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PyQt5.QtWidgets import QWidget, QLabel
from rare.components.tabs.shop.shop_models import ShopGame
from rare.ui.components.tabs.store.shop_game_info import Ui_shop_info
from rare.utils.extra_widgets import WaitingSpinner, ImageLabel
from rare.utils.utils import get_lang
from rare.utils.utils import get_lang, QtRequestManager
logger = logging.getLogger("ShopInfo")
@ -28,7 +25,8 @@ class ShopGameInfo(QWidget, Ui_shop_info):
self.image = ImageLabel()
self.image_stack.addWidget(self.image)
self.image_stack.addWidget(WaitingSpinner())
self.manager = QNetworkAccessManager()
self.manager = QtRequestManager("json")
self.manager.data_ready.connect(self.data_received)
def update_game(self, data: dict):
self.image_stack.setCurrentIndex(1)
@ -60,25 +58,9 @@ class ShopGameInfo(QWidget, Ui_shop_info):
locale = get_lang()
url = f"https://store-content.ak.epicgames.com/api/{locale}/content/{'products' if not is_bundle else 'bundles'}/{slug}"
# game = api_utils.get_product(slug, locale)
self.request = self.manager.get(QNetworkRequest(QUrl(url)))
self.request.finished.connect(self.data_received)
self.manager.get(url)
def data_received(self):
if self.request:
if self.request.error() == QNetworkReply.NoError:
error = QJsonParseError()
json_data = QJsonDocument.fromJson(self.request.readAll().data(), error)
if error.error == error.NoError:
game = json.loads(json_data.toJson().data().decode())
else:
logging.info(self.slug, error.errorString())
return
else:
logger.error("Data failed")
return
else:
return
def data_received(self, game):
self.game = ShopGame.from_json(game, self.data)
self.title.setText(self.game.title)
self.price.setFont(QFont())
@ -133,7 +115,6 @@ class ShopGameInfo(QWidget, Ui_shop_info):
pass
self.tags.setText(", ".join(self.game.tags))
# self.price.setText(self.game.price)
self.request.deleteLater()
def button_clicked(self):
webbrowser.open("https://www.epicgames.com/store/de/p/" + self.slug)

View file

@ -1,24 +1,22 @@
import datetime
import json
import logging
from json import JSONDecodeError
from PyQt5.QtCore import Qt, pyqtSignal, QUrl, QJsonDocument, QJsonParseError, \
QStringListModel
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PyQt5.QtCore import Qt, pyqtSignal, QStringListModel
from PyQt5.QtNetwork import QNetworkAccessManager
from PyQt5.QtWidgets import QWidget, QCompleter, QGroupBox, QHBoxLayout, QScrollArea
from rare.components.tabs.shop.constants import search_query
from rare.components.tabs.shop.game_widgets import GameWidget
from rare.ui.components.tabs.store.store import Ui_ShopWidget
from rare.utils.extra_widgets import WaitingSpinner, FlowLayout, ButtonLineEdit
from rare.utils.utils import get_lang
from rare.utils.utils import QtRequestManager, get_lang
logger = logging.getLogger("Shop")
# noinspection PyAttributeOutsideInit,PyBroadException
class ShopWidget(QScrollArea, Ui_ShopWidget):
show_info = pyqtSignal(list)
show_info = pyqtSignal(str)
show_game = pyqtSignal(dict)
free_game_widgets = []
active_search_request = False
@ -49,31 +47,40 @@ class ShopWidget(QScrollArea, Ui_ShopWidget):
self.search_bar = ButtonLineEdit("fa.search", placeholder_text=self.tr("Search Games"))
self.scrollAreaWidgetContents.layout().insertWidget(0, self.search_bar)
self.search_bar.textChanged.connect(self.search_games)
# self.search_bar.textChanged.connect(self.search_games)
self.search_bar.setCompleter(self.completer)
self.search_bar.returnPressed.connect(self.show_search_result)
self.search_bar.buttonClicked.connect(self.show_search_result)
self.search_bar.returnPressed.connect(self.show_search_results)
self.search_bar.buttonClicked.connect(self.show_search_results)
self.games_groupbox.setLayout(FlowLayout())
self.games_groupbox.setVisible(False)
self.search_request_manager = QtRequestManager("json")
self.search_request_manager.data_ready.connect(self.set_completer)
self.search_bar.textChanged.connect(self.load_completer)
def load_completer(self, text):
if text != "":
locale = get_lang()
payload = {
"query": search_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}
}
self.search_request_manager.post("https://www.epicgames.com/graphql", payload)
def load(self):
url = "https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions"
self.free_game_request = self.manager.get(QNetworkRequest(QUrl(url)))
self.free_game_request.finished.connect(self.add_free_games)
self.free_game_request_manager = QtRequestManager("json")
self.free_game_request_manager.get(url)
self.free_game_request_manager.data_ready.connect(self.add_free_games)
def add_free_games(self):
if self.free_game_request:
if self.free_game_request.error() == QNetworkReply.NoError:
try:
free_games = json.loads(self.free_game_request.readAll().data().decode())
except JSONDecodeError:
return
else:
return
else:
return
def add_free_games(self, free_games):
free_games = free_games["data"]["Catalog"]["searchStore"]["elements"]
date = datetime.datetime.now()
free_games_now = []
@ -132,100 +139,13 @@ class ShopWidget(QScrollArea, Ui_ShopWidget):
self.coming_free_games.layout().addStretch(1)
# self.coming_free_games.setFixedWidth(int(40 + len(coming_free_games) * 300))
self.free_games_stack.setCurrentIndex(1)
self.free_game_request.deleteLater()
def search_games(self, text, show_direct=False):
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))
self.active_search_request = True
def set_completer(self, search_data):
search_data = search_data["data"]["Catalog"]["searchStore"]["elements"]
titles = [i.get("title") for i in search_data]
model = QStringListModel()
model.setStringList(titles)
self.completer.setModel(model)
else:
self.next_search = text
def show_search_results(self, show_direct=False):
self.active_search_request = False
if self.search_request:
try:
if self.search_request.error() == QNetworkReply.NoError:
error = QJsonParseError()
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)
else:
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())
# response = .decode(encoding="utf-8")
# print(response)
# results = json.loads(response)
except RuntimeError:
return
if self.next_search:
self.search_games(self.next_search)
self.next_search = ""
def show_search_result(self, show_direct=False):
if not show_direct:
self.show_info.emit(self.data)
else:
try:
result = self.data[0]
except IndexError:
print("error")
return
self.show_game.emit(result)
query = "query searchStoreQuery($allowCountries: String, $category: String, $count: Int, $country: String!, " \
"$keywords: String, $locale: String, $namespace: String, $withMapping: Boolean = false, $itemNs: String, " \
"$sortBy: String, $sortDir: String, $start: Int, $tag: String, $releaseDate: String, $withPrice: Boolean = " \
"false, $withPromotions: Boolean = false, $priceRange: String, $freeGame: Boolean, $onSale: Boolean, " \
"$effectiveDate: String) {\n Catalog {\n searchStore(\n allowCountries: $allowCountries\n " \
"category: $category\n count: $count\n country: $country\n keywords: $keywords\n locale: " \
"$locale\n namespace: $namespace\n itemNs: $itemNs\n sortBy: $sortBy\n sortDir: " \
"$sortDir\n releaseDate: $releaseDate\n start: $start\n tag: $tag\n priceRange: " \
"$priceRange\n freeGame: $freeGame\n onSale: $onSale\n effectiveDate: $effectiveDate\n ) {" \
"\n elements {\n title\n id\n namespace\n description\n " \
"effectiveDate\n keyImages {\n type\n url\n }\n currentPrice\n " \
"seller {\n id\n name\n }\n productSlug\n urlSlug\n url\n " \
" tags {\n id\n }\n items {\n id\n namespace\n }\n " \
"customAttributes {\n key\n value\n }\n categories {\n path\n " \
"}\n catalogNs @include(if: $withMapping) {\n mappings(pageType: \"productHome\") {\n " \
" pageSlug\n pageType\n }\n }\n offerMappings @include(if: $withMapping) " \
"{\n pageSlug\n pageType\n }\n price(country: $country) @include(if: " \
"$withPrice) {\n totalPrice {\n discountPrice\n originalPrice\n " \
"voucherDiscount\n discount\n currencyCode\n currencyInfo {\n " \
"decimals\n }\n fmtPrice(locale: $locale) {\n originalPrice\n " \
"discountPrice\n intermediatePrice\n }\n }\n lineOffers {\n " \
" appliedRules {\n id\n endDate\n discountSetting {\n " \
"discountType\n }\n }\n }\n }\n promotions(category: " \
"$category) @include(if: $withPromotions) {\n promotionalOffers {\n promotionalOffers {\n " \
" startDate\n endDate\n discountSetting {\n " \
"discountType\n discountPercentage\n }\n }\n }\n " \
"upcomingPromotionalOffers {\n promotionalOffers {\n startDate\n " \
"endDate\n discountSetting {\n discountType\n discountPercentage\n " \
" }\n }\n }\n }\n }\n paging {\n count\n " \
"total\n }\n }\n }\n}\n "
def show_search_results(self):
self.show_info.emit(self.search_bar.text())

View file

@ -3,15 +3,15 @@ import os
from logging import getLogger
from PIL import Image
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal, QUrl, QSettings
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal, QSettings
from PyQt5.QtGui import QMovie, QPixmap
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLabel, QFileDialog, QHBoxLayout, QWidget, QPushButton, \
QStyleOptionTab, QStylePainter, QTabBar, QLineEdit, QToolButton
from qtawesome import icon
from rare import style_path
from rare.ui.utils.pathedit import Ui_PathEdit
from rare.utils.utils import QtRequestManager
logger = getLogger("ExtraWidgets")
@ -266,7 +266,8 @@ class ImageLabel(QLabel):
if p := os.environ.get("XDG_CACHE_HOME"):
path = os.path.join(p, "rare", "cache")
self.path = path
self.manager = QNetworkAccessManager()
self.manager = QtRequestManager("bytes")
self.manager.data_ready.connect(self.image_ready)
def update_image(self, url, name, size: tuple = (240, 320)):
self.setFixedSize(*size)
@ -280,32 +281,26 @@ class ImageLabel(QLabel):
name_extension = "tall"
self.name = f"{self.name}_{name_extension}.png"
if not os.path.exists(os.path.join(self.path, self.name)):
self.request = self.manager.get(QNetworkRequest(QUrl(url)))
self.request.finished.connect(self.image_ready)
self.manager.get(url)
# self.request.finished.connect(self.image_ready)
else:
self.show_image()
def image_ready(self):
def image_ready(self, data):
self.setPixmap(QPixmap())
if self.request:
if self.request.error() == QNetworkReply.NoError:
data = self.request.readAll().data()
image: Image.Image = Image.open(io.BytesIO(data))
image = image.resize((self.img_size[0], self.img_size[1]))
if QSettings().value("cache_images", True, bool):
image.save(os.path.join(self.path, self.name), format="png")
byte_array = io.BytesIO()
image.save(byte_array, format="PNG")
# pixmap = QPixmap.fromImage(ImageQt(image))
pixmap = QPixmap()
pixmap.loadFromData(byte_array.getvalue())
# pixmap = QPixmap.fromImage(ImageQt.ImageQt(image))
self.setPixmap(pixmap)
else:
logger.error(self.request.errorString())
else:
return
image: Image.Image = Image.open(io.BytesIO(data))
image = image.resize((self.img_size[0], self.img_size[1]))
if QSettings().value("cache_images", True, bool):
image.save(os.path.join(self.path, self.name), format="png")
byte_array = io.BytesIO()
image.save(byte_array, format="PNG")
# pixmap = QPixmap.fromImage(ImageQt(image))
pixmap = QPixmap()
pixmap.loadFromData(byte_array.getvalue())
# pixmap = QPixmap.fromImage(ImageQt.ImageQt(image))
self.setPixmap(pixmap)
def show_image(self):
self.image = QPixmap(os.path.join(self.path, self.name)).scaled(*self.img_size,

View file

@ -6,8 +6,9 @@ from logging import getLogger
import requests
from PIL import Image, UnidentifiedImageError
from PyQt5.QtCore import pyqtSignal, QLocale, QSettings
from PyQt5.QtCore import pyqtSignal, QLocale, QSettings, QObject, QUrl, QJsonParseError, QJsonDocument
from PyQt5.QtGui import QPalette, QColor
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
# Windows
if os.name == "nt":
@ -336,3 +337,85 @@ def create_desktop_link(app_name, core: LegendaryCore, type_of_link="desktop"):
shortcut.IconLocation = os.path.join(icon + ".ico")
shortcut.save()
class QtRequestManager(QObject):
data_ready = pyqtSignal(object)
request = None
request_active = False
def __init__(self, type: str = "json", queue=False):
super(QtRequestManager, self).__init__()
self.manager = QNetworkAccessManager()
self.type = type
self.queue = queue
if self.queue:
self.next_request = []
else:
self.next_request = ["", tuple(())]
def post(self, url: str, payload: dict):
if not self.request_active:
request = QNetworkRequest(QUrl(url))
request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json")
payload = json.dumps(payload).encode("utf-8")
self.request = self.manager.post(request, payload)
self.request_active = True
self.request.finished.connect(self.prepare_data)
else:
if self.queue:
self.next_request.append(["post", (url, payload)])
else:
self.next_request = ["post", (url, payload)]
def get(self, url: str):
if not self.request_active:
self.request_active = True
self.request = self.manager.get(QNetworkRequest(QUrl(url)))
self.request.finished.connect(self.prepare_data)
else:
if self.queue:
self.next_request.append(["get", (url,)])
else:
self.next_request = ["get", (url,)]
def prepare_data(self):
self.request_active = False
data = {} if self.type == "json" else b""
if self.request:
try:
if self.request.error() == QNetworkReply.NoError:
if self.type == "json":
error = QJsonParseError()
json_data = QJsonDocument.fromJson(self.request.readAll().data(), error)
if QJsonParseError.NoError == error.error:
data = json.loads(json_data.toJson().data().decode())
else:
logger.error(error.errorString())
else:
data = self.request.readAll().data()
except RuntimeError as e:
logger.error(str(e))
self.data_ready.emit(data)
self.request.deleteLater()
if self.queue:
if self.next_request:
if self.next_request[0][0] == "post":
self.post(*self.next_request[0][1])
else:
self.get(self.next_request[0][1][0])
self.next_request.pop(0)
else:
if method := self.next_request[0]:
if method == "post":
self.post(*self.next_request[1])
self.next_request = ["", ()]
else:
self.get(self.next_request[1][0])
self.next_request = ["", ()]