Add basic store
This commit is contained in:
parent
7b44b91b72
commit
b31080a5ae
14 changed files with 704 additions and 13 deletions
|
@ -144,3 +144,39 @@ class VerifyResult(Enum):
|
||||||
HASH_MISMATCH = 1
|
HASH_MISMATCH = 1
|
||||||
FILE_MISSING = 2
|
FILE_MISSING = 2
|
||||||
OTHER_ERROR = 3
|
OTHER_ERROR = 3
|
||||||
|
|
||||||
|
|
||||||
|
x = {'title': 'Frostpunk',
|
||||||
|
'id': 'b43c1e1e0ca14b6784b323c59c751136', 'namespace': 'd5241c76f178492ea1540fce45616757',
|
||||||
|
'description': 'Frostpunk', 'effectiveDate': '2099-01-01T00:00:00.000Z', 'offerType': 'OTHERS', 'expiryDate': None,
|
||||||
|
'status': 'ACTIVE', 'isCodeRedemptionOnly': True, 'keyImages': [{'type': 'VaultClosed',
|
||||||
|
'url': 'https://cdn1.epicgames.com/d5241c76f178492ea1540fce45616757/offer/EpicVault_Clean_OPEN_V10_LightsON-1920x1080-75e6d0636a6083944570a1c6f94ead4f.png'},
|
||||||
|
{'type': 'DieselStoreFrontWide',
|
||||||
|
'url': 'https://cdn1.epicgames.com/salesEvent/salesEvent/EGS_Frostpunk_wide_2560x1440-ef2f4d458120af0839dde35b1a022828'},
|
||||||
|
{'type': 'DieselStoreFrontTall',
|
||||||
|
'url': 'https://cdn1.epicgames.com/salesEvent/salesEvent/EGS_Frostpunk_Tall_1200x1600-c71dc27cfe505c6c662c49011b36a0c5'}],
|
||||||
|
'seller': {'id': 'o-ufmrk5furrrxgsp5tdngefzt5rxdcn', 'name': 'Epic Dev Test Account'}, 'productSlug': 'frostpunk',
|
||||||
|
'urlSlug': 'free-games-06', 'url': None,
|
||||||
|
'items': [{'id': '8341d7c7e4534db7848cc428aa4cbe5a', 'namespace': 'd5241c76f178492ea1540fce45616757'}],
|
||||||
|
'customAttributes': [{'key': 'com.epicgames.app.freegames.vault.close', 'value': '[]'},
|
||||||
|
{'key': 'com.epicgames.app.blacklist', 'value': '[]'},
|
||||||
|
{'key': 'com.epicgames.app.freegames.vault.slug',
|
||||||
|
'value': 'news/the-epic-mega-sale-returns-for-2021'},
|
||||||
|
{'key': 'publisherName', 'value': '11 bit studios'}, {'key': 'dupe', 'value': '[]'},
|
||||||
|
{'key': 'com.epicgames.app.freegames.vault.open', 'value': '[]'},
|
||||||
|
{'key': 'developerName', 'value': '11 bit studios'},
|
||||||
|
{'key': 'com.epicgames.app.productSlug', 'value': 'frostpunk'}],
|
||||||
|
'categories': [{'path': 'freegames/vaulted'}, {'path': 'freegames'}, {'path': 'games'}, {'path': 'applications'}],
|
||||||
|
'tags': [], 'price': {'totalPrice': {'discountPrice': 0, 'originalPrice': 0, 'voucherDiscount': 0, 'discount': 0,
|
||||||
|
'currencyCode': 'USD', 'currencyInfo': {'decimals': 2},
|
||||||
|
'fmtPrice': {'originalPrice': '0', 'discountPrice': '0',
|
||||||
|
'intermediatePrice': '0'}},
|
||||||
|
'lineOffers': [{'appliedRules': []}]}, 'promotions': {'promotionalOffers': [],
|
||||||
|
'upcomingPromotionalOffers': [{
|
||||||
|
'promotionalOffers': [
|
||||||
|
{
|
||||||
|
'startDate': '2021-06-03T15:00:00.000Z',
|
||||||
|
'endDate': '2021-06-10T15:00:00.000Z',
|
||||||
|
'discountSetting': {
|
||||||
|
'discountType': 'PERCENTAGE',
|
||||||
|
'discountPercentage': 0}}]}]}}
|
||||||
|
|
|
@ -13,6 +13,7 @@ from rare.components.tabs.cloud_saves import SyncSaves
|
||||||
from rare.components.tabs.downloads import DownloadTab
|
from rare.components.tabs.downloads import DownloadTab
|
||||||
from rare.components.tabs.games import GameTab
|
from rare.components.tabs.games import GameTab
|
||||||
from rare.components.tabs.settings import SettingsTab
|
from rare.components.tabs.settings import SettingsTab
|
||||||
|
from rare.components.tabs.shop import Shop
|
||||||
from rare.utils import legendary_utils
|
from rare.utils import legendary_utils
|
||||||
from rare.utils.models import InstallQueueItemModel, InstallOptionsModel
|
from rare.utils.models import InstallQueueItemModel, InstallOptionsModel
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ class TabWidget(QTabWidget):
|
||||||
|
|
||||||
def __init__(self, core: LegendaryCore, parent, offline):
|
def __init__(self, core: LegendaryCore, parent, offline):
|
||||||
super(TabWidget, self).__init__(parent=parent)
|
super(TabWidget, self).__init__(parent=parent)
|
||||||
disabled_tab = 3 if not offline else 1
|
disabled_tab = 4 if not offline else 1
|
||||||
self.core = core
|
self.core = core
|
||||||
self.setTabBar(TabBar(disabled_tab))
|
self.setTabBar(TabBar(disabled_tab))
|
||||||
|
|
||||||
|
@ -38,6 +39,9 @@ class TabWidget(QTabWidget):
|
||||||
self.cloud_saves = SyncSaves(core, self)
|
self.cloud_saves = SyncSaves(core, self)
|
||||||
self.addTab(self.cloud_saves, "Cloud Saves")
|
self.addTab(self.cloud_saves, "Cloud Saves")
|
||||||
|
|
||||||
|
self.store = Shop()
|
||||||
|
self.addTab(self.store, self.tr("Store"))
|
||||||
|
|
||||||
self.settings = SettingsTab(core, self)
|
self.settings = SettingsTab(core, self)
|
||||||
|
|
||||||
# Space Tab
|
# Space Tab
|
||||||
|
@ -92,9 +96,15 @@ class TabWidget(QTabWidget):
|
||||||
self.games_tab.default_widget.game_list.game_exited.connect(self.game_finished)
|
self.games_tab.default_widget.game_list.game_exited.connect(self.game_finished)
|
||||||
|
|
||||||
# Open game list on click on Games tab button
|
# Open game list on click on Games tab button
|
||||||
self.tabBarClicked.connect(lambda x: self.games_tab.layout.setCurrentIndex(0) if x == 0 else None)
|
self.tabBarClicked.connect(self.mouse_clicked)
|
||||||
self.setIconSize(QSize(25, 25))
|
self.setIconSize(QSize(25, 25))
|
||||||
|
|
||||||
|
def mouse_clicked(self, tab_num):
|
||||||
|
if tab_num == 0:
|
||||||
|
self.games_tab.layout.setCurrentIndex(0)
|
||||||
|
if tab_num == 3:
|
||||||
|
self.store.load()
|
||||||
|
|
||||||
def install_game(self, app_name, disable_path=False):
|
def install_game(self, app_name, disable_path=False):
|
||||||
install_dialog = InstallDialog(self.core,
|
install_dialog = InstallDialog(self.core,
|
||||||
InstallQueueItemModel(options=InstallOptionsModel(app_name=app_name)),
|
InstallQueueItemModel(options=InstallOptionsModel(app_name=app_name)),
|
||||||
|
|
|
@ -8,7 +8,6 @@ from qtawesome import icon
|
||||||
from custom_legendary.core import LegendaryCore
|
from custom_legendary.core import LegendaryCore
|
||||||
from custom_legendary.models.game import InstalledGame
|
from custom_legendary.models.game import InstalledGame
|
||||||
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
|
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
|
||||||
from rare.utils.extra_widgets import ClickableLabel
|
|
||||||
|
|
||||||
logger = getLogger("GameWidgetInstalled")
|
logger = getLogger("GameWidgetInstalled")
|
||||||
|
|
||||||
|
@ -36,7 +35,7 @@ class GameWidgetInstalled(BaseInstalledWidget):
|
||||||
if self.pixmap:
|
if self.pixmap:
|
||||||
w = 200
|
w = 200
|
||||||
self.pixmap = self.pixmap.scaled(w, int(w * 4 / 3), transformMode=Qt.SmoothTransformation)
|
self.pixmap = self.pixmap.scaled(w, int(w * 4 / 3), transformMode=Qt.SmoothTransformation)
|
||||||
self.image = ClickableLabel()
|
self.image = QLabel()
|
||||||
self.image.setObjectName("game_widget")
|
self.image.setObjectName("game_widget")
|
||||||
self.image.setPixmap(self.pixmap)
|
self.image.setPixmap(self.pixmap)
|
||||||
self.layout.addWidget(self.image)
|
self.layout.addWidget(self.image)
|
||||||
|
|
|
@ -5,7 +5,6 @@ from PyQt5.QtWidgets import QVBoxLayout, QLabel
|
||||||
from custom_legendary.core import LegendaryCore
|
from custom_legendary.core import LegendaryCore
|
||||||
from custom_legendary.models.game import Game
|
from custom_legendary.models.game import Game
|
||||||
from rare.components.tabs.games.game_widgets.base_uninstalled_widget import BaseUninstalledWidget
|
from rare.components.tabs.games.game_widgets.base_uninstalled_widget import BaseUninstalledWidget
|
||||||
from rare.utils.extra_widgets import ClickableLabel
|
|
||||||
|
|
||||||
logger = getLogger("Uninstalled")
|
logger = getLogger("Uninstalled")
|
||||||
|
|
||||||
|
@ -19,7 +18,7 @@ class IconWidgetUninstalled(BaseUninstalledWidget):
|
||||||
if self.pixmap:
|
if self.pixmap:
|
||||||
w = 200
|
w = 200
|
||||||
self.pixmap = self.pixmap.scaled(w, int(w * 4 / 3))
|
self.pixmap = self.pixmap.scaled(w, int(w * 4 / 3))
|
||||||
self.image = ClickableLabel()
|
self.image = QLabel()
|
||||||
self.image.setPixmap(self.pixmap)
|
self.image.setPixmap(self.pixmap)
|
||||||
self.layout.addWidget(self.image)
|
self.layout.addWidget(self.image)
|
||||||
|
|
||||||
|
|
28
rare/components/tabs/shop/__init__.py
Normal file
28
rare/components/tabs/shop/__init__.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
from PyQt5.QtWidgets import QStackedWidget, QWidget, QVBoxLayout, QLabel
|
||||||
|
|
||||||
|
from rare.components.tabs.shop.shop_info import ShopGameInfo
|
||||||
|
from rare.components.tabs.shop.shop_widget import ShopWidget
|
||||||
|
|
||||||
|
|
||||||
|
class Shop(QStackedWidget):
|
||||||
|
init = False
|
||||||
|
def __init__(self):
|
||||||
|
super(Shop, self).__init__()
|
||||||
|
|
||||||
|
self.shop = ShopWidget()
|
||||||
|
self.addWidget(self.shop)
|
||||||
|
|
||||||
|
self.info = ShopGameInfo()
|
||||||
|
self.addWidget(self.info)
|
||||||
|
|
||||||
|
self.shop.show_info.connect(self.show_info)
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
if not self.init:
|
||||||
|
self.init = True
|
||||||
|
self.shop.load()
|
||||||
|
|
||||||
|
|
||||||
|
def show_info(self, slug):
|
||||||
|
self.info.update_game(slug)
|
||||||
|
self.setCurrentIndex(1)
|
35
rare/components/tabs/shop/shop_info.py
Normal file
35
rare/components/tabs/shop/shop_info.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import os
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QLocale, Qt
|
||||||
|
from PyQt5.QtGui import QPixmap
|
||||||
|
from PyQt5.QtNetwork import QNetworkAccessManager
|
||||||
|
from PyQt5.QtWidgets import QWidget
|
||||||
|
|
||||||
|
from rare.ui.components.tabs.store.shop_game_info import Ui_shop_info
|
||||||
|
from rare.utils import api_utils
|
||||||
|
|
||||||
|
|
||||||
|
class ShopGameInfo(QWidget, Ui_shop_info):
|
||||||
|
slug = ""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(ShopGameInfo, self).__init__()
|
||||||
|
self.setupUi(self)
|
||||||
|
self.pushButton.clicked.connect(self.button_clicked)
|
||||||
|
self.manager = QNetworkAccessManager()
|
||||||
|
|
||||||
|
def update_game(self, slug: str):
|
||||||
|
locale = QLocale.system().name().split("_")[0]
|
||||||
|
game = api_utils.get_product(slug, locale)
|
||||||
|
self.slug = slug
|
||||||
|
self.title.setText(game[0]["productName"])
|
||||||
|
self.image.setPixmap(
|
||||||
|
QPixmap(os.path.expanduser(f"~/.cache/rare/cache/{game[0]['productName']}.png")).scaled(180,
|
||||||
|
int(180 * 9 / 16),
|
||||||
|
transformMode=Qt.SmoothTransformation))
|
||||||
|
|
||||||
|
self.dev.setText(game[0]["data"]["meta"]["developer"][0])
|
||||||
|
|
||||||
|
def button_clicked(self):
|
||||||
|
webbrowser.open("https://www.epicgames.com/store/de/p/" + self.slug)
|
209
rare/components/tabs/shop/shop_widget.py
Normal file
209
rare/components/tabs/shop/shop_widget.py
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from json import JSONDecodeError
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from PyQt5 import QtGui
|
||||||
|
from PyQt5.QtCore import Qt, pyqtSignal, QUrl, QByteArray, QJsonDocument, QJsonParseError, QObjectCleanupHandler, \
|
||||||
|
QStringListModel
|
||||||
|
from PyQt5.QtGui import QPixmap
|
||||||
|
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
||||||
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QCompleter
|
||||||
|
|
||||||
|
from rare.ui.components.tabs.store.store import Ui_ShopWidget
|
||||||
|
from rare.utils.extra_widgets import WaitingSpinner
|
||||||
|
from rare.utils.utils import get_lang
|
||||||
|
|
||||||
|
|
||||||
|
class ShopWidget(QWidget, Ui_ShopWidget):
|
||||||
|
show_info = pyqtSignal(str)
|
||||||
|
free_game_widgets = []
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(ShopWidget, self).__init__()
|
||||||
|
self.setupUi(self)
|
||||||
|
self.search_results.setVisible(False)
|
||||||
|
self.manager = QNetworkAccessManager()
|
||||||
|
self.free_games_stack.addWidget(WaitingSpinner())
|
||||||
|
self.free_games_stack.setCurrentIndex(1)
|
||||||
|
self.search.textChanged.connect(self.search_games)
|
||||||
|
self.completer = QCompleter()
|
||||||
|
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
|
||||||
|
self.search.setCompleter(self.completer)
|
||||||
|
self.search.returnPressed.connect(self.show_game)
|
||||||
|
self.data = []
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
if not os.path.exists(p := os.path.expanduser(f"~/.cache/rare/cache/")):
|
||||||
|
os.makedirs(p)
|
||||||
|
url = "https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions"
|
||||||
|
self.free_game_request = self.manager.get(QNetworkRequest(QUrl(url)))
|
||||||
|
self.free_game_request.readyRead.connect(self.add_free_games)
|
||||||
|
self.free_game_request.finished.connect(self.free_game_request.deleteLater if self.free_game_request else None)
|
||||||
|
|
||||||
|
# free_games = api_utils.get_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:
|
||||||
|
print(self.free_game_request.readAll().data().decode())
|
||||||
|
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
|
||||||
|
end_date = datetime.datetime.strptime(
|
||||||
|
game["promotions"].get("promotionalOffers", game["promotions"].get("upcomingPromotionalOffers"))[0]["promotionalOffers"][0]["endDate"],
|
||||||
|
'%Y-%m-%dT%H:%M:%S.%fZ')
|
||||||
|
start_date = datetime.datetime.strptime(
|
||||||
|
game["promotions"].get("promotionalOffers", game["promotions"].get("upcomingPromotionalOffers"))[0][
|
||||||
|
"promotionalOffers"][0]["startDate"],
|
||||||
|
'%Y-%m-%dT%H:%M:%S.%fZ')
|
||||||
|
except IndexError:
|
||||||
|
print("index error")
|
||||||
|
continue
|
||||||
|
except KeyError:
|
||||||
|
print("keyerror")
|
||||||
|
continue
|
||||||
|
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(free_game)
|
||||||
|
w.show_info.connect(self.show_info)
|
||||||
|
self.free_game_now.layout().addWidget(w)
|
||||||
|
self.free_game_widgets.append(w)
|
||||||
|
self.free_game_group_box_2.setMinimumHeight(200)
|
||||||
|
|
||||||
|
for free_game in coming_free_games:
|
||||||
|
w = GameWidget(free_game)
|
||||||
|
if free_game["title"] != "Mystery Game":
|
||||||
|
w.show_info.connect(self.show_info)
|
||||||
|
self.comming_free_game.layout().addWidget(w)
|
||||||
|
self.free_game_widgets.append(w)
|
||||||
|
self.free_games_stack.setCurrentIndex(0)
|
||||||
|
|
||||||
|
def search_games(self, text):
|
||||||
|
if text == "":
|
||||||
|
self.search_results.setVisible(False)
|
||||||
|
else:
|
||||||
|
locale = get_lang()
|
||||||
|
payload = QByteArray()
|
||||||
|
payload.append(
|
||||||
|
"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")
|
||||||
|
|
||||||
|
payload = json.dumps({
|
||||||
|
"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",
|
||||||
|
"variables": {"category": "games/edition/base|bundles/games|editors|software/edition/base", "count": 10,
|
||||||
|
"country": "DE", "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 = 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(
|
||||||
|
self.search_request.deleteLater if self.search_request else None)
|
||||||
|
|
||||||
|
def show_search_results(self):
|
||||||
|
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"]
|
||||||
|
else:
|
||||||
|
logging.error(error.errorString())
|
||||||
|
self.search_results.setVisible(False)
|
||||||
|
return
|
||||||
|
#response = .decode(encoding="utf-8")
|
||||||
|
#print(response)
|
||||||
|
#results = json.loads(response)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
self.data = data
|
||||||
|
titles = [i.get("title") for i in data]
|
||||||
|
model = QStringListModel()
|
||||||
|
model.setStringList(titles)
|
||||||
|
self.completer.setModel(model)
|
||||||
|
self.completer.popup()
|
||||||
|
# self.search_results.setLayout(layout)
|
||||||
|
# self.search_results.setVisible(True)
|
||||||
|
|
||||||
|
def show_game(self):
|
||||||
|
if self.data:
|
||||||
|
slug = self.data[0].get("productSlug")
|
||||||
|
self.show_info.emit(slug)
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
||||||
|
show_info = pyqtSignal(str)
|
||||||
|
|
||||||
|
def __init__(self, json_info):
|
||||||
|
super(GameWidget, self).__init__()
|
||||||
|
self.layout = QVBoxLayout()
|
||||||
|
self.image = QLabel()
|
||||||
|
self.slug = json_info["productSlug"]
|
||||||
|
if not os.path.exists(path := os.path.expanduser(f"~/.cache/rare/cache/{json_info['title']}.png")):
|
||||||
|
for img in json_info["keyImages"]:
|
||||||
|
if json_info["title"] != "Mystery Game":
|
||||||
|
if img["type"] == "DieselStoreFrontWide":
|
||||||
|
with open(path, "wb") as img_file:
|
||||||
|
content = requests.get(img["url"]).content
|
||||||
|
img_file.write(content)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if img["type"] == "VaultClosed":
|
||||||
|
with open(path, "wb") as img_file:
|
||||||
|
content = requests.get(img["url"]).content
|
||||||
|
img_file.write(content)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("No image found")
|
||||||
|
width = 300
|
||||||
|
self.image.setPixmap(QPixmap(os.path.expanduser(f"~/.cache/rare/cache/{json_info['title']}.png"))
|
||||||
|
.scaled(width, int(width * 9 / 16), transformMode=Qt.SmoothTransformation))
|
||||||
|
self.layout.addWidget(self.image)
|
||||||
|
|
||||||
|
self.title = QLabel(json_info["title"])
|
||||||
|
self.layout.addWidget(self.title)
|
||||||
|
|
||||||
|
self.setLayout(self.layout)
|
||||||
|
|
||||||
|
def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
|
||||||
|
self.show_info.emit(self.slug)
|
61
rare/ui/components/tabs/store/shop_game_info.py
Normal file
61
rare/ui/components/tabs/store/shop_game_info.py
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'shop_game_info.ui'
|
||||||
|
#
|
||||||
|
# Created by: PyQt5 UI code generator 5.15.4
|
||||||
|
#
|
||||||
|
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||||
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
|
||||||
|
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
|
class Ui_shop_info(object):
|
||||||
|
def setupUi(self, shop_info):
|
||||||
|
shop_info.setObjectName("shop_info")
|
||||||
|
shop_info.resize(702, 468)
|
||||||
|
self.gridLayout = QtWidgets.QGridLayout(shop_info)
|
||||||
|
self.gridLayout.setObjectName("gridLayout")
|
||||||
|
self.pushButton = QtWidgets.QPushButton(shop_info)
|
||||||
|
self.pushButton.setObjectName("pushButton")
|
||||||
|
self.gridLayout.addWidget(self.pushButton, 3, 1, 1, 1)
|
||||||
|
self.price = QtWidgets.QLabel(shop_info)
|
||||||
|
self.price.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||||
|
self.price.setObjectName("price")
|
||||||
|
self.gridLayout.addWidget(self.price, 1, 1, 1, 1)
|
||||||
|
self.title = QtWidgets.QLabel(shop_info)
|
||||||
|
self.title.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||||
|
self.title.setObjectName("title")
|
||||||
|
self.gridLayout.addWidget(self.title, 0, 1, 1, 1)
|
||||||
|
self.image = QtWidgets.QLabel(shop_info)
|
||||||
|
self.image.setObjectName("image")
|
||||||
|
self.gridLayout.addWidget(self.image, 0, 0, 1, 1)
|
||||||
|
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||||
|
self.gridLayout.addItem(spacerItem, 4, 1, 1, 1)
|
||||||
|
self.dev = QtWidgets.QLabel(shop_info)
|
||||||
|
self.dev.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||||
|
self.dev.setObjectName("dev")
|
||||||
|
self.gridLayout.addWidget(self.dev, 2, 1, 1, 1)
|
||||||
|
|
||||||
|
self.retranslateUi(shop_info)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(shop_info)
|
||||||
|
|
||||||
|
def retranslateUi(self, shop_info):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
shop_info.setWindowTitle(_translate("shop_info", "Form"))
|
||||||
|
self.pushButton.setText(_translate("shop_info", "Buy Game in Epic Games Store"))
|
||||||
|
self.price.setText(_translate("shop_info", "TextLabel"))
|
||||||
|
self.title.setText(_translate("shop_info", "Error"))
|
||||||
|
self.image.setText(_translate("shop_info", "TextLabel"))
|
||||||
|
self.dev.setText(_translate("shop_info", "TextLabel"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
shop_info = QtWidgets.QWidget()
|
||||||
|
ui = Ui_shop_info()
|
||||||
|
ui.setupUi(shop_info)
|
||||||
|
shop_info.show()
|
||||||
|
sys.exit(app.exec_())
|
78
rare/ui/components/tabs/store/shop_game_info.ui
Normal file
78
rare/ui/components/tabs/store/shop_game_info.ui
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>shop_info</class>
|
||||||
|
<widget class="QWidget" name="shop_info">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>702</width>
|
||||||
|
<height>468</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Buy Game in Epic Games Store</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="price">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="title">
|
||||||
|
<property name="text">
|
||||||
|
<string>Error</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="image">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<spacer name="spacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="dev">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
80
rare/ui/components/tabs/store/store.py
Normal file
80
rare/ui/components/tabs/store/store.py
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'store.ui'
|
||||||
|
#
|
||||||
|
# Created by: PyQt5 UI code generator 5.15.4
|
||||||
|
#
|
||||||
|
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||||
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
|
||||||
|
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
|
class Ui_ShopWidget(object):
|
||||||
|
def setupUi(self, ShopWidget):
|
||||||
|
ShopWidget.setObjectName("ShopWidget")
|
||||||
|
ShopWidget.resize(697, 362)
|
||||||
|
self.verticalLayout = QtWidgets.QVBoxLayout(ShopWidget)
|
||||||
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
|
self.search = QtWidgets.QLineEdit(ShopWidget)
|
||||||
|
self.search.setObjectName("search")
|
||||||
|
self.verticalLayout.addWidget(self.search)
|
||||||
|
self.search_results = QtWidgets.QGroupBox(ShopWidget)
|
||||||
|
self.search_results.setFlat(False)
|
||||||
|
self.search_results.setObjectName("search_results")
|
||||||
|
self.verticalLayout.addWidget(self.search_results)
|
||||||
|
self.free_game_group_box_2 = QtWidgets.QGroupBox(ShopWidget)
|
||||||
|
self.free_game_group_box_2.setObjectName("free_game_group_box_2")
|
||||||
|
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.free_game_group_box_2)
|
||||||
|
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||||
|
self.free_games_stack = QtWidgets.QStackedWidget(self.free_game_group_box_2)
|
||||||
|
self.free_games_stack.setObjectName("free_games_stack")
|
||||||
|
self.free_games_page = QtWidgets.QWidget()
|
||||||
|
self.free_games_page.setObjectName("free_games_page")
|
||||||
|
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.free_games_page)
|
||||||
|
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||||
|
self.free_game_now = QtWidgets.QGroupBox(self.free_games_page)
|
||||||
|
self.free_game_now.setObjectName("free_game_now")
|
||||||
|
self.horizontalLayout = QtWidgets.QHBoxLayout(self.free_game_now)
|
||||||
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
|
self.horizontalLayout_3.addWidget(self.free_game_now)
|
||||||
|
self.comming_free_game = QtWidgets.QGroupBox(self.free_games_page)
|
||||||
|
self.comming_free_game.setObjectName("comming_free_game")
|
||||||
|
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.comming_free_game)
|
||||||
|
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||||
|
self.horizontalLayout_3.addWidget(self.comming_free_game)
|
||||||
|
self.free_games_stack.addWidget(self.free_games_page)
|
||||||
|
self.verticalLayout_2.addWidget(self.free_games_stack)
|
||||||
|
self.verticalLayout.addWidget(self.free_game_group_box_2)
|
||||||
|
self.games_groupbox_2 = QtWidgets.QGroupBox(ShopWidget)
|
||||||
|
self.games_groupbox_2.setObjectName("games_groupbox_2")
|
||||||
|
self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.games_groupbox_2)
|
||||||
|
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
|
||||||
|
self.verticalLayout.addWidget(self.games_groupbox_2)
|
||||||
|
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||||
|
self.verticalLayout.addItem(spacerItem)
|
||||||
|
|
||||||
|
self.retranslateUi(ShopWidget)
|
||||||
|
self.free_games_stack.setCurrentIndex(0)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(ShopWidget)
|
||||||
|
|
||||||
|
def retranslateUi(self, ShopWidget):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
ShopWidget.setWindowTitle(_translate("ShopWidget", "Form"))
|
||||||
|
self.search.setPlaceholderText(_translate("ShopWidget", "Search Games"))
|
||||||
|
self.search_results.setTitle(_translate("ShopWidget", "Search results"))
|
||||||
|
self.free_game_group_box_2.setTitle(_translate("ShopWidget", "Free Games"))
|
||||||
|
self.free_game_now.setTitle(_translate("ShopWidget", "Free Game"))
|
||||||
|
self.comming_free_game.setTitle(_translate("ShopWidget", "Comming Free Game"))
|
||||||
|
self.games_groupbox_2.setTitle(_translate("ShopWidget", "Other nice games"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
ShopWidget = QtWidgets.QWidget()
|
||||||
|
ui = Ui_ShopWidget()
|
||||||
|
ui.setupUi(ShopWidget)
|
||||||
|
ShopWidget.show()
|
||||||
|
sys.exit(app.exec_())
|
95
rare/ui/components/tabs/store/store.ui
Normal file
95
rare/ui/components/tabs/store/store.ui
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ShopWidget</class>
|
||||||
|
<widget class="QWidget" name="ShopWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>697</width>
|
||||||
|
<height>362</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="search">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Search Games</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="search_results">
|
||||||
|
<property name="title">
|
||||||
|
<string>Search results</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="free_game_group_box_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Free Games</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QStackedWidget" name="free_games_stack">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="free_games_page">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="free_game_now">
|
||||||
|
<property name="title">
|
||||||
|
<string>Free Game</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="comming_free_game">
|
||||||
|
<property name="title">
|
||||||
|
<string>Comming Free Game</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="games_groupbox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Other nice games</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_7"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="spacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -114,13 +114,6 @@ class FlowLayout(QLayout):
|
||||||
return parent.spacing()
|
return parent.spacing()
|
||||||
|
|
||||||
|
|
||||||
class ClickableLabel(QLabel):
|
|
||||||
clicked = pyqtSignal()
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(ClickableLabel, self).__init__()
|
|
||||||
|
|
||||||
|
|
||||||
class PathEdit(QWidget, Ui_PathEdit):
|
class PathEdit(QWidget, Ui_PathEdit):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
text: str = "",
|
text: str = "",
|
||||||
|
|
|
@ -34,3 +34,51 @@ class InstallQueueItemModel:
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return (self.status_q is not None) and (self.download is not None) and (self.options is not None)
|
return (self.status_q is not None) and (self.download is not None) and (self.options is not None)
|
||||||
|
|
||||||
|
|
||||||
|
class ShopGame:
|
||||||
|
# TODO: Copyrights etc
|
||||||
|
def __init__(self, title: str = "", image_urls: dict = None, social_links: dict = None,
|
||||||
|
langs: list = None, reqs: list = None, publisher: str = "", developer: str = ""):
|
||||||
|
self.title = title
|
||||||
|
self.image_urls = image_urls
|
||||||
|
self.links = []
|
||||||
|
if social_links:
|
||||||
|
for item in social_links:
|
||||||
|
if item.startswith("link"):
|
||||||
|
self.links.append(tuple((item.replace("link", ""), social_links[item])))
|
||||||
|
else:
|
||||||
|
self.links = []
|
||||||
|
self.languages = langs
|
||||||
|
self.reqs = reqs # {"Betriebssystem":win7, processor:i9 9900k, ram...}; Note: name from language
|
||||||
|
self.publisher = publisher
|
||||||
|
self.developer = developer
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, data: dict):
|
||||||
|
if isinstance(data, list):
|
||||||
|
for product in data:
|
||||||
|
if product["_title"] == "home":
|
||||||
|
data = product
|
||||||
|
break
|
||||||
|
tmp = cls()
|
||||||
|
tmp.title = data.get("productName", "undefined")
|
||||||
|
tmp.img_urls = {
|
||||||
|
"DieselImage": data["data"]["about"]["image"]["src"],
|
||||||
|
"banner": data["data"]["hero"]["backgroundImageUrl"]
|
||||||
|
}
|
||||||
|
links = data["data"]["socialLinks"]
|
||||||
|
tmp.links = []
|
||||||
|
for item in links:
|
||||||
|
if item.startswith("link"):
|
||||||
|
tmp.links.append(tuple((item.replace("link", ""), links[item])))
|
||||||
|
tmp.available_voice_langs = data["data"]["requirements"]["languages"]
|
||||||
|
tmp.reqs = {}
|
||||||
|
for system in data["data"]["requirements"]["systems"]:
|
||||||
|
tmp.reqs[system] = {}
|
||||||
|
for i in system:
|
||||||
|
tmp.reqs[i[system]["title"]] = tuple((i[system]["minimum"], i[system]["recommend"]))
|
||||||
|
|
||||||
|
tmp.publisher = data["data"]["meta"].get("publisher", "undefined")
|
||||||
|
tmp.developer = data["data"]["meta"].get("developer", "undefined")
|
||||||
|
return tmp
|
||||||
|
|
20
test.py
Normal file
20
test.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import sys
|
||||||
|
from PyQt5.QtCore import Qt, QStringListModel
|
||||||
|
from PyQt5.QtWidgets import QApplication, QCompleter, QLineEdit
|
||||||
|
|
||||||
|
def get_data(model):
|
||||||
|
model.setStringList(["completion", "data", "goes", "here"])
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
edit = QLineEdit()
|
||||||
|
completer = QCompleter()
|
||||||
|
edit.setCompleter(completer)
|
||||||
|
|
||||||
|
model = QStringListModel()
|
||||||
|
completer.setModel(model)
|
||||||
|
get_data(model)
|
||||||
|
|
||||||
|
edit.show()
|
||||||
|
sys.exit(app.exec_())
|
Loading…
Reference in a new issue