Improve user delete/purge function

This commit is contained in:
JonnyWong16 2020-04-10 13:15:29 -07:00
parent 377a23478e
commit faac6b11c2
No known key found for this signature in database
GPG key ID: B1F1F9807184697A
6 changed files with 128 additions and 121 deletions

View file

@ -167,7 +167,7 @@ $('.user_ip_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['friendly_name'] }, data: { row_id: rowData['history_row_id'], user: rowData['friendly_name'] },
cache: false, cache: false,
async: true, async: true,
complete: function (xhr, status) { complete: function (xhr, status) {

View file

@ -44,8 +44,8 @@ users_list_table_options = {
"data": null, "data": null,
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
$(td).html('<div class="edit-user-toggles">' + $(td).html('<div class="edit-user-toggles">' +
'<button class="btn btn-xs btn-warning delete-user" data-id="' + rowData['user_id'] + '" data-toggle="button"><i class="fa fa-trash-o fa-fw"></i> Delete</button>&nbsp' + '<button class="btn btn-xs btn-warning delete-user" data-id="' + rowData['row_id'] + '" data-toggle="button"><i class="fa fa-trash-o fa-fw"></i> Delete</button>&nbsp' +
'<button class="btn btn-xs btn-warning purge-user" data-id="' + rowData['user_id'] + '" data-toggle="button"><i class="fa fa-eraser fa-fw"></i> Purge</button>&nbsp&nbsp&nbsp' + '<button class="btn btn-xs btn-warning purge-user" data-id="' + rowData['row_id'] + '" data-toggle="button"><i class="fa fa-eraser fa-fw"></i> Purge</button>&nbsp&nbsp&nbsp' +
'<input type="checkbox" id="keep_history-' + rowData['user_id'] + '" name="keep_history" value="1" ' + rowData['keep_history'] + '><label class="edit-tooltip" for="keep_history-' + rowData['user_id'] + '" data-toggle="tooltip" title="Toggle History"><i class="fa fa-history fa-lg fa-fw"></i></label>&nbsp' + '<input type="checkbox" id="keep_history-' + rowData['user_id'] + '" name="keep_history" value="1" ' + rowData['keep_history'] + '><label class="edit-tooltip" for="keep_history-' + rowData['user_id'] + '" data-toggle="tooltip" title="Toggle History"><i class="fa fa-history fa-lg fa-fw"></i></label>&nbsp' +
'<input type="checkbox" id="allow_guest-' + rowData['user_id'] + '" name="allow_guest" value="1" ' + rowData['allow_guest'] + '><label class="edit-tooltip" for="allow_guest-' + rowData['user_id'] + '" data-toggle="tooltip" title="Toggle Guest Access"><i class="fa fa-unlock-alt fa-lg fa-fw"></i></label>&nbsp' + '<input type="checkbox" id="allow_guest-' + rowData['user_id'] + '" name="allow_guest" value="1" ' + rowData['allow_guest'] + '><label class="edit-tooltip" for="allow_guest-' + rowData['user_id'] + '" data-toggle="tooltip" title="Toggle Guest Access"><i class="fa fa-unlock-alt fa-lg fa-fw"></i></label>&nbsp' +
'</div>'); '</div>');
@ -77,7 +77,7 @@ users_list_table_options = {
"data": "friendly_name", "data": "friendly_name",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') { if (cellData !== null && cellData !== '') {
$(td).html('<div class="edit-user-name" data-id="' + rowData['user_id'] + '">' + $(td).html('<div class="edit-user-name" data-id="' + rowData['row_id'] + '">' +
'<a href="' + page('user', rowData['user_id']) + '">' + cellData + '</a>' + '<a href="' + page('user', rowData['user_id']) + '">' + cellData + '</a>' +
'<input type="text" class="hidden" value="' + cellData + '">' + '<input type="text" class="hidden" value="' + cellData + '">' +
'</div>'); '</div>');
@ -256,10 +256,10 @@ users_list_table_options = {
}, },
"rowCallback": function (row, rowData) { "rowCallback": function (row, rowData) {
if ($.inArray(rowData['user_id'], users_to_delete) !== -1) { if ($.inArray(rowData['user_id'], users_to_delete) !== -1) {
$(row).find('button.delete-user[data-id="' + rowData['user_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger'); $(row).find('button.delete-user[data-id="' + rowData['row_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger');
} }
if ($.inArray(rowData['user_id'], users_to_purge) !== -1) { if ($.inArray(rowData['user_id'], users_to_purge) !== -1) {
$(row).find('button.purge-user[data-id="' + rowData['user_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger'); $(row).find('button.purge-user[data-id="' + rowData['row_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger');
} }
} }
} }
@ -270,7 +270,7 @@ $('#users_list_table').on('click', 'td.modal-control', function () {
var rowData = row.data(); var rowData = row.data();
$.get('get_stream_data', { $.get('get_stream_data', {
row_id: rowData['id'], row_id: rowData['history_row_id'],
user: rowData['friendly_name'] user: rowData['friendly_name']
}).then(function (jqXHR) { }).then(function (jqXHR) {
$("#info-modal").html(jqXHR); $("#info-modal").html(jqXHR);
@ -328,11 +328,11 @@ $('#users_list_table').on('click', 'td.edit-control > .edit-user-toggles > butto
var row = users_list_table.row(tr); var row = users_list_table.row(tr);
var rowData = row.data(); var rowData = row.data();
var index_delete = $.inArray(rowData['user_id'], users_to_delete); var index_delete = $.inArray(rowData['row_id'], users_to_delete);
var index_purge = $.inArray(rowData['user_id'], users_to_purge); var index_purge = $.inArray(rowData['row_id'], users_to_purge);
if (index_delete === -1) { if (index_delete === -1) {
users_to_delete.push(rowData['user_id']); users_to_delete.push(rowData['row_id']);
if (index_purge === -1) { if (index_purge === -1) {
tr.find('button.purge-user').click(); tr.find('button.purge-user').click();
} }
@ -351,11 +351,11 @@ $('#users_list_table').on('click', 'td.edit-control > .edit-user-toggles > butto
var row = users_list_table.row(tr); var row = users_list_table.row(tr);
var rowData = row.data(); var rowData = row.data();
var index_delete = $.inArray(rowData['user_id'], users_to_delete); var index_delete = $.inArray(rowData['row_id'], users_to_delete);
var index_purge = $.inArray(rowData['user_id'], users_to_purge); var index_purge = $.inArray(rowData['row_id'], users_to_purge);
if (index_purge === -1) { if (index_purge === -1) {
users_to_purge.push(rowData['user_id']); users_to_purge.push(rowData['row_id']);
} else { } else {
users_to_purge.splice(index_purge, 1); users_to_purge.splice(index_purge, 1);
if (index_delete != -1) { if (index_delete != -1) {

View file

@ -119,14 +119,14 @@
}); });
if (users_to_delete.length > 0) { if (users_to_delete.length > 0) {
$('#users-to-delete').prepend('<p>Are you REALLY sure you want to delete and purge all history for the following users:</p>') $('#users-to-delete').prepend('<p>Are you REALLY sure you want to delete and purge all history for the following users:</p>');
for (var i = 0; i < users_to_delete.length; i++) { for (var i = 0; i < users_to_delete.length; i++) {
$('#users-to-delete').append('<li>' + $('div[data-id=' + users_to_delete[i] + '] > input').val() + '</li>'); $('#users-to-delete').append('<li>' + $('div[data-id=' + users_to_delete[i] + '] > input').val() + '</li>');
} }
} }
if (users_to_purge.length > 0) { if (users_to_purge.length > 0) {
$('#users-to-purge').prepend('<p>Are you REALLY sure you want to purge all history for the following users:</p>') $('#users-to-purge').prepend('<p>Are you REALLY sure you want to purge all history for the following users:</p>');
for (var i = 0; i < users_to_purge.length; i++) { for (var i = 0; i < users_to_purge.length; i++) {
$('#users-to-purge').append('<li>' + $('div[data-id=' + users_to_purge[i] + '] > input').val() + '</li>'); $('#users-to-purge').append('<li>' + $('div[data-id=' + users_to_purge[i] + '] > input').val() + '</li>');
} }
@ -134,11 +134,10 @@
$('#confirm-modal-delete').modal(); $('#confirm-modal-delete').modal();
$('#confirm-modal-delete').one('click', '#confirm-delete', function () { $('#confirm-modal-delete').one('click', '#confirm-delete', function () {
users_to_delete.forEach(function(row, idx) {
$.ajax({ $.ajax({
url: 'delete_user', url: 'delete_user',
type: 'POST', type: 'POST',
data: { user_id: row }, data: { row_ids: users_to_delete.join(',') },
cache: false, cache: false,
async: true, async: true,
success: function (data) { success: function (data) {
@ -146,12 +145,10 @@
showMsg(msg, false, true, 2000); showMsg(msg, false, true, 2000);
} }
}); });
});
users_to_purge.forEach(function(row, idx) {
$.ajax({ $.ajax({
url: 'delete_all_user_history', url: 'delete_all_user_history',
type: 'POST', type: 'POST',
data: { user_id: row }, data: { row_ids: users_to_purge.join(',') },
cache: false, cache: false,
async: true, async: true,
success: function (data) { success: function (data) {
@ -159,7 +156,6 @@
showMsg(msg, false, true, 2000); showMsg(msg, false, true, 2000);
} }
}); });
});
users_list_table.draw(); users_list_table.draw();
}); });
} }
@ -192,7 +188,7 @@
complete: function (xhr, status) { complete: function (xhr, status) {
var result = $.parseJSON(xhr.responseText); var result = $.parseJSON(xhr.responseText);
var msg = result.message; var msg = result.message;
if (result.result == 'success') { if (result.result === 'success') {
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 2000, false); showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 2000, false);
users_list_table.draw(); users_list_table.draw();
} else { } else {

View file

@ -58,14 +58,6 @@ def delete_recently_added():
return clear_table('recently_added') return clear_table('recently_added')
def delete_session_history_rows(row_ids=None):
if row_ids:
for table in ('session_history', 'session_history_media_info', 'session_history_metadata'):
delete_rows_from_table(table=table, row_ids=row_ids)
return True
return False
def delete_rows_from_table(table, row_ids): def delete_rows_from_table(table, row_ids):
if row_ids and isinstance(row_ids, basestring): if row_ids and isinstance(row_ids, basestring):
row_ids = map(helpers.cast_to_int, row_ids.split(',')) row_ids = map(helpers.cast_to_int, row_ids.split(','))
@ -76,6 +68,26 @@ def delete_rows_from_table(table, row_ids):
monitor_db.action(query, row_ids) monitor_db.action(query, row_ids)
def delete_session_history_rows(row_ids=None):
if row_ids:
for table in ('session_history', 'session_history_media_info', 'session_history_metadata'):
delete_rows_from_table(table=table, row_ids=row_ids)
return True
return False
def delete_user_history(user_id=None):
if str(user_id).isdigit():
monitor_db = MonitorDatabase()
# Get all history associated with the user_id
result = monitor_db.select('SELECT id FROM session_history WHERE user_id = ?', [user_id])
row_ids = [row['id'] for row in result]
logger.info(u"Tautulli Database :: Deleting all history for user id %s from database." % user_id)
return delete_session_history_rows(row_ids=row_ids)
def db_filename(filename=FILENAME): def db_filename(filename=FILENAME):
""" Returns the filepath to the db """ """ Returns the filepath to the db """

View file

@ -99,7 +99,8 @@ class Users(object):
group_by = 'session_history.reference_id' if grouping else 'session_history.id' group_by = 'session_history.reference_id' if grouping else 'session_history.id'
columns = ['users.user_id', columns = ['users.id AS row_id',
'users.user_id',
'(CASE WHEN users.friendly_name IS NULL OR TRIM(users.friendly_name) = "" \ '(CASE WHEN users.friendly_name IS NULL OR TRIM(users.friendly_name) = "" \
THEN users.username ELSE users.friendly_name END) AS friendly_name', THEN users.username ELSE users.friendly_name END) AS friendly_name',
'users.thumb AS user_thumb', 'users.thumb AS user_thumb',
@ -109,7 +110,7 @@ class Users(object):
ELSE 0 END) - SUM(CASE WHEN session_history.paused_counter IS NULL THEN 0 ELSE \ ELSE 0 END) - SUM(CASE WHEN session_history.paused_counter IS NULL THEN 0 ELSE \
session_history.paused_counter END) AS duration', session_history.paused_counter END) AS duration',
'MAX(session_history.started) AS last_seen', 'MAX(session_history.started) AS last_seen',
'MAX(session_history.id) AS id', 'MAX(session_history.id) AS history_row_id',
'session_history_metadata.full_title AS last_played', 'session_history_metadata.full_title AS last_played',
'session_history.ip_address', 'session_history.ip_address',
'session_history.platform', 'session_history.platform',
@ -128,10 +129,10 @@ class Users(object):
'session_history_metadata.originally_available_at', 'session_history_metadata.originally_available_at',
'session_history_metadata.guid', 'session_history_metadata.guid',
'session_history_media_info.transcode_decision', 'session_history_media_info.transcode_decision',
'users.do_notify as do_notify', 'users.do_notify AS do_notify',
'users.keep_history as keep_history', 'users.keep_history AS keep_history',
'users.allow_guest as allow_guest', 'users.allow_guest AS allow_guest',
'users.is_active as is_active' 'users.is_active AS is_active'
] ]
try: try:
query = data_tables.ssp_query(table_name='users', query = data_tables.ssp_query(table_name='users',
@ -173,14 +174,15 @@ class Users(object):
# Rename Mystery platform names # Rename Mystery platform names
platform = common.PLATFORM_NAME_OVERRIDES.get(item['platform'], item['platform']) platform = common.PLATFORM_NAME_OVERRIDES.get(item['platform'], item['platform'])
row = {'user_id': item['user_id'], row = {'row_id': item['row_id'],
'user_id': item['user_id'],
'friendly_name': item['friendly_name'], 'friendly_name': item['friendly_name'],
'user_thumb': user_thumb, 'user_thumb': user_thumb,
'plays': item['plays'], 'plays': item['plays'],
'duration': item['duration'], 'duration': item['duration'],
'last_seen': item['last_seen'], 'last_seen': item['last_seen'],
'last_played': item['last_played'], 'last_played': item['last_played'],
'id': item['id'], 'history_row_id': item['history_row_id'],
'ip_address': item['ip_address'], 'ip_address': item['ip_address'],
'platform': platform, 'platform': platform,
'player': item['player'], 'player': item['player'],
@ -225,7 +227,7 @@ class Users(object):
custom_where = ['users.user_id', user_id] custom_where = ['users.user_id', user_id]
columns = ['session_history.id', columns = ['session_history.id AS history_row_id',
'MAX(session_history.started) AS last_seen', 'MAX(session_history.started) AS last_seen',
'session_history.ip_address', 'session_history.ip_address',
'COUNT(session_history.id) AS play_count', 'COUNT(session_history.id) AS play_count',
@ -285,7 +287,7 @@ class Users(object):
# Rename Mystery platform names # Rename Mystery platform names
platform = common.PLATFORM_NAME_OVERRIDES.get(item["platform"], item["platform"]) platform = common.PLATFORM_NAME_OVERRIDES.get(item["platform"], item["platform"])
row = {'id': item['id'], row = {'history_row_id': item['history_row_id'],
'last_seen': item['last_seen'], 'last_seen': item['last_seen'],
'ip_address': item['ip_address'], 'ip_address': item['ip_address'],
'play_count': item['play_count'], 'play_count': item['play_count'],
@ -334,7 +336,8 @@ class Users(object):
logger.warn(u"Tautulli Users :: Unable to execute database query for set_config: %s." % e) logger.warn(u"Tautulli Users :: Unable to execute database query for set_config: %s." % e)
def get_details(self, user_id=None, user=None, email=None): def get_details(self, user_id=None, user=None, email=None):
default_return = {'user_id': 0, default_return = {'row_id': 0,
'user_id': 0,
'username': 'Local', 'username': 'Local',
'friendly_name': 'Local', 'friendly_name': 'Local',
'user_thumb': common.DEFAULT_USER_THUMB, 'user_thumb': common.DEFAULT_USER_THUMB,
@ -359,7 +362,8 @@ class Users(object):
try: try:
if str(user_id).isdigit(): if str(user_id).isdigit():
query = 'SELECT user_id, username, friendly_name, thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \ query = 'SELECT id AS row_id, user_id, username, friendly_name, ' \
'thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \
'email, is_active, is_admin, is_home_user, is_allow_sync, is_restricted, ' \ 'email, is_active, is_admin, is_home_user, is_allow_sync, is_restricted, ' \
'do_notify, keep_history, deleted_user, ' \ 'do_notify, keep_history, deleted_user, ' \
'allow_guest, shared_libraries ' \ 'allow_guest, shared_libraries ' \
@ -367,7 +371,8 @@ class Users(object):
'WHERE user_id = ? ' 'WHERE user_id = ? '
result = monitor_db.select(query, args=[user_id]) result = monitor_db.select(query, args=[user_id])
elif user: elif user:
query = 'SELECT user_id, username, friendly_name, thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \ query = 'SELECT id AS row_id, user_id, username, friendly_name, ' \
'thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \
'email, is_active, is_admin, is_home_user, is_allow_sync, is_restricted, ' \ 'email, is_active, is_admin, is_home_user, is_allow_sync, is_restricted, ' \
'do_notify, keep_history, deleted_user, ' \ 'do_notify, keep_history, deleted_user, ' \
'allow_guest, shared_libraries ' \ 'allow_guest, shared_libraries ' \
@ -375,7 +380,8 @@ class Users(object):
'WHERE username = ? COLLATE NOCASE ' 'WHERE username = ? COLLATE NOCASE '
result = monitor_db.select(query, args=[user]) result = monitor_db.select(query, args=[user])
elif email: elif email:
query = 'SELECT user_id, username, friendly_name, thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \ query = 'SELECT id AS row_id, user_id, username, friendly_name, ' \
'thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \
'email, is_active, is_admin, is_home_user, is_allow_sync, is_restricted, ' \ 'email, is_active, is_admin, is_home_user, is_allow_sync, is_restricted, ' \
'do_notify, keep_history, deleted_user, ' \ 'do_notify, keep_history, deleted_user, ' \
'allow_guest, shared_libraries ' \ 'allow_guest, shared_libraries ' \
@ -407,7 +413,8 @@ class Users(object):
shared_libraries = tuple(item['shared_libraries'].split(';')) if item['shared_libraries'] else () shared_libraries = tuple(item['shared_libraries'].split(';')) if item['shared_libraries'] else ()
user_details = {'user_id': item['user_id'], user_details = {'row_id': item['row_id'],
'user_id': item['user_id'],
'username': item['username'], 'username': item['username'],
'friendly_name': friendly_name, 'friendly_name': friendly_name,
'user_thumb': user_thumb, 'user_thumb': user_thumb,
@ -619,7 +626,7 @@ class Users(object):
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
try: try:
query = 'SELECT user_id, username, friendly_name, thumb, custom_avatar_url, email, ' \ query = 'SELECT id AS row_id, user_id, username, friendly_name, thumb, custom_avatar_url, email, ' \
'is_active, is_admin, is_home_user, is_allow_sync, is_restricted, ' \ 'is_active, is_admin, is_home_user, is_allow_sync, is_restricted, ' \
'do_notify, keep_history, allow_guest, server_token, shared_libraries, ' \ 'do_notify, keep_history, allow_guest, server_token, shared_libraries, ' \
'filter_all, filter_movies, filter_tv, filter_music, filter_photos ' \ 'filter_all, filter_movies, filter_tv, filter_music, filter_photos ' \
@ -631,7 +638,8 @@ class Users(object):
users = [] users = []
for item in result: for item in result:
user = {'user_id': item['user_id'], user = {'row_id': item['row_id'],
'user_id': item['user_id'],
'username': item['username'], 'username': item['username'],
'friendly_name': item['friendly_name'] or item['username'], 'friendly_name': item['friendly_name'] or item['username'],
'thumb': item['custom_avatar_url'] or item['thumb'], 'thumb': item['custom_avatar_url'] or item['thumb'],
@ -656,54 +664,39 @@ class Users(object):
return users return users
def delete_all_history(self, user_id=None): def delete(self, user_id=None, row_ids=None, purge_only=False):
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
try: if row_ids and row_ids is not None:
if str(user_id).isdigit(): row_ids = map(helpers.cast_to_int, row_ids.split(','))
logger.info(u"Tautulli Users :: Deleting all history for user id %s from database." % user_id)
session_history_media_info_del = \
monitor_db.action('DELETE FROM '
'session_history_media_info '
'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id '
'FROM session_history_media_info '
'JOIN session_history ON session_history_media_info.id = session_history.id '
'WHERE session_history.user_id = ?)', [user_id])
session_history_metadata_del = \
monitor_db.action('DELETE FROM '
'session_history_metadata '
'WHERE session_history_metadata.id IN (SELECT session_history_metadata.id '
'FROM session_history_metadata '
'JOIN session_history ON session_history_metadata.id = session_history.id '
'WHERE session_history.user_id = ?)', [user_id])
session_history_del = \
monitor_db.action('DELETE FROM '
'session_history '
'WHERE session_history.user_id = ?', [user_id])
return 'Deleted all items for user_id %s.' % user_id # Get the user_ids corresponding to the row_ids
result = monitor_db.select('SELECT user_id FROM users '
'WHERE id IN ({})'.format(','.join(['?'] * len(row_ids))), row_ids)
user_ids = [user['user_id'] for user in result]
success = []
for user_id in user_ids:
success.append(self.delete(user_id=user_id, purge_only=purge_only))
return all(success)
elif str(user_id).isdigit():
database.delete_user_history(user_id=user_id)
if purge_only:
return True
else: else:
return 'Unable to delete items. Input user_id not valid.' logger.info(u"Tautulli Users :: Deleting user with user_id %s from database." % user_id)
except Exception as e:
logger.warn(u"Tautulli Users :: Unable to execute database query for delete_all_history: %s." % e)
def delete(self, user_id=None):
monitor_db = database.MonitorDatabase()
try: try:
if str(user_id).isdigit(): monitor_db.action('UPDATE users '
self.delete_all_history(user_id) 'SET deleted_user = 1, keep_history = 0, do_notify = 0 '
logger.info(u"Tautulli Users :: Deleting user with id %s from database." % user_id) 'WHERE user_id = ?', [user_id])
monitor_db.action('UPDATE users SET deleted_user = 1 WHERE user_id = ?', [user_id]) return True
monitor_db.action('UPDATE users SET keep_history = 0 WHERE user_id = ?', [user_id])
monitor_db.action('UPDATE users SET do_notify = 0 WHERE user_id = ?', [user_id])
return 'Deleted user with id %s.' % user_id
else:
return 'Unable to delete user, user_id not valid.'
except Exception as e: except Exception as e:
logger.warn(u"Tautulli Users :: Unable to execute database query for delete: %s." % e) logger.warn(u"Tautulli Users :: Unable to execute database query for delete: %s." % e)
else:
return False
def undelete(self, user_id=None, username=None): def undelete(self, user_id=None, username=None):
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()

View file

@ -1417,6 +1417,7 @@ class WebInterface(object):
"is_home_user": 1, "is_home_user": 1,
"is_restricted": 0, "is_restricted": 0,
"keep_history": 1, "keep_history": 1,
"row_id": 1,
"shared_libraries": ["10", "1", "4", "5", "15", "20", "2"], "shared_libraries": ["10", "1", "4", "5", "15", "20", "2"],
"user_id": 133788, "user_id": 133788,
"user_thumb": "https://plex.tv/users/k10w42309cynaopq/avatar", "user_thumb": "https://plex.tv/users/k10w42309cynaopq/avatar",
@ -1529,7 +1530,7 @@ class WebInterface(object):
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def delete_all_user_history(self, user_id, **kwargs): def delete_all_user_history(self, user_id=None, row_ids=None, **kwargs):
""" Delete all Tautulli history for a specific user. """ Delete all Tautulli history for a specific user.
``` ```
@ -1537,25 +1538,27 @@ class WebInterface(object):
user_id (str): The id of the Plex user user_id (str): The id of the Plex user
Optional parameters: Optional parameters:
None row_ids (str): Comma separated row ids to delete, e.g. "2,3,8"
Returns: Returns:
None None
``` ```
""" """
if user_id: if user_id or row_ids:
user_data = users.Users() user_data = users.Users()
delete_row = user_data.delete_all_history(user_id=user_id) success = user_data.delete(user_id=user_id, row_ids=row_ids, purge_only=True)
if delete_row: if success:
return {'message': delete_row} return {'result': 'success', 'message': 'Deleted user history.'}
else: else:
return {'message': 'no data received'} return {'result': 'error', 'message': 'Failed to delete user(s) history.'}
else:
return {'result': 'error', 'message': 'No user id or row ids received.'}
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def delete_user(self, user_id, **kwargs): def delete_user(self, user_id=None, row_ids=None, **kwargs):
""" Delete a user from Tautulli. Also erases all history for the user. """ Delete a user from Tautulli. Also erases all history for the user.
``` ```
@ -1563,19 +1566,21 @@ class WebInterface(object):
user_id (str): The id of the Plex user user_id (str): The id of the Plex user
Optional parameters: Optional parameters:
None row_ids (str): Comma separated row ids to delete, e.g. "2,3,8"
Returns: Returns:
None None
``` ```
""" """
if user_id: if user_id or row_ids:
user_data = users.Users() user_data = users.Users()
delete_row = user_data.delete(user_id=user_id) success = user_data.delete(user_id=user_id, row_ids=row_ids)
if delete_row: if success:
return {'message': delete_row} return {'result': 'success', 'message': 'Deleted user.'}
else: else:
return {'message': 'no data received'} return {'result': 'error', 'message': 'Failed to delete user(s).'}
else:
return {'result': 'error', 'message': 'No user id or row ids received.'}
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@ -5427,6 +5432,7 @@ class WebInterface(object):
"is_home_user": 1, "is_home_user": 1,
"is_restricted": 0, "is_restricted": 0,
"keep_history": 1, "keep_history": 1,
"row_id": 1,
"server_token": "PU9cMuQZxJKFBtGqHk68", "server_token": "PU9cMuQZxJKFBtGqHk68",
"shared_libraries": "1;2;3", "shared_libraries": "1;2;3",
"thumb": "https://plex.tv/users/k10w42309cynaopq/avatar", "thumb": "https://plex.tv/users/k10w42309cynaopq/avatar",