uiprotect 1.19.3__py3-none-any.whl → 1.20.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 CHANGED
@@ -4,10 +4,26 @@ from __future__ import annotations
4
4
 
5
5
  from .api import ProtectApiClient
6
6
  from .exceptions import Invalid, NotAuthorized, NvrError
7
+ from .utils import (
8
+ get_nested_attr,
9
+ get_nested_attr_as_bool,
10
+ get_top_level_attr,
11
+ get_top_level_attr_as_bool,
12
+ make_enabled_getter,
13
+ make_required_getter,
14
+ make_value_getter,
15
+ )
7
16
 
8
17
  __all__ = [
9
18
  "Invalid",
10
19
  "NotAuthorized",
11
20
  "NvrError",
12
21
  "ProtectApiClient",
22
+ "get_nested_attr",
23
+ "get_nested_attr_as_bool",
24
+ "get_top_level_attr",
25
+ "get_top_level_attr_as_bool",
26
+ "make_value_getter",
27
+ "make_enabled_getter",
28
+ "make_required_getter",
13
29
  ]
uiprotect/utils.py CHANGED
@@ -17,11 +17,12 @@ from copy import deepcopy
17
17
  from datetime import datetime, timedelta, timezone, tzinfo
18
18
  from decimal import Decimal
19
19
  from enum import Enum
20
- from functools import cache, lru_cache
20
+ from functools import cache, lru_cache, partial
21
21
  from hashlib import sha224
22
22
  from http.cookies import Morsel
23
23
  from inspect import isclass
24
24
  from ipaddress import IPv4Address, IPv6Address, ip_address
25
+ from operator import attrgetter
25
26
  from pathlib import Path
26
27
  from typing import TYPE_CHECKING, Any, TypeVar, Union, overload
27
28
  from uuid import UUID
@@ -619,3 +620,57 @@ def clamp_value(value: float, step_size: float) -> float:
619
620
  def normalize_mac(mac: str) -> str:
620
621
  """Normalize MAC address."""
621
622
  return mac.lower().replace(":", "").replace("-", "").replace("_", "")
623
+
624
+
625
+ _SENTINEL = object()
626
+
627
+
628
+ def get_nested_attr(attrs: tuple[str, ...], obj: Any) -> Any:
629
+ """Fetch a nested attribute."""
630
+ value = obj
631
+ for key in attrs:
632
+ if (value := getattr(value, key, _SENTINEL)) is _SENTINEL:
633
+ return None
634
+ return value.value if isinstance(value, Enum) else value
635
+
636
+
637
+ def get_nested_attr_as_bool(attrs: tuple[str, ...], obj: Any) -> bool:
638
+ """Fetch a nested attribute as a bool."""
639
+ value = obj
640
+ for key in attrs:
641
+ if (value := getattr(value, key, _SENTINEL)) is _SENTINEL:
642
+ return False
643
+ return bool(value.value if isinstance(value, Enum) else value)
644
+
645
+
646
+ def get_top_level_attr(attr: str, obj: Any) -> Any:
647
+ """Fetch a top level attribute."""
648
+ value = getattr(obj, attr)
649
+ return value.value if isinstance(value, Enum) else value
650
+
651
+
652
+ def get_top_level_attr_as_bool(attr: str, obj: Any) -> Any:
653
+ """Fetch a top level attribute as a bool."""
654
+ value = getattr(obj, attr)
655
+ return bool(value.value if isinstance(value, Enum) else value)
656
+
657
+
658
+ def make_value_getter(ufp_value: str) -> Callable[[T], Any]:
659
+ """Return a function to get a value from a Protect device."""
660
+ if "." not in ufp_value:
661
+ return partial(get_top_level_attr, ufp_value)
662
+ return partial(get_nested_attr, tuple(ufp_value.split(".")))
663
+
664
+
665
+ def make_enabled_getter(ufp_enabled: str) -> Callable[[T], bool]:
666
+ """Return a function to get a value from a Protect device."""
667
+ if "." not in ufp_enabled:
668
+ return attrgetter(ufp_enabled)
669
+ return partial(get_nested_attr, tuple(ufp_enabled.split(".")))
670
+
671
+
672
+ def make_required_getter(ufp_required_field: str) -> Callable[[T], bool]:
673
+ """Return a function to get a value from a Protect device."""
674
+ if "." not in ufp_required_field:
675
+ return partial(get_top_level_attr_as_bool, ufp_required_field)
676
+ return partial(get_nested_attr_as_bool, tuple(ufp_required_field.split(".")))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uiprotect
3
- Version: 1.19.3
3
+ Version: 1.20.0
4
4
  Summary: Python API for Unifi Protect (Unofficial)
5
5
  Home-page: https://github.com/uilibs/uiprotect
6
6
  License: MIT
@@ -1,4 +1,4 @@
1
- uiprotect/__init__.py,sha256=llnQNtiBfwQG8IkQXovvFz4LZeFjrJx7XdmmUhu3a9E,289
1
+ uiprotect/__init__.py,sha256=UdpRSSLSy7pdDfTKf0zRIfy6KRGt_Jv-fMzYWgibbG4,686
2
2
  uiprotect/__main__.py,sha256=C_bHCOkv5qj6WMy-6ELoY3Y6HDhLxOa1a30CzmbZhsg,462
3
3
  uiprotect/api.py,sha256=SvAni2arXGtP8HzvTljKNLclSfzpRL03RaEF8o1o6K4,65561
4
4
  uiprotect/cli/__init__.py,sha256=sSLW9keVQOkgFcMW18HTDjRrt9sJ0KWjn9DJDA6f9Pc,8658
@@ -28,10 +28,10 @@ uiprotect/release_cache.json,sha256=NamnSFy78hOWY0DPO87J9ELFCAN6NnVquv8gQO75ZG4,
28
28
  uiprotect/stream.py,sha256=McV3XymKyjn-1uV5jdQHcpaDjqLS4zWyMASQ8ubcyb4,4924
29
29
  uiprotect/test_util/__init__.py,sha256=d2g7afa0LSdixQ0kjEDYwafDFME_UlW2LzxpamZ2BC0,18556
30
30
  uiprotect/test_util/anonymize.py,sha256=f-8ijU-_y9r-uAbhIPn0f0I6hzJpAkvJzc8UpWihObI,8478
31
- uiprotect/utils.py,sha256=NXMLqQFiTP1rHAyNK179jWgj2O0RpUCWljaLLgg8q4M,18143
31
+ uiprotect/utils.py,sha256=3SJFF8qs1Jz8t3mD8qwc1hFSocolFjdXI_v4yVlC7o4,20088
32
32
  uiprotect/websocket.py,sha256=JHI_2EZeRPqPyQopsBZS0dr3tu0HaTiqeLazfBXhW_8,7339
33
- uiprotect-1.19.3.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
34
- uiprotect-1.19.3.dist-info/METADATA,sha256=wwNTlD0-tf7_gRV0ORwawfuyUw5olAq8q6aadEwvXa4,10983
35
- uiprotect-1.19.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
- uiprotect-1.19.3.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
37
- uiprotect-1.19.3.dist-info/RECORD,,
33
+ uiprotect-1.20.0.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
34
+ uiprotect-1.20.0.dist-info/METADATA,sha256=2tR-i6s0-c1E1PzpEfVbFq9V9jA2RjilNdhywYM9NW0,10983
35
+ uiprotect-1.20.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
+ uiprotect-1.20.0.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
37
+ uiprotect-1.20.0.dist-info/RECORD,,