offer.py (15810B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\store\client\targetaudience\offer.py 2 from __future__ import absolute_import, division, print_function 3 from datetime import datetime 4 from eveProto.generated.eve_public.inventory.generic_item_type_pb2 import Identifier as ItemTypeIdentifier 5 from eveProto.generated.eve_public.store.targetaudience.image_resource_pb2 import ImageResource 6 from eveProto.generated.eve_public.store.targetaudience.localized_text_pb2 import LocalizedEntry, LocalizedText 7 from eveProto.generated.eve_public.store.targetaudience.offer.content_pb2 import BlueprintCopyGrant, Content, EveItemGrant, GrantedProduct, LicenceGrant, PlexGrant 8 from eveProto.generated.eve_public.store.targetaudience.offer.offer_pb2 import Attributes as OfferAttributes 9 from eveProto.generated.eve_public.store.targetaudience.offer.overlay_pb2 import Overlay 10 from eveProto.generated.eve_public.store.targetaudience.offer.price_pb2 import PlexPrice, Price, PriceInCurrency 11 12 def _build_localized_text_from_proto(payload): 13 return {entry.id:entry.text for entry in payload.entries} 14 15 16 def _localized_text_to_proto(text_by_language): 17 return LocalizedText(entries=[ LocalizedEntry(id=language, text=text) for language, text in sorted(text_by_language.items()) ]) 18 19 20 class TargetAudienceOfferPrice(object): 21 PRICE_TYPE_FREE = 'free' 22 PRICE_TYPE_REAL_MONEY = 'real_money_price' 23 PRICE_TYPE_PLEX = 'plex_price' 24 25 def __init__(self, price_type, currency_prices = None, plex_price_in_cents = None): 26 self._price_type = price_type 27 self._currency_prices = currency_prices if currency_prices is not None else [] 28 self._plex_price_in_cents = plex_price_in_cents 29 30 @property 31 def price_type(self): 32 return self._price_type 33 34 @property 35 def currency_prices(self): 36 return self._currency_prices 37 38 @property 39 def plex_price_in_cents(self): 40 return self._plex_price_in_cents 41 42 def is_free(self): 43 return self.price_type == self.PRICE_TYPE_FREE 44 45 def has_currency_prices(self): 46 return self.price_type == self.PRICE_TYPE_REAL_MONEY 47 48 def has_plex_price(self): 49 return self.price_type == self.PRICE_TYPE_PLEX 50 51 @classmethod 52 def build_from_proto(cls, payload): 53 price_type = payload.WhichOneof('price_details') 54 currency_prices = [] 55 plex_price_in_cents = None 56 if price_type == cls.PRICE_TYPE_REAL_MONEY: 57 currency_prices = [ (x.currency, x.amount_in_cents) for x in payload.real_money_price.prices ] 58 elif price_type == cls.PRICE_TYPE_PLEX: 59 plex_price_in_cents = payload.plex_price.amount_in_cents 60 return TargetAudienceOfferPrice(price_type=price_type, currency_prices=currency_prices, plex_price_in_cents=plex_price_in_cents) 61 62 @classmethod 63 def to_proto(cls, price): 64 if price.is_free(): 65 return Price(free=True) 66 if price.has_currency_prices(): 67 prices = [ PriceInCurrency(currency=currency, amount_in_cents=amount_in_cents) for currency, amount_in_cents in price.currency_prices ] 68 return Price(real_money_price=Price.Payable(prices=prices)) 69 if price.has_plex_price(): 70 return Price(plex_price=PlexPrice(amount_in_cents=price.plex_price_in_cents)) 71 return Price() 72 73 def __eq__(self, other): 74 return other is not None and self.price_type == other.price_type and self.currency_prices == other.currency_prices and self.plex_price_in_cents == other.plex_price_in_cents 75 76 def __ne__(self, other): 77 return not self.__eq__(other) 78 79 80 class TargetAudienceOfferGrantedProduct(object): 81 GRANT_TYPE_EVE_ITEM = 'eve_item' 82 GRANT_TYPE_BLUEPRINT_COPY = 'blueprint_copy' 83 GRANT_TYPE_LICENCE = 'licence' 84 GRANT_TYPE_PLEX = 'plex' 85 EXPIRY_TYPE_LICENCE_DAYS = 'licence_days' 86 EXPIRY_TYPE_FIXED_DAY = 'fixed_expiry_day' 87 88 def __init__(self, grant_type, quantity, type_id = None, soulbound = False, blueprint_runs = 0, blueprint_material_level = 0, blueprint_productivity_level = 0, licence_entitlement_id = '', licence_days = None, licence_expiry = None): 89 self._grant_type = grant_type 90 self._quantity = quantity 91 self._type_id = type_id 92 self._soulbound = soulbound 93 self._blueprint_runs = blueprint_runs 94 self._blueprint_material_level = blueprint_material_level 95 self._blueprint_productivity_level = blueprint_productivity_level 96 self._licence_entitlement_id = licence_entitlement_id 97 self._licence_days = licence_days 98 self._licence_expiry = licence_expiry 99 100 @property 101 def grant_type(self): 102 return self._grant_type 103 104 @property 105 def quantity(self): 106 return self._quantity 107 108 @property 109 def type_id(self): 110 return self._type_id 111 112 @property 113 def soulbound(self): 114 return self._soulbound 115 116 @property 117 def blueprint_runs(self): 118 return self._blueprint_runs 119 120 @property 121 def blueprint_material_level(self): 122 return self._blueprint_material_level 123 124 @property 125 def blueprint_productivity_level(self): 126 return self._blueprint_productivity_level 127 128 @property 129 def licence_entitlement_id(self): 130 return self._licence_entitlement_id 131 132 @property 133 def licence_days(self): 134 return self._licence_days 135 136 @property 137 def licence_expiry(self): 138 return self._licence_expiry 139 140 def is_eve_item(self): 141 return self.grant_type == self.GRANT_TYPE_EVE_ITEM 142 143 def is_blueprint_copy(self): 144 return self.grant_type == self.GRANT_TYPE_BLUEPRINT_COPY 145 146 def is_licence(self): 147 return self.grant_type == self.GRANT_TYPE_LICENCE 148 149 def is_plex(self): 150 return self.grant_type == self.GRANT_TYPE_PLEX 151 152 def has_type_id(self): 153 return self.type_id is not None 154 155 @classmethod 156 def build_from_proto(cls, payload): 157 grant_type = payload.WhichOneof('grant') 158 type_id = None 159 soulbound = False 160 blueprint_runs = 0 161 blueprint_material_level = 0 162 blueprint_productivity_level = 0 163 licence_entitlement_id = '' 164 licence_days = None 165 licence_expiry = None 166 if grant_type == cls.GRANT_TYPE_EVE_ITEM: 167 type_id = payload.eve_item.type_id.sequential 168 soulbound = payload.eve_item.soulbound 169 elif grant_type == cls.GRANT_TYPE_BLUEPRINT_COPY: 170 type_id = payload.blueprint_copy.type_id.sequential 171 blueprint_runs = payload.blueprint_copy.runs 172 blueprint_material_level = payload.blueprint_copy.material_level 173 blueprint_productivity_level = payload.blueprint_copy.productivity_level 174 elif grant_type == cls.GRANT_TYPE_LICENCE: 175 licence_entitlement_id = payload.licence.entitlement_id 176 expiry_type = payload.licence.WhichOneof('expiry') 177 if expiry_type == cls.EXPIRY_TYPE_LICENCE_DAYS: 178 licence_days = payload.licence.licence_days 179 elif expiry_type == cls.EXPIRY_TYPE_FIXED_DAY: 180 licence_expiry = datetime.fromtimestamp(payload.licence.fixed_expiry_day.ToSeconds()) 181 return TargetAudienceOfferGrantedProduct(grant_type=grant_type, quantity=payload.quantity, type_id=type_id, soulbound=soulbound, blueprint_runs=blueprint_runs, blueprint_material_level=blueprint_material_level, blueprint_productivity_level=blueprint_productivity_level, licence_entitlement_id=licence_entitlement_id, licence_days=licence_days, licence_expiry=licence_expiry) 182 183 @classmethod 184 def to_proto(cls, granted_product): 185 if granted_product.is_eve_item(): 186 return GrantedProduct(quantity=granted_product.quantity, eve_item=EveItemGrant(type_id=ItemTypeIdentifier(sequential=granted_product.type_id), soulbound=granted_product.soulbound)) 187 if granted_product.is_blueprint_copy(): 188 return GrantedProduct(quantity=granted_product.quantity, blueprint_copy=BlueprintCopyGrant(type_id=ItemTypeIdentifier(sequential=granted_product.type_id), runs=granted_product.blueprint_runs, material_level=granted_product.blueprint_material_level, productivity_level=granted_product.blueprint_productivity_level)) 189 if granted_product.is_licence(): 190 licence = LicenceGrant(entitlement_id=granted_product.licence_entitlement_id) 191 if granted_product.licence_days is not None: 192 licence.licence_days = granted_product.licence_days 193 elif granted_product.licence_expiry is not None: 194 licence.fixed_expiry_day.FromDatetime(granted_product.licence_expiry) 195 return GrantedProduct(quantity=granted_product.quantity, licence=licence) 196 if granted_product.is_plex(): 197 return GrantedProduct(quantity=granted_product.quantity, plex=PlexGrant()) 198 return GrantedProduct(quantity=granted_product.quantity) 199 200 def __eq__(self, other): 201 return other is not None and self.grant_type == other.grant_type and self.quantity == other.quantity and self.type_id == other.type_id and self.soulbound == other.soulbound and self.blueprint_runs == other.blueprint_runs and self.blueprint_material_level == other.blueprint_material_level and self.blueprint_productivity_level == other.blueprint_productivity_level and self.licence_entitlement_id == other.licence_entitlement_id and self.licence_days == other.licence_days and self.licence_expiry == other.licence_expiry 202 203 def __ne__(self, other): 204 return not self.__eq__(other) 205 206 207 class TargetAudienceOfferContent(object): 208 209 def __init__(self, name, title, description, quantity, thumbnail_url, granted_products): 210 self._name = name 211 self._title = title 212 self._description = description 213 self._quantity = quantity 214 self._thumbnail_url = thumbnail_url 215 self._granted_products = granted_products 216 217 @property 218 def name(self): 219 return self._name 220 221 @property 222 def title(self): 223 return self._title 224 225 @property 226 def description(self): 227 return self._description 228 229 @property 230 def quantity(self): 231 return self._quantity 232 233 @property 234 def thumbnail_url(self): 235 return self._thumbnail_url 236 237 @property 238 def granted_products(self): 239 return self._granted_products 240 241 def get_type_ids(self): 242 return [ x.type_id for x in self.granted_products if x.has_type_id() ] 243 244 @classmethod 245 def build_from_proto(cls, payload): 246 return TargetAudienceOfferContent(name=payload.name, title=_build_localized_text_from_proto(payload.title), description=_build_localized_text_from_proto(payload.description), quantity=payload.quantity, thumbnail_url=payload.thumbnail.signed_cdn_url, granted_products=[ TargetAudienceOfferGrantedProduct.build_from_proto(x) for x in payload.granted_products ]) 247 248 @classmethod 249 def to_proto(cls, content): 250 return Content(name=content.name, title=_localized_text_to_proto(content.title), description=_localized_text_to_proto(content.description), quantity=content.quantity, thumbnail=ImageResource(signed_cdn_url=content.thumbnail_url), granted_products=[ TargetAudienceOfferGrantedProduct.to_proto(x) for x in content.granted_products ]) 251 252 def __eq__(self, other): 253 return other is not None and self.name == other.name and self.title == other.title and self.description == other.description and self.quantity == other.quantity and self.thumbnail_url == other.thumbnail_url and self.granted_products == other.granted_products 254 255 def __ne__(self, other): 256 return not self.__eq__(other) 257 258 259 class TargetAudienceOffer(object): 260 261 def __init__(self, title, description, last_issued, expiry, thumbnail_url, contents, price, comparison_price, overlays, notification_types): 262 self._title = title 263 self._description = description 264 self._last_issued = last_issued 265 self._expiry = expiry 266 self._thumbnail_url = thumbnail_url 267 self._contents = contents 268 self._price = price 269 self._comparison_price = comparison_price 270 self._overlays = overlays 271 self._notification_types = notification_types 272 273 @property 274 def title(self): 275 return self._title 276 277 @property 278 def description(self): 279 return self._description 280 281 @property 282 def last_issued(self): 283 return self._last_issued 284 285 @property 286 def expiry(self): 287 return self._expiry 288 289 @property 290 def thumbnail_url(self): 291 return self._thumbnail_url 292 293 @property 294 def contents(self): 295 return self._contents 296 297 @property 298 def price(self): 299 return self._price 300 301 @property 302 def comparison_price(self): 303 return self._comparison_price 304 305 @property 306 def overlays(self): 307 return self._overlays 308 309 @property 310 def notification_types(self): 311 return self._notification_types 312 313 def has_comparison_price(self): 314 return self.comparison_price is not None 315 316 def get_type_ids(self): 317 return [ type_id for content in self.contents for type_id in content.get_type_ids() ] 318 319 @classmethod 320 def build_from_proto(cls, payload): 321 has_comparison_price = payload.WhichOneof('comparison_price_details') == 'comparison_price' 322 return TargetAudienceOffer(title=_build_localized_text_from_proto(payload.title), description=_build_localized_text_from_proto(payload.description), last_issued=datetime.fromtimestamp(payload.last_issued.ToSeconds()) if payload.HasField('last_issued') else None, expiry=datetime.fromtimestamp(payload.expiry.ToSeconds()) if payload.HasField('expiry') else None, thumbnail_url=payload.nes_thumbnail.signed_cdn_url, contents=[ TargetAudienceOfferContent.build_from_proto(x) for x in payload.contents ], price=TargetAudienceOfferPrice.build_from_proto(payload.price), comparison_price=TargetAudienceOfferPrice.build_from_proto(payload.comparison_price) if has_comparison_price else None, overlays=[ (x.name, 323 _build_localized_text_from_proto(x.displayed_text), 324 x.overlay_type, 325 x.display_type) for x in payload.overlays ], notification_types=[ x for x in payload.notification_types ]) 326 327 @classmethod 328 def to_proto(cls, offer): 329 payload = OfferAttributes(title=_localized_text_to_proto(offer.title), description=_localized_text_to_proto(offer.description), nes_thumbnail=ImageResource(signed_cdn_url=offer.thumbnail_url), contents=[ TargetAudienceOfferContent.to_proto(x) for x in offer.contents ], price=TargetAudienceOfferPrice.to_proto(offer.price), overlays=[ Overlay(name=name, displayed_text=_localized_text_to_proto(displayed_text), overlay_type=overlay_type, display_type=display_type) for name, displayed_text, overlay_type, display_type in offer.overlays ], notification_types=offer.notification_types) 330 if offer.last_issued is not None: 331 payload.last_issued.FromDatetime(offer.last_issued) 332 if offer.expiry is not None: 333 payload.expiry.FromDatetime(offer.expiry) 334 if offer.has_comparison_price(): 335 payload.comparison_price.CopyFrom(TargetAudienceOfferPrice.to_proto(offer.comparison_price)) 336 else: 337 payload.no_comparison_price = True 338 return payload 339 340 def __eq__(self, other): 341 return other is not None and self.title == other.title and self.description == other.description and self.last_issued == other.last_issued and self.expiry == other.expiry and self.thumbnail_url == other.thumbnail_url and self.contents == other.contents and self.price == other.price and self.comparison_price == other.comparison_price and self.overlays == other.overlays and self.notification_types == other.notification_types 342 343 def __ne__(self, other): 344 return not self.__eq__(other)