Filter all library and user data for guests

This commit is contained in:
JonnyWong16 2016-04-25 23:51:34 -07:00
parent d462ebe8e5
commit c0a5a8d775
13 changed files with 382 additions and 246 deletions

View file

@ -1791,7 +1791,7 @@ a:hover .item-children-poster {
height: 80px; height: 80px;
width: 80px; width: 80px;
} }
.library-user-instance-box:hover { a .library-user-instance-box:hover {
-webkit-box-shadow: inset 0 0 0 2px #e9a049; -webkit-box-shadow: inset 0 0 0 2px #e9a049;
-moz-box-shadow: inset 0 0 0 2px #e9a049; -moz-box-shadow: inset 0 0 0 2px #e9a049;
box-shadow: inset 0 0 0 2px #e9a049; box-shadow: inset 0 0 0 2px #e9a049;

View file

@ -540,12 +540,10 @@ DOCUMENTATION :: END
<h4> <h4>
% if top_stat['rows'][0]['user_id']: % if top_stat['rows'][0]['user_id']:
<a href="user?user_id=${top_stat['rows'][0]['user_id']}" title="${top_stat['rows'][0]['friendly_name']}"> <a href="user?user_id=${top_stat['rows'][0]['user_id']}" title="${top_stat['rows'][0]['friendly_name']}">
% elif top_stat['rows'][0]['user']:
<a href="user?user=${top_stat['rows'][0]['user']}" title="${top_stat['rows'][0]['friendly_name']}">
% endif
${top_stat['rows'][0]['friendly_name']} ${top_stat['rows'][0]['friendly_name']}
% if top_stat['rows'][0]['user_id'] or top_stat['rows'][0]['user']:
</a> </a>
% else:
${top_stat['rows'][0]['friendly_name']}
% endif % endif
</h4> </h4>
% if top_stat['stat_type'] == 'total_plays': % if top_stat['stat_type'] == 'total_plays':
@ -558,8 +556,6 @@ DOCUMENTATION :: END
</div> </div>
% if top_stat['rows'][0]['user_id']: % if top_stat['rows'][0]['user_id']:
<a href="user?user_id=${top_stat['rows'][0]['user_id']}" title="${top_stat['rows'][0]['friendly_name']}"> <a href="user?user_id=${top_stat['rows'][0]['user_id']}" title="${top_stat['rows'][0]['friendly_name']}">
% elif top_stat['rows'][0]['user']:
<a href="user?user=${top_stat['rows'][0]['user']}" title="${top_stat['rows'][0]['friendly_name']}">
% endif % endif
% if top_stat['rows'][0]['user_thumb'] != '': % if top_stat['rows'][0]['user_thumb'] != '':
<div class="home-platforms-instance-poster"> <div class="home-platforms-instance-poster">
@ -570,7 +566,7 @@ DOCUMENTATION :: END
<div class="home-platforms-instance-oval" style="background-image: url(${http_root}images/gravatar-default.png);"></div> <div class="home-platforms-instance-oval" style="background-image: url(${http_root}images/gravatar-default.png);"></div>
</div> </div>
% endif % endif
% if top_stat['rows'][0]['user_id'] or top_stat['rows'][0]['user']: % if top_stat['rows'][0]['user_id']:
</a> </a>
% endif % endif
% if len(top_stat['rows']) > 1: % if len(top_stat['rows']) > 1:
@ -586,12 +582,10 @@ DOCUMENTATION :: END
<h5> <h5>
% if top_stat['rows'][loop.index]['user_id']: % if top_stat['rows'][loop.index]['user_id']:
<a href="user?user_id=${top_stat['rows'][loop.index]['user_id']}" title="${top_stat['rows'][loop.index]['friendly_name']}"> <a href="user?user_id=${top_stat['rows'][loop.index]['user_id']}" title="${top_stat['rows'][loop.index]['friendly_name']}">
% elif top_stat['rows'][loop.index]['user']:
<a href="user?user=${top_stat['rows'][loop.index]['user']}" title="${top_stat['rows'][loop.index]['friendly_name']}">
% endif
${top_stat['rows'][loop.index]['friendly_name']} ${top_stat['rows'][loop.index]['friendly_name']}
% if top_stat['rows'][loop.index]['user_id'] or top_stat['rows'][loop.index]['user']:
</a> </a>
% else:
${top_stat['rows'][loop.index]['friendly_name']}
% endif % endif
</h5> </h5>
</div> </div>
@ -606,8 +600,6 @@ DOCUMENTATION :: END
</div> </div>
% if top_stat['rows'][loop.index]['user_id']: % if top_stat['rows'][loop.index]['user_id']:
<a href="user?user_id=${top_stat['rows'][loop.index]['user_id']}" title="${top_stat['rows'][loop.index]['friendly_name']}"> <a href="user?user_id=${top_stat['rows'][loop.index]['user_id']}" title="${top_stat['rows'][loop.index]['friendly_name']}">
% elif top_stat['rows'][loop.index]['user']:
<a href="user?user=${top_stat['rows'][loop.index]['user']}" title="${top_stat['rows'][loop.index]['friendly_name']}">
% endif % endif
% if top_stat['rows'][loop.index]['user_thumb'] != '': % if top_stat['rows'][loop.index]['user_thumb'] != '':
<div class="home-platforms-instance-poster"> <div class="home-platforms-instance-poster">
@ -618,7 +610,7 @@ DOCUMENTATION :: END
<div class="home-platforms-instance-list-oval" style="background-image: url(${http_root}images/gravatar-default.png);"></div> <div class="home-platforms-instance-list-oval" style="background-image: url(${http_root}images/gravatar-default.png);"></div>
</div> </div>
% endif % endif
% if top_stat['rows'][loop.index]['user_id'] or top_stat['rows'][loop.index]['user']: % if top_stat['rows'][loop.index]['user_id']:
</a> </a>
% endif % endif
<div class="home-platforms-instance-list-number"> <div class="home-platforms-instance-list-number">
@ -711,11 +703,11 @@ DOCUMENTATION :: END
<h5> <h5>
% if top_stat['rows'][0]['user_id']: % if top_stat['rows'][0]['user_id']:
<a href="user?user_id=${top_stat['rows'][0]['user_id']}" title="${top_stat['rows'][0]['friendly_name']}"> <a href="user?user_id=${top_stat['rows'][0]['user_id']}" title="${top_stat['rows'][0]['friendly_name']}">
% else:
<a href="user?user=${top_stat['rows'][0]['user']}" title="${top_stat['rows'][0]['friendly_name']}">
% endif
${top_stat['rows'][0]['friendly_name']} ${top_stat['rows'][0]['friendly_name']}
</a> </a>
% else:
${top_stat['rows'][0]['friendly_name']}
% endif
</h5> </h5>
<p> <p>
<span id="last-watch-stat"> <span id="last-watch-stat">
@ -757,11 +749,11 @@ DOCUMENTATION :: END
<h5> <h5>
% if top_stat['rows'][loop.index]['user_id']: % if top_stat['rows'][loop.index]['user_id']:
<a href="user?user_id=${top_stat['rows'][loop.index]['user_id']}" title="${top_stat['rows'][loop.index]['friendly_name']}"> <a href="user?user_id=${top_stat['rows'][loop.index]['user_id']}" title="${top_stat['rows'][loop.index]['friendly_name']}">
% else:
<a href="user?user=${top_stat['rows'][loop.index]['user']}" title="${top_stat['rows'][loop.index]['friendly_name']}">
% endif
${top_stat['rows'][loop.index]['friendly_name']} ${top_stat['rows'][loop.index]['friendly_name']}
</a> </a>
% else:
${top_stat['rows'][loop.index]['friendly_name']}
% endif
</h5> </h5>
<p> <p>
<span id="home-platforms-instance-list-last-watch-${loop.index + 1}"> <span id="home-platforms-instance-list-last-watch-${loop.index + 1}">

View file

@ -181,10 +181,12 @@ DOCUMENTATION :: END
</div> </div>
<div class="button-bar"> <div class="button-bar">
<div class="colvis-button-bar hidden-xs" id="button-bar-history"></div> <div class="colvis-button-bar hidden-xs" id="button-bar-history"></div>
% if _session['user_group'] == 'admin':
<button class="btn btn-danger btn-edit" data-toggle="button" aria-pressed="false" autocomplete="off" id="row-edit-mode"> <button class="btn btn-danger btn-edit" data-toggle="button" aria-pressed="false" autocomplete="off" id="row-edit-mode">
<i class="fa fa-trash-o"></i> Delete mode <i class="fa fa-trash-o"></i> Delete mode
</button> </button>
<div class="alert alert-danger alert-edit" role="alert" id="row-edit-mode-alert"><i class="fa fa-exclamation-triangle"></i>&nbspSelect rows to delete. Data is deleted upon exiting delete mode.</div> <div class="alert alert-danger alert-edit" role="alert" id="row-edit-mode-alert"><i class="fa fa-exclamation-triangle"></i>&nbspSelect rows to delete. Data is deleted upon exiting delete mode.</div>
% endif
</div> </div>
</div> </div>
<div class="table-card-back"> <div class="table-card-back">

View file

@ -10,9 +10,9 @@ Variable names: data [array]
data[array_index] :: Usable parameters data[array_index] :: Usable parameters
== Global keys == == Global keys ==
user Returns the name of the user. friendly_name Returns the friendly name of the user.
user_id Returns the user id of the user. user_id Returns the user id of the user.
thumb Returns the avatar of the user. user_thumb Returns the avatar of the user.
total_plays Returns the play count for the user. total_plays Returns the play count for the user.
DOCUMENTATION :: END DOCUMENTATION :: END
@ -23,12 +23,19 @@ DOCUMENTATION :: END
<ul class="list-unstyled"> <ul class="list-unstyled">
<div class="user-player-instance"> <div class="user-player-instance">
<li> <li>
<a href="user?user_id=${a['user_id']}" title="${a['user']}"> % if a['user_id']:
<div class="library-user-instance-box" style="background-image: url(${a['thumb']});"></div> <a href="user?user_id=${a['user_id']}" title="${a['friendly_name']}">
<div class="library-user-instance-box" style="background-image: url(${a['user_thumb']});"></div>
</a> </a>
<div class=" user-player-instance-name"> <div class=" user-player-instance-name">
<a href="user?user_id=${a['user_id']}" title="${a['user']}">${a['user']}</a> <a href="user?user_id=${a['user_id']}" title="${a['friendly_name']}">${a['friendly_name']}</a>
</div> </div>
% else:
<div class="library-user-instance-box" style="background-image: url(${a['user_thumb']});"></div>
<div class=" user-player-instance-name">
${a['friendly_name']}
</div>
% endif
<div class="user-player-instance-playcount"> <div class="user-player-instance-playcount">
<h3>${a['total_plays']}</h3> <h3>${a['total_plays']}</h3>
<p> plays</p> <p> plays</p>

View file

@ -13,10 +13,10 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# 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, datatables, common, database, helpers
import datetime import datetime
from plexpy import logger, datatables, common, database, helpers, session
class DataFactory(object): class DataFactory(object):
""" """
@ -29,6 +29,23 @@ class DataFactory(object):
def get_datatables_history(self, kwargs=None, custom_where=None, grouping=0, watched_percent=85): def get_datatables_history(self, kwargs=None, custom_where=None, grouping=0, watched_percent=85):
data_tables = datatables.DataTables() data_tables = datatables.DataTables()
if session.get_session_user_id():
session_user_id = str(session.get_session_user_id())
added = False
for c_where in custom_where:
if 'user_id' in c_where[0]:
# This currently only works if c_where[1] is not a list or tuple
if str(c_where[1]) == session_user_id:
added = True
break
else:
c_where[1] = (c_where[1], session_user_id)
added = True
if not added:
custom_where = [['session_history.user_id', session.get_session_user_id()]]
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 = ['session_history.reference_id', columns = ['session_history.reference_id',
@ -148,7 +165,7 @@ class DataFactory(object):
dict = {'recordsFiltered': query['filteredCount'], dict = {'recordsFiltered': query['filteredCount'],
'recordsTotal': query['totalCount'], 'recordsTotal': query['totalCount'],
'data': helpers.filter_session_info(rows, 'user_id'), 'data': rows,
'draw': query['draw'], 'draw': query['draw'],
'filter_duration': helpers.human_duration(filter_duration, sig='dhm'), 'filter_duration': helpers.human_duration(filter_duration, sig='dhm'),
'total_duration': helpers.human_duration(total_duration, sig='dhm') 'total_duration': helpers.human_duration(total_duration, sig='dhm')
@ -162,6 +179,13 @@ class DataFactory(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'
sort_type = 'total_plays' if stats_type == 0 else 'total_duration' sort_type = 'total_plays' if stats_type == 0 else 'total_duration'
library_cond = ''
if session.get_session_libraries():
library_cond = 'AND ('
for section_id in session.get_session_libraries():
library_cond += 'session_history_metadata.section_id = %s OR ' % section_id
library_cond = library_cond.rstrip(' OR ') + ')'
home_stats = [] home_stats = []
for stat in stats_cards: for stat in stats_cards:
@ -177,11 +201,11 @@ class DataFactory(object):
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ ' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ ' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
' >= datetime("now", "-%s days", "localtime") ' \ ' >= datetime("now", "-%s days", "localtime") ' \
' AND session_history.media_type = "episode" ' \ ' AND session_history.media_type = "episode" %s ' \
' GROUP BY %s) AS t ' \ ' GROUP BY %s) AS t ' \
'GROUP BY t.grandparent_title ' \ 'GROUP BY t.grandparent_title ' \
'ORDER BY %s DESC ' \ 'ORDER BY %s DESC ' \
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count) 'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
result = monitor_db.select(query) result = monitor_db.select(query)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_tv: %s." % e) logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_tv: %s." % e)
@ -207,7 +231,7 @@ class DataFactory(object):
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_type': sort_type, 'stat_type': sort_type,
'rows': helpers.filter_session_info(top_tv, 'section_id')}) 'rows': session.mask_session_info(top_tv, mask_metadata=True)})
elif stat == 'popular_tv': elif stat == 'popular_tv':
popular_tv = [] popular_tv = []
@ -222,11 +246,11 @@ class DataFactory(object):
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ ' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ ' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
' >= datetime("now", "-%s days", "localtime") ' \ ' >= datetime("now", "-%s days", "localtime") ' \
' AND session_history.media_type = "episode" ' \ ' AND session_history.media_type = "episode" %s ' \
' GROUP BY %s) AS t ' \ ' GROUP BY %s) AS t ' \
'GROUP BY t.grandparent_title ' \ 'GROUP BY t.grandparent_title ' \
'ORDER BY users_watched DESC, %s DESC ' \ 'ORDER BY users_watched DESC, %s DESC ' \
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count) 'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
result = monitor_db.select(query) result = monitor_db.select(query)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_tv: %s." % e) logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_tv: %s." % e)
@ -250,7 +274,7 @@ class DataFactory(object):
popular_tv.append(row) popular_tv.append(row)
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'rows': helpers.filter_session_info(popular_tv, 'section_id')}) 'rows': session.mask_session_info(popular_tv, mask_metadata=True)})
elif stat == 'top_movies': elif stat == 'top_movies':
top_movies = [] top_movies = []
@ -264,11 +288,11 @@ class DataFactory(object):
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ ' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ ' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
' >= datetime("now", "-%s days", "localtime") ' \ ' >= datetime("now", "-%s days", "localtime") ' \
' AND session_history.media_type = "movie" ' \ ' AND session_history.media_type = "movie" %s ' \
' GROUP BY %s) AS t ' \ ' GROUP BY %s) AS t ' \
'GROUP BY t.full_title ' \ 'GROUP BY t.full_title ' \
'ORDER BY %s DESC ' \ 'ORDER BY %s DESC ' \
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count) 'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
result = monitor_db.select(query) result = monitor_db.select(query)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_movies: %s." % e) logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_movies: %s." % e)
@ -291,9 +315,10 @@ class DataFactory(object):
'row_id': item['id'] 'row_id': item['id']
} }
top_movies.append(row) top_movies.append(row)
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_type': sort_type, 'stat_type': sort_type,
'rows': helpers.filter_session_info(top_movies, 'section_id')}) 'rows': session.mask_session_info(top_movies, mask_metadata=True)})
elif stat == 'popular_movies': elif stat == 'popular_movies':
popular_movies = [] popular_movies = []
@ -308,11 +333,11 @@ class DataFactory(object):
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ ' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ ' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
' >= datetime("now", "-%s days", "localtime") ' \ ' >= datetime("now", "-%s days", "localtime") ' \
' AND session_history.media_type = "movie" ' \ ' AND session_history.media_type = "movie" %s ' \
' GROUP BY %s) AS t ' \ ' GROUP BY %s) AS t ' \
'GROUP BY t.full_title ' \ 'GROUP BY t.full_title ' \
'ORDER BY users_watched DESC, %s DESC ' \ 'ORDER BY users_watched DESC, %s DESC ' \
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count) 'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
result = monitor_db.select(query) result = monitor_db.select(query)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_movies: %s." % e) logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_movies: %s." % e)
@ -336,7 +361,7 @@ class DataFactory(object):
popular_movies.append(row) popular_movies.append(row)
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'rows': helpers.filter_session_info(popular_movies, 'section_id')}) 'rows': session.mask_session_info(popular_movies, mask_metadata=True)})
elif stat == 'top_music': elif stat == 'top_music':
top_music = [] top_music = []
@ -350,11 +375,11 @@ class DataFactory(object):
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ ' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ ' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
' >= datetime("now", "-%s days", "localtime") ' \ ' >= datetime("now", "-%s days", "localtime") ' \
' AND session_history.media_type = "track" ' \ ' AND session_history.media_type = "track" %s ' \
' GROUP BY %s) AS t ' \ ' GROUP BY %s) AS t ' \
'GROUP BY t.grandparent_title ' \ 'GROUP BY t.grandparent_title ' \
'ORDER BY %s DESC ' \ 'ORDER BY %s DESC ' \
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count) 'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
result = monitor_db.select(query) result = monitor_db.select(query)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_music: %s." % e) logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_music: %s." % e)
@ -380,7 +405,7 @@ class DataFactory(object):
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_type': sort_type, 'stat_type': sort_type,
'rows': helpers.filter_session_info(top_music, 'section_id')}) 'rows': session.mask_session_info(top_music, mask_metadata=True)})
elif stat == 'popular_music': elif stat == 'popular_music':
popular_music = [] popular_music = []
@ -395,11 +420,11 @@ class DataFactory(object):
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ ' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ ' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
' >= datetime("now", "-%s days", "localtime") ' \ ' >= datetime("now", "-%s days", "localtime") ' \
' AND session_history.media_type = "track" ' \ ' AND session_history.media_type = "track" %s ' \
' GROUP BY %s) AS t ' \ ' GROUP BY %s) AS t ' \
'GROUP BY t.grandparent_title ' \ 'GROUP BY t.grandparent_title ' \
'ORDER BY users_watched DESC, %s DESC ' \ 'ORDER BY users_watched DESC, %s DESC ' \
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count) 'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
result = monitor_db.select(query) result = monitor_db.select(query)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_music: %s." % e) logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_music: %s." % e)
@ -423,7 +448,7 @@ class DataFactory(object):
popular_music.append(row) popular_music.append(row)
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'rows': helpers.filter_session_info(popular_music, 'section_id')}) 'rows': session.mask_session_info(popular_music, mask_metadata=True)})
elif stat == 'top_users': elif stat == 'top_users':
top_users = [] top_users = []
@ -476,7 +501,7 @@ class DataFactory(object):
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_type': sort_type, 'stat_type': sort_type,
'rows': helpers.mask_session_info(top_users)}) 'rows': session.mask_session_info(top_users, mask_metadata=True)})
elif stat == 'top_platforms': elif stat == 'top_platforms':
top_platform = [] top_platform = []
@ -522,13 +547,13 @@ class DataFactory(object):
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_type': sort_type, 'stat_type': sort_type,
'rows': top_platform}) 'rows': session.mask_session_info(top_platform, mask_metadata=True)})
elif stat == 'last_watched': elif stat == 'last_watched':
last_watched = [] last_watched = []
try: try:
query = 'SELECT t.id, t.full_title, t.rating_key, t.thumb, t.grandparent_thumb, ' \ query = 'SELECT t.id, t.full_title, t.rating_key, t.thumb, t.grandparent_thumb, ' \
't.user, t.user_id, t.custom_avatar_url as user_thumb, t.player, ' \ 't.user, t.user_id, t.custom_avatar_url as user_thumb, t.player, t.section_id, ' \
'(CASE WHEN t.friendly_name IS NULL THEN t.username ELSE t.friendly_name END) ' \ '(CASE WHEN t.friendly_name IS NULL THEN t.username ELSE t.friendly_name END) ' \
' AS friendly_name, ' \ ' AS friendly_name, ' \
'MAX(t.started) AS last_watch, ' \ 'MAX(t.started) AS last_watch, ' \
@ -541,12 +566,12 @@ class DataFactory(object):
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \ ' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
' >= datetime("now", "-%s days", "localtime") ' \ ' >= datetime("now", "-%s days", "localtime") ' \
' AND (session_history.media_type = "movie" ' \ ' AND (session_history.media_type = "movie" ' \
' OR session_history_metadata.media_type = "episode") ' \ ' OR session_history_metadata.media_type = "episode") %s ' \
' GROUP BY %s) AS t ' \ ' GROUP BY %s) AS t ' \
'WHERE percent_complete >= %s ' \ 'WHERE percent_complete >= %s ' \
'GROUP BY t.id ' \ 'GROUP BY t.id ' \
'ORDER BY last_watch DESC ' \ 'ORDER BY last_watch DESC ' \
'LIMIT %s' % (time_range, group_by, notify_watched_percent, stats_count) 'LIMIT %s' % (time_range, library_cond, group_by, notify_watched_percent, stats_count)
result = monitor_db.select(query) result = monitor_db.select(query)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: last_watched: %s." % e) logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: last_watched: %s." % e)
@ -567,13 +592,14 @@ class DataFactory(object):
'rating_key': item['rating_key'], 'rating_key': item['rating_key'],
'thumb': thumb, 'thumb': thumb,
'grandparent_thumb': item['grandparent_thumb'], 'grandparent_thumb': item['grandparent_thumb'],
'section_id': item['section_id'],
'last_watch': item['last_watch'], 'last_watch': item['last_watch'],
'player': item['player'] 'player': item['player']
} }
last_watched.append(row) last_watched.append(row)
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'rows': helpers.filter_session_info(last_watched, 'user_id')}) 'rows': session.mask_session_info(last_watched, mask_metadata=True)})
elif stat == 'most_concurrent': elif stat == 'most_concurrent':
@ -692,19 +718,24 @@ class DataFactory(object):
} }
library_stats.append(library) library_stats.append(library)
return helpers.filter_session_info(library_stats, 'section_id') return session.filter_session_info(library_stats, 'section_id')
def get_stream_details(self, row_id=None): def get_stream_details(self, row_id=None):
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
user_cond = ''
if session.get_session_user_id():
user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
if row_id: if row_id:
query = 'SELECT container, bitrate, video_resolution, width, height, aspect_ratio, video_framerate, ' \ query = 'SELECT container, bitrate, video_resolution, width, height, aspect_ratio, video_framerate, ' \
'video_codec, audio_codec, audio_channels, video_decision, transcode_video_codec, transcode_height, ' \ 'video_codec, audio_codec, audio_channels, video_decision, transcode_video_codec, transcode_height, ' \
'transcode_width, audio_decision, transcode_audio_codec, transcode_audio_channels, media_type, ' \ 'transcode_width, audio_decision, transcode_audio_codec, transcode_audio_channels, ' \
'title, grandparent_title ' \ 'session_history_metadata.media_type, title, grandparent_title ' \
'from session_history_media_info ' \ 'FROM session_history_media_info ' \
'join session_history_metadata on session_history_media_info.id = session_history_metadata.id ' \ 'JOIN session_history ON session_history_media_info.id = session_history.id ' \
'where session_history_media_info.id = ?' 'JOIN session_history_metadata ON session_history_media_info.id = session_history_metadata.id ' \
'WHERE session_history_media_info.id = ? %s' % user_cond
result = monitor_db.select(query, args=[row_id]) result = monitor_db.select(query, args=[row_id])
else: else:
return None return None

View file

@ -89,16 +89,15 @@ class DataTables(object):
# Build custom where parameters # Build custom where parameters
if custom_where: if custom_where:
for w in custom_where: for w in custom_where:
c_where += w[0] + ' = ? AND ' if isinstance(w[1], (list, tuple)) and len(w[1]):
c_where += '('
# The order of our args changes if we are grouping for w_ in w[1]:
#if grouping: c_where += w[0] + ' = ? OR '
# args.insert(0, w[1]) args.append(w_)
#else: c_where = c_where.rstrip(' OR ') + ') AND '
# args.append(w[1]) else:
c_where += w[0] + ' = ? AND '
# My testing shows that order of args doesn't change args.append(w[1])
args.append(w[1])
if c_where: if c_where:
c_where = 'WHERE ' + c_where.rstrip(' AND ') c_where = 'WHERE ' + c_where.rstrip(' AND ')

View file

@ -563,104 +563,4 @@ def uploadToImgur(imgPath, imgTitle=''):
except (urllib2.HTTPError, urllib2.URLError) as e: except (urllib2.HTTPError, urllib2.URLError) as e:
logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur: %s" % e) logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur: %s" % e)
return img_url return img_url
def allow_session_user(user_id):
"""
Returns True or False if the user_id is allowed for the user session
"""
import cherrypy
from plexpy.webauth import SESSION_KEY
if cherrypy.config.get('tools.auth.on'):
_session = cherrypy.session.get(SESSION_KEY)
if str(user_id) != _session['user_id']:
return False
return True
def allow_session_library(section_id):
"""
Returns True or False if the section_id is allowed for the user session
"""
import cherrypy
from plexpy.webauth import SESSION_KEY
if cherrypy.config.get('tools.auth.on'):
_session = cherrypy.session.get(SESSION_KEY)
if str(section_id) not in _session['user_libraries']:
return False
return True
def filter_session_info(list_of_dicts, filter_key=None):
"""
Filters a list of dictionary items to only return the info for the current logged in user
"""
import cherrypy
from plexpy.webauth import SESSION_KEY
if cherrypy.config.get('tools.auth.on'):
_session = cherrypy.session.get(SESSION_KEY)
if filter_key == 'user_id' and _session['user_id']:
session_user_id = str(_session['user_id'])
return [d for d in list_of_dicts if str(d.get('user_id','')) == session_user_id]
elif filter_key == 'section_id' and _session['user_libraries']:
session_library_ids = _session['user_libraries']
return [d for d in list_of_dicts if str(d.get('section_id','')) in session_library_ids]
return list_of_dicts
def mask_session_info(list_of_dicts, mask_metadata=False):
"""
Masks user info in a list of dictionary items to only display info for the current logged in user
"""
import cherrypy
from plexpy.webauth import SESSION_KEY
if cherrypy.config.get('tools.auth.on'):
_session = cherrypy.session.get(SESSION_KEY)
keys_to_mask = {'user_id': '',
'user': '',
'friendly_name': 'Plex User',
'user_thumb': common.DEFAULT_USER_THUMB,
'ip_address': 'N/A',
'machine_id': ''
}
metadata_to_mask = {'media_index': '',
'parent_media_index': '',
'art': common.DEFAULT_ART,
'parent_thumb': common.DEFAULT_POSTER_THUMB,
'grandparent_thumb': common.DEFAULT_POSTER_THUMB,
'thumb': common.DEFAULT_POSTER_THUMB,
'bif_thumb': '',
'grandparent_title': '',
'parent_title': '',
'title': '',
'rating_key': '',
'parent_rating_key': '',
'grandparent_rating_key': '',
'year': ''
}
if _session['user_id']:
session_user_id = str(_session['user_id'])
session_library_ids = _session['user_libraries']
for d in list_of_dicts:
if not (str(d.get('user_id')) == session_user_id or d.get('user') == _session['user']):
for k, v in keys_to_mask.iteritems():
if k in d: d[k] = keys_to_mask[k]
if mask_metadata and str(d.get('section_id','')) not in session_library_ids:
for k, v in metadata_to_mask.iteritems():
if k in d: d[k] = metadata_to_mask[k]
return list_of_dicts
return list_of_dicts

View file

@ -13,8 +13,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# 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, datatables, common, database, helpers
import plexpy import plexpy
from plexpy import logger, datatables, common, database, helpers, session
def update_section_ids(): def update_section_ids():
from plexpy import pmsconnect, activity_pinger from plexpy import pmsconnect, activity_pinger
@ -119,9 +119,18 @@ class Libraries(object):
pass pass
def get_datatables_list(self, kwargs=None): def get_datatables_list(self, kwargs=None):
default_return = {'recordsFiltered': 0,
'recordsTotal': 0,
'draw': 0,
'data': 'null',
'error': 'Unable to execute database query.'}
data_tables = datatables.DataTables() data_tables = datatables.DataTables()
custom_where = ['library_sections.deleted_section', 0] custom_where = [['library_sections.deleted_section', 0]]
if session.get_session_libraries():
custom_where.append(['library_sections.section_id', session.get_session_libraries()])
columns = ['library_sections.section_id', columns = ['library_sections.section_id',
'library_sections.section_name', 'library_sections.section_name',
@ -155,7 +164,7 @@ class Libraries(object):
try: try:
query = data_tables.ssp_query(table_name='library_sections', query = data_tables.ssp_query(table_name='library_sections',
columns=columns, columns=columns,
custom_where=[custom_where], custom_where=custom_where,
group_by=['library_sections.server_id', 'library_sections.section_id'], group_by=['library_sections.server_id', 'library_sections.section_id'],
join_types=['LEFT OUTER JOIN', join_types=['LEFT OUTER JOIN',
'LEFT OUTER JOIN', 'LEFT OUTER JOIN',
@ -169,11 +178,7 @@ class Libraries(object):
kwargs=kwargs) kwargs=kwargs)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_list: %s." % e) logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_list: %s." % e)
return {'recordsFiltered': 0, return default_return
'recordsTotal': 0,
'draw': 0,
'data': 'null',
'error': 'Unable to execute database query.'}
result = query['result'] result = query['result']
@ -222,7 +227,7 @@ class Libraries(object):
dict = {'recordsFiltered': query['filteredCount'], dict = {'recordsFiltered': query['filteredCount'],
'recordsTotal': query['totalCount'], 'recordsTotal': query['totalCount'],
'data': helpers.filter_session_info(rows, 'section_id'), 'data': rows,
'draw': query['draw'] 'draw': query['draw']
} }
@ -235,9 +240,12 @@ class Libraries(object):
default_return = {'recordsFiltered': 0, default_return = {'recordsFiltered': 0,
'recordsTotal': 0, 'recordsTotal': 0,
'draw': 0, 'draw': 0,
'data': None, 'data': 'null',
'error': 'Unable to execute database query.'} 'error': 'Unable to execute database query.'}
if not session.allow_session_library(section_id):
return default_return
if section_id and not str(section_id).isdigit(): if section_id and not str(section_id).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info called by invalid section_id provided.") logger.warn(u"PlexPy Libraries :: Datatable media info called by invalid section_id provided.")
return default_return return default_return
@ -443,6 +451,9 @@ class Libraries(object):
from plexpy import pmsconnect from plexpy import pmsconnect
import json, os import json, os
if not session.allow_session_library(section_id):
return False
if section_id and not str(section_id).isdigit(): if section_id and not str(section_id).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info file size called by invalid section_id provided.") logger.warn(u"PlexPy Libraries :: Datatable media info file size called by invalid section_id provided.")
return False return False
@ -619,6 +630,9 @@ class Libraries(object):
return default_return return default_return
def get_watch_time_stats(self, section_id=None): def get_watch_time_stats(self, section_id=None):
if not session.allow_session_library(section_id):
return []
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
time_queries = [1, 7, 30, 0] time_queries = [1, 7, 30, 0]
@ -671,6 +685,9 @@ class Libraries(object):
return library_watch_time_stats return library_watch_time_stats
def get_user_stats(self, section_id=None): def get_user_stats(self, section_id=None):
if not session.allow_session_library(section_id):
return []
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
user_stats = [] user_stats = []
@ -678,7 +695,7 @@ class Libraries(object):
try: try:
if str(section_id).isdigit(): if str(section_id).isdigit():
query = 'SELECT (CASE WHEN users.friendly_name IS NULL THEN users.username ' \ query = 'SELECT (CASE WHEN users.friendly_name IS NULL THEN users.username ' \
'ELSE users.friendly_name END) AS user, users.user_id, users.thumb, COUNT(user) AS user_count ' \ 'ELSE users.friendly_name END) AS friendly_name, users.user_id, users.thumb, COUNT(user) AS user_count ' \
'FROM session_history ' \ 'FROM session_history ' \
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
'JOIN users ON users.user_id = session_history.user_id ' \ 'JOIN users ON users.user_id = session_history.user_id ' \
@ -693,16 +710,19 @@ class Libraries(object):
result = [] result = []
for item in result: for item in result:
row = {'user': item['user'], row = {'friendly_name': item['friendly_name'],
'user_id': item['user_id'], 'user_id': item['user_id'],
'thumb': item['thumb'], 'user_thumb': item['thumb'],
'total_plays': item['user_count'] 'total_plays': item['user_count']
} }
user_stats.append(row) user_stats.append(row)
return helpers.filter_session_info(user_stats, 'user_id') return session.mask_session_info(user_stats)
def get_recently_watched(self, section_id=None, limit='10'): def get_recently_watched(self, section_id=None, limit='10'):
if not session.allow_session_library(section_id):
return []
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
recently_watched = [] recently_watched = []

View file

@ -16,14 +16,13 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# 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, http_handler, database, users
import xmltodict
import json
from xml.dom import minidom
import requests
import base64 import base64
import json
import xmltodict
from xml.dom import minidom
import plexpy import plexpy
from plexpy import logger, helpers, http_handler, database, users, session
def refresh_users(): def refresh_users():
@ -401,7 +400,7 @@ class PlexTV(object):
synced_items.append(sync_details) synced_items.append(sync_details)
return helpers.filter_session_info(synced_items, 'user_id') return session.filter_session_info(synced_items, 'user_id')
def get_server_urls(self, include_https=True): def get_server_urls(self, include_https=True):

View file

@ -13,11 +13,11 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# 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, users, http_handler, common, database import urllib2
from urlparse import urlparse from urlparse import urlparse
import plexpy import plexpy
import urllib2 from plexpy import logger, helpers, users, http_handler, common, database, session
def get_server_friendly_name(): def get_server_friendly_name():
@ -462,7 +462,7 @@ class PmsConnect(object):
'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'), 'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'),
'media_index': helpers.get_xml_attr(item, 'index'), 'media_index': helpers.get_xml_attr(item, 'index'),
'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'),
'section_id': helpers.get_xml_attr(item, 'librarySectionID'), 'section_id': section_id if section_id else helpers.get_xml_attr(item, 'librarySectionID'),
'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'), 'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'),
'year': helpers.get_xml_attr(item, 'year'), 'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'), 'thumb': helpers.get_xml_attr(item, 'thumb'),
@ -484,7 +484,7 @@ class PmsConnect(object):
'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'), 'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'),
'media_index': helpers.get_xml_attr(item, 'index'), 'media_index': helpers.get_xml_attr(item, 'index'),
'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'),
'section_id': helpers.get_xml_attr(item, 'librarySectionID'), 'section_id': section_id if section_id else helpers.get_xml_attr(item, 'librarySectionID'),
'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'), 'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'),
'year': helpers.get_xml_attr(item, 'year'), 'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'), 'thumb': helpers.get_xml_attr(item, 'thumb'),
@ -493,9 +493,10 @@ class PmsConnect(object):
'added_at': helpers.get_xml_attr(item, 'addedAt') 'added_at': helpers.get_xml_attr(item, 'addedAt')
} }
recents_list.append(recent_items) recents_list.append(recent_items)
output = {'recently_added': helpers.filter_session_info( output = {'recently_added': session.filter_session_info(
sorted(recents_list, key=lambda k: k['added_at'], reverse=True), 'section_id')} sorted(recents_list, key=lambda k: k['added_at'], reverse=True), 'section_id')}
return output return output
def get_metadata_details(self, rating_key='', get_media_info=False): def get_metadata_details(self, rating_key='', get_media_info=False):
@ -975,7 +976,7 @@ class PmsConnect(object):
session_list.append(session_output) session_list.append(session_output)
output = {'stream_count': helpers.get_xml_attr(xml_head[0], 'size'), output = {'stream_count': helpers.get_xml_attr(xml_head[0], 'size'),
'sessions': helpers.mask_session_info(session_list, True) 'sessions': session.mask_session_info(session_list, True)
} }
return output return output

150
plexpy/session.py Normal file
View file

@ -0,0 +1,150 @@
# This file is part of PlexPy.
#
# PlexPy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
import cherrypy
from plexpy import common
def get_session_info():
"""
Returns the session info for the user session
"""
from plexpy.webauth import SESSION_KEY
if cherrypy.config.get('tools.auth.on'):
_session = cherrypy.session.get(SESSION_KEY)
if _session:
return _session
return {'user_id': None,
'user': None,
'user_group': 'admin',
'user_libraries': None,
'expiry': None}
def get_session_user():
"""
Returns the user_id for the current logged in session
"""
_session = get_session_info()
return _session['user']
def get_session_user_id():
"""
Returns the user_id for the current logged in session
"""
_session = get_session_info()
return str(_session['user_id']) if _session['user_id'] else None
def get_session_libraries():
"""
Returns a tuple of section_id for the current logged in session
"""
_session = get_session_info()
return _session['user_libraries']
def allow_session_user(user_id):
"""
Returns True or False if the user_id is allowed for the current logged in session
"""
session_user_id = get_session_user_id()
if session_user_id and str(user_id) != session_user_id:
return False
return True
def allow_session_library(section_id):
"""
Returns True or False if the section_id is allowed for the current logged in session
"""
session_library_ids = get_session_libraries()
if session_library_ids and str(section_id) not in session_library_ids:
return False
return True
def filter_session_info(list_of_dicts, filter_key=None):
"""
Filters a list of dictionary items to only return the info for the current logged in session
"""
session_user_id = get_session_user_id()
session_library_ids = get_session_libraries()
list_of_dicts = friendly_name_to_username(list_of_dicts)
if filter_key == 'user_id' and session_user_id:
return [d for d in list_of_dicts if str(d.get('user_id','')) == session_user_id]
elif filter_key == 'section_id' and session_library_ids:
return [d for d in list_of_dicts if str(d.get('section_id','')) in session_library_ids]
return list_of_dicts
def mask_session_info(list_of_dicts, mask_metadata=False):
"""
Masks user info in a list of dictionary items to only display info for the current logged in session
"""
session_user = get_session_user()
session_user_id = get_session_user_id()
session_library_ids = get_session_libraries()
keys_to_mask = {'user_id': '',
'user': 'Plex User',
'friendly_name': 'Plex User',
'user_thumb': common.DEFAULT_USER_THUMB,
'ip_address': 'N/A',
'machine_id': '',
'player': 'Player'
}
metadata_to_mask = {'media_index': '',
'parent_media_index': '',
'art': common.DEFAULT_ART,
'parent_thumb': common.DEFAULT_POSTER_THUMB,
'grandparent_thumb': common.DEFAULT_POSTER_THUMB,
'thumb': common.DEFAULT_POSTER_THUMB,
'bif_thumb': '',
'grandparent_title': '',
'parent_title': '',
'title': '',
'rating_key': '',
'parent_rating_key': '',
'grandparent_rating_key': '',
'year': ''
}
list_of_dicts = friendly_name_to_username(list_of_dicts)
for d in list_of_dicts:
if session_user_id and not (str(d.get('user_id')) == session_user_id or d.get('user') == session_user):
for k, v in keys_to_mask.iteritems():
if k in d: d[k] = keys_to_mask[k]
if mask_metadata and session_library_ids and str(d.get('section_id','')) not in session_library_ids:
for k, v in metadata_to_mask.iteritems():
if k in d: d[k] = metadata_to_mask[k]
return list_of_dicts
def friendly_name_to_username(list_of_dicts):
"""
Reverts the friendly name back to the username of the current logged in session
"""
session_user = get_session_user()
for d in list_of_dicts:
if 'friendly_name' in d and d['friendly_name'] != session_user:
d['friendly_name'] = session_user
return list_of_dicts

View file

@ -13,7 +13,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# 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, datatables, common, database, helpers import plexpy
from plexpy import logger, datatables, common, database, helpers, session
def user_login(username=None, password=None): def user_login(username=None, password=None):
from plexpy import plextv from plexpy import plextv
@ -85,9 +86,18 @@ class Users(object):
pass pass
def get_datatables_list(self, kwargs=None): def get_datatables_list(self, kwargs=None):
default_return = {'recordsFiltered': 0,
'recordsTotal': 0,
'draw': 0,
'data': 'null',
'error': 'Unable to execute database query.'}
data_tables = datatables.DataTables() data_tables = datatables.DataTables()
custom_where = ['users.deleted_user', 0] custom_where = [['users.deleted_user', 0]]
if session.get_session_user_id():
custom_where.append(['users.user_id', session.get_session_user_id()])
columns = ['users.user_id', columns = ['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) = "" \
@ -121,7 +131,7 @@ class Users(object):
try: try:
query = data_tables.ssp_query(table_name='users', query = data_tables.ssp_query(table_name='users',
columns=columns, columns=columns,
custom_where=[custom_where], custom_where=custom_where,
group_by=['users.user_id'], group_by=['users.user_id'],
join_types=['LEFT OUTER JOIN', join_types=['LEFT OUTER JOIN',
'LEFT OUTER JOIN', 'LEFT OUTER JOIN',
@ -135,11 +145,7 @@ class Users(object):
kwargs=kwargs) kwargs=kwargs)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_list: %s." % e) logger.warn(u"PlexPy Users :: Unable to execute database query for get_list: %s." % e)
return {'recordsFiltered': 0, return default_return
'recordsTotal': 0,
'draw': 0,
'data': 'null',
'error': 'Unable to execute database query.'}
users = query['result'] users = query['result']
@ -190,13 +196,22 @@ class Users(object):
dict = {'recordsFiltered': query['filteredCount'], dict = {'recordsFiltered': query['filteredCount'],
'recordsTotal': query['totalCount'], 'recordsTotal': query['totalCount'],
'data': helpers.filter_session_info(rows, 'user_id'), 'data': session.friendly_name_to_username(rows),
'draw': query['draw'] 'draw': query['draw']
} }
return dict return dict
def get_datatables_unique_ips(self, user_id=None, kwargs=None): def get_datatables_unique_ips(self, user_id=None, kwargs=None):
default_return = {'recordsFiltered': 0,
'recordsTotal': 0,
'draw': 0,
'data': 'null',
'error': 'Unable to execute database query.'}
if not session.allow_session_user(user_id):
return default_return
data_tables = datatables.DataTables() data_tables = datatables.DataTables()
custom_where = ['users.user_id', user_id] custom_where = ['users.user_id', user_id]
@ -241,11 +256,7 @@ class Users(object):
kwargs=kwargs) kwargs=kwargs)
except Exception as e: except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_unique_ips: %s." % e) logger.warn(u"PlexPy Users :: Unable to execute database query for get_unique_ips: %s." % e)
return {'recordsFiltered': 0, return default_return
'recordsTotal': 0,
'draw': 0,
'data': 'null',
'error': 'Unable to execute database query.'}
results = query['result'] results = query['result']
@ -284,7 +295,7 @@ class Users(object):
dict = {'recordsFiltered': query['filteredCount'], dict = {'recordsFiltered': query['filteredCount'],
'recordsTotal': query['totalCount'], 'recordsTotal': query['totalCount'],
'data': helpers.filter_session_info(rows, 'user_id'), 'data': session.friendly_name_to_username(rows),
'draw': query['draw'] 'draw': query['draw']
} }
@ -356,7 +367,9 @@ class Users(object):
user_details = {} user_details = {}
if result: if result:
for item in result: for item in result:
if item['friendly_name']: if session.get_session_user():
friendly_name = session.get_session_user()
elif item['friendly_name']:
friendly_name = item['friendly_name'] friendly_name = item['friendly_name']
else: else:
friendly_name = item['username'] friendly_name = item['username']
@ -407,6 +420,9 @@ class Users(object):
return default_return return default_return
def get_watch_time_stats(self, user_id=None): def get_watch_time_stats(self, user_id=None):
if not session.allow_session_user(user_id):
return []
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
time_queries = [1, 7, 30, 0] time_queries = [1, 7, 30, 0]
@ -457,6 +473,9 @@ class Users(object):
return user_watch_time_stats return user_watch_time_stats
def get_player_stats(self, user_id=None): def get_player_stats(self, user_id=None):
if not session.allow_session_user(user_id):
return []
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
player_stats = [] player_stats = []
@ -491,6 +510,9 @@ class Users(object):
return player_stats return player_stats
def get_recently_watched(self, user_id=None, limit='10'): def get_recently_watched(self, user_id=None, limit='10'):
if not session.allow_session_user(user_id):
return []
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
recently_watched = [] recently_watched = []

View file

@ -13,32 +13,24 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# 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, notifiers, plextv, pmsconnect, common, log_reader, \
datafactory, graphs, users, libraries, database, web_socket
from plexpy.helpers import checked, addtoapi, get_ip, create_https_certificates
from plexpy.webauth import AuthController, requireAuth, member_of, name_is, SESSION_KEY
from mako.lookup import TemplateLookup
from mako import exceptions
from hashing_passwords import make_hash
import plexpy
import threading
import cherrypy import cherrypy
import hashlib import hashlib
import random
import json import json
import os import os
from api2 import API2 import random
import threading
try: from hashing_passwords import make_hash
# pylint:disable=E0611 from mako.lookup import TemplateLookup
# ignore this error because we are catching the ImportError from mako import exceptions
from collections import OrderedDict
# pylint:enable=E0611 import plexpy
except ImportError: from plexpy import logger, notifiers, plextv, pmsconnect, common, log_reader, \
# Python 2.6.x fallback, from libs datafactory, graphs, users, libraries, database, web_socket
from ordereddict import OrderedDict from plexpy.api2 import API2
from plexpy.helpers import checked, addtoapi, get_ip, create_https_certificates
from plexpy.session import get_session_info, allow_session_user, allow_session_library
from plexpy.webauth import AuthController, requireAuth, member_of, name_is, SESSION_KEY
def serve_template(templatename, **kwargs): def serve_template(templatename, **kwargs):
@ -49,13 +41,7 @@ def serve_template(templatename, **kwargs):
server_name = plexpy.CONFIG.PMS_NAME server_name = plexpy.CONFIG.PMS_NAME
_session = {'user_id': None, _session = get_session_info()
'user': None,
'user_group': 'admin',
'expiry': None}
if cherrypy.config.get('tools.auth.on'):
_session = cherrypy.session.get(SESSION_KEY)
try: try:
template = _hplookup.get_template(templatename) template = _hplookup.get_template(templatename)
@ -351,6 +337,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def library(self, section_id=None): def library(self, section_id=None):
if not allow_session_library(section_id):
raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT)
config = { config = {
"get_file_sizes": plexpy.CONFIG.GET_FILE_SIZES, "get_file_sizes": plexpy.CONFIG.GET_FILE_SIZES,
"get_file_sizes_hold": plexpy.CONFIG.GET_FILE_SIZES_HOLD "get_file_sizes_hold": plexpy.CONFIG.GET_FILE_SIZES_HOLD
@ -409,6 +398,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_library_watch_time_stats(self, section_id=None, **kwargs): def get_library_watch_time_stats(self, section_id=None, **kwargs):
if not allow_session_library(section_id):
return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats")
if section_id: if section_id:
library_data = libraries.Libraries() library_data = libraries.Libraries()
result = library_data.get_watch_time_stats(section_id=section_id) result = library_data.get_watch_time_stats(section_id=section_id)
@ -424,6 +416,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_library_user_stats(self, section_id=None, **kwargs): def get_library_user_stats(self, section_id=None, **kwargs):
if not allow_session_library(section_id):
return serve_template(templatename="library_user_stats.html", data=None, title="Player Stats")
if section_id: if section_id:
library_data = libraries.Libraries() library_data = libraries.Libraries()
result = library_data.get_user_stats(section_id=section_id) result = library_data.get_user_stats(section_id=section_id)
@ -439,6 +434,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_library_recently_watched(self, section_id=None, limit='10', **kwargs): def get_library_recently_watched(self, section_id=None, limit='10', **kwargs):
if not allow_session_library(section_id):
return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched")
if section_id: if section_id:
library_data = libraries.Libraries() library_data = libraries.Libraries()
result = library_data.get_recently_watched(section_id=section_id, limit=limit) result = library_data.get_recently_watched(section_id=section_id, limit=limit)
@ -454,6 +452,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_library_recently_added(self, section_id=None, limit='10', **kwargs): def get_library_recently_added(self, section_id=None, limit='10', **kwargs):
if not allow_session_library(section_id):
return serve_template(templatename="library_recently_added.html", data=None, title="Recently Added")
if section_id: if section_id:
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_recently_added_details(section_id=section_id, count=limit) result = pms_connect.get_recently_added_details(section_id=section_id, count=limit)
@ -649,6 +650,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def user(self, user_id=None): def user(self, user_id=None):
if not allow_session_user(user_id):
raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT)
user_data = users.Users() user_data = users.Users()
if user_id: if user_id:
try: try:
@ -702,6 +706,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_user_watch_time_stats(self, user=None, user_id=None, **kwargs): def get_user_watch_time_stats(self, user=None, user_id=None, **kwargs):
if not allow_session_user(user_id):
return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats")
if user_id or user: if user_id or user:
user_data = users.Users() user_data = users.Users()
result = user_data.get_watch_time_stats(user_id=user_id) result = user_data.get_watch_time_stats(user_id=user_id)
@ -717,6 +724,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_user_player_stats(self, user=None, user_id=None, **kwargs): def get_user_player_stats(self, user=None, user_id=None, **kwargs):
if not allow_session_user(user_id):
return serve_template(templatename="user_player_stats.html", data=None, title="Player Stats")
if user_id or user: if user_id or user:
user_data = users.Users() user_data = users.Users()
result = user_data.get_player_stats(user_id=user_id) result = user_data.get_player_stats(user_id=user_id)
@ -732,6 +742,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_user_recently_watched(self, user=None, user_id=None, limit='10', **kwargs): def get_user_recently_watched(self, user=None, user_id=None, limit='10', **kwargs):
if not allow_session_user(user_id):
return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched")
if user_id or user: if user_id or user:
user_data = users.Users() user_data = users.Users()
result = user_data.get_recently_watched(user_id=user_id, limit=limit) result = user_data.get_recently_watched(user_id=user_id, limit=limit)
@ -1239,10 +1252,10 @@ class WebInterface(object):
def log_js_errors(self, page, message, file, line): def log_js_errors(self, page, message, file, line):
""" Logs javascript errors from the web interface. """ """ Logs javascript errors from the web interface. """
logger.error(u"WebUI :: /%s : %s. (%s:%s)" % (page.rpartition('/')[-1], logger.error(u"WebUI :: /%s : %s. (%s:%s)" % (page.rpartition('/')[-1],
message, message,
file.rpartition('/')[-1].partition('?')[0], file.rpartition('/')[-1].partition('?')[0],
line)) line))
return True return "js error logged."
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))