#144 Added ability to sync watched status across all owned servers
This commit is contained in:
parent
e45ff63d9b
commit
1adcc9e41b
@ -31,7 +31,7 @@ Script Arguments:
|
||||
Taultulli > Settings > Notification Agents > New Script > Script Arguments:
|
||||
|
||||
Select: Notify on Watched
|
||||
Arguments: --ratingKey {rating_key} --userTo "Username2" "Username3" --userFrom {username}
|
||||
Arguments: --ratingKey {rating_key} --userTo "Username2=Server1" "Username3=Server1" --userFrom {username}={server_name}
|
||||
|
||||
Save
|
||||
Close
|
||||
@ -39,28 +39,26 @@ Taultulli > Settings > Notification Agents > New Script > Script Arguments:
|
||||
Example:
|
||||
Set in Tautulli in script notification agent or run manually
|
||||
|
||||
plex_api_share.py --userFrom USER1 --userTo USER2 --libraries Movies
|
||||
sync_watch_status.py --userFrom USER1=Server --userTo USER2=Server --libraries Movies
|
||||
- Synced watch status of {title from library} to {USER2}'s account.
|
||||
|
||||
plex_api_share.py --userFrom USER1 --userTo USER2 USER3 --allLibraries
|
||||
sync_watch_status.py --userFrom USER1=Server --userTo USER2=Server USER3=Server --allLibraries
|
||||
- Synced watch status of {title from library} to {USER2 or USER3}'s account.
|
||||
|
||||
Excluding;
|
||||
--libraries becomes excluded if --allLibraries is set
|
||||
sync_watch_status.py --userFrom USER1 --userTo USER2 --allLibraries --libraries Movies
|
||||
sync_watch_status.py --userFrom USER1=Server --userTo USER2=Server --allLibraries --libraries Movies
|
||||
- Shared [all libraries but Movies] with USER.
|
||||
|
||||
"""
|
||||
import requests
|
||||
import argparse
|
||||
from plexapi.myplex import MyPlexAccount
|
||||
from plexapi.server import PlexServer, CONFIG
|
||||
|
||||
# Using CONFIG file
|
||||
PLEX_URL = ''
|
||||
PLEX_TOKEN = ''
|
||||
|
||||
if not PLEX_URL:
|
||||
PLEX_URL = CONFIG.data['auth'].get('server_baseurl', '')
|
||||
# Using CONFIG file
|
||||
PLEX_TOKEN = ''
|
||||
|
||||
if not PLEX_TOKEN:
|
||||
PLEX_TOKEN = CONFIG.data['auth'].get('server_token', '')
|
||||
@ -78,41 +76,107 @@ if sess.verify is False:
|
||||
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
|
||||
account = MyPlexAccount(PLEX_TOKEN)
|
||||
|
||||
sections_lst = [x.title for x in plex.library.sections()]
|
||||
user_lst = [x.title for x in plex.myPlexAccount().users()]
|
||||
servers_dict = {acct.name: acct for acct in plex.myPlexAccount().resources()
|
||||
if 'server' in [acct.provides] and acct.ownerid == 0}
|
||||
# Adding admin account name to list
|
||||
user_lst.append(plex.myPlexAccount().title)
|
||||
sections_lst = []
|
||||
user_servers = {}
|
||||
admin_servers = {}
|
||||
server_users = account.users()
|
||||
user_server_dict = {'data': {}}
|
||||
user_data = user_server_dict['data']
|
||||
|
||||
# Finding and connecting to owned servers.
|
||||
print('Connecting to admin owned servers.')
|
||||
for resource in account.resources():
|
||||
if 'server' in [resource.provides] and resource.ownerid == 0:
|
||||
server_connect = resource.connect()
|
||||
admin_servers[resource.name] = server_connect
|
||||
# Pull section names to check against
|
||||
server_sections = [section.title for section in server_connect.library.sections()]
|
||||
sections_lst += server_sections
|
||||
|
||||
sections_lst = list(set(sections_lst))
|
||||
|
||||
# Add admin account
|
||||
user_data[account.title] = {'account': account,
|
||||
'servers': admin_servers}
|
||||
|
||||
# Finding what user has access to which admin owned servers
|
||||
for user in server_users:
|
||||
for server in user.servers:
|
||||
if admin_servers.get(server.name):
|
||||
user_servers[server.name] = admin_servers.get(server.name)
|
||||
if not user_data.get(user.title):
|
||||
user_data[user.title] = {'account': user,
|
||||
'servers': user_servers}
|
||||
|
||||
|
||||
def get_account(user):
|
||||
if user == plex.myPlexAccount().title:
|
||||
account = plex
|
||||
def get_account(user, server):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
user: str
|
||||
User's name
|
||||
server: str
|
||||
Server's name
|
||||
|
||||
Returns
|
||||
-------
|
||||
User server class
|
||||
|
||||
"""
|
||||
print('Checking {} on {}'.format(user, server))
|
||||
if user_server_dict['data'][user]['servers'].get(server):
|
||||
user_server = user_server_dict['data'][user]['servers'].get(server)
|
||||
baseurl = user_server._baseurl.split('.')
|
||||
url = ''.join([baseurl[0].replace('-', '.'),
|
||||
baseurl[-1].replace('direct', '')])
|
||||
if user == MyPlexAccount(PLEX_TOKEN).title:
|
||||
token = PLEX_TOKEN
|
||||
else:
|
||||
userAccount = user_server.myPlexAccount().user(user)
|
||||
token = userAccount.get_token(user_server.machineIdentifier)
|
||||
account = PlexServer(baseurl=url, token=token, session=sess)
|
||||
return account
|
||||
else:
|
||||
# Access Plex User's Account
|
||||
userAccount = plex.myPlexAccount().user(user)
|
||||
token = userAccount.get_token(plex.machineIdentifier)
|
||||
account = PlexServer(PLEX_URL, token)
|
||||
return account
|
||||
print('{} is not shared to {}'.format(user, server))
|
||||
exit()
|
||||
|
||||
|
||||
def mark_watached(sectionFrom, accountTo, userTo):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
sectionFrom: class
|
||||
Section class of sync from server
|
||||
accountTo: class
|
||||
User's server class of sync to user
|
||||
|
||||
"""
|
||||
# Check sections for watched items
|
||||
print('Marking watched...')
|
||||
sectionTo = accountTo.library.section(sectionFrom.title)
|
||||
for item in sectionFrom.search(unwatched=False):
|
||||
title = item.title.encode('utf-8')
|
||||
# Check movie media type
|
||||
if item.type == 'movie':
|
||||
accountTo.fetchItem(item.key).markWatched()
|
||||
print('Synced watch status of {} to {}\'s account.'.format(title, userTo))
|
||||
# Check show media type
|
||||
elif item.type == 'show':
|
||||
for episode in sectionFrom.searchEpisodes(unwatched=False, title=title):
|
||||
ep_title = episode.title.encode('utf-8')
|
||||
accountTo.fetchItem(episode.key).markWatched()
|
||||
print('Synced watch status of {} - {} to {}\'s account.'.format(title, ep_title, userTo))
|
||||
try:
|
||||
# Check movie media type
|
||||
if item.type == 'movie':
|
||||
watch_check = sectionTo.get(item.title)
|
||||
fetch_check = sectionTo.fetchItem(watch_check.key)
|
||||
if not fetch_check.isWatched:
|
||||
fetch_check.markWatched()
|
||||
print('Synced watch status of {} to {}\'s account.'.format(title, userTo))
|
||||
# Check show media type
|
||||
elif item.type == 'show':
|
||||
for episode in sectionFrom.searchEpisodes(unwatched=False, title=title):
|
||||
ep_title = episode.title.encode('utf-8')
|
||||
watch_check = sectionTo.get(item.title)
|
||||
fetch_check = sectionTo.fetchItem(watch_check.key)
|
||||
if not fetch_check.isWatched:
|
||||
fetch_check.markWatched()
|
||||
print('Synced watch status of {} - {} to {}\'s account.'.format(title, ep_title, userTo))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
@ -125,23 +189,16 @@ if __name__ == '__main__':
|
||||
'(choices: %(choices)s)')
|
||||
parser.add_argument('--allLibraries', action='store_true',
|
||||
help='Select all libraries.')
|
||||
parser.add_argument('--servers', nargs='*', choices=servers_dict.keys(),
|
||||
help='Space separated list of case sensitive names to process. Allowed names are: \n'
|
||||
'(choices: %(choices)s)')
|
||||
parser.add_argument('--ratingKey', nargs=1,
|
||||
help='Rating key of item whose watch status is to be synced.')
|
||||
requiredNamed.add_argument('--userFrom', choices=user_lst, metavar='username', required=True,
|
||||
help='Space separated list of case sensitive names to process. Allowed names are: \n'
|
||||
'(choices: %(choices)s)')
|
||||
requiredNamed.add_argument('--userTo', nargs='*', choices=user_lst, metavar='usernames', required=True,
|
||||
help='Space separated list of case sensitive names to process. Allowed names are: \n'
|
||||
'(choices: %(choices)s)')
|
||||
requiredNamed.add_argument('--userFrom', metavar='user=server', required=True,
|
||||
type=lambda kv: kv.split("="),
|
||||
help='Select user and server to sync from')
|
||||
requiredNamed.add_argument('--userTo', nargs='*', metavar='user=server', required=True,
|
||||
type=lambda kv: kv.split("="),
|
||||
help='Select user and server to sync to.')
|
||||
|
||||
opts = parser.parse_args()
|
||||
# print(opts)
|
||||
|
||||
# Create Sync-From user account
|
||||
plexFrom = get_account(opts.userFrom)
|
||||
|
||||
# Defining libraries
|
||||
libraries = ''
|
||||
@ -155,10 +212,12 @@ if __name__ == '__main__':
|
||||
sections_lst.remove(library)
|
||||
libraries = sections_lst
|
||||
|
||||
# Create Sync-From user account
|
||||
plexFrom = get_account(opts.userFrom[0], opts.userFrom[1])
|
||||
|
||||
# Go through list of users
|
||||
for user in opts.userTo:
|
||||
# Create Sync-To user account
|
||||
plexTo = get_account(user)
|
||||
plexTo = get_account(user[0], user[1])
|
||||
if libraries:
|
||||
# Go through Libraries
|
||||
for library in libraries:
|
||||
@ -166,12 +225,10 @@ if __name__ == '__main__':
|
||||
print('Checking library: {}'.format(library))
|
||||
# Check library for watched items
|
||||
section = plexFrom.library.section(library)
|
||||
mark_watached(section, plexTo, user)
|
||||
mark_watached(section, plexTo, user[0])
|
||||
except Exception as e:
|
||||
if str(e).startswith('Unknown'):
|
||||
print('Library ({}) does not have a watch status.'.format(library))
|
||||
elif str(e).startswith('Invalid'):
|
||||
print('Library ({}) not shared to user: {}.'.format(library, opts.userFrom))
|
||||
elif str(e).startswith('(404)'):
|
||||
print('Library ({}) not shared to user: {}.'.format(library, user))
|
||||
else:
|
||||
@ -179,9 +236,10 @@ if __name__ == '__main__':
|
||||
pass
|
||||
# Check rating key from Tautulli
|
||||
elif opts.ratingKey:
|
||||
item = plexTo.fetchItem(opts.ratingKey)
|
||||
title = item.title.encode('utf-8')
|
||||
print('Syncing watch status of {} to {}\'s account.'.format(title, user))
|
||||
item.markWatched()
|
||||
for key in opts.ratingKey:
|
||||
item = plexTo.fetchItem(int(key))
|
||||
title = item.title.encode('utf-8')
|
||||
print('Syncing watch status of {} to {}\'s account.'.format(title, user[0]))
|
||||
item.markWatched()
|
||||
else:
|
||||
print('No libraries or rating key provided.')
|
||||
|
Loading…
Reference in New Issue
Block a user