diff --git a/data/interfaces/default/base.html b/data/interfaces/default/base.html index f0918641..96aa9c81 100644 --- a/data/interfaces/default/base.html +++ b/data/interfaces/default/base.html @@ -62,16 +62,16 @@ from plexpy import version % else:
  • % endif - % if title=="History": -
  • History
  • - % else: -
  • History
  • - % endif % if title=="Users" or title=="User":
  • Users
  • % else:
  • Users
  • % endif + % if title=="History": +
  • History
  • + % else: +
  • History
  • + % endif % if title=="Graphs":
  • Graphs
  • % else: diff --git a/data/interfaces/default/css/plexpy.css b/data/interfaces/default/css/plexpy.css index d9ecc338..903f91a9 100644 --- a/data/interfaces/default/css/plexpy.css +++ b/data/interfaces/default/css/plexpy.css @@ -995,7 +995,7 @@ a .dashboard-activity-metadata-user-thumb:hover { display: block; width: 100%; height: 100%; - background-image: url(/interfaces/default/images/plex-logo-light.svg); + background-image: url(../images/plex-logo-light.svg); background-size: 100px; background-repeat: no-repeat; background-position: center; diff --git a/data/interfaces/default/graphs.html b/data/interfaces/default/graphs.html index a2439250..af6ed442 100644 --- a/data/interfaces/default/graphs.html +++ b/data/interfaces/default/graphs.html @@ -48,7 +48,7 @@

    Daily Play count Last 30 days

    - The total play count or duration of movies and tv played per day. Click a graph point to open up a list of items played for that specific date. + The total play count or duration of tv, movies, and music played per day. Click a graph point to open up a list of items played for that specific date.

    @@ -62,7 +62,7 @@

    Play count by day of week Last 30 days

    - The combined total of movies and tv played per day of the week. + The combined total of tv, movies, and music played per day of the week.

    @@ -75,7 +75,7 @@

    Play count by hour of day Last 30 days

    - The combined total of movies and tv played per hour of the day. + The combined total of tv, movies, and music played per hour of the day.

    @@ -90,7 +90,7 @@

    Play count by top 10 platforms Last 30 days

    - The combined total of movies and tv played by top 10 most active platforms. + The combined total of tv, movies, and music played by top 10 most active platforms.

    @@ -103,7 +103,7 @@

    Play count by top 10 users Last 30 days

    - The combined total of movies and tv played by top 10 most active users. + The combined total of tv, movies, and music played by top 10 most active users.

    @@ -121,7 +121,7 @@

    Daily Stream type breakdown Last 30 days

    - The total play count or duration of movies and tv by the transcode decision. Click a graph point to open up a list of items played for that specific date. + The total play count or duration of tv, movies, and music by the transcode decision. Click a graph point to open up a list of items played for that specific date.

    @@ -135,7 +135,7 @@

    Play count by source resolution Last 30 days

    - The combined total of movies and tv by their original resolution (pre-transcoding). + The combined total of tv and movies by their original resolution (pre-transcoding).

    @@ -148,7 +148,7 @@

    Play count by stream resolution Last 30 days

    - The combined total of movies and tv by their streamed resolution (post-transcoding). + The combined total of tv and movies by their streamed resolution (post-transcoding).

    @@ -163,7 +163,7 @@

    Play count by platform and stream type Last 30 days

    - The combined total of movies and tv by platform and stream type. + The combined total of tv, movies, and music by platform and stream type.

    @@ -176,7 +176,7 @@

    Play count by user and stream type Last 30 days

    - The combined total of movies and tv by user and stream type. + The combined total of tv, movies, and music by user and stream type.

    @@ -194,7 +194,7 @@

    Plays by Month Last 12 months

    - The combined total of movies and tv by month. + The combined total of tv, movies, and music by month.

    diff --git a/data/interfaces/default/home_stats.html b/data/interfaces/default/home_stats.html index 733bea85..01fb0cdd 100644 --- a/data/interfaces/default/home_stats.html +++ b/data/interfaces/default/home_stats.html @@ -51,16 +51,17 @@ DOCUMENTATION :: END from plexpy import helpers # Human readable duration - def hd(minutes): - if int(minutes) > 60: - hours = int(helpers.cast_to_float(minutes) / 60) - minutes = int(helpers.cast_to_float(minutes) % 60 ) + def hd(seconds): + minutes = helpers.cast_to_float(seconds) / 60 + if minutes > 60: + hours = int(minutes / 60) + minutes = int(minutes % 60) if minutes > 0: return "

    " + str(hours) + "

    hrs

    " + str(minutes) + "

    mins

    " else: return "

    " + str(hours) + "

    hrs

    " else: - return "

    " + minutes + "

    mins

    " + return "

    " + str(int(minutes)) + "

    mins

    " %> % if data: diff --git a/data/interfaces/default/js/graphs/plays_by_day.js b/data/interfaces/default/js/graphs/plays_by_day.js index c8dad53f..6eabea39 100644 --- a/data/interfaces/default/js/graphs/plays_by_day.js +++ b/data/interfaces/default/js/graphs/plays_by_day.js @@ -35,7 +35,7 @@ var hc_plays_by_day_options = { } } }, - colors: ['#F9AA03', '#FFFFFF'], + colors: ['#F9AA03', '#FFFFFF', '#FF4747'], xAxis: { type: 'datetime', labels: { diff --git a/data/interfaces/default/js/graphs/plays_by_dayofweek.js b/data/interfaces/default/js/graphs/plays_by_dayofweek.js index 75407fcf..a0d66bbe 100644 --- a/data/interfaces/default/js/graphs/plays_by_dayofweek.js +++ b/data/interfaces/default/js/graphs/plays_by_dayofweek.js @@ -29,7 +29,7 @@ var hc_plays_by_dayofweek_options = { credits: { enabled: false }, - colors: ['#F9AA03', '#FFFFFF'], + colors: ['#F9AA03', '#FFFFFF', '#FF4747'], xAxis: { categories: [{}], labels: { @@ -46,8 +46,26 @@ var hc_plays_by_dayofweek_options = { style: { color: '#aaa' } + }, + stackLabels: { + enabled: false, + style: { + color: '#fff' + } } }, + plotOptions: { + column: { + stacking: 'normal', + borderWidth: '0', + dataLabels: { + enabled: false, + style: { + color: '#000' + } + } + } + }, tooltip: { shared: true }, diff --git a/data/interfaces/default/js/graphs/plays_by_hourofday.js b/data/interfaces/default/js/graphs/plays_by_hourofday.js index 82adde20..e2e036e3 100644 --- a/data/interfaces/default/js/graphs/plays_by_hourofday.js +++ b/data/interfaces/default/js/graphs/plays_by_hourofday.js @@ -29,7 +29,7 @@ var hc_plays_by_hourofday_options = { credits: { enabled: false }, - colors: ['#F9AA03', '#FFFFFF'], + colors: ['#F9AA03', '#FFFFFF', '#FF4747'], xAxis: { categories: [{}], labels: { @@ -46,8 +46,26 @@ var hc_plays_by_hourofday_options = { style: { color: '#aaa' } + }, + stackLabels: { + enabled: false, + style: { + color: '#fff' + } } }, + plotOptions: { + column: { + stacking: 'normal', + borderWidth: '0', + dataLabels: { + enabled: false, + style: { + color: '#000' + } + } + } + }, tooltip: { shared: true }, diff --git a/data/interfaces/default/js/graphs/plays_by_month.js b/data/interfaces/default/js/graphs/plays_by_month.js index d8cf6ebd..c43cf041 100644 --- a/data/interfaces/default/js/graphs/plays_by_month.js +++ b/data/interfaces/default/js/graphs/plays_by_month.js @@ -23,7 +23,7 @@ var hc_plays_by_month_options = { credits: { enabled: false }, - colors: ['#F9AA03', '#FFFFFF'], + colors: ['#F9AA03', '#FFFFFF', '#FF4747'], xAxis: { labels: { style: { diff --git a/data/interfaces/default/js/graphs/plays_by_platform.js b/data/interfaces/default/js/graphs/plays_by_platform.js index 0e3ca9bd..c84d785e 100644 --- a/data/interfaces/default/js/graphs/plays_by_platform.js +++ b/data/interfaces/default/js/graphs/plays_by_platform.js @@ -29,7 +29,7 @@ var hc_plays_by_platform_options = { credits: { enabled: false }, - colors: ['#F9AA03', '#FFFFFF'], + colors: ['#F9AA03', '#FFFFFF', '#FF4747'], xAxis: { categories: [{}], labels: { @@ -46,8 +46,26 @@ var hc_plays_by_platform_options = { style: { color: '#aaa' } + }, + stackLabels: { + enabled: false, + style: { + color: '#fff' + } } }, + plotOptions: { + column: { + stacking: 'normal', + borderWidth: '0', + dataLabels: { + enabled: false, + style: { + color: '#000' + } + } + } + }, tooltip: { shared: true }, diff --git a/data/interfaces/default/js/graphs/plays_by_source_resolution.js b/data/interfaces/default/js/graphs/plays_by_source_resolution.js index 88b02209..c82f16bc 100644 --- a/data/interfaces/default/js/graphs/plays_by_source_resolution.js +++ b/data/interfaces/default/js/graphs/plays_by_source_resolution.js @@ -29,7 +29,7 @@ var hc_plays_by_source_resolution_options = { credits: { enabled: false }, - colors: ['#F9AA03', '#FFFFFF'], + colors: ['#F9AA03', '#FFFFFF', '#FF4747'], xAxis: { categories: [{}], labels: { @@ -46,8 +46,26 @@ var hc_plays_by_source_resolution_options = { style: { color: '#aaa' } + }, + stackLabels: { + enabled: false, + style: { + color: '#fff' + } } }, + plotOptions: { + column: { + stacking: 'normal', + borderWidth: '0', + dataLabels: { + enabled: false, + style: { + color: '#000' + } + } + } + }, tooltip: { shared: true }, diff --git a/data/interfaces/default/js/graphs/plays_by_stream_resolution.js b/data/interfaces/default/js/graphs/plays_by_stream_resolution.js index 5a7b546c..7ae7f84d 100644 --- a/data/interfaces/default/js/graphs/plays_by_stream_resolution.js +++ b/data/interfaces/default/js/graphs/plays_by_stream_resolution.js @@ -29,7 +29,7 @@ var hc_plays_by_stream_resolution_options = { credits: { enabled: false }, - colors: ['#F9AA03', '#FFFFFF'], + colors: ['#F9AA03', '#FFFFFF', '#FF4747'], xAxis: { categories: [{}], labels: { @@ -46,8 +46,26 @@ var hc_plays_by_stream_resolution_options = { style: { color: '#aaa' } + }, + stackLabels: { + enabled: false, + style: { + color: '#fff' + } } }, + plotOptions: { + column: { + stacking: 'normal', + borderWidth: '0', + dataLabels: { + enabled: false, + style: { + color: '#000' + } + } + } + }, tooltip: { shared: true }, diff --git a/data/interfaces/default/js/graphs/plays_by_user.js b/data/interfaces/default/js/graphs/plays_by_user.js index c065321d..8700b445 100644 --- a/data/interfaces/default/js/graphs/plays_by_user.js +++ b/data/interfaces/default/js/graphs/plays_by_user.js @@ -29,7 +29,7 @@ var hc_plays_by_user_options = { credits: { enabled: false }, - colors: ['#F9AA03', '#FFFFFF'], + colors: ['#F9AA03', '#FFFFFF', '#FF4747'], xAxis: { categories: [{}], labels: { @@ -46,8 +46,26 @@ var hc_plays_by_user_options = { style: { color: '#aaa' } + }, + stackLabels: { + enabled: false, + style: { + color: '#fff' + } } }, + plotOptions: { + column: { + stacking: 'normal', + borderWidth: '0', + dataLabels: { + enabled: false, + style: { + color: '#000' + } + } + } + }, tooltip: { shared: true }, diff --git a/data/interfaces/default/js/tables/history_table.js b/data/interfaces/default/js/tables/history_table.js index 3e4b9d43..2633e09b 100644 --- a/data/interfaces/default/js/tables/history_table.js +++ b/data/interfaces/default/js/tables/history_table.js @@ -125,7 +125,7 @@ history_table_options = { } else if (rowData['media_type'] === 'episode') { media_type = ''; thumb_popover = '' + cellData + ' \ - (S' + ('00' + rowData['parent_media_index']).slice(-2) + 'E' + ('00' + rowData['media_index']).slice(-2) + ')' + (S' + rowData['parent_media_index'] + '· E' + rowData['media_index'] + ')' $(td).html(''); } else if (rowData['media_type'] === 'track') { media_type = ''; diff --git a/data/interfaces/default/js/tables/history_table_modal.js b/data/interfaces/default/js/tables/history_table_modal.js index 8a0afa22..125c250a 100644 --- a/data/interfaces/default/js/tables/history_table_modal.js +++ b/data/interfaces/default/js/tables/history_table_modal.js @@ -103,7 +103,7 @@ history_table_modal_options = { } else if (rowData['media_type'] === 'episode') { media_type = ''; thumb_popover = '' + cellData + ' \ - (S' + ('00' + rowData['parent_media_index']).slice(-2) + 'E' + ('00' + rowData['media_index']).slice(-2) + ')' + (S' + rowData['parent_media_index'] + '· E' + rowData['media_index'] + ')' $(td).html(''); } else if (rowData['media_type'] === 'track') { media_type = ''; diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index a498399d..f6ba79ee 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -282,12 +282,13 @@ available_notification_agents = notifiers.available_notification_agents()
    - +
    +

    Token for Plex.tv authentication.

    diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py index 549612e4..df6d3686 100644 --- a/plexpy/datafactory.py +++ b/plexpy/datafactory.py @@ -153,10 +153,10 @@ class DataFactory(object): query = 'SELECT session_history_metadata.id, ' \ 'session_history_metadata.grandparent_title, ' \ 'COUNT(session_history_metadata.grandparent_title) as total_plays, ' \ - 'cast(round(SUM(round((julianday(datetime(session_history.stopped, "unixepoch", "localtime")) - ' \ - 'julianday(datetime(session_history.started, "unixepoch", "localtime"))) * 86400) - ' \ - '(CASE WHEN session_history.paused_counter IS NULL THEN 0 ' \ - 'ELSE session_history.paused_counter END))/60) as integer) as total_duration,' \ + 'SUM(case when session_history.stopped > 0 ' \ + 'then (session_history.stopped - session_history.started) ' \ + ' - (case when session_history.paused_counter is NULL then 0 else session_history.paused_counter end) ' \ + 'else 0 end) as total_duration, ' \ 'session_history_metadata.grandparent_rating_key, ' \ 'MAX(session_history.started) as last_watch,' \ 'session_history_metadata.grandparent_thumb ' \ @@ -193,52 +193,6 @@ class DataFactory(object): 'stat_type': sort_type, 'rows': top_tv}) - elif 'top_movies' in stat: - top_movies = [] - try: - query = 'SELECT session_history_metadata.id, ' \ - 'session_history_metadata.full_title, ' \ - 'COUNT(session_history_metadata.full_title) as total_plays, ' \ - 'cast(round(SUM(round((julianday(datetime(session_history.stopped, "unixepoch", "localtime")) - ' \ - 'julianday(datetime(session_history.started, "unixepoch", "localtime"))) * 86400) - ' \ - '(CASE WHEN session_history.paused_counter IS NULL THEN 0 ' \ - 'ELSE session_history.paused_counter END))/60) as integer) as total_duration,' \ - 'session_history_metadata.rating_key, ' \ - 'MAX(session_history.started) as last_watch,' \ - 'session_history_metadata.thumb ' \ - 'FROM session_history_metadata ' \ - 'JOIN session_history on session_history_metadata.id = session_history.id ' \ - 'WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ - '>= datetime("now", "-%s days", "localtime") ' \ - 'AND session_history_metadata.media_type = "movie" ' \ - 'GROUP BY session_history_metadata.full_title ' \ - 'ORDER BY %s DESC LIMIT %s' % (time_range, sort_type, stat_count) - result = monitor_db.select(query) - except: - logger.warn("Unable to execute database query.") - return None - - for item in result: - row = {'title': item[1], - 'total_plays': item[2], - 'total_duration': item[3], - 'users_watched': '', - 'rating_key': item[4], - 'last_play': item[5], - 'grandparent_thumb': '', - 'thumb': item[6], - 'user': '', - 'friendly_name': '', - 'platform_type': '', - 'platform': '', - 'row_id': item[0] - } - top_movies.append(row) - - home_stats.append({'stat_id': stat, - 'stat_type': sort_type, - 'rows': top_movies}) - elif 'popular_tv' in stat: popular_tv = [] try: @@ -281,6 +235,52 @@ class DataFactory(object): home_stats.append({'stat_id': stat, 'rows': popular_tv}) + elif 'top_movies' in stat: + top_movies = [] + try: + query = 'SELECT session_history_metadata.id, ' \ + 'session_history_metadata.full_title, ' \ + 'COUNT(session_history_metadata.full_title) as total_plays, ' \ + 'SUM(case when session_history.stopped > 0 ' \ + 'then (session_history.stopped - session_history.started) ' \ + ' - (case when session_history.paused_counter is NULL then 0 else session_history.paused_counter end) ' \ + 'else 0 end) as total_duration, ' \ + 'session_history_metadata.rating_key, ' \ + 'MAX(session_history.started) as last_watch,' \ + 'session_history_metadata.thumb ' \ + 'FROM session_history_metadata ' \ + 'JOIN session_history on session_history_metadata.id = session_history.id ' \ + 'WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ + '>= datetime("now", "-%s days", "localtime") ' \ + 'AND session_history_metadata.media_type = "movie" ' \ + 'GROUP BY session_history_metadata.full_title ' \ + 'ORDER BY %s DESC LIMIT %s' % (time_range, sort_type, stat_count) + result = monitor_db.select(query) + except: + logger.warn("Unable to execute database query.") + return None + + for item in result: + row = {'title': item[1], + 'total_plays': item[2], + 'total_duration': item[3], + 'users_watched': '', + 'rating_key': item[4], + 'last_play': item[5], + 'grandparent_thumb': '', + 'thumb': item[6], + 'user': '', + 'friendly_name': '', + 'platform_type': '', + 'platform': '', + 'row_id': item[0] + } + top_movies.append(row) + + home_stats.append({'stat_id': stat, + 'stat_type': sort_type, + 'rows': top_movies}) + elif 'popular_movies' in stat: popular_movies = [] try: @@ -330,10 +330,10 @@ class DataFactory(object): '(case when users.friendly_name is null then session_history.user else ' \ 'users.friendly_name end) as friendly_name,' \ 'COUNT(session_history.id) as total_plays, ' \ - 'cast(round(SUM(round((julianday(datetime(session_history.stopped, "unixepoch", "localtime")) - ' \ - 'julianday(datetime(session_history.started, "unixepoch", "localtime"))) * 86400) - ' \ - '(CASE WHEN session_history.paused_counter IS NULL THEN 0 ' \ - 'ELSE session_history.paused_counter END))/60) as integer) as total_duration,' \ + 'SUM(case when session_history.stopped > 0 ' \ + 'then (session_history.stopped - session_history.started) ' \ + ' - (case when session_history.paused_counter is NULL then 0 else session_history.paused_counter end) ' \ + 'else 0 end) as total_duration, ' \ 'MAX(session_history.started) as last_watch, ' \ 'users.custom_avatar_url as thumb, ' \ 'users.user_id ' \ @@ -382,10 +382,10 @@ class DataFactory(object): try: query = 'SELECT session_history.platform, ' \ 'COUNT(session_history.id) as total_plays, ' \ - 'cast(round(SUM(round((julianday(datetime(session_history.stopped, "unixepoch", "localtime")) - ' \ - 'julianday(datetime(session_history.started, "unixepoch", "localtime"))) * 86400) - ' \ - '(CASE WHEN session_history.paused_counter IS NULL THEN 0 ' \ - 'ELSE session_history.paused_counter END))/60) as integer) as total_duration,' \ + 'SUM(case when session_history.stopped > 0 ' \ + 'then (session_history.stopped - session_history.started) ' \ + ' - (case when session_history.paused_counter is NULL then 0 else session_history.paused_counter end) ' \ + 'else 0 end) as total_duration, ' \ 'MAX(session_history.started) as last_watch ' \ 'FROM session_history ' \ 'WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ diff --git a/plexpy/graphs.py b/plexpy/graphs.py index 8b139d82..7de362a9 100644 --- a/plexpy/graphs.py +++ b/plexpy/graphs.py @@ -1,4 +1,4 @@ -# This file is part of PlexPy. +# This file is part of PlexPy. # # PlexPy is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -33,7 +33,8 @@ class Graphs(object): if y_axis == 'plays': query = 'SELECT date(started, "unixepoch", "localtime") as date_played, ' \ 'SUM(case when media_type = "episode" then 1 else 0 end) as tv_count, ' \ - 'SUM(case when media_type = "movie" then 1 else 0 end) as movie_count ' \ + 'SUM(case when media_type = "movie" then 1 else 0 end) as movie_count, ' \ + 'SUM(case when media_type = "track" then 1 else 0 end) as music_count ' \ 'FROM session_history ' \ 'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \ 'GROUP BY date_played ' \ @@ -42,8 +43,12 @@ class Graphs(object): result = monitor_db.select(query) else: query = 'SELECT date(started, "unixepoch", "localtime") as date_played, ' \ - 'SUM(case when media_type = "episode" and stopped > 0 then (stopped - started) else 0 end) as tv_duration, ' \ - 'SUM(case when media_type = "movie" and stopped > 0 then (stopped - started) else 0 end) as movie_duration ' \ + 'SUM(case when media_type = "episode" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tv_duration, ' \ + 'SUM(case when media_type = "movie" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as movie_duration, ' \ + 'SUM(case when media_type = "track" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as music_duration ' \ 'FROM session_history ' \ 'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \ 'GROUP BY date_played ' \ @@ -62,31 +67,38 @@ class Graphs(object): categories = [] series_1 = [] series_2 = [] + series_3 = [] for date_item in sorted(date_list): date_string = date_item.strftime('%Y-%m-%d') categories.append(date_string) series_1_value = 0 series_2_value = 0 + series_3_value = 0 for item in result: if date_string == item[0]: series_1_value = item[1] series_2_value = item[2] + series_3_value = item[3] break else: series_1_value = 0 series_2_value = 0 + series_3_value = 0 series_1.append(series_1_value) series_2.append(series_2_value) + series_3.append(series_3_value) series_1_output = {'name': 'TV', 'data': series_1} series_2_output = {'name': 'Movies', 'data': series_2} + series_3_output = {'name': 'Music', + 'data': series_3} output = {'categories': categories, - 'series': [series_1_output, series_2_output]} + 'series': [series_1_output, series_2_output, series_3_output]} return output def get_total_plays_per_dayofweek(self, time_range='30', y_axis='plays'): @@ -105,16 +117,16 @@ class Graphs(object): 'when 4 then "Thursday" ' \ 'when 5 then "Friday" ' \ 'else "Saturday" end as dayofweek, ' \ - 'COUNT(id) as total_plays ' \ - 'from session_history ' \ + 'SUM(case when media_type = "episode" then 1 else 0 end) as tv_count, ' \ + 'SUM(case when media_type = "movie" then 1 else 0 end) as movie_count, ' \ + 'SUM(case when media_type = "track" then 1 else 0 end) as music_count ' \ + 'FROM session_history ' \ 'WHERE datetime(stopped, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime") AND ' \ - '(media_type = "episode" OR media_type = "movie") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime") ' \ 'GROUP BY dayofweek ' \ 'ORDER BY daynumber' result = monitor_db.select(query) - y_axis_label = 'Total plays' else: query = 'SELECT strftime("%w", datetime(started, "unixepoch", "localtime")) as daynumber, ' \ 'case cast (strftime("%w", datetime(started, "unixepoch", "localtime")) as integer) ' \ @@ -125,40 +137,57 @@ class Graphs(object): 'when 4 then "Thursday" ' \ 'when 5 then "Friday" ' \ 'else "Saturday" end as dayofweek, ' \ - 'SUM(case when media_type != "track" and stopped > 0 then (stopped - started) else 0 end) as duration ' \ - 'from session_history ' \ + 'SUM(case when media_type = "episode" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tv_duration, ' \ + 'SUM(case when media_type = "movie" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as movie_duration, ' \ + 'SUM(case when media_type = "track" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as music_duration ' \ + 'FROM session_history ' \ 'WHERE datetime(stopped, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime") AND ' \ - '(media_type = "episode" OR media_type = "movie") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime") ' \ 'GROUP BY dayofweek ' \ 'ORDER BY daynumber' result = monitor_db.select(query) - y_axis_label = 'Total duration' days_list = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] categories = [] series_1 = [] + series_2 = [] + series_3 = [] for day_item in days_list: categories.append(day_item) series_1_value = 0 + series_2_value = 0 + series_3_value = 0 for item in result: if day_item == item[1]: series_1_value = item[2] + series_2_value = item[3] + series_3_value = item[4] break else: series_1_value = 0 + series_2_value = 0 + series_3_value = 0 series_1.append(series_1_value) + series_2.append(series_2_value) + series_3.append(series_3_value) - series_1_output = {'name': y_axis_label, + series_1_output = {'name': 'TV', 'data': series_1} + series_2_output = {'name': 'Movies', + 'data': series_2} + series_3_output = {'name': 'Music', + 'data': series_3} output = {'categories': categories, - 'series': [series_1_output]} + 'series': [series_1_output, series_2_output, series_3_output]} return output def get_total_plays_per_hourofday(self, time_range='30', y_axis='plays'): @@ -169,28 +198,31 @@ class Graphs(object): if y_axis == 'plays': query = 'select strftime("%H", datetime(started, "unixepoch", "localtime")) as hourofday, ' \ - 'COUNT(id) ' \ + 'SUM(case when media_type = "episode" then 1 else 0 end) as tv_count, ' \ + 'SUM(case when media_type = "movie" then 1 else 0 end) as movie_count, ' \ + 'SUM(case when media_type = "track" then 1 else 0 end) as music_count ' \ 'FROM session_history ' \ 'WHERE datetime(stopped, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime") AND ' \ - '(media_type = "episode" OR media_type = "movie") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime") ' \ 'GROUP BY hourofday ' \ 'ORDER BY hourofday' result = monitor_db.select(query) - y_axis_label = 'Total plays' else: query = 'select strftime("%H", datetime(started, "unixepoch", "localtime")) as hourofday, ' \ - 'SUM(case when media_type != "track" and stopped > 0 then (stopped - started) else 0 end) as duration ' \ + 'SUM(case when media_type = "episode" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tv_duration, ' \ + 'SUM(case when media_type = "movie" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as movie_duration, ' \ + 'SUM(case when media_type = "track" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as music_duration ' \ 'FROM session_history ' \ 'WHERE datetime(stopped, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime") AND ' \ - '(media_type = "episode" OR media_type = "movie") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime") ' \ 'GROUP BY hourofday ' \ 'ORDER BY hourofday' result = monitor_db.select(query) - y_axis_label = 'Total duration' hours_list = ['00','01','02','03','04','05', '06','07','08','09','10','11', @@ -199,24 +231,38 @@ class Graphs(object): categories = [] series_1 = [] + series_2 = [] + series_3 = [] for hour_item in hours_list: categories.append(hour_item) series_1_value = 0 + series_2_value = 0 + series_3_value = 0 for item in result: if hour_item == item[0]: series_1_value = item[1] + series_2_value = item[2] + series_3_value = item[3] break else: series_1_value = 0 + series_2_value = 0 + series_3_value = 0 series_1.append(series_1_value) + series_2.append(series_2_value) + series_3.append(series_3_value) - series_1_output = {'name': y_axis_label, + series_1_output = {'name': 'TV', 'data': series_1} + series_2_output = {'name': 'Movies', + 'data': series_2} + series_3_output = {'name': 'Music', + 'data': series_3} output = {'categories': categories, - 'series': [series_1_output]} + 'series': [series_1_output, series_2_output, series_3_output]} return output def get_total_plays_per_month(self, y_axis='plays'): @@ -226,7 +272,8 @@ class Graphs(object): if y_axis == 'plays': query = 'SELECT strftime("%Y-%m", datetime(started, "unixepoch", "localtime")) as datestring, ' \ 'SUM(case when media_type = "episode" then 1 else 0 end) as tv_count, ' \ - 'SUM(case when media_type = "movie" then 1 else 0 end) as movie_count ' \ + 'SUM(case when media_type = "movie" then 1 else 0 end) as movie_count, ' \ + 'SUM(case when media_type = "track" then 1 else 0 end) as music_count ' \ 'FROM session_history ' \ 'WHERE datetime(started, "unixepoch", "localtime") >= datetime("now", "-12 months", "localtime") ' \ 'GROUP BY strftime("%Y-%m", datetime(started, "unixepoch", "localtime")) ' \ @@ -235,8 +282,12 @@ class Graphs(object): result = monitor_db.select(query) else: query = 'SELECT strftime("%Y-%m", datetime(started, "unixepoch", "localtime")) as datestring, ' \ - 'SUM(case when media_type = "episode" and stopped > 0 then (stopped - started) else 0 end) as tv_duration, ' \ - 'SUM(case when media_type = "movie" and stopped > 0 then (stopped - started) else 0 end) as movie_duration ' \ + 'SUM(case when media_type = "episode" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tv_duration, ' \ + 'SUM(case when media_type = "movie" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as movie_duration, ' \ + 'SUM(case when media_type = "track" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as music_duration ' \ 'FROM session_history ' \ 'WHERE datetime(started, "unixepoch", "localtime") >= datetime("now", "-12 months", "localtime") ' \ 'GROUP BY strftime("%Y-%m", datetime(started, "unixepoch", "localtime")) ' \ @@ -254,6 +305,7 @@ class Graphs(object): categories = [] series_1 = [] series_2 = [] + series_3 = [] for month_item in sorted(month_range): dt = datetime.datetime(*month_item[:6]) @@ -262,25 +314,31 @@ class Graphs(object): categories.append(dt.strftime('%b %Y')) series_1_value = 0 series_2_value = 0 + series_3_value = 0 for item in result: if date_string == item[0]: series_1_value = item[1] series_2_value = item[2] + series_3_value = item[3] break else: series_1_value = 0 series_2_value = 0 + series_3_value = 0 series_1.append(series_1_value) series_2.append(series_2_value) + series_3.append(series_3_value) series_1_output = {'name': 'TV', 'data': series_1} series_2_output = {'name': 'Movies', 'data': series_2} + series_3_output = {'name': 'Music', + 'data': series_3} output = {'categories': categories, - 'series': [series_1_output, series_2_output]} + 'series': [series_1_output, series_2_output, series_3_output]} return output def get_total_plays_by_top_10_platforms(self, time_range='30', y_axis='plays'): @@ -291,43 +349,64 @@ class Graphs(object): if y_axis == 'plays': query = 'SELECT platform, ' \ - 'count(id) as platform_count ' \ + 'SUM(case when media_type = "episode" then 1 else 0 end) as tv_count, ' \ + 'SUM(case when media_type = "movie" then 1 else 0 end) as movie_count, ' \ + 'SUM(case when media_type = "track" then 1 else 0 end) as music_count, ' \ + 'COUNT(id) as total_count ' \ 'FROM session_history ' \ 'WHERE (datetime(stopped, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime")) AND ' \ - '(media_type = "episode" OR media_type = "movie") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime")) ' \ 'GROUP BY platform ' \ - 'ORDER BY platform_count DESC ' \ + 'ORDER BY total_count DESC ' \ 'LIMIT 10' result = monitor_db.select(query) - y_axis_label = 'Total plays' else: query = 'SELECT platform, ' \ - 'SUM(case when stopped > 0 then (stopped - started) else 0 end) as duration ' \ + 'SUM(case when media_type = "episode" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tv_duration, ' \ + 'SUM(case when media_type = "movie" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as movie_duration, ' \ + 'SUM(case when media_type = "track" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as music_duration, ' \ + 'SUM(case when stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as total_duration ' \ 'FROM session_history ' \ 'WHERE (datetime(stopped, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime")) AND ' \ - '(media_type = "episode" OR media_type = "movie") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime")) ' \ 'GROUP BY platform ' \ - 'ORDER BY duration DESC ' \ + 'ORDER BY total_duration DESC ' \ 'LIMIT 10' result = monitor_db.select(query) - y_axis_label = 'Total duration' categories = [] series_1 = [] + series_2 = [] + series_3 = [] for item in result: categories.append(item[0]) series_1.append(item[1]) + series_2.append(item[2]) + series_3.append(item[3]) - series_1_output = {'name': y_axis_label, + # Rename Mystery platform names + platform_names = [('Mystery 3', 'Playstation 3'), + ('Mystery 4', 'Playstation 4'), + ('Mystery 5', 'Xbox 360')] + for old_name, new_name in platform_names: + categories = [item.replace(old_name, new_name) for item in categories] + + series_1_output = {'name': 'TV', 'data': series_1} + series_2_output = {'name': 'Movies', + 'data': series_2} + series_3_output = {'name': 'Music', + 'data': series_3} output = {'categories': categories, - 'series': [series_1_output]} + 'series': [series_1_output, series_2_output, series_3_output]} return output def get_total_plays_by_top_10_users(self, time_range='30', y_axis='plays'): @@ -340,47 +419,61 @@ class Graphs(object): query = 'SELECT ' \ '(case when users.friendly_name is null then session_history.user else ' \ 'users.friendly_name end) as friendly_name,' \ - 'count(session_history.id) as user_count ' \ + 'SUM(case when media_type = "episode" then 1 else 0 end) as tv_count, ' \ + 'SUM(case when media_type = "movie" then 1 else 0 end) as movie_count, ' \ + 'SUM(case when media_type = "track" then 1 else 0 end) as music_count, ' \ + 'COUNT(session_history.id) as total_count ' \ 'FROM session_history ' \ 'JOIN users on session_history.user_id = users.user_id ' \ 'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime")) AND ' \ - '(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime")) ' \ 'GROUP BY session_history.user_id ' \ - 'ORDER BY user_count DESC ' \ + 'ORDER BY total_count DESC ' \ 'LIMIT 10' result = monitor_db.select(query) - y_axis_label = 'Total plays' else: query = 'SELECT ' \ '(case when users.friendly_name is null then session_history.user else ' \ 'users.friendly_name end) as friendly_name,' \ - 'SUM(case when stopped > 0 then (stopped - started) else 0 end) as duration ' \ + 'SUM(case when media_type = "episode" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tv_duration, ' \ + 'SUM(case when media_type = "movie" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as movie_duration, ' \ + 'SUM(case when media_type = "track" and stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as music_duration, ' \ + 'SUM(case when stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as total_duration ' \ 'FROM session_history ' \ 'JOIN users on session_history.user_id = users.user_id ' \ 'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime")) AND ' \ - '(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime")) ' \ 'GROUP BY session_history.user_id ' \ - 'ORDER BY duration DESC ' \ + 'ORDER BY total_duration DESC ' \ 'LIMIT 10' result = monitor_db.select(query) - y_axis_label = 'Total duration' categories = [] series_1 = [] + series_2 = [] + series_3 = [] for item in result: categories.append(item[0]) series_1.append(item[1]) + series_2.append(item[2]) + series_3.append(item[3]) - series_1_output = {'name': y_axis_label, + series_1_output = {'name': 'TV', 'data': series_1} + series_2_output = {'name': 'Movies', + 'data': series_2} + series_3_output = {'name': 'Music', + 'data': series_3} output = {'categories': categories, - 'series': [series_1_output]} + 'series': [series_1_output, series_2_output, series_3_output]} return output def get_total_plays_per_stream_type(self, time_range='30', y_axis='plays'): @@ -392,31 +485,43 @@ class Graphs(object): try: if y_axis == 'plays': query = 'SELECT date(session_history.started, "unixepoch", "localtime") as date_played, ' \ - 'SUM(case when session_history_media_info.video_decision = "direct play" then 1 else 0 end) as dp_count, ' \ - 'SUM(case when session_history_media_info.video_decision = "copy" then 1 else 0 end) as ds_count, ' \ - 'SUM(case when session_history_media_info.video_decision = "transcode" then 1 else 0 end) as tc_count ' \ + 'SUM(case when session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play") ' \ + 'then 1 else 0 end) as dp_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy") ' \ + 'then 1 else 0 end) as ds_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode") ' \ + 'then 1 else 0 end) as tc_count ' \ 'FROM session_history ' \ 'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \ 'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \ 'datetime("now", "-%s days", "localtime")) AND ' \ - '(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \ + '(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \ 'GROUP BY date_played ' \ 'ORDER BY started ASC' % time_range result = monitor_db.select(query) else: query = 'SELECT date(session_history.started, "unixepoch", "localtime") as date_played, ' \ - 'SUM(case when session_history_media_info.video_decision = "direct play" AND ' \ - 'session_history.stopped > 0 then (stopped - started) else 0 end) as dp_duration, ' \ - 'SUM(case when session_history_media_info.video_decision = "copy" AND ' \ - 'session_history.stopped > 0 then (stopped - started) else 0 end) as ds_duration, ' \ - 'SUM(case when session_history_media_info.video_decision = "transcode" ' \ - 'AND session_history.stopped > 0 then (stopped - started) else 0 end) as tc_duration ' \ + 'SUM(case when (session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as dp_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as ds_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tc_duration ' \ 'FROM session_history ' \ 'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \ 'WHERE datetime(session_history.stopped, "unixepoch", "localtime") >= ' \ 'datetime("now", "-%s days", "localtime") AND ' \ - '(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \ + '(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \ 'GROUP BY date_played ' \ 'ORDER BY started ASC' % time_range @@ -465,7 +570,6 @@ class Graphs(object): output = {'categories': categories, 'series': [series_1_output, series_2_output, series_3_output]} - return output def get_total_plays_by_source_resolution(self, time_range='30', y_axis='plays'): @@ -475,49 +579,74 @@ class Graphs(object): time_range = '30' if y_axis == 'plays': - query = 'SELECT ' \ - 'count(session_history.id) as play_count, ' \ - 'session_history_media_info.video_resolution AS resolution ' \ + query = 'SELECT session_history_media_info.video_resolution AS resolution, ' \ + 'SUM(case when session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play") ' \ + 'then 1 else 0 end) as dp_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy") ' \ + 'then 1 else 0 end) as ds_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode") ' \ + 'then 1 else 0 end) as tc_count, ' \ + 'COUNT(session_history.id) as total_count ' \ 'FROM session_history ' \ 'JOIN session_history_media_info on session_history.id = session_history_media_info.id ' \ 'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \ 'datetime("now", "-' + time_range + ' days", "localtime")) AND ' \ '(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \ 'GROUP BY resolution ' \ - 'ORDER BY play_count DESC ' \ + 'ORDER BY total_count DESC ' \ 'LIMIT 10' result = monitor_db.select(query) - y_axis_label = 'Total plays' else: - query = 'SELECT ' \ - 'SUM(case when stopped > 0 then (stopped - started) else 0 end) as duration, ' \ - 'session_history_media_info.video_resolution AS resolution ' \ + query = 'SELECT session_history_media_info.video_resolution AS resolution,' \ + 'SUM(case when (session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as dp_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as ds_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tc_duration, ' \ + 'SUM(case when stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as total_duration ' \ 'FROM session_history ' \ 'JOIN session_history_media_info on session_history.id = session_history_media_info.id ' \ 'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \ 'datetime("now", "-' + time_range + ' days", "localtime")) AND ' \ '(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \ 'GROUP BY resolution ' \ - 'ORDER BY duration DESC ' \ + 'ORDER BY total_duration DESC ' \ 'LIMIT 10' result = monitor_db.select(query) - y_axis_label = 'Total duration' categories = [] series_1 = [] + series_2 = [] + series_3 = [] for item in result: - categories.append(item[1]) - series_1.append(item[0]) + categories.append(item[0]) + series_1.append(item[1]) + series_2.append(item[2]) + series_3.append(item[3]) - series_1_output = {'name': y_axis_label, + series_1_output = {'name': 'Direct Play', 'data': series_1} + series_2_output = {'name': 'Direct Stream', + 'data': series_2} + series_3_output = {'name': 'Transcode', + 'data': series_3} output = {'categories': categories, - 'series': [series_1_output]} - + 'series': [series_1_output, series_2_output, series_3_output]} return output def get_total_plays_by_stream_resolution(self, time_range='30', y_axis='plays'): @@ -528,7 +657,6 @@ class Graphs(object): if y_axis == 'plays': query = 'SELECT ' \ - 'count(session_history.id) as play_count, ' \ '(case when session_history_media_info.video_decision = "transcode" then ' \ '(case ' \ 'when session_history_media_info.transcode_height <= 360 then "sd" ' \ @@ -538,21 +666,29 @@ class Graphs(object): 'when session_history_media_info.transcode_height <= 1080 then "1080" ' \ 'when session_history_media_info.transcode_height <= 1440 then "QHD" ' \ 'when session_history_media_info.transcode_height <= 2160 then "4K" ' \ - 'else "unknown" end) else session_history_media_info.video_resolution end) as resolution ' \ + 'else "unknown" end) else session_history_media_info.video_resolution end) as resolution, ' \ + 'SUM(case when session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play") ' \ + 'then 1 else 0 end) as dp_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy") ' \ + 'then 1 else 0 end) as ds_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode") ' \ + 'then 1 else 0 end) as tc_count, ' \ + 'COUNT(session_history.id) as total_count ' \ 'FROM session_history ' \ 'JOIN session_history_media_info on session_history.id = session_history_media_info.id ' \ 'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \ 'datetime("now", "-' + time_range + ' days", "localtime")) AND ' \ '(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \ 'GROUP BY resolution ' \ - 'ORDER BY play_count DESC ' \ + 'ORDER BY total_count DESC ' \ 'LIMIT 10' result = monitor_db.select(query) - y_axis_label = 'Total plays' else: query = 'SELECT ' \ - 'SUM(case when stopped > 0 then (stopped - started) else 0 end) as duration, ' \ '(case when session_history_media_info.video_decision = "transcode" then ' \ '(case ' \ 'when session_history_media_info.transcode_height <= 360 then "sd" ' \ @@ -562,31 +698,137 @@ class Graphs(object): 'when session_history_media_info.transcode_height <= 1080 then "1080" ' \ 'when session_history_media_info.transcode_height <= 1440 then "QHD" ' \ 'when session_history_media_info.transcode_height <= 2160 then "4K" ' \ - 'else "unknown" end) else session_history_media_info.video_resolution end) as resolution ' \ + 'else "unknown" end) else session_history_media_info.video_resolution end) as resolution, ' \ + 'SUM(case when (session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as dp_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as ds_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tc_duration, ' \ + 'SUM(case when stopped > 0 then (stopped - started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as total_duration ' \ 'FROM session_history ' \ 'JOIN session_history_media_info on session_history.id = session_history_media_info.id ' \ 'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \ 'datetime("now", "-' + time_range + ' days", "localtime")) AND ' \ '(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \ 'GROUP BY resolution ' \ - 'ORDER BY duration DESC ' \ + 'ORDER BY total_duration DESC ' \ 'LIMIT 10' result = monitor_db.select(query) - y_axis_label = 'Total duration' categories = [] series_1 = [] + series_2 = [] + series_3 = [] for item in result: - categories.append(item[1]) - series_1.append(item[0]) + categories.append(item[0]) + series_1.append(item[1]) + series_2.append(item[2]) + series_3.append(item[3]) - series_1_output = {'name': y_axis_label, + series_1_output = {'name': 'Direct Play', 'data': series_1} + series_2_output = {'name': 'Direct Stream', + 'data': series_2} + series_3_output = {'name': 'Transcode', + 'data': series_3} output = {'categories': categories, - 'series': [series_1_output]} + 'series': [series_1_output, series_2_output, series_3_output]} + return output + + def get_stream_type_by_top_10_platforms(self, time_range='30', y_axis='plays'): + monitor_db = database.MonitorDatabase() + + if not time_range.isdigit(): + time_range = '30' + + if y_axis == 'plays': + query = 'SELECT ' \ + 'session_history.platform as platform, ' \ + 'SUM(case when session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play") ' \ + 'then 1 else 0 end) as dp_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy") ' \ + 'then 1 else 0 end) as ds_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode") ' \ + 'then 1 else 0 end) as tc_count, ' \ + 'COUNT(session_history.id) as total_count ' \ + 'FROM session_history ' \ + 'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \ + 'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \ + 'datetime("now", "-' + time_range + ' days", "localtime") AND ' \ + '(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \ + 'GROUP BY platform ' \ + 'ORDER BY total_count DESC LIMIT 10' + + result = monitor_db.select(query) + else: + query = 'SELECT ' \ + 'session_history.platform as platform, ' \ + 'SUM(case when (session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as dp_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as ds_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tc_duration, ' \ + 'SUM(case when session_history.stopped > 0 ' \ + 'then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as total_duration ' \ + 'FROM session_history ' \ + 'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \ + 'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \ + 'datetime("now", "-' + time_range + ' days", "localtime") AND ' \ + '(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \ + 'GROUP BY platform ' \ + 'ORDER BY total_duration DESC LIMIT 10' + + result = monitor_db.select(query) + + categories = [] + series_1 = [] + series_2 = [] + series_3 = [] + + for item in result: + categories.append(item[0]) + series_1.append(item[1]) + series_2.append(item[2]) + series_3.append(item[3]) + + # Rename Mystery platform names + platform_names = [('Mystery 3', 'Playstation 3'), + ('Mystery 4', 'Playstation 4'), + ('Mystery 5', 'Xbox 360')] + for old_name, new_name in platform_names: + categories = [item.replace(old_name, new_name) for item in categories] + + series_1_output = {'name': 'Direct Play', + 'data': series_1} + series_2_output = {'name': 'Direct Stream', + 'data': series_2} + series_3_output = {'name': 'Transcode', + 'data': series_3} + + output = {'categories': categories, + 'series': [series_1_output, series_2_output, series_3_output]} return output @@ -599,15 +841,22 @@ class Graphs(object): if y_axis == 'plays': query = 'SELECT ' \ 'CASE WHEN users.friendly_name is null then users.username else users.friendly_name end as username, ' \ - 'SUM(case when session_history_media_info.video_decision = "direct play" then 1 else 0 end) as dp_count, ' \ - 'SUM(case when session_history_media_info.video_decision = "copy" then 1 else 0 end) as ds_count, ' \ - 'SUM(case when session_history_media_info.video_decision = "transcode" then 1 else 0 end) as tr_count, ' \ - 'SUM(case when session_history.media_type != "track" then 1 else 0 end) as total_count ' \ + 'SUM(case when session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play") ' \ + 'then 1 else 0 end) as dp_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy") ' \ + 'then 1 else 0 end) as ds_count, ' \ + 'SUM(case when session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode") ' \ + 'then 1 else 0 end) as tc_count, ' \ + 'COUNT(session_history.id) as total_count ' \ 'FROM session_history ' \ 'JOIN users ON session_history.user_id = users.user_id ' \ 'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \ 'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime") AND ' \ + '(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \ 'GROUP BY username ' \ 'ORDER BY total_count DESC LIMIT 10' @@ -615,85 +864,29 @@ class Graphs(object): else: query = 'SELECT ' \ 'CASE WHEN users.friendly_name is null then users.username else users.friendly_name end as username, ' \ - 'SUM(case when session_history.stopped > 0 AND session_history_media_info.video_decision = "direct play" ' \ - 'then (session_history.stopped - session_history.started) else 0 end) as dp_count, ' \ - 'SUM(case when session_history.stopped > 0 AND session_history_media_info.video_decision = "copy" ' \ - 'then (session_history.stopped - session_history.started) else 0 end) as ds_count, ' \ - 'SUM(case when session_history.stopped > 0 AND session_history_media_info.video_decision = "transcode" ' \ - 'then (session_history.stopped - session_history.started) else 0 end) as tr_count, ' \ - 'SUM(case when session_history.stopped > 0 AND session_history.media_type != "track" ' \ - 'then (session_history.stopped - session_history.started) else 0 end) as total_count ' \ + 'SUM(case when (session_history_media_info.video_decision = "direct play" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "direct play")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as dp_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "copy" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "copy")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as ds_duration, ' \ + 'SUM(case when (session_history_media_info.video_decision = "transcode" ' \ + 'or (session_history_media_info.video_decision = "" and session_history_media_info.audio_decision = "transcode")) ' \ + 'and session_history.stopped > 0 then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as tc_duration, ' \ + 'SUM(case when session_history.stopped > 0 ' \ + 'then (session_history.stopped - session_history.started) ' \ + ' - (case when paused_counter is NULL then 0 else paused_counter end) else 0 end) as total_duration ' \ 'FROM session_history ' \ 'JOIN users ON session_history.user_id = users.user_id ' \ 'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \ 'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime") ' \ + 'datetime("now", "-' + time_range + ' days", "localtime") AND ' \ + '(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \ 'GROUP BY username ' \ - 'ORDER BY total_count DESC LIMIT 10' - - result = monitor_db.select(query) - - categories = [] - series_1 = [] - series_2 = [] - series_3 = [] - - for item in result: - categories.append(item[0]) - series_1.append(item[1]) - series_2.append(item[2]) - series_3.append(item[3]) - - series_1_output = {'name': 'Direct Play', - 'data': series_1} - series_2_output = {'name': 'Direct Stream', - 'data': series_2} - series_3_output = {'name': 'Transcode', - 'data': series_3} - - output = {'categories': categories, - 'series': [series_1_output, series_2_output, series_3_output]} - - return output - - def get_stream_type_by_top_10_platforms(self, time_range='30', y_axis='plays'): - monitor_db = database.MonitorDatabase() - - if not time_range.isdigit(): - time_range = '30' - - if y_axis == 'plays': - query = 'SELECT ' \ - 'session_history.platform as platform, ' \ - 'SUM(case when session_history_media_info.video_decision = "direct play" then 1 else 0 end) as dp_count, ' \ - 'SUM(case when session_history_media_info.video_decision = "copy" then 1 else 0 end) as ds_count, ' \ - 'SUM(case when session_history_media_info.video_decision = "transcode" then 1 else 0 end) as tr_count, ' \ - 'SUM(case when session_history.media_type != "track" then 1 else 0 end) as total_count ' \ - 'FROM session_history ' \ - 'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \ - 'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime") ' \ - 'GROUP BY platform ' \ - 'ORDER BY total_count DESC LIMIT 10' - - result = monitor_db.select(query) - else: - query = 'SELECT ' \ - 'session_history.platform as platform, ' \ - 'SUM(case when session_history.stopped > 0 AND session_history_media_info.video_decision = "direct play" ' \ - 'then (session_history.stopped - session_history.started) else 0 end) as dp_count, ' \ - 'SUM(case when session_history.stopped > 0 AND session_history_media_info.video_decision = "copy" ' \ - 'then (session_history.stopped - session_history.started) else 0 end) as ds_count, ' \ - 'SUM(case when session_history.stopped > 0 AND session_history_media_info.video_decision = "transcode" ' \ - 'then (session_history.stopped - session_history.started) else 0 end) as tr_count, ' \ - 'SUM(case when session_history.stopped > 0 AND session_history.media_type != "track" ' \ - 'then (session_history.stopped - session_history.started) else 0 end) as total_count ' \ - 'FROM session_history ' \ - 'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \ - 'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \ - 'datetime("now", "-' + time_range + ' days", "localtime") ' \ - 'GROUP BY platform ' \ - 'ORDER BY total_count DESC LIMIT 10' + 'ORDER BY total_duration DESC LIMIT 10' result = monitor_db.select(query) diff --git a/plexpy/monitor.py b/plexpy/monitor.py index c6d52936..478f2e78 100644 --- a/plexpy/monitor.py +++ b/plexpy/monitor.py @@ -151,7 +151,9 @@ def check_active_sessions(): kwargs=dict(stream_data=stream, notify_action='stop')).start() # Write the item history on playback stop - monitor_process.write_session_history(session=stream) + # Just make sure that the ratingKey is indeed an integer + if stream['rating_key'].isdigit(): + monitor_process.write_session_history(session=stream) # Process the newly received session data for session in media_container: