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

295 lines
12 KiB
Python
Raw Normal View History

2021-06-04 09:23:55 +12:00
import datetime
import logging
2021-08-25 10:01:53 +12:00
import random
2021-06-04 09:23:55 +12:00
2021-09-06 07:52:47 +12:00
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QGroupBox, QScrollArea, QCheckBox, QVBoxLayout, QLabel, QPushButton, QHBoxLayout
2021-06-04 09:23:55 +12:00
from legendary.core import LegendaryCore
2021-08-23 08:22:17 +12:00
from rare.components.tabs.shop import ShopApiCore
2021-08-25 10:01:53 +12:00
from rare.components.tabs.shop.constants import Constants
2021-09-06 07:52:47 +12:00
from rare.components.tabs.shop.game_widgets import GameWidget
2021-08-25 10:01:53 +12:00
from rare.components.tabs.shop.shop_models import BrowseModel
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
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):
2021-08-08 09:42:40 +12:00
show_info = pyqtSignal(str)
show_game = pyqtSignal(dict)
2021-06-04 09:23:55 +12:00
free_game_widgets = []
active_search_request = False
next_search = ""
2021-08-23 08:22:17 +12:00
wishlist: list = []
2021-06-04 09:23:55 +12:00
2021-08-23 08:22:17 +12:00
def __init__(self, path, core: LegendaryCore, shop_api: ShopApiCore):
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-08-19 08:17:14 +12:00
self.core = core
2021-08-25 10:01:53 +12:00
self.api_core = shop_api
self.price = ""
self.tags = []
self.types = []
self.update_games_allowed = True
2021-09-06 07:52:47 +12:00
self.free_widget.setLayout(FlowLayout())
2021-08-25 10:01:53 +12:00
self.free_stack.addWidget(WaitingSpinner())
self.free_stack.setCurrentIndex(1)
self.discount_widget.setLayout(FlowLayout())
self.discount_stack.addWidget(WaitingSpinner())
self.discount_stack.setCurrentIndex(1)
self.game_widget.setLayout(FlowLayout())
self.game_stack.addWidget(WaitingSpinner())
self.game_stack.setCurrentIndex(1)
self.search_bar = ButtonLineEdit("fa.search", placeholder_text=self.tr("Search Games"))
2021-08-25 10:01:53 +12:00
self.layout().insertWidget(0, self.search_bar)
2021-08-08 09:42:40 +12:00
# self.search_bar.textChanged.connect(self.search_games)
2021-08-08 09:42:40 +12:00
self.search_bar.returnPressed.connect(self.show_search_results)
self.search_bar.buttonClicked.connect(self.show_search_results)
2021-08-25 10:01:53 +12:00
self.init_filter()
2021-08-19 08:17:14 +12:00
2021-08-25 10:01:53 +12:00
# self.search_bar.textChanged.connect(self.load_completer)
2021-08-08 09:42:40 +12:00
2021-06-04 09:23:55 +12:00
def load(self):
2021-08-23 08:22:17 +12:00
# load free games
2021-08-25 10:01:53 +12:00
self.api_core.get_free_games(self.add_free_games)
2021-08-23 08:22:17 +12:00
# load wishlist
2021-08-25 10:01:53 +12:00
self.api_core.get_wishlist(self.add_wishlist_items)
2021-09-13 07:19:51 +12:00
# load browse games
2021-08-25 10:01:53 +12:00
self.prepare_request()
2021-08-23 08:22:17 +12:00
def update_wishlist(self):
2021-08-25 10:01:53 +12:00
self.api_core.get_wishlist(self.add_wishlist_items)
2021-08-23 08:22:17 +12:00
def add_wishlist_items(self, wishlist):
for i in range(self.discount_widget.layout().count()):
item = self.discount_widget.layout().itemAt(i)
if item:
item.widget().deleteLater()
2021-11-07 13:19:37 +13:00
if wishlist and wishlist[0] == "error":
self.discount_widget.layout().addWidget(QLabel(self.tr("Failed to get wishlist: ") + wishlist[1]))
btn = QPushButton(self.tr("Reload"))
self.discount_widget.layout().addWidget(btn)
btn.clicked.connect(lambda: self.api_core.get_wishlist(self.add_wishlist_items))
self.discount_stack.setCurrentIndex(0)
return
2021-08-19 08:17:14 +12:00
discounts = 0
for game in wishlist:
2021-08-26 06:25:10 +12:00
if not game:
continue
2021-09-13 07:19:51 +12:00
try:
if game["offer"]["price"]["totalPrice"]["discount"] > 0:
w = GameWidget(self.path, game["offer"])
w.show_info.connect(self.show_game.emit)
self.discount_widget.layout().addWidget(w)
discounts += 1
except Exception as e:
logger.warning(str(game) + str(e))
continue
2021-08-25 10:01:53 +12:00
self.discounts_gb.setVisible(discounts > 0)
2021-08-26 08:08:24 +12:00
self.discount_stack.setCurrentIndex(0)
2021-06-04 09:23:55 +12:00
def add_free_games(self, free_games: list):
for i in range(self.free_widget.layout().count()):
item = self.free_widget.layout().itemAt(i)
if item:
item.widget().deleteLater()
if free_games and free_games[0] == "error":
self.free_widget.layout().addWidget(QLabel(self.tr("Failed to fetch free games: ") + free_games[1]))
btn = QPushButton(self.tr("Reload"))
self.free_widget.layout().addWidget(btn)
btn.clicked.connect(lambda: self.api_core.get_free_games(self.add_free_games))
self.free_stack.setCurrentIndex(0)
return
self.free_games_now = QGroupBox(self.tr("Now Free"))
self.free_games_now.setLayout(QHBoxLayout())
self.free_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_widget.layout().addWidget(self.coming_free_games)
2021-06-04 09:23:55 +12:00
date = datetime.datetime.now()
free_games_now = []
coming_free_games = []
for game in free_games:
2021-09-13 07:19:51 +12:00
try:
if game['price']['totalPrice']['fmtPrice']['discountPrice'] == "0" and \
game['price']['totalPrice']['fmtPrice']['originalPrice'] != \
game['price']['totalPrice']['fmtPrice']['discountPrice']:
2021-09-13 07:19:51 +12:00
free_games_now.append(game)
continue
if game["title"] == "Mystery Game":
coming_free_games.append(game)
continue
except KeyError as e:
logger.warning(str(e))
2021-06-04 09:23:55 +12:00
try:
2021-08-25 10:01:53 +12:00
# parse datetime to check if game is next week or now
2021-06-11 05:58:35 +12:00
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:
2021-09-13 07:19:51 +12:00
2021-06-11 05:58:35 +12:00
continue
2021-06-04 09:23:55 +12:00
except TypeError:
print("type error")
continue
2021-09-13 07:19:51 +12:00
if start_date > date:
2021-06-04 09:23:55 +12:00
coming_free_games.append(game)
2021-08-25 10:01:53 +12:00
# free games now
2021-06-04 09:23:55 +12:00
for free_game in free_games_now:
2021-09-06 07:52:47 +12:00
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-08-25 10:01:53 +12:00
# free games next week
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)
# self.coming_free_games.setFixedWidth(int(40 + len(coming_free_games) * 300))
2021-08-25 10:01:53 +12:00
self.free_stack.setCurrentIndex(0)
2021-08-08 09:42:40 +12:00
def show_search_results(self):
self.show_info.emit(self.search_bar.text())
2021-08-25 10:01:53 +12:00
def init_filter(self):
self.none_price.toggled.connect(lambda: self.prepare_request("") if self.none_price.isChecked() else None)
self.free_button.toggled.connect(lambda: self.prepare_request("free") if self.free_button.isChecked() else None)
self.under10.toggled.connect(
lambda: self.prepare_request("<price>[0, 1000)") if self.under10.isChecked() else None)
self.under20.toggled.connect(
lambda: self.prepare_request("<price>[0, 2000)") if self.under20.isChecked() else None)
self.under30.toggled.connect(
lambda: self.prepare_request("<price>[0, 3000)") if self.under30.isChecked() else None)
self.above.toggled.connect(lambda: self.prepare_request("<price>[1499,]") if self.above.isChecked() else None)
2021-08-26 08:08:24 +12:00
# self.on_discount.toggled.connect(lambda: self.prepare_request("sale") if self.on_discount.isChecked() else None)
self.on_discount.toggled.connect(lambda: self.prepare_request())
2021-08-25 10:01:53 +12:00
constants = Constants()
self.checkboxes = []
for groupbox, variables in [(self.genre_gb, constants.categories),
(self.platform_gb, constants.platforms),
(self.others_gb, constants.others),
(self.type_gb, constants.types)]:
for text, tag in variables:
checkbox = CheckBox(text, tag)
checkbox.activated.connect(lambda x: self.prepare_request(added_tag=x))
checkbox.deactivated.connect(lambda x: self.prepare_request(removed_tag=x))
groupbox.layout().addWidget(checkbox)
self.checkboxes.append(checkbox)
self.reset_button.clicked.connect(self.reset_filters)
def reset_filters(self):
self.update_games_allowed = False
for cb in self.checkboxes:
cb.setChecked(False)
self.none_price.setChecked(True)
self.tags = []
self.types = []
self.update_games_allowed = True
self.prepare_request("")
2021-08-26 08:08:24 +12:00
def prepare_request(self, price: str = None, added_tag: int = 0, removed_tag: int = 0,
2021-08-25 10:01:53 +12:00
added_type: str = "", removed_type: str = ""):
if not self.update_games_allowed:
return
2021-08-26 08:08:24 +12:00
if price is not None:
self.price = price
2021-08-25 10:01:53 +12:00
if added_tag != 0:
self.tags.append(added_tag)
if removed_tag != 0 and removed_tag in self.tags:
self.tags.remove(removed_tag)
if added_type:
self.types.append(added_type)
if removed_type and removed_type in self.types:
self.types.remove(removed_type)
2021-08-26 08:08:24 +12:00
if (self.types or self.price) or self.tags or self.on_discount.isChecked():
2021-08-25 10:01:53 +12:00
self.free_game_group_box.setVisible(False)
self.discounts_gb.setVisible(False)
else:
self.free_game_group_box.setVisible(True)
if len(self.discounts_gb.layout().children()) > 0:
self.discounts_gb.setVisible(True)
self.game_stack.setCurrentIndex(1)
date = f"[,{datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%dT%X')}.{str(random.randint(0, 999)).zfill(3)}Z]"
browse_model = BrowseModel(language_code=self.core.language_code, country_code=self.core.country_code,
date=date, count=20, price=self.price,
2021-08-26 08:08:24 +12:00
onSale=self.on_discount.isChecked())
2021-08-25 10:01:53 +12:00
browse_model.tag = "|".join(self.tags)
if self.types:
browse_model.category = "|".join(self.types)
self.api_core.browse_games(browse_model, self.show_games)
def show_games(self, data):
for child in self.game_widget.layout().children():
child.deleteLater()
del child
2021-08-25 10:01:53 +12:00
if data:
for game in data:
2021-09-13 07:19:51 +12:00
w = GameWidget(self.path, game, 275)
2021-08-25 10:01:53 +12:00
self.game_widget.layout().addWidget(w)
w.show_info.connect(self.show_game.emit)
else:
layout = QVBoxLayout()
layout.addWidget(
2021-08-25 10:01:53 +12:00
QLabel(self.tr("Could not get games matching the filter")))
layout.addStretch(1)
self.game_widget.setLayout(layout)
2021-08-25 10:01:53 +12:00
self.game_stack.setCurrentIndex(0)
class CheckBox(QCheckBox):
activated = pyqtSignal(str)
deactivated = pyqtSignal(str)
def __init__(self, text, tag):
super(CheckBox, self).__init__(text)
self.tag = tag
self.toggled.connect(self.handle_toggle)
def handle_toggle(self):
if self.isChecked():
self.activated.emit(self.tag)
else:
self.deactivated.emit(self.tag)