Compare commits
14 Commits
v2.1.10-be
...
v2.1.11-be
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c19cc858bd | ||
![]() |
668913fd60 | ||
![]() |
50c5407a46 | ||
![]() |
939755d3b7 | ||
![]() |
54f4696713 | ||
![]() |
c85af521fe | ||
![]() |
917d19db85 | ||
![]() |
7292f25eb9 | ||
![]() |
22a2ad4bc7 | ||
![]() |
95e56f5ea5 | ||
![]() |
ed24232a0a | ||
![]() |
15225faee7 | ||
![]() |
041a35a35a | ||
![]() |
6d365c174a |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v2.1.11-beta (2018-06-02)
|
||||||
|
|
||||||
|
* Monitoring:
|
||||||
|
* Fix: Activity progress bar not updating in some cases.
|
||||||
|
* Fix: Monitory Remote Access setting disabled due to Plex Media Server API changes.
|
||||||
|
* Change: Improved logic for grouping history items without being successive plays.
|
||||||
|
* Notifications:
|
||||||
|
* New: Added filename to notification parameters.
|
||||||
|
* Other:
|
||||||
|
* Fix: Update metadata failing for tracks without track numbers.
|
||||||
|
|
||||||
|
|
||||||
## v2.1.10-beta (2018-05-28)
|
## v2.1.10-beta (2018-05-28)
|
||||||
|
|
||||||
* Monitoring:
|
* Monitoring:
|
||||||
|
@@ -292,6 +292,7 @@ ${next.modalIncludes()}
|
|||||||
<script src="${http_root}js/pnotify.custom.min.js"></script>
|
<script src="${http_root}js/pnotify.custom.min.js"></script>
|
||||||
<script src="${http_root}js/script.js${cache_param}"></script>
|
<script src="${http_root}js/script.js${cache_param}"></script>
|
||||||
<script src="${http_root}js/jquery.qrcode.min.js"></script>
|
<script src="${http_root}js/jquery.qrcode.min.js"></script>
|
||||||
|
<script src="${http_root}js/jquery.tripleclick.min.js"></script>
|
||||||
% if _session['user_group'] == 'admin' and BROWSER_NOTIFIERS:
|
% if _session['user_group'] == 'admin' and BROWSER_NOTIFIERS:
|
||||||
<script src="${http_root}js/ajaxNotifications.js"></script>
|
<script src="${http_root}js/ajaxNotifications.js"></script>
|
||||||
% endif
|
% endif
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="padded-header" id="current-activity-header">
|
<div class="padded-header" id="current-activity-header">
|
||||||
<h3><span id="sessions-shortcut">Activity</span>
|
<h3><span id="sessions-xml">Activity</span>
|
||||||
<small>
|
<small>
|
||||||
<span id="currentActivityHeader" style="display: none;">
|
<span id="currentActivityHeader" style="display: none;">
|
||||||
Streams: <span id="currentActivityHeader-streams"></span> |
|
Streams: <span id="currentActivityHeader-streams"></span> |
|
||||||
@@ -236,7 +236,6 @@
|
|||||||
<script src="${http_root}js/moment-with-locale.js"></script>
|
<script src="${http_root}js/moment-with-locale.js"></script>
|
||||||
<script src="${http_root}js/jquery.scrollbar.min.js"></script>
|
<script src="${http_root}js/jquery.scrollbar.min.js"></script>
|
||||||
<script src="${http_root}js/jquery.mousewheel.min.js"></script>
|
<script src="${http_root}js/jquery.mousewheel.min.js"></script>
|
||||||
<script src="${http_root}js/jquery.tripleclick.min.js"></script>
|
|
||||||
<script>
|
<script>
|
||||||
var date_format = 'YYYY-MM-DD';
|
var date_format = 'YYYY-MM-DD';
|
||||||
var time_format = 'hh:mm a';
|
var time_format = 'hh:mm a';
|
||||||
@@ -546,7 +545,7 @@
|
|||||||
.attr('data-original-title', 'Transcoder Progress ' + s.transcode_progress + '%');
|
.attr('data-original-title', 'Transcoder Progress ' + s.transcode_progress + '%');
|
||||||
var progress_bar = $('#progress-bar-' + key);
|
var progress_bar = $('#progress-bar-' + key);
|
||||||
progress_bar.data('state', s.state);
|
progress_bar.data('state', s.state);
|
||||||
if (progress_bar.data('last_view_offset') && progress_bar.data('last_view_offset') !== s.view_offset) {
|
if (progress_bar.data('last_view_offset') !== s.view_offset) {
|
||||||
progress_bar.data('last_view_offset', s.view_offset).data('view_offset', s.view_offset);
|
progress_bar.data('last_view_offset', s.view_offset).data('view_offset', s.view_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,10 +693,8 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#sessions-shortcut').on('tripleclick', function () {
|
$('#sessions-xml').on('tripleclick', function () {
|
||||||
$.getJSON('return_sessions_url', function(sessions_url) {
|
openPlexXML('/status/sessions');
|
||||||
window.open(sessions_url, '_blank');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
% endif
|
% endif
|
||||||
</script>
|
</script>
|
||||||
|
@@ -83,31 +83,31 @@ DOCUMENTATION :: END
|
|||||||
<ul class="list-unstyled breadcrumb">
|
<ul class="list-unstyled breadcrumb">
|
||||||
% if data['media_type'] in ('movie', 'collection'):
|
% if data['media_type'] in ('movie', 'collection'):
|
||||||
<li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
<li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||||
<li class="active">${data['title']}</li>
|
<li class="active metadata-xml">${data['title']}</li>
|
||||||
% elif data['media_type'] == 'show':
|
% elif data['media_type'] == 'show':
|
||||||
<li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
<li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||||
<li class="active">${data['title']}</li>
|
<li class="active metadata-xml">${data['title']}</li>
|
||||||
% elif data['media_type'] == 'season':
|
% elif data['media_type'] == 'season':
|
||||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||||
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
||||||
<li class="active">Season ${data['media_index']}</li>
|
<li class="active metadata-xml">Season ${data['media_index']}</li>
|
||||||
% elif data['media_type'] == 'episode':
|
% elif data['media_type'] == 'episode':
|
||||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||||
<li class="hidden-xs hidden-sm"><a href="info?rating_key=${data['grandparent_rating_key']}">${data['grandparent_title']}</a></li>
|
<li class="hidden-xs hidden-sm"><a href="info?rating_key=${data['grandparent_rating_key']}">${data['grandparent_title']}</a></li>
|
||||||
<li><a href="info?rating_key=${data['parent_rating_key']}">Season ${data['parent_media_index']}</a></li>
|
<li><a href="info?rating_key=${data['parent_rating_key']}">Season ${data['parent_media_index']}</a></li>
|
||||||
<li class="active">Episode ${data['media_index']} - ${data['title']}</li>
|
<li class="active metadata-xml">Episode ${data['media_index']} - ${data['title']}</li>
|
||||||
% elif data['media_type'] == 'artist':
|
% elif data['media_type'] == 'artist':
|
||||||
<li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
<li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||||
<li class="active">${data['title']}</li>
|
<li class="active metadata-xml">${data['title']}</li>
|
||||||
% elif data['media_type'] == 'album':
|
% elif data['media_type'] == 'album':
|
||||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||||
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
||||||
<li class="active">${data['title']}</li>
|
<li class="active metadata-xml">${data['title']}</li>
|
||||||
% elif data['media_type'] == 'track':
|
% elif data['media_type'] == 'track':
|
||||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||||
<li class="hidden-xs hidden-sm"><a href="info?rating_key=${data['grandparent_rating_key']}">${data['grandparent_title']}</a></li>
|
<li class="hidden-xs hidden-sm"><a href="info?rating_key=${data['grandparent_rating_key']}">${data['grandparent_title']}</a></li>
|
||||||
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
||||||
<li class="active">Track ${data['media_index']} - ${data['title']}</li>
|
<li class="active metadata-xml">Track ${data['media_index']} - ${data['title']}</li>
|
||||||
% endif
|
% endif
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -703,6 +703,10 @@ DOCUMENTATION :: END
|
|||||||
</script>
|
</script>
|
||||||
% endif
|
% endif
|
||||||
<script>
|
<script>
|
||||||
|
$('.metadata-xml').on('tripleclick', function () {
|
||||||
|
openPlexXML("/library/metadata/${data['rating_key']}");
|
||||||
|
});
|
||||||
|
|
||||||
$("#airdate").html(moment($("#airdate").text()).format('MMM DD, YYYY'));
|
$("#airdate").html(moment($("#airdate").text()).format('MMM DD, YYYY'));
|
||||||
$("#runtime").html(millisecondsToMinutes($("#runtime").text(), true));
|
$("#runtime").html(millisecondsToMinutes($("#runtime").text(), true));
|
||||||
$('div.art-face').animate({ opacity: 0.2 }, { duration: 1000 });
|
$('div.art-face').animate({ opacity: 0.2 }, { duration: 1000 });
|
||||||
|
@@ -457,4 +457,11 @@ function capitalizeFirstLetter(string) {
|
|||||||
|
|
||||||
$.fn.slideToggleBool = function(bool, options) {
|
$.fn.slideToggleBool = function(bool, options) {
|
||||||
return bool ? $(this).slideDown(options) : $(this).slideUp(options);
|
return bool ? $(this).slideDown(options) : $(this).slideUp(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function openPlexXML(endpoint, plextv, params) {
|
||||||
|
var data = $.extend({endpoint: endpoint, plextv: plextv}, params);
|
||||||
|
$.getJSON('return_plex_xml_url', data, function(xml_url) {
|
||||||
|
window.open(xml_url, '_blank');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
<div class='container-fluid'>
|
<div class='container-fluid'>
|
||||||
<div class='table-card-header'>
|
<div class='table-card-header'>
|
||||||
<div class="header-bar">
|
<div class="header-bar">
|
||||||
<span><i class="fa fa-book"></i> All Libraries</span>
|
<span id="libraries-xml"><i class="fa fa-book"></i> All Libraries</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-bar">
|
<div class="button-bar">
|
||||||
% if _session['user_group'] == 'admin':
|
% if _session['user_group'] == 'admin':
|
||||||
@@ -198,5 +198,9 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
$('#libraries-xml').on('tripleclick', function () {
|
||||||
|
openPlexXML('/library/sections/all');
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</%def>
|
</%def>
|
||||||
|
@@ -115,9 +115,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="checkbox advanced-setting">
|
<div class="checkbox advanced-setting">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="group_history_tables" name="group_history_tables" value="1" ${config['group_history_tables']}> Group Successive Play History
|
<input type="checkbox" id="group_history_tables" name="group_history_tables" value="1" ${config['group_history_tables']}> Group Play History
|
||||||
</label>
|
</label>
|
||||||
<p class="help-block">Group successive play history by the same user as a single entry in the watch statistics, tables, and graphs.</p>
|
<p class="help-block">Group play history for the same item and user as a single entry when progress is less than the watched percent.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox advanced-setting">
|
<div class="checkbox advanced-setting">
|
||||||
<label>
|
<label>
|
||||||
@@ -646,7 +646,7 @@
|
|||||||
<div role="tabpanel" class="tab-pane" id="tabs-plex_media_server">
|
<div role="tabpanel" class="tab-pane" id="tabs-plex_media_server">
|
||||||
|
|
||||||
<div class="padded-header">
|
<div class="padded-header">
|
||||||
<h3>Plex Media Server <small style="color: #fff;">Version <span id="pms_version">${config['pms_version']}</span></small></h3>
|
<h3 id="resources-xml">Plex Media Server <small style="color: #fff;">Version <span id="pms_version">${config['pms_version']}</span></small></h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group has-feedback" id="pms_ip_group">
|
<div class="form-group has-feedback" id="pms_ip_group">
|
||||||
@@ -2358,7 +2358,7 @@ $(document).ready(function() {
|
|||||||
data: { pref: 'PublishServerOnPlexOnlineKey' },
|
data: { pref: 'PublishServerOnPlexOnlineKey' },
|
||||||
async: true,
|
async: true,
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
if (data !== 'true') {
|
if (data === 'false' || data === '0') {
|
||||||
$("#remoteAccessCheck").html("Remote access must be enabled on your Plex Server. <a target='_blank' href='${anon_url('https://support.plex.tv/hc/en-us/articles/200484543-Enabling-Remote-Access-for-a-Server')}'>Click here</a> for help.");
|
$("#remoteAccessCheck").html("Remote access must be enabled on your Plex Server. <a target='_blank' href='${anon_url('https://support.plex.tv/hc/en-us/articles/200484543-Enabling-Remote-Access-for-a-Server')}'>Click here</a> for help.");
|
||||||
$("#monitor_remote_access").attr("checked", false).attr("disabled", true);
|
$("#monitor_remote_access").attr("checked", false).attr("disabled", true);
|
||||||
}
|
}
|
||||||
@@ -2753,6 +2753,10 @@ $(document).ready(function() {
|
|||||||
body_container.animate({scrollTop: scroll_pos});
|
body_container.animate({scrollTop: scroll_pos});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#resources-xml').on('tripleclick', function () {
|
||||||
|
openPlexXML('/api/resources', true, {includeHttps: 1});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</%def>
|
</%def>
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
<div class='container-fluid'>
|
<div class='container-fluid'>
|
||||||
<div class='table-card-header'>
|
<div class='table-card-header'>
|
||||||
<div class="header-bar">
|
<div class="header-bar">
|
||||||
<span><i class="fa fa-cloud-download"></i> Synced Items</span>
|
<span id="sync-xml"><i class="fa fa-cloud-download"></i> Synced Items</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-bar">
|
<div class="button-bar">
|
||||||
% if _session['user_group'] == 'admin':
|
% if _session['user_group'] == 'admin':
|
||||||
@@ -185,5 +185,9 @@
|
|||||||
$("#refresh-syncs-list").click(function() {
|
$("#refresh-syncs-list").click(function() {
|
||||||
sync_table.ajax.reload();
|
sync_table.ajax.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#sync-xml').on('tripleclick', function () {
|
||||||
|
openPlexXML('/servers/{machine_id}/sync_lists', true);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</%def>
|
</%def>
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
<div class='container-fluid'>
|
<div class='container-fluid'>
|
||||||
<div class='table-card-header'>
|
<div class='table-card-header'>
|
||||||
<div class="header-bar">
|
<div class="header-bar">
|
||||||
<span><i class="fa fa-group"></i> All Users</span>
|
<span id="users-xml"><i class="fa fa-group"></i> All Users</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-bar">
|
<div class="button-bar">
|
||||||
% if _session['user_group'] == 'admin':
|
% if _session['user_group'] == 'admin':
|
||||||
@@ -202,5 +202,9 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
$('#users-xml').on('tripleclick', function () {
|
||||||
|
openPlexXML('/api/users', true);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</%def>
|
</%def>
|
@@ -15,18 +15,13 @@
|
|||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import json
|
import json
|
||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
import re
|
|
||||||
|
|
||||||
import plexpy
|
import plexpy
|
||||||
import database
|
import database
|
||||||
import datafactory
|
import helpers
|
||||||
import libraries
|
import libraries
|
||||||
import log_reader
|
|
||||||
import logger
|
import logger
|
||||||
import notification_handler
|
|
||||||
import notifiers
|
|
||||||
import pmsconnect
|
import pmsconnect
|
||||||
import users
|
import users
|
||||||
|
|
||||||
@@ -272,14 +267,15 @@ class ActivityProcessor(object):
|
|||||||
self.db.upsert(table_name='session_history', key_dict=keys, value_dict=values)
|
self.db.upsert(table_name='session_history', key_dict=keys, value_dict=values)
|
||||||
|
|
||||||
# Check if we should group the session, select the last two rows from the user
|
# Check if we should group the session, select the last two rows from the user
|
||||||
query = 'SELECT id, rating_key, view_offset, user_id, reference_id FROM session_history \
|
query = 'SELECT id, rating_key, view_offset, user_id, reference_id FROM session_history ' \
|
||||||
WHERE user_id = ? ORDER BY id DESC LIMIT 2 '
|
'WHERE user_id = ? AND rating_key = ? ORDER BY id DESC LIMIT 2 '
|
||||||
|
|
||||||
args = [session['user_id']]
|
args = [session['user_id'], session['rating_key']]
|
||||||
|
|
||||||
result = self.db.select(query=query, args=args)
|
result = self.db.select(query=query, args=args)
|
||||||
|
|
||||||
new_session = prev_session = None
|
new_session = prev_session = None
|
||||||
|
prev_progress_percent = media_watched_percent = 0
|
||||||
# Get the last insert row id
|
# Get the last insert row id
|
||||||
last_id = self.db.last_insert_id()
|
last_id = self.db.last_insert_id()
|
||||||
|
|
||||||
@@ -296,11 +292,23 @@ class ActivityProcessor(object):
|
|||||||
'user_id': result[1]['user_id'],
|
'user_id': result[1]['user_id'],
|
||||||
'reference_id': result[1]['reference_id']}
|
'reference_id': result[1]['reference_id']}
|
||||||
|
|
||||||
|
watched_percent = {'movie': plexpy.CONFIG.MOVIE_WATCHED_PERCENT,
|
||||||
|
'episode': plexpy.CONFIG.TV_WATCHED_PERCENT,
|
||||||
|
'track': plexpy.CONFIG.MUSIC_WATCHED_PERCENT
|
||||||
|
}
|
||||||
|
prev_progress_percent = helpers.get_percent(prev_session['view_offset'], session['duration'])
|
||||||
|
media_watched_percent = watched_percent.get(session['media_type'], 0)
|
||||||
|
|
||||||
query = 'UPDATE session_history SET reference_id = ? WHERE id = ? '
|
query = 'UPDATE session_history SET reference_id = ? WHERE id = ? '
|
||||||
# If rating_key is the same in the previous session, then set the reference_id to the previous row, else set the reference_id to the new id
|
|
||||||
|
# If previous session view offset less than watched percent,
|
||||||
|
# and new session view offset is greater,
|
||||||
|
# then set the reference_id to the previous row,
|
||||||
|
# else set the reference_id to the new id
|
||||||
if prev_session is None and new_session is None:
|
if prev_session is None and new_session is None:
|
||||||
args = [last_id, last_id]
|
args = [last_id, last_id]
|
||||||
elif prev_session['rating_key'] == new_session['rating_key'] and prev_session['view_offset'] <= new_session['view_offset']:
|
elif prev_progress_percent < media_watched_percent and \
|
||||||
|
prev_session['view_offset'] <= new_session['view_offset']:
|
||||||
args = [prev_session['reference_id'], new_session['id']]
|
args = [prev_session['reference_id'], new_session['id']]
|
||||||
else:
|
else:
|
||||||
args = [new_session['id'], new_session['id']]
|
args = [new_session['id'], new_session['id']]
|
||||||
|
@@ -23,6 +23,7 @@ PLATFORM = platform.system()
|
|||||||
PLATFORM_RELEASE = platform.release()
|
PLATFORM_RELEASE = platform.release()
|
||||||
PLATFORM_VERSION = platform.version()
|
PLATFORM_VERSION = platform.version()
|
||||||
PLATFORM_LINUX_DISTRO = ' '.join(x for x in platform.linux_distribution() if x)
|
PLATFORM_LINUX_DISTRO = ' '.join(x for x in platform.linux_distribution() if x)
|
||||||
|
PLATFORM_DEVICE_NAME = platform.node()
|
||||||
BRANCH = version.PLEXPY_BRANCH
|
BRANCH = version.PLEXPY_BRANCH
|
||||||
RELEASE = version.PLEXPY_RELEASE_VERSION
|
RELEASE = version.PLEXPY_RELEASE_VERSION
|
||||||
|
|
||||||
@@ -475,6 +476,7 @@ NOTIFICATION_PARAMETERS = [
|
|||||||
{'name': 'Subtitle Language', 'type': 'str', 'value': 'subtitle_language', 'description': 'The subtitle language of the original media.'},
|
{'name': 'Subtitle Language', 'type': 'str', 'value': 'subtitle_language', 'description': 'The subtitle language of the original media.'},
|
||||||
{'name': 'Subtitle Language Code', 'type': 'str', 'value': 'subtitle_language_code', 'description': 'The subtitle language code of the original media.'},
|
{'name': 'Subtitle Language Code', 'type': 'str', 'value': 'subtitle_language_code', 'description': 'The subtitle language code of the original media.'},
|
||||||
{'name': 'File', 'type': 'str', 'value': 'file', 'description': 'The file path to the item.'},
|
{'name': 'File', 'type': 'str', 'value': 'file', 'description': 'The file path to the item.'},
|
||||||
|
{'name': 'Filename', 'type': 'str', 'value': 'filename', 'description': 'The file name of the item.'},
|
||||||
{'name': 'File Size', 'type': 'int', 'value': 'file_size', 'description': 'The file size of the item.'},
|
{'name': 'File Size', 'type': 'int', 'value': 'file_size', 'description': 'The file size of the item.'},
|
||||||
{'name': 'Section ID', 'type': 'int', 'value': 'section_id', 'description': 'The unique identifier for the library.'},
|
{'name': 'Section ID', 'type': 'int', 'value': 'section_id', 'description': 'The unique identifier for the library.'},
|
||||||
{'name': 'Rating Key', 'type': 'int', 'value': 'rating_key', 'description': 'The unique identifier for the movie, episode, or track.'},
|
{'name': 'Rating Key', 'type': 'int', 'value': 'rating_key', 'description': 'The unique identifier for the movie, episode, or track.'},
|
||||||
|
@@ -54,6 +54,7 @@ _CONFIG_DEFINITIONS = {
|
|||||||
'PMS_TOKEN': (str, 'PMS', ''),
|
'PMS_TOKEN': (str, 'PMS', ''),
|
||||||
'PMS_SSL': (int, 'PMS', 0),
|
'PMS_SSL': (int, 'PMS', 0),
|
||||||
'PMS_URL': (str, 'PMS', ''),
|
'PMS_URL': (str, 'PMS', ''),
|
||||||
|
'PMS_URL_OVERRIDE': (str, 'PMS', ''),
|
||||||
'PMS_URL_MANUAL': (int, 'PMS', 0),
|
'PMS_URL_MANUAL': (int, 'PMS', 0),
|
||||||
'PMS_USE_BIF': (int, 'PMS', 0),
|
'PMS_USE_BIF': (int, 'PMS', 0),
|
||||||
'PMS_UUID': (str, 'PMS', ''),
|
'PMS_UUID': (str, 'PMS', ''),
|
||||||
|
@@ -65,7 +65,7 @@ class DataFactory(object):
|
|||||||
columns = [
|
columns = [
|
||||||
'session_history.reference_id',
|
'session_history.reference_id',
|
||||||
'session_history.id',
|
'session_history.id',
|
||||||
'started AS date',
|
'MAX(started) AS date',
|
||||||
'MIN(started) AS started',
|
'MIN(started) AS started',
|
||||||
'MAX(stopped) AS stopped',
|
'MAX(stopped) AS stopped',
|
||||||
'SUM(CASE WHEN stopped > 0 THEN (stopped - started) ELSE 0 END) - \
|
'SUM(CASE WHEN stopped > 0 THEN (stopped - started) ELSE 0 END) - \
|
||||||
@@ -1467,7 +1467,7 @@ class DataFactory(object):
|
|||||||
result = monitor_db.select(query=query.format('parent_rating_key', 'rating_key'),
|
result = monitor_db.select(query=query.format('parent_rating_key', 'rating_key'),
|
||||||
args=[item['parent_rating_key']])
|
args=[item['parent_rating_key']])
|
||||||
for item in result:
|
for item in result:
|
||||||
key = item['media_index']
|
key = item['media_index'] if item['media_index'] else item['title']
|
||||||
children.update({key: {'rating_key': item['rating_key']}})
|
children.update({key: {'rating_key': item['rating_key']}})
|
||||||
|
|
||||||
key = item['parent_media_index'] if match_type == 'index' else item['parent_title']
|
key = item['parent_media_index'] if match_type == 'index' else item['parent_title']
|
||||||
|
@@ -39,12 +39,13 @@ class HTTPHandler(object):
|
|||||||
else:
|
else:
|
||||||
self.urls = urls
|
self.urls = urls
|
||||||
|
|
||||||
self.headers = {'X-Plex-Device-Name': 'Tautulli',
|
self.headers = {'X-Plex-Product': 'Tautulli',
|
||||||
'X-Plex-Product': 'Tautulli',
|
|
||||||
'X-Plex-Version': plexpy.common.RELEASE,
|
'X-Plex-Version': plexpy.common.RELEASE,
|
||||||
|
'X-Plex-Client-Identifier': plexpy.CONFIG.PMS_UUID,
|
||||||
'X-Plex-Platform': plexpy.common.PLATFORM,
|
'X-Plex-Platform': plexpy.common.PLATFORM,
|
||||||
'X-Plex-Platform-Version': plexpy.common.PLATFORM_RELEASE,
|
'X-Plex-Platform-Version': plexpy.common.PLATFORM_RELEASE,
|
||||||
'X-Plex-Client-Identifier': plexpy.CONFIG.PMS_UUID,
|
'X-Plex-Device': 'Web',
|
||||||
|
'X-Plex-Device-Name': plexpy.common.PLATFORM_DEVICE_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
self.token = token
|
self.token = token
|
||||||
|
@@ -883,6 +883,7 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
|||||||
'subtitle_language': notify_params['subtitle_language'],
|
'subtitle_language': notify_params['subtitle_language'],
|
||||||
'subtitle_language_code': notify_params['subtitle_language_code'],
|
'subtitle_language_code': notify_params['subtitle_language_code'],
|
||||||
'file': notify_params['file'],
|
'file': notify_params['file'],
|
||||||
|
'filename': os.path.basename(notify_params['file']),
|
||||||
'file_size': helpers.humanFileSize(notify_params['file_size']),
|
'file_size': helpers.humanFileSize(notify_params['file_size']),
|
||||||
'indexes': notify_params['indexes'],
|
'indexes': notify_params['indexes'],
|
||||||
'section_id': notify_params['section_id'],
|
'section_id': notify_params['section_id'],
|
||||||
|
@@ -2664,7 +2664,7 @@ class PmsConnect(object):
|
|||||||
child_title = helpers.get_xml_attr(item, 'title')
|
child_title = helpers.get_xml_attr(item, 'title')
|
||||||
|
|
||||||
if child_rating_key:
|
if child_rating_key:
|
||||||
key = int(child_index)
|
key = int(child_index) if child_index else child_title
|
||||||
children.update({key: {'rating_key': int(child_rating_key)}})
|
children.update({key: {'rating_key': int(child_rating_key)}})
|
||||||
|
|
||||||
key = int(parent_index) if match_type == 'index' else parent_title
|
key = int(parent_index) if match_type == 'index' else parent_title
|
||||||
@@ -2676,9 +2676,9 @@ class PmsConnect(object):
|
|||||||
key = 0 if match_type == 'index' else title
|
key = 0 if match_type == 'index' else title
|
||||||
key_list = {key: {'rating_key': int(rating_key),
|
key_list = {key: {'rating_key': int(rating_key),
|
||||||
'children': parents},
|
'children': parents},
|
||||||
'section_id': section_id,
|
'section_id': section_id,
|
||||||
'library_name': library_name
|
'library_name': library_name
|
||||||
}
|
}
|
||||||
|
|
||||||
return key_list
|
return key_list
|
||||||
|
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
PLEXPY_BRANCH = "beta"
|
PLEXPY_BRANCH = "beta"
|
||||||
PLEXPY_RELEASE_VERSION = "v2.1.10-beta"
|
PLEXPY_RELEASE_VERSION = "v2.1.11-beta"
|
||||||
|
@@ -18,6 +18,7 @@ import json
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import threading
|
import threading
|
||||||
|
import urllib
|
||||||
|
|
||||||
import cherrypy
|
import cherrypy
|
||||||
from cherrypy.lib.static import serve_file, serve_download
|
from cherrypy.lib.static import serve_file, serve_download
|
||||||
@@ -273,8 +274,21 @@ class WebInterface(object):
|
|||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@cherrypy.tools.json_out()
|
@cherrypy.tools.json_out()
|
||||||
@requireAuth(member_of("admin"))
|
@requireAuth(member_of("admin"))
|
||||||
def return_sessions_url(self, **kwargs):
|
def return_plex_xml_url(self, endpoint='', plextv=False, **kwargs):
|
||||||
return plexpy.CONFIG.PMS_URL + '/status/sessions?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN
|
kwargs['X-Plex-Token'] = plexpy.CONFIG.PMS_TOKEN
|
||||||
|
|
||||||
|
if plextv:
|
||||||
|
base_url = 'https://plex.tv'
|
||||||
|
else:
|
||||||
|
if plexpy.CONFIG.PMS_URL_OVERRIDE:
|
||||||
|
base_url = plexpy.CONFIG.PMS_URL_OVERRIDE
|
||||||
|
else:
|
||||||
|
base_url = plexpy.CONFIG.PMS_URL
|
||||||
|
|
||||||
|
if '{machine_id}' in endpoint:
|
||||||
|
endpoint = endpoint.format(machine_id=plexpy.CONFIG.PMS_IDENTIFIER)
|
||||||
|
|
||||||
|
return base_url + endpoint + '?' + urllib.urlencode(kwargs)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@requireAuth()
|
@requireAuth()
|
||||||
|
Reference in New Issue
Block a user