plexpy/data/interfaces/default/welcome.html
2017-12-17 23:12:56 -08:00

480 lines
23 KiB
HTML

<%
import plexpy
from plexpy import common
%>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tautulli - ${title} | ${server_name}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link href="${http_root}css/bootstrap3/bootstrap.css" rel="stylesheet">
<link href="${http_root}css/bootstrap-wizard.css" rel="stylesheet">
<link href="${http_root}css/plexpy.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">
<!-- Favicons -->
<link rel="icon" type="image/png" sizes="32x32" href="${http_root}images/favicon/favicon-32x32.png?v=2.0.0">
<link rel="icon" type="image/png" sizes="16x16" href="${http_root}images/favicon/favicon-16x16.png?v=2.0.0">
<link rel="shortcut icon" href="${http_root}images/favicon/favicon.ico?v=2.0.0">
<!-- ICONS -->
<!-- Android >M39 icon -->
<link rel="icon" type="image/png" sizes="192x192" href="${http_root}images/favicon/android-chrome-192x192.png?v=2.0.0">
<link rel="manifest" href="${http_root}json/Android-manifest.json?v=2.0.0">
<meta name="theme-color" content="#1f1f1f">
<!-- Apple -->
<link rel="apple-touch-icon" sizes="180x180" href="${http_root}images/favicon/apple-touch-icon.png?v=2.0.0">
<link rel="mask-icon" href="${http_root}images/favicon/safari-pinned-tab.svg?v=2.0.0" color="#1f1f1f">
<meta name="apple-mobile-web-app-title" content="Tautulli">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="viewport" content="initial-scale=1">
<meta name="format-detection" content="telephone=no">
<!-- IE10 icon -->
<meta name="application-name" content="Tautulli">
<meta name="msapplication-TileColor" content="#1f1f1f">
<meta name="msapplication-TileImage" content="${http_root}images/favicon/mstile-144x144.png?v=2.0.0">
<meta name="msapplication-config" content="${http_root}xml/IEconfig.xml?v=2.0.0" />
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="wizard" id="some-wizard" data-title="Tautulli Setup Wizard">
<form>
<div class="wizard-card" data-cardname="card1">
<div style="float: right;">
<img alt="Tautulli" src="${http_root}images/logo-tautulli-50.png" />
</div>
<h3 style="line-height: 50px;">Welcome!</h3>
<br />
<div>
Thanks for taking the time to try out Tautulli. Hope you find it useful.
<br /><br />
Tautulli requires a permanent internet connection to ensure a reliable experience.
<br /><br />
This wizard will help you get set up, to continue press Next.
</div>
</div>
<div class="wizard-card" data-cardname="card2">
<h3>Plex Authentication</h3>
<p class="help-block">Enter your Plex.tv username and password. Tautulli does not store your username or password.</p>
<div class="wizard-input-section">
<label for="pms_username">Plex.tv Username</label>
<div class="row">
<div class="col-xs-8">
<input type="text" class="form-control pms-auth" id="pms_username" placeholder="" required>
</div>
</div>
</div>
<div class="wizard-input-section">
<label for="pms_password">Plex.tv Password</label>
<div class="row">
<div class="col-xs-8">
<input type="password" class="form-control pms-auth" id="pms_password" placeholder="" required>
</div>
</div>
</div>
<input type="hidden" class="form-control pms-auth" name="pms_token" id="pms_token" value="${config['pms_token']}" data-validate="validatePMStoken">
<a class="btn btn-dark" id="pms-authenticate" href="#" role="button">Authenticate</a><span style="margin-left: 10px; display: none;" id="pms-token-status"></span>
</div>
<div class="wizard-card" data-cardname="card3">
<h3>Plex Media Server</h3>
<p class="help-block">Enter your Plex Server details and then click the Verify button to make sure Tautulli can reach the server.</p>
<div class="wizard-input-section">
<label for="pms_ip">Plex IP or Hostname</label>
<div class="row">
<div class="col-xs-8">
<select id="pms_ip" name="pms_ip"></select>
</div>
</div>
</div>
<div class="wizard-input-section">
<label for="pms_port">Port Number</label>
<div class="row">
<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>
</div>
<div class="col-xs-4">
<div class="checkbox">
<label>
<input type="checkbox" id="pms_ssl" name="pms_ssl" value="1"> Use SSL
</label>
</div>
</div>
<div class="col-xs-4">
<div class="checkbox">
<label>
<input type="checkbox" id="pms_is_remote" name="pms_is_remote" value="1"> Remote Server
</label>
</div>
</div>
</div>
</div>
<input type="hidden" class="form-control pms-settings" id="pms_valid" data-validate="validatePMSip" value="">
<input type="hidden" class="form-control pms-settings" id="pms_identifier" name="pms_identifier" value="${config['pms_identifier']}">
<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>
</div>
<div class="wizard-card" data-cardname="card4">
<h3>Activity Logging</h3>
<p class="help-block">Tautulli will keep a history of all streaming activity on your Plex server.</p>
<div class="wizard-input-section">
<label for="logging_ignore_interval">Ignore Interval</label>
<div class="row">
<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>
</div>
<span style="margin-left: 10px; line-height: 35px; display: none;" id="ignore-int-status"></span>
</div>
<p class="help-block">The interval (in seconds) an item must be in a playing state before logging it. 0 to disable.</p>
</div>
<p class="help-block">
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.
</p>
</div>
<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">
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.
</p>
</div>
<div class="wizard-card" data-cardname="card5">
<h3>Database Import</h3>
<p class="help-block">If you have an existing PlexWatch/Plexivity database, you can import the data into Tautulli.</p>
<p class="help-block">
To import a database, navigate to the <strong>Settings</strong> page
and to the <strong>Import & Backups</strong> tab after you have completed this setup wizard.
</p>
<!-- Required fields but hidden -->
<div style="display: none;">
<input type="checkbox" name="first_run" id="first_run" value="1" checked>
<input type="checkbox" name="launch_browser" id="launch_browser" value="1" ${config['launch_browser']}>
<input type="checkbox" name="refresh_users_on_startup" id="refresh_users_on_startup" value="1" ${config['refresh_users_on_startup']}>
<input type="checkbox" name="refresh_libraries_on_startup" id="refresh_libraries_on_startup" value="1" ${config['refresh_libraries_on_startup']}>
<input type="checkbox" name="check_github" id="check_github" value="1" ${config['check_github']}>
<input type="checkbox" name="log_blacklist" id="log_blacklist" value="1" ${config['log_blacklist']}>
<input type="checkbox" name="cache_images" id="cache_images" value="1" ${config['cache_images']}>
<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="text" name="home_stats_cards" id="home_stats_cards" value="first_run_wizard">
<input type="text" name="home_library_cards" id="home_library_cards" value="first_run_wizard">
</div>
</div>
</form>
<div class="wizard-success">
<h3>Setup Complete!</h3>
<br/>
<p>Setup is now complete. For more configuration options please visit the Settings menu on the home page.</p>
<br/>
<i class="fa fa-refresh fa-spin"></i>&nbspWaiting <span class="countdown">5</span> seconds to ensure authentication token is registered...
</div>
</div>
</div>
</div>
<script src="${http_root}js/jquery-2.1.4.min.js"></script>
<script src="${http_root}js/bootstrap.min.js"></script>
<script src="${http_root}js/selectize.min.js"></script>
<script src="${http_root}js/script.js${cache_param}"></script>
<script src="${http_root}js/bootstrap-wizard.min.js"></script>
<script>
$(document).ready(function() {
$.fn.wizard.logging = false;
var options = {
keyboard : false,
contentHeight : 400,
contentWidth : 700,
backdrop: 'static',
buttons: {submitText: 'Finish'},
submitUrl: "configUpdate"
};
var wizard = $("#some-wizard").wizard(options);
wizard.show();
wizard.on("submit", function(wizard) {
// Probably should not success before we know, but hopefully validation is good enough.
wizard.submitSuccess();
$.ajax({
url: "configUpdate",
type: "POST",
url: wizard.args.submitUrl,
data: wizard.serialize(),
dataType: "json",
complete: function (data) {
$(".countdown").countdown(function () { location.reload(); }, 5, "");
}
})
});
$select_pms = $('#pms_ip').selectize({
create: true,
createOnBlur: true,
openOnFocus: true,
maxItems: 1,
closeAfterSelect: true,
onInitialize: function () {
var s = this;
this.revertSettings.$children.each(function () {
$.extend(s.options[this.value], $(this).data());
});
},
render: {
option: function (item, escape) {
return '<div data-use_ssl="' + item.httpsRequired + '" data-local="' + item.local + '" data-ci="' + item.clientIdentifier + '" data-ip="' + item.ip + '" data-port="' + item.port + '" data-label="' + item.label + '">' + item.value + ' (' + item.label + ')</div>';
},
item: function (item, escape) {
// first item is rendered before initialization bug?
if (!item.ci) {
$.extend(item,
$(this.revertSettings.$children)
.filter('[value="' + item.value + '"]').data());
}
return '<div data-use_ssl="' + item.httpsRequired + '" data-local="' + item.local + '" data-ci="' + item.clientIdentifier + '" data-ip="' + item.ip + '" data-port="' + item.port + '" data-label="' + item.label + '">' + item.value + ' (' + item.label + ')</div>';
}
},
onChange: function (item) {
var ci = $('.selectize-input').find('div').attr('data-ci');
var port = $('.selectize-input').find('div').attr('data-port')
var local = $('.selectize-input').find('div').attr('data-local')
var ssl = $('.selectize-input').find('div').attr('data-use_ssl')
$("#pms-verify-status").html("");
// If a option was added by a user its
// data-xxx="undefined"
if (ci != "undefined") {
// To allow next step in the guide.
// servers with clientIdentifier is verified
$("#pms_identifier").val(ci);
$("#pms_valid").val("valid");
$("#pms-verify-status").html('<i class="fa fa-check"></i> Server found!').show();
} else {
// Self made options must be verified
$("#pms_valid").val("");
$("#pms-verify-status").html("").hide();
}
// If the server is verified set the correct port
if (port != "undefined") {
$('#pms_port').val(port);
} else {
// set default port
$('#pms_port').val("32400");
}
if (local != "undefined" && local == '0') {
$('#pms_is_remote').prop('checked', true);
} else {
$('#pms_is_remote').prop('checked', false);
}
if (ssl != "undefined" && ssl == "1") {
$('#pms_ssl').prop('checked', true);
} else {
$('#pms_ssl').prop('checked', false);
}
}
});
});
function validatePMSip(el) {
var valid_pms_ip = el.val();
var retValue = {};
if (valid_pms_ip == "") {
retValue.status = false;
retValue.msg = "Please verify your server.";
$("#pms-verify-status").html('<i class="fa fa-exclamation-circle"></i> Please verify your server.');
$('#pms-verify-status').fadeIn('fast').delay(2000).fadeOut('fast');
} else {
retValue.status = true;
}
return retValue;
}
function validatePMStoken(el) {
var valid_pms_token = el.val();
var retValue = {};
if (valid_pms_token == "") {
retValue.status = false;
retValue.msg = "Please authenticate.";
$("#pms-token-status").html('<i class="fa fa-exclamation-circle"></i> Please authenticate.');
$('#pms-token-status').fadeIn('fast').delay(2000).fadeOut('fast');
} else {
retValue.status = true;
}
return retValue;
}
function validateIgnoreInterval(el) {
var valid_ignore_int = el.val();
var retValue = {};
if (!isPositiveInt(valid_ignore_int)) {
retValue.status = false;
retValue.msg = "Please enter a valid integer.";
$("#ignore-int-status").html('<i class="fa fa-exclamation-circle"></i> Please enter a valid ignore interval.');
$('#ignore-int-status').fadeIn('fast').delay(2000).fadeOut('fast');
} else {
retValue.status = true;
}
return retValue;
}
function isPositiveInt(n) {
return $.isNumeric(n) && (Math.floor(n) == n) && (n >= 0)
}
var pms_verified = false;
var authenticated = false;
$("#verify-plex-server").click(function () {
if (!(pms_verified)) {
var pms_ip = $("#pms_ip").val().trim();
var pms_port = $("#pms_port").val().trim();
var pms_identifier = $("#pms_identifier").val();
var pms_ssl = $("#pms_ssl").is(':checked') ? 1 : 0;
var pms_is_remote = $("#pms_is_remote").is(':checked') ? 1 : 0;
if ((pms_ip !== '') || (pms_port !== '')) {
$("#pms-verify-status").html('<i class="fa fa-refresh fa-spin"></i> Validating server...');
$('#pms-verify-status').fadeIn('fast');
$.ajax({
url: 'get_server_id',
data: { hostname: pms_ip, port: pms_port, identifier: pms_identifier, ssl: pms_ssl, remote: pms_is_remote },
cache: true,
async: true,
timeout: 5000,
error: function (jqXHR, textStatus, errorThrown) {
$("#pms-verify-status").html('<i class="fa fa-exclamation-circle"></i> This is not a Plex Server!');
$('#pms-verify-status').fadeIn('fast');
},
success: function (json) {
var machine_identifier = json;
if (machine_identifier) {
$("#pms_identifier").val(machine_identifier);
$("#pms-verify-status").html('<i class="fa fa-check"></i> Server found!');
$('#pms-verify-status').fadeIn('fast');
pms_verified = true;
$("#pms_valid").val("valid");
} else {
$("#pms-verify-status").html('<i class="fa fa-exclamation-circle"></i> This is not a Plex Server!');
$('#pms-verify-status').fadeIn('fast');
}
}
});
} else {
$("#pms-verify-status").html('<i class="fa fa-exclamation-circle"></i> Please enter both fields.');
$('#pms-verify-status').fadeIn('fast');
}
}
});
$( ".pms-settings" ).change(function() {
pms_verified = false;
$("#pms_valid").val("");
$("#pms-verify-status").html("");
});
$( ".pms-auth" ).change(function() {
authenticated = false;
$("#pms_token").val("");
$("#pms-token-status").html("");
});
// Plex.tv auth token fetch
$("#pms-authenticate").click(function() {
$("#pms-token-status").html('<i class="fa fa-refresh fa-spin"></i> Fetching token...');
$('#pms-token-status').fadeIn('fast');
var pms_username = $("#pms_username").val().trim();
var pms_password = $("#pms_password").val().trim();
if ((pms_username !== '') && (pms_password !== '')) {
$.ajax({
type: 'GET',
url: 'get_plexpy_pms_token',
data: {
username: pms_username,
password: pms_password
},
cache: false,
async: true,
complete: function (xhr, status) {
var result = $.parseJSON(xhr.responseText);
var msg = result.message;
if (result.result == 'success') {
var authToken = result.token;
$("#pms-token-status").html('<i class="fa fa-check"></i> ' + msg);
$('#pms-token-status').fadeIn('fast');
$("#pms_token").val(authToken);
authenticated = true;
getServerOptions(authToken)
} else {
$("#pms-token-status").html('<i class="fa fa-exclamation-circle"></i> ' + msg);
}
}
});
} else {
$("#pms-token-status").html('<i class="fa fa-exclamation-circle"></i> Username and password required.');
$('#pms-token-status').fadeIn('fast');
}
});
// Send database path to import script
//$("#plexwatch-import").click(function() {
// var database_path = $("#db_location").val();
// var table_name = 'processed';
// var import_ignore_interval = 0;
// $.ajax({
// url: 'get_plexwatch_export_data',
// data: {database_path: database_path, table_name:table_name, import_ignore_interval:import_ignore_interval},
// cache: false,
// async: true,
// success: function(data) {
// if (data === 'Import has started. Check the Tautulli logs to monitor any problems.') {
// $("#plexwatch-import-status").html('Started');
// } else {
// $("#plexwatch-import-status").html(data);
// }
// $("#db_location").val('')
// }
// });
//});
function getServerOptions(token) {
/* Set token and returns server options */
$.ajax({
url: "discover/" + token + '?include_cloud=false',
success: function (result) {
$('#pms_ip').html("")
// Add all servers to the "combobox"
$select_pms[0].selectize.addOption(result);
}
})
}
</script>
</body>
</html>