Template the Datatables JS

Add Links to user screen
Add Public IP list to user screen
Add Watch history to user screen
This commit is contained in:
Tim 2015-06-20 22:27:12 +02:00
parent c4504d8be0
commit 6a026d510d
12 changed files with 536 additions and 335 deletions

View file

@ -25,7 +25,7 @@
<!-- <img src="interfaces/default/images/platforms/roku.png"> platform image --> <!-- <img src="interfaces/default/images/platforms/roku.png"> platform image -->
</div> </div>
<div class="dashboard-activity-metadata-user"> <div class="dashboard-activity-metadata-user">
${a['user']} is ${a['state']} <a href="user?user=${a['user']}">${a['user']}</a> is ${a['state']}
</div> </div>
<div class="dashboard-activity-metadata-title"> <div class="dashboard-activity-metadata-title">
% if a['type'] == 'episode': % if a['type'] == 'episode':

View file

@ -208,3 +208,13 @@ function getPlatformImagePath(platformName) {
return 'interfaces/default/images/platforms/default.png'; return 'interfaces/default/images/platforms/default.png';
} }
} }
function isPrivateIP(ip_address) {
var parts = ip_address.split('.');
if (parts[0] === '10' ||
(parts[0] === '172' && (parseInt(parts[1], 10) >= 16 && parseInt(parts[1], 10) <= 31)) ||
(parts[0] === '192' && parts[1] === '168')) {
return true;
}
return false;
}

View file

@ -20,7 +20,7 @@ history_table_options = {
"infoFiltered":"(filtered from _MAX_ total entries)", "infoFiltered":"(filtered from _MAX_ total entries)",
"emptyTable": "No data in table", "emptyTable": "No data in table",
}, },
"stateSave": true, "stateSave": false,
"sPaginationType": "bootstrap", "sPaginationType": "bootstrap",
"processing": false, "processing": false,
"serverSide": true, "serverSide": true,
@ -48,7 +48,14 @@ history_table_options = {
}, },
{ {
"targets": [2], "targets": [2],
"data":"user" "data":"user",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') {
$(td).html('<a href="user?user=' + cellData + '">' + cellData + '</a>');
} else {
$(td).html(cellData);
}
},
}, },
{ {
"targets": [3], "targets": [3],

View file

@ -0,0 +1,41 @@
$('#log_table').dataTable( {
"processing": false,
"serverSide": true,
"ajax": {
"url": "getLog"
},
"sPaginationType": "bootstrap",
"order": [ 0, 'desc'],
"pageLength": 10,
"stateSave": true,
"language": {
"search":"Search: ",
"lengthMenu":"Show _MENU_ lines per page",
"emptyTable": "No log information available",
"info":"Showing _START_ to _END_ of _TOTAL_ lines",
"infoEmpty":"Showing 0 to 0 of 0 lines",
"infoFiltered":"(filtered from _MAX_ total lines)"},
"columnDefs": [
{
"targets": [0],
"width": "15%"
},
{
"targets": [1],
"width": "10%"
},
{
"targets": [2],
"width": "75%"
}
],
"drawCallback": function (settings) {
// Jump to top of page
$('html,body').scrollTop(0);
$('#ajaxMsg').addClass('success').fadeOut();
},
"preDrawCallback": function(settings) {
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>Fetching rows...</div>");
$('#ajaxMsg').addClass('success').fadeIn();
}
});

View file

@ -0,0 +1,105 @@
user_ip_table_options = {
"destroy": true,
"language": {
"search": "Search: ",
"lengthMenu":"Show _MENU_ entries per page",
"info":"Showing _START_ to _END_ of _TOTAL_ results",
"infoEmpty":"Showing 0 to 0 of 0 entries",
"infoFiltered":"(filtered from _MAX_ total entries)",
"emptyTable": "No data in table",
},
"stateSave": false,
"sPaginationType": "bootstrap",
"processing": false,
"serverSide": true,
"pageLength": 10,
"order": [ 0, 'desc'],
"autoWidth": false,
"columnDefs": [
{
"targets": [0],
"data":"last_seen",
"render": function ( data, type, full ) {
return moment(data, "X").fromNow();
},
"searchable": false,
"width": "15%"
},
{
"targets": [1],
"data":"ip_address",
"width": "15%",
"className": "modal-control",
"createdCell": function (td, cellData, rowData, row, col) {
if (isPrivateIP(cellData)) {
$(td).html(cellData);
} else {
$(td).html('<a href="#ip-info-modal" data-toggle="modal"><span data-toggle="ip-tooltip" data-placement="left" title="IP Address Info" id="ip-info"><i class="icon-map-marker icon-white"></i></span>&nbsp' + cellData +'</a>');
}
},
"width": "15%"
},
{
"targets": [2],
"data":"play_count",
"width": "10%"
},
{
"targets": [3],
"data":"platform",
"width": "15%"
},
{
"targets": [4],
"data":"last_watched",
"width": "30%"
}
],
"drawCallback": function (settings) {
// Jump to top of page
// $('html,body').scrollTop(0);
$('#ajaxMsg').addClass('success').fadeOut();
},
"preDrawCallback": function(settings) {
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>Fetching rows...</div>");
$('#ajaxMsg').addClass('success').fadeIn();
}
}
$('#user_ip_table').on('mouseenter', 'td.modal-control span', function () {
$(this).tooltip();
});
$('#user_ip_table').on('click', 'td.modal-control', function () {
var tr = $(this).parents('tr');
var row = user_ip_table.row( tr );
var rowData = row.data();
function getUserLocation(ip_address) {
if (isPrivateIP(ip_address)) {
return "n/a"
} else {
$.ajax({
url: 'http://ip-api.com/json/' + ip_address,
cache: true,
async: true,
type: 'GET',
dataType: 'json',
success: function(data) {
$('#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);
}
});
}
}
getUserLocation(rowData['ip_address']);
});

View file

@ -0,0 +1,77 @@
users_list_table_options = {
"language": {
"search": "Search: ",
"lengthMenu":"Show _MENU_ entries per page",
"info":"Showing _START_ to _END_ of _TOTAL_ active users",
"infoEmpty":"Showing 0 to 0 of 0 entries",
"infoFiltered":"",
"emptyTable": "No data in table",
},
"destroy": true,
"processing": false,
"serverSide": true,
"pageLength": 10,
"order": [ 0, 'asc'],
"ajax": {
"url": "get_user_list"
},
"bLengthChange": true,
"bInfo": true,
"bAutoWidth": true,
"aaSorting": [[ 0, "asc" ]],
"bStateSave": true,
"bSortClasses": true,
"sPaginationType": "bootstrap",
"columnDefs": [
{
"targets": [0],
"data": null,
"createdCell": function (td, cellData, rowData, row, col) {
//if (rowData['user_thumb'] === '') {
$(td).html('<img src="interfaces/default/images/gravatar-default-80x80.png" alt="User Logo"/>');
//} else {
// $(td).html('<img src="' + rowData['user_thumb'] + '" alt="User Logo"/>');
//}
},
"orderable": false,
"className": "users-poster-face",
"width": "40px"
},
{
"targets": [1],
"data": "user",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') {
$(td).html('<a href="user?user=' + cellData + '">' + cellData + '</a>');
} else {
$(td).html(cellData);
}
},
},
{
"targets": [2],
"data": "time",
"render": function ( data, type, full ) {
return moment(data, "X").fromNow();
}
},
{
"targets": [3],
"data": "ip_address",
"searchable": false
},
{
"targets": [4],
"data": "plays"
}
],
"drawCallback": function (settings) {
// Jump to top of page
$('html,body').scrollTop(0);
$('#ajaxMsg').addClass('success').fadeOut();
},
"preDrawCallback": function(settings) {
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>Fetching rows...</div>");
$('#ajaxMsg').addClass('success').fadeIn();
}
}

View file

@ -24,7 +24,12 @@
<div class="span12"> <div class="span12">
<div class="wellheader-bg"> <div class="wellheader-bg">
<div class="dashboard-wellheader-no-chevron"> <div class="dashboard-wellheader-no-chevron">
<h2><i class="fa fa-book"></i> Logs</h2> <div class="span9"><h2><i class="fa fa-book"></i> Logs</h2></div>
<div class="span3">
<div class="pull-right">
<h5><a id="menu_link_edit" href="clearLogs"><i class="fa fa-trash-o"></i> Clear log</a>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -68,53 +73,7 @@
<%def name="javascriptIncludes()"> <%def name="javascriptIncludes()">
<script src="interfaces/default/js/jquery.dataTables.min.js"></script> <script src="interfaces/default/js/jquery.dataTables.min.js"></script>
<script src="interfaces/default/js/jquery.dataTables.bootstrap.pagination.integration.js"></script> <script src="interfaces/default/js/jquery.dataTables.bootstrap.pagination.integration.js"></script>
<script src="interfaces/default/js/tables/logs.js"></script>
<script>
$(document).ready(function() {
$('#log_table').dataTable( {
"processing": false,
"serverSide": true,
"ajax": {
"url": "getLog"
},
"sPaginationType": "bootstrap",
"order": [ 0, 'desc'],
"pageLength": 10,
"stateSave": true,
"language": {
"search":"Search: ",
"lengthMenu":"Show _MENU_ lines per page",
"emptyTable": "No log information available",
"info":"Showing _START_ to _END_ of _TOTAL_ lines",
"infoEmpty":"Showing 0 to 0 of 0 lines",
"infoFiltered":"(filtered from _MAX_ total lines)"},
"columnDefs": [
{
"targets": [0],
"width": "15%"
},
{
"targets": [1],
"width": "10%"
},
{
"targets": [2],
"width": "75%"
}
],
"drawCallback": function (settings) {
// Jump to top of page
$('html,body').scrollTop(0);
$('#ajaxMsg').addClass('success').fadeOut();
},
"preDrawCallback": function(settings) {
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>Fetching rows...</div>");
$('#ajaxMsg').addClass('success').fadeIn();
}
});
});
</script>
<script> <script>
var timer; var timer;
function setRefresh() function setRefresh()

View file

@ -7,6 +7,7 @@
<link rel="stylesheet" href="interfaces/default/css/plexwatch-tables.css"> <link rel="stylesheet" href="interfaces/default/css/plexwatch-tables.css">
</%def> </%def>
% if user != None:
<%def name="body()"> <%def name="body()">
<div class="container-fluid"> <div class="container-fluid">
<div class="row-fluid"> <div class="row-fluid">
@ -16,7 +17,7 @@
<img src="interfaces/default/images/gravatar-default-80x80.png"> <img src="interfaces/default/images/gravatar-default-80x80.png">
</div> </div>
<div class="user-info-username"> <div class="user-info-username">
Username ${user}
</div> </div>
<div class="user-info-nav"> <div class="user-info-nav">
<ul class="user-info-nav"> <ul class="user-info-nav">
@ -88,22 +89,49 @@
<div class="wellheader"> <div class="wellheader">
<div class="dashboard-wellheader"> <div class="dashboard-wellheader">
<h3>Public IP Addresses for <strong> <h3>Public IP Addresses for <strong>
Username ${user}
</strong></h3> </strong></h3>
</div> </div>
</div> </div>
<table id="tableUserIpAddresses" class="display" width="100%"> <table id="user_ip_table" class="display" width="100%">
<thead> <thead>
<tr> <tr>
<th align="left"><i class="fa fa-sort"></i> Last seen</th> <th align="left"><i class="fa fa-sort"></i> Last seen</th>
<th align="left"><i class="fa fa-sort"></i> IP Address</th> <th align="left"><i class="fa fa-sort"></i> IP Address</th>
<th align="left"><i class="fa fa-sort"></i> Play Count</th> <th align="left"><i class="fa fa-sort"></i> Play Count</th>
<th align="left"><i class="fa fa-sort"></i> Platform (Last Seen)</th> <th align="left"><i class="fa fa-sort"></i> Platform (Last Seen)</th>
<th align="left"><i class="fa fa-sort"></i> Location</th> <th align="left"> Last Watched</th>
<th align="left"><i class="fa fa-sort"></i> Location</th>
</tr> </tr>
</thead> </thead>
</table> </table>
<div id="ip-info-modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="ip-info-modal" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
<h3 id="myModalLabel">IP Address: <strong><span id="ip_address"></span></strong></h3>
</div>
<div class="modal-body" id="modal-text">
<div class="span6">
<h4>Location Details</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="span6">
<h4>Connection Details</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>
</div> </div>
@ -116,8 +144,8 @@
<div class="wellbg"> <div class="wellbg">
<div class="wellheader"> <div class="wellheader">
<div class="dashboard-wellheader"> <div class="dashboard-wellheader">
<h3>Watching History for <strong> <h3>Watch History for <strong>
Username ${user}
</strong></h3> </strong></h3>
</div> </div>
</div> </div>
@ -143,53 +171,6 @@
</tbody> </tbody>
</table> </table>
<div id="info-modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="info-modal" aria-hidden="true"> <div id="info-modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="info-modal" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
<h3 id="myModalLabel">Stream Info: <strong><span id="modal-stream-info"></span></strong></h3>
</div>
<div class="modal-body" id="modal-text">
<div class="span4">
<h4>Stream Details</h4>
<ul>
<h5>Video</h5>
<li>Stream Type: <strong><span id="transcode_video_dec"></span></strong></li>
<li>Video Resolution: <strong><span id="transcode_video_resolution"></span>p</strong></li>
<li>Video Codec: <strong><span id="transcode_video_codec"></span></strong></li>
<li>Video Width: <strong><span id="transcode_video_width"></span></strong></li>
<li>Video Height: <strong><span id="transcode_video_height"></span></strong></li>
</ul>
<ul>
<h5>Audio</h5>
<li>Stream Type: <strong><span id="transcode_audio_dec"></span></strong></li>
<li>Audio Codec: <strong><span id="transcode_audio_codec"></span></strong></li>
<li>Audio Channels: <strong><span id="transcode_audio_channels"></span></strong></li>
</ul>
</div>
<div class="span4">
<h4>Media Source Details</h4>
<li>Container: <strong><span id="media_container"></span></strong></li>
<li>Resolution: <strong><span id="media_resolution"></span>p</strong></li>
<li>Bitrate: <strong><span id="media_bitrate"></span> kbps</strong></li>
</div>
<div class="span4">
<h4>Video Source Details</h4>
<ul>
<li>Width: <strong><span id="video_width"></span></strong></li>
<li>Height: <strong><span id="video_height"></span></strong></li>
<li>Aspect Ratio: <strong><span id="video_aspect"></span></strong></li>
<li>Video Frame Rate: <strong><span id="video_framerate"></span></strong></li>
<li>Video Codec: <strong><span id="video_codec"></span></strong></li>
</ul>
<ul></ul>
<h4>Audio Source Details</h4>
<ul>
<li>Audio Codec: <strong><span id="audio_codec"></span></strong></li>
<li>Audio Channels: <strong><span id="audio_channels"></span></strong></li>
</ul>
</div>
</div>
<div class="modal-footer">
</div>
</div> </div>
</div> </div>
</div> </div>
@ -204,21 +185,36 @@
<script src="interfaces/default/js/jquery.dataTables.min.js"></script> <script src="interfaces/default/js/jquery.dataTables.min.js"></script>
<script src="interfaces/default/js/jquery.dataTables.bootstrap.pagination.integration.js"></script> <script src="interfaces/default/js/jquery.dataTables.bootstrap.pagination.integration.js"></script>
<script src="interfaces/default/js/moment-with-locale.js"></script> <script src="interfaces/default/js/moment-with-locale.js"></script>
<script src="interfaces/default/js/tables/history_table.js"></script> <script src="interfaces/default/js/tables/history_table.js"></script>
<script src="interfaces/default/js/tables/user_ips.js"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
history_table_options.ajax = { history_table_options.ajax = {
"url": "get_history", "url": "get_history",
"data": function(d) { "data": function(d) {
d.user = "drzoidberg33"; d.user = "${user}";
} }
} }
history_table = $('#history_table').DataTable(history_table_options); history_table = $('#history_table').DataTable(history_table_options);
history_table.column(2).visible(false); // Hide the title column
// Hide the title column user_ip_table_options.ajax = {
// history_table.column(5).visible(false); "url": "get_user_ips",
"data": function(d) {
d.user = "${user}";
}
}
user_ip_table = $('#user_ip_table').DataTable(user_ip_table_options);
}); });
</script> </script>
</%def> </%def>
% else:
<div class="clear"></div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span10 offset1">
<h3>Error retrieving user information. Please see the logs for more details.</h3>
</div>
</div>
</div>
% endif

View file

@ -23,7 +23,7 @@
<div class='row-fluid'> <div class='row-fluid'>
<div class='span12'> <div class='span12'>
<div class='wellbg'> <div class='wellbg'>
<table id="usersTable" class="display" width="100%"> <table id="users_list_table" class="display" width="100%">
<thead> <thead>
<tr> <tr>
<th align="right" id="avatar"></th> <th align="right" id="avatar"></th>
@ -48,79 +48,8 @@
<script src="interfaces/default/js/jquery.dataTables.min.js"></script> <script src="interfaces/default/js/jquery.dataTables.min.js"></script>
<script src="interfaces/default/js/jquery.dataTables.bootstrap.pagination.integration.js"></script> <script src="interfaces/default/js/jquery.dataTables.bootstrap.pagination.integration.js"></script>
<script src="interfaces/default/js/moment-with-locale.js"></script> <script src="interfaces/default/js/moment-with-locale.js"></script>
<script src="interfaces/default/js/tables/users.js"></script>
<script> <script>
$(document).ready(function() { var users_list_table = $('#users_list_table').DataTable(users_list_table_options);
var oTable = $('#usersTable').dataTable({
"language": {
"search": "Search: ",
"lengthMenu":"Show _MENU_ entries per page",
"info":"Showing _START_ to _END_ of _TOTAL_ active users",
"infoEmpty":"Showing 0 to 0 of 0 entries",
"infoFiltered":"",
"emptyTable": "No data in table",
},
"destroy": true,
"processing": false,
"serverSide": true,
"pageLength": 10,
"order": [ 0, 'asc'],
"ajax": {
"url": "get_user_list"
},
"bLengthChange": true,
"bInfo": true,
"bAutoWidth": true,
"aaSorting": [[ 0, "asc" ]],
"bStateSave": true,
"bSortClasses": true,
"sPaginationType": "bootstrap",
"columnDefs": [
{
"targets": [0],
"data": null,
"createdCell": function (td, cellData, rowData, row, col) {
//if (rowData['user_thumb'] === '') {
$(td).html('<img src="interfaces/default/images/gravatar-default-80x80.png" alt="User Logo"/>');
//} else {
// $(td).html('<img src="' + rowData['user_thumb'] + '" alt="User Logo"/>');
//}
},
"orderable": false,
"className": "users-poster-face",
"width": "40px"
},
{
"targets": [1],
"data": "user"
},
{
"targets": [2],
"data": "time",
"render": function ( data, type, full ) {
return moment(data, "X").fromNow();
}
},
{
"targets": [3],
"data": "ip_address",
"searchable": false
},
{
"targets": [4],
"data": "plays"
}
],
"drawCallback": function (settings) {
// Jump to top of page
$('html,body').scrollTop(0);
$('#ajaxMsg').addClass('success').fadeOut();
},
"preDrawCallback": function(settings) {
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>Fetching rows...</div>");
$('#ajaxMsg').addClass('success').fadeIn();
}
});
});
</script> </script>
</%def> </%def>

View file

@ -75,14 +75,14 @@ class DataTables(object):
% (column_data['column_string'], table_name, where, % (column_data['column_string'], table_name, where,
order, custom_where) order, custom_where)
# logger.debug(u"Query string: %s" % query)
filtered = self.ssp_db.select(query) filtered = self.ssp_db.select(query)
if search_value == '': if search_value == '':
totalcount = len(filtered) totalcount = len(filtered)
else: else:
totalcount = self.ssp_db.select('SELECT COUNT(*) from %s' % table_name)[0][0] totalcount = self.ssp_db.select('SELECT COUNT(*) from %s' % table_name)[0][0]
# logger.debug(u"Query string: %s" % query)
result = filtered[start:(start + length)] result = filtered[start:(start + length)]
output = {'result': result, output = {'result': result,
'filteredCount': len(filtered), 'filteredCount': len(filtered),

View file

@ -14,8 +14,8 @@
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>. # along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
from plexpy import logger, helpers, request, datatables, config, db from plexpy import logger, helpers, request, datatables, config, db
from xml.dom import minidom from xml.dom import minidom
import plexpy import plexpy
import json import json
@ -104,6 +104,70 @@ class PlexWatch(object):
return dict return dict
def get_user_unique_ips(self, start='', length='', kwargs=None, custom_where=''):
data_tables = datatables.DataTables()
start = int(start)
length = int(length)
filtered = []
totalcount = 0
search_value = ""
search_regex = ""
order_column = 0
order_dir = "desc"
if 'order[0][dir]' in kwargs:
order_dir = kwargs.get('order[0][dir]', "desc")
if 'order[0][column]' in kwargs:
order_column = kwargs.get('order[0][column]', 1)
if 'search[value]' in kwargs:
search_value = kwargs.get('search[value]', "")
if 'search[regex]' in kwargs:
search_regex = kwargs.get('search[regex]', "")
columns = ['time as last_seen',
'ip_address',
'COUNT(ip_address) as play_count',
'platform',
'user',
'orig_title as last_watched'
]
query = data_tables.ssp_query(table_name=self.get_user_table_name(),
columns=columns,
start=start,
length=length,
order_column=int(order_column),
order_dir=order_dir,
search_value=search_value,
search_regex=search_regex,
custom_where=custom_where,
group_by='ip_address',
kwargs=kwargs)
results = query['result']
rows = []
for item in results:
row = {"last_seen": item['last_seen'],
"ip_address": item['ip_address'],
"play_count": item['play_count'],
"platform": item['platform'],
"last_watched": item['last_watched']
}
rows.append(row)
dict = {'recordsFiltered': query['filteredCount'],
'recordsTotal': query['totalCount'],
'data': rows,
}
return dict
def get_history(self, start='', length='', kwargs=None, custom_where=''): def get_history(self, start='', length='', kwargs=None, custom_where=''):
data_tables = datatables.DataTables() data_tables = datatables.DataTables()

View file

@ -92,11 +92,11 @@ class WebInterface(object):
return serve_template(templatename="users.html", title="Users") return serve_template(templatename="users.html", title="Users")
@cherrypy.expose @cherrypy.expose
def user(self): def user(self, user=None):
return serve_template(templatename="user.html", title="User") return serve_template(templatename="user.html", title="User", user=user)
@cherrypy.expose @cherrypy.expose
def get_stream_data(self, row_id=None, user='', **kwargs): def get_stream_data(self, row_id=None, user=None, **kwargs):
plex_watch = plexwatch.PlexWatch() plex_watch = plexwatch.PlexWatch()
stream_data = plex_watch.get_stream_details(row_id) stream_data = plex_watch.get_stream_details(row_id)
@ -581,3 +581,16 @@ class WebInterface(object):
return result return result
else: else:
logger.warn('Unable to retrieve data.') logger.warn('Unable to retrieve data.')
@cherrypy.expose
def get_user_ips(self, start=0, length=100, custom_where='', **kwargs):
if 'user' in kwargs:
user = kwargs.get('user', "")
custom_where = 'user = "%s"' % user
plex_watch = plexwatch.PlexWatch()
history = plex_watch.get_user_unique_ips(start, length, kwargs, custom_where)
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps(history)