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:
Tim 2015-08-04 01:06:56 +02:00
parent b68a7956c3
commit c02b7a0079
7 changed files with 148 additions and 71 deletions

View file

@ -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>

View 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>&nbspLoading Details...
</span></strong>
% else:
<i class="fa fa-exclamation-circle"></i>&nbspInvalid 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

View file

@ -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>&nbsp' + 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']);
});

View file

@ -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);
}
});
}

View file

@ -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>

View file

@ -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>

View file

@ -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):