1
0
Fork 0
mirror of synced 2024-06-28 11:11:15 +12:00

Show search results: Not pretty: no images

This commit is contained in:
Dummerle 2021-06-09 00:00:00 +02:00
parent bcce9487cd
commit 89afebd9fd
5 changed files with 153 additions and 73 deletions

View file

@ -1,5 +1,6 @@
from PyQt5.QtWidgets import QStackedWidget from PyQt5.QtWidgets import QStackedWidget
from rare.components.tabs.shop.search_results import SearchResults
from rare.components.tabs.shop.shop_info import ShopGameInfo from rare.components.tabs.shop.shop_info import ShopGameInfo
from rare.components.tabs.shop.shop_widget import ShopWidget from rare.components.tabs.shop.shop_widget import ShopWidget
@ -13,17 +14,27 @@ class Shop(QStackedWidget):
self.shop = ShopWidget() self.shop = ShopWidget()
self.addWidget(self.shop) self.addWidget(self.shop)
self.search_results = SearchResults()
self.addWidget(self.search_results)
self.search_results.show_info.connect(self.show_game_info)
self.info = ShopGameInfo() self.info = ShopGameInfo()
self.addWidget(self.info) self.addWidget(self.info)
self.info.back_button.clicked.connect(lambda: self.setCurrentIndex(0)) self.info.back_button.clicked.connect(lambda: self.setCurrentIndex(0))
self.shop.show_info.connect(self.show_info) self.shop.show_info.connect(self.show_info)
self.shop.show_game.connect(self.show_game_info)
def load(self): def load(self):
if not self.init: if not self.init:
self.init = True self.init = True
self.shop.load() self.shop.load()
def show_info(self, slug): def show_game_info(self, data):
self.info.update_game(slug) self.info.update_game(data)
self.setCurrentIndex(2)
def show_info(self, data):
self.search_results.show_results(data)
self.setCurrentIndex(1) self.setCurrentIndex(1)

View file

@ -0,0 +1,49 @@
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QScrollArea
class SearchResults(QScrollArea):
show_info = pyqtSignal(dict)
def __init__(self):
super(SearchResults, self).__init__()
self.widget = QWidget()
self.layout = QVBoxLayout()
self.widget.setLayout(self.layout)
self.setWidget(self.widget)
def show_results(self, results: list):
QVBoxLayout().addWidget(self.widget)
self.widget = QWidget()
self.layout = QVBoxLayout()
for i in range(self.layout.count()):
self.layout.removeItem(i)
for res in results:
w = _SearchResultItem(res)
w.show_info.connect(self.show_info.emit)
self.layout.addWidget(w)
self.layout.addStretch(1)
self.widget.setLayout(self.layout)
self.setWidget(self.widget)
class _SearchResultItem(QWidget):
res: dict
show_info = pyqtSignal(dict)
def __init__(self, result: dict):
super(_SearchResultItem, self).__init__()
self.layout = QHBoxLayout()
self.res = result
self.title = QLabel(self.res["title"])
self.layout.addWidget(self.title)
original_price = result['price']['totalPrice']['fmtPrice']['originalPrice']
self.price = QLabel(f"{self.tr('Original price: ')}{original_price}")
self.layout.addWidget(self.price)
self.setLayout(self.layout)
def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
if a0.button() == 1:
self.show_info.emit(self.res)

View file

@ -1,20 +1,19 @@
import json import json
import logging import logging
import os
import webbrowser import webbrowser
import requests from PyQt5.QtCore import QLocale, QUrl, QJsonDocument, QJsonParseError
from PyQt5.QtCore import QLocale, QUrl, QJsonDocument, QJsonParseError, Qt
from PyQt5.QtGui import QPixmap from PyQt5.QtGui import QPixmap
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QWidget
from rare.utils import models
from rare.ui.components.tabs.store.shop_game_info import Ui_shop_info from rare.ui.components.tabs.store.shop_game_info import Ui_shop_info
from rare.utils import models
class ShopGameInfo(QWidget, Ui_shop_info): class ShopGameInfo(QWidget, Ui_shop_info):
slug = "" game: models.ShopGame
data: dict
# TODO GANZ VIEL # TODO GANZ VIEL
def __init__(self): def __init__(self):
@ -23,12 +22,18 @@ class ShopGameInfo(QWidget, Ui_shop_info):
self.open_store_button.clicked.connect(self.button_clicked) self.open_store_button.clicked.connect(self.button_clicked)
self.manager = QNetworkAccessManager() self.manager = QNetworkAccessManager()
def update_game(self, slug: str): def update_game(self, data: dict):
self.title.setText(self.tr("Loading")) slug = data["productSlug"]
self.price.setText(self.tr("Loading")) if "/home" in slug:
slug = slug.replace("/home", "")
self.slug = slug
self.title.setText(data["title"])
self.price.setText(data['price']['totalPrice']['fmtPrice']['originalPrice'])
self.dev.setText(self.tr("Loading")) self.dev.setText(self.tr("Loading"))
self.image.setPixmap(QPixmap()) self.image.setPixmap(QPixmap())
self.slug = slug self.data = data
# init API request
locale = QLocale.system().name().split("_")[0] locale = QLocale.system().name().split("_")[0]
url = f"https://store-content.ak.epicgames.com/api/{locale}/content/products/{slug}" url = f"https://store-content.ak.epicgames.com/api/{locale}/content/products/{slug}"
# game = api_utils.get_product(slug, locale) # game = api_utils.get_product(slug, locale)
@ -37,7 +42,7 @@ class ShopGameInfo(QWidget, Ui_shop_info):
# self.request.finished.connect(self.request.deleteLater if self.request else None) # self.request.finished.connect(self.request.deleteLater if self.request else None)
def data_received(self): def data_received(self):
logging.info(f"Data of game {self.slug} received") logging.info(f"Data of game {self.data['title']} received")
if self.request: if self.request:
if self.request.error() == QNetworkReply.NoError: if self.request.error() == QNetworkReply.NoError:
error = QJsonParseError() error = QJsonParseError()
@ -52,19 +57,23 @@ class ShopGameInfo(QWidget, Ui_shop_info):
return return
else: else:
return return
self.game = models.ShopGame.from_json(game) self.game = models.ShopGame.from_json(game, self.data)
# print(game) # print(game)
self.title.setText(self.game.title) self.title.setText(self.game.title)
"""
if not os.path.exists(path := os.path.expanduser(f"~/.cache/rare/cache/{self.game.title}.png")): if not os.path.exists(path := os.path.expanduser(f"~/.cache/rare/cache/{self.game.title}.png")):
url = game["pages"][0]["_images_"][0] url = game["pages"][0]["_images_"][0]
open(os.path.expanduser(path), "wb").write(requests.get(url).content) open(os.path.expanduser(path), "wb").write(requests.get(url).content)
width = 360 width = 360
self.image.setPixmap(QPixmap(path).scaled(width, int(width * 9 / 16), transformMode=Qt.SmoothTransformation)) self.image.setPixmap(QPixmap(path).scaled(width, int(width * 9 / 16), transformMode=Qt.SmoothTransformation))
"""
try: try:
self.dev.setText(",".join(self.game.developer)) self.dev.setText(",".join(self.game.developer))
except KeyError: except KeyError:
pass pass
# self.price.setText(self.game.price)
self.request.deleteLater() self.request.deleteLater()
def button_clicked(self): def button_clicked(self):

View file

@ -18,7 +18,8 @@ from rare.utils.utils import get_lang
class ShopWidget(QWidget, Ui_ShopWidget): class ShopWidget(QWidget, Ui_ShopWidget):
show_info = pyqtSignal(str) show_info = pyqtSignal(list)
show_game = pyqtSignal(dict)
free_game_widgets = [] free_game_widgets = []
def __init__(self): def __init__(self):
@ -32,12 +33,16 @@ class ShopWidget(QWidget, Ui_ShopWidget):
self.completer = QCompleter() self.completer = QCompleter()
self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCaseSensitivity(Qt.CaseInsensitive)
self.search.setCompleter(self.completer) self.search.setCompleter(self.completer)
self.search.returnPressed.connect(self.show_game) self.search.returnPressed.connect(self.show_search_result)
self.data = [] self.data = []
def load(self): def load(self):
if not os.path.exists(p := os.path.expanduser(f"~/.cache/rare/cache/")): if p := os.getenv("XDG_CACHE_HOME"):
os.makedirs(p) self.path = p
else:
self.path = os.path.expanduser("~/.cache/rare/cache/")
if not os.path.exists(self.path):
os.makedirs(self.path)
url = "https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions" url = "https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions"
self.free_game_request = self.manager.get(QNetworkRequest(QUrl(url))) self.free_game_request = self.manager.get(QNetworkRequest(QUrl(url)))
self.free_game_request.readyRead.connect(self.add_free_games) self.free_game_request.readyRead.connect(self.add_free_games)
@ -50,8 +55,8 @@ class ShopWidget(QWidget, Ui_ShopWidget):
if self.free_game_request.error() == QNetworkReply.NoError: if self.free_game_request.error() == QNetworkReply.NoError:
try: try:
free_games = json.loads(self.free_game_request.readAll().data().decode()) free_games = json.loads(self.free_game_request.readAll().data().decode())
print(free_games)
except JSONDecodeError: except JSONDecodeError:
print(self.free_game_request.readAll().data().decode())
return return
else: else:
return return
@ -68,7 +73,8 @@ class ShopWidget(QWidget, Ui_ShopWidget):
try: try:
# parse datetime # parse datetime
end_date = datetime.datetime.strptime( end_date = datetime.datetime.strptime(
game["promotions"].get("promotionalOffers", game["promotions"].get("upcomingPromotionalOffers"))[0]["promotionalOffers"][0]["endDate"], game["promotions"].get("promotionalOffers", game["promotions"].get("upcomingPromotionalOffers"))[0][
"promotionalOffers"][0]["endDate"],
'%Y-%m-%dT%H:%M:%S.%fZ') '%Y-%m-%dT%H:%M:%S.%fZ')
start_date = datetime.datetime.strptime( start_date = datetime.datetime.strptime(
game["promotions"].get("promotionalOffers", game["promotions"].get("upcomingPromotionalOffers"))[0][ game["promotions"].get("promotionalOffers", game["promotions"].get("upcomingPromotionalOffers"))[0][
@ -89,21 +95,21 @@ class ShopWidget(QWidget, Ui_ShopWidget):
coming_free_games.append(game) coming_free_games.append(game)
for free_game in free_games_now: for free_game in free_games_now:
w = GameWidget(free_game) w = GameWidget(free_game, self.path)
w.show_info.connect(self.show_info) w.show_info.connect(lambda x: self.search_games(x, True))
self.free_game_now.layout().addWidget(w) self.free_game_now.layout().addWidget(w)
self.free_game_widgets.append(w) self.free_game_widgets.append(w)
self.free_game_group_box_2.setMinimumHeight(200) self.free_game_group_box_2.setMinimumHeight(200)
for free_game in coming_free_games: for free_game in coming_free_games:
w = GameWidget(free_game) w = GameWidget(free_game, self.path)
if free_game["title"] != "Mystery Game": if free_game["title"] != "Mystery Game":
w.show_info.connect(self.show_info) w.show_info.connect(self.show_info)
self.comming_free_game.layout().addWidget(w) self.comming_free_game.layout().addWidget(w)
self.free_game_widgets.append(w) self.free_game_widgets.append(w)
self.free_games_stack.setCurrentIndex(0) self.free_games_stack.setCurrentIndex(0)
def search_games(self, text): def search_games(self, text, show_direct=False):
if text == "": if text == "":
self.search_results.setVisible(False) self.search_results.setVisible(False)
else: else:
@ -123,11 +129,9 @@ class ShopWidget(QWidget, Ui_ShopWidget):
request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json")
self.search_request = self.manager.post(request, payload) self.search_request = self.manager.post(request, payload)
# self.search_request = self.manager.post(QNetworkRequest(QUrl("https://www.epicgames.com/graphql")), payload) # self.search_request = self.manager.post(QNetworkRequest(QUrl("https://www.epicgames.com/graphql")), payload)
self.search_request.readyRead.connect(self.show_search_results) self.search_request.finished.connect(lambda: self.show_search_results(show_direct))
self.search_request.finished.connect(
self.search_request.deleteLater if self.search_request else None)
def show_search_results(self): def show_search_results(self, show_direct=False):
if self.search_request: if self.search_request:
if self.search_request.error() == QNetworkReply.NoError: if self.search_request.error() == QNetworkReply.NoError:
error = QJsonParseError() error = QJsonParseError()
@ -138,72 +142,68 @@ class ShopWidget(QWidget, Ui_ShopWidget):
logging.error(error.errorString()) logging.error(error.errorString())
self.search_results.setVisible(False) self.search_results.setVisible(False)
return return
#response = .decode(encoding="utf-8") # response = .decode(encoding="utf-8")
#print(response) # print(response)
#results = json.loads(response) # results = json.loads(response)
else: else:
return return
else: else:
return return
self.data = data self.data = data
if show_direct:
self.show_search_result(True)
return
titles = [i.get("title") for i in data] titles = [i.get("title") for i in data]
model = QStringListModel() model = QStringListModel()
model.setStringList(titles) model.setStringList(titles)
self.completer.setModel(model) self.completer.setModel(model)
self.completer.popup() # self.completer.popup()
# self.search_results.setLayout(layout) # self.search_results.setLayout(layout)
# self.search_results.setVisible(True) # self.search_results.setVisible(True)
if self.search_request:
self.search_request.deleteLater()
def show_game(self): def show_search_result(self, show_direct=False):
if self.data: if not show_direct:
slug = self.data[0].get("productSlug") if self.data:
self.show_info.emit(slug) self.show_info.emit(self.data)
else:
self.show_game.emit(self.data[0])
class SearchResultItem(QWidget):
def __init__(self, json_info):
super(SearchResultItem, self).__init__()
self.layout = QHBoxLayout()
self.title = QLabel(json_info.get("title", "undefined"))
self.layout.addWidget(self.title)
self.slug = json_info.get("productSlug", "undefined")
self.setLayout(self.layout)
class GameWidget(QWidget): class GameWidget(QWidget):
show_info = pyqtSignal(str) show_info = pyqtSignal(str)
def __init__(self, json_info): def __init__(self, json_info, path: str):
super(GameWidget, self).__init__() super(GameWidget, self).__init__()
self.layout = QVBoxLayout() self.layout = QVBoxLayout()
self.image = QLabel() self.image = QLabel()
self.slug = json_info["productSlug"] self.slug = json_info["productSlug"]
if not os.path.exists(path := os.path.expanduser(f"~/.cache/rare/cache/{json_info['title']}.png")): self.title = json_info["title"]
if not os.path.exists(p := os.path.join(path, f"{json_info['title']}.png")):
for img in json_info["keyImages"]: for img in json_info["keyImages"]:
if json_info["title"] != "Mystery Game": if json_info["title"] != "Mystery Game":
if img["type"] == "DieselStoreFrontWide": if img["type"] == "DieselStoreFrontWide":
with open(path, "wb") as img_file: with open(p, "wb") as img_file:
content = requests.get(img["url"]).content content = requests.get(img["url"]).content
img_file.write(content) img_file.write(content)
break break
else: else:
if img["type"] == "VaultClosed": if img["type"] == "VaultClosed":
with open(path, "wb") as img_file: with open(p, "wb") as img_file:
content = requests.get(img["url"]).content content = requests.get(img["url"]).content
img_file.write(content) img_file.write(content)
break break
else: else:
print("No image found") print("No image found")
width = 300 width = 300
self.image.setPixmap(QPixmap(os.path.expanduser(f"~/.cache/rare/cache/{json_info['title']}.png")) self.image.setPixmap(QPixmap(os.path.join(path, f"{json_info['title']}.png"))
.scaled(width, int(width * 9 / 16), transformMode=Qt.SmoothTransformation)) .scaled(width, int(width * 9 / 16), transformMode=Qt.SmoothTransformation))
self.layout.addWidget(self.image) self.layout.addWidget(self.image)
self.title = QLabel(json_info["title"]) self.title_label = QLabel(json_info["title"])
self.layout.addWidget(self.title) self.layout.addWidget(self.title_label)
self.setLayout(self.layout) self.setLayout(self.layout)
def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None: def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
self.show_info.emit(self.slug) self.show_info.emit(self.title)

View file

@ -39,7 +39,8 @@ class InstallQueueItemModel:
class ShopGame: class ShopGame:
# TODO: Copyrights etc # TODO: Copyrights etc
def __init__(self, title: str = "", image_urls: dict = None, social_links: dict = None, def __init__(self, title: str = "", image_urls: dict = None, social_links: dict = None,
langs: list = None, reqs: list = None, publisher: str = "", developer: str = ""): langs: list = None, reqs: list = None, publisher: str = "", developer: str = "",
price: str = ""):
self.title = title self.title = title
self.image_urls = image_urls self.image_urls = image_urls
self.links = [] self.links = []
@ -53,32 +54,42 @@ class ShopGame:
self.reqs = reqs # {"Betriebssystem":win7, processor:i9 9900k, ram...}; Note: name from language self.reqs = reqs # {"Betriebssystem":win7, processor:i9 9900k, ram...}; Note: name from language
self.publisher = publisher self.publisher = publisher
self.developer = developer self.developer = developer
self.price = price
@classmethod @classmethod
def from_json(cls, data: dict): def from_json(cls, api_data: dict, search_data: dict):
if isinstance(data, list): print(api_data)
for product in data: if isinstance(api_data, list):
for product in api_data:
if product["_title"] == "home": if product["_title"] == "home":
data = product api_data = product
print("home")
break break
tmp = cls() tmp = cls()
tmp.title = data.get("productName", "undefined") tmp.title = api_data.get("productName", "undefined")
tmp.img_urls = { """tmp.img_urls = {
"DieselImage": data["pages"][0]["data"]["about"]["image"]["src"], "DieselImage": data["pages"][0]["data"]["about"]["image"]["src"],
"banner": data["pages"][0]["data"]["hero"]["backgroundImageUrl"] "banner": data["pages"][0]["data"]["hero"]["backgroundImageUrl"]
} }"""
links = data["pages"][0]["data"]["socialLinks"] links = api_data["pages"][0]["data"]["socialLinks"]
tmp.links = [] tmp.links = []
for item in links: for item in links:
if item.startswith("link"): if item.startswith("link"):
tmp.links.append(tuple((item.replace("link", ""), links[item]))) tmp.links.append(tuple((item.replace("link", ""), links[item])))
tmp.available_voice_langs = data["pages"][0]["data"]["requirements"]["languages"] tmp.available_voice_langs = api_data["pages"][0]["data"]["requirements"]["languages"]
tmp.reqs = [] tmp.reqs = []
"""for system in data["pages"][0]["data"]["requirements"]["systems"]: for i, system in enumerate(api_data["pages"][0]["data"]["requirements"]["systems"]):
tmp.reqs.append({"name": system, "value": []}) tmp.reqs.append({"name": system["systemType"], "value": []})
for i in system: for req in system["details"]:
tmp.reqs[system].append(tuple((i[system]["minimum"], i[system]["recommend"]))) tmp.reqs[i]["value"].append(tuple((req["minimum"], req["recommended"])))
"""
tmp.publisher = data["pages"][0]["data"]["meta"].get("publisher", "undefined") tmp.publisher = api_data["pages"][0]["data"]["meta"].get("publisher", "undefined")
tmp.developer = data["pages"][0]["data"]["meta"].get("developer", "undefined") tmp.developer = api_data["pages"][0]["data"]["meta"].get("developer", "undefined")
tmp.price = {
"normal": search_data["price"]["totalPrice"]["originalPrice"]
}
if price := search_data["price"]["totalPrice"].get("discountPrice"):
tmp.price["discount"] = price
return tmp return tmp