diff --git a/.gitignore b/.gitignore
index 3e58c483..cb7eb12f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,9 @@ cache/*
*.csr
*.pem
+# Mergetool
+*.orgin
+
# OS generated files #
######################
.DS_Store?
@@ -32,7 +35,7 @@ Icon?
Thumbs.db
#Ignore files generated by PyCharm
-.idea/*
+*.idea/*
#Ignore files generated by vi
*.swp
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 446f639b..30a3279a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,33 @@
# Changelog
+## v1.3.7 (2016-02-20)
+
+* Fix: Verifying server with SSL enabled.
+* Fix: Regression where {stream_duration} reported as 0.
+* Fix: Video metadata flags showing up for track info.
+* Fix: Custom library icons not applied to Library Statistics.
+* Fix: Typos in the Web UI.
+* Add: ETA to Current Activity overlay.
+* Add: Total duration to Libraries and Users tables.
+* Add: {machine_id} to notification options.
+* Add: IMDB, TVDB, TMDb, Last.fm, and Trackt IDs/URLs to notification options.
+* Add: {poster_url} to notification options using Imgur.
+* Add: Poster and link for Facebook notifications.
+* Add: Log javascript errors from the Web UI.
+* Add: Configuration and Scheduler info to the settings page.
+* Add: Schedule background task to backup the PlexPy database.
+* Add: URL anonymizer for external links.
+* Add: Plex Media Scanner log file to Log viewer.
+* Add: API v2 (sill very experimental) (Thanks @Hellowlol)
+* Change: Allow secure websocket connections.
+* Change: History grouping now accounts for the view offset.
+* Change: Subject line can be toggled off for Facebook, Slack, Telegram, and Twitter.
+* Change: Create self-signed SSL certificates when enabling HTTPS.
+* Change: Revert homepage "Last Played" to "Last Watched".
+* Change: Disable monitor remote access checkbox if remote access is not enabled on the PMS.
+* Change: Disable IP logging checkbox if PMS version is 0.9.14 or greater.
+
+
## v1.3.6 (2016-02-03)
* Fix: Regression where {duration} not reported in minutes.
diff --git a/data/interfaces/default/css/plexpy.css b/data/interfaces/default/css/plexpy.css
index ad0a0c8d..e200da78 100644
--- a/data/interfaces/default/css/plexpy.css
+++ b/data/interfaces/default/css/plexpy.css
@@ -501,7 +501,8 @@ textarea.form-control:focus {
.libraries-poster-face {
overflow: hidden;
float: left;
- background-size: contain;
+ background-size: cover;
+ background-position: center;
height: 40px;
width: 40px;
/*-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
@@ -1717,7 +1718,8 @@ a:hover .item-children-poster {
float: left;
margin-top: 15px;
margin-right: 15px;
- background-size: contain;
+ background-size: cover;
+ background-position: center;
height: 80px;
width: 80px;
/*-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
@@ -2178,6 +2180,10 @@ a .home-platforms-instance-list-oval:hover,
.refresh-libraries-button {
float: right;
}
+.refresh-users-button,
+.refresh-libraries-button {
+ margin-right: 5px;
+}
.nav-settings,
.nav-settings ul {
margin: 0px 0px 20px 0px;
@@ -2712,4 +2718,44 @@ table[id^='media_info_child'] table[id^='media_info_child'] thead th {
}
.selectize-input input[type='text'] {
height: 20px;
+}
+.small-muted {
+ font-size: small;
+ color: #777;
+}
+.config-info-table,
+.config-scheduler-table {
+ width: 100%
+}
+.config-info-table td,
+.config-info-table th,
+.config-scheduler-table td,
+.config-scheduler-table th {
+ padding-bottom: 5px;
+}
+.config-info-table td:first-child {
+ width: 150px;
+}
+.config-scheduler-table td:first-child {
+ width: 225px;
+}
+.config-scheduler-table th {
+ color: #fff;
+}
+a.no-highlight {
+ color: #777;
+}
+a.no-highlight:hover {
+ color: #fff;
+}
+.top-line {
+ border-top: 1px dotted #777;
+ padding-top: 5px;
+}
+.help-bold {
+ font-weight: bold;
+ color: #fff;
+}
+.save-button {
+ margin-top: 15px;
}
\ No newline at end of file
diff --git a/data/interfaces/default/current_activity.html b/data/interfaces/default/current_activity.html
index 5b4ab21e..47be0dcd 100644
--- a/data/interfaces/default/current_activity.html
+++ b/data/interfaces/default/current_activity.html
@@ -198,6 +198,13 @@ DOCUMENTATION :: END
% else:
IP: N/A
% endif
+
+ ETA:
+
+
+
days
hrs
mins
'; + text = 'days
' + + 'hrs
' + + 'mins
'; return text; } else if (seconds >= 3600) { - text = 'hrs
mins
'; + text = 'hrs
' + + 'mins
'; return text; } else if (seconds >= 60) { text = 'mins
'; @@ -269,6 +272,25 @@ function humanTime(seconds) { } } +function humanTimeClean(seconds) { + if (seconds >= 86400) { + text = Math.floor(moment.duration(seconds, 'seconds').asDays()) + ' days ' + + Math.floor(moment.duration((seconds % 86400), 'seconds').asHours()) + ' hrs ' + + Math.floor(moment.duration(((seconds % 86400) % 3600), 'seconds').asMinutes()) + ' mins'; + return text; + } else if (seconds >= 3600) { + text = Math.floor(moment.duration((seconds % 86400), 'seconds').asHours()) + ' hrs ' + + Math.floor(moment.duration(((seconds % 86400) % 3600), 'seconds').asMinutes()) + ' mins'; + return text; + } else if (seconds >= 60) { + text = Math.floor(moment.duration(((seconds % 86400) % 3600), 'seconds').asMinutes()) + ' mins'; + return text; + } else { + text = '0'; + return text; + } +} + String.prototype.toProperCase = function () { return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}); }; @@ -372,3 +394,16 @@ function clearSearchButton(tableName, table) { table.search('').draw(); }); } + +// Taken from https://github.com/Hellowlol/HTPC-Manager +window.onerror = function (message, file, line) { + var e = { + 'page': window.location.href, + 'message': message, + 'file': file, + 'line': line + }; + + $.post("log_js_errors", e, function (data) { + }); +}; \ No newline at end of file diff --git a/data/interfaces/default/js/tables/libraries.js b/data/interfaces/default/js/tables/libraries.js index 377295ae..46844506 100644 --- a/data/interfaces/default/js/tables/libraries.js +++ b/data/interfaces/default/js/tables/libraries.js @@ -161,12 +161,28 @@ libraries_list_table_options = { $(td).html('n/a'); } }, - "width": "25%", + "width": "18%", "className": "hidden-sm hidden-xs" }, { "targets": [9], "data": "plays", + "createdCell": function (td, cellData, rowData, row, col) { + if (cellData !== null && cellData !== '') { + $(td).html(cellData); + } + }, + "searchable": false, + "width": "7%" + }, + { + "targets": [10], + "data": "duration", + "createdCell": function (td, cellData, rowData, row, col) { + if (cellData !== null && cellData !== '') { + $(td).html(humanTimeClean(cellData)); + } + }, "searchable": false, "width": "10%" } diff --git a/data/interfaces/default/js/tables/users.js b/data/interfaces/default/js/tables/users.js index f7147a17..d1abb6c9 100644 --- a/data/interfaces/default/js/tables/users.js +++ b/data/interfaces/default/js/tables/users.js @@ -165,12 +165,28 @@ users_list_table_options = { $(td).html('n/a'); } }, - "width": "30%", + "width": "23%", "className": "hidden-sm hidden-xs" }, { "targets": [8], "data": "plays", + "createdCell": function (td, cellData, rowData, row, col) { + if (cellData !== null && cellData !== '') { + $(td).html(cellData); + } + }, + "searchable": false, + "width": "7%" + }, + { + "targets": [9], + "data": "duration", + "createdCell": function (td, cellData, rowData, row, col) { + if (cellData !== null && cellData !== '') { + $(td).html(humanTimeClean(cellData)); + } + }, "searchable": false, "width": "10%" } diff --git a/data/interfaces/default/libraries.html b/data/interfaces/default/libraries.html index 1e99697c..41fc9825 100644 --- a/data/interfaces/default/libraries.html +++ b/data/interfaces/default/libraries.html @@ -2,6 +2,7 @@ <%def name="headIncludes()"> + %def> @@ -23,6 +24,7 @@ All LibrariesTimestamp | +Level | +Message | +
---|
Scheduled Task | +State | +Interval | +Next Run In | +Next Run Time | +
---|---|---|---|---|
${sched_job.id} | +Active | +${arrow.get(run_interval).format('HH:mm:ss')} | +${arrow.get(next_run_interval).format('HH:mm:ss')} | +${arrow.get(sched_job.next_run_time).format('YYYY-MM-DD HH:mm:ss')} | +
${job} | +Using Websocket | +N/A | +N/A | +N/A | +
${job} | +Inactive | +N/A | +N/A | +N/A | +
Backlink protection via anonymizer service, must end in "?".
+Instead of polling the server at regular intervals let the server tell us when something happens.
- This is currently experimental. Encrypted websocket is not currently supported.
Enable to have PlexPy check if remote access to the Plex Media Server goes down. Your server needs to have remote access enabled.
+ +Enable to have PlexPy check if remote access to the Plex Media Server goes down.
- Enable this to attempt to log the IP address of the user (for PMS 0.9.12 and below, IP address is automatically logged for PMS 0.9.14 and above). + Enable this to attempt to log the IP address of the user.
You can set custom formatted text for each type of notification. - Click here for a list of available parameters which can be used. + Click here for a list of available parameters which can be used.
- You can also add tags to exclude certain text depending on the media type. Click - here to view usage information. + You can also add tags to exclude certain text depending on the media type. + Click here to view usage information.
- Toggle the desired notification options by clicking the bell icon and configure it by clicking the settings icon to the right. + Toggle the desired notification options by clicking the bell icon () and configure it by clicking the settings icon to the right.