From 9cf6793b240d14b5516450a48492fbf3e49fc3be Mon Sep 17 00:00:00 2001 From: Jonathan Wong Date: Sat, 12 Dec 2015 14:28:59 -0800 Subject: [PATCH] Add most concurrent streams home statistic --- data/interfaces/default/home_stats.html | 29 ++++++++++++++++ .../images/home-stat_most-concurrent.png | Bin 0 -> 4864 bytes data/interfaces/default/settings.html | 1 + plexpy/config.py | 3 +- plexpy/datafactory.py | 32 ++++++++++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 data/interfaces/default/images/home-stat_most-concurrent.png diff --git a/data/interfaces/default/home_stats.html b/data/interfaces/default/home_stats.html index e3773f3f..e6efb512 100644 --- a/data/interfaces/default/home_stats.html +++ b/data/interfaces/default/home_stats.html @@ -44,6 +44,11 @@ player Returns the player name for the associated stat. == Only if 'stat_id' is 'last_watched' == last_watch Returns the time the media item was last watched. +== Only if 'stat_id' is 'most_concurrent' == +count Returns the count of the most concurrent streams. +started Returns the start time of the most concurrent streams. +stopped Returns the stop time of the most concurrent streams. + DOCUMENTATION :: END @@ -782,6 +787,30 @@ DOCUMENTATION :: END % endif + % elif top_stat['stat_id'] == 'most_concurrent' and top_stat['rows']: +
+
  • +
    +
    +

    Most Concurrent Streams

    +
    +
    +

    + + + +

    +

    ${top_stat['rows'][0]['count']}

    +

    streams

    +
    +
    +
    +
    +
    +
  • +
    % endif % endfor diff --git a/data/interfaces/default/images/home-stat_most-concurrent.png b/data/interfaces/default/images/home-stat_most-concurrent.png new file mode 100644 index 0000000000000000000000000000000000000000..085dc93eb193971cd91cfca0c794b52db91c1260 GIT binary patch literal 4864 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 Popular Music + diff --git a/plexpy/config.py b/plexpy/config.py index 491f2081..664a69ec 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -98,7 +98,8 @@ _CONFIG_DEFINITIONS = { 'HOME_STATS_LENGTH': (int, 'General', 30), 'HOME_STATS_TYPE': (int, 'General', 0), 'HOME_STATS_COUNT': (int, 'General', 5), - 'HOME_STATS_CARDS': (str, 'General', 'watch_statistics, top_tv, popular_tv, top_movies, popular_movies, top_music, popular_music, top_users, top_platforms, last_watched'), + 'HOME_STATS_CARDS': (str, 'General', 'watch_statistics, top_tv, popular_tv, top_movies, popular_movies, ' \ + 'top_music, popular_music, last_watched, top_users, top_platforms, most_concurrent'), 'HTTPS_CERT': (str, 'General', ''), 'HTTPS_KEY': (str, 'General', ''), 'HTTP_HOST': (str, 'General', '0.0.0.0'), diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py index 8d797fae..d1b656e5 100644 --- a/plexpy/datafactory.py +++ b/plexpy/datafactory.py @@ -589,6 +589,38 @@ class DataFactory(object): home_stats.append({'stat_id': stat, 'rows': last_watched}) + elif stat == 'most_concurrent': + try: + query = 'SELECT started, stopped ' \ + 'FROM session_history ' + result = monitor_db.select(query) + except: + logger.warn("Unable to execute database query for get_home_stats: most_concurrent.") + return None + + times = {} + for item in result: + times.update({str(item['stopped']) + 'A': -1, str(item['started']) + 'B': 1}) + + count = 0 + last_start = 0 + most_concurrent = {'count': count} + + for key in sorted(times): + if times[key] == 1: + count += times[key] + if count >= most_concurrent['count']: + last_start = key + else: + if count >= most_concurrent['count']: + most_concurrent = {'count': count, + 'started': last_start[:-1], + 'stopped': key[:-1]} + count += times[key] + + home_stats.append({'stat_id': stat, + 'rows': [most_concurrent]}) + return home_stats def get_stream_details(self, row_id=None):