uiprotect 1.3.0__py3-none-any.whl → 1.4.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/api.py +2 -2
- uiprotect/data/base.py +4 -4
- uiprotect/data/bootstrap.py +41 -39
- uiprotect/data/convert.py +4 -0
- uiprotect/data/types.py +44 -13
- uiprotect/data/user.py +1 -1
- {uiprotect-1.3.0.dist-info → uiprotect-1.4.1.dist-info}/METADATA +1 -1
- {uiprotect-1.3.0.dist-info → uiprotect-1.4.1.dist-info}/RECORD +11 -11
- {uiprotect-1.3.0.dist-info → uiprotect-1.4.1.dist-info}/LICENSE +0 -0
- {uiprotect-1.3.0.dist-info → uiprotect-1.4.1.dist-info}/WHEEL +0 -0
- {uiprotect-1.3.0.dist-info → uiprotect-1.4.1.dist-info}/entry_points.txt +0 -0
uiprotect/api.py
CHANGED
|
@@ -1146,7 +1146,7 @@ class ProtectApiClient(BaseApiClient):
|
|
|
1146
1146
|
|
|
1147
1147
|
async def get_devices_raw(self, model_type: ModelType) -> list[dict[str, Any]]:
|
|
1148
1148
|
"""Gets a raw device list given a model_type"""
|
|
1149
|
-
return await self.api_request_list(
|
|
1149
|
+
return await self.api_request_list(model_type.devices_key)
|
|
1150
1150
|
|
|
1151
1151
|
async def get_devices(
|
|
1152
1152
|
self,
|
|
@@ -1703,7 +1703,7 @@ class ProtectApiClient(BaseApiClient):
|
|
|
1703
1703
|
|
|
1704
1704
|
async def adopt_device(self, model_type: ModelType, device_id: str) -> None:
|
|
1705
1705
|
"""Adopts a device"""
|
|
1706
|
-
key =
|
|
1706
|
+
key = model_type.devices_key
|
|
1707
1707
|
data = await self.api_request_obj(
|
|
1708
1708
|
"devices/adopt",
|
|
1709
1709
|
method="post",
|
uiprotect/data/base.py
CHANGED
|
@@ -84,7 +84,7 @@ class ProtectBaseObject(BaseModel):
|
|
|
84
84
|
* Provides `.unifi_dict` to convert object back into UFP JSON
|
|
85
85
|
"""
|
|
86
86
|
|
|
87
|
-
_api: ProtectApiClient = PrivateAttr(
|
|
87
|
+
_api: ProtectApiClient = PrivateAttr(None)
|
|
88
88
|
|
|
89
89
|
_protect_objs: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
|
|
90
90
|
_protect_lists: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
|
|
@@ -633,9 +633,9 @@ class ProtectModel(ProtectBaseObject):
|
|
|
633
633
|
class ProtectModelWithId(ProtectModel):
|
|
634
634
|
id: str
|
|
635
635
|
|
|
636
|
-
_update_lock: asyncio.Lock = PrivateAttr(
|
|
637
|
-
_update_queue: asyncio.Queue[Callable[[], None]] = PrivateAttr(
|
|
638
|
-
_update_event: asyncio.Event = PrivateAttr(
|
|
636
|
+
_update_lock: asyncio.Lock = PrivateAttr(None)
|
|
637
|
+
_update_queue: asyncio.Queue[Callable[[], None]] = PrivateAttr(None)
|
|
638
|
+
_update_event: asyncio.Event = PrivateAttr(None)
|
|
639
639
|
|
|
640
640
|
def __init__(self, **data: Any) -> None:
|
|
641
641
|
update_lock = data.pop("update_lock", None)
|
uiprotect/data/bootstrap.py
CHANGED
|
@@ -197,8 +197,8 @@ class Bootstrap(ProtectBaseObject):
|
|
|
197
197
|
)
|
|
198
198
|
data["macLookup"] = {}
|
|
199
199
|
data["idLookup"] = {}
|
|
200
|
-
for model_type in ModelType.
|
|
201
|
-
key =
|
|
200
|
+
for model_type in ModelType.bootstrap_models_types_set():
|
|
201
|
+
key = model_type.devices_key
|
|
202
202
|
items: dict[str, ProtectModel] = {}
|
|
203
203
|
for item in data[key]:
|
|
204
204
|
if (
|
|
@@ -234,8 +234,8 @@ class Bootstrap(ProtectBaseObject):
|
|
|
234
234
|
if "idLookup" in data:
|
|
235
235
|
del data["idLookup"]
|
|
236
236
|
|
|
237
|
-
for model_type in ModelType.
|
|
238
|
-
attr =
|
|
237
|
+
for model_type in ModelType.bootstrap_models_types_set():
|
|
238
|
+
attr = model_type.devices_key
|
|
239
239
|
if attr in data and isinstance(data[attr], dict):
|
|
240
240
|
data[attr] = list(data[attr].values())
|
|
241
241
|
|
|
@@ -302,7 +302,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
302
302
|
if ref is None:
|
|
303
303
|
return None
|
|
304
304
|
|
|
305
|
-
devices: dict[str, ProtectModelWithId] = getattr(self,
|
|
305
|
+
devices: dict[str, ProtectModelWithId] = getattr(self, ref.model.devices_key)
|
|
306
306
|
return cast(ProtectAdoptableDeviceModel, devices.get(ref.id))
|
|
307
307
|
|
|
308
308
|
def get_device_from_id(self, device_id: str) -> ProtectAdoptableDeviceModel | None:
|
|
@@ -310,7 +310,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
310
310
|
ref = self.id_lookup.get(device_id)
|
|
311
311
|
if ref is None:
|
|
312
312
|
return None
|
|
313
|
-
devices: dict[str, ProtectModelWithId] = getattr(self,
|
|
313
|
+
devices: dict[str, ProtectModelWithId] = getattr(self, ref.model.devices_key)
|
|
314
314
|
return cast(ProtectAdoptableDeviceModel, devices.get(ref.id))
|
|
315
315
|
|
|
316
316
|
def process_event(self, event: Event) -> None:
|
|
@@ -344,21 +344,24 @@ class Bootstrap(ProtectBaseObject):
|
|
|
344
344
|
|
|
345
345
|
def _process_add_packet(
|
|
346
346
|
self,
|
|
347
|
+
model_type: ModelType,
|
|
347
348
|
packet: WSPacket,
|
|
348
349
|
data: dict[str, Any],
|
|
349
350
|
) -> WSSubscriptionMessage | None:
|
|
350
|
-
obj = create_from_unifi_dict(data, api=self._api)
|
|
351
|
-
|
|
352
|
-
|
|
351
|
+
obj = create_from_unifi_dict(data, api=self._api, model_type=model_type)
|
|
352
|
+
if model_type is ModelType.EVENT:
|
|
353
|
+
if TYPE_CHECKING:
|
|
354
|
+
assert isinstance(obj, Event)
|
|
353
355
|
self.process_event(obj)
|
|
354
|
-
|
|
356
|
+
if model_type is ModelType.NVR:
|
|
357
|
+
if TYPE_CHECKING:
|
|
358
|
+
assert isinstance(obj, NVR)
|
|
355
359
|
self.nvr = obj
|
|
356
|
-
elif (
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
key = f"{obj.model.value}s"
|
|
360
|
+
elif model_type in ModelType.bootstrap_models_types_set():
|
|
361
|
+
if TYPE_CHECKING:
|
|
362
|
+
assert isinstance(obj, ProtectAdoptableDeviceModel)
|
|
363
|
+
assert isinstance(obj.model, ModelType)
|
|
364
|
+
key = obj.model.devices_key
|
|
362
365
|
if not self._api.ignore_unadopted or (
|
|
363
366
|
obj.is_adopted and not obj.is_adopted_by_other
|
|
364
367
|
):
|
|
@@ -381,9 +384,12 @@ class Bootstrap(ProtectBaseObject):
|
|
|
381
384
|
new_obj=obj,
|
|
382
385
|
)
|
|
383
386
|
|
|
384
|
-
def _process_remove_packet(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
+
def _process_remove_packet(
|
|
388
|
+
self, model_type: ModelType, packet: WSPacket
|
|
389
|
+
) -> WSSubscriptionMessage | None:
|
|
390
|
+
devices: dict[str, ProtectDeviceModel] | None = getattr(
|
|
391
|
+
self, model_type.devices_key, None
|
|
392
|
+
)
|
|
387
393
|
|
|
388
394
|
if devices is None:
|
|
389
395
|
return None
|
|
@@ -443,12 +449,12 @@ class Bootstrap(ProtectBaseObject):
|
|
|
443
449
|
|
|
444
450
|
def _process_device_update(
|
|
445
451
|
self,
|
|
452
|
+
model_type: ModelType,
|
|
446
453
|
packet: WSPacket,
|
|
447
454
|
action: dict[str, Any],
|
|
448
455
|
data: dict[str, Any],
|
|
449
456
|
ignore_stats: bool,
|
|
450
457
|
) -> WSSubscriptionMessage | None:
|
|
451
|
-
model_type = action["modelKey"]
|
|
452
458
|
remove_keys = (
|
|
453
459
|
STATS_AND_IGNORE_DEVICE_KEYS if ignore_stats else IGNORE_DEVICE_KEYS
|
|
454
460
|
)
|
|
@@ -456,33 +462,31 @@ class Bootstrap(ProtectBaseObject):
|
|
|
456
462
|
del data[key]
|
|
457
463
|
# `last_motion` from cameras update every 100 milliseconds when a motion event is active
|
|
458
464
|
# this overrides the behavior to only update `last_motion` when a new event starts
|
|
459
|
-
if model_type
|
|
465
|
+
if model_type is ModelType.CAMERA and "lastMotion" in data:
|
|
460
466
|
del data["lastMotion"]
|
|
461
467
|
# nothing left to process
|
|
462
468
|
if not data:
|
|
463
469
|
self._create_stat(packet, None, True)
|
|
464
470
|
return None
|
|
465
471
|
|
|
466
|
-
|
|
467
|
-
devices: dict[str, ProtectModelWithId] = getattr(self, key)
|
|
472
|
+
devices: dict[str, ProtectModelWithId] = getattr(self, model_type.devices_key)
|
|
468
473
|
action_id: str = action["id"]
|
|
469
474
|
if action_id not in devices:
|
|
470
475
|
# ignore updates to events that phase out
|
|
471
|
-
if model_type
|
|
476
|
+
if model_type is not ModelType.EVENT:
|
|
472
477
|
_LOGGER.debug("Unexpected %s: %s", key, action_id)
|
|
473
478
|
return None
|
|
474
479
|
|
|
475
480
|
obj = devices[action_id]
|
|
476
|
-
model = obj.model
|
|
477
481
|
data = obj.unifi_dict_to_dict(data)
|
|
478
482
|
old_obj = obj.copy()
|
|
479
483
|
obj = obj.update_from_dict(deepcopy(data))
|
|
480
484
|
|
|
481
|
-
if
|
|
485
|
+
if model_type is ModelType.EVENT:
|
|
482
486
|
if TYPE_CHECKING:
|
|
483
487
|
assert isinstance(obj, Event)
|
|
484
488
|
self.process_event(obj)
|
|
485
|
-
elif
|
|
489
|
+
elif model_type is ModelType.CAMERA:
|
|
486
490
|
if TYPE_CHECKING:
|
|
487
491
|
assert isinstance(obj, Camera)
|
|
488
492
|
if "last_ring" in data and obj.last_ring:
|
|
@@ -490,7 +494,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
490
494
|
_LOGGER.debug("last_ring for %s (%s)", obj.id, is_recent)
|
|
491
495
|
if is_recent:
|
|
492
496
|
obj.set_ring_timeout()
|
|
493
|
-
elif
|
|
497
|
+
elif model_type is ModelType.SENSOR:
|
|
494
498
|
if TYPE_CHECKING:
|
|
495
499
|
assert isinstance(obj, Sensor)
|
|
496
500
|
if "alarm_triggered_at" in data and obj.alarm_triggered_at:
|
|
@@ -532,13 +536,14 @@ class Bootstrap(ProtectBaseObject):
|
|
|
532
536
|
self._create_stat(packet, None, True)
|
|
533
537
|
return None
|
|
534
538
|
|
|
535
|
-
|
|
539
|
+
model_type = ModelType.from_string(model_key)
|
|
540
|
+
if models and model_type not in models:
|
|
536
541
|
self._create_stat(packet, None, True)
|
|
537
542
|
return None
|
|
538
543
|
|
|
539
544
|
action_action: str = action["action"]
|
|
540
545
|
if action_action == "remove":
|
|
541
|
-
return self._process_remove_packet(packet)
|
|
546
|
+
return self._process_remove_packet(model_type, packet)
|
|
542
547
|
|
|
543
548
|
if not data:
|
|
544
549
|
self._create_stat(packet, None, True)
|
|
@@ -546,16 +551,13 @@ class Bootstrap(ProtectBaseObject):
|
|
|
546
551
|
|
|
547
552
|
try:
|
|
548
553
|
if action_action == "add":
|
|
549
|
-
return self._process_add_packet(packet, data)
|
|
554
|
+
return self._process_add_packet(model_type, packet, data)
|
|
550
555
|
if action_action == "update":
|
|
551
|
-
if
|
|
556
|
+
if model_type is ModelType.NVR:
|
|
552
557
|
return self._process_nvr_update(packet, data, ignore_stats)
|
|
553
|
-
|
|
554
|
-
if (
|
|
555
|
-
model_key in ModelType.bootstrap_models_set()
|
|
556
|
-
or model_key == _ModelType_Event_value
|
|
557
|
-
):
|
|
558
|
+
if model_type in ModelType.bootstrap_models_types_and_event_set():
|
|
558
559
|
return self._process_device_update(
|
|
560
|
+
model_type,
|
|
559
561
|
packet,
|
|
560
562
|
action,
|
|
561
563
|
data,
|
|
@@ -576,7 +578,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
576
578
|
msg = f"Validation error processing event: {action['id']}. Ignoring event."
|
|
577
579
|
else:
|
|
578
580
|
try:
|
|
579
|
-
model_type = ModelType(action["modelKey"])
|
|
581
|
+
model_type = ModelType.from_string(action["modelKey"])
|
|
580
582
|
device_id: str = action["id"]
|
|
581
583
|
task = asyncio.create_task(self.refresh_device(model_type, device_id))
|
|
582
584
|
self._refresh_tasks.add(task)
|
|
@@ -609,7 +611,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
609
611
|
self.nvr = device
|
|
610
612
|
else:
|
|
611
613
|
devices: dict[str, ProtectModelWithId] = getattr(
|
|
612
|
-
self,
|
|
614
|
+
self, model_type.devices_key
|
|
613
615
|
)
|
|
614
616
|
devices[device.id] = device
|
|
615
617
|
_LOGGER.debug("Successfully refresh model: %s %s", model_type, device_id)
|
uiprotect/data/convert.py
CHANGED
|
@@ -63,6 +63,7 @@ def create_from_unifi_dict(
|
|
|
63
63
|
data: dict[str, Any],
|
|
64
64
|
api: ProtectApiClient | None = None,
|
|
65
65
|
klass: type[ProtectModel] | None = None,
|
|
66
|
+
model_type: ModelType | None = None,
|
|
66
67
|
) -> ProtectModel:
|
|
67
68
|
"""
|
|
68
69
|
Helper method to read the `modelKey` from a UFP JSON dict and convert to currect Python class.
|
|
@@ -71,6 +72,9 @@ def create_from_unifi_dict(
|
|
|
71
72
|
if "modelKey" not in data:
|
|
72
73
|
raise DataDecodeError("No modelKey")
|
|
73
74
|
|
|
75
|
+
if model_type is not None and klass is None:
|
|
76
|
+
klass = MODEL_TO_CLASS.get(model_type)
|
|
77
|
+
|
|
74
78
|
if klass is None:
|
|
75
79
|
klass = get_klass_from_dict(data)
|
|
76
80
|
|
uiprotect/data/types.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import enum
|
|
4
4
|
from collections.abc import Callable, Coroutine
|
|
5
|
-
from functools import cache
|
|
5
|
+
from functools import cache, cached_property
|
|
6
6
|
from typing import Any, Literal, Optional, TypeVar, Union
|
|
7
7
|
|
|
8
8
|
from packaging.version import Version as BaseVersion
|
|
@@ -109,31 +109,62 @@ class ModelType(str, UnknownValuesEnumMixin, enum.Enum):
|
|
|
109
109
|
RECORDING_SCHEDULE = "recordingSchedule"
|
|
110
110
|
UNKNOWN = "unknown"
|
|
111
111
|
|
|
112
|
+
@cached_property
|
|
113
|
+
def devices_key(self) -> str:
|
|
114
|
+
"""Return the devices key."""
|
|
115
|
+
return f"{self.value}s"
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
@cache
|
|
119
|
+
def from_string(cls, value: str) -> ModelType:
|
|
120
|
+
return cls(value)
|
|
121
|
+
|
|
112
122
|
@staticmethod
|
|
113
123
|
@cache
|
|
114
|
-
def
|
|
124
|
+
def bootstrap_model_types() -> tuple[ModelType, ...]:
|
|
125
|
+
"""Return the bootstrap models as a tuple."""
|
|
115
126
|
# TODO:
|
|
116
127
|
# legacyUFV
|
|
117
128
|
# display
|
|
118
|
-
|
|
119
129
|
return (
|
|
120
|
-
ModelType.CAMERA
|
|
121
|
-
ModelType.USER
|
|
122
|
-
ModelType.GROUP
|
|
123
|
-
ModelType.LIVEVIEW
|
|
124
|
-
ModelType.VIEWPORT
|
|
125
|
-
ModelType.LIGHT
|
|
126
|
-
ModelType.BRIDGE
|
|
127
|
-
ModelType.SENSOR
|
|
128
|
-
ModelType.DOORLOCK
|
|
129
|
-
ModelType.CHIME
|
|
130
|
+
ModelType.CAMERA,
|
|
131
|
+
ModelType.USER,
|
|
132
|
+
ModelType.GROUP,
|
|
133
|
+
ModelType.LIVEVIEW,
|
|
134
|
+
ModelType.VIEWPORT,
|
|
135
|
+
ModelType.LIGHT,
|
|
136
|
+
ModelType.BRIDGE,
|
|
137
|
+
ModelType.SENSOR,
|
|
138
|
+
ModelType.DOORLOCK,
|
|
139
|
+
ModelType.CHIME,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
@staticmethod
|
|
143
|
+
@cache
|
|
144
|
+
def bootstrap_models() -> tuple[str, ...]:
|
|
145
|
+
"""Return the bootstrap models strings as a tuple."""
|
|
146
|
+
return tuple(
|
|
147
|
+
model_type.value for model_type in ModelType.bootstrap_model_types()
|
|
130
148
|
)
|
|
131
149
|
|
|
132
150
|
@staticmethod
|
|
133
151
|
@cache
|
|
134
152
|
def bootstrap_models_set() -> set[str]:
|
|
153
|
+
"""Return the set of bootstrap models strings as a set."""
|
|
135
154
|
return set(ModelType.bootstrap_models())
|
|
136
155
|
|
|
156
|
+
@staticmethod
|
|
157
|
+
@cache
|
|
158
|
+
def bootstrap_models_types_set() -> set[ModelType]:
|
|
159
|
+
"""Return the set of bootstrap models as a set."""
|
|
160
|
+
return set(ModelType.bootstrap_model_types())
|
|
161
|
+
|
|
162
|
+
@staticmethod
|
|
163
|
+
@cache
|
|
164
|
+
def bootstrap_models_types_and_event_set() -> set[ModelType]:
|
|
165
|
+
"""Return the set of bootstrap models and the event model as a set."""
|
|
166
|
+
return ModelType.bootstrap_models_types_set() | {ModelType.EVENT}
|
|
167
|
+
|
|
137
168
|
|
|
138
169
|
@enum.unique
|
|
139
170
|
class EventType(str, ValuesEnumMixin, enum.Enum):
|
uiprotect/data/user.py
CHANGED
|
@@ -54,7 +54,7 @@ class Permission(ProtectBaseObject):
|
|
|
54
54
|
if self.obj_ids == {"self"} or self.obj_ids is None:
|
|
55
55
|
return None
|
|
56
56
|
|
|
57
|
-
devices = getattr(self._api.bootstrap,
|
|
57
|
+
devices = getattr(self._api.bootstrap, self.model.devices_key)
|
|
58
58
|
return [devices[oid] for oid in self.obj_ids]
|
|
59
59
|
|
|
60
60
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
uiprotect/__init__.py,sha256=llnQNtiBfwQG8IkQXovvFz4LZeFjrJx7XdmmUhu3a9E,289
|
|
2
2
|
uiprotect/__main__.py,sha256=C_bHCOkv5qj6WMy-6ELoY3Y6HDhLxOa1a30CzmbZhsg,462
|
|
3
|
-
uiprotect/api.py,sha256=
|
|
3
|
+
uiprotect/api.py,sha256=t3E1wMja0av6ENtvXJHGv70WC6NCCWbF_wFIJxOLS0I,66463
|
|
4
4
|
uiprotect/cli/__init__.py,sha256=sSLW9keVQOkgFcMW18HTDjRrt9sJ0KWjn9DJDA6f9Pc,8658
|
|
5
5
|
uiprotect/cli/backup.py,sha256=ZiS7RZnJGKI8TJKLW2cOUzkRM8nyTvE5Ov_jZZGtvSM,36708
|
|
6
6
|
uiprotect/cli/base.py,sha256=zpTm2kyJe_GLixnv3Uadke__iRLh64AEwQzp-2hqS7g,7730
|
|
@@ -14,13 +14,13 @@ 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=
|
|
19
|
-
uiprotect/data/convert.py,sha256=
|
|
17
|
+
uiprotect/data/base.py,sha256=CidfMMC7GdNCPUK6Mcy2BHYtNF2C_wY3WtdLUip8DCM,38379
|
|
18
|
+
uiprotect/data/bootstrap.py,sha256=INRUEbLWnsEJuzlcoFlm7RAT-WPx6odje3aD092QKGo,21465
|
|
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=jwJEl4o2kbvoYFB9wSJPghNj0905847-86ElT51nNs0,47580
|
|
22
|
-
uiprotect/data/types.py,sha256=
|
|
23
|
-
uiprotect/data/user.py,sha256=
|
|
22
|
+
uiprotect/data/types.py,sha256=1dj9jCk7btAa2hkiEo1Y5NoAFsQtOroCWT6KQKqG5eo,17213
|
|
23
|
+
uiprotect/data/user.py,sha256=Wb-ZWSwIJbyUbfVuENtUYbuW-uftHNDcoMH85dvEjkw,7071
|
|
24
24
|
uiprotect/data/websocket.py,sha256=WZJVA7EfYuKYMv-9jmvGgMWXKzE9ES25SKv1NQ2eHjc,6281
|
|
25
25
|
uiprotect/exceptions.py,sha256=kgn0cRM6lTtgLza09SDa3ZiX6ue1QqHCOogQ4qu6KTQ,965
|
|
26
26
|
uiprotect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -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.
|
|
34
|
-
uiprotect-1.
|
|
35
|
-
uiprotect-1.
|
|
36
|
-
uiprotect-1.
|
|
37
|
-
uiprotect-1.
|
|
33
|
+
uiprotect-1.4.1.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
|
|
34
|
+
uiprotect-1.4.1.dist-info/METADATA,sha256=6QEx8JjpfP1wIFmUgR9fegd9jOd8tA0pFZzoLFQ_2io,10984
|
|
35
|
+
uiprotect-1.4.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
36
|
+
uiprotect-1.4.1.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
|
|
37
|
+
uiprotect-1.4.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|