MouseTools 4.3.0__tar.gz → 4.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mousetools-4.3.0 → mousetools-4.4.0}/PKG-INFO +1 -1
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/api/menu.py +88 -82
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/api/search.py +2 -2
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/auth.py +11 -6
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/__init__.py +50 -27
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/calendar/__init__.py +33 -21
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/characters/__init__.py +3 -3
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/enums.py +11 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/facilities/__init__.py +79 -80
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/facilitystatus/__init__.py +35 -20
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/forecastedwaittimes/__init__.py +3 -3
- mousetools-4.4.0/mousetools/channels/today/__init__.py +121 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/decorators.py +23 -2
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/mixins/couchbase.py +16 -7
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/mixins/disney.py +4 -7
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/PKG-INFO +1 -1
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/SOURCES.txt +1 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/pyproject.toml +24 -3
- {mousetools-4.3.0 → mousetools-4.4.0}/LICENSE +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/README.md +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/__init__.py +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/api/__init__.py +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/facilities/enums.py +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/enums.py +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/mixins/__init__.py +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/resources/environments.bin +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/dependency_links.txt +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/requires.txt +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/top_level.txt +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/setup.cfg +0 -0
- {mousetools-4.3.0 → mousetools-4.4.0}/tests/test_mixins.py +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import logging
|
|
2
2
|
from datetime import datetime, timedelta
|
|
3
|
+
from typing import Optional
|
|
3
4
|
from zoneinfo import ZoneInfo
|
|
4
5
|
|
|
5
6
|
from dateutil.parser import isoparse
|
|
@@ -8,11 +9,11 @@ from mousetools.auth import auth_obj
|
|
|
8
9
|
from mousetools.decorators import disney_property, json_property
|
|
9
10
|
from mousetools.mixins.disney import DisneyAPIMixin
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class MenuItem:
|
|
15
|
-
def __init__(self, raw_item_data: dict, parent_resturant_id:
|
|
16
|
+
def __init__(self, raw_item_data: dict, parent_resturant_id: Optional[str] = None) -> None:
|
|
16
17
|
self._raw_item_data = raw_item_data
|
|
17
18
|
self._parent_restaurant_id = parent_resturant_id
|
|
18
19
|
|
|
@@ -20,118 +21,118 @@ class MenuItem:
|
|
|
20
21
|
return f"MenuItem(entity_id={self.entity_id}, parent_resturant_id={self._parent_restaurant_id})"
|
|
21
22
|
|
|
22
23
|
@json_property
|
|
23
|
-
def entity_id(self) ->
|
|
24
|
+
def entity_id(self) -> Optional[str]:
|
|
24
25
|
"""
|
|
25
26
|
The entity id of the menu item.
|
|
26
27
|
|
|
27
28
|
Returns:
|
|
28
|
-
(
|
|
29
|
+
(Optional[str]): The entity id of the menu item.
|
|
29
30
|
"""
|
|
30
31
|
return self._raw_item_data["id"]
|
|
31
32
|
|
|
32
33
|
@json_property
|
|
33
|
-
def pc_short_name(self) ->
|
|
34
|
+
def pc_short_name(self) -> Optional[str]:
|
|
34
35
|
"""
|
|
35
36
|
The short name of the menu item.
|
|
36
37
|
|
|
37
38
|
Returns:
|
|
38
|
-
(
|
|
39
|
+
(Optional[str]): The short name of the menu item.
|
|
39
40
|
"""
|
|
40
41
|
return self._raw_item_data["names"]["PCShort"]
|
|
41
42
|
|
|
42
43
|
@json_property
|
|
43
|
-
def pc_long_name(self) ->
|
|
44
|
+
def pc_long_name(self) -> Optional[str]:
|
|
44
45
|
"""
|
|
45
46
|
The long name of the menu item.
|
|
46
47
|
|
|
47
48
|
Returns:
|
|
48
|
-
(
|
|
49
|
+
(Optional[str]): The long name of the menu item.
|
|
49
50
|
"""
|
|
50
51
|
return self._raw_item_data["names"]["PCLong"]
|
|
51
52
|
|
|
52
53
|
@json_property
|
|
53
|
-
def mobile_short_name(self) ->
|
|
54
|
+
def mobile_short_name(self) -> Optional[str]:
|
|
54
55
|
"""
|
|
55
56
|
The short name of the menu item.
|
|
56
57
|
|
|
57
58
|
Returns:
|
|
58
|
-
(
|
|
59
|
+
(Optional[str]): The short name of the menu item.
|
|
59
60
|
"""
|
|
60
61
|
return self._raw_item_data["names"]["MobileShort"]
|
|
61
62
|
|
|
62
63
|
@json_property
|
|
63
|
-
def mobile_long_name(self) ->
|
|
64
|
+
def mobile_long_name(self) -> Optional[str]:
|
|
64
65
|
"""
|
|
65
66
|
The long name of the menu item.
|
|
66
67
|
|
|
67
68
|
Returns:
|
|
68
|
-
(
|
|
69
|
+
(Optional[str]): The long name of the menu item.
|
|
69
70
|
"""
|
|
70
71
|
return self._raw_item_data["names"]["MobileLong"]
|
|
71
72
|
|
|
72
73
|
@json_property
|
|
73
|
-
def mickey_check(self) ->
|
|
74
|
+
def mickey_check(self) -> Optional[bool]:
|
|
74
75
|
"""
|
|
75
76
|
Whether the menu item is mickey check.
|
|
76
77
|
|
|
77
78
|
Returns:
|
|
78
|
-
(
|
|
79
|
+
(Optional[bool]): Whether the menu item is mickey check.
|
|
79
80
|
"""
|
|
80
81
|
return self._raw_item_data["mickeyCheck"]
|
|
81
82
|
|
|
82
83
|
@json_property
|
|
83
|
-
def pc_long_description(self) ->
|
|
84
|
+
def pc_long_description(self) -> Optional[str]:
|
|
84
85
|
"""
|
|
85
86
|
The long description of the menu item.
|
|
86
87
|
|
|
87
88
|
Returns:
|
|
88
|
-
(
|
|
89
|
+
(Optional[str]): The long description of the menu item.
|
|
89
90
|
"""
|
|
90
91
|
return self._raw_item_data["descriptions"]["PCLong"]["text"]
|
|
91
92
|
|
|
92
93
|
@json_property
|
|
93
|
-
def mobile_short_description(self) ->
|
|
94
|
+
def mobile_short_description(self) -> Optional[str]:
|
|
94
95
|
"""
|
|
95
96
|
The short description of the menu item.
|
|
96
97
|
|
|
97
98
|
Returns:
|
|
98
|
-
(
|
|
99
|
+
(Optional[str]): The short description of the menu item.
|
|
99
100
|
"""
|
|
100
101
|
return self._raw_item_data["descriptions"]["MobileShort"]["text"]
|
|
101
102
|
|
|
102
103
|
@json_property
|
|
103
|
-
def default_selection(self) ->
|
|
104
|
+
def default_selection(self) -> Optional[bool]:
|
|
104
105
|
"""
|
|
105
106
|
Whether the menu item is the default selection.
|
|
106
107
|
|
|
107
108
|
Returns:
|
|
108
|
-
(
|
|
109
|
+
(Optional[bool]): Whether the menu item is the default selection.
|
|
109
110
|
"""
|
|
110
111
|
return self._raw_item_data["defaultSelection"]
|
|
111
112
|
|
|
112
113
|
@json_property
|
|
113
|
-
def prices(self) ->
|
|
114
|
+
def prices(self) -> Optional[dict]:
|
|
114
115
|
"""
|
|
115
116
|
The prices of the menu item.
|
|
116
117
|
|
|
117
118
|
Returns:
|
|
118
|
-
(
|
|
119
|
+
(Optional[dict]): The prices of the menu item.
|
|
119
120
|
"""
|
|
120
121
|
return self._raw_item_data["prices"]
|
|
121
122
|
|
|
122
123
|
@json_property
|
|
123
|
-
def per_serving_without_tax(self) ->
|
|
124
|
+
def per_serving_without_tax(self) -> Optional[float]:
|
|
124
125
|
"""
|
|
125
126
|
The per serving without tax of the menu item.
|
|
126
127
|
|
|
127
128
|
Returns:
|
|
128
|
-
(
|
|
129
|
+
(Optional[float]): The per serving without tax of the menu item.
|
|
129
130
|
"""
|
|
130
131
|
return self._raw_item_data["prices"]["PerServing"]["withoutTax"]
|
|
131
132
|
|
|
132
133
|
|
|
133
134
|
class MenuGroup:
|
|
134
|
-
def __init__(self, raw_menu_group_data: dict, parent_restaurant_id:
|
|
135
|
+
def __init__(self, raw_menu_group_data: dict, parent_restaurant_id: Optional[str] = None) -> None:
|
|
135
136
|
self._raw_menu_group_data = raw_menu_group_data
|
|
136
137
|
self._parent_restaurant_id = parent_restaurant_id
|
|
137
138
|
|
|
@@ -139,92 +140,92 @@ class MenuGroup:
|
|
|
139
140
|
return f"MenuGroup(menu_group_type={self.menu_group_type}, parent_restaurant_id={self._parent_restaurant_id})"
|
|
140
141
|
|
|
141
142
|
@json_property
|
|
142
|
-
def menu_group_type(self) ->
|
|
143
|
+
def menu_group_type(self) -> Optional[str]:
|
|
143
144
|
"""
|
|
144
145
|
The type of the menu group.
|
|
145
146
|
|
|
146
147
|
Returns:
|
|
147
|
-
(
|
|
148
|
+
(Optional[str]): The type of the menu group.
|
|
148
149
|
"""
|
|
149
150
|
return self._raw_menu_group_data["menuGroupType"]
|
|
150
151
|
|
|
151
152
|
@json_property
|
|
152
|
-
def multiple_price_types(self) ->
|
|
153
|
+
def multiple_price_types(self) -> Optional[bool]:
|
|
153
154
|
"""
|
|
154
155
|
Whether the menu group has multiple price types.
|
|
155
156
|
|
|
156
157
|
Returns:
|
|
157
|
-
(
|
|
158
|
+
(Optional[bool]): Whether the menu group has multiple price types.
|
|
158
159
|
"""
|
|
159
160
|
return self._raw_menu_group_data["multiplePriceTypes"]
|
|
160
161
|
|
|
161
162
|
@json_property
|
|
162
|
-
def mickey_check_items(self) ->
|
|
163
|
+
def mickey_check_items(self) -> Optional[bool]:
|
|
163
164
|
"""
|
|
164
165
|
Whether the menu group has mickey check items.
|
|
165
166
|
|
|
166
167
|
Returns:
|
|
167
|
-
(
|
|
168
|
+
(Optional[bool]): Whether the menu group has mickey check items.
|
|
168
169
|
"""
|
|
169
170
|
return self._raw_menu_group_data["mickeyCheckItems"]
|
|
170
171
|
|
|
171
172
|
@json_property
|
|
172
|
-
def names(self) ->
|
|
173
|
+
def names(self) -> Optional[dict]:
|
|
173
174
|
"""
|
|
174
175
|
The names of the menu group.
|
|
175
176
|
|
|
176
177
|
Returns:
|
|
177
|
-
(
|
|
178
|
+
(Optional[dict]): The names of the menu group.
|
|
178
179
|
"""
|
|
179
180
|
return self._raw_menu_group_data["names"]
|
|
180
181
|
|
|
181
182
|
@json_property
|
|
182
|
-
def pc_short_name(self) ->
|
|
183
|
+
def pc_short_name(self) -> Optional[str]:
|
|
183
184
|
"""
|
|
184
185
|
The short name of the menu group.
|
|
185
186
|
|
|
186
187
|
Returns:
|
|
187
|
-
(
|
|
188
|
+
(Optional[str]): The short name of the menu group.
|
|
188
189
|
"""
|
|
189
190
|
return self._raw_menu_group_data["names"]["PCShort"]
|
|
190
191
|
|
|
191
192
|
@json_property
|
|
192
|
-
def pc_long_name(self) ->
|
|
193
|
+
def pc_long_name(self) -> Optional[str]:
|
|
193
194
|
"""
|
|
194
195
|
The long name of the menu group.
|
|
195
196
|
|
|
196
197
|
Returns:
|
|
197
|
-
(
|
|
198
|
+
(Optional[str]): The long name of the menu group.
|
|
198
199
|
"""
|
|
199
200
|
return self._raw_menu_group_data["names"]["PCLong"]
|
|
200
201
|
|
|
201
202
|
@json_property
|
|
202
|
-
def mobile_short_name(self) ->
|
|
203
|
+
def mobile_short_name(self) -> Optional[str]:
|
|
203
204
|
"""
|
|
204
205
|
The short name of the menu group.
|
|
205
206
|
|
|
206
207
|
Returns:
|
|
207
|
-
(
|
|
208
|
+
(Optional[str]): The short name of the menu group.
|
|
208
209
|
"""
|
|
209
210
|
return self._raw_menu_group_data["names"]["MobileShort"]
|
|
210
211
|
|
|
211
212
|
@json_property
|
|
212
|
-
def mobile_long_name(self) ->
|
|
213
|
+
def mobile_long_name(self) -> Optional[str]:
|
|
213
214
|
"""
|
|
214
215
|
The long name of the menu group.
|
|
215
216
|
|
|
216
217
|
Returns:
|
|
217
|
-
(
|
|
218
|
+
(Optional[str]): The long name of the menu group.
|
|
218
219
|
"""
|
|
219
220
|
return self._raw_menu_group_data["names"]["MobileLong"]
|
|
220
221
|
|
|
221
222
|
@property
|
|
222
|
-
def menu_items(self) ->
|
|
223
|
+
def menu_items(self) -> Optional[list[MenuItem]]:
|
|
223
224
|
"""
|
|
224
225
|
The menu items of the menu group.
|
|
225
226
|
|
|
226
227
|
Returns:
|
|
227
|
-
(
|
|
228
|
+
(Optional[list[MenuItem]]): The menu items of the menu group.
|
|
228
229
|
"""
|
|
229
230
|
try:
|
|
230
231
|
return [MenuItem(i, self._parent_restaurant_id) for i in self._raw_menu_group_data["menuItems"]]
|
|
@@ -233,80 +234,80 @@ class MenuGroup:
|
|
|
233
234
|
|
|
234
235
|
|
|
235
236
|
class Menu:
|
|
236
|
-
def __init__(self, raw_menu_data: dict, parent_restaurant_id:
|
|
237
|
+
def __init__(self, raw_menu_data: dict, parent_restaurant_id: Optional[str] = None) -> None:
|
|
237
238
|
self._raw_menu_data = raw_menu_data
|
|
238
239
|
self._parent_restaurant_id = parent_restaurant_id
|
|
239
240
|
|
|
240
|
-
def __str__(self):
|
|
241
|
+
def __str__(self) -> str:
|
|
241
242
|
return f"Menu(entity_id={self.entity_id}, menu_type={self.menu_type}, parent_restaurant_id={self._parent_restaurant_id})"
|
|
242
243
|
|
|
243
244
|
@json_property
|
|
244
|
-
def entity_id(self) ->
|
|
245
|
+
def entity_id(self) -> Optional[str]:
|
|
245
246
|
"""
|
|
246
247
|
The entity id of the menu.
|
|
247
248
|
|
|
248
249
|
Returns:
|
|
249
|
-
(
|
|
250
|
+
(Optional[str]): The entity id of the menu.
|
|
250
251
|
"""
|
|
251
252
|
return self._raw_menu_data["id"]
|
|
252
253
|
|
|
253
254
|
@json_property
|
|
254
|
-
def menu_type(self) ->
|
|
255
|
+
def menu_type(self) -> Optional[str]:
|
|
255
256
|
"""
|
|
256
257
|
The type of the menu.
|
|
257
258
|
|
|
258
259
|
Returns:
|
|
259
|
-
(
|
|
260
|
+
(Optional[str]): The type of the menu.
|
|
260
261
|
"""
|
|
261
262
|
return self._raw_menu_data["menuType"]
|
|
262
263
|
|
|
263
264
|
@json_property
|
|
264
|
-
def localized_menu_type(self) ->
|
|
265
|
+
def localized_menu_type(self) -> Optional[str]:
|
|
265
266
|
"""
|
|
266
267
|
The localized type of the menu.
|
|
267
268
|
|
|
268
269
|
Returns:
|
|
269
|
-
(
|
|
270
|
+
(Optional[str]): The localized type of the menu.
|
|
270
271
|
"""
|
|
271
272
|
return self._raw_menu_data["localizedMenuType"]
|
|
272
273
|
|
|
273
274
|
@json_property
|
|
274
|
-
def experience_type(self) ->
|
|
275
|
+
def experience_type(self) -> Optional[str]:
|
|
275
276
|
"""
|
|
276
277
|
The experience type of the menu.
|
|
277
278
|
|
|
278
279
|
Returns:
|
|
279
|
-
(
|
|
280
|
+
(Optional[str]): The experience type of the menu.
|
|
280
281
|
"""
|
|
281
282
|
return self._raw_menu_data["experienceType"]
|
|
282
283
|
|
|
283
284
|
@json_property
|
|
284
|
-
def service_style(self) ->
|
|
285
|
+
def service_style(self) -> Optional[str]:
|
|
285
286
|
"""
|
|
286
287
|
The service style of the menu.
|
|
287
288
|
|
|
288
289
|
Returns:
|
|
289
|
-
(
|
|
290
|
+
(Optional[str]): The service style of the menu.
|
|
290
291
|
"""
|
|
291
292
|
return self._raw_menu_data["serviceStyle"]
|
|
292
293
|
|
|
293
294
|
@json_property
|
|
294
|
-
def primary_cuisine_type(self) ->
|
|
295
|
+
def primary_cuisine_type(self) -> Optional[str]:
|
|
295
296
|
"""
|
|
296
297
|
The primary cuisine type of the menu.
|
|
297
298
|
|
|
298
299
|
Returns:
|
|
299
|
-
(
|
|
300
|
+
(Optional[str]): The primary cuisine type of the menu.
|
|
300
301
|
"""
|
|
301
302
|
return self._raw_menu_data["primaryCuisineType"]
|
|
302
303
|
|
|
303
304
|
@json_property
|
|
304
|
-
def secondary_cuisine_type(self) ->
|
|
305
|
+
def secondary_cuisine_type(self) -> Optional[str]:
|
|
305
306
|
"""
|
|
306
307
|
The secondary cuisine type of the menu.
|
|
307
308
|
|
|
308
309
|
Returns:
|
|
309
|
-
(
|
|
310
|
+
(Optional[str]): The secondary cuisine type of the menu.
|
|
310
311
|
"""
|
|
311
312
|
return self._raw_menu_data["secondaryCuisineType"]
|
|
312
313
|
|
|
@@ -329,7 +330,7 @@ class Menus(DisneyAPIMixin):
|
|
|
329
330
|
|
|
330
331
|
_menu_service_base = f"{auth_obj._environments['serviceMenuUrl']}/diningMenuSvc/orchestration/menus"
|
|
331
332
|
|
|
332
|
-
def __init__(self, restaurant_channel_id: str, lazy_load: bool = True):
|
|
333
|
+
def __init__(self, restaurant_channel_id: str, lazy_load: bool = True) -> None:
|
|
333
334
|
self.entity_id = restaurant_channel_id.rsplit(".", 1)[-1]
|
|
334
335
|
self._menu_service_url = f"{self._menu_service_base}/{self.entity_id}"
|
|
335
336
|
|
|
@@ -338,20 +339,30 @@ class Menus(DisneyAPIMixin):
|
|
|
338
339
|
) # properties are rarely updated, no need to spam the API
|
|
339
340
|
self._tz = ZoneInfo("UTC")
|
|
340
341
|
|
|
341
|
-
self._disney_data:
|
|
342
|
+
self._disney_data: Optional[dict] = None
|
|
342
343
|
self._disney_data_pull_time: datetime = datetime.now(tz=self._tz)
|
|
343
344
|
if not lazy_load:
|
|
344
345
|
self.refresh()
|
|
345
346
|
|
|
346
|
-
def __str__(self):
|
|
347
|
+
def __str__(self) -> str:
|
|
347
348
|
return f"Menus(entity_id={self.entity_id})"
|
|
348
349
|
|
|
349
|
-
def __repr__(self):
|
|
350
|
+
def __repr__(self) -> str:
|
|
350
351
|
return f"Menus(restaurant_channel_id={self.entity_id})"
|
|
351
352
|
|
|
352
353
|
def refresh(self) -> None:
|
|
353
354
|
"""Pulls initial data if none exists or if it is older than the refresh interval"""
|
|
354
|
-
|
|
355
|
+
no_data_check = self._disney_data is None
|
|
356
|
+
time_since_pull = datetime.now(tz=self._tz) - self._disney_data_pull_time
|
|
357
|
+
old_data_check = time_since_pull > self._refresh_interval
|
|
358
|
+
logger.debug(
|
|
359
|
+
"No data check: %s, Time since last update: %s, Old data check: %s",
|
|
360
|
+
no_data_check,
|
|
361
|
+
time_since_pull,
|
|
362
|
+
old_data_check,
|
|
363
|
+
)
|
|
364
|
+
if no_data_check or old_data_check:
|
|
365
|
+
logger.info("Refreshing menu data %s", self.entity_id)
|
|
355
366
|
self._disney_data = self.get_disney_data(self._menu_service_url)
|
|
356
367
|
self._disney_data_pull_time = datetime.now(tz=self._tz)
|
|
357
368
|
|
|
@@ -367,48 +378,43 @@ class Menus(DisneyAPIMixin):
|
|
|
367
378
|
return [Menu(i, self.entity_id) for i in self._disney_data["menus"]]
|
|
368
379
|
|
|
369
380
|
@disney_property()
|
|
370
|
-
def facility_name(self) ->
|
|
381
|
+
def facility_name(self) -> Optional[str]:
|
|
371
382
|
"""
|
|
372
383
|
The name of the facility.
|
|
373
384
|
|
|
374
385
|
Returns:
|
|
375
|
-
(
|
|
386
|
+
(Optional[str]): The name of the facility.
|
|
376
387
|
"""
|
|
377
388
|
return self._disney_data["facilityName"]
|
|
378
389
|
|
|
379
390
|
@disney_property()
|
|
380
|
-
def ancestor_location_park_resort(self) ->
|
|
391
|
+
def ancestor_location_park_resort(self) -> Optional[str]:
|
|
381
392
|
"""
|
|
382
393
|
The name of the ancestor location.
|
|
383
394
|
|
|
384
395
|
Returns:
|
|
385
|
-
(
|
|
396
|
+
(Optional[str]): The name of the ancestor location.
|
|
386
397
|
"""
|
|
387
398
|
return self._disney_data["ancestorLocationParkResort"]
|
|
388
399
|
|
|
389
400
|
@disney_property()
|
|
390
|
-
def ancestor_location_land_area(self) ->
|
|
401
|
+
def ancestor_location_land_area(self) -> Optional[str]:
|
|
391
402
|
"""
|
|
392
403
|
The name of the ancestor location.
|
|
393
404
|
|
|
394
405
|
Returns:
|
|
395
|
-
(
|
|
406
|
+
(Optional[str]): The name of the ancestor location.
|
|
396
407
|
"""
|
|
397
408
|
return self._disney_data["ancestorLocationLandArea"]
|
|
398
409
|
|
|
399
|
-
@
|
|
400
|
-
def last_refresh(self) -> datetime:
|
|
410
|
+
@disney_property()
|
|
411
|
+
def last_refresh(self) -> Optional[datetime]:
|
|
401
412
|
"""
|
|
402
413
|
The last time the menus were refreshed.
|
|
403
414
|
|
|
404
415
|
Returns:
|
|
405
|
-
(datetime): The last time the menus were refreshed.
|
|
416
|
+
(Optional[datetime]): The last time the menus were refreshed.
|
|
406
417
|
"""
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
refresh_time = isoparse(self._disney_data["lastRefresh"])
|
|
411
|
-
refresh_time = refresh_time.replace(tzinfo=self._tz)
|
|
412
|
-
return refresh_time
|
|
413
|
-
except (KeyError, TypeError, ValueError):
|
|
414
|
-
return self._disney_data_pull_time
|
|
418
|
+
refresh_time = isoparse(self._disney_data["lastRefresh"])
|
|
419
|
+
refresh_time = refresh_time.replace(tzinfo=self._tz)
|
|
420
|
+
return refresh_time
|
|
@@ -9,7 +9,7 @@ from mousetools.mixins.disney import DisneyAPIMixin
|
|
|
9
9
|
class Search(DisneyAPIMixin):
|
|
10
10
|
_search_service_base = auth_obj._environments["searchServiceUrl"]
|
|
11
11
|
|
|
12
|
-
def __init__(self, destination: Union[DestinationShort, str]):
|
|
12
|
+
def __init__(self, destination: Union[DestinationShort, str]) -> None:
|
|
13
13
|
"""
|
|
14
14
|
Args:
|
|
15
15
|
destination (Union[DestinationShort, str]): Search the facilities for this destination
|
|
@@ -54,5 +54,5 @@ class Search(DisneyAPIMixin):
|
|
|
54
54
|
"""
|
|
55
55
|
return self.search(*args, **kwargs)
|
|
56
56
|
|
|
57
|
-
def __repr__(self):
|
|
57
|
+
def __repr__(self) -> str:
|
|
58
58
|
return f"Search(destination='{self.destination}')"
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import json
|
|
3
|
-
import
|
|
3
|
+
import logging
|
|
4
4
|
from datetime import datetime, timedelta
|
|
5
5
|
from importlib.resources import as_file, files
|
|
6
|
+
from typing import Optional
|
|
6
7
|
|
|
7
8
|
import httpx
|
|
8
9
|
from Crypto.Cipher import AES
|
|
9
10
|
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
10
13
|
|
|
11
14
|
class Authentication:
|
|
12
|
-
def __init__(self):
|
|
13
|
-
self.time_of_expire:
|
|
14
|
-
self.access_token:
|
|
15
|
+
def __init__(self) -> None:
|
|
16
|
+
self.time_of_expire: Optional[datetime] = None
|
|
17
|
+
self.access_token: Optional[str] = None
|
|
15
18
|
self._environments = self._decrypt_file("resources/environments.bin").get("production", {})
|
|
16
19
|
|
|
17
20
|
def authenticate(self) -> tuple[str, int]:
|
|
@@ -38,6 +41,7 @@ class Authentication:
|
|
|
38
41
|
"client_id": self._environments["authzClientId"],
|
|
39
42
|
}
|
|
40
43
|
|
|
44
|
+
logger.debug("Sending request for authentication token")
|
|
41
45
|
response = httpx.post(
|
|
42
46
|
f"{self._environments['authzServiceUrl']}/token",
|
|
43
47
|
headers=headers,
|
|
@@ -57,6 +61,7 @@ class Authentication:
|
|
|
57
61
|
"""
|
|
58
62
|
|
|
59
63
|
if self.time_of_expire is None or (datetime.now() > self.time_of_expire):
|
|
64
|
+
logger.info("Requesting new authentication token")
|
|
60
65
|
access_token, expires_in = self.authenticate()
|
|
61
66
|
self.time_of_expire = datetime.now() + timedelta(seconds=(expires_in - 10))
|
|
62
67
|
self.access_token = access_token
|
|
@@ -95,7 +100,7 @@ class Authentication:
|
|
|
95
100
|
decrypted = cipher.decrypt(file.read())
|
|
96
101
|
return json.loads(decrypted.decode("Windows-1252")[:-16])
|
|
97
102
|
|
|
98
|
-
def _e(self):
|
|
103
|
+
def _e(self) -> bytes:
|
|
99
104
|
s = ""
|
|
100
105
|
for i in range(1, 17):
|
|
101
106
|
if i % 2 != 0 or i >= 16:
|
|
@@ -105,7 +110,7 @@ class Authentication:
|
|
|
105
110
|
bytes_ = s.encode("utf-8")
|
|
106
111
|
return bytes_
|
|
107
112
|
|
|
108
|
-
def _b(self):
|
|
113
|
+
def _b(self) -> bytes:
|
|
109
114
|
return bytes(reversed(self._e()))
|
|
110
115
|
|
|
111
116
|
|