diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py index ecf816b7..cfe51cb6 100644 --- a/plexpy/datafactory.py +++ b/plexpy/datafactory.py @@ -1017,9 +1017,10 @@ class DataFactory(object): return library_stats - def get_watch_time_stats(self, rating_key=None, media_type=None, grouping=None, query_days=None): + def get_watch_time_stats(self, rating_key=None, grouping=None, query_days=None): if rating_key is None: return [] + if grouping is None: grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES @@ -1036,13 +1037,6 @@ class DataFactory(object): section_ids = set() - if media_type in ('show', 'artist'): - media_type_key = 'session_history.grandparent_rating_key' - elif media_type in ('season', 'album'): - media_type_key = 'session_history.parent_rating_key' - else: # movie, episode, track - media_type_key = 'session_history.rating_key' - group_by = 'session_history.reference_id' if grouping else 'session_history.id' for days in query_days: @@ -1057,8 +1051,10 @@ class DataFactory(object): 'FROM session_history ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ 'WHERE stopped >= %s ' \ - 'AND %s = ?' % (group_by, timestamp_query, media_type_key) - result = monitor_db.select(query, args=[rating_key]) + 'AND (session_history.grandparent_rating_key = ? ' \ + 'OR session_history.parent_rating_key = ? ' \ + 'OR session_history.rating_key = ?)' % (group_by, timestamp_query) + result = monitor_db.select(query, args=[rating_key, rating_key, rating_key]) else: result = [] else: @@ -1068,8 +1064,10 @@ class DataFactory(object): 'COUNT(DISTINCT %s) AS total_plays, section_id ' \ 'FROM session_history ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ - 'WHERE %s = ?' % (group_by, media_type_key) - result = monitor_db.select(query, args=[rating_key]) + 'WHERE (session_history.grandparent_rating_key = ? ' \ + 'OR session_history.parent_rating_key = ? ' \ + 'OR session_history.rating_key = ?)' % group_by + result = monitor_db.select(query, args=[rating_key, rating_key, rating_key]) else: result = [] except Exception as e: @@ -1098,7 +1096,7 @@ class DataFactory(object): return item_watch_time_stats - def get_user_stats(self, rating_key=None, media_type=None, grouping=None): + def get_user_stats(self, rating_key=None, grouping=None): if grouping is None: grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES @@ -1108,13 +1106,6 @@ class DataFactory(object): section_ids = set() - if media_type in ('show', 'artist'): - media_type_key = 'session_history.grandparent_rating_key' - elif media_type in ('season', 'album'): - media_type_key = 'session_history.parent_rating_key' - else: # movie, episode, track - media_type_key = 'session_history.rating_key' - group_by = 'session_history.reference_id' if grouping else 'session_history.id' try: @@ -1122,14 +1113,18 @@ class DataFactory(object): 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.username, users.thumb, users.custom_avatar_url AS custom_thumb, ' \ - 'COUNT(DISTINCT %s) AS user_count, section_id ' \ + 'COUNT(DISTINCT %s) AS total_plays, (SUM(stopped - started) - ' \ + 'SUM(CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END)) AS total_time, ' \ + 'section_id ' \ '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 %s = ? ' \ + 'WHERE (session_history.grandparent_rating_key = ? ' \ + 'OR session_history.parent_rating_key = ? ' \ + 'OR session_history.rating_key = ?) ' \ 'GROUP BY users.user_id ' \ - 'ORDER BY user_count DESC' % (group_by, media_type_key) - result = monitor_db.select(query, args=[rating_key]) + 'ORDER BY total_plays DESC, total_time DESC' % group_by + result = monitor_db.select(query, args=[rating_key, rating_key, rating_key]) else: result = [] except Exception as e: @@ -1150,7 +1145,8 @@ class DataFactory(object): 'user_id': item['user_id'], 'user_thumb': user_thumb, 'username': item['username'], - 'total_plays': item['user_count'] + 'total_plays': item['total_plays'], + 'total_time': item['total_time'] } user_stats.append(row) diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 6bd8fbe5..24acb65c 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -1060,7 +1060,7 @@ class WebInterface(object): ``` Required parameters: - section_id (str): The id of the Plex library section + section_id (str): The id of the Plex library section Optional parameters: grouping (int): 0 or 1 @@ -1069,12 +1069,14 @@ class WebInterface(object): json: [{"friendly_name": "Jon Snow", "total_plays": 170, + "total_time": 349618 "user_id": 133788, "user_thumb": "https://plex.tv/users/k10w42309cynaopq/avatar", "username": "LordCommanderSnow" }, {"friendly_name": "DanyKhaleesi69", "total_plays": 42, + "total_time": 50185 "user_id": 8008135, "user_thumb": "https://plex.tv/users/568gwwoib5t98a3a/avatar", "username: "DanyKhaleesi69" @@ -4515,10 +4517,10 @@ class WebInterface(object): @cherrypy.expose @requireAuth() - def item_watch_time_stats(self, rating_key=None, media_type=None, **kwargs): + def item_watch_time_stats(self, rating_key=None, **kwargs): if rating_key: item_data = datafactory.DataFactory() - result = item_data.get_watch_time_stats(rating_key=rating_key, media_type=media_type) + result = item_data.get_watch_time_stats(rating_key=rating_key) else: result = None @@ -4528,20 +4530,35 @@ class WebInterface(object): logger.warn("Unable to retrieve data for item_watch_time_stats.") return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats") + @cherrypy.expose + @requireAuth() + def item_user_stats(self, rating_key=None, **kwargs): + if rating_key: + item_data = datafactory.DataFactory() + result = item_data.get_user_stats(rating_key=rating_key) + else: + result = None + + if result: + return serve_template(templatename="library_user_stats.html", data=result, title="Player Stats") + else: + logger.warn("Unable to retrieve data for item_user_stats.") + return serve_template(templatename="library_user_stats.html", data=None, title="Player Stats") + @cherrypy.expose @cherrypy.tools.json_out() @requireAuth(member_of("admin")) @addtoapi() - def get_item_watch_time_stats(self, rating_key=None, media_type=None, **kwargs): + def get_item_watch_time_stats(self, rating_key=None, grouping=None, query_days=None, **kwargs): """ Get the watch time stats for the media item. ``` Required parameters: rating_key (str): Rating key of the item - media_type (str): Media type of the item Optional parameters: - None + grouping (int): 0 or 1 + query_days (str): Comma separated days, e.g. "1,7,30,0" Returns: json: @@ -4569,47 +4586,33 @@ class WebInterface(object): ] ``` """ + grouping = helpers.bool_true(grouping, return_none=True) + if rating_key: item_data = datafactory.DataFactory() - stats = item_data.get_watch_time_stats(rating_key=rating_key, media_type=media_type) + result = item_data.get_watch_time_stats(rating_key=rating_key, grouping=grouping, + query_days=query_days) + if result: + return result + else: + logger.warn("Unable to retrieve data for get_item_watch_time_stats.") + return result else: - stats = None - - if stats: - return stats - else: - logger.warn("Unable to retrieve data for get_item_watch_time_stats.") - return stats - - @cherrypy.expose - @requireAuth() - def item_user_stats(self, rating_key=None, media_type=None, **kwargs): - if rating_key: - item_data = datafactory.DataFactory() - result = item_data.get_user_stats(rating_key=rating_key, media_type=media_type) - else: - result = None - - if result: - return serve_template(templatename="library_user_stats.html", data=result, title="Player Stats") - else: - logger.warn("Unable to retrieve data for item_user_stats.") - return serve_template(templatename="library_user_stats.html", data=None, title="Player Stats") + logger.warn("Item watch time stats requested but no rating_key received.") @cherrypy.expose @cherrypy.tools.json_out() @requireAuth(member_of("admin")) @addtoapi() - def get_item_user_stats(self, rating_key=None, media_type=None, **kwargs): + def get_item_user_stats(self, rating_key=None, grouping=None, **kwargs): """ Get the user stats for the media item. ``` Required parameters: rating_key (str): Rating key of the item - media_type (str): Media type of the item Optional parameters: - None + grouping (int): 0 or 1 Returns: json: @@ -4619,29 +4622,32 @@ class WebInterface(object): "user_id": 1601089, "user_thumb": "", "username": "jsnow@thewinteriscoming.com", - "total_plays": 6 + "total_plays": 6, + "total_time": 28743 }, { "friendly_name": "DanyKhaleesi69", "user_id": 8008135, "user_thumb": "", "username": "DanyKhaleesi69", - "total_plays": 5 + "total_plays": 5, + "total_time": 18583 } ] ``` """ + grouping = helpers.bool_true(grouping, return_none=True) + if rating_key: item_data = datafactory.DataFactory() - stats = item_data.get_user_stats(rating_key=rating_key, media_type=media_type) + result = item_data.get_user_stats(rating_key=rating_key, grouping=grouping) + if result: + return result + else: + logger.warn("Unable to retrieve data for get_item_user_stats.") + return result else: - stats = None - - if stats: - return stats - else: - logger.warn("Unable to retrieve data for get_item_user_stats.") - return stats + logger.warn("Item user stats requested but no rating_key received.") @cherrypy.expose @cherrypy.tools.json_out()