From 19ac14ed0eaf8ed7094bdca1a19717972bfae4b6 Mon Sep 17 00:00:00 2001 From: Ross Mountjoy Date: Sat, 30 May 2020 08:25:16 -0400 Subject: [PATCH] (MANUALLY ADDING PR FROM Thlb 0.6 version) Add Sonarr,Radarr,Tautulli,Healthchecks platforms --- dashmachine/platform/healthchecks.py | 238 +++++++++++++++++++++ dashmachine/platform/radarr.py | 303 +++++++++++++++++++++++++++ dashmachine/platform/sonarr.py | 303 +++++++++++++++++++++++++++ dashmachine/platform/tautulli.py | 260 +++++++++++++++++++++++ 4 files changed, 1104 insertions(+) create mode 100644 dashmachine/platform/healthchecks.py create mode 100644 dashmachine/platform/radarr.py create mode 100644 dashmachine/platform/sonarr.py create mode 100644 dashmachine/platform/tautulli.py diff --git a/dashmachine/platform/healthchecks.py b/dashmachine/platform/healthchecks.py new file mode 100644 index 0000000..d2d88fc --- /dev/null +++ b/dashmachine/platform/healthchecks.py @@ -0,0 +1,238 @@ +from flask import render_template_string +import requests + + +class Healthchecks(object): + def __init__(self, method, prefix, host, port, api_key, project, verify): + self.endpoint = "/api/v1/checks/" + self.method = method + self.prefix = prefix + self.host = host + self.port = port + self.api_key = api_key + self.project = project + self.verify = verify + + # Initialize results + self.error = None + self.status = "" + self.count_checks = 0 + self.count_up = 0 + self.count_down = 0 + self.count_grace = 0 + self.count_paused = 0 + + def check(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint, + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + if "error" in rawdata: + self.error = rawdata["error"] + + def getChecks(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint, + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + for check in rawdata["checks"]: + self.count_checks += 1 + if check["status"] == "up": + self.count_up += 1 + if check["status"] == "down": + self.count_down += 1 + if check["status"] == "grace": + self.count_grace += 1 + if check["status"] == "paused": + self.count_paused += 1 + + if self.count_down > 0: + self.status = "down" + if self.count_down == 0 and self.count_grace > 0: + self.status = "grace" + if self.count_down == 0 and self.count_grace == 0: + self.status = "up" + + def refresh(self): + self.check() + if self.error == None: + self.error = "" + self.getChecks() + + +class Platform: + def docs(self): + documentation = { + "name": "healthchecks", + "author": "Thlb", + "author_url": "https://github.com/Thlb", + "version": 1.0, + "description": "Display information from Healthchecks API", + "returns": "`value_template` as rendered string", + "returns_json_keys": [ + "status", + "count_checks", + "count_up", + "count_down", + "count_grace", + "count_paused", + "error (for debug)", + ], + "example": """ +```ini +[healthchecks-data] +platform = healthchecks +prefix = http:// +host = 192.168.0.110 +port = 8080 +api_key = {{ API Key }} +project = {{ Project name }} +verify = False +value_template = {{error}}

fiber_manual_record{{count_up}}fiber_manual_record{{count_grace}}fiber_manual_record{{count_down}}

+ +[Healthchecks] +prefix = http:// +url = 192.168.0.110 +icon = static/images/apps/healthchecks.png +description = Healthchecks is a watchdog for your cron jobs. It's a web server that listens for pings from your cron jobs, plus a web interface. +open_in = this_tab +data_sources = healthchecks-data +``` + """, + "variables": [ + { + "variable": "[variable_name]", + "description": "Name for the data source.", + "default": "None, entry is required", + "options": ".ini header", + }, + { + "variable": "platform", + "description": "Name of the platform.", + "default": "healthchecks", + "options": "healthchecks", + }, + { + "variable": "prefix", + "description": "The prefix for the app's url.", + "default": "", + "options": "web prefix, e.g. http:// or https://", + }, + { + "variable": "host", + "description": "Healthchecks Host", + "default": "", + "options": "url,ip", + }, + { + "variable": "port", + "description": "Healthchecks Port", + "default": "", + "options": "port", + }, + { + "variable": "api_key", + "description": "ApiKey", + "default": "", + "options": "api key", + }, + { + "variable": "project", + "description": "Healthchecks project name", + "default": "", + "options": "project name", + }, + { + "variable": "verify", + "description": "Turn TLS verification on or off, default is true", + "default": "", + "options": "true,false", + }, + { + "variable": "value_template", + "description": "Jinja template for how the returned data from API is displayed.", + "default": "", + "options": "jinja template", + }, + ], + } + return documentation + + def __init__(self, *args, **kwargs): + # parse the user's options from the config entries + for key, value in kwargs.items(): + self.__dict__[key] = value + + # set defaults for omitted options + if not hasattr(self, "method"): + self.method = "GET" + if not hasattr(self, "prefix"): + self.prefix = "http://" + if not hasattr(self, "host"): + self.host = None + if not hasattr(self, "port"): + self.port = None + if not hasattr(self, "api_key"): + self.api_key = None + if not hasattr(self, "project"): + self.project = None + if not hasattr(self, "verify"): + self.verify = True + + self.healthchecks = Healthchecks( + self.method, + self.prefix, + self.host, + self.port, + self.api_key, + self.project, + self.verify, + ) + + def process(self): + if self.api_key == None: + return "api_key missing" + if self.host == None: + return "host missing" + + self.healthchecks.refresh() + value_template = render_template_string( + self.value_template, **self.healthchecks.__dict__ + ) + return value_template diff --git a/dashmachine/platform/radarr.py b/dashmachine/platform/radarr.py new file mode 100644 index 0000000..9997650 --- /dev/null +++ b/dashmachine/platform/radarr.py @@ -0,0 +1,303 @@ +from flask import render_template_string +import requests + + +class Radarr(object): + def __init__(self, method, prefix, host, port, api_key, verify): + self.endpoint = "/api" + self.method = method + self.prefix = prefix + self.host = host + self.port = port + self.api_key = api_key + self.verify = verify + + # Initialize results + self.error = None + self.version = "?" + self.movies = 0 + self.queue = 0 + self.diskspace = [ + {"path": "", "total": "", "free": "", "used": ""}, + {"path": "", "total": "", "free": "", "used": ""}, + ] + + def check(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/system/status", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + if "error" in rawdata: + self.error = rawdata["error"] + + def getVersion(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/system/status", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.version = rawdata["version"] + + def getMovies(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/movie", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.movies = len(rawdata) + + def getQueue(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/queue", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.queue = len((rawdata)) + + def getDiskspace(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/diskspace", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.diskspace = rawdata + for item in self.diskspace: + item["used"] = self.formatSize(item["totalSpace"] - item["freeSpace"]) + item["total"] = self.formatSize(item["totalSpace"]) + item["free"] = self.formatSize(item["freeSpace"]) + item.pop("totalSpace", None) + item.pop("freeSpace", None) + + def formatSize(self, size): + # 2**10 = 1024 + power = 2 ** 10 + n = 0 + power_labels = {0: "", 1: "KB", 2: "MB", 3: "GB", 4: "TB"} + while size > power: + size /= power + n += 1 + return str(round(size, 1)) + " " + power_labels[n] + + def refresh(self): + self.check() + if self.error == None: + self.error = "" + self.getVersion() + self.getMovies() + self.getQueue() + self.getDiskspace() + + +class Platform: + def docs(self): + documentation = { + "name": "radarr", + "author": "Thlb", + "author_url": "https://github.com/Thlb", + "version": 1.0, + "description": "Display information from Radarr API", + "returns": "`value_template` as rendered string", + "returns_json_keys": [ + "version", + "movies", + "queue", + "diskspace[x]['path']", + "diskspace[x]['total']", + "diskspace[x]['used']", + "diskspace[x]['free']", + "error (for debug)", + ], + "example": """ +```ini +[radarr-data] +platform = radarr +prefix = http:// +host = 192.168.0.110 +port = 7878 +api_key = {{ API Key }} +verify = False +value_template = {{error}}Movies : {{movies}}
Queue : {{queue}}
Free ({{diskspace[0]['path']}}) : {{diskspace[0]['free']}} + +[Radarr] +prefix = http:// +url = 192.168.0.110:7878 +icon = static/images/apps/radarr.png +sidebar_icon = static/images/apps/radarr.png +description = A fork of Sonarr to work with movies à la Couchpotato +open_in = this_tab +data_sources = radarr-data +``` + """, + "variables": [ + { + "variable": "[variable_name]", + "description": "Name for the data source.", + "default": "None, entry is required", + "options": ".ini header", + }, + { + "variable": "platform", + "description": "Name of the platform.", + "default": "radarr", + "options": "radarr", + }, + { + "variable": "prefix", + "description": "The prefix for the app's url.", + "default": "", + "options": "web prefix, e.g. http:// or https://", + }, + { + "variable": "host", + "description": "Radarr Host", + "default": "", + "options": "url,ip", + }, + { + "variable": "port", + "description": "Radarr Port", + "default": "", + "options": "port", + }, + { + "variable": "api_key", + "description": "ApiKey", + "default": "", + "options": "api key", + }, + { + "variable": "verify", + "description": "Turn TLS verification on or off, default is true", + "default": "", + "options": "true,false", + }, + { + "variable": "value_template", + "description": "Jinja template for how the returned data from API is displayed.", + "default": "", + "options": "jinja template", + }, + ], + } + return documentation + + def __init__(self, *args, **kwargs): + # parse the user's options from the config entries + for key, value in kwargs.items(): + self.__dict__[key] = value + + # set defaults for omitted options + if not hasattr(self, "method"): + self.method = "GET" + if not hasattr(self, "prefix"): + self.prefix = "http://" + if not hasattr(self, "host"): + self.host = None + if not hasattr(self, "port"): + self.port = None + if not hasattr(self, "api_key"): + self.api_key = None + if not hasattr(self, "verify"): + self.verify = True + + self.radarr = Radarr( + self.method, self.prefix, self.host, self.port, self.api_key, self.verify + ) + + def process(self): + if self.api_key == None: + return "api_key missing" + if self.host == None: + return "host missing" + + self.radarr.refresh() + value_template = render_template_string( + self.value_template, **self.radarr.__dict__ + ) + return value_template diff --git a/dashmachine/platform/sonarr.py b/dashmachine/platform/sonarr.py new file mode 100644 index 0000000..b7a8ed0 --- /dev/null +++ b/dashmachine/platform/sonarr.py @@ -0,0 +1,303 @@ +from flask import render_template_string +import requests + + +class Sonarr(object): + def __init__(self, method, prefix, host, port, api_key, verify): + self.endpoint = "/api" + self.method = method + self.prefix = prefix + self.host = host + self.port = port + self.api_key = api_key + self.verify = verify + + # Initialize results + self.error = None + self.version = "?" + self.wanted_missing = 0 + self.queue = 0 + self.diskspace = [ + {"path": "", "total": "", "free": "", "used": ""}, + {"path": "", "total": "", "free": "", "used": ""}, + ] + + def check(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/system/status", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + if "error" in rawdata: + self.error = rawdata["error"] + + def getVersion(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/system/status", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.version = rawdata["version"] + + def getWanted(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/wanted/missing/", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.wanted_missing = rawdata["totalRecords"] + + def getQueue(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/queue", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.queue = len(rawdata) + + def getDiskspace(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + self.host + port + self.endpoint + "/diskspace", + headers=headers, + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.diskspace = rawdata + for item in self.diskspace: + item["used"] = self.formatSize(item["totalSpace"] - item["freeSpace"]) + item["total"] = self.formatSize(item["totalSpace"]) + item["free"] = self.formatSize(item["freeSpace"]) + item.pop("totalSpace", None) + item.pop("freeSpace", None) + + def formatSize(self, size): + # 2**10 = 1024 + power = 2 ** 10 + n = 0 + power_labels = {0: "", 1: "KB", 2: "MB", 3: "GB", 4: "TB"} + while size > power: + size /= power + n += 1 + return str(round(size, 1)) + " " + power_labels[n] + + def refresh(self): + self.check() + if self.error == None: + self.error = "" + self.getVersion() + self.getWanted() + self.getQueue() + self.getDiskspace() + + +class Platform: + def docs(self): + documentation = { + "name": "sonarr", + "author": "Thlb", + "author_url": "https://github.com/Thlb", + "version": 1.0, + "description": "Display information from Sonarr API", + "returns": "`value_template` as rendered string", + "returns_json_keys": [ + "version", + "wanted_missing", + "queue", + "diskspace[x]['path']", + "diskspace[x]['total']", + "diskspace[x]['used']", + "diskspace[x]['free']", + "error (for debug)", + ], + "example": """ +```ini +[sonarr-data] +platform = sonarr +prefix = http:// +host = 192.168.0.110 +port = 8989 +api_key = {{ API Key }} +verify = False +value_template = {{error}}Missing : {{wanted_missing}}
Queue : {{queue}}
Free ({{diskspace[0]['path']}}) : {{diskspace[0]['free']}} + +[Sonarr] +prefix = http:// +url = 192.168.0.110:8989 +icon = static/images/apps/sonarr.png +sidebar_icon = static/images/apps/sonarr.png +description = Smart PVR for newsgroup and bittorrent users +open_in = this_tab +data_sources = sonarr-data +``` + """, + "variables": [ + { + "variable": "[variable_name]", + "description": "Name for the data source.", + "default": "None, entry is required", + "options": ".ini header", + }, + { + "variable": "platform", + "description": "Name of the platform.", + "default": "sonarr", + "options": "sonarr", + }, + { + "variable": "prefix", + "description": "The prefix for the app's url.", + "default": "", + "options": "web prefix, e.g. http:// or https://", + }, + { + "variable": "host", + "description": "Sonarr Host", + "default": "", + "options": "url,ip", + }, + { + "variable": "port", + "description": "Sonarr Port", + "default": "", + "options": "port", + }, + { + "variable": "api_key", + "description": "ApiKey", + "default": "", + "options": "api key", + }, + { + "variable": "verify", + "description": "Turn TLS verification on or off, default is true", + "default": "", + "options": "true,false", + }, + { + "variable": "value_template", + "description": "Jinja template for how the returned data from API is displayed.", + "default": "", + "options": "jinja template", + }, + ], + } + return documentation + + def __init__(self, *args, **kwargs): + # parse the user's options from the config entries + for key, value in kwargs.items(): + self.__dict__[key] = value + + # set defaults for omitted options + if not hasattr(self, "method"): + self.method = "GET" + if not hasattr(self, "prefix"): + self.prefix = "http://" + if not hasattr(self, "host"): + self.host = None + if not hasattr(self, "port"): + self.port = None + if not hasattr(self, "api_key"): + self.api_key = None + if not hasattr(self, "verify"): + self.verify = True + + self.sonarr = Sonarr( + self.method, self.prefix, self.host, self.port, self.api_key, self.verify + ) + + def process(self): + if self.api_key == None: + return "api_key missing" + if self.host == None: + return "host missing" + + self.sonarr.refresh() + value_template = render_template_string( + self.value_template, **self.sonarr.__dict__ + ) + return value_template diff --git a/dashmachine/platform/tautulli.py b/dashmachine/platform/tautulli.py new file mode 100644 index 0000000..7df565d --- /dev/null +++ b/dashmachine/platform/tautulli.py @@ -0,0 +1,260 @@ +from flask import render_template_string +import requests + + +class Tautulli(object): + def __init__(self, method, prefix, host, port, api_key, verify): + self.endpoint = "/api/v2" + self.method = method + self.prefix = prefix + self.host = host + self.port = port + self.api_key = api_key + self.verify = verify + + # Initialize results + self.error = None + self.update_available = "" + self.update_message = "" + self.stream_count = "" + + def check(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + headers = {"X-Api-Key": self.api_key} + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + + self.host + + port + + self.endpoint + + "?apikey=" + + self.api_key + + "&cmd=" + + "update_check", + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + if "response" in rawdata and rawdata["response"]["result"] == "error": + self.error = rawdata["response"]["message"] + + def getUpdate(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + + self.host + + port + + self.endpoint + + "?apikey=" + + self.api_key + + "&cmd=" + + "update_check", + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.update_message = rawdata["response"]["message"] + self.update_available = rawdata["response"]["data"]["update"] + + def getActivity(self): + verify = ( + False + if str(self.verify).lower() == "false" + or str(self.prefix).lower() == "http://" + else True + ) + port = "" if self.port == None else ":" + self.port + + if self.method.upper() == "GET": + try: + rawdata = requests.get( + self.prefix + + self.host + + port + + self.endpoint + + "?apikey=" + + self.api_key + + "&cmd=" + + "get_activity", + verify=verify, + timeout=10, + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + self.stream_count = rawdata["response"]["data"]["stream_count"] + self.stream_count_direct_play = rawdata["response"]["data"][ + "stream_count_direct_play" + ] + self.stream_count_direct_stream = rawdata["response"]["data"][ + "stream_count_direct_stream" + ] + self.stream_count_transcode = rawdata["response"]["data"][ + "stream_count_transcode" + ] + self.total_bandwidth = rawdata["response"]["data"]["total_bandwidth"] + self.wan_bandwidth = rawdata["response"]["data"]["wan_bandwidth"] + + def refresh(self): + self.check() + if self.error == None: + self.error = "" + self.getUpdate() + self.getActivity() + + +class Platform: + def docs(self): + documentation = { + "name": "tautulli", + "author": "Thlb", + "author_url": "https://github.com/Thlb", + "version": 1.0, + "description": "Display information from Tautulli API", + "returns": "`value_template` as rendered string", + "returns_json_keys": [ + "stream_count", + "stream_count_direct_play", + "stream_count_direct_stream", + "stream_count_transcode", + "total_bandwidth", + "wan_bandwidth", + "update_available", + "update_message", + "error (for debug)", + ], + "example": """ +```ini +[tautulli-data] +platform = tautulli +prefix = http:// +host = 192.168.0.110 +port = 8181 +api_key = myApiKey +verify = False +value_template = {{error}}Active sessions : {{stream_count}} + +[Tautulli] +prefix = http:// +url = 192.168.0.110:8181 +icon = static/images/apps/tautulli.png +sidebar_icon = static/images/apps/tautulli.png +description = A Python based monitoring and tracking tool for Plex Media Server +open_in = this_tab +data_sources = tautulli-data +``` + """, + "variables": [ + { + "variable": "[variable_name]", + "description": "Name for the data source.", + "default": "None, entry is required", + "options": ".ini header", + }, + { + "variable": "platform", + "description": "Name of the platform.", + "default": "tautulli", + "options": "tautulli", + }, + { + "variable": "prefix", + "description": "The prefix for the app's url.", + "default": "", + "options": "web prefix, e.g. http:// or https://", + }, + { + "variable": "host", + "description": "Tautulli Host", + "default": "", + "options": "url,ip", + }, + { + "variable": "port", + "description": "Tautulli Port", + "default": "", + "options": "port", + }, + { + "variable": "api_key", + "description": "ApiKey", + "default": "", + "options": "api key", + }, + { + "variable": "verify", + "description": "Turn TLS verification on or off, default is true", + "default": "", + "options": "true,false", + }, + { + "variable": "value_template", + "description": "Jinja template for how the returned data from API is displayed.", + "default": "", + "options": "jinja template", + }, + ], + } + return documentation + + def __init__(self, *args, **kwargs): + # parse the user's options from the config entries + for key, value in kwargs.items(): + self.__dict__[key] = value + + # set defaults for omitted options + if not hasattr(self, "method"): + self.method = "GET" + if not hasattr(self, "prefix"): + self.prefix = "http://" + if not hasattr(self, "host"): + self.host = None + if not hasattr(self, "port"): + self.port = None + if not hasattr(self, "api_key"): + self.api_key = None + if not hasattr(self, "verify"): + self.verify = True + + self.tautulli = Tautulli( + self.method, self.prefix, self.host, self.port, self.api_key, self.verify + ) + + def process(self): + if self.api_key == None: + return "api_key missing" + if self.host == None: + return "host missing" + + self.tautulli.refresh() + value_template = render_template_string( + self.value_template, **self.tautulli.__dict__ + ) + return value_template