Skip to content

Instantly share code, notes, and snippets.

@Hellowlol
Forked from JonnyWong16/update_all_metadata.py
Last active August 19, 2017 21:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hellowlol/5a1355fbb0ab71ac25f4f8ee232be36d to your computer and use it in GitHub Desktop.
Save Hellowlol/5a1355fbb0ab71ac25f4f8ee232be36d to your computer and use it in GitHub Desktop.
Updates all metadata in the PlexPy database after moving Plex libraries.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Description: Updates all metadata in the PlexPy database after moving Plex libraries.
# Author: /u/SwiftPanda16
# Requires: plexapi, requests
from plexapi.server import PlexServer
import requests
### EDIT SETTINGS ###
## NOTE: Only works with movie and tv show libraries.
## NOTE: Script requires 'api_sql = 1' to be enabled in the PlexPy config.ini file.
PLEXPY_URL = 'http://localhost:8181'
PLEXPY_APIKEY = 'xxxxxxxxxx'
PLEX_URL = 'http://localhost:32400'
PLEX_TOKEN = 'xxxxxxxxxx'
FALLBACK_MATCH_TITLE_YEAR = True # True or False, fallback to matching by title and year if matching my ID fails
DRY_RUN = True # True to dry run without making changes to the PlexPy database, False to make changes
## CODE BELOW ##
def get_id_from_guid(guid):
id = None
if 'imdb://' in guid:
id = guid.split('imdb://')[1].split('?')[0]
elif 'themoviedb://' in guid:
id = guid.split('themoviedb://')[1].split('?')[0]
elif 'thetvdb://' in guid:
id = guid.split('thetvdb://')[1].split('?')[0].split('/')[0]
elif 'thetvdbdvdorder://' in guid:
id = guid.split('thetvdbdvdorder://')[1].split('?')[0].split('/')[0]
return id
def main():
new_key_map = {}
old_key_map = {}
COUNT = 0
# Check for DRY_RUN. Backup PlexPy database if needed.
if DRY_RUN:
print("Dry run enabled. No changes will be made to the PlexPy database.")
else:
print("Not dry run. Creating a backup of the PlexPy database.")
params = {'cmd': 'backup_db',
'apikey': PLEXPY_APIKEY,
}
requests.post(PLEXPY_URL.rstrip('/') + '/api/v2', params=params)
# Get all old items from the PlexPy database (using raw SQL)
print("Retrieving all history items from the PlexPy database...")
params = {'cmd': 'sql',
'apikey': PLEXPY_APIKEY,
'query': 'SELECT rating_key, grandparent_rating_key, title, grandparent_title, year, media_type, guid FROM session_history_metadata;'
}
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=params).json()
if r['response']['result'] == 'error':
print("Error retrieving PlexPy history: {}".format(r['response']['message']))
print("Exiting script...")
return
else:
for row in r['response']['data']:
if row['media_type'] not in ('movie', 'episode'):
continue
id = get_id_from_guid(row['guid'])
if id:
key = row['grandparent_rating_key'] or row['rating_key']
media_type = 'show' if row['media_type'] == 'episode' else row['media_type']
title = row['grandparent_title'] or row['title']
year = row['year']
old_key_map[id] = (key, media_type, title, year)
#print(id, key, title)
else:
title = row['grandparent_title'] or row['title']
print("...Invalid guid for '{title}' in the PlexPy database. Guid: {guid}".format(title=title, guid=row['guid']))
old_title_map = {(title, year): (id, key, media_type) for id, (key, media_type, title, year) in old_key_map.items()}
# Get all new items from the Plex server
print("Retrieving all library items from the Plex server...")
plex = PlexServer(PLEX_URL, PLEX_TOKEN)
for library in plex.library.sections():
if library.type not in ('movie', 'show') or library.agent == 'com.plexapp.agents.none':
print("...Skipping library: {title}".format(title=library.title))
continue
print("...Scanning library: {title}".format(title=library.title))
for item in library.all():
id = get_id_from_guid(item.guid)
if id:
new_key_map[id] = (item.ratingKey, item.type, item.title, str(item.year))
else:
print("Missing guid for '{item.title}' in the Plex library. Skipping...".format(item=item))
new_title_map = {(title, year): (id, key, media_type) for id, (key, media_type, title, year) in new_key_map.items()}
# Update metadata in the PlexPy database
print("{}Updating all metadata in the PlexPy database...".format("(DRY RUN) " if DRY_RUN else ""))
for id, (old_rating_key, old_type, title, year) in old_key_map.items():
new_rating_key, new_type, _, _ = new_key_map.get(id, (None, None, None, None))
if not new_rating_key and FALLBACK_MATCH_TITLE_YEAR:
_, new_rating_key, new_type = new_title_map.get((title, year), (None, None, None))
if new_rating_key:
if new_rating_key != old_rating_key and new_type == old_type:
if not DRY_RUN:
params = {'cmd': 'update_metadata_details',
'apikey': PLEXPY_APIKEY,
'old_rating_key': old_rating_key,
'new_rating_key': new_rating_key,
'media_type': new_type}
requests.post(PLEXPY_URL + '/api/v2', params=params)
print("...Updated '{title} {year}' ({old} --> {new})".format(title=title.encode('UTF-8'),
year=year, old=old_rating_key, new=new_rating_key))
COUNT += 1
else:
print("...No mapping for the '{title} {year}' ({old}). Metadata not updated.".format(title=title.encode('UTF-8'), year=year, old=old_rating_key))
print('Updated metadata for %s items' % COUNT)
if __name__ == "__main__":
main()
print("Done.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment