ported ombi

This commit is contained in:
Nicholas St. Germain 2018-12-01 22:26:44 -06:00
parent c3c0381fe1
commit 818f4bea7c
12 changed files with 137 additions and 225 deletions

View file

@ -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'

View file

@ -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'

View file

@ -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/<user> 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

View file

@ -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)

View file

@ -93,7 +93,7 @@ class SonarrServer(NamedTuple):
future_days: int = 0 future_days: int = 0
future_days_run_seconds: int = 30 future_days_run_seconds: int = 30
queue: bool = False queue: bool = False
queue_run_seconds: int = 1 queue_run_seconds: int = 30
class RadarrServer(NamedTuple): class RadarrServer(NamedTuple):
id: int = None id: int = None
@ -101,15 +101,20 @@ class RadarrServer(NamedTuple):
api_key: str = None api_key: str = None
verify_ssl: bool = False verify_ssl: bool = False
queue: bool = False queue: bool = False
queue_run_seconds: int = 1 queue_run_seconds: int = 30
get_missing: bool = False get_missing: bool = False
get_missing_run_seconds: int = 30 get_missing_run_seconds: int = 30
class Server(NamedTuple):
class OmbiServer(NamedTuple):
id: int = None id: int = None
url: str = None url: str = None
api_key: str = None api_key: str = None
verify_ssl: bool = False 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): class TautulliServer(NamedTuple):
@ -131,6 +136,12 @@ class InfluxServer(NamedTuple):
password: str = 'root' password: str = 'root'
class OmbiRequestCounts(NamedTuple):
pending: int = 0
approved: int = 0
available: int = 0
class TautulliStream(NamedTuple): class TautulliStream(NamedTuple):
rating: str = None rating: str = None
transcode_width: str = None transcode_width: str = None

View file

@ -1,7 +1,7 @@
import sys import sys
import configparser import configparser
from os.path import abspath, join 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): class INIParser(object):
@ -17,7 +17,7 @@ class INIParser(object):
self.radarr_servers = [] self.radarr_servers = []
self.ombi_enabled = False self.ombi_enabled = False
self.ombi_server = None self.ombi_servers = []
self.tautulli_enabled = False self.tautulli_enabled = False
self.tautulli_servers = [] self.tautulli_servers = []
@ -45,7 +45,7 @@ class INIParser(object):
# Parse Sonarr options # Parse Sonarr options
try: try:
if not self.config.getboolean('global', 'sonarr_server_ids'): 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'): elif self.config.getint('global', 'sonarr_server_ids'):
self.sonarr_enabled = True self.sonarr_enabled = True
except ValueError: except ValueError:
@ -75,7 +75,7 @@ class INIParser(object):
# Parse Radarr options # Parse Radarr options
try: try:
if not self.config.getboolean('global', 'radarr_server_ids'): 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'): elif self.config.getint('global', 'radarr_server_ids'):
self.radarr_enabled = True self.radarr_enabled = True
except ValueError: except ValueError:
@ -102,7 +102,7 @@ class INIParser(object):
# Parse Tautulli options # Parse Tautulli options
try: try:
if not self.config.getboolean('global', 'tautulli_server_ids'): 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'): elif self.config.getint('global', 'tautulli_server_ids'):
self.tautulli_enabled = True self.tautulli_enabled = True
except ValueError: except ValueError:
@ -128,14 +128,30 @@ class INIParser(object):
self.tautulli_servers.append(server) self.tautulli_servers.append(server)
# Parse Ombi Options # 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 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 # Parse ASA opts
if self.config.getboolean('global', 'asa'): if self.config.getboolean('global', 'asa'):

70
Varken/ombi.py Normal file
View file

@ -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)

View file

@ -1,4 +1,4 @@
import requests from requests import Session
from datetime import datetime, timezone from datetime import datetime, timezone
from influxdb import InfluxDBClient from influxdb import InfluxDBClient
@ -13,10 +13,9 @@ class RadarrAPI(object):
influx_server.password, 'plex2') influx_server.password, 'plex2')
self.server = server self.server = server
# Create session to reduce server web thread load, and globally define pageSize for all requests # 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): def influx_push(self, payload):
# TODO: error handling for failed connection
self.influx.write_points(payload) self.influx.write_points(payload)
@logging @logging

View file

@ -1,4 +1,4 @@
import requests from requests import Session
from influxdb import InfluxDBClient from influxdb import InfluxDBClient
from datetime import datetime, timezone, date, timedelta from datetime import datetime, timezone, date, timedelta
@ -15,7 +15,7 @@ class SonarrAPI(object):
influx_server.password, 'plex') influx_server.password, 'plex')
self.server = server self.server = server
# Create session to reduce server web thread load, and globally define pageSize for all requests # 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} self.session.params = {'pageSize': 1000}
@logging @logging
@ -60,7 +60,6 @@ class SonarrAPI(object):
self.influx_push(influx_payload) self.influx_push(influx_payload)
@logging @logging
def get_future(self): def get_future(self):
endpoint = '/api/calendar/' endpoint = '/api/calendar/'
@ -146,5 +145,4 @@ class SonarrAPI(object):
self.influx_push(influx_payload) self.influx_push(influx_payload)
def influx_push(self, payload): def influx_push(self, payload):
# TODO: error handling for failed connection
self.influx.write_points(payload) self.influx.write_points(payload)

View file

@ -1,7 +1,7 @@
from datetime import datetime, timezone from datetime import datetime, timezone
from geoip2.errors import AddressNotFoundError from geoip2.errors import AddressNotFoundError
from influxdb import InfluxDBClient from influxdb import InfluxDBClient
import requests from requests import Session
from Varken.helpers import TautulliStream, geo_lookup from Varken.helpers import TautulliStream, geo_lookup
from Varken.logger import logging from Varken.logger import logging
@ -13,11 +13,10 @@ class TautulliAPI(object):
self.influx = InfluxDBClient(influx_server.url, influx_server.port, influx_server.username, self.influx = InfluxDBClient(influx_server.url, influx_server.port, influx_server.username,
influx_server.password, 'plex2') influx_server.password, 'plex2')
self.server = server self.server = server
self.session = requests.Session() self.session = Session()
self.endpoint = '/api/v2' self.endpoint = '/api/v2'
def influx_push(self, payload): def influx_push(self, payload):
# TODO: error handling for failed connection
self.influx.write_points(payload) self.influx.write_points(payload)
@logging @logging
@ -68,7 +67,7 @@ class TautulliAPI(object):
if self.server.fallback_ip: if self.server.fallback_ip:
geodata = geo_lookup(self.server.fallback_ip) geodata = geo_lookup(self.server.fallback_ip)
else: 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) geodata = geo_lookup(my_ip)
if not all([geodata.location.latitude, geodata.location.longitude]): if not all([geodata.location.latitude, geodata.location.longitude]):

View file

@ -9,7 +9,7 @@
sonarr_server_ids = 1,2 sonarr_server_ids = 1,2
radarr_server_ids = 1,2 radarr_server_ids = 1,2
tautulli_server_ids = 1 tautulli_server_ids = 1
ombi = true ombi_server_ids = 1
asa = false asa = false
[influxdb] [influxdb]
@ -68,13 +68,20 @@ url = radarr2.domain.tld
apikey = yyyyyyyyyyyyyyyy apikey = yyyyyyyyyyyyyyyy
ssl = false ssl = false
verify_ssl = true verify_ssl = true
queue = true
queue_run_seconds = 300
get_missing = true
get_missing_run_seconds = 300
[ombi] [ombi-1]
url = ombi.domain.tld url = ombi.domain.tld
apikey = xxxxxxxxxxxxxxxx apikey = xxxxxxxxxxxxxxxx
ssl = false ssl = false
verify_ssl = true verify_ssl = true
get_request_type_counts = true
request_type_run_seconds = 300
get_request_total_counts = true
request_total_run_seconds = 300
[asa] [asa]
url = firewall.domain.tld url = firewall.domain.tld

View file

@ -6,7 +6,7 @@ from Varken.iniparser import INIParser
from Varken.sonarr import SonarrAPI from Varken.sonarr import SonarrAPI
from Varken.tautulli import TautulliAPI from Varken.tautulli import TautulliAPI
from Varken.radarr import RadarrAPI from Varken.radarr import RadarrAPI
from Varken.ombi import OmbiAPI
def threaded(job): def threaded(job):
thread = threading.Thread(target=job) thread = threading.Thread(target=job)
@ -42,6 +42,14 @@ if __name__ == "__main__":
if server.queue: if server.queue:
schedule.every(server.queue_run_seconds).seconds.do(threaded, RADARR.get_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: while True:
schedule.run_pending() schedule.run_pending()
sleep(1) sleep(1)