diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..920d523
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 2162161..f3954ec 100644
--- a/README.md
+++ b/README.md
@@ -3,10 +3,10 @@
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4J6RPWZ9J9YML) [](https://www.reddit.com/user/Blacktwin/) [](https://forums.plex.tv/profile/discussions/Blacktwin) [](https://github.com/blacktwin/JBOPS/issues/new)
-Most of these scripts utilize a combination of [PlexPy](https://github.com/JonnyWong16/plexpy), [python-plexapi](https://github.com/pkkid/python-plexapi), and [requests](http://docs.python-requests.org/en/master/user/install/#install).
+Most of these scripts utilize a combination of [Tautulli](https://github.com/Tautulli/Tautulli), [python-plexapi](https://github.com/pkkid/python-plexapi), and [requests](http://docs.python-requests.org/en/master/user/install/#install).
## Notice:
-These scripts have not been tested using Tautulli. The improvements in Tautulli may cause errors with scripts that pull data from Tautulli, especailly metadata. If you come into a problem please create an issue and reference the script that errors out with Tautulli. Once Tautulli is out of Beta I'll look into which scripts need updated and which can be removed.
+Updating for Tautulli
## Scripts List
[](https://gist.github.com/blacktwin)
@@ -28,7 +28,7 @@ Scripts pulled from my gist profile.
- Receive session_key from PlexPy when paused. Use sub-script wait_kill_pause_notify_sub
- to wait for X time then check if still paused. If so, kill. Toggle whether you'd like to be notified through a PlexPy notification agent.
+ Receive session_key from Tautulli when paused. Use sub-script wait_kill_pause_notify_sub
+ to wait for X time then check if still paused. If so, kill. Toggle whether you'd like to be notified through a Tautulli notification agent.
@@ -97,7 +97,7 @@ Scripts pulled from my gist profile.
Receive session_key and IP from PlexPy when playback starts. Use IP to check against whitelist. If not in whitelist use session_key to determine stream and kill.
+
Receive session_key and IP from Tautulli when playback starts. Use IP to check against whitelist. If not in whitelist use session_key to determine stream and kill.
@@ -107,7 +107,7 @@ Scripts pulled from my gist profile.
Send an email with what was added to Plex in the past week using PlexPy. Email includes title (TV: Show Name: Episode Name; Movie: Movie Title), time added, image, and summary.
+
Send an email with what was added to Plex in the past week using Tautulli. Email includes title (TV: Show Name: Episode Name; Movie: Movie Title), time added, image, and summary.
@@ -223,7 +223,7 @@ Scripts pulled from my gist profile.
Use PlexPy to count how many plays per user occurred this week and send email via PlexPy.
+
Use Tautulli to count how many plays per user occurred this week and send email via Tautulli.
@@ -334,26 +334,43 @@ Scripts pulled from my gist profile.
----
-Setting Up PlexPy for Custom Scripts
+Setting Up Tautulli for Custom Scripts
-#### Enabling Scripts in PlexPy:
+#### Enabling Scripts in Tautulli:
-Settings > Notification Agents > Click the Scripts gear
+Taultulli > Settings > Notification Agents > Add a Notification Agent > Script
-- [ ] Set scripts location to location of your scripts
+#### Configuration
+
+Taultulli > Settings > Notification Agents > New Script > Configuration:
+- [ ] Set scripts location to location of your script
- [ ] Scroll down to option you want to use and select the script from the drop down menu
+- [ ] Set desired Script Timeout value
+- [ ] Optional - Add a description of the script for easy reference
- [ ] Save
-Settings > Notification Agents > Click the Bell next to Scripts
+#### Triggers
+Taultulli > Settings > Notification Agents > New Script > Triggers:
- [ ] Check desired trigger
-- [ ] Close
-
-Settings > Notifications > Click Script
-
-- [ ] Enter in the Script Arguments
- [ ] Save
+#### Conditions
+Taultulli > Settings > Notification Agents > New Script > Conditions:
+
+- [ ] Set desired conditions
+- [ ] Save
+
+For more information on Tautulli conditions see [here](https://github.com/Tautulli/Tautulli-Wiki/wiki/Custom-Notification-Conditions)
+
+#### Script Arguments
+Taultulli > Settings > Notification Agents > New Script > Script Arguments:
+
+- [ ] Select desired trigger
+- [ ] Input desired notification parameters (List of parameters will likely be found inside script)
+- [ ] Save
+- [ ] Close
+
@@ -364,21 +381,15 @@ Settings > Notifications > Click Script
Plex
-- [ ] PLEX_HOST - Local IP to connect to Plex ('localhost', '192.168.0.x', '127.0.0.1', etc.)
-- [ ] PLEX_PORT - Port number used by Plex (default: 32400)
-- [ ] PLEX_SSL - http:// or https://? '' if http and 's' if https
-- [ ] PLEX_TOKEN - [Plex](https://support.plex.tv/hc/en-us/articles/204059436-Finding-an-authentication-token-X-Plex-Token) or PlexPy Settings > Plex.tv Account > PMS Token
+- [ ] PLEX_URL - Local/Remote IP to connect to Plex ('http://localhost:32400', 'https://x.x.x.x:32412', etc.)
+- [ ] PLEX_TOKEN - [Plex](https://support.plex.tv/hc/en-us/articles/204059436-Finding-an-authentication-token-X-Plex-Token) or Tautulli Settings > Plex.tv Account > PMS Token
-PlexPy
+Tautulli
-- [ ] PLEXPY_URL - Local IP to connect to PlexPy ('localhost', '192.168.0.x', '127.0.0.1', etc.)
-- [ ] PLEXPY_APIKEY - PlexPy Settings > Access Control > Enable API - API Key
+- [ ] TAUTULLI_URL - Local/Remote IP to connect to Tautulli ('http://localhost:8181', 'https://x.x.x.x:8182', etc.)
+- [ ] TAUTULLI_APIKEY - Tautulli Settings > Access Control > Enable API - API Key
-
-
-
-
diff --git a/archive/create_wait_kill_all.py b/archive/create_wait_kill_all.py
deleted file mode 100644
index c1a5a46..0000000
--- a/archive/create_wait_kill_all.py
+++ /dev/null
@@ -1,187 +0,0 @@
-'''
-fetch function from https://gist.github.com/Hellowlol/ee47b6534410b1880e19
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
- [X] Notify on pause
-
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
- Playback Pause: create_wait_kill_all.py
-
-PlexPy > Settings > Notifications > Script > Script Arguments:
- {session_key}
-
-
-create_wait_kill_all.py creates a new file with the session_id (sub_script) as it's name.
-PlexPy will timeout create_wait_kill_all.py after 30 seconds (default) but sub_script.py will continue.
-sub_script will check if the stream's session_id is still pause or if playing as restarted.
-If playback is restarted then sub_script will stop and delete itself.
-If stream remains paused then it will be killed and sub_script will stop and delete itself.
-
-Set TIMEOUT to max time before killing stream
-Set INTERVAL to how often you want to check the stream status
-'''
-
-import os
-import platform
-import subprocess
-import sys
-from uuid import getnode
-import unicodedata
-
-import requests
-
-## EDIT THESE SETTINGS ##
-
-PLEX_HOST = ''
-PLEX_PORT = 32400
-PLEX_SSL = '' # s or ''
-PLEX_TOKEN = ''
-PLEXPY_APIKEY = 'xxxxxxx' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
-
-TIMEOUT = 120
-INTERVAL = 20
-
-REASON = 'Because....'
-ignore_lst = ('test')
-
-
-class Activity(object):
- def __init__(self, data=None):
- d = data or {}
- self.video_decision = d['video_decision']
- self.state = d['state']
- self.session_key = d['session_key']
-
-
-def get_get_activity():
- # Get the user IP list from PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
- 'cmd': 'get_activity'}
-
- try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
- response = r.json()
- res_data = response['response']['data']['sessions']
- return [Activity(data=d) for d in res_data]
-
- except Exception as e:
- sys.stderr.write("PlexPy API 'get_get_activity' request failed: {0}.".format(e))
-
-
-def fetch(path, t='GET'):
- url = 'http{}://{}:{}/'.format(PLEX_SSL, PLEX_HOST, PLEX_PORT)
-
- headers = {'X-Plex-Token': PLEX_TOKEN,
- 'Accept': 'application/json',
- 'X-Plex-Provides': 'controller',
- 'X-Plex-Platform': platform.uname()[0],
- 'X-Plex-Platform-Version': platform.uname()[2],
- 'X-Plex-Product': 'Plexpy script',
- 'X-Plex-Version': '0.9.5',
- 'X-Plex-Device': platform.platform(),
- 'X-Plex-Client-Identifier': str(hex(getnode()))
- }
-
- try:
- if t == 'GET':
- r = requests.get(url + path, headers=headers, verify=False)
- elif t == 'POST':
- r = requests.post(url + path, headers=headers, verify=False)
- elif t == 'DELETE':
- r = requests.delete(url + path, headers=headers, verify=False)
-
- if r and len(r.content): # incase it dont return anything
- return r.json()
- else:
- return r.content
-
- except Exception as e:
- print e
-
-
-def kill_stream(sessionId, message, xtime, ntime, user, title, sessionKey):
- headers = {'X-Plex-Token': PLEX_TOKEN}
- params = {'sessionId': sessionId,
- 'reason': message}
-
- activity = get_get_activity()
-
- for a in activity:
- if a.session_key == sessionKey:
- if a.state == 'paused' and xtime == ntime:
- sys.stdout.write("Killing {user}'s paused stream of {title}".format(user=user, title=title))
- requests.get('http{}://{}:{}/status/sessions/terminate'.format(PLEX_SSL, PLEX_HOST, PLEX_PORT),
- headers=headers, params=params)
- return ntime
- elif a.state in ('playing', 'buffering'):
- sys.stdout.write("{user}'s stream of {title} is now {state}".format(user=user, title=title,
- state=a.state))
- return None
- else:
- return xtime
-
-
-def find_sessionID(response):
-
- sessions = []
- for video in response['MediaContainer']['Video']:
- if video['sessionKey'] == sys.argv[1]:
- sess_id = video['Session']['id']
- user = video['User']['title']
- sess_key = video['sessionKey']
- title = (video['grandparentTitle'] + ' - ' if video['type'] == 'episode' else '') + video['title']
- title = unicodedata.normalize('NFKD', title).encode('ascii','ignore')
- sessions.append((sess_id, user, title, sess_key))
- else:
- pass
-
- for session in sessions:
- if session[1] not in ignore_lst:
- return session
- else:
- print("{}'s stream of {} is ignored.".format(session[1], session[2]))
- return None
-
-
-if __name__ == '__main__':
-
- startupinfo = None
- if os.name == 'nt':
- startupinfo = subprocess.STARTUPINFO()
- startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
-
- response = fetch('status/sessions')
- fileDir = fileDir = os.path.dirname(os.path.realpath(__file__))
-
- try:
- if find_sessionID(response):
- stream_info = find_sessionID(response)
- file_name = "{}.py".format(stream_info[0])
- full_path = os.path.join(fileDir, file_name)
- file = 'from time import sleep\n' \
- 'import sys, os\n' \
- 'from {script} import kill_stream \n' \
- 'message = "{REASON}"\n' \
- 'sessionID = os.path.basename(sys.argv[0])[:-3]\n' \
- 'x = 0\n' \
- 'n = {ntime}\n' \
- 'try:\n' \
- ' while x < n and x is not None:\n' \
- ' sleep({xtime})\n' \
- ' x += kill_stream(sessionID, message, {xtime}, n, "{user}", "{title}", "{sess_key}")\n' \
- ' kill_stream(sessionID, message, {ntime}, n, "{user}", "{title}", "{sess_key}")\n' \
- ' os.remove(sys.argv[0])\n' \
- 'except TypeError as e:\n' \
- ' os.remove(sys.argv[0])'.format(script=os.path.basename(__file__)[:-3],
- ntime=TIMEOUT, xtime=INTERVAL, REASON=REASON,
- user=stream_info[1], title=stream_info[2], sess_key=stream_info[3])
-
- with open(full_path, "w+") as output:
- output.write(file)
-
- subprocess.Popen([sys.executable, full_path], startupinfo=startupinfo)
- exit(0)
-
- except TypeError as e:
- print(e)
- pass
diff --git a/archive/create_wait_kill_trans.py b/archive/create_wait_kill_trans.py
deleted file mode 100644
index 75ac9a0..0000000
--- a/archive/create_wait_kill_trans.py
+++ /dev/null
@@ -1,172 +0,0 @@
-'''
-fetch function from https://gist.github.com/Hellowlol/ee47b6534410b1880e19
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
- [X] Notify on pause
-
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
- Playback Pause: create_wait_kill_trans.py
-
-PlexPy > Settings > Notifications > Script > Script Arguments:
- {session_key}
-
-
-create_wait_kill_trans.py creates a new file with the session_id (sub_script) as it's name.
-PlexPy will timeout create_wait_kill_trans.py after 30 seconds (default) but sub_script.py will continue.
-sub_script will check if the transcoding and stream's session_id is still pause or if playing as restarted.
-If playback is restarted then sub_script will stop and delete itself.
-If stream remains paused then it will be killed and sub_script will stop and delete itself.
-
-Set TIMEOUT to max time before killing stream
-Set INTERVAL to how often you want to check the stream status
-'''
-
-import os
-import platform
-import subprocess
-import sys
-from uuid import getnode
-import unicodedata
-
-import requests
-
-## EDIT THESE SETTINGS ##
-
-PLEX_HOST = ''
-PLEX_PORT = 32400
-PLEX_SSL = '' # s or ''
-PLEX_TOKEN = 'xxxxx'
-
-TIMEOUT = 30
-INTERVAL = 10
-
-REASON = 'Because....'
-ignore_lst = ('test')
-
-
-def fetch(path, t='GET'):
- url = 'http{}://{}:{}/'.format(PLEX_SSL, PLEX_HOST, PLEX_PORT)
-
- headers = {'X-Plex-Token': PLEX_TOKEN,
- 'Accept': 'application/json',
- 'X-Plex-Provides': 'controller',
- 'X-Plex-Platform': platform.uname()[0],
- 'X-Plex-Platform-Version': platform.uname()[2],
- 'X-Plex-Product': 'Plexpy script',
- 'X-Plex-Version': '0.9.5',
- 'X-Plex-Device': platform.platform(),
- 'X-Plex-Client-Identifier': str(hex(getnode()))
- }
-
- try:
- if t == 'GET':
- r = requests.get(url + path, headers=headers, verify=False)
- elif t == 'POST':
- r = requests.post(url + path, headers=headers, verify=False)
- elif t == 'DELETE':
- r = requests.delete(url + path, headers=headers, verify=False)
-
- if r and len(r.content): # incase it dont return anything
- return r.json()
- else:
- return r.content
-
- except Exception as e:
- print e
-
-
-def kill_stream(sessionId, message, xtime, ntime, user, title, sessionKey):
- headers = {'X-Plex-Token': PLEX_TOKEN}
- params = {'sessionId': sessionId,
- 'reason': message}
-
- response = fetch('status/sessions')
-
- if response['MediaContainer']['Video']:
- for video in response['MediaContainer']['Video']:
- part = video['Media'][0]['Part'][0]
- if video['sessionKey'] == sessionKey:
- if xtime == ntime and video['Player']['state'] == 'paused' and part['decision'] == 'transcode':
- sys.stdout.write("Killing {user}'s paused stream of {title}".format(user=user, title=title))
- requests.get('http{}://{}:{}/status/sessions/terminate'.format(PLEX_SSL, PLEX_HOST, PLEX_PORT),
- headers=headers, params=params)
- return ntime
- elif video['Player']['state'] in ('playing', 'buffering'):
- sys.stdout.write("{user}'s stream of {title} is now {state}".
- format(user=user, title=title, state=video['Player']['state']))
- return None
- else:
- return xtime
- else:
- return None
-
-
-def find_sessionID(response):
-
- sessions = []
- for video in response['MediaContainer']['Video']:
- part = video['Media'][0]['Part'][0]
- if video['sessionKey'] == sys.argv[1] and video['Player']['state'] == 'paused' \
- and part['decision'] == 'transcode':
- sess_id = video['Session']['id']
- user = video['User']['title']
- sess_key = video['sessionKey']
- title = (video['grandparentTitle'] + ' - ' if video['type'] == 'episode' else '') + video['title']
- title = unicodedata.normalize('NFKD', title).encode('ascii', 'ignore').translate(None,"'")
- sessions.append((sess_id, user, title, sess_key))
-
- else:
- pass
-
- print(sessions)
- for session in sessions:
- if session[1] not in ignore_lst:
- return session
- else:
- print("{}'s stream of {} is ignored.".format(session[1], session[2]))
- return None
-
-
-if __name__ == '__main__':
-
- startupinfo = None
- if os.name == 'nt':
- startupinfo = subprocess.STARTUPINFO()
- startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
-
- response = fetch('status/sessions')
-
- fileDir = os.path.dirname(os.path.realpath(__file__))
-
- try:
- if find_sessionID(response):
- stream_info = find_sessionID(response)
- file_name = "{}.py".format(stream_info[0])
- full_path = os.path.join(fileDir, file_name)
- file = "from time import sleep\n" \
- "import sys, os\n" \
- "from {script} import kill_stream \n" \
- "message = '{REASON}'\n" \
- "sessionID = os.path.basename(sys.argv[0])[:-3]\n" \
- "x = 0\n" \
- "n = {ntime}\n" \
- "try:\n" \
- " while x < n and x is not None:\n" \
- " sleep({xtime})\n" \
- " x += kill_stream(sessionID, message, {xtime}, n, '{user}', '{title}', '{sess_key}')\n" \
- " kill_stream(sessionID, message, {ntime}, n, '{user}', '{title}', '{sess_key}')\n" \
- " os.remove(sys.argv[0])\n" \
- "except TypeError as e:\n" \
- " os.remove(sys.argv[0])".format(script=os.path.basename(__file__)[:-3],
- ntime=TIMEOUT, xtime=INTERVAL, REASON=REASON,
- user=stream_info[1], title=stream_info[2],
- sess_key=stream_info[3])
-
- with open(full_path, "w+") as output:
- output.write(file)
-
- subprocess.Popen([sys.executable, full_path], startupinfo=startupinfo)
- exit(0)
-
- except TypeError as e:
- print(e)
- pass
diff --git a/archive/notify_geomail.py b/archive/notify_geomail.py
deleted file mode 100644
index 758b112..0000000
--- a/archive/notify_geomail.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# 1. Install the requests module for python.
-# pip install requests
-# 2. Add script arguments in PlexPy. The following script arguments are available by default. More can be added below.
-# -ip {ip_address} -us {user} -med {media_type} -tt {title} -pf {platform} -pl {player} -da {datestamp} -ti {timestamp}
-
-import argparse
-import requests
-import sys
-
-
-## EDIT THESE SETTINGS ##
-
-PLEXPY_APIKEY = 'XXXXX' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
-AGENT_ID = 10 # The notification agent ID for PlexPy
-# 10 Email
-# 15 Scripts
-# 17 Browser
-
-# 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 = ('192.168')
-REPLACEMENT_WAN_IP = ''
-
-# The notification subject and body
-# - Use "{p.argument}" for script arguments
-# - Use "{g.value}" for geolocation data
-# - Use "{u.value}" for user data
-SUBJECT_TEXT = "PlexPy Notification"
-BODY_TEXT = """\
-
-
-
-
Hi!
- {p.user} has watched {p.media_type}:{p.title}
- On {p.platform}[{p.player}] in {g.city}, {g.country}.
- At {p.timestamp} on {p.datestamp}.
- IP address: {p.ip_address}
- User email is: {u.email}
- TEst area Data:{uip.data}
-
-
-
-"""
-
-## CODE BELOW ##
-
-##Geo Space##
-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')
-
-##USER Space##
-class UserEmail(object):
- def __init__(self, data=None):
- data = data or {}
- self.email = data.get('email', 'N/A')
- self.user_id = data.get('user_id', 'N/A')
- self.user_thumb = data.get('user_thumb', 'N/A')
-
-##API Space##
-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()
-
-
-def get_user_email(user_id=''):
- # Get the user email from PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
- 'cmd': 'get_user',
- 'user_id': user_id}
-
- 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 user email data.")
- return UserEmail(data=data)
- else:
- raise Exception(response['response']['message'])
- except Exception as e:
- sys.stderr.write("PlexPy API 'get_user' request failed: {0}.".format(e))
- return UserEmail()
-
-def send_notification(arguments=None, geodata=None, useremail=None, user_address=None):
- # Format notification text
- try:
- subject = SUBJECT_TEXT.format(p=arguments, g=geodata, u=useremail)
- body = BODY_TEXT.format(p=arguments, g=geodata, u=useremail)
- except LookupError as e:
- sys.stderr.write("Unable to substitute '{0}' in the notification subject or body".format(e))
- return None
- # Send the notification through PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
- 'cmd': 'notify',
- 'agent_id': AGENT_ID,
- 'subject': subject,
- 'body': body}
-
- try:
- r = requests.post(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
- response = r.json()
-
- if response['response']['result'] == 'success':
- sys.stdout.write("Successfully sent PlexPy notification.")
- else:
- raise Exception(response['response']['message'])
- except Exception as e:
- sys.stderr.write("PlexPy API 'notify' request failed: {0}.".format(e))
- return None
-
-if __name__ == '__main__':
- # Parse arguments from PlexPy
- parser = argparse.ArgumentParser()
-
- parser.add_argument('-ip', '--ip_address', action='store', default='',
- help='The IP address of the stream')
- parser.add_argument('-us', '--user', action='store', default='',
- help='Username of the person watching the stream')
- parser.add_argument('-uid', '--user_id', action='store', default='',
- help='User_ID of the person watching the stream')
- parser.add_argument('-med', '--media_type', action='store', default='',
- help='The media type of the stream')
- parser.add_argument('-tt', '--title', action='store', default='',
- help='The title of the media')
- parser.add_argument('-pf', '--platform', action='store', default='',
- help='The platform of the stream')
- parser.add_argument('-pl', '--player', action='store', default='',
- help='The player of the stream')
- parser.add_argument('-da', '--datestamp', action='store', default='',
- help='The date of the stream')
- parser.add_argument('-ti', '--timestamp', action='store', default='',
- help='The time of the stream')
- parser.add_argument('-sn', '--show_name', action='store', default='',
- help='The name of the TV show')
- parser.add_argument('-ena', '--episode_name', action='store', default='',
- help='The name of the episode')
- parser.add_argument('-ssn', '--season_num', action='store', default='',
- help='The season number of the TV show')
- parser.add_argument('-enu', '--episode_num', action='store', default='',
- help='The episode number of the TV show')
- parser.add_argument('-srv', '--plex_server', action='store', default='',
- help='The name of the Plex server')
- parser.add_argument('-pos', '--poster', action='store', default='',
- help='The poster url')
- parser.add_argument('-sum', '--summary', action='store', default='',
- help='The summary of the TV show')
- parser.add_argument('-lbn', '--library_name', action='store', default='',
- help='The name of the TV show')
-
- p = parser.parse_args()
-
- # Check to make sure there is an IP address before proceeding
- if p.ip_address:
- if p.ip_address.startswith(LAN_SUBNET) and REPLACEMENT_WAN_IP:
- ip_address = REPLACEMENT_WAN_IP
- else:
- ip_address = p.ip_address
-
- g = get_geoip_info(ip_address=ip_address)
- u = get_user_email(user_id=p.user_id)
- send_notification(arguments=p, geodata=g, useremail=u)
-
- else:
- sys.stdout.write("No IP address passed from PlexPy.")
diff --git a/killstream/ip_whitelist.py b/killstream/ip_whitelist.py
index 80e25fc..14a354b 100644
--- a/killstream/ip_whitelist.py
+++ b/killstream/ip_whitelist.py
@@ -1,15 +1,15 @@
# -*- coding: utf-8 -*-
'''
-Receive session_key and IP from PlexPy when playback starts.
+Receive session_key and IP from Tautulli when playback starts.
Use IP to check against whitelist.
If not in whitelist use session_key to determine stream and kill.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: ip_whitelist.py
-PlexPy > Settings > Notifications > Script > Script Arguments:
+Tautulli > Settings > Notifications > Script > Script Arguments:
{session_key} {ip_address}
'''
@@ -24,17 +24,17 @@ from plexapi.server import PlexServer
PLEX_TOKEN = 'xxxxxx'
PLEX_URL = 'http://localhost:32400'
-PLEXPY_APIKEY = 'xxxxxx' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8182/' # Your PlexPy URL
+TAUTULLI_APIKEY = 'xxxxxx' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8182/' # Your Tautulli URL
IP_WHITELIST = ['10.10.0.12'] # List IP addresses.
IGNORE_LST = ('') # List usernames that should be ignored.
REASON = 'IP Address: {} was not found in whitelist.'
-AGENT_ID = 14 # Notification agent ID for PlexPy
+NOTIFIER_ID = 14 # Notification agent ID for Tautulli
# Find Notification agent ID here:
-# https://github.com/JonnyWong16/plexpy/blob/master/API.md#notify
+# Tautulli Settings -> NOTIFICATION AGENTS -> :bell: Agent (NotifierID - {Description)
SUBJECT_TEXT = "IP Whitelist Violation"
BODY_TEXT = "Killed {user}'s stream of {title}. IP: {ip} not in whitelist"
@@ -56,23 +56,23 @@ def send_notification(subject_text, body_text):
except LookupError as e:
sys.stderr.write("Unable to substitute '{0}' in the notification subject or body".format(e))
return None
- # Send the notification through PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
+ # Send the notification through Tautulli
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'notify',
- 'agent_id': AGENT_ID,
+ 'notifier_id': NOTIFIER_ID,
'subject': subject,
'body': body}
try:
- r = requests.post(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.post(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
- sys.stdout.write("Successfully sent PlexPy notification.")
+ sys.stdout.write("Successfully sent Tautulli notification.")
else:
raise Exception(response['response']['message'])
except Exception as e:
- sys.stderr.write("PlexPy API 'notify' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'notify' request failed: {0}.".format(e))
return None
diff --git a/killstream/kill_all_more_than.py b/killstream/kill_all_more_than.py
index 437743b..2f6c5e6 100644
--- a/killstream/kill_all_more_than.py
+++ b/killstream/kill_all_more_than.py
@@ -2,16 +2,16 @@
If user has 2* or more concurrent streams kill all user's streams
-*PlexPy > Settings > Notification> User Concurrent Stream Threshold
- The number of concurrent streams by a single user for PlexPy to trigger a notification. Minimum 2.
+*Tautulli > Settings > Notification> User Concurrent Stream Threshold
+ The number of concurrent streams by a single user for Tautulli to trigger a notification. Minimum 2.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on user concurrent streams
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback User Concurrent Streams: kill_more_than.py
-PlexPy > Settings > Notifications > Script > Script Arguments
+Tautulli > Settings > Notifications > Script > Script Arguments
{user}
"""
diff --git a/killstream/kill_device.py b/killstream/kill_device.py
index 45f19c8..fdc7045 100644
--- a/killstream/kill_device.py
+++ b/killstream/kill_device.py
@@ -1,10 +1,10 @@
"""
Kill Plex streams based on device.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: kill_device.py
"""
@@ -18,7 +18,7 @@ PLEX_URL = 'http://localhost:32400'
DEFAULT_REASON = 'This stream has ended due to your device type.'
-# Find platforms that have history in PlexPy in Play count by platform and stream type Graph
+# Find platforms that have history in Tautulli in Play count by platform and stream type Graph
DEVICES = {'Android': 'Andriod message',
'Chrome': 'Chrome message',
'Plex Media Player': 'PMP message',
diff --git a/killstream/kill_else_if_buffering.py b/killstream/kill_else_if_buffering.py
index f1a0d33..db9198d 100644
--- a/killstream/kill_else_if_buffering.py
+++ b/killstream/kill_else_if_buffering.py
@@ -5,10 +5,10 @@ kill stream will list why it was killed ('Server Admin's stream take priority an
concurrent streams'). Message will also include an approximation of when the other concurrent stream
will finish, stream that is closest to finish will be used.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on buffer warning
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Buffer Warnings: kill_else_if_buffering.py
'''
diff --git a/killstream/kill_more_than.py b/killstream/kill_more_than.py
index d07456d..b59141d 100644
--- a/killstream/kill_more_than.py
+++ b/killstream/kill_more_than.py
@@ -1,15 +1,15 @@
"""
If user has 2* or more concurrent streams and the IP of the 2nd stream differs from 1st kill 2nd.
If 2nd stream IP is the same as 1st stream don't kill.
-*PlexPy > Settings > Notification> User Concurrent Stream Threshold
- The number of concurrent streams by a single user for PlexPy to trigger a notification. Minimum 2.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+*Tautulli > Settings > Notification> User Concurrent Stream Threshold
+ The number of concurrent streams by a single user for Tautulli to trigger a notification. Minimum 2.
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on user concurrent streams
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback User Concurrent Streams: kill_more_than.py
-PlexPy > Settings > Notifications > Script > Script Arguments
+Tautulli > Settings > Notifications > Script > Script Arguments
{username} {ip_address} {session_key}
"""
diff --git a/killstream/kill_outsider_stream.py b/killstream/kill_outsider_stream.py
index d13abc6..75b3fce 100644
--- a/killstream/kill_outsider_stream.py
+++ b/killstream/kill_outsider_stream.py
@@ -1,13 +1,13 @@
"""
Kill stream of user if they are accessing Plex from outside network
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: kill_outsider_stream.py
-PlexPy > Settings > Notifications > Script > Script Arguments
+Tautulli > Settings > Notifications > Script > Script Arguments
{username}
"""
diff --git a/killstream/kill_session_bitrate.py b/killstream/kill_session_bitrate.py
index 7e68345..2c63777 100644
--- a/killstream/kill_session_bitrate.py
+++ b/killstream/kill_session_bitrate.py
@@ -1,10 +1,10 @@
"""
Kill stream if bitrate is > BITRATE_LIMIT
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: kill_session_bitrate.py
"""
diff --git a/killstream/kill_time.py b/killstream/kill_time.py
index 04cf975..886e925 100644
--- a/killstream/kill_time.py
+++ b/killstream/kill_time.py
@@ -2,13 +2,13 @@
Limit number of plays of TV Show episodes during time of day.
Idea is to reduce continuous plays while sleeping.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: kill_time.py
-PlexPy > Settings > Notifications > Script > Script Arguments
+Tautulli > Settings > Notifications > Script > Script Arguments
{username} {media_type} {grandparent_rating_key}
"""
@@ -20,8 +20,8 @@ from time import time as ttime
from plexapi.server import PlexServer
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = 'xxxx' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8182/' # Your PlexPy URL
+TAUTULLI_APIKEY = 'xxxx' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8182/' # Your Tautulli URL
PLEX_TOKEN = 'xxxx'
PLEX_URL = 'http://localhost:32400'
@@ -51,16 +51,16 @@ sess.verify = False
plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
-def get_get_history(username):
- # Get the PlexPy history.
- payload = {'apikey': PLEXPY_APIKEY,
+def get_history(username):
+ # Get the Tautulli history.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_history',
'user': username,
'start_date': TODAY,
'order_column': 'date'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
@@ -70,7 +70,7 @@ def get_get_history(username):
return [ep_watched, stopped_time[0]]
except Exception as e:
- sys.stderr.write("PlexPy API 'get_history' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_history' request failed: {0}.".format(e))
def kill_session(user):
@@ -85,7 +85,7 @@ def kill_session(user):
if media_type is not 'episode':
exit()
-watched_count, last_stop = get_get_history(username)
+watched_count, last_stop = get_history(username)
if abs(last_stop - unix_time) > 20:
exit()
diff --git a/killstream/kill_trans_exp_audio.py b/killstream/kill_trans_exp_audio.py
index 4b2bce6..bb031aa 100644
--- a/killstream/kill_trans_exp_audio.py
+++ b/killstream/kill_trans_exp_audio.py
@@ -1,10 +1,10 @@
"""
Kill Plex video transcoding streams only. All audio streams are left alone.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: kill_trans_exp_audio.py
"""
@@ -19,7 +19,7 @@ PLEX_URL = 'http://localhost:32400'
DEFAULT_REASON = 'This stream has ended due to requiring video transcoding. ' \
'Please raise your Remote Quality to Original to play this content.'
-# Find platforms that have history in PlexPy in Play count by platform and stream type Graph
+# Find platforms that have history in Tautulli in Play count by platform and stream type Graph
DEVICES = {'Android': 'Andriod message',
'Chrome': 'Chrome message',
'Plex Media Player': 'PMP message',
diff --git a/killstream/kill_trans_library.py b/killstream/kill_trans_library.py
index 9f659a4..cac7cd6 100644
--- a/killstream/kill_trans_library.py
+++ b/killstream/kill_trans_library.py
@@ -1,13 +1,13 @@
"""
Kill Plex transcoding streams from specific libraries
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: kill_trans_library.py
-PlexPy > Settings > Notifications > Script > Script Arguments:
+Tautulli > Settings > Notifications > Script > Script Arguments:
{section_id} {session_key}
"""
@@ -24,7 +24,7 @@ TARGET_LIBRARIES = ['1', '2'] # Library IDs
DEFAULT_REASON = 'Stream terminated due to video transcoding of {} content. ' \
'Please set your device to use "Original" quality.'.format(', '.join(TARGET_LIBRARIES))
-# Find platforms that have history in PlexPy in Play count by platform and stream type Graph
+# Find platforms that have history in Tautulli in Play count by platform and stream type Graph
DEVICES = {'Android': 'Andriod message',
'Chrome': 'Chrome message',
'Plex Media Player': 'PMP message',
@@ -32,7 +32,7 @@ DEVICES = {'Android': 'Andriod message',
USER_IGNORE = ('') # ('Username','User2')
-PLEXPY_LOG = 'Killing {user}\'s stream of {title} due to video transcoding content from section {section}.'
+TAUTULLI_LOG = 'Killing {user}\'s stream of {title} due to video transcoding content from section {section}.'
##
sess = requests.Session()
@@ -57,5 +57,5 @@ if __name__ == '__main__':
trans_dec = session.transcodeSessions[0].videoDecision
if trans_dec == 'transcode':
reason = DEVICES.get(session.players[0].platform, DEFAULT_REASON)
- print(PLEXPY_LOG.format(user=username, title=title, section=section_id))
+ print(TAUTULLI_LOG.format(user=username, title=title, section=section_id))
session.stop(reason=reason)
diff --git a/killstream/kill_trans_pause.py b/killstream/kill_trans_pause.py
index 1959fad..4a7de6b 100644
--- a/killstream/kill_trans_pause.py
+++ b/killstream/kill_trans_pause.py
@@ -1,13 +1,13 @@
"""
Kill Plex paused video transcoding streams.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback pause
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Pause: kill_trans_pause.py
-PlexPy > Settings > Notifications > Script > Script Arguments:
+Tautulli > Settings > Notifications > Script > Script Arguments:
{session_key}
"""
diff --git a/killstream/kill_trans_pause_notify.py b/killstream/kill_trans_pause_notify.py
index 9e74476..825b008 100644
--- a/killstream/kill_trans_pause_notify.py
+++ b/killstream/kill_trans_pause_notify.py
@@ -2,10 +2,10 @@
Kill Plex paused video transcoding streams and receive notification.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback pause
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Pause: kill_trans_pause.py
"""
@@ -18,8 +18,8 @@ from plexapi.server import PlexServer
## EDIT THESE SETTINGS ##
PLEX_URL = 'http://localhost:32400'
PLEX_TOKEN = 'xxxxx'
-PLEXPY_APIKEY = 'xxxxx' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
+TAUTULLI_APIKEY = 'xxxxx' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8181/' # Your Tautulli URL
KILL_MESSAGE = 'This stream has ended due to being paused and transcoding.'
@@ -28,9 +28,9 @@ USER_IGNORE = ('') # ('Username','User2')
SUBJECT_TEXT = "Killed Paused Transcoded Stream."
BODY_TEXT = "Killed {user}'s paused transcoded stream of {title}."
-AGENT_ID = 14 # Notification agent ID for PlexPy
+NOTIFIER_ID = 14 # Notification agent ID for Tautulli
# Find Notification agent ID here:
-# https://github.com/JonnyWong16/plexpy/blob/master/API.md#notify
+# Tautulli Settings -> NOTIFICATION AGENTS -> :bell: Agent (NotifierID - {Description)
##/EDIT THESE SETTINGS ##
@@ -39,23 +39,23 @@ sess.verify = False
plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
def send_notification(subject_text, body_text):
- # Send the notification through PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
+ # Send the notification through Tautulli
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'notify',
- 'agent_id': AGENT_ID,
+ 'notifier_id': NOTIFIER_ID,
'subject': subject_text,
'body': body_text}
try:
- r = requests.post(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.post(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
- sys.stdout.write("Successfully sent PlexPy notification.")
+ sys.stdout.write("Successfully sent Tautulli notification.")
else:
raise Exception(response['response']['message'])
except Exception as e:
- sys.stderr.write("PlexPy API 'notify' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'notify' request failed: {0}.".format(e))
return None
diff --git a/killstream/kill_trans_quality.py b/killstream/kill_trans_quality.py
index 02b8d0c..411ab36 100644
--- a/killstream/kill_trans_quality.py
+++ b/killstream/kill_trans_quality.py
@@ -1,13 +1,13 @@
"""
Kill Plex transcoding streams only. Checks original quality.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: kill_trans_quality.py
-PlexPy > Settings > Notifications > Script > Script Arguments:
+Tautulli > Settings > Notifications > Script > Script Arguments:
{rating_key}
"""
@@ -31,7 +31,7 @@ DEVICES = {'Android': 'Andriod message',
USER_IGNORE = ('') # ('Username','User2')
-PLEXPY_LOG = 'Killing {user}\'s stream of {title} due to video transcoding of {original} content'
+TAUTULLI_LOG = 'Killing {user}\'s stream of {title} due to video transcoding of {original} content'
##
sess = requests.Session()
@@ -54,5 +54,5 @@ if __name__ == '__main__':
trans_dec = session.transcodeSessions[0].videoDecision
if sess_rating == str(rating_key) and orig_quality in TARGET_QUALITY and trans_dec == 'transcode':
reason = DEVICES.get(session.players[0].platform, DEFAULT_REASON)
- print(PLEXPY_LOG.format(user=username, title=title,original=orig_quality))
+ print(TAUTULLI_LOG.format(user=username, title=title,original=orig_quality))
session.stop(reason=reason)
diff --git a/killstream/play_limit.py b/killstream/play_limit.py
index 8b7cc2f..be81cf5 100644
--- a/killstream/play_limit.py
+++ b/killstream/play_limit.py
@@ -1,13 +1,13 @@
"""
Kill streams if user has played too much Plex Today.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: play_limit.py
-PlexPy > Settings > Notifications > Script > Script Arguments
+Tautulli > Settings > Notifications > Script > Script Arguments
{username} {section_id}
"""
@@ -19,8 +19,8 @@ from plexapi.server import PlexServer
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = 'xxxxx' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8182/' # Your PlexPy URL
+TAUTULLI_APIKEY = 'xxxxx' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8182/' # Your Tautulli URL
PLEX_TOKEN = 'xxxxx'
PLEX_URL = 'http://localhost:32400'
@@ -48,23 +48,23 @@ sess.verify = False
plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
-def get_get_history(username, section_id):
- # Get the PlexPy history.
- payload = {'apikey': PLEXPY_APIKEY,
+def get_history(username, section_id):
+ # Get the Tautulli history.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_history',
'user': username,
'section_id': section_id,
'start_date': TODAY}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['recordsFiltered']
return res_data
except Exception as e:
- sys.stderr.write("PlexPy API 'get_history' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_history' request failed: {0}.".format(e))
def kill_session(user):
@@ -82,6 +82,6 @@ for items in PLAY_LIMIT[username]:
section_id = items['section_id']
limit = items['limit']
-if get_get_history(username, section_id) > limit:
+if get_history(username, section_id) > limit:
print('User has reached play limit for today.')
kill_session(username)
diff --git a/killstream/time_limit.py b/killstream/time_limit.py
index f45ca08..5994ecc 100644
--- a/killstream/time_limit.py
+++ b/killstream/time_limit.py
@@ -1,13 +1,13 @@
"""
Kill streams if user has exceeded time limit on Plex server. Choose to unshare or remove user.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: time_limit.py
-PlexPy > Settings > Notifications > Script > Script Arguments
+Tautulli > Settings > Notifications > Script > Script Arguments
{username}
"""
@@ -18,8 +18,8 @@ from plexapi.server import PlexServer
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = 'xxxx' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8182/' # Your PlexPy URL
+TAUTULLI_APIKEY = 'xxxx' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8182/' # Your Tautulli URL
PLEX_TOKEN = 'xxxx'
PLEX_URL = 'http://localhost:32400'
@@ -41,21 +41,21 @@ plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
sections_lst = [x.title for x in plex.library.sections()]
-def get_get_history(username):
- # Get the PlexPy history.
- payload = {'apikey': PLEXPY_APIKEY,
+def get_history(username):
+ # Get the Tautulli history.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_history',
'user': username}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
return sum([data['duration'] for data in res_data])
except Exception as e:
- sys.stderr.write("PlexPy API 'get_history' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_history' request failed: {0}.".format(e))
def unshare(user, libraries):
@@ -88,7 +88,7 @@ if TIME_LIMIT[username]['m']:
total_time += TIME_LIMIT[username]['m'] * 60
-if get_get_history(username) > total_time:
+if get_history(username) > total_time:
print('User has reached time limit.')
kill_session(username)
if TIME_LIMIT[username]['remove']:
diff --git a/killstream/wait_kill_pause_notify_main.py b/killstream/wait_kill_pause_notify_main.py
index af8ecd0..cda861d 100644
--- a/killstream/wait_kill_pause_notify_main.py
+++ b/killstream/wait_kill_pause_notify_main.py
@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
'''
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on pause
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Pause: wait_kill_pause_notify_main.py
-PlexPy > Settings > Notifications > Script > Script Arguments:
+Tautulli > Settings > Notifications > Script > Script Arguments:
{session_key}
wait_kill_pause_notify_main.py & wait_kill_pause_notify_sub.py should be in the same directory.
wait_kill_pause_notify_main.py executes sub_script wait_kill_pause_notify_sub.py.
-PlexPy will timeout wait_kill_pause_notify_main.py after 30 seconds (default)
+Tautulli will timeout wait_kill_pause_notify_main.py after 30 seconds (default)
but wait_kill_pause_notify_sub.py will continue.
wait_kill_pause_notify_sub will check if the stream's session_id is still paused or if playing as restarted.
@@ -31,8 +31,8 @@ from plexapi.server import PlexServer
## EDIT THESE SETTINGS ##
PLEX_TOKEN = ''
PLEX_URL = 'http://localhost:32400'
-PLEXPY_APIKEY = '' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8182/' # Your PlexPy URL
+TAUTULLI_APIKEY = '' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8182/' # Your Tautulli URL
TIMEOUT = '120'
INTERVAL = '20'
@@ -44,10 +44,10 @@ USER_IGNORE = ('') # ('Username','User2')
SUBJECT_TEXT = "Killed Paused Transcoded Stream."
BODY_TEXT = "Killed {user}'s paused transcoded stream of {title}."
-AGENT_ID = 10 # Notification agent ID for PlexPy
+NOTIFIER_ID = 10 # Notification agent ID for Tautulli
# Find Notification agent ID here:
-# https://github.com/JonnyWong16/plexpy/blob/master/API.md#notify
-# AGENT = '' to disable notification
+# Tautulli Settings -> NOTIFICATION AGENTS -> :bell: Agent (NotifierID - {Description)
+# NOTIFIER_ID = '' to disable notification
sub_script = 'wait_kill_pause_notify_sub.py'
##/EDIT THESE SETTINGS ##
@@ -60,23 +60,23 @@ sessionKey = sys.argv[1]
def send_notification(subject_text, body_text):
- # Send the notification through PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
+ # Send the notification through Tautulli
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'notify',
- 'agent_id': AGENT_ID,
+ 'notifier_id': NOTIFIER_ID,
'subject': subject_text,
'body': body_text}
try:
- r = requests.post(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.post(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
- sys.stdout.write("Successfully sent PlexPy notification.")
+ sys.stdout.write("Successfully sent Tautulli notification.")
else:
raise Exception(response['response']['message'])
except Exception as e:
- sys.stderr.write("PlexPy API 'notify' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'notify' request failed: {0}.".format(e))
return None
@@ -92,7 +92,7 @@ def kill_stream(session, xtime, ntime):
title = (session.grandparentTitle + ' - ' if session.type == 'episode' else '') + session.title
if state == 'paused' and xtime == ntime:
- if AGENT_ID:
+ if NOTIFIER_ID:
send_notification(SUBJECT_TEXT, BODY_TEXT.format(user=username, title=title))
session.stop(reason=KILL_MESSAGE)
return ntime
diff --git a/killstream/wait_kill_pause_notify_sub.py b/killstream/wait_kill_pause_notify_sub.py
index 3d845a9..12dc1ec 100644
--- a/killstream/wait_kill_pause_notify_sub.py
+++ b/killstream/wait_kill_pause_notify_sub.py
@@ -4,7 +4,7 @@
wait_kill_pause_notify_main.py & wait_kill_pause_notify_sub.py should be in the same directory.
wait_kill_pause_notify_main.py executes sub_script wait_kill_pause_notify_sub.py.
-PlexPy will timeout wait_kill_pause_notify_main.py after 30 seconds (default)
+Tautulli will timeout wait_kill_pause_notify_main.py after 30 seconds (default)
but wait_kill_pause_notify_sub.py will continue.
wait_kill_pause_notify_sub will check if the stream's session_id is still paused or if playing as restarted.
diff --git a/killstream/wait_kill_paused_notify.py b/killstream/wait_kill_paused_notify.py
new file mode 100644
index 0000000..c0f6996
--- /dev/null
+++ b/killstream/wait_kill_paused_notify.py
@@ -0,0 +1,119 @@
+"""
+Description: Kill paused sessions if paused for X amount of time.
+Author: samwiseg00
+Requires: requests, plexapi
+
+Enabling Scripts in Tautulli:
+Taultulli > Settings > Notification Agents > Add a Notification Agent > Script
+
+Configuration:
+Taultulli > Settings > Notification Agents > New Script > Configuration:
+
+ Script Name: wait_kill_notify.py
+ Set Script Timeout: 0
+ Description: Killing long pauses
+ Save
+
+Triggers:
+Taultulli > Settings > Notification Agents > New Script > Triggers:
+
+ Check: Playback Pause
+ Save
+
+Conditions:
+Taultulli > Settings > Notification Agents > New Script > Conditions:
+
+ Set Conditions: Condition {1} | Username | is not | UsernameToExclude
+ Save
+
+Script Arguments:
+Taultulli > Settings > Notification Agents > New Script > Script Arguments:
+
+ Select: Playback Pause
+ Arguments: {session_key} {user} {title} TIMEOUT INTERVAL
+
+ Save
+ Close
+
+Example:
+ {session_key} {user} {title} 1200 20
+ This will tell the script to kill the stream after 20 minutes and check every 20 seconds
+
+"""
+
+import os
+import sys
+from time import sleep
+from datetime import datetime
+from plexapi.server import PlexServer
+import requests
+
+PLEX_FALLBACK_URL = 'http://127.0.0.1:32400'
+PLEX_FALLBACK_TOKEN = ''
+PLEX_URL = os.getenv('PLEX_URL', PLEX_FALLBACK_URL)
+PLEX_TOKEN = os.getenv('PLEX_TOKEN', PLEX_FALLBACK_TOKEN)
+
+PLEX_OVERRIDE_URL = ''
+PLEX_OVERRIDE_TOKEN = ''
+
+if PLEX_OVERRIDE_URL:
+ PLEX_URL = PLEX_OVERRIDE_URL
+if PLEX_OVERRIDE_TOKEN:
+ PLEX_TOKEN = PLEX_OVERRIDE_TOKEN
+
+
+sess = requests.Session()
+sess.verify = False
+plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
+
+sessionKey = sys.argv[1]
+username = sys.argv[2]
+streamTitle = sys.argv[3]
+timeout = int(sys.argv[4])
+interval = int(sys.argv[5])
+
+seconds = int(timeout)
+
+minutes, seconds = divmod(seconds, 60)
+hours, minutes = divmod(minutes, 60)
+
+periods = [('hours', hours), ('minutes', minutes), ('seconds', seconds)]
+time_string = ', '.join('{} {}'.format(value, name)
+ for name, value in periods
+ if value)
+start = datetime.now()
+
+countdown = 0
+counter = timeout + interval + 100
+
+while countdown < counter and countdown is not None:
+
+ foundSession = False
+
+ for session in plex.sessions():
+
+ if session.sessionKey == int(sessionKey):
+ foundSession = True
+ state = session.players[0].state
+
+ if state == 'paused':
+ now = datetime.now()
+ diff = now - start
+
+ if diff.total_seconds() >= timeout:
+ session.stop(reason="This stream has ended due to being paused for over {}.".format(time_string))
+ print ("Killed {}'s {} paused stream of {}.".format(username, time_string, streamTitle))
+ sys.exit(0)
+
+ else:
+ sleep(interval)
+ counter = counter - interval
+
+ elif state == 'playing' or state == 'buffering':
+ print ("{} resumed the stream of {} so we killed the script.".format(username, streamTitle))
+ sys.exit(0)
+
+ if not foundSession:
+ print ("Session key ({}) for user {} not found while playing {}. "
+ "The player may have gone to a paused then stopped state.".format(sessionKey, username, streamTitle))
+ sys.exit(0)
diff --git a/killstream/watch_limit.py b/killstream/watch_limit.py
index 480d419..a5b3450 100644
--- a/killstream/watch_limit.py
+++ b/killstream/watch_limit.py
@@ -1,13 +1,13 @@
"""
Kill streams if user has watched too much Plex Today.
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: watch_limit.py
-PlexPy > Settings > Notifications > Script > Script Arguments
+Tautulli > Settings > Notifications > Script > Script Arguments
{username}
"""
@@ -19,8 +19,8 @@ from plexapi.server import PlexServer
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = 'xxxx' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8182/' # Your PlexPy URL
+TAUTULLI_APIKEY = 'xxxx' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8182/' # Your Tautulli URL
PLEX_TOKEN = 'xxxxx'
PLEX_URL = 'http://localhost:32400'
@@ -41,22 +41,22 @@ sess.verify = False
plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
-def get_get_history(username):
- # Get the PlexPy history.
- payload = {'apikey': PLEXPY_APIKEY,
+def get_history(username):
+ # Get the Tautulli history.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_history',
'user': username,
'start_date': TODAY}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
return sum([data['watched_status'] for data in res_data])
except Exception as e:
- sys.stderr.write("PlexPy API 'get_history' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_history' request failed: {0}.".format(e))
def kill_session(user):
@@ -69,6 +69,6 @@ def kill_session(user):
session.stop(reason=MESSAGE)
-if get_get_history(username) > WATCH_LIMIT[username]:
+if get_history(username) > WATCH_LIMIT[username]:
print('User has reached watch limit for today.')
kill_session(username)
diff --git a/maps/ips_to_maps.py b/maps/ips_to_maps.py
index 33ffe2a..92bafdf 100644
--- a/maps/ips_to_maps.py
+++ b/maps/ips_to_maps.py
@@ -1,5 +1,5 @@
"""
-Use PlexPy draw a map connecting Server to Clients based on IP addresses.
+Use Tautulli draw a map connecting Server to Clients based on IP addresses.
optional arguments:
-h, --help show this help message and exit
@@ -32,13 +32,11 @@ from collections import OrderedDict
import argparse
import numpy as np
import time
-from collections import Counter
-
import webbrowser
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = '' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
+TAUTULLI_APIKEY = '' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8181/' # Your Tautulli 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.
@@ -56,16 +54,16 @@ SERVER_CITY = ''
SERVER_STATE = ''
SERVER_PLATFORM = 'Server'
-DEFAULT_COLOR = '#A96A1C' # Plex Orange?
+DEFAULT_COLOR = '#A96A1C' # Plex Orange?
-PLATFORM_COLORS = {'Android': '#a4c639', # Green
- 'Roku':'#800080', # Purple
- 'Chromecast':'#ffff00', # Yellow
- 'Xbox One':'#ffffff', # White
- 'Chrome':'#ff0000', # Red
- 'Playstation 4':'#0000ff', # Blue
- 'iOS':'#8b4513', # Poop brown
- 'Samsung': '#0c4da2', # Blue
+PLATFORM_COLORS = {'Android': '#a4c639', # Green
+ 'Roku': '#800080', # Purple
+ 'Chromecast': '#ffff00', # Yellow
+ 'Xbox One': '#ffffff', # White
+ 'Chrome': '#ff0000', # Red
+ 'Playstation 4': '#0000ff', # Blue
+ 'iOS': '#8b4513', # Poop brown
+ 'Samsung': '#0c4da2', # Blue
'Windows': DEFAULT_COLOR,
'Xbox 360 App': DEFAULT_COLOR}
@@ -95,19 +93,20 @@ class UserIPs(object):
self.play_count = d['play_count']
self.platform = d['platform']
-def get_get_users_tables(users='', length=''):
- # Get the users list from PlexPy
+
+def get_users_tables(users='', length=''):
+ # Get the users list from Tautulli
if length:
- payload = {'apikey': PLEXPY_APIKEY,
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_users_table',
'length': length}
else:
- payload = {'apikey': PLEXPY_APIKEY,
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_users_table'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
if not length and not users:
@@ -122,31 +121,32 @@ def get_get_users_tables(users='', length=''):
return [d['user_id'] for user in users for d in res_data if user == d['friendly_name']]
except Exception as e:
- sys.stderr.write("PlexPy API 'get_get_users_tables' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_users_tables' request failed: {0}.".format(e))
-def get_get_users_ips(user_id, length):
- # Get the user IP list from PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
+
+def get_users_ips(user_id, length):
+ # Get the user IP list from Tautulli
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_user_ips',
- 'user_id': user_id,
- 'length': length}
+ 'user_id': user_id}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
return [UserIPs(data=d) for d in res_data]
except Exception as e:
- sys.stderr.write("PlexPy API 'get_get_users_ips' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API '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,
+ # Get the geo IP lookup from Tautulli
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_geoip_lookup',
'ip_address': ip_address}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
data = response['response']['data']
@@ -158,21 +158,23 @@ def get_geoip_info(ip_address=''):
else:
raise Exception(response['response']['message'])
except Exception as e:
- sys.stderr.write("PlexPy API 'get_geoip_lookup' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_geoip_lookup' request failed: {0}.".format(e))
pass
+
def get_stream_type_by_top_10_platforms():
- # Get the user IP list from PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
+ # Get the user IP list from Tautulli
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_stream_type_by_top_10_platforms'} # length is number of returns, default is 25
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['categories']
return res_data
except Exception as e:
- sys.stderr.write("PlexPy API 'get_stream_type_by_top_10_platforms' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_stream_type_by_top_10_platforms' request failed: {0}.".format(e))
+
def add_to_dictlist(d, key, val):
if key not in d:
@@ -183,13 +185,14 @@ def add_to_dictlist(d, key, val):
if (val['region'], val['city']) == (x['region'], x['city']):
x['location_count'] += 1
+
def get_geo_dict(length, users):
geo_dict = {SERVER_FRIENDLY: [{'lon': SERVER_LON, 'lat': SERVER_LAT, 'city': SERVER_CITY, 'region': SERVER_STATE,
'ip': REPLACEMENT_WAN_IP, 'play_count': 0, 'platform': SERVER_PLATFORM,
'location_count': 0}]}
- for i in get_get_users_tables(users):
- user_ip = get_get_users_ips(user_id=i, length=length)
+ for i in get_users_tables(users):
+ user_ip = get_users_ips(user_id=i, length=length)
city_cnt = 0
for a in user_ip:
try:
@@ -201,8 +204,8 @@ def get_geo_dict(length, users):
add_to_dictlist(geo_dict, a.friendly_name, {'lon': str(g.longitude), 'lat': str(g.latitude),
'city': str(g.city), 'region': str(g.region),
- 'ip': ip, 'play_count': a.play_count,
- 'platform':a.platform, 'location_count': city_cnt})
+ 'ip': ip, 'play_count': a.play_count,
+ 'platform': a.platform, 'location_count': city_cnt})
except AttributeError:
print('User: {} IP: {} caused error in geo_dict.'.format(a.friendly_name, a.ip_address))
pass
@@ -211,6 +214,7 @@ def get_geo_dict(length, users):
pass
return geo_dict
+
def get_geojson_dict(user_locations):
locs = []
for username, locations in user_locations.iteritems():
@@ -255,13 +259,14 @@ def get_geojson_dict(user_locations):
"features": locs
}
+
def draw_map(map_type, geo_dict, filename, headless):
import matplotlib as mpl
if headless:
mpl.use("Agg")
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
-
+
## Map stuff ##
plt.figure(figsize=(16, 9), dpi=100, frameon=False, tight_layout=True)
lon_r = 0
@@ -324,7 +329,7 @@ def draw_map(map_type, geo_dict, filename, headless):
# Keeping lines inside the Location. Plots outside Location will still be in legend
if float(data['lon']) != float(SERVER_LON) and float(data['lat']) != float(SERVER_LAT) and \
- lon_l < float(data['lon']) < lon_r:
+ lon_l < float(data['lon']) < lon_r:
# Drawing lines from Server location to client location
if data['location_count'] > 1:
lines = m.plot(x, y, marker=marker, color=color, markersize=0,
@@ -332,16 +337,14 @@ def draw_map(map_type, geo_dict, filename, headless):
# Adding dash sequence to 2nd, 3rd, etc lines from same city,state
for line in lines:
line.set_solid_capstyle('round')
- dashes = [x * data['location_count'] for x in [5,8,5,8]]
+ dashes = [x * data['location_count'] for x in [5, 8, 5, 8]]
line.set_dashes(dashes)
else:
- lines = m.plot(x, y, marker=marker, color=color, markersize=0, label=legend, alpha=.4, zorder=zord,
- linewidth=2)
-
- client_plot = m.plot(px, py, marker=marker, color=color, markersize=markersize,
- label=legend, alpha=alph, zorder=zord)
+ m.plot(x, y, marker=marker, color=color, markersize=0, label=legend, alpha=.4, zorder=zord,
+ linewidth=2)
+ m.plot(px, py, marker=marker, color=color, markersize=markersize, label=legend, alpha=alph, zorder=zord)
handles, labels = plt.gca().get_legend_handles_labels()
idx = labels.index('Location: {}, {}, User: {}\nPlatform: {}, IP: {}, Play Count: {}'.
@@ -376,16 +379,16 @@ def draw_map(map_type, geo_dict, filename, headless):
if __name__ == '__main__':
timestr = time.strftime("%Y%m%d-%H%M%S")
- user_count = get_get_users_tables()
- user_lst = sorted(get_get_users_tables('friendly_name', user_count))
+ user_count = get_users_tables()
+ user_lst = sorted(get_users_tables('friendly_name', user_count))
json_check = sorted([f for f in os.listdir('.') if os.path.isfile(f) and f.endswith(".json")], key=os.path.getmtime)
- parser = argparse.ArgumentParser(description="Use PlexPy to draw map of user locations base on IP address.",
+ parser = argparse.ArgumentParser(description="Use Tautulli to draw map of user locations base on IP address.",
formatter_class=argparse.RawTextHelpFormatter)
- parser.add_argument('-l', '--location', default='NA', choices=['NA', 'EU','World', 'Geo'], metavar='',
+ parser.add_argument('-l', '--location', default='NA', choices=['NA', 'EU', 'World', 'Geo'], metavar='',
help='Map location. choices: (%(choices)s) \n(default: %(default)s)')
- parser.add_argument('-c', '--count', nargs='?', type=int , default=2, metavar='',
+ parser.add_argument('-c', '--count', nargs='?', type=int, default=2, metavar='',
help='How many IPs to attempt to check. \n(default: %(default)s)')
- parser.add_argument('-u', '--users', nargs='+', type=str ,default='all', choices=user_lst, metavar='',
+ parser.add_argument('-u', '--users', nargs='+', type=str, default='all', choices=user_lst, metavar='',
help='Space separated list of case sensitive names to process. Allowed names are: \n'
'%(choices)s \n(default: %(default)s)')
parser.add_argument('-i', '--ignore', nargs='+', type=str, default=None, choices=user_lst, metavar='',
@@ -410,7 +413,7 @@ if __name__ == '__main__':
with open(''.join(opts.json)) as json_data:
geo_json = json.load(json_data)
else:
- print(opts)
+ # print(opts)
if opts.ignore and opts.users == 'all':
users = [x for x in user_lst if x not in opts.ignore]
else:
@@ -445,4 +448,5 @@ if __name__ == '__main__':
print(r.json()['html_url'])
webbrowser.open(r.json()['html_url'])
else:
+ print(geo_json)
draw_map(opts.location, geo_json, filename, opts.headless)
diff --git a/notify/find_unwatched_notify.py b/notify/find_unwatched_notify.py
index cef3f99..a5ce082 100644
--- a/notify/find_unwatched_notify.py
+++ b/notify/find_unwatched_notify.py
@@ -1,23 +1,23 @@
"""
-Find what was added TFRAME ago and not watched and notify admin using PlexPy.
+Find what was added TFRAME ago and not watched and notify admin using Tautulli.
+TAUTULLI_URL + delete_media_info_cache?section_id={section_id}
"""
import requests
import sys
import time
-TFRAME = 1.577e+7 # ~ 6 months in seconds
+TFRAME = 1.577e+7 # ~ 6 months in seconds
TODAY = time.time()
-
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = 'XXXXXXX' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
-LIBRARY_NAMES = ['My Movies', 'My TV Shows'] # Name of libraries you want to check.
-SUBJECT_TEXT = "PlexPy Notification"
-AGENT_ID = 10 # The email notification agent ID for PlexPy
+TAUTULLI_APIKEY = '' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8183/' # Your Tautulli URL
+LIBRARY_NAMES = ['Movies', 'TV Shows'] # Name of libraries you want to check.
+SUBJECT_TEXT = "Tautulli Notification"
+NOTIFIER_ID = 12 # The email notification agent ID for Tautulli
class LIBINFO(object):
@@ -40,19 +40,21 @@ class METAINFO(object):
self.rating_key = d['rating_key']
self.media_type = d['media_type']
self.grandparent_title = d['grandparent_title']
- self.file_size = d['file_size']
- self.file = d['file']
+ media_info = d['media_info'][0]
+ parts = media_info['parts'][0]
+ self.file_size = parts['file_size']
+ self.file = parts['file']
-def get_get_new_rating_keys(rating_key, media_type):
+def get_new_rating_keys(rating_key, media_type):
# Get a list of new rating keys for the PMS of all of the item's parent/children.
- payload = {'apikey': PLEXPY_APIKEY,
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_new_rating_keys',
'rating_key': rating_key,
'media_type': media_type}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']
@@ -63,139 +65,141 @@ def get_get_new_rating_keys(rating_key, media_type):
return episode_lst
except Exception as e:
- sys.stderr.write("PlexPy API 'get_new_rating_keys' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_new_rating_keys' request failed: {0}.".format(e))
-def get_get_metadata(rating_key):
+def get_metadata(rating_key):
# Get the metadata for a media item.
- payload = {'apikey': PLEXPY_APIKEY,
+ payload = {'apikey': TAUTULLI_APIKEY,
'rating_key': rating_key,
- 'cmd': 'get_metadata',
- 'media_info': True}
+ 'cmd': 'get_metadata'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
-
- res_data = response['response']['data']['metadata']
+ res_data = response['response']['data']
return METAINFO(data=res_data)
except Exception as e:
- # sys.stderr.write("PlexPy API 'get_get_metadata' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_metadata' request failed: {0}.".format(e))
pass
-def get_get_library_media_info(section_id):
- # Get the data on the PlexPy media info tables.
- payload = {'apikey': PLEXPY_APIKEY,
+def get_library_media_info(section_id):
+ # Get the data on the Tautulli media info tables.
+ payload = {'apikey': TAUTULLI_APIKEY,
'section_id': section_id,
- 'cmd': 'get_library_media_info',
- 'length': 10000}
+ 'cmd': 'get_library_media_info'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
-
res_data = response['response']['data']['data']
return [LIBINFO(data=d) for d in res_data if d['play_count'] is None and (TODAY - int(d['added_at'])) > TFRAME]
except Exception as e:
- sys.stderr.write("PlexPy API 'get_library_media_info' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_library_media_info' request failed: {0}.".format(e))
-def get_get_libraries_table():
- # Get the data on the PlexPy libraries table.
- payload = {'apikey': PLEXPY_APIKEY,
+
+def get_libraries_table():
+ # Get the data on the Tautulli libraries table.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_libraries_table'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
return [d['section_id'] for d in res_data if d['section_name'] in LIBRARY_NAMES]
except Exception as e:
- sys.stderr.write("PlexPy API 'get_libraries_table' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_libraries_table' request failed: {0}.".format(e))
-def send_notification(BODY_TEXT):
+
+def send_notification(body_text):
# Format notification text
try:
subject = SUBJECT_TEXT
- body = BODY_TEXT
+ body = body_text
except LookupError as e:
sys.stderr.write("Unable to substitute '{0}' in the notification subject or body".format(e))
return None
- # Send the notification through PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
+ # Send the notification through Tautulli
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'notify',
- 'agent_id': AGENT_ID,
+ 'notifier_id': NOTIFIER_ID,
'subject': subject,
'body': body}
try:
- r = requests.post(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.post(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
- sys.stdout.write("Successfully sent PlexPy notification.")
+ sys.stdout.write("Successfully sent Tautulli notification.")
else:
raise Exception(response['response']['message'])
except Exception as e:
- sys.stderr.write("PlexPy API 'notify' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'notify' request failed: {0}.".format(e))
return None
show_lst = []
notify_lst = []
-glt = [lib for lib in get_get_libraries_table()]
+libraries = [lib for lib in get_libraries_table()]
-for i in glt:
+for library in libraries:
try:
- gglm = get_get_library_media_info(i)
- for x in gglm:
+ library_media_info = get_library_media_info(library)
+ for lib in library_media_info:
try:
- if x.media_type in ['show', 'episode']:
+ if lib.media_type in ['show', 'episode']:
# Need to find TV shows rating_key for episode.
- show_lst += get_get_new_rating_keys(x.rating_key, x.media_type)
+ show_lst += get_new_rating_keys(lib.rating_key, lib.media_type)
else:
# Find movie rating_key.
- show_lst += [int(x.rating_key)]
+ show_lst += [int(lib.rating_key)]
except Exception as e:
- print("Rating_key failed: {e}").format(e=e)
+ print "Rating_key failed: {e}".format(e=e)
except Exception as e:
- print("Library media info failed: {e}").format(e=e)
+ print "Library media info failed: {e}".format(e=e)
-for i in show_lst:
+for show in show_lst:
try:
- x = get_get_metadata(str(i))
- added = time.ctime(float(x.added_at))
- if x.grandparent_title == '' or x.media_type == 'movie':
+ meta = get_metadata(str(show))
+ added = time.ctime(float(meta.added_at))
+ if meta.grandparent_title == '' or meta.media_type == 'movie':
# Movies
notify_lst += [u"
{x.title} ({x.rating_key}) was added {when} and has not been"
- u" watched.
Hi!
- Below is the list of {LIBRARY_NAMES} that have not been watched.
-
- {notify_lst}
-
-
-
-
-""".format(notify_lst="\n".join(notify_lst).encode("utf-8"),LIBRARY_NAMES=" & ".join(LIBRARY_NAMES))
-
-send_notification(BODY_TEXT)
+ print(BODY_TEXT)
+ send_notification(BODY_TEXT)
+else:
+ print('Nothing to report.')
+ exit()
diff --git a/notify/notify_added_custom.py b/notify/notify_added_custom.py
index eef1f88..59c7dbf 100644
--- a/notify/notify_added_custom.py
+++ b/notify/notify_added_custom.py
@@ -1,5 +1,5 @@
"""
-Send an email with what was added to Plex in the past week using PlexPy.
+Send an email with what was added to Plex in the past week using Tautulli.
Email includes title (TV: Show Name: Episode Name; Movie: Movie Title), time added, image, and summary.
Uses:
@@ -35,9 +35,10 @@ import uuid
import argparse
+
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = 'xxx' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
+TAUTULLI_APIKEY = '' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8181/' # Your Tautulli URL
LIBRARY_NAMES = ['Movies', 'TV Shows'] # Name of libraries you want to check.
# Email settings
@@ -49,7 +50,7 @@ email_server = 'smtp.gmail.com' # Email server (Gmail: smtp.gmail.com)
email_port = 587 # Email port (Gmail: 587)
email_username = '' # Your email username
email_password = '' # Your email password
-email_subject = 'PlexPy Added Last {} day(s) Notification' #The email subject
+email_subject = 'Tautulli Added Last {} day(s) Notification' #The email subject
# Default sizing for pictures
# Poster
@@ -70,21 +71,20 @@ class METAINFO(object):
self.rating_key = d['rating_key']
self.media_type = d['media_type']
self.grandparent_title = d['grandparent_title']
- self.file_size = d['file_size']
self.thumb = d['art']
self.summary = d['summary']
-def get_get_recent(section_id, start, count):
+def get_recent(section_id, start, count):
# Get the metadata for a media item. Count matters!
- payload = {'apikey': PLEXPY_APIKEY,
+ payload = {'apikey': TAUTULLI_APIKEY,
'start': str(start),
'count': str(count),
'section_id': section_id,
'cmd': 'get_recently_added'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
@@ -93,86 +93,87 @@ def get_get_recent(section_id, start, count):
return res_data
except Exception as e:
- sys.stderr.write("PlexPy API 'get_recently_added' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_recently_added' request failed: {0}.".format(e))
-def get_get_metadata(rating_key):
+def get_metadata(rating_key):
# Get the metadata for a media item.
- payload = {'apikey': PLEXPY_APIKEY,
+ payload = {'apikey': TAUTULLI_APIKEY,
'rating_key': rating_key,
'cmd': 'get_metadata',
'media_info': True}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
- res_data = response['response']['data']['metadata']
+ res_data = response['response']['data']
+
return METAINFO(data=res_data)
except Exception as e:
- sys.stderr.write("PlexPy API 'get_metadata' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_metadata' request failed: {0}.".format(e))
-def get_get_libraries_table():
- # Get the data on the PlexPy libraries table.
- payload = {'apikey': PLEXPY_APIKEY,
+def get_libraries_table():
+ # Get the data on the Tautulli libraries table.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_libraries_table'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
return [d['section_id'] for d in res_data if d['section_name'] in LIBRARY_NAMES]
except Exception as e:
- sys.stderr.write("PlexPy API 'get_libraries_table' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_libraries_table' request failed: {0}.".format(e))
def update_library_media_info(section_id):
- # Get the data on the PlexPy media info tables.
- payload = {'apikey': PLEXPY_APIKEY,
+ # Get the data on the Tautulli media info tables.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_library_media_info',
'section_id': section_id,
'refresh': True}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.status_code
if response != 200:
print(r.content)
except Exception as e:
- sys.stderr.write("PlexPy API 'update_library_media_info' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'update_library_media_info' request failed: {0}.".format(e))
def get_pms_image_proxy(thumb):
# Gets an image from the PMS and saves it to the image cache directory.
- payload = {'apikey': PLEXPY_APIKEY,
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'pms_image_proxy',
'img': thumb}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload, stream=True)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload, stream=True)
return r.url
except Exception as e:
- sys.stderr.write("PlexPy API 'get_get_users_tables' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_users_tables' request failed: {0}.".format(e))
-def get_get_users():
- # Get the user list from PlexPy.
- payload = {'apikey': PLEXPY_APIKEY,
+def get_users():
+ # Get the user list from Tautulli.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_users'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']
return [d for d in res_data]
except Exception as e:
- sys.stderr.write("PlexPy API 'get_user' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_user' request failed: {0}.".format(e))
def get_rating_keys(TODAY, LASTDATE):
@@ -185,7 +186,7 @@ def get_rating_keys(TODAY, LASTDATE):
while True:
# Assume all items will be returned in descending order of added_at
- recent_items = get_get_recent(section_id, start, count)
+ recent_items = get_recent(section_id, start, count)
if all([recent_items]):
start += count
@@ -205,7 +206,7 @@ def get_rating_keys(TODAY, LASTDATE):
def build_html(rating_key, height, width, pic_type):
- meta = get_get_metadata(str(rating_key))
+ meta = get_metadata(str(rating_key))
added = time.ctime(float(meta.added_at))
# Pull image url
@@ -286,12 +287,12 @@ def send_email(msg_text_lst, notify_lst, image_lst, to, days):
mailserver.login(email_username, email_password)
mailserver.sendmail(sender, to, message.as_string())
mailserver.quit()
- print 'Email sent'
+ print('Email sent')
if __name__ == '__main__':
- parser = argparse.ArgumentParser(description="Send an email with what was added to Plex in the past week using PlexPy.")
+ parser = argparse.ArgumentParser(description="Send an email with what was added to Plex in the past week using Tautulli.")
parser.add_argument('-t', '--type', help='Metadata picture type from Plex.',
required= True, choices=['art', 'poster'])
parser.add_argument('-s', '--size', help='Metadata picture size from Plex {Height Width}.', nargs='*')
@@ -320,17 +321,17 @@ if __name__ == '__main__':
width = art_w
# Find the libraries from LIBRARY_NAMES
- glt = [lib for lib in get_get_libraries_table()]
+ glt = [lib for lib in get_libraries_table()]
# Update media info for libraries.
[update_library_media_info(i) for i in glt]
# Gather all users email addresses
if opts.users == ['all']:
- [to.append(x['email']) for x in get_get_users() if x['email'] != '' and x['email'] not in to
+ [to.append(x['email']) for x in get_users() if x['email'] != '' and x['email'] not in to
and x['username'] not in opts.ignore]
elif opts.users != ['all'] and opts.users != 'self':
- for get_users in get_get_users():
+ for get_users in get_users():
for arg_users in opts.users:
if arg_users in get_users['username']:
to = to + [str(get_users['email'])]
diff --git a/notify/notify_delay.py b/notify/notify_delay.py
index db3c665..642dbed 100644
--- a/notify/notify_delay.py
+++ b/notify/notify_delay.py
@@ -1,33 +1,32 @@
-'''
+"""
Delay Notification Agent message for concurrent streams
-Arguments passed from PlexPy
+Arguments passed from Tautulli
-u {user} -srv {server_name}
You can add more arguments if you want more details in the email body
-Adding to PlexPy
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Adding to Tautulli
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on concurrent streams
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
User Concurrent Streams: notify_delay.py
-PlexPy Settings > Notification Agents > Scripts (Gear) > Script Timeout: 0 to disable or set to > 180
-'''
+Tautulli Settings > Notification Agents > Scripts (Gear) > Script Timeout: 0 to disable or set to > 180
+"""
import requests
import sys
import argparse
from time import sleep
-
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = 'xxxxx' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8182/' # Your PlexPy URL
+TAUTULLI_APIKEY = '' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8181/' # Your Tautulli URL
CONCURRENT_TOTAL = 2
TIMEOUT = 180
INTERVAL = 20
-AGENT_ID = 10 # Notification agent ID for PlexPy
+NOTIFIER_ID = 10 # Notification notifier ID for Tautulli
# Find Notification agent ID here:
# https://github.com/JonnyWong16/plexpy/blob/master/API.md#notify
@@ -44,49 +43,51 @@ BODY_TEXT = """\
"""
-def get_get_activity():
+def get_activity():
# Get the current activity on the PMS.
- payload = {'apikey': PLEXPY_APIKEY,
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_activity'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['sessions']
return [d['user'] for d in res_data]
except Exception as e:
- sys.stderr.write("PlexPy API 'get_activity' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_activity' request failed: {0}.".format(e))
pass
-def send_notification(SUBJECT_TEXT, BODY_TEXT):
+
+def send_notification(subject_text, body_text):
# Format notification text
try:
- subject = SUBJECT_TEXT.format(p=p, total=cc_total)
- body = BODY_TEXT.format(p=p, total=cc_total, time=TIMEOUT/60)
+ subject = subject_text.format(p=p, total=cc_total)
+ body = body_text.format(p=p, total=cc_total, time=TIMEOUT / 60)
except LookupError as e:
sys.stderr.write("Unable to substitute '{0}' in the notification subject or body".format(e))
return None
- # Send the notification through PlexPy
- payload = {'apikey': PLEXPY_APIKEY,
+ # Send the notification through Tautulli
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'notify',
- 'agent_id': AGENT_ID,
+ 'notifier_id': NOTIFIER_ID,
'subject': subject,
'body': body}
try:
- r = requests.post(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.post(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
- sys.stdout.write("Successfully sent PlexPy notification.")
+ sys.stdout.write("Successfully sent Tautulli notification.")
else:
raise Exception(response['response']['message'])
except Exception as e:
- sys.stderr.write("PlexPy API 'notify' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'notify' request failed: {0}.".format(e))
return None
+
if __name__ == '__main__':
parser = argparse.ArgumentParser()
@@ -101,7 +102,7 @@ if __name__ == '__main__':
while x < TIMEOUT and x is not None:
# check if user still has concurrent streams
print('Checking concurrent stream count.')
- cc_total = get_get_activity().count(p.user)
+ cc_total = get_activity().count(p.user)
if cc_total >= CONCURRENT_TOTAL:
print('{p.user} still has {total} concurrent streams.'.format(p=p, total=cc_total))
sleep(INTERVAL)
diff --git a/notify/notify_fav_tv_all_movie.py b/notify/notify_fav_tv_all_movie.py
index 67ef9a3..296b96b 100644
--- a/notify/notify_fav_tv_all_movie.py
+++ b/notify/notify_fav_tv_all_movie.py
@@ -3,15 +3,15 @@ Notify users of recently added episode to show that they have watched at least L
Also notify users of new movies.
Block users with IGNORE_LST.
-Arguments passed from PlexPy
+Arguments passed from Tautulli
-sn {show_name} -ena {episode_name} -ssn {season_num00} -enu {episode_num00} -srv {server_name} -med {media_type}
-pos {poster_url} -tt {title} -sum {summary} -lbn {library_name} -grk {grandparent_rating_key}
You can add more arguments if you want more details in the email body
-Adding to PlexPy
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Adding to Tautulli
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on recently added
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Recently Added: notify_fav_tv_all_movie.py
"""
@@ -23,8 +23,8 @@ import sys
import argparse
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = 'XXXXXXX' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
+TAUTULLI_APIKEY = 'XXXXXXX' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8181/' # Your Tautulli URL
IGNORE_LST = ['123456', '123456'] # User_ids
LIMIT = 3
@@ -93,52 +93,52 @@ class UserHIS(object):
self.show_key = d['grandparent_rating_key']
-def get_get_user(user_id):
- # Get the user list from PlexPy.
- payload = {'apikey': PLEXPY_APIKEY,
+def get_user(user_id):
+ # Get the user list from Tautulli.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_user',
'user_id': int(user_id)}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']
return Users(data=res_data)
except Exception as e:
- sys.stderr.write("PlexPy API 'get_user' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_user' request failed: {0}.".format(e))
-def get_get_users():
- # Get the user list from PlexPy.
- payload = {'apikey': PLEXPY_APIKEY,
+def get_users():
+ # Get the user list from Tautulli.
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_users'}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']
return res_data
except Exception as e:
- sys.stderr.write("PlexPy API 'get_user' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_user' request failed: {0}.".format(e))
-def get_get_history(showkey):
- # Get the user history from PlexPy. Length matters!
- payload = {'apikey': PLEXPY_APIKEY,
+def get_history(showkey):
+ # Get the user history from Tautulli. Length matters!
+ payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_history',
'grandparent_rating_key': showkey,
'length': 10000}
try:
- r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
+ r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
return [UserHIS(data=d) for d in res_data if d['watched_status'] == 1
and d['media_type'].lower() in ('episode', 'show')]
except Exception as e:
- sys.stderr.write("PlexPy API 'get_history' request failed: {0}.".format(e))
+ sys.stderr.write("Tautulli API 'get_history' request failed: {0}.".format(e))
def add_to_dictlist(d, key, val):
@@ -149,7 +149,7 @@ def add_to_dictlist(d, key, val):
def get_email(show):
- history = get_get_history(show)
+ history = get_history(show)
[add_to_dictlist(user_dict, h.user_id, h.show_key) for h in history]
# {user_id1: [grand_key, grand_key], user_id2: [grand_key]}
@@ -166,7 +166,7 @@ def get_email(show):
for i in user_lst:
try:
if user_dict[i][show] > LIMIT:
- g = get_get_user(i)
+ g = get_user(i)
if g.user_id not in IGNORE_LST:
sys.stdout.write("Sending {g.user_id} email for %s.".format(g=g) % show)
email_lst += [g.email]
@@ -237,7 +237,7 @@ if __name__ == '__main__':
if p.media_type == 'movie':
email_subject = MOVIE_SUBJECT.format(p=p)
- to = filter(None, [x['email'] for x in get_get_users() if x['user_id'] not in IGNORE_LST])
+ to = filter(None, [x['email'] for x in get_users() if x['user_id'] not in IGNORE_LST])
body_html = MOVIE_BODY.format(p=p)
send_email(to, email_subject, body_html)
diff --git a/notify/notify_newip.py b/notify/notify_newip.py
index d3f624d..7171272 100644
--- a/notify/notify_newip.py
+++ b/notify/notify_newip.py
@@ -1,15 +1,16 @@
-
"""
Pulling together User IP information and Email.
-Adding to PlexPy
-PlexPy > Settings > Notification Agents > Scripts > Bell icon:
+Adding to Tautulli
+Tautulli > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on playback start
-PlexPy > Settings > Notification Agents > Scripts > Gear icon:
+Tautulli > Settings > Notification Agents > Scripts > Gear icon:
Playback Start: notify_newip.py
-Arguments passed from PlexPy
--sn {show_name} -ena {episode_name} -ssn {season_num00} -enu {episode_num00} -srv {server_name} -med {media_type} -pos {poster_url} -tt {title} -sum {summary} -lbn {library_name} -ip {ip_address} -us {user} -uid {user_id} -pf {platform} -pl {player} -da {datestamp} -ti {timestamp}
+Arguments passed from Tautulli
+-sn {show_name} -ena {episode_name} -ssn {season_num00} -enu {episode_num00} -srv {server_name} -med {media_type}
+-pos {poster_url} -tt {title} -sum {summary} -lbn {library_name} -ip {ip_address} -us {user} -uid {user_id}
+-pf {platform} -pl {player} -da {datestamp} -ti {timestamp}
"""
@@ -17,11 +18,10 @@ import argparse
import requests
import sys
-
## EDIT THESE SETTINGS ##
-PLEXPY_APIKEY = 'XXXX' # Your PlexPy API key
-PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
-NOTIFICATION_ID = 10 # The notification agent ID for PlexPy 10 = Email
+TAUTULLI_APIKEY = '' # Your Tautulli API key
+TAUTULLI_URL = 'http://localhost:8181/' # Your Tautulli URL
+NOTIFIER_ID = 12 # The notification notifier ID
# 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.
@@ -38,16 +38,19 @@ BODY_TEXT = """\
Hi!
- {p.user} has watched {p.media_type}:{p.title} from a new IP address: {p.ip_address}
- On {p.platform}[{p.player}] in {g.city}, {g.country} {g.postal_code} at {p.timestamp} on {p.datestamp}
+
+ {p.user} has watched {p.media_type}:{p.title} from a new IP address: {p.ip_address}
+ On {p.platform}[{p.player}] in
+ {g.city}, {g.country} {g.postal_code}
+ at {p.timestamp} on {p.datestamp}