forked from Admin9705/Multi-Session-PLEX-Killer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplex-session-killer.sh
172 lines (143 loc) · 5.89 KB
/
plex-session-killer.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/bin/bash
# ============================================================
# Multi-Server Tautulli Checker & Plex Session Killer
# ------------------------------------------------------------
# 1) Loops every WAIT_TIME seconds
# 2) For each Tautulli server, queries get_activity, groups by (username, session_id),
# writes lines to /tmp/user.log: "username session_id session_key server_api server_url"
# 3) We parse /tmp/user.log line by line, properly counting sessions per user
# 4) If user_counts[user] > MAX_STREAMS => kill them from the lines in user.log
#
# Dependencies: jq
# ============================================================
WAIT_TIME=60
MAX_STREAMS=2
USER_LOG="/tmp/user.log"
# Add an array of exempt users who won't be limited
EXEMPT_USERS=(
"user1"
"user2"
# Add more exempt users as needed
)
TAUTULLI_API_KEYS=(
"dad9bbb78bde43249754b630b58fbf7c" #server 1
"f0a6722ac8ec4899abef2e9f32c6d7ca" #server 2
"d02d602b0cb94070ad4055d4dbd6502e" #server 3
"e7981b9c0342423e9e064fbef1c7dcdc" #server 4
)
TAUTULLI_URLS=(
"http://10.0.0.10:8181/api/v2" #server 1
"http://10.0.0.10:8182/api/v2" #server 2
"http://10.0.0.10:8183/api/v2" #server 3
"http://10.0.0.10:8184/api/v2" #server 4
)
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}
# Function to check if a user is exempt
is_exempt_user() {
local check_user="$1"
for exempt_user in "${EXEMPT_USERS[@]}"; do
if [ "$check_user" = "$exempt_user" ]; then
return 0 # True, user is exempt
fi
done
return 1 # False, user is not exempt
}
gather_server_sessions() {
local apikey="$1"
local url="$2"
local server_name="$3"
log_message "[${server_name}] Querying Tautulli at ${url}"
local resp
resp=$(curl -s "${url}?apikey=${apikey}&cmd=get_activity")
if ! echo "$resp" | jq -e '.response.data.sessions' >/dev/null 2>&1; then
log_message "[${server_name}] WARNING: Invalid or empty JSON. Skipping."
return
fi
local sessions_array
sessions_array=$(echo "$resp" | jq '.response.data.sessions')
local count
count=$(echo "$sessions_array" | jq 'length')
log_message "[${server_name}] Found ${count} raw session object(s)."
if [ "$count" -gt 0 ]; then
log_message "[${server_name}] Processing sessions:"
echo "$sessions_array" | jq -r --arg ak "$apikey" --arg surl "$url" '.[] | select(.username != null and .username != "") | "\(.username)|\(.session_id)|\(.session_key)|\($ak)|\($surl)"' > /tmp/temp_sessions.log
while IFS='|' read -r username session_id session_key server_api server_url; do
log_message " User: $username, Session ID: $session_id"
echo "$username $session_id $session_key $server_api $server_url" >> "$USER_LOG"
done < /tmp/temp_sessions.log
rm -f /tmp/temp_sessions.log
fi
}
kill_user_sessions() {
local user="$1"
log_message "Terminating ALL sessions for user: $user"
grep "^$user " "$USER_LOG" | while read -r username session_id session_key apikey url; do
log_message " Terminating session ID: $session_id on server: $url"
local enc_user
enc_user=$(echo "$username" | sed 's/ /%20/g')
local msg="Too%20Many%20Streaming%20Sessions%20For%20USER%20${enc_user}%20between%20all%20PLEX%20servers!%20Only%20${MAX_STREAMS}%20are%20allowed%20at%20a%20time!"
local resp
resp=$(curl -s "${url}?apikey=${apikey}&cmd=terminate_session&session_id=${session_id}&session_key=${session_key}&message=${msg}")
log_message " Terminate response: ${resp}"
done
}
while true; do
log_message "Starting multi-server Tautulli check..."
# CRITICAL: Reset the user log file at the start of each cycle
rm -f "$USER_LOG"
touch "$USER_LOG"
# Reset the user_counts array completely for each new check
unset user_counts
declare -A user_counts
# 1) Gather lines from all servers
for i in 0 1 2 3; do
api_key="${TAUTULLI_API_KEYS[$i]}"
url="${TAUTULLI_URLS[$i]}"
server_name="Server $((i+1))"
if [ -z "$api_key" ] || [ -z "$url" ]; then
continue
fi
gather_server_sessions "$api_key" "$url" "$server_name"
done
# 2) Count sessions per user - ONLY from the current scan
if [ -s "$USER_LOG" ]; then
log_message "Processing user sessions from log file..."
while read -r line; do
# Extract username (first field)
username=$(echo "$line" | awk '{print $1}')
if [ -n "$username" ]; then
# Increment count for this user
user_counts["$username"]=$((${user_counts["$username"]:-0} + 1))
fi
done < "$USER_LOG"
# 3) Display user counts
log_message "User session counts:"
for user in "${!user_counts[@]}"; do
# Check if user is exempt
if is_exempt_user "$user"; then
log_message " $user: ${user_counts[$user]} session(s) [EXEMPT]"
else
log_message " $user: ${user_counts[$user]} session(s)"
fi
done
# 4) Check for users exceeding limits and terminate their sessions
for user in "${!user_counts[@]}"; do
# Skip exempt users
if is_exempt_user "$user"; then
log_message "USER $user is exempt from the stream limit (${user_counts[$user]} active streams)"
continue
fi
if [ "${user_counts[$user]}" -gt "$MAX_STREAMS" ]; then
log_message "USER $user has exceeded the stream limit! (${user_counts[$user]}/${MAX_STREAMS})"
kill_user_sessions "$user"
fi
done
else
log_message "No active sessions found."
fi
log_message "Check complete. Waiting ${WAIT_TIME} seconds for next run..."
echo ""
sleep "$WAIT_TIME"
done