Merge pull request #76 from Arcanemagus/kill_stream-paused
Incorporate waiting to kill paused streams into kill_stream.py
This commit is contained in:
commit
203a3b0bb9
@ -1,23 +1,25 @@
|
||||
"""
|
||||
Description: Use conditions to kill a stream
|
||||
Author: Blacktwin
|
||||
Author: Blacktwin, Arcanemagus, samwiseg00
|
||||
Requires: requests
|
||||
|
||||
Enabling Scripts in Tautulli:
|
||||
Taultulli > Settings > Notification Agents > Add a Notification Agent > Script
|
||||
Adding the script to Tautulli:
|
||||
Taultulli > Settings > Notification Agents > Add a new notification agent >
|
||||
Script
|
||||
|
||||
Configuration:
|
||||
Taultulli > Settings > Notification Agents > New Script > Configuration:
|
||||
|
||||
Script Name: kill_stream
|
||||
Set Script Timeout: {timeout}
|
||||
Script Folder: /path/to/your/scripts
|
||||
Script File: ./kill_stream.py (Should be selectable in a dropdown list)
|
||||
Script Timeout: {timeout}
|
||||
Description: Kill stream(s)
|
||||
Save
|
||||
|
||||
Triggers:
|
||||
Taultulli > Settings > Notification Agents > New Script > Triggers:
|
||||
|
||||
Check: {trigger}
|
||||
Check: Playback Start and/or Playback Pause
|
||||
Save
|
||||
|
||||
Conditions:
|
||||
@ -31,17 +33,20 @@ Taultulli > Settings > Notification Agents > New Script > Script Arguments:
|
||||
|
||||
Select: Playback Start, Playback Pause
|
||||
Arguments: --jbop SELECTOR --userId {user_id} --username {username}
|
||||
--sessionId {session_id} --killMessage Your message here. No quotes. --notify notifierID
|
||||
--sessionId {session_id} --notify notifierID
|
||||
--interval 30 --limit 1200
|
||||
--killMessage Your message here. No quotes.
|
||||
|
||||
Save
|
||||
Close
|
||||
|
||||
"""
|
||||
|
||||
import requests
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
from time import sleep
|
||||
from datetime import datetime
|
||||
|
||||
TAUTULLI_URL = ''
|
||||
TAUTULLI_APIKEY = ''
|
||||
@ -49,19 +54,35 @@ TAUTULLI_URL = os.getenv('TAUTULLI_URL', TAUTULLI_URL)
|
||||
TAUTULLI_APIKEY = os.getenv('TAUTULLI_APIKEY', TAUTULLI_APIKEY)
|
||||
|
||||
SUBJECT_TEXT = "Tautulli has killed a stream."
|
||||
BODY_TEXT = "Killed {user}'s stream. Reason: {message}."
|
||||
BODY_TEXT = "Killed session ID '{id}'. Reason: {message}"
|
||||
BODY_TEXT_USER = "Killed {user}'s stream. Reason: {message}."
|
||||
|
||||
sess = requests.Session()
|
||||
# Ignore verifying the SSL certificate
|
||||
sess.verify = False # '/path/to/certfile'
|
||||
sess.verify = False # '/path/to/certfile'
|
||||
# If verify is set to a path to a directory,
|
||||
# the directory must have been processed using the c_rehash utility supplied with OpenSSL.
|
||||
# the directory must have been processed using the c_rehash utility supplied
|
||||
# with OpenSSL.
|
||||
if sess.verify is False:
|
||||
# Disable the warning that the request is insecure, we know that...
|
||||
import urllib3
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
SELECTOR = ['stream', 'allStreams']
|
||||
SELECTOR = ['stream', 'allStreams', 'paused']
|
||||
|
||||
|
||||
def send_notification(subject_text, body_text, notifier_id):
|
||||
# Send the notification through Tautulli
|
||||
"""Send a notification through Tautulli
|
||||
|
||||
Parameters
|
||||
----------
|
||||
subject_text : str
|
||||
The text to use for the subject line of the message.
|
||||
body_text : str
|
||||
The text to use for the body of the notification.
|
||||
notifier_id : int
|
||||
Tautulli Notification Agent ID to send the notification to.
|
||||
"""
|
||||
payload = {'apikey': TAUTULLI_APIKEY,
|
||||
'cmd': 'notify',
|
||||
'notifier_id': notifier_id,
|
||||
@ -69,7 +90,7 @@ def send_notification(subject_text, body_text, notifier_id):
|
||||
'body': body_text}
|
||||
|
||||
try:
|
||||
r = requests.post(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
|
||||
r = sess.post(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
|
||||
response = r.json()
|
||||
|
||||
if response['response']['result'] == 'success':
|
||||
@ -77,30 +98,69 @@ def send_notification(subject_text, body_text, notifier_id):
|
||||
else:
|
||||
raise Exception(response['response']['message'])
|
||||
except Exception as e:
|
||||
sys.stderr.write("Tautulli API 'notify' request failed: {0}.".format(e))
|
||||
sys.stderr.write(
|
||||
"Tautulli API 'notify' request failed: {0}.".format(e))
|
||||
return None
|
||||
|
||||
|
||||
def get_activity(user_id):
|
||||
# Get the current activity on the PMS.
|
||||
def get_activity():
|
||||
"""Get the current activity on the PMS.
|
||||
|
||||
Returns
|
||||
-------
|
||||
list
|
||||
The current active sessions on the Plex server.
|
||||
"""
|
||||
payload = {'apikey': TAUTULLI_APIKEY,
|
||||
'cmd': 'get_activity'}
|
||||
|
||||
try:
|
||||
req = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
|
||||
req = sess.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
|
||||
response = req.json()
|
||||
|
||||
res_data = response['response']['data']['sessions']
|
||||
user_streams = [d['session_id'] for d in res_data if d['user_id'] == user_id]
|
||||
return user_streams
|
||||
return res_data
|
||||
|
||||
except Exception as e:
|
||||
sys.stderr.write("Tautulli API 'get_activity' request failed: {0}.".format(e))
|
||||
sys.stderr.write(
|
||||
"Tautulli API 'get_activity' request failed: {0}.".format(e))
|
||||
pass
|
||||
|
||||
|
||||
def terminate_session(session_id, message):
|
||||
# Stop a streaming session.
|
||||
def get_user_session_ids(user_id):
|
||||
"""Get current session IDs for a specific user.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
user_id : int
|
||||
The ID of the user to grab sessions for.
|
||||
|
||||
Returns
|
||||
-------
|
||||
list
|
||||
The active session IDs for the specific user ID.
|
||||
|
||||
"""
|
||||
sessions = get_activity()
|
||||
user_streams = [s['session_id']
|
||||
for s in sessions if s['user_id'] == user_id]
|
||||
return user_streams
|
||||
|
||||
|
||||
def terminate_session(session_id, message, notifier=None, username=None):
|
||||
"""Stop a streaming session.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
session_id : str
|
||||
The session ID of the stream to terminate.
|
||||
message : str
|
||||
The message to display to the user when terminating a stream.
|
||||
notifier : int
|
||||
Notification agent ID to send a message to (the default is None).
|
||||
username : str
|
||||
The username for the terminated session (the default is None).
|
||||
"""
|
||||
payload = {'apikey': TAUTULLI_APIKEY,
|
||||
'cmd': 'terminate_session',
|
||||
'session_id': session_id,
|
||||
@ -111,16 +171,79 @@ def terminate_session(session_id, message):
|
||||
response = req.json()
|
||||
|
||||
if response['response']['result'] == 'success':
|
||||
sys.stdout.write("Successfully killed Plex session: {0}.".format(session_id))
|
||||
sys.stdout.write(
|
||||
"Successfully killed Plex session: {0}.".format(session_id))
|
||||
if notifier:
|
||||
if username:
|
||||
body = BODY_TEXT_USER.format(user=username,
|
||||
message=message)
|
||||
else:
|
||||
body = BODY_TEXT.format(id=session_id, message=message)
|
||||
send_notification(SUBJECT_TEXT, body, notifier)
|
||||
else:
|
||||
raise Exception(response['response']['message'])
|
||||
except Exception as e:
|
||||
sys.stderr.write("Tautulli API 'terminate_session' request failed: {0}.".format(e))
|
||||
sys.stderr.write(
|
||||
"Tautulli API 'terminate_session' request failed: {0}.".format(e))
|
||||
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()
|
||||
checked_time = 0
|
||||
# Continue checking 2 intervals past the allowed limit in order to
|
||||
# account for system variances.
|
||||
check_limit = limit + (interval * 2)
|
||||
|
||||
while checked_time < check_limit:
|
||||
sessions = get_activity()
|
||||
found_session = False
|
||||
|
||||
for session in sessions:
|
||||
if session['session_id'] == session_id:
|
||||
found_session = True
|
||||
state = session['state']
|
||||
now = datetime.now()
|
||||
checked_time = (now - start).total_seconds()
|
||||
|
||||
if state == 'paused':
|
||||
if checked_time >= limit:
|
||||
terminate_session(session_id, message, notify)
|
||||
return
|
||||
else:
|
||||
sleep(interval)
|
||||
elif state == 'playing' or state == 'buffering':
|
||||
sys.stdout.write(
|
||||
"Session '{}' has resumed, ".format(session_id) +
|
||||
"stopping monitoring.")
|
||||
return
|
||||
if not found_session:
|
||||
sys.stdout.write(
|
||||
"Session '{}' is no longer active ".format(session_id) +
|
||||
"on the server, stopping monitoring.")
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Killing Plex streams from Tautulli.")
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Killing Plex streams from Tautulli.")
|
||||
parser.add_argument('--jbop', required=True, choices=SELECTOR,
|
||||
help='Kill selector.\nChoices: (%(choices)s)')
|
||||
parser.add_argument('--userId', type=int,
|
||||
@ -129,10 +252,15 @@ if __name__ == "__main__":
|
||||
help='The username of the person streaming.')
|
||||
parser.add_argument('--sessionId', required=True,
|
||||
help='The unique identifier for the stream.')
|
||||
parser.add_argument('--notify', type=int,
|
||||
help='Notification Agent ID number to Agent to send ' +
|
||||
'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='+',
|
||||
help='Message to send to user whose stream is killed.')
|
||||
parser.add_argument('--notify', type=int,
|
||||
help='Notification Agent ID number to Agent to send notification.')
|
||||
|
||||
opts = parser.parse_args()
|
||||
|
||||
@ -142,12 +270,11 @@ if __name__ == "__main__":
|
||||
message = ''
|
||||
|
||||
if opts.jbop == 'stream':
|
||||
terminate_session(opts.sessionId, message)
|
||||
terminate_session(opts.sessionId, message, opts.notify, opts.username)
|
||||
elif opts.jbop == 'allStreams':
|
||||
streams = get_activity(opts.userId)
|
||||
streams = get_user_session_ids(opts.userId)
|
||||
for session_id in streams:
|
||||
terminate_session(session_id, message)
|
||||
|
||||
if opts.notify:
|
||||
BODY_TEXT = BODY_TEXT.format(user=opts.username, message=message)
|
||||
send_notification(SUBJECT_TEXT, BODY_TEXT, opts.notify)
|
||||
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,81 +1,166 @@
|
||||
## README
|
||||
# README
|
||||
|
||||
Killing streams is a Plex Pass only feature. So these scripts will only work for Plex Pass users.
|
||||
Killing streams is a Plex Pass only feature. So these scripts will **only** work for Plex Pass users.
|
||||
|
||||
## `kill_stream.py` examples:
|
||||
|
||||
### Kill transcodes
|
||||
|
||||
### Kill_stream.py examples:
|
||||
Triggers: Playback Start
|
||||
Conditions: \[ `Transcode Decision` | `is` | `transcode` \]
|
||||
|
||||
#### Arguments examples:
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage Transcoding streams are not allowed.
|
||||
```
|
||||
|
||||
Kill the one offending stream with a custom message and send notification to notfication agent ID 1
|
||||
|
||||
--jbop stream --userId {user_id} --username {username} --sessionId {session_id} --killMessage You did something wrong. --notify 1
|
||||
### Kill non-local streams paused for a long time
|
||||
|
||||
Kill all the offending users streams with a custom message and send notification to notfication agent ID 1
|
||||
|
||||
--jbop allStreams --userId {user_id} --username {username} --sessionId {session_id} --killMessage You did something wrong. --notify 1
|
||||
_The default values will kill anything paused for over 20 minutes, checking every 30 seconds._
|
||||
|
||||
Kill the one offending stream with default message
|
||||
Script Timeout: 0 _**Important!**_
|
||||
Triggers: Playback Paused
|
||||
Conditions: \[ `Stream Local` | `is not` | `1` \]
|
||||
|
||||
--jbop stream --userId {user_id} --username {username} --sessionId {session_id}
|
||||
Arguments:
|
||||
```
|
||||
--jbop paused --sessionId {session_id} --killMessage Your stream was paused for over 20 minutes and has been automatically stopped for you.
|
||||
```
|
||||
|
||||
### Kill streams paused for a custom time
|
||||
|
||||
#### Condition Examples:
|
||||
_This is an example of customizing the paused stream monitoring to check every 15 seconds, and kill any stream paused for over 5 minutes._
|
||||
|
||||
Kill transcodes:
|
||||
Script Timeout: 0 _**Important!**_
|
||||
Triggers: Playback Paused
|
||||
|
||||
Set Trigger: Playback Start
|
||||
Set Conditions: [ {Transcode Decision} | {is} | {transcode} ]
|
||||
Arguments:
|
||||
```
|
||||
--jbop paused --interval 15 --limit 300 --sessionId {session_id} --killMessage Your stream was paused for over 5 minutes and has been automatically stopped for you.
|
||||
```
|
||||
|
||||
Kill paused transcodes:
|
||||
|
||||
Set Trigger: Playback Paused
|
||||
Set Conditions: [ {Transcode Decision} | {is} | {transcode} ]
|
||||
### Kill paused transcodes
|
||||
|
||||
Limit User stream count, kill last stream:
|
||||
|
||||
Set Trigger: Playback Start
|
||||
Set Conditions: [ {User Streams} | {is greater than} | {3} ]
|
||||
Triggers: Playback Paused
|
||||
Conditions: \[ `Transcode Decision` | `is` | `transcode` \]
|
||||
|
||||
IP Whitelist:
|
||||
|
||||
Set Trigger: Playback Start
|
||||
Set Conditions: [ {IP Address} | {is not} | {192.168.0.100 or 192.168.0.101} ]
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage Paused streams are automatically stopped.
|
||||
```
|
||||
|
||||
Kill by platform:
|
||||
|
||||
Set Trigger: Playback Start
|
||||
Set Conditions: [ {Platform} | {is} | {Roku or Android} ]
|
||||
### Limit User stream count, kill last stream
|
||||
|
||||
Kill transcode by library:
|
||||
|
||||
Set Trigger: Playback Start
|
||||
Set Conditions: [ {Transcode Decision} | {is} | {transcode} ]
|
||||
[ {Library Name} | {is} | {4K Movies} ]
|
||||
Triggers: Playback Start
|
||||
Conditions: \[ `User Streams` | `is greater than` | `3` \]
|
||||
|
||||
Kill transcode by original resolution:
|
||||
|
||||
Set Trigger: Playback Start
|
||||
Set Conditions: [ {Transcode Decision} | {is} | {transcode} ]
|
||||
[ {Video Resolution} | {is} | {1080 or 720}]
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage You are only allowed 3 streams.
|
||||
```
|
||||
|
||||
Kill transcode by bitrate:
|
||||
|
||||
Set Trigger: Playback Start
|
||||
Set Conditions: [ {Transcode Decision} | {is} | {transcode} ]
|
||||
[ {Bitrate} | {is greater than} | {4000} ]
|
||||
### IP Whitelist
|
||||
|
||||
Kill by hours of the day:
|
||||
|
||||
Set Trigger: Playback Start
|
||||
Set Conditions: [ {Timestamp} | {begins with} | {09 or 10} ]
|
||||
# Killing any streams from 9am to 11am
|
||||
Triggers: Playback Start
|
||||
Conditions: \[ `IP Address` | `is not` | `192.168.0.100 or 192.168.0.101` \]
|
||||
|
||||
Kill non local streams:
|
||||
|
||||
Set Trigger: Playback Start
|
||||
Set Conditions: [ {Stream location} | {is} | {wan} ]
|
||||
or
|
||||
Set Conditions: [ {Stream location} | {is not} | {lan} ]
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage {ip_address} is not allowed to access {server_name}.
|
||||
```
|
||||
|
||||
### Kill by platform
|
||||
|
||||
Triggers: Playback Start
|
||||
Conditions: \[ `Platform` | `is` | `Roku or Android` \]
|
||||
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage {platform} is not allowed on {server_name}.
|
||||
```
|
||||
|
||||
### Kill transcode by library
|
||||
|
||||
Triggers: Playback Start
|
||||
Conditions:
|
||||
* \[ `Transcode Decision` | `is` | `transcode` \]
|
||||
* \[ `Library Name` | `is` | `4K Movies` \]
|
||||
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage Transcoding streams are not allowed from the 4K Movies library.
|
||||
```
|
||||
|
||||
### Kill transcode by original resolution
|
||||
|
||||
Triggers: Playback Start
|
||||
Conditions:
|
||||
* \[ `Transcode Decision` | `is` | `transcode` \]
|
||||
* \[ `Video Resolution` | `is` | `1080 or 720`\]
|
||||
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage Transcoding streams are not allowed for {stream_video_resolution}p streams.
|
||||
```
|
||||
|
||||
### Kill transcode by bitrate
|
||||
|
||||
Triggers: Playback Start
|
||||
Conditions:
|
||||
* \[ `Transcode Decision` | `is` | `transcode` \]
|
||||
* \[ `Bitrate` | `is greater than` | `4000` \]
|
||||
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage Transcoding streams are not allowed from over 4 Mbps (Yours: {stream_bitrate}).
|
||||
```
|
||||
|
||||
### Kill by hours of the day
|
||||
|
||||
_Kills any streams during 9 AM to 10 AM._
|
||||
|
||||
Triggers: Playback Start
|
||||
Conditions: \[ `Timestamp` | `begins with` | `09 or 10` \]
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage {server_name} is unavailable between 9 and 10 AM.
|
||||
```
|
||||
|
||||
### Kill non local streams
|
||||
|
||||
Triggers: Playback Start
|
||||
Conditions: \[ `Stream Local` | `is not` | `1` \]
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --killMessage {server_name} only allows local streams.
|
||||
```
|
||||
|
||||
### Kill transcodes and send a notification to agent 1
|
||||
|
||||
Triggers: Playback Start
|
||||
Conditions: \[ `Transcode Decision` | `is` | `transcode` \]
|
||||
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id} --notify 1 --killMessage Transcoding streams are not allowed.
|
||||
```
|
||||
|
||||
### Kill transcodes using the default message
|
||||
|
||||
Triggers: Playback Start
|
||||
Conditions: \[ `Transcode Decision` | `is` | `transcode` \]
|
||||
|
||||
Arguments:
|
||||
```
|
||||
--jbop stream --username {username} --sessionId {session_id}
|
||||
```
|
||||
|
||||
### Kill all of a user's streams with notification
|
||||
|
||||
Triggers: Playback Start
|
||||
Conditions: \[ `Username` | `is` | `Bob` \]
|
||||
|
||||
Arguments:
|
||||
```
|
||||
--jbop allStreams --userId {user_id} --notify 1 --killMessage Hey Bob, we need to talk!
|
||||
```
|
||||
|
@ -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…
Reference in New Issue
Block a user