pynintendoparental 1.0.0__py3-none-any.whl → 1.0.2__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.
@@ -1 +1 @@
1
- __version__ = "1.0.0"
1
+ __version__ = "1.0.2"
pynintendoparental/api.py CHANGED
@@ -192,3 +192,22 @@ class Api:
192
192
  "unlockCode": new_code
193
193
  }
194
194
  )
195
+
196
+ async def async_update_extra_playing_time(
197
+ self,
198
+ device_id: str,
199
+ additional_time: int
200
+ ) -> dict:
201
+ """Update device extra playing time."""
202
+ body = {
203
+ "deviceId": device_id,
204
+ "additionalTime": additional_time,
205
+ "status": "TO_ADDED"
206
+ }
207
+ if additional_time == -1:
208
+ body["status"] = "TO_INFINITY"
209
+ body.pop("additionalTime")
210
+ return await self.send_request(
211
+ endpoint="update_extra_playing_time",
212
+ body=body
213
+ )
@@ -5,8 +5,8 @@ import logging
5
5
 
6
6
  _LOGGER = logging.getLogger(__package__)
7
7
  MOBILE_APP_PKG = "com.nintendo.znma"
8
- MOBILE_APP_VERSION = "2.0.0"
9
- MOBILE_APP_BUILD = "502"
8
+ MOBILE_APP_VERSION = "2.1.1"
9
+ MOBILE_APP_BUILD = "540"
10
10
  OS_NAME = "ANDROID"
11
11
  OS_VERSION = "33"
12
12
  OS_STR = f"{OS_NAME} {OS_VERSION}"
@@ -52,5 +52,9 @@ ENDPOINTS = {
52
52
  "get_device_monthly_summary": {
53
53
  "url": "{BASE_URL}/actions/playSummary/fetchMonthlySummary?deviceId={DEVICE_ID}&year={YEAR}&month={MONTH}&containLatest=false",
54
54
  "method": "GET"
55
+ },
56
+ "update_extra_playing_time": {
57
+ "url": "{BASE_URL}/actions/device/updateExtraPlayingTime",
58
+ "method": "POST"
55
59
  }
56
60
  }
@@ -63,11 +63,7 @@ class Device:
63
63
  else:
64
64
  for player in self.players:
65
65
  player.update_from_daily_summary(self.daily_summaries)
66
- for cb in self._callbacks:
67
- if is_awaitable(cb):
68
- await cb()
69
- else:
70
- cb()
66
+ await self._execute_callbacks()
71
67
 
72
68
  def add_device_callback(self, callback):
73
69
  """Add a callback to the device."""
@@ -83,6 +79,14 @@ class Device:
83
79
  if callback in self._callbacks:
84
80
  self._callbacks.remove(callback)
85
81
 
82
+ async def _execute_callbacks(self):
83
+ """Execute all callbacks."""
84
+ for cb in self._callbacks:
85
+ if is_awaitable(cb):
86
+ await cb()
87
+ else:
88
+ cb()
89
+
86
90
  async def set_new_pin(self, pin: str):
87
91
  """Updates the pin for the device."""
88
92
  _LOGGER.debug(">> Device.set_new_pin(pin=REDACTED)")
@@ -92,6 +96,17 @@ class Device:
92
96
  device_id=self.device_id
93
97
  )
94
98
  self._parse_parental_control_setting(response["json"])
99
+ await self._execute_callbacks()
100
+
101
+ async def add_extra_time(self, minutes: int):
102
+ """Add extra time to the device."""
103
+ _LOGGER.debug(">> Device.add_extra_time(minutes=%s)", minutes)
104
+ await self._api.async_update_extra_playing_time(
105
+ device_id=self.device_id,
106
+ additional_time=minutes
107
+ )
108
+ await self._execute_callbacks()
109
+
95
110
 
96
111
  async def set_restriction_mode(self, mode: RestrictionMode):
97
112
  """Updates the restriction mode of the device."""
@@ -104,6 +119,7 @@ class Device:
104
119
  }
105
120
  )
106
121
  self._parse_parental_control_setting(response["json"])
122
+ await self._execute_callbacks()
107
123
 
108
124
  async def set_bedtime_alarm(self, end_time: time = None, enabled: bool = True):
109
125
  """Update the bedtime alarm for the device."""
@@ -134,6 +150,8 @@ class Device:
134
150
  }
135
151
  )
136
152
  self._parse_parental_control_setting(response["json"])
153
+ self._calculate_times()
154
+ await self._execute_callbacks()
137
155
 
138
156
  async def update_max_daily_playtime(self, minutes: int = 0):
139
157
  """Updates the maximum daily playtime of a device."""
@@ -176,6 +194,8 @@ class Device:
176
194
  }
177
195
  )
178
196
  self._parse_parental_control_setting(response["json"])
197
+ self._calculate_times()
198
+ await self._execute_callbacks()
179
199
 
180
200
  def _update_applications(self):
181
201
  """Updates applications from daily summary."""
@@ -229,31 +249,22 @@ class Device:
229
249
  self._update_day_of_week_regulations()
230
250
  self._update_applications()
231
251
 
232
- async def _get_parental_control_setting(self):
233
- """Retreives parental control settings from the API."""
234
- _LOGGER.debug(">> Device._get_parental_control_setting()")
235
- response = await self._api.async_get_device_parental_control_setting(
236
- device_id=self.device_id
237
- )
238
- self._parse_parental_control_setting(response["json"])
239
-
240
- async def _get_daily_summaries(self):
241
- """Retrieve daily summaries."""
242
- _LOGGER.debug(">> Device._get_daily_summaries()")
243
- response = await self._api.async_get_device_daily_summaries(
244
- device_id = self.device_id
245
- )
246
- self.daily_summaries = response["json"]["dailySummaries"]
247
- _LOGGER.debug("New daily summary %s", self.daily_summaries)
248
- try:
249
- today_playing_time = self.get_date_summary()[0].get("playingTime", 0)
250
- self.today_playing_time = 0 if today_playing_time is None else today_playing_time/60
251
- today_disabled_time = self.get_date_summary()[0].get("disabledTime", 0)
252
- self.today_disabled_time = 0 if today_disabled_time is None else today_disabled_time/60
253
- today_exceeded_time = self.get_date_summary()[0].get("exceededTime", 0)
254
- self.today_exceeded_time = 0 if today_exceeded_time is None else today_exceeded_time/60
255
- _LOGGER.debug("Cached playing, disabled and exceeded time for today for device %s",
252
+ def _calculate_times(self):
253
+ """Calculate times from parental control settings."""
254
+ if not isinstance(self.daily_summaries, list) or not self.daily_summaries:
255
+ return
256
+ if len(self.daily_summaries) == 0:
257
+ return
258
+ _LOGGER.debug(">> Device._calculate_times()")
259
+ today_playing_time = self.daily_summaries[0].get("playingTime", 0)
260
+ self.today_playing_time = 0 if today_playing_time is None else today_playing_time
261
+ today_disabled_time = self.daily_summaries[0].get("disabledTime", 0)
262
+ self.today_disabled_time = 0 if today_disabled_time is None else today_disabled_time
263
+ today_exceeded_time = self.daily_summaries[0].get("exceededTime", 0)
264
+ self.today_exceeded_time = 0 if today_exceeded_time is None else today_exceeded_time
265
+ _LOGGER.debug("Cached playing, disabled and exceeded time for today for device %s",
256
266
  self.device_id)
267
+ try:
257
268
  now = datetime.now()
258
269
  current_minutes_past_midnight = now.hour * 60 + now.minute
259
270
  minutes_in_day = 1440 # 24 * 60
@@ -328,6 +339,25 @@ class Device:
328
339
  _LOGGER.debug("Unable to retrieve applications for device %s: %s", self.name, err)
329
340
  self.application_update_failed = True
330
341
 
342
+ async def _get_parental_control_setting(self):
343
+ """Retreives parental control settings from the API."""
344
+ _LOGGER.debug(">> Device._get_parental_control_setting()")
345
+ response = await self._api.async_get_device_parental_control_setting(
346
+ device_id=self.device_id
347
+ )
348
+ self._parse_parental_control_setting(response["json"])
349
+ self._calculate_times()
350
+
351
+ async def _get_daily_summaries(self):
352
+ """Retrieve daily summaries."""
353
+ _LOGGER.debug(">> Device._get_daily_summaries()")
354
+ response = await self._api.async_get_device_daily_summaries(
355
+ device_id = self.device_id
356
+ )
357
+ self.daily_summaries = response["json"]["dailySummaries"]
358
+ _LOGGER.debug("New daily summary %s", self.daily_summaries)
359
+ self._calculate_times()
360
+
331
361
  async def _get_extras(self):
332
362
  """Retrieve extra properties."""
333
363
  _LOGGER.debug(">> Device._get_extras()")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pynintendoparental
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: A Python module to interact with Nintendo Parental Controls
5
5
  Home-page: http://github.com/pantherale0/pynintendoparental
6
6
  Author: pantherale0
@@ -17,7 +17,7 @@ Requires-Dist: black<26,>=23; extra == "dev"
17
17
  Requires-Dist: build<1.3,>=0.10; extra == "dev"
18
18
  Requires-Dist: flake8<8,>=6; extra == "dev"
19
19
  Requires-Dist: isort<7,>=5; extra == "dev"
20
- Requires-Dist: mypy<1.16,>=1.5; extra == "dev"
20
+ Requires-Dist: mypy<1.17,>=1.5; extra == "dev"
21
21
  Requires-Dist: pytest<9,>=7; extra == "dev"
22
22
  Requires-Dist: pytest-cov<7,>=4; extra == "dev"
23
23
  Requires-Dist: twine<7,>=4; extra == "dev"
@@ -1,9 +1,9 @@
1
1
  pynintendoparental/__init__.py,sha256=CDz2tdO25y3vO3lLA6VQZOJl2Np10wgPIl8oWA4aGdE,2039
2
- pynintendoparental/_version.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
3
- pynintendoparental/api.py,sha256=WW_2VqPH8qs09G8vIMDOcoEgXf-8yyOpmAH8wsYAC1w,6469
2
+ pynintendoparental/_version.py,sha256=Y3LSfRioSl2xch70pq_ULlvyECXyEtN3krVaWeGyaxk,22
3
+ pynintendoparental/api.py,sha256=WzsWhQQcexJ5PIdem0WrC5XZ4FtnIeA29XZmV6tfBp0,7027
4
4
  pynintendoparental/application.py,sha256=l-oVwM4hrVVUf_2djQ7rJVya7LQP38yhaLPAWt8V8TY,3941
5
- pynintendoparental/const.py,sha256=0ROFl98eEOTWqTJBu7ElPgdsILJOyXJi4Xp7Dk8LRUY,1967
6
- pynintendoparental/device.py,sha256=6y_cDI2eG7tp5Ybzen0xwZQaQ5nGcwK3X_mGeekM75o,20613
5
+ pynintendoparental/const.py,sha256=Ao38EeEXMOouY4DRgOfeytDY8Kwj3XAaiaCDteSJ7IE,2101
6
+ pynintendoparental/device.py,sha256=glwB1UdgiOcMKwmC1RjYtP3L-xDBiSXCGqiFxwrjoII,21634
7
7
  pynintendoparental/enum.py,sha256=lzacGti7fcQqAOROjB9782De7bOMYKSEM61SQd6aYG4,401
8
8
  pynintendoparental/exceptions.py,sha256=5M3y0OLSRvX9Ly8D4981HqiKTNxxVqeyzPIuAekQ6J8,410
9
9
  pynintendoparental/player.py,sha256=WDl0pspHgrV9lGhDp-NKlfP8DV4Yxe02aYaGg9wTTeg,1785
@@ -11,8 +11,8 @@ pynintendoparental/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  pynintendoparental/utils.py,sha256=5-EP_rmPnSSWtbi18Y226GtjLhF3PLONKwmRdiy7m2c,198
12
12
  pynintendoparental/authenticator/__init__.py,sha256=dnmp6YjBJ0fQ5YWhWGJsAjj1ROxLihPPGr0PVJtTsgI,7589
13
13
  pynintendoparental/authenticator/const.py,sha256=_nUJVC0U64j_n1LaQd_KDg0EWFcezb87bQyYYXpbPPY,917
14
- pynintendoparental-1.0.0.dist-info/licenses/LICENSE,sha256=zsxHgHVMnyWq121yND8zBl9Rl9H6EF2K9N51B2ZSm_k,1071
15
- pynintendoparental-1.0.0.dist-info/METADATA,sha256=uJ0risDPvT2nkM4Ba1emWw-ehldZl5zB6wCvE_TJJkA,1871
16
- pynintendoparental-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- pynintendoparental-1.0.0.dist-info/top_level.txt,sha256=QQ5bAl-Ljso16P8KLf1NHrFmKk9jLT7bVJG_rVlIXWk,19
18
- pynintendoparental-1.0.0.dist-info/RECORD,,
14
+ pynintendoparental-1.0.2.dist-info/licenses/LICENSE,sha256=zsxHgHVMnyWq121yND8zBl9Rl9H6EF2K9N51B2ZSm_k,1071
15
+ pynintendoparental-1.0.2.dist-info/METADATA,sha256=DvMCwNlUuNKr9KdvzvakZyHmKC118w65vqP3KQMSC18,1871
16
+ pynintendoparental-1.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ pynintendoparental-1.0.2.dist-info/top_level.txt,sha256=QQ5bAl-Ljso16P8KLf1NHrFmKk9jLT7bVJG_rVlIXWk,19
18
+ pynintendoparental-1.0.2.dist-info/RECORD,,