Add metadata labels to database

This commit is contained in:
JonnyWong16 2016-04-30 15:19:08 -07:00
parent 03faebe776
commit ae60b21375
7 changed files with 216 additions and 69 deletions

View file

@ -438,7 +438,8 @@ def dbcheck():
'parent_media_index INTEGER, section_id INTEGER, thumb TEXT, parent_thumb TEXT, grandparent_thumb TEXT, '
'art TEXT, media_type TEXT, year INTEGER, originally_available_at TEXT, added_at INTEGER, updated_at INTEGER, '
'last_viewed_at INTEGER, content_rating TEXT, summary TEXT, tagline TEXT, rating TEXT, '
'duration INTEGER DEFAULT 0, guid TEXT, directors TEXT, writers TEXT, actors TEXT, genres TEXT, studio TEXT)'
'duration INTEGER DEFAULT 0, guid TEXT, directors TEXT, writers TEXT, actors TEXT, genres TEXT, studio TEXT, '
'labels TEXT)'
)
# users table :: This table keeps record of the friends list
@ -692,6 +693,15 @@ def dbcheck():
'ALTER TABLE session_history_metadata ADD COLUMN section_id INTEGER'
)
# Upgrade session_history_metadata table from earlier versions
try:
c_db.execute('SELECT labels FROM session_history_metadata')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table session_history_metadata.")
c_db.execute(
'ALTER TABLE session_history_metadata ADD COLUMN labels TEXT'
)
# Upgrade session_history_media_info table from earlier versions
try:
c_db.execute('SELECT transcode_decision FROM session_history_media_info')

View file

@ -278,6 +278,7 @@ class ActivityProcessor(object):
writers = ";".join(metadata['writers'])
actors = ";".join(metadata['actors'])
genres = ";".join(metadata['genres'])
labels = ";".join(metadata['labels'])
# Build media item title
if session['media_type'] == 'episode' or session['media_type'] == 'track':
@ -292,9 +293,9 @@ class ActivityProcessor(object):
'grandparent_rating_key, title, parent_title, grandparent_title, full_title, media_index, ' \
'parent_media_index, section_id, thumb, parent_thumb, grandparent_thumb, art, media_type, ' \
'year, originally_available_at, added_at, updated_at, last_viewed_at, content_rating, ' \
'summary, tagline, rating, duration, guid, directors, writers, actors, genres, studio) VALUES ' \
'(last_insert_rowid(), ' \
'?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
'summary, tagline, rating, duration, guid, directors, writers, actors, genres, studio, labels) ' \
'VALUES (last_insert_rowid(), ' \
'?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
args = [session['rating_key'], session['parent_rating_key'], session['grandparent_rating_key'],
session['title'], session['parent_title'], session['grandparent_title'], full_title,
@ -303,7 +304,7 @@ class ActivityProcessor(object):
metadata['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'],
metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'],
metadata['rating'], metadata['duration'], metadata['guid'], directors, writers, actors, genres,
metadata['studio']]
metadata['studio'], labels]
# logger.debug(u"PlexPy ActivityProcessor :: Writing session_history_metadata transaction...")
self.db.action(query=query, args=args)

View file

@ -418,6 +418,7 @@ _CONFIG_DEFINITIONS = {
'TWITTER_ON_PMSUPDATE': (int, 'Twitter', 0),
'UPDATE_DB_INTERVAL': (int, 'General', 24),
'UPDATE_SECTION_IDS': (int, 'General', 1),
'UPDATE_LABELS': (int, 'General', 1),
'VERIFY_SSL_CERT': (bool_int, 'Advanced', 1),
'VIDEO_LOGGING_ENABLE': (int, 'Monitoring', 1),
'XBMC_ENABLED': (int, 'XBMC', 0),

View file

@ -1155,6 +1155,7 @@ class DataFactory(object):
writers = ";".join(metadata['writers'])
actors = ";".join(metadata['actors'])
genres = ";".join(metadata['genres'])
labels = ";".join(metadata['labels'])
#logger.info(u"PlexPy DataFactory :: Updating metadata in the database for rating key: %s." % new_rating_key)
monitor_db = database.MonitorDatabase()

View file

@ -18,18 +18,9 @@ from plexpy import logger, datatables, common, database, helpers, session
def update_section_ids():
from plexpy import pmsconnect, activity_pinger
#import threading
plexpy.CONFIG.UPDATE_SECTION_IDS = -1
#logger.debug(u"PlexPy Libraries :: Disabling monitoring while update in progress.")
#plexpy.schedule_job(activity_pinger.check_active_sessions, 'Check for active sessions',
# hours=0, minutes=0, seconds=0)
#plexpy.schedule_job(activity_pinger.check_recently_added, 'Check for recently added items',
# hours=0, minutes=0, seconds=0)
#plexpy.schedule_job(activity_pinger.check_server_response, 'Check for server response',
# hours=0, minutes=0, seconds=0)
monitor_db = database.MonitorDatabase()
try:
@ -44,9 +35,6 @@ def update_section_ids():
logger.warn(u"PlexPy Libraries :: Unable to update section_id's in database.")
plexpy.CONFIG.UPDATE_SECTION_IDS = 1
plexpy.CONFIG.write()
#logger.debug(u"PlexPy Libraries :: Re-enabling monitoring.")
#plexpy.initialize_scheduler()
return None
if not history_results:
@ -54,13 +42,7 @@ def update_section_ids():
plexpy.CONFIG.write()
return None
logger.info(u"PlexPy Libraries :: Updating section_id's in database.")
# Add thread filter to the logger
#logger.debug(u"PlexPy Libraries :: Disabling logging in the current thread while update in progress.")
#thread_filter = logger.NoThreadFilter(threading.current_thread().name)
#for handler in logger.logger.handlers:
# handler.addFilter(thread_filter)
logger.debug(u"PlexPy Libraries :: Updating section_id's in database.")
# Get rating_key: section_id mapping pairs
key_mappings = {}
@ -94,11 +76,6 @@ def update_section_ids():
else:
error_keys.add(item['rating_key'])
# Remove thread filter from the logger
#for handler in logger.logger.handlers:
# handler.removeFilter(thread_filter)
#logger.debug(u"PlexPy Libraries :: Re-enabling logging in the current thread.")
if error_keys:
logger.info(u"PlexPy Libraries :: Updated all section_id's in database except for rating_keys: %s." %
', '.join(str(key) for key in error_keys))
@ -108,11 +85,87 @@ def update_section_ids():
plexpy.CONFIG.UPDATE_SECTION_IDS = 0
plexpy.CONFIG.write()
#logger.debug(u"PlexPy Libraries :: Re-enabling monitoring.")
#plexpy.initialize_scheduler()
return True
def update_labels():
from plexpy import pmsconnect
plexpy.CONFIG.UPDATE_LABELS = -1
monitor_db = database.MonitorDatabase()
try:
query = 'SELECT section_id, section_type FROM library_sections'
library_results = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for update_labels: %s." % e)
logger.warn(u"PlexPy Libraries :: Unable to update labels in database.")
plexpy.CONFIG.UPDATE_LABELS = 1
plexpy.CONFIG.write()
return None
if not library_results:
plexpy.CONFIG.UPDATE_LABELS = 0
plexpy.CONFIG.write()
return None
logger.debug(u"PlexPy Libraries :: Updating labels in database.")
# Get rating_key: section_id mapping pairs
key_mappings = {}
pms_connect = pmsconnect.PmsConnect()
for library in library_results:
section_id = library['section_id']
section_type = library['section_type']
if section_type != 'photo':
library_children = []
library_labels = pms_connect.get_library_label_details(section_id=section_id)
if library_labels:
for label in library_labels:
library_children = pms_connect.get_library_children_details(section_id=section_id,
section_type=section_type,
label_key=label['label_key'])
if library_children:
children_list = library_children['childern_list']
rating_key_list = [child['rating_key'] for child in children_list]
for rating_key in [child['rating_key'] for child in children_list]:
if key_mappings.get(rating_key):
key_mappings[rating_key].append(label['label_title'])
else:
key_mappings[rating_key] = [label['label_title']]
else:
logger.warn(u"PlexPy Libraries :: Unable to get a list of library items for section_id %s."
% section_id)
error_keys = set()
for rating_key, labels in key_mappings.iteritems():
try:
labels = ';'.join(labels)
monitor_db.action('UPDATE session_history_metadata SET labels = ? '
'WHERE rating_key = ? OR parent_rating_key = ? OR grandparent_rating_key = ? ',
args=[labels, rating_key, rating_key, rating_key])
except:
error_keys.add(rating_key)
if error_keys:
logger.info(u"PlexPy Libraries :: Updated all labels in database except for rating_keys: %s." %
', '.join(str(key) for key in error_keys))
else:
logger.info(u"PlexPy Libraries :: Updated all labels in database.")
plexpy.CONFIG.UPDATE_LABELS = 0
plexpy.CONFIG.write()
return True
class Libraries(object):
def __init__(self):

View file

@ -148,6 +148,12 @@ def extract_plexwatch_xml(xml=None):
for i in genre_elem:
genres.append(helpers.get_xml_attr(i, 'tag'))
labels = []
if a.getElementsByTagName('Lables'):
label_elem = a.getElementsByTagName('Lables')
for i in label_elem:
labels.append(helpers.get_xml_attr(i, 'tag'))
output = {'added_at': added_at,
'art': art,
'duration': duration,
@ -196,7 +202,8 @@ def extract_plexwatch_xml(xml=None):
'writers': writers,
'actors': actors,
'genres': genres,
'studio': studio
'studio': studio,
'labels': labels
}
return output
@ -380,6 +387,7 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
'actors': extracted_xml['actors'],
'genres': extracted_xml['genres'],
'studio': extracted_xml['studio'],
'labels': extracted_xml['labels'],
'full_title': row['full_title']
}

View file

@ -84,6 +84,13 @@ def refresh_libraries():
# Start library section_id update on it's own thread
threading.Thread(target=libraries.update_section_ids).start()
if plexpy.CONFIG.UPDATE_LABELS == 1 or plexpy.CONFIG.UPDATE_LABELS == -1:
from plexpy import libraries
import threading
# Start library labels update on it's own thread
threading.Thread(target=libraries.update_labels).start()
logger.info(u"PlexPy Pmsconnect :: Libraries list refreshed.")
else:
logger.warn(u"PlexPy Pmsconnect :: Unable to refresh libraries list.")
@ -105,7 +112,16 @@ class PmsConnect(object):
port = plexpy.CONFIG.PMS_PORT
self.protocol = 'http'
token = token if token else plexpy.CONFIG.PMS_TOKEN
if token == 'admin':
token = plexpy.CONFIG.PMS_TOKEN
elif not token:
# Check if we should use the admin token, or the guest server token
if session.get_session_user_id():
user_data = users.Users()
user_tokens = user_data.get_tokens(user_id=session.get_session_user_id())
token = user_tokens['server_token']
else:
token = plexpy.CONFIG.PMS_TOKEN
self.request_handler = http_handler.HTTPHandler(host=hostname,
port=port,
@ -293,7 +309,7 @@ class PmsConnect(object):
return request
def get_library_list(self, section_id='', list_type='all', count='0', sort_type='', output_format=''):
def get_library_list(self, section_id='', list_type='all', count='0', sort_type='', label_key='', output_format=''):
"""
Return list of items in library on server.
@ -302,8 +318,25 @@ class PmsConnect(object):
Output: array
"""
count = '&X-Plex-Container-Size=' + count if count else ''
label_key = '&label=' + label_key if label_key else ''
uri = '/library/sections/' + section_id + '/' + list_type + '?X-Plex-Container-Start=0' + count + sort_type
uri = '/library/sections/' + section_id + '/' + list_type + '?X-Plex-Container-Start=0' + count + sort_type + label_key
request = self.request_handler.make_request(uri=uri,
proto=self.protocol,
request_type='GET',
output_format=output_format)
return request
def get_library_labels(self, section_id='', output_format=''):
"""
Return list of labels for a library on server.
Optional parameters: output_format { dict, json }
Output: array
"""
uri = '/library/sections/' + section_id + '/label'
request = self.request_handler.make_request(uri=uri,
proto=self.protocol,
request_type='GET',
@ -539,26 +572,31 @@ class PmsConnect(object):
section_id = helpers.get_xml_attr(a, 'librarySectionID')
library_name = helpers.get_xml_attr(a, 'librarySectionTitle')
genres = []
actors = []
writers = []
directors = []
writers = []
actors = []
genres = []
labels = []
if metadata_main.getElementsByTagName('Genre'):
for genre in metadata_main.getElementsByTagName('Genre'):
genres.append(helpers.get_xml_attr(genre, 'tag'))
if metadata_main.getElementsByTagName('Role'):
for actor in metadata_main.getElementsByTagName('Role'):
actors.append(helpers.get_xml_attr(actor, 'tag'))
if metadata_main.getElementsByTagName('Director'):
for director in metadata_main.getElementsByTagName('Director'):
directors.append(helpers.get_xml_attr(director, 'tag'))
if metadata_main.getElementsByTagName('Writer'):
for writer in metadata_main.getElementsByTagName('Writer'):
writers.append(helpers.get_xml_attr(writer, 'tag'))
if metadata_main.getElementsByTagName('Director'):
for director in metadata_main.getElementsByTagName('Director'):
directors.append(helpers.get_xml_attr(director, 'tag'))
if metadata_main.getElementsByTagName('Role'):
for actor in metadata_main.getElementsByTagName('Role'):
actors.append(helpers.get_xml_attr(actor, 'tag'))
if metadata_main.getElementsByTagName('Genre'):
for genre in metadata_main.getElementsByTagName('Genre'):
genres.append(helpers.get_xml_attr(genre, 'tag'))
if metadata_main.getElementsByTagName('Label'):
for labels in metadata_main.getElementsByTagName('Label'):
labels.append(helpers.get_xml_attr(labels, 'tag'))
if metadata_type == 'movie':
metadata = {'media_type': metadata_type,
@ -588,10 +626,11 @@ class PmsConnect(object):
'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
'guid': helpers.get_xml_attr(metadata_main, 'guid'),
'genres': genres,
'actors': actors,
'directors': directors,
'writers': writers,
'directors': directors
'actors': actors,
'genres': genres,
'labels': labels
}
metadata_list = {'metadata': metadata}
@ -623,10 +662,11 @@ class PmsConnect(object):
'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
'guid': helpers.get_xml_attr(metadata_main, 'guid'),
'writers': writers,
'directors': directors,
'writers': writers,
'actors': actors,
'genres': genres,
'actors': actors
'labels': labels
}
metadata_list = {'metadata': metadata}
@ -660,10 +700,11 @@ class PmsConnect(object):
'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
'guid': helpers.get_xml_attr(metadata_main, 'guid'),
'genres': show_details['metadata']['genres'],
'actors': show_details['metadata']['actors'],
'directors': show_details['metadata']['directors'],
'writers': show_details['metadata']['writers'],
'directors': show_details['metadata']['directors']
'actors': show_details['metadata']['actors'],
'genres': show_details['metadata']['genres'],
'labels': show_details['metadata']['labels']
}
metadata_list = {'metadata': metadata}
@ -697,10 +738,11 @@ class PmsConnect(object):
'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
'guid': helpers.get_xml_attr(metadata_main, 'guid'),
'genres': show_details['metadata']['genres'],
'actors': show_details['metadata']['actors'],
'directors': directors,
'writers': writers,
'directors': directors
'actors': show_details['metadata']['actors'],
'genres': show_details['metadata']['genres'],
'labels': show_details['metadata']['labels']
}
metadata_list = {'metadata': metadata}
@ -732,10 +774,11 @@ class PmsConnect(object):
'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
'guid': helpers.get_xml_attr(metadata_main, 'guid'),
'writers': writers,
'directors': directors,
'writers': writers,
'actors': actors,
'genres': genres,
'actors': actors
'labels': labels
}
metadata_list = {'metadata': metadata}
@ -769,10 +812,11 @@ class PmsConnect(object):
'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
'guid': helpers.get_xml_attr(metadata_main, 'guid'),
'genres': genres,
'actors': actors,
'directors': directors,
'writers': writers,
'directors': directors
'actors': actors,
'genres': genres,
'labels': labels
}
metadata_list = {'metadata': metadata}
@ -806,10 +850,11 @@ class PmsConnect(object):
'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
'guid': helpers.get_xml_attr(metadata_main, 'guid'),
'genres': album_details['metadata']['genres'],
'actors': actors,
'directors': directors,
'writers': writers,
'directors': directors
'actors': actors,
'genres': album_details['metadata']['genres'],
'labels': album_details['metadata']['labels']
}
metadata_list = {'metadata': metadata}
@ -1611,7 +1656,8 @@ class PmsConnect(object):
return output
def get_library_children_details(self, section_id='', section_type='', list_type='all', count='', rating_key='', get_media_info=False):
def get_library_children_details(self, section_id='', section_type='', list_type='all', count='',
rating_key='', label_key='', get_media_info=False):
"""
Return processed and validated server library items list.
@ -1645,7 +1691,7 @@ class PmsConnect(object):
sort_type = ''
if str(section_id).isdigit():
library_data = self.get_library_list(str(section_id), list_type, count, sort_type, output_format='xml')
library_data = self.get_library_list(str(section_id), list_type, count, sort_type, label_key, output_format='xml')
elif str(rating_key).isdigit():
library_data = self.get_children_list(str(rating_key), output_format='xml')
else:
@ -1792,6 +1838,33 @@ class PmsConnect(object):
return server_library_stats
def get_library_label_details(self, section_id=''):
labels_data = self.get_library_labels(section_id=str(section_id), output_format='xml')
try:
xml_head = labels_data.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_library_label_details: %s." % e)
return None
labels_list = []
for a in xml_head:
if a.getAttribute('size'):
if a.getAttribute('size') == '0':
logger.debug(u"PlexPy Pmsconnect :: No labels data.")
return labels_list
if a.getElementsByTagName('Directory'):
labels_main = a.getElementsByTagName('Directory')
for item in labels_main:
label = {'label_key': helpers.get_xml_attr(item, 'key'),
'label_title': helpers.get_xml_attr(item, 'title')
}
labels_list.append(label)
return labels_list
def get_image(self, img=None, width=None, height=None):
"""
Return image data as array.