|
8 | 8 | import datetime |
9 | 9 | import logging |
10 | 10 | from abc import ABC |
11 | | -from collections.abc import Callable, Mapping |
12 | | -from typing import Any, TypeVar, cast |
| 11 | +from collections.abc import Callable |
| 12 | +from typing import Any |
13 | 13 |
|
14 | 14 | from roborock.callbacks import CallbackList |
15 | 15 | from roborock.data import HomeDataDevice, HomeDataProduct |
| 16 | +from roborock.diagnostics import redact_device_data |
16 | 17 | from roborock.exceptions import RoborockException |
17 | 18 | from roborock.roborock_message import RoborockMessage |
18 | 19 | from roborock.util import RoborockLoggerAdapter |
@@ -65,7 +66,7 @@ def __init__( |
65 | 66 | """ |
66 | 67 | TraitsMixin.__init__(self, trait) |
67 | 68 | self._duid = device_info.duid |
68 | | - self._logger = RoborockLoggerAdapter(self._duid, _LOGGER) |
| 69 | + self._logger = RoborockLoggerAdapter(duid=self._duid, logger=_LOGGER) |
69 | 70 | self._name = device_info.name |
70 | 71 | self._device_info = device_info |
71 | 72 | self._product = product |
@@ -223,52 +224,9 @@ def diagnostic_data(self) -> dict[str, Any]: |
223 | 224 | """Return diagnostics information about the device.""" |
224 | 225 | extra: dict[str, Any] = {} |
225 | 226 | if self.v1_properties: |
226 | | - extra["traits"] = _redact_data(self.v1_properties.as_dict()) |
| 227 | + extra["traits"] = redact_device_data(self.v1_properties.as_dict()) |
227 | 228 | return { |
228 | | - "device": _redact_data(self.device_info.as_dict()), |
229 | | - "product": _redact_data(self.product.as_dict()), |
| 229 | + "device": redact_device_data(self.device_info.as_dict()), |
| 230 | + "product": redact_device_data(self.product.as_dict()), |
230 | 231 | **extra, |
231 | 232 | } |
232 | | - |
233 | | - |
234 | | -T = TypeVar("T") |
235 | | - |
236 | | -REDACT_KEYS = { |
237 | | - # Potential identifiers |
238 | | - "duid", |
239 | | - "localKey", |
240 | | - "mac", |
241 | | - "bssid", |
242 | | - "sn", |
243 | | - "ip", |
244 | | - "u", |
245 | | - "s", |
246 | | - "h", |
247 | | - "k", |
248 | | - # Large binary blobs are entirely omitted |
249 | | - "imageContent", |
250 | | - "mapData", |
251 | | - "rawApiResponse", |
252 | | -} |
253 | | -REDACTED = "**REDACTED**" |
254 | | - |
255 | | - |
256 | | -def _redact_data(data: T) -> T | dict[str, Any]: |
257 | | - """Redact sensitive data in a dict.""" |
258 | | - if not isinstance(data, (Mapping, list)): |
259 | | - return data |
260 | | - |
261 | | - if isinstance(data, list): |
262 | | - return cast(T, [_redact_data(item) for item in data]) |
263 | | - |
264 | | - redacted = {**data} |
265 | | - |
266 | | - for key, value in redacted.items(): |
267 | | - if key in REDACT_KEYS: |
268 | | - redacted[key] = REDACTED |
269 | | - elif isinstance(value, dict): |
270 | | - redacted[key] = _redact_data(value) |
271 | | - elif isinstance(value, list): |
272 | | - redacted[key] = [_redact_data(item) for item in value] |
273 | | - |
274 | | - return redacted |
0 commit comments