Implement friendly names across entire project scope.

This commit is contained in:
Tim 2015-06-29 21:53:41 +02:00
parent e7b305a1d5
commit 6f7194593b
8 changed files with 121 additions and 66 deletions

View file

@ -30,7 +30,7 @@ from plexpy import helpers
<tr> <tr>
<th class="never" align='left' id="id">ID</th> <th class="never" align='left' id="id">ID</th>
<th class="all" align='left' id="time">Time</th> <th class="all" align='left' id="time">Time</th>
<th class="all" align='left' id="user">User</th> <th class="all" align='left' id="friendly_name">User</th>
<th class="desktop" align='left' id="platform">Platform</th> <th class="desktop" align='left' id="platform">Platform</th>
<th class="desktop" align='left' id="ip_address">IP Address</th> <th class="desktop" align='left' id="ip_address">IP Address</th>
<th class="min-tablet" align='left' id="title">Title</th> <th class="min-tablet" align='left' id="title">Title</th>
@ -41,6 +41,7 @@ from plexpy import helpers
<th class="desktop" align='left' id="percent_complete">Completed</th> <th class="desktop" align='left' id="percent_complete">Completed</th>
<th class="never" align='left' id="rating_key">RatingKey</th> <th class="never" align='left' id="rating_key">RatingKey</th>
<th class="never" align='left' id="xml"></th> <th class="never" align='left' id="xml"></th>
<th class="never" align='left' id="user"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View file

@ -189,7 +189,7 @@ from plexpy import helpers
<tr> <tr>
<th class="never" align='left' id="id">ID</th> <th class="never" align='left' id="id">ID</th>
<th class="all" align='left' id="time">Time</th> <th class="all" align='left' id="time">Time</th>
<th class="all" align='left' id="user">User</th> <th class="all" align='left' id="friendly_name">User</th>
<th class="desktop" align='left' id="platform">Platform</th> <th class="desktop" align='left' id="platform">Platform</th>
<th class="desktop" align='left' id="ip_address">IP Address</th> <th class="desktop" align='left' id="ip_address">IP Address</th>
<th class="min-tablet" align='left' id="title">Title</th> <th class="min-tablet" align='left' id="title">Title</th>
@ -200,6 +200,7 @@ from plexpy import helpers
<th class="desktop" align='left' id="percent_complete">Completed</th> <th class="desktop" align='left' id="percent_complete">Completed</th>
<th class="never" align='left' id="rating_key">RatingKey</th> <th class="never" align='left' id="rating_key">RatingKey</th>
<th class="never" align='left' id="xml"></th> <th class="never" align='left' id="xml"></th>
<th class="never" align='left' id="user"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View file

@ -53,10 +53,10 @@ history_table_options = {
}, },
{ {
"targets": [2], "targets": [2],
"data":"user", "data":"friendly_name",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') { if (cellData !== '') {
$(td).html('<a href="user?user=' + cellData + '">' + cellData + '</a>'); $(td).html('<a href="user?user=' + rowData['user'] + '">' + cellData + '</a>');
} else { } else {
$(td).html(cellData); $(td).html(cellData);
} }
@ -162,7 +162,14 @@ history_table_options = {
"data":"xml", "data":"xml",
"searchable":false, "searchable":false,
"visible":false "visible":false
},
{
"targets": [13],
"data":"user",
"searchable":false,
"visible":false
} }
], ],
"drawCallback": function (settings) { "drawCallback": function (settings) {
// Jump to top of page // Jump to top of page
@ -187,7 +194,7 @@ $('#history_table').on('click', 'td.modal-control', function () {
function showStreamDetails() { function showStreamDetails() {
$.ajax({ $.ajax({
url: 'get_stream_data', url: 'get_stream_data',
data: {row_id: rowData['id'], user: rowData['user']}, data: {row_id: rowData['id'], user: rowData['friendly_name']},
cache: false, cache: false,
async: true, async: true,
complete: function(xhr, status) { complete: function(xhr, status) {

View file

@ -18,12 +18,8 @@ users_list_table_options = {
"ajax": { "ajax": {
"url": "get_user_list" "url": "get_user_list"
}, },
"bLengthChange": true, "autoWidth": true,
"bInfo": true, "stateSave": true,
"bAutoWidth": true,
"aaSorting": [[ 0, "asc" ]],
"bStateSave": true,
"bSortClasses": true,
"sPaginationType": "bootstrap", "sPaginationType": "bootstrap",
"columnDefs": [ "columnDefs": [
{ {
@ -42,10 +38,10 @@ users_list_table_options = {
}, },
{ {
"targets": [1], "targets": [1],
"data": "user", "data": "friendly_name",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') { if (cellData !== '') {
$(td).html('<a href="user?user=' + cellData + '">' + cellData + '</a>'); $(td).html('<a href="user?user=' + rowData['user'] + '">' + cellData + '</a>');
} else { } else {
$(td).html(cellData); $(td).html(cellData);
} }
@ -66,7 +62,14 @@ users_list_table_options = {
{ {
"targets": [4], "targets": [4],
"data": "plays" "data": "plays"
},
{
"targets": [5],
"data": "user",
"searchable": false,
"visible": false
} }
], ],
"drawCallback": function (settings) { "drawCallback": function (settings) {
// Jump to top of page // Jump to top of page

View file

@ -177,7 +177,7 @@ from plexpy import helpers
<tr> <tr>
<th class="never" align='left' id="id">ID</th> <th class="never" align='left' id="id">ID</th>
<th class="all" align='left' id="time">Time</th> <th class="all" align='left' id="time">Time</th>
<th class="never" align='left' id="user">User</th> <th class="never" align='left' id="friendly_name">User</th>
<th class="min-tablet" align='left' id="platform">Platform</th> <th class="min-tablet" align='left' id="platform">Platform</th>
<th class="desktop" align='left' id="ip_address">IP Address</th> <th class="desktop" align='left' id="ip_address">IP Address</th>
<th class="min-tablet" align='left' id="title">Title</th> <th class="min-tablet" align='left' id="title">Title</th>
@ -188,6 +188,7 @@ from plexpy import helpers
<th class="desktop" align='left' id="percent_complete">Completed</th> <th class="desktop" align='left' id="percent_complete">Completed</th>
<th class="never" align='left' id="rating_key">RatingKey</th> <th class="never" align='left' id="rating_key">RatingKey</th>
<th class="never" align='left' id="xml"></th> <th class="never" align='left' id="xml"></th>
<th class="never" align='left' id="user"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View file

@ -28,10 +28,11 @@ from plexpy import helpers
<thead> <thead>
<tr> <tr>
<th class="all" align="right" id="avatar"></th> <th class="all" align="right" id="avatar"></th>
<th class="all" align="left" id="username">User</th> <th class="all" align="left" id="friendly_name">User</th>
<th class="min-tablet" align="left" id="last_seen">Last Seen</th> <th class="min-tablet" align="left" id="last_seen">Last Seen</th>
<th class="min-tablet" align="left" id="last_known_ip">Last Known IP</th> <th class="min-tablet" align="left" id="last_known_ip">Last Known IP</th>
<th class="min-tablet" align="left" id="total_plays">Total Plays</th> <th class="min-tablet" align="left" id="total_plays">Total Plays</th>
<th class="never" align="left" id="user"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View file

@ -39,6 +39,9 @@ class DataTables(object):
search_regex='', search_regex='',
custom_where='', custom_where='',
group_by='', group_by='',
join_type=None,
join_table=None,
join_evals=None,
kwargs=None): kwargs=None):
parameters = self.process_kwargs(kwargs) parameters = self.process_kwargs(kwargs)
@ -50,7 +53,14 @@ class DataTables(object):
column_data = self.extract_columns(columns) column_data = self.extract_columns(columns)
where = self.construct_where(column_data, search_value, grouping, parameters) where = self.construct_where(column_data, search_value, grouping, parameters)
order = self.construct_order(column_data, order_column, order_dir, parameters) order = self.construct_order(column_data, order_column, order_dir, parameters, table_name, grouping)
join = ''
if join_type:
if join_type.upper() == 'LEFT OUTER JOIN':
join = 'LEFT OUTER JOIN %s ON %s = %s' % (join_table, join_evals[0], join_evals[1])
else:
join = ''
# TODO: custom_where is ugly and causes issues with reported total results # TODO: custom_where is ugly and causes issues with reported total results
if custom_where != '': if custom_where != '':
@ -58,21 +68,21 @@ class DataTables(object):
if grouping: if grouping:
if custom_where == '': if custom_where == '':
query = 'SELECT * FROM (SELECT %s FROM %s GROUP BY %s) %s %s' \ query = 'SELECT * FROM (SELECT %s FROM %s %s GROUP BY %s) %s %s' \
% (column_data['column_string'], table_name, group_by, % (column_data['column_string'], table_name, join, group_by,
where, order) where, order)
else: else:
query = 'SELECT * FROM (SELECT * FROM (SELECT %s FROM %s GROUP BY %s) %s %s) %s' \ query = 'SELECT * FROM (SELECT * FROM (SELECT %s FROM %s %s GROUP BY %s) %s %s) %s' \
% (column_data['column_string'], table_name, group_by, % (column_data['column_string'], table_name, join, group_by,
where, order, custom_where) where, order, custom_where)
else: else:
if custom_where == '': if custom_where == '':
query = 'SELECT %s FROM %s %s %s' \ query = 'SELECT %s FROM %s %s %s %s' \
% (column_data['column_string'], table_name, where, % (column_data['column_string'], table_name, join, where,
order) order)
else: else:
query = 'SELECT * FROM (SELECT %s FROM %s %s %s) %s' \ query = 'SELECT * FROM (SELECT %s FROM %s %s %s %s) %s' \
% (column_data['column_string'], table_name, where, % (column_data['column_string'], table_name, join, where,
order, custom_where) order, custom_where)
# logger.debug(u"Query string: %s" % query) # logger.debug(u"Query string: %s" % query)
@ -91,16 +101,23 @@ class DataTables(object):
return output return output
@staticmethod @staticmethod
def construct_order(column_data, order_column, order_dir, parameters=None): def construct_order(column_data, order_column, order_dir, parameters=None, table_name=None, grouped=False):
order = '' order = ''
if grouped:
sort_col = column_data['column_named'][order_column]
else:
sort_col = column_data['column_order'][order_column]
if parameters: if parameters:
for parameter in parameters: for parameter in parameters:
if parameter['data'] != '': if parameter['data'] != '':
if int(order_column) == parameter['index']: if int(order_column) == parameter['index']:
if parameter['data'] in column_data['column_named'] and parameter['orderable'] == 'true': if parameter['data'] in column_data['column_named'] and parameter['orderable'] == 'true':
order = 'ORDER BY %s COLLATE NOCASE %s' % (parameter['data'], order_dir) if table_name and table_name != '':
order = 'ORDER BY %s COLLATE NOCASE %s' % (sort_col, order_dir)
else:
order = 'ORDER BY %s COLLATE NOCASE %s' % (sort_col, order_dir)
else: else:
order = 'ORDER BY %s COLLATE NOCASE %s' % (column_data['column_named'][order_column], order_dir) order = 'ORDER BY %s COLLATE NOCASE %s' % (sort_col, order_dir)
return order return order
@ -112,7 +129,7 @@ class DataTables(object):
for column in column_data['column_named']: for column in column_data['column_named']:
search_skip = False search_skip = False
for parameter in parameters: for parameter in parameters:
if column in parameter['data']: if column.rpartition('.')[-1] in parameter['data']:
if parameter['searchable'] == 'true': if parameter['searchable'] == 'true':
where += column + ' LIKE "%' + search_value + '%" OR ' where += column + ' LIKE "%' + search_value + '%" OR '
search_skip = True search_skip = True
@ -139,6 +156,7 @@ class DataTables(object):
columns_string = '' columns_string = ''
columns_literal = [] columns_literal = []
columns_named = [] columns_named = []
columns_order = []
for column in columns: for column in columns:
columns_string += column columns_string += column
@ -146,23 +164,25 @@ class DataTables(object):
# TODO: make this case insensitive # TODO: make this case insensitive
if ' as ' in column: if ' as ' in column:
columns_literal.append(column.rpartition(' as ')[0]) columns_literal.append(column.rpartition(' as ')[0])
columns_named.append(column.rpartition(' as ')[-1]) columns_named.append(column.rpartition(' as ')[-1].rpartition('.')[-1])
columns_order.append(column.rpartition(' as ')[-1])
else: else:
columns_literal.append(column) columns_literal.append(column)
columns_named.append(column) columns_named.append(column.rpartition('.')[-1])
columns_order.append(column)
columns_string = columns_string[:-2] columns_string = columns_string[:-2]
column_data = {'column_string': columns_string, column_data = {'column_string': columns_string,
'column_literal': columns_literal, 'column_literal': columns_literal,
'column_named': columns_named 'column_named': columns_named,
'column_order': columns_order
} }
return column_data return column_data
# TODO: Fix this method. Should not break if kwarg list is not sorted. # TODO: Fix this method. Should not break if kwarg list is not sorted.
@staticmethod def process_kwargs(self, kwargs):
def process_kwargs(kwargs):
column_parameters = [] column_parameters = []

View file

@ -64,12 +64,16 @@ class PlexWatch(object):
if 'search[regex]' in kwargs: if 'search[regex]' in kwargs:
search_regex = kwargs.get('search[regex]', "") search_regex = kwargs.get('search[regex]', "")
columns = ['user', t = self.get_history_table_name()
'time',
'ip_address', columns = [t + '.id',
'COUNT(title) as plays'] '(case when plexpy_users.friendly_name is null then ' + t + '.user else plexpy_users.friendly_name end) as friendly_name',
t + '.time',
t + '.ip_address',
'COUNT(' + t + '.title) as plays',
t + '.user']
try: try:
query = data_tables.ssp_query(table_name=self.get_history_table_name(), query = data_tables.ssp_query(table_name=t,
columns=columns, columns=columns,
start=start, start=start,
length=length, length=length,
@ -78,7 +82,10 @@ class PlexWatch(object):
search_value=search_value, search_value=search_value,
search_regex=search_regex, search_regex=search_regex,
custom_where='', custom_where='',
group_by='user', group_by=(t + '.user'),
join_type='LEFT OUTER JOIN',
join_table='plexpy_users',
join_evals=[t + '.user', 'plexpy_users.username'],
kwargs=kwargs) kwargs=kwargs)
except: except:
logger.warn("Unable to open PlexWatch database.") logger.warn("Unable to open PlexWatch database.")
@ -94,9 +101,10 @@ class PlexWatch(object):
row = {"plays": item['plays'], row = {"plays": item['plays'],
"time": item['time'], "time": item['time'],
"user": item["user"], "friendly_name": item["friendly_name"],
"ip_address": item["ip_address"], "ip_address": item["ip_address"],
"thumb": thumb['user_thumb'] "thumb": thumb['user_thumb'],
"user": item["user"]
} }
rows.append(row) rows.append(row)
@ -132,12 +140,14 @@ class PlexWatch(object):
if 'search[regex]' in kwargs: if 'search[regex]' in kwargs:
search_regex = kwargs.get('search[regex]', "") search_regex = kwargs.get('search[regex]', "")
columns = ['time as last_seen', t = self.get_history_table_name()
'ip_address',
'COUNT(ip_address) as play_count', columns = [t + '.time as last_seen',
'platform', t + '.user',
'user', t + '.ip_address',
'orig_title as last_watched' 'COUNT(' + t + '.ip_address) as play_count',
t + '.platform',
t + '.title as last_watched'
] ]
try: try:
@ -150,7 +160,10 @@ class PlexWatch(object):
search_value=search_value, search_value=search_value,
search_regex=search_regex, search_regex=search_regex,
custom_where=custom_where, custom_where=custom_where,
group_by='ip_address', group_by=(t + '.ip_address'),
join_type=None,
join_table=None,
join_evals=None,
kwargs=kwargs) kwargs=kwargs)
except: except:
logger.warn("Unable to open PlexWatch database.") logger.warn("Unable to open PlexWatch database.")
@ -190,6 +203,8 @@ class PlexWatch(object):
order_column = 1 order_column = 1
order_dir = "desc" order_dir = "desc"
t = self.get_history_table_name()
if 'order[0][dir]' in kwargs: if 'order[0][dir]' in kwargs:
order_dir = kwargs.get('order[0][dir]', "desc") order_dir = kwargs.get('order[0][dir]', "desc")
@ -202,24 +217,25 @@ class PlexWatch(object):
if 'search[regex]' in kwargs: if 'search[regex]' in kwargs:
search_regex = kwargs.get('search[regex]', "") search_regex = kwargs.get('search[regex]', "")
columns = ['id', columns = [t + '.id',
'time as date', t + '.time as date',
'user', '(case when plexpy_users.friendly_name is null then ' + t + '.user else plexpy_users.friendly_name end) as friendly_name',
'platform', t + '.platform',
'ip_address', t + '.ip_address',
'title', t + '.title',
'time as started', t + '.time as started',
'paused_counter', t + '.paused_counter',
'stopped', t + '.stopped',
'ratingKey as rating_key', 'round((julianday(datetime(' + t + '.stopped, "unixepoch", "localtime")) - \
'xml', julianday(datetime(' + t + '.time, "unixepoch", "localtime"))) * 86400) - \
'round((julianday(datetime(stopped, "unixepoch", "localtime")) - \ (case when ' + t + '.paused_counter is null then 0 else ' + t + '.paused_counter end) as duration',
julianday(datetime(time, "unixepoch", "localtime"))) * 86400) - \ t + '.ratingKey as rating_key',
(case when paused_counter is null then 0 else paused_counter end) as duration', t + '.xml',
'grandparentRatingKey as grandparent_rating_key' t + '.user',
t + '.grandparentRatingKey as grandparent_rating_key'
] ]
try: try:
query = data_tables.ssp_query(table_name=self.get_history_table_name(), query = data_tables.ssp_query(table_name=t,
columns=columns, columns=columns,
start=start, start=start,
length=length, length=length,
@ -229,6 +245,9 @@ class PlexWatch(object):
search_regex=search_regex, search_regex=search_regex,
custom_where=custom_where, custom_where=custom_where,
group_by='', group_by='',
join_type='LEFT OUTER JOIN',
join_table='plexpy_users',
join_evals=[t + '.user', 'plexpy_users.username'],
kwargs=kwargs) kwargs=kwargs)
except: except:
logger.warn("Unable to open PlexWatch database.") logger.warn("Unable to open PlexWatch database.")
@ -243,7 +262,7 @@ class PlexWatch(object):
for item in history: for item in history:
row = {"id": item['id'], row = {"id": item['id'],
"date": item['date'], "date": item['date'],
"user": item["user"], "friendly_name": item['friendly_name'],
"platform": item["platform"], "platform": item["platform"],
"ip_address": item["ip_address"], "ip_address": item["ip_address"],
"title": item["title"], "title": item["title"],
@ -253,7 +272,9 @@ class PlexWatch(object):
"rating_key": item["rating_key"], "rating_key": item["rating_key"],
"duration": item["duration"], "duration": item["duration"],
"percent_complete": 0, "percent_complete": 0,
"xml": ""} "xml": "",
"user": item["user"]
}
if item['paused_counter'] > 0: if item['paused_counter'] > 0:
row['paused_counter'] = item['paused_counter'] row['paused_counter'] = item['paused_counter']