diff --git a/data/interfaces/default/css/plexpy.css b/data/interfaces/default/css/plexpy.css index b09227b2..8f951655 100644 --- a/data/interfaces/default/css/plexpy.css +++ b/data/interfaces/default/css/plexpy.css @@ -253,6 +253,12 @@ fieldset[disabled] .btn-dark.active { background-color: #333; color: #aaa; } +.btn-dark.inactive:hover { + color: #d7d7d7; + background-color: #3B3B3B; + border-color: transparent; + cursor: default; +} .btn-dark .badge { color: #e5e5e5; background-color: #3B3B3B; @@ -1865,9 +1871,36 @@ a .library-user-instance-box:hover { -moz-box-shadow: inset 0 0 0 2px #e9a049; box-shadow: inset 0 0 0 2px #e9a049; } +#watched-stats-days-selection label { + margin-bottom: 0; +} +#watched-stats-days { + margin: 0; + width: 75px; + height: 34px; +} +#watched-stats-count { + margin: 0; + width: 75px; + height: 34px; +} +#recently-added-count { + margin: 0; + width: 75px; + height: 34px; +} +.home-padded-header { + margin: 25px 0; + height: 34px; +} +.home-padded-header h3 { + margin-top: 9px; + width: 175px; +} .home-platforms { } -.home-platforms ul { +.home-platforms ul, +.library-platforms ul { list-style: none; margin: 0; } diff --git a/data/interfaces/default/graphs.html b/data/interfaces/default/graphs.html index 0ebdc28b..ac6a8294 100644 --- a/data/interfaces/default/graphs.html +++ b/data/interfaces/default/graphs.html @@ -20,7 +20,7 @@ -
+
% if config['graph_type'] == 'duration': % endif
-
- +
+ Last + + days
-
- +
+ Last + + months
@@ -572,11 +572,7 @@ e.preventDefault(); current_tab = $(this).attr('href'); loadGraphsTab1(current_day_range, yaxis); - $.ajax({ - url: 'set_graph_config', - data: { graph_tab: current_tab.replace('#','') }, - async: true - }); + $.post('set_graph_config', { graph_tab: current_tab.replace('#','') }); }) // Tab2 opened @@ -584,11 +580,7 @@ e.preventDefault(); current_tab = $(this).attr('href'); loadGraphsTab2(current_day_range, yaxis); - $.ajax({ - url: 'set_graph_config', - data: { graph_tab: current_tab.replace('#','') }, - async: true - }); + $.post('set_graph_config', { graph_tab: current_tab.replace('#','') }); }) // Tab3 opened @@ -596,46 +588,28 @@ e.preventDefault(); current_tab = $(this).attr('href'); loadGraphsTab3(current_month_range, yaxis); - $.ajax({ - url: 'set_graph_config', - data: { graph_tab: current_tab.replace('#','') }, - async: true - }); + $.post('set_graph_config', { graph_tab: current_tab.replace('#','') }); }) // Date range changed + $('#graph-days').tooltip({ container: 'body', placement: 'top', html: true }); $('#graph-days').on('change', function() { - current_day_range = Math.round($(this).val()); - $(this).val(current_day_range); - if (current_day_range < 1) { - $(this).val(7); - current_day_range = 7; - } + forceMinMax($(this)); + current_day_range = $(this).val(); if (current_tab == '#tabs-1') { loadGraphsTab1(current_day_range, yaxis); } if (current_tab == '#tabs-2') { loadGraphsTab2(current_day_range, yaxis); } $('.days').html(current_day_range); - $.ajax({ - url: 'set_graph_config', - data: { graph_days: current_day_range}, - async: true - }); + $.post('set_graph_config', { graph_days: current_day_range }); }); // Month range changed + $('#graph-months').tooltip({ container: 'body', placement: 'top', html: true }); $('#graph-months').on('change', function() { - current_month_range = Math.round($(this).val()); - $(this).val(current_month_range); - if (current_month_range < 1) { - $(this).val(12); - current_month_range = 12; - } + forceMinMax($(this)); + current_month_range = $(this).val(); if (current_tab == '#tabs-3') { loadGraphsTab3(current_month_range, yaxis); } $('.months').html(current_month_range); - $.ajax({ - url: 'set_graph_config', - data: { graph_months: current_month_range}, - async: true - }); + $.post('set_graph_config', { graph_months: current_month_range }); }); // User changed @@ -652,11 +626,7 @@ if (current_tab == '#tabs-1') { loadGraphsTab1(current_day_range, yaxis); } if (current_tab == '#tabs-2') { loadGraphsTab2(current_day_range, yaxis); } if (current_tab == '#tabs-3') { loadGraphsTab3(current_month_range, yaxis); } - $.ajax({ - url: 'set_graph_config', - data: { graph_type: yaxis}, - async: true - }); + $.post('set_graph_config', { graph_type: yaxis }); }); function setGraphFormat(type) { diff --git a/data/interfaces/default/index.html b/data/interfaces/default/index.html index 492df1a6..d7e71f73 100644 --- a/data/interfaces/default/index.html +++ b/data/interfaces/default/index.html @@ -20,9 +20,40 @@ % elif section == 'watch_stats':
-
-

Watch Statistics   Last ${config['home_stats_length']} days

+
+

Watch Statistics

+
+ % if config['home_stats_type'] == 0: + + + % else: + + + % endif +
+
+ Last + + days +
+
+ Top + + items +
+
+
+
+
Loading stats...

@@ -32,9 +63,14 @@ % elif section == 'library_stats':
-
-

Library Statistics   ${config['pms_name']}

+
+

Library Statistics

+ ${config['pms_name']}
+
+
+
+
Loading stats...

@@ -44,8 +80,9 @@ % elif section == 'recently_added':
-
-
+
+
+
Looking for new items...

@@ -345,19 +397,48 @@ % endif % if 'watch_stats' in config['home_sections']: % endif % if 'library_stats' in config['home_sections']: @@ -379,25 +460,35 @@ % endif % if 'recently_added' in config['home_sections']: % endif % if _session['user_group'] == 'admin' and config['update_show_changelog']: diff --git a/data/interfaces/default/js/script.js b/data/interfaces/default/js/script.js index a1cc43fb..cdb85c65 100644 --- a/data/interfaces/default/js/script.js +++ b/data/interfaces/default/js/script.js @@ -495,4 +495,24 @@ function humanFileSize(bytes, si) { ++u; } while (Math.abs(bytes) >= thresh && u < units.length - 1); return bytes.toFixed(1) + ' ' + units[u]; +} + +// Force max/min in number inputs +function forceMinMax(elem) { + var min = parseInt(elem.attr('min')); + var max = parseInt(elem.attr('max')); + var val = parseInt(elem.val()); + var default_val = parseInt(elem.data('default')); + if (isNaN(val)) { + elem.val(default_val); + } + else if (min != undefined && val < min) { + elem.val(min); + } + else if (max != undefined && val > max) { + elem.val(max); + } + else { + elem.val(val); + } } \ No newline at end of file diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 014ad460..c02e84e0 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -300,32 +300,6 @@
-
- -
-
- -
- -
-

Specify the number of days for the watch statistics on the home page. Default is 30 days.

-
-
- -
-
- -
- -
-

Specify the number of items to show in the top lists for the watch statistics on the home page. Maximum 10 items, default 5 items, 0 to disable.

-
-
- -

Use play duration instead of play count to generate statistics.

-

Library Statistics

diff --git a/plexpy/config.py b/plexpy/config.py index db465f02..86319803 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -203,6 +203,7 @@ _CONFIG_DEFINITIONS = { 'HOME_STATS_COUNT': (int, 'General', 5), 'HOME_STATS_CARDS': (list, 'General', ['top_movies', 'popular_movies', 'top_tv', 'popular_tv', 'top_music', \ 'popular_music', 'last_watched', 'top_users', 'top_platforms', 'most_concurrent']), + 'HOME_STATS_RECENTLY_ADDED_COUNT': (int, 'General', 50), 'HTTPS_CREATE_CERT': (int, 'General', 1), 'HTTPS_CERT': (str, 'General', ''), 'HTTPS_CERT_CHAIN': (str, 'General', ''), diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py index 11c23465..d7759d2f 100644 --- a/plexpy/datafactory.py +++ b/plexpy/datafactory.py @@ -255,21 +255,26 @@ class DataFactory(object): return dict - def get_home_stats(self, grouping=0, time_range=0, stats_type=0, stats_count=0, stats_cards=[]): + def get_home_stats(self, grouping=None, time_range=None, stats_type=None, stats_count=None, stats_cards=None): monitor_db = database.MonitorDatabase() - grouping = grouping or plexpy.CONFIG.GROUP_HISTORY_TABLES - time_range = time_range or plexpy.CONFIG.HOME_STATS_LENGTH - stats_type = stats_type or plexpy.CONFIG.HOME_STATS_TYPE - stats_count = stats_count or plexpy.CONFIG.HOME_STATS_COUNT - stats_cards = stats_cards or plexpy.CONFIG.HOME_STATS_CARDS + if grouping is None: + grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES + if time_range is None: + time_range = plexpy.CONFIG.HOME_STATS_LENGTH + if stats_type is None: + stats_type = plexpy.CONFIG.HOME_STATS_TYPE + if stats_count is None: + stats_count = plexpy.CONFIG.HOME_STATS_COUNT + if stats_cards is None: + stats_cards = plexpy.CONFIG.HOME_STATS_CARDS movie_watched_percent = plexpy.CONFIG.MOVIE_WATCHED_PERCENT tv_watched_percent = plexpy.CONFIG.TV_WATCHED_PERCENT music_watched_percent = plexpy.CONFIG.MUSIC_WATCHED_PERCENT group_by = 'session_history.reference_id' if grouping else 'session_history.id' - sort_type = 'total_plays' if stats_type == 0 else 'total_duration' + sort_type = 'total_duration' if helpers.cast_to_int(stats_type) == 1 else 'total_plays' home_stats = [] diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 336752eb..5b52d9bc 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -173,6 +173,9 @@ class WebInterface(object): config = { "home_sections": plexpy.CONFIG.HOME_SECTIONS, "home_stats_length": plexpy.CONFIG.HOME_STATS_LENGTH, + "home_stats_type": plexpy.CONFIG.HOME_STATS_TYPE, + "home_stats_count": plexpy.CONFIG.HOME_STATS_COUNT, + "home_stats_recently_added_count": plexpy.CONFIG.HOME_STATS_RECENTLY_ADDED_COUNT, "pms_name": plexpy.CONFIG.PMS_NAME, "pms_use_bif": plexpy.CONFIG.PMS_USE_BIF, "update_show_changelog": plexpy.CONFIG.UPDATE_SHOW_CHANGELOG @@ -308,12 +311,32 @@ class WebInterface(object): @cherrypy.expose @requireAuth() - def home_stats(self, **kwargs): + def home_stats(self, time_range=30, stats_type=0, stats_count=5, **kwargs): data_factory = datafactory.DataFactory() - stats_data = data_factory.get_home_stats() + stats_data = data_factory.get_home_stats(time_range=time_range, + stats_type=stats_type, + stats_count=stats_count) return serve_template(templatename="home_stats.html", title="Stats", data=stats_data) + @cherrypy.expose + @requireAuth(member_of("admin")) + def set_home_stats_config(self, time_range=None, stats_type=None, stats_count=None, recently_added_count=None, **kwargs): + if time_range: + plexpy.CONFIG.__setattr__('HOME_STATS_LENGTH', time_range) + plexpy.CONFIG.write() + if stats_type: + plexpy.CONFIG.__setattr__('HOME_STATS_TYPE', stats_type) + plexpy.CONFIG.write() + if stats_count: + plexpy.CONFIG.__setattr__('HOME_STATS_COUNT', stats_count) + plexpy.CONFIG.write() + if recently_added_count: + plexpy.CONFIG.__setattr__('HOME_STATS_RECENTLY_ADDED_COUNT', recently_added_count) + plexpy.CONFIG.write() + + return "Updated home stats config values." + @cherrypy.expose @requireAuth() def library_stats(self, **kwargs): @@ -2589,9 +2612,6 @@ class WebInterface(object): "notify_concurrent_by_ip": checked(plexpy.CONFIG.NOTIFY_CONCURRENT_BY_IP), "notify_concurrent_threshold": plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD, "home_sections": json.dumps(plexpy.CONFIG.HOME_SECTIONS), - "home_stats_length": plexpy.CONFIG.HOME_STATS_LENGTH, - "home_stats_type": checked(plexpy.CONFIG.HOME_STATS_TYPE), - "home_stats_count": plexpy.CONFIG.HOME_STATS_COUNT, "home_stats_cards": json.dumps(plexpy.CONFIG.HOME_STATS_CARDS), "home_library_cards": json.dumps(plexpy.CONFIG.HOME_LIBRARY_CARDS), "buffer_threshold": plexpy.CONFIG.BUFFER_THRESHOLD,