WIP
This commit is contained in:
parent
2a2458bacb
commit
9ec349e2d1
|
@ -28,21 +28,15 @@ class StoreTab(SideTabWidget):
|
|||
self.landing = LandingPage(self.api, parent=self)
|
||||
self.landing_index = self.addTab(self.landing, self.tr("Store"))
|
||||
|
||||
self.search = SearchPage(self.core, self.api, parent=self)
|
||||
self.search = SearchPage(self.api, parent=self)
|
||||
self.search_index = self.addTab(self.search, self.tr("Search"))
|
||||
|
||||
self.wishlist = WishlistPage(self.api, parent=self)
|
||||
self.wishlist_index = self.addTab(self.wishlist, self.tr("Wishlist"))
|
||||
|
||||
self.api.update_wishlist.connect(self.update_wishlist)
|
||||
|
||||
self.previous_index = self.landing_index
|
||||
|
||||
def showEvent(self, a0: QShowEvent) -> None:
|
||||
if a0.spontaneous() or self.init:
|
||||
return super().showEvent(a0)
|
||||
# self.landing.load()
|
||||
# self.wishlist.update_wishlist()
|
||||
self.init = True
|
||||
return super().showEvent(a0)
|
||||
|
||||
|
@ -51,6 +45,3 @@ class StoreTab(SideTabWidget):
|
|||
return super().hideEvent(a0)
|
||||
# TODO: Implement store unloading
|
||||
return super().hideEvent(a0)
|
||||
|
||||
def update_wishlist(self):
|
||||
self.landing.update_wishlist()
|
||||
|
|
|
@ -25,14 +25,14 @@ type DiscountSetting {
|
|||
discountType: String
|
||||
}
|
||||
|
||||
type AppliedRuled {
|
||||
type AppliedRules {
|
||||
id: ID
|
||||
endDate: Date
|
||||
discountSetting: DiscountSetting
|
||||
}
|
||||
|
||||
type LineOfferRes {
|
||||
appliedRules: [AppliedRuled]
|
||||
appliedRules: [AppliedRules]
|
||||
}
|
||||
|
||||
type GetPriceRes {
|
||||
|
|
|
@ -33,7 +33,7 @@ class DieselSystemDetailItem:
|
|||
class DieselSystemDetail:
|
||||
p_type: Optional[str] = None
|
||||
details: Optional[List[DieselSystemDetailItem]] = None
|
||||
system_type: Optional[str] = None
|
||||
systemType: Optional[str] = None
|
||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@classmethod
|
||||
|
@ -47,7 +47,7 @@ class DieselSystemDetail:
|
|||
tmp = cls(
|
||||
p_type=d.pop("_type", ""),
|
||||
details=details,
|
||||
system_type=d.pop("systemType", ""),
|
||||
systemType=d.pop("systemType", ""),
|
||||
)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
@ -107,7 +107,7 @@ class DieselProductDetail:
|
|||
p_type: Optional[str] = None
|
||||
about: Optional[DieselProductAbout] = None
|
||||
requirements: Optional[DieselSystemDetails] = None
|
||||
social_links: Optional[DieselSocialLinks] = None
|
||||
socialLinks: Optional[DieselSocialLinks] = None
|
||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@classmethod
|
||||
|
@ -119,7 +119,7 @@ class DieselProductDetail:
|
|||
p_type=d.pop("_type", ""),
|
||||
about=about,
|
||||
requirements=requirements,
|
||||
social_links=d.pop("socialLinks", {}),
|
||||
socialLinks=d.pop("socialLinks", {}),
|
||||
)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
@ -136,7 +136,7 @@ class DieselProduct:
|
|||
namespace: Optional[str] = None
|
||||
pages: Optional[List["DieselProduct"]] = None
|
||||
data: Optional[DieselProductDetail] = None
|
||||
product_name: Optional[str] = None
|
||||
productName: Optional[str] = None
|
||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@classmethod
|
||||
|
@ -158,7 +158,7 @@ class DieselProduct:
|
|||
namespace=d.pop("namespace", ""),
|
||||
pages=pages,
|
||||
data=data,
|
||||
product_name=d.pop("productName", ""),
|
||||
productName=d.pop("productName", ""),
|
||||
)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import logging
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import List, Dict, Any, Type, Optional
|
||||
from typing import List, Dict, Any, Type, Optional, Tuple
|
||||
|
||||
from .utils import parse_date
|
||||
|
||||
|
@ -17,7 +17,6 @@ ItemModel = Dict
|
|||
SellerModel = Dict
|
||||
PageSandboxModel = Dict
|
||||
TagModel = Dict
|
||||
PromotionsModel = Dict
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -39,16 +38,15 @@ class ImageUrlModel:
|
|||
d = src.copy()
|
||||
type = d.pop("type", None)
|
||||
url = d.pop("url", None)
|
||||
tmp = cls(
|
||||
type=type,
|
||||
url=url,
|
||||
)
|
||||
tmp = cls(type=type, url=url)
|
||||
return tmp
|
||||
|
||||
|
||||
@dataclass
|
||||
class KeyImagesModel:
|
||||
key_images: Optional[List[ImageUrlModel]] = None
|
||||
tall_types = ("DieselStoreFrontTall", "OfferImageTall", "Thumbnail", "ProductLogo", "DieselGameBoxLogo")
|
||||
wide_types = ("DieselStoreFrontWide", "OfferImageWide", "VaultClosed", "ProductLogo")
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self.key_images[item]
|
||||
|
@ -76,21 +74,13 @@ class KeyImagesModel:
|
|||
return tmp
|
||||
|
||||
def available_tall(self) -> List[ImageUrlModel]:
|
||||
tall_types = [
|
||||
"DieselStoreFrontTall",
|
||||
"OfferImageTall",
|
||||
"Thumbnail",
|
||||
"ProductLogo",
|
||||
"DieselGameBoxLogo",
|
||||
]
|
||||
tall_images = filter(lambda img: img.type in tall_types, self.key_images)
|
||||
tall_images = sorted(tall_images, key=lambda x: tall_types.index(x.type))
|
||||
tall_images = filter(lambda img: img.type in KeyImagesModel.tall_types, self.key_images)
|
||||
tall_images = sorted(tall_images, key=lambda x: KeyImagesModel.tall_types.index(x.type))
|
||||
return tall_images
|
||||
|
||||
def available_wide(self) -> List[ImageUrlModel]:
|
||||
wide_types = ["DieselStoreFrontWide", "OfferImageWide", "VaultClosed", "ProductLogo"]
|
||||
wide_images = filter(lambda img: img.type in wide_types, self.key_images)
|
||||
wide_images = sorted(wide_images, key=lambda x: wide_types.index(x.type))
|
||||
wide_images = filter(lambda img: img.type in KeyImagesModel.wide_types, self.key_images)
|
||||
wide_images = sorted(wide_images, key=lambda x: KeyImagesModel.wide_types.index(x.type))
|
||||
return wide_images
|
||||
|
||||
def for_dimensions(self, w: int, h: int) -> ImageUrlModel:
|
||||
|
@ -107,55 +97,133 @@ class KeyImagesModel:
|
|||
return model
|
||||
|
||||
|
||||
TotalPriceModel = Dict
|
||||
FmtPriceModel = Dict
|
||||
CurrencyModel = Dict
|
||||
FormattedPriceModel = Dict
|
||||
LineOffersModel = Dict
|
||||
|
||||
|
||||
@dataclass
|
||||
class GetPriceResModel:
|
||||
total_price: Optional[TotalPriceModel] = None
|
||||
fmt_price: Optional[FmtPriceModel] = None
|
||||
line_offers: Optional[LineOffersModel] = None
|
||||
class TotalPriceModel:
|
||||
discountPrice: Optional[int] = None
|
||||
originalPrice: Optional[int] = None
|
||||
voucherDiscount: Optional[int] = None
|
||||
discount: Optional[int] = None
|
||||
currencyCode: Optional[str] = None
|
||||
currencyInfo: Optional[CurrencyModel] = None
|
||||
fmtPrice: Optional[FormattedPriceModel] = None
|
||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls: Type["GetPriceResModel"], src: Dict[str, Any]) -> "GetPriceResModel":
|
||||
def from_dict(cls: Type["TotalPriceModel"], src: Dict[str, Any]) -> "TotalPriceModel":
|
||||
d = src.copy()
|
||||
tmp = cls(
|
||||
total_price=d.pop("totalPrice", {}),
|
||||
fmt_price=d.pop("fmtPrice", {}),
|
||||
line_offers=d.pop("lineOffers", {}),
|
||||
discountPrice=d.pop("discountPrice", None),
|
||||
originalPrice=d.pop("originalPrice", None),
|
||||
voucherDiscount=d.pop("voucherDiscount", None),
|
||||
discount=d.pop("discount", None),
|
||||
currencyCode=d.pop("currencyCode", None),
|
||||
currencyInfo=d.pop("currrencyInfo", {}),
|
||||
fmtPrice=d.pop("fmtPrice", {}),
|
||||
)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
||||
@dataclass
|
||||
class GetPriceResModel:
|
||||
totalPrice: Optional[TotalPriceModel] = None
|
||||
lineOffers: Optional[LineOffersModel] = None
|
||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls: Type["GetPriceResModel"], src: Dict[str, Any]) -> "GetPriceResModel":
|
||||
d = src.copy()
|
||||
total_price = TotalPriceModel.from_dict(x) if (x := d.pop("totalPrice", {})) else None
|
||||
tmp = cls(totalPrice=total_price, lineOffers=d.pop("lineOffers", {}))
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
||||
DiscountSettingModel = Dict
|
||||
|
||||
|
||||
@dataclass
|
||||
class PromotionalOfferModel:
|
||||
startDate: Optional[datetime] = None
|
||||
endDate: Optional[datetime] = None
|
||||
discountSetting: Optional[DiscountSettingModel] = None
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls: Type["PromotionalOfferModel"], src: Dict[str, Any]) -> "PromotionalOfferModel":
|
||||
d = src.copy()
|
||||
start_date = parse_date(x) if (x := d.pop("startDate", "")) else None
|
||||
end_date = parse_date(x) if (x := d.pop("endDate", "")) else None
|
||||
tmp = cls(startDate=start_date, endDate=end_date, discountSetting=d.pop("discountSetting", {}))
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
||||
@dataclass
|
||||
class PromotionalOffersModel:
|
||||
promotionalOffers: Optional[Tuple[PromotionalOfferModel]] = None
|
||||
|
||||
@classmethod
|
||||
def from_list(cls: Type["PromotionalOffersModel"], src: Dict[str, List]) -> "PromotionalOffersModel":
|
||||
d = src.copy()
|
||||
promotional_offers = (
|
||||
tuple([PromotionalOfferModel.from_dict(y) for y in x]) if (x := d.pop("promotionalOffers", [])) else None
|
||||
)
|
||||
tmp = cls(promotionalOffers=promotional_offers)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
||||
@dataclass
|
||||
class PromotionsModel:
|
||||
promotionalOffers: Optional[Tuple[PromotionalOffersModel]] = None
|
||||
upcomingPromotionalOffers: Optional[Tuple[PromotionalOffersModel]] = None
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls: Type["PromotionsModel"], src: Dict[str, Any]) -> "PromotionsModel":
|
||||
d = src.copy()
|
||||
promotional_offers = (
|
||||
tuple([PromotionalOffersModel.from_list(y) for y in x]) if (x := d.pop("promotionalOffers", [])) else None
|
||||
)
|
||||
upcoming_promotional_offers = (
|
||||
tuple([PromotionalOffersModel.from_list(y) for y in x])
|
||||
if (x := d.pop("upcomingPromotionalOffers", []))
|
||||
else None
|
||||
)
|
||||
tmp = cls(promotionalOffers=promotional_offers, upcomingPromotionalOffers=upcoming_promotional_offers)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
||||
@dataclass
|
||||
class CatalogOfferModel:
|
||||
catalog_ns: Optional[CatalogNamespaceModel] = None
|
||||
catalogNs: Optional[CatalogNamespaceModel] = None
|
||||
categories: Optional[List[CategoryModel]] = None
|
||||
custom_attributes: Optional[List[CustomAttributeModel]] = None
|
||||
customAttributes: Optional[List[CustomAttributeModel]] = None
|
||||
description: Optional[str] = None
|
||||
effective_date: Optional[datetime] = None
|
||||
expiry_date: Optional[datetime] = None
|
||||
effectiveDate: Optional[datetime] = None
|
||||
expiryDate: Optional[datetime] = None
|
||||
id: Optional[str] = None
|
||||
is_code_redemption_only: Optional[bool] = None
|
||||
isCodeRedemptionOnly: Optional[bool] = None
|
||||
items: Optional[List[ItemModel]] = None
|
||||
key_images: Optional[KeyImagesModel] = None
|
||||
keyImages: Optional[KeyImagesModel] = None
|
||||
namespace: Optional[str] = None
|
||||
offer_mappings: Optional[List[PageSandboxModel]] = None
|
||||
offer_type: Optional[str] = None
|
||||
offerMappings: Optional[List[PageSandboxModel]] = None
|
||||
offerType: Optional[str] = None
|
||||
price: Optional[GetPriceResModel] = None
|
||||
product_slug: Optional[str] = None
|
||||
productSlug: Optional[str] = None
|
||||
promotions: Optional[PromotionsModel] = None
|
||||
seller: Optional[SellerModel] = None
|
||||
status: Optional[str] = None
|
||||
tags: Optional[List[TagModel]] = None
|
||||
title: Optional[str] = None
|
||||
url: Optional[str] = None
|
||||
url_slug: Optional[str] = None
|
||||
viewable_date: Optional[datetime] = None
|
||||
urlSlug: Optional[str] = None
|
||||
viewableDate: Optional[datetime] = None
|
||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@classmethod
|
||||
|
@ -165,31 +233,32 @@ class CatalogOfferModel:
|
|||
expiry_date = parse_date(x) if (x := d.pop("expiryDate", "")) else None
|
||||
key_images = KeyImagesModel.from_list(d.pop("keyImages", []))
|
||||
price = GetPriceResModel.from_dict(x) if (x := d.pop("price", {})) else None
|
||||
promotions = PromotionsModel.from_dict(x) if (x := d.pop("promotions", {})) else None
|
||||
viewable_date = parse_date(x) if (x := d.pop("viewableDate", "")) else None
|
||||
tmp = cls(
|
||||
catalog_ns=d.pop("catalogNs", {}),
|
||||
catalogNs=d.pop("catalogNs", {}),
|
||||
categories=d.pop("categories", []),
|
||||
custom_attributes=d.pop("customAttributes", []),
|
||||
customAttributes=d.pop("customAttributes", []),
|
||||
description=d.pop("description", ""),
|
||||
effective_date=effective_date,
|
||||
expiry_date=expiry_date,
|
||||
effectiveDate=effective_date,
|
||||
expiryDate=expiry_date,
|
||||
id=d.pop("id", ""),
|
||||
is_code_redemption_only=d.pop("isCodeRedemptionOnly", None),
|
||||
isCodeRedemptionOnly=d.pop("isCodeRedemptionOnly", None),
|
||||
items=d.pop("items", []),
|
||||
key_images=key_images,
|
||||
keyImages=key_images,
|
||||
namespace=d.pop("namespace", ""),
|
||||
offer_mappings=d.pop("offerMappings", []),
|
||||
offer_type=d.pop("offerType", ""),
|
||||
offerMappings=d.pop("offerMappings", []),
|
||||
offerType=d.pop("offerType", ""),
|
||||
price=price,
|
||||
product_slug=d.pop("productSlug", ""),
|
||||
promotions=d.pop("promotions", {}),
|
||||
productSlug=d.pop("productSlug", ""),
|
||||
promotions=promotions,
|
||||
seller=d.pop("seller", {}),
|
||||
status=d.pop("status", ""),
|
||||
tags=d.pop("tags", []),
|
||||
title=d.pop("title", ""),
|
||||
url=d.pop("url", ""),
|
||||
url_slug=d.pop("urlSlug", ""),
|
||||
viewable_date=viewable_date,
|
||||
urlSlug=d.pop("urlSlug", ""),
|
||||
viewableDate=viewable_date,
|
||||
)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
@ -200,8 +269,8 @@ class WishlistItemModel:
|
|||
created: Optional[datetime] = None
|
||||
id: Optional[str] = None
|
||||
namespace: Optional[str] = None
|
||||
is_first_time: Optional[bool] = None
|
||||
offer_id: Optional[str] = None
|
||||
isFirstTime: Optional[bool] = None
|
||||
offerId: Optional[str] = None
|
||||
order: Optional[Any] = None
|
||||
updated: Optional[datetime] = None
|
||||
offer: Optional[CatalogOfferModel] = None
|
||||
|
@ -217,8 +286,8 @@ class WishlistItemModel:
|
|||
created=created,
|
||||
id=d.pop("id", ""),
|
||||
namespace=d.pop("namespace", ""),
|
||||
is_first_time=d.pop("isFirstTime", None),
|
||||
offer_id=d.pop("offerId", ""),
|
||||
isFirstTime=d.pop("isFirstTime", None),
|
||||
offerId=d.pop("offerId", ""),
|
||||
order=d.pop("order", ""),
|
||||
updated=updated,
|
||||
offer=offer,
|
||||
|
@ -238,10 +307,7 @@ class PagingModel:
|
|||
d = src.copy()
|
||||
count = d.pop("count", None)
|
||||
total = d.pop("total", None)
|
||||
tmp = cls(
|
||||
count=count,
|
||||
total=total,
|
||||
)
|
||||
tmp = cls(count=count, total=total)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
@ -261,26 +327,21 @@ class SearchStoreModel:
|
|||
elem = CatalogOfferModel.from_dict(item)
|
||||
elements.append(elem)
|
||||
paging = PagingModel.from_dict(x) if (x := d.pop("paging", {})) else None
|
||||
tmp = cls(
|
||||
elements=elements,
|
||||
paging=paging,
|
||||
)
|
||||
tmp = cls(elements=elements, paging=paging)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
||||
@dataclass
|
||||
class CatalogModel:
|
||||
search_store: Optional[SearchStoreModel] = None
|
||||
searchStore: Optional[SearchStoreModel] = None
|
||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls: Type["CatalogModel"], src: Dict[str, Any]) -> "CatalogModel":
|
||||
d = src.copy()
|
||||
search_store = SearchStoreModel.from_dict(x) if (x := d.pop("searchStore", {})) else None
|
||||
tmp = cls(
|
||||
search_store=search_store,
|
||||
)
|
||||
tmp = cls(searchStore=search_store)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
@ -300,10 +361,7 @@ class WishlistItemsModel:
|
|||
elem = WishlistItemModel.from_dict(item)
|
||||
elements.append(elem)
|
||||
paging = PagingModel.from_dict(x) if (x := d.pop("paging", {})) else None
|
||||
tmp = cls(
|
||||
elements=elements,
|
||||
paging=paging,
|
||||
)
|
||||
tmp = cls(elements=elements, paging=paging)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
@ -316,16 +374,14 @@ class RemoveFromWishlistModel:
|
|||
@classmethod
|
||||
def from_dict(cls: Type["RemoveFromWishlistModel"], src: Dict[str, Any]) -> "RemoveFromWishlistModel":
|
||||
d = src.copy()
|
||||
tmp = cls(
|
||||
success=d.pop("success", None),
|
||||
)
|
||||
tmp = cls(success=d.pop("success", None))
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
||||
@dataclass
|
||||
class AddToWishlistModel:
|
||||
wishlist_item: Optional[WishlistItemModel] = None
|
||||
wishlistItem: Optional[WishlistItemModel] = None
|
||||
success: Optional[bool] = None
|
||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
|
@ -333,33 +389,26 @@ class AddToWishlistModel:
|
|||
def from_dict(cls: Type["AddToWishlistModel"], src: Dict[str, Any]) -> "AddToWishlistModel":
|
||||
d = src.copy()
|
||||
wishlist_item = WishlistItemModel.from_dict(x) if (x := d.pop("wishlistItem", {})) else None
|
||||
tmp = cls(
|
||||
wishlist_item=wishlist_item,
|
||||
success=d.pop("success", None),
|
||||
)
|
||||
tmp = cls(wishlistItem=wishlist_item, success=d.pop("success", None))
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
||||
|
||||
@dataclass
|
||||
class WishlistModel:
|
||||
wishlist_items: Optional[WishlistItemsModel] = None
|
||||
remove_from_wishlist: Optional[RemoveFromWishlistModel] = None
|
||||
add_to_wishlist: Optional[AddToWishlistModel] = None
|
||||
wishlistItems: Optional[WishlistItemsModel] = None
|
||||
removeFromWishlist: Optional[RemoveFromWishlistModel] = None
|
||||
addToWishlist: Optional[AddToWishlistModel] = None
|
||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls: Type["WishlistModel"], src: Dict[str, Any]) -> "WishlistModel":
|
||||
d = src.copy()
|
||||
wishlist_items = WishlistItemsModel.from_dict(x) if (x := d.pop("wishlistItems", {})) else None
|
||||
remove_from_wishlist = (
|
||||
RemoveFromWishlistModel.from_dict(x) if (x := d.pop("removeFromWishlist", {})) else None
|
||||
)
|
||||
remove_from_wishlist = RemoveFromWishlistModel.from_dict(x) if (x := d.pop("removeFromWishlist", {})) else None
|
||||
add_to_wishlist = AddToWishlistModel.from_dict(x) if (x := d.pop("addToWishlist", {})) else None
|
||||
tmp = cls(
|
||||
wishlist_items=wishlist_items,
|
||||
remove_from_wishlist=remove_from_wishlist,
|
||||
add_to_wishlist=add_to_wishlist,
|
||||
wishlistItems=wishlist_items, removeFromWishlist=remove_from_wishlist, addToWishlist=add_to_wishlist
|
||||
)
|
||||
tmp.unmapped = d
|
||||
return tmp
|
||||
|
|
|
@ -2,4 +2,4 @@ from datetime import datetime, timezone
|
|||
|
||||
|
||||
def parse_date(date: str):
|
||||
return datetime.fromisoformat(date[:-1]).replace(tzinfo=timezone.utc)
|
||||
return datetime.fromisoformat(date[:-1]).replace(tzinfo=timezone.utc)
|
||||
|
|
|
@ -14,26 +14,25 @@ from PyQt5.QtWidgets import (
|
|||
QFrame,
|
||||
)
|
||||
|
||||
from rare.components.tabs.store.api.models.response import CatalogOfferModel, WishlistItemModel
|
||||
from rare.widgets.flow_layout import FlowLayout
|
||||
from rare.widgets.side_tab import SideTabContents
|
||||
from rare.widgets.sliding_stack import SlidingStackedWidget
|
||||
from rare.components.tabs.store.api.models.response import CatalogOfferModel, WishlistItemModel
|
||||
from .api.models.utils import parse_date
|
||||
from .store_api import StoreAPI
|
||||
from .widgets.details import DetailsWidget
|
||||
from .widgets.items import StoreItemWidget
|
||||
from .widgets.groups import StoreGroup
|
||||
from .widgets.items import StoreItemWidget
|
||||
|
||||
logger = logging.getLogger("StoreLanding")
|
||||
|
||||
|
||||
class LandingPage(SlidingStackedWidget, SideTabContents):
|
||||
|
||||
def __init__(self, api: StoreAPI, parent=None):
|
||||
def __init__(self, store_api: StoreAPI, parent=None):
|
||||
super(LandingPage, self).__init__(parent=parent)
|
||||
self.implements_scrollarea = True
|
||||
|
||||
self.landing_widget = LandingWidget(api, parent=self)
|
||||
self.landing_widget = LandingWidget(store_api, parent=self)
|
||||
self.landing_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
self.landing_widget.set_title.connect(self.set_title)
|
||||
self.landing_widget.show_details.connect(self.show_details)
|
||||
|
@ -43,7 +42,7 @@ class LandingPage(SlidingStackedWidget, SideTabContents):
|
|||
self.landing_scroll.setFrameStyle(QFrame.NoFrame | QFrame.Plain)
|
||||
self.landing_scroll.setWidget(self.landing_widget)
|
||||
|
||||
self.details_widget = DetailsWidget([], api, parent=self)
|
||||
self.details_widget = DetailsWidget([], store_api, parent=self)
|
||||
self.details_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
self.details_widget.set_title.connect(self.set_title)
|
||||
self.details_widget.back_clicked.connect(self.show_main)
|
||||
|
@ -83,7 +82,7 @@ class LandingWidget(QWidget, SideTabContents):
|
|||
self.discounts_group = StoreGroup(self.tr("Wishlist discounts"), layout=FlowLayout, parent=self)
|
||||
self.discounts_group.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
|
||||
self.games_group = StoreGroup(self.tr("Games"), FlowLayout, self)
|
||||
self.games_group = StoreGroup(self.tr("Free to play"), FlowLayout, self)
|
||||
self.games_group.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
self.games_group.loading(False)
|
||||
self.games_group.setVisible(True)
|
||||
|
@ -97,8 +96,8 @@ class LandingWidget(QWidget, SideTabContents):
|
|||
def showEvent(self, a0: QShowEvent) -> None:
|
||||
if a0.spontaneous():
|
||||
return super().showEvent(a0)
|
||||
self.api.get_free_games(self.__add_free)
|
||||
self.api.get_wishlist(self.__add_discounts)
|
||||
self.api.get_free(self.__update_free_games)
|
||||
self.api.get_wishlist(self.__update_wishlist_discounts)
|
||||
return super().showEvent(a0)
|
||||
|
||||
def hideEvent(self, a0: QHideEvent) -> None:
|
||||
|
@ -107,28 +106,20 @@ class LandingWidget(QWidget, SideTabContents):
|
|||
# TODO: Implement tab unloading
|
||||
return super().hideEvent(a0)
|
||||
|
||||
def __add_discounts(self, wishlist: List[WishlistItemModel]):
|
||||
def __update_wishlist_discounts(self, wishlist: List[WishlistItemModel]):
|
||||
for w in self.discounts_group.findChildren(StoreItemWidget, options=Qt.FindDirectChildrenOnly):
|
||||
self.discounts_group.layout().removeWidget(w)
|
||||
w.deleteLater()
|
||||
|
||||
discounts = 0
|
||||
for game in wishlist:
|
||||
if not game:
|
||||
continue
|
||||
try:
|
||||
if game.offer.price.total_price["discount"] > 0:
|
||||
w = StoreItemWidget(self.api.cached_manager, game.offer)
|
||||
w.show_details.connect(self.show_details)
|
||||
self.discounts_group.layout().addWidget(w)
|
||||
discounts += 1
|
||||
except Exception as e:
|
||||
logger.warning(f"{game} {e}")
|
||||
continue
|
||||
# self.discounts_group.setVisible(discounts > 0)
|
||||
for item in wishlist:
|
||||
if item.offer.price.totalPrice.discount > 0:
|
||||
w = StoreItemWidget(self.api.cached_manager, item.offer)
|
||||
w.show_details.connect(self.show_details)
|
||||
self.discounts_group.layout().addWidget(w)
|
||||
self.discounts_group.setVisible(bool(wishlist))
|
||||
self.discounts_group.loading(False)
|
||||
|
||||
def __add_free(self, free_games: List[CatalogOfferModel]):
|
||||
def __update_free_games(self, free_games: List[CatalogOfferModel]):
|
||||
for w in self.free_games_now.findChildren(StoreItemWidget, options=Qt.FindDirectChildrenOnly):
|
||||
self.free_games_now.layout().removeWidget(w)
|
||||
w.deleteLater()
|
||||
|
@ -140,56 +131,38 @@ class LandingWidget(QWidget, SideTabContents):
|
|||
date = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
|
||||
free_now = []
|
||||
free_next = []
|
||||
for game in free_games:
|
||||
for item in free_games:
|
||||
try:
|
||||
if (
|
||||
game.price.total_price["fmtPrice"]["discountPrice"] == "0"
|
||||
and game.price.total_price["fmtPrice"]["originalPrice"]
|
||||
!= game.price.total_price["fmtPrice"]["discountPrice"]
|
||||
):
|
||||
free_now.append(game)
|
||||
if item.price.totalPrice.discountPrice == 0:
|
||||
free_now.append(item)
|
||||
continue
|
||||
|
||||
if game.title == "Mystery Game":
|
||||
free_next.append(game)
|
||||
if item.title == "Mystery Game":
|
||||
free_next.append(item)
|
||||
continue
|
||||
except KeyError as e:
|
||||
logger.warning(str(e))
|
||||
|
||||
try:
|
||||
# parse datetime to check if game is next week or now
|
||||
try:
|
||||
start_date = parse_date(
|
||||
game.promotions["upcomingPromotionalOffers"][0]["promotionalOffers"][0]["startDate"]
|
||||
)
|
||||
except Exception:
|
||||
try:
|
||||
start_date = parse_date(
|
||||
game.promotions["promotionalOffers"][0]["promotionalOffers"][0]["startDate"]
|
||||
)
|
||||
except Exception as e:
|
||||
continue
|
||||
|
||||
except TypeError:
|
||||
print("type error")
|
||||
continue
|
||||
if not item.promotions.promotionalOffers:
|
||||
start_date = item.promotions.upcomingPromotionalOffers[0].promotionalOffers[0].startDate
|
||||
else:
|
||||
start_date = item.promotions.promotionalOffers[0].promotionalOffers[0].startDate
|
||||
|
||||
if start_date > date:
|
||||
free_next.append(game)
|
||||
free_next.append(item)
|
||||
|
||||
# free games now
|
||||
self.free_games_now.setVisible(bool(len(free_now)))
|
||||
for game in free_now:
|
||||
w = StoreItemWidget(self.api.cached_manager, game)
|
||||
self.free_games_now.setVisible(bool(free_now))
|
||||
for item in free_now:
|
||||
w = StoreItemWidget(self.api.cached_manager, item)
|
||||
w.show_details.connect(self.show_details)
|
||||
self.free_games_now.layout().addWidget(w)
|
||||
self.free_games_now.loading(False)
|
||||
|
||||
# free games next week
|
||||
self.free_games_next.setVisible(bool(len(free_next)))
|
||||
for game in free_next:
|
||||
w = StoreItemWidget(self.api.cached_manager, game)
|
||||
if game.title != "Mystery Game":
|
||||
self.free_games_next.setVisible(bool(free_next))
|
||||
for item in free_next:
|
||||
w = StoreItemWidget(self.api.cached_manager, item)
|
||||
if item.title != "Mystery Game":
|
||||
w.show_details.connect(self.show_details)
|
||||
self.free_games_next.layout().addWidget(w)
|
||||
self.free_games_next.loading(False)
|
||||
|
|
|
@ -26,16 +26,16 @@ logger = logging.getLogger("Shop")
|
|||
|
||||
|
||||
class SearchPage(SlidingStackedWidget, SideTabContents):
|
||||
def __init__(self, core, api: StoreAPI, parent=None):
|
||||
def __init__(self, store_api: StoreAPI, parent=None):
|
||||
super(SearchPage, self).__init__(parent=parent)
|
||||
self.implements_scrollarea = True
|
||||
|
||||
self.search_widget = SearchWidget(core, api, parent=self)
|
||||
self.search_widget = SearchWidget(store_api, parent=self)
|
||||
self.search_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||
self.search_widget.set_title.connect(self.set_title)
|
||||
self.search_widget.show_details.connect(self.show_details)
|
||||
|
||||
self.details_widget = DetailsWidget([], api, parent=self)
|
||||
self.details_widget = DetailsWidget([], store_api, parent=self)
|
||||
self.details_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||
self.details_widget.set_title.connect(self.set_title)
|
||||
self.details_widget.back_clicked.connect(self.show_main)
|
||||
|
@ -58,27 +58,25 @@ class SearchPage(SlidingStackedWidget, SideTabContents):
|
|||
class SearchWidget(QWidget, SideTabContents):
|
||||
show_details = pyqtSignal(CatalogOfferModel)
|
||||
|
||||
def __init__(self, core: LegendaryCore, api: StoreAPI, parent=None):
|
||||
def __init__(self, store_api: StoreAPI, parent=None):
|
||||
super(SearchWidget, self).__init__(parent=parent)
|
||||
self.implements_scrollarea = True
|
||||
self.ui = Ui_SearchWidget()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.main_layout.setContentsMargins(0, 0, 3, 0)
|
||||
|
||||
self.core = core
|
||||
self.api_core = api
|
||||
self.store_api = store_api
|
||||
self.price = ""
|
||||
self.tags = []
|
||||
self.types = []
|
||||
self.update_games_allowed = True
|
||||
|
||||
self.free_game_widgets = []
|
||||
self.active_search_request = False
|
||||
self.next_search = ""
|
||||
self.wishlist: List = []
|
||||
|
||||
self.search_bar = ButtonLineEdit("fa.search", placeholder_text=self.tr("Search Games"))
|
||||
self.results_scrollarea = ResultsWidget(self.api_core, self)
|
||||
self.results_scrollarea = ResultsWidget(self.store_api, self)
|
||||
self.results_scrollarea.show_details.connect(self.show_details)
|
||||
|
||||
self.ui.left_layout.addWidget(self.search_bar)
|
||||
|
@ -188,8 +186,8 @@ class SearchWidget(QWidget, SideTabContents):
|
|||
self.games_group.loading(True)
|
||||
|
||||
browse_model = SearchStoreQuery(
|
||||
language=self.core.language_code,
|
||||
country=self.core.country_code,
|
||||
language=self.store_api.language_code,
|
||||
country=self.store_api.country_code,
|
||||
count=20,
|
||||
price_range=self.price,
|
||||
on_sale=self.ui.on_discount.isChecked(),
|
||||
|
@ -198,7 +196,7 @@ class SearchWidget(QWidget, SideTabContents):
|
|||
|
||||
if self.types:
|
||||
browse_model.category = "|".join(self.types)
|
||||
self.api_core.browse_games(browse_model, self.show_games)
|
||||
self.store_api.browse_games(browse_model, self.show_games)
|
||||
|
||||
|
||||
class CheckBox(QCheckBox):
|
||||
|
|
|
@ -20,7 +20,7 @@ from .api.models.response import (
|
|||
CatalogOfferModel,
|
||||
)
|
||||
|
||||
logger = getLogger("ShopAPICore")
|
||||
logger = getLogger("StoreAPI")
|
||||
graphql_url = "https://graphql.epicgames.com/graphql"
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ class StoreAPI(QObject):
|
|||
self.browse_active = False
|
||||
self.next_browse_request = tuple(())
|
||||
|
||||
def get_free_games(self, handle_func: callable):
|
||||
def get_free(self, handle_func: callable):
|
||||
url = "https://store-site-backend-static-ipv4.ak.epicgames.com/freeGamesPromotions"
|
||||
params = {
|
||||
"locale": self.locale,
|
||||
|
@ -59,7 +59,7 @@ class StoreAPI(QObject):
|
|||
def __handle_free_games(data, handle_func):
|
||||
try:
|
||||
response = ResponseModel.from_dict(data)
|
||||
results: List[CatalogOfferModel] = response.data.catalog.search_store.elements
|
||||
results: List[CatalogOfferModel] = response.data.catalog.searchStore.elements
|
||||
handle_func(results)
|
||||
except KeyError as e:
|
||||
if DEBUG():
|
||||
|
@ -94,7 +94,7 @@ class StoreAPI(QObject):
|
|||
response = ResponseModel.from_dict(data)
|
||||
if response.errors:
|
||||
logger.error(response.errors)
|
||||
handle_func(response.data.wishlist.wishlist_items.elements)
|
||||
handle_func(response.data.wishlist.wishlistItems.elements)
|
||||
except KeyError as e:
|
||||
if DEBUG():
|
||||
raise e
|
||||
|
@ -132,7 +132,7 @@ class StoreAPI(QObject):
|
|||
def __handle_search(data, handler):
|
||||
try:
|
||||
response = ResponseModel.from_dict(data)
|
||||
handler(response.data.catalog.search_store.elements)
|
||||
handler(response.data.catalog.searchStore.elements)
|
||||
except KeyError as e:
|
||||
logger.error(str(e))
|
||||
if DEBUG():
|
||||
|
@ -167,7 +167,7 @@ class StoreAPI(QObject):
|
|||
if not self.next_browse_request:
|
||||
try:
|
||||
response = ResponseModel.from_dict(data)
|
||||
handle_func(response.data.catalog.search_store.elements)
|
||||
handle_func(response.data.catalog.searchStore.elements)
|
||||
except KeyError as e:
|
||||
if DEBUG():
|
||||
raise e
|
||||
|
@ -233,7 +233,7 @@ class StoreAPI(QObject):
|
|||
# debug.exec()
|
||||
try:
|
||||
response = ResponseModel.from_dict(data)
|
||||
data = response.data.wishlist.add_to_wishlist
|
||||
data = response.data.wishlist.addToWishlist
|
||||
handle_func(data.success)
|
||||
except Exception as e:
|
||||
if DEBUG():
|
||||
|
@ -259,7 +259,7 @@ class StoreAPI(QObject):
|
|||
# debug.exec()
|
||||
try:
|
||||
response = ResponseModel.from_dict(data)
|
||||
data = response.data.wishlist.remove_from_wishlist
|
||||
data = response.data.wishlist.removeFromWishlist
|
||||
handle_func(data.success)
|
||||
except Exception as e:
|
||||
if DEBUG():
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import logging
|
||||
from typing import List
|
||||
from typing import List, Dict
|
||||
|
||||
from PyQt5.QtCore import Qt, QUrl, pyqtSignal
|
||||
from PyQt5.QtGui import QFont, QDesktopServices, QKeyEvent
|
||||
|
@ -14,6 +14,7 @@ from PyQt5.QtWidgets import (
|
|||
from rare.components.tabs.store.api.debug import DebugDialog
|
||||
from rare.components.tabs.store.api.models.diesel import DieselProduct, DieselProductDetail, DieselSystemDetail
|
||||
from rare.components.tabs.store.api.models.response import CatalogOfferModel
|
||||
from rare.components.tabs.store.store_api import StoreAPI
|
||||
from rare.models.image import ImageSize
|
||||
from rare.ui.components.tabs.store.details import Ui_DetailsWidget
|
||||
from rare.utils.misc import icon
|
||||
|
@ -28,7 +29,7 @@ class DetailsWidget(QWidget, SideTabContents):
|
|||
back_clicked: pyqtSignal = pyqtSignal()
|
||||
|
||||
# TODO Design
|
||||
def __init__(self, installed_titles: list, api_core, parent=None):
|
||||
def __init__(self, installed: List, store_api: StoreAPI, parent=None):
|
||||
super(DetailsWidget, self).__init__(parent=parent)
|
||||
self.implements_scrollarea = True
|
||||
|
||||
|
@ -36,13 +37,11 @@ class DetailsWidget(QWidget, SideTabContents):
|
|||
self.ui.setupUi(self)
|
||||
self.ui.main_layout.setContentsMargins(0, 0, 3, 0)
|
||||
|
||||
# self.core = LegendaryCoreSingleton()
|
||||
self.api_core = api_core
|
||||
self.installed = installed_titles
|
||||
self.offer: CatalogOfferModel = None
|
||||
self.data: dict = {}
|
||||
self.store_api = store_api
|
||||
self.installed = installed
|
||||
self.catalog_offer: CatalogOfferModel = None
|
||||
|
||||
self.image = LoadingImageWidget(api_core.cached_manager, self)
|
||||
self.image = LoadingImageWidget(store_api.cached_manager, self)
|
||||
self.image.setFixedSize(ImageSize.Display)
|
||||
self.ui.left_layout.insertWidget(0, self.image, alignment=Qt.AlignTop)
|
||||
self.ui.left_layout.setAlignment(Qt.AlignTop)
|
||||
|
@ -53,7 +52,7 @@ class DetailsWidget(QWidget, SideTabContents):
|
|||
self.in_wishlist = False
|
||||
self.wishlist = []
|
||||
|
||||
self.requirements_tabs: SideTabWidget = SideTabWidget(parent=self.ui.requirements_frame)
|
||||
self.requirements_tabs = SideTabWidget(parent=self.ui.requirements_frame)
|
||||
self.requirements_tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||
self.ui.requirements_layout.addWidget(self.requirements_tabs)
|
||||
|
||||
|
@ -78,15 +77,17 @@ class DetailsWidget(QWidget, SideTabContents):
|
|||
self.ui.title.setText(offer.title)
|
||||
self.title_str = offer.title
|
||||
self.id_str = offer.id
|
||||
self.api_core.get_wishlist(self.handle_wishlist_update)
|
||||
self.store_api.get_wishlist(self.handle_wishlist_update)
|
||||
|
||||
# lk: delete tabs in reverse order because indices are updated on deletion
|
||||
while self.requirements_tabs.count():
|
||||
self.requirements_tabs.widget(0).deleteLater()
|
||||
self.requirements_tabs.removeTab(0)
|
||||
self.requirements_tabs.clear()
|
||||
slug = offer.product_slug
|
||||
|
||||
slug = offer.productSlug
|
||||
if not slug:
|
||||
for mapping in offer.offer_mappings:
|
||||
for mapping in offer.offerMappings:
|
||||
if mapping["pageType"] == "productHome":
|
||||
slug = mapping["pageSlug"]
|
||||
break
|
||||
|
@ -114,24 +115,24 @@ class DetailsWidget(QWidget, SideTabContents):
|
|||
|
||||
# init API request
|
||||
if slug:
|
||||
self.api_core.get_game_config_cms(offer.product_slug, is_bundle, self.data_received)
|
||||
self.store_api.get_game_config_cms(offer.productSlug, is_bundle, self.data_received)
|
||||
# else:
|
||||
# self.data_received({})
|
||||
self.offer = offer
|
||||
self.catalog_offer = offer
|
||||
|
||||
def add_to_wishlist(self):
|
||||
if not self.in_wishlist:
|
||||
self.api_core.add_to_wishlist(
|
||||
self.offer.namespace,
|
||||
self.offer.id,
|
||||
self.store_api.add_to_wishlist(
|
||||
self.catalog_offer.namespace,
|
||||
self.catalog_offer.id,
|
||||
lambda success: self.ui.wishlist_button.setText(self.tr("Remove from wishlist"))
|
||||
if success
|
||||
else self.ui.wishlist_button.setText("Something went wrong")
|
||||
)
|
||||
else:
|
||||
self.api_core.remove_from_wishlist(
|
||||
self.offer.namespace,
|
||||
self.offer.id,
|
||||
self.store_api.remove_from_wishlist(
|
||||
self.catalog_offer.namespace,
|
||||
self.catalog_offer.id,
|
||||
lambda success: self.ui.wishlist_button.setText(self.tr("Add to wishlist"))
|
||||
if success
|
||||
else self.ui.wishlist_button.setText("Something went wrong"),
|
||||
|
@ -146,34 +147,16 @@ class DetailsWidget(QWidget, SideTabContents):
|
|||
except Exception as e:
|
||||
raise e
|
||||
logger.error(str(e))
|
||||
self.price.setText("Error")
|
||||
self.requirements_tabs.setEnabled(False)
|
||||
for img in self.data.get("keyImages"):
|
||||
if img["type"] in [
|
||||
"DieselStoreFrontWide",
|
||||
"OfferImageTall",
|
||||
"VaultClosed",
|
||||
"ProductLogo",
|
||||
]:
|
||||
self.image.fetchPixmap(img["url"])
|
||||
break
|
||||
self.price.setText("")
|
||||
self.discount_price.setText("")
|
||||
self.social_group.setEnabled(False)
|
||||
self.tags.setText("")
|
||||
self.dev.setText(self.data.get("seller", {}).get("name", ""))
|
||||
return
|
||||
# self.title.setText(self.game.title)
|
||||
|
||||
self.ui.price.setFont(QFont())
|
||||
price = self.offer.price.total_price["fmtPrice"]["originalPrice"]
|
||||
discount_price = self.offer.price.total_price["fmtPrice"]["discountPrice"]
|
||||
self.ui.price.setFont(self.font())
|
||||
price = self.catalog_offer.price.totalPrice.fmtPrice["originalPrice"]
|
||||
discount_price = self.catalog_offer.price.totalPrice.fmtPrice["discountPrice"]
|
||||
if price == "0" or price == 0:
|
||||
self.ui.price.setText(self.tr("Free"))
|
||||
else:
|
||||
self.ui.price.setText(price)
|
||||
if price != discount_price:
|
||||
font = QFont()
|
||||
font = self.font()
|
||||
font.setStrikeOut(True)
|
||||
self.ui.price.setFont(font)
|
||||
self.ui.discount_price.setText(
|
||||
|
@ -189,18 +172,11 @@ class DetailsWidget(QWidget, SideTabContents):
|
|||
if requirements and requirements.systems:
|
||||
for system in requirements.systems:
|
||||
req_widget = RequirementsWidget(system, self.requirements_tabs)
|
||||
self.requirements_tabs.addTab(req_widget, system.system_type)
|
||||
# self.req_group_box.layout().addWidget(req_tabs)
|
||||
# self.req_group_box.layout().setAlignment(Qt.AlignTop)
|
||||
# else:
|
||||
# self.req_group_box.layout().addWidget(
|
||||
# QLabel(self.tr("Could not get requirements"))
|
||||
# )
|
||||
self.ui.requirements_frame.setVisible(True)
|
||||
self.requirements_tabs.addTab(req_widget, system.systemType)
|
||||
else:
|
||||
self.ui.requirements_frame.setVisible(False)
|
||||
|
||||
key_images = self.offer.key_images
|
||||
key_images = self.catalog_offer.keyImages
|
||||
img_url = key_images.for_dimensions(self.image.size().width(), self.image.size().height())
|
||||
self.image.fetchPixmap(img_url.url)
|
||||
|
||||
|
@ -223,7 +199,7 @@ class DetailsWidget(QWidget, SideTabContents):
|
|||
self.ui.social_layout.removeWidget(b)
|
||||
b.deleteLater()
|
||||
|
||||
links = product_data.social_links
|
||||
links = product_data.socialLinks
|
||||
link_count = 0
|
||||
for name, url in links.items():
|
||||
if name == "_type":
|
||||
|
@ -252,8 +228,7 @@ class DetailsWidget(QWidget, SideTabContents):
|
|||
# self.wishlist.append(game["offer"]["title"])
|
||||
|
||||
def button_clicked(self):
|
||||
return
|
||||
QDesktopServices.openUrl(QUrl(f"https://www.epicgames.com/store/{self.core.language_code}/p/{self.slug}"))
|
||||
QDesktopServices.openUrl(QUrl(f"https://www.epicgames.com/store/{self.store_api.language_code}/p/{self.slug}"))
|
||||
|
||||
def keyPressEvent(self, a0: QKeyEvent):
|
||||
if a0.key() == Qt.Key_Escape:
|
||||
|
|
|
@ -11,7 +11,7 @@ from rare.utils.misc import qta_icon
|
|||
from rare.utils.qt_requests import QtRequests
|
||||
from .image import LoadingImageWidget
|
||||
|
||||
logger = logging.getLogger("GameWidgets")
|
||||
logger = logging.getLogger("StoreWidgets")
|
||||
|
||||
|
||||
class ItemWidget(LoadingImageWidget):
|
||||
|
@ -46,15 +46,15 @@ class StoreItemWidget(ItemWidget):
|
|||
return
|
||||
|
||||
self.ui.title_label.setText(game.title)
|
||||
for attr in game.custom_attributes:
|
||||
for attr in game.customAttributes:
|
||||
if attr["key"] == "developerName":
|
||||
developer = attr["value"]
|
||||
break
|
||||
else:
|
||||
developer = game.seller["name"]
|
||||
self.ui.developer_label.setText(developer)
|
||||
price = game.price.total_price["fmtPrice"]["originalPrice"]
|
||||
discount_price = game.price.total_price["fmtPrice"]["discountPrice"]
|
||||
price = game.price.totalPrice.fmtPrice["originalPrice"]
|
||||
discount_price = game.price.totalPrice.fmtPrice["discountPrice"]
|
||||
self.ui.price_label.setText(f'{price if price != "0" else self.tr("Free")}')
|
||||
if price != discount_price:
|
||||
font = self.ui.price_label.font()
|
||||
|
@ -64,7 +64,7 @@ class StoreItemWidget(ItemWidget):
|
|||
else:
|
||||
self.ui.discount_label.setVisible(False)
|
||||
|
||||
key_images = game.key_images
|
||||
key_images = game.keyImages
|
||||
self.fetchPixmap(key_images.for_dimensions(self.width(), self.height()).url)
|
||||
|
||||
# for img in json_info["keyImages"]:
|
||||
|
@ -83,13 +83,13 @@ class ResultsItemWidget(ItemWidget):
|
|||
self.setFixedSize(ImageSize.Display)
|
||||
self.ui.setupUi(self)
|
||||
|
||||
key_images = catalog_game.key_images
|
||||
key_images = catalog_game.keyImages
|
||||
self.fetchPixmap(key_images.for_dimensions(self.width(), self.height()).url)
|
||||
|
||||
self.ui.title_label.setText(catalog_game.title)
|
||||
|
||||
price = catalog_game.price.total_price["fmtPrice"]["originalPrice"]
|
||||
discount_price = catalog_game.price.total_price["fmtPrice"]["discountPrice"]
|
||||
price = catalog_game.price.totalPrice.fmtPrice["originalPrice"]
|
||||
discount_price = catalog_game.price.totalPrice.fmtPrice["discountPrice"]
|
||||
self.ui.price_label.setText(f'{price if price != "0" else self.tr("Free")}')
|
||||
if price != discount_price:
|
||||
font = self.ui.price_label.font()
|
||||
|
@ -108,14 +108,14 @@ class WishlistItemWidget(ItemWidget):
|
|||
super(WishlistItemWidget, self).__init__(manager, catalog_game, parent=parent)
|
||||
self.setFixedSize(ImageSize.DisplayWide)
|
||||
self.ui.setupUi(self)
|
||||
for attr in catalog_game.custom_attributes:
|
||||
for attr in catalog_game.customAttributes:
|
||||
if attr["key"] == "developerName":
|
||||
developer = attr["value"]
|
||||
break
|
||||
else:
|
||||
developer = catalog_game.seller["name"]
|
||||
original_price = catalog_game.price.total_price["fmtPrice"]["originalPrice"]
|
||||
discount_price = catalog_game.price.total_price["fmtPrice"]["discountPrice"]
|
||||
original_price = catalog_game.price.totalPrice.fmtPrice["originalPrice"]
|
||||
discount_price = catalog_game.price.totalPrice.fmtPrice["discountPrice"]
|
||||
|
||||
self.ui.title_label.setText(catalog_game.title)
|
||||
self.ui.developer_label.setText(developer)
|
||||
|
@ -127,7 +127,7 @@ class WishlistItemWidget(ItemWidget):
|
|||
self.ui.discount_label.setText(f'{discount_price if discount_price != "0" else self.tr("Free")}')
|
||||
else:
|
||||
self.ui.discount_label.setVisible(False)
|
||||
key_images = catalog_game.key_images
|
||||
key_images = catalog_game.keyImages
|
||||
self.fetchPixmap(
|
||||
key_images.for_dimensions(self.width(), self.height()).url
|
||||
)
|
||||
|
|
|
@ -116,13 +116,13 @@ class WishlistWidget(QWidget, SideTabContents):
|
|||
func = lambda x: x.catalog_game.title
|
||||
reverse = self.ui.reverse.isChecked()
|
||||
elif sort == 1:
|
||||
func = lambda x: x.catalog_game.price.total_price["fmtPrice"]["discountPrice"]
|
||||
func = lambda x: x.catalog_game.price.totalPrice["fmtPrice"]["discountPrice"]
|
||||
reverse = self.ui.reverse.isChecked()
|
||||
elif sort == 2:
|
||||
func = lambda x: x.catalog_game.seller["name"]
|
||||
reverse = self.ui.reverse.isChecked()
|
||||
elif sort == 3:
|
||||
func = lambda x: 1 - (x.catalog_game.price.total_price["discountPrice"] / x.catalog_game.price.total_price["originalPrice"])
|
||||
func = lambda x: 1 - (x.catalog_game.price.totalPrice["discountPrice"] / x.catalog_game.price.totalPrice["originalPrice"])
|
||||
reverse = not self.ui.reverse.isChecked()
|
||||
else:
|
||||
func = lambda x: x.catalog_game.title
|
||||
|
|
|
@ -18,6 +18,8 @@ class Ui_DetailsWidget(object):
|
|||
DetailsWidget.setWindowTitle("DetailsWidget")
|
||||
self.main_layout = QtWidgets.QHBoxLayout(DetailsWidget)
|
||||
self.main_layout.setObjectName("main_layout")
|
||||
self.left_layout = QtWidgets.QVBoxLayout()
|
||||
self.left_layout.setObjectName("left_layout")
|
||||
self.back_button = QtWidgets.QPushButton(DetailsWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
|
@ -28,9 +30,7 @@ class Ui_DetailsWidget(object):
|
|||
self.back_button.setIconSize(QtCore.QSize(32, 32))
|
||||
self.back_button.setFlat(True)
|
||||
self.back_button.setObjectName("back_button")
|
||||
self.main_layout.addWidget(self.back_button)
|
||||
self.left_layout = QtWidgets.QVBoxLayout()
|
||||
self.left_layout.setObjectName("left_layout")
|
||||
self.left_layout.addWidget(self.back_button)
|
||||
self.main_layout.addLayout(self.left_layout)
|
||||
self.right_layout = QtWidgets.QVBoxLayout()
|
||||
self.right_layout.setObjectName("right_layout")
|
||||
|
@ -176,7 +176,7 @@ class Ui_DetailsWidget(object):
|
|||
self.description_label.setObjectName("description_label")
|
||||
self.right_layout.addWidget(self.description_label)
|
||||
self.main_layout.addLayout(self.right_layout)
|
||||
self.main_layout.setStretch(2, 1)
|
||||
self.main_layout.setStretch(1, 1)
|
||||
|
||||
self.retranslateUi(DetailsWidget)
|
||||
|
||||
|
|
|
@ -13,31 +13,32 @@
|
|||
<property name="windowTitle">
|
||||
<string notr="true">DetailsWidget</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="main_layout" stretch="0,0,1">
|
||||
<layout class="QHBoxLayout" name="main_layout" stretch="0,1">
|
||||
<item>
|
||||
<widget class="QPushButton" name="back_button">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="left_layout"/>
|
||||
<layout class="QVBoxLayout" name="left_layout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="back_button">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="right_layout">
|
||||
|
|
|
@ -5,7 +5,7 @@ from typing import Callable, Dict, TypeVar, List, Tuple
|
|||
from typing import Union
|
||||
|
||||
import orjson
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, QUrl, QUrlQuery, pyqtSlot
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, QUrl, QUrlQuery, pyqtSlot, QJsonDocument
|
||||
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply, QNetworkDiskCache
|
||||
|
||||
USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
|
||||
|
|
Loading…
Reference in a new issue