uiprotect 1.11.0__py3-none-any.whl → 1.11.1__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.
Potentially problematic release.
This version of uiprotect might be problematic. Click here for more details.
- uiprotect/data/base.py +1 -2
- uiprotect/data/bootstrap.py +38 -19
- {uiprotect-1.11.0.dist-info → uiprotect-1.11.1.dist-info}/METADATA +1 -1
- {uiprotect-1.11.0.dist-info → uiprotect-1.11.1.dist-info}/RECORD +7 -7
- {uiprotect-1.11.0.dist-info → uiprotect-1.11.1.dist-info}/LICENSE +0 -0
- {uiprotect-1.11.0.dist-info → uiprotect-1.11.1.dist-info}/WHEEL +0 -0
- {uiprotect-1.11.0.dist-info → uiprotect-1.11.1.dist-info}/entry_points.txt +0 -0
uiprotect/data/base.py
CHANGED
|
@@ -6,7 +6,7 @@ import asyncio
|
|
|
6
6
|
import logging
|
|
7
7
|
from collections.abc import Callable
|
|
8
8
|
from datetime import datetime, timedelta
|
|
9
|
-
from functools import cache
|
|
9
|
+
from functools import cache
|
|
10
10
|
from ipaddress import IPv4Address
|
|
11
11
|
from typing import TYPE_CHECKING, Any, ClassVar, TypeVar
|
|
12
12
|
from uuid import UUID
|
|
@@ -89,7 +89,6 @@ class ProtectBaseObject(BaseModel):
|
|
|
89
89
|
arbitrary_types_allowed = True
|
|
90
90
|
validate_assignment = True
|
|
91
91
|
copy_on_model_validation = "shallow"
|
|
92
|
-
keep_untouched = (cached_property,)
|
|
93
92
|
|
|
94
93
|
def __init__(self, api: ProtectApiClient | None = None, **data: Any) -> None:
|
|
95
94
|
"""
|
uiprotect/data/bootstrap.py
CHANGED
|
@@ -8,7 +8,7 @@ from collections.abc import Iterable
|
|
|
8
8
|
from copy import deepcopy
|
|
9
9
|
from dataclasses import dataclass
|
|
10
10
|
from datetime import datetime
|
|
11
|
-
from functools import cache
|
|
11
|
+
from functools import cache
|
|
12
12
|
from typing import TYPE_CHECKING, Any, cast
|
|
13
13
|
|
|
14
14
|
from aiohttp.client_exceptions import ServerDisconnectedError
|
|
@@ -181,6 +181,10 @@ class Bootstrap(ProtectBaseObject):
|
|
|
181
181
|
mac_lookup: dict[str, ProtectDeviceRef] = {}
|
|
182
182
|
id_lookup: dict[str, ProtectDeviceRef] = {}
|
|
183
183
|
_ws_stats: list[WSStat] = PrivateAttr([])
|
|
184
|
+
_has_doorbell: bool | None = PrivateAttr(None)
|
|
185
|
+
_has_smart: bool | None = PrivateAttr(None)
|
|
186
|
+
_has_media: bool | None = PrivateAttr(None)
|
|
187
|
+
_recording_start: datetime | None = PrivateAttr(None)
|
|
184
188
|
_refresh_tasks: set[asyncio.Task[None]] = PrivateAttr(set())
|
|
185
189
|
|
|
186
190
|
@classmethod
|
|
@@ -248,33 +252,48 @@ class Bootstrap(ProtectBaseObject):
|
|
|
248
252
|
def auth_user(self) -> User:
|
|
249
253
|
return self._api.bootstrap.users[self.auth_user_id]
|
|
250
254
|
|
|
251
|
-
@
|
|
255
|
+
@property
|
|
252
256
|
def has_doorbell(self) -> bool:
|
|
253
|
-
|
|
257
|
+
if self._has_doorbell is None:
|
|
258
|
+
self._has_doorbell = any(
|
|
259
|
+
c.feature_flags.is_doorbell for c in self.cameras.values()
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
return self._has_doorbell
|
|
254
263
|
|
|
255
|
-
@
|
|
264
|
+
@property
|
|
256
265
|
def recording_start(self) -> datetime | None:
|
|
257
|
-
"""Get
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
+
"""Get earilest recording date."""
|
|
267
|
+
if self._recording_start is None:
|
|
268
|
+
try:
|
|
269
|
+
self._recording_start = min(
|
|
270
|
+
c.stats.video.recording_start
|
|
271
|
+
for c in self.cameras.values()
|
|
272
|
+
if c.stats.video.recording_start is not None
|
|
273
|
+
)
|
|
274
|
+
except ValueError:
|
|
275
|
+
return None
|
|
276
|
+
return self._recording_start
|
|
266
277
|
|
|
267
|
-
@
|
|
278
|
+
@property
|
|
268
279
|
def has_smart_detections(self) -> bool:
|
|
269
280
|
"""Check if any camera has smart detections."""
|
|
270
|
-
|
|
281
|
+
if self._has_smart is None:
|
|
282
|
+
self._has_smart = any(
|
|
283
|
+
c.feature_flags.has_smart_detect for c in self.cameras.values()
|
|
284
|
+
)
|
|
285
|
+
return self._has_smart
|
|
271
286
|
|
|
272
|
-
@
|
|
287
|
+
@property
|
|
273
288
|
def has_media(self) -> bool:
|
|
274
289
|
"""Checks if user can read media for any camera."""
|
|
275
|
-
if self.
|
|
276
|
-
|
|
277
|
-
|
|
290
|
+
if self._has_media is None:
|
|
291
|
+
if self.recording_start is None:
|
|
292
|
+
return False
|
|
293
|
+
self._has_media = any(
|
|
294
|
+
c.can_read_media(self.auth_user) for c in self.cameras.values()
|
|
295
|
+
)
|
|
296
|
+
return self._has_media
|
|
278
297
|
|
|
279
298
|
def get_device_from_mac(self, mac: str) -> ProtectAdoptableDeviceModel | None:
|
|
280
299
|
"""Retrieve a device from MAC address."""
|
|
@@ -14,8 +14,8 @@ uiprotect/cli/nvr.py,sha256=TwxEg2XT8jXAbOqv6gc7KFXELKadeItEDYweSL4_-e8,4260
|
|
|
14
14
|
uiprotect/cli/sensors.py,sha256=fQtcDJCVxs4VbAqcavgBy2ABiVxAW3GXtna6_XFBp2k,8153
|
|
15
15
|
uiprotect/cli/viewers.py,sha256=2cyrp104ffIvgT0wYGIO0G35QMkEbFe7fSVqLwDXQYQ,2171
|
|
16
16
|
uiprotect/data/__init__.py,sha256=OcfuJl2qXfHcj_mdnrHhzZ5tEIZrw8auziX5IE7dn-I,2938
|
|
17
|
-
uiprotect/data/base.py,sha256=
|
|
18
|
-
uiprotect/data/bootstrap.py,sha256=
|
|
17
|
+
uiprotect/data/base.py,sha256=apIXKZHL6dbyXTT4C4lkyo4M-Nf_DwsVXoXBL5jcXVo,37574
|
|
18
|
+
uiprotect/data/bootstrap.py,sha256=gDoYacz_WOIOSegGoL-kuw3WQdRcDWUYPd1BL8oBZJ8,21515
|
|
19
19
|
uiprotect/data/convert.py,sha256=8h6Il_DhMkPRDPj9F_rA2UZIlTuchS3BQD24peKpk2A,2185
|
|
20
20
|
uiprotect/data/devices.py,sha256=Nq3bOko5PFf5LvEBoD4JV8kmbq50laRdh3VHMWX7t-0,111809
|
|
21
21
|
uiprotect/data/nvr.py,sha256=XC4NO1c_Mom-hIpzj9ksKFcgKbHd6ToqWjkgzxJ1PJY,47636
|
|
@@ -30,8 +30,8 @@ uiprotect/test_util/__init__.py,sha256=d2g7afa0LSdixQ0kjEDYwafDFME_UlW2LzxpamZ2B
|
|
|
30
30
|
uiprotect/test_util/anonymize.py,sha256=f-8ijU-_y9r-uAbhIPn0f0I6hzJpAkvJzc8UpWihObI,8478
|
|
31
31
|
uiprotect/utils.py,sha256=6OLY8hNiCzk418PjJJIlFW7jjPzVt1vxBKEzBSqMeTk,18418
|
|
32
32
|
uiprotect/websocket.py,sha256=IzDPyqbzrkOMREvahN-e2zdvVD0VABSCWy6jSoCwOT0,7299
|
|
33
|
-
uiprotect-1.11.
|
|
34
|
-
uiprotect-1.11.
|
|
35
|
-
uiprotect-1.11.
|
|
36
|
-
uiprotect-1.11.
|
|
37
|
-
uiprotect-1.11.
|
|
33
|
+
uiprotect-1.11.1.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
|
|
34
|
+
uiprotect-1.11.1.dist-info/METADATA,sha256=fkeec2n5_8G4aBG4D3zqBu4FJM7Nle4ATE14_bm6neo,10985
|
|
35
|
+
uiprotect-1.11.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
36
|
+
uiprotect-1.11.1.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
|
|
37
|
+
uiprotect-1.11.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|