1"""
2Common functions for other core-modules.
3"""
4
5import re
6import requests
7
8from xml.etree import ElementTree as etree
9from .exceptions import FritzConnectionException
10from .logger import fritzlogger
11
12
13NS_REGEX = re.compile("({(?P<namespace>.*)})?(?P<localname>.*)")
14
15
16def localname(node):
17    if callable(node.tag):
18        return "comment"
19    m = NS_REGEX.match(node.tag)
20    return m.group('localname')
21
22
23def get_content_from(url, timeout=None, session=None):
24    """
25    Returns text from a get-request for the given url. In case of a
26    secure request (using TLS) the parameter verify is set to False, to
27    disable certificate verifications. As the Fritz!Box creates a
28    self-signed certificate for use in the LAN, encryption will work but
29    verification will fail.
30    """
31    def handle_response(response):
32        fritzlogger.log(response.text, "debug")
33        ct = response.headers.get("Content-type")
34        if ct == "text/html":
35            message = f"Unable to retrieve resource '{url}' from the device."
36            raise FritzConnectionException(message)
37        return response.text
38
39    fritzlogger.log(f"\n{url}", "debug")
40    if session:
41        with session.get(url, timeout=timeout) as response:
42            return handle_response(response)
43    response = requests.get(url, timeout=timeout, verify=False)
44    return handle_response(response)
45
46
47def get_xml_root(source, timeout=None, session=None):
48    """
49    Function to help migrate from lxml to the standard-library xml-package.
50
51    'source' must be a string and can be an xml-string, a uri or a file
52    name. `timeout` is an optional parameter limiting the time waiting
53    for a router response.
54    In all cases this function returns an xml.etree.Element instance
55    which is the root of the parsed tree.
56    """
57    if source.startswith("http://") or source.startswith("https://"):
58        # it's a uri, use requests to get the content
59        source = get_content_from(source, timeout=timeout, session=session)
60    elif not source.startswith("<"):
61        # assume it's a filename
62        with open(source) as fobj:
63            source = fobj.read()
64    return etree.fromstring(source)
65