pynintendoparental 1.1.2__py3-none-any.whl → 1.1.3__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.1.2"
1
+ __version__ = "1.1.3"
pynintendoparental/api.py CHANGED
@@ -97,6 +97,14 @@ class Api:
97
97
  resp["json"] = {}
98
98
  resp["headers"] = response.headers
99
99
  else:
100
+ if response.content_type == "application/problem+json":
101
+ try:
102
+ error = await response.json()
103
+ if "detail" in error:
104
+ raise HttpException(response.status, error["detail"], error.get("errorCode"))
105
+ except (aiohttp.ContentTypeError, ValueError):
106
+ # Fall through to the generic exception below on parsing failure.
107
+ pass
100
108
  raise HttpException(response.status, await response.text())
101
109
 
102
110
  # now return the resp dict
@@ -8,8 +8,8 @@ from typing import Callable
8
8
 
9
9
  from .api import Api
10
10
  from .const import _LOGGER, DAYS_OF_WEEK
11
- from .exceptions import HttpException, BedtimeOutOfRangeError, DailyPlaytimeOutOfRangeError
12
- from .enum import AlarmSettingState, RestrictionMode
11
+ from .exceptions import BedtimeOutOfRangeError, DailyPlaytimeOutOfRangeError, HttpException
12
+ from .enum import AlarmSettingState, DeviceTimerMode, RestrictionMode
13
13
  from .player import Player
14
14
  from .utils import is_awaitable
15
15
  from .application import Application
@@ -28,7 +28,7 @@ class Device:
28
28
  self.parental_control_settings: dict = {}
29
29
  self.players: list[Player] = []
30
30
  self.limit_time: int | float | None = 0
31
- self.timer_mode: str = ""
31
+ self.timer_mode: DeviceTimerMode | None = None
32
32
  self.today_playing_time: int | float = 0
33
33
  self.today_time_remaining: int | float = 0
34
34
  self.bedtime_alarm: time | None = None
@@ -66,13 +66,14 @@ class Device:
66
66
  async def update(self):
67
67
  """Update data."""
68
68
  _LOGGER.debug(">> Device.update()")
69
+ now = datetime.now()
69
70
  await asyncio.gather(
70
- self._get_daily_summaries(),
71
- self._get_parental_control_setting(),
71
+ self._get_daily_summaries(now),
72
+ self._get_parental_control_setting(now),
72
73
  self.get_monthly_summary(),
73
74
  self._get_extras()
74
75
  )
75
- if self.players is None:
76
+ if not self.players:
76
77
  self.players = Player.from_device_daily_summary(self.daily_summaries)
77
78
  else:
78
79
  for player in self.players:
@@ -101,26 +102,29 @@ class Device:
101
102
  else:
102
103
  cb()
103
104
 
105
+ async def _send_api_update(self, api_call: Callable, *args, **kwargs):
106
+ """Sends an update to the API and refreshes local state."""
107
+ now = kwargs.pop("now", datetime.now())
108
+ response = await api_call(*args, **kwargs)
109
+ self._parse_parental_control_setting(response["json"], now)
110
+ self._calculate_times(now)
111
+ await self._execute_callbacks()
112
+
104
113
  async def set_new_pin(self, pin: str):
105
114
  """Updates the pin for the device."""
106
115
  _LOGGER.debug(">> Device.set_new_pin(pin=REDACTED)")
107
- self.parental_control_settings["unlockCode"] = pin
108
- response = await self._api.async_update_unlock_code(
116
+ await self._send_api_update(
117
+ self._api.async_update_unlock_code,
109
118
  new_code=pin,
110
119
  device_id=self.device_id
111
120
  )
112
- self._parse_parental_control_setting(response["json"])
113
- await self._execute_callbacks()
114
121
 
115
122
  async def add_extra_time(self, minutes: int):
116
123
  """Add extra time to the device."""
117
124
  _LOGGER.debug(">> Device.add_extra_time(minutes=%s)", minutes)
118
- await self._api.async_update_extra_playing_time(
119
- device_id=self.device_id,
120
- additional_time=minutes
121
- )
122
- await self._execute_callbacks()
123
-
125
+ # This endpoint does not return parental control settings, so we call it directly.
126
+ await self._api.async_update_extra_playing_time(self.device_id, minutes)
127
+ await self._get_parental_control_setting(datetime.now())
124
128
 
125
129
  async def set_restriction_mode(self, mode: RestrictionMode):
126
130
  """Updates the restriction mode of the device."""
@@ -132,7 +136,8 @@ class Device:
132
136
  "playTimerRegulations": self.parental_control_settings["playTimerRegulations"]
133
137
  }
134
138
  )
135
- self._parse_parental_control_setting(response["json"])
139
+ now = datetime.now()
140
+ self._parse_parental_control_setting(response["json"], now) # Don't need to recalculate times
136
141
  await self._execute_callbacks()
137
142
 
138
143
  async def set_bedtime_alarm(self, value: time):
@@ -145,6 +150,7 @@ class Device:
145
150
  (value.hour == 0 and value.minute == 0)
146
151
  ):
147
152
  raise BedtimeOutOfRangeError(value=value)
153
+ now = datetime.now()
148
154
  bedtime = {
149
155
  "enabled": value.hour != 0 and value.minute != 0,
150
156
  }
@@ -156,21 +162,33 @@ class Device:
156
162
  "minute": value.minute
157
163
  }
158
164
  }
159
- if self.timer_mode == "DAILY":
165
+ if self.timer_mode == DeviceTimerMode.DAILY:
160
166
  self.parental_control_settings["playTimerRegulations"]["dailyRegulations"]["bedtime"] = bedtime
161
167
  else:
162
168
  self.parental_control_settings["playTimerRegulations"]["eachDayOfTheWeekRegulations"][
163
- DAYS_OF_WEEK[datetime.now().weekday()]
169
+ DAYS_OF_WEEK[now.weekday()]
164
170
  ]["bedtime"] = bedtime
165
- response = await self._api.async_update_play_timer(
171
+ await self._send_api_update(
172
+ self._api.async_update_play_timer,
173
+ settings={
174
+ "deviceId": self.device_id,
175
+ "playTimerRegulations": self.parental_control_settings["playTimerRegulations"]
176
+ },
177
+ now=now
178
+ )
179
+
180
+ async def set_timer_mode(self, mode: DeviceTimerMode):
181
+ """Updates the timer mode of the device."""
182
+ _LOGGER.debug(">> Device.set_timer_mode(mode=%s)", mode)
183
+ self.timer_mode = mode
184
+ self.parental_control_settings["playTimerRegulations"]["timerMode"] = str(mode)
185
+ await self._send_api_update(
186
+ self._api.async_update_play_timer,
166
187
  settings={
167
188
  "deviceId": self.device_id,
168
189
  "playTimerRegulations": self.parental_control_settings["playTimerRegulations"]
169
190
  }
170
191
  )
171
- self._parse_parental_control_setting(response["json"])
172
- self._calculate_times()
173
- await self._execute_callbacks()
174
192
 
175
193
  async def update_max_daily_playtime(self, minutes: int | float = 0):
176
194
  """Updates the maximum daily playtime of a device."""
@@ -180,11 +198,12 @@ class Device:
180
198
  minutes = int(minutes)
181
199
  if minutes > 360 or minutes < -1:
182
200
  raise DailyPlaytimeOutOfRangeError(minutes)
201
+ now = datetime.now()
183
202
  ttpiod = True
184
203
  if minutes == -1:
185
204
  ttpiod = False
186
205
  minutes = None
187
- if self.timer_mode == "DAILY":
206
+ if self.timer_mode == DeviceTimerMode.DAILY:
188
207
  _LOGGER.debug(
189
208
  "Setting timeToPlayInOneDay.limitTime for device %s to value %s",
190
209
  self.device_id,
@@ -201,22 +220,21 @@ class Device:
201
220
  minutes
202
221
  )
203
222
  day_of_week_regs = self.parental_control_settings["playTimerRegulations"]["eachDayOfTheWeekRegulations"]
204
- current_day = DAYS_OF_WEEK[datetime.now().weekday()]
223
+ current_day = DAYS_OF_WEEK[now.weekday()]
205
224
  day_of_week_regs[current_day]["timeToPlayInOneDay"]["enabled"] = ttpiod
206
225
  if "limitTime" in day_of_week_regs[current_day]["timeToPlayInOneDay"] and minutes is None:
207
226
  day_of_week_regs[current_day]["timeToPlayInOneDay"].pop("limitTime")
208
227
  else:
209
228
  day_of_week_regs[current_day]["timeToPlayInOneDay"]["limitTime"] = minutes
210
229
 
211
- response = await self._api.async_update_play_timer(
230
+ await self._send_api_update(
231
+ self._api.async_update_play_timer,
212
232
  settings={
213
233
  "deviceId": self.device_id,
214
234
  "playTimerRegulations": self.parental_control_settings["playTimerRegulations"]
215
- }
235
+ },
236
+ now=now
216
237
  )
217
- self._parse_parental_control_setting(response["json"])
218
- self._calculate_times()
219
- await self._execute_callbacks()
220
238
 
221
239
  def _update_applications(self):
222
240
  """Updates applications from daily summary."""
@@ -229,112 +247,71 @@ class Device:
229
247
  except ValueError:
230
248
  self.applications.append(app)
231
249
 
232
- def _update_day_of_week_regulations(self):
233
- """Override the limit / bed time for the device from parental_control_settings if individual days are configured."""
234
- day_of_week_regs = self.parental_control_settings["playTimerRegulations"].get("eachDayOfTheWeekRegulations", {})
235
- current_day = day_of_week_regs.get(DAYS_OF_WEEK[datetime.now().weekday()], {})
236
- self.timer_mode = self.parental_control_settings["playTimerRegulations"]["timerMode"]
237
- if self.timer_mode == "EACH_DAY_OF_THE_WEEK":
238
- regulations = current_day
239
- else:
240
- regulations = self.parental_control_settings.get("playTimerRegulations", {}).get("dailyRegulations", {})
241
-
242
- limit_time = regulations.get("timeToPlayInOneDay", {}).get("limitTime")
243
- self.limit_time = limit_time if limit_time is not None else -1
244
-
245
- if self.timer_mode == "EACH_DAY_OF_THE_WEEK":
246
- if current_day["bedtime"]["enabled"]:
247
- self.bedtime_alarm = time(hour=
248
- current_day["bedtime"]["endingTime"]["hour"],
249
- minute=current_day["bedtime"]["endingTime"]["minute"])
250
- else:
251
- self.bedtime_alarm = time(hour=0, minute=0)
252
- else:
253
- bedtime_alarm = self.parental_control_settings["playTimerRegulations"]["dailyRegulations"]["bedtime"]
254
- if bedtime_alarm["enabled"]:
255
- self.bedtime_alarm = time(hour=
256
- bedtime_alarm["endingTime"]["hour"],
257
- minute=bedtime_alarm["endingTime"]["minute"])
258
- else:
259
- self.bedtime_alarm = time(hour=0, minute=0)
260
- return True
250
+ def _get_today_regulation(self, now: datetime) -> dict:
251
+ """Returns the regulation settings for the current day."""
252
+ if self.timer_mode == DeviceTimerMode.EACH_DAY_OF_THE_WEEK:
253
+ day_of_week_regs = self.parental_control_settings["playTimerRegulations"].get("eachDayOfTheWeekRegulations", {})
254
+ return day_of_week_regs.get(DAYS_OF_WEEK[now.weekday()], {})
255
+ return self.parental_control_settings.get("playTimerRegulations", {}).get("dailyRegulations", {})
261
256
 
262
- def _parse_parental_control_setting(self, pcs: dict):
257
+ def _parse_parental_control_setting(self, pcs: dict, now: datetime):
263
258
  """Parse a parental control setting request response."""
264
259
  _LOGGER.debug(">> Device._parse_parental_control_setting()")
265
260
  self.parental_control_settings = pcs["parentalControlSetting"]
261
+
262
+ # Clean up bedtimeStartingTime if it's empty
266
263
  if "bedtimeStartingTime" in self.parental_control_settings["playTimerRegulations"]:
267
264
  if self.parental_control_settings["playTimerRegulations"].get("bedtimeStartingTime", {}).get("hour", 0) == 0:
268
265
  self.parental_control_settings["playTimerRegulations"].pop("bedtimeStartingTime")
266
+
269
267
  self.forced_termination_mode = (
270
268
  self.parental_control_settings["playTimerRegulations"]["restrictionMode"] == str(RestrictionMode.FORCED_TERMINATION)
271
269
  )
272
- self._update_day_of_week_regulations()
270
+
271
+ # Update limit and bedtime from regulations
272
+ self.timer_mode = DeviceTimerMode(
273
+ self.parental_control_settings["playTimerRegulations"]["timerMode"]
274
+ )
275
+ today_reg = self._get_today_regulation(now)
276
+ limit_time = today_reg.get("timeToPlayInOneDay", {}).get("limitTime")
277
+ self.limit_time = limit_time if limit_time is not None else -1
278
+
279
+ bedtime_setting = today_reg.get("bedtime", {})
280
+ if bedtime_setting.get("enabled"):
281
+ self.bedtime_alarm = time(
282
+ hour=bedtime_setting["endingTime"]["hour"],
283
+ minute=bedtime_setting["endingTime"]["minute"]
284
+ )
285
+ else:
286
+ self.bedtime_alarm = time(hour=0, minute=0)
287
+
273
288
  self._update_applications()
274
289
 
275
- def _calculate_times(self):
290
+ def _calculate_times(self, now: datetime):
276
291
  """Calculate times from parental control settings."""
277
292
  if not isinstance(self.daily_summaries, list) or not self.daily_summaries:
278
293
  return
279
294
  if len(self.daily_summaries) == 0:
280
295
  return
281
296
  _LOGGER.debug(">> Device._calculate_times()")
282
- today_playing_time = self.daily_summaries[0].get("playingTime", 0)
283
- self.today_playing_time = 0 if today_playing_time is None else today_playing_time
284
- today_disabled_time = self.daily_summaries[0].get("disabledTime", 0)
285
- self.today_disabled_time = 0 if today_disabled_time is None else today_disabled_time
286
- today_exceeded_time = self.daily_summaries[0].get("exceededTime", 0)
287
- self.today_exceeded_time = 0 if today_exceeded_time is None else today_exceeded_time
297
+ if self.daily_summaries[0]["date"] != now.strftime("%Y-%m-%d"):
298
+ _LOGGER.debug("No daily summary for today, assuming 0 playing time.")
299
+ self.today_playing_time = 0
300
+ self.today_disabled_time = 0
301
+ self.today_exceeded_time = 0
302
+ else:
303
+ self.today_playing_time = self.daily_summaries[0].get("playingTime") or 0
304
+ self.today_disabled_time = self.daily_summaries[0].get("disabledTime") or 0
305
+ self.today_exceeded_time = self.daily_summaries[0].get("exceededTime") or 0
288
306
  _LOGGER.debug("Cached playing, disabled and exceeded time for today for device %s",
289
307
  self.device_id)
290
- try:
291
- now = datetime.now()
292
- current_minutes_past_midnight = now.hour * 60 + now.minute
293
- minutes_in_day = 1440 # 24 * 60
294
-
295
- # 1. Calculate remaining time based on play limit
296
-
297
- time_remaining_by_play_limit = 0.0
298
- if self.limit_time in (-1, None):
299
- # No specific play limit, effectively limited by end of day for this calculation step.
300
- time_remaining_by_play_limit = float(minutes_in_day - current_minutes_past_midnight)
301
- elif self.limit_time == 0:
302
- time_remaining_by_play_limit = 0.0
303
- else:
304
- time_remaining_by_play_limit = float(self.limit_time - self.today_playing_time)
305
-
306
- time_remaining_by_play_limit = max(0.0, time_remaining_by_play_limit)
307
-
308
- # Initialize overall remaining time with play limit constraint
309
- effective_remaining_time = time_remaining_by_play_limit
310
-
311
- # 2. Factor in bedtime alarm, if any, to further constrain remaining time
312
- if self.bedtime_alarm not in (None, time(hour=0, minute=0)):
313
- bedtime_dt = datetime.combine(now.date(), self.bedtime_alarm)
314
- time_remaining_by_bedtime = 0.0
315
- if bedtime_dt > now: # Bedtime is in the future today
316
- time_remaining_by_bedtime = (bedtime_dt - now).total_seconds() / 60
317
- time_remaining_by_bedtime = max(0.0, time_remaining_by_bedtime)
318
- # else: Bedtime has passed for today or is now, so time_remaining_by_bedtime remains 0.0
319
-
320
- effective_remaining_time = min(effective_remaining_time, time_remaining_by_bedtime)
321
-
322
- self.today_time_remaining = int(max(0.0, effective_remaining_time)) # Ensure non-negative and integer
323
- _LOGGER.debug("Calculated and updated the amount of time remaining for today: %s", self.today_time_remaining)
324
- self.stats_update_failed = False
325
- except ValueError as err:
326
- _LOGGER.debug("Unable to update daily summary for device %s: %s", self.name, err)
327
- self.stats_update_failed = True
308
+ self._calculate_today_remaining_time(now)
328
309
 
329
- current_month = datetime(
330
- year=datetime.now().year,
331
- month=datetime.now().month,
332
- day=1)
333
310
  month_playing_time: int = 0
334
311
 
335
312
  for summary in self.daily_summaries:
336
313
  date_parsed = datetime.strptime(summary["date"], "%Y-%m-%d")
337
- if date_parsed > current_month:
314
+ if date_parsed.year == now.year and date_parsed.month == now.month:
338
315
  month_playing_time += summary["playingTime"]
339
316
  self.month_playing_time = month_playing_time
340
317
  _LOGGER.debug("Cached current month playing time for device %s", self.device_id)
@@ -362,16 +339,47 @@ class Device:
362
339
  _LOGGER.debug("Unable to retrieve applications for device %s: %s", self.name, err)
363
340
  self.application_update_failed = True
364
341
 
365
- async def _get_parental_control_setting(self):
342
+ def _calculate_today_remaining_time(self, now: datetime):
343
+ """Calculates the remaining playing time for today."""
344
+ self.stats_update_failed = True # Assume failure until success
345
+ try:
346
+ minutes_in_day = 1440 # 24 * 60
347
+ current_minutes_past_midnight = now.hour * 60 + now.minute
348
+
349
+ if self.limit_time in (-1, None):
350
+ # No play limit, so remaining time is until end of day.
351
+ time_remaining_by_play_limit = minutes_in_day - current_minutes_past_midnight
352
+ else:
353
+ time_remaining_by_play_limit = self.limit_time - self.today_playing_time
354
+
355
+ # 2. Calculate remaining time until bedtime
356
+ if self.bedtime_alarm and self.bedtime_alarm != time(hour=0, minute=0) and self.alarms_enabled:
357
+ bedtime_dt = datetime.combine(now.date(), self.bedtime_alarm)
358
+ if bedtime_dt > now: # Bedtime is in the future today
359
+ time_remaining_by_bedtime = (bedtime_dt - now).total_seconds() / 60
360
+ else: # Bedtime has passed
361
+ time_remaining_by_bedtime = 0.0
362
+ else:
363
+ time_remaining_by_bedtime = minutes_in_day - current_minutes_past_midnight
364
+
365
+ # Effective remaining time is the minimum of the two constraints
366
+ effective_remaining_time = min(time_remaining_by_play_limit, time_remaining_by_bedtime)
367
+ self.today_time_remaining = int(max(0.0, effective_remaining_time))
368
+ _LOGGER.debug("Calculated today's remaining time: %s minutes", self.today_time_remaining)
369
+ self.stats_update_failed = False
370
+ except (ValueError, TypeError, AttributeError) as err:
371
+ _LOGGER.warning("Unable to calculate remaining time for device %s: %s", self.name, err)
372
+
373
+ async def _get_parental_control_setting(self, now: datetime):
366
374
  """Retreives parental control settings from the API."""
367
375
  _LOGGER.debug(">> Device._get_parental_control_setting()")
368
376
  response = await self._api.async_get_device_parental_control_setting(
369
377
  device_id=self.device_id
370
378
  )
371
- self._parse_parental_control_setting(response["json"])
372
- self._calculate_times()
379
+ self._parse_parental_control_setting(response["json"], now)
380
+ self._calculate_times(now)
373
381
 
374
- async def _get_daily_summaries(self):
382
+ async def _get_daily_summaries(self, now: datetime):
375
383
  """Retrieve daily summaries."""
376
384
  _LOGGER.debug(">> Device._get_daily_summaries()")
377
385
  response = await self._api.async_get_device_daily_summaries(
@@ -379,7 +387,7 @@ class Device:
379
387
  )
380
388
  self.daily_summaries = response["json"]["dailySummaries"]
381
389
  _LOGGER.debug("New daily summary %s", self.daily_summaries)
382
- self._calculate_times()
390
+ self._calculate_times(now)
383
391
 
384
392
  async def _get_extras(self):
385
393
  """Retrieve extra properties."""
@@ -443,6 +451,8 @@ class Device:
443
451
 
444
452
  def get_date_summary(self, input_date: datetime = datetime.now()) -> dict:
445
453
  """Returns usage for a given date."""
454
+ if not self.daily_summaries:
455
+ raise ValueError("No daily summaries available to search.")
446
456
  summary = [
447
457
  x for x in self.daily_summaries
448
458
  if x["date"] == input_date.strftime('%Y-%m-%d')
@@ -459,19 +469,17 @@ class Device:
459
469
 
460
470
  def get_application(self, application_id: str) -> Application:
461
471
  """Returns a single application."""
462
- app = [x for x in self.applications
463
- if x.application_id == application_id]
464
- if len(app) == 1:
465
- return app[0]
466
- raise ValueError("Application not found.")
472
+ app = next((app for app in self.applications if app.application_id == application_id), None)
473
+ if app:
474
+ return app
475
+ raise ValueError(f"Application with id {application_id} not found.")
467
476
 
468
477
  def get_player(self, player_id: str) -> Player:
469
478
  """Returns a player."""
470
- player = [x for x in self.players
471
- if x.player_id == player_id]
472
- if len(player) == 1:
473
- return player[0]
474
- raise ValueError("Player not found.")
479
+ player = next((p for p in self.players if p.player_id == player_id), None)
480
+ if player:
481
+ return player
482
+ raise ValueError(f"Player with id {player_id} not found.")
475
483
 
476
484
  @classmethod
477
485
  async def from_devices_response(cls, raw: dict, api) -> list['Device']:
@@ -1,6 +1,6 @@
1
1
  """Enums"""
2
2
 
3
- from enum import Enum
3
+ from enum import Enum, StrEnum
4
4
 
5
5
  class AlarmSettingState(Enum):
6
6
  """Alarm setting states."""
@@ -20,3 +20,11 @@ class RestrictionMode(Enum):
20
20
 
21
21
  def __str__(self) -> str:
22
22
  return self.name
23
+
24
+ class DeviceTimerMode(StrEnum):
25
+ """Device timer modes."""
26
+ DAILY = "DAILY"
27
+ EACH_DAY_OF_THE_WEEK = "EACH_DAY_OF_THE_WEEK"
28
+
29
+ def __str__(self) -> str:
30
+ return self.name
@@ -10,13 +10,16 @@ class RangeErrorKeys(StrEnum):
10
10
 
11
11
  class HttpException(Exception):
12
12
  """A HTTP error occured"""
13
- def __init__(self, status_code: int, message: str) -> None:
13
+ def __init__(self, status_code: int, message: str, error_code: str | None = None) -> None:
14
14
  """Initialize the exception."""
15
15
  super().__init__(message)
16
16
  self.status_code = status_code
17
17
  self.message = message
18
+ self.error_code = error_code
18
19
 
19
20
  def __str__(self) -> str:
21
+ if self.error_code:
22
+ return f"HTTP {self.status_code}: {self.message} ({self.error_code})"
20
23
  return f"HTTP {self.status_code}: {self.message}"
21
24
 
22
25
  class InvalidSessionTokenException(HttpException):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pynintendoparental
3
- Version: 1.1.2
3
+ Version: 1.1.3
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
@@ -1,18 +1,18 @@
1
1
  pynintendoparental/__init__.py,sha256=pNcBsHRa4B85USP7uzwPEGF9fu3MA9YgW_hI82F_NXQ,2460
2
- pynintendoparental/_version.py,sha256=5SgGjThsHu_ITn8V83BvCziqCwxdXxTQqcC3KQMHPfM,22
3
- pynintendoparental/api.py,sha256=hMXq0eNIgFELlNZJtN0rK3plKyu9nirvwiUPNlkjOCY,7013
2
+ pynintendoparental/_version.py,sha256=u9ExJqoMv3fQc8WmLTw4I2FnQo6u4xRrBc6DLy6G1IE,22
3
+ pynintendoparental/api.py,sha256=0rqfgSE3mYemk9-220zpdA6Q0HIs_Xyst3WyLOjZqDw,7502
4
4
  pynintendoparental/application.py,sha256=l-oVwM4hrVVUf_2djQ7rJVya7LQP38yhaLPAWt8V8TY,3941
5
5
  pynintendoparental/const.py,sha256=sQZqU0f1NSClMPfCSJonlCunLdbPPiXjL-JS2LMZGd4,2101
6
- pynintendoparental/device.py,sha256=EEQfnab96CIGlB2n1gePQBn5SWx7cck8tX_qz8xAHjc,22956
7
- pynintendoparental/enum.py,sha256=lzacGti7fcQqAOROjB9782De7bOMYKSEM61SQd6aYG4,401
8
- pynintendoparental/exceptions.py,sha256=-KuRBoMtzWKycjdgIsRYPzSVi_uzPjROq7blJSgq-iw,1450
6
+ pynintendoparental/device.py,sha256=VhWVE3IRbxKMwKnAHgMdGmXT-eZFsbCfYE2VFRIvDek,23223
7
+ pynintendoparental/enum.py,sha256=whmcX5JRx60tq6OgviId_0c5JZpiBvmPZSnY6UTGtb8,599
8
+ pynintendoparental/exceptions.py,sha256=rf8uroPkRB9zcIpjQCzKoXJqOzMOAQyy6KITs1vLmoQ,1628
9
9
  pynintendoparental/player.py,sha256=WDl0pspHgrV9lGhDp-NKlfP8DV4Yxe02aYaGg9wTTeg,1785
10
10
  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=MZdA6qqHV0i7rspNL9Z9xl7aRy-EJEm3NIapiIgEJBA,7688
13
13
  pynintendoparental/authenticator/const.py,sha256=_nUJVC0U64j_n1LaQd_KDg0EWFcezb87bQyYYXpbPPY,917
14
- pynintendoparental-1.1.2.dist-info/licenses/LICENSE,sha256=zsxHgHVMnyWq121yND8zBl9Rl9H6EF2K9N51B2ZSm_k,1071
15
- pynintendoparental-1.1.2.dist-info/METADATA,sha256=wV4_2Gwy86YLWZe8SOu5svDLpH2VWsi5ORPCVfYzLKk,1871
16
- pynintendoparental-1.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- pynintendoparental-1.1.2.dist-info/top_level.txt,sha256=QQ5bAl-Ljso16P8KLf1NHrFmKk9jLT7bVJG_rVlIXWk,19
18
- pynintendoparental-1.1.2.dist-info/RECORD,,
14
+ pynintendoparental-1.1.3.dist-info/licenses/LICENSE,sha256=zsxHgHVMnyWq121yND8zBl9Rl9H6EF2K9N51B2ZSm_k,1071
15
+ pynintendoparental-1.1.3.dist-info/METADATA,sha256=w1pPcFJx1kiBOpDwzz9es7kuKASf2gFa8ksGEaCBqhM,1871
16
+ pynintendoparental-1.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ pynintendoparental-1.1.3.dist-info/top_level.txt,sha256=QQ5bAl-Ljso16P8KLf1NHrFmKk9jLT7bVJG_rVlIXWk,19
18
+ pynintendoparental-1.1.3.dist-info/RECORD,,