mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-07 05:31:15 -07:00
Filter all library and user data for guests
This commit is contained in:
parent
d462ebe8e5
commit
c0a5a8d775
13 changed files with 382 additions and 246 deletions
|
@ -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;
|
||||||
|
|
|
@ -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}">
|
||||||
|
|
|
@ -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> Select 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> Select 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">
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -89,15 +89,14 @@ 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:
|
||||||
|
if isinstance(w[1], (list, tuple)) and len(w[1]):
|
||||||
|
c_where += '('
|
||||||
|
for w_ in w[1]:
|
||||||
|
c_where += w[0] + ' = ? OR '
|
||||||
|
args.append(w_)
|
||||||
|
c_where = c_where.rstrip(' OR ') + ') AND '
|
||||||
|
else:
|
||||||
c_where += w[0] + ' = ? AND '
|
c_where += w[0] + ' = ? AND '
|
||||||
|
|
||||||
# The order of our args changes if we are grouping
|
|
||||||
#if grouping:
|
|
||||||
# args.insert(0, w[1])
|
|
||||||
#else:
|
|
||||||
# args.append(w[1])
|
|
||||||
|
|
||||||
# My testing shows that order of args doesn't change
|
|
||||||
args.append(w[1])
|
args.append(w[1])
|
||||||
|
|
||||||
if c_where:
|
if c_where:
|
||||||
|
|
|
@ -564,103 +564,3 @@ def uploadToImgur(imgPath, imgTitle=''):
|
||||||
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
|
|
|
@ -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 = []
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
||||||
|
|
|
@ -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'),
|
||||||
|
@ -494,8 +494,9 @@ class PmsConnect(object):
|
||||||
}
|
}
|
||||||
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
150
plexpy/session.py
Normal 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
|
|
@ -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 = []
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -1242,7 +1255,7 @@ class WebInterface(object):
|
||||||
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"))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue