From 493d3e3878f2db869a99247083b55d9cbda9ff7a Mon Sep 17 00:00:00 2001 From: Jeff Culverhouse Date: Sun, 6 Apr 2025 11:18:50 -0400 Subject: [PATCH] feature: lookup camera hostname just once --- CHANGELOG | 7 +++++++ VERSION | 2 +- amcrest_api.py | 9 ++++++++- util.py | 17 +++++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..1e4983a --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,7 @@ +1.0.1 + - lookup camera hostnames to get ip at config, so we aren't don't + 100k lookups every day (in my 4 camera setup) + +1.0.0 + - initial release + diff --git a/VERSION b/VERSION index 3eefcb9..7dea76e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0 +1.0.1 diff --git a/amcrest_api.py b/amcrest_api.py index 08e1e4b..b0ad1fa 100644 --- a/amcrest_api.py +++ b/amcrest_api.py @@ -61,7 +61,13 @@ class AmcrestAPI(object): async def get_device(self, host, device_name): try: - camera = self.get_camera(host) + # resolve host and setup camera by ip so we aren't making 100k DNS lookups per day + try: + host_ip = get_ip_address(host) + self.logger.info(f'nslookup {host} got us {host_ip}') + camera = self.get_camera(host_ip) + except Exception as err: + self.logger.error(f'Failed to resolve {host} to ip address: {err}') device_type = camera.device_type.replace('type=', '').strip() is_ad110 = device_type == 'AD110' @@ -89,6 +95,7 @@ class AmcrestAPI(object): 'camera': camera, 'config': { 'host': host, + 'host_ip': host_ip, 'device_name': device_name, 'device_type': device_type, 'device_class': camera.device_class, diff --git a/util.py b/util.py index a7fbe1c..5212308 100644 --- a/util.py +++ b/util.py @@ -5,7 +5,9 @@ # # The software is provided 'as is', without any warranty. +import ipaddress import os +import socket # Helper functions and callbacks def read_file(file_name): @@ -22,3 +24,18 @@ def read_version(): def to_gb(total): return str(round(float(total[0]) / 1024 / 1024 / 1024, 2)) + +def is_ipv4(string): + try: + ipaddress.IPv4Network(string) + return True + except ValueError: + return False + +def get_ip_address(string): + if is_ipv4(string): + return string + for i in socket.getaddrinfo(string, 0): + if i[0] is socket.AddressFamily.AF_INET and i[1] is socket.SocketKind.SOCK_RAW: + return i[4][0] + raise Exception(f'failed to find ip address for {string}') \ No newline at end of file