New watch statistics cards

This commit is contained in:
JonnyWong16 2017-11-05 00:30:44 -07:00
parent de589f59a1
commit 8d2c9a7764
3 changed files with 488 additions and 1110 deletions

View file

@ -9,7 +9,7 @@ a {
} }
a:hover, a:hover,
a:focus { a:focus {
color: #e9a049; color: #f9be03;
text-decoration: none; text-decoration: none;
outline: none; outline: none;
} }
@ -974,6 +974,264 @@ a .dashboard-activity-metadata-user-thumb:hover {
.dashboard-activity-metadata-title a:hover { .dashboard-activity-metadata-title a:hover {
color: #e9a049; color: #e9a049;
} }
.dashboard-stats-instance {
float: left;
position: relative;
height: 160px;
min-width: 350px;
max-width: 500px;
margin-right: 20px;
margin-bottom: 20px;
}
.dashboard-stats-container {
height: 160px;
width: 100%;
position: relative;
padding: 0px;
-webkit-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
overflow: hidden;
}
.dashboard-stats-background-overlay {
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: nowrap;
flex-wrap: nowrap;
height: 160px;
width: 100%;
padding: 5px;
overflow: hidden;
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
-moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
}
.dashboard-stats-background {
background-color: #282828;
background-position: center;
background-size: cover;
height: 160px;
width: 100%;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0.40;
-webkit-filter: blur(3px);
-moz-filter: blur(3px);
filter: blur(3px);
-webkit-transition: background .2s linear;
transition: background .2s linear;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
z-index: -1;
}
.dashboard-stats-background.flat {
opacity: 1;
}
.dashboard-stats-poster {
background-position: center;
background-size: cover;
height: 150px;
width: 100px;
margin-right: 5px;
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
-moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
-webkit-flex-shrink: 0;
flex-shrink: 0;
-webkit-transition: background .2s linear;
transition: background .2s linear;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
z-index: 1;
}
.dashboard-stats-cover {
background-position: center;
background-size: cover;
height: 100px;
width: 100px;
margin-top: 25px;
margin-right: 5px;
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
-moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
-webkit-flex-shrink: 0;
flex-shrink: 0;
-webkit-transition: background .2s linear;
transition: background .2s linear;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
z-index: 1;
}
.dashboard-stats-circle {
background-position: center;
background-size: cover;
height: 100px;
width: 100px;
margin-top: 25px;
margin-right: 5px;
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
-moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
-webkit-flex-shrink: 0;
flex-shrink: 0;
-webkit-transition: background .2s linear;
transition: background .2s linear;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
z-index: 1;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 350%;
overflow: hidden;
}
.dashboard-stats-square {
background-position: center;
background-size: cover;
height: 100px;
width: 100px;
margin-top: 25px;
margin-right: 5px;
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
-moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
box-shadow: 0 0 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
-webkit-flex-shrink: 0;
flex-shrink: 0;
-webkit-transition: background .2s linear;
transition: background .2s linear;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
z-index: 1;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
overflow: hidden;
}
.dashboard-stats-info-container {
display: -webkit-flex;
display: flex;
flex-direction: column;
height: 150px;
width: 385px;
overflow: hidden;
}
.dashboard-stats-info-title {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: baseline;
height: 30px;
width: 385px;
padding: 5px 5px 5px 15px;
line-height: 20px;
border-bottom: 1px solid rgba(255,255,255,.1);
-webkit-flex-grow: 1;
flex-grow: 1;
z-index: 1;
}
.dashboard-stats-info-title h4 {
margin: 0;
-webkit-flex-grow: 1;
flex-grow: 1;
}
.dashboard-stats-info-title .dashboard-stats-stats-units {
color: #aaa;
font-size: 12px;
text-align: right;
text-transform: uppercase;
}
.dashboard-stats-info-scroller {
height: 120px;
width: 385px;
-webkit-flex-grow: 1;
flex-grow: 1;
z-index: 1;
}
.dashboard-stats-info-scroller.scrollbar-macosx > .scroll-element.scroll-y {
left: 10px;
}
.dashboard-stats-info-scroller.scrollbar-macosx > .scroll-element .scroll-bar {
background-color: #999;
}
.dashboard-stats-info {
width: 100%;
font-size: 12px;
padding: 5px 0 5px 15px;
position: relative;
}
.dashboard-stats-info-list {
margin-bottom: 20px;
padding-right: 0;
}
.dashboard-stats-info-list:last-of-type {
margin-bottom: 0;
}
.dashboard-stats-info-item {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: baseline;
width: 100%;
padding: 2.5px 5px;
line-height: 14px;
border-bottom: 1px solid rgba(255,255,255,0.05);
}
.dashboard-stats-info-item:last-of-type {
margin-bottom: 0;
}
.dashboard-stats-info-item .sub-heading {
height: 100%;
width: 6px;
color: #aaa;
font-size: 10px;
text-align: right;
text-transform: uppercase;
}
.dashboard-stats-info-item .sub-value {
height: 100%;
margin-left: 10px;
font-size: 12px;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
-webkit-flex-grow: 1;
flex-grow: 1;
}
.dashboard-stats-info-item .sub-count {
height: 100%;
margin-left: 10px;
color: #f9be03;
font-size: 12px;
text-align: right;
white-space: nowrap;
overflow: hidden;
}
.dashboard-stats-info-item:first-of-type {
padding: 5px 5px;
line-height: 20px;
}
.dashboard-stats-info-item:first-of-type .sub-heading {
font-size: 13px;
}
.dashboard-stats-info-item:first-of-type .sub-value {
font-size: 16px;
}
.dashboard-stats-info-item:first-of-type .sub-count {
font-size: 16px;
}
.dashboard-stats-info-item:hover {
background-color: rgba(255,255,255,0.05);
}
a:hover .dashboard-stats-poster,
a:hover .dashboard-stats-cover,
a:hover .dashboard-stats-circle,
a:hover .dashboard-stats-square {
-webkit-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;
}
#dashboard-no-recently-added { #dashboard-no-recently-added {
margin-bottom: 20px; margin-bottom: 20px;
} }

File diff suppressed because it is too large Load diff

View file

@ -281,104 +281,7 @@ class DataFactory(object):
home_stats = [] home_stats = []
for stat in stats_cards: for stat in stats_cards:
if stat == 'top_tv': if stat == 'top_movies':
top_tv = []
try:
query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \
't.art, t.media_type, t.content_rating, t.labels, t.started, ' \
'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) ' \
' AS d ' \
' FROM session_history ' \
' 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" ' \
' GROUP BY %s) AS t ' \
'GROUP BY t.grandparent_title ' \
'ORDER BY %s DESC, started DESC ' \
'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)
return None
for item in result:
row = {'title': item['grandparent_title'],
'total_plays': item['total_plays'],
'total_duration': item['total_duration'],
'users_watched': '',
'rating_key': item['grandparent_rating_key'],
'last_play': item['last_watch'],
'grandparent_thumb': item['grandparent_thumb'],
'thumb': '',
'art': item['art'],
'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': '',
'platform': '',
'row_id': item['id']
}
top_tv.append(row)
home_stats.append({'stat_id': stat,
'stat_type': sort_type,
'rows': session.mask_session_info(top_tv)})
elif stat == 'popular_tv':
popular_tv = []
try:
query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \
't.art, t.media_type, t.content_rating, t.labels, t.started, ' \
'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) - ' \
' (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) ' \
' AS d ' \
' FROM session_history ' \
' 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" ' \
' GROUP BY %s) AS t ' \
'GROUP BY t.grandparent_title ' \
'ORDER BY users_watched DESC, %s DESC, started DESC ' \
'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)
return None
for item in result:
row = {'title': item['grandparent_title'],
'users_watched': item['users_watched'],
'rating_key': item['grandparent_rating_key'],
'last_play': item['last_watch'],
'total_plays': item['total_plays'],
'grandparent_thumb': item['grandparent_thumb'],
'thumb': '',
'art': item['art'],
'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': '',
'platform': '',
'row_id': item['id']
}
popular_tv.append(row)
home_stats.append({'stat_id': stat,
'rows': session.mask_session_info(popular_tv)})
elif stat == 'top_movies':
top_movies = [] top_movies = []
try: try:
query = 'SELECT t.id, t.full_title, t.rating_key, t.thumb, t.section_id, ' \ query = 'SELECT t.id, t.full_title, t.rating_key, t.thumb, t.section_id, ' \
@ -425,6 +328,7 @@ class DataFactory(object):
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_type': sort_type, 'stat_type': sort_type,
'stat_title': 'Most Watched Movies',
'rows': session.mask_session_info(top_movies)}) 'rows': session.mask_session_info(top_movies)})
elif stat == 'popular_movies': elif stat == 'popular_movies':
@ -473,8 +377,108 @@ class DataFactory(object):
popular_movies.append(row) popular_movies.append(row)
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_title': 'Most Popular Movies',
'rows': session.mask_session_info(popular_movies)}) 'rows': session.mask_session_info(popular_movies)})
elif stat == 'top_tv':
top_tv = []
try:
query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \
't.art, t.media_type, t.content_rating, t.labels, t.started, ' \
'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) ' \
' AS d ' \
' FROM session_history ' \
' 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" ' \
' GROUP BY %s) AS t ' \
'GROUP BY t.grandparent_title ' \
'ORDER BY %s DESC, started DESC ' \
'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)
return None
for item in result:
row = {'title': item['grandparent_title'],
'total_plays': item['total_plays'],
'total_duration': item['total_duration'],
'users_watched': '',
'rating_key': item['grandparent_rating_key'],
'last_play': item['last_watch'],
'grandparent_thumb': item['grandparent_thumb'],
'thumb': item['grandparent_thumb'],
'art': item['art'],
'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': '',
'platform': '',
'row_id': item['id']
}
top_tv.append(row)
home_stats.append({'stat_id': stat,
'stat_type': sort_type,
'stat_title': 'Most Watched TV Shows',
'rows': session.mask_session_info(top_tv)})
elif stat == 'popular_tv':
popular_tv = []
try:
query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \
't.art, t.media_type, t.content_rating, t.labels, t.started, ' \
'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) - ' \
' (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) ' \
' AS d ' \
' FROM session_history ' \
' 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" ' \
' GROUP BY %s) AS t ' \
'GROUP BY t.grandparent_title ' \
'ORDER BY users_watched DESC, %s DESC, started DESC ' \
'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)
return None
for item in result:
row = {'title': item['grandparent_title'],
'users_watched': item['users_watched'],
'rating_key': item['grandparent_rating_key'],
'last_play': item['last_watch'],
'total_plays': item['total_plays'],
'grandparent_thumb': item['grandparent_thumb'],
'thumb': item['grandparent_thumb'],
'art': item['art'],
'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': '',
'platform': '',
'row_id': item['id']
}
popular_tv.append(row)
home_stats.append({'stat_id': stat,
'stat_title': 'Most Popular TV Shows',
'rows': session.mask_session_info(popular_tv)})
elif stat == 'top_music': elif stat == 'top_music':
top_music = [] top_music = []
try: try:
@ -506,7 +510,7 @@ class DataFactory(object):
'rating_key': item['grandparent_rating_key'], 'rating_key': item['grandparent_rating_key'],
'last_play': item['last_watch'], 'last_play': item['last_watch'],
'grandparent_thumb': item['grandparent_thumb'], 'grandparent_thumb': item['grandparent_thumb'],
'thumb': '', 'thumb': item['grandparent_thumb'],
'art': item['art'], 'art': item['art'],
'section_id': item['section_id'], 'section_id': item['section_id'],
'media_type': item['media_type'], 'media_type': item['media_type'],
@ -522,6 +526,7 @@ class DataFactory(object):
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_type': sort_type, 'stat_type': sort_type,
'stat_title': 'Most Played Artists',
'rows': session.mask_session_info(top_music)}) 'rows': session.mask_session_info(top_music)})
elif stat == 'popular_music': elif stat == 'popular_music':
@ -555,7 +560,7 @@ class DataFactory(object):
'last_play': item['last_watch'], 'last_play': item['last_watch'],
'total_plays': item['total_plays'], 'total_plays': item['total_plays'],
'grandparent_thumb': item['grandparent_thumb'], 'grandparent_thumb': item['grandparent_thumb'],
'thumb': '', 'thumb': item['grandparent_thumb'],
'art': item['art'], 'art': item['art'],
'section_id': item['section_id'], 'section_id': item['section_id'],
'media_type': item['media_type'], 'media_type': item['media_type'],
@ -570,6 +575,7 @@ class DataFactory(object):
popular_music.append(row) popular_music.append(row)
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_title': 'Most Popular Artists',
'rows': session.mask_session_info(popular_music)}) 'rows': session.mask_session_info(popular_music)})
elif stat == 'top_users': elif stat == 'top_users':
@ -610,8 +616,10 @@ class DataFactory(object):
'total_plays': item['total_plays'], 'total_plays': item['total_plays'],
'total_duration': item['total_duration'], 'total_duration': item['total_duration'],
'last_play': item['last_watch'], 'last_play': item['last_watch'],
'thumb': user_thumb,
'user_thumb': user_thumb, 'user_thumb': user_thumb,
'grandparent_thumb': '', 'grandparent_thumb': '',
'art': '',
'users_watched': '', 'users_watched': '',
'rating_key': '', 'rating_key': '',
'title': '', 'title': '',
@ -623,6 +631,7 @@ class DataFactory(object):
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_type': sort_type, 'stat_type': sort_type,
'stat_title': 'Most Active Users',
'rows': session.mask_session_info(top_users, mask_metadata=False)}) 'rows': session.mask_session_info(top_users, mask_metadata=False)})
elif stat == 'top_platforms': elif stat == 'top_platforms':
@ -659,6 +668,7 @@ class DataFactory(object):
'title': '', 'title': '',
'thumb': '', 'thumb': '',
'grandparent_thumb': '', 'grandparent_thumb': '',
'art': '',
'users_watched': '', 'users_watched': '',
'rating_key': '', 'rating_key': '',
'user': '', 'user': '',
@ -669,6 +679,7 @@ class DataFactory(object):
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_type': sort_type, 'stat_type': sort_type,
'stat_title': 'Most Active Platforms',
'rows': session.mask_session_info(top_platform, mask_metadata=False)}) 'rows': session.mask_session_info(top_platform, mask_metadata=False)})
elif stat == 'last_watched': elif stat == 'last_watched':
@ -727,6 +738,7 @@ class DataFactory(object):
last_watched.append(row) last_watched.append(row)
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_title': 'Last Watched Items',
'rows': session.mask_session_info(last_watched)}) 'rows': session.mask_session_info(last_watched)})
elif stat == 'most_concurrent': elif stat == 'most_concurrent':
@ -807,6 +819,7 @@ class DataFactory(object):
return None return None
home_stats.append({'stat_id': stat, home_stats.append({'stat_id': stat,
'stat_title': 'Most Concurrent Streams',
'rows': most_concurrent}) 'rows': most_concurrent})
return home_stats return home_stats