diff --git a/dashmachine/platform/lidarr.py b/dashmachine/platform/lidarr.py new file mode 100644 index 00000000..857f1f2f --- /dev/null +++ b/dashmachine/platform/lidarr.py @@ -0,0 +1,274 @@ +""" + +##### Lidarr +Display information from Lidarr API +```ini +[variable_name] +platform = lidarr +prefix = http:// +host = localhost +port = 8686 +api_key = my_api_key +verify = true +value_template = {{ value_template }} +``` +> **Returns:** `value_template` as rendered string + +| Variable | Required | Description | Options | +|-----------------|----------|-----------------------------------------------------------------|-------------------| +| [variable_name] | Yes | Name for the data source. | [variable_name] | +| platform | Yes | Name of the platform. | lidarr | +| prefix | No | The prefix for the app's url. | web prefix, e.g. http:// or https:// | +| host | Yes | Lidarr Host | url,ip | +| port | No | Lidarr Port | port | +| api_key | Yes | ApiKey | api key | +| api_version | No | API version (default : v1) | v1 | +| verify | No | Turn TLS verification on or off, default is true | true,false | +| value_template | Yes | Jinja template for how the returned data from API is displayed. | jinja template | + +
+###### **Available fields for value_template** + +* version +* wanted_missing +* wanted_cutoff +* queue +* diskspace[x]['path'] +* diskspace[x]['total'] +* diskspace[x]['used'] +* diskspace[x]['free'] +* error (for debug) + +> **Working example:** +>```ini +> [lidarr-data] +> platform = lidarr +> prefix = http:// +> host = 192.168.0.110 +> port = 8686 +> api_key = {{ API Key }} +> verify = False +> value_template = {{error}}Missing : {{wanted_missing}}
Queue : {{queue}}
Free ({{diskspace[0]['path']}}) : {{diskspace[0]['free']}} +> +> [Lidarr] +> prefix = http:// +> url = 192.168.0.110:8686 +> icon = static/images/apps/lidarr.png +> sidebar_icon = static/images/apps/lidarr.png +> description = Looks and smells like Sonarr but made for music +> open_in = this_tab +> data_sources = lidarr-data +>``` +""" + +import json +from flask import render_template_string +import requests + +class Lidarr(object): + + def __init__(self,method, prefix, host, port, api_key, api_version, verify): + self.api_version = api_version + self.endpoint = "/api/" + self.api_version + 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.wanted_cutoff = 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, wType): + 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/" + + wType + "/" + , headers=headers + , verify=verify + , timeout=10 + ).json() + except Exception as e: + rawdata = None + self.error = f"{e}" + + if rawdata != None: + if wType == "missing": + self.wanted_missing = rawdata['totalRecords'] + else: + self.wanted_cutoff = 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 = rawdata['totalRecords'] + + 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("missing") + self.getWanted("cutoff") + self.getQueue() + self.getDiskspace() + + +class Platform: + 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, "api_version"): + self.api_version = "v1" + if not hasattr(self, "verify"): + self.verify = True + + self.lidarr = Lidarr(self.method, self.prefix, self.host, self.port, self.api_key, self.api_version, self.verify) + + def process(self): + if self.api_key == None: + return "api_key missing" + if self.host == None: + return "host missing" + + self.lidarr.refresh() + value_template = render_template_string( + self.value_template, **self.lidarr.__dict__ + ) + return value_template