From 1a46da5aaedfc5c275c22a12e3de9cebc9a1a28e Mon Sep 17 00:00:00 2001 From: Ivan Pavlina Date: Sat, 4 Apr 2020 17:51:35 +0200 Subject: [PATCH] Add ability to return list results of API call instead of generator. On generator return do not call iterate over object, removes redundant calls to API. Update calls to api.path with new input param. Fix logging in helper object. --- custom_components/mikrotik_router/helper.py | 4 +- .../mikrotik_router/mikrotik_controller.py | 18 +++--- .../mikrotik_router/mikrotikapi.py | 60 +++++++++---------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/custom_components/mikrotik_router/helper.py b/custom_components/mikrotik_router/helper.py index 826dc81..6f10b86 100644 --- a/custom_components/mikrotik_router/helper.py +++ b/custom_components/mikrotik_router/helper.py @@ -57,6 +57,8 @@ def parse_api( data = fill_defaults(data, vals) return data + _LOGGER.debug("Processing source %s", source) + keymap = generate_keymap(data, key_search) for entry in source: if only and not matches_only(entry, only): @@ -74,7 +76,7 @@ def parse_api( if uid not in data: data[uid] = {} - _LOGGER.debug("Processing entry %s, entry %s", source, entry) + _LOGGER.debug("Processing entry %s", entry) if vals: data = fill_vals(data, entry, uid, vals) diff --git a/custom_components/mikrotik_router/mikrotik_controller.py b/custom_components/mikrotik_router/mikrotik_controller.py index bbe632c..be7fcf5 100644 --- a/custom_components/mikrotik_router/mikrotik_controller.py +++ b/custom_components/mikrotik_router/mikrotik_controller.py @@ -229,7 +229,7 @@ class MikrotikControllerData: """Get all interfaces data from Mikrotik""" self.data["interface"] = parse_api( data=self.data["interface"], - source=self.api.path("/interface"), + source=self.api.path("/interface", return_list=True), key="default-name", vals=[ {"name": "default-name"}, @@ -331,7 +331,7 @@ class MikrotikControllerData: # --------------------------- def update_arp(self, mac2ip, bridge_used): """Get list of hosts in ARP for interface client data from Mikrotik""" - data = self.api.path("/ip/arp") + data = self.api.path("/ip/arp", return_list=True) if not data: return mac2ip, bridge_used @@ -382,7 +382,7 @@ class MikrotikControllerData: # --------------------------- def update_bridge_hosts(self, mac2ip): """Get list of hosts in bridge for interface client data from Mikrotik""" - data = self.api.path("/interface/bridge/host") + data = self.api.path("/interface/bridge/host", return_list=True) if not data: return @@ -437,7 +437,7 @@ class MikrotikControllerData: """Get NAT data from Mikrotik""" self.data["nat"] = parse_api( data=self.data["nat"], - source=self.api.path("/ip/firewall/nat"), + source=self.api.path("/ip/firewall/nat", return_list=True, return_list=True), key=".id", vals=[ {"name": ".id"}, @@ -473,7 +473,7 @@ class MikrotikControllerData: """Get routerboard data from Mikrotik""" self.data["routerboard"] = parse_api( data=self.data["routerboard"], - source=self.api.path("/system/routerboard"), + source=self.api.path("/system/routerboard", return_list=True), vals=[ {"name": "routerboard", "type": "bool"}, {"name": "model", "default": "unknown"}, @@ -489,7 +489,7 @@ class MikrotikControllerData: """Get system resources data from Mikrotik""" self.data["resource"] = parse_api( data=self.data["resource"], - source=self.api.path("/system/resource"), + source=self.api.path("/system/resource", return_list=True), vals=[ {"name": "platform", "default": "unknown"}, {"name": "board-name", "default": "unknown"}, @@ -538,7 +538,7 @@ class MikrotikControllerData: """Check for firmware update on Mikrotik""" self.data["fw-update"] = parse_api( data=self.data["fw-update"], - source=self.api.path("/system/package/update"), + source=self.api.path("/system/package/update", return_list=True), vals=[ {"name": "status"}, {"name": "channel", "default": "unknown"}, @@ -563,7 +563,7 @@ class MikrotikControllerData: """Get list of all scripts from Mikrotik""" self.data["script"] = parse_api( data=self.data["script"], - source=self.api.path("/system/script"), + source=self.api.path("/system/script", return_list=True), key="name", vals=[ {"name": "name"}, @@ -580,7 +580,7 @@ class MikrotikControllerData: """Get Queue data from Mikrotik""" self.data["queue"] = parse_api( data=self.data["queue"], - source=self.api.path("/queue/simple"), + source=self.api.path("/queue/simple", return_list=True), key="name", vals=[ {"name": ".id"}, diff --git a/custom_components/mikrotik_router/mikrotikapi.py b/custom_components/mikrotik_router/mikrotikapi.py index 0c08f48..883e865 100644 --- a/custom_components/mikrotik_router/mikrotikapi.py +++ b/custom_components/mikrotik_router/mikrotikapi.py @@ -167,8 +167,9 @@ class MikrotikAPI: # --------------------------- # path # --------------------------- - def path(self, path) -> Optional(list): + def path(self, path, return_list=False) -> Optional(list): """Retrieve data from Mikrotik API.""" + """Returns generator object, unless return_list passed as True""" if not self._connected or not self._connection: if self._connection_epoch > time.time() - self._connection_retry_sec: return None @@ -189,18 +190,17 @@ class MikrotikAPI: self.lock.release() return None except ( - librouteros_custom.exceptions.TrapError, - librouteros_custom.exceptions.MultiTrapError, - librouteros_custom.exceptions.ProtocolError, - librouteros_custom.exceptions.FatalError, - ssl.SSLError, - BrokenPipeError, - OSError, - ValueError, + librouteros_custom.exceptions.TrapError, + librouteros_custom.exceptions.MultiTrapError, + librouteros_custom.exceptions.ProtocolError, + librouteros_custom.exceptions.FatalError, + ssl.SSLError, + BrokenPipeError, + OSError, + ValueError, ) as api_error: if not self.connection_error_reported: - _LOGGER.error("Mikrotik %s error while path %s", self._host, - api_error) + _LOGGER.error("Mikrotik %s error while path %s", self._host, api_error) self.connection_error_reported = True self.disconnect() @@ -208,34 +208,32 @@ class MikrotikAPI: return None except: if not self.connection_error_reported: - _LOGGER.error("Mikrotik %s error while path %s", self._host, - "unknown") + _LOGGER.error("Mikrotik %s error while path %s", self._host, "unknown") self.connection_error_reported = True self.disconnect() self.lock.release() return None - try: - tuple(response) - except librouteros_custom.exceptions.ConnectionClosed as api_error: - if not self.connection_error_reported: - _LOGGER.error("Mikrotik %s error while path %s", self._host, - api_error) - self.connection_error_reported = True + if return_list: + try: + response = list(response) + except librouteros_custom.exceptions.ConnectionClosed as api_error: + if not self.connection_error_reported: + _LOGGER.error("Mikrotik %s error while building list for path %s", self._host, api_error) + self.connection_error_reported = True - self.disconnect() - self.lock.release() - return None - except: - if not self.connection_error_reported: - _LOGGER.error("Mikrotik %s error while path %s", self._host, - "unknown") - self.connection_error_reported = True + self.disconnect() + self.lock.release() + return None + except: + if not self.connection_error_reported: + _LOGGER.error("Mikrotik %s error while building list for path %s", self._host, "unknown") + self.connection_error_reported = True - self.disconnect() - self.lock.release() - return None + self.disconnect() + self.lock.release() + return None self.lock.release() return response if response else None