Add media info table to library page

This commit is contained in:
Jonathan Wong 2016-01-10 13:35:20 -08:00
parent 10e4d562ab
commit 381c3da31c
28 changed files with 1415 additions and 462 deletions

View file

@ -377,7 +377,7 @@ def dbcheck():
# sessions table :: This is a temp table that logs currently active sessions
c_db.execute(
'CREATE TABLE IF NOT EXISTS sessions (id INTEGER PRIMARY KEY AUTOINCREMENT, '
'session_key INTEGER, rating_key INTEGER, library_id INTEGER, media_type TEXT, started INTEGER, '
'session_key INTEGER, rating_key INTEGER, section_id INTEGER, media_type TEXT, started INTEGER, '
'paused_counter INTEGER DEFAULT 0, state TEXT, user_id INTEGER, user TEXT, friendly_name TEXT, '
'ip_address TEXT, machine_id TEXT, player TEXT, platform TEXT, title TEXT, parent_title TEXT, '
'grandparent_title TEXT, parent_rating_key INTEGER, grandparent_rating_key INTEGER, '
@ -413,7 +413,7 @@ def dbcheck():
'CREATE TABLE IF NOT EXISTS session_history_metadata (id INTEGER PRIMARY KEY, '
'rating_key INTEGER, parent_rating_key INTEGER, grandparent_rating_key INTEGER, '
'title TEXT, parent_title TEXT, grandparent_title TEXT, full_title TEXT, media_index INTEGER, '
'parent_media_index INTEGER, library_id INTEGER, thumb TEXT, parent_thumb TEXT, grandparent_thumb TEXT, '
'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)'
@ -594,11 +594,11 @@ def dbcheck():
# Upgrade sessions table from earlier versions
try:
c_db.execute('SELECT library_id from sessions')
c_db.execute('SELECT section_id from sessions')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table sessions.")
c_db.execute(
'ALTER TABLE sessions ADD COLUMN library_id INTEGER'
'ALTER TABLE sessions ADD COLUMN section_id INTEGER'
)
# Upgrade session_history table from earlier versions
@ -644,11 +644,11 @@ def dbcheck():
# Upgrade session_history_metadata table from earlier versions
try:
c_db.execute('SELECT library_id from session_history_metadata')
c_db.execute('SELECT section_id 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 library_id INTEGER'
'ALTER TABLE session_history_metadata ADD COLUMN section_id INTEGER'
)
# Upgrade users table from earlier versions

View file

@ -192,7 +192,7 @@ def check_recently_added():
recently_added = recently_added_list['recently_added']
for item in recently_added:
library_details = library_data.get_details(section_id=item['library_id'])
library_details = library_data.get_details(section_id=item['section_id'])
if not library_details['do_notify_created']:
continue
@ -221,7 +221,7 @@ def check_recently_added():
if not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT:
for item in metadata:
library_details = library_data.get_details(section_id=item['library_id'])
library_details = library_data.get_details(section_id=item['section_id'])
if 0 < time_threshold - int(item['added_at']) <= time_interval:
logger.debug(u"PlexPy Monitor :: Library item %s has been added to Plex." % str(item['rating_key']))

View file

@ -29,7 +29,7 @@ class ActivityProcessor(object):
def write_session(self, session=None, notify=True):
if session:
values = {'session_key': session['session_key'],
'library_id': session['library_id'],
'section_id': session['section_id'],
'rating_key': session['rating_key'],
'media_type': session['media_type'],
'state': session['state'],
@ -104,7 +104,7 @@ class ActivityProcessor(object):
user_details = user_data.get_details(user_id=session['user_id'])
library_data = libraries.Libraries()
library_details = library_data.get_details(section_id=session['library_id'])
library_details = library_data.get_details(section_id=session['section_id'])
if session:
logging_enabled = False
@ -257,7 +257,7 @@ class ActivityProcessor(object):
# logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history_metadata table...")
query = 'INSERT INTO session_history_metadata (id, rating_key, parent_rating_key, ' \
'grandparent_rating_key, title, parent_title, grandparent_title, full_title, media_index, ' \
'parent_media_index, library_id, thumb, parent_thumb, grandparent_thumb, art, media_type, ' \
'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(), ' \
@ -265,7 +265,7 @@ class ActivityProcessor(object):
args = [session['rating_key'], session['parent_rating_key'], session['grandparent_rating_key'],
session['title'], session['parent_title'], session['grandparent_title'], full_title,
metadata['media_index'], metadata['parent_media_index'], metadata['library_id'], metadata['thumb'],
metadata['media_index'], metadata['parent_media_index'], metadata['section_id'], metadata['thumb'],
metadata['parent_thumb'], metadata['grandparent_thumb'], metadata['art'], session['media_type'],
metadata['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'],
metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'],

View file

@ -372,7 +372,7 @@ _CONFIG_DEFINITIONS = {
'TWITTER_ON_EXTUP': (int, 'Twitter', 0),
'TWITTER_ON_INTUP': (int, 'Twitter', 0),
'UPDATE_DB_INTERVAL': (int, 'General', 24),
'UPDATE_LIBRARY_IDS': (int, 'General', 1),
'UPDATE_SECTION_IDS': (int, 'General', 1),
'VERIFY_SSL_CERT': (bool_int, 'Advanced', 1),
'VIDEO_LOGGING_ENABLE': (int, 'Monitoring', 1),
'XBMC_ENABLED': (int, 'XBMC', 0),

View file

@ -98,12 +98,12 @@ class DataFactory(object):
for item in history:
filter_duration += int(item['duration'])
if item["media_type"] == 'episode' and item["parent_thumb"]:
thumb = item["parent_thumb"]
elif item["media_type"] == 'episode':
thumb = item["grandparent_thumb"]
if item['media_type'] == 'episode' and item['parent_thumb']:
thumb = item['parent_thumb']
elif item['media_type'] == 'episode':
thumb = item['grandparent_thumb']
else:
thumb = item["thumb"]
thumb = item['thumb']
if item['percent_complete'] >= watched_percent:
watched_status = 1
@ -113,37 +113,37 @@ class DataFactory(object):
watched_status = 0
# Rename Mystery platform names
platform = common.PLATFORM_NAME_OVERRIDES.get(item["platform"], item["platform"])
platform = common.PLATFORM_NAME_OVERRIDES.get(item['platform'], item['platform'])
row = {"reference_id": item["reference_id"],
"id": item["id"],
"date": item["date"],
"started": item["started"],
"stopped": item["stopped"],
"duration": item["duration"],
"paused_counter": item["paused_counter"],
"user_id": item["user_id"],
"user": item["user"],
"friendly_name": item["friendly_name"],
"platform": platform,
"player": item['player'],
"ip_address": item["ip_address"],
"media_type": item["media_type"],
"rating_key": item["rating_key"],
"parent_rating_key": item["parent_rating_key"],
"grandparent_rating_key": item["grandparent_rating_key"],
"full_title": item["full_title"],
"parent_title": item["parent_title"],
"year": item["year"],
"media_index": item["media_index"],
"parent_media_index": item["parent_media_index"],
"thumb": thumb,
"video_decision": item["video_decision"],
"audio_decision": item["audio_decision"],
"percent_complete": int(round(item['percent_complete'])),
"watched_status": watched_status,
"group_count": item["group_count"],
"group_ids": item["group_ids"]
row = {'reference_id': item['reference_id'],
'id': item['id'],
'date': item['date'],
'started': item['started'],
'stopped': item['stopped'],
'duration': item['duration'],
'paused_counter': item['paused_counter'],
'user_id': item['user_id'],
'user': item['user'],
'friendly_name': item['friendly_name'],
'platform': platform,
'player': item['player'],
'ip_address': item['ip_address'],
'media_type': item['media_type'],
'rating_key': item['rating_key'],
'parent_rating_key': item['parent_rating_key'],
'grandparent_rating_key': item['grandparent_rating_key'],
'full_title': item['full_title'],
'parent_title': item['parent_title'],
'year': item['year'],
'media_index': item['media_index'],
'parent_media_index': item['parent_media_index'],
'thumb': thumb,
'video_decision': item['video_decision'],
'audio_decision': item['audio_decision'],
'percent_complete': int(round(item['percent_complete'])),
'watched_status': watched_status,
'group_count': item['group_count'],
'group_ids': item['group_ids']
}
rows.append(row)
@ -154,7 +154,7 @@ class DataFactory(object):
'draw': query['draw'],
'filter_duration': helpers.human_duration(filter_duration, sig='dhm'),
'total_duration': helpers.human_duration(total_duration, sig='dhm')
}
}
return dict
@ -736,7 +736,7 @@ class DataFactory(object):
'session_history_metadata.parent_title, session_history_metadata.grandparent_title, ' \
'session_history_metadata.full_title, library_sections.section_name, ' \
'session_history_metadata.media_index, session_history_metadata.parent_media_index, ' \
'session_history_metadata.library_id, session_history_metadata.thumb, ' \
'session_history_metadata.section_id, session_history_metadata.thumb, ' \
'session_history_metadata.parent_thumb, session_history_metadata.grandparent_thumb, ' \
'session_history_metadata.art, session_history_metadata.media_type, session_history_metadata.year, ' \
'session_history_metadata.originally_available_at, session_history_metadata.added_at, ' \
@ -746,7 +746,7 @@ class DataFactory(object):
'session_history_metadata.guid, session_history_metadata.directors, session_history_metadata.writers, ' \
'session_history_metadata.actors, session_history_metadata.genres, session_history_metadata.studio ' \
'FROM session_history_metadata ' \
'JOIN library_sections ON session_history_metadata.library_id = library_sections.section_id ' \
'JOIN library_sections ON session_history_metadata.section_id = library_sections.section_id ' \
'WHERE session_history_metadata.rating_key = ?'
result = monitor_db.select(query=query, args=[rating_key])
else:
@ -789,7 +789,7 @@ class DataFactory(object):
'genres': genres,
'actors': actors,
'library_name': item['section_name'],
'library_id': item['library_id']
'section_id': item['section_id']
}
return metadata
@ -1056,7 +1056,7 @@ class DataFactory(object):
# Update the session_history_metadata table
query = 'UPDATE session_history_metadata SET rating_key = ?, parent_rating_key = ?, ' \
'grandparent_rating_key = ?, title = ?, parent_title = ?, grandparent_title = ?, full_title = ?, ' \
'media_index = ?, parent_media_index = ?, library_id = ?, thumb = ?, parent_thumb = ?, ' \
'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 = ?, ' \
@ -1065,7 +1065,7 @@ class DataFactory(object):
args = [metadata['rating_key'], metadata['parent_rating_key'], metadata['grandparent_rating_key'],
metadata['title'], metadata['parent_title'], metadata['grandparent_title'], full_title,
metadata['media_index'], metadata['parent_media_index'], metadata['library_id'], metadata['thumb'],
metadata['media_index'], metadata['parent_media_index'], metadata['section_id'], metadata['thumb'],
metadata['parent_thumb'], metadata['grandparent_thumb'], metadata['art'], metadata['media_type'],
metadata['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'],
metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'],
@ -1073,35 +1073,4 @@ class DataFactory(object):
metadata['studio'],
old_rating_key]
monitor_db.action(query=query, args=args)
def update_library_ids(self):
from plexpy import pmsconnect
pms_connect = pmsconnect.PmsConnect()
monitor_db = database.MonitorDatabase()
try:
query = 'SELECT id, rating_key FROM session_history_metadata WHERE library_id IS NULL'
result = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for update_library_id: %s." % e)
return None
for item in result:
id = item['id']
rating_key = item['rating_key']
result = pms_connect.get_metadata_details(rating_key=rating_key)
if result:
metadata = result['metadata']
section_keys = {'id': id}
section_values = {'library_id': metadata['library_id']}
monitor_db.upsert('session_history_metadata', key_dict=section_keys, value_dict=section_values)
else:
continue
return True
monitor_db.action(query=query, args=args)

View file

@ -124,8 +124,9 @@ class DataTables(object):
order += ', '
order = order.rstrip(', ')
if order:
order = 'ORDER BY ' + order.rstrip(', ')
order = 'ORDER BY ' + order
# Build where parameters
if parameters['search']['value']:

View file

@ -60,7 +60,7 @@ class Libraries(object):
join_tables=['session_history_metadata',
'session_history',
'session_history_media_info'],
join_evals=[['session_history_metadata.library_id', 'library_sections.section_id'],
join_evals=[['session_history_metadata.section_id', 'library_sections.section_id'],
['session_history_metadata.id', 'session_history.id'],
['session_history_metadata.id', 'session_history_media_info.id']],
kwargs=kwargs)
@ -116,10 +116,295 @@ class Libraries(object):
'recordsTotal': query['totalCount'],
'data': rows,
'draw': query['draw']
}
}
return dict
def get_datatables_media_info(self, section_id=None, kwargs=None):
data_tables = datatables.DataTables()
custom_where = ['library_sections.section_id', section_id]
columns = ['session_history.id',
'session_history.started AS last_watched',
'COUNT(DISTINCT session_history.reference_id) AS play_count',
'session_history_metadata.rating_key',
'session_history_metadata.parent_rating_key',
'session_history_metadata.grandparent_rating_key',
'session_history_metadata.full_title',
'session_history_metadata.year',
'session_history_metadata.media_index',
'session_history_metadata.parent_media_index',
'session_history_metadata.thumb',
'session_history_metadata.parent_thumb',
'session_history_metadata.grandparent_thumb',
'session_history_metadata.media_type',
'session_history_metadata.added_at',
'session_history_media_info.container',
'session_history_media_info.bitrate',
'session_history_media_info.video_codec',
'session_history_media_info.video_resolution',
'session_history_media_info.video_framerate',
'session_history_media_info.audio_codec',
'session_history_media_info.audio_channels',
'session_history_media_info.duration AS file_size'
]
try:
query = data_tables.ssp_query(table_name='session_history',
columns=columns,
custom_where=[custom_where],
group_by=['session_history_metadata.rating_key'],
join_types=['JOIN',
'JOIN',
'JOIN'],
join_tables=['library_sections',
'session_history_metadata',
'session_history_media_info'],
join_evals=[['session_history_metadata.section_id', 'library_sections.section_id'],
['session_history.id', 'session_history_metadata.id'],
['session_history.id', 'session_history_media_info.id']],
kwargs=kwargs)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_datatables_media_info: %s." % e)
return {'recordsFiltered': 0,
'recordsTotal': 0,
'draw': 0,
'data': 'null',
'error': 'Unable to execute database query.'}
results = query['result']
rows = []
for item in results:
if item['media_type'] == 'episode' and item['parent_thumb']:
thumb = item['parent_thumb']
elif item['media_type'] == 'episode':
thumb = item['grandparent_thumb']
else:
thumb = item['thumb']
row = {'id': item['id'],
'last_watched': item['last_watched'],
'added_at': item['added_at'],
'play_count': item['play_count'],
'media_type': item['media_type'],
'rating_key': item['rating_key'],
'parent_rating_key': item['parent_rating_key'],
'grandparent_rating_key': item['grandparent_rating_key'],
'full_title': item['full_title'],
'year': item['year'],
'media_index': item['media_index'],
'parent_media_index': item['parent_media_index'],
'thumb': thumb,
'container': item['container'],
'bitrate': item['bitrate'],
'video_codec': item['video_codec'],
'video_resolution': item['video_resolution'],
'video_framerate': item['video_framerate'],
'audio_codec': item['audio_codec'],
'audio_channels': item['audio_channels'],
'file_size': item['file_size']
}
rows.append(row)
dict = {'recordsFiltered': query['filteredCount'],
'recordsTotal': query['totalCount'],
'data': rows,
'draw': query['draw']
}
return dict
def get_datatables_media_info2(self, section_id=None, section_type=None, rating_key=None, kwargs=None):
from plexpy import pmsconnect
import json, os
default_return = {'recordsFiltered': 0,
'recordsTotal': 0,
'draw': 0,
'data': None,
'error': 'Unable to execute database query.'}
if section_id and not str(section_id).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info called by invalid section_id provided.")
return default_return
elif rating_key and not str(rating_key).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info called by invalid rating_key provided.")
return default_return
rows = []
if rating_key:
try:
inFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s_%s.json' % (section_id, rating_key))
with open(inFilePath, 'r') as inFile:
rows = json.load(inFile)
library_count = len(rows)
except IOError as e:
logger.debug(u"PlexPy Libraries :: No JSON file for rating_key %s." % rating_key)
logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for rating_key %s." % rating_key)
elif section_id:
try:
inFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s.json' % section_id)
with open(inFilePath, 'r') as inFile:
rows = json.load(inFile)
library_count = len(rows)
except IOError as e:
logger.debug(u"PlexPy Libraries :: No JSON file for library section_id %s." % section_id)
logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for section_id %s." % section_id)
if not rows:
# Get the library details
library_details = self.get_details(section_id=section_id)
if library_details['section_id'] == None:
logger.warn(u"PlexPy Libraries :: Library section_id %s not found." % section_id)
return default_return
if not section_type:
section_type = library_details['section_type']
# Get play counts from the database
monitor_db = database.MonitorDatabase()
if section_type == 'show' or section_type == 'artist':
group_by = 'grandparent_rating_key'
elif section_type == 'season' or section_type == 'album':
group_by = 'parent_rating_key'
else:
group_by = 'rating_key'
try:
query = 'SELECT MAX(session_history.started) AS last_watched, COUNT(session_history.id) AS play_count, ' \
'session_history.rating_key, session_history.parent_rating_key, session_history.grandparent_rating_key ' \
'FROM session_history ' \
'JOIN session_history_metadata ON session_history.id = session_history_metadata.id ' \
'WHERE session_history_metadata.section_id = ? ' \
'GROUP BY session_history.%s ' % group_by
result = monitor_db.select(query, args=[section_id])
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_datatables_media_info2: %s." % e)
return default_return
watched_list = {}
for item in result:
watched_list[str(item[group_by])] = {'last_watched': item['last_watched'],
'play_count': item['play_count']}
# Get all library children items
pms_connect = pmsconnect.PmsConnect()
if rating_key:
library_children = pms_connect.get_library_children(rating_key=rating_key,
get_media_info=True)
elif section_id:
library_children = pms_connect.get_library_children(section_id=section_id,
section_type=section_type,
get_media_info=True)
if library_children:
library_count = library_children['library_count']
children_list = library_children['childern_list']
else:
logger.warn(u"PlexPy Libraries :: Unable to get a list of library items.")
return default_return
rows = []
for item in children_list:
thumb = item['thumb']
if item['media_type'] == 'episode' or item['media_type'] == 'track':
full_title = 'E%s - %s' % (item['media_index'], item['title'])
else:
full_title = item['title']
watched_item = watched_list.get(item['rating_key'], None)
if watched_item:
last_watched = watched_item['last_watched']
play_count = watched_item['play_count']
else:
last_watched = None
play_count = None
row = {'section_id': library_details['section_id'],
'section_type': library_details['section_type'],
'last_watched': last_watched,
'added_at': item['added_at'],
'media_type': item['media_type'],
'rating_key': item['rating_key'],
'parent_rating_key': item['parent_rating_key'],
'grandparent_rating_key': item['grandparent_rating_key'],
'full_title': full_title,
'title': item['title'],
'year': item['year'],
'media_index': item['media_index'],
'parent_media_index': item['parent_media_index'],
'thumb': thumb,
'container': item.get('container', ''),
'bitrate': item.get('bitrate', ''),
'video_codec': item.get('video_codec', ''),
'video_resolution': item.get('video_resolution', ''),
'video_framerate': item.get('video_framerate', ''),
'audio_codec': item.get('audio_codec', ''),
'audio_channels': item.get('audio_channels', ''),
'file_size': item.get('file_size', ''),
'play_count': play_count
}
rows.append(row)
if rating_key:
outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s_%s.json' % (section_id, rating_key))
with open(outFilePath, 'w') as outFile:
json.dump(rows, outFile)
elif section_id:
outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s.json' % section_id)
with open(outFilePath, 'w') as outFile:
json.dump(rows, outFile)
results = []
# Get datatables JSON data
if kwargs.get('json_data'):
json_data = helpers.process_json_kwargs(json_kwargs=kwargs.get('json_data'))
#print json_data
# Search results
search_value = json_data['search']['value'].lower()
if search_value:
searchable_columns = [d['data'] for d in json_data['columns'] if d['searchable']]
for row in rows:
for k,v in row.iteritems():
if k in searchable_columns and search_value in v.lower():
results.append(row)
break
else:
results = rows
filtered_count = len(results)
# Sort results
sort_order = json_data['order']
for order in reversed(sort_order):
sort_key = json_data['columns'][int(order['column'])]['data']
reverse = True if order['dir'] == 'desc' else False
if rating_key and sort_key == 'title':
results = sorted(results, key=lambda k: int(k['media_index']), reverse=reverse)
else:
results = sorted(results, key=lambda k: k[sort_key], reverse=reverse)
# Paginate results
results = results[json_data['start']:(json_data['start'] + json_data['length'])]
dict = {'recordsFiltered': filtered_count,
'recordsTotal': library_count,
'data': results,
'draw': int(json_data['draw'])
}
## Add total disk space used
return dict
def set_config(self, section_id=None, custom_thumb='', do_notify=1, keep_history=1, do_notify_created=1):
if section_id:
monitor_db = database.MonitorDatabase()
@ -234,7 +519,7 @@ class Libraries(object):
'keep_history': 0
}
def get_watch_time_stats(self, library_id=None):
def get_watch_time_stats(self, section_id=None):
monitor_db = database.MonitorDatabase()
time_queries = [1, 7, 30, 0]
@ -243,26 +528,26 @@ class Libraries(object):
for days in time_queries:
try:
if days > 0:
if str(library_id).isdigit():
if str(section_id).isdigit():
query = 'SELECT (SUM(stopped - started) - ' \
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
'COUNT(session_history.id) AS total_plays ' \
'FROM session_history ' \
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
'AND library_id = ?' % days
result = monitor_db.select(query, args=[library_id])
'AND section_id = ?' % days
result = monitor_db.select(query, args=[section_id])
else:
result = []
else:
if str(library_id).isdigit():
if str(section_id).isdigit():
query = 'SELECT (SUM(stopped - started) - ' \
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
'COUNT(session_history.id) AS total_plays ' \
'FROM session_history ' \
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
'WHERE library_id = ?'
result = monitor_db.select(query, args=[library_id])
'WHERE section_id = ?'
result = monitor_db.select(query, args=[section_id])
else:
result = []
except Exception as e:
@ -286,22 +571,22 @@ class Libraries(object):
return library_watch_time_stats
def get_user_stats(self, library_id=None):
def get_user_stats(self, section_id=None):
monitor_db = database.MonitorDatabase()
user_stats = []
try:
if str(library_id).isdigit():
if str(section_id).isdigit():
query = 'SELECT (CASE WHEN users.friendly_name IS NULL THEN users.username ' \
'ELSE users.friendly_name END) AS user, users.user_id, users.thumb, COUNT(user) AS user_count ' \
'FROM session_history ' \
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
'JOIN users ON users.user_id = session_history.user_id ' \
'WHERE library_id = ? ' \
'WHERE section_id = ? ' \
'GROUP BY user ' \
'ORDER BY user_count DESC'
result = monitor_db.select(query, args=[library_id])
result = monitor_db.select(query, args=[section_id])
else:
result = []
except Exception as e:
@ -318,7 +603,7 @@ class Libraries(object):
return user_stats
def get_recently_watched(self, library_id=None, limit='10'):
def get_recently_watched(self, section_id=None, limit='10'):
monitor_db = database.MonitorDatabase()
recently_watched = []
@ -326,17 +611,17 @@ class Libraries(object):
limit = '10'
try:
if str(library_id).isdigit():
if str(section_id).isdigit():
query = 'SELECT session_history.id, session_history.media_type, session_history.rating_key, session_history.parent_rating_key, ' \
'title, parent_title, grandparent_title, thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \
'year, started, user ' \
'FROM session_history_metadata ' \
'JOIN session_history ON session_history_metadata.id = session_history.id ' \
'WHERE library_id = ? ' \
'WHERE section_id = ? ' \
'GROUP BY (CASE WHEN session_history.media_type = "track" THEN session_history.parent_rating_key ' \
' ELSE session_history.rating_key END) ' \
'ORDER BY started DESC LIMIT ?'
result = monitor_db.select(query, args=[library_id, limit])
result = monitor_db.select(query, args=[section_id, limit])
else:
result = []
except Exception as e:
@ -399,18 +684,18 @@ class Libraries(object):
'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id '
'FROM session_history_media_info '
'JOIN session_history_metadata ON session_history_media_info.id = session_history_metadata.id '
'WHERE session_history_metadata.library_id = ?)', [section_id])
'WHERE session_history_metadata.section_id = ?)', [section_id])
session_history_del = \
monitor_db.action('DELETE FROM '
'session_history '
'WHERE session_history.id IN (SELECT session_history.id '
'FROM session_history '
'JOIN session_history_metadata ON session_history.id = session_history_metadata.id '
'WHERE session_history_metadata.library_id = ?)', [section_id])
'WHERE session_history_metadata.section_id = ?)', [section_id])
session_history_metadata_del = \
monitor_db.action('DELETE FROM '
'session_history_metadata '
'WHERE session_history_metadata.library_id = ?', [section_id])
'WHERE session_history_metadata.section_id = ?', [section_id])
return 'Deleted all items for section_id %s.' % section_id
else:
@ -465,4 +750,50 @@ class Libraries(object):
else:
return 'Unable to re-add library, section_id or section_name not valid.'
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for undelete: %s." % e)
logger.warn(u"PlexPy Libraries :: Unable to execute database query for undelete: %s." % e)
def update_section_ids(self):
from plexpy import pmsconnect
pms_connect = pmsconnect.PmsConnect()
monitor_db = database.MonitorDatabase()
try:
query = 'SELECT id, rating_key FROM session_history_metadata WHERE section_id IS NULL'
result = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for update_section_ids: %s." % e)
return None
for item in result:
id = item['id']
rating_key = item['rating_key']
result = pms_connect.get_metadata_details(rating_key=rating_key)
if result:
metadata = result['metadata']
section_keys = {'id': id}
section_values = {'section_id': metadata['section_id']}
monitor_db.upsert('session_history_metadata', key_dict=section_keys, value_dict=section_values)
else:
continue
return True
def delete_datatable_media_info_cache(self, section_id=None):
import os
try:
if section_id.isdigit():
[os.remove(os.path.join(plexpy.CONFIG.CACHE_DIR, f)) for f in os.listdir(plexpy.CONFIG.CACHE_DIR)
if f.startswith('media_info-%s' % section_id) and f.endswith('.json')]
logger.debug(u"PlexPy Libraries :: Deleted media info table cache for section_id %s." % section_id)
return 'Deleted media info table cache for library with id %s.' % section_id
else:
return 'Unable to delete media info table cache, section_id not valid.'
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to delete media info table cache: %s." % e)

View file

@ -31,7 +31,7 @@ def notify(stream_data=None, notify_action=None):
user_details = user_data.get_details(user_id=stream_data['user_id'])
library_data = libraries.Libraries()
library_details = library_data.get_details(section_id=stream_data['library_id'])
library_details = library_data.get_details(section_id=stream_data['section_id'])
if not user_details['do_notify']:
# logger.debug(u"PlexPy NotificationHandler :: Notifications for user '%s' is disabled." % user_details['username'])

View file

@ -41,7 +41,7 @@ def extract_plexwatch_xml(xml=None):
grandparent_thumb = helpers.get_xml_attr(a, 'grandparentThumb')
grandparent_title = helpers.get_xml_attr(a, 'grandparentTitle')
guid = helpers.get_xml_attr(a, 'guid')
library_id = helpers.get_xml_attr(a, 'librarySectionID')
section_id = helpers.get_xml_attr(a, 'librarySectionID')
media_index = helpers.get_xml_attr(a, 'index')
originally_available_at = helpers.get_xml_attr(a, 'originallyAvailableAt')
last_viewed_at = helpers.get_xml_attr(a, 'lastViewedAt')
@ -157,7 +157,7 @@ def extract_plexwatch_xml(xml=None):
'title': title,
'tagline': tagline,
'guid': guid,
'library_id': library_id,
'section_id': section_id,
'media_index': media_index,
'originally_available_at': originally_available_at,
'last_viewed_at': last_viewed_at,
@ -251,6 +251,8 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
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)
ap = activity_processor.ActivityProcessor()
user_data = users.Users()
@ -372,7 +374,7 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
'rating': extracted_xml['rating'],
'duration': extracted_xml['duration'],
'guid': extracted_xml['guid'],
'library_id': extracted_xml['library_id'],
'section_id': extracted_xml['section_id'],
'directors': extracted_xml['directors'],
'writers': extracted_xml['writers'],
'actors': extracted_xml['actors'],

View file

@ -44,11 +44,6 @@ def refresh_libraries():
server_id = plexpy.CONFIG.PMS_IDENTIFIER
if plexpy.CONFIG.HOME_LIBRARY_CARDS == ['first_run']:
populate_cards = True
else:
populate_cards = False
library_keys = []
if library_sections:
@ -56,11 +51,11 @@ def refresh_libraries():
for section in library_sections:
section_keys = {'server_id': server_id,
'section_id': section['key']}
'section_id': section['section_id']}
section_values = {'server_id': server_id,
'section_id': section['key'],
'section_name': section['title'],
'section_type': section['type'],
'section_id': section['section_id'],
'section_name': section['section_name'],
'section_type': section['section_type'],
'thumb': section['thumb'],
'art': section['art'],
'count': section['count'],
@ -70,13 +65,42 @@ def refresh_libraries():
monitor_db.upsert('library_sections', key_dict=section_keys, value_dict=section_values)
library_keys.append(section['key'])
library_keys.append(section['section_id'])
if populate_cards:
if plexpy.CONFIG.HOME_LIBRARY_CARDS == ['first_run']:
plexpy.CONFIG.__setattr__('HOME_LIBRARY_CARDS', library_keys)
plexpy.CONFIG.write()
if plexpy.CONFIG.UPDATE_SECTION_IDS == 1:
from plexpy import libraries
plexpy.CONFIG.UPDATE_SECTION_IDS = -1
logger.info(u"PlexPy Pmsconnect :: Updating section_id's in database.")
logger.debug(u"PlexPy Pmsconnect :: 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)
result = libraries.Libraries().update_section_ids()
if result:
logger.debug(u"PlexPy Pmsconnect :: Updated all section_id's in database.")
plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 0)
plexpy.CONFIG.write()
else:
logger.debug(u"PlexPy Pmsconnect :: Unable to update section_id's in database.")
plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 1)
plexpy.CONFIG.write()
logger.debug(u"PlexPy Pmsconnect :: Re-enabling monitoring.")
plexpy.initialize_scheduler()
logger.info(u"PlexPy Pmsconnect :: Libraries list refreshed.")
else:
logger.warn(u"PlexPy Pmsconnect :: Unable to refresh libraries list.")
@ -169,7 +193,7 @@ class PmsConnect(object):
return request
def get_library_recently_added(self, section_key='', count='0', output_format=''):
def get_library_recently_added(self, section_id='', count='0', output_format=''):
"""
Return list of recently added items.
@ -178,7 +202,7 @@ class PmsConnect(object):
Output: array
"""
uri = '/library/sections/' + section_key + '/recentlyAdded?X-Plex-Container-Start=0&X-Plex-Container-Size=' + count
uri = '/library/sections/' + section_id + '/recentlyAdded?X-Plex-Container-Start=0&X-Plex-Container-Size=' + count
request = self.request_handler.make_request(uri=uri,
proto=self.protocol,
request_type='GET',
@ -203,6 +227,23 @@ class PmsConnect(object):
return request
def get_childrens_list(self, rating_key='', output_format=''):
"""
Return list of children in requested library item.
Parameters required: rating_key { ratingKey of parent }
Optional parameters: output_format { dict, json }
Output: array
"""
uri = '/library/metadata/' + rating_key + '/allLeaves'
request = self.request_handler.make_request(uri=uri,
proto=self.protocol,
request_type='GET',
output_format=output_format)
return request
def get_server_list(self, output_format=''):
"""
Return list of local servers.
@ -267,7 +308,7 @@ class PmsConnect(object):
return request
def get_library_list(self, section_key='', list_type='all', count='0', sort_type='', output_format=''):
def get_library_list(self, section_id='', list_type='all', count='0', sort_type='', output_format=''):
"""
Return list of items in library on server.
@ -275,7 +316,9 @@ class PmsConnect(object):
Output: array
"""
uri = '/library/sections/' + section_key + '/' + list_type +'?X-Plex-Container-Start=0&X-Plex-Container-Size=' + count + sort_type
count = '&X-Plex-Container-Size=' + count if count else ''
uri = '/library/sections/' + section_id + '/' + list_type +'?X-Plex-Container-Start=0' + count + sort_type
request = self.request_handler.make_request(uri=uri,
proto=self.protocol,
request_type='GET',
@ -363,7 +406,7 @@ class PmsConnect(object):
return request
def get_recently_added_details(self, library_id='', count='0'):
def get_recently_added_details(self, section_id='', count='0'):
"""
Return processed and validated list of recently added items.
@ -371,8 +414,8 @@ class PmsConnect(object):
Output: array
"""
if library_id:
recent = self.get_library_recently_added(library_id, count, output_format='xml')
if section_id:
recent = self.get_library_recently_added(section_id, count, output_format='xml')
else:
recent = self.get_recently_added(count, output_format='xml')
@ -402,7 +445,7 @@ class PmsConnect(object):
'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'),
'media_index': helpers.get_xml_attr(item, 'index'),
'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'),
'library_id': helpers.get_xml_attr(item, 'librarySectionID'),
'section_id': helpers.get_xml_attr(item, 'librarySectionID'),
'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'),
'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'),
@ -424,7 +467,7 @@ class PmsConnect(object):
'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'),
'media_index': helpers.get_xml_attr(item, 'index'),
'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'),
'library_id': helpers.get_xml_attr(item, 'librarySectionID'),
'section_id': helpers.get_xml_attr(item, 'librarySectionID'),
'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'),
'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'),
@ -450,7 +493,7 @@ class PmsConnect(object):
try:
xml_head = metadata.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_metadata: %s: %s." % e)
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_metadata: %s." % e)
return []
metadata_list = []
@ -474,7 +517,7 @@ class PmsConnect(object):
logger.debug(u"PlexPy Pmsconnect :: Metadata failed")
return None
library_id = helpers.get_xml_attr(a, 'librarySectionID')
section_id = helpers.get_xml_attr(a, 'librarySectionID')
library_name = helpers.get_xml_attr(a, 'librarySectionTitle')
genres = []
@ -500,7 +543,7 @@ class PmsConnect(object):
if metadata_type == 'movie':
metadata = {'media_type': metadata_type,
'library_id': library_id,
'section_id': section_id,
'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -535,7 +578,7 @@ class PmsConnect(object):
elif metadata_type == 'show':
metadata = {'media_type': metadata_type,
'library_id': library_id,
'section_id': section_id,
'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -572,7 +615,7 @@ class PmsConnect(object):
parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
show_details = self.get_metadata_details(parent_rating_key)
metadata = {'media_type': metadata_type,
'library_id': library_id,
'section_id': section_id,
'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -609,7 +652,7 @@ class PmsConnect(object):
grandparent_rating_key = helpers.get_xml_attr(metadata_main, 'grandparentRatingKey')
show_details = self.get_metadata_details(grandparent_rating_key)
metadata = {'media_type': metadata_type,
'library_id': library_id,
'section_id': section_id,
'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -644,7 +687,7 @@ class PmsConnect(object):
elif metadata_type == 'artist':
metadata = {'media_type': metadata_type,
'library_id': library_id,
'section_id': section_id,
'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -681,7 +724,7 @@ class PmsConnect(object):
parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
artist_details = self.get_metadata_details(parent_rating_key)
metadata = {'media_type': metadata_type,
'library_id': library_id,
'section_id': section_id,
'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -718,7 +761,7 @@ class PmsConnect(object):
parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
album_details = self.get_metadata_details(parent_rating_key)
metadata = {'media_type': metadata_type,
'library_id': library_id,
'section_id': section_id,
'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -798,11 +841,11 @@ class PmsConnect(object):
output = {'metadata': metadata_list}
return output
def get_library_metadata_details(self, library_id=''):
def get_library_metadata_details(self, section_id=''):
"""
Return processed and validated metadata list for requested library.
Parameters required: library_id { Plex library key }
Parameters required: section_id { Plex library key }
Output: array
"""
@ -826,9 +869,9 @@ class PmsConnect(object):
result_data = a.getElementsByTagName('Directory')
for result in result_data:
key = helpers.get_xml_attr(result, 'key')
if key == library_id:
if key == section_id:
metadata = {'media_type': 'library',
'library_id': helpers.get_xml_attr(result, 'key'),
'section_id': helpers.get_xml_attr(result, 'key'),
'library': helpers.get_xml_attr(result, 'type'),
'title': helpers.get_xml_attr(result, 'title'),
'art': helpers.get_xml_attr(result, 'art'),
@ -945,7 +988,7 @@ class PmsConnect(object):
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'),
'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'),
@ -1067,7 +1110,7 @@ class PmsConnect(object):
if helpers.get_xml_attr(session, 'type') == 'episode':
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'),
'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'),
@ -1125,7 +1168,7 @@ class PmsConnect(object):
elif helpers.get_xml_attr(session, 'type') == 'movie':
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'),
'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'),
@ -1183,7 +1226,7 @@ class PmsConnect(object):
elif helpers.get_xml_attr(session, 'type') == 'clip':
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'),
'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'),
@ -1274,7 +1317,7 @@ class PmsConnect(object):
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'),
'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'),
@ -1494,9 +1537,9 @@ class PmsConnect(object):
if a.getElementsByTagName('Directory'):
result_data = a.getElementsByTagName('Directory')
for result in result_data:
libraries_output = {'key': helpers.get_xml_attr(result, 'key'),
'type': helpers.get_xml_attr(result, 'type'),
'title': helpers.get_xml_attr(result, 'title'),
libraries_output = {'section_id': helpers.get_xml_attr(result, 'key'),
'section_type': helpers.get_xml_attr(result, 'type'),
'section_name': helpers.get_xml_attr(result, 'title'),
'thumb': helpers.get_xml_attr(result, 'thumb'),
'art': helpers.get_xml_attr(result, 'art')
}
@ -1509,71 +1552,123 @@ class PmsConnect(object):
return output
def get_library_children(self, library_type='', section_key='', list_type='all', count='1', sort_type = ''):
def get_library_children(self, section_id='', section_type='', list_type='all', count='', rating_key='', get_media_info=False):
"""
Return processed and validated server library items list.
Parameters required: library_type { movie, show, episode, artist }
section_key { unique library key }
Parameters required: section_type { movie, show, episode, artist }
section_id { unique library key }
Output: array
"""
if library_type == 'movie':
if section_type == 'movie':
sort_type = '&type=1'
elif library_type == 'show':
elif section_type == 'show':
sort_type = '&type=2'
elif library_type == 'season':
elif section_type == 'season':
sort_type = '&type=3'
elif library_type == 'episode':
elif section_type == 'episode':
sort_type = '&type=4'
elif library_type == 'artist':
elif section_type == 'artist':
sort_type = '&type=8'
elif library_type == 'album':
elif section_type == 'album':
sort_type = '&type=9'
elif library_type == 'track':
elif section_type == 'track':
sort_type = '&type=10'
elif library_type == 'photo':
elif section_type == 'photo':
sort_type = ''
elif library_type == 'photoAlbum':
elif section_type == 'photoAlbum':
sort_type = '&type=14'
elif library_type == 'picture':
elif section_type == 'picture':
sort_type = '&type=13'
else:
sort_type = ''
if str(section_id).isdigit():
library_data = self.get_library_list(section_id, list_type, count, sort_type, output_format='xml')
elif str(rating_key).isdigit():
library_data = self.get_children_list(rating_key, output_format='xml')
else:
logger.warn(u"PlexPy Pmsconnect :: get_library_children called by invalid section_id or rating_key provided.")
return []
library_data = self.get_library_list(section_key, list_type, count, sort_type, output_format='xml')
try:
xml_head = library_data.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_library_children: %s." % e)
return []
library_list = []
childern_list = []
for a in xml_head:
if a.getAttribute('size'):
if a.getAttribute('size') == '0':
logger.debug(u"PlexPy Pmsconnect :: No library data.")
library_list = {'library_count': '0',
'library_list': []
childern_list = {'library_count': '0',
'childern_list': []
}
return library_list
return childern_list
if rating_key:
library_count = helpers.get_xml_attr(xml_head[0], 'size')
else:
library_count = helpers.get_xml_attr(xml_head[0], 'totalSize')
# Get show/season info from xml_head
if a.getElementsByTagName('Directory'):
result_data = a.getElementsByTagName('Directory')
for result in result_data:
library_output = {'key': helpers.get_xml_attr(result, 'key'),
'type': helpers.get_xml_attr(result, 'type'),
'title': helpers.get_xml_attr(result, 'title'),
'thumb': helpers.get_xml_attr(result, 'thumb')
item_main = a.getElementsByTagName('Directory')
item_main = [d for d in item_main if helpers.get_xml_attr(d, 'ratingKey')]
elif a.getElementsByTagName('Video'):
item_main = a.getElementsByTagName('Video')
elif a.getElementsByTagName('Track'):
item_main = a.getElementsByTagName('Track')
elif a.getElementsByTagName('Photo'):
item_main = a.getElementsByTagName('Photo')
else:
item_main = []
for item in item_main:
item_info = {'section_id': helpers.get_xml_attr(item, 'key'),
'section_type': helpers.get_xml_attr(item, 'type'),
'media_type': helpers.get_xml_attr(item, 'type'),
'rating_key': helpers.get_xml_attr(item, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(item, 'parentRatingKey'),
'grandparent_rating_key': helpers.get_xml_attr(item, 'grandparentRatingKey'),
'title': helpers.get_xml_attr(item, 'title'),
'parent_title': helpers.get_xml_attr(item, 'parentTitle'),
'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'),
'media_index': helpers.get_xml_attr(item, 'index'),
'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'),
'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'),
'parent_thumb': helpers.get_xml_attr(item, 'parentThumb'),
'grandparent_thumb': helpers.get_xml_attr(item, 'grandparentThumb'),
'added_at': helpers.get_xml_attr(item, 'addedAt')
}
if get_media_info:
item_media = item.getElementsByTagName('Media')
for media in item_media:
media_info = {'container': helpers.get_xml_attr(media, 'container'),
'bitrate': helpers.get_xml_attr(media, 'bitrate'),
'video_codec': helpers.get_xml_attr(media, 'videoCodec'),
'video_resolution': helpers.get_xml_attr(media, 'videoResolution'),
'video_framerate': helpers.get_xml_attr(media, 'videoFrameRate'),
'audio_codec': helpers.get_xml_attr(media, 'audioCodec'),
'audio_channels': helpers.get_xml_attr(media, 'audioChannels'),
'file': helpers.get_xml_attr(media.getElementsByTagName('Part')[0], 'file'),
'file_size': helpers.get_xml_attr(media.getElementsByTagName('Part')[0], 'size'),
}
library_list.append(library_output)
item_info.update(media_info)
output = {'library_count': helpers.get_xml_attr(xml_head[0], 'totalSize'),
'count_type': helpers.get_xml_attr(xml_head[0], 'title2'),
'library_list': library_list
childern_list.append(item_info)
output = {'library_count': library_count,
'childern_list': childern_list
}
return output
def get_library_details(self):
@ -1590,57 +1685,44 @@ class PmsConnect(object):
libraries_list = server_libraries['libraries_list']
for library in libraries_list:
library_type = library['type']
section_key = library['key']
library_list = self.get_library_children(library_type, section_key)
section_type = library['section_type']
section_id = library['section_id']
children_list = self.get_library_children(section_id=section_id, section_type=section_type, count='1')
if library_list['library_count'] != '0':
library_stats = {'key': library['key'],
'title': library['title'],
'type': library_type,
if children_list['library_count'] != '0':
library_stats = {'section_id': library['section_id'],
'section_name': library['section_name'],
'section_type': section_type,
'thumb': library['thumb'],
'art': library['art'],
'count': library_list['library_count'],
'count_type': library_list['count_type']
'count': children_list['library_count']
}
if library_type == 'show':
parent_list = self.get_library_children(library_type='season', section_key=section_key)
parent_stats = {'parent_count': parent_list['library_count'],
'parent_count_type': 'All Seasons'
}
if section_type == 'show':
parent_list = self.get_library_children(section_id=section_id, section_type='season', count='1')
parent_stats = {'parent_count': parent_list['library_count']}
library_stats.update(parent_stats)
child_list = self.get_library_children(library_type='episode', section_key=section_key)
child_stats = {'child_count': child_list['library_count'],
'child_count_type': 'All Episodes'
}
child_list = self.get_library_children(section_id=section_id, section_type='episode', count='1')
child_stats = {'child_count': child_list['library_count']}
library_stats.update(child_stats)
if library_type == 'artist':
parent_list = self.get_library_children(library_type='album', section_key=section_key)
parent_stats = {'parent_count': parent_list['library_count'],
'parent_count_type': 'All Seasons'
}
if section_type == 'artist':
parent_list = self.get_library_children(section_id=section_id, section_type='album', count='1')
parent_stats = {'parent_count': parent_list['library_count']}
library_stats.update(parent_stats)
child_list = self.get_library_children(library_type='track', section_key=section_key)
child_stats = {'child_count': child_list['library_count'],
'child_count_type': 'All Albums'
}
child_list = self.get_library_children(section_id=section_id, section_type='track', count='1')
child_stats = {'child_count': child_list['library_count']}
library_stats.update(child_stats)
if library_type == 'photo':
parent_list = self.get_library_children(library_type='photoAlbum', section_key=section_key)
parent_stats = {'parent_count': parent_list['library_count'],
'parent_count_type': 'All Photo Albums'
}
if section_type == 'photo':
parent_list = self.get_library_children(section_id=section_id, section_type='photoAlbum', count='1')
parent_stats = {'parent_count': parent_list['library_count']}
library_stats.update(parent_stats)
child_list = self.get_library_children(library_type='picture', section_key=section_key)
child_stats = {'child_count': child_list['library_count'],
'child_count_type': 'All Photos'
}
child_list = self.get_library_children(section_id=section_id, section_type='picture', count='1')
child_stats = {'child_count': child_list['library_count']}
library_stats.update(child_stats)
server_library_stats.append(library_stats)
@ -1782,7 +1864,7 @@ class PmsConnect(object):
else:
match_type = 'index'
library_id = None
section_id = None
library_name = None
# get grandparent rating key
@ -1790,7 +1872,7 @@ class PmsConnect(object):
try:
metadata = self.get_metadata_details(rating_key=rating_key)
rating_key = metadata['metadata']['parent_rating_key']
library_id = metadata['metadata']['library_id']
section_id = metadata['metadata']['section_id']
library_name = metadata['metadata']['library_name']
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to get parent_rating_key for get_rating_keys_list: %s." % e)
@ -1800,7 +1882,7 @@ class PmsConnect(object):
try:
metadata = self.get_metadata_details(rating_key=rating_key)
rating_key = metadata['metadata']['grandparent_rating_key']
library_id = metadata['metadata']['library_id']
section_id = metadata['metadata']['section_id']
library_name = metadata['metadata']['library_name']
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to get grandparent_rating_key for get_rating_keys_list: %s." % e)
@ -1875,10 +1957,10 @@ class PmsConnect(object):
key_list = {key:
{'rating_key': int(rating_key),
'children': parents },
'library_id': library_id,
'library_name': library_name
}
'section_id': section_id,
'library_name': library_name
}
return key_list
def get_server_response(self):

View file

@ -73,6 +73,11 @@ class Users(object):
rows = []
for item in users:
if item['friendly_name']:
friendly_name = item['friendly_name']
else:
friendly_name = item['username']
if item['media_type'] == 'episode' and item['parent_thumb']:
thumb = item['parent_thumb']
elif item['media_type'] == 'episode':
@ -114,7 +119,7 @@ class Users(object):
'recordsTotal': query['totalCount'],
'data': rows,
'draw': query['draw']
}
}
return dict
@ -199,7 +204,7 @@ class Users(object):
'recordsTotal': query['totalCount'],
'data': rows,
'draw': query['draw']
}
}
return dict

View file

@ -234,7 +234,11 @@ class WebInterface(object):
@cherrypy.expose
def libraries(self):
return serve_template(templatename="libraries.html", title="Libraries")
config = {
"update_section_ids": plexpy.CONFIG.UPDATE_SECTION_IDS
}
return serve_template(templatename="libraries.html", title="Libraries", config=config)
@cherrypy.expose
def get_library_list(self, **kwargs):
@ -300,10 +304,10 @@ class WebInterface(object):
return status_message
@cherrypy.expose
def get_library_watch_time_stats(self, library_id=None, **kwargs):
def get_library_watch_time_stats(self, section_id=None, **kwargs):
library_data = libraries.Libraries()
result = library_data.get_watch_time_stats(library_id=library_id)
result = library_data.get_watch_time_stats(section_id=section_id)
if result:
return serve_template(templatename="user_watch_time_stats.html", data=result, title="Watch Stats")
@ -312,10 +316,10 @@ class WebInterface(object):
return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats")
@cherrypy.expose
def get_library_user_stats(self, library_id=None, **kwargs):
def get_library_user_stats(self, section_id=None, **kwargs):
library_data = libraries.Libraries()
result = library_data.get_user_stats(library_id=library_id)
result = library_data.get_user_stats(section_id=section_id)
if result:
return serve_template(templatename="library_user_stats.html", data=result, title="Player Stats")
@ -324,10 +328,10 @@ class WebInterface(object):
return serve_template(templatename="library_user_stats.html", data=None, title="Player Stats")
@cherrypy.expose
def get_library_recently_watched(self, library_id=None, limit='10', **kwargs):
def get_library_recently_watched(self, section_id=None, limit='10', **kwargs):
library_data = libraries.Libraries()
result = library_data.get_recently_watched(library_id=library_id, limit=limit)
result = library_data.get_recently_watched(section_id=section_id, limit=limit)
if result:
return serve_template(templatename="user_recently_watched.html", data=result, title="Recently Watched")
@ -336,10 +340,10 @@ class WebInterface(object):
return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched")
@cherrypy.expose
def get_library_recently_added(self, library_id=None, limit='10', **kwargs):
def get_library_recently_added(self, section_id=None, limit='10', **kwargs):
library_data = pmsconnect.PmsConnect()
result = library_data.get_recently_added_details(library_id=library_id, count=limit)
pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_recently_added_details(section_id=section_id, count=limit)
if result:
return serve_template(templatename="library_recently_added.html", data=result['recently_added'], title="Recently Added")
@ -347,6 +351,39 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_library_recently_added.")
return serve_template(templatename="library_recently_added.html", data=None, title="Recently Added")
@cherrypy.expose
def get_library_media_info(self, section_id=None, **kwargs):
library_data = libraries.Libraries()
result = library_data.get_datatables_media_info(section_id=section_id, kwargs=kwargs)
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps(result)
@cherrypy.expose
def get_library_media_info2(self, section_id=None, section_type=None, rating_key=None, **kwargs):
library_data = libraries.Libraries()
result = library_data.get_datatables_media_info2(section_id=section_id,
section_type=section_type,
rating_key=rating_key,
kwargs=kwargs)
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps(result)
@cherrypy.expose
def get_library_unwatched(self, section_id=None, section_type=None, **kwargs):
pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_library_children(section_id=section_id,
section_type=section_type,
get_media_info=True,
kwargs=kwargs)
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps(result)
@cherrypy.expose
def delete_all_library_history(self, section_id, **kwargs):
library_data = libraries.Libraries()
@ -395,6 +432,35 @@ class WebInterface(object):
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': 'no data received'})
@cherrypy.expose
def update_section_ids(self, **kwargs):
logger.debug(u"Updating section_id's in database.")
library_data = libraries.Libraries()
result = library_data.update_section_ids()
if result:
logger.debug(u"Updated all section_id's in database.")
plexpy.CONFIG.UPDATE_SECTION_IDS = 0
plexpy.CONFIG.write()
return "Section ids updated."
else:
logger.debug(u"Unable to update section_id's in database.")
return "Unable to update section ids in database."
@cherrypy.expose
def delete_datatable_media_info_cache(self, section_id, **kwargs):
library_data = libraries.Libraries()
if section_id:
delete_row = library_data.delete_datatable_media_info_cache(section_id=section_id)
if delete_row:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': delete_row})
else:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': 'no data received'})
##### Users #####
@ -595,7 +661,7 @@ class WebInterface(object):
custom_where.append(['session_history.reference_id', reference_id])
if 'section_id' in kwargs:
section_id = kwargs.get('section_id', "")
custom_where.append(['session_history_metadata.library_id', section_id])
custom_where.append(['session_history_metadata.section_id', section_id])
if 'media_type' in kwargs:
media_type = kwargs.get('media_type', "")
if media_type != 'all':
@ -1348,14 +1414,10 @@ class WebInterface(object):
@cherrypy.expose
def info(self, rating_key=None, source=None, **kwargs):
# temporary until I find a beter place to put this
#data_factory.update_library_ids()
metadata = None
config = {
"pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER,
"update_library_ids": plexpy.CONFIG.UPDATE_LIBRARY_IDS
"pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER
}
if source == 'history':
@ -1371,7 +1433,6 @@ class WebInterface(object):
return serve_template(templatename="info.html", data=metadata, title="Info", config=config)
else:
return self.update_metadata(rating_key)
#raise cherrypy.InternalRedirect("/update_metadata?rating_key=" + rating_key)
@cherrypy.expose
def get_item_children(self, rating_key='', **kwargs):
@ -1493,24 +1554,7 @@ class WebInterface(object):
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': 'no data received'})
@cherrypy.expose
def update_history_rating_key(self, old_rating_key, new_rating_key, media_type, **kwargs):
data_factory = datafactory.DataFactory()
pms_connect = pmsconnect.PmsConnect()
old_key_list = data_factory.get_rating_keys_list(rating_key=old_rating_key, media_type=media_type)
new_key_list = pms_connect.get_rating_keys_list(rating_key=new_rating_key, media_type=media_type)
update_db = data_factory.update_rating_key(old_key_list=old_key_list,
new_key_list=new_key_list,
media_type=media_type)
if update_db:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': update_db})
else:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': 'no data received'})
# test code
@cherrypy.expose
@ -1537,22 +1581,6 @@ class WebInterface(object):
else:
logger.warn(u"Unable to retrieve data for get_old_rating_keys.")
@cherrypy.expose
def update_library_ids(self, **kwargs):
logger.debug(u"Updating library_id's in database.")
data_factory = datafactory.DataFactory()
result = data_factory.update_library_ids()
if result:
logger.debug(u"Updated all library_id's in database.")
plexpy.CONFIG.UPDATE_LIBRARY_IDS = 0
plexpy.CONFIG.write()
return "Library ids updated."
else:
logger.debug(u"Unable to update library_id's in database.")
return "Unable to update library ids in database."
##### API #####