1
0
Fork 0
mirror of synced 2024-06-26 18:20:50 +12:00
Rare/rare/components/tabs/shop/shop_widget.py

232 lines
12 KiB
Python
Raw Normal View History

2021-06-04 09:23:55 +12:00
import datetime
import json
import logging
from json import JSONDecodeError
2021-06-11 05:58:35 +12:00
from PyQt5.QtCore import Qt, pyqtSignal, QUrl, QJsonDocument, QJsonParseError, \
2021-06-15 08:30:57 +12:00
QStringListModel
2021-06-04 09:23:55 +12:00
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
2021-06-15 08:30:57 +12:00
from PyQt5.QtWidgets import QWidget, QCompleter, QGroupBox, QHBoxLayout, QScrollArea
2021-06-04 09:23:55 +12:00
2021-06-15 08:30:57 +12:00
from rare.components.tabs.shop.game_widgets import GameWidget
2021-06-04 09:23:55 +12:00
from rare.ui.components.tabs.store.store import Ui_ShopWidget
from rare.utils.extra_widgets import WaitingSpinner, FlowLayout, ButtonLineEdit
2021-06-04 09:23:55 +12:00
from rare.utils.utils import get_lang
logger = logging.getLogger("Shop")
2021-06-04 09:23:55 +12:00
2021-06-11 05:58:35 +12:00
# noinspection PyAttributeOutsideInit,PyBroadException
class ShopWidget(QScrollArea, Ui_ShopWidget):
show_info = pyqtSignal(list)
show_game = pyqtSignal(dict)
2021-06-04 09:23:55 +12:00
free_game_widgets = []
active_search_request = False
next_search = ""
2021-06-04 09:23:55 +12:00
2021-06-15 08:30:57 +12:00
def __init__(self, path):
2021-06-04 09:23:55 +12:00
super(ShopWidget, self).__init__()
self.setWidgetResizable(True)
2021-06-04 09:23:55 +12:00
self.setupUi(self)
2021-06-15 08:30:57 +12:00
self.path = path
2021-06-04 09:23:55 +12:00
self.manager = QNetworkAccessManager()
2021-06-11 05:58:35 +12:00
self.free_games_widget = QWidget()
self.free_games_widget.setLayout(FlowLayout())
self.free_games_now = QGroupBox(self.tr("Free Games"))
self.free_games_now.setLayout(QHBoxLayout())
self.free_games_widget.layout().addWidget(self.free_games_now)
self.coming_free_games = QGroupBox(self.tr("Free Games next week"))
self.coming_free_games.setLayout(QHBoxLayout())
self.free_games_widget.layout().addWidget(self.coming_free_games)
2021-06-04 09:23:55 +12:00
self.free_games_stack.addWidget(WaitingSpinner())
2021-06-11 05:58:35 +12:00
self.free_games_stack.addWidget(self.free_games_widget)
2021-06-04 09:23:55 +12:00
self.completer = QCompleter()
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
2021-06-04 09:23:55 +12:00
self.data = []
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.setCompleter(self.completer)
self.search_bar.returnPressed.connect(self.show_search_result)
self.search_bar.buttonClicked.connect(self.show_search_result)
self.games_groupbox.setLayout(FlowLayout())
2021-06-15 08:30:57 +12:00
self.games_groupbox.setVisible(False)
2021-06-04 09:23:55 +12:00
def load(self):
url = "https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions"
self.free_game_request = self.manager.get(QNetworkRequest(QUrl(url)))
2021-06-11 05:58:35 +12:00
self.free_game_request.finished.connect(self.add_free_games)
2021-06-04 09:23:55 +12:00
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
free_games = free_games["data"]["Catalog"]["searchStore"]["elements"]
date = datetime.datetime.now()
free_games_now = []
coming_free_games = []
for game in free_games:
if game["title"] == "Mystery Game":
coming_free_games.append(game)
continue
try:
# parse datetime
2021-06-11 05:58:35 +12:00
try:
end_date = datetime.datetime.strptime(
game["promotions"]["upcomingPromotionalOffers"][0]["promotionalOffers"][0]["endDate"],
'%Y-%m-%dT%H:%M:%S.%fZ')
except Exception:
try:
end_date = datetime.datetime.strptime(
game["promotions"]["promotionalOffers"][0]["promotionalOffers"][0]["endDate"],
'%Y-%m-%dT%H:%M:%S.%fZ')
except Exception:
continue
try:
start_date = datetime.datetime.strptime(
game["promotions"]["upcomingPromotionalOffers"][0]["promotionalOffers"][0]["startDate"],
'%Y-%m-%dT%H:%M:%S.%fZ')
except Exception:
try:
start_date = datetime.datetime.strptime(
game["promotions"]["promotionalOffers"][0]["promotionalOffers"][0]["startDate"],
'%Y-%m-%dT%H:%M:%S.%fZ')
except Exception as e:
print(e)
continue
2021-06-04 09:23:55 +12:00
except TypeError:
print("type error")
continue
if start_date < date < end_date:
free_games_now.append(game)
elif start_date > date:
coming_free_games.append(game)
for free_game in free_games_now:
w = GameWidget(self.path, free_game)
2021-06-11 05:58:35 +12:00
w.show_info.connect(self.show_game.emit)
self.free_games_now.layout().addWidget(w)
2021-06-04 09:23:55 +12:00
self.free_game_widgets.append(w)
2021-06-11 05:58:35 +12:00
self.free_games_now.layout().addStretch(1)
2021-06-04 09:23:55 +12:00
for free_game in coming_free_games:
w = GameWidget(self.path, free_game)
2021-06-04 09:23:55 +12:00
if free_game["title"] != "Mystery Game":
2021-06-11 05:58:35 +12:00
w.show_info.connect(self.show_game.emit)
self.coming_free_games.layout().addWidget(w)
2021-06-04 09:23:55 +12:00
self.free_game_widgets.append(w)
2021-06-11 05:58:35 +12:00
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()
2021-06-04 09:23:55 +12:00
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))
2021-06-30 10:38:42 +12:00
self.active_search_request = True
else:
self.next_search = text
2021-06-04 09:23:55 +12:00
def show_search_results(self, show_direct=False):
2021-06-30 10:38:42 +12:00
self.active_search_request = False
2021-06-04 09:23:55 +12:00
if self.search_request:
2021-06-15 08:30:57 +12:00
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)
2021-06-30 10:38:42 +12:00
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()
2021-06-15 08:30:57 +12:00
else:
logging.error(error.errorString())
# response = .decode(encoding="utf-8")
# print(response)
# results = json.loads(response)
except RuntimeError:
return
2021-06-30 10:38:42 +12:00
if self.next_search:
self.search_games(self.next_search)
self.next_search = ""
2021-06-04 09:23:55 +12:00
def show_search_result(self, show_direct=False):
if not show_direct:
2021-06-30 10:38:42 +12:00
self.show_info.emit(self.data)
else:
2021-06-11 05:58:35 +12:00
try:
result = self.data[0]
except IndexError:
print("error")
return
self.show_game.emit(result)
2021-06-04 09:23:55 +12:00
2021-06-11 05:58:35 +12:00
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 "