mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-08 14:10:52 -07:00
Add Last Watched to home stats
This commit is contained in:
parent
a682cd31af
commit
28d136075c
4 changed files with 229 additions and 14 deletions
|
@ -1597,6 +1597,29 @@ a .season-episodes-card-overlay:hover {
|
||||||
left: 0px;
|
left: 0px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
.home-platforms-instance-last-user {
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
padding: 6px 0 0 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.home-platforms-instance-last-user h5 {
|
||||||
|
font-size: 12px;
|
||||||
|
position: relative;
|
||||||
|
margin: 0 0 3px 0;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.home-platforms-instance-last-user p {
|
||||||
|
color: #aaa;
|
||||||
|
font-size: 12px;
|
||||||
|
float: left;
|
||||||
|
clear: left;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
.home-platforms-instance-poster {
|
.home-platforms-instance-poster {
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -1724,6 +1747,29 @@ a .season-episodes-card-overlay:hover {
|
||||||
left: 0px;
|
left: 0px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
.home-platforms-instance-list-last-user {
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 0 0 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.home-platforms-instance-list-last-user h5 {
|
||||||
|
font-size: 12px;
|
||||||
|
position: relative;
|
||||||
|
margin: 0 0 2px 0;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.home-platforms-instance-list-last-user p {
|
||||||
|
color: #aaa;
|
||||||
|
font-size: 12px;
|
||||||
|
float: left;
|
||||||
|
clear: left;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
.home-platforms-instance-list-poster {
|
.home-platforms-instance-list-poster {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
|
@ -1769,7 +1815,7 @@ a .season-episodes-card-overlay:hover {
|
||||||
}
|
}
|
||||||
.home-platforms-instance-list-chevron {
|
.home-platforms-instance-list-chevron {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 100px;
|
top: 105px;
|
||||||
right: 0;
|
right: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ data[array_index]['rows'] :: Usable parameters
|
||||||
|
|
||||||
row_id Return the db row id for a metadata item if one exists
|
row_id Return the db row id for a metadata item if one exists
|
||||||
|
|
||||||
|
== Only if 'stat_id' is 'top_tv' or 'popular_tv' or 'top_movies' or 'popular_movies' or 'last_watched' ==
|
||||||
|
thumb Return the thumb for the media item.
|
||||||
|
|
||||||
== Only if 'stat_id' is 'top_tv' or 'popular_tv' ==
|
== Only if 'stat_id' is 'top_tv' or 'popular_tv' ==
|
||||||
grandparent_thumb Returns location of the item's thumbnail. Use with pms_image_proxy.
|
grandparent_thumb Returns location of the item's thumbnail. Use with pms_image_proxy.
|
||||||
rating_key Returns the unique identifier for the media item.
|
rating_key Returns the unique identifier for the media item.
|
||||||
|
@ -29,15 +32,18 @@ total_duration Returns the total duration for the associated stat.
|
||||||
== Only of 'stat_id' is 'popular_tv' or 'popular_movies' ==
|
== Only of 'stat_id' is 'popular_tv' or 'popular_movies' ==
|
||||||
users_watched Returns the count for the associated stat.
|
users_watched Returns the count for the associated stat.
|
||||||
|
|
||||||
== Only if 'stat_id' is 'top_user' ==
|
== Only if 'stat_id' is 'top_user' or 'last_watched' ==
|
||||||
thumb Returns url of the user's gravatar. Returns '' if none exists.
|
user_thumb Returns url of the user's gravatar. Returns '' if none exists.
|
||||||
user Returns the username for the associated stat.
|
user Returns the username for the associated stat.
|
||||||
user_id Returns the user id for the associated stat.
|
user_id Returns the user id for the associated stat.
|
||||||
friendly_name Returns the friendly name of the user for the associated stat.
|
friendly_name Returns the friendly name of the user for the associated stat.
|
||||||
|
|
||||||
== Only if 'stat_id' is 'top_platform' ==
|
== Only if 'stat_id' is 'top_platform' or 'last_watched' ==
|
||||||
platform_type Returns the platform name for the associated stat.
|
platform_type Returns the platform name for the associated stat.
|
||||||
|
|
||||||
|
== Only if 'stat_id' is 'last_watched' ==
|
||||||
|
last_watch Returns the time the media item was last watched.
|
||||||
|
|
||||||
DOCUMENTATION :: END
|
DOCUMENTATION :: END
|
||||||
</%doc>
|
</%doc>
|
||||||
|
|
||||||
|
@ -395,9 +401,9 @@ DOCUMENTATION :: END
|
||||||
% else:
|
% else:
|
||||||
<a href="user?user=${top_stat['rows'][0]['user']}">
|
<a href="user?user=${top_stat['rows'][0]['user']}">
|
||||||
% endif
|
% endif
|
||||||
% if top_stat['rows'][0]['thumb'] != '':
|
% if top_stat['rows'][0]['user_thumb'] != '':
|
||||||
<div class="home-platforms-instance-poster">
|
<div class="home-platforms-instance-poster">
|
||||||
<div class="home-platforms-instance-oval" style="background-image: url(${top_stat['rows'][0]['thumb']});"></div>
|
<div class="home-platforms-instance-oval" style="background-image: url(${top_stat['rows'][0]['user_thumb']});"></div>
|
||||||
</div>
|
</div>
|
||||||
% else:
|
% else:
|
||||||
<div class="home-platforms-instance-poster">
|
<div class="home-platforms-instance-poster">
|
||||||
|
@ -439,9 +445,9 @@ DOCUMENTATION :: END
|
||||||
% else:
|
% else:
|
||||||
<a href="user?user=${top_stat['rows'][loop.index]['user']}">
|
<a href="user?user=${top_stat['rows'][loop.index]['user']}">
|
||||||
% endif
|
% endif
|
||||||
% if top_stat['rows'][loop.index]['thumb'] != '':
|
% if top_stat['rows'][loop.index]['user_thumb'] != '':
|
||||||
<div class="home-platforms-instance-poster">
|
<div class="home-platforms-instance-poster">
|
||||||
<div class="home-platforms-instance-list-oval" style="background-image: url(${top_stat['rows'][loop.index]['thumb']});"></div>
|
<div class="home-platforms-instance-list-oval" style="background-image: url(${top_stat['rows'][loop.index]['user_thumb']});"></div>
|
||||||
</div>
|
</div>
|
||||||
% else:
|
% else:
|
||||||
<div class="home-platforms-instance-poster">
|
<div class="home-platforms-instance-poster">
|
||||||
|
@ -479,7 +485,9 @@ DOCUMENTATION :: END
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="platform-stat" class="home-platforms-instance-poster">
|
<div id="platform-stat" class="home-platforms-instance-poster">
|
||||||
<div class="home-platforms-instance-box" style="background-image: url(interfaces/default/images/platforms/default.png);"></div>
|
<script>
|
||||||
|
$("#platform-stat").html("<div class='home-platforms-instance-box' style='background-image: url(" + getPlatformImagePath('${top_stat['rows'][0]['platform_type']}') + ");'>");
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
%if len(top_stat['rows']) > 1:
|
%if len(top_stat['rows']) > 1:
|
||||||
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
|
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
|
||||||
|
@ -521,9 +529,106 @@ DOCUMENTATION :: END
|
||||||
% endif
|
% endif
|
||||||
</li>
|
</li>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
% elif top_stat['stat_id'] == 'last_watched' and top_stat['rows']:
|
||||||
$("#platform-stat").html("<div class='home-platforms-instance-box' style='background-image: url(" + getPlatformImagePath('${top_stat['rows'][0]['platform_type']}') + ");'>");
|
<div class="home-platforms-instance">
|
||||||
</script>
|
<li>
|
||||||
|
<div class="home-platforms-instance-info">
|
||||||
|
<div class="home-platforms-instance-name">
|
||||||
|
<h4>Last Watched</h4>
|
||||||
|
<h5>
|
||||||
|
<a href="info?source=history&item_id=${top_stat['rows'][0]['row_id']}">
|
||||||
|
${top_stat['rows'][0]['title']}
|
||||||
|
</a>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="home-platforms-instance-last-user">
|
||||||
|
<h5>
|
||||||
|
% if top_stat['rows'][0]['user_id']:
|
||||||
|
<a href="user?user_id=${top_stat['rows'][0]['user_id']}">
|
||||||
|
% else:
|
||||||
|
<a href="user?user=${top_stat['rows'][0]['user']}">
|
||||||
|
% endif
|
||||||
|
${top_stat['rows'][0]['friendly_name']}
|
||||||
|
</a>
|
||||||
|
</h5>
|
||||||
|
<p>
|
||||||
|
<span id="last-watch-stat">
|
||||||
|
<script>
|
||||||
|
$('#last-watch-stat').text(moment(${top_stat['rows'][0]['last_watch']},"X").format(date_format));
|
||||||
|
</script>
|
||||||
|
</span> - ${top_stat['rows'][0]['platform_type']}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="info?source=history&item_id=${top_stat['rows'][0]['row_id']}">
|
||||||
|
% if top_stat['rows'][0]['thumb']:
|
||||||
|
<div class="home-platforms-instance-poster">
|
||||||
|
<div class="home-platforms-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][0]['thumb']}&width=300&height=450&fallback=poster);"></div>
|
||||||
|
</div>
|
||||||
|
% else:
|
||||||
|
<div class="home-platforms-instance-poster">
|
||||||
|
<div class="home-platforms-poster-face" style="background-image: url(interfaces/default/images/poster.png);"></div>
|
||||||
|
</div>
|
||||||
|
% endif
|
||||||
|
</a>
|
||||||
|
%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">
|
||||||
|
<div class="slider">
|
||||||
|
<div class="home-platforms-instance-list">
|
||||||
|
% for row in top_stat['rows']:
|
||||||
|
%if loop.index > 0:
|
||||||
|
<li>
|
||||||
|
<div class="home-platforms-instance-list-info">
|
||||||
|
<div class="home-platforms-instance-list-name">
|
||||||
|
<h5>
|
||||||
|
<a href="info?source=history&item_id=${top_stat['rows'][loop.index]['row_id']}">
|
||||||
|
${top_stat['rows'][loop.index]['title']}
|
||||||
|
</a>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="home-platforms-instance-list-last-user">
|
||||||
|
<h5>
|
||||||
|
% if top_stat['rows'][loop.index]['user_id']:
|
||||||
|
<a href="user?user_id=${top_stat['rows'][loop.index]['user_id']}">
|
||||||
|
% else:
|
||||||
|
<a href="user?user=${top_stat['rows'][loop.index]['user']}">
|
||||||
|
% endif
|
||||||
|
${top_stat['rows'][loop.index]['friendly_name']}
|
||||||
|
</a>
|
||||||
|
</h5>
|
||||||
|
<p>
|
||||||
|
<span id="home-platforms-instance-list-last-watch-${loop.index + 1}">
|
||||||
|
<script>
|
||||||
|
$('#home-platforms-instance-list-last-watch-${loop.index + 1}').text(moment(${top_stat['rows'][loop.index]['last_watch']},"X").format(date_format));
|
||||||
|
</script>
|
||||||
|
</span> - ${top_stat['rows'][loop.index]['platform_type']}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="info?source=history&item_id=${top_stat['rows'][loop.index]['row_id']}">
|
||||||
|
% 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-list-poster-face" style="background-image: url(interfaces/default/images/poster.png);"></div>
|
||||||
|
</div>
|
||||||
|
% endif
|
||||||
|
</a>
|
||||||
|
<div class="home-platforms-instance-list-number">
|
||||||
|
<h4>${loop.index + 1}</h4>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
% endif
|
||||||
|
% endfor
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
% endif
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
% endif
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -110,6 +110,17 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var date_format = 'YYYY-MM-DD';
|
||||||
|
var time_format = 'hh:mm a';
|
||||||
|
$.ajax({
|
||||||
|
url: 'get_date_formats',
|
||||||
|
type: 'GET',
|
||||||
|
success: function(data) {
|
||||||
|
date_format = data.date_format;
|
||||||
|
time_format = data.time_format;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
getHomeStats(${config['home_stats_length']}, ${config['home_stats_type']}, ${config['home_stats_count']});
|
getHomeStats(${config['home_stats_length']}, ${config['home_stats_type']}, ${config['home_stats_count']});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ class DataFactory(object):
|
||||||
stat_count = '5'
|
stat_count = '5'
|
||||||
|
|
||||||
# This actually determines the output order in the home page
|
# This actually determines the output order in the home page
|
||||||
stats_queries = ["top_tv", "popular_tv", "top_movies", "popular_movies", "top_users", "top_platforms"]
|
stats_queries = ["top_tv", "popular_tv", "top_movies", "popular_movies", "top_users", "top_platforms", "last_watched"]
|
||||||
home_stats = []
|
home_stats = []
|
||||||
|
|
||||||
for stat in stats_queries:
|
for stat in stats_queries:
|
||||||
|
@ -361,7 +361,7 @@ class DataFactory(object):
|
||||||
'total_plays': item[2],
|
'total_plays': item[2],
|
||||||
'total_duration': item[3],
|
'total_duration': item[3],
|
||||||
'last_play': item[4],
|
'last_play': item[4],
|
||||||
'thumb': user_thumb,
|
'user_thumb': user_thumb,
|
||||||
'grandparent_thumb': '',
|
'grandparent_thumb': '',
|
||||||
'users_watched': '',
|
'users_watched': '',
|
||||||
'rating_key': '',
|
'rating_key': '',
|
||||||
|
@ -418,6 +418,59 @@ class DataFactory(object):
|
||||||
'stat_type': sort_type,
|
'stat_type': sort_type,
|
||||||
'rows': top_platform})
|
'rows': top_platform})
|
||||||
|
|
||||||
|
elif 'last_watched' in stat:
|
||||||
|
last_watched = []
|
||||||
|
try:
|
||||||
|
query = 'SELECT session_history_metadata.id, ' \
|
||||||
|
'session_history.user, ' \
|
||||||
|
'(case when users.friendly_name is null then session_history.user else ' \
|
||||||
|
'users.friendly_name end) as friendly_name,' \
|
||||||
|
'users.user_id, ' \
|
||||||
|
'users.custom_avatar_url as user_thumb, ' \
|
||||||
|
'session_history_metadata.full_title, ' \
|
||||||
|
'session_history_metadata.rating_key, ' \
|
||||||
|
'session_history_metadata.thumb, ' \
|
||||||
|
'session_history_metadata.grandparent_thumb, ' \
|
||||||
|
'MAX(session_history.started) as last_watch, ' \
|
||||||
|
'session_history.player as platform ' \
|
||||||
|
'FROM session_history_metadata ' \
|
||||||
|
'JOIN session_history ON session_history_metadata.id = session_history.id ' \
|
||||||
|
'LEFT OUTER JOIN users ON session_history.user_id = users.user_id ' \
|
||||||
|
'WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
|
||||||
|
'>= datetime("now", "-%s days", "localtime") ' \
|
||||||
|
'AND (session_history_metadata.media_type = "movie" ' \
|
||||||
|
'OR session_history_metadata.media_type = "episode") ' \
|
||||||
|
'GROUP BY session_history_metadata.full_title ' \
|
||||||
|
'ORDER BY last_watch DESC ' \
|
||||||
|
'LIMIT %s' % (time_range, stat_count)
|
||||||
|
result = monitor_db.select(query)
|
||||||
|
except:
|
||||||
|
logger.warn("Unable to execute database query.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
for item in result:
|
||||||
|
if not item[8] or item[8] == '':
|
||||||
|
thumb = item[7]
|
||||||
|
else:
|
||||||
|
thumb = item[8]
|
||||||
|
|
||||||
|
row = {'row_id': item[0],
|
||||||
|
'user': item[1],
|
||||||
|
'friendly_name': item[2],
|
||||||
|
'user_id': item[3],
|
||||||
|
'user_thumb': item[4],
|
||||||
|
'title': item[5],
|
||||||
|
'rating_key': item[6],
|
||||||
|
'thumb': thumb,
|
||||||
|
'grandparent_thumb': item[8],
|
||||||
|
'last_watch': item[9],
|
||||||
|
'platform': item[10],
|
||||||
|
}
|
||||||
|
last_watched.append(row)
|
||||||
|
|
||||||
|
home_stats.append({'stat_id': stat,
|
||||||
|
'rows': last_watched})
|
||||||
|
|
||||||
return home_stats
|
return home_stats
|
||||||
|
|
||||||
def get_stream_details(self, row_id=None):
|
def get_stream_details(self, row_id=None):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue