more removal of cloud services, progress on setup wizard
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<%
|
<%
|
||||||
import jellypy
|
import jellypy
|
||||||
from jellypy import common, helpers
|
from jellypy import common, helpers
|
||||||
%>
|
%>
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
@@ -69,7 +69,8 @@
|
|||||||
<label for="http_username">Username</label>
|
<label for="http_username">Username</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-8">
|
<div class="col-xs-8">
|
||||||
<input type="text" class="form-control auth-settings" id="http_username" name="http_username" value="" size="30">
|
<input type="text" class="form-control auth-settings" id="http_username"
|
||||||
|
name="http_username" value="" size="30">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -77,18 +78,20 @@
|
|||||||
<label for="http_password">Password</label>
|
<label for="http_password">Password</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-8">
|
<div class="col-xs-8">
|
||||||
<input type="password" class="form-control auth-settings" id="http_password" name="http_password" value="" size="30" autocomplete="new-password">
|
<input type="password" class="form-control auth-settings" id="http_password"
|
||||||
|
name="http_password" value="" size="30" autocomplete="new-password">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" class="form-control" name="http_hash_password" id="http_hash_password" value="1">
|
<input type="hidden" class="form-control" name="http_hash_password" id="http_hash_password"
|
||||||
|
value="1">
|
||||||
<input type="hidden" class="form-control" name="http_plex_admin" id="http_plex_admin" value="1">
|
<input type="hidden" class="form-control" name="http_plex_admin" id="http_plex_admin" value="1">
|
||||||
<input type="hidden" id="authentication_valid" data-validate="validateAuthentication" value="">
|
<input type="hidden" id="authentication_valid" data-validate="validateAuthentication" value="">
|
||||||
<span style="display: none;" id="authentication-status"></span>
|
<span style="display: none;" id="authentication-status"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="wizard-card" data-cardname="card3">
|
<div class="wizard-card" data-cardname="card3">
|
||||||
<h3>Jellyfin</h3>
|
<h3>Jellyfin Server</h3>
|
||||||
<div class="wizard-input-section">
|
<div class="wizard-input-section">
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
Select your Jellyfin Server from the dropdown menu or enter an IP address or hostname.
|
Select your Jellyfin Server from the dropdown menu or enter an IP address or hostname.
|
||||||
@@ -108,7 +111,8 @@
|
|||||||
data-ssl="${config['pms_ssl']}"
|
data-ssl="${config['pms_ssl']}"
|
||||||
data-is_cloud="${config['pms_is_cloud']}"
|
data-is_cloud="${config['pms_is_cloud']}"
|
||||||
data-label="${config['pms_name'] or 'Local'}"
|
data-label="${config['pms_name'] or 'Local'}"
|
||||||
selected>${config['pms_ip']}</option>
|
selected>${config['pms_ip']}
|
||||||
|
</option>
|
||||||
% endif
|
% endif
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -118,12 +122,15 @@
|
|||||||
<label for="pms_port">Jellyfin Port</label>
|
<label for="pms_port">Jellyfin Port</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-3">
|
<div class="col-xs-3">
|
||||||
<input type="text" class="form-control pms-settings" name="pms_port" id="pms_port" placeholder="32400" value="${config['pms_port']}" required>
|
<input type="text" class="form-control pms-settings" name="pms_port" id="pms_port"
|
||||||
|
placeholder="8096" value="${config['pms_port']}" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-4">
|
<div class="col-xs-4">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="pms_ssl_checkbox" class="checkbox-toggle pms-settings" data-id="pms_ssl" value="1" ${helpers.checked(config['pms_ssl'])}> Use SSL
|
<input type="checkbox" id="pms_ssl_checkbox"
|
||||||
|
class="checkbox-toggle pms-settings" data-id="pms_ssl" value="1"
|
||||||
|
${helpers.checked(config['pms_ssl'])}> Use SSL
|
||||||
<input type="hidden" id="pms_ssl" name="pms_ssl" value="${config['pms_ssl']}">
|
<input type="hidden" id="pms_ssl" name="pms_ssl" value="${config['pms_ssl']}">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,22 +138,50 @@
|
|||||||
<div class="col-xs-4">
|
<div class="col-xs-4">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="pms_is_remote_checkbox" class="checkbox-toggle pms-settings" data-id="pms_is_remote" value="1" ${helpers.checked(config['pms_is_remote'])}> Remote Server
|
<input type="checkbox" id="pms_is_remote_checkbox"
|
||||||
<input type="hidden" id="pms_is_remote" name="pms_is_remote" value="${config['pms_is_remote']}">
|
class="checkbox-toggle pms-settings" data-id="pms_is_remote" value="1"
|
||||||
|
${helpers.checked(config['pms_is_remote'])}> Remote Server
|
||||||
|
<input type="hidden" id="pms_is_remote" name="pms_is_remote"
|
||||||
|
value="${config['pms_is_remote']}">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" id="pms_valid" data-validate="validatePMSip" value="">
|
|
||||||
<input type="hidden" id="pms_ip" name="pms_ip" value="${config['pms_ip']}">
|
<input type="hidden" id="pms_ip" name="pms_ip" value="${config['pms_ip']}">
|
||||||
<input type="hidden" id="pms_is_cloud" name="pms_is_cloud" value="${config['pms_is_cloud']}">
|
</div>
|
||||||
|
|
||||||
|
<div class="wizard-card" data-cardname="card4">
|
||||||
|
<h3>Jellyfin Auth</h3>
|
||||||
|
<div class="wizard-input-section">
|
||||||
|
<p class="help-block">
|
||||||
|
Authentificate with your Jellyfin instance.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="wizard-input-section">
|
||||||
|
<label for="jellyfin_user">Jellyfin Username</label>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<input type="text" class="form-control pms-settings" name="jellyfin_user"
|
||||||
|
id="jellyfin_user" value="" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wizard-input-section">
|
||||||
|
<label for="jellyfin_password">Jellyfin Password</label>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<input type="password" class="form-control pms-settings" name="jellyfin_password"
|
||||||
|
id="jellyfin_password" value="" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<input type="hidden" id="pms_identifier" name="pms_identifier" value="${config['pms_identifier']}">
|
<input type="hidden" id="pms_identifier" name="pms_identifier" value="${config['pms_identifier']}">
|
||||||
<a class="btn btn-dark" id="verify-plex-server" href="#" role="button">Verify</a>
|
<a class="btn btn-dark" id="verify-plex-server" href="#" role="button">Verify</a>
|
||||||
<span style="margin-left: 10px; display: none;" id="pms-verify-status"></span>
|
<span style="margin-left: 10px; display: none;" id="pms-verify-status"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="wizard-card" data-cardname="card4">
|
<div class="wizard-card" data-cardname="card5">
|
||||||
<h3>Activity Logging</h3>
|
<h3>Activity Logging</h3>
|
||||||
<div class="wizard-input-section">
|
<div class="wizard-input-section">
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
@@ -157,38 +192,47 @@
|
|||||||
<label for="logging_ignore_interval">Ignore Interval</label>
|
<label for="logging_ignore_interval">Ignore Interval</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-4">
|
<div class="col-xs-4">
|
||||||
<input type="text" class="form-control pms-monitoring" id="logging_ignore_interval" name="logging_ignore_interval" placeholder="120" value="${config['logging_ignore_interval']}" data-validate="validateIgnoreInterval" required>
|
<input type="text" class="form-control pms-monitoring" id="logging_ignore_interval"
|
||||||
|
name="logging_ignore_interval" placeholder="120"
|
||||||
|
value="${config['logging_ignore_interval']}"
|
||||||
|
data-validate="validateIgnoreInterval" required>
|
||||||
</div>
|
</div>
|
||||||
<span style="margin-left: 10px; line-height: 35px; display: none;" id="ignore-int-status"></span>
|
<span style="margin-left: 10px; line-height: 35px; display: none;"
|
||||||
|
id="ignore-int-status"></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="help-block">The interval (in seconds) an item must be in a playing state before logging it. 0 to disable.</p>
|
<p class="help-block">The interval (in seconds) an item must be in a playing state before
|
||||||
|
logging it. 0 to disable.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="wizard-input-section">
|
<div class="wizard-input-section">
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
Additional options to disable history logging for certain libraries or users can be found by editing them
|
Additional options to disable history logging for certain libraries or users can be found by
|
||||||
|
editing them
|
||||||
on the <strong>Libraries</strong> or <strong>Users</strong> pages.
|
on the <strong>Libraries</strong> or <strong>Users</strong> pages.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="wizard-card" data-cardname="card5">
|
<div class="wizard-card" data-cardname="card6">
|
||||||
<h3>Notifications</h3>
|
<h3>Notifications</h3>
|
||||||
<div class="wizard-input-section">
|
<div class="wizard-input-section">
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
Tautulli can send a wide variety of notifications to alert you of activity on your Plex server.
|
Tautulli can send a wide variety of notifications to alert you of activity on your Plex
|
||||||
|
server.
|
||||||
</p>
|
</p>
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
To set up a notification agent, navigate to the <strong>Settings</strong> page
|
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.
|
and to the <strong>Notification Agents</strong> tab after you have completed this setup
|
||||||
|
wizard.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="wizard-card" data-cardname="card6">
|
<div class="wizard-card" data-cardname="card7">
|
||||||
<h3>Database Import</h3>
|
<h3>Database Import</h3>
|
||||||
<div class="wizard-input-section">
|
<div class="wizard-input-section">
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
If you have an existing Tautulli, PlexWatch, or Plexivity database, you can import the data into Tautulli.
|
If you have an existing Tautulli, PlexWatch, or Plexivity database, you can import the data
|
||||||
|
into Tautulli.
|
||||||
</p>
|
</p>
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
To import a database, navigate to the <strong>Settings</strong> page
|
To import a database, navigate to the <strong>Settings</strong> page
|
||||||
@@ -200,18 +244,23 @@
|
|||||||
<div style="display: none;">
|
<div style="display: none;">
|
||||||
<input type="checkbox" name="first_run" id="first_run" value="1" checked>
|
<input type="checkbox" name="first_run" id="first_run" value="1" checked>
|
||||||
<input type="checkbox" name="group_history_tables" id="group_history_tables" value="1" checked>
|
<input type="checkbox" name="group_history_tables" id="group_history_tables" value="1" checked>
|
||||||
<input type="checkbox" name="history_table_activity" id="history_table_activity" value="1" checked>
|
<input type="checkbox" name="history_table_activity" id="history_table_activity" value="1"
|
||||||
|
checked>
|
||||||
<input type="checkbox" name="sys_tray_icon" id="sys_tray_icon" value="1" checked>
|
<input type="checkbox" name="sys_tray_icon" id="sys_tray_icon" value="1" checked>
|
||||||
<input type="checkbox" name="launch_startup" id="launch_startup" value="1" checked>
|
<input type="checkbox" name="launch_startup" id="launch_startup" value="1" checked>
|
||||||
<input type="checkbox" name="launch_browser" id="launch_browser" value="1" checked>
|
<input type="checkbox" name="launch_browser" id="launch_browser" value="1" checked>
|
||||||
<input type="checkbox" name="api_enabled" id="api_enabled" value="1" checked>
|
<input type="checkbox" name="api_enabled" id="api_enabled" value="1" checked>
|
||||||
<input type="checkbox" name="refresh_users_on_startup" id="refresh_users_on_startup" value="1" checked>
|
<input type="checkbox" name="refresh_users_on_startup" id="refresh_users_on_startup" value="1"
|
||||||
<input type="checkbox" name="refresh_libraries_on_startup" id="refresh_libraries_on_startup" value="1" checked>
|
checked>
|
||||||
|
<input type="checkbox" name="refresh_libraries_on_startup" id="refresh_libraries_on_startup"
|
||||||
|
value="1" checked>
|
||||||
<input type="checkbox" name="check_github" id="check_github" value="1" checked>
|
<input type="checkbox" name="check_github" id="check_github" value="1" checked>
|
||||||
<input type="checkbox" name="log_blacklist" id="log_blacklist" value="1" checked>
|
<input type="checkbox" name="log_blacklist" id="log_blacklist" value="1" checked>
|
||||||
<input type="checkbox" name="cache_images" id="cache_images" value="1" checked>
|
<input type="checkbox" name="cache_images" id="cache_images" value="1" checked>
|
||||||
<input type="checkbox" name="notify_group_recently_added_grandparent" id="notify_group_recently_added_grandparent" value="1" checked>
|
<input type="checkbox" name="notify_group_recently_added_grandparent"
|
||||||
<input type="checkbox" name="notify_group_recently_added_parent" id="notify_group_recently_added_parent" value="1" checked>
|
id="notify_group_recently_added_grandparent" value="1" checked>
|
||||||
|
<input type="checkbox" name="notify_group_recently_added_parent"
|
||||||
|
id="notify_group_recently_added_parent" value="1" checked>
|
||||||
<input type="checkbox" name="server_changed" id="server_changed" value="1" checked>
|
<input type="checkbox" name="server_changed" id="server_changed" value="1" checked>
|
||||||
<input type="checkbox" name="first_run_complete" id="first_run_complete" value="1" checked>
|
<input type="checkbox" name="first_run_complete" id="first_run_complete" value="1" checked>
|
||||||
<input type="text" name="home_stats_cards" id="home_stats_cards" value="first_run_wizard">
|
<input type="text" name="home_stats_cards" id="home_stats_cards" value="first_run_wizard">
|
||||||
@@ -224,9 +273,11 @@
|
|||||||
<div class="wizard-success">
|
<div class="wizard-success">
|
||||||
<h3>Setup Complete!</h3>
|
<h3>Setup Complete!</h3>
|
||||||
<br/>
|
<br/>
|
||||||
<p>Setup is now complete. For more configuration options please visit the Settings menu on the home page.</p>
|
<p>Setup is now complete. For more configuration options please visit the Settings menu on the home
|
||||||
|
page.</p>
|
||||||
<br/>
|
<br/>
|
||||||
<i class="fa fa-refresh fa-spin"></i> Waiting <span class="countdown">5</span> seconds to ensure authentication token is registered...
|
<i class="fa fa-refresh fa-spin"></i> Waiting <span class="countdown">5</span> seconds to ensure
|
||||||
|
authentication token is registered...
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -243,7 +294,6 @@
|
|||||||
function validateAuthentication(el) {
|
function validateAuthentication(el) {
|
||||||
var http_username = $("#http_username").val();
|
var http_username = $("#http_username").val();
|
||||||
var http_password = $("#http_password").val();
|
var http_password = $("#http_password").val();
|
||||||
var valid_authentication = el.val();
|
|
||||||
var retValue = {};
|
var retValue = {};
|
||||||
|
|
||||||
if (http_username === "" || http_password === "") {
|
if (http_username === "" || http_password === "") {
|
||||||
@@ -310,13 +360,13 @@
|
|||||||
return $.isNumeric(n) && (Math.floor(n) == n) && (n >= 0)
|
return $.isNumeric(n) && (Math.floor(n) == n) && (n >= 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function () {
|
||||||
|
|
||||||
$.fn.wizard.logging = false;
|
$.fn.wizard.logging = false;
|
||||||
var options = {
|
var options = {
|
||||||
keyboard : false,
|
keyboard: false,
|
||||||
contentHeight : 450,
|
contentHeight: 450,
|
||||||
contentWidth : 700,
|
contentWidth: 700,
|
||||||
backdrop: 'static',
|
backdrop: 'static',
|
||||||
buttons: {submitText: 'Finish'},
|
buttons: {submitText: 'Finish'},
|
||||||
submitUrl: "configUpdate"
|
submitUrl: "configUpdate"
|
||||||
@@ -326,14 +376,14 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
// Change button classes
|
// Change button classes
|
||||||
wizard.find('.wizard-back').addClass('btn-dark');
|
wizard.find('.wizard-back').addClass('btn-dark');
|
||||||
wizard.on('incrementCard', function(wizard) {
|
wizard.on('incrementCard', function (wizard) {
|
||||||
wizard.find('.wizard-next.btn-success').removeClass('btn-success').addClass('btn-bright');
|
wizard.find('.wizard-next.btn-success').removeClass('btn-success').addClass('btn-bright');
|
||||||
});
|
});
|
||||||
wizard.on('decrementCard', function(wizard) {
|
wizard.on('decrementCard', function (wizard) {
|
||||||
wizard.find('.wizard-next').removeClass('btn-bright').text('Next');
|
wizard.find('.wizard-next').removeClass('btn-bright').text('Next');
|
||||||
});
|
});
|
||||||
|
|
||||||
wizard.on("submit", function(wizard) {
|
wizard.on("submit", function (wizard) {
|
||||||
// Probably should not success before we know, but hopefully validation is good enough.
|
// Probably should not success before we know, but hopefully validation is good enough.
|
||||||
wizard.submitSuccess();
|
wizard.submitSuccess();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@@ -342,7 +392,9 @@ $(document).ready(function() {
|
|||||||
data: wizard.serialize(),
|
data: wizard.serialize(),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
complete: function (data) {
|
complete: function (data) {
|
||||||
$(".countdown").countdown(function () { location.reload(); }, 5, "");
|
$(".countdown").countdown(function () {
|
||||||
|
location.reload();
|
||||||
|
}, 5, "");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@@ -350,9 +402,9 @@ $(document).ready(function() {
|
|||||||
$('.checkbox-toggle').click(function () {
|
$('.checkbox-toggle').click(function () {
|
||||||
var configToggle = $(this).data('id');
|
var configToggle = $(this).data('id');
|
||||||
if ($(this).is(':checked')) {
|
if ($(this).is(':checked')) {
|
||||||
$('#'+configToggle).val(1);
|
$('#' + configToggle).val(1);
|
||||||
} else {
|
} else {
|
||||||
$('#'+configToggle).val(0);
|
$('#' + configToggle).val(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -400,7 +452,7 @@ $(document).ready(function() {
|
|||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
create: function(input) {
|
create: function (input) {
|
||||||
return {label: '', value: input};
|
return {label: '', value: input};
|
||||||
},
|
},
|
||||||
onInitialize: function () {
|
onInitialize: function () {
|
||||||
@@ -416,7 +468,6 @@ $(document).ready(function() {
|
|||||||
var port = $(pms_ip_selected).data('port');
|
var port = $(pms_ip_selected).data('port');
|
||||||
var local = $(pms_ip_selected).data('local');
|
var local = $(pms_ip_selected).data('local');
|
||||||
var ssl = $(pms_ip_selected).data('ssl');
|
var ssl = $(pms_ip_selected).data('ssl');
|
||||||
var is_cloud = $(pms_ip_selected).data('is_cloud');
|
|
||||||
var value = $(pms_ip_selected).data('value');
|
var value = $(pms_ip_selected).data('value');
|
||||||
|
|
||||||
$("#pms_valid").val(identifier !== 'undefined' ? 'valid' : '');
|
$("#pms_valid").val(identifier !== 'undefined' ? 'valid' : '');
|
||||||
@@ -424,24 +475,18 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
$("#pms_identifier").val(identifier !== 'undefined' ? identifier : '');
|
$("#pms_identifier").val(identifier !== 'undefined' ? identifier : '');
|
||||||
$('#pms_ip').val(ip !== 'undefined' ? ip : value);
|
$('#pms_ip').val(ip !== 'undefined' ? ip : value);
|
||||||
$('#pms_port').val(port !== 'undefined' ? port : 32400);
|
$('#pms_port').val(port !== 'undefined' ? port : 8096);
|
||||||
$('#pms_is_remote_checkbox').prop('checked', (local !== 'undefined' && local === 0));
|
$('#pms_is_remote_checkbox').prop('checked', (local !== 'undefined' && local === 0));
|
||||||
$('#pms_is_remote').val(local !== 'undefined' && local === 0 ? 1 : 0);
|
$('#pms_is_remote').val(local !== 'undefined' && local === 0 ? 1 : 0);
|
||||||
$('#pms_ssl_checkbox').prop('checked', (ssl !== 'undefined' && ssl === 1));
|
$('#pms_ssl_checkbox').prop('checked', (ssl !== 'undefined' && ssl === 1));
|
||||||
$('#pms_ssl').val(ssl !== 'undefined' && ssl === 1 ? 1 : 0);
|
$('#pms_ssl').val(ssl !== 'undefined' && ssl === 1 ? 1 : 0);
|
||||||
$('#pms_is_cloud').val(is_cloud !== 'undefined' && is_cloud === true ? 1 : 0);
|
|
||||||
|
|
||||||
if (is_cloud === true) {
|
|
||||||
$('#pms_port').prop('readonly', true);
|
|
||||||
$('#pms_is_remote_checkbox').prop('disabled', true);
|
|
||||||
$('#pms_ssl_checkbox').prop('disabled', true);
|
|
||||||
} else {
|
|
||||||
$('#pms_port').prop('readonly', false);
|
$('#pms_port').prop('readonly', false);
|
||||||
$('#pms_is_remote_checkbox').prop('disabled', false);
|
$('#pms_is_remote_checkbox').prop('disabled', false);
|
||||||
$('#pms_ssl_checkbox').prop('disabled', false);
|
$('#pms_ssl_checkbox').prop('disabled', false);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onDropdownOpen: function() {
|
onDropdownOpen: function () {
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -469,6 +514,7 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var pms_verified = false;
|
var pms_verified = false;
|
||||||
var authenticated = false;
|
var authenticated = false;
|
||||||
|
|
||||||
@@ -498,7 +544,7 @@ $(document).ready(function() {
|
|||||||
$("#pms-verify-status").html('<i class="fa fa-exclamation-circle"></i> Error verifying server: ' + textStatus);
|
$("#pms-verify-status").html('<i class="fa fa-exclamation-circle"></i> Error verifying server: ' + textStatus);
|
||||||
$('#pms-verify-status').fadeIn('fast');
|
$('#pms-verify-status').fadeIn('fast');
|
||||||
},
|
},
|
||||||
success: function(xhr, status) {
|
success: function (xhr, status) {
|
||||||
var result = xhr;
|
var result = xhr;
|
||||||
var identifier = result.identifier;
|
var identifier = result.identifier;
|
||||||
if (identifier) {
|
if (identifier) {
|
||||||
@@ -520,30 +566,12 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$( ".pms-settings" ).change(function() {
|
$(".pms-settings").change(function () {
|
||||||
pms_verified = false;
|
pms_verified = false;
|
||||||
$("#pms_valid").val("");
|
$("#pms_valid").val("");
|
||||||
$("#pms-verify-status").html("");
|
$("#pms-verify-status").html("");
|
||||||
});
|
});
|
||||||
|
|
||||||
function OAuthPreFunction() {
|
|
||||||
$("#pms_token").val('');
|
|
||||||
$("#pms-token-status").html('<i class="fa fa-refresh fa-spin"></i> Waiting for authentication...').fadeIn('fast');
|
|
||||||
}
|
|
||||||
function OAuthSuccessCallback(authToken) {
|
|
||||||
$("#pms_token").val(authToken);
|
|
||||||
$("#pms-token-status").html('<i class="fa fa-check"></i> Authentication successful.').fadeIn('fast');
|
|
||||||
authenticated = true;
|
|
||||||
getServerOptions(authToken);
|
|
||||||
}
|
|
||||||
function OAuthErrorCallback() {
|
|
||||||
$("#pms-token-status").html('<i class="fa fa-exclamation-circle"></i> Error communicating with Plex.tv.').fadeIn('fast');
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#sign-in-plex').click(function() {
|
|
||||||
PlexOAuth(OAuthSuccessCallback, OAuthErrorCallback, OAuthPreFunction);
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@@ -15,11 +15,9 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
|
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import json
|
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
|
|
||||||
import jellypy
|
import jellypy
|
||||||
|
|
||||||
from jellypy import common
|
from jellypy import common
|
||||||
from jellypy import database
|
from jellypy import database
|
||||||
from jellypy import datatables
|
from jellypy import datatables
|
||||||
|
@@ -37,15 +37,11 @@ from urllib.parse import urlencode
|
|||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
import cloudinary
|
|
||||||
import ipwhois
|
import ipwhois
|
||||||
import ipwhois.exceptions
|
import ipwhois.exceptions
|
||||||
import ipwhois.utils
|
import ipwhois.utils
|
||||||
import xmltodict
|
import xmltodict
|
||||||
from IPy import IP
|
from IPy import IP
|
||||||
from cloudinary.api import delete_resources_by_tag
|
|
||||||
from cloudinary.uploader import upload
|
|
||||||
from cloudinary.utils import cloudinary_url
|
|
||||||
|
|
||||||
import jellypy
|
import jellypy
|
||||||
from jellypy import common
|
from jellypy import common
|
||||||
@@ -795,110 +791,6 @@ def delete_from_imgur(delete_hash, img_title='', fallback=''):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def upload_to_cloudinary(img_data, img_title='', rating_key='', fallback=''):
|
|
||||||
""" Uploads an image to Cloudinary """
|
|
||||||
img_url = ''
|
|
||||||
|
|
||||||
if not jellypy.CONFIG.CLOUDINARY_CLOUD_NAME or not jellypy.CONFIG.CLOUDINARY_API_KEY or not jellypy.CONFIG.CLOUDINARY_API_SECRET:
|
|
||||||
logger.error(
|
|
||||||
"Tautulli Helpers :: Cannot upload image to Cloudinary. Cloudinary settings not specified in the settings.")
|
|
||||||
return img_url
|
|
||||||
|
|
||||||
cloudinary.config(
|
|
||||||
cloud_name=jellypy.CONFIG.CLOUDINARY_CLOUD_NAME,
|
|
||||||
api_key=jellypy.CONFIG.CLOUDINARY_API_KEY,
|
|
||||||
api_secret=jellypy.CONFIG.CLOUDINARY_API_SECRET
|
|
||||||
)
|
|
||||||
|
|
||||||
# Cloudinary library has very poor support for non-ASCII characters on Python 2
|
|
||||||
if jellypy.PYTHON2:
|
|
||||||
_img_title = latinToAscii(img_title, replace=True)
|
|
||||||
else:
|
|
||||||
_img_title = img_title
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = upload((img_title, img_data),
|
|
||||||
public_id='{}_{}'.format(fallback, rating_key),
|
|
||||||
tags=['tautulli', fallback, str(rating_key)],
|
|
||||||
context={'title': _img_title, 'rating_key': str(rating_key), 'fallback': fallback})
|
|
||||||
logger.debug("Tautulli Helpers :: Image '{}' ({}) uploaded to Cloudinary.".format(img_title, fallback))
|
|
||||||
img_url = response.get('url', '')
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(
|
|
||||||
"Tautulli Helpers :: Unable to upload image '{}' ({}) to Cloudinary: {}".format(img_title, fallback, e))
|
|
||||||
|
|
||||||
return img_url
|
|
||||||
|
|
||||||
|
|
||||||
def delete_from_cloudinary(rating_key=None, delete_all=False):
|
|
||||||
""" Deletes an image from Cloudinary """
|
|
||||||
if not jellypy.CONFIG.CLOUDINARY_CLOUD_NAME or not jellypy.CONFIG.CLOUDINARY_API_KEY or not jellypy.CONFIG.CLOUDINARY_API_SECRET:
|
|
||||||
logger.error(
|
|
||||||
"Tautulli Helpers :: Cannot delete image from Cloudinary. Cloudinary settings not specified in the settings.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
cloudinary.config(
|
|
||||||
cloud_name=jellypy.CONFIG.CLOUDINARY_CLOUD_NAME,
|
|
||||||
api_key=jellypy.CONFIG.CLOUDINARY_API_KEY,
|
|
||||||
api_secret=jellypy.CONFIG.CLOUDINARY_API_SECRET
|
|
||||||
)
|
|
||||||
|
|
||||||
if delete_all:
|
|
||||||
delete_resources_by_tag('tautulli')
|
|
||||||
logger.debug("Tautulli Helpers :: Deleted all images from Cloudinary.")
|
|
||||||
elif rating_key:
|
|
||||||
delete_resources_by_tag(str(rating_key))
|
|
||||||
logger.debug("Tautulli Helpers :: Deleted images from Cloudinary with rating_key {}.".format(rating_key))
|
|
||||||
else:
|
|
||||||
logger.debug("Tautulli Helpers :: Unable to delete images from Cloudinary: No rating_key provided.")
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def cloudinary_transform(rating_key=None, width=1000, height=1500, opacity=100, background='000000', blur=0,
|
|
||||||
img_format='png', img_title='', fallback=None):
|
|
||||||
url = ''
|
|
||||||
|
|
||||||
if not jellypy.CONFIG.CLOUDINARY_CLOUD_NAME or not jellypy.CONFIG.CLOUDINARY_API_KEY or not jellypy.CONFIG.CLOUDINARY_API_SECRET:
|
|
||||||
logger.error(
|
|
||||||
"Tautulli Helpers :: Cannot transform image on Cloudinary. Cloudinary settings not specified in the settings.")
|
|
||||||
return url
|
|
||||||
|
|
||||||
cloudinary.config(
|
|
||||||
cloud_name=jellypy.CONFIG.CLOUDINARY_CLOUD_NAME,
|
|
||||||
api_key=jellypy.CONFIG.CLOUDINARY_API_KEY,
|
|
||||||
api_secret=jellypy.CONFIG.CLOUDINARY_API_SECRET
|
|
||||||
)
|
|
||||||
|
|
||||||
img_options = {'format': img_format,
|
|
||||||
'fetch_format': 'auto',
|
|
||||||
'quality': 'auto',
|
|
||||||
'version': timestamp(),
|
|
||||||
'secure': True}
|
|
||||||
|
|
||||||
if width != 1000:
|
|
||||||
img_options['width'] = str(width)
|
|
||||||
img_options['crop'] = 'fill'
|
|
||||||
if height != 1500:
|
|
||||||
img_options['height'] = str(height)
|
|
||||||
img_options['crop'] = 'fill'
|
|
||||||
if opacity != 100:
|
|
||||||
img_options['opacity'] = opacity
|
|
||||||
if background != '000000':
|
|
||||||
img_options['background'] = 'rgb:{}'.format(background)
|
|
||||||
if blur != 0:
|
|
||||||
img_options['effect'] = 'blur:{}'.format(blur * 100)
|
|
||||||
|
|
||||||
try:
|
|
||||||
url, options = cloudinary_url('{}_{}'.format(fallback, rating_key), **img_options)
|
|
||||||
logger.debug("Tautulli Helpers :: Image '{}' ({}) transformed on Cloudinary.".format(img_title, fallback))
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(
|
|
||||||
"Tautulli Helpers :: Unable to transform image '{}' ({}) on Cloudinary: {}".format(img_title, fallback, e))
|
|
||||||
|
|
||||||
return url
|
|
||||||
|
|
||||||
|
|
||||||
def cache_image(url, image=None):
|
def cache_image(url, image=None):
|
||||||
"""
|
"""
|
||||||
Saves an image to the cache directory.
|
Saves an image to the cache directory.
|
||||||
|
@@ -19,7 +19,7 @@ from jellyfin_apiclient_python import JellyfinClient
|
|||||||
|
|
||||||
|
|
||||||
class Jellyfin(object):
|
class Jellyfin(object):
|
||||||
def __init__(self, url, token):
|
def __init__(self, url, token=None):
|
||||||
self.jf = JellyfinClient()
|
self.jf = JellyfinClient()
|
||||||
|
|
||||||
def get_library(self, section_id):
|
def get_library(self, section_id):
|
||||||
@@ -30,3 +30,6 @@ class Jellyfin(object):
|
|||||||
|
|
||||||
def get_item(self, rating_key):
|
def get_item(self, rating_key):
|
||||||
return self.jf.fetchItem(rating_key)
|
return self.jf.fetchItem(rating_key)
|
||||||
|
|
||||||
|
def login(self, user, password):
|
||||||
|
pass
|
||||||
|
Reference in New Issue
Block a user