mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-16 02:02:58 -07:00
Fix the way the IP address modal works.
Allow IP address info modal on history page. Some minor styling changes to improve layout of settings on mobile.
This commit is contained in:
parent
b68a7956c3
commit
c02b7a0079
7 changed files with 148 additions and 71 deletions
|
@ -37,6 +37,8 @@
|
|||
</table>
|
||||
<div class="modal fade" id="info-modal" tabindex="-1" role="dialog" aria-labelledby="info-modal">
|
||||
</div>
|
||||
<div class="modal fade" id="ip-info-modal" tabindex="-1" role="dialog" aria-labelledby="ip-info-modal">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</%def>
|
||||
|
|
69
data/interfaces/default/ip_address_modal.html
Normal file
69
data/interfaces/default/ip_address_modal.html
Normal file
|
@ -0,0 +1,69 @@
|
|||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title" id="myModalLabel">
|
||||
% if data:
|
||||
<strong><span id="modal_header_ip_address">
|
||||
<i class="fa fa-spin fa-refresh"></i> Loading Details...
|
||||
</span></strong>
|
||||
% else:
|
||||
<i class="fa fa-exclamation-circle"></i> Invalid IP Address</span></strong>
|
||||
% endif
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body" id="modal-text">
|
||||
<div class="col-md-6">
|
||||
<h4><strong>Location Details</strong></h4>
|
||||
<ul>
|
||||
<li>Country: <strong><span id="country"></span></strong></li>
|
||||
<li>City: <strong><span id="city"></span></strong></li>
|
||||
<li>Region: <strong><span id="region"></span></strong></li>
|
||||
<li>Timezone: <strong><span id="timezone"></span></strong></li>
|
||||
<li>Latitude: <strong><span id="lat"></span></strong></li>
|
||||
<li>Longitude: <strong><span id="lon"></span></strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h4><strong>Connection Details</strong></h4>
|
||||
<ul>
|
||||
<li>ISP: <strong><span id="isp"></span></strong></li>
|
||||
<li>Organization: <strong><span id="org"></span></strong></li>
|
||||
<li>AS: <strong><span id="as"></span></strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
% if data:
|
||||
<script>
|
||||
function getUserLocation(ip_address) {
|
||||
$.ajax({
|
||||
url: 'http://ip-api.com/json/' + ip_address,
|
||||
cache: true,
|
||||
async: true,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
error: function(){
|
||||
$('#modal_header_ip_address').html("Request failed. Server may be too busy.");
|
||||
},
|
||||
success: function(data) {
|
||||
$('#modal_header_ip_address').html("IP Address: " + ip_address);
|
||||
$('#country').html(data.country);
|
||||
$('#city').html(data.city);
|
||||
$('#region').html(data.regionName);
|
||||
$('#timezone').html(data.timezone);
|
||||
$('#lat').html(data.lat);
|
||||
$('#lon').html(data.lon);
|
||||
$('#isp').html(data.isp);
|
||||
$('#org').html(data.org);
|
||||
$('#as').html(data.as);
|
||||
},
|
||||
timeout: 5000
|
||||
});
|
||||
}
|
||||
getUserLocation('${data}');
|
||||
</script>
|
||||
% endif
|
|
@ -32,7 +32,6 @@ history_table_options = {
|
|||
"data":"date",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (rowData['stopped'] === null) {
|
||||
$(td).addClass('currentlyWatching');
|
||||
$(td).html('Currently watching...');
|
||||
} else {
|
||||
$(td).html(moment(cellData,"X").format(date_format));
|
||||
|
@ -71,11 +70,21 @@ history_table_options = {
|
|||
"targets": [3],
|
||||
"data":"ip_address",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if ((cellData == '') || (cellData == '0')) {
|
||||
if (cellData) {
|
||||
if (isPrivateIP(cellData)) {
|
||||
if (cellData != '') {
|
||||
$(td).html(cellData);
|
||||
} else {
|
||||
$(td).html('n/a');
|
||||
}
|
||||
} else {
|
||||
$(td).html('<a href="javascript:void(0)" data-toggle="modal" data-target="#ip-info-modal"><i class="fa fa-map-marker"></i> ' + cellData +'</a>');
|
||||
}
|
||||
} else {
|
||||
$(td).html('n/a');
|
||||
}
|
||||
},
|
||||
"className": "no-wrap hidden-xs"
|
||||
"className": "no-wrap hidden-xs modal-control-ip"
|
||||
},
|
||||
{
|
||||
"targets": [4],
|
||||
|
@ -99,8 +108,12 @@ history_table_options = {
|
|||
{
|
||||
"targets": [5],
|
||||
"data":"started",
|
||||
"render": function ( data, type, full ) {
|
||||
return moment(data, "X").format(time_format);
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData === null) {
|
||||
$(td).html('n/a');
|
||||
} else {
|
||||
$(td).html(moment(cellData,"X").format(time_format));
|
||||
}
|
||||
},
|
||||
"searchable": false,
|
||||
"className": "no-wrap hidden-sm hidden-xs"
|
||||
|
@ -121,11 +134,11 @@ history_table_options = {
|
|||
{
|
||||
"targets": [7],
|
||||
"data":"stopped",
|
||||
"render": function ( data, type, full ) {
|
||||
if (data !== null) {
|
||||
return moment(data, "X").format(time_format);
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData === null) {
|
||||
$(td).html('n/a');
|
||||
} else {
|
||||
return data;
|
||||
$(td).html(moment(cellData,"X").format(time_format));
|
||||
}
|
||||
},
|
||||
"searchable": false,
|
||||
|
@ -193,4 +206,27 @@ $('#history_table').on('click', 'td.modal-control', function () {
|
|||
});
|
||||
}
|
||||
showStreamDetails();
|
||||
});
|
||||
|
||||
$('#history_table').on('click', 'td.modal-control-ip', function () {
|
||||
var tr = $(this).parents('tr');
|
||||
var row = history_table.row( tr );
|
||||
var rowData = row.data();
|
||||
|
||||
function getUserLocation(ip_address) {
|
||||
if (isPrivateIP(ip_address)) {
|
||||
return "n/a"
|
||||
} else {
|
||||
$.ajax({
|
||||
url: 'get_ip_address_details',
|
||||
data: {ip_address: ip_address},
|
||||
async: true,
|
||||
complete: function(xhr, status) {
|
||||
$("#ip-info-modal").html(xhr.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getUserLocation(rowData['ip_address']);
|
||||
});
|
|
@ -92,22 +92,11 @@ $('#user_ip_table').on('click', 'td.modal-control', function () {
|
|||
return "n/a"
|
||||
} else {
|
||||
$.ajax({
|
||||
url: 'http://ip-api.com/json/' + ip_address,
|
||||
cache: true,
|
||||
url: 'get_ip_address_details',
|
||||
data: {ip_address: ip_address},
|
||||
async: true,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
$('#modal_header_ip_address').html(ip_address);
|
||||
$('#country').html(data.country);
|
||||
$('#city').html(data.city);
|
||||
$('#region').html(data.regionName);
|
||||
$('#timezone').html(data.timezone);
|
||||
$('#lat').html(data.lat);
|
||||
$('#lon').html(data.lon);
|
||||
$('#isp').html(data.isp);
|
||||
$('#org').html(data.org);
|
||||
$('#as').html(data.as);
|
||||
complete: function(xhr, status) {
|
||||
$("#ip-info-modal").html(xhr.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="date_format">Date Format</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-4">
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control" id="date_format" name="date_format" value="${config['date_format']}" data-parsley-trigger="change" required>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -73,7 +73,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="date_format">Time Format</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<div class="col-md-2">
|
||||
<input type="text" class="form-control" id="time_format" name="time_format" value="${config['time_format']}" data-parsley-trigger="change" required>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -89,7 +89,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="http_host">HTTP Host</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="http_host" name="http_host" value="${config['http_host']}" data-parsley-trigger="change" required>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -98,7 +98,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="http_port">HTTP Port</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<div class="col-md-2">
|
||||
<input type="text" class="form-control" data-parsley-type="integer" id="http_port" name="http_port" value="${config['http_port']}" data-parsley-trigger="change" required>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -138,7 +138,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="http_username">HTTP Username</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-4">
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control" id="http_username" name="http_username" value="${config['http_username']}" size="30">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -147,7 +147,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="http_password">HTTP Password</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-4">
|
||||
<div class="col-md-4">
|
||||
<input type="password" class="form-control" id="http_password" name="http_password" value="${config['http_password']}" size="30">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -167,7 +167,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div id="apioptions" class="form-group">
|
||||
<label for="api_key">API key</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="col-md-6">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" name="api_key" id="api_key" value="${config['api_key']}" size="20">
|
||||
<span class="input-group-btn">
|
||||
|
@ -189,7 +189,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group has-feedback" id="pms-ip-group">
|
||||
<label for="pms_ip">Plex IP or Hostname</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="pms-settings form-control" id="pms_ip" name="pms_ip" value="${config['pms_ip']}" size="30" data-parsley-trigger="change" aria-describedby="server-verified" required>
|
||||
<span class="form-control-feedback" id="pms-verify" aria-hidden="true" style="display: none;"></span>
|
||||
</div>
|
||||
|
@ -199,7 +199,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="pms_port">Plex Port</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<div class="col-md-2">
|
||||
<input data-parsley-type="integer" class="pms-settings form-control" type="text" id="pms_port" name="pms_port" value="${config['pms_port']}" size="30" data-parsley-trigger="change" required>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -229,7 +229,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="pms_token">PMS Token</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="col-md-6">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="pms_token" name="pms_token" value="${config['pms_token']}" data-parsley-trigger="change" required>
|
||||
<span class="input-group-btn">
|
||||
|
@ -247,7 +247,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="refresh_users_interval">User list Refresh Interval</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<div class="col-md-2">
|
||||
<input type="text" class="form-control" data-parsley-type="integer" id="refresh_users_interval" name="refresh_users_interval" value="${config['refresh_users_interval']}" size="5" data-parsley-range="[1,24]" data-parsley-trigger="change" required>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -281,7 +281,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="pms_logs_folder">Logs Folder</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="pms_logs_folder" name="pms_logs_folder" value="${config['pms_logs_folder']}" size="30" data-parsley-trigger="change">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -304,7 +304,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="monitoring_interval">Monitoring Interval</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<div class="col-md-2">
|
||||
<input type="text" class="form-control" data-parsley-type="integer" id="monitoring_interval" name="monitoring_interval" value="${config['monitoring_interval']}" size="5" data-parsley-min="30" data-parsley-trigger="change" required>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -323,7 +323,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="monitoring_interval">Ignore Interval</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<div class="col-md-2">
|
||||
<input type="text" class="form-control" data-parsley-type="integer" id="logging_ignore_interval" name="logging_ignore_interval" value="${config['logging_ignore_interval']}" size="5" data-parsley-min="0" data-parsley-trigger="change" required>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -374,7 +374,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="notify_watched_percent">Watched Percent</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<div class="col-md-2">
|
||||
<input type="text" class="form-control" data-parsley-type="integer" id="notify_watched_percent" name="notify_watched_percent" value="${config['notify_watched_percent']}" size="5" data-parsley-range="[50,95]" data-parsley-trigger="change" required>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -624,7 +624,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="pms_username">PMS Username</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control" id="pms_username" name="pms_username" size="30">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -633,7 +633,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
|||
<div class="form-group">
|
||||
<label for="pms_password">PMS Password</label>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="col-md-6">
|
||||
<input type="password" class="form-control" id="pms_password" name="pms_password" size="30">
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -127,36 +127,6 @@ from plexpy import helpers
|
|||
</table>
|
||||
</div>
|
||||
<div id="ip-info-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="ip-info-modal">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title" id="myModalLabel">IP Address: <strong><span id="modal_header_ip_address"></span></strong></h4>
|
||||
</div>
|
||||
<div class="modal-body" id="modal-text">
|
||||
<div class="col-md-6">
|
||||
<h4><strong>Location Details</strong></h4>
|
||||
<ul>
|
||||
<li>Country: <strong><span id="country"></span></strong></li>
|
||||
<li>City: <strong><span id="city"></span></strong></li>
|
||||
<li>Region: <strong><span id="region"></span></strong></li>
|
||||
<li>Timezone: <strong><span id="timezone"></span></strong></li>
|
||||
<li>Latitude: <strong><span id="lat"></span></strong></li>
|
||||
<li>Longitude: <strong><span id="lon"></span></strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h4><strong>Connection Details</strong></h4>
|
||||
<ul>
|
||||
<li>ISP: <strong><span id="isp"></span></strong></li>
|
||||
<li>Organization: <strong><span id="org"></span></strong></li>
|
||||
<li>AS: <strong><span id="as"></span></strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -208,6 +208,17 @@ class WebInterface(object):
|
|||
|
||||
return serve_template(templatename="stream_data.html", title="Stream Data", data=stream_data, user=user)
|
||||
|
||||
@cherrypy.expose
|
||||
def get_ip_address_details(self, ip_address=None, **kwargs):
|
||||
import socket
|
||||
|
||||
try:
|
||||
socket.inet_aton(ip_address)
|
||||
except socket.error:
|
||||
ip_address = None
|
||||
|
||||
return serve_template(templatename="ip_address_modal.html", title="IP Address Details", data=ip_address)
|
||||
|
||||
@cherrypy.expose
|
||||
def get_user_list(self, **kwargs):
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue