uiprotect 0.4.1__py3-none-any.whl → 0.6.0__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/__init__.py +2 -2
- uiprotect/__main__.py +1 -1
- uiprotect/api.py +7 -7
- uiprotect/cli/__init__.py +16 -15
- uiprotect/cli/backup.py +4 -4
- uiprotect/cli/base.py +4 -4
- uiprotect/cli/cameras.py +3 -3
- uiprotect/cli/chimes.py +3 -3
- uiprotect/cli/doorlocks.py +3 -3
- uiprotect/cli/events.py +5 -5
- uiprotect/cli/lights.py +3 -3
- uiprotect/cli/liveviews.py +3 -3
- uiprotect/cli/nvr.py +2 -2
- uiprotect/cli/sensors.py +3 -3
- uiprotect/cli/viewers.py +3 -3
- uiprotect/data/__init__.py +8 -8
- uiprotect/data/base.py +20 -26
- uiprotect/data/bootstrap.py +17 -11
- uiprotect/data/convert.py +7 -7
- uiprotect/data/devices.py +17 -17
- uiprotect/data/nvr.py +6 -6
- uiprotect/data/user.py +2 -2
- uiprotect/data/websocket.py +3 -3
- uiprotect/stream.py +2 -2
- uiprotect/test_util/__init__.py +5 -5
- uiprotect/test_util/anonymize.py +1 -1
- uiprotect/utils.py +10 -4
- {uiprotect-0.4.1.dist-info → uiprotect-0.6.0.dist-info}/METADATA +1 -1
- uiprotect-0.6.0.dist-info/RECORD +37 -0
- uiprotect-0.4.1.dist-info/RECORD +0 -37
- {uiprotect-0.4.1.dist-info → uiprotect-0.6.0.dist-info}/LICENSE +0 -0
- {uiprotect-0.4.1.dist-info → uiprotect-0.6.0.dist-info}/WHEEL +0 -0
- {uiprotect-0.4.1.dist-info → uiprotect-0.6.0.dist-info}/entry_points.txt +0 -0
uiprotect/__init__.py
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
5
|
+
from .api import ProtectApiClient
|
|
6
|
+
from .exceptions import Invalid, NotAuthorized, NvrError
|
|
7
7
|
|
|
8
8
|
__all__ = [
|
|
9
9
|
"Invalid",
|
uiprotect/__main__.py
CHANGED
uiprotect/api.py
CHANGED
|
@@ -25,7 +25,7 @@ from aiohttp import CookieJar, client_exceptions
|
|
|
25
25
|
from platformdirs import user_cache_dir, user_config_dir
|
|
26
26
|
from yarl import URL
|
|
27
27
|
|
|
28
|
-
from
|
|
28
|
+
from .data import (
|
|
29
29
|
NVR,
|
|
30
30
|
Bootstrap,
|
|
31
31
|
Bridge,
|
|
@@ -50,11 +50,11 @@ from uiprotect.data import (
|
|
|
50
50
|
WSSubscriptionMessage,
|
|
51
51
|
create_from_unifi_dict,
|
|
52
52
|
)
|
|
53
|
-
from
|
|
54
|
-
from
|
|
55
|
-
from
|
|
56
|
-
from
|
|
57
|
-
from
|
|
53
|
+
from .data.base import ProtectModelWithId
|
|
54
|
+
from .data.devices import Chime
|
|
55
|
+
from .data.types import IteratorCallback, ProgressCallback, RecordingMode
|
|
56
|
+
from .exceptions import BadRequest, NotAuthorized, NvrError
|
|
57
|
+
from .utils import (
|
|
58
58
|
decode_token_cookie,
|
|
59
59
|
get_response_reason,
|
|
60
60
|
ip_from_host,
|
|
@@ -62,7 +62,7 @@ from uiprotect.utils import (
|
|
|
62
62
|
to_js_time,
|
|
63
63
|
utc_now,
|
|
64
64
|
)
|
|
65
|
-
from
|
|
65
|
+
from .websocket import Websocket
|
|
66
66
|
|
|
67
67
|
TOKEN_COOKIE_MAX_EXP_SECONDS = 60
|
|
68
68
|
|
uiprotect/cli/__init__.py
CHANGED
|
@@ -12,23 +12,24 @@ import typer
|
|
|
12
12
|
from rich.progress import track
|
|
13
13
|
|
|
14
14
|
from uiprotect.api import ProtectApiClient
|
|
15
|
-
|
|
16
|
-
from
|
|
17
|
-
from
|
|
18
|
-
from
|
|
19
|
-
from
|
|
20
|
-
from
|
|
21
|
-
from
|
|
22
|
-
from
|
|
23
|
-
from
|
|
24
|
-
from
|
|
25
|
-
from
|
|
26
|
-
from
|
|
27
|
-
from
|
|
28
|
-
from
|
|
15
|
+
|
|
16
|
+
from ..data import Version, WSPacket
|
|
17
|
+
from ..test_util import SampleDataGenerator
|
|
18
|
+
from ..utils import RELEASE_CACHE, get_local_timezone, run_async
|
|
19
|
+
from ..utils import profile_ws as profile_ws_job
|
|
20
|
+
from .base import CliContext, OutputFormatEnum
|
|
21
|
+
from .cameras import app as camera_app
|
|
22
|
+
from .chimes import app as chime_app
|
|
23
|
+
from .doorlocks import app as doorlock_app
|
|
24
|
+
from .events import app as event_app
|
|
25
|
+
from .lights import app as light_app
|
|
26
|
+
from .liveviews import app as liveview_app
|
|
27
|
+
from .nvr import app as nvr_app
|
|
28
|
+
from .sensors import app as sensor_app
|
|
29
|
+
from .viewers import app as viewer_app
|
|
29
30
|
|
|
30
31
|
try:
|
|
31
|
-
from
|
|
32
|
+
from .backup import app as backup_app
|
|
32
33
|
except ImportError:
|
|
33
34
|
backup_app = None # type: ignore[assignment]
|
|
34
35
|
|
uiprotect/cli/backup.py
CHANGED
|
@@ -32,10 +32,10 @@ from sqlalchemy import event as saevent
|
|
|
32
32
|
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine
|
|
33
33
|
from sqlalchemy.orm import Mapped, declarative_base, relationship
|
|
34
34
|
|
|
35
|
-
from
|
|
36
|
-
from
|
|
37
|
-
from
|
|
38
|
-
from
|
|
35
|
+
from .. import data as d
|
|
36
|
+
from ..api import ProtectApiClient
|
|
37
|
+
from ..cli import base
|
|
38
|
+
from ..utils import (
|
|
39
39
|
format_duration,
|
|
40
40
|
get_local_timezone,
|
|
41
41
|
local_datetime,
|
uiprotect/cli/base.py
CHANGED
|
@@ -9,10 +9,10 @@ import orjson
|
|
|
9
9
|
import typer
|
|
10
10
|
from pydantic.v1 import ValidationError
|
|
11
11
|
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
from
|
|
15
|
-
from
|
|
12
|
+
from ..api import ProtectApiClient
|
|
13
|
+
from ..data import NVR, ProtectAdoptableDeviceModel, ProtectBaseObject
|
|
14
|
+
from ..exceptions import BadRequest, NvrError, StreamError
|
|
15
|
+
from ..utils import run_async
|
|
16
16
|
|
|
17
17
|
try:
|
|
18
18
|
from pydantic.v1 import ValidationError
|
uiprotect/cli/cameras.py
CHANGED
|
@@ -8,9 +8,9 @@ from typing import Optional, cast
|
|
|
8
8
|
import typer
|
|
9
9
|
from rich.progress import Progress
|
|
10
10
|
|
|
11
|
-
from
|
|
12
|
-
from
|
|
13
|
-
from
|
|
11
|
+
from .. import data as d
|
|
12
|
+
from ..api import ProtectApiClient
|
|
13
|
+
from ..cli import base
|
|
14
14
|
|
|
15
15
|
app = typer.Typer(rich_markup_mode="rich")
|
|
16
16
|
|
uiprotect/cli/chimes.py
CHANGED
|
@@ -5,9 +5,9 @@ from typing import Optional
|
|
|
5
5
|
|
|
6
6
|
import typer
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from ..api import ProtectApiClient
|
|
9
|
+
from ..cli import base
|
|
10
|
+
from ..data import Chime
|
|
11
11
|
|
|
12
12
|
app = typer.Typer(rich_markup_mode="rich")
|
|
13
13
|
|
uiprotect/cli/doorlocks.py
CHANGED
|
@@ -6,9 +6,9 @@ from typing import Optional
|
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from
|
|
9
|
+
from ..api import ProtectApiClient
|
|
10
|
+
from ..cli import base
|
|
11
|
+
from ..data import Doorlock
|
|
12
12
|
|
|
13
13
|
app = typer.Typer(rich_markup_mode="rich")
|
|
14
14
|
|
uiprotect/cli/events.py
CHANGED
|
@@ -9,11 +9,11 @@ from typing import Optional
|
|
|
9
9
|
import typer
|
|
10
10
|
from rich.progress import Progress
|
|
11
11
|
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
from
|
|
15
|
-
from
|
|
16
|
-
from
|
|
12
|
+
from .. import data as d
|
|
13
|
+
from ..api import ProtectApiClient
|
|
14
|
+
from ..cli import base
|
|
15
|
+
from ..exceptions import NvrError
|
|
16
|
+
from ..utils import local_datetime
|
|
17
17
|
|
|
18
18
|
app = typer.Typer(rich_markup_mode="rich")
|
|
19
19
|
|
uiprotect/cli/lights.py
CHANGED
|
@@ -6,9 +6,9 @@ from typing import Optional
|
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from
|
|
9
|
+
from ..api import ProtectApiClient
|
|
10
|
+
from ..cli import base
|
|
11
|
+
from ..data import Light
|
|
12
12
|
|
|
13
13
|
app = typer.Typer(rich_markup_mode="rich")
|
|
14
14
|
|
uiprotect/cli/liveviews.py
CHANGED
|
@@ -5,9 +5,9 @@ from typing import Optional
|
|
|
5
5
|
|
|
6
6
|
import typer
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from ..api import ProtectApiClient
|
|
9
|
+
from ..cli import base
|
|
10
|
+
from ..data import Liveview
|
|
11
11
|
|
|
12
12
|
app = typer.Typer(rich_markup_mode="rich")
|
|
13
13
|
|
uiprotect/cli/nvr.py
CHANGED
|
@@ -6,8 +6,8 @@ from datetime import timedelta
|
|
|
6
6
|
import orjson
|
|
7
7
|
import typer
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
9
|
+
from ..cli import base
|
|
10
|
+
from ..data import NVR, AnalyticsOption
|
|
11
11
|
|
|
12
12
|
app = typer.Typer(rich_markup_mode="rich")
|
|
13
13
|
|
uiprotect/cli/sensors.py
CHANGED
|
@@ -5,9 +5,9 @@ from typing import Optional
|
|
|
5
5
|
|
|
6
6
|
import typer
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from ..api import ProtectApiClient
|
|
9
|
+
from ..cli import base
|
|
10
|
+
from ..data import MountType, Sensor
|
|
11
11
|
|
|
12
12
|
app = typer.Typer(rich_markup_mode="rich")
|
|
13
13
|
|
uiprotect/cli/viewers.py
CHANGED
|
@@ -5,9 +5,9 @@ from typing import Optional
|
|
|
5
5
|
|
|
6
6
|
import typer
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from ..api import ProtectApiClient
|
|
9
|
+
from ..cli import base
|
|
10
|
+
from ..data import Viewer
|
|
11
11
|
|
|
12
12
|
app = typer.Typer(rich_markup_mode="rich")
|
|
13
13
|
|
uiprotect/data/__init__.py
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from .base import (
|
|
4
4
|
ProtectAdoptableDeviceModel,
|
|
5
5
|
ProtectBaseObject,
|
|
6
6
|
ProtectDeviceModel,
|
|
7
7
|
ProtectModel,
|
|
8
8
|
ProtectModelWithId,
|
|
9
9
|
)
|
|
10
|
-
from
|
|
11
|
-
from
|
|
12
|
-
from
|
|
10
|
+
from .bootstrap import Bootstrap
|
|
11
|
+
from .convert import create_from_unifi_dict
|
|
12
|
+
from .devices import (
|
|
13
13
|
Bridge,
|
|
14
14
|
Camera,
|
|
15
15
|
CameraChannel,
|
|
@@ -21,7 +21,7 @@ from uiprotect.data.devices import (
|
|
|
21
21
|
Sensor,
|
|
22
22
|
Viewer,
|
|
23
23
|
)
|
|
24
|
-
from
|
|
24
|
+
from .nvr import (
|
|
25
25
|
NVR,
|
|
26
26
|
DoorbellMessage,
|
|
27
27
|
Event,
|
|
@@ -30,7 +30,7 @@ from uiprotect.data.nvr import (
|
|
|
30
30
|
SmartDetectItem,
|
|
31
31
|
SmartDetectTrack,
|
|
32
32
|
)
|
|
33
|
-
from
|
|
33
|
+
from .types import (
|
|
34
34
|
DEFAULT,
|
|
35
35
|
DEFAULT_TYPE,
|
|
36
36
|
AnalyticsOption,
|
|
@@ -69,8 +69,8 @@ from uiprotect.data.types import (
|
|
|
69
69
|
VideoMode,
|
|
70
70
|
WDRLevel,
|
|
71
71
|
)
|
|
72
|
-
from
|
|
73
|
-
from
|
|
72
|
+
from .user import CloudAccount, Group, Permission, User, UserLocation
|
|
73
|
+
from .websocket import (
|
|
74
74
|
WS_HEADER_SIZE,
|
|
75
75
|
WSAction,
|
|
76
76
|
WSJSONPacketFrame,
|
uiprotect/data/base.py
CHANGED
|
@@ -11,28 +11,28 @@ from ipaddress import IPv4Address
|
|
|
11
11
|
from typing import TYPE_CHECKING, Any, ClassVar, TypeVar
|
|
12
12
|
from uuid import UUID
|
|
13
13
|
|
|
14
|
-
from
|
|
14
|
+
from ..exceptions import BadRequest, ClientError, NotAuthorized
|
|
15
|
+
from ..utils import (
|
|
16
|
+
asyncio_timeout,
|
|
17
|
+
convert_unifi_data,
|
|
18
|
+
dict_diff,
|
|
19
|
+
is_debug,
|
|
20
|
+
process_datetime,
|
|
21
|
+
serialize_unifi_obj,
|
|
22
|
+
to_snake_case,
|
|
23
|
+
)
|
|
24
|
+
from .types import (
|
|
15
25
|
ModelType,
|
|
16
26
|
PercentFloat,
|
|
17
27
|
PermissionNode,
|
|
18
28
|
ProtectWSPayloadFormat,
|
|
19
29
|
StateType,
|
|
20
30
|
)
|
|
21
|
-
from
|
|
31
|
+
from .websocket import (
|
|
22
32
|
WSJSONPacketFrame,
|
|
23
33
|
WSPacket,
|
|
24
34
|
WSPacketFrameHeader,
|
|
25
35
|
)
|
|
26
|
-
from uiprotect.exceptions import BadRequest, ClientError, NotAuthorized
|
|
27
|
-
from uiprotect.utils import (
|
|
28
|
-
asyncio_timeout,
|
|
29
|
-
convert_unifi_data,
|
|
30
|
-
dict_diff,
|
|
31
|
-
is_debug,
|
|
32
|
-
process_datetime,
|
|
33
|
-
serialize_unifi_obj,
|
|
34
|
-
to_snake_case,
|
|
35
|
-
)
|
|
36
36
|
|
|
37
37
|
try:
|
|
38
38
|
from pydantic.v1 import BaseModel
|
|
@@ -50,10 +50,10 @@ if TYPE_CHECKING:
|
|
|
50
50
|
|
|
51
51
|
from typing_extensions import Self # requires Python 3.11+
|
|
52
52
|
|
|
53
|
-
from
|
|
54
|
-
from
|
|
55
|
-
from
|
|
56
|
-
from
|
|
53
|
+
from ..api import ProtectApiClient
|
|
54
|
+
from ..data.devices import Bridge
|
|
55
|
+
from ..data.nvr import Event
|
|
56
|
+
from ..data.user import User
|
|
57
57
|
|
|
58
58
|
try:
|
|
59
59
|
from pydantic.v1.typing import DictStrAny, SetStr
|
|
@@ -140,7 +140,7 @@ class ProtectBaseObject(BaseModel):
|
|
|
140
140
|
|
|
141
141
|
@classmethod
|
|
142
142
|
def construct(cls, _fields_set: set[str] | None = None, **values: Any) -> Self:
|
|
143
|
-
api = values.pop("api", None)
|
|
143
|
+
api: ProtectApiClient | None = values.pop("api", None)
|
|
144
144
|
values_set = set(values)
|
|
145
145
|
|
|
146
146
|
unifi_objs = cls._get_protect_objs()
|
|
@@ -281,14 +281,6 @@ class ProtectBaseObject(BaseModel):
|
|
|
281
281
|
|
|
282
282
|
return cls._protect_dicts_set
|
|
283
283
|
|
|
284
|
-
@classmethod
|
|
285
|
-
def _get_api(cls, api: ProtectApiClient | None) -> ProtectApiClient | None:
|
|
286
|
-
"""Helper method to try to find and the current ProjtectAPIClient instance from given data"""
|
|
287
|
-
if api is None and isinstance(cls, ProtectBaseObject) and hasattr(cls, "_api"): # type: ignore[unreachable]
|
|
288
|
-
api = cls._api # type: ignore[unreachable]
|
|
289
|
-
|
|
290
|
-
return api
|
|
291
|
-
|
|
292
284
|
@classmethod
|
|
293
285
|
def _clean_protect_obj(
|
|
294
286
|
cls,
|
|
@@ -340,7 +332,9 @@ class ProtectBaseObject(BaseModel):
|
|
|
340
332
|
|
|
341
333
|
"""
|
|
342
334
|
# get the API client instance
|
|
343
|
-
api =
|
|
335
|
+
api: ProtectApiClient | None = data.get("api") or (
|
|
336
|
+
cls._api if isinstance(cls, ProtectBaseObject) else None
|
|
337
|
+
)
|
|
344
338
|
|
|
345
339
|
# remap keys that will not be converted correctly by snake_case convert
|
|
346
340
|
remaps = cls._get_unifi_remaps()
|
uiprotect/data/bootstrap.py
CHANGED
|
@@ -7,7 +7,7 @@ import logging
|
|
|
7
7
|
from copy import deepcopy
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from datetime import datetime
|
|
10
|
-
from typing import Any, cast
|
|
10
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
11
11
|
|
|
12
12
|
from aiohttp.client_exceptions import ServerDisconnectedError
|
|
13
13
|
|
|
@@ -16,14 +16,16 @@ try:
|
|
|
16
16
|
except ImportError:
|
|
17
17
|
from pydantic import PrivateAttr, ValidationError # type: ignore[assignment]
|
|
18
18
|
|
|
19
|
-
from
|
|
19
|
+
from ..exceptions import ClientError
|
|
20
|
+
from ..utils import utc_now
|
|
21
|
+
from .base import (
|
|
20
22
|
RECENT_EVENT_MAX,
|
|
21
23
|
ProtectBaseObject,
|
|
22
24
|
ProtectModel,
|
|
23
25
|
ProtectModelWithId,
|
|
24
26
|
)
|
|
25
|
-
from
|
|
26
|
-
from
|
|
27
|
+
from .convert import create_from_unifi_dict
|
|
28
|
+
from .devices import (
|
|
27
29
|
Bridge,
|
|
28
30
|
Camera,
|
|
29
31
|
Chime,
|
|
@@ -33,17 +35,19 @@ from uiprotect.data.devices import (
|
|
|
33
35
|
Sensor,
|
|
34
36
|
Viewer,
|
|
35
37
|
)
|
|
36
|
-
from
|
|
37
|
-
from
|
|
38
|
-
from
|
|
39
|
-
from
|
|
38
|
+
from .nvr import NVR, Event, Liveview
|
|
39
|
+
from .types import EventType, FixSizeOrderedDict, ModelType
|
|
40
|
+
from .user import Group, User
|
|
41
|
+
from .websocket import (
|
|
40
42
|
WSAction,
|
|
41
43
|
WSJSONPacketFrame,
|
|
42
44
|
WSPacket,
|
|
43
45
|
WSSubscriptionMessage,
|
|
44
46
|
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
|
|
48
|
+
if TYPE_CHECKING:
|
|
49
|
+
from ..api import ProtectApiClient
|
|
50
|
+
|
|
47
51
|
|
|
48
52
|
_LOGGER = logging.getLogger(__name__)
|
|
49
53
|
|
|
@@ -198,7 +202,9 @@ class Bootstrap(ProtectBaseObject):
|
|
|
198
202
|
|
|
199
203
|
@classmethod
|
|
200
204
|
def unifi_dict_to_dict(cls, data: dict[str, Any]) -> dict[str, Any]:
|
|
201
|
-
api =
|
|
205
|
+
api: ProtectApiClient | None = data.get("api") or (
|
|
206
|
+
cls._api if isinstance(cls, ProtectBaseObject) else None
|
|
207
|
+
)
|
|
202
208
|
data["macLookup"] = {}
|
|
203
209
|
data["idLookup"] = {}
|
|
204
210
|
for model_type in ModelType.bootstrap_models():
|
uiprotect/data/convert.py
CHANGED
|
@@ -4,7 +4,8 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from ..exceptions import DataDecodeError
|
|
8
|
+
from .devices import (
|
|
8
9
|
Bridge,
|
|
9
10
|
Camera,
|
|
10
11
|
Chime,
|
|
@@ -13,14 +14,13 @@ from uiprotect.data.devices import (
|
|
|
13
14
|
Sensor,
|
|
14
15
|
Viewer,
|
|
15
16
|
)
|
|
16
|
-
from
|
|
17
|
-
from
|
|
18
|
-
from
|
|
19
|
-
from uiprotect.exceptions import DataDecodeError
|
|
17
|
+
from .nvr import NVR, Event, Liveview
|
|
18
|
+
from .types import ModelType
|
|
19
|
+
from .user import CloudAccount, Group, User, UserLocation
|
|
20
20
|
|
|
21
21
|
if TYPE_CHECKING:
|
|
22
|
-
from
|
|
23
|
-
from
|
|
22
|
+
from ..api import ProtectApiClient
|
|
23
|
+
from ..data.base import ProtectModel
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
MODEL_TO_CLASS: dict[str, type[ProtectModel]] = {
|
uiprotect/data/devices.py
CHANGED
|
@@ -17,13 +17,26 @@ try:
|
|
|
17
17
|
except ImportError:
|
|
18
18
|
from pydantic.fields import PrivateAttr
|
|
19
19
|
|
|
20
|
-
from
|
|
20
|
+
from ..exceptions import BadRequest, NotAuthorized, StreamError
|
|
21
|
+
from ..stream import TalkbackStream
|
|
22
|
+
from ..utils import (
|
|
23
|
+
clamp_value,
|
|
24
|
+
convert_smart_audio_types,
|
|
25
|
+
convert_smart_types,
|
|
26
|
+
convert_video_modes,
|
|
27
|
+
from_js_time,
|
|
28
|
+
process_datetime,
|
|
29
|
+
serialize_point,
|
|
30
|
+
to_js_time,
|
|
31
|
+
utc_now,
|
|
32
|
+
)
|
|
33
|
+
from .base import (
|
|
21
34
|
EVENT_PING_INTERVAL,
|
|
22
35
|
ProtectAdoptableDeviceModel,
|
|
23
36
|
ProtectBaseObject,
|
|
24
37
|
ProtectMotionDeviceModel,
|
|
25
38
|
)
|
|
26
|
-
from
|
|
39
|
+
from .types import (
|
|
27
40
|
DEFAULT,
|
|
28
41
|
DEFAULT_TYPE,
|
|
29
42
|
AudioCodecs,
|
|
@@ -65,23 +78,10 @@ from uiprotect.data.types import (
|
|
|
65
78
|
VideoMode,
|
|
66
79
|
WDRLevel,
|
|
67
80
|
)
|
|
68
|
-
from
|
|
69
|
-
from uiprotect.exceptions import BadRequest, NotAuthorized, StreamError
|
|
70
|
-
from uiprotect.stream import TalkbackStream
|
|
71
|
-
from uiprotect.utils import (
|
|
72
|
-
clamp_value,
|
|
73
|
-
convert_smart_audio_types,
|
|
74
|
-
convert_smart_types,
|
|
75
|
-
convert_video_modes,
|
|
76
|
-
from_js_time,
|
|
77
|
-
process_datetime,
|
|
78
|
-
serialize_point,
|
|
79
|
-
to_js_time,
|
|
80
|
-
utc_now,
|
|
81
|
-
)
|
|
81
|
+
from .user import User
|
|
82
82
|
|
|
83
83
|
if TYPE_CHECKING:
|
|
84
|
-
from
|
|
84
|
+
from .nvr import Event, Liveview
|
|
85
85
|
|
|
86
86
|
PRIVACY_ZONE_NAME = "pyufp_privacy_zone"
|
|
87
87
|
LUX_MAPPING_VALUES = [
|
uiprotect/data/nvr.py
CHANGED
|
@@ -16,12 +16,14 @@ import aiofiles
|
|
|
16
16
|
import orjson
|
|
17
17
|
from aiofiles import os as aos
|
|
18
18
|
|
|
19
|
-
from
|
|
19
|
+
from ..exceptions import BadRequest, NotAuthorized
|
|
20
|
+
from ..utils import RELEASE_CACHE, process_datetime
|
|
21
|
+
from .base import (
|
|
20
22
|
ProtectBaseObject,
|
|
21
23
|
ProtectDeviceModel,
|
|
22
24
|
ProtectModelWithId,
|
|
23
25
|
)
|
|
24
|
-
from
|
|
26
|
+
from .devices import (
|
|
25
27
|
Camera,
|
|
26
28
|
CameraZone,
|
|
27
29
|
Light,
|
|
@@ -30,7 +32,7 @@ from uiprotect.data.devices import (
|
|
|
30
32
|
Sensor,
|
|
31
33
|
SmartDetectSettings,
|
|
32
34
|
)
|
|
33
|
-
from
|
|
35
|
+
from .types import (
|
|
34
36
|
AnalyticsOption,
|
|
35
37
|
DoorbellMessageType,
|
|
36
38
|
DoorbellText,
|
|
@@ -53,9 +55,7 @@ from uiprotect.data.types import (
|
|
|
53
55
|
StorageType,
|
|
54
56
|
Version,
|
|
55
57
|
)
|
|
56
|
-
from
|
|
57
|
-
from uiprotect.exceptions import BadRequest, NotAuthorized
|
|
58
|
-
from uiprotect.utils import RELEASE_CACHE, process_datetime
|
|
58
|
+
from .user import User, UserLocation
|
|
59
59
|
|
|
60
60
|
try:
|
|
61
61
|
from pydantic.v1.fields import PrivateAttr
|
uiprotect/data/user.py
CHANGED
|
@@ -11,8 +11,8 @@ try:
|
|
|
11
11
|
except ImportError:
|
|
12
12
|
from pydantic.fields import PrivateAttr
|
|
13
13
|
|
|
14
|
-
from
|
|
15
|
-
from
|
|
14
|
+
from .base import ProtectBaseObject, ProtectModel, ProtectModelWithId
|
|
15
|
+
from .types import ModelType, PermissionNode
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class Permission(ProtectBaseObject):
|
uiprotect/data/websocket.py
CHANGED
|
@@ -11,11 +11,11 @@ from typing import TYPE_CHECKING, Any
|
|
|
11
11
|
|
|
12
12
|
import orjson
|
|
13
13
|
|
|
14
|
-
from
|
|
15
|
-
from
|
|
14
|
+
from ..exceptions import WSDecodeError, WSEncodeError
|
|
15
|
+
from .types import ProtectWSPayloadFormat
|
|
16
16
|
|
|
17
17
|
if TYPE_CHECKING:
|
|
18
|
-
from
|
|
18
|
+
from .base import ProtectModelWithId
|
|
19
19
|
|
|
20
20
|
WS_HEADER_SIZE = 8
|
|
21
21
|
|
uiprotect/stream.py
CHANGED
|
@@ -11,10 +11,10 @@ from urllib.parse import urlparse
|
|
|
11
11
|
|
|
12
12
|
from aioshutil import which
|
|
13
13
|
|
|
14
|
-
from
|
|
14
|
+
from .exceptions import BadRequest, StreamError
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
|
-
from
|
|
17
|
+
from .data import Camera
|
|
18
18
|
|
|
19
19
|
_LOGGER = logging.getLogger(__name__)
|
|
20
20
|
|
uiprotect/test_util/__init__.py
CHANGED
|
@@ -15,14 +15,14 @@ from typing import Any, overload
|
|
|
15
15
|
import aiohttp
|
|
16
16
|
from PIL import Image
|
|
17
17
|
|
|
18
|
-
from
|
|
19
|
-
from
|
|
20
|
-
from
|
|
21
|
-
from
|
|
18
|
+
from ..api import ProtectApiClient
|
|
19
|
+
from ..data import EventType, WSJSONPacketFrame, WSPacket
|
|
20
|
+
from ..exceptions import BadRequest
|
|
21
|
+
from ..test_util.anonymize import (
|
|
22
22
|
anonymize_data,
|
|
23
23
|
anonymize_prefixed_event_id,
|
|
24
24
|
)
|
|
25
|
-
from
|
|
25
|
+
from ..utils import from_js_time, is_online, run_async, write_json
|
|
26
26
|
|
|
27
27
|
BLANK_VIDEO_CMD = "ffmpeg -y -hide_banner -loglevel error -f lavfi -i color=size=1280x720:rate=25:color=black -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -t {length} {filename}"
|
|
28
28
|
|
uiprotect/test_util/anonymize.py
CHANGED
uiprotect/utils.py
CHANGED
|
@@ -29,14 +29,14 @@ from uuid import UUID
|
|
|
29
29
|
import jwt
|
|
30
30
|
from aiohttp import ClientResponse
|
|
31
31
|
|
|
32
|
-
from
|
|
32
|
+
from .data.types import (
|
|
33
33
|
Color,
|
|
34
34
|
SmartDetectAudioType,
|
|
35
35
|
SmartDetectObjectType,
|
|
36
36
|
Version,
|
|
37
37
|
VideoMode,
|
|
38
38
|
)
|
|
39
|
-
from
|
|
39
|
+
from .exceptions import NvrError
|
|
40
40
|
|
|
41
41
|
try:
|
|
42
42
|
from pydantic.v1.fields import SHAPE_DICT, SHAPE_LIST, SHAPE_SET, ModelField
|
|
@@ -234,11 +234,11 @@ def convert_unifi_data(value: Any, field: ModelField) -> Any:
|
|
|
234
234
|
return value
|
|
235
235
|
if type_ == datetime:
|
|
236
236
|
return from_js_time(value)
|
|
237
|
-
if type_ in _CREATE_TYPES or (
|
|
237
|
+
if type_ in _CREATE_TYPES or _is_enum_type(type_):
|
|
238
238
|
# cannot do this check too soon because some types cannot be used in isinstance
|
|
239
239
|
if isinstance(value, type_):
|
|
240
240
|
return value
|
|
241
|
-
# handle edge case for improperly
|
|
241
|
+
# handle edge case for improperly formatted UUIDs
|
|
242
242
|
# 00000000-0000-00 0- 000-000000000000
|
|
243
243
|
if type_ == UUID and value == _BAD_UUID:
|
|
244
244
|
value = "0" * 32
|
|
@@ -247,6 +247,12 @@ def convert_unifi_data(value: Any, field: ModelField) -> Any:
|
|
|
247
247
|
return value
|
|
248
248
|
|
|
249
249
|
|
|
250
|
+
@lru_cache
|
|
251
|
+
def _is_enum_type(type_: Any) -> bool:
|
|
252
|
+
"""Checks if type is an Enum."""
|
|
253
|
+
return isclass(type_) and issubclass(type_, Enum)
|
|
254
|
+
|
|
255
|
+
|
|
250
256
|
def serialize_unifi_obj(value: Any, levels: int = -1) -> Any:
|
|
251
257
|
"""Serializes UFP data"""
|
|
252
258
|
if unifi_dict := getattr(value, "unifi_dict", None):
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
uiprotect/__init__.py,sha256=llnQNtiBfwQG8IkQXovvFz4LZeFjrJx7XdmmUhu3a9E,289
|
|
2
|
+
uiprotect/__main__.py,sha256=C_bHCOkv5qj6WMy-6ELoY3Y6HDhLxOa1a30CzmbZhsg,462
|
|
3
|
+
uiprotect/api.py,sha256=1eIAuA4GC32-mpibk-Avd4vU59fT_UgxqjKVP9ISTkY,65943
|
|
4
|
+
uiprotect/cli/__init__.py,sha256=sSLW9keVQOkgFcMW18HTDjRrt9sJ0KWjn9DJDA6f9Pc,8658
|
|
5
|
+
uiprotect/cli/backup.py,sha256=SxUyFFwLHcU60qsI8qBS_Xw7RLJeqUEdMAyjwk30MKw,36715
|
|
6
|
+
uiprotect/cli/base.py,sha256=zpTm2kyJe_GLixnv3Uadke__iRLh64AEwQzp-2hqS7g,7730
|
|
7
|
+
uiprotect/cli/cameras.py,sha256=YvvMccQEYG3Wih0Ix8tan1R1vfaJ6cogg6YKWLzMUV8,16973
|
|
8
|
+
uiprotect/cli/chimes.py,sha256=XANn21bQVkestkKOm9HjxSM8ZGrRrqvUXLouaQ3LTqs,5326
|
|
9
|
+
uiprotect/cli/doorlocks.py,sha256=Go_Tn68bAcmrRAnUIi4kBiR7ciKQsu_R150ubPTjUAs,3523
|
|
10
|
+
uiprotect/cli/events.py,sha256=D5SRejKzsPpKlZ9O2J4wkJRigFRVEymiLyU8VQ43fqI,7186
|
|
11
|
+
uiprotect/cli/lights.py,sha256=RxP1ebYEn2o5812OfrovmJLaNuIDoSNWiX1FvCbcdDw,3314
|
|
12
|
+
uiprotect/cli/liveviews.py,sha256=GU5z-ZLRBXHyspDKiJpiv-kbaBcvxK_-K70rPoqx2Ms,1863
|
|
13
|
+
uiprotect/cli/nvr.py,sha256=TwxEg2XT8jXAbOqv6gc7KFXELKadeItEDYweSL4_-e8,4260
|
|
14
|
+
uiprotect/cli/sensors.py,sha256=fQtcDJCVxs4VbAqcavgBy2ABiVxAW3GXtna6_XFBp2k,8153
|
|
15
|
+
uiprotect/cli/viewers.py,sha256=2cyrp104ffIvgT0wYGIO0G35QMkEbFe7fSVqLwDXQYQ,2171
|
|
16
|
+
uiprotect/data/__init__.py,sha256=OcfuJl2qXfHcj_mdnrHhzZ5tEIZrw8auziX5IE7dn-I,2938
|
|
17
|
+
uiprotect/data/base.py,sha256=esEXOzJt2xKOeYASwCcCotjeZLQEPiT08bnGzNv-k8c,37501
|
|
18
|
+
uiprotect/data/bootstrap.py,sha256=ibfCHqNhH44iw-JsuQs41zBCjb9ksSXz_QQq7qDbLsQ,21876
|
|
19
|
+
uiprotect/data/convert.py,sha256=rOQplUMIdTMD2SbAx_iI9BNPDscnhDvyRVLEMDhtADg,2047
|
|
20
|
+
uiprotect/data/devices.py,sha256=AsCQCoOpswdIU7X5ty1XhhOl2v6CkQCXu2Y-lIS_6_k,111712
|
|
21
|
+
uiprotect/data/nvr.py,sha256=c8WxXpBcMaZ5REzCUb8aqmlLkttFYO1O5jLMhus5rkw,47605
|
|
22
|
+
uiprotect/data/types.py,sha256=MTi9dVzKTp_8XtAmWKtbZujwE5plKGHdjglFGcJ4Yxs,15789
|
|
23
|
+
uiprotect/data/user.py,sha256=yBnUQ3qpHL745hLhR41WjWv_Yx51RlmfHapgvK0KSgM,7067
|
|
24
|
+
uiprotect/data/websocket.py,sha256=lkdobRh5SPu7YzLHyhZVe7qlh5W3L8LKzS63Md-4DOk,6048
|
|
25
|
+
uiprotect/exceptions.py,sha256=kgn0cRM6lTtgLza09SDa3ZiX6ue1QqHCOogQ4qu6KTQ,965
|
|
26
|
+
uiprotect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
uiprotect/release_cache.json,sha256=NamnSFy78hOWY0DPO87J9ELFCAN6NnVquv8gQO75ZG4,386
|
|
28
|
+
uiprotect/stream.py,sha256=McV3XymKyjn-1uV5jdQHcpaDjqLS4zWyMASQ8ubcyb4,4924
|
|
29
|
+
uiprotect/test_util/__init__.py,sha256=d2g7afa0LSdixQ0kjEDYwafDFME_UlW2LzxpamZ2BC0,18556
|
|
30
|
+
uiprotect/test_util/anonymize.py,sha256=f-8ijU-_y9r-uAbhIPn0f0I6hzJpAkvJzc8UpWihObI,8478
|
|
31
|
+
uiprotect/utils.py,sha256=gCLoZBQ94Yi9PqefiqTZK7WrvT3Byue79a4jvDc0k44,18226
|
|
32
|
+
uiprotect/websocket.py,sha256=iMTdchymaCgVHsmY1bRbxkcymqt6WQircIHYNxCu178,7289
|
|
33
|
+
uiprotect-0.6.0.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
|
|
34
|
+
uiprotect-0.6.0.dist-info/METADATA,sha256=bWI_c91BlR_JzCp3RhTjbiTUVR-adQJH61fNBqZt5fE,10984
|
|
35
|
+
uiprotect-0.6.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
36
|
+
uiprotect-0.6.0.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
|
|
37
|
+
uiprotect-0.6.0.dist-info/RECORD,,
|
uiprotect-0.4.1.dist-info/RECORD
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
uiprotect/__init__.py,sha256=tzcxK6cOIIkFEtST4Zjq3bafYTFWtwnaL92DgypjFi8,307
|
|
2
|
-
uiprotect/__main__.py,sha256=T69KE5W4zek6qeNEL8_Fq2DEfBc04SqSuIOJpiW4ydE,471
|
|
3
|
-
uiprotect/api.py,sha256=G2cvwLuanzvZ7dGfJOlAMvbKSBIsb7t3uOPB-KyT8gk,66006
|
|
4
|
-
uiprotect/cli/__init__.py,sha256=tmwtYrhM8rjOw8noKD6NALl_2Nu3xIycDuQyEKD5oMk,8832
|
|
5
|
-
uiprotect/cli/backup.py,sha256=Mtjd2f0w7zjIeLkJILKxiBnZJYXypzC9gpyAmBZ8sq0,36746
|
|
6
|
-
uiprotect/cli/base.py,sha256=dE6vYb4nLAYbUdHwcKkN7I3iXqTjz84jfHGnsLmk_Ds,7762
|
|
7
|
-
uiprotect/cli/cameras.py,sha256=mVLJ5FjZPSbpNXvtd7Yiz17zMDSdLWT0p6Wcaqpt0GQ,16996
|
|
8
|
-
uiprotect/cli/chimes.py,sha256=92kNiZN7FpuCF7CqK9oLPt2jQ96tNhTjP1JcOdJAKhU,5350
|
|
9
|
-
uiprotect/cli/doorlocks.py,sha256=XMftrrK0O0bWZHOuTwg9m4p9U7gC0FzHFb72bSnlUEg,3547
|
|
10
|
-
uiprotect/cli/events.py,sha256=Ni_igTOdOf11pklpNEocBdwd3EW6O0wD8Iz-lN2zMJA,7225
|
|
11
|
-
uiprotect/cli/lights.py,sha256=EgJsQ37c3QzSKoYf6h-rCaQoiftNh2igY1bTB_tQz14,3338
|
|
12
|
-
uiprotect/cli/liveviews.py,sha256=TrLAqG2_GpNoWyw9IRY-4mJmlFwxGZxUuIdi-YU_NuM,1887
|
|
13
|
-
uiprotect/cli/nvr.py,sha256=PVpUitWzP9HLy2yoj0HP-b-4Te5AFCrahUAmrQJ4z-w,4276
|
|
14
|
-
uiprotect/cli/sensors.py,sha256=CE77weDkYepo9eEs1J0ModIs3pWNWmesjAq3rlmiez0,8177
|
|
15
|
-
uiprotect/cli/viewers.py,sha256=SZlolZH3kkcWKjATrA37TCVZYRpF0t4cCccrC8vIv-M,2195
|
|
16
|
-
uiprotect/data/__init__.py,sha256=38Kb1DVi4kv9FTTwugatPNSWLiIp6uvUlTMZRQp2jTY,3050
|
|
17
|
-
uiprotect/data/base.py,sha256=YJ0iofoy1K3EG55npokU3T2CLRC8kctutfIy0Sq_6Sg,37850
|
|
18
|
-
uiprotect/data/bootstrap.py,sha256=fyC6CoYnm90r1VAWSuOe8FFh8ULaGSv6jNMQcpKPBZA,21821
|
|
19
|
-
uiprotect/data/convert.py,sha256=f8QkwZnlNbV_W-YognlDvZ1gQKp5yFuC50396hcu6DU,2127
|
|
20
|
-
uiprotect/data/devices.py,sha256=3UOOzFXgJP7AOPKTE1SgPcLy37W4DmSNflIFiyi8tSE,111792
|
|
21
|
-
uiprotect/data/nvr.py,sha256=JZja0QiT91Eu8-lw_M0Ora1KGNXhbG5dVNLN8YdeSw0,47677
|
|
22
|
-
uiprotect/data/types.py,sha256=MTi9dVzKTp_8XtAmWKtbZujwE5plKGHdjglFGcJ4Yxs,15789
|
|
23
|
-
uiprotect/data/user.py,sha256=HZJh9IOXS23kM-szTn7dGGsRZz9w2_9DqltL90gcMoE,7095
|
|
24
|
-
uiprotect/data/websocket.py,sha256=3iU8hcH5GsVrGLoDjhXcv7zOKmXrMuQUqUud_ZsF6vw,6084
|
|
25
|
-
uiprotect/exceptions.py,sha256=kgn0cRM6lTtgLza09SDa3ZiX6ue1QqHCOogQ4qu6KTQ,965
|
|
26
|
-
uiprotect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
-
uiprotect/release_cache.json,sha256=NamnSFy78hOWY0DPO87J9ELFCAN6NnVquv8gQO75ZG4,386
|
|
28
|
-
uiprotect/stream.py,sha256=V4aJfVWpSUsWE1PQrXH8F7obQQi1ukPAZ7PzwABjt0I,4942
|
|
29
|
-
uiprotect/test_util/__init__.py,sha256=sSEXu6_pwdYNQSCYtftpX1Dy1S8XYOvhrpECYRxeKJE,18596
|
|
30
|
-
uiprotect/test_util/anonymize.py,sha256=AGYELhDC4BrdK0deI6zh5jFp3SuM_HvAWLeoxFHSiwg,8486
|
|
31
|
-
uiprotect/utils.py,sha256=xP8t0wEBIGS___LUYRNnQuXvUbjKDbsOnnSwWDzphSw,18124
|
|
32
|
-
uiprotect/websocket.py,sha256=iMTdchymaCgVHsmY1bRbxkcymqt6WQircIHYNxCu178,7289
|
|
33
|
-
uiprotect-0.4.1.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
|
|
34
|
-
uiprotect-0.4.1.dist-info/METADATA,sha256=EOocaNozRAuUHiD47vXbmqj_HzZfd5jK8zB6GhmP-Ew,10984
|
|
35
|
-
uiprotect-0.4.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
36
|
-
uiprotect-0.4.1.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
|
|
37
|
-
uiprotect-0.4.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|