"""JSON utility functions.""" from __future__ import annotations import json import logging from .error import PytradfriError # https://github.com/home-assistant/home-assistant/blob/4e8723f345d526ffbcbea74444e1a140a7eec863/homeassistant/util/json.py _LOGGER = logging.getLogger(__name__) def load_json(filename: str) -> list | dict: """Load JSON data from a file and return as dict or list. Defaults to returning empty dict if file is not found. """ try: with open(filename, encoding="utf-8") as fdesc: return json.loads(fdesc.read()) except FileNotFoundError: # This is not a fatal error _LOGGER.debug("JSON file not found: %s", filename) except ValueError as exc: _LOGGER.exception("Could not parse JSON content: %s", filename) raise PytradfriError(exc) from exc except OSError as exc: _LOGGER.exception("JSON file reading failed: %s", filename) raise PytradfriError(exc) from exc return {} # (also evaluates to False) def save_json(filename: str, config: list | dict) -> bool: """Save JSON data to a file. Returns True on success. """ try: data = json.dumps(config, sort_keys=True, indent=4) with open(filename, "w", encoding="utf-8") as fdesc: fdesc.write(data) return True except TypeError as exc: _LOGGER.exception("Failed to serialize to JSON: %s", filename) raise PytradfriError(exc) from exc except OSError as exc: _LOGGER.exception("Saving JSON file failed: %s", filename) raise PytradfriError(exc) from exc class BitChoices: """Helper class for bitwise dates. http://stackoverflow.com/questions/3663898/representing-a-multi-select-field-for-weekdays-in-a-django-model """ def __init__(self, choices): """Initialize BitChoices class.""" self._choices = [] self._lookup = {} for index, (key, val) in enumerate(choices): index = 2**index self._choices.append((index, val)) self._lookup[key] = index def __iter__(self): """Iterate over object.""" return iter(self._choices) def __len__(self): """Len.""" return len(self._choices) def __getattr__(self, attr): """Getattr.""" try: return self._lookup[attr] except KeyError as exc: raise AttributeError(attr) from exc def get_selected_keys(self, selection): """Return a list of keys for the given selection.""" return [k for k, b in self._lookup.items() if b & selection] def get_selected_values(self, selection): """Return a list of values for the given selection.""" return [v for b, v in self._choices if b & selection]