Compare commits

..

21 Commits

Author SHA1 Message Date
JonnyWong16
9678d29246 v2.1.15-beta 2018-07-01 23:36:14 -07:00
JonnyWong16
b49e500221 Update Font Awesome css links 2018-07-01 21:51:18 -07:00
JonnyWong16
f9fd0558a5 Fix grouping of SD resolution on graphs 2018-07-01 08:35:21 -07:00
JonnyWong16
5cf1cac7e9 Change get_users API command to pull from database instead of Plex.tv 2018-06-30 16:45:56 -07:00
JonnyWong16
9355d31a27 Fix selectize multiselect box expanding 2018-06-30 16:29:52 -07:00
JonnyWong16
457c23c648 HTTPS urls for tautulli.com newsletter images 2018-06-30 16:11:46 -07:00
JonnyWong16
11d563e4cd Don't return on script error 2018-06-29 23:37:26 -07:00
JonnyWong16
4437a94675 Add PYTHONPATH to script environment variables 2018-06-29 23:13:20 -07:00
JonnyWong16
d4784dff23 Encode terminate session message 2018-06-29 13:24:57 -07:00
JonnyWong16
fdd8ac7c7b Add TAUTULLI_ENCODING to script environment variables 2018-06-29 13:11:44 -07:00
JonnyWong16
2e290d0b0c Refactor test script arg splitting 2018-06-29 12:36:35 -07:00
JonnyWong16
ae49b08e19 Decode script args when logging to database 2018-06-29 10:49:00 -07:00
JonnyWong16
f9f05be978 Encode script args for triggers 2018-06-29 10:35:49 -07:00
JonnyWong16
47df4ee884 Encode script args for all systems 2018-06-29 09:48:24 -07:00
JonnyWong16
a3ead41990 Handle unicode script arguments 2018-06-28 18:37:07 -07:00
JonnyWong16
b248dbacf2 Correct script environment if http host changed 2018-06-27 14:04:28 -07:00
JonnyWong16
5fc182dcc2 Alias platform Tizen to Samsung 2018-06-26 21:02:20 -07:00
JonnyWong16
274a7e5827 Removed unused font awesome js files 2018-06-25 20:42:04 -07:00
JonnyWong16
656e811eae Fix typo on setup wizard 2018-06-24 22:00:55 -07:00
JonnyWong16
6ac9dc112c Update Plex forum urls 2018-06-24 15:21:17 -07:00
JonnyWong16
753257ddb3 Fix NaN percent for live sessions 2018-06-23 14:12:19 -07:00
25 changed files with 128 additions and 74 deletions

14
API.md
View File

@@ -2293,15 +2293,21 @@ Optional parameters:
Returns:
json:
[{"email": "Jon.Snow.1337@CastleBlack.com",
[{"allow_guest": 1,
"do_notify": 1,
"email": "Jon.Snow.1337@CastleBlack.com",
"filter_all": "",
"filter_movies": "",
"filter_music": "",
"filter_photos": "",
"filter_tv": "",
"is_allow_sync": null,
"is_home_user": "1",
"is_restricted": "0",
"is_admin": 0,
"is_allow_sync": 1,
"is_home_user": 1,
"is_restricted": 0,
"keep_history": 1,
"server_token": "PU9cMuQZxJKFBtGqHk68",
"shared_libraries": "1;2;3",
"thumb": "https://plex.tv/users/k10w42309cynaopq/avatar",
"user_id": "133788",
"username": "Jon Snow"

View File

@@ -1,5 +1,22 @@
# Changelog
## v2.1.15-beta (2018-07-01)
* Monitoring:
* Fix: Progress percent displaying NaN for live TV.
* Fix: Unable to terminate sessions with unicode characters in the message.
* Change: Tizen platform to display the Samsung icon.
* Notifications:
* New: Added PYTHONPATH to script environment variables so scripts can automatically import from Tautulli libraries.
* Fix: Proper handling of unicode script arguments.
* Fix: Incorrect TAUTULLI_URL environment variable if the HTTP host setting is changed.
* Fix: Email addresses selectize box not expanding.
* Newsletters:
* Change: HTTPS URLS for images hosted on tautulli.com.
* Graphs:
* Fix: SD resolution sometimes not grouped together.
## v2.1.14 (2018-06-21)
* Notifications:

View File

@@ -2,7 +2,7 @@
[![Discord](https://img.shields.io/badge/Discord-Tautulli-7289DA.svg?style=flat-square)](https://tautulli.com/discord)
[![Reddit](https://img.shields.io/badge/Reddit-Tautulli-FF5700.svg?style=flat-square)](https://www.reddit.com/r/Tautulli/)
[![Plex Forums](https://img.shields.io/badge/Plex%20Forums-Tautulli-E5A00D.svg?style=flat-square)](https://forums.plex.tv/discussion/307821/tautulli-monitor-your-plex-media-server)
[![Plex Forums](https://img.shields.io/badge/Plex%20Forums-Tautulli-E5A00D.svg?style=flat-square)](https://forums.plex.tv/t/tautulli-monitor-your-plex-media-server/225242)
A python based web application for monitoring, analytics and notifications for [Plex Media Server](https://plex.tv).
@@ -35,7 +35,7 @@ This project is based on code from [Headphones](https://github.com/rembo10/headp
* Read the [Installation Guides](https://github.com/Tautulli/Tautulli-Wiki/wiki/Installation) for instructions to install Tautulli.
* The [Frequently Asked Questions](https://github.com/Tautulli/Tautulli-Wiki/wiki/Frequently-Asked-Questions) in the wiki can help you with common problems.
* Support is available on [Discord](https://tautulli.com/discord), [Reddit](https://www.reddit.com/r/Tautulli), or the [Plex Forums](https://forums.plex.tv/discussion/307821/tautulli-monitor-your-plex-media-server).
* Support is available on [Discord](https://tautulli.com/discord), [Reddit](https://www.reddit.com/r/Tautulli), or the [Plex Forums](https://forums.plex.tv/t/tautulli-monitor-your-plex-media-server/225242).
## Issues & Feature Requests

View File

@@ -25,7 +25,7 @@ import os
import sys
# Ensure lib added to path, before any other imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib/'))
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'lib'))
import argparse
import locale

View File

@@ -90,7 +90,7 @@ DOCUMENTATION :: END
<td>
<a class="no-highlight support-modal-link" href="${anon_url('https://tautulli.com/discord')}" target="_blank">Tautulli Discord Server</a> |
<a class="no-highlight support-modal-link" href="${anon_url('https://www.reddit.com/r/Tautulli')}" target="_blank">Tautulli Subreddit</a> |
<a class="no-highlight support-modal-link" href="${anon_url('https://forums.plex.tv/discussion/307821/tautulli-monitor-your-plex-media-server')}" target="_blank">Plex Forums</a>
<a class="no-highlight support-modal-link" href="${anon_url('https://forums.plex.tv/t/tautulli-monitor-your-plex-media-server/225242')}" target="_blank">Plex Forums</a>
</td>
</tr>
</tbody>

View File

@@ -70,6 +70,8 @@ div.form-control .selectize-input {
background-color: #555;
border-radius: 3px;
transition: background-color .3s;
}
select.form-control {
height: 32px !important;
}
.react-selectize.root-node .react-selectize-control,

View File

@@ -530,7 +530,7 @@
bw = bw + ' kbps'
}
$('#stream-bandwidth-' + key).html(bw);
};
}
// Update the stream progress times
$('#stream-eta-' + key).html(moment().add(parseInt(s.duration) - parseInt(s.view_offset), 'milliseconds').format(time_format));
@@ -617,7 +617,7 @@
if ($(this).data('state') === 'playing' && $(this).data('view_offset') >= 0) {
var view_offset = parseInt($(this).data('view_offset'));
var stream_duration = parseInt($(this).data('stream_duration'));
var progress_percent = Math.min(Math.trunc(view_offset / stream_duration * 100), 100);
var progress_percent = Math.min(Math.floor(view_offset / stream_duration * 100) || 100, 100);
$(this).width(progress_percent - 3 + '%').html(progress_percent + '%')
.attr('data-original-title', 'Stream Progress ' + progress_percent + '%')
.data('view_offset', Math.min(view_offset + 1000, stream_duration));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -11,7 +11,8 @@
<link href="${http_root}css/pnotify.custom.min.css" rel="stylesheet" />
<link href="${http_root}css/tautulli.css${cache_param}" rel="stylesheet">
<link href="${http_root}css/opensans.min.css" rel="stylesheet">
<link href="${http_root}css/font-awesome.min.css" rel="stylesheet">
<link href="${http_root}css/font-awesome.all.min.css" rel="stylesheet">
<link href="${http_root}css/font-awesome.v4-shims.min.css" rel="stylesheet">
<!-- Favicons -->
<link rel="icon" type="image/png" sizes="32x32" href="${http_root}images/favicon/favicon-32x32.png?v=2.0.5">

View File

@@ -11,7 +11,8 @@
<link href="${http_root}css/bootstrap3/bootstrap.css" rel="stylesheet">
<link href="${http_root}css/tautulli.css${cache_param}" rel="stylesheet">
<link href="${http_root}css/opensans.min.css" rel="stylesheet">
<link href="${http_root}css/font-awesome.min.css" rel="stylesheet">
<link href="${http_root}css/font-awesome.all.min.css" rel="stylesheet">
<link href="${http_root}css/font-awesome.v4-shims.min.css" rel="stylesheet">
</head>
<body>

View File

@@ -17,7 +17,8 @@
<link href="${http_root}css/tautulli.css${cache_param}" rel="stylesheet">
<link href="${http_root}css/selectize.bootstrap3.css" rel="stylesheet">
<link href="${http_root}css/opensans.min.css" rel="stylesheet">
<link href="${http_root}css/font-awesome.min.css" rel="stylesheet">
<link href="${http_root}css/font-awesome.all.min.css" rel="stylesheet">
<link href="${http_root}css/font-awesome.v4-shims.min.css" rel="stylesheet">
<!-- Favicons -->
<link rel="icon" type="image/png" sizes="32x32" href="${http_root}images/favicon/favicon-32x32.png?v=2.0.0">
@@ -153,7 +154,7 @@
<div class="wizard-card" data-cardname="card4">
<h3>Notifications</h3>
<p class="help-block">Tautulli can send a wide variety of notification to alert you of activity on your Plex server.</p>
<p class="help-block">Tautulli can send a wide variety of notifications to alert you of activity on your Plex server.</p>
<p class="help-block">
To set up a notification agent, navigate to the <strong>Settings</strong> page
and to the <strong>Notification Agents</strong> tab after you have completed this setup wizard.

View File

@@ -551,7 +551,7 @@
<tr>
<td class="wrapper" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;box-sizing: border-box;padding: 5px;overflow: auto;">
<div class="header" style="width: 100%;height: 90px;text-align: center;">
<img src="${base_url_image + 'images/newsletter/newsletter-header.png' if base_url_image else 'http://tautulli.com/images/newsletter/newsletter-header.png'}" class="header-img" width="492" height="90" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;width: 492px;height: 90px;margin-left: -35px;">
<img src="${base_url_image + 'images/newsletter/newsletter-header.png' if base_url_image else 'https://tautulli.com/images/newsletter/newsletter-header.png'}" class="header-img" width="492" height="90" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;width: 492px;height: 90px;margin-left: -35px;">
</div>
<div class="server-name" style="font-size: 30px;text-align: center;">${parameters['server_name']}</div>
<div class="dates" style="color: #aaaaaa;font-size: 20px;text-align: center;">${parameters['start_date']} - ${parameters['end_date']}</div>
@@ -570,7 +570,7 @@
<td class="wrapper" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;box-sizing: border-box;padding: 5px;overflow: auto;">
<div class="sub-header-bar" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;width: 200px;border-top: 1px solid #E5A00D;margin-top: 15px;margin-bottom: 25px;"></div>
<div class="sub-header-title" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;font-weight: lighter;">
<img src="${(base_url_image + 'images/libraries/movie.png') if base_url_image else 'http://tautulli.com/images/libraries/movie.png'}" class="sub-header-icon" width="30" height="30" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;height: 30px;width: 30px;vertical-align: middle;margin-right: 5px;margin-bottom: 5px;"> Recently Added Movies
<img src="${(base_url_image + 'images/libraries/movie.png') if base_url_image else 'https://tautulli.com/images/libraries/movie.png'}" class="sub-header-icon" width="30" height="30" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;height: 30px;width: 30px;vertical-align: middle;margin-right: 5px;margin-bottom: 5px;"> Recently Added Movies
</div>
<div class="sub-header-count" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;">
<span class="count" style="color: #E5A00D;">${len(recently_added['movie'])}</span> <span class="count-units" style="color: #aaaaaa;font-size: 20px;text-transform: uppercase;">movie${'s' if len(recently_added['movie']) > 1 else ''}</span>
@@ -598,7 +598,7 @@
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${movie['rating_key']}" title="${movie['title']}" target="_blank" style="text-decoration: underline;">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-poster.png' if base_url_image else 'http://tautulli.com/images/newsletter/view-on-plex-poster.png'}" width="150" height="225" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;display: block;">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-poster.png' if base_url_image else 'https://tautulli.com/images/newsletter/view-on-plex-poster.png'}" width="150" height="225" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;display: block;">
</a>
</td>
</tr>
@@ -688,7 +688,7 @@
<td class="wrapper" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;box-sizing: border-box;padding: 5px;overflow: auto;">
<div class="sub-header-bar" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;width: 200px;border-top: 1px solid #E5A00D;margin-top: 15px;margin-bottom: 25px;"></div>
<div class="sub-header-title" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;font-weight: lighter;">
<img src="${(base_url_image + 'images/libraries/show.png') if base_url_image else 'http://tautulli.com/images/libraries/show.png'}" class="sub-header-icon" width="30" height="30" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;height: 30px;width: 30px;vertical-align: middle;margin-right: 5px;margin-bottom: 5px;"> Recently Added TV Shows
<img src="${(base_url_image + 'images/libraries/show.png') if base_url_image else 'https://tautulli.com/images/libraries/show.png'}" class="sub-header-icon" width="30" height="30" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;height: 30px;width: 30px;vertical-align: middle;margin-right: 5px;margin-bottom: 5px;"> Recently Added TV Shows
</div>
<div class="sub-header-count" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;">
<span class="count" style="color: #E5A00D;">${len(recently_added['show'])}</span> <span class="count-units" style="color: #aaaaaa;font-size: 20px;text-transform: uppercase;">show${'s' if len(recently_added['show']) > 1 else ''}</span> /
@@ -727,7 +727,7 @@
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${link_rating_key}" title="${show['title']}" target="_blank" style="text-decoration: underline;">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-poster.png' if base_url_image else 'http://tautulli.com/images/newsletter/view-on-plex-poster.png'}" width="150" height="225" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;display: block;">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-poster.png' if base_url_image else 'https://tautulli.com/images/newsletter/view-on-plex-poster.png'}" width="150" height="225" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;display: block;">
</a>
</td>
</tr>
@@ -840,7 +840,7 @@
<td class="wrapper" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;box-sizing: border-box;padding: 5px;overflow: auto;">
<div class="sub-header-bar" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;width: 200px;border-top: 1px solid #E5A00D;margin-top: 15px;margin-bottom: 25px;"></div>
<div class="sub-header-title" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;font-weight: lighter;">
<img src="${(base_url_image + 'images/libraries/artist.png') if base_url_image else 'http://tautulli.com/images/libraries/artist.png'}" class="sub-header-icon" width="30" height="30" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;height: 30px;width: 30px;vertical-align: middle;margin-right: 5px;margin-bottom: 5px;"> Recently Added Music
<img src="${(base_url_image + 'images/libraries/artist.png') if base_url_image else 'https://tautulli.com/images/libraries/artist.png'}" class="sub-header-icon" width="30" height="30" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;height: 30px;width: 30px;vertical-align: middle;margin-right: 5px;margin-bottom: 5px;"> Recently Added Music
</div>
<div class="sub-header-count" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;">
<span class="count" style="color: #E5A00D;">${len(recently_added['artist'])}</span> <span class="count-units" style="color: #aaaaaa;font-size: 20px;text-transform: uppercase;">artist${'s' if len(recently_added['artist']) > 1 else ''}</span> /
@@ -870,7 +870,7 @@
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${album['rating_key']}" title="${album['title']}" target="_blank" style="text-decoration: underline;">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-cover.png' if base_url_image else 'http://tautulli.com/images/newsletter/view-on-plex-cover.png'}" width="150" height="150" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;display: block;">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-cover.png' if base_url_image else 'https://tautulli.com/images/newsletter/view-on-plex-cover.png'}" width="150" height="150" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;display: block;">
</a>
</td>
</tr>

View File

@@ -552,7 +552,7 @@
<tr>
<td class="wrapper">
<div class="header">
<img src="${base_url_image + 'images/newsletter/newsletter-header.png' if base_url_image else 'http://tautulli.com/images/newsletter/newsletter-header.png'}" class="header-img" width="492" height="90"/>
<img src="${base_url_image + 'images/newsletter/newsletter-header.png' if base_url_image else 'https://tautulli.com/images/newsletter/newsletter-header.png'}" class="header-img" width="492" height="90"/>
</div>
<div class="server-name">${parameters['server_name']}</div>
<div class="dates">${parameters['start_date']} - ${parameters['end_date']}</div>
@@ -571,7 +571,7 @@
<td class="wrapper">
<div class="sub-header-bar"></div>
<div class="sub-header-title">
<img src="${(base_url_image + 'images/libraries/movie.png') if base_url_image else 'http://tautulli.com/images/libraries/movie.png'}" class="sub-header-icon" width="30" height="30"/> Recently Added Movies
<img src="${(base_url_image + 'images/libraries/movie.png') if base_url_image else 'https://tautulli.com/images/libraries/movie.png'}" class="sub-header-icon" width="30" height="30"/> Recently Added Movies
</div>
<div class="sub-header-count">
<span class="count">${len(recently_added['movie'])}</span> <span class="count-units">movie${'s' if len(recently_added['movie']) > 1 else ''}</span>
@@ -599,7 +599,7 @@
<tr>
<td>
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${movie['rating_key']}" title="${movie['title']}" target="_blank">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-poster.png' if base_url_image else 'http://tautulli.com/images/newsletter/view-on-plex-poster.png'}" width="150" height="225">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-poster.png' if base_url_image else 'https://tautulli.com/images/newsletter/view-on-plex-poster.png'}" width="150" height="225">
</a>
</td>
</tr>
@@ -689,7 +689,7 @@
<td class="wrapper">
<div class="sub-header-bar"></div>
<div class="sub-header-title">
<img src="${(base_url_image + 'images/libraries/show.png') if base_url_image else 'http://tautulli.com/images/libraries/show.png'}" class="sub-header-icon" width="30" height="30"/> Recently Added TV Shows
<img src="${(base_url_image + 'images/libraries/show.png') if base_url_image else 'https://tautulli.com/images/libraries/show.png'}" class="sub-header-icon" width="30" height="30"/> Recently Added TV Shows
</div>
<div class="sub-header-count">
<span class="count">${len(recently_added['show'])}</span> <span class="count-units">show${'s' if len(recently_added['show']) > 1 else ''}</span> /
@@ -728,7 +728,7 @@
<tr>
<td>
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${link_rating_key}" title="${show['title']}" target="_blank">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-poster.png' if base_url_image else 'http://tautulli.com/images/newsletter/view-on-plex-poster.png'}" width="150" height="225">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-poster.png' if base_url_image else 'https://tautulli.com/images/newsletter/view-on-plex-poster.png'}" width="150" height="225">
</a>
</td>
</tr>
@@ -841,7 +841,7 @@
<td class="wrapper">
<div class="sub-header-bar"></div>
<div class="sub-header-title">
<img src="${(base_url_image + 'images/libraries/artist.png') if base_url_image else 'http://tautulli.com/images/libraries/artist.png'}" class="sub-header-icon" width="30" height="30"/> Recently Added Music
<img src="${(base_url_image + 'images/libraries/artist.png') if base_url_image else 'https://tautulli.com/images/libraries/artist.png'}" class="sub-header-icon" width="30" height="30"/> Recently Added Music
</div>
<div class="sub-header-count">
<span class="count">${len(recently_added['artist'])}</span> <span class="count-units">artist${'s' if len(recently_added['artist']) > 1 else ''}</span> /
@@ -871,7 +871,7 @@
<tr>
<td>
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${album['rating_key']}" title="${album['title']}" target="_blank">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-cover.png' if base_url_image else 'http://tautulli.com/images/newsletter/view-on-plex-cover.png'}" width="150" height="150">
<img class="card-poster-overlay" src="${base_url_image + 'images/newsletter/view-on-plex-cover.png' if base_url_image else 'https://tautulli.com/images/newsletter/view-on-plex-cover.png'}" width="150" height="150">
</a>
</td>
</tr>

View File

@@ -88,6 +88,7 @@ PLATFORM_NAMES = {
'samsung': 'samsung',
'synclounge': 'synclounge',
'tivo': 'tivo',
'tizen': 'samsung',
'tvos': 'atv',
'vizio': 'opera',
'wiiu': 'wiiu',

View File

@@ -660,8 +660,7 @@ class DataFactory(object):
platform = common.PLATFORM_NAME_OVERRIDES.get(item['platform'], item['platform'])
platform_name = next((v for k, v in common.PLATFORM_NAMES.iteritems() if k in platform.lower()), 'default')
row = {'platform': item['platform'],
'total_plays': item['total_plays'],
row = {'total_plays': item['total_plays'],
'total_duration': item['total_duration'],
'last_play': item['last_watch'],
'platform': platform,

View File

@@ -698,7 +698,7 @@ class Graphs(object):
try:
if y_axis == 'plays':
query = 'SELECT session_history_media_info.video_resolution AS resolution, ' \
query = 'SELECT UPPER(session_history_media_info.video_resolution) AS resolution, ' \
'SUM(CASE WHEN session_history_media_info.transcode_decision = "direct play" ' \
'THEN 1 ELSE 0 END) AS dp_count, ' \
'SUM(CASE WHEN session_history_media_info.transcode_decision = "copy" ' \
@@ -717,7 +717,7 @@ class Graphs(object):
result = monitor_db.select(query)
else:
query = 'SELECT session_history_media_info.video_resolution AS resolution,' \
query = 'SELECT UPPER(session_history_media_info.video_resolution) AS resolution,' \
'SUM(CASE WHEN session_history_media_info.transcode_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_count, ' \
@@ -799,8 +799,8 @@ 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) ' \
'ELSE session_history_media_info.stream_video_resolution END) AS resolution, ' \
'ELSE "unknown" END) ELSE UPPER(session_history_media_info.video_resolution) END) ' \
'ELSE UPPER(session_history_media_info.stream_video_resolution) END) AS resolution, ' \
'SUM(CASE WHEN session_history_media_info.transcode_decision = "direct play" ' \
'THEN 1 ELSE 0 END) AS dp_count, ' \
'SUM(CASE WHEN session_history_media_info.transcode_decision = "copy" ' \
@@ -830,8 +830,8 @@ 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) ' \
'ELSE session_history_media_info.stream_video_resolution END) AS resolution, ' \
'ELSE "unknown" END) ELSE UPPER(session_history_media_info.video_resolution) END) ' \
'ELSE UPPER(session_history_media_info.stream_video_resolution) END) AS resolution, ' \
'SUM(CASE WHEN session_history_media_info.transcode_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_count, ' \

View File

@@ -1083,6 +1083,8 @@ def get_plexpy_url(hostname=None):
if not hostname:
hostname = 'localhost'
elif hostname == 'localhost' and plexpy.CONFIG.HTTP_HOST != '0.0.0.0':
hostname = plexpy.CONFIG.HTTP_HOST
else:
hostname = hostname or plexpy.CONFIG.HTTP_HOST

View File

@@ -338,6 +338,12 @@ def notify(notifier_id=None, notify_action=None, stream_data=None, timeline_data
subject = kwargs.pop('subject', 'Tautulli')
body = kwargs.pop('body', 'Test Notification')
script_args = kwargs.pop('script_args', [])
if script_args and isinstance(script_args, basestring):
# Attemps to format test script args for the user
script_args = [arg.decode(plexpy.SYS_ENCODING, 'ignore')
for arg in shlex.split(script_args.encode(plexpy.SYS_ENCODING, 'ignore'))]
else:
# Get the subject and body strings
subject_string = notifier_config['notify_text'][notify_action]['subject']
@@ -1028,7 +1034,8 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
if agent_id == 15:
try:
script_args = [custom_formatter.format(unicode(arg), **parameters) for arg in shlex.split(subject)]
script_args = [custom_formatter.format(arg, **parameters).decode(plexpy.SYS_ENCODING, 'ignore')
for arg in shlex.split(subject.encode(plexpy.SYS_ENCODING, 'ignore'))]
except LookupError as e:
logger.error(u"Tautulli NotificationHandler :: Unable to parse parameter %s in script argument. Using fallback." % e)
script_args = []

View File

@@ -23,9 +23,9 @@ from paho.mqtt.publish import single
import os
import re
import requests
import shlex
import smtplib
import subprocess
import sys
import threading
import time
from urllib import urlencode
@@ -2993,12 +2993,15 @@ class SCRIPTS(Notifier):
def run_script(self, script):
# Common environment variables
env = {'PLEX_URL': plexpy.CONFIG.PMS_URL,
env = os.environ.copy()
env.update({
'PLEX_URL': plexpy.CONFIG.PMS_URL,
'PLEX_TOKEN': plexpy.CONFIG.PMS_TOKEN,
'TAUTULLI_URL': helpers.get_plexpy_url(hostname='localhost'),
'TAUTULLI_APIKEY': plexpy.CONFIG.API_KEY
}
env.update(os.environ)
'TAUTULLI_APIKEY': plexpy.CONFIG.API_KEY,
'TAUTULLI_ENCODING': plexpy.SYS_ENCODING,
'PYTHONPATH': (';' if os.name == 'nt' else ':').join(sys.path)
})
try:
process = subprocess.Popen(script,
@@ -3028,12 +3031,11 @@ class SCRIPTS(Notifier):
if error:
err = '\n '.join([l for l in error.splitlines()])
logger.error(u"Tautulli Notifiers :: Script error: \n %s" % err)
return False
logger.error("Tautulli Notifiers :: Script error: \n %s" % err)
if output:
out = '\n '.join([l for l in output.splitlines()])
logger.debug(u"Tautulli Notifiers :: Script returned: \n %s" % out)
logger.debug("Tautulli Notifiers :: Script returned: \n %s" % out)
if not self.script_killed:
logger.info(u"Tautulli Notifiers :: Script notification sent.")
@@ -3083,14 +3085,14 @@ class SCRIPTS(Notifier):
script = [script]
# For manual notifications
if script_args and isinstance(script_args, basestring):
# attemps for format it for the user
script_args = shlex.split(script_args)
# if script_args and isinstance(script_args, basestring):
# # attemps for format it for the user
# script_args = [arg for arg in shlex.split(script_args.encode(plexpy.SYS_ENCODING, 'ignore'))]
# Windows handles unicode very badly.
# https://bugs.python.org/issue19264
if script_args and os.name == 'nt':
script_args = [s.encode(plexpy.SYS_ENCODING, 'ignore') for s in script_args]
if script_args: # and os.name == 'nt':
script_args = [arg.encode(plexpy.SYS_ENCODING, 'ignore') for arg in script_args]
# Allow overrides for shitty systems
if prefix and script_args:

View File

@@ -355,8 +355,8 @@ class PlexTV(object):
"username": helpers.get_xml_attr(a, 'username'),
"thumb": helpers.get_xml_attr(a, 'thumb'),
"email": helpers.get_xml_attr(a, 'email'),
"is_home_user": helpers.get_xml_attr(a, 'home'),
"is_admin": 1,
"is_home_user": helpers.get_xml_attr(a, 'home'),
"is_allow_sync": 1,
"is_restricted": helpers.get_xml_attr(a, 'restricted'),
"filter_all": helpers.get_xml_attr(a, 'filterAll'),

View File

@@ -1934,7 +1934,7 @@ class PmsConnect(object):
Output: bool
"""
message = message or 'The server owner has ended the stream.'
message = message.encode('utf-8') or 'The server owner has ended the stream.'
if session_key and not session_id:
ap = activity_processor.ActivityProcessor()

View File

@@ -579,7 +579,11 @@ class Users(object):
monitor_db = database.MonitorDatabase()
try:
query = 'SELECT user_id, username, friendly_name, email FROM users WHERE deleted_user = 0'
query = 'SELECT user_id, username, friendly_name, thumb, custom_avatar_url, email, ' \
'is_admin, is_home_user, is_allow_sync, is_restricted, ' \
'do_notify, keep_history, allow_guest, server_token, shared_libraries, ' \
'filter_all, filter_movies, filter_tv, filter_music, filter_photos ' \
'FROM users WHERE deleted_user = 0'
result = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"Tautulli Users :: Unable to execute database query for get_users: %s." % e)
@@ -590,7 +594,22 @@ class Users(object):
user = {'user_id': item['user_id'],
'username': item['username'],
'friendly_name': item['friendly_name'] or item['username'],
'email': item['email']
'thumb': item['custom_avatar_url'] or item['thumb'],
'email': item['email'],
'is_admin': item['is_admin'],
'is_home_user': item['is_home_user'],
'is_allow_sync': item['is_allow_sync'],
'is_restricted': item['is_restricted'],
'do_notify': item['do_notify'],
'keep_history': item['keep_history'],
'allow_guest': item['allow_guest'],
'server_token': item['server_token'],
'shared_libraries': item['shared_libraries'],
'filter_all': item['filter_all'],
'filter_movies': item['filter_movies'],
'filter_tv': item['filter_tv'],
'filter_music': item['filter_music'],
'filter_photos': item['filter_photos'],
}
users.append(user)

View File

@@ -1,2 +1,2 @@
PLEXPY_BRANCH = "master"
PLEXPY_RELEASE_VERSION = "v2.1.14"
PLEXPY_BRANCH = "beta"
PLEXPY_RELEASE_VERSION = "v2.1.15-beta"

View File

@@ -5214,15 +5214,21 @@ class WebInterface(object):
Returns:
json:
[{"email": "Jon.Snow.1337@CastleBlack.com",
[{"allow_guest": 1,
"do_notify": 1,
"email": "Jon.Snow.1337@CastleBlack.com",
"filter_all": "",
"filter_movies": "",
"filter_music": "",
"filter_photos": "",
"filter_tv": "",
"is_allow_sync": null,
"is_home_user": "1",
"is_restricted": "0",
"is_admin": 0,
"is_allow_sync": 1,
"is_home_user": 1,
"is_restricted": 0,
"keep_history": 1,
"server_token": "PU9cMuQZxJKFBtGqHk68",
"shared_libraries": "1;2;3",
"thumb": "https://plex.tv/users/k10w42309cynaopq/avatar",
"user_id": "133788",
"username": "Jon Snow"
@@ -5232,8 +5238,8 @@ class WebInterface(object):
]
```
"""
plex_tv = plextv.PlexTV()
result = plex_tv.get_full_users_list()
user_data = users.Users()
result = user_data.get_users()
if result:
return result