MouseTools 4.4.1__tar.gz → 4.5.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.
Files changed (33) hide show
  1. {mousetools-4.4.1 → mousetools-4.5.0}/PKG-INFO +1 -1
  2. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/channels/__init__.py +11 -1
  3. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/channels/facilities/__init__.py +6 -6
  4. mousetools-4.5.0/mousetools/channels/manager.py +103 -0
  5. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/mixins/couchbase.py +28 -13
  6. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools.egg-info/PKG-INFO +1 -1
  7. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools.egg-info/SOURCES.txt +2 -0
  8. {mousetools-4.4.1 → mousetools-4.5.0}/pyproject.toml +1 -1
  9. mousetools-4.5.0/tests/test_manager.py +28 -0
  10. {mousetools-4.4.1 → mousetools-4.5.0}/LICENSE +0 -0
  11. {mousetools-4.4.1 → mousetools-4.5.0}/README.md +0 -0
  12. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/__init__.py +0 -0
  13. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/api/__init__.py +0 -0
  14. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/api/menu.py +0 -0
  15. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/api/search.py +0 -0
  16. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/auth.py +0 -0
  17. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/channels/calendar/__init__.py +0 -0
  18. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/channels/characters/__init__.py +0 -0
  19. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/channels/enums.py +0 -0
  20. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/channels/facilities/enums.py +0 -0
  21. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/channels/facilitystatus/__init__.py +0 -0
  22. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/channels/forecastedwaittimes/__init__.py +0 -0
  23. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/channels/today/__init__.py +0 -0
  24. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/decorators.py +0 -0
  25. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/enums.py +0 -0
  26. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/mixins/__init__.py +0 -0
  27. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/mixins/disney.py +0 -0
  28. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools/resources/environments.bin +0 -0
  29. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools.egg-info/dependency_links.txt +0 -0
  30. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools.egg-info/requires.txt +0 -0
  31. {mousetools-4.4.1 → mousetools-4.5.0}/mousetools.egg-info/top_level.txt +0 -0
  32. {mousetools-4.4.1 → mousetools-4.5.0}/setup.cfg +0 -0
  33. {mousetools-4.4.1 → mousetools-4.5.0}/tests/test_mixins.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mousetools
3
- Version: 4.4.1
3
+ Version: 4.5.0
4
4
  Summary: An unofficial Python wrapper for Disney's API
5
5
  Author: Scott Caratozzolo
6
6
  License-Expression: MIT
@@ -47,6 +47,11 @@ class CouchbaseChildChannel(CouchbaseMixin):
47
47
  self._cb_data = self.get_channel_data(self.channel_id)
48
48
  self._cb_data_pull_time = datetime.now(tz=self._tz.value)
49
49
 
50
+ def _refresh_from_manager(self, cb_data: dict) -> None:
51
+ logger.info("Refreshing new data from manager for %s", self.channel_id)
52
+ self._cb_data = cb_data
53
+ self._cb_data_pull_time = datetime.now(tz=self._tz.value)
54
+
50
55
  @disney_property()
51
56
  def last_update(self) -> Optional[datetime]:
52
57
  """
@@ -79,7 +84,7 @@ class CouchbaseChannel(CouchbaseMixin):
79
84
  )
80
85
 
81
86
  self._cb_data = None
82
- self._refresh_interval = timedelta(minutes=10)
87
+ self._refresh_interval = timedelta(hours=12)
83
88
  self._cb_data_pull_time = datetime.now(tz=self._tz.value)
84
89
 
85
90
  if not lazy_load:
@@ -101,6 +106,11 @@ class CouchbaseChannel(CouchbaseMixin):
101
106
  self._cb_data = self.get_channel_changes(self.channel_id)
102
107
  self._cb_data_pull_time = datetime.now(tz=self._tz.value)
103
108
 
109
+ def _refresh_from_manager(self, cb_data: dict) -> None:
110
+ logger.info("Refreshing new data from manager for %s", self.channel_id)
111
+ self._cb_data = cb_data
112
+ self._cb_data_pull_time = datetime.now(tz=self._tz.value)
113
+
104
114
  def get_children_channel_ids(self) -> list[str]:
105
115
  """Returns a list of child channel ids for the channel."""
106
116
  self.refresh()
@@ -532,7 +532,7 @@ DiningEventFacilityChild = type("DiningEventFacilityChild", (FacilityChildChanne
532
532
  DinnerShowFacilityChild = type("DinnerShowFacilityChild", (FacilityChildChannel,), {})
533
533
  EntertainmentFacilityChild = type("EntertainmentFacilityChild", (FacilityChildChannel,), {})
534
534
  EntertainmentVenueFacilityChild = type("EntertainmentVenueFacilityChild", (FacilityChildChannel,), {})
535
- WaterParkFacilityChild = type("WaterParkFacilityChild", (FacilityChildChannel,), {})
535
+ EventFacilityChild = type("EventFacilityChild", (FacilityChildChannel,), {})
536
536
  GuestServiceFacilityChild = type("GuestServiceFacilityChild", (FacilityChildChannel,), {})
537
537
  LandFacilityChild = type("LandFacilityChild", (FacilityChildChannel,), {})
538
538
  MerchandiseFacilityChild = type("MerchandiseFacilityChild", (FacilityChildChannel,), {})
@@ -546,8 +546,8 @@ SpaFacilityChild = type("SpaFacilityChild", (FacilityChildChannel,), {})
546
546
  ThemeParkFacilityChild = type("ThemeParkFacilityChild", (FacilityChildChannel,), {})
547
547
  TourFacilityChild = type("TourFacilityChild", (FacilityChildChannel,), {})
548
548
  TransportationFacilityChild = type("TransportationFacilityChild", (FacilityChildChannel,), {})
549
- WaterParkFacilityChild = type("WaterParkFacilityChild", (FacilityChildChannel,), {})
550
549
  RestaurantFacilityChild = type("RestaurantFacilityChild", (FacilityChildChannel,), {})
550
+ WaterParkFacilityChild = type("WaterParkFacilityChild", (FacilityChildChannel,), {})
551
551
 
552
552
 
553
553
  class FacilityChannel(CouchbaseChannel):
@@ -631,13 +631,13 @@ class FacilityChannel(CouchbaseChannel):
631
631
  """
632
632
  return self._get_children_objects_helper(EntertainmentFacilityChild, EntityType.ENTERTAINMENT)
633
633
 
634
- def get_children_events(self) -> list[WaterParkFacilityChild]: # type: ignore
635
- """Get WaterParkFacilityChild Children of a Facility
634
+ def get_children_events(self) -> list[EventFacilityChild]: # type: ignore
635
+ """Get EventFacilityChild Children of a Facility
636
636
 
637
637
  Returns:
638
- (list[WaterParkFacilityChild]): A list of WaterParkFacilityChild Children
638
+ (list[EventFacilityChild]): A list of EventFacilityChild Children
639
639
  """
640
- return self._get_children_objects_helper(WaterParkFacilityChild, EntityType.EVENT)
640
+ return self._get_children_objects_helper(EventFacilityChild, EntityType.EVENT)
641
641
 
642
642
  def get_children_entertainment_venues(self) -> list[EntertainmentVenueFacilityChild]: # type: ignore
643
643
  """Get EntertainmentVenueFacilityChild Children of a Facility
@@ -0,0 +1,103 @@
1
+ import logging
2
+ from typing import Optional, Union
3
+
4
+ from mousetools.channels import CouchbaseChannel, CouchbaseChildChannel
5
+ from mousetools.mixins.couchbase import CouchbaseMixin
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ class ChannelManager(CouchbaseMixin):
11
+ def __init__(self, channels: list[Union[CouchbaseChannel, CouchbaseChildChannel]]) -> None:
12
+ self._channel_store = {}
13
+ for channel in channels:
14
+ self._channel_store[channel.channel_id] = channel
15
+
16
+ def add_channel(self, channel: Union[CouchbaseChannel, CouchbaseChildChannel]) -> None:
17
+ """Adds a channel to the manager
18
+
19
+ Args:
20
+ channel (Union[CouchbaseChannel, CouchbaseChildChannel]): Channel to add
21
+ """
22
+ self._channel_store[channel.channel_id] = channel
23
+
24
+ def get_channel(self, channel_id: str) -> Union[CouchbaseChannel, CouchbaseChildChannel]:
25
+ """Returns a channel from the manager
26
+
27
+ Args:
28
+ channel_id (str): Channel ID
29
+
30
+ Returns:
31
+ Union[CouchbaseChannel, CouchbaseChildChannel]: The channel
32
+ """
33
+ return self._channel_store[channel_id]
34
+
35
+ def get_all_channels(self) -> list[Union[CouchbaseChannel, CouchbaseChildChannel]]:
36
+ """Returns a list of all channels in the manager
37
+
38
+ Returns:
39
+ list[Union[CouchbaseChannel, CouchbaseChildChannel]]: List of channels
40
+ """
41
+ return list(self._channel_store.values())
42
+
43
+ def get_channel_ids(self) -> list[str]:
44
+ """Returns a list of all channel ids in the manager
45
+
46
+ Returns:
47
+ list[str]: List of channel ids
48
+ """
49
+ return list(self._channel_store.keys())
50
+
51
+ def remove_channel(
52
+ self, channel_id: str, return_channel: bool = False
53
+ ) -> Optional[Union[CouchbaseChannel, CouchbaseChildChannel]]:
54
+ """Removes a channel from the manager
55
+
56
+ Args:
57
+ channel_id (str): Channel ID
58
+ return_channel (bool, optional): If True, will return the channel. Defaults to False.
59
+
60
+ Returns:
61
+ Optional[Union[CouchbaseChannel, CouchbaseChildChannel]]: The channel
62
+ """
63
+ channel = self._channel_store.pop(channel_id)
64
+ if return_channel:
65
+ return channel
66
+
67
+ def refresh(self) -> None:
68
+ """Refreshes all channels in the manager
69
+
70
+ Raises:
71
+ ValueError: If the channel is not a child or parent channel
72
+ """
73
+ children_channels: dict[str, CouchbaseChildChannel] = {}
74
+ parent_channels: dict[str, CouchbaseChannel] = {}
75
+
76
+ for channel_id, channel in self._channel_store.items():
77
+ if isinstance(channel, CouchbaseChildChannel):
78
+ children_channels[channel_id] = channel
79
+ elif isinstance(channel, CouchbaseChannel):
80
+ parent_channels[channel_id] = channel
81
+ else:
82
+ raise ValueError(f"Channel {channel} is not a child or parent channel")
83
+ logger.info(
84
+ "Refreshing %d children channels and %d parent channels", len(children_channels), len(parent_channels)
85
+ )
86
+
87
+ if children_channels:
88
+ logger.debug("Refreshing children channels")
89
+ children_results = self.get_channel_data(list(children_channels.keys()))
90
+ for children_channel, result in zip(children_channels.values(), children_results):
91
+ children_channel._refresh_from_manager(result)
92
+
93
+ if parent_channels:
94
+ logger.debug("Refreshing parent channels")
95
+ parent_results = self.get_channel_changes(list(parent_channels.keys()))
96
+ for channel_id, parent_channel in parent_channels.items():
97
+ copy_results = parent_results.copy()
98
+ new_results = []
99
+ for result in copy_results["results"]:
100
+ if channel_id in result["id"]:
101
+ new_results.append(result)
102
+ copy_results["results"] = new_results
103
+ parent_channel._refresh_from_manager(copy_results)
@@ -14,28 +14,33 @@ class CouchbaseMixin:
14
14
  _couchbase_url = "https://" + auth_obj._environments["syncGatewayUrl"].split("//")[1].rstrip("/")
15
15
  _headers: dict = auth_obj.get_couchbase_headers()
16
16
 
17
- def get_channel_data(self, channel_name: str) -> Union[dict, None]:
17
+ def get_channel_data(self, channel_name: Union[str, list[str]]) -> Union[list[dict], dict, None]:
18
18
  """
19
19
  Sends a request to the Disney Couchbase API with the given channel ID and returns the data.
20
20
 
21
21
  Args:
22
- channel_name (str): Couchbase channel to request data from.
22
+ channel_name (Union[str, list[str]]): Couchbase channel(s) to request data from.
23
23
 
24
24
  Returns:
25
- (dict): The disney data.
25
+ (Union[list[dict], dict, None]): The disney data.
26
26
  """
27
27
 
28
+ if isinstance(channel_name, str):
29
+ _channel_names = [channel_name]
30
+ return_list = False
31
+ else:
32
+ _channel_names = channel_name
33
+ return_list = True
34
+
28
35
  payload = {
29
- "docs": [
30
- {"id": channel_name},
31
- ],
36
+ "docs": [{"id": name} for name in _channel_names],
32
37
  "json": True,
33
38
  }
34
39
 
35
- logger.info("Sending request for channel data: %s", channel_name)
40
+ logger.info("Sending request for channel data: %s", _channel_names)
36
41
  response = requests.post(self._couchbase_url + "/_bulk_get", json=payload, headers=self._headers, timeout=10)
37
- logger.debug("Response status for %s: %s", channel_name, response.status_code)
38
- data = None
42
+ logger.debug("Response status for %s: %s", _channel_names, response.status_code)
43
+ results = []
39
44
  try:
40
45
  response.raise_for_status()
41
46
  raw_data = response.text
@@ -48,6 +53,7 @@ class CouchbaseMixin:
48
53
  if line != "" and line[0] != "-":
49
54
  try:
50
55
  data = json.loads(line)
56
+ results.append(data)
51
57
  except Exception:
52
58
  logger.debug("Failed to parse line: %s", line)
53
59
  continue
@@ -55,21 +61,30 @@ class CouchbaseMixin:
55
61
  logger.error("Request failed: %s", err)
56
62
  return None
57
63
 
58
- return data
64
+ if return_list:
65
+ return results
66
+ else:
67
+ return results[0]
59
68
 
60
- def get_channel_changes(self, channel_name: str, since: Union[int, None] = None) -> Union[dict, None]:
69
+ def get_channel_changes(
70
+ self, channel_name: Union[str, list[str]], since: Union[int, None] = None
71
+ ) -> Union[dict, None]:
61
72
  """Sends a request to the Disney Couchbase API with the given channel ID and returns the data.
62
73
 
63
74
  Args:
64
- channel_name (str): Couchbase channel to request data from.
75
+ channel_name (Union[str, list[str]]): Couchbase channel to request data from.
65
76
  since (Union[int, None], optional): Since when to get changes. Defaults to None.
66
77
 
67
78
  Returns:
68
79
  Union[dict, None]: The disney data.
69
80
  """
81
+
82
+ if isinstance(channel_name, str):
83
+ channel_name = [channel_name]
84
+
70
85
  try:
71
86
  payload = {
72
- "channels": channel_name,
87
+ "channels": ",".join(channel_name),
73
88
  "style": "all_docs",
74
89
  "filter": "sync_gateway/bychannel",
75
90
  "feed": "normal",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mousetools
3
- Version: 4.4.1
3
+ Version: 4.5.0
4
4
  Summary: An unofficial Python wrapper for Disney's API
5
5
  Author: Scott Caratozzolo
6
6
  License-Expression: MIT
@@ -15,6 +15,7 @@ mousetools/api/menu.py
15
15
  mousetools/api/search.py
16
16
  mousetools/channels/__init__.py
17
17
  mousetools/channels/enums.py
18
+ mousetools/channels/manager.py
18
19
  mousetools/channels/calendar/__init__.py
19
20
  mousetools/channels/characters/__init__.py
20
21
  mousetools/channels/facilities/__init__.py
@@ -26,4 +27,5 @@ mousetools/mixins/__init__.py
26
27
  mousetools/mixins/couchbase.py
27
28
  mousetools/mixins/disney.py
28
29
  mousetools/resources/environments.bin
30
+ tests/test_manager.py
29
31
  tests/test_mixins.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mousetools"
3
- version = "4.4.1"
3
+ version = "4.5.0"
4
4
  authors = [{name = "Scott Caratozzolo"}]
5
5
  description = "An unofficial Python wrapper for Disney's API"
6
6
  readme = "README.md"
@@ -0,0 +1,28 @@
1
+ from mousetools.channels.facilities import FacilityChannel, FacilityChildChannel
2
+ from mousetools.channels.facilities.enums import DLRCouchbaseChannels, WDWCouchbaseChannels
3
+ from mousetools.channels.manager import ChannelManager
4
+
5
+
6
+ def test_manager():
7
+ channel_manager = ChannelManager([])
8
+ assert channel_manager.get_channel_ids() == []
9
+
10
+ wdw = FacilityChannel(WDWCouchbaseChannels.FACILITIES)
11
+ dlr = FacilityChannel(DLRCouchbaseChannels.FACILITIES)
12
+ channel_manager.add_channel(wdw)
13
+ channel_manager.add_channel(dlr)
14
+ assert channel_manager.get_all_channels() == [wdw, dlr]
15
+
16
+ channel = channel_manager.remove_channel(WDWCouchbaseChannels.FACILITIES.value, return_channel=True)
17
+ assert channel.channel_id == WDWCouchbaseChannels.FACILITIES.value
18
+ assert len(channel_manager.get_all_channels()) == 1
19
+
20
+ channel_manager.add_channel(
21
+ FacilityChildChannel("wdw.facilities.1_0.en_us.attraction.80010177;entityType=Attraction")
22
+ )
23
+ assert dlr._cb_data is None
24
+ channel_manager.refresh()
25
+ assert dlr._cb_data is not None
26
+
27
+ channel = channel_manager.get_channel("wdw.facilities.1_0.en_us.attraction.80010177;entityType=Attraction")
28
+ assert channel.channel_id == "wdw.facilities.1_0.en_us.attraction.80010177;entityType=Attraction"
File without changes
File without changes
File without changes