Incorporate waiting to kill paused streams into kill_stream.py
Incorporate the functionality of `wait_kill_paused_notify.py` into `kill_stream.py`. A new selector is added of `paused` enabling this mode, and adds two additional arguments to control how long to wait for paused streams, and how often to check a stream's status. The default values are to kill a stream after 20 minutes, checking every 30 seconds. The Tautulli API is used for all functionality, meaning the `plexapi` module is no longer required.
This commit is contained in:
parent
0ba8e2bda0
commit
c03860ec70
@ -32,6 +32,7 @@ Taultulli > Settings > Notification Agents > New Script > Script Arguments:
|
|||||||
Select: Playback Start, Playback Pause
|
Select: Playback Start, Playback Pause
|
||||||
Arguments: --jbop SELECTOR --userId {user_id} --username {username}
|
Arguments: --jbop SELECTOR --userId {user_id} --username {username}
|
||||||
--sessionId {session_id} --notify notifierID
|
--sessionId {session_id} --notify notifierID
|
||||||
|
--interval 30 --limit 1200
|
||||||
--killMessage Your message here. No quotes.
|
--killMessage Your message here. No quotes.
|
||||||
|
|
||||||
Save
|
Save
|
||||||
@ -43,6 +44,8 @@ import requests
|
|||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
from time import sleep
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
TAUTULLI_URL = ''
|
TAUTULLI_URL = ''
|
||||||
TAUTULLI_APIKEY = ''
|
TAUTULLI_APIKEY = ''
|
||||||
@ -64,7 +67,7 @@ if sess.verify is False:
|
|||||||
import urllib3
|
import urllib3
|
||||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
SELECTOR = ['stream', 'allStreams']
|
SELECTOR = ['stream', 'allStreams', 'paused']
|
||||||
|
|
||||||
|
|
||||||
def send_notification(subject_text, body_text, notifier_id):
|
def send_notification(subject_text, body_text, notifier_id):
|
||||||
@ -183,6 +186,59 @@ def terminate_session(session_id, message, notifier=None, username=None):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def terminate_long_pause(session_id, message, limit, interval, notify=None):
|
||||||
|
"""Kills the session if it is paused for longer than <limit> seconds.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
session_id : str
|
||||||
|
The session id of the session to monitor.
|
||||||
|
message : str
|
||||||
|
The message to use if the stream is terminated.
|
||||||
|
limit : int
|
||||||
|
The number of seconds the session is allowed to remain paused before it
|
||||||
|
is terminated.
|
||||||
|
interval : int
|
||||||
|
The amount of time to wait between checks of the session state.
|
||||||
|
notify : int
|
||||||
|
Tautulli Notification Agent ID to send a notification to on killing a
|
||||||
|
stream.
|
||||||
|
"""
|
||||||
|
start = datetime.now()
|
||||||
|
fudgeFactor = 100 # Keep checking this long after the defined limit
|
||||||
|
pausedTime = 0
|
||||||
|
checkLimit = limit + interval + fudgeFactor
|
||||||
|
|
||||||
|
while pausedTime < checkLimit:
|
||||||
|
sessions = get_activity()
|
||||||
|
foundSession = False
|
||||||
|
|
||||||
|
for session in sessions:
|
||||||
|
if session['session_id'] == session_id:
|
||||||
|
foundSession = True
|
||||||
|
state = session['state']
|
||||||
|
|
||||||
|
if state == 'paused':
|
||||||
|
now = datetime.now()
|
||||||
|
diff = now - start
|
||||||
|
|
||||||
|
if diff.total_seconds() >= limit:
|
||||||
|
terminate_session(session_id, message, notify)
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
sleep(interval)
|
||||||
|
elif state == 'playing' or state == 'buffering':
|
||||||
|
sys.stdout.write(
|
||||||
|
"Session '{}' has resumed, ".format(session_id) +
|
||||||
|
"stopping monitoring.")
|
||||||
|
sys.exit(0)
|
||||||
|
if not foundSession:
|
||||||
|
sys.stdout.write(
|
||||||
|
"Session '{}' is no longer active ".format(session_id) +
|
||||||
|
"on the server, stopping monitoring.")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Killing Plex streams from Tautulli.")
|
description="Killing Plex streams from Tautulli.")
|
||||||
@ -197,6 +253,10 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument('--notify', type=int,
|
parser.add_argument('--notify', type=int,
|
||||||
help='Notification Agent ID number to Agent to send ' +
|
help='Notification Agent ID number to Agent to send ' +
|
||||||
'notification.')
|
'notification.')
|
||||||
|
parser.add_argument('--limit', type=int, default=(20 * 60), # 20 minutes
|
||||||
|
help='The time session is allowed to remain paused.')
|
||||||
|
parser.add_argument('--interval', type=int, default=30,
|
||||||
|
help='The seconds between paused session checks.')
|
||||||
parser.add_argument('--killMessage', nargs='+',
|
parser.add_argument('--killMessage', nargs='+',
|
||||||
help='Message to send to user whose stream is killed.')
|
help='Message to send to user whose stream is killed.')
|
||||||
|
|
||||||
@ -213,3 +273,6 @@ if __name__ == "__main__":
|
|||||||
streams = get_user_session_ids(opts.userId)
|
streams = get_user_session_ids(opts.userId)
|
||||||
for session_id in streams:
|
for session_id in streams:
|
||||||
terminate_session(session_id, message, opts.notify, opts.username)
|
terminate_session(session_id, message, opts.notify, opts.username)
|
||||||
|
elif opts.jbop == 'paused':
|
||||||
|
terminate_long_pause(opts.sessionId, message, opts.limit,
|
||||||
|
opts.interval, opts.notify)
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
"""
|
|
||||||
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)
|
|
Loading…
x
Reference in New Issue
Block a user