import logging from PyQt5.QtCore import Qt, QUrl from PyQt5.QtGui import QPixmap, QFont, QDesktopServices from PyQt5.QtWidgets import ( QWidget, QLabel, QPushButton, QHBoxLayout, QSpacerItem, QGroupBox, QTabWidget, QGridLayout, ) from rare.components.tabs.store.shop_models import ShopGame from rare.shared import LegendaryCoreSingleton from rare.ui.components.tabs.store.shop_game_info import Ui_shop_info from rare.utils.extra_widgets import ImageLabel from rare.utils.misc import qta_icon as icon from rare.widgets.loading_widget import LoadingWidget logger = logging.getLogger("ShopInfo") class ShopGameInfo(QWidget, Ui_shop_info): game: ShopGame data: dict # TODO Design def __init__(self, installed_titles: list, api_core): super(ShopGameInfo, self).__init__() self.setupUi(self) self.core = LegendaryCoreSingleton() self.api_core = api_core self.installed = installed_titles self.open_store_button.clicked.connect(self.button_clicked) self.image = ImageLabel() self.image_stack.addWidget(self.image) self.image_stack.addWidget(LoadingWidget()) warn_label = QLabel() warn_label.setPixmap( icon("fa.warning").pixmap(160, 160).scaled(240, 320, Qt.IgnoreAspectRatio) ) self.image_stack.addWidget(warn_label) self.wishlist_button.clicked.connect(self.add_to_wishlist) self.in_wishlist = False self.wishlist = [] def handle_wishlist_update(self, data): if data and data[0] == "error": return self.wishlist = [i["offer"]["title"] for i in data] if self.title_str in self.wishlist: self.in_wishlist = True self.wishlist_button.setVisible(True) self.wishlist_button.setText(self.tr("Remove from Wishlist")) else: self.in_wishlist = False self.wishlist_button.setVisible(False) def update_game(self, data: dict): self.image_stack.setCurrentIndex(1) self.title.setText(data["title"]) self.title_str = data["title"] self.api_core.get_wishlist(self.handle_wishlist_update) for i in reversed(range(self.req_group_box.layout().count())): self.req_group_box.layout().itemAt(i).widget().deleteLater() slug = data["productSlug"] if not slug: for mapping in data["offerMappings"]: if mapping["pageType"] == "productHome": slug = mapping["pageSlug"] break else: logger.error("Could not get page information") slug = "" if "/home" in slug: slug = slug.replace("/home", "") self.slug = slug if data["namespace"] in self.installed: self.open_store_button.setText(self.tr("Show Game on Epic Page")) self.owned_label.setVisible(True) else: self.open_store_button.setText(self.tr("Buy Game in Epic Games Store")) self.owned_label.setVisible(False) for i in range(self.req_group_box.layout().count()): self.req_group_box.layout().itemAt(i).widget().deleteLater() self.price.setText(self.tr("Loading")) self.wishlist_button.setVisible(False) # self.title.setText(self.tr("Loading")) self.image.setPixmap(QPixmap()) self.data = data is_bundle = False for i in data["categories"]: if "bundles" in i.get("path", ""): is_bundle = True # init API request if slug: self.api_core.get_game(slug, is_bundle, self.data_received) else: self.data_received({}) def add_to_wishlist(self): if not self.in_wishlist: return # self.api_core.add_to_wishlist(self.game.namespace, self.game.offer_id, # lambda success: self.wishlist_button.setText(self.tr("Remove from wishlist")) # if success else self.wishlist_button.setText("Something goes wrong")) else: self.api_core.remove_from_wishlist( self.game.namespace, self.game.offer_id, lambda success: self.wishlist_button.setVisible(False) if success else self.wishlist_button.setText("Something goes wrong"), ) def data_received(self, game): try: self.game = ShopGame.from_json(game, self.data) except Exception as e: logger.error(str(e)) self.price.setText("Error") self.req_group_box.setVisible(False) for img in self.data.get("keyImages"): if img["type"] in [ "DieselStoreFrontWide", "OfferImageTall", "VaultClosed", "ProductLogo", ]: self.image.update_image(img["url"], self.title_str, size=(240, 320)) self.image_stack.setCurrentIndex(0) break else: self.image_stack.setCurrentIndex(2) self.price.setText("") self.discount_price.setText("") self.social_link_gb.setVisible(False) self.tags.setText("") self.dev.setText(self.data.get("seller", {}).get("name", "")) return self.title.setText(self.game.title) self.price.setFont(QFont()) if self.game.price == "0" or self.game.price == 0: self.price.setText(self.tr("Free")) else: self.price.setText(self.game.price) if self.game.price != self.game.discount_price: font = QFont() font.setStrikeOut(True) self.price.setFont(font) self.discount_price.setText( self.game.discount_price if self.game.discount_price != "0" else self.tr("Free") ) self.discount_price.setVisible(True) else: self.discount_price.setVisible(False) bold_font = QFont() bold_font.setBold(True) if self.game.reqs: req_tabs = QTabWidget() for system in self.game.reqs: min_label = QLabel(self.tr("Minimum")) min_label.setFont(bold_font) rec_label = QLabel(self.tr("Recommend")) rec_label.setFont(bold_font) req_widget = QWidget() req_widget.setLayout(QGridLayout()) req_widget.layout().addWidget(min_label, 0, 1) req_widget.layout().addWidget(rec_label, 0, 2) for i, (key, value) in enumerate( self.game.reqs.get(system, {}).items() ): req_widget.layout().addWidget(QLabel(key), i + 1, 0) min_label = QLabel(value[0]) min_label.setWordWrap(True) req_widget.layout().addWidget(min_label, i + 1, 1) rec_label = QLabel(value[1]) rec_label.setWordWrap(True) req_widget.layout().addWidget(rec_label, i + 1, 2) req_tabs.addTab(req_widget, system) self.req_group_box.layout().addWidget(req_tabs) else: self.req_group_box.layout().addWidget( QLabel(self.tr("Could not get requirements")) ) self.req_group_box.setVisible(True) if self.game.image_urls.front_tall: img_url = self.game.image_urls.front_tall elif self.game.image_urls.offer_image_tall: img_url = self.game.image_urls.offer_image_tall elif self.game.image_urls.product_logo: img_url = self.game.image_urls.product_logo else: img_url = "" self.image.update_image(img_url, self.game.title, (240, 320)) self.image_stack.setCurrentIndex(0) try: if isinstance(self.game.developer, list): self.dev.setText(", ".join(self.game.developer)) else: self.dev.setText(self.game.developer) except KeyError: pass self.tags.setText(", ".join(self.game.tags)) # clear Layout for widget in ( self.social_link_gb.layout().itemAt(i) for i in range(self.social_link_gb.layout().count()) ): if not isinstance(widget, QSpacerItem): widget.widget().deleteLater() self.social_link_gb.deleteLater() self.social_link_gb = QGroupBox(self.tr("Social Links")) self.social_link_gb.setLayout(QHBoxLayout()) self.layout().insertWidget(3, self.social_link_gb) self.social_link_gb.layout().addStretch(1) link_count = 0 for name, url in self.game.links: if name.lower() == "homepage": icn = icon("mdi.web", "fa.search", scale_factor=1.5) else: try: icn = icon(f"mdi.{name.lower()}", f"fa.{name.lower()}", scale_factor=1.5) except Exception as e: logger.error(str(e)) continue button = SocialButton(icn, url) self.social_link_gb.layout().addWidget(button) link_count += 1 self.social_link_gb.layout().addStretch(1) if link_count == 0: self.social_link_gb.setVisible(False) else: self.social_link_gb.setVisible(True) self.social_link_gb.layout().addStretch(1) def add_wishlist_items(self, wishlist): wishlist = wishlist["data"]["Wishlist"]["wishlistItems"]["elements"] for game in wishlist: self.wishlist.append(game["offer"]["title"]) def button_clicked(self): QDesktopServices.openUrl(QUrl(f"https://www.epicgames.com/store/{self.core.language_code}/p/{self.slug}")) class SocialButton(QPushButton): def __init__(self, icn, url): super(SocialButton, self).__init__(icn, "") self.url = url self.clicked.connect(lambda: QDesktopServices.openUrl(QUrl(url))) self.setToolTip(url)