MouseTools 3.1.0.dev2__py3-none-any.whl → 4.0.0__py3-none-any.whl

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.
Files changed (42) hide show
  1. mousetools/__init__.py +1 -1
  2. mousetools/api/__init__.py +0 -0
  3. mousetools/api/menu.py +433 -0
  4. mousetools/auth.py +49 -7
  5. mousetools/channels/__init__.py +46 -0
  6. mousetools/channels/enums.py +67 -0
  7. mousetools/channels/facilities/__init__.py +520 -0
  8. mousetools/channels/facilities/enums.py +30 -0
  9. mousetools/channels/facilitystatus/__init__.py +153 -0
  10. mousetools/mixins/couchbase.py +80 -0
  11. mousetools/mixins/disney.py +3 -22
  12. mousetools/resources/environments.bin +0 -0
  13. mousetools-4.0.0.dist-info/METADATA +108 -0
  14. mousetools-4.0.0.dist-info/RECORD +18 -0
  15. {MouseTools-3.1.0.dev2.dist-info → mousetools-4.0.0.dist-info}/WHEEL +1 -1
  16. {MouseTools-3.1.0.dev2.dist-info → mousetools-4.0.0.dist-info/licenses}/LICENSE +1 -1
  17. MouseTools-3.1.0.dev2.dist-info/METADATA +0 -78
  18. MouseTools-3.1.0.dev2.dist-info/RECORD +0 -32
  19. mousetools/entities/__init__.py +0 -43
  20. mousetools/entities/attraction.py +0 -12
  21. mousetools/entities/base.py +0 -488
  22. mousetools/entities/character.py +0 -12
  23. mousetools/entities/destination.py +0 -16
  24. mousetools/entities/dining_event.py +0 -12
  25. mousetools/entities/dinner_show.py +0 -12
  26. mousetools/entities/entertainment.py +0 -12
  27. mousetools/entities/entertainment_venue.py +0 -12
  28. mousetools/entities/event.py +0 -12
  29. mousetools/entities/guest_services.py +0 -12
  30. mousetools/entities/land.py +0 -12
  31. mousetools/entities/menu.py +0 -226
  32. mousetools/entities/merchandise_facility.py +0 -12
  33. mousetools/entities/park.py +0 -42
  34. mousetools/entities/point_of_interest.py +0 -12
  35. mousetools/entities/resort.py +0 -12
  36. mousetools/entities/resort_area.py +0 -12
  37. mousetools/entities/restaurant.py +0 -53
  38. mousetools/exceptions.py +0 -17
  39. mousetools/ids.py +0 -96
  40. mousetools/mixins/themeparksapi.py +0 -128
  41. mousetools/urls.py +0 -4
  42. {MouseTools-3.1.0.dev2.dist-info → mousetools-4.0.0.dist-info}/top_level.txt +0 -0
mousetools/__init__.py CHANGED
@@ -3,5 +3,5 @@ import logging
3
3
  logger = logging.getLogger(__name__)
4
4
  logger.addHandler(logging.NullHandler())
5
5
 
6
- __version__ = "3.1.0-dev.2" # will be set at runtime
6
+ __version__ = "0.0.0" # will be set at runtime
7
7
  logger.info(f"MouseTools version: {__version__}")
File without changes
mousetools/api/menu.py ADDED
@@ -0,0 +1,433 @@
1
+ import typing
2
+
3
+ from mousetools.auth import auth_obj
4
+ from mousetools.mixins.disney import DisneyAPIMixin
5
+
6
+ # menus -> menu -> menugroups -> menuitems
7
+
8
+
9
+ class MenuItem:
10
+ def __init__(self, raw_item_data: dict, parent_resturant_id: typing.Optional[str] = None):
11
+ self._raw_item_data = raw_item_data
12
+ self._parent_restaurant_id = parent_resturant_id
13
+
14
+ def __repr__(self) -> str:
15
+ return f"MenuItem(entity_id={self.entity_id}, parent_resturant_id={self._parent_restaurant_id})"
16
+
17
+ @property
18
+ def entity_id(self) -> typing.Optional[str]:
19
+ """
20
+ The entity id of the menu item.
21
+
22
+ Returns:
23
+ (typing.Optional[str]): The entity id of the menu item.
24
+ """
25
+ try:
26
+ return self._raw_item_data["id"]
27
+ except KeyError:
28
+ return None
29
+
30
+ @property
31
+ def pc_short_name(self) -> typing.Optional[str]:
32
+ """
33
+ The short name of the menu item.
34
+
35
+ Returns:
36
+ (typing.Optional[str]): The short name of the menu item.
37
+ """
38
+ try:
39
+ return self._raw_item_data["names"]["PCShort"]
40
+ except KeyError:
41
+ return None
42
+
43
+ @property
44
+ def pc_long_name(self) -> typing.Optional[str]:
45
+ """
46
+ The long name of the menu item.
47
+
48
+ Returns:
49
+ (typing.Optional[str]): The long name of the menu item.
50
+ """
51
+ try:
52
+ return self._raw_item_data["names"]["PCLong"]
53
+ except KeyError:
54
+ return None
55
+
56
+ @property
57
+ def mobile_short_name(self) -> typing.Optional[str]:
58
+ """
59
+ The short name of the menu item.
60
+
61
+ Returns:
62
+ (typing.Optional[str]): The short name of the menu item.
63
+ """
64
+ try:
65
+ return self._raw_item_data["names"]["MobileShort"]
66
+ except KeyError:
67
+ return None
68
+
69
+ @property
70
+ def mobile_long_name(self) -> typing.Optional[str]:
71
+ """
72
+ The long name of the menu item.
73
+
74
+ Returns:
75
+ (typing.Optional[str]): The long name of the menu item.
76
+ """
77
+ try:
78
+ return self._raw_item_data["names"]["MobileLong"]
79
+ except KeyError:
80
+ return None
81
+
82
+ @property
83
+ def mickey_check(self) -> typing.Optional[bool]:
84
+ """
85
+ Whether the menu item is mickey check.
86
+
87
+ Returns:
88
+ (typing.Optional[bool]): Whether the menu item is mickey check.
89
+ """
90
+ try:
91
+ return self._raw_item_data["mickeyCheck"]
92
+ except KeyError:
93
+ return None
94
+
95
+ @property
96
+ def pc_long_description(self) -> typing.Optional[str]:
97
+ """
98
+ The long description of the menu item.
99
+
100
+ Returns:
101
+ (typing.Optional[str]): The long description of the menu item.
102
+ """
103
+ try:
104
+ return self._raw_item_data["descriptions"]["PCLong"]["text"]
105
+ except KeyError:
106
+ return None
107
+
108
+ @property
109
+ def mobile_short_description(self) -> typing.Optional[str]:
110
+ """
111
+ The short description of the menu item.
112
+
113
+ Returns:
114
+ (typing.Optional[str]): The short description of the menu item.
115
+ """
116
+ try:
117
+ return self._raw_item_data["descriptions"]["MobileShort"]["text"]
118
+ except KeyError:
119
+ return None
120
+
121
+ @property
122
+ def default_selection(self) -> typing.Optional[bool]:
123
+ """
124
+ Whether the menu item is the default selection.
125
+
126
+ Returns:
127
+ (typing.Optional[bool]): Whether the menu item is the default selection.
128
+ """
129
+ try:
130
+ return self._raw_item_data["defaultSelection"]
131
+ except KeyError:
132
+ return None
133
+
134
+ @property
135
+ def prices(self) -> typing.Optional[dict]:
136
+ """
137
+ The prices of the menu item.
138
+
139
+ Returns:
140
+ (typing.Optional[dict]): The prices of the menu item.
141
+ """
142
+ try:
143
+ return self._raw_item_data["prices"]
144
+ except KeyError:
145
+ return None
146
+
147
+ @property
148
+ def per_serving_without_tax(self) -> typing.Optional[float]:
149
+ """
150
+ The per serving without tax of the menu item.
151
+
152
+ Returns:
153
+ (typing.Optional[float]): The per serving without tax of the menu item.
154
+ """
155
+ try:
156
+ return self._raw_item_data["prices"]["PerServing"]["withoutTax"]
157
+ except KeyError:
158
+ return None
159
+
160
+
161
+ class MenuGroup:
162
+ def __init__(self, raw_menu_group_data: dict, parent_restaurant_id: typing.Optional[str] = None):
163
+ self._raw_menu_group_data = raw_menu_group_data
164
+ self._parent_restaurant_id = parent_restaurant_id
165
+
166
+ def __str__(self) -> str:
167
+ return f"MenuGroup(menu_group_type={self.menu_group_type}, parent_restaurant_id={self._parent_restaurant_id})"
168
+
169
+ @property
170
+ def menu_group_type(self) -> typing.Optional[str]:
171
+ """
172
+ The type of the menu group.
173
+
174
+ Returns:
175
+ (typing.Optional[str]): The type of the menu group.
176
+ """
177
+ try:
178
+ return self._raw_menu_group_data["menuGroupType"]
179
+ except KeyError:
180
+ return None
181
+
182
+ @property
183
+ def multiple_price_types(self) -> typing.Optional[bool]:
184
+ """
185
+ Whether the menu group has multiple price types.
186
+
187
+ Returns:
188
+ (typing.Optional[bool]): Whether the menu group has multiple price types.
189
+ """
190
+ try:
191
+ return self._raw_menu_group_data["multiplePriceTypes"]
192
+ except KeyError:
193
+ return None
194
+
195
+ @property
196
+ def mickey_check_items(self) -> typing.Optional[bool]:
197
+ """
198
+ Whether the menu group has mickey check items.
199
+
200
+ Returns:
201
+ (typing.Optional[bool]): Whether the menu group has mickey check items.
202
+ """
203
+ try:
204
+ return self._raw_menu_group_data["mickeyCheckItems"]
205
+ except KeyError:
206
+ return None
207
+
208
+ @property
209
+ def names(self) -> typing.Optional[dict]:
210
+ """
211
+ The names of the menu group.
212
+
213
+ Returns:
214
+ (typing.Optional[dict]): The names of the menu group.
215
+ """
216
+ try:
217
+ return self._raw_menu_group_data["names"]
218
+ except KeyError:
219
+ return None
220
+
221
+ @property
222
+ def pc_short_name(self) -> typing.Optional[str]:
223
+ """
224
+ The short name of the menu group.
225
+
226
+ Returns:
227
+ (typing.Optional[str]): The short name of the menu group.
228
+ """
229
+ try:
230
+ return self._raw_menu_group_data["names"]["PCShort"]
231
+ except KeyError:
232
+ return None
233
+
234
+ @property
235
+ def pc_long_name(self) -> typing.Optional[str]:
236
+ """
237
+ The long name of the menu group.
238
+
239
+ Returns:
240
+ (typing.Optional[str]): The long name of the menu group.
241
+ """
242
+ try:
243
+ return self._raw_menu_group_data["names"]["PCLong"]
244
+ except KeyError:
245
+ return None
246
+
247
+ @property
248
+ def mobile_short_name(self) -> typing.Optional[str]:
249
+ """
250
+ The short name of the menu group.
251
+
252
+ Returns:
253
+ (typing.Optional[str]): The short name of the menu group.
254
+ """
255
+ try:
256
+ return self._raw_menu_group_data["names"]["MobileShort"]
257
+ except KeyError:
258
+ return None
259
+
260
+ @property
261
+ def mobile_long_name(self) -> typing.Optional[str]:
262
+ """
263
+ The long name of the menu group.
264
+
265
+ Returns:
266
+ (typing.Optional[str]): The long name of the menu group.
267
+ """
268
+ try:
269
+ return self._raw_menu_group_data["names"]["MobileLong"]
270
+ except KeyError:
271
+ return None
272
+
273
+ @property
274
+ def menu_items(self) -> typing.Optional[list[MenuItem]]:
275
+ """
276
+ The menu items of the menu group.
277
+
278
+ Returns:
279
+ (typing.Optional[list[MenuItem]]): The menu items of the menu group.
280
+ """
281
+ try:
282
+ return [MenuItem(i, self._parent_restaurant_id) for i in self._raw_menu_group_data["menuItems"]]
283
+ except KeyError:
284
+ return None
285
+
286
+
287
+ class Menu:
288
+ def __init__(self, raw_menu_data: dict, parent_restaurant_id: typing.Optional[str] = None):
289
+ self._raw_menu_data = raw_menu_data
290
+ self._parent_restaurant_id = parent_restaurant_id
291
+
292
+ def __str__(self):
293
+ return f"Menu(entity_id={self.entity_id}, menu_type={self.menu_type}, parent_restaurant_id={self._parent_restaurant_id})"
294
+
295
+ @property
296
+ def entity_id(self) -> typing.Optional[str]:
297
+ """
298
+ The entity id of the menu.
299
+
300
+ Returns:
301
+ (typing.Optional[str]): The entity id of the menu.
302
+ """
303
+ try:
304
+ return self._raw_menu_data["id"]
305
+ except KeyError:
306
+ return None
307
+
308
+ @property
309
+ def menu_type(self) -> typing.Optional[str]:
310
+ """
311
+ The type of the menu.
312
+
313
+ Returns:
314
+ (typing.Optional[str]): The type of the menu.
315
+ """
316
+ try:
317
+ return self._raw_menu_data["menuType"]
318
+ except KeyError:
319
+ return None
320
+
321
+ @property
322
+ def localized_menu_type(self) -> typing.Optional[str]:
323
+ """
324
+ The localized type of the menu.
325
+
326
+ Returns:
327
+ (typing.Optional[str]): The localized type of the menu.
328
+ """
329
+ try:
330
+ return self._raw_menu_data["localizedMenuType"]
331
+ except KeyError:
332
+ return None
333
+
334
+ @property
335
+ def experience_type(self) -> typing.Optional[str]:
336
+ """
337
+ The experience type of the menu.
338
+
339
+ Returns:
340
+ (typing.Optional[str]): The experience type of the menu.
341
+ """
342
+ try:
343
+ return self._raw_menu_data["experienceType"]
344
+ except KeyError:
345
+ return None
346
+
347
+ @property
348
+ def service_style(self) -> typing.Optional[str]:
349
+ """
350
+ The service style of the menu.
351
+
352
+ Returns:
353
+ (typing.Optional[str]): The service style of the menu.
354
+ """
355
+ try:
356
+ return self._raw_menu_data["serviceStyle"]
357
+ except KeyError:
358
+ return None
359
+
360
+ @property
361
+ def primary_cuisine_type(self) -> typing.Optional[str]:
362
+ """
363
+ The primary cuisine type of the menu.
364
+
365
+ Returns:
366
+ (typing.Optional[str]): The primary cuisine type of the menu.
367
+ """
368
+ try:
369
+ return self._raw_menu_data["primaryCuisineType"]
370
+ except KeyError:
371
+ return None
372
+
373
+ @property
374
+ def secondary_cuisine_type(self) -> typing.Optional[str]:
375
+ """
376
+ The secondary cuisine type of the menu.
377
+
378
+ Returns:
379
+ (typing.Optional[str]): The secondary cuisine type of the menu.
380
+ """
381
+ try:
382
+ return self._raw_menu_data["secondaryCuisineType"]
383
+ except KeyError:
384
+ return None
385
+
386
+ @property
387
+ def menu_groups(self) -> list[MenuGroup]:
388
+ """
389
+ The menu groups of the menu.
390
+
391
+ Returns:
392
+ (list[MenuGroup]): The menu items of the menu.
393
+ """
394
+ try:
395
+ return [MenuGroup(i, self._parent_restaurant_id) for i in self._raw_menu_data["menuGroups"]]
396
+ except KeyError:
397
+ return []
398
+
399
+
400
+ class Menus(DisneyAPIMixin):
401
+ """Class for Menu Entities."""
402
+
403
+ _menu_service_base = f"{auth_obj._environments['serviceMenuUrl']}/diningMenuSvc/orchestration/menus"
404
+
405
+ def __init__(self, restaurant_channel_id: str, lazy_load: bool = True):
406
+ self.entity_id = restaurant_channel_id.rsplit(".", 1)[-1]
407
+ self._menu_service_url = f"{self._menu_service_base}/{self.entity_id}"
408
+
409
+ if lazy_load:
410
+ self.disney_data: typing.Optional[dict] = None
411
+ else:
412
+ self.disney_data = self.get_disney_data(self.entity_id)
413
+
414
+ def __str__(self):
415
+ return f"Menus(entity_id={self.entity_id})"
416
+
417
+ def __repr__(self):
418
+ return f"Menus(restaurant_channel_id={self.entity_id})"
419
+
420
+ @property
421
+ def menus(self) -> list[Menu]:
422
+ """
423
+ Returns a list of all the menus associated with this entity.
424
+
425
+ Returns:
426
+ (list[Menu]): List of Menu objects that are associated with this entity.
427
+ """
428
+ if self.disney_data is None:
429
+ self.disney_data = self.get_disney_data(self._menu_service_url)
430
+ try:
431
+ return [Menu(i, self.entity_id) for i in self.disney_data["menus"]]
432
+ except KeyError:
433
+ return []
mousetools/auth.py CHANGED
@@ -1,20 +1,24 @@
1
+ import base64
2
+ import json
1
3
  import typing
2
4
  from datetime import datetime, timedelta
5
+ from importlib.resources import as_file, files
3
6
 
4
7
  import httpx
8
+ from Crypto.Cipher import AES
5
9
 
6
10
 
7
11
  class Authentication:
8
12
  def __init__(self):
9
13
  self.time_of_expire: typing.Optional[datetime] = None
10
14
  self.access_token: typing.Optional[str] = None
15
+ self._environments = self._decrypt_file("resources/environments.bin").get("production", {})
11
16
 
12
- @staticmethod
13
- def authenticate() -> typing.Tuple[str, int]:
17
+ def authenticate(self) -> tuple[str, int]:
14
18
  """Gets an access token from Disney and the token's expiration time
15
19
 
16
20
  Returns:
17
- (typing.Tuple[str, int]): Access token to the api and how long until it expires
21
+ (tuple[str, int]): Access token to the api and how long until it expires
18
22
  """
19
23
 
20
24
  headers = {
@@ -31,11 +35,11 @@ class Authentication:
31
35
  body = {
32
36
  "grant_type": "assertion",
33
37
  "assertion_type": "public",
34
- "client_id": "TPR-DLR-LBSDK.AND-PROD",
38
+ "client_id": self._environments["authzClientId"],
35
39
  }
36
40
 
37
41
  response = httpx.post(
38
- "https://authorization.go.com/token",
42
+ f"{self._environments['authzServiceUrl']}/token",
39
43
  headers=headers,
40
44
  params=body,
41
45
  timeout=10,
@@ -45,11 +49,11 @@ class Authentication:
45
49
 
46
50
  return auth["access_token"], int(auth["expires_in"])
47
51
 
48
- def get_headers(self) -> typing.Dict[str, str]:
52
+ def get_headers(self) -> dict[str, str]:
49
53
  """Creates the headers to send during the request
50
54
 
51
55
  Returns:
52
- (typing.Dict[str, str]): Headers for the request
56
+ (dict[str, str]): Headers for the request
53
57
  """
54
58
 
55
59
  if self.time_of_expire is None or (datetime.now() > self.time_of_expire):
@@ -66,5 +70,43 @@ class Authentication:
66
70
 
67
71
  return headers
68
72
 
73
+ def get_couchbase_headers(self) -> dict[str, str]:
74
+ """Creates the headers to send during the couchbase request
75
+
76
+ Returns:
77
+ (dict[str, str]): Headers for the couchbase request
78
+ """
79
+ username = self._environments["syncGatewayUser"]
80
+ password = self._environments["syncGatewayPass"]
81
+ token = base64.b64encode(f"{username}:{password}".encode()).decode()
82
+
83
+ header = {
84
+ "Authorization": f"Basic {token}",
85
+ "User-Agent": "CouchbaseLite/3.2.1-9 (Java; Android 16; sdk_gphone64_x86_64) EE/release, Commit/2109502be2@02fbcb1b8b44 Core/3.2.1 (19)",
86
+ "Content-Type": "application/json",
87
+ "Accept": "multipart/related",
88
+ }
89
+
90
+ return header
91
+
92
+ def _decrypt_file(self, filename: str) -> dict:
93
+ cipher = AES.new(self._e(), AES.MODE_GCM, nonce=self._b())
94
+ with as_file(files("mousetools") / filename) as f, open(f, "rb") as file:
95
+ decrypted = cipher.decrypt(file.read())
96
+ return json.loads(decrypted.decode("Windows-1252")[:-16])
97
+
98
+ def _e(self):
99
+ s = ""
100
+ for i in range(1, 17):
101
+ if i % 2 != 0 or i >= 16:
102
+ s += chr(i + 65)
103
+ else:
104
+ s += str(3.141592653589793)[i]
105
+ bytes_ = s.encode("utf-8")
106
+ return bytes_
107
+
108
+ def _b(self):
109
+ return bytes(reversed(self._e()))
110
+
69
111
 
70
112
  auth_obj = Authentication()
@@ -0,0 +1,46 @@
1
+ import typing
2
+ from datetime import datetime, timedelta
3
+ from enum import Enum
4
+
5
+ from mousetools.channels.enums import DestinationShort, DestinationTimezones, DLRCouchbaseChannels, WDWCouchbaseChannels
6
+ from mousetools.mixins.couchbase import CouchbaseMixin
7
+
8
+
9
+ class CouchbaseChannel(CouchbaseMixin):
10
+ def __init__(self, channel_id: typing.Union[WDWCouchbaseChannels, DLRCouchbaseChannels], lazy_load: bool = True):
11
+ """
12
+ Args:
13
+ channel_id (typing.Union[WDWCouchbaseChannels, DLRCouchbaseChannels]): Channel ID from the enum
14
+ lazy_load (bool, optional): If True, will not pull data until a method or property is called. Defaults to True.
15
+ """
16
+ if isinstance(channel_id, Enum):
17
+ channel_id = channel_id.value
18
+ self.channel_id = channel_id
19
+
20
+ self._destination_short: DestinationShort = channel_id.split(".")[0]
21
+ self._tz: DestinationTimezones = (
22
+ DestinationTimezones.WALT_DISNEY_WORLD
23
+ if self._destination_short == DestinationShort.WALT_DISNEY_WORLD
24
+ else DestinationTimezones.DISNEYLAND_RESORT
25
+ )
26
+
27
+ self._cb_data = None
28
+ self._refresh_interval = timedelta(minutes=10)
29
+ self.last_update = datetime.now(tz=self._tz.value)
30
+
31
+ if not lazy_load:
32
+ self.refresh()
33
+
34
+ def refresh(self) -> None:
35
+ """Pulls initial data if none exists or if it is older than the refresh interval"""
36
+ if self._cb_data is None or datetime.now(tz=self._tz.value) - self.last_update > self._refresh_interval:
37
+ self._cb_data = self.get_channel_changes(self.channel_id)
38
+
39
+ def get_children_channel_ids(self) -> list[str]:
40
+ """Returns a list of child channel ids for the channel."""
41
+ self.refresh()
42
+
43
+ return [i["id"] for i in self._cb_data["results"]]
44
+
45
+ def __repr__(self):
46
+ return f"{self.__class__.__name__}({self.channel_id})"
@@ -0,0 +1,67 @@
1
+ from enum import Enum
2
+ from zoneinfo import ZoneInfo
3
+
4
+
5
+ class DestinationShort(str, Enum):
6
+ WALT_DISNEY_WORLD = "wdw"
7
+ DISNEYLAND_RESORT = "dlr"
8
+
9
+
10
+ class CouchbaseChannels(str, Enum):
11
+ FACILITIES = "facilities"
12
+ FACILITY_STATUS = "facilitystatus"
13
+ CALENDAR = "calendar"
14
+ FORECASTED_WAIT_TIME = "forecastedwaittimes"
15
+ TODAY = "today"
16
+
17
+
18
+ def get_complete_channel_id(
19
+ destination_short: DestinationShort, channel: CouchbaseChannels, version: str, is_multi_language: bool
20
+ ) -> str:
21
+ channel_id = f"{destination_short.value}.{channel.value}.{version}"
22
+
23
+ if is_multi_language:
24
+ channel_id += ".en_us"
25
+
26
+ return channel_id
27
+
28
+
29
+ class WDWCouchbaseChannels(str, Enum):
30
+ FACILITIES = get_complete_channel_id(DestinationShort.WALT_DISNEY_WORLD, CouchbaseChannels.FACILITIES, "1_0", True)
31
+ """Walt Disney World Facilities Channel"""
32
+ FACILITY_STATUS = get_complete_channel_id(
33
+ DestinationShort.WALT_DISNEY_WORLD, CouchbaseChannels.FACILITY_STATUS, "1_0", False
34
+ )
35
+ """Walt Disney World Facility Status Channel"""
36
+ CALENDAR = get_complete_channel_id(DestinationShort.WALT_DISNEY_WORLD, CouchbaseChannels.CALENDAR, "1_0", False)
37
+ """Walt Disney World Calendar Channel"""
38
+ FORECASTED_WAIT_TIME = get_complete_channel_id(
39
+ DestinationShort.WALT_DISNEY_WORLD, CouchbaseChannels.FORECASTED_WAIT_TIME, "1_0", True
40
+ )
41
+ """Walt Disney World Forecasted Wait Time Channel"""
42
+ TODAY = get_complete_channel_id(DestinationShort.WALT_DISNEY_WORLD, CouchbaseChannels.TODAY, "1_0", False)
43
+ """Walt Disney World Today Channel"""
44
+
45
+
46
+ class DLRCouchbaseChannels(str, Enum):
47
+ FACILITIES = get_complete_channel_id(DestinationShort.DISNEYLAND_RESORT, CouchbaseChannels.FACILITIES, "1_0", True)
48
+ """Disneyland Resort Facilities Channel"""
49
+ FACILITY_STATUS = get_complete_channel_id(
50
+ DestinationShort.DISNEYLAND_RESORT, CouchbaseChannels.FACILITY_STATUS, "1_0", False
51
+ )
52
+ """Disneyland Resort Facility Status Channel"""
53
+ CALENDAR = get_complete_channel_id(DestinationShort.DISNEYLAND_RESORT, CouchbaseChannels.CALENDAR, "1_0", False)
54
+ """Disneyland Resort Calendar Channel"""
55
+ FORECASTED_WAIT_TIME = get_complete_channel_id(
56
+ DestinationShort.DISNEYLAND_RESORT, CouchbaseChannels.FORECASTED_WAIT_TIME, "1_0", True
57
+ )
58
+ """Disneyland Resort Forecasted Wait Time Channel"""
59
+ TODAY = get_complete_channel_id(DestinationShort.DISNEYLAND_RESORT, CouchbaseChannels.TODAY, "1_0", False)
60
+ """Disneyland Resort Today Channel"""
61
+
62
+
63
+ class DestinationTimezones(Enum):
64
+ WALT_DISNEY_WORLD = ZoneInfo("America/New_York")
65
+ """Walt Disney World Timezone"""
66
+ DISNEYLAND_RESORT = ZoneInfo("America/Los_Angeles")
67
+ """Disneyland Resort Timezone"""