2021-01-27 15:53:45 +00:00
|
|
|
"""Base class for fritzbox_callmonitor entities."""
|
2022-04-25 12:28:17 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2021-03-23 13:36:43 +00:00
|
|
|
from contextlib import suppress
|
2021-01-27 15:53:45 +00:00
|
|
|
from datetime import timedelta
|
|
|
|
import logging
|
|
|
|
import re
|
|
|
|
|
|
|
|
from fritzconnection.lib.fritzphonebook import FritzPhonebook
|
|
|
|
|
|
|
|
from homeassistant.util import Throttle
|
|
|
|
|
2021-06-11 11:35:03 +00:00
|
|
|
from .const import REGEX_NUMBER, UNKNOWN_NAME
|
2021-01-27 15:53:45 +00:00
|
|
|
|
|
|
|
_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."""
|
|
|
|
|
2022-04-25 12:28:17 +00:00
|
|
|
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:
|
2021-01-27 15:53:45 +00:00
|
|
|
"""Initialize the class."""
|
|
|
|
self.host = host
|
|
|
|
self.username = username
|
|
|
|
self.password = password
|
|
|
|
self.phonebook_id = phonebook_id
|
|
|
|
self.prefixes = prefixes
|
|
|
|
|
2022-04-25 12:28:17 +00:00
|
|
|
def init_phonebook(self) -> None:
|
2021-01-27 15:53:45 +00:00
|
|
|
"""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)
|
2022-04-25 12:28:17 +00:00
|
|
|
def update_phonebook(self) -> None:
|
2021-01-27 15:53:45 +00:00
|
|
|
"""Update the phone book dictionary."""
|
2021-02-05 01:31:47 +00:00
|
|
|
if self.phonebook_id is None:
|
2021-01-27 15:53:45 +00:00
|
|
|
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")
|
|
|
|
|
2022-04-25 12:28:17 +00:00
|
|
|
def get_phonebook_ids(self) -> list[int]:
|
2021-01-27 15:53:45 +00:00
|
|
|
"""Return list of phonebook ids."""
|
|
|
|
return self.fph.phonebook_ids
|
|
|
|
|
2022-04-25 12:28:17 +00:00
|
|
|
def get_name(self, number: str) -> str:
|
2021-01-27 15:53:45 +00:00
|
|
|
"""Return a name for a given phone number."""
|
|
|
|
number = re.sub(REGEX_NUMBER, "", str(number))
|
|
|
|
|
2022-04-25 12:28:17 +00:00
|
|
|
with suppress(KeyError):
|
2021-01-27 15:53:45 +00:00
|
|
|
return self.number_dict[number]
|
|
|
|
|
|
|
|
if not self.prefixes:
|
2021-06-11 11:35:03 +00:00
|
|
|
return UNKNOWN_NAME
|
2021-01-27 15:53:45 +00:00
|
|
|
|
|
|
|
for prefix in self.prefixes:
|
2021-03-23 13:36:43 +00:00
|
|
|
with suppress(KeyError):
|
2021-01-27 15:53:45 +00:00
|
|
|
return self.number_dict[prefix + number]
|
2021-03-23 13:36:43 +00:00
|
|
|
with suppress(KeyError):
|
2021-01-27 15:53:45 +00:00
|
|
|
return self.number_dict[prefix + number.lstrip("0")]
|
2022-04-25 12:28:17 +00:00
|
|
|
|
|
|
|
return UNKNOWN_NAME
|