Compare commits

...

17 Commits

Author SHA1 Message Date
Scott Bressler
b2e7f05521
Merge f41e3fca69 into 9177c8b007 2025-04-01 07:23:49 -04:00
blacktwin
9177c8b007
Merge pull request #423 from noamokman/add-delay-to-kill-stream-script
Add delay to kill stream script
2025-03-28 12:41:59 -04:00
blacktwin
9f4a94a578
Merge pull request #421 from JonnyWong16/select_tmdb_poster
Add utility/select_tmdb_poster.py
2025-03-28 12:40:55 -04:00
blacktwin
071709171e
Merge pull request #406 from yuk7hi/master
Fix same server matching bug in watch status sync script
2025-03-28 12:40:23 -04:00
blacktwin
74369eacae
Merge pull request #438 from blacktwin/sync_env
Adding Environmental Variables for when running through Tautulli
2025-03-28 12:37:26 -04:00
blacktwin
c11db32b70 Adding Environmental Variables for when running through Tautulli 2025-03-28 12:29:40 -04:00
Noam Okman
4961e33a8e Add delay to kill stream script 2024-05-03 09:05:46 +03:00
JonnyWong16
93bfb92056
Fix typo 2024-03-03 23:45:24 -08:00
JonnyWong16
f9a2e28ab6
Fix typo 2024-03-01 00:08:59 -08:00
JonnyWong16
a6f7fa2ffd
Simplify reload 2024-02-28 19:52:46 -08:00
JonnyWong16
46071481a9
Print out current poster provider 2024-02-21 09:32:41 -08:00
JonnyWong16
2fd1481dea
Update select_tmdb_poster.py 2024-02-20 01:00:43 -08:00
JonnyWong16
c03ee8103c
Newline at end of file 2024-02-20 00:20:04 -08:00
JonnyWong16
0ff3c5dfc0
Rename --ignore_locked to --include_locked 2024-02-20 00:19:29 -08:00
JonnyWong16
d00dd4a840
Add utility/select_tmdb_poster.py 2024-02-18 12:20:44 -08:00
yuk7hi
ae89009073
Fix same server matching bug in watch status sync 2023-11-27 12:04:23 +05:30
Scott Bressler
f41e3fca69
Remove extra quote in docstring for media_manager 2022-12-03 05:10:01 -08:00
5 changed files with 130 additions and 7 deletions

View File

@ -592,6 +592,8 @@ if __name__ == "__main__":
help='Poster URL of the media') help='Poster URL of the media')
parser.add_argument('--richColor', type=arg_decoding, parser.add_argument('--richColor', type=arg_decoding,
help='Color of the rich message') help='Color of the rich message')
parser.add_argument('--delay', type=int, default=0,
help='Delay in seconds before killing the stream.')
parser.add_argument("--debug", action='store_true', parser.add_argument("--debug", action='store_true',
help='Enable debug messages.') help='Enable debug messages.')
@ -623,6 +625,9 @@ if __name__ == "__main__":
else: else:
kill_message = 'The server owner has ended the stream.' kill_message = 'The server owner has ended the stream.'
if opts.delay:
time.sleep(opts.delay)
if opts.jbop == 'stream': if opts.jbop == 'stream':
tautulli_stream.terminate(kill_message) tautulli_stream.terminate(kill_message)
notify(opts, kill_message, 'Stream', tautulli_stream, tautulli_server) notify(opts, kill_message, 'Stream', tautulli_stream, tautulli_server)

View File

@ -185,6 +185,21 @@ Arguments:
--jbop stream --username {username} --sessionId {session_id} --jbop stream --username {username} --sessionId {session_id}
``` ```
### Kill transcodes with a delay
_This will wait 10 seconds before killing the stream._
Triggers:
* Playback Start
* Transcode Decision Change
Conditions: \[ `Transcode Decision` | `is` | `transcode` \]
Arguments:
```
--jbop stream --username {username} --sessionId {session_id} --killMessage 'Transcoding streams are not allowed.' --delay 10
```
### Kill all of a user's streams with notification ### Kill all of a user's streams with notification
Triggers: Playback Start Triggers: Playback Start

View File

@ -23,7 +23,7 @@ Enabling Scripts in Tautulli:
python media_manager.py --libraries "TV Shows" --select watched --users User1 User2 --action show python media_manager.py --libraries "TV Shows" --select watched --users User1 User2 --action show
Find library items that were last played before 2021-01-01 Find library items that were last played before 2021-01-01
python media_manger.py --libraries "Movies --select lastPlayed --date 2021-01-01 --action show python media_manger.py --libraries Movies --select lastPlayed --date 2021-01-01 --action show
Find library items that have audience rating less than 6 Find library items that have audience rating less than 6
python3 media_manager.py --libraries "Movies 2022" --select rating --selectValue "<_6" --action show python3 media_manager.py --libraries "Movies 2022" --select rating --selectValue "<_6" --action show

View File

@ -0,0 +1,91 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Description: Selects the default TMDB poster if no poster is selected
or the current poster is from Gracenote.
Author: /u/SwiftPanda16
Requires: plexapi
Usage:
* Change the posters for an entire library:
python select_tmdb_poster.py --library "Movies"
* Change the poster for a specific item:
python select_tmdb_poster.py --rating_key 1234
* By default locked posters are skipped. To update locked posters:
python select_tmdb_poster.py --library "Movies" --include_locked
Tautulli script trigger:
* Notify on recently added
Tautulli script conditions:
* Filter which media to select the poster. Examples:
[ Media Type | is | movie ]
Tautulli script arguments:
* Recently Added:
--rating_key {rating_key}
'''
import argparse
import os
import plexapi.base
from plexapi.server import PlexServer
plexapi.base.USER_DONT_RELOAD_FOR_KEYS.add('fields')
# ## OVERRIDES - ONLY EDIT IF RUNNING SCRIPT WITHOUT TAUTULLI ##
PLEX_URL = ''
PLEX_TOKEN = ''
# Environmental Variables
PLEX_URL = PLEX_URL or os.getenv('PLEX_URL', PLEX_URL)
PLEX_TOKEN = PLEX_TOKEN or os.getenv('PLEX_TOKEN', PLEX_TOKEN)
def select_tmdb_poster_library(library, include_locked=False):
for item in library.all(includeGuids=False):
# Only reload for fields
item.reload(**{k: 0 for k, v in item._INCLUDES.items()})
select_tmdb_poster_item(item, include_locked=include_locked)
def select_tmdb_poster_item(item, include_locked=False):
if item.isLocked('thumb') and not include_locked:
print(f"Locked poster for {item.title}. Skipping.")
return
posters = item.posters()
selected_poster = next((p for p in posters if p.selected), None)
if selected_poster is None:
print(f"WARNING: No poster selected for {item.title}.")
else:
skipping = ' Skipping.' if selected_poster.provider != 'gracenote' else ''
print(f"Poster provider is '{selected_poster.provider}' for {item.title}.{skipping}")
if selected_poster is None or selected_poster.provider == 'gracenote':
# Fallback to first poster if no TMDB posters are available
tmdb_poster = next((p for p in posters if p.provider == 'tmdb'), posters[0])
# Selecting the poster automatically locks it
tmdb_poster.select()
print(f"Selected {tmdb_poster.provider} poster for {item.title}.")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--rating_key', type=int)
parser.add_argument('--library')
parser.add_argument('--include_locked', action='store_true')
opts = parser.parse_args()
plex = PlexServer(PLEX_URL, PLEX_TOKEN)
if opts.rating_key:
item = plex.fetchItem(opts.rating_key)
select_tmdb_poster_item(item, opts.include_locked)
elif opts.library:
library = plex.library.section(opts.library)
select_tmdb_poster_library(library, opts.include_locked)
else:
print("No --rating_key or --library specified. Exiting.")

View File

@ -59,6 +59,7 @@ from __future__ import print_function
from __future__ import unicode_literals from __future__ import unicode_literals
from builtins import object from builtins import object
import argparse import argparse
import os
from plexapi.myplex import MyPlexAccount from plexapi.myplex import MyPlexAccount
from plexapi.server import PlexServer from plexapi.server import PlexServer
from plexapi.server import CONFIG from plexapi.server import CONFIG
@ -66,17 +67,28 @@ from requests import Session
from requests.adapters import HTTPAdapter from requests.adapters import HTTPAdapter
from requests.exceptions import RequestException from requests.exceptions import RequestException
# Using CONFIG file # Manual
PLEX_URL = ''
PLEX_TOKEN = '' PLEX_TOKEN = ''
TAUTULLI_URL = '' TAUTULLI_URL = ''
TAUTULLI_APIKEY = '' TAUTULLI_APIKEY = ''
# Environmental Variables
PLEX_URL = os.getenv('PLEX_URL', PLEX_URL)
PLEX_TOKEN = os.getenv('PLEX_TOKEN', PLEX_TOKEN)
TAUTULLI_URL = os.getenv('TAUTULLI_URL', TAUTULLI_URL)
TAUTULLI_APIKEY = os.getenv('TAUTULLI_APIKEY', TAUTULLI_APIKEY)
TAUTULLI_ENCODING = os.getenv('TAUTULLI_ENCODING', 'UTF-8')
# Using CONFIG file
if not PLEX_URL:
PLEX_URL = CONFIG.data['auth'].get('server_baseurl', '')
if not PLEX_TOKEN: if not PLEX_TOKEN:
PLEX_TOKEN = CONFIG.data['auth'].get('server_token') PLEX_TOKEN = CONFIG.data['auth'].get('server_token', '')
if not TAUTULLI_URL: if not TAUTULLI_URL:
TAUTULLI_URL = CONFIG.data['auth'].get('tautulli_baseurl') TAUTULLI_URL = CONFIG.data['auth'].get('tautulli_baseurl', '')
if not TAUTULLI_APIKEY: if not TAUTULLI_APIKEY:
TAUTULLI_APIKEY = CONFIG.data['auth'].get('tautulli_apikey') TAUTULLI_APIKEY = CONFIG.data['auth'].get('tautulli_apikey', '')
VERIFY_SSL = False VERIFY_SSL = False
@ -195,7 +207,7 @@ class Tautulli(object):
class Plex(object): class Plex(object):
def __init__(self, token, url=None): def __init__(self, token, url=None):
if token and not url: if token and not url:
self.account = MyPlexAccount(token) self.account = MyPlexAccount(token=token)
if token and url: if token and url:
session = Connection().session session = Connection().session
self.server = PlexServer(baseurl=url, token=token, session=session) self.server = PlexServer(baseurl=url, token=token, session=session)
@ -526,7 +538,7 @@ if __name__ == '__main__':
for user in plexTo: for user in plexTo:
username, server = user username, server = user
if server == serverFrom: if server.friendlyName == serverFrom:
same_server = True same_server = True
sync_watch_status(watched_lst, _library.title, server, username, same_server) sync_watch_status(watched_lst, _library.title, server, username, same_server)