def get_user_stats(self, section_id=None): if not session.allow_session_library(section_id): return [] monitor_db = database.MonitorDatabase() user_stats = [] try: if str(section_id).isdigit(): query = 'SELECT (CASE WHEN users.friendly_name IS NULL OR TRIM(users.friendly_name) = "" ' \ 'THEN users.username ELSE users.friendly_name END) AS friendly_name, ' \ '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 section_id = ? ' \ 'GROUP BY users.user_id ' \ 'ORDER BY user_count DESC' result = monitor_db.select(query, args=[section_id]) else: result = [] except Exception as e: logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_user_stats: %s." % e) result = [] for item in result: row = {'friendly_name': item['friendly_name'], 'user_id': item['user_id'], 'user_thumb': item['thumb'], 'total_plays': item['user_count'] } user_stats.append(row) return session.mask_session_info(user_stats, mask_metadata=False)
def get_user_stats(self, section_id=None): if not session.allow_session_library(section_id): return [] monitor_db = database.MonitorDatabase() user_stats = [] try: if str(section_id).isdigit(): query = 'SELECT (CASE WHEN users.friendly_name IS NULL THEN users.username ' \ 'ELSE users.friendly_name END) AS friendly_name, 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 section_id = ? ' \ 'GROUP BY users.user_id ' \ 'ORDER BY user_count DESC' result = monitor_db.select(query, args=[section_id]) else: result = [] except Exception as e: logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_user_stats: %s." % e) result = [] for item in result: row = {'friendly_name': item['friendly_name'], 'user_id': item['user_id'], 'user_thumb': item['thumb'], 'total_plays': item['user_count'] } user_stats.append(row) return session.mask_session_info(user_stats, mask_metadata=False)
def get_recently_watched(self, section_id=None, limit='10'): if not session.allow_session_library(section_id): return [] monitor_db = database.MonitorDatabase() recently_watched = [] if not limit.isdigit(): limit = '10' try: if str(section_id).isdigit(): query = 'SELECT session_history.id, session_history.media_type, ' \ 'session_history.rating_key, session_history.parent_rating_key, session_history.grandparent_rating_key, ' \ 'title, parent_title, grandparent_title, thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \ 'year, started, user, content_rating, labels, section_id ' \ 'FROM session_history_metadata ' \ 'JOIN session_history ON session_history_metadata.id = session_history.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=[section_id, limit]) else: result = [] except Exception as e: logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_recently_watched: %s." % e) result = [] for row in result: if row['media_type'] == 'episode' and row['parent_thumb']: thumb = row['parent_thumb'] elif row['media_type'] == 'episode': thumb = row['grandparent_thumb'] else: thumb = row['thumb'] recent_output = {'row_id': row['id'], 'media_type': row['media_type'], 'rating_key': row['rating_key'], 'parent_rating_key': row['parent_rating_key'], 'grandparent_rating_key': row['grandparent_rating_key'], 'title': row['title'], 'parent_title': row['parent_title'], 'grandparent_title': row['grandparent_title'], 'thumb': thumb, 'media_index': row['media_index'], 'parent_media_index': row['parent_media_index'], 'year': row['year'], 'time': row['started'], 'user': row['user'], 'section_id': row['section_id'], 'content_rating': row['content_rating'], 'labels': row['labels'].split(';') if row['labels'] else (), } recently_watched.append(recent_output) return session.mask_session_info(recently_watched)
def get_watch_time_stats(self, section_id=None): if not session.allow_session_library(section_id): return [] monitor_db = database.MonitorDatabase() time_queries = [1, 7, 30, 0] library_watch_time_stats = [] for days in time_queries: try: if days > 0: 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 section_id = ?' % days result = monitor_db.select(query, args=[section_id]) else: result = [] else: 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 section_id = ?' result = monitor_db.select(query, args=[section_id]) else: result = [] except Exception as e: logger.warn( u"PlexPy Libraries :: Unable to execute database query for get_watch_time_stats: %s." % e) result = [] for item in result: if item['total_time']: total_time = item['total_time'] total_plays = item['total_plays'] else: total_time = 0 total_plays = 0 row = { 'query_days': days, 'total_time': total_time, 'total_plays': total_plays } library_watch_time_stats.append(row) return library_watch_time_stats
def get_watch_time_stats(self, section_id=None): if not session.allow_session_library(section_id): return [] monitor_db = database.MonitorDatabase() time_queries = [1, 7, 30, 0] library_watch_time_stats = [] for days in time_queries: try: if days > 0: 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 section_id = ?' % days result = monitor_db.select(query, args=[section_id]) else: result = [] else: 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 section_id = ?' result = monitor_db.select(query, args=[section_id]) else: result = [] except Exception as e: logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_watch_time_stats: %s." % e) result = [] for item in result: if item['total_time']: total_time = item['total_time'] total_plays = item['total_plays'] else: total_time = 0 total_plays = 0 row = {'query_days': days, 'total_time': total_time, 'total_plays': total_plays } library_watch_time_stats.append(row) return library_watch_time_stats
def get_user_stats(self, section_id=None, grouping=None): if not session.allow_session_library(section_id): return [] if grouping is None: grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES monitor_db = database.MonitorDatabase() user_stats = [] group_by = 'session_history.reference_id' if grouping else 'session_history.id' try: if str(section_id).isdigit(): query = 'SELECT (CASE WHEN users.friendly_name IS NULL OR TRIM(users.friendly_name) = "" ' \ 'THEN users.username ELSE users.friendly_name END) AS friendly_name, ' \ 'users.user_id, users.thumb, users.custom_avatar_url AS custom_thumb, ' \ 'COUNT(DISTINCT %s) 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 section_id = ? ' \ 'GROUP BY users.user_id ' \ 'ORDER BY user_count DESC' % group_by result = monitor_db.select(query, args=[section_id]) else: result = [] except Exception as e: logger.warn( "Tautulli Libraries :: Unable to execute database query for get_user_stats: %s." % e) result = [] for item in result: if item['custom_thumb'] and item['custom_thumb'] != item['thumb']: user_thumb = item['custom_thumb'] elif item['thumb']: user_thumb = item['thumb'] else: user_thumb = common.DEFAULT_USER_THUMB row = { 'friendly_name': item['friendly_name'], 'user_id': item['user_id'], 'user_thumb': user_thumb, 'total_plays': item['user_count'] } user_stats.append(row) return session.mask_session_info(user_stats, mask_metadata=False)
def get_media_info_file_sizes(self, section_id=None, rating_key=None): if not session.allow_session_library(section_id): return False if section_id and not str(section_id).isdigit(): logger.warn( u"PlexPy Libraries :: Datatable media info file size called by invalid section_id provided." ) return False elif rating_key and not str(rating_key).isdigit(): logger.warn( u"PlexPy Libraries :: Datatable media info file size called by invalid rating_key provided." ) return False # Get the library details library_details = self.get_details(section_id=section_id) if library_details['section_id'] == None: logger.debug( u"PlexPy Libraries :: Library section_id %s not found." % section_id) return False if library_details['section_type'] == 'photo': return False rows = [] # Import media info cache from json file if rating_key: #logger.debug(u"PlexPy Libraries :: Getting file sizes for rating_key %s." % 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) 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) pass elif section_id: logger.debug( u"PlexPy Libraries :: Getting file sizes for section_id %s." % 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) 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) pass # Get the total file size for each item pms_connect = pmsconnect.PmsConnect() for item in rows: if item['rating_key'] and not item['file_size']: file_size = 0 child_metadata = pms_connect.get_metadata_children_details( rating_key=item['rating_key'], get_children=True, get_media_info=True) metadata_list = child_metadata['metadata'] for child_metadata in metadata_list: file_size += helpers.cast_to_int( child_metadata.get('file_size', 0)) item['file_size'] = file_size # Cache the media info to a json file if rating_key: try: 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) except IOError as e: logger.debug( u"PlexPy Libraries :: Unable to create cache file with file sizes for rating_key %s." % rating_key) elif section_id: try: outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR, 'media_info_%s.json' % section_id) with open(outFilePath, 'w') as outFile: json.dump(rows, outFile) except IOError as e: logger.debug( u"PlexPy Libraries :: Unable to create cache file with file sizes for section_id %s." % section_id) if rating_key: #logger.debug(u"PlexPy Libraries :: File sizes updated for rating_key %s." % rating_key) pass elif section_id: logger.debug( u"PlexPy Libraries :: File sizes updated for section_id %s." % section_id) return True
def get_datatables_media_info(self, section_id=None, section_type=None, rating_key=None, refresh=False, kwargs=None): default_return = { 'recordsFiltered': 0, 'recordsTotal': 0, 'draw': 0, 'data': 'null', 'error': 'Unable to execute database query.' } if not session.allow_session_library(section_id): return default_return if section_id and not str(section_id).isdigit(): logger.warn( u"PlexPy Libraries :: Datatable media info called but 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 but invalid rating_key provided." ) return default_return elif not section_id and not rating_key: logger.warn( u"PlexPy Libraries :: Datatable media info called but no input provided." ) return default_return # Get the library details library_details = self.get_details(section_id=section_id) if library_details['section_id'] == None: logger.debug( 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 plexpy.CONFIG.GROUP_HISTORY_TABLES: count_by = 'reference_id' else: count_by = 'id' 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_played, COUNT(DISTINCT session_history.%s) 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 ' % (count_by, 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_played': item['last_played'], 'play_count': item['play_count'] } rows = [] # Import media info cache from json file 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) pass 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) pass # If no cache was imported, get all library children items cached_items = {d['rating_key']: d['file_size'] for d in rows} if not refresh else {} if refresh or not rows: pms_connect = pmsconnect.PmsConnect() if rating_key: library_children = pms_connect.get_library_children_details( rating_key=rating_key, get_media_info=True) elif section_id: library_children = pms_connect.get_library_children_details( 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 new_rows = [] for item in children_list: cached_file_size = cached_items.get(item['rating_key'], None) file_size = cached_file_size if cached_file_size else item.get( 'file_size', '') row = { 'section_id': library_details['section_id'], 'section_type': library_details['section_type'], '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'], 'title': item['title'], 'year': item['year'], 'media_index': item['media_index'], 'parent_media_index': item['parent_media_index'], 'thumb': item['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': file_size } new_rows.append(row) rows = new_rows if not rows: return default_return # Cache the media info to a json file if rating_key: try: 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) except IOError as e: logger.debug( u"PlexPy Libraries :: Unable to create cache file for rating_key %s." % rating_key) elif section_id: try: outFilePath = os.path.join( plexpy.CONFIG.CACHE_DIR, 'media_info_%s.json' % section_id) with open(outFilePath, 'w') as outFile: json.dump(rows, outFile) except IOError as e: logger.debug( u"PlexPy Libraries :: Unable to create cache file for section_id %s." % section_id) # Update the last_played and play_count for item in rows: watched_item = watched_list.get(item['rating_key'], None) if watched_item: item['last_played'] = watched_item['last_played'] item['play_count'] = watched_item['play_count'] else: item['last_played'] = None item['play_count'] = None 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 results = sorted(results, key=lambda k: k['title']) 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: helpers.cast_to_int(k['media_index']), reverse=reverse) elif sort_key == 'file_size' or sort_key == 'bitrate': results = sorted( results, key=lambda k: helpers.cast_to_int(k[sort_key]), reverse=reverse) elif sort_key == 'video_resolution': results = sorted( results, key=lambda k: helpers.cast_to_int(k[sort_key].replace( '4k', '2160p').rstrip('p')), reverse=reverse) else: results = sorted(results, key=lambda k: k[sort_key], reverse=reverse) total_file_size = sum( [helpers.cast_to_int(d['file_size']) for d in results]) # Paginate results results = results[json_data['start']:(json_data['start'] + json_data['length'])] filtered_file_size = sum( [helpers.cast_to_int(d['file_size']) for d in results]) dict = { 'recordsFiltered': filtered_count, 'recordsTotal': library_count, 'data': results, 'draw': int(json_data['draw']), 'filtered_file_size': filtered_file_size, 'total_file_size': total_file_size } return dict
def get_watch_time_stats(self, section_id=None, grouping=None, query_days=None): if not session.allow_session_library(section_id): return [] if grouping is None: grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES if query_days and query_days is not None: query_days = map(helpers.cast_to_int, query_days.split(',')) else: query_days = [1, 7, 30, 0] monitor_db = database.MonitorDatabase() library_watch_time_stats = [] group_by = 'session_history.reference_id' if grouping else 'session_history.id' for days in query_days: try: if days > 0: 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(DISTINCT %s) 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 section_id = ?' % (group_by, days) result = monitor_db.select(query, args=[section_id]) else: result = [] else: 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(DISTINCT %s) AS total_plays ' \ 'FROM session_history ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ 'WHERE section_id = ?' % group_by result = monitor_db.select(query, args=[section_id]) else: result = [] except Exception as e: logger.warn("Tautulli Libraries :: Unable to execute database query for get_watch_time_stats: %s." % e) result = [] for item in result: if item['total_time']: total_time = item['total_time'] total_plays = item['total_plays'] else: total_time = 0 total_plays = 0 row = {'query_days': days, 'total_time': total_time, 'total_plays': total_plays } library_watch_time_stats.append(row) return library_watch_time_stats
def get_media_info_file_sizes(self, section_id=None, rating_key=None): if not session.allow_session_library(section_id): return False if section_id and not str(section_id).isdigit(): logger.warn(u"PlexPy Libraries :: Datatable media info file size called by invalid section_id provided.") return False elif rating_key and not str(rating_key).isdigit(): logger.warn(u"PlexPy Libraries :: Datatable media info file size called by invalid rating_key provided.") return False # Get the library details library_details = self.get_details(section_id=section_id) if library_details['section_id'] == None: logger.debug(u"PlexPy Libraries :: Library section_id %s not found." % section_id) return False if library_details['section_type'] == 'photo': return False rows = [] # Import media info cache from json file if rating_key: #logger.debug(u"PlexPy Libraries :: Getting file sizes for rating_key %s." % 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) 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) pass elif section_id: logger.debug(u"PlexPy Libraries :: Getting file sizes for section_id %s." % 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) 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) pass # Get the total file size for each item pms_connect = pmsconnect.PmsConnect() for item in rows: if item['rating_key'] and not item['file_size']: file_size = 0 child_metadata = pms_connect.get_metadata_children_details(rating_key=item['rating_key'], get_children=True, get_media_info=True) metadata_list = child_metadata['metadata'] for child_metadata in metadata_list: file_size += helpers.cast_to_int(child_metadata.get('file_size', 0)) item['file_size'] = file_size # Cache the media info to a json file if rating_key: try: 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) except IOError as e: logger.debug(u"PlexPy Libraries :: Unable to create cache file with file sizes for rating_key %s." % rating_key) elif section_id: try: outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info_%s.json' % section_id) with open(outFilePath, 'w') as outFile: json.dump(rows, outFile) except IOError as e: logger.debug(u"PlexPy Libraries :: Unable to create cache file with file sizes for section_id %s." % section_id) if rating_key: #logger.debug(u"PlexPy Libraries :: File sizes updated for rating_key %s." % rating_key) pass elif section_id: logger.debug(u"PlexPy Libraries :: File sizes updated for section_id %s." % section_id) return True
def get_datatables_media_info(self, section_id=None, section_type=None, rating_key=None, refresh=False, kwargs=None): default_return = {'recordsFiltered': 0, 'recordsTotal': 0, 'draw': 0, 'data': 'null', 'error': 'Unable to execute database query.'} if not session.allow_session_library(section_id): return default_return if section_id and not str(section_id).isdigit(): logger.warn(u"PlexPy Libraries :: Datatable media info called but 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 but invalid rating_key provided.") return default_return elif not section_id and not rating_key: logger.warn(u"PlexPy Libraries :: Datatable media info called but no input provided.") return default_return # Get the library details library_details = self.get_details(section_id=section_id) if library_details['section_id'] == None: logger.debug(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 plexpy.CONFIG.GROUP_HISTORY_TABLES: count_by = 'reference_id' else: count_by = 'id' 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_played, COUNT(DISTINCT session_history.%s) 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 ' % (count_by, 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_played': item['last_played'], 'play_count': item['play_count']} rows = [] # Import media info cache from json file 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) pass 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) pass # If no cache was imported, get all library children items cached_items = {d['rating_key']: d['file_size'] for d in rows} if refresh or not rows: pms_connect = pmsconnect.PmsConnect() if rating_key: library_children = pms_connect.get_library_children_details(rating_key=rating_key, get_media_info=True) elif section_id: library_children = pms_connect.get_library_children_details(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 new_rows = [] for item in children_list: cached_file_size = cached_items.get(item['rating_key'], None) file_size = cached_file_size if cached_file_size else item.get('file_size', '') row = {'section_id': library_details['section_id'], 'section_type': library_details['section_type'], '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'], 'title': item['title'], 'year': item['year'], 'media_index': item['media_index'], 'parent_media_index': item['parent_media_index'], 'thumb': item['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': file_size } new_rows.append(row) rows = new_rows if not rows: return default_return # Cache the media info to a json file if rating_key: try: 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) except IOError as e: logger.debug(u"PlexPy Libraries :: Unable to create cache file for rating_key %s." % rating_key) elif section_id: try: outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info_%s.json' % section_id) with open(outFilePath, 'w') as outFile: json.dump(rows, outFile) except IOError as e: logger.debug(u"PlexPy Libraries :: Unable to create cache file for section_id %s." % section_id) # Update the last_played and play_count for item in rows: watched_item = watched_list.get(item['rating_key'], None) if watched_item: item['last_played'] = watched_item['last_played'] item['play_count'] = watched_item['play_count'] else: item['last_played'] = None item['play_count'] = None 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 results = sorted(results, key=lambda k: k['title']) 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: helpers.cast_to_int(k['media_index']), reverse=reverse) elif sort_key == 'file_size' or sort_key == 'bitrate': results = sorted(results, key=lambda k: helpers.cast_to_int(k[sort_key]), reverse=reverse) else: results = sorted(results, key=lambda k: k[sort_key], reverse=reverse) total_file_size = sum([helpers.cast_to_int(d['file_size']) for d in results]) # Paginate results results = results[json_data['start']:(json_data['start'] + json_data['length'])] filtered_file_size = sum([helpers.cast_to_int(d['file_size']) for d in results]) dict = {'recordsFiltered': filtered_count, 'recordsTotal': library_count, 'data': results, 'draw': int(json_data['draw']), 'filtered_file_size': filtered_file_size, 'total_file_size': total_file_size } return dict