MouseTools 2.1.2.dev2__tar.gz → 3.0.0.dev1__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-2.1.2.dev2 → mousetools-3.0.0.dev1}/LICENSE +1 -1
- mousetools-3.0.0.dev1/MouseTools.egg-info/PKG-INFO +39 -0
- mousetools-3.0.0.dev1/MouseTools.egg-info/SOURCES.txt +32 -0
- {mousetools-2.1.2.dev2/src → mousetools-3.0.0.dev1}/MouseTools.egg-info/requires.txt +0 -1
- mousetools-3.0.0.dev1/PKG-INFO +39 -0
- mousetools-3.0.0.dev1/README.md +26 -0
- mousetools-3.0.0.dev1/mousetools/__init__.py +13 -0
- mousetools-3.0.0.dev1/mousetools/auth.py +60 -0
- mousetools-3.0.0.dev1/mousetools/entities/__init__.py +13 -0
- mousetools-3.0.0.dev1/mousetools/entities/attraction.py +8 -0
- mousetools-3.0.0.dev1/mousetools/entities/base.py +381 -0
- mousetools-3.0.0.dev1/mousetools/entities/destination.py +8 -0
- mousetools-3.0.0.dev1/mousetools/entities/dining_event.py +15 -0
- mousetools-3.0.0.dev1/mousetools/entities/entertainment.py +8 -0
- mousetools-3.0.0.dev1/mousetools/entities/entertainment_venue.py +8 -0
- mousetools-3.0.0.dev1/mousetools/entities/event.py +8 -0
- mousetools-3.0.0.dev1/mousetools/entities/merchandise_facility.py +8 -0
- mousetools-3.0.0.dev1/mousetools/entities/park.py +8 -0
- mousetools-3.0.0.dev1/mousetools/entities/resort.py +8 -0
- mousetools-3.0.0.dev1/mousetools/entities/restaurant.py +8 -0
- mousetools-3.0.0.dev1/mousetools/exceptions.py +17 -0
- mousetools-3.0.0.dev1/mousetools/ids.py +90 -0
- mousetools-3.0.0.dev1/mousetools/mixins/__init__.py +0 -0
- mousetools-3.0.0.dev1/mousetools/mixins/disney.py +64 -0
- mousetools-3.0.0.dev1/mousetools/mixins/themeparksapi.py +122 -0
- mousetools-3.0.0.dev1/mousetools/urls.py +5 -0
- {mousetools-2.1.2.dev2 → mousetools-3.0.0.dev1}/pyproject.toml +78 -75
- mousetools-3.0.0.dev1/tests/test_auth.py +12 -0
- mousetools-3.0.0.dev1/tests/test_entities.py +45 -0
- mousetools-3.0.0.dev1/tests/test_entity.py +45 -0
- mousetools-3.0.0.dev1/tests/test_ids.py +47 -0
- mousetools-2.1.2.dev2/PKG-INFO +0 -101
- mousetools-2.1.2.dev2/README.md +0 -87
- mousetools-2.1.2.dev2/src/MouseTools.egg-info/PKG-INFO +0 -101
- mousetools-2.1.2.dev2/src/MouseTools.egg-info/SOURCES.txt +0 -19
- mousetools-2.1.2.dev2/src/mousetools/__init__.py +0 -27
- mousetools-2.1.2.dev2/src/mousetools/attractions.py +0 -370
- mousetools-2.1.2.dev2/src/mousetools/auth.py +0 -42
- mousetools-2.1.2.dev2/src/mousetools/characters.py +0 -241
- mousetools-2.1.2.dev2/src/mousetools/destinations.py +0 -400
- mousetools-2.1.2.dev2/src/mousetools/entertainments.py +0 -470
- mousetools-2.1.2.dev2/src/mousetools/entertainmentvenues.py +0 -264
- mousetools-2.1.2.dev2/src/mousetools/facilities.py +0 -248
- mousetools-2.1.2.dev2/src/mousetools/ids.py +0 -44
- mousetools-2.1.2.dev2/src/mousetools/parks.py +0 -446
- mousetools-2.1.2.dev2/src/mousetools/pointsofinterest.py +0 -186
- {mousetools-2.1.2.dev2/src → mousetools-3.0.0.dev1}/MouseTools.egg-info/dependency_links.txt +0 -0
- {mousetools-2.1.2.dev2/src → mousetools-3.0.0.dev1}/MouseTools.egg-info/top_level.txt +0 -0
- {mousetools-2.1.2.dev2 → mousetools-3.0.0.dev1}/setup.cfg +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: MouseTools
|
|
3
|
+
Version: 3.0.0.dev1
|
|
4
|
+
Summary: An unofficial Python wrapper for Disney's API
|
|
5
|
+
Author: Scott Caratozzolo
|
|
6
|
+
Project-URL: repository, https://gitlab.com/caratozzoloxyz/public/MouseTools
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: requests
|
|
13
|
+
|
|
14
|
+
# MouseTools
|
|
15
|
+
[](https://badge.fury.io/py/MouseTools) [](https://pepy.tech/project/mousetools)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
An unofficial Python wrapper for the Disney API. Data is pulled directly from Disney. This package supports Walt Disney World and Disneyland.
|
|
19
|
+
|
|
20
|
+
Read the [documentation](https://caratozzoloxyz.gitlab.io/public/MouseTools/)/
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Installation
|
|
24
|
+
You can install using pip:
|
|
25
|
+
```bash
|
|
26
|
+
pip install MouseTools
|
|
27
|
+
```
|
|
28
|
+
You can also install directly from this repo in case of any changes not uploaded to Pypi.
|
|
29
|
+
```bash
|
|
30
|
+
pip install git+https://gitlab.com/caratozzoloxyz/public/MouseTools
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### License
|
|
34
|
+
This project is distributed under the MIT license. For more information see [LICENSE](https://gitlab.com/caratozzoloxyz/public/MouseTools/-/blob/master/LICENSE?ref_type=heads)
|
|
35
|
+
|
|
36
|
+
### Disclaimer
|
|
37
|
+
This project is in no way affiliated with The Walt Disney Company and all use of Disney Services is subject to the [Disney Terms of Use](https://disneytermsofuse.com/).
|
|
38
|
+
|
|
39
|
+
This package uses the [ThemeParks.wiki API](https://themeparks.wiki/).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
MouseTools.egg-info/PKG-INFO
|
|
5
|
+
MouseTools.egg-info/SOURCES.txt
|
|
6
|
+
MouseTools.egg-info/dependency_links.txt
|
|
7
|
+
MouseTools.egg-info/requires.txt
|
|
8
|
+
MouseTools.egg-info/top_level.txt
|
|
9
|
+
mousetools/__init__.py
|
|
10
|
+
mousetools/auth.py
|
|
11
|
+
mousetools/exceptions.py
|
|
12
|
+
mousetools/ids.py
|
|
13
|
+
mousetools/urls.py
|
|
14
|
+
mousetools/entities/__init__.py
|
|
15
|
+
mousetools/entities/attraction.py
|
|
16
|
+
mousetools/entities/base.py
|
|
17
|
+
mousetools/entities/destination.py
|
|
18
|
+
mousetools/entities/dining_event.py
|
|
19
|
+
mousetools/entities/entertainment.py
|
|
20
|
+
mousetools/entities/entertainment_venue.py
|
|
21
|
+
mousetools/entities/event.py
|
|
22
|
+
mousetools/entities/merchandise_facility.py
|
|
23
|
+
mousetools/entities/park.py
|
|
24
|
+
mousetools/entities/resort.py
|
|
25
|
+
mousetools/entities/restaurant.py
|
|
26
|
+
mousetools/mixins/__init__.py
|
|
27
|
+
mousetools/mixins/disney.py
|
|
28
|
+
mousetools/mixins/themeparksapi.py
|
|
29
|
+
tests/test_auth.py
|
|
30
|
+
tests/test_entities.py
|
|
31
|
+
tests/test_entity.py
|
|
32
|
+
tests/test_ids.py
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: MouseTools
|
|
3
|
+
Version: 3.0.0.dev1
|
|
4
|
+
Summary: An unofficial Python wrapper for Disney's API
|
|
5
|
+
Author: Scott Caratozzolo
|
|
6
|
+
Project-URL: repository, https://gitlab.com/caratozzoloxyz/public/MouseTools
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: requests
|
|
13
|
+
|
|
14
|
+
# MouseTools
|
|
15
|
+
[](https://badge.fury.io/py/MouseTools) [](https://pepy.tech/project/mousetools)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
An unofficial Python wrapper for the Disney API. Data is pulled directly from Disney. This package supports Walt Disney World and Disneyland.
|
|
19
|
+
|
|
20
|
+
Read the [documentation](https://caratozzoloxyz.gitlab.io/public/MouseTools/)/
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Installation
|
|
24
|
+
You can install using pip:
|
|
25
|
+
```bash
|
|
26
|
+
pip install MouseTools
|
|
27
|
+
```
|
|
28
|
+
You can also install directly from this repo in case of any changes not uploaded to Pypi.
|
|
29
|
+
```bash
|
|
30
|
+
pip install git+https://gitlab.com/caratozzoloxyz/public/MouseTools
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### License
|
|
34
|
+
This project is distributed under the MIT license. For more information see [LICENSE](https://gitlab.com/caratozzoloxyz/public/MouseTools/-/blob/master/LICENSE?ref_type=heads)
|
|
35
|
+
|
|
36
|
+
### Disclaimer
|
|
37
|
+
This project is in no way affiliated with The Walt Disney Company and all use of Disney Services is subject to the [Disney Terms of Use](https://disneytermsofuse.com/).
|
|
38
|
+
|
|
39
|
+
This package uses the [ThemeParks.wiki API](https://themeparks.wiki/).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# MouseTools
|
|
2
|
+
[](https://badge.fury.io/py/MouseTools) [](https://pepy.tech/project/mousetools)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
An unofficial Python wrapper for the Disney API. Data is pulled directly from Disney. This package supports Walt Disney World and Disneyland.
|
|
6
|
+
|
|
7
|
+
Read the [documentation](https://caratozzoloxyz.gitlab.io/public/MouseTools/)/
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Installation
|
|
11
|
+
You can install using pip:
|
|
12
|
+
```bash
|
|
13
|
+
pip install MouseTools
|
|
14
|
+
```
|
|
15
|
+
You can also install directly from this repo in case of any changes not uploaded to Pypi.
|
|
16
|
+
```bash
|
|
17
|
+
pip install git+https://gitlab.com/caratozzoloxyz/public/MouseTools
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### License
|
|
21
|
+
This project is distributed under the MIT license. For more information see [LICENSE](https://gitlab.com/caratozzoloxyz/public/MouseTools/-/blob/master/LICENSE?ref_type=heads)
|
|
22
|
+
|
|
23
|
+
### Disclaimer
|
|
24
|
+
This project is in no way affiliated with The Walt Disney Company and all use of Disney Services is subject to the [Disney Terms of Use](https://disneytermsofuse.com/).
|
|
25
|
+
|
|
26
|
+
This package uses the [ThemeParks.wiki API](https://themeparks.wiki/).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from mousetools.ids import ancestor_entities, DestinationIds
|
|
3
|
+
|
|
4
|
+
logger = logging.getLogger(__name__)
|
|
5
|
+
logger.addHandler(logging.NullHandler())
|
|
6
|
+
|
|
7
|
+
__version__ = "3.0.0-dev.1" # will be set at runtime
|
|
8
|
+
logger.info(f"MouseTools version: {__version__}")
|
|
9
|
+
|
|
10
|
+
WALT_DISNEY_WORLD_ENTITIES = ancestor_entities(DestinationIds.WALT_DISNEY_WORLD)
|
|
11
|
+
logger.debug("%s Walt Disney World Entities", len(WALT_DISNEY_WORLD_ENTITIES))
|
|
12
|
+
DISNEYLAND_RESORT_ENTITIES = ancestor_entities(DestinationIds.DISNEYLAND_RESORT)
|
|
13
|
+
logger.debug("%s Disneyland Resort Entities", len(DISNEYLAND_RESORT_ENTITIES))
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
import requests
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Authentication:
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.time_of_expire: typing.Optional[datetime] = None
|
|
9
|
+
self.access_token: typing.Optional[str] = None
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def authenticate() -> typing.Tuple[str, int]:
|
|
13
|
+
"""Gets an access token from Disney and the token's expiration time
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
(typing.Tuple[str, int]): Access token to the api and how long until it expires
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
headers = {
|
|
20
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
|
|
21
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
22
|
+
"Cache-Control": "max-age=0",
|
|
23
|
+
"Accept": "application/json",
|
|
24
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
25
|
+
"Connection": "keep-alive",
|
|
26
|
+
"Proxy-Connection": "keep-alive",
|
|
27
|
+
"Accept-Encoding": "gzip, deflate",
|
|
28
|
+
}
|
|
29
|
+
response = requests.get(
|
|
30
|
+
"https://disneyworld.disney.go.com/authentication/get-client-token",
|
|
31
|
+
headers=headers,
|
|
32
|
+
timeout=10,
|
|
33
|
+
)
|
|
34
|
+
auth = response.json()
|
|
35
|
+
|
|
36
|
+
return auth["access_token"], int(auth["expires_in"])
|
|
37
|
+
|
|
38
|
+
def get_headers(self) -> typing.Dict[str, str]:
|
|
39
|
+
"""Creates the headers to send during the request
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
(typing.Dict[str, str]): Headers for the request
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
if self.time_of_expire is None or (datetime.now() > self.time_of_expire):
|
|
46
|
+
access_token, expires_in = self.authenticate()
|
|
47
|
+
self.time_of_expire = datetime.now() + timedelta(seconds=(expires_in - 10))
|
|
48
|
+
self.access_token = access_token
|
|
49
|
+
|
|
50
|
+
headers = {
|
|
51
|
+
"Authorization": f"BEARER {self.access_token}",
|
|
52
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
"Accept": "*/*",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return headers
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
auth_obj = Authentication()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from mousetools.entities.attraction import Attraction
|
|
2
|
+
from mousetools.entities.entertainment import Entertainment
|
|
3
|
+
from mousetools.entities.destination import Destination
|
|
4
|
+
from mousetools.entities.park import Park
|
|
5
|
+
from mousetools.entities.entertainment_venue import EntertainmentVenue
|
|
6
|
+
from mousetools.entities.merchandise_facility import MerchandiseFacility
|
|
7
|
+
from mousetools.entities.restaurant import Restaurant
|
|
8
|
+
from mousetools.entities.resort import Resort
|
|
9
|
+
from mousetools.entities.dining_event import DiningEvent, DinnerShow
|
|
10
|
+
from mousetools.entities.event import Event
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
__all__ = ["Attraction", "Entertainment", "Destination", "Park", "EntertainmentVenue" ,"MerchandiseFacility", "Restaurant", "Resort", "DiningEvent", "DinnerShow", "Event"]
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import typing
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from zoneinfo import ZoneInfo
|
|
5
|
+
from mousetools.mixins.disney import DisneyAPIMixin
|
|
6
|
+
from mousetools.mixins.themeparksapi import ThemeParkAPIMixin
|
|
7
|
+
from mousetools.ids import DestinationIds
|
|
8
|
+
from mousetools.urls import ENTITY_DETAILS_SIMPLE_BASE_URL
|
|
9
|
+
from mousetools.exceptions import AncestorDestinationMissing
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Entity(DisneyAPIMixin, ThemeParkAPIMixin):
|
|
16
|
+
def __init__(self, id: str):
|
|
17
|
+
self.id: str = id
|
|
18
|
+
self.disney_data: typing.Optional[dict] = None
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def name(self) -> typing.Optional[str]:
|
|
22
|
+
"""
|
|
23
|
+
The name of the entity.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
(typing.Optional[str]): The name of the entity, or None if it was not found.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
if self.disney_data is None:
|
|
30
|
+
self.disney_data = self.get_disney_data()
|
|
31
|
+
try:
|
|
32
|
+
return self.disney_data["name"]
|
|
33
|
+
except KeyError:
|
|
34
|
+
logger.debug("No name found for %s", self.id)
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def entity_type(self) -> typing.Optional[str]:
|
|
39
|
+
"""
|
|
40
|
+
The type of entity this is.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
(typing.Optional[str]): The type of entity this is, or None if it was not found.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
if self.disney_data is None:
|
|
47
|
+
self.disney_data = self.get_disney_data()
|
|
48
|
+
try:
|
|
49
|
+
return self.disney_data["entityType"]
|
|
50
|
+
except KeyError:
|
|
51
|
+
logger.debug("No entity type found for %s", self.id)
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def entity_type_name(self) -> typing.Optional[str]:
|
|
56
|
+
"""
|
|
57
|
+
The name of the type of entity.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
(typing.Optional[str]): The name of the type of entity, or None if it was not found.
|
|
61
|
+
"""
|
|
62
|
+
if self.disney_data is None:
|
|
63
|
+
self.disney_data = self.get_disney_data()
|
|
64
|
+
try:
|
|
65
|
+
return self.disney_data["entityTypeName"]
|
|
66
|
+
except KeyError:
|
|
67
|
+
logger.debug("No entity type name found for %s", self.id)
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def url_friendly_id(self) -> typing.Optional[str]:
|
|
72
|
+
"""
|
|
73
|
+
The url friendly id of the entity.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
(typing.Optional[str]): The url friendly id of the entity, or None if not found.
|
|
77
|
+
"""
|
|
78
|
+
if self.disney_data is None:
|
|
79
|
+
self.disney_data = self.get_disney_data()
|
|
80
|
+
try:
|
|
81
|
+
id = self.disney_data["urlFriendlyId"]
|
|
82
|
+
# for some reason pirates in wdw has a -wdw and its wrong
|
|
83
|
+
id = id.replace("-wdw", "").replace("-dlr", "")
|
|
84
|
+
return id
|
|
85
|
+
except KeyError:
|
|
86
|
+
logger.debug("No url friendly id found for %s", self.id)
|
|
87
|
+
return None
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def coordinates(self) -> typing.Optional[dict[str, float]]:
|
|
91
|
+
"""
|
|
92
|
+
The coordinates of this entity
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
(typing.Optional[dict[str, float]]): A dict with "lat" and "lng" keys containing the coordinates of this entity as floats, or None if no coordinates are found
|
|
96
|
+
"""
|
|
97
|
+
if self.disney_data is None:
|
|
98
|
+
self.disney_data = self.get_disney_data()
|
|
99
|
+
try:
|
|
100
|
+
return {
|
|
101
|
+
"lat": float(self.disney_data["marker"]["lat"]),
|
|
102
|
+
"lng": float(self.disney_data["marker"]["lng"]),
|
|
103
|
+
}
|
|
104
|
+
except KeyError:
|
|
105
|
+
logger.debug("No coordinates found for %s", self.id)
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def ancestor_destination_id(self) -> typing.Optional[str]:
|
|
110
|
+
"""
|
|
111
|
+
The id of the ancestor destination of this entity.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
(typing.Optional[str]): The id of the ancestor destination of this entity, or None if it was not found.
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
if self.disney_data is None:
|
|
118
|
+
self.disney_data = self.get_disney_data()
|
|
119
|
+
try:
|
|
120
|
+
return self._ancestor_destination_id
|
|
121
|
+
except KeyError:
|
|
122
|
+
logger.debug("No ancestor destination id found for %s", self.id)
|
|
123
|
+
return None
|
|
124
|
+
|
|
125
|
+
@ancestor_destination_id.setter
|
|
126
|
+
def ancestor_destination_id(self, value: typing.Optional[str]):
|
|
127
|
+
"""
|
|
128
|
+
Set the ancestor destination id
|
|
129
|
+
|
|
130
|
+
Required for ThemeParkAPIMixin
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
value (typing.Optional[str]): Str to set ancestor_destination_id to
|
|
134
|
+
"""
|
|
135
|
+
self.ancestor_destination_id = value
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def ancestor_park_ids(self) -> typing.Optional[list[str]]:
|
|
139
|
+
"""
|
|
140
|
+
The ids of parks that are ancestors of this entity.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
(typing.Optional[list[str]]): A list of park ids that are ancestors of this entity, or None if no such ids are found.
|
|
144
|
+
"""
|
|
145
|
+
if self.disney_data is None:
|
|
146
|
+
self.disney_data = self.get_disney_data()
|
|
147
|
+
try:
|
|
148
|
+
return [
|
|
149
|
+
i
|
|
150
|
+
for i in self.disney_data["parkIds"]
|
|
151
|
+
if any(j in i for j in ["theme-park", "water-park"])
|
|
152
|
+
]
|
|
153
|
+
except KeyError:
|
|
154
|
+
logger.debug("No ancestor park ids found for %s", self.id)
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def ancestor_resort_ids(self) -> typing.Optional[list[str]]:
|
|
159
|
+
"""
|
|
160
|
+
The ids of resorts that are ancestors of this entity.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
(typing.Optional[list[str]]): A list of resort ids that are ancestors of this entity, or None if no such ids are found.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
if self.disney_data is None:
|
|
167
|
+
self.disney_data = self.get_disney_data()
|
|
168
|
+
try:
|
|
169
|
+
return [i for i in self.disney_data["parkIds"] if "resort" in i]
|
|
170
|
+
except KeyError:
|
|
171
|
+
logger.debug("No ancestor resort ids found for %s", self.id)
|
|
172
|
+
return None
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def ancestor_land_id(self) -> typing.Optional[str]:
|
|
176
|
+
"""
|
|
177
|
+
The id of the land that is an ancestor of this entity.
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
(typing.Optional[str]): The id of the land that is an ancestor of this entity, or None if no such id is found.
|
|
181
|
+
"""
|
|
182
|
+
if self.disney_data is None:
|
|
183
|
+
self.disney_data = self.get_disney_data()
|
|
184
|
+
try:
|
|
185
|
+
return self.disney_data["landId"]
|
|
186
|
+
except KeyError:
|
|
187
|
+
logger.debug("No ancestor land id found for %s", self.id)
|
|
188
|
+
return None
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def ancestor_resort_area_ids(self) -> typing.Optional[list[str]]:
|
|
192
|
+
"""
|
|
193
|
+
The ids of resort areas that are ancestors of this entity.
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
(typing.Optional[list[str]]): A list of resort area ids that are ancestors of this entity, or None if no such ids are found.
|
|
197
|
+
"""
|
|
198
|
+
if self.disney_data is None:
|
|
199
|
+
self.disney_data = self.get_disney_data()
|
|
200
|
+
try:
|
|
201
|
+
return [i for i in self.disney_data["parkIds"] if "resort-area" in i]
|
|
202
|
+
except KeyError:
|
|
203
|
+
logger.debug("No ancestor resort area ids found for %s", self.id)
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def ancestor_entertainment_venue_ids(self) -> typing.Optional[list[str]]:
|
|
208
|
+
"""
|
|
209
|
+
The ids of entertainment venues that are ancestors of this entity.
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
(typing.Optional[list[str]]): A list of entertainment venue ids that are ancestors of this entity, or None if no such ids are found.
|
|
213
|
+
"""
|
|
214
|
+
if self.disney_data is None:
|
|
215
|
+
self.disney_data = self.get_disney_data()
|
|
216
|
+
try:
|
|
217
|
+
return [
|
|
218
|
+
i for i in self.disney_data["parkIds"] if "Entertainment-Venue" in i
|
|
219
|
+
]
|
|
220
|
+
except KeyError:
|
|
221
|
+
logger.debug("No ancestor entertainment venue ids found for %s", self.id)
|
|
222
|
+
return None
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def ancestor_restaurant_ids(self) -> typing.Optional[list[str]]:
|
|
226
|
+
"""
|
|
227
|
+
The ids of restaurants that are ancestors of this entity.
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
(typing.Optional[list[str]]): A list of restaurant ids that are ancestors of this entity, or None if no such ids are found.
|
|
231
|
+
"""
|
|
232
|
+
if self.disney_data is None:
|
|
233
|
+
self.disney_data = self.get_disney_data()
|
|
234
|
+
try:
|
|
235
|
+
return [i["id"] for i in self.disney_data["restaurants"]]
|
|
236
|
+
except KeyError:
|
|
237
|
+
logger.debug("No ancestor restaurant ids found for %s", self.id)
|
|
238
|
+
return None
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
def time_zone(self) -> ZoneInfo:
|
|
242
|
+
"""
|
|
243
|
+
The time zone of the entity.
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
(ZoneInfo): The time zone of the entity.
|
|
247
|
+
"""
|
|
248
|
+
|
|
249
|
+
if self.ancestor_destination_id == DestinationIds.WALT_DISNEY_WORLD:
|
|
250
|
+
return ZoneInfo("America/New_York")
|
|
251
|
+
elif self.ancestor_destination_id == DestinationIds.DISNEYLAND_RESORT:
|
|
252
|
+
return ZoneInfo("America/Los_Angeles")
|
|
253
|
+
else:
|
|
254
|
+
return ZoneInfo("UTC")
|
|
255
|
+
|
|
256
|
+
def details_simple_url(self) -> str:
|
|
257
|
+
"""
|
|
258
|
+
Gets the simple details url for this entity
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
(str): The simple details url
|
|
262
|
+
|
|
263
|
+
Raises:
|
|
264
|
+
AncestorDestinationMissing: If the ancestor destination id is not
|
|
265
|
+
either Walt Disney World or Disneyland Resort
|
|
266
|
+
"""
|
|
267
|
+
if self.ancestor_destination_id == DestinationIds.WALT_DISNEY_WORLD:
|
|
268
|
+
dest_url_friendly_id = "wdw"
|
|
269
|
+
elif self.ancestor_destination_id == DestinationIds.DISNEYLAND_RESORT:
|
|
270
|
+
dest_url_friendly_id = "dlr"
|
|
271
|
+
else:
|
|
272
|
+
raise AncestorDestinationMissing
|
|
273
|
+
return f"{ENTITY_DETAILS_SIMPLE_BASE_URL}/{dest_url_friendly_id}/{self.url_friendly_id}/{datetime.now().strftime('%Y-%m-%d')}"
|
|
274
|
+
|
|
275
|
+
def status(self) -> typing.Optional[str]:
|
|
276
|
+
"""
|
|
277
|
+
The current status of the entity.
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
(typing.Optional[str]): The current status of the entity, or None if no such data exists.
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
live_data = self.get_entity_live_tp()
|
|
284
|
+
try:
|
|
285
|
+
return live_data["liveData"][0]["status"]
|
|
286
|
+
except (KeyError, IndexError):
|
|
287
|
+
logger.debug("No status found for %s", self.id)
|
|
288
|
+
return None
|
|
289
|
+
|
|
290
|
+
def wait_time(self) -> typing.Optional[int]:
|
|
291
|
+
"""
|
|
292
|
+
The current wait time for the entity.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
(typing.Optional[int]): The current wait time for the entity, or None if no such data exists.
|
|
296
|
+
"""
|
|
297
|
+
live_data = self.get_entity_live_tp()
|
|
298
|
+
try:
|
|
299
|
+
return live_data["liveData"][0]["queue"]["STANDBY"]["waitTime"]
|
|
300
|
+
except (KeyError, IndexError):
|
|
301
|
+
logger.debug("No wait time found for %s", self.id)
|
|
302
|
+
return None
|
|
303
|
+
|
|
304
|
+
def last_updated(self) -> typing.Optional[datetime]:
|
|
305
|
+
"""
|
|
306
|
+
The last time the entity's data was updated.
|
|
307
|
+
|
|
308
|
+
Returns:
|
|
309
|
+
(typing.Optional[datetime]): The last time the entity's data was updated, or None if no such data exists.
|
|
310
|
+
"""
|
|
311
|
+
live_data = self.get_entity_live_tp()
|
|
312
|
+
try:
|
|
313
|
+
return datetime.strptime(
|
|
314
|
+
live_data["liveData"][0]["lastUpdated"], "%Y-%m-%dT%H:%M:%SZ"
|
|
315
|
+
).replace(tzinfo=ZoneInfo("UTC"))
|
|
316
|
+
except (KeyError, IndexError):
|
|
317
|
+
logger.debug("No last updated found for %s", self.id)
|
|
318
|
+
return None
|
|
319
|
+
|
|
320
|
+
def today_operating_hours(self) -> typing.Optional[dict[str, dict[str, datetime]]]:
|
|
321
|
+
"""
|
|
322
|
+
The operating hours for today for the entity.
|
|
323
|
+
|
|
324
|
+
Returns:
|
|
325
|
+
(typing.Optional[dict[str, dict[str, datetime]]]): A dictionary of the operating hours for today, or None if no such data exists.
|
|
326
|
+
"""
|
|
327
|
+
|
|
328
|
+
live_data = self.get_entity_live_tp()
|
|
329
|
+
temp = {}
|
|
330
|
+
|
|
331
|
+
try:
|
|
332
|
+
for i in live_data["liveData"][0]["operatingHours"]:
|
|
333
|
+
temp[i["type"]] = {
|
|
334
|
+
"start_time": datetime.strptime(
|
|
335
|
+
i["startTime"], "%Y-%m-%dT%H:%M:%S%z"
|
|
336
|
+
).replace(tzinfo=self.time_zone),
|
|
337
|
+
"end_time": datetime.strptime(
|
|
338
|
+
i["endTime"], "%Y-%m-%dT%H:%M:%S%z"
|
|
339
|
+
).replace(tzinfo=self.time_zone),
|
|
340
|
+
}
|
|
341
|
+
except (KeyError, IndexError):
|
|
342
|
+
logger.debug("No operating hours found for %s", self.id)
|
|
343
|
+
return None
|
|
344
|
+
|
|
345
|
+
return temp
|
|
346
|
+
|
|
347
|
+
def today_showtimes(self) -> typing.Optional[list[datetime]]:
|
|
348
|
+
"""
|
|
349
|
+
The showtimes for today for the entity.
|
|
350
|
+
|
|
351
|
+
Returns:
|
|
352
|
+
(typing.Optional[list[datetime]]): A list of the showtimes for today, or None if no such data exists.
|
|
353
|
+
"""
|
|
354
|
+
live_data = self.get_entity_live_tp()
|
|
355
|
+
temp = []
|
|
356
|
+
|
|
357
|
+
try:
|
|
358
|
+
for i in live_data["liveData"][0]["showtimes"]:
|
|
359
|
+
temp.append(
|
|
360
|
+
datetime.strptime(i["startTime"], "%Y-%m-%dT%H:%M:%S%z").replace(
|
|
361
|
+
tzinfo=self.time_zone
|
|
362
|
+
)
|
|
363
|
+
)
|
|
364
|
+
except (KeyError, IndexError):
|
|
365
|
+
logger.debug("No showtimes found for %s", self.id)
|
|
366
|
+
return None
|
|
367
|
+
|
|
368
|
+
return temp
|
|
369
|
+
|
|
370
|
+
def __str__(self) -> str:
|
|
371
|
+
return f"{self.entity_type}: {self.name} ({self.id})"
|
|
372
|
+
|
|
373
|
+
def __repr__(self) -> str:
|
|
374
|
+
return f"Entity(id='{self.id}')"
|
|
375
|
+
|
|
376
|
+
def __eq__(self, other) -> bool:
|
|
377
|
+
if isinstance(other, Entity):
|
|
378
|
+
return self.id == other.id
|
|
379
|
+
return False
|
|
380
|
+
|
|
381
|
+
# TODO virtual queue
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from mousetools.entities.base import Entity
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DiningEvent(Entity):
|
|
5
|
+
"""Class for DiningEvent Entities."""
|
|
6
|
+
|
|
7
|
+
def __repr__(self) -> str:
|
|
8
|
+
return f"DiningEvent(id='{self.id}')"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DinnerShow(Entity):
|
|
12
|
+
"""Class for DiningEvent Entities."""
|
|
13
|
+
|
|
14
|
+
def __repr__(self) -> str:
|
|
15
|
+
return f"DinnerShow(id='{self.id}')"
|