Skip to content

Commit

Permalink
Store WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
loathingKernel committed Sep 23, 2023
1 parent d4be76f commit b0fd6c6
Show file tree
Hide file tree
Showing 15 changed files with 374 additions and 649 deletions.
17 changes: 8 additions & 9 deletions rare/components/tabs/store/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from legendary.core import LegendaryCore

from rare.shared import RareCore
from rare.utils.paths import cache_dir
from rare.widgets.side_tab import SideTabWidget
from .api.models.response import CatalogOfferModel
from .game_info import ShopGameInfo
from .search_results import SearchResults
from .shop_api_core import ShopApiCore
from .api.models.response import CatalogOfferModel
from .shop_widget import ShopWidget
from .wishlist import WishlistWidget, Wishlist

Expand All @@ -28,11 +27,11 @@ def __init__(self, core: LegendaryCore, parent=None):
self.shop = ShopWidget(cache_dir(), self.core, self.api_core, parent=self)
self.shop_index = self.addTab(self.shop, self.tr("Store"))
self.shop.show_game.connect(self.show_game)
self.shop.show_info.connect(self.show_search)
# self.shop.show_info.connect(self.show_search)

self.search = SearchResults(self.api_core, parent=self)
self.search_index = self.addTab(self.search, self.tr("Search"), self.tr("Results"))
self.search.show_info.connect(self.show_game)
# self.search = SearchResults(self.api_core, parent=self)
# self.search_index = self.addTab(self.search, self.tr("Search"), self.tr("Results"))
# self.search.show_info.connect(self.show_game)
# self.search.back_button.clicked.connect(lambda: self.setCurrentIndex(self.shop_index))

self.info = ShopGameInfo(
Expand Down Expand Up @@ -67,6 +66,6 @@ def show_game(self, data: CatalogOfferModel):
self.info.update_game(data)
self.setCurrentIndex(self.info_index)

def show_search(self, text: str):
self.search.load_results(text)
self.setCurrentIndex(self.search_index)
# def show_search(self, text: str):
# self.search.load_results(text)
# self.setCurrentIndex(self.search_index)
2 changes: 1 addition & 1 deletion rare/components/tabs/store/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ def __init__(self):


if __name__ == "__main__":
from rare.utils.misc import set_style_sheet
import rare.resources.static_css
import rare.resources.stylesheets.RareStyle
from rare.utils.misc import set_style_sheet

app = QApplication(sys.argv)
app.setApplicationName("Rare")
Expand Down
2 changes: 1 addition & 1 deletion rare/components/tabs/store/api/debug.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QTreeView, QDialog, QVBoxLayout

from utils.json_formatter import QJsonModel
from rare.utils.json_formatter import QJsonModel


class DebugView(QTreeView):
Expand Down
35 changes: 35 additions & 0 deletions rare/components/tabs/store/api/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,39 @@ type LineOfferRes {
type GetPriceRes {
totalPrice: TotalPrice
lineOffers: [LineOfferRes]
}

type Image {
type: String
url: String
alt: String
}

type StorePageMapping {
cmsSlug: String
offerId: ID
prePurchaseOfferId: ID
}

type PageSandboxModel {
pageSlug: String
pageType: String
productId: ID
sandboxId: ID
createdDate: Date
updatedDate: Date
deletedDate: Date
mappings: [StorePageMapping]
}

type CatalogNamespace {
parent: ID
displayName: String
store: String
mappings: [PageSandboxModel]
}

type CatalogItem {
id: ID
namespace: ID
}
4 changes: 2 additions & 2 deletions rare/components/tabs/store/api/models/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
@dataclass
class SearchDateRange:
start_date: datetime = datetime(year=1990, month=1, day=1, tzinfo=timezone.utc)
end_date: datetime = datetime.utcnow()
end_date: datetime = datetime.utcnow().replace(tzinfo=timezone.utc)

def __str__(self):
def fmt_date(date: datetime) -> str:
# lk: The formatting accepted by the GraphQL API is either '%Y-%m-%dT%H:%M:%S.000Z' or '%Y-%m-%dT'
# lk: The formatting accepted by the GraphQL API is either '%Y-%m-%dT%H:%M:%S.000Z' or '%Y-%m-%d'
return datetime.strftime(date, '%Y-%m-%dT%H:%M:%S.000Z')
return f"[{fmt_date(self.start_date)},{fmt_date(self.end_date)}]"

Expand Down
176 changes: 9 additions & 167 deletions rare/components/tabs/store/api/models/response.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import logging
from dataclasses import dataclass, field
from datetime import datetime, timezone
from datetime import datetime
from typing import List, Dict, Any, Type, Optional

from .utils import parse_date

logger = logging.getLogger("StoreApiModels")

# lk: Typing overloads for unimplemented types
Expand All @@ -13,171 +15,11 @@
CustomAttributeModel = Dict
ItemModel = Dict
SellerModel = Dict
OfferMappingModel = Dict
PageSandboxModel = Dict
TagModel = Dict
PromotionsModel = Dict


def parse_date(date: str):
return datetime.fromisoformat(date[:-1]).replace(tzinfo=timezone.utc)


@dataclass
class DieselSystemDetailItem:
p_type: Optional[str] = None
minimum: Optional[str] = None
recommended: Optional[str] = None
title: Optional[str] = None
unmapped: Dict[str, Any] = field(default_factory=dict)

@classmethod
def from_dict(cls: Type["DieselSystemDetailItem"], src: Dict[str, Any]) -> "DieselSystemDetailItem":
d = src.copy()
tmp = cls(
p_type=d.pop("_type", ""),
minimum=d.pop("minimum", ""),
recommended=d.pop("recommended", ""),
title=d.pop("title", ""),
)
tmp.unmapped = d
return tmp


@dataclass
class DieselSystemDetail:
p_type: Optional[str] = None
details: Optional[List[DieselSystemDetailItem]] = None
system_type: Optional[str] = None
unmapped: Dict[str, Any] = field(default_factory=dict)

@classmethod
def from_dict(cls: Type["DieselSystemDetail"], src: Dict[str, Any]) -> "DieselSystemDetail":
d = src.copy()
_details = d.pop("details", [])
details = [] if _details else None
for item in _details:
detail = DieselSystemDetailItem.from_dict(item)
details.append(detail)
tmp = cls(
p_type=d.pop("_type", ""),
details=details,
system_type=d.pop("systemType", ""),
)
tmp.unmapped = d
return tmp


@dataclass
class DieselSystemDetails:
p_type: Optional[str] = None
languages: Optional[List[str]] = None
rating: Optional[Dict] = None
systems: Optional[List[DieselSystemDetail]] = None
unmapped: Dict[str, Any] = field(default_factory=dict)

@classmethod
def from_dict(cls: Type["DieselSystemDetails"], src: Dict[str, Any]) -> "DieselSystemDetails":
d = src.copy()
_systems = d.pop("systems", [])
systems = [] if _systems else None
for item in _systems:
system = DieselSystemDetail.from_dict(item)
systems.append(system)
tmp = cls(
p_type=d.pop("_type", ""),
languages=d.pop("languages", []),
rating=d.pop("rating", {}),
systems=systems,
)
tmp.unmapped = d
return tmp


@dataclass
class DieselProductAbout:
p_type: Optional[str] = None
desciption: Optional[str] = None
developer_attribution: Optional[str] = None
publisher_attribution: Optional[str] = None
short_description: Optional[str] = None
unmapped: Dict[str, Any] = field(default_factory=dict)

@classmethod
def from_dict(cls: Type["DieselProductAbout"], src: Dict[str, Any]) -> "DieselProductAbout":
d = src.copy()
tmp = cls(
p_type=d.pop("_type", ""),
desciption=d.pop("description", ""),
developer_attribution=d.pop("developerAttribution", ""),
publisher_attribution=d.pop("publisherAttribution", ""),
short_description=d.pop("shortDescription", ""),
)
tmp.unmapped = d
return tmp


@dataclass
class DieselProductDetail:
p_type: Optional[str] = None
about: Optional[DieselProductAbout] = None
requirements: Optional[DieselSystemDetails] = None
social_links: Optional[DieselSocialLinks] = None
unmapped: Dict[str, Any] = field(default_factory=dict)

@classmethod
def from_dict(cls: Type["DieselProductDetail"], src: Dict[str, Any]) -> "DieselProductDetail":
d = src.copy()
about = DieselProductAbout.from_dict(x) if (x := d.pop("about"), {}) else None
requirements = DieselSystemDetails.from_dict(x) if (x := d.pop("requirements", {})) else None
tmp = cls(
p_type=d.pop("_type", ""),
about=about,
requirements=requirements,
social_links=d.pop("socialLinks", {}),
)
tmp.unmapped = d
return tmp


@dataclass
class DieselProduct:
p_id: Optional[str] = None
p_images_: Optional[List[str]] = None
p_locale: Optional[str] = None
p_slug: Optional[str] = None
p_title: Optional[str] = None
p_url_pattern: Optional[str] = None
namespace: Optional[str] = None
pages: Optional[List["DieselProduct"]] = None
data: Optional[DieselProductDetail] = None
product_name: Optional[str] = None
unmapped: Dict[str, Any] = field(default_factory=dict)

@classmethod
def from_dict(cls: Type["DieselProduct"], src: Dict[str, Any]) -> "DieselProduct":
d = src.copy()
_pages = d.pop("pages", [])
pages = [] if _pages else None
for item in _pages:
page = DieselProduct.from_dict(item)
pages.append(page)
data = DieselProductDetail.from_dict(x) if (x := d.pop("data", {})) else None
tmp = cls(
p_id=d.pop("_id", ""),
p_images_=d.pop("_images_", []),
p_locale=d.pop("_locale", ""),
p_slug=d.pop("_slug", ""),
p_title=d.pop("_title", ""),
p_url_pattern=d.pop("_urlPattern", ""),
namespace=d.pop("namespace", ""),
pages=pages,
data=data,
product_name=d.pop("productName", ""),
)
tmp.unmapped = d
return tmp


@dataclass
class ImageUrlModel:
type: Optional[str] = None
Expand Down Expand Up @@ -271,14 +113,14 @@ def for_dimensions(self, w: int, h: int) -> ImageUrlModel:


@dataclass
class PriceModel:
class GetPriceResModel:
total_price: Optional[TotalPriceModel] = None
fmt_price: Optional[FmtPriceModel] = None
line_offers: Optional[LineOffersModel] = None
unmapped: Dict[str, Any] = field(default_factory=dict)

@classmethod
def from_dict(cls: Type["PriceModel"], src: Dict[str, Any]) -> "PriceModel":
def from_dict(cls: Type["GetPriceResModel"], src: Dict[str, Any]) -> "GetPriceResModel":
d = src.copy()
tmp = cls(
total_price=d.pop("totalPrice", {}),
Expand All @@ -302,9 +144,9 @@ class CatalogOfferModel:
items: Optional[List[ItemModel]] = None
key_images: Optional[KeyImagesModel] = None
namespace: Optional[str] = None
offer_mappings: Optional[List[OfferMappingModel]] = None
offer_mappings: Optional[List[PageSandboxModel]] = None
offer_type: Optional[str] = None
price: Optional[PriceModel] = None
price: Optional[GetPriceResModel] = None
product_slug: Optional[str] = None
promotions: Optional[PromotionsModel] = None
seller: Optional[SellerModel] = None
Expand All @@ -322,7 +164,7 @@ def from_dict(cls: Type["CatalogOfferModel"], src: Dict[str, Any]) -> "CatalogOf
effective_date = parse_date(x) if (x := d.pop("effectiveDate", "")) else None
expiry_date = parse_date(x) if (x := d.pop("expiryDate", "")) else None
key_images = KeyImagesModel.from_list(d.pop("keyImages", []))
price = PriceModel.from_dict(x) if (x := d.pop("price", {})) else None
price = GetPriceResModel.from_dict(x) if (x := d.pop("price", {})) else None
viewable_date = parse_date(x) if (x := d.pop("viewableDate", "")) else None
tmp = cls(
catalog_ns=d.pop("catalogNs", {}),
Expand Down
11 changes: 5 additions & 6 deletions rare/components/tabs/store/game_info.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import logging
from pprint import pprint
from typing import List

from PyQt5.QtCore import Qt, QUrl
Expand All @@ -12,14 +11,14 @@
QSizePolicy,
)

from rare.components.tabs.store.api.models.response import CatalogOfferModel, DieselProduct, DieselProductDetail
from rare.shared import LegendaryCoreSingleton
from rare.shared.image_manager import ImageSize
from rare.models.image import ImageSize
from rare.ui.components.tabs.store.shop_game_info import Ui_ShopInfo
from rare.utils.misc import icon
from rare.widgets.side_tab import SideTabWidget, SideTabContents
from rare.widgets.elide_label import ElideLabel
from rare.widgets.side_tab import SideTabWidget, SideTabContents
from .api.debug import DebugDialog
from .api.models.diesel import DieselProduct, DieselProductDetail
from .api.models.response import CatalogOfferModel
from .image_widget import ShopImageWidget

logger = logging.getLogger("ShopInfo")
Expand Down Expand Up @@ -107,7 +106,7 @@ def update_game(self, offer: CatalogOfferModel):

# init API request
if slug:
self.api_core.get_game(offer.product_slug, is_bundle, self.data_received)
self.api_core.get_game_config_cms(offer.product_slug, is_bundle, self.data_received)
# else:
# self.data_received({})
self.offer = offer
Expand Down
3 changes: 1 addition & 2 deletions rare/components/tabs/store/game_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtGui import QMouseEvent
from PyQt5.QtWidgets import QPushButton
from orjson import orjson

from rare.components.tabs.store.api.models.response import CatalogOfferModel
from rare.shared.image_manager import ImageSize
from rare.models.image import ImageSize
from rare.utils.misc import icon
from rare.utils.qt_requests import QtRequestManager
from .api.debug import DebugDialog
Expand Down
Loading

0 comments on commit b0fd6c6

Please sign in to comment.