|
4 | 4 | from http import HTTPStatus
|
5 | 5 | from typing import Any, Union
|
6 | 6 |
|
| 7 | +import babel.numbers |
7 | 8 | import humanize
|
8 | 9 | import requests
|
9 | 10 |
|
@@ -52,44 +53,64 @@ class Item:
|
52 | 53 | returns well formated data for notifications.
|
53 | 54 | """
|
54 | 55 |
|
55 |
| - def __init__(self, data: dict, location: Union[Location, None] = None): |
56 |
| - self.items_available = data.get("items_available", 0) |
57 |
| - self.display_name = data.get("display_name", "-") |
58 |
| - self.favorite = "Yes" if data.get("favorite", False) else "No" |
59 |
| - self.pickup_interval_start = data.get("pickup_interval", {}).get("start", None) |
60 |
| - self.pickup_interval_end = data.get("pickup_interval", {}).get("end", None) |
61 |
| - self.pickup_location = data.get("pickup_location", {}).get("address", {}).get("address_line", "-") |
62 |
| - |
63 |
| - item = data.get("item", {}) |
64 |
| - self.item_id = item.get("item_id") |
65 |
| - self.rating = item.get("average_overall_rating", {}).get("average_overall_rating", None) |
66 |
| - self.rating = "-" if not self.rating else f"{self.rating:.1f}" |
67 |
| - self.packaging_option = item.get("packaging_option", "-") |
68 |
| - self.item_name = item.get("name", "-") |
69 |
| - self.buffet = "Yes" if item.get("buffet", False) else "No" |
70 |
| - self.item_category = item.get("item_category", "-") |
71 |
| - self.description = item.get("description", "-") |
72 |
| - item_price = item.get("item_price", {}) |
73 |
| - item_value = item.get("item_value", {}) |
74 |
| - price = item_price.get("minor_units", 0) / 10 ** item_price.get("decimals", 0) |
75 |
| - value = item_value.get("minor_units", 0) / 10 ** item_value.get("decimals", 0) |
76 |
| - self.price = f"{price:.2f}" |
77 |
| - self.value = f"{value:.2f}" |
78 |
| - self.currency = item_price.get("code", "-") |
79 |
| - self.item_logo = item.get("logo_picture", {}).get( |
| 56 | + def __init__(self, data: dict, location: Union[Location, None] = None, locale: str = "en_US"): |
| 57 | + self.items_available: int = data.get("items_available", 0) |
| 58 | + self.display_name: str = data.get("display_name", "-") |
| 59 | + self.favorite: str = "Yes" if data.get("favorite", False) else "No" |
| 60 | + self.pickup_interval_start: Union[str, None] = data.get("pickup_interval", {}).get("start", None) |
| 61 | + self.pickup_interval_end: Union[str, None] = data.get("pickup_interval", {}).get("end", None) |
| 62 | + self.pickup_location: str = data.get("pickup_location", {}).get("address", {}).get("address_line", "-") |
| 63 | + |
| 64 | + item: dict = data.get("item", {}) |
| 65 | + self.item_id: str = item.get("item_id", None) |
| 66 | + self._rating: Union[float, None] = item.get("average_overall_rating", {}).get("average_overall_rating", None) |
| 67 | + self.packaging_option: str = item.get("packaging_option", "-") |
| 68 | + self.item_name: str = item.get("name", "-") |
| 69 | + self.buffet: str = "Yes" if item.get("buffet", False) else "No" |
| 70 | + self.item_category: str = item.get("item_category", "-") |
| 71 | + self.description: str = item.get("description", "-") |
| 72 | + item_price: dict = item.get("item_price", {}) |
| 73 | + item_value: dict = item.get("item_value", {}) |
| 74 | + self._price: float = item_price.get("minor_units", 0) / 10 ** item_price.get("decimals", 0) |
| 75 | + self._value: float = item_value.get("minor_units", 0) / 10 ** item_value.get("decimals", 0) |
| 76 | + self.currency: str = item_price.get("code", "-") |
| 77 | + self.item_logo: str = item.get("logo_picture", {}).get( |
80 | 78 | "current_url",
|
81 | 79 | "https://tgtg-mkt-cms-prod.s3.eu-west-1.amazonaws.com/13512/TGTG_Icon_White_Cirle_1988x1988px_RGB.png",
|
82 | 80 | )
|
83 |
| - self.item_cover = item.get("cover_picture", {}).get( |
| 81 | + self.item_cover: str = item.get("cover_picture", {}).get( |
84 | 82 | "current_url",
|
85 | 83 | "https://images.tgtg.ninja/standard_images/GENERAL/other1.jpg",
|
86 | 84 | )
|
87 | 85 |
|
88 |
| - store = data.get("store", {}) |
89 |
| - self.store_name = store.get("store_name", "-") |
| 86 | + store: dict = data.get("store", {}) |
| 87 | + self.store_name: str = store.get("store_name", "-") |
90 | 88 |
|
91 |
| - self.scanned_on = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
| 89 | + self.scanned_on: str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
92 | 90 | self.location = location
|
| 91 | + self.locale = locale |
| 92 | + |
| 93 | + @property |
| 94 | + def rating(self) -> str: |
| 95 | + if self._rating is None: |
| 96 | + return "-" |
| 97 | + return self._format_decimal(round(self._rating, 1)) |
| 98 | + |
| 99 | + @property |
| 100 | + def price(self) -> str: |
| 101 | + return self._format_currency(self._price) |
| 102 | + |
| 103 | + @property |
| 104 | + def value(self) -> str: |
| 105 | + return self._format_currency(self._value) |
| 106 | + |
| 107 | + def _format_decimal(self, number: float) -> str: |
| 108 | + return babel.numbers.format_decimal(number, locale=self.locale) |
| 109 | + |
| 110 | + def _format_currency(self, number: float) -> str: |
| 111 | + if self.currency == "-": |
| 112 | + return self._format_decimal(number) |
| 113 | + return babel.numbers.format_currency(number, self.currency, locale=self.locale) |
93 | 114 |
|
94 | 115 | @staticmethod
|
95 | 116 | def _datetimeparse(datestr: str) -> datetime.datetime:
|
@@ -155,18 +176,18 @@ def pickupdate(self) -> str:
|
155 | 176 | """
|
156 | 177 | Returns a well formated string, providing the pickup time range
|
157 | 178 | """
|
158 |
| - if self.pickup_interval_start and self.pickup_interval_end: |
159 |
| - now = datetime.datetime.now() |
160 |
| - pfr = self._datetimeparse(self.pickup_interval_start) |
161 |
| - pto = self._datetimeparse(self.pickup_interval_end) |
162 |
| - prange = f"{pfr.hour:02d}:{pfr.minute:02d} - {pto.hour:02d}:{pto.minute:02d}" |
163 |
| - tommorow = now + datetime.timedelta(days=1) |
164 |
| - if now.date() == pfr.date(): |
165 |
| - return f"{humanize.naturalday(now)}, {prange}" |
166 |
| - if (pfr.date() - now.date()).days == 1: |
167 |
| - return f"{humanize.naturalday(tommorow)}, {prange}" |
168 |
| - return f"{pfr.day}/{pfr.month}, {prange}" |
169 |
| - return "-" |
| 179 | + if self.pickup_interval_start is None or self.pickup_interval_end is None: |
| 180 | + return "-" |
| 181 | + now = datetime.datetime.now() |
| 182 | + pfr = self._datetimeparse(self.pickup_interval_start) |
| 183 | + pto = self._datetimeparse(self.pickup_interval_end) |
| 184 | + prange = f"{pfr.hour:02d}:{pfr.minute:02d} - {pto.hour:02d}:{pto.minute:02d}" |
| 185 | + tommorow = now + datetime.timedelta(days=1) |
| 186 | + if now.date() == pfr.date(): |
| 187 | + return f"{humanize.naturalday(now)}, {prange}" |
| 188 | + if (pfr.date() - now.date()).days == 1: |
| 189 | + return f"{humanize.naturalday(tommorow)}, {prange}" |
| 190 | + return f"{pfr.day}/{pfr.month}, {prange}" |
170 | 191 |
|
171 | 192 | def _get_distance_time(self, travel_mode: str) -> Union[DistanceTime, None]:
|
172 | 193 | if self.location is None:
|
|
0 commit comments