Varken/Legacy/tautulli.py

179 lines
5.9 KiB
Python

import os
import tarfile
import urllib.request
import time
from datetime import datetime, timezone
import geoip2.database
from influxdb import InfluxDBClient
import requests
from Varken import configuration
CURRENT_TIME = datetime.now(timezone.utc).astimezone().isoformat()
PAYLOAD = {'apikey': configuration.tautulli_api_key, 'cmd': 'get_activity'}
ACTIVITY = requests.get('{}/api/v2'.format(configuration.tautulli_url),
params=PAYLOAD).json()['response']['data']
SESSIONS = {d['session_id']: d for d in ACTIVITY['sessions']}
TAR_DBFILE = '{}/GeoLite2-City.tar.gz'.format(os.path.dirname(os.path.realpath(__file__)))
DBFILE = '{}/GeoLite2-City.mmdb'.format(os.path.dirname(os.path.realpath(__file__)))
NOW = time.time()
DB_AGE = NOW - (86400 * 35)
#remove the running db file if it is older than 35 days
try:
t = os.stat(DBFILE)
c = t.st_ctime
if c < DB_AGE:
os.remove(DBFILE)
except FileNotFoundError:
pass
def geo_lookup(ipaddress):
"""Lookup an IP using the local GeoLite2 DB"""
if not os.path.isfile(DBFILE):
urllib.request.urlretrieve(
'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz',
TAR_DBFILE)
tar = tarfile.open(TAR_DBFILE, "r:gz")
for files in tar.getmembers():
if 'GeoLite2-City.mmdb' in files.name:
files.name = os.path.basename(files.name)
tar.extract(files, '{}/'.format(os.path.dirname(os.path.realpath(__file__))))
reader = geoip2.database.Reader(DBFILE)
return reader.city(ipaddress)
INFLUX_PAYLOAD = [
{
"measurement": "Tautulli",
"tags": {
"type": "stream_count"
},
"time": CURRENT_TIME,
"fields": {
"current_streams": int(ACTIVITY['stream_count']),
"transcode_streams": int(ACTIVITY['stream_count_transcode']),
"direct_play_streams": int(ACTIVITY['stream_count_direct_play']),
"direct_streams": int(ACTIVITY['stream_count_direct_stream'])
}
}
]
for session in SESSIONS.keys():
try:
geodata = geo_lookup(SESSIONS[session]['ip_address_public'])
except (ValueError, geoip2.errors.AddressNotFoundError):
if configuration.tautulli_failback_ip:
geodata = geo_lookup(configuration.tautulli_failback_ip)
else:
geodata = geo_lookup(requests.get('http://ip.42.pl/raw').text)
latitude = geodata.location.latitude
if not geodata.location.latitude:
latitude = 37.234332396
else:
latitude = geodata.location.latitude
if not geodata.location.longitude:
longitude = -115.80666344
else:
longitude = geodata.location.longitude
decision = SESSIONS[session]['transcode_decision']
if decision == 'copy':
decision = 'direct stream'
video_decision = SESSIONS[session]['stream_video_decision']
if video_decision == 'copy':
video_decision = 'direct stream'
elif video_decision == '':
video_decision = 'Music'
quality = SESSIONS[session]['stream_video_resolution']
# If the video resolution is empty. Asssume it's an audio stream
# and use the container for music
if not quality:
quality = SESSIONS[session]['container'].upper()
elif quality in ('SD', 'sd'):
quality = SESSIONS[session]['stream_video_resolution'].upper()
elif quality in '4k':
quality = SESSIONS[session]['stream_video_resolution'].upper()
else:
quality = '{}p'.format(SESSIONS[session]['stream_video_resolution'])
# Translate player_state to integers so we can colorize the table
player_state = SESSIONS[session]['state'].lower()
if player_state == 'playing':
player_state = 0
elif player_state == 'paused':
player_state = 1
elif player_state == 'buffering':
player_state = 3
INFLUX_PAYLOAD.append(
{
"measurement": "Tautulli",
"tags": {
"type": "Session",
"session_id": SESSIONS[session]['session_id'],
"name": SESSIONS[session]['friendly_name'],
"title": SESSIONS[session]['full_title'],
"platform": SESSIONS[session]['platform'],
"product_version": SESSIONS[session]['product_version'],
"quality": quality,
"video_decision": video_decision.title(),
"transcode_decision": decision.title(),
"media_type": SESSIONS[session]['media_type'].title(),
"audio_codec": SESSIONS[session]['audio_codec'].upper(),
"audio_profile": SESSIONS[session]['audio_profile'].upper(),
"stream_audio_codec": SESSIONS[session]['stream_audio_codec'].upper(),
"quality_profile": SESSIONS[session]['quality_profile'],
"progress_percent": SESSIONS[session]['progress_percent'],
"region_code": geodata.subdivisions.most_specific.iso_code,
"location": geodata.city.name,
"full_location": '{} - {}'.format(geodata.subdivisions.most_specific.name,
geodata.city.name),
"latitude": latitude,
"longitude": longitude,
"player_state": player_state,
"device_type": SESSIONS[session]['platform']
},
"time": CURRENT_TIME,
"fields": {
"session_id": SESSIONS[session]['session_id'],
"session_key": SESSIONS[session]['session_key']
}
}
)
INFLUX_SENDER = InfluxDBClient(configuration.influxdb_url,
configuration.influxdb_port,
configuration.influxdb_username,
configuration.influxdb_password,
configuration.tautulli_influxdb_db_name)
INFLUX_SENDER.write_points(INFLUX_PAYLOAD)