mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-15 01:32:57 -07:00
Merge branch 'nightly' into python3
# Conflicts: # plexpy/database.py # plexpy/version.py
This commit is contained in:
commit
3ca4351aeb
10 changed files with 116 additions and 53 deletions
28
CHANGELOG.md
28
CHANGELOG.md
|
@ -1,5 +1,33 @@
|
|||
# Changelog
|
||||
|
||||
## v2.2.2-beta (2020-04-12)
|
||||
|
||||
* Notifications:
|
||||
* New: Added notification trigger for Tautulli database corruption.
|
||||
* New: Added TAUTULLI_PYTHON_VERSION to script notification environment variables.
|
||||
* Fix: Notification grouping by season/album and show/artist not enabled by default.
|
||||
* Change: The file size notification parameter is now reported in SI units. (Thanks @aaronldunlap)
|
||||
* UI:
|
||||
* Fix: Delete lookup info from the media info page failing.
|
||||
* New: Added icon on the users table to indicate if the user is not on the Plex server.
|
||||
* New: Added icon on the libraries table to indicate if the library is not on the Plex server.
|
||||
* Fix: XBMC platform icon not being redirected to the Kodi platform icon.
|
||||
* Change: Improved deleting libraries so libraries with the same section ID are not also deleted.
|
||||
* API:
|
||||
* Fix: Returning XML for the API failing due to unicode characters.
|
||||
* Fix: Grouping parameter for various API commands not falling back to default setting.
|
||||
* New: Added time_queries parameter to get_library_watch_time_stats and get_user_watch_time_stats API command. (Thanks @KaasKop97)
|
||||
* New: Added an "is_active" return value to the get_user, get_users, get_library, and get_libraries API commands which indicates if the user or library is on the Plex server.
|
||||
* New: Added delete_history API command.
|
||||
* Change: Added optional parameter for row_ids for delete_library, delete_user, delete_all_library_history, and delete_all_user_history API commands.
|
||||
* Mobile App:
|
||||
* Fix: Temporary device token not being invalidated after cancelling device registration.
|
||||
* Other:
|
||||
* Fix: Update failing on CentOS due to an older git version.
|
||||
* Fix: Manifest file for creating a web app had incorrect info.
|
||||
* New: Docker images updated to support ARM platforms.
|
||||
|
||||
|
||||
## v2.2.1 (2020-03-28)
|
||||
|
||||
* Notifications:
|
||||
|
|
|
@ -131,17 +131,6 @@
|
|||
|
||||
$('#confirm-modal-delete').modal();
|
||||
$('#confirm-modal-delete').one('click', '#confirm-delete', function () {
|
||||
$.ajax({
|
||||
url: 'delete_library',
|
||||
type: 'POST',
|
||||
data: { row_ids: libraries_to_delete.join(',') },
|
||||
cache: false,
|
||||
async: true,
|
||||
success: function (data) {
|
||||
var msg = "Library deleted";
|
||||
showMsg(msg, false, true, 2000);
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: 'delete_all_library_history',
|
||||
type: 'POST',
|
||||
|
@ -151,9 +140,21 @@
|
|||
success: function (data) {
|
||||
var msg = "Library history purged";
|
||||
showMsg(msg, false, true, 2000);
|
||||
libraries_list_table.draw();
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: 'delete_library',
|
||||
type: 'POST',
|
||||
data: { row_ids: libraries_to_delete.join(',') },
|
||||
cache: false,
|
||||
async: true,
|
||||
success: function (data) {
|
||||
var msg = "Library deleted";
|
||||
showMsg(msg, false, true, 2000);
|
||||
libraries_list_table.draw();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -134,17 +134,6 @@
|
|||
|
||||
$('#confirm-modal-delete').modal();
|
||||
$('#confirm-modal-delete').one('click', '#confirm-delete', function () {
|
||||
$.ajax({
|
||||
url: 'delete_user',
|
||||
type: 'POST',
|
||||
data: { row_ids: users_to_delete.join(',') },
|
||||
cache: false,
|
||||
async: true,
|
||||
success: function (data) {
|
||||
var msg = "User deleted";
|
||||
showMsg(msg, false, true, 2000);
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: 'delete_all_user_history',
|
||||
type: 'POST',
|
||||
|
@ -154,9 +143,21 @@
|
|||
success: function (data) {
|
||||
var msg = "User history purged";
|
||||
showMsg(msg, false, true, 2000);
|
||||
users_list_table.draw();
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: 'delete_user',
|
||||
type: 'POST',
|
||||
data: { row_ids: users_to_delete.join(',') },
|
||||
cache: false,
|
||||
async: true,
|
||||
success: function (data) {
|
||||
var msg = "User deleted";
|
||||
showMsg(msg, false, true, 2000);
|
||||
users_list_table.draw();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ class API2(object):
|
|||
self._api_app = True
|
||||
|
||||
if plexpy.CONFIG.API_ENABLED and not self._api_msg or self._api_cmd in ('get_apikey', 'docs', 'docs_md'):
|
||||
if self._api_apikey == plexpy.CONFIG.API_KEY or (self._api_app and self._api_apikey == mobile_app.TEMP_DEVICE_TOKEN):
|
||||
if self._api_apikey == plexpy.CONFIG.API_KEY or (self._api_app and self._api_apikey == mobile_app.get_temp_device_token()):
|
||||
self._api_authenticated = True
|
||||
|
||||
elif self._api_app and mobile_app.get_mobile_device_by_token(self._api_apikey):
|
||||
|
@ -420,7 +420,7 @@ class API2(object):
|
|||
if result:
|
||||
self._api_msg = 'Device registration successful.'
|
||||
self._api_result_type = 'success'
|
||||
mobile_app.TEMP_DEVICE_TOKEN = None
|
||||
mobile_app.set_temp_device_token(None)
|
||||
else:
|
||||
self._api_msg = 'Device registartion failed: database error.'
|
||||
self._api_result_type = 'error'
|
||||
|
|
|
@ -70,18 +70,26 @@ def delete_rows_from_table(table, row_ids):
|
|||
if row_ids and isinstance(row_ids, str):
|
||||
row_ids = list(map(cast_to_int, row_ids.split(',')))
|
||||
|
||||
if row_ids:
|
||||
logger.info("Tautulli Database :: Deleting row ids %s from %s database table", row_ids, table)
|
||||
query = "DELETE FROM " + table + " WHERE id IN (%s) " % ','.join(['?'] * len(row_ids))
|
||||
monitor_db = MonitorDatabase()
|
||||
|
||||
try:
|
||||
monitor_db.action(query, row_ids)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error("Tautulli Database :: Failed to delete rows from %s database table: %s" % (table, e))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def delete_session_history_rows(row_ids=None):
|
||||
if row_ids:
|
||||
success = []
|
||||
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
|
||||
success.append(delete_rows_from_table(table=table, row_ids=row_ids))
|
||||
return all(success)
|
||||
|
||||
|
||||
def delete_user_history(user_id=None):
|
||||
|
@ -97,19 +105,18 @@ def delete_user_history(user_id=None):
|
|||
return delete_session_history_rows(row_ids=row_ids)
|
||||
|
||||
|
||||
def delete_library_history(server_id=None, section_id=None):
|
||||
if server_id and str(section_id).isdigit():
|
||||
def delete_library_history(section_id=None):
|
||||
if str(section_id).isdigit():
|
||||
monitor_db = MonitorDatabase()
|
||||
|
||||
# Get all history associated with the server_id and section_id
|
||||
# Get all history associated with the section_id
|
||||
result = monitor_db.select('SELECT session_history.id FROM session_history '
|
||||
'JOIN session_history_metadata ON session_history.id = session_history_metadata.id '
|
||||
'WHERE session_history.server_id = ? AND session_history_metadata.section_id = ?',
|
||||
[server_id, section_id])
|
||||
'WHERE session_history_metadata.section_id = ?',
|
||||
[section_id])
|
||||
row_ids = [row['id'] for row in result]
|
||||
|
||||
logger.info("Tautulli Database :: Deleting all history for library server_id %s and section_id %s from database."
|
||||
% (server_id, section_id))
|
||||
logger.info("Tautulli Database :: Deleting all history for library section_id %s from database." % section_id)
|
||||
return delete_session_history_rows(row_ids=row_ids)
|
||||
|
||||
|
||||
|
|
|
@ -1058,9 +1058,16 @@ class Libraries(object):
|
|||
|
||||
elif str(section_id).isdigit():
|
||||
server_id = server_id or plexpy.CONFIG.PMS_IDENTIFIER
|
||||
database.delete_library_history(server_id=server_id, section_id=section_id)
|
||||
if server_id == plexpy.CONFIG.PMS_IDENTIFIER:
|
||||
delete_success = database.delete_library_history(section_id=section_id)
|
||||
else:
|
||||
logger.warn("Tautulli Libraries :: Library history not deleted for library section_id %s "
|
||||
"because library server_id %s does not match Plex server identifier %s."
|
||||
% (section_id, server_id, plexpy.CONFIG.PMS_IDENTIFIER))
|
||||
delete_success = True
|
||||
|
||||
if purge_only:
|
||||
return True
|
||||
return delete_success
|
||||
else:
|
||||
logger.info("Tautulli Libraries :: Deleting library with server_id %s and section_id %s from database."
|
||||
% (server_id, section_id))
|
||||
|
@ -1068,7 +1075,7 @@ class Libraries(object):
|
|||
monitor_db.action('UPDATE library_sections '
|
||||
'SET deleted_section = 1, keep_history = 0, do_notify = 0, do_notify_created = 0 '
|
||||
'WHERE server_id = ? AND section_id = ?', [server_id, section_id])
|
||||
return True
|
||||
return delete_success
|
||||
except Exception as e:
|
||||
logger.warn("Tautulli Libraries :: Unable to execute database query for delete: %s." % e)
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
from __future__ import unicode_literals
|
||||
from future.builtins import str
|
||||
|
||||
import time
|
||||
import threading
|
||||
|
||||
import plexpy
|
||||
if plexpy.PYTHON2:
|
||||
|
@ -32,6 +32,24 @@ else:
|
|||
|
||||
|
||||
TEMP_DEVICE_TOKEN = None
|
||||
INVALIDATE_TIMER = None
|
||||
|
||||
|
||||
def set_temp_device_token(token=None):
|
||||
global TEMP_DEVICE_TOKEN
|
||||
TEMP_DEVICE_TOKEN = token
|
||||
|
||||
if TEMP_DEVICE_TOKEN is not None:
|
||||
global INVALIDATE_TIMER
|
||||
if INVALIDATE_TIMER:
|
||||
INVALIDATE_TIMER.cancel()
|
||||
invalidate_time = 5 * 60 # 5 minutes
|
||||
INVALIDATE_TIMER = threading.Timer(invalidate_time, set_temp_device_token, args=[None])
|
||||
INVALIDATE_TIMER.start()
|
||||
|
||||
|
||||
def get_temp_device_token():
|
||||
return TEMP_DEVICE_TOKEN
|
||||
|
||||
|
||||
def get_mobile_devices(device_id=None, device_token=None):
|
||||
|
|
|
@ -698,9 +698,10 @@ class Users(object):
|
|||
return all(success)
|
||||
|
||||
elif str(user_id).isdigit():
|
||||
database.delete_user_history(user_id=user_id)
|
||||
delete_success = database.delete_user_history(user_id=user_id)
|
||||
|
||||
if purge_only:
|
||||
return True
|
||||
return delete_success
|
||||
else:
|
||||
logger.info("Tautulli Users :: Deleting user with user_id %s from database."
|
||||
% user_id)
|
||||
|
@ -708,7 +709,7 @@ class Users(object):
|
|||
monitor_db.action('UPDATE users '
|
||||
'SET deleted_user = 1, keep_history = 0, do_notify = 0 '
|
||||
'WHERE user_id = ?', [user_id])
|
||||
return True
|
||||
return delete_success
|
||||
except Exception as e:
|
||||
logger.warn("Tautulli Users :: Unable to execute database query for delete: %s." % e)
|
||||
|
||||
|
|
|
@ -18,4 +18,4 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
PLEXPY_BRANCH = "python3"
|
||||
PLEXPY_RELEASE_VERSION = "v2.2.1"
|
||||
PLEXPY_RELEASE_VERSION = "v2.2.2-beta"
|
||||
|
|
|
@ -3674,12 +3674,12 @@ class WebInterface(object):
|
|||
@requireAuth(member_of("admin"))
|
||||
def verify_mobile_device(self, device_token='', cancel=False, **kwargs):
|
||||
if helpers.bool_true(cancel):
|
||||
mobile_app.TEMP_DEVICE_TOKEN = None
|
||||
mobile_app.set_temp_device_token(None)
|
||||
return {'result': 'error', 'message': 'Device registration cancelled.'}
|
||||
|
||||
result = mobile_app.get_mobile_device_by_token(device_token)
|
||||
if result:
|
||||
mobile_app.TEMP_DEVICE_TOKEN = None
|
||||
mobile_app.set_temp_device_token(None)
|
||||
return {'result': 'success', 'message': 'Device registered successfully.', 'data': result}
|
||||
else:
|
||||
return {'result': 'error', 'message': 'Device not registered.'}
|
||||
|
@ -3966,7 +3966,7 @@ class WebInterface(object):
|
|||
logger._BLACKLIST_WORDS.add(apikey)
|
||||
|
||||
if helpers.bool_true(device):
|
||||
mobile_app.TEMP_DEVICE_TOKEN = apikey
|
||||
mobile_app.set_temp_device_token(apikey)
|
||||
|
||||
return apikey
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue