Skip to content

Instantly share code, notes, and snippets.

@blacktwin
Last active November 9, 2016 20:54
Show Gist options
  • Save blacktwin/2cba1511a93e8f506d13e1ad37e91f08 to your computer and use it in GitHub Desktop.
Save blacktwin/2cba1511a93e8f506d13e1ad37e91f08 to your computer and use it in GitHub Desktop.
Pull all user IP data from PlexPy and using get_geoip_lookup grab the city name. Use the city name to map location on map.
import requests
import sys
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from geopy.geocoders import Nominatim
import math
## EDIT THESE SETTINGS ##
PLEXPY_APIKEY = 'XXXXXXXXX' # Your PlexPy API key
PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
# Replace LAN IP addresses that start with the LAN_SUBNET with a WAN IP address
# to retrieve geolocation data. Leave REPLACEMENT_WAN_IP blank for no replacement.
LAN_SUBNET = ('127.0.0')
REPLACEMENT_WAN_IP = ''
# Find your user_id number and play at least one file from the server.
# This will be use to mark the server location.
SERVER_USER_ID = 'XXXX'
## Map stuff ##
geolocator = Nominatim()
scale = 2
map = Basemap(llcrnrlon=-119, llcrnrlat=22, urcrnrlon=-64, urcrnrlat=49, projection='lcc', lat_1=32, lat_2=45, lon_0=-95)
# load the shapefile, use the name 'states'
map.readshapefile('st99_d00', name='states', drawbounds=True)
title_string = "Location of Plex users based on ISP data"
class GeoData(object):
def __init__(self, data=None):
data = data or {}
self.continent = data.get('continent', 'N/A')
self.country = data.get('country', 'N/A')
self.region = data.get('region', 'N/A')
self.city = data.get('city', 'N/A')
self.postal_code = data.get('postal_code', 'N/A')
self.timezone = data.get('timezone', 'N/A')
self.latitude = data.get('latitude', 'N/A')
self.longitude = data.get('longitude', 'N/A')
self.accuracy = data.get('accuracy', 'N/A')
class UserTB(object):
def __init__(self, data=None):
data = data or []
self.user_id = [d['user_id'] for d in data]
class UserIPs(object):
def __init__(self, data=None):
data = data or []
self.ip_address = [d['ip_address'] for d in data]
self.friendly_name = [d['friendly_name'] for d in data]
self.player = [d['player'] for d in data]
def get_get_users_tables():
# Get the user IP list from PlexPy
payload = {'apikey': PLEXPY_APIKEY,
'cmd': 'get_users_table'}
try:
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
return UserTB(data=res_data)
except Exception as e:
sys.stderr.write("PlexPy API 'get_get_users_tables' request failed: {0}.".format(e))
def get_get_users_ips(user_id=''):
# Get the user IP list from PlexPy
payload = {'apikey': PLEXPY_APIKEY,
'cmd': 'get_user_ips',
'user_id': user_id,
'length': 25} #length is number of returns, default is 25
try:
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
recordsTotal = response['response']['data']['recordsTotal']
res_data = response['response']['data']['data']
return UserIPs(data=res_data)
except Exception as e:
sys.stderr.write("PlexPy API 'get_get_users_ips' request failed: {0}.".format(e))
def get_geoip_info(ip_address=''):
# Get the geo IP lookup from PlexPy
payload = {'apikey': PLEXPY_APIKEY,
'cmd': 'get_geoip_lookup',
'ip_address': ip_address}
try:
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
data = response['response']['data']
if data.get('error'):
raise Exception(data['error'])
else:
sys.stdout.write("Successfully retrieved geolocation data.")
return GeoData(data=data)
else:
raise Exception(response['response']['message'])
except Exception as e:
sys.stderr.write("PlexPy API 'get_geoip_lookup' request failed: {0}.".format(e))
return GeoData()
if __name__ == '__main__':
geo_lst = []
ut = get_get_users_tables()
for i in ut.user_id:
ip = get_get_users_ips(user_id=i)
fn = [x.encode('UTF8') for x in ip.friendly_name]
fn = list(set(fn))
ulst = [str(i)]
for x in ip.ip_address:
if x.startswith(LAN_SUBNET) and REPLACEMENT_WAN_IP:
x = REPLACEMENT_WAN_IP
g = get_geoip_info(ip_address=x)
glst = [str(g.city)]
geo_lst += [glst + ulst + [str(x)] + fn]
for (city, id, ip, fn) in geo_lst:
if id == SERVER_USER_ID and ip == REPLACEMENT_WAN_IP:
color = 'gold'
marker = '*'
markersize = 10
else:
color = 'darkred'
marker = 'd'
markersize = 5
loc = geolocator.geocode(city)
x, y = map(loc.longitude, loc.latitude)
map.plot(x, y, marker=marker, color=color, markersize=markersize)
#map.bluemarble()
plt.title(title_string)
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment