A new first run setup wizard (WIP)

Move all user related links to use user_id instead of username.
Remove excess debug loggin.
Catch more exceptions on PW importer.
This commit is contained in:
Tim 2015-07-17 00:31:46 +02:00
parent 96f48291e5
commit 4f00ecc070
20 changed files with 7975 additions and 94 deletions

View file

@ -53,6 +53,7 @@ _CONFIG_DEFINITIONS = {
'EMAIL_SMTP_PORT': (int, 'Email', 25),
'EMAIL_TLS': (int, 'Email', 0),
'ENABLE_HTTPS': (int, 'General', 0),
'FIRST_RUN_COMPLETE': (int, 'General', 0),
'FREEZE_DB': (int, 'General', 0),
'GIT_BRANCH': (str, 'General', 'master'),
'GIT_PATH': (str, 'General', ''),

View file

@ -73,13 +73,13 @@ class DataFactory(object):
search_value=search_value,
search_regex=search_regex,
custom_where='',
group_by=(t1 + '.user'),
group_by=(t1 + '.user_id'),
join_type=['LEFT OUTER JOIN'],
join_table=['users'],
join_evals=[[t1 + '.user', 'users.username']],
join_evals=[[t1 + '.user_id', 'users.user_id']],
kwargs=kwargs)
except:
logger.warn("Unable to open session_history table.")
logger.warn("Unable to execute database query.")
return {'recordsFiltered': 0,
'recordsTotal': 0,
'data': 'null'},
@ -159,7 +159,8 @@ class DataFactory(object):
t1 + '.rating_key as rating_key',
t1 + '.user',
t2 + '.media_type',
t4 + '.video_decision'
t4 + '.video_decision',
t1 + '.user_id as user_id'
]
try:
query = data_tables.ssp_query(table_name=t1,
@ -179,7 +180,7 @@ class DataFactory(object):
[t1 + '.id', t4 + '.id']],
kwargs=kwargs)
except:
logger.warn("Unable to open PlexWatch database.")
logger.warn("Unable to execute database query.")
return {'recordsFiltered': 0,
'recordsTotal': 0,
'data': 'null'},
@ -205,6 +206,7 @@ class DataFactory(object):
"user": item["user"],
"media_type": item["media_type"],
"video_decision": item["video_decision"],
"user_id": item["user_id"]
}
if item['paused_counter'] > 0:
@ -260,7 +262,8 @@ class DataFactory(object):
'COUNT(session_history.ip_address) as play_count',
'session_history.player as platform',
'session_history_metadata.full_title as last_watched',
'session_history.user as user'
'session_history.user as user',
'session_history.user_id as user_id'
]
try:
@ -304,7 +307,19 @@ class DataFactory(object):
return dict
def set_user_friendly_name(self, user=None, friendly_name=None):
def set_user_friendly_name(self, user=None, user_id=None, friendly_name=None):
if user_id:
if friendly_name.strip() == '':
friendly_name = None
monitor_db = database.MonitorDatabase()
control_value_dict = {"user_id": user_id}
new_value_dict = {"friendly_name": friendly_name}
try:
monitor_db.upsert('users', new_value_dict, control_value_dict)
except Exception, e:
logger.debug(u"Uncaught exception %s" % e)
if user:
if friendly_name.strip() == '':
friendly_name = None
@ -318,18 +333,51 @@ class DataFactory(object):
except Exception, e:
logger.debug(u"Uncaught exception %s" % e)
def get_user_friendly_name(self, user=None):
if user:
def get_user_friendly_name(self, user=None, user_id=None):
if user_id:
try:
monitor_db = database.MonitorDatabase()
query = 'select friendly_name FROM users WHERE username = ?'
result = monitor_db.select_single(query, args=[user])
query = 'select username, ' \
'(CASE WHEN friendly_name IS NULL THEN username ELSE friendly_name END) ' \
'FROM users WHERE user_id = ?'
result = monitor_db.select(query, args=[user_id])
if result:
return result
user_detail = {'user_id': user_id,
'user': result[0][0],
'friendly_name': result[0][1]}
return user_detail
else:
return user
user_detail = {'user_id': user_id,
'user': '',
'friendly_name': ''}
return user_detail
except:
return user
user_detail = {'user_id': user_id,
'user': '',
'friendly_name': ''}
return user_detail
elif user:
try:
monitor_db = database.MonitorDatabase()
query = 'select user_id, ' \
'(CASE WHEN friendly_name IS NULL THEN username ELSE friendly_name END) ' \
'FROM users WHERE username = ?'
result = monitor_db.select(query, args=[user])
if result:
user_detail = {'user_id': result[0][0],
'user': user,
'friendly_name': result[0][1]}
return user_detail
else:
user_detail = {'user_id': None,
'user': user,
'friendly_name': ''}
return user_detail
except:
user_detail = {'user_id': None,
'user': user,
'friendly_name': ''}
return user_detail
return None
@ -608,7 +656,7 @@ class DataFactory(object):
return stream_output
def get_recently_watched(self, user=None, limit='10'):
def get_recently_watched(self, user=None, user_id=None, limit='10'):
monitor_db = database.MonitorDatabase()
recently_watched = []
@ -616,7 +664,14 @@ class DataFactory(object):
limit = '10'
try:
if user:
if user_id:
query = 'SELECT session_history.media_type, session_history.rating_key, title, thumb, parent_thumb, ' \
'media_index, parent_media_index, year, started, user ' \
'FROM session_history_metadata ' \
'JOIN session_history ON session_history_metadata.id = session_history.id ' \
'WHERE user_id = ? ORDER BY started DESC LIMIT ?'
result = monitor_db.select(query, args=[user_id, limit])
elif user:
query = 'SELECT session_history.media_type, session_history.rating_key, title, thumb, parent_thumb, ' \
'media_index, parent_media_index, year, started, user ' \
'FROM session_history_metadata ' \
@ -654,7 +709,7 @@ class DataFactory(object):
return recently_watched
def get_user_watch_time_stats(self, user=None):
def get_user_watch_time_stats(self, user=None, user_id=None):
monitor_db = database.MonitorDatabase()
time_queries = [1, 7, 30, 0]
@ -662,13 +717,22 @@ class DataFactory(object):
for days in time_queries:
if days > 0:
query = 'SELECT (SUM(stopped - started) - ' \
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
'COUNT(id) AS total_plays ' \
'FROM session_history ' \
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
'AND user = ?' % days
result = monitor_db.select(query, args=[user])
if user_id:
query = 'SELECT (SUM(stopped - started) - ' \
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
'COUNT(id) AS total_plays ' \
'FROM session_history ' \
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
'AND user_id = ?' % days
result = monitor_db.select(query, args=[user_id])
elif user:
query = 'SELECT (SUM(stopped - started) - ' \
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
'COUNT(id) AS total_plays ' \
'FROM session_history ' \
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
'AND user = ?' % days
result = monitor_db.select(query, args=[user])
else:
query = 'SELECT (SUM(stopped - started) - ' \
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
@ -694,19 +758,27 @@ class DataFactory(object):
return user_watch_time_stats
def get_user_platform_stats(self, user=None):
def get_user_platform_stats(self, user=None, user_id=None):
monitor_db = database.MonitorDatabase()
platform_stats = []
result_id = 0
try:
query = 'SELECT player, COUNT(player) as player_count, platform ' \
'FROM session_history ' \
'WHERE user = ? ' \
'GROUP BY player ' \
'ORDER BY player_count DESC'
result = monitor_db.select(query, args=[user])
if user_id:
query = 'SELECT player, COUNT(player) as player_count, platform ' \
'FROM session_history ' \
'WHERE user_id = ? ' \
'GROUP BY player ' \
'ORDER BY player_count DESC'
result = monitor_db.select(query, args=[user_id])
else:
query = 'SELECT player, COUNT(player) as player_count, platform ' \
'FROM session_history ' \
'WHERE user = ? ' \
'GROUP BY player ' \
'ORDER BY player_count DESC'
result = monitor_db.select(query, args=[user])
except:
logger.warn("Unable to execute database query.")
return None

View file

@ -27,7 +27,6 @@ class DataTables(object):
def __init__(self):
self.ssp_db = database.MonitorDatabase()
logger.debug(u"Database initilised!")
# TODO: Pass all parameters via kwargs
def ssp_query(self, table_name,
@ -71,8 +70,6 @@ class DataTables(object):
join_iter += 1
join += join_item
logger.debug(u"join string = %s" % join)
# TODO: custom_where is ugly and causes issues with reported total results
if custom_where != '':
custom_where = 'WHERE (' + custom_where + ')'
@ -96,7 +93,7 @@ class DataTables(object):
% (column_data['column_string'], table_name, join, where,
order, custom_where)
logger.debug(u"Query string: %s" % query)
# logger.debug(u"Query string: %s" % query)
filtered = self.ssp_db.select(query)
if search_value == '':

View file

@ -206,6 +206,9 @@ def validate_database(database=None, table_name=None):
except ValueError:
logger.error('PlexPy Importer :: Invalid database specified.')
return 'Invalid database specified.'
except:
logger.error('PlexPy Importer :: Uncaught exception.')
return 'Uncaught exception.'
try:
connection.execute('SELECT ratingKey from %s' % table_name)
@ -213,6 +216,9 @@ def validate_database(database=None, table_name=None):
except sqlite3.OperationalError:
logger.error('PlexPy Importer :: Invalid database specified.')
return 'Invalid database specified.'
except:
logger.error('PlexPy Importer :: Uncaught exception.')
return 'Uncaught exception.'
return 'success'

View file

@ -57,12 +57,42 @@ class WebInterface(object):
@cherrypy.expose
def index(self):
raise cherrypy.HTTPRedirect("home")
if plexpy.CONFIG.FIRST_RUN_COMPLETE:
raise cherrypy.HTTPRedirect("home")
else:
raise cherrypy.HTTPRedirect("welcome")
@cherrypy.expose
def home(self):
return serve_template(templatename="index.html", title="Home")
@cherrypy.expose
def welcome(self, **kwargs):
config = {
"launch_browser": checked(plexpy.CONFIG.LAUNCH_BROWSER),
"refresh_users_on_startup": checked(plexpy.CONFIG.REFRESH_USERS_ON_STARTUP),
"pms_ip": plexpy.CONFIG.PMS_IP,
"pms_port": plexpy.CONFIG.PMS_PORT,
"pms_token": plexpy.CONFIG.PMS_TOKEN,
"pms_uuid": plexpy.CONFIG.PMS_UUID,
"tv_notify_enable": checked(plexpy.CONFIG.TV_NOTIFY_ENABLE),
"movie_notify_enable": checked(plexpy.CONFIG.MOVIE_NOTIFY_ENABLE),
"music_notify_enable": checked(plexpy.CONFIG.MUSIC_NOTIFY_ENABLE),
"tv_notify_on_start": checked(plexpy.CONFIG.TV_NOTIFY_ON_START),
"movie_notify_on_start": checked(plexpy.CONFIG.MOVIE_NOTIFY_ON_START),
"music_notify_on_start": checked(plexpy.CONFIG.MUSIC_NOTIFY_ON_START),
"video_logging_enable": checked(plexpy.CONFIG.VIDEO_LOGGING_ENABLE),
"music_logging_enable": checked(plexpy.CONFIG.MUSIC_LOGGING_ENABLE),
"logging_ignore_interval": plexpy.CONFIG.LOGGING_IGNORE_INTERVAL
}
# The setup wizard just refreshes the page on submit so we must redirect to home if config set.
# Also redirecting to home if a PMS token already exists - will remove this in future.
if plexpy.CONFIG.FIRST_RUN_COMPLETE or plexpy.CONFIG.PMS_TOKEN:
raise cherrypy.HTTPRedirect("home")
else:
return serve_template(templatename="welcome.html", title="Welcome", config=config)
@cherrypy.expose
def get_date_formats(self):
if plexpy.CONFIG.DATE_FORMAT:
@ -104,40 +134,57 @@ class WebInterface(object):
return serve_template(templatename="sync.html", title="Synced Items")
@cherrypy.expose
def user(self, user=None):
try:
data_factory = datafactory.DataFactory()
user_details = data_factory.get_user_details(user=user)
except:
logger.warn("Unable to retrieve friendly name for user %s " % user)
def user(self, user=None, user_id=None):
if user_id:
try:
data_factory = datafactory.DataFactory()
user_details = data_factory.get_user_details(user_id=user_id)
except:
logger.warn("Unable to retrieve friendly name for user_id %s " % user_id)
elif user:
try:
data_factory = datafactory.DataFactory()
user_details = data_factory.get_user_details(user=user)
except:
logger.warn("Unable to retrieve friendly name for user %s " % user)
else:
logger.debug(u"User page requested but no parameters received.")
raise cherrypy.HTTPRedirect("home")
return serve_template(templatename="user.html", title="User", data=user_details)
@cherrypy.expose
def edit_user_dialog(self, user=None, **kwargs):
if user:
try:
data_factory = datafactory.DataFactory()
result = {'user': user,
'friendly_name': data_factory.get_user_friendly_name(user)
}
status_message = ""
except:
result = {'user': user,
'friendly_name': ''
}
status_message = "There was an error."
return serve_template(templatename="edit_user.html", title="Edit User", data=result, status_message=status_message)
def edit_user_dialog(self, user=None, user_id=None, **kwargs):
if user_id:
data_factory = datafactory.DataFactory()
result = data_factory.get_user_friendly_name(user_id=user_id)
status_message = ''
elif user:
data_factory = datafactory.DataFactory()
result = data_factory.get_user_friendly_name(user=user)
status_message = ''
else:
return serve_template(templatename="edit_user.html", title="Edit User", data=user, status_message='Unknown error.')
result = None
status_message = 'An error occured.'
return serve_template(templatename="edit_user.html", title="Edit User", data=result, status_message=status_message)
@cherrypy.expose
def edit_user(self, user=None, friendly_name=None, **kwargs):
def edit_user(self, user=None, user_id=None, friendly_name=None, **kwargs):
if user_id:
try:
data_factory = datafactory.DataFactory()
data_factory.set_user_friendly_name(user_id=user_id, friendly_name=friendly_name)
status_message = "Successfully updated user."
return status_message
except:
status_message = "Failed to update user."
return status_message
if user:
try:
data_factory = datafactory.DataFactory()
data_factory.set_user_friendly_name(user, friendly_name)
data_factory.set_user_friendly_name(user=user, friendly_name=friendly_name)
status_message = "Successfully updated user."
return status_message
@ -376,8 +423,9 @@ class WebInterface(object):
kwargs[checked_config] = 0
# If http password exists in config, do not overwrite when blank value received
if kwargs['http_password'] == ' ' and plexpy.CONFIG.HTTP_PASSWORD != '':
kwargs['http_password'] = plexpy.CONFIG.HTTP_PASSWORD
if 'http_password' in kwargs:
if kwargs['http_password'] == ' ' and plexpy.CONFIG.HTTP_PASSWORD != '':
kwargs['http_password'] = plexpy.CONFIG.HTTP_PASSWORD
for plain_config, use_config in [(x[4:], x) for x in kwargs if x.startswith('use_')]:
# the use prefix is fairly nice in the html, but does not match the actual config
@ -405,10 +453,12 @@ class WebInterface(object):
message=message, timer=timer)
@cherrypy.expose
def get_history(self, start=0, length=100, custom_where='', **kwargs):
def get_history(self, start=0, length=100, user=None, user_id=None, **kwargs):
if 'user' in kwargs:
user = kwargs.get('user', "")
custom_where=''
if user_id:
custom_where = 'user_id = "%s"' % user_id
elif user:
custom_where = 'user = "%s"' % user
if 'rating_key' in kwargs:
rating_key = kwargs.get('rating_key', "")
@ -603,10 +653,10 @@ class WebInterface(object):
logger.warn('Unable to retrieve data.')
@cherrypy.expose
def get_user_recently_watched(self, user=None, limit='10', **kwargs):
def get_user_recently_watched(self, user=None, user_id=None, limit='10', **kwargs):
data_factory = datafactory.DataFactory()
result = data_factory.get_recently_watched(user=user, limit=limit)
result = data_factory.get_recently_watched(user_id=user_id, user=user, limit=limit)
if result:
return serve_template(templatename="user_recently_watched.html", data=result,
@ -617,10 +667,10 @@ class WebInterface(object):
logger.warn('Unable to retrieve data.')
@cherrypy.expose
def get_user_watch_time_stats(self, user=None, **kwargs):
def get_user_watch_time_stats(self, user=None, user_id=None, **kwargs):
data_factory = datafactory.DataFactory()
result = data_factory.get_user_watch_time_stats(user=user)
result = data_factory.get_user_watch_time_stats(user_id=user_id, user=user)
if result:
return serve_template(templatename="user_watch_time_stats.html", data=result, title="Watch Stats")
@ -629,10 +679,10 @@ class WebInterface(object):
logger.warn('Unable to retrieve data.')
@cherrypy.expose
def get_user_platform_stats(self, user=None, **kwargs):
def get_user_platform_stats(self, user=None, user_id=None, **kwargs):
data_factory = datafactory.DataFactory()
result = data_factory.get_user_platform_stats(user=user)
result = data_factory.get_user_platform_stats(user_id=user_id, user=user)
if result:
return serve_template(templatename="user_platform_stats.html", data=result,
@ -702,10 +752,12 @@ class WebInterface(object):
logger.warn('Unable to retrieve data.')
@cherrypy.expose
def get_user_ips(self, start=0, length=100, custom_where='', **kwargs):
def get_user_ips(self, start=0, length=100, user_id=None, user=None, **kwargs):
if 'user' in kwargs:
user = kwargs.get('user', "")
custom_where=''
if user_id:
custom_where = 'user_id = "%s"' % user_id
elif user:
custom_where = 'user = "%s"' % user
data_factory = datafactory.DataFactory()
@ -939,4 +991,4 @@ class WebInterface(object):
@cherrypy.expose
def plexwatch_import(self, **kwargs):
return serve_template(templatename="plexwatch_import.html", title="Import PlexWatch Database")
return serve_template(templatename="plexwatch_import.html", title="Import PlexWatch Database")