pyezvizapi 1.0.3.5__py3-none-any.whl → 1.0.3.7__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 pyezvizapi might be problematic. Click here for more details.
- pyezvizapi/__init__.py +6 -0
- pyezvizapi/__main__.py +2 -2
- pyezvizapi/client.py +40 -0
- pyezvizapi/constants.py +1 -0
- pyezvizapi/feature.py +47 -9
- pyezvizapi/mqtt.py +1 -1
- pyezvizapi/test_mqtt.py +1 -1
- pyezvizapi/utils.py +52 -11
- {pyezvizapi-1.0.3.5.dist-info → pyezvizapi-1.0.3.7.dist-info}/METADATA +1 -1
- pyezvizapi-1.0.3.7.dist-info/RECORD +22 -0
- pyezvizapi-1.0.3.5.dist-info/RECORD +0 -22
- {pyezvizapi-1.0.3.5.dist-info → pyezvizapi-1.0.3.7.dist-info}/WHEEL +0 -0
- {pyezvizapi-1.0.3.5.dist-info → pyezvizapi-1.0.3.7.dist-info}/entry_points.txt +0 -0
- {pyezvizapi-1.0.3.5.dist-info → pyezvizapi-1.0.3.7.dist-info}/licenses/LICENSE +0 -0
- {pyezvizapi-1.0.3.5.dist-info → pyezvizapi-1.0.3.7.dist-info}/licenses/LICENSE.md +0 -0
- {pyezvizapi-1.0.3.5.dist-info → pyezvizapi-1.0.3.7.dist-info}/top_level.txt +0 -0
pyezvizapi/__init__.py
CHANGED
|
@@ -57,6 +57,9 @@ from .feature import (
|
|
|
57
57
|
port_security_has_port,
|
|
58
58
|
port_security_port_enabled,
|
|
59
59
|
resolve_channel,
|
|
60
|
+
supplement_light_available,
|
|
61
|
+
supplement_light_enabled,
|
|
62
|
+
supplement_light_params,
|
|
60
63
|
support_ext_value,
|
|
61
64
|
)
|
|
62
65
|
from .light_bulb import EzvizLightBulb
|
|
@@ -118,5 +121,8 @@ __all__ = [
|
|
|
118
121
|
"port_security_has_port",
|
|
119
122
|
"port_security_port_enabled",
|
|
120
123
|
"resolve_channel",
|
|
124
|
+
"supplement_light_available",
|
|
125
|
+
"supplement_light_enabled",
|
|
126
|
+
"supplement_light_params",
|
|
121
127
|
"support_ext_value",
|
|
122
128
|
]
|
pyezvizapi/__main__.py
CHANGED
|
@@ -421,7 +421,7 @@ def _handle_devices_light(args: argparse.Namespace, client: EzvizClient) -> int:
|
|
|
421
421
|
|
|
422
422
|
def _handle_pagelist(client: EzvizClient) -> int:
|
|
423
423
|
"""Output full pagelist (raw JSON) for exploration in editors like Notepad++."""
|
|
424
|
-
data = client.
|
|
424
|
+
data = client.get_page_list()
|
|
425
425
|
_write_json(data)
|
|
426
426
|
return 0
|
|
427
427
|
|
|
@@ -611,7 +611,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
611
611
|
return 2
|
|
612
612
|
finally:
|
|
613
613
|
if args.save_token and args.token_file:
|
|
614
|
-
_save_token_file(args.token_file,
|
|
614
|
+
_save_token_file(args.token_file, client.export_token())
|
|
615
615
|
client.close_session()
|
|
616
616
|
|
|
617
617
|
|
pyezvizapi/client.py
CHANGED
|
@@ -1615,6 +1615,35 @@ class EzvizClient:
|
|
|
1615
1615
|
error_message="Could not fetch device feature value",
|
|
1616
1616
|
)
|
|
1617
1617
|
|
|
1618
|
+
def set_intelligent_fill_light(
|
|
1619
|
+
self,
|
|
1620
|
+
serial: str,
|
|
1621
|
+
*,
|
|
1622
|
+
enabled: bool,
|
|
1623
|
+
local_index: str = "1",
|
|
1624
|
+
max_retries: int = 0,
|
|
1625
|
+
) -> dict:
|
|
1626
|
+
"""Toggle the intelligent fill light mode via the IoT feature API."""
|
|
1627
|
+
|
|
1628
|
+
payload = {
|
|
1629
|
+
"value": {
|
|
1630
|
+
"enabled": bool(enabled),
|
|
1631
|
+
"supplementLightSwitchMode": "eventIntelligence"
|
|
1632
|
+
if enabled
|
|
1633
|
+
else "irLight",
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
body = self._normalize_json_payload(payload)
|
|
1637
|
+
return self.set_iot_feature(
|
|
1638
|
+
serial,
|
|
1639
|
+
resource_identifier="Video",
|
|
1640
|
+
local_index=local_index,
|
|
1641
|
+
domain_id="SupplementLightMgr",
|
|
1642
|
+
action_id="ImageSupplementLightModeSwitchParams",
|
|
1643
|
+
value=body,
|
|
1644
|
+
max_retries=max_retries,
|
|
1645
|
+
)
|
|
1646
|
+
|
|
1618
1647
|
def set_image_flip_iot(
|
|
1619
1648
|
self,
|
|
1620
1649
|
serial: str,
|
|
@@ -2074,6 +2103,7 @@ class EzvizClient:
|
|
|
2074
2103
|
# Create camera object
|
|
2075
2104
|
cam = EzvizCamera(self, device, dict(rec.raw))
|
|
2076
2105
|
self._cameras[device] = cam.status(refresh=refresh)
|
|
2106
|
+
|
|
2077
2107
|
except (
|
|
2078
2108
|
PyEzvizError,
|
|
2079
2109
|
KeyError,
|
|
@@ -4368,6 +4398,16 @@ class EzvizClient:
|
|
|
4368
4398
|
json_key=None,
|
|
4369
4399
|
)
|
|
4370
4400
|
|
|
4401
|
+
def get_page_list(self) -> Any:
|
|
4402
|
+
"""Return the full pagelist payload without filtering."""
|
|
4403
|
+
|
|
4404
|
+
return self._get_page_list()
|
|
4405
|
+
|
|
4406
|
+
def export_token(self) -> dict[str, Any]:
|
|
4407
|
+
"""Return a shallow copy of the current authentication token."""
|
|
4408
|
+
|
|
4409
|
+
return dict(self._token)
|
|
4410
|
+
|
|
4371
4411
|
def get_device(self) -> Any:
|
|
4372
4412
|
"""Get ezviz devices filter."""
|
|
4373
4413
|
return self._api_get_pagelist(page_filter="CLOUD", json_key="deviceInfos")
|
pyezvizapi/constants.py
CHANGED
pyezvizapi/feature.py
CHANGED
|
@@ -5,23 +5,61 @@ from __future__ import annotations
|
|
|
5
5
|
from collections.abc import Iterable, Iterator, Mapping, MutableMapping
|
|
6
6
|
from typing import Any, cast
|
|
7
7
|
|
|
8
|
-
from .utils import coerce_int, decode_json
|
|
8
|
+
from .utils import WILDCARD_STEP, coerce_int, decode_json, first_nested
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def _feature_video_section(camera_data: Mapping[str, Any]) -> dict[str, Any]:
|
|
12
12
|
"""Return the nested Video feature section from feature info payload."""
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
video = first_nested(
|
|
15
|
+
camera_data,
|
|
16
|
+
("FEATURE_INFO", WILDCARD_STEP, "Video"),
|
|
17
|
+
)
|
|
18
|
+
if isinstance(video, MutableMapping):
|
|
19
|
+
return cast(dict[str, Any], video)
|
|
20
|
+
return {}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def supplement_light_params(camera_data: Mapping[str, Any]) -> dict[str, Any]:
|
|
24
|
+
"""Return SupplementLightMgr parameters if present."""
|
|
25
|
+
|
|
26
|
+
video = _feature_video_section(camera_data)
|
|
27
|
+
if not video:
|
|
16
28
|
return {}
|
|
17
29
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return cast(dict[str, Any], video)
|
|
30
|
+
manager: Any = video.get("SupplementLightMgr")
|
|
31
|
+
manager = decode_json(manager)
|
|
32
|
+
if not isinstance(manager, Mapping):
|
|
33
|
+
return {}
|
|
23
34
|
|
|
24
|
-
|
|
35
|
+
params: Any = manager.get("ImageSupplementLightModeSwitchParams")
|
|
36
|
+
params = decode_json(params)
|
|
37
|
+
return dict(params) if isinstance(params, Mapping) else {}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def supplement_light_enabled(camera_data: Mapping[str, Any]) -> bool:
|
|
41
|
+
"""Return True when intelligent fill light is enabled."""
|
|
42
|
+
|
|
43
|
+
params = supplement_light_params(camera_data)
|
|
44
|
+
if not params:
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
enabled = params.get("enabled")
|
|
48
|
+
if isinstance(enabled, bool):
|
|
49
|
+
return enabled
|
|
50
|
+
if isinstance(enabled, str):
|
|
51
|
+
lowered = enabled.strip().lower()
|
|
52
|
+
if lowered in {"true", "1", "yes", "on"}:
|
|
53
|
+
return True
|
|
54
|
+
if lowered in {"false", "0", "no", "off"}:
|
|
55
|
+
return False
|
|
56
|
+
return bool(enabled)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def supplement_light_available(camera_data: Mapping[str, Any]) -> bool:
|
|
60
|
+
"""Return True when intelligent fill light parameters are present."""
|
|
61
|
+
|
|
62
|
+
return bool(supplement_light_params(camera_data))
|
|
25
63
|
|
|
26
64
|
|
|
27
65
|
def lens_defog_config(camera_data: Mapping[str, Any]) -> dict[str, Any]:
|
pyezvizapi/mqtt.py
CHANGED
|
@@ -247,7 +247,7 @@ class MQTTClient:
|
|
|
247
247
|
# Stop background thread and disconnect
|
|
248
248
|
self.mqtt_client.loop_stop()
|
|
249
249
|
self.mqtt_client.disconnect()
|
|
250
|
-
except
|
|
250
|
+
except (OSError, ValueError, RuntimeError) as err:
|
|
251
251
|
_LOGGER.debug("MQTT disconnect failed: %s", err)
|
|
252
252
|
# Always attempt to stop push on server side
|
|
253
253
|
self._stop_ezviz_push()
|
pyezvizapi/test_mqtt.py
CHANGED
|
@@ -125,7 +125,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
125
125
|
print("Stopped.")
|
|
126
126
|
|
|
127
127
|
if args.save_token and args.token_file:
|
|
128
|
-
_save_token_file(args.token_file,
|
|
128
|
+
_save_token_file(args.token_file, client.export_token())
|
|
129
129
|
|
|
130
130
|
return 0
|
|
131
131
|
|
pyezvizapi/utils.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from collections.abc import Iterable, Iterator
|
|
5
6
|
import datetime
|
|
6
7
|
from hashlib import md5
|
|
7
8
|
import json
|
|
@@ -13,6 +14,7 @@ from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
|
|
13
14
|
|
|
14
15
|
from Crypto.Cipher import AES
|
|
15
16
|
|
|
17
|
+
from .constants import HIK_ENCRYPTION_HEADER
|
|
16
18
|
from .exceptions import PyEzvizError
|
|
17
19
|
|
|
18
20
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -74,6 +76,49 @@ def string_to_list(data: Any, separator: str = ",") -> Any:
|
|
|
74
76
|
return data
|
|
75
77
|
|
|
76
78
|
|
|
79
|
+
PathComponent = str | int
|
|
80
|
+
WILDCARD_STEP = "*"
|
|
81
|
+
_MISSING = object()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def iter_nested(data: Any, path: Iterable[PathComponent]) -> Iterator[Any]:
|
|
85
|
+
"""Yield values reachable by following a dotted path with optional wildcards."""
|
|
86
|
+
|
|
87
|
+
current: list[Any] = [data]
|
|
88
|
+
|
|
89
|
+
for step in path:
|
|
90
|
+
next_level: list[Any] = []
|
|
91
|
+
for candidate in current:
|
|
92
|
+
if step == WILDCARD_STEP:
|
|
93
|
+
if isinstance(candidate, dict):
|
|
94
|
+
next_level.extend(candidate.values())
|
|
95
|
+
elif isinstance(candidate, (list, tuple)):
|
|
96
|
+
next_level.extend(candidate)
|
|
97
|
+
continue
|
|
98
|
+
|
|
99
|
+
if isinstance(candidate, dict) and step in candidate:
|
|
100
|
+
next_level.append(candidate[step])
|
|
101
|
+
continue
|
|
102
|
+
|
|
103
|
+
if isinstance(candidate, (list, tuple)) and isinstance(step, int):
|
|
104
|
+
if -len(candidate) <= step < len(candidate):
|
|
105
|
+
next_level.append(candidate[step])
|
|
106
|
+
|
|
107
|
+
current = next_level
|
|
108
|
+
if not current:
|
|
109
|
+
break
|
|
110
|
+
|
|
111
|
+
yield from current
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def first_nested(
|
|
115
|
+
data: Any, path: Iterable[PathComponent], default: Any = None
|
|
116
|
+
) -> Any:
|
|
117
|
+
"""Return the first value produced by iter_nested or ``default``."""
|
|
118
|
+
|
|
119
|
+
return next(iter_nested(data, path), default)
|
|
120
|
+
|
|
121
|
+
|
|
77
122
|
def fetch_nested_value(data: Any, keys: list, default_value: Any = None) -> Any:
|
|
78
123
|
"""Fetch the value corresponding to the given nested keys in a dictionary.
|
|
79
124
|
|
|
@@ -88,14 +133,8 @@ def fetch_nested_value(data: Any, keys: list, default_value: Any = None) -> Any:
|
|
|
88
133
|
The value corresponding to the nested keys or the default value.
|
|
89
134
|
|
|
90
135
|
"""
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
data = data[key]
|
|
94
|
-
|
|
95
|
-
except (KeyError, TypeError):
|
|
96
|
-
return default_value
|
|
97
|
-
|
|
98
|
-
return data
|
|
136
|
+
value = first_nested(data, keys, _MISSING)
|
|
137
|
+
return default_value if value is _MISSING else value
|
|
99
138
|
|
|
100
139
|
|
|
101
140
|
def decrypt_image(input_data: bytes, password: str) -> bytes:
|
|
@@ -116,8 +155,10 @@ def decrypt_image(input_data: bytes, password: str) -> bytes:
|
|
|
116
155
|
raise PyEzvizError("Invalid image data")
|
|
117
156
|
|
|
118
157
|
# check header
|
|
119
|
-
|
|
120
|
-
|
|
158
|
+
header_len = len(HIK_ENCRYPTION_HEADER)
|
|
159
|
+
|
|
160
|
+
if input_data[:header_len] != HIK_ENCRYPTION_HEADER:
|
|
161
|
+
_LOGGER.debug("Image header doesn't contain %s", HIK_ENCRYPTION_HEADER)
|
|
121
162
|
return input_data
|
|
122
163
|
|
|
123
164
|
file_hash = input_data[16:48]
|
|
@@ -132,7 +173,7 @@ def decrypt_image(input_data: bytes, password: str) -> bytes:
|
|
|
132
173
|
next_chunk = b""
|
|
133
174
|
output_data = b""
|
|
134
175
|
finished = False
|
|
135
|
-
i = 48 # offset
|
|
176
|
+
i = 48 # offset HIK header + hash
|
|
136
177
|
chunk_size = 1024 * AES.block_size
|
|
137
178
|
while not finished:
|
|
138
179
|
chunk, next_chunk = next_chunk, cipher.decrypt(input_data[i : i + chunk_size])
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
pyezvizapi/__init__.py,sha256=-OxHqxA9h0JZQW__GoZd1aByGquIHawCnNdeNlIg2Qo,3382
|
|
2
|
+
pyezvizapi/__main__.py,sha256=6vFvkh8gCD-Mo4CXd1deZfDeaaHR-Kc8pOu9vkUjQf4,20878
|
|
3
|
+
pyezvizapi/api_endpoints.py,sha256=2M5Vs4YB1VWZGcowT-4Fj2hhRNjFh976LT3jtRrqvrc,5754
|
|
4
|
+
pyezvizapi/camera.py,sha256=Pl5oIEdrFcv1Hz5sQI1IyyJIDCMjOjQdtExgKzmLoK8,22102
|
|
5
|
+
pyezvizapi/cas.py,sha256=3zHe-_a0KchCmGeAj1of-pV6oMPRUmSCIiDqBFsTK8A,6025
|
|
6
|
+
pyezvizapi/client.py,sha256=CKSK7hdQFmJAD0p1GPgEaqw7QAtqyhqLN8soR_VmSeA,142146
|
|
7
|
+
pyezvizapi/constants.py,sha256=4aoo2jKV88quLIPRwRAH0xW7yCuQfsU9tNtSxq7Xnnk,12854
|
|
8
|
+
pyezvizapi/exceptions.py,sha256=8rmxEUQdrziqMe-M1SeeRd0HtP2IDQ2xpJVj7wvOQyo,976
|
|
9
|
+
pyezvizapi/feature.py,sha256=TwQDAVFXqrpe5s0rXyJSqsHCnQsw1MNSTsUGhb61EzI,15886
|
|
10
|
+
pyezvizapi/light_bulb.py,sha256=9wgycG3dTvBbrsxQjQnXal-GA8VXPsIN1m-CTtRh8i0,7797
|
|
11
|
+
pyezvizapi/models.py,sha256=NQzwTP0yEe2IWU-Vc6nAn87xulpTuo0MX2Rcf0WxifA,4176
|
|
12
|
+
pyezvizapi/mqtt.py,sha256=_JHklUsqqwrgKk3k8RyBgo3bp1utEOr5KSBe8Oz92qg,22375
|
|
13
|
+
pyezvizapi/test_cam_rtsp.py,sha256=O9NHh-vcNFfnzNw8jbuhM9a_5TWfNZIMXaJP7Lmkaj4,5162
|
|
14
|
+
pyezvizapi/test_mqtt.py,sha256=-0L621V4nzm6x0oLgurAgkJZopVZ5Os7n1hLVMh3qIc,4117
|
|
15
|
+
pyezvizapi/utils.py,sha256=Gmn6Ljuo7SUSt1nFN-JmuoWAJGKqUYqur4SBESlhjKI,14153
|
|
16
|
+
pyezvizapi-1.0.3.7.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
17
|
+
pyezvizapi-1.0.3.7.dist-info/licenses/LICENSE.md,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
18
|
+
pyezvizapi-1.0.3.7.dist-info/METADATA,sha256=UYwabH3pFMA4UryJZ8h9Pu-alu2TuG1ee-enZQ2j8bU,695
|
|
19
|
+
pyezvizapi-1.0.3.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
20
|
+
pyezvizapi-1.0.3.7.dist-info/entry_points.txt,sha256=_BSJ3eNb2H_AZkRdsv1s4mojqWn3N7m503ujvg1SudA,56
|
|
21
|
+
pyezvizapi-1.0.3.7.dist-info/top_level.txt,sha256=gMZTelIi8z7pXyTCQLLaIkxVRrDQ_lS2NEv0WgfHrHs,11
|
|
22
|
+
pyezvizapi-1.0.3.7.dist-info/RECORD,,
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
pyezvizapi/__init__.py,sha256=YdtiEuNKa2P0iH4GzIFGpnLmoMYn84AhHpBSaEm9nCQ,3194
|
|
2
|
-
pyezvizapi/__main__.py,sha256=9uttTuOfO22tzyomJIV8ebFJ-G-YUNDYOadZ_0AgdNA,20925
|
|
3
|
-
pyezvizapi/api_endpoints.py,sha256=2M5Vs4YB1VWZGcowT-4Fj2hhRNjFh976LT3jtRrqvrc,5754
|
|
4
|
-
pyezvizapi/camera.py,sha256=Pl5oIEdrFcv1Hz5sQI1IyyJIDCMjOjQdtExgKzmLoK8,22102
|
|
5
|
-
pyezvizapi/cas.py,sha256=3zHe-_a0KchCmGeAj1of-pV6oMPRUmSCIiDqBFsTK8A,6025
|
|
6
|
-
pyezvizapi/client.py,sha256=rQ95oGgx16M69BWA8WTmmpyX9d4kHdxt6biVMrjDmOQ,140990
|
|
7
|
-
pyezvizapi/constants.py,sha256=5AxJYfof6NvebBcFvPkoKI6xinpkwmCnaauUvhvBMDY,12810
|
|
8
|
-
pyezvizapi/exceptions.py,sha256=8rmxEUQdrziqMe-M1SeeRd0HtP2IDQ2xpJVj7wvOQyo,976
|
|
9
|
-
pyezvizapi/feature.py,sha256=0cVUPmFge5qa70yblBJ-DVXagLxrI2Vg_21d_nj1Rt8,14680
|
|
10
|
-
pyezvizapi/light_bulb.py,sha256=9wgycG3dTvBbrsxQjQnXal-GA8VXPsIN1m-CTtRh8i0,7797
|
|
11
|
-
pyezvizapi/models.py,sha256=NQzwTP0yEe2IWU-Vc6nAn87xulpTuo0MX2Rcf0WxifA,4176
|
|
12
|
-
pyezvizapi/mqtt.py,sha256=aOL-gexZgYvCCaNQ03M4vZan91d5p2Fl_qsFykn9NW4,22365
|
|
13
|
-
pyezvizapi/test_cam_rtsp.py,sha256=O9NHh-vcNFfnzNw8jbuhM9a_5TWfNZIMXaJP7Lmkaj4,5162
|
|
14
|
-
pyezvizapi/test_mqtt.py,sha256=Orn-fwZPJIE4G5KROMX0MRAkLwU6nLb9LUtXyb2ZCQs,4147
|
|
15
|
-
pyezvizapi/utils.py,sha256=ozGncEyaIJJ8VYw8f-xfM2OBmqR8eNYLq728FFvbvr8,12757
|
|
16
|
-
pyezvizapi-1.0.3.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
17
|
-
pyezvizapi-1.0.3.5.dist-info/licenses/LICENSE.md,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
18
|
-
pyezvizapi-1.0.3.5.dist-info/METADATA,sha256=nskhuwQbsfgTbcDlJChcWsktleT3pRUdNvBlCHPQbk0,695
|
|
19
|
-
pyezvizapi-1.0.3.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
20
|
-
pyezvizapi-1.0.3.5.dist-info/entry_points.txt,sha256=_BSJ3eNb2H_AZkRdsv1s4mojqWn3N7m503ujvg1SudA,56
|
|
21
|
-
pyezvizapi-1.0.3.5.dist-info/top_level.txt,sha256=gMZTelIi8z7pXyTCQLLaIkxVRrDQ_lS2NEv0WgfHrHs,11
|
|
22
|
-
pyezvizapi-1.0.3.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|