def test_load_bad_data(self):
     """Test error from trying to load unserialisable data."""
     fname = self._path_for("test3")
     with open(fname, "w") as fh:
         fh.write(TEST_BAD_YAML)
     with pytest.raises(HomeAssistantError):
         util_yaml.load_yaml(fname, True)
def test_load_bad_data():
    """Test error from trying to load unserialisable data."""
    fname = _path_for("test3")
    with open(fname, "w") as fh:
        fh.write(TEST_BAD_YAML)
    with pytest.raises(HomeAssistantError):
        util_yaml.load_yaml(fname, True)
Example #3
0
def load_config(hass) -> JSON_TYPE:
    """Load a YAML file."""
    fname = hass.config.path(LOVELACE_CONFIG_FILE)

    # Check for a cached version of the config
    if LOVELACE_DATA in hass.data:
        config, last_update = hass.data[LOVELACE_DATA]
        modtime = os.path.getmtime(fname)
        if config and last_update > modtime:
            return config

    config = yaml.load_yaml(fname, False)
    seen_card_ids = set()
    seen_view_ids = set()
    for view in config.get('views', []):
        view_id = str(view.get('id', ''))
        if view_id:
            if view_id in seen_view_ids:
                raise DuplicateIdError(
                    'ID `{}` has multiple occurances in views'.format(view_id))
            seen_view_ids.add(view_id)
        for card in view.get('cards', []):
            card_id = str(card.get('id', ''))
            if card_id:
                if card_id in seen_card_ids:
                    raise DuplicateIdError(
                        'ID `{}` has multiple occurances in cards'.format(
                            card_id))
                seen_card_ids.add(card_id)
    hass.data[LOVELACE_DATA] = (config, time.time())
    return config
Example #4
0
def migrate_config(fname: str) -> None:
    """Add id to views and cards if not present and check duplicates."""
    config = yaml.load_yaml(fname, True)
    updated = False
    seen_card_ids = set()
    seen_view_ids = set()
    index = 0
    for view in config.get('views', []):
        view_id = str(view.get('id', ''))
        if not view_id:
            updated = True
            view.insert(0, 'id', index, comment="Automatically created id")
        else:
            if view_id in seen_view_ids:
                raise DuplicateIdError(
                    'ID `{}` has multiple occurrences in views'.format(
                        view_id))
            seen_view_ids.add(view_id)
        for card in view.get('cards', []):
            card_id = str(card.get('id', ''))
            if not card_id:
                updated = True
                card.insert(0,
                            'id',
                            uuid.uuid4().hex,
                            comment="Automatically created id")
            else:
                if card_id in seen_card_ids:
                    raise DuplicateIdError(
                        'ID `{}` has multiple occurrences in cards'.format(
                            card_id))
                seen_card_ids.add(card_id)
        index += 1
    if updated:
        yaml.save_yaml(fname, config)
 def test_save_and_load(self):
     """Test saving and loading back."""
     fname = self._path_for("test1")
     open(fname, "w+")
     util_yaml.save_yaml(fname, self.yaml.load(TEST_YAML_A))
     data = util_yaml.load_yaml(fname, True)
     assert data == self.yaml.load(TEST_YAML_A)
Example #6
0
    def set_schedule(service):
        """Handle the service call."""
        entity_id = service.data[ATTR_ENTITY_ID]
        filename = service.data[ATTR_FILENAME]
        schedule_data = None

        # Set schedule data
        _LOGGER.debug("Setting schedule for %s from file %s", entity_id,
                      filename)
        if entity_id in data.schedules:
            try:
                _LOGGER.debug("Loading schedule file - %s", filename)
                schedule_data = yaml.load_yaml(filename)
            except Exception as ex:
                _LOGGER.error("Error loading schedule file %s. Error is %s",
                              filename, str(ex))
            # Set schedule
            if schedule_data is not None:
                hass.async_create_task(
                    data.set_schedule(entity_id, data.schedules[entity_id],
                                      schedule_data))
            else:
                _LOGGER.error("Error loading schedule data from file")
        else:
            _LOGGER.error("No schedule exists for %s", entity_id)
Example #7
0
 def test_save_and_load(self):
     """Test saving and loading back."""
     fname = self._path_for("test1")
     open(fname, "w+")
     util_yaml.save_yaml(fname, self.yaml.load(TEST_YAML_A))
     data = util_yaml.load_yaml(fname, True)
     assert data == self.yaml.load(TEST_YAML_A)
Example #8
0
def move_card_view(fname: str,
                   card_id: str,
                   view_id: str,
                   position: int = None) -> None:
    """Move a card to a different view."""
    config = yaml.load_yaml(fname, True)
    for view in config.get('views', []):
        if str(view.get('id', '')) == view_id:
            destination = view.get('cards')
        for card in view.get('cards'):
            if str(card.get('id', '')) != card_id:
                continue
            origin = view.get('cards')
            card_to_move = card

    if 'destination' not in locals():
        raise ViewNotFoundError("View with ID: {} was not found in {}.".format(
            view_id, fname))
    if 'card_to_move' not in locals():
        raise CardNotFoundError("Card with ID: {} was not found in {}.".format(
            card_id, fname))

    origin.pop(origin.index(card_to_move))

    if position is None:
        destination.append(card_to_move)
    else:
        destination.insert(position, card_to_move)

    yaml.save_yaml(fname, config)
def test_save_and_load():
    """Test saving and loading back."""
    yaml = YAML(typ="rt")
    fname = _path_for("test1")
    open(fname, "w+").close()
    util_yaml.save_yaml(fname, yaml.load(TEST_YAML_A))
    data = util_yaml.load_yaml(fname, True)
    assert data == yaml.load(TEST_YAML_A)
 def test_overwrite_and_reload(self):
     """Test that we can overwrite an existing file and read back."""
     fname = self._path_for("test2")
     open(fname, "w+")
     util_yaml.save_yaml(fname, self.yaml.load(TEST_YAML_A))
     util_yaml.save_yaml(fname, self.yaml.load(TEST_YAML_B))
     data = util_yaml.load_yaml(fname, True)
     assert data == self.yaml.load(TEST_YAML_B)
Example #11
0
 def test_overwrite_and_reload(self):
     """Test that we can overwrite an existing file and read back."""
     fname = self._path_for("test2")
     open(fname, "w+")
     util_yaml.save_yaml(fname, self.yaml.load(TEST_YAML_A))
     util_yaml.save_yaml(fname, self.yaml.load(TEST_YAML_B))
     data = util_yaml.load_yaml(fname, True)
     assert data == self.yaml.load(TEST_YAML_B)
def test_overwrite_and_reload():
    """Test that we can overwrite an existing file and read back."""
    yaml = YAML(typ="rt")
    fname = _path_for("test2")
    open(fname, "w+").close()
    util_yaml.save_yaml(fname, yaml.load(TEST_YAML_A))
    util_yaml.save_yaml(fname, yaml.load(TEST_YAML_B))
    data = util_yaml.load_yaml(fname, True)
    assert data == yaml.load(TEST_YAML_B)
 def set_schedule(service):
     """Handle the service call."""
     entity_id = service.data[ATTR_ENTITY_ID]
     filename = service.data[ATTR_FILENAME]
     # Get schedule data
     schedule_data = yaml.load_yaml(filename)
     # Set schedule
     for room in wiser_rooms:
         if room.entity_id == entity_id:
             hass.async_create_task(
                 room.set_room_schedule(room.room_id, schedule_data))
             room.schedule_update_ha_state(True)
             break
Example #14
0
def add_view(fname: str,
             view_config: str,
             position: int = None,
             data_format: str = FORMAT_YAML) -> None:
    """Add a view."""
    config = yaml.load_yaml(fname, True)
    views = config.get('views', [])
    if data_format == FORMAT_YAML:
        view_config = yaml.yaml_to_object(view_config)
    if position is None:
        views.append(view_config)
    else:
        views.insert(position, view_config)
    yaml.save_yaml(fname, config)
Example #15
0
def delete_card(fname: str, card_id: str) -> None:
    """Delete a card from view."""
    config = yaml.load_yaml(fname, True)
    for view in config.get('views', []):
        for card in view.get('cards', []):
            if str(card.get('id', '')) != card_id:
                continue
            cards = view.get('cards')
            cards.pop(cards.index(card))
            yaml.save_yaml(fname, config)
            return

    raise CardNotFoundError("Card with ID: {} was not found in {}.".format(
        card_id, fname))
Example #16
0
def delete_view(fname: str, view_id: str) -> None:
    """Delete a view."""
    config = yaml.load_yaml(fname, True)
    views = config.get('views', [])
    found = None
    for view in views:
        if str(view.get('id', '')) == view_id:
            found = view
            break
    if found is None:
        raise ViewNotFoundError("View with ID: {} was not found in {}.".format(
            view_id, fname))

    views.pop(views.index(found))
    yaml.save_yaml(fname, config)
Example #17
0
def move_view(fname: str, view_id: str, position: int) -> None:
    """Move a view to a different position."""
    config = yaml.load_yaml(fname, True)
    views = config.get('views', [])
    found = None
    for view in views:
        if str(view.get('id', '')) == view_id:
            found = view
            break
    if found is None:
        raise ViewNotFoundError("View with ID: {} was not found in {}.".format(
            view_id, fname))

    views.insert(position, views.pop(views.index(found)))
    yaml.save_yaml(fname, config)
Example #18
0
def move_card(fname: str, card_id: str, position: int = None) -> None:
    """Move a card to a different position."""
    if position is None:
        raise HomeAssistantError(
            'Position is required if view is not specified.')
    config = yaml.load_yaml(fname, True)
    for view in config.get('views', []):
        for card in view.get('cards', []):
            if str(card.get('id', '')) != card_id:
                continue
            cards = view.get('cards')
            cards.insert(position, cards.pop(cards.index(card)))
            yaml.save_yaml(fname, config)
            return

    raise CardNotFoundError("Card with ID: {} was not found in {}.".format(
        card_id, fname))
Example #19
0
def get_view(fname: str, view_id: str, data_format: str = FORMAT_YAML) -> None:
    """Get view without it's cards."""
    round_trip = data_format == FORMAT_YAML
    config = yaml.load_yaml(fname, round_trip)
    found = None
    for view in config.get('views', []):
        if str(view.get('id', '')) == view_id:
            found = view
            break
    if found is None:
        raise ViewNotFoundError("View with ID: {} was not found in {}.".format(
            view_id, fname))

    del found['cards']
    if data_format == FORMAT_YAML:
        return yaml.object_to_yaml(found)
    return found
Example #20
0
def get_card(fname: str, card_id: str, data_format: str = FORMAT_YAML)\
        -> JSON_TYPE:
    """Load a specific card config for id."""
    round_trip = data_format == FORMAT_YAML

    config = yaml.load_yaml(fname, round_trip)

    for view in config.get('views', []):
        for card in view.get('cards', []):
            if str(card.get('id', '')) != card_id:
                continue
            if data_format == FORMAT_YAML:
                return yaml.object_to_yaml(card)
            return card

    raise CardNotFoundError("Card with ID: {} was not found in {}.".format(
        card_id, fname))
Example #21
0
def update_card(fname: str,
                card_id: str,
                card_config: str,
                data_format: str = FORMAT_YAML) -> None:
    """Save a specific card config for id."""
    config = yaml.load_yaml(fname, True)
    for view in config.get('views', []):
        for card in view.get('cards', []):
            if str(card.get('id', '')) != card_id:
                continue
            if data_format == FORMAT_YAML:
                card_config = yaml.yaml_to_object(card_config)
            card.clear()
            card.update(card_config)
            yaml.save_yaml(fname, config)
            return

    raise CardNotFoundError("Card with ID: {} was not found in {}.".format(
        card_id, fname))
Example #22
0
def update_view(fname: str,
                view_id: str,
                view_config,
                data_format: str = FORMAT_YAML) -> None:
    """Update view."""
    config = yaml.load_yaml(fname, True)
    found = None
    for view in config.get('views', []):
        if str(view.get('id', '')) == view_id:
            found = view
            break
    if found is None:
        raise ViewNotFoundError("View with ID: {} was not found in {}.".format(
            view_id, fname))
    if data_format == FORMAT_YAML:
        view_config = yaml.yaml_to_object(view_config)
    view_config['cards'] = found.get('cards', [])
    found.clear()
    found.update(view_config)
    yaml.save_yaml(fname, config)
Example #23
0
def add_card(fname: str,
             view_id: str,
             card_config: str,
             position: int = None,
             data_format: str = FORMAT_YAML) -> None:
    """Add a card to a view."""
    config = yaml.load_yaml(fname, True)
    for view in config.get('views', []):
        if str(view.get('id', '')) != view_id:
            continue
        cards = view.get('cards', [])
        if data_format == FORMAT_YAML:
            card_config = yaml.yaml_to_object(card_config)
        if position is None:
            cards.append(card_config)
        else:
            cards.insert(position, card_config)
        yaml.save_yaml(fname, config)
        return

    raise ViewNotFoundError("View with ID: {} was not found in {}.".format(
        view_id, fname))