Compare commits

...

7 Commits

Author SHA1 Message Date
Tim
fd3daae491 v1.1.1 2015-08-15 21:54:43 +02:00
drzoidberg33
697d107952 Merge pull request #71 from jroyal/include-show-title-in-rec-add
Recently added TV Shows display title of the show
2015-08-15 21:49:29 +02:00
drzoidberg33
65e42be278 Merge pull request #69 from jroyal/feature-show-most-watched-movie
Most watched movie is now on home page
2015-08-15 21:48:27 +02:00
Tim
ad79d860db Allow the buffer warnings to be completely disabled by setting buffer threshold to 0.
Fix bug with buffer warnings where notification would trigger continuously after first trigger.
Fix bug where custom avatar URL would get reset on every user refresh.
2015-08-15 21:30:31 +02:00
James Royal
5826a823a8 Add parent_title to the docs of recently_added.html 2015-08-15 13:52:50 -05:00
James Royal
cbec1e7768 Recently added TV Shows display title of the show 2015-08-15 13:28:32 -05:00
James Royal
40f72bbe5f Most watched movie is now on home page 2015-08-15 12:26:37 -05:00
11 changed files with 135 additions and 28 deletions

View File

@@ -23,3 +23,10 @@
* Fix alignment of bands on daily graphs which highlight weekends.
* Fix behaviour of close button on update popup, will now stay closed for an hour after clicking close.
* Fix some styling niggles.
## v1.1.1 (2015-08-15)
* Added Most watched movie for home stats. Thanks @jroyal.
* Added TV show title to recently added text. Thanks @jroyal.
* Fix bug with buffer warnings where notification would trigger continuously after first trigger.
* Fix bug where custom avatar URL would get reset on every user refresh.

View File

@@ -31,7 +31,7 @@ DOCUMENTATION :: END
<div class="form-group">
<label for="friendly_name">Friendly Name</label>
<div class="row">
<div class="col-xs-6">
<div class="col-md-6">
<input type="text" class="form-control" id="friendly_name" name="friendly_name" value="${data['friendly_name']}" size="30">
</div>
</div>
@@ -40,11 +40,11 @@ DOCUMENTATION :: END
<div class="form-group">
<label for="profile_url">Profile Picture URL</label>
<div class="row">
<div class="col-xs-6">
<div class="col-md-8">
<input type="text" class="form-control" id="profile_url" name="profile_url" value="${data['thumb']}">
</div>
</div>
<p class="help-block">Change the users profile picture in plexpy. You should save the URL if you would like to go back as this replaces the existing one.</p>
<p class="help-block">Change the users profile picture in PlexPy.</p>
</div>
<div class="checkbox">
<label>

View File

@@ -93,6 +93,31 @@ DOCUMENTATION :: END
</div>
</li>
</div>
% elif a['stat_id'] == 'top_movies' and a['rows']:
<div class="home-platforms-instance">
<li>
<span>
<a href="info?item_id=${a['rows'][0]['rating_key']}">
% if a['rows'][0]['thumb']:
<img class="home-platforms-instance-poster"
src="pms_image_proxy?img=${a['rows'][0]['thumb']}&width=162&height=240&fallback=poster">
% else:
<img class="home-platforms-instance-poster" src="interfaces/default/images/poster.png">
% endif
</a>
</span>
<div class="home-platforms-instance-name">
<h4>Most Watched Movie</h4>
<h5><a href="info?item_id=${a['rows'][0]['rating_key']}">
${a['rows'][0]['title']}
</a></h5>
</div>
<div class="user-platforms-instance-playcount">
<h3>${a['rows'][0]['total_plays']}</h3>
<p> plays</p>
</div>
</li>
</div>
% elif a['stat_id'] == 'top_users' and a['rows']:
<div class="home-platforms-instance">
<li>

View File

@@ -15,6 +15,7 @@ type Returns the type of media. Either 'movie' or 'season'.
thumb Returns the location of the item's thumbnail. Use with pms_image_proxy.
added_at Returns the time when the media was added to the library.
title Returns the name of the movie or season.
parent_title Returns the name of the TV Show a season belongs too.
== Only if 'type' is 'movie' ==
year Returns the movie release year.
@@ -42,7 +43,9 @@ DOCUMENTATION :: END
% endif
</div>
<div class="dashboard-recent-media-metacontainer">
% if item['type'] == 'season' or item['type'] == 'album':
% if item['type'] == 'season':
<h3>${item['parent_title']} - ${item['title']}</h3>
% elif item['type'] == 'album':
<h3>${item['title']}</h3>
% elif item['type'] == 'movie':
<h3>${item['title']} (${item['year']})</h3>

View File

@@ -369,10 +369,10 @@ available_notification_agents = notifiers.available_notification_agents()
<label for="buffer_threshold">Buffer Threshold</label>
<div class="row">
<div class="col-md-2">
<input type="text" class="form-control" data-parsley-type="integer" id="buffer_threshold" name="buffer_threshold" value="${config['buffer_threshold']}" data-parsley-range="[1,50]" data-parsley-trigger="change" required>
<input type="text" class="form-control" data-parsley-type="integer" id="buffer_threshold" name="buffer_threshold" value="${config['buffer_threshold']}" data-parsley-range="[0,50]" data-parsley-trigger="change" required>
</div>
</div>
<p class="help-block">How many buffer events should we wait before triggering the first warning. Buffer events increment on each monitor ping if play state is buffering.</p>
<p class="help-block">How many buffer events should we wait before triggering the first warning. Buffer events increment on each monitor ping if play state is buffering. 0 to disable buffer warnings.</p>
</div>
<div class="form-group">
<label for="buffer_wait">Buffer Wait</label>

View File

@@ -388,7 +388,7 @@ def dbcheck():
'user_id INTEGER DEFAULT NULL UNIQUE, username TEXT NOT NULL UNIQUE, '
'friendly_name TEXT, thumb TEXT, email TEXT, is_home_user INTEGER DEFAULT NULL, '
'is_allow_sync INTEGER DEFAULT NULL, is_restricted INTEGER DEFAULT NULL, do_notify INTEGER DEFAULT 1, '
'keep_history INTEGER DEFAULT 1)'
'keep_history INTEGER DEFAULT 1, custom_avatar_url TEXT)'
)
# Upgrade sessions table from earlier versions
@@ -534,29 +534,29 @@ def dbcheck():
'on_pause INTEGER, on_resume INTEGER, on_buffer INTEGER)'
)
# Upgrade sessions table from earlier versions
# Upgrade users table from earlier versions
try:
c_db.execute('SELECT do_notify from users')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table sessions.")
logger.debug(u"Altering database. Updating database table users.")
c_db.execute(
'ALTER TABLE users ADD COLUMN do_notify INTEGER DEFAULT 1'
)
# Upgrade sessions table from earlier versions
# Upgrade users table from earlier versions
try:
c_db.execute('SELECT keep_history from users')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table sessions.")
logger.debug(u"Altering database. Updating database table users.")
c_db.execute(
'ALTER TABLE users ADD COLUMN keep_history INTEGER DEFAULT 1'
)
# Upgrade sessions table from earlier versions
# Upgrade notify_log table from earlier versions
try:
c_db.execute('SELECT on_pause from notify_log')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table sessions.")
logger.debug(u"Altering database. Updating database table notify_log.")
c_db.execute(
'ALTER TABLE notify_log ADD COLUMN on_pause INTEGER'
)
@@ -579,6 +579,15 @@ def dbcheck():
'ALTER TABLE sessions ADD COLUMN buffer_last_triggered INTEGER'
)
# Upgrade users table from earlier versions
try:
c_db.execute('SELECT custom_avatar_url from users')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table users.")
c_db.execute(
'ALTER TABLE users ADD COLUMN custom_avatar_url TEXT'
)
conn_db.commit()
c_db.close()

View File

@@ -30,7 +30,7 @@ class DataFactory(object):
data_tables = datatables.DataTables()
columns = ['users.user_id as user_id',
'users.thumb as thumb',
'users.custom_avatar_url as thumb',
'(case when users.friendly_name is null then users.username else \
users.friendly_name end) as friendly_name',
'MAX(session_history.started) as last_seen',
@@ -256,7 +256,7 @@ class DataFactory(object):
monitor_db = database.MonitorDatabase()
control_value_dict = {"user_id": user_id}
new_value_dict = {"thumb": profile_url}
new_value_dict = {"custom_avatar_url": profile_url}
try:
monitor_db.upsert('users', new_value_dict, control_value_dict)
except Exception, e:
@@ -268,7 +268,7 @@ class DataFactory(object):
monitor_db = database.MonitorDatabase()
control_value_dict = {"username": user}
new_value_dict = {"thumb": profile_url}
new_value_dict = {"custom_avatar_url": profile_url}
try:
monitor_db.upsert('users', new_value_dict, control_value_dict)
except Exception, e:
@@ -279,7 +279,7 @@ class DataFactory(object):
monitor_db = database.MonitorDatabase()
query = 'select username, ' \
'(CASE WHEN friendly_name IS NULL THEN username ELSE friendly_name END),' \
'do_notify, keep_history, thumb ' \
'do_notify, keep_history, custom_avatar_url as thumb ' \
'FROM users WHERE user_id = ?'
result = monitor_db.select(query, args=[user_id])
if result:
@@ -303,7 +303,7 @@ class DataFactory(object):
monitor_db = database.MonitorDatabase()
query = 'select user_id, ' \
'(CASE WHEN friendly_name IS NULL THEN username ELSE friendly_name END),' \
'do_notify, keep_history, thumb ' \
'do_notify, keep_history, custom_avatar_url as thumb ' \
'FROM users WHERE username = ?'
result = monitor_db.select(query, args=[user])
if result:
@@ -347,7 +347,7 @@ class DataFactory(object):
if user:
query = 'SELECT user_id, username, friendly_name, email, ' \
'thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
'custom_avatar_url as thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
'FROM users ' \
'WHERE username = ? ' \
'UNION ALL ' \
@@ -359,7 +359,7 @@ class DataFactory(object):
result = monitor_db.select(query, args=[user, user])
elif user_id:
query = 'SELECT user_id, username, friendly_name, email, ' \
'thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
'custom_avatar_url as thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
'FROM users ' \
'WHERE user_id = ? ' \
'UNION ALL ' \
@@ -402,7 +402,7 @@ class DataFactory(object):
# Refresh users
plextv.refresh_users()
query = 'SELECT user_id, username, friendly_name, email, ' \
'thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
'custom_avatar_url as thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
'FROM users ' \
'WHERE username = ? ' \
'UNION ALL ' \
@@ -416,7 +416,7 @@ class DataFactory(object):
# Refresh users
plextv.refresh_users()
query = 'SELECT user_id, username, friendly_name, email, ' \
'thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
'custom_avatar_url as thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
'FROM users ' \
'WHERE user_id = ? ' \
'UNION ALL ' \
@@ -472,7 +472,8 @@ class DataFactory(object):
if not time_range.isdigit():
time_range = '30'
stats_queries = ["top_tv", "popular_tv", "top_users", "top_platforms"]
# This actually determines the output order in the home page
stats_queries = ["top_tv", "popular_tv", "top_movies", "top_users", "top_platforms"]
home_stats = []
for stat in stats_queries:
@@ -516,6 +517,46 @@ class DataFactory(object):
home_stats.append({'stat_id': stat,
'rows': top_tv})
elif 'top_movies' in stat:
top_movies = []
try:
query = 'SELECT session_history_metadata.id, ' \
'session_history_metadata.full_title, ' \
'COUNT(session_history_metadata.full_title) as total_plays, ' \
'session_history_metadata.rating_key, ' \
'MAX(session_history.started) as last_watch,' \
'session_history_metadata.thumb ' \
'FROM session_history_metadata ' \
'JOIN session_history on session_history_metadata.id = session_history.id ' \
'WHERE datetime(session_history.stopped, "unixepoch", "localtime") ' \
'>= datetime("now", "-%s days", "localtime") ' \
'AND session_history_metadata.media_type = "movie" ' \
'GROUP BY session_history_metadata.full_title ' \
'ORDER BY total_plays DESC LIMIT 10' % time_range
result = monitor_db.select(query)
except:
logger.warn("Unable to execute database query.")
return None
for item in result:
row = {'title': item[1],
'total_plays': item[2],
'users_watched': '',
'rating_key': item[3],
'last_play': item[4],
'grandparent_thumb': '',
'thumb': item[5],
'user': '',
'friendly_name': '',
'platform_type': '',
'platform': '',
'row_id': item[0]
}
top_movies.append(row)
home_stats.append({'stat_id': stat,
'rows': top_movies})
elif 'popular_tv' in stat:
popular_tv = []
try:
@@ -566,7 +607,7 @@ class DataFactory(object):
'users.friendly_name end) as friendly_name,' \
'COUNT(session_history.id) as total_plays, ' \
'MAX(session_history.started) as last_watch, ' \
'users.thumb, ' \
'users.custom_avatar_url as thumb, ' \
'users.user_id ' \
'FROM session_history ' \
'JOIN session_history_metadata ON session_history.id = session_history_metadata.id ' \

View File

@@ -72,7 +72,7 @@ def check_active_sessions():
monitor_db.action('UPDATE sessions SET paused_counter = ? '
'WHERE session_key = ? AND rating_key = ?',
[paused_counter, stream['session_key'], stream['rating_key']])
if session['state'] == 'buffering':
if session['state'] == 'buffering' and plexpy.CONFIG.BUFFER_THRESHOLD > 0:
# The stream is buffering so we need to increment the buffer_count
# We're going just increment on every monitor ping,
# would be difficult to keep track otherwise
@@ -107,6 +107,12 @@ def check_active_sessions():
plexpy.CONFIG.BUFFER_WAIT:
logger.info(u"PlexPy Monitor :: User '%s' has triggered multiple buffer warnings."
% stream['user'])
# Set the buffer trigger time
monitor_db.action('UPDATE sessions '
'SET buffer_last_triggered = strftime("%s","now") '
'WHERE session_key = ? AND rating_key = ?',
[stream['session_key'], stream['rating_key']])
threading.Thread(target=notification_handler.notify,
kwargs=dict(stream_data=stream, notify_action='buffer')).start()

View File

@@ -37,6 +37,15 @@ def refresh_users():
"is_restricted": item['is_restricted']
}
# Check if we've set a custom avatar if so don't overwrite it.
avatar_urls = monitor_db.select('SELECT thumb, custom_avatar_url '
'FROM users WHERE user_id = ?',
[item['user_id']])
if not avatar_urls[0]['custom_avatar_url'] or \
avatar_urls[0]['custom_avatar_url'] == avatar_urls[0]['thumb']:
new_value_dict['custom_avatar_url'] = item['thumb']
monitor_db.upsert('users', new_value_dict, control_value_dict)
logger.info("Users list refreshed.")

View File

@@ -218,6 +218,7 @@ class PmsConnect(object):
recent_items = {'type': recent_type,
'rating_key': helpers.get_xml_attr(item, 'ratingKey'),
'title': helpers.get_xml_attr(item, 'title'),
'parent_title': helpers.get_xml_attr(item, 'parentTitle'),
'thumb': helpers.get_xml_attr(item, 'thumb'),
'added_at': helpers.get_xml_attr(item, 'addedAt')
}
@@ -232,6 +233,7 @@ class PmsConnect(object):
recent_items = {'type': recent_type,
'rating_key': helpers.get_xml_attr(item, 'ratingKey'),
'title': helpers.get_xml_attr(item, 'title'),
'parent_title': helpers.get_xml_attr(item, 'parentTitle'),
'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'),
'added_at': helpers.get_xml_attr(item, 'addedAt')

View File

@@ -186,6 +186,11 @@ class WebInterface(object):
keep_history = kwargs.get('keep_history')
else:
keep_history = 0
if 'thumb' in kwargs:
custom_avatar = kwargs['thumb']
else:
custom_avatar = ''
if user_id:
try:
data_factory = datafactory.DataFactory()
@@ -194,7 +199,7 @@ class WebInterface(object):
do_notify=do_notify,
keep_history=keep_history)
data_factory.set_user_profile_url(user_id=user_id,
profile_url=kwargs['thumb'])
profile_url=custom_avatar)
status_message = "Successfully updated user."
return status_message
@@ -209,7 +214,7 @@ class WebInterface(object):
do_notify=do_notify,
keep_history=keep_history)
data_factory.set_user_profile_url(user=user,
profile_url=kwargs['thumb'])
profile_url=custom_avatar)
status_message = "Successfully updated user."
return status_message