diff --git a/Legacy/configuration.example.py b/Legacy/configuration.example.py deleted file mode 100644 index a0df50a..0000000 --- a/Legacy/configuration.example.py +++ /dev/null @@ -1,49 +0,0 @@ -''' -Notes: - - Domains should be either http(s)://subdomain.domain.com or http(s)://domain.com/url_suffix - - - Sonarr + Radarr scripts support multiple servers. You can remove the second - server by putting a # in front of the line. - - - tautulli_failback_ip, This is used when there is no IP listed in tautulli. - This can happen when you are streaming locally. This is usually your public IP. -''' - -########################### INFLUXDB CONFIG ########################### -influxdb_url = 'influxdb.domain.tld' -influxdb_port = 8086 -influxdb_username = '' -influxdb_password = '' - -############################ SONARR CONFIG ############################ -sonarr_server_list = [ - ('https://sonarr1.domain.tld', 'xxxxxxxxxxxxxxx', '1'), - ('https://sonarr2.domain.tld', 'xxxxxxxxxxxxxxx', '2'), - #('https://sonarr3.domain.tld', 'xxxxxxxxxxxxxxx', '3') - ] -sonarr_influxdb_db_name = 'plex' - -############################ RADARR CONFIG ############################ -radarr_server_list = [ - ('https://radarr1.domain.tld', 'xxxxxxxxxxxxxxx', '1'), - ('https://radarr2.domain.tld', 'xxxxxxxxxxxxxxx', '2'), - #('https://radarr3.domain.tld', 'xxxxxxxxxxxxxxx', '3') - ] -radarr_influxdb_db_name = 'plex' - -############################ OMBI CONFIG ############################## -ombi_url = 'https://ombi.domain.tld' -ombi_api_key = 'xxxxxxxxxxxxxxx' -ombi_influxdb_db_name = 'plex' - -########################## TAUTULLI CONFIG ############################ -tautulli_url = 'https://tautulli.domain.tld' -tautulli_api_key = 'xxxxxxxxxxxxxxx' -tautulli_failback_ip = '' -tautulli_influxdb_db_name = 'plex' - -########################## FIREWALL CONFIG ############################ -asa_url = 'https://firewall.domain.tld' -asa_username = 'cisco' -asa_password = 'cisco' -asa_influxdb_db_name = 'asa' diff --git a/Legacy/configuration.py b/Legacy/configuration.py deleted file mode 100644 index a0df50a..0000000 --- a/Legacy/configuration.py +++ /dev/null @@ -1,49 +0,0 @@ -''' -Notes: - - Domains should be either http(s)://subdomain.domain.com or http(s)://domain.com/url_suffix - - - Sonarr + Radarr scripts support multiple servers. You can remove the second - server by putting a # in front of the line. - - - tautulli_failback_ip, This is used when there is no IP listed in tautulli. - This can happen when you are streaming locally. This is usually your public IP. -''' - -########################### INFLUXDB CONFIG ########################### -influxdb_url = 'influxdb.domain.tld' -influxdb_port = 8086 -influxdb_username = '' -influxdb_password = '' - -############################ SONARR CONFIG ############################ -sonarr_server_list = [ - ('https://sonarr1.domain.tld', 'xxxxxxxxxxxxxxx', '1'), - ('https://sonarr2.domain.tld', 'xxxxxxxxxxxxxxx', '2'), - #('https://sonarr3.domain.tld', 'xxxxxxxxxxxxxxx', '3') - ] -sonarr_influxdb_db_name = 'plex' - -############################ RADARR CONFIG ############################ -radarr_server_list = [ - ('https://radarr1.domain.tld', 'xxxxxxxxxxxxxxx', '1'), - ('https://radarr2.domain.tld', 'xxxxxxxxxxxxxxx', '2'), - #('https://radarr3.domain.tld', 'xxxxxxxxxxxxxxx', '3') - ] -radarr_influxdb_db_name = 'plex' - -############################ OMBI CONFIG ############################## -ombi_url = 'https://ombi.domain.tld' -ombi_api_key = 'xxxxxxxxxxxxxxx' -ombi_influxdb_db_name = 'plex' - -########################## TAUTULLI CONFIG ############################ -tautulli_url = 'https://tautulli.domain.tld' -tautulli_api_key = 'xxxxxxxxxxxxxxx' -tautulli_failback_ip = '' -tautulli_influxdb_db_name = 'plex' - -########################## FIREWALL CONFIG ############################ -asa_url = 'https://firewall.domain.tld' -asa_username = 'cisco' -asa_password = 'cisco' -asa_influxdb_db_name = 'asa' diff --git a/Legacy/crontabs b/Legacy/crontabs deleted file mode 100644 index 413be4e..0000000 --- a/Legacy/crontabs +++ /dev/null @@ -1,11 +0,0 @@ -### Modify paths as appropriate. python3 is located in different places for different users. (`which python3` will give you the path) -### to edit your crontab entry, do not modify /var/spool/cron/crontabs/ directly, use `crontab -e` -### Crontabs require an empty line at the end or they WILL not run. Make sure to have 2 lines to be safe -### -* * * * * /usr/bin/python3 /path-to-grafana-scripts/ombi.py -* * * * * ( sleep 30 ; /usr/bin/python3 /path-to-grafana-scripts/ombi.py ) -* * * * * /usr/bin/python3 /path-to-grafana-scripts/taurulli.py -* * * * * ( sleep 30 ; /usr/bin/python3 /path-to-grafana-scripts/tautulli.py ) -*/30 * * * * /usr/bin/python3 /path-to-grafana-scripts/radarr.py -*/30 * * * * /usr/bin/python3 /path-to-grafana-scripts/sonarr.py -#*/30 * * * * /usr/bin/python3 /path-to-grafana-scripts/sickrage.py diff --git a/Legacy/ombi.py b/Legacy/ombi.py deleted file mode 100644 index bcea45f..0000000 --- a/Legacy/ombi.py +++ /dev/null @@ -1,87 +0,0 @@ -# Do not edit this script. Edit configuration.py -import sys -import requests -from datetime import datetime, timezone -from influxdb import InfluxDBClient -import argparse -from argparse import RawTextHelpFormatter -from Legacy import configuration - -headers = {'Apikey': configuration.ombi_api_key} - -def now_iso(): - now_iso = datetime.now(timezone.utc).astimezone().isoformat() - return now_iso - -def influx_sender(influx_payload): - influx = InfluxDBClient(configuration.influxdb_url, configuration.influxdb_port, configuration.influxdb_username, - configuration.influxdb_password, configuration.ombi_influxdb_db_name) - influx.write_points(influx_payload) - -def get_total_requests(): - get_tv_requests = requests.get('{}/api/v1/Request/tv'.format(configuration.ombi_url), headers=headers).json() - get_movie_requests = requests.get('{}/api/v1/Request/movie'.format(configuration.ombi_url), headers=headers).json() - - count_movie_requests = 0 - count_tv_requests = 0 - - for show in get_tv_requests: - count_tv_requests += 1 - - for movie in get_movie_requests: - count_movie_requests += 1 - - influx_payload = [ - { - "measurement": "Ombi", - "tags": { - "type": "Request_Total" - }, - "time": now_iso(), - "fields": { - "total": count_movie_requests + count_tv_requests - } - } - ] - return influx_payload - -def get_request_counts(): - get_request_counts = requests.get('{}/api/v1/Request/count'.format(configuration.ombi_url), headers=headers).json() - - influx_payload = [ - { - "measurement": "Ombi", - "tags": { - "type": "Request_Counts" - }, - "time": now_iso(), - "fields": { - "pending": int(get_request_counts['pending']), - "approved": int(get_request_counts['approved']), - "available": int(get_request_counts['available']) - } - } - ] - return influx_payload - -if __name__ == "__main__": - parser = argparse.ArgumentParser(prog='Ombi stats operations', - description='Script to aid in data gathering from Ombi', formatter_class=RawTextHelpFormatter) - - parser.add_argument("--total", action='store_true', - help='Get the total count of all requests') - - parser.add_argument("--counts", action='store_true', - help='Get the count of pending, approved, and available requests') - - opts = parser.parse_args() - - if opts.total: - influx_sender(get_total_requests()) - - elif opts.counts: - influx_sender(get_request_counts()) - - elif len(sys.argv) == 1: - parser.print_help(sys.stderr) - sys.exit(1) diff --git a/Varken/helpers.py b/Varken/helpers.py index c3d8d2e..e464b89 100644 --- a/Varken/helpers.py +++ b/Varken/helpers.py @@ -93,7 +93,7 @@ class SonarrServer(NamedTuple): future_days: int = 0 future_days_run_seconds: int = 30 queue: bool = False - queue_run_seconds: int = 1 + queue_run_seconds: int = 30 class RadarrServer(NamedTuple): id: int = None @@ -101,15 +101,20 @@ class RadarrServer(NamedTuple): api_key: str = None verify_ssl: bool = False queue: bool = False - queue_run_seconds: int = 1 + queue_run_seconds: int = 30 get_missing: bool = False get_missing_run_seconds: int = 30 -class Server(NamedTuple): + +class OmbiServer(NamedTuple): id: int = None url: str = None api_key: str = None verify_ssl: bool = False + request_type_counts: bool = False + request_type_run_seconds: int = 30 + request_total_counts: bool = False + request_total_run_seconds: int = 30 class TautulliServer(NamedTuple): @@ -131,6 +136,12 @@ class InfluxServer(NamedTuple): password: str = 'root' +class OmbiRequestCounts(NamedTuple): + pending: int = 0 + approved: int = 0 + available: int = 0 + + class TautulliStream(NamedTuple): rating: str = None transcode_width: str = None diff --git a/Varken/iniparser.py b/Varken/iniparser.py index 89d56fc..9a21e11 100644 --- a/Varken/iniparser.py +++ b/Varken/iniparser.py @@ -1,7 +1,7 @@ import sys import configparser from os.path import abspath, join -from Varken.helpers import Server, TautulliServer, SonarrServer, InfluxServer, RadarrServer +from Varken.helpers import OmbiServer, TautulliServer, SonarrServer, InfluxServer, RadarrServer class INIParser(object): @@ -17,7 +17,7 @@ class INIParser(object): self.radarr_servers = [] self.ombi_enabled = False - self.ombi_server = None + self.ombi_servers = [] self.tautulli_enabled = False self.tautulli_servers = [] @@ -45,7 +45,7 @@ class INIParser(object): # Parse Sonarr options try: if not self.config.getboolean('global', 'sonarr_server_ids'): - sys.exit('sonarr_server_ids must be either false, or a comma-separated list of server ids') + sys.exit('server_ids must be either false, or a comma-separated list of server ids') elif self.config.getint('global', 'sonarr_server_ids'): self.sonarr_enabled = True except ValueError: @@ -75,7 +75,7 @@ class INIParser(object): # Parse Radarr options try: if not self.config.getboolean('global', 'radarr_server_ids'): - sys.exit('radarr_server_ids must be either false, or a comma-separated list of server ids') + sys.exit('server_ids must be either false, or a comma-separated list of server ids') elif self.config.getint('global', 'radarr_server_ids'): self.radarr_enabled = True except ValueError: @@ -102,7 +102,7 @@ class INIParser(object): # Parse Tautulli options try: if not self.config.getboolean('global', 'tautulli_server_ids'): - sys.exit('tautulli_server_ids must be either false, or a comma-separated list of server ids') + sys.exit('server_ids must be either false, or a comma-separated list of server ids') elif self.config.getint('global', 'tautulli_server_ids'): self.tautulli_enabled = True except ValueError: @@ -128,14 +128,30 @@ class INIParser(object): self.tautulli_servers.append(server) # Parse Ombi Options - if self.config.getboolean('global', 'ombi'): + try: + if not self.config.getboolean('global', 'ombi_server_ids'): + sys.exit('server_ids must be either false, or a comma-separated list of server ids') + elif self.config.getint('global', 'ombi_server_ids'): + self.ombi_enabled = True + except ValueError: self.ombi_enabled = True - url = self.config.get('ombi', 'url') - apikey = self.config.get('ombi', 'apikey') - scheme = 'https://' if self.config.getboolean('ombi', 'ssl') else 'http://' - verify_ssl = self.config.getboolean('ombi', 'verify_ssl') - self.ombi_server = Server(url=scheme + url, api_key=apikey, verify_ssl=verify_ssl) + if self.ombi_enabled: + sids = self.config.get('global', 'ombi_server_ids').strip(' ').split(',') + for server_id in sids: + ombi_section = 'ombi-' + server_id + url = self.config.get(ombi_section, 'url') + apikey = self.config.get(ombi_section, 'apikey') + scheme = 'https://' if self.config.getboolean(ombi_section, 'ssl') else 'http://' + verify_ssl = self.config.getboolean(ombi_section, 'verify_ssl') + request_type_counts = self.config.getboolean(ombi_section, 'get_request_type_counts') + request_type_run_seconds = self.config.getint(ombi_section, 'request_type_run_seconds') + request_total_counts = self.config.getboolean(ombi_section, 'get_request_total_counts') + request_total_run_seconds = self.config.getint(ombi_section, 'request_total_run_seconds') + + server = OmbiServer(server_id, scheme + url, apikey, verify_ssl, request_type_counts, + request_type_run_seconds, request_total_counts, request_total_run_seconds) + self.ombi_servers.append(server) # Parse ASA opts if self.config.getboolean('global', 'asa'): diff --git a/Varken/ombi.py b/Varken/ombi.py new file mode 100644 index 0000000..47c620c --- /dev/null +++ b/Varken/ombi.py @@ -0,0 +1,70 @@ +from requests import Session +from datetime import datetime, timezone +from influxdb import InfluxDBClient + +from Varken.helpers import OmbiRequestCounts +from Varken.logger import logging + +class OmbiAPI(object): + def __init__(self, server, influx_server): + self.now = datetime.now(timezone.utc).astimezone().isoformat() + self.influx = InfluxDBClient(influx_server.url, influx_server.port, influx_server.username, + influx_server.password, 'plex2') + self.server = server + # Create session to reduce server web thread load, and globally define pageSize for all requests + self.session = Session() + self.session.headers = {'Apikey': self.server.api_key} + + def influx_push(self, payload): + self.influx.write_points(payload) + + @logging + def get_total_requests(self): + self.now = datetime.now(timezone.utc).astimezone().isoformat() + tv_endpoint = '/api/v1/Request/tv' + movie_endpoint = "/api/v1/Request/movie" + get_tv = self.session.get(self.server.url + tv_endpoint, verify=self.server.verify_ssl).json() + get_movie = self.session.get(self.server.url + movie_endpoint, verify=self.server.verify_ssl).json() + + movie_requests = len(get_movie) + tv_requests = len(get_tv) + + influx_payload = [ + { + "measurement": "Ombi", + "tags": { + "type": "Request_Total" + }, + "time": self.now, + "fields": { + "total": movie_requests + tv_requests, + "movies": movie_requests, + "tv_shows": tv_requests + } + } + ] + + self.influx_push(influx_payload) + + @logging + def get_request_counts(self): + self.now = datetime.now(timezone.utc).astimezone().isoformat() + endpoint = '/api/v1/Request/count' + get = self.session.get(self.server.url + endpoint, verify=self.server.verify_ssl).json() + requests = OmbiRequestCounts(**get) + influx_payload = [ + { + "measurement": "Ombi", + "tags": { + "type": "Request_Counts" + }, + "time": self.now, + "fields": { + "pending": requests.pending, + "approved": requests.approved, + "available": requests.available + } + } + ] + + self.influx_push(influx_payload) diff --git a/Varken/radarr.py b/Varken/radarr.py index c31e2e0..d385ed7 100644 --- a/Varken/radarr.py +++ b/Varken/radarr.py @@ -1,4 +1,4 @@ -import requests +from requests import Session from datetime import datetime, timezone from influxdb import InfluxDBClient @@ -13,10 +13,9 @@ class RadarrAPI(object): influx_server.password, 'plex2') self.server = server # Create session to reduce server web thread load, and globally define pageSize for all requests - self.session = requests.Session() + self.session = Session() def influx_push(self, payload): - # TODO: error handling for failed connection self.influx.write_points(payload) @logging diff --git a/Varken/sonarr.py b/Varken/sonarr.py index 7fb7a04..8967564 100644 --- a/Varken/sonarr.py +++ b/Varken/sonarr.py @@ -1,4 +1,4 @@ -import requests +from requests import Session from influxdb import InfluxDBClient from datetime import datetime, timezone, date, timedelta @@ -15,7 +15,7 @@ class SonarrAPI(object): influx_server.password, 'plex') self.server = server # Create session to reduce server web thread load, and globally define pageSize for all requests - self.session = requests.Session() + self.session = Session() self.session.params = {'pageSize': 1000} @logging @@ -60,7 +60,6 @@ class SonarrAPI(object): self.influx_push(influx_payload) - @logging def get_future(self): endpoint = '/api/calendar/' @@ -146,5 +145,4 @@ class SonarrAPI(object): self.influx_push(influx_payload) def influx_push(self, payload): - # TODO: error handling for failed connection self.influx.write_points(payload) diff --git a/Varken/tautulli.py b/Varken/tautulli.py index a2789d0..03aaa6d 100644 --- a/Varken/tautulli.py +++ b/Varken/tautulli.py @@ -1,7 +1,7 @@ from datetime import datetime, timezone from geoip2.errors import AddressNotFoundError from influxdb import InfluxDBClient -import requests +from requests import Session from Varken.helpers import TautulliStream, geo_lookup from Varken.logger import logging @@ -13,11 +13,10 @@ class TautulliAPI(object): self.influx = InfluxDBClient(influx_server.url, influx_server.port, influx_server.username, influx_server.password, 'plex2') self.server = server - self.session = requests.Session() + self.session = Session() self.endpoint = '/api/v2' def influx_push(self, payload): - # TODO: error handling for failed connection self.influx.write_points(payload) @logging @@ -68,7 +67,7 @@ class TautulliAPI(object): if self.server.fallback_ip: geodata = geo_lookup(self.server.fallback_ip) else: - my_ip = requests.get('http://ip.42.pl/raw').text + my_ip = self.session.get('http://ip.42.pl/raw').text geodata = geo_lookup(my_ip) if not all([geodata.location.latitude, geodata.location.longitude]): diff --git a/data/varken.example.ini b/data/varken.example.ini index 4d28054..c51272b 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -9,7 +9,7 @@ sonarr_server_ids = 1,2 radarr_server_ids = 1,2 tautulli_server_ids = 1 -ombi = true +ombi_server_ids = 1 asa = false [influxdb] @@ -68,13 +68,20 @@ url = radarr2.domain.tld apikey = yyyyyyyyyyyyyyyy ssl = false verify_ssl = true +queue = true +queue_run_seconds = 300 +get_missing = true +get_missing_run_seconds = 300 -[ombi] +[ombi-1] url = ombi.domain.tld apikey = xxxxxxxxxxxxxxxx ssl = false verify_ssl = true - +get_request_type_counts = true +request_type_run_seconds = 300 +get_request_total_counts = true +request_total_run_seconds = 300 [asa] url = firewall.domain.tld diff --git a/varken.py b/varken.py index 921b8fb..dbe72b7 100644 --- a/varken.py +++ b/varken.py @@ -6,7 +6,7 @@ from Varken.iniparser import INIParser from Varken.sonarr import SonarrAPI from Varken.tautulli import TautulliAPI from Varken.radarr import RadarrAPI - +from Varken.ombi import OmbiAPI def threaded(job): thread = threading.Thread(target=job) @@ -42,6 +42,14 @@ if __name__ == "__main__": if server.queue: schedule.every(server.queue_run_seconds).seconds.do(threaded, RADARR.get_queue) + if CONFIG.ombi_enabled: + for server in CONFIG.ombi_servers: + OMBI = OmbiAPI(server, CONFIG.influx_server) + if server.request_type_counts: + schedule.every(server.request_type_run_seconds).seconds.do(threaded, OMBI.get_request_counts) + if server.request_total_counts: + schedule.every(server.request_total_run_seconds).seconds.do(threaded, OMBI.get_total_requests) + while True: schedule.run_pending() sleep(1)