diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1266e43f..d5eb4c5a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,19 @@
# Changelog
+## v2.13.2 (2023-10-26)
+* History:
+ * New: Added quarter values icons for history watch status. (#2179, #2156) (Thanks @herby2212)
+* Graphs:
+ * New: Added concurrent streams per day graph. (#2046) (Thanks @herby2212)
+* Exporter:
+ * New: Added metadata directory to exporter fields.
+ * Removed: Banner exporter fields for tv shows.
+* UI:
+ * New: Added last triggered time to notification agents and newsletter agent lists.
+* Other:
+ * New: Added X-Plex-Language header override to config file.
+
+
## v2.13.1 (2023-08-25)
* Notes:
* Support for Python 3.7 has been dropped. The minimum Python version is now 3.8.
diff --git a/data/interfaces/default/configuration_table.html b/data/interfaces/default/configuration_table.html
index 676876d6..66d8ef40 100644
--- a/data/interfaces/default/configuration_table.html
+++ b/data/interfaces/default/configuration_table.html
@@ -11,6 +11,7 @@ DOCUMENTATION :: END
<%!
import os
+ import sqlite3
import sys
import plexpy
from plexpy import common, logger
@@ -71,10 +72,18 @@ DOCUMENTATION :: END
Resources: |
diff --git a/data/interfaces/default/css/tautulli.css b/data/interfaces/default/css/tautulli.css
index 8cad039f..0c81f0e5 100644
--- a/data/interfaces/default/css/tautulli.css
+++ b/data/interfaces/default/css/tautulli.css
@@ -338,20 +338,20 @@ object {
}
.btn-dark:focus,
.btn-dark.focus {
- color: #d7d7d7;
- background-color: #3B3B3B;
+ color: #d7d7d7;
+ background-color: #3B3B3B;
}
.btn-dark:hover {
- color: #eee;
- background-color: #333;
- border-color: #444;
+ color: #eee;
+ background-color: #333;
+ border-color: #444;
}
.btn-dark:active,
.btn-dark.active,
.open > .dropdown-toggle.btn-dark {
- color: #eee;
- background-color: #333;
- border-color: #444;
+ color: #eee;
+ background-color: #333;
+ border-color: #444;
}
.btn-dark:active:hover,
.btn-dark.active:hover,
@@ -362,13 +362,13 @@ object {
.btn-dark:active.focus,
.btn-dark.active.focus,
.open > .dropdown-toggle.btn-dark.focus {
- color: #eee;
- background-color: #333;
+ color: #eee;
+ background-color: #333;
}
.btn-dark:active,
.btn-dark.active,
.open > .dropdown-toggle.btn-dark {
- background-image: none;
+ background-image: none;
}
.btn-dark.disabled,
.btn-dark[disabled],
@@ -388,8 +388,8 @@ fieldset[disabled] .btn-dark:active,
.btn-dark.disabled.active,
.btn-dark[disabled].active,
fieldset[disabled] .btn-dark.active {
- background-color: #333;
- color: #aaa;
+ background-color: #333;
+ color: #aaa;
}
.btn-dark.inactive:hover {
color: #d7d7d7;
@@ -398,30 +398,30 @@ fieldset[disabled] .btn-dark.active {
cursor: default;
}
.btn-dark .badge {
- color: #e5e5e5;
- background-color: #3B3B3B;
+ color: #e5e5e5;
+ background-color: #3B3B3B;
}
.btn-bright {
- color: #eee;
- background-color: #cc7b19;
- box-shadow: inset 0 1px 0 #e7993b;
+ color: #eee;
+ background-color: #cc7b19;
+ box-shadow: inset 0 1px 0 #e7993b;
}
.btn-bright:focus,
.btn-bright.focus {
- color: #eee;
- background-color: #eb8600;
+ color: #eee;
+ background-color: #eb8600;
}
.btn-bright:hover {
- color: #eee;
- background-color: #e59029;
- box-shadow: inset 0 1px 0 #ebac60;
+ color: #eee;
+ background-color: #e59029;
+ box-shadow: inset 0 1px 0 #ebac60;
}
.btn-bright:active,
.btn-bright.active,
.open > .dropdown-toggle.btn-bright {
- color: #eee;
- background-color: #cc7b19;
- box-shadow: inset 0 1px 0 #e7993b;
+ color: #eee;
+ background-color: #cc7b19;
+ box-shadow: inset 0 1px 0 #e7993b;
}
.btn-bright:active:hover,
.btn-bright.active:hover,
@@ -432,14 +432,14 @@ fieldset[disabled] .btn-dark.active {
.btn-bright:active.focus,
.btn-bright.active.focus,
.open > .dropdown-toggle.btn-bright.focus {
- color: #eee;
- background-color: #cc7b19;
- box-shadow: inset 0 1px 0 #e7993b;
+ color: #eee;
+ background-color: #cc7b19;
+ box-shadow: inset 0 1px 0 #e7993b;
}
.btn-bright:active,
.btn-bright.active,
.open > .dropdown-toggle.btn-bright {
- background-image: none;
+ background-image: none;
}
.btn-bright.disabled,
.btn-bright[disabled],
@@ -459,13 +459,13 @@ fieldset[disabled] .btn-bright:active,
.btn-bright.disabled.active,
.btn-bright[disabled].active,
fieldset[disabled] .btn-bright.active {
- background-color: #cc7b19;
- border-color: #b56d16;
+ background-color: #cc7b19;
+ border-color: #b56d16;
}
.btn-bright .badge {
- color: #eee;
- background-color: #cc7b19;
- box-shadow: inset 0 1px 0 #e7993b;
+ color: #eee;
+ background-color: #cc7b19;
+ box-shadow: inset 0 1px 0 #e7993b;
}
.btn-danger.btn-edit {
color: #d7d7d7;
@@ -479,14 +479,14 @@ fieldset[disabled] .btn-bright.active {
border-color: #ac2925;
}
.btn-danger.btn-edit.active {
- color: #eee;
- background-color: #c9302c;
- border-color: #ac2925;
+ color: #eee;
+ background-color: #c9302c;
+ border-color: #ac2925;
}
.btn-danger.btn-edit.active:hover {
- color: #eee;
- background-color: #ac2925;
- border-color: #761c19;
+ color: #eee;
+ background-color: #ac2925;
+ border-color: #761c19;
}
.btn-group select {
margin-top: 0;
@@ -667,12 +667,12 @@ textarea.form-control:focus {
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
- touch-action: manipulation;
+ touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
background-image: none;
background-color: #3B3B3B;
color: #e5e5e5;
@@ -690,10 +690,10 @@ textarea.form-control:focus {
}
.btn-filter.active,
.btn-filter.active.focus {
- background-color: #b7800a !important;
+ background-color: #b7800a !important;
}
.btn-filter.active:hover {
- background-color: #896007 !important;
+ background-color: #896007 !important;
}
.form-control-feedback {
color: #E5A00D;
@@ -1281,7 +1281,7 @@ a .dashboard-activity-metadata-user-thumb:hover {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
z-index: 1;
- -webkit-border-radius: 50%;
+ -webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 350%;
overflow: hidden;
@@ -2203,8 +2203,8 @@ span.settings-warning {
padding-left: 10px;
}
#menu_link_show_advanced_settings.active {
- color: #eee;
- background-color: #cc7b19;
+ color: #eee;
+ background-color: #cc7b19;
}
#configUpdate .form-group,
#configUpdate .checkbox{
@@ -2854,6 +2854,30 @@ a .home-platforms-list-cover-face:hover
overflow: hidden;
max-width: 350px;
}
+.circle {
+ width: 1.55rem;
+ height: 1.55rem;
+ border-radius: 50%;
+ border: 0.2rem solid #eeeeee;
+}
+.circle-quarter {
+ background-image:
+ linear-gradient(00deg, #2b2b2b 50%, transparent 50%),
+ linear-gradient(270deg, #eeeeee 50%, transparent 50%);
+}
+.circle-half {
+ background-image:
+ linear-gradient(90deg, #2b2b2b 50%, transparent 50%),
+ linear-gradient(-90deg, #eeeeee 50%, transparent 50%);
+ }
+.circle-three-quarter {
+ background-image:
+ linear-gradient(180deg, transparent 50%, #eeeeee 50%),
+ linear-gradient(-90deg, #eeeeee 50%, transparent 50%);
+}
+.circle-full {
+ background: #eeeeee;
+}
#graph-tabs {
padding-bottom: 10px;
float: none;
@@ -2991,8 +3015,8 @@ a .home-platforms-list-cover-face:hover
border-left: 2px solid #444;
border-top: 1px solid #2d2d2d;
-webkit-transition: all 0.3s ease;
- -o-transition: all 0.3s ease;
- transition: all 0.3s ease;
+ -o-transition: all 0.3s ease;
+ transition: all 0.3s ease;
}
.stacked-configs > li > span:hover,
.stacked-configs > li > span:focus {
diff --git a/data/interfaces/default/graphs.html b/data/interfaces/default/graphs.html
index 7cd0c98b..15a96a69 100644
--- a/data/interfaces/default/graphs.html
+++ b/data/interfaces/default/graphs.html
@@ -137,7 +137,7 @@
-
+
Daily concurrent stream count by stream type Last 30 days
@@ -372,6 +372,10 @@
break
}
+ if (window.location.hash === '#concurrent-graph') {
+ current_tab = '#tabs-stream';
+ }
+
$('#yaxis-' + yaxis).prop('checked', true);
$('#yaxis-' + yaxis).closest('label').addClass('active');
$('#graph-days').val(current_day_range);
@@ -639,7 +643,7 @@
}
});
- $('#nav-tabs-2').tab('show');
+ $('#nav-tabs-stream').tab('show');
}
function loadGraphsTab3(time_range, yaxis) {
diff --git a/data/interfaces/default/home_stats.html b/data/interfaces/default/home_stats.html
index 1d9e03dd..5e0d0855 100644
--- a/data/interfaces/default/home_stats.html
+++ b/data/interfaces/default/home_stats.html
@@ -177,7 +177,9 @@ DOCUMENTATION :: END
% elif stat_id == 'top_platforms':
${row['platform']}
% elif stat_id == 'most_concurrent':
- ${row['title']}
+
+ ${row['title']}
+
% endif
diff --git a/data/interfaces/default/js/tables/history_table.js b/data/interfaces/default/js/tables/history_table.js
index b56304ee..40c3ab6c 100644
--- a/data/interfaces/default/js/tables/history_table.js
+++ b/data/interfaces/default/js/tables/history_table.js
@@ -263,13 +263,17 @@ history_table_options = {
"targets": [12],
"data": "watched_status",
"createdCell": function (td, cellData, rowData, row, col) {
+ var circleValue = "";
if (cellData == 1) {
- $(td).html(' ');
+ circleValue = " circle-full";
+ } else if (cellData == 0.75) {
+ circleValue = " circle-three-quarter";
} else if (cellData == 0.5) {
- $(td).html(' ');
- } else {
- $(td).html(' ');
+ circleValue = " circle-half";
+ } else if (cellData == 0.25) {
+ circleValue = " circle-quarter";
}
+ $(td).html(' ');
},
"searchable": false,
"orderable": false,
diff --git a/plexpy/__init__.py b/plexpy/__init__.py
index a2062c43..1a1564ac 100644
--- a/plexpy/__init__.py
+++ b/plexpy/__init__.py
@@ -236,6 +236,9 @@ def initialize(config_file):
logger.info("{} (UTC{})".format(
str(SYS_TIMEZONE), SYS_UTC_OFFSET
))
+ logger.info("Language {}{} / Encoding {}".format(
+ SYS_LANGUAGE, f' (override {CONFIG.PMS_LANGUAGE})' if CONFIG.PMS_LANGUAGE else '', SYS_ENCODING
+ ))
logger.info("Python {}".format(
sys.version.replace('\n', '')
))
diff --git a/plexpy/activity_handler.py b/plexpy/activity_handler.py
index 0dd6e5e5..3280d055 100644
--- a/plexpy/activity_handler.py
+++ b/plexpy/activity_handler.py
@@ -311,7 +311,9 @@ class ActivityHandler(object):
last_state = self.db_session['state']
last_rating_key = str(self.db_session['rating_key'])
last_live_uuid = self.db_session['live_uuid']
- last_transcode_key = self.db_session['transcode_key'].split('/')[-1]
+ last_transcode_key = self.db_session['transcode_key']
+ if isinstance(last_transcode_key, str):
+ last_transcode_key = last_transcode_key.split('/')[-1]
last_paused = self.db_session['last_paused']
last_rating_key_websocket = self.db_session['rating_key_websocket']
last_guid = self.db_session['guid']
diff --git a/plexpy/config.py b/plexpy/config.py
index 6f2926d9..dbcd294d 100644
--- a/plexpy/config.py
+++ b/plexpy/config.py
@@ -55,6 +55,7 @@ _CONFIG_DEFINITIONS = {
'PMS_IP': (str, 'PMS', '127.0.0.1'),
'PMS_IS_CLOUD': (int, 'PMS', 0),
'PMS_IS_REMOTE': (int, 'PMS', 0),
+ 'PMS_LANGUAGE': (str, 'PMS', ''),
'PMS_LOGS_FOLDER': (str, 'PMS', ''),
'PMS_LOGS_LINE_CAP': (int, 'PMS', 1000),
'PMS_NAME': (str, 'PMS', ''),
diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py
index dfe64992..05af1285 100644
--- a/plexpy/datafactory.py
+++ b/plexpy/datafactory.py
@@ -283,13 +283,19 @@ class DataFactory(object):
if item['live']:
item['percent_complete'] = 100
+ base_watched_value = watched_percent[item['media_type']] / 4.0
+
if helpers.check_watched(
item['media_type'], item['view_offset'], item['duration'],
item['marker_credits_first'], item['marker_credits_final']
):
watched_status = 1
- elif item['percent_complete'] >= watched_percent[item['media_type']] / 2.0:
- watched_status = 0.5
+ elif item['percent_complete'] >= base_watched_value * 3.0:
+ watched_status = 0.75
+ elif item['percent_complete'] >= base_watched_value * 2.0:
+ watched_status = 0.50
+ elif item['percent_complete'] >= base_watched_value:
+ watched_status = 0.25
else:
watched_status = 0
diff --git a/plexpy/http_handler.py b/plexpy/http_handler.py
index 87c4cff5..79bb3562 100644
--- a/plexpy/http_handler.py
+++ b/plexpy/http_handler.py
@@ -62,7 +62,7 @@ class HTTPHandler(object):
plexpy.common.PLATFORM_RELEASE),
'X-Plex-Device-Name': '{} ({})'.format(plexpy.common.PLATFORM_DEVICE_NAME,
plexpy.common.PRODUCT),
- 'Accept-Language': plexpy.SYS_LANGUAGE
+ 'X-Plex-Language': plexpy.CONFIG.PMS_LANGUAGE or plexpy.SYS_LANGUAGE
}
self.token = token
diff --git a/plexpy/version.py b/plexpy/version.py
index c5ee1521..5ca70297 100644
--- a/plexpy/version.py
+++ b/plexpy/version.py
@@ -18,4 +18,4 @@
from __future__ import unicode_literals
PLEXPY_BRANCH = "master"
-PLEXPY_RELEASE_VERSION = "v2.13.1"
\ No newline at end of file
+PLEXPY_RELEASE_VERSION = "v2.13.2"
\ No newline at end of file
|