mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-07 05:31:15 -07:00
Add all content rating and label filters for guest
This commit is contained in:
parent
2aa059a170
commit
e147ce9039
14 changed files with 599 additions and 220 deletions
|
@ -2138,8 +2138,8 @@ a .home-platforms-instance-box:hover,
|
|||
a .home-platforms-instance-oval:hover,
|
||||
a .home-platforms-instance-list-box:hover,
|
||||
a .home-platforms-instance-list-oval:hover,
|
||||
.home-platforms-poster-face:hover,
|
||||
.home-platforms-list-poster-face:hover
|
||||
a .home-platforms-poster-face:hover,
|
||||
a .home-platforms-list-poster-face:hover
|
||||
{
|
||||
-webkit-box-shadow: inset 0 0 0 2px #e9a049;
|
||||
-moz-box-shadow: inset 0 0 0 2px #e9a049;
|
||||
|
|
|
@ -82,9 +82,13 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
<div class="home-platforms-instance-playcount">
|
||||
<h4>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
${top_stat['rows'][0]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][0]['title']}
|
||||
% endif
|
||||
</h4>
|
||||
% if top_stat['stat_type'] == 'total_plays':
|
||||
<h3>${top_stat['rows'][0]['total_plays']}</h3>
|
||||
|
@ -94,6 +98,7 @@ DOCUMENTATION :: END
|
|||
% endif
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
% if top_stat['rows'][0]['grandparent_thumb']:
|
||||
<div class="home-platforms-instance-poster">
|
||||
|
@ -105,6 +110,11 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster">
|
||||
<div class="home-platforms-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
% if len(top_stat['rows']) > 1:
|
||||
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
|
||||
<ul class="list-unstyled">
|
||||
|
@ -116,9 +126,13 @@ DOCUMENTATION :: END
|
|||
<div class="home-platforms-instance-list-info">
|
||||
<div class="home-platforms-instance-list-name">
|
||||
<h5>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
% endif
|
||||
</h5>
|
||||
</div>
|
||||
<div class="home-platforms-instance-list-playcount">
|
||||
|
@ -130,17 +144,23 @@ DOCUMENTATION :: END
|
|||
% endif
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
% if top_stat['rows'][loop.index]['grandparent_thumb']:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['grandparent_thumb']}&width=300&height=450&fallback=poster);"></div>
|
||||
</div>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster2">
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
<div class="home-platforms-instance-list-number">
|
||||
<h4>${loop.index + 1}</h4>
|
||||
</div>
|
||||
|
@ -162,14 +182,19 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
<div class="home-platforms-instance-playcount">
|
||||
<h4>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
${top_stat['rows'][0]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][0]['title']}
|
||||
% endif
|
||||
</h4>
|
||||
<h3>${top_stat['rows'][0]['users_watched']}</h3>
|
||||
<p> users</p>
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
% if top_stat['rows'][0]['grandparent_thumb'] != '':
|
||||
<div class="home-platforms-instance-poster">
|
||||
|
@ -181,6 +206,11 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster">
|
||||
<div class="home-platforms-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
% if len(top_stat['rows']) > 1:
|
||||
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
|
||||
<ul class="list-unstyled">
|
||||
|
@ -192,9 +222,13 @@ DOCUMENTATION :: END
|
|||
<div class="home-platforms-instance-list-info">
|
||||
<div class="home-platforms-instance-list-name">
|
||||
<h5>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
% endif
|
||||
</h5>
|
||||
</div>
|
||||
<div class="home-platforms-instance-list-playcount">
|
||||
|
@ -202,17 +236,23 @@ DOCUMENTATION :: END
|
|||
<p> users</p>
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
% if top_stat['rows'][loop.index]['grandparent_thumb']:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['grandparent_thumb']}&width=300&height=450&fallback=poster);"></div>
|
||||
</div>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster2">
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
<div class="home-platforms-instance-list-number">
|
||||
<h4>${loop.index + 1}</h4>
|
||||
</div>
|
||||
|
@ -234,9 +274,13 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
<div class="home-platforms-instance-playcount">
|
||||
<h4>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
${top_stat['rows'][0]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][0]['title']}
|
||||
% endif
|
||||
</h4>
|
||||
% if top_stat['stat_type'] == 'total_plays':
|
||||
<h3>${top_stat['rows'][0]['total_plays']}</h3>
|
||||
|
@ -246,6 +290,7 @@ DOCUMENTATION :: END
|
|||
% endif
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
% if top_stat['rows'][0]['thumb']:
|
||||
<div class="home-platforms-instance-poster">
|
||||
|
@ -257,6 +302,11 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster">
|
||||
<div class="home-platforms-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
% if len(top_stat['rows']) > 1:
|
||||
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
|
||||
<ul class="list-unstyled">
|
||||
|
@ -268,9 +318,13 @@ DOCUMENTATION :: END
|
|||
<div class="home-platforms-instance-list-info">
|
||||
<div class="home-platforms-instance-list-name">
|
||||
<h5>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
% endif
|
||||
</h5>
|
||||
</div>
|
||||
<div class="home-platforms-instance-list-playcount">
|
||||
|
@ -282,17 +336,23 @@ DOCUMENTATION :: END
|
|||
% endif
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
% if top_stat['rows'][loop.index]['thumb']:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['thumb']}&width=300&height=450&fallback=poster);"></div>
|
||||
</div>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster2">
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
<div class="home-platforms-instance-list-number">
|
||||
<h4>${loop.index + 1}</h4>
|
||||
</div>
|
||||
|
@ -314,14 +374,19 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
<div class="home-platforms-instance-playcount">
|
||||
<h4>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
${top_stat['rows'][0]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][0]['title']}
|
||||
% endif
|
||||
</h4>
|
||||
<h3>${top_stat['rows'][0]['users_watched']}</h3>
|
||||
<p> users</p>
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
% if top_stat['rows'][0]['thumb']:
|
||||
<div class="home-platforms-instance-poster">
|
||||
|
@ -333,6 +398,11 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster">
|
||||
<div class="home-platforms-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
% if len(top_stat['rows']) > 1:
|
||||
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
|
||||
<ul class="list-unstyled">
|
||||
|
@ -344,9 +414,13 @@ DOCUMENTATION :: END
|
|||
<div class="home-platforms-instance-list-info">
|
||||
<div class="home-platforms-instance-list-name">
|
||||
<h5>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
% endif
|
||||
</h5>
|
||||
</div>
|
||||
<div class="home-platforms-instance-list-playcount">
|
||||
|
@ -354,17 +428,23 @@ DOCUMENTATION :: END
|
|||
<p> users</p>
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
% if top_stat['rows'][loop.index]['thumb']:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['thumb']}&width=300&height=450&fallback=poster);"></div>
|
||||
</div>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster2">
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
<div class="home-platforms-instance-list-number">
|
||||
<h4>${loop.index + 1}</h4>
|
||||
</div>
|
||||
|
@ -386,9 +466,13 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
<div class="home-platforms-instance-playcount">
|
||||
<h4>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
${top_stat['rows'][0]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][0]['title']}
|
||||
% endif
|
||||
</h4>
|
||||
% if top_stat['stat_type'] == 'total_plays':
|
||||
<h3>${top_stat['rows'][0]['total_plays']}</h3>
|
||||
|
@ -398,6 +482,7 @@ DOCUMENTATION :: END
|
|||
% endif
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
% if top_stat['rows'][0]['grandparent_thumb']:
|
||||
<div class="home-platforms-instance-poster">
|
||||
|
@ -409,6 +494,11 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster">
|
||||
<div class="home-platforms-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
% if len(top_stat['rows']) > 1:
|
||||
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
|
||||
<ul class="list-unstyled">
|
||||
|
@ -420,9 +510,13 @@ DOCUMENTATION :: END
|
|||
<div class="home-platforms-instance-list-info">
|
||||
<div class="home-platforms-instance-list-name">
|
||||
<h5>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
% endif
|
||||
</h5>
|
||||
</div>
|
||||
<div class="home-platforms-instance-list-playcount">
|
||||
|
@ -434,17 +528,23 @@ DOCUMENTATION :: END
|
|||
% endif
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
% if top_stat['rows'][loop.index]['grandparent_thumb']:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['grandparent_thumb']}&width=300&height=300&fallback=poster);"></div>
|
||||
</div>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster2">
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
<div class="home-platforms-instance-list-number">
|
||||
<h4>${loop.index + 1}</h4>
|
||||
</div>
|
||||
|
@ -466,14 +566,19 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
<div class="home-platforms-instance-playcount">
|
||||
<h4>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
${top_stat['rows'][0]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][0]['title']}
|
||||
% endif
|
||||
</h4>
|
||||
<h3>${top_stat['rows'][0]['users_watched']}</h3>
|
||||
<p> users</p>
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
% if top_stat['rows'][0]['grandparent_thumb'] != '':
|
||||
<div class="home-platforms-instance-poster">
|
||||
|
@ -485,6 +590,11 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster">
|
||||
<div class="home-platforms-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
% if len(top_stat['rows']) > 1:
|
||||
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
|
||||
<ul class="list-unstyled">
|
||||
|
@ -496,9 +606,13 @@ DOCUMENTATION :: END
|
|||
<div class="home-platforms-instance-list-info">
|
||||
<div class="home-platforms-instance-list-name">
|
||||
<h5>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
% endif
|
||||
</h5>
|
||||
</div>
|
||||
<div class="home-platforms-instance-list-playcount">
|
||||
|
@ -506,17 +620,23 @@ DOCUMENTATION :: END
|
|||
<p> users</p>
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
% if top_stat['rows'][loop.index]['grandparent_thumb']:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['grandparent_thumb']}&width=300&height=300&fallback=poster);"></div>
|
||||
</div>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster2">
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
<div class="home-platforms-instance-list-number">
|
||||
<h4>${loop.index + 1}</h4>
|
||||
</div>
|
||||
|
@ -696,9 +816,13 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
<div class="home-platforms-instance-last-user">
|
||||
<h4>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?source=history&rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
${top_stat['rows'][0]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][0]['title']}
|
||||
% endif
|
||||
</h4>
|
||||
<h5>
|
||||
% if top_stat['rows'][0]['user_id']:
|
||||
|
@ -718,6 +842,7 @@ DOCUMENTATION :: END
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][0]['rating_key']:
|
||||
<a href="info?source=history&rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
|
||||
% if top_stat['rows'][0]['thumb']:
|
||||
<div class="home-platforms-instance-poster">
|
||||
|
@ -729,6 +854,11 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-poster">
|
||||
<div class="home-platforms-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
% if len(top_stat['rows']) > 1:
|
||||
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
|
||||
<ul class="list-unstyled">
|
||||
|
@ -740,9 +870,13 @@ DOCUMENTATION :: END
|
|||
<div class="home-platforms-instance-list-info">
|
||||
<div class="home-platforms-instance-list-name">
|
||||
<h5>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?source=history&rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
</a>
|
||||
% else:
|
||||
${top_stat['rows'][loop.index]['title']}
|
||||
% endif
|
||||
</h5>
|
||||
</div>
|
||||
<div class="home-platforms-instance-list-last-user">
|
||||
|
@ -764,6 +898,7 @@ DOCUMENTATION :: END
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
% if top_stat['rows'][loop.index]['rating_key']:
|
||||
<a href="info?source=history&rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
|
||||
% if top_stat['rows'][loop.index]['thumb']:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
|
@ -775,6 +910,11 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
% endif
|
||||
</a>
|
||||
% else:
|
||||
<div class="home-platforms-instance-list-poster">
|
||||
<div class="home-platforms-list-poster-face" style="background-image: url(${http_root}images/poster.png);"></div>
|
||||
</div>
|
||||
% endif
|
||||
<div class="home-platforms-instance-list-number">
|
||||
<h4>${loop.index + 1}</h4>
|
||||
</div>
|
||||
|
|
|
@ -140,22 +140,41 @@ libraries_list_table_options = {
|
|||
var media_type = '';
|
||||
var thumb_popover = '';
|
||||
if (rowData['media_type'] === 'movie') {
|
||||
if (rowData['year']) { parent_info = ' (' + rowData['year'] + ')'; }
|
||||
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Movie"><i class="fa fa-film fa-fw"></i></span>';
|
||||
if (rowData['rating_key']) {
|
||||
if (rowData['year']) { parent_info = ' (' + rowData['year'] + ')'; }
|
||||
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=450&fallback=poster" data-height="120" data-width="80">' + cellData + parent_info + '</span>'
|
||||
$(td).html('<div class="history-title"><a href="info?source=history&rating_key=' + rowData['rating_key'] + '"><div style="float: left;">' + media_type + ' ' + thumb_popover + '</div></a></div>');
|
||||
} else {
|
||||
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="images/poster.png" data-height="120" data-width="80">' + cellData + parent_info + '</span>'
|
||||
$(td).html('<div class="history-title"><div style="float: left;">' + media_type + ' ' + thumb_popover + '</div></div>');
|
||||
}
|
||||
} else if (rowData['media_type'] === 'episode') {
|
||||
if (rowData['parent_media_index'] && rowData['media_index']) { parent_info = ' (S' + rowData['parent_media_index'] + '· E' + rowData['media_index'] + ')'; }
|
||||
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Episode"><i class="fa fa-television fa-fw"></i></span>';
|
||||
if (rowData['rating_key']) {
|
||||
if (rowData['parent_media_index'] && rowData['media_index']) { parent_info = ' (S' + rowData['parent_media_index'] + '· E' + rowData['media_index'] + ')'; }
|
||||
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=450&fallback=poster" data-height="120" data-width="80">' + cellData + parent_info + '</span>'
|
||||
$(td).html('<div class="history-title"><a href="info?source=history&rating_key=' + rowData['rating_key'] + '"><div style="float: left;" >' + media_type + ' ' + thumb_popover + '</div></a></div>');
|
||||
} else {
|
||||
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="images/poster.png" data-height="120" data-width="80">' + cellData + parent_info + '</span>'
|
||||
$(td).html('<div class="history-title"><div style="float: left;" >' + media_type + ' ' + thumb_popover + '</div></div>');
|
||||
}
|
||||
} else if (rowData['media_type'] === 'track') {
|
||||
if (rowData['parent_title']) { parent_info = ' (' + rowData['parent_title'] + ')'; }
|
||||
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Track"><i class="fa fa-music fa-fw"></i></span>';
|
||||
if (rowData['rating_key']) {
|
||||
if (rowData['parent_title']) { parent_info = ' (' + rowData['parent_title'] + ')'; }
|
||||
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=300&fallback=cover" data-height="80" data-width="80">' + cellData + parent_info + '</span>'
|
||||
$(td).html('<div class="history-title"><a href="info?source=history&rating_key=' + rowData['rating_key'] + '"><div style="float: left;">' + media_type + ' ' + thumb_popover + '</div></a></div>');
|
||||
} else {
|
||||
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="images/cover.png" data-height="80" data-width="80">' + cellData + parent_info + '</span>'
|
||||
$(td).html('<div class="history-title"><div style="float: left;">' + media_type + ' ' + thumb_popover + '</div></div>');
|
||||
}
|
||||
} else if (rowData['media_type']) {
|
||||
if (rowData['rating_key']) {
|
||||
$(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>');
|
||||
} else {
|
||||
$(td).html(cellData);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$(td).html('n/a');
|
||||
|
|
|
@ -71,7 +71,9 @@ DOCUMENTATION :: END
|
|||
<ul class="user-info-nav">
|
||||
<li class="active"><a href="#profile" data-toggle="tab">Profile</a></li>
|
||||
<li><a id="history-tab-btn" href="#libraryHistory" data-toggle="tab">History</a></li>
|
||||
% if _session['user_group'] == 'admin':
|
||||
<li><a id="media-info-tab-btn" href="#libraryMediaInfo" data-toggle="tab">Media Info</a></li>
|
||||
% endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -33,6 +33,7 @@ DOCUMENTATION :: END
|
|||
% for item in data:
|
||||
<li>
|
||||
% if item['media_type'] == 'episode' or item['media_type'] == 'movie':
|
||||
% if item['rating_key']:
|
||||
<a href="info?source=history&rating_key=${item['rating_key']}">
|
||||
<div class="dashboard-recent-media-poster">
|
||||
<div class="dashboard-recent-media-poster-face" style="background-image: url(pms_image_proxy?img=${item['thumb']}&width=300&height=450&fallback=poster);">
|
||||
|
@ -64,7 +65,26 @@ DOCUMENTATION :: END
|
|||
<h3 class="text-muted">${item['year']}</h3>
|
||||
% endif
|
||||
</div>
|
||||
% else:
|
||||
<div class="dashboard-recent-media-poster">
|
||||
<div class="dashboard-recent-media-poster-face" style="background-image: url(${http_root}images/poster.png);">
|
||||
<div class="dashboard-recent-media-overlay">
|
||||
<div class="dashboard-recent-media-overlay-text" id="time-${item['time']}">
|
||||
<script>
|
||||
$('#time-${item['time']}').text('Watched ' + moment(${item['time']}, "X").fromNow())
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-recent-media-metacontainer">
|
||||
<h3 title="${item['title']}">
|
||||
${item['title']}
|
||||
</h3>
|
||||
</div>
|
||||
% endif
|
||||
% elif item['media_type'] == 'track':
|
||||
% if item['rating_key']:
|
||||
<a href="info?source=history&rating_key=${item['rating_key']}">
|
||||
<div class="dashboard-recent-media-cover">
|
||||
<div class="dashboard-recent-media-cover-face" style="background-image: url(pms_image_proxy?img=${item['thumb']}&width=300&height=300&fallback=cover);">
|
||||
|
@ -86,9 +106,27 @@ DOCUMENTATION :: END
|
|||
<a href="info?source=history&rating_key=${item['rating_key']}">${item['title']}</a>
|
||||
</h3>
|
||||
<h3 class="text-muted">
|
||||
<a href="info?rating_key=${item['parent_rating_key']}">${item['parent_title']}</a></a>
|
||||
<a href="info?rating_key=${item['parent_rating_key']}">${item['parent_title']}</a>
|
||||
</h3>
|
||||
</div>
|
||||
% else:
|
||||
<div class="dashboard-recent-media-cover">
|
||||
<div class="dashboard-recent-media-cover-face" style="background-image: url(${http_root}images/cover.png);">
|
||||
<div class="dashboard-recent-media-overlay">
|
||||
<div class="dashboard-recent-media-overlay-text" id="time-${item['time']}">
|
||||
<script>
|
||||
$('#time-${item['time']}').text('Watched ' + moment(${item['time']}, "X").fromNow())
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-recent-media-metacontainer">
|
||||
<h3 title="${item['title']}">
|
||||
${item['title']}
|
||||
</h3>
|
||||
</div>
|
||||
% endif
|
||||
% endif
|
||||
</li>
|
||||
% endfor
|
||||
|
|
|
@ -179,13 +179,6 @@ class DataFactory(object):
|
|||
group_by = 'session_history.reference_id' if grouping else 'session_history.id'
|
||||
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 = []
|
||||
|
||||
for stat in stats_cards:
|
||||
|
@ -193,6 +186,7 @@ class DataFactory(object):
|
|||
top_tv = []
|
||||
try:
|
||||
query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \
|
||||
't.media_type, t.content_rating, t.labels, ' \
|
||||
'MAX(t.started) AS last_watch, COUNT(t.id) AS total_plays, SUM(t.d) AS total_duration ' \
|
||||
'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \
|
||||
' (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) ' \
|
||||
|
@ -201,11 +195,11 @@ class DataFactory(object):
|
|||
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
|
||||
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
|
||||
' >= datetime("now", "-%s days", "localtime") ' \
|
||||
' AND session_history.media_type = "episode" %s' \
|
||||
' AND session_history.media_type = "episode" ' \
|
||||
' GROUP BY %s) AS t ' \
|
||||
'GROUP BY t.grandparent_title ' \
|
||||
'ORDER BY %s DESC ' \
|
||||
'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
|
||||
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
|
||||
result = monitor_db.select(query)
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_tv: %s." % e)
|
||||
|
@ -221,6 +215,9 @@ class DataFactory(object):
|
|||
'grandparent_thumb': item['grandparent_thumb'],
|
||||
'thumb': '',
|
||||
'section_id': item['section_id'],
|
||||
'media_type': item['media_type'],
|
||||
'content_rating': item['content_rating'],
|
||||
'labels': item['labels'].split(';') if item['labels'] else (),
|
||||
'user': '',
|
||||
'friendly_name': '',
|
||||
'platform_type': '',
|
||||
|
@ -237,6 +234,7 @@ class DataFactory(object):
|
|||
popular_tv = []
|
||||
try:
|
||||
query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \
|
||||
't.media_type, t.content_rating, t.labels, ' \
|
||||
'COUNT(DISTINCT t.user_id) AS users_watched, ' \
|
||||
'MAX(t.started) AS last_watch, COUNT(t.id) as total_plays, SUM(t.d) AS total_duration ' \
|
||||
'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \
|
||||
|
@ -246,11 +244,11 @@ class DataFactory(object):
|
|||
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
|
||||
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
|
||||
' >= datetime("now", "-%s days", "localtime") ' \
|
||||
' AND session_history.media_type = "episode" %s' \
|
||||
' AND session_history.media_type = "episode" ' \
|
||||
' GROUP BY %s) AS t ' \
|
||||
'GROUP BY t.grandparent_title ' \
|
||||
'ORDER BY users_watched DESC, %s DESC ' \
|
||||
'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
|
||||
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
|
||||
result = monitor_db.select(query)
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_tv: %s." % e)
|
||||
|
@ -265,6 +263,9 @@ class DataFactory(object):
|
|||
'grandparent_thumb': item['grandparent_thumb'],
|
||||
'thumb': '',
|
||||
'section_id': item['section_id'],
|
||||
'media_type': item['media_type'],
|
||||
'content_rating': item['content_rating'],
|
||||
'labels': item['labels'].split(';') if item['labels'] else (),
|
||||
'user': '',
|
||||
'friendly_name': '',
|
||||
'platform_type': '',
|
||||
|
@ -280,6 +281,7 @@ class DataFactory(object):
|
|||
top_movies = []
|
||||
try:
|
||||
query = 'SELECT t.id, t.full_title, t.rating_key, t.thumb, t.section_id, ' \
|
||||
't.media_type, t.content_rating, t.labels, ' \
|
||||
'MAX(t.started) AS last_watch, COUNT(t.id) AS total_plays, SUM(t.d) AS total_duration ' \
|
||||
'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \
|
||||
' (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) ' \
|
||||
|
@ -288,11 +290,11 @@ class DataFactory(object):
|
|||
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
|
||||
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
|
||||
' >= datetime("now", "-%s days", "localtime") ' \
|
||||
' AND session_history.media_type = "movie" %s' \
|
||||
' AND session_history.media_type = "movie" ' \
|
||||
' GROUP BY %s) AS t ' \
|
||||
'GROUP BY t.full_title ' \
|
||||
'ORDER BY %s DESC ' \
|
||||
'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
|
||||
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
|
||||
result = monitor_db.select(query)
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_movies: %s." % e)
|
||||
|
@ -308,6 +310,9 @@ class DataFactory(object):
|
|||
'grandparent_thumb': '',
|
||||
'thumb': item['thumb'],
|
||||
'section_id': item['section_id'],
|
||||
'media_type': item['media_type'],
|
||||
'content_rating': item['content_rating'],
|
||||
'labels': item['labels'].split(';') if item['labels'] else (),
|
||||
'user': '',
|
||||
'friendly_name': '',
|
||||
'platform_type': '',
|
||||
|
@ -324,6 +329,7 @@ class DataFactory(object):
|
|||
popular_movies = []
|
||||
try:
|
||||
query = 'SELECT t.id, t.full_title, t.rating_key, t.thumb, t.section_id, ' \
|
||||
't.media_type, t.content_rating, t.labels, ' \
|
||||
'COUNT(DISTINCT t.user_id) AS users_watched, ' \
|
||||
'MAX(t.started) AS last_watch, COUNT(t.id) as total_plays, SUM(t.d) AS total_duration ' \
|
||||
'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \
|
||||
|
@ -333,11 +339,11 @@ class DataFactory(object):
|
|||
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
|
||||
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
|
||||
' >= datetime("now", "-%s days", "localtime") ' \
|
||||
' AND session_history.media_type = "movie" %s' \
|
||||
' AND session_history.media_type = "movie" ' \
|
||||
' GROUP BY %s) AS t ' \
|
||||
'GROUP BY t.full_title ' \
|
||||
'ORDER BY users_watched DESC, %s DESC ' \
|
||||
'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
|
||||
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
|
||||
result = monitor_db.select(query)
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_movies: %s." % e)
|
||||
|
@ -352,6 +358,9 @@ class DataFactory(object):
|
|||
'grandparent_thumb': '',
|
||||
'thumb': item['thumb'],
|
||||
'section_id': item['section_id'],
|
||||
'media_type': item['media_type'],
|
||||
'content_rating': item['content_rating'],
|
||||
'labels': item['labels'].split(';') if item['labels'] else (),
|
||||
'user': '',
|
||||
'friendly_name': '',
|
||||
'platform_type': '',
|
||||
|
@ -367,6 +376,7 @@ class DataFactory(object):
|
|||
top_music = []
|
||||
try:
|
||||
query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \
|
||||
't.media_type, t.content_rating, t.labels, ' \
|
||||
'MAX(t.started) AS last_watch, COUNT(t.id) AS total_plays, SUM(t.d) AS total_duration ' \
|
||||
'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \
|
||||
' (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) ' \
|
||||
|
@ -375,11 +385,11 @@ class DataFactory(object):
|
|||
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
|
||||
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
|
||||
' >= datetime("now", "-%s days", "localtime") ' \
|
||||
' AND session_history.media_type = "track" %s' \
|
||||
' AND session_history.media_type = "track" ' \
|
||||
' GROUP BY %s) AS t ' \
|
||||
'GROUP BY t.grandparent_title ' \
|
||||
'ORDER BY %s DESC ' \
|
||||
'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
|
||||
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
|
||||
result = monitor_db.select(query)
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_music: %s." % e)
|
||||
|
@ -395,6 +405,9 @@ class DataFactory(object):
|
|||
'grandparent_thumb': item['grandparent_thumb'],
|
||||
'thumb': '',
|
||||
'section_id': item['section_id'],
|
||||
'media_type': item['media_type'],
|
||||
'content_rating': item['content_rating'],
|
||||
'labels': item['labels'].split(';') if item['labels'] else (),
|
||||
'user': '',
|
||||
'friendly_name': '',
|
||||
'platform_type': '',
|
||||
|
@ -411,6 +424,7 @@ class DataFactory(object):
|
|||
popular_music = []
|
||||
try:
|
||||
query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \
|
||||
't.media_type, t.content_rating, t.labels, ' \
|
||||
'COUNT(DISTINCT t.user_id) AS users_watched, ' \
|
||||
'MAX(t.started) AS last_watch, COUNT(t.id) as total_plays, SUM(t.d) AS total_duration ' \
|
||||
'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \
|
||||
|
@ -420,11 +434,11 @@ class DataFactory(object):
|
|||
' JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
|
||||
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
|
||||
' >= datetime("now", "-%s days", "localtime") ' \
|
||||
' AND session_history.media_type = "track" %s' \
|
||||
' AND session_history.media_type = "track" ' \
|
||||
' GROUP BY %s) AS t ' \
|
||||
'GROUP BY t.grandparent_title ' \
|
||||
'ORDER BY users_watched DESC, %s DESC ' \
|
||||
'LIMIT %s ' % (time_range, library_cond, group_by, sort_type, stats_count)
|
||||
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
|
||||
result = monitor_db.select(query)
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_music: %s." % e)
|
||||
|
@ -439,6 +453,9 @@ class DataFactory(object):
|
|||
'grandparent_thumb': item['grandparent_thumb'],
|
||||
'thumb': '',
|
||||
'section_id': item['section_id'],
|
||||
'media_type': item['media_type'],
|
||||
'content_rating': item['content_rating'],
|
||||
'labels': item['labels'].split(';') if item['labels'] else (),
|
||||
'user': '',
|
||||
'friendly_name': '',
|
||||
'platform_type': '',
|
||||
|
@ -501,7 +518,7 @@ class DataFactory(object):
|
|||
|
||||
home_stats.append({'stat_id': stat,
|
||||
'stat_type': sort_type,
|
||||
'rows': session.mask_session_info(top_users)})
|
||||
'rows': session.mask_session_info(top_users, mask_metadata=False)})
|
||||
|
||||
elif stat == 'top_platforms':
|
||||
top_platform = []
|
||||
|
@ -547,13 +564,14 @@ class DataFactory(object):
|
|||
|
||||
home_stats.append({'stat_id': stat,
|
||||
'stat_type': sort_type,
|
||||
'rows': session.mask_session_info(top_platform)})
|
||||
'rows': session.mask_session_info(top_platform, mask_metadata=False)})
|
||||
|
||||
elif stat == 'last_watched':
|
||||
last_watched = []
|
||||
try:
|
||||
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.section_id, ' \
|
||||
't.media_type, t.content_rating, t.labels, ' \
|
||||
'(CASE WHEN t.friendly_name IS NULL THEN t.username ELSE t.friendly_name END) ' \
|
||||
' AS friendly_name, ' \
|
||||
'MAX(t.started) AS last_watch, ' \
|
||||
|
@ -566,12 +584,12 @@ class DataFactory(object):
|
|||
' WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
|
||||
' >= datetime("now", "-%s days", "localtime") ' \
|
||||
' AND (session_history.media_type = "movie" ' \
|
||||
' OR session_history_metadata.media_type = "episode") %s' \
|
||||
' OR session_history_metadata.media_type = "episode") ' \
|
||||
' GROUP BY %s) AS t ' \
|
||||
'WHERE percent_complete >= %s ' \
|
||||
'GROUP BY t.id ' \
|
||||
'ORDER BY last_watch DESC ' \
|
||||
'LIMIT %s' % (time_range, library_cond, group_by, notify_watched_percent, stats_count)
|
||||
'LIMIT %s' % (time_range, group_by, notify_watched_percent, stats_count)
|
||||
result = monitor_db.select(query)
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: last_watched: %s." % e)
|
||||
|
@ -593,6 +611,9 @@ class DataFactory(object):
|
|||
'thumb': thumb,
|
||||
'grandparent_thumb': item['grandparent_thumb'],
|
||||
'section_id': item['section_id'],
|
||||
'media_type': item['media_type'],
|
||||
'content_rating': item['content_rating'],
|
||||
'labels': item['labels'].split(';') if item['labels'] else (),
|
||||
'last_watch': item['last_watch'],
|
||||
'player': item['player']
|
||||
}
|
||||
|
@ -686,6 +707,9 @@ class DataFactory(object):
|
|||
def get_library_stats(self, library_cards=[]):
|
||||
monitor_db = database.MonitorDatabase()
|
||||
|
||||
if session.get_session_shared_libraries():
|
||||
library_cards = session.get_session_shared_libraries()
|
||||
|
||||
library_stats = []
|
||||
|
||||
for id in library_cards:
|
||||
|
@ -718,7 +742,7 @@ class DataFactory(object):
|
|||
}
|
||||
library_stats.append(library)
|
||||
|
||||
return session.filter_session_info(library_stats, filter_key='section_id')
|
||||
return library_stats
|
||||
|
||||
def get_stream_details(self, row_id=None):
|
||||
monitor_db = database.MonitorDatabase()
|
||||
|
|
|
@ -92,9 +92,15 @@ class DataTables(object):
|
|||
if isinstance(w[1], (list, tuple)) and len(w[1]):
|
||||
c_where += '('
|
||||
for w_ in w[1]:
|
||||
if w_ == None:
|
||||
c_where += w[0] + ' IS NULL OR '
|
||||
else:
|
||||
c_where += w[0] + ' = ? OR '
|
||||
args.append(w_)
|
||||
c_where = c_where.rstrip(' OR ') + ') AND '
|
||||
else:
|
||||
if w[1] == None:
|
||||
c_where += w[0] + ' IS NULL AND '
|
||||
else:
|
||||
c_where += w[0] + ' = ? AND '
|
||||
args.append(w[1])
|
||||
|
|
|
@ -182,8 +182,8 @@ class Libraries(object):
|
|||
|
||||
custom_where = [['library_sections.deleted_section', 0]]
|
||||
|
||||
if session.get_session_libraries():
|
||||
custom_where.append(['library_sections.section_id', session.get_session_libraries()])
|
||||
if session.get_session_shared_libraries():
|
||||
custom_where.append(['library_sections.section_id', session.get_session_shared_libraries()])
|
||||
|
||||
columns = ['library_sections.section_id',
|
||||
'library_sections.section_name',
|
||||
|
@ -210,6 +210,8 @@ class Libraries(object):
|
|||
'session_history_metadata.year',
|
||||
'session_history_metadata.media_index',
|
||||
'session_history_metadata.parent_media_index',
|
||||
'session_history_metadata.content_rating',
|
||||
'session_history_metadata.labels',
|
||||
'library_sections.do_notify',
|
||||
'library_sections.do_notify_created',
|
||||
'library_sections.keep_history'
|
||||
|
@ -271,6 +273,8 @@ class Libraries(object):
|
|||
'year': item['year'],
|
||||
'media_index': item['media_index'],
|
||||
'parent_media_index': item['parent_media_index'],
|
||||
'content_rating': item['content_rating'],
|
||||
'labels': item['labels'].split(';') if item['labels'] else (),
|
||||
'do_notify': helpers.checked(item['do_notify']),
|
||||
'do_notify_created': helpers.checked(item['do_notify_created']),
|
||||
'keep_history': helpers.checked(item['keep_history'])
|
||||
|
@ -280,7 +284,7 @@ class Libraries(object):
|
|||
|
||||
dict = {'recordsFiltered': query['filteredCount'],
|
||||
'recordsTotal': query['totalCount'],
|
||||
'data': rows,
|
||||
'data': session.mask_session_info(rows),
|
||||
'draw': query['draw']
|
||||
}
|
||||
|
||||
|
@ -787,7 +791,7 @@ class Libraries(object):
|
|||
query = 'SELECT session_history.id, session_history.media_type, ' \
|
||||
'session_history.rating_key, session_history.parent_rating_key, session_history.grandparent_rating_key, ' \
|
||||
'title, parent_title, grandparent_title, thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \
|
||||
'year, started, user ' \
|
||||
'year, started, user, content_rating, labels, section_id ' \
|
||||
'FROM session_history_metadata ' \
|
||||
'JOIN session_history ON session_history_metadata.id = session_history.id ' \
|
||||
'WHERE section_id = ? ' \
|
||||
|
@ -822,11 +826,14 @@ class Libraries(object):
|
|||
'parent_media_index': row['parent_media_index'],
|
||||
'year': row['year'],
|
||||
'time': row['started'],
|
||||
'user': row['user']
|
||||
'user': row['user'],
|
||||
'section_id': row['section_id'],
|
||||
'content_rating': row['content_rating'],
|
||||
'labels': row['labels'].split(';') if row['labels'] else (),
|
||||
}
|
||||
recently_watched.append(recent_output)
|
||||
|
||||
return recently_watched
|
||||
return session.mask_session_info(recently_watched)
|
||||
|
||||
def get_sections(self):
|
||||
monitor_db = database.MonitorDatabase()
|
||||
|
|
|
@ -131,9 +131,7 @@ class PlexTV(object):
|
|||
self.password = password
|
||||
self.ssl_verify = plexpy.CONFIG.VERIFY_SSL_CERT
|
||||
|
||||
if token == 'admin':
|
||||
token = plexpy.CONFIG.PMS_TOKEN
|
||||
elif not token:
|
||||
if not token:
|
||||
# Check if we should use the admin token, or the guest server token
|
||||
if session.get_session_user_id():
|
||||
user_data = users.Users()
|
||||
|
|
|
@ -112,9 +112,7 @@ class PmsConnect(object):
|
|||
port = plexpy.CONFIG.PMS_PORT
|
||||
self.protocol = 'http'
|
||||
|
||||
if token == 'admin':
|
||||
token = plexpy.CONFIG.PMS_TOKEN
|
||||
elif not token:
|
||||
if not token:
|
||||
# Check if we should use the admin token, or the guest server token
|
||||
if session.get_session_user_id():
|
||||
user_data = users.Users()
|
||||
|
@ -1077,6 +1075,11 @@ class PmsConnect(object):
|
|||
else:
|
||||
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')
|
||||
|
||||
labels = []
|
||||
if session.getElementsByTagName('Label'):
|
||||
for label in session.getElementsByTagName('Label'):
|
||||
labels.append(helpers.get_xml_attr(label, 'tag'))
|
||||
|
||||
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
|
||||
'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
|
||||
'media_index': helpers.get_xml_attr(session, 'index'),
|
||||
|
@ -1102,6 +1105,8 @@ class PmsConnect(object):
|
|||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||
'content_rating': helpers.get_xml_attr(session, 'contentRating'),
|
||||
'labels': labels,
|
||||
'transcode_key': transcode_key,
|
||||
'throttled': throttled,
|
||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||
|
@ -1177,7 +1182,6 @@ class PmsConnect(object):
|
|||
transcode_container = ''
|
||||
transcode_protocol = ''
|
||||
|
||||
media_info = session.getElementsByTagName('Media')[0]
|
||||
if media_info.getElementsByTagName('Part'):
|
||||
indexes = helpers.get_xml_attr(media_info.getElementsByTagName('Part')[0], 'indexes')
|
||||
part_id = helpers.get_xml_attr(media_info.getElementsByTagName('Part')[0], 'id')
|
||||
|
@ -1202,6 +1206,11 @@ class PmsConnect(object):
|
|||
else:
|
||||
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')
|
||||
|
||||
labels = []
|
||||
if session.getElementsByTagName('Label'):
|
||||
for label in session.getElementsByTagName('Label'):
|
||||
labels.append(helpers.get_xml_attr(label, 'tag'))
|
||||
|
||||
if helpers.get_xml_attr(session, 'type') == 'episode':
|
||||
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
|
||||
'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
|
||||
|
@ -1228,6 +1237,8 @@ class PmsConnect(object):
|
|||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||
'content_rating': helpers.get_xml_attr(session, 'contentRating'),
|
||||
'labels': labels,
|
||||
'transcode_key': transcode_key,
|
||||
'throttled': throttled,
|
||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||
|
@ -1287,6 +1298,8 @@ class PmsConnect(object):
|
|||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||
'content_rating': helpers.get_xml_attr(session, 'contentRating'),
|
||||
'labels': labels,
|
||||
'transcode_key': transcode_key,
|
||||
'throttled': throttled,
|
||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||
|
@ -1346,6 +1359,8 @@ class PmsConnect(object):
|
|||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||
'content_rating': helpers.get_xml_attr(session, 'contentRating'),
|
||||
'labels': labels,
|
||||
'transcode_key': transcode_key,
|
||||
'throttled': throttled,
|
||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||
|
@ -1415,6 +1430,11 @@ class PmsConnect(object):
|
|||
else:
|
||||
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')
|
||||
|
||||
labels = []
|
||||
if session.getElementsByTagName('Label'):
|
||||
for label in session.getElementsByTagName('Label'):
|
||||
labels.append(helpers.get_xml_attr(label, 'tag'))
|
||||
|
||||
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
|
||||
'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
|
||||
'media_index': helpers.get_xml_attr(session, 'index'),
|
||||
|
@ -1440,6 +1460,8 @@ class PmsConnect(object):
|
|||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||
'content_rating': helpers.get_xml_attr(session, 'contentRating'),
|
||||
'labels': labels,
|
||||
'transcode_key': transcode_key,
|
||||
'throttled': throttled,
|
||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import cherrypy
|
||||
import threading
|
||||
|
||||
from plexpy import common
|
||||
|
||||
|
@ -28,7 +27,6 @@ def get_session_info():
|
|||
_session = {'user_id': None,
|
||||
'user': None,
|
||||
'user_group': 'admin',
|
||||
'user_libraries': None,
|
||||
'expiry': None}
|
||||
try:
|
||||
return cherrypy.session.get(SESSION_KEY, _session)
|
||||
|
@ -49,12 +47,49 @@ def get_session_user_id():
|
|||
_session = get_session_info()
|
||||
return str(_session['user_id']) if _session and _session['user_id'] else None
|
||||
|
||||
def get_session_libraries():
|
||||
def get_session_shared_libraries():
|
||||
"""
|
||||
Returns a tuple of section_id for the current logged in session
|
||||
"""
|
||||
_session = get_session_info()
|
||||
return _session['user_libraries'] if _session and _session['user_libraries'] else None
|
||||
from plexpy import users
|
||||
user_details = users.Users().get_details(user_id=get_session_user_id())
|
||||
return user_details['shared_libraries']
|
||||
|
||||
def get_session_library_filters():
|
||||
"""
|
||||
Returns a dict of library filters for the current logged in session
|
||||
|
||||
{'content_rating': ('PG', 'R')
|
||||
'labels': ('label1', label2')},
|
||||
|
||||
"""
|
||||
from plexpy import users
|
||||
filters = users.Users().get_filters(user_id=get_session_user_id())
|
||||
return filters
|
||||
|
||||
def get_session_library_filters_type(filters, media_type=None):
|
||||
"""
|
||||
Returns a dict of library filters for the current logged in session
|
||||
|
||||
{'content_rating': ('PG', 'R')
|
||||
'labels': ('label1', label2')},
|
||||
|
||||
"""
|
||||
if media_type == 'movie':
|
||||
filters = filters.get('filter_movies', ())
|
||||
elif media_type == 'show' or media_type == 'season' or media_type == 'episode':
|
||||
filters = filters.get('filter_tv', ())
|
||||
elif media_type == 'artist' or media_type == 'album' or media_type == 'track':
|
||||
filters = filters.get('filter_music', ())
|
||||
elif media_type == 'photo' or media_type == 'photoAlbum' or media_type == 'picture':
|
||||
filters = filters.get('filter_photos', ())
|
||||
else:
|
||||
filters = filters.get('filter_all', ())
|
||||
|
||||
content_rating = filters.get('content_rating', ())
|
||||
labels = filters.get('labels', ())
|
||||
|
||||
return content_rating, tuple(f.lower() for f in labels)
|
||||
|
||||
def allow_session_user(user_id):
|
||||
"""
|
||||
|
@ -69,74 +104,11 @@ 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()
|
||||
session_library_ids = get_session_shared_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=True):
|
||||
"""
|
||||
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
|
||||
|
@ -150,3 +122,124 @@ def friendly_name_to_username(list_of_dicts):
|
|||
d['friendly_name'] = session_user
|
||||
|
||||
return list_of_dicts
|
||||
|
||||
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()
|
||||
|
||||
if not session_user_id:
|
||||
return list_of_dicts
|
||||
|
||||
session_library_ids = get_session_shared_libraries()
|
||||
session_library_filters = get_session_library_filters()
|
||||
|
||||
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:
|
||||
new_list_of_dicts = []
|
||||
|
||||
for d in list_of_dicts:
|
||||
if str(d.get('section_id','')) not in session_library_ids:
|
||||
continue
|
||||
|
||||
if d.get('media_type'):
|
||||
f_content_rating, f_labels = get_session_library_filters_type(session_library_filters,
|
||||
media_type=d['media_type'])
|
||||
|
||||
d_content_rating = d.get('content_rating', '').lower()
|
||||
d_labels = tuple(f.lower() for f in d.get('labels', ()))
|
||||
|
||||
if (not f_content_rating or set(d_content_rating).intersection(set(f_content_rating))) and \
|
||||
(not f_labels or set(d_labels).intersection(set(f_labels))):
|
||||
continue
|
||||
|
||||
new_list_of_dicts.append(d)
|
||||
|
||||
return new_list_of_dicts
|
||||
|
||||
return list_of_dicts
|
||||
|
||||
def mask_session_info(list_of_dicts, mask_metadata=True):
|
||||
"""
|
||||
Masks user info in a list of dictionary items to only display info for the current logged in session
|
||||
"""
|
||||
session_user_id = get_session_user_id()
|
||||
|
||||
if not session_user_id:
|
||||
return list_of_dicts
|
||||
|
||||
session_user = get_session_user()
|
||||
session_library_ids = get_session_shared_libraries()
|
||||
session_library_filters = get_session_library_filters()
|
||||
|
||||
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': '0',
|
||||
'parent_media_index': '0',
|
||||
'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': 'Title',
|
||||
'parent_title': 'Title',
|
||||
'title': 'Title',
|
||||
'rating_key': '',
|
||||
'parent_rating_key': '',
|
||||
'grandparent_rating_key': '',
|
||||
'year': '',
|
||||
'last_played': 'Title'
|
||||
}
|
||||
|
||||
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 not mask_metadata:
|
||||
continue
|
||||
|
||||
if 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]
|
||||
continue
|
||||
|
||||
media_type = d.get('media_type')
|
||||
if media_type:
|
||||
f_content_rating, f_labels = get_session_library_filters_type(session_library_filters,
|
||||
media_type=d['media_type'])
|
||||
|
||||
if not f_content_rating and not f_labels:
|
||||
continue
|
||||
|
||||
d_content_rating = d.get('content_rating', '')
|
||||
d_labels = tuple(f.lower() for f in d.get('labels', ()))
|
||||
|
||||
if not f_content_rating and f_labels:
|
||||
if set(d_labels).intersection(set(f_labels)):
|
||||
continue
|
||||
elif f_content_rating and not f_labels:
|
||||
if d_content_rating in f_content_rating:
|
||||
continue
|
||||
elif f_content_rating and f_labels:
|
||||
if d_content_rating in f_content_rating or set(d_labels).intersection(set(f_labels)):
|
||||
continue
|
||||
|
||||
for k, v in metadata_to_mask.iteritems():
|
||||
if k in d: d[k] = metadata_to_mask[k]
|
||||
|
||||
return list_of_dicts
|
112
plexpy/users.py
112
plexpy/users.py
|
@ -16,73 +16,6 @@
|
|||
import plexpy
|
||||
from plexpy import logger, datatables, common, database, helpers, session
|
||||
|
||||
def user_login(username=None, password=None):
|
||||
from plexpy import plextv
|
||||
|
||||
if not username and not password:
|
||||
return None
|
||||
|
||||
user_data = Users()
|
||||
|
||||
# Try to login to Plex.tv to check if the user has a vaild account
|
||||
plex_tv = plextv.PlexTV(username=username, password=password)
|
||||
plex_user = plex_tv.get_token()
|
||||
if plex_user:
|
||||
user_token = plex_user['auth_token']
|
||||
user_id = plex_user['user_id']
|
||||
|
||||
# Retrieve user token from the database and check against the Plex.tv token.
|
||||
# Also Make sure 'allow_guest' access is enabled for the user.
|
||||
# The user tokens should match if it is the same PlexPy install.
|
||||
tokens = user_data.get_tokens(user_id=user_id)
|
||||
if not tokens:
|
||||
# The user is not in the database
|
||||
return None
|
||||
elif not tokens['allow_guest'] or not user_token == tokens['user_token']:
|
||||
# Guest access is disabled, or user tokens don't match
|
||||
return None
|
||||
|
||||
# Otherwise it is a new user or token is no longer valid.
|
||||
# Check if the user is in the database, not deleted, and 'allow_guest' access.
|
||||
user_details = user_data.get_details(user_id=user_id)
|
||||
if user_id == str(user_details['user_id']) and \
|
||||
not user_details['deleted_user'] and user_details['allow_guest']:
|
||||
|
||||
# The user is in the database, so try to retrieve a new server token.
|
||||
# If a server token is returned, then the user is a valid friend
|
||||
plex_tv = plextv.PlexTV(token=user_token)
|
||||
server_token = plex_tv.get_server_token()
|
||||
if server_token:
|
||||
|
||||
# Register the new user / update the access tokens.
|
||||
monitor_db = database.MonitorDatabase()
|
||||
try:
|
||||
logger.debug(u"PlexPy Users :: Regestering tokens for user '%s' in the database." % username)
|
||||
result = monitor_db.action('UPDATE users SET user_token = ?, server_token = ? WHERE user_id = ?',
|
||||
[user_token, server_token, user_id])
|
||||
|
||||
if result:
|
||||
# Successful login
|
||||
return True
|
||||
else:
|
||||
logger.warn(u"PlexPy Users :: Unable to register user '%s' in database." % username)
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy Users :: Unable to register user '%s' in database: %s." % (username, e))
|
||||
return None
|
||||
else:
|
||||
logger.warn(u"PlexPy Users :: Unable to retrieve Plex.tv server token for user '%s'." % username)
|
||||
return None
|
||||
else:
|
||||
logger.warn(u"PlexPy Users :: Unable to register user '%s'. User not in the database." % username)
|
||||
return None
|
||||
else:
|
||||
logger.warn(u"PlexPy Users :: Unable to retrieve Plex.tv user token for user '%s'." % username)
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class Users(object):
|
||||
|
||||
def __init__(self):
|
||||
|
@ -333,7 +266,8 @@ class Users(object):
|
|||
'is_restricted': 0,
|
||||
'do_notify': 0,
|
||||
'keep_history': 1,
|
||||
'allow_guest': 0
|
||||
'allow_guest': 0,
|
||||
'shared_libraries': ()
|
||||
}
|
||||
|
||||
if not user_id and not user and not email:
|
||||
|
@ -345,19 +279,22 @@ class Users(object):
|
|||
try:
|
||||
if str(user_id).isdigit():
|
||||
query = 'SELECT user_id, username, friendly_name, thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \
|
||||
'email, is_home_user, is_allow_sync, is_restricted, do_notify, keep_history, deleted_user, allow_guest ' \
|
||||
'email, is_home_user, is_allow_sync, is_restricted, do_notify, keep_history, deleted_user, ' \
|
||||
'allow_guest, shared_libraries ' \
|
||||
'FROM users ' \
|
||||
'WHERE user_id = ? '
|
||||
result = monitor_db.select(query, args=[user_id])
|
||||
elif user:
|
||||
query = 'SELECT user_id, username, friendly_name, thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \
|
||||
'email, is_home_user, is_allow_sync, is_restricted, do_notify, keep_history, deleted_user, allow_guest ' \
|
||||
'email, is_home_user, is_allow_sync, is_restricted, do_notify, keep_history, deleted_user, ' \
|
||||
'allow_guest, shared_libraries ' \
|
||||
'FROM users ' \
|
||||
'WHERE username = ? '
|
||||
result = monitor_db.select(query, args=[user])
|
||||
elif email:
|
||||
query = 'SELECT user_id, username, friendly_name, thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \
|
||||
'email, is_home_user, is_allow_sync, is_restricted, do_notify, keep_history, deleted_user, allow_guest ' \
|
||||
'email, is_home_user, is_allow_sync, is_restricted, do_notify, keep_history, deleted_user, ' \
|
||||
'allow_guest, shared_libraries ' \
|
||||
'FROM users ' \
|
||||
'WHERE email = ? '
|
||||
result = monitor_db.select(query, args=[email])
|
||||
|
@ -395,7 +332,8 @@ class Users(object):
|
|||
'do_notify': item['do_notify'],
|
||||
'keep_history': item['keep_history'],
|
||||
'deleted_user': item['deleted_user'],
|
||||
'allow_guest': item['allow_guest']
|
||||
'allow_guest': item['allow_guest'],
|
||||
'shared_libraries': tuple(item['shared_libraries'].split(';'))
|
||||
}
|
||||
return user_details
|
||||
|
||||
|
@ -691,3 +629,33 @@ class Users(object):
|
|||
return None
|
||||
|
||||
return None
|
||||
|
||||
def get_filters(self, user_id=None):
|
||||
import urlparse
|
||||
|
||||
if not user_id:
|
||||
return {}
|
||||
|
||||
try:
|
||||
monitor_db = database.MonitorDatabase()
|
||||
query = 'SELECT filter_all, filter_movies, filter_tv, filter_music, filter_photos FROM users ' \
|
||||
'WHERE user_id = ?'
|
||||
result = monitor_db.select_single(query, args=[user_id])
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy Users :: Unable to execute database query for get_filters: %s." % e)
|
||||
result = {}
|
||||
|
||||
filters_list = {}
|
||||
for k, v in result.iteritems():
|
||||
filters = {}
|
||||
|
||||
for f in v.split('|'):
|
||||
if 'contentRating=' in f or 'label=' in f:
|
||||
filters.update(dict(urlparse.parse_qsl(f)))
|
||||
|
||||
filters['content_rating'] = tuple(f for f in filters.pop('contentRating', '').split(',') if f)
|
||||
filters['labels'] = tuple(f for f in filters.pop('label', '').split(',') if f)
|
||||
|
||||
filters_list[k] = filters
|
||||
|
||||
return filters_list
|
|
@ -26,12 +26,78 @@ import re
|
|||
|
||||
import plexpy
|
||||
from plexpy import logger
|
||||
from plexpy.users import Users, user_login
|
||||
from plexpy.database import MonitorDatabase
|
||||
from plexpy.users import Users
|
||||
from plexpy.plextv import PlexTV
|
||||
from plexpy.pmsconnect import PmsConnect
|
||||
|
||||
|
||||
SESSION_KEY = '_cp_username'
|
||||
|
||||
def user_login(username=None, password=None):
|
||||
if not username and not password:
|
||||
return None
|
||||
|
||||
user_data = Users()
|
||||
|
||||
# Try to login to Plex.tv to check if the user has a vaild account
|
||||
plex_tv = PlexTV(username=username, password=password)
|
||||
plex_user = plex_tv.get_token()
|
||||
if plex_user:
|
||||
user_token = plex_user['auth_token']
|
||||
user_id = plex_user['user_id']
|
||||
|
||||
# Retrieve user token from the database and check against the Plex.tv token.
|
||||
# Also Make sure 'allow_guest' access is enabled for the user.
|
||||
# The user tokens should match if it is the same PlexPy install.
|
||||
tokens = user_data.get_tokens(user_id=user_id)
|
||||
if not tokens:
|
||||
# The user is not in the database
|
||||
return None
|
||||
elif not tokens['allow_guest'] or not user_token == tokens['user_token']:
|
||||
# Guest access is disabled, or user tokens don't match
|
||||
return None
|
||||
|
||||
# Otherwise it is a new user or token is no longer valid.
|
||||
# Check if the user is in the database, not deleted, and 'allow_guest' access.
|
||||
user_details = user_data.get_details(user_id=user_id)
|
||||
if user_id == str(user_details['user_id']) and \
|
||||
not user_details['deleted_user'] and user_details['allow_guest']:
|
||||
|
||||
# The user is in the database, so try to retrieve a new server token.
|
||||
# If a server token is returned, then the user is a valid friend
|
||||
plex_tv = PlexTV(token=user_token)
|
||||
server_token = plex_tv.get_server_token()
|
||||
if server_token:
|
||||
|
||||
# Register the new user / update the access tokens.
|
||||
monitor_db = MonitorDatabase()
|
||||
try:
|
||||
logger.debug(u"PlexPy Users :: Regestering tokens for user '%s' in the database." % username)
|
||||
result = monitor_db.action('UPDATE users SET user_token = ?, server_token = ? WHERE user_id = ?',
|
||||
[user_token, server_token, user_id])
|
||||
|
||||
if result:
|
||||
# Successful login
|
||||
return True
|
||||
else:
|
||||
logger.warn(u"PlexPy Users :: Unable to register user '%s' in database." % username)
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.warn(u"PlexPy Users :: Unable to register user '%s' in database: %s." % (username, e))
|
||||
return None
|
||||
else:
|
||||
logger.warn(u"PlexPy Users :: Unable to retrieve Plex.tv server token for user '%s'." % username)
|
||||
return None
|
||||
else:
|
||||
logger.warn(u"PlexPy Users :: Unable to register user '%s'. User not in the database." % username)
|
||||
return None
|
||||
else:
|
||||
logger.warn(u"PlexPy Users :: Unable to retrieve Plex.tv user token for user '%s'." % username)
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
def check_credentials(username, password):
|
||||
"""Verifies credentials for username and password.
|
||||
Returns True and the user group on success or False and no user group"""
|
||||
|
@ -151,16 +217,10 @@ class AuthController(object):
|
|||
user_details = Users().get_details(email=username)
|
||||
else:
|
||||
user_details = Users().get_details(user=username)
|
||||
|
||||
user_id = user_details['user_id']
|
||||
|
||||
user_tokens = Users().get_tokens(user_id=user_details['user_id'])
|
||||
server_token = user_tokens['server_token']
|
||||
|
||||
library_details = PmsConnect(token=server_token).get_server_children()
|
||||
user_libraries = tuple(d['section_id'] for d in library_details['libraries_list'])
|
||||
else:
|
||||
user_id = None
|
||||
user_libraries = None
|
||||
|
||||
expiry = datetime.now() + (timedelta(days=30) if remember_me == '1' else timedelta(minutes=60))
|
||||
|
||||
|
@ -169,7 +229,6 @@ class AuthController(object):
|
|||
cherrypy.session[SESSION_KEY] = {'user_id': user_id,
|
||||
'user': username,
|
||||
'user_group': user_group,
|
||||
'user_libraries': user_libraries,
|
||||
'expiry': expiry}
|
||||
|
||||
self.on_login(username)
|
||||
|
|
|
@ -29,7 +29,7 @@ from plexpy import logger, notifiers, plextv, pmsconnect, common, log_reader, \
|
|||
datafactory, graphs, users, libraries, database, web_socket
|
||||
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.session import get_session_info, get_session_user_id, allow_session_user, allow_session_library
|
||||
from plexpy.webauth import AuthController, requireAuth, member_of, name_is, SESSION_KEY
|
||||
|
||||
|
||||
|
@ -182,7 +182,7 @@ class WebInterface(object):
|
|||
def get_current_activity(self, **kwargs):
|
||||
|
||||
try:
|
||||
pms_connect = pmsconnect.PmsConnect()
|
||||
pms_connect = pmsconnect.PmsConnect(token=plexpy.CONFIG.PMS_TOKEN)
|
||||
result = pms_connect.get_current_activity()
|
||||
|
||||
data_factory = datafactory.DataFactory()
|
||||
|
@ -205,7 +205,7 @@ class WebInterface(object):
|
|||
def get_current_activity_header(self, **kwargs):
|
||||
|
||||
try:
|
||||
pms_connect = pmsconnect.PmsConnect()
|
||||
pms_connect = pmsconnect.PmsConnect(token=plexpy.CONFIG.PMS_TOKEN)
|
||||
result = pms_connect.get_current_activity()
|
||||
except:
|
||||
return serve_template(templatename="current_activity_header.html", data=None)
|
||||
|
@ -468,7 +468,7 @@ class WebInterface(object):
|
|||
return serve_template(templatename="library_recently_added.html", data=None, title="Recently Added")
|
||||
|
||||
@cherrypy.expose
|
||||
@requireAuth()
|
||||
@requireAuth(member_of("admin"))
|
||||
@addtoapi()
|
||||
def get_library_media_info(self, section_id=None, section_type=None, rating_key=None, refresh='', **kwargs):
|
||||
|
||||
|
@ -1863,6 +1863,9 @@ class WebInterface(object):
|
|||
raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT)
|
||||
|
||||
return serve_template(templatename="info.html", data=metadata, title="Info", config=config, source=source)
|
||||
else:
|
||||
if get_session_user_id():
|
||||
raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT)
|
||||
else:
|
||||
return self.update_metadata(rating_key, query)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue