core/homeassistant/components/fritzbox_callmonitor/base.py

87 lines
2.5 KiB
Python

"""Base class for fritzbox_callmonitor entities."""
from __future__ import annotations
from contextlib import suppress
from datetime import timedelta
import logging
import re
from fritzconnection.lib.fritzphonebook import FritzPhonebook
from homeassistant.util import Throttle
from .const import REGEX_NUMBER, UNKNOWN_NAME
_LOGGER = logging.getLogger(__name__)
# Return cached results if phonebook was downloaded less then this time ago.
MIN_TIME_PHONEBOOK_UPDATE = timedelta(hours=6)
class FritzBoxPhonebook:
"""This connects to a FritzBox router and downloads its phone book."""
fph: FritzPhonebook
phonebook_dict: dict[str, list[str]]
number_dict: dict[str, str]
def __init__(
self,
host: str,
username: str,
password: str,
phonebook_id: int | None = None,
prefixes: list[str] | None = None,
) -> None:
"""Initialize the class."""
self.host = host
self.username = username
self.password = password
self.phonebook_id = phonebook_id
self.prefixes = prefixes
def init_phonebook(self) -> None:
"""Establish a connection to the FRITZ!Box and check if phonebook_id is valid."""
self.fph = FritzPhonebook(
address=self.host,
user=self.username,
password=self.password,
)
self.update_phonebook()
@Throttle(MIN_TIME_PHONEBOOK_UPDATE)
def update_phonebook(self) -> None:
"""Update the phone book dictionary."""
if self.phonebook_id is None:
return
self.phonebook_dict = self.fph.get_all_names(self.phonebook_id)
self.number_dict = {
re.sub(REGEX_NUMBER, "", nr): name
for name, nrs in self.phonebook_dict.items()
for nr in nrs
}
_LOGGER.info("Fritz!Box phone book successfully updated")
def get_phonebook_ids(self) -> list[int]:
"""Return list of phonebook ids."""
return self.fph.phonebook_ids
def get_name(self, number: str) -> str:
"""Return a name for a given phone number."""
number = re.sub(REGEX_NUMBER, "", str(number))
with suppress(KeyError):
return self.number_dict[number]
if not self.prefixes:
return UNKNOWN_NAME
for prefix in self.prefixes:
with suppress(KeyError):
return self.number_dict[prefix + number]
with suppress(KeyError):
return self.number_dict[prefix + number.lstrip("0")]
return UNKNOWN_NAME